Работа с календарём рабочих дней (для разработчика)¶
Настройка через SiteSettings¶
- В системных настройках (
SiteSettings) указывается ключ меры календаря рабочих дней:working_days_calendar__is_working_day. - Если настройка не указана, расчёты ведутся по календарным дням.
Требования к параметру календаря¶
- Мера: тип INTEGER, значения:
1— рабочий,0— нерабочий. - Параметр должен быть связан с уровнем иерархии "День" (
horizon__day). - Ключи:
- Меры:
WORKING_DAYS_CALENDAR_MEASURE_KEY(см.horizons/models.py) - Уровня:
HORIZON_DAY_LEVEL_KEY(см.horizons/models.py)
- Меры:
Ключевые константы и настройки¶
- WORKING_DAYS_CALENDAR_MEASURE_KEY: "working_days_calendar__is_working_day" — ключ для SiteSettings, определяет меру календаря рабочих дней.
- HORIZON_DAY_LEVEL_KEY: "horizon__day" — ключ уровня иерархии для дней.
Структура параметра и меры¶
- Parameter (
core/parameters/models.py): key= "working_days_calendar"dimensions— обязательно содержит Dimension сkey="horizon__day"- Measure (
core/parameters/models.py): key= "working_days_calendar__is_working_day"type= 1 (INTEGER)- Значения: 1 — рабочий, 0 — нерабочий
- Dimension:
key= "horizon__day"hierarchy_level— ссылка на уровень иерархии "День"
Модель HorizonItem (core/horizons/models.py)¶
- Поля:
num,start_date,end_date,period,level(ForeignKey на уровень иерархии) - Используется для хранения дат и идентификаторов дней
Сценарий автоматического заполнения¶
- Сценарий:
fill_working_days(core/horizons/scripts/fill_working_days.py). - Аргументы:
start_date,end_date,holidays_key(страна),create_measure_if_missing. - Если мера или параметр отсутствуют — создаются автоматически.
- Используется библиотека
workalendarдля определения рабочих дней.
Методы расчёта дат и длительности¶
calculate_due_date(start_date, duration_days)— возвращает дату окончания задачи с учётом рабочих дней (если календарь настроен), иначе — по календарным дням.calculate_duration(start_date, due_date)— возвращает длительность задачи в рабочих днях (если календарь настроен), иначе — по календарным дням.- Оба метода реализованы в
core/workflow/utils.py.
⚠️ Важное поведение: Если в SiteSettings указан ключ меры календаря, но мера отсутствует, методы
calculate_due_date()иcalculate_duration()вcore/workflow/models.pyвыбрасываютValueError. Это может привести к ошибкам при создании рабочих процессов.
Методы расчёта (core/workflow/utils.py)¶
- _get_working_days_from_db(start_date, end_date=None): возвращает словарь {дата: 1/0} из БД по мере календаря
- calculate_due_date(start_date: date, duration_days: int) -> date: возвращает дату окончания задачи, учитывая только рабочие дни (если календарь настроен)
- calculate_duration(start_date: date, due_date: date) -> int: возвращает количество рабочих дней между датами (включительно)
- get_critical_path_duration(obj): рекурсивно вычисляет длительность по критическому пути для задач с вложенностью и последовательностью
Примеры из тестов¶
- Тесты:
core/workflow/tests/test_issue_working_days.py. - Проверяются случаи:
- Расчёт через выходные и праздники.
- Корректный пересчёт при изменении дат/длительности.
- Fallback на календарные дни, если календарь не настроен.
Важно¶
- Все расчёты дат и длительностей в workflow используют эти методы.
- Если календарь не настроен — используется обычный календарь.
- Для ручного редактирования меры используйте метод корректировки
set_equal.
См. также¶
Ручное редактирование¶
- Для ручного редактирования меры календаря рабочих дней используйте метод корректировки
set_equal(привязывается через админку к мере)
SQL-структуры¶
- Таблица фактов для параметра создаётся автоматически методом
param.sync()
Подробнее о синхронизации: См. Синхронизация параметров (для разработчиков) — как работает автоматическое создание таблиц. - Для dimension:
dim_<key>, для measure:m_<key>
Примеры использования¶
- Пример создания параметра и меры см. в тестах:
core/workflow/tests/test_issue_working_days.py - Пример вызова сценария:
fill_working_days(start_date='2024-01-01', end_date='2024-12-31', holidays_key='RU')
Ссылки на код¶
- Константы:
src/planiqum/core/horizons/models.py - Сценарий:
src/planiqum/core/horizons/scripts/fill_working_days.py - Методы расчёта:
src/planiqum/core/workflow/utils.py - Модели:
src/planiqum/core/parameters/models.py,src/planiqum/core/horizons/models.py - Тесты:
src/planiqum/core/workflow/tests/test_issue_working_days.py