Друзья, коллеги.
Хотел бы обсудить скажем так идеальный алгоритм. Т.е. некий способ управления историей изменения штатного расписания (количества ставок), который был бы безошибочный
Задача довольно специфична, конечно, но в принципе у нее есть аналогии и в других предметных областях.
Итак.
Штатное расписание (ШР) - здесь список уникальных штатных единиц
Штатная единица (ШЕ) - уникальное сочетания подразделения и должности.
Ставка - количество одноименных штатных единиц
Нас пока интересуют только две дополнительные характеристики штатной единицы: количество ставок по плану просто Ставки, и количество занятых ставок Занято. Величина Ставки и Занято - историческая
Ставки отражают изменения максимально возможного количества
Занято отражают изменения фактически занятого количества
Занято не может превышать Ставки
История плана (Ставки) может выглядеть как-то так
01.01.2011,3
01.05.2011,2
01.08.2011,4
01.10.2011,3
А история Занято
01.01.2011,2
15.01.2011,3
01.05.2011,2
01.09.2011,3.5
01.10.2011,4
На величину Занято влияют следующие операции (документы)
- прием на работу - увеличивает Занято
- увольнение - уменьшает Занято
- перевод - увеличивает Занято одной ШЕ, уменьшает Занято другой ШЕ
- доплата в счет вакансии
-- без ограничения срока действия - аналог приема на работу
-- с ограничением срока действия - увеличивает Занято с даты начала действия доплаты и уменьшает Занято после даты снятия (завершения) доплаты - это единственный особый случай по сути.
Документ подразумевает прямое действие - проведение, и обратное - отведение.
В качестве примера я предложу свое видение алгоритма для двух ситуаций - проведение приема и отведение приема
Договоримся, что в документе приема (и других) нам известно:
- ДатаОперации
- ID ШЕ - идентификатор штатной единицы
- КолСтав - количество ставки, на которую принимается сотрудник
Алгоритм при проведении:
1. Проверить возможность осуществления операции - проверяется не принят ли уже сотрудник, нет ли будущих документов по данному сотруднику (переводы, увольнения, доплаты) - в принципе об этом можно не заморачиваться
2. Проверить наличие вакансии
2.1 Получить СтарКолСтавЗанято на ближайшую ДатуЗанято <= ДатаОперации
2.2 НовКолСтавЗанято = СтарКолСтавЗанято + КолСтав
2.3 Получить КолСтавПлан на ближайшую ДатуПлан < (строго!) ДатаОперации
2.4 Если НовКолСтавЗанято > КолСтавПлан : Стоп! Нет вакансий!
3. Пересчитать историю занято
3.1 Если на Дату > ДатаОперации история Занято пустая : выход
3.2 Для каждой ДатаИстории Занято делать
3.2.1 НовКолСтавЗанято = СтарКолСтавЗанято + КолСтав
3.2.2 Получить КолСтавПлан на ближайшую ДатуПлана < (строго!) ДатаИстории
3.2.3 Если НовКолСтавЗанято > КолСтавПлан : Стоп! на ДатаИстории занято больше, чем по плану. Нарушение согласованности!
4. Принять изменения - завершить проведение документа, записать новую историю
Отведение очень похожее
1. Проверить возможность отведения - разрешено, если это бы последний документ
2. Пересчитать историю занято
2.1 Получить историю Занято с Даты >= ДатаОперации
2.2 Для каждой ДатаИстории Занято делать
2.2.1 НовКолСтавЗанято = СтарКолСтавЗанято - КолСтав
2.2.2 Получить КолСтавПлан на ближайшую ДатуПлана < (строго!) ДатаИстории
2.2.3 Если НовКолСтавЗанято > КолСтавПлан : Стоп! на ДатаИстории занято больше, чем по плану. Нарушение согласованности!
3. Принять изменения - завершить проведение документа, записать новую историю
В алгоритмах учтена следующая особенность: документы, изменяющие Историю занято могут создаваться не в той последовательности, которая обнаруживается при анализе их дат операции. Т.е. например может быть создан прием человека с 10.02.2011, а потом прием с 05.02.2011 и т.п. Это нормально особенно, когда много кадровиков работают и штат большой