Проверьте, перекрывает ли период даты какой-либо из заданных периодов в массиве

У меня есть модуль для продавцов, где они могут добавлять своих менеджеров. Они будут отображаться в ag-сетке пользовательского интерфейса. Чтобы добавить менеджеров, мне нужно выбрать менеджера, дату начала периода и дату окончания периода для данного менеджера. Но одновременно мне также нужно проверить период каждого менеджера, что ни одна из дат менеджера не должна пересекаться друг с другом, на основе этого там решается Статус. У одного продавца может быть N менеджеров, но у каждого продавца одновременно должен быть только один активный менеджер.

В настоящее время я сталкиваюсь с проблемой при сравнении дат текущего менеджера с каждым из заданных менеджеров в массиве.

Я определяю статус на основе следующего кода:

decideStatus(): string {
    let status = '';
    let currentDate = new Date();
    let fromDate = this.salesPersonForm.value.StartDate;
    let tillDate = this.salesPersonForm.value.EndDate;

    if (fromDate <= currentDate && (tillDate > currentDate || tillDate == null)) {
      return status = 'Active'
    } else if (fromDate > currentDate) {
      return status = 'Onhold'
    } else if (tillDate < currentDate) {
      return status = 'Inactive'
    }
  }

У меня есть следующий фрагмент кода для добавления менеджера в сетку.

addManagers(){
    if (this.salesPersonForm.value.SalesPerson) {
      if (this.salesPersonForm.value.StartDate) {
        if (this.salesPersonForm.value.EndDate == null || (this.salesPersonForm.value.EndDate > this.salesPersonForm.value.StartDate)) {
          let loggedInUser = userName;
          let manager = {
            Name: someName
            FromDate: this.salesPersonForm.value.StartDate 
            TillDate: this.salesPersonForm.value.EndDate 
            CreatedAt: new Date()
            CreatedBy: loggedInUser,
            Status: this.decideStatus()
          }
          this.managers.push(manager)
        } else {
          return;
        }
      } else {
        return;
      }
    } else {
      return
    }
    this.clear();
    setTimeout(() => {
      this.agGridReference.assignData(this.managers)
    }, 200);
  }

Прецедент бездействия: M1 — с 01.01.2020 по 31.06.2020 — неактивен M2 — с 08.01.2020 по 31.12.2021 — неактивен M3 - 01.01.2022 to somefuturevalue - Активный

Если даты находятся в будущем, чем текущая дата, она будет считаться отложенной.

Недействительный случай: M1 — с 01.01.2020 по 31.06.2020 — InActive M2 — с 05.01.2020 по 28.02.2021 — неактивен M3 — с 01.01.2021 по 30.05.2021 — неактивен

Ваш метод decideStatus выдает ошибки? Если это так - можете ли вы поделиться этими ошибками? Являются ли даты, которые вы сравниваете, одного типа?

Misha Mashina 17.03.2022 15:37

@MishaMashina NosolveStatus ошибок не выдает, и даты однотипные.

Rohn07 17.03.2022 16:10

Итак, где-то в методе decideStatus вы хотели бы проверить, не пересекается ли интервал этого нового менеджера с интервалами уже существующих менеджеров? Я предполагаю, что перекрытие имеет смысл только в том случае, если новый менеджер имеет статус «активный» и уже есть хотя бы один менеджер с таким статусом?

Misha Mashina 17.03.2022 16:34

@MishaMashina Думаю, я могу проверить интервалы любым из методов. Но какая логика должна быть реализована для проверки каждого периода с несколькими периодами в одном и том же массиве, я не могу понять. Перекрытие необходимо для проверки, потому что в эти периоды работает система комиссий, независимо от статуса. Но да, только один менеджер должен иметь статус «Активен» одновременно.

Rohn07 17.03.2022 17:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
32
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, вы собираетесь поместить нового менеджера в массив managers только в том случае, если интервал нового менеджера не перекрывается с интервалом любого существующего менеджера. Таким образом, проверка должна быть сделана перед вашей строкой this.managers.push(manager), примерно так:

  • заменив this.managers.push(manager) на: this.compareDates(manager);

  • добавив эти два метода:

compareDates(newM) {
    let overlaps = 0;
    this.managers.forEach(m => {
      if (
        // first case:
        // saved manager starts before FromDate
        // and finishes after FromDate
        // of new manager:
        (this.prepareDate(m.FromDate) <= this.prepareDate(newM.FromDate) &&
          this.prepareDate(m.TillDate) >= this.prepareDate(newM.FromDate)) ||
        // second case:
        // saved manager starts after FromDate
        // and before the TillDate
        // of new manager:
        (this.prepareDate(m.FromDate) >= this.prepareDate(newM.FromDate) &&
          this.prepareDate(m.FromDate) <= this.prepareDate(newM.TillDate))
      ) {
        overlaps++;
      }
    });
    if (overlaps == 0) {
      // no overlaps, so push this new manager and do whatever else needs to be done
      this.managers.push(newM);
      console.info('Welcome, new manager!');
    } 
    else {
      // there is at least 1 overlap, so do something else
      // like: return with error message  
      console.info("This manager's interval overlaps with interval(s) of " 
      + overlaps +' other manager(s)!'
      );
    }
  }

И вспомогательный метод для возврата отметки времени каждой даты в предыдущем методе:

prepareDate(date) {
    let parts = date.split('/');
    return Date.parse(parts[2] + '/' + parts[1] + '/' + parts[0]);
}

Чтобы увидеть это в действии: https://stackblitz.com/edit/angular-ivy-j9ldef

Спасибо за идею сойтись, по поводу как решить. Это не совсем решило проблему, но да, это полезно. Большое спасибо.

Rohn07 18.03.2022 10:54

Другие вопросы по теме