В рамках обмена опытом, представляю настройки своей системы.
Вот картинка, по которой возник вопрос -$Expert писал(а):Евгений! Здравствуйте! Вопрос немного не в тему, но помогите, пожалуйста, разобраться в вопросе на примере вашего вложения (Гант 2 фильтр). Вижу, что у Вас в колонке "Просрочено дней" посчитано количество дней просрочки от плановой даты окончания до фактической (в 1 и 2 строках одна дата окончания, но разное количество дней просрочки). Может где то не там "копал", но перерыл весь форум и сайт и так и не разобрался, как "останавливать" счётчик просроченных дней при фактическом выполнении задачи. Заранее благодарю.
Конкретно по этим двум задачам, которые имеют одинаковую плановую дату окончания. Обе задачи имеют статус Исполнено. Но задача с ИД=22 была выполнен 02.11.2016, а задача с ИД=24 выполнена 08.12.2016. Поэтому разное число просроченных дней.
В сущность Задача добавлено поле "Просрочено дней" типа Формула -
В настройках поля видно, что значение вычисляется путём вызова пользовательской функции из БД, с передачей параметров. Вот код самой функции -
Код: Выделить всё
CREATE DEFINER = 'root'@'%'
FUNCTION rukovoditel.over_due(Task_id INT, Complite_id INT, Status INT, DateStop INT)
RETURNS int(11)
BEGIN
-- Параметры
-- Task_id - ИД задачи
-- Complite_id - ИД статуса "Исполнено" из глобального списка
-- Status - фактическое значение поля Статус [169]
-- DateStop - плановая Дата окончания [176]
--
-- Волшебные константы
-- ac.entities_id=22 - ИД сущности Задача
-- ach.fields_id=169 - ИД поля Статус в сущности Задача
-- Количество дней сверх даты окончания
set @over := DATEDIFF( NOW(), FROM_UNIXTIME(DateStop) );
set @over := if(@over>0, @over, 0);
-- Поле Статус установлено в Исполнено, учитываем наличие комментариев
IF (Status = Complite_id) THEN
-- Получаем самый последний по времени комментарий с выставленным флагом Исполнено
set @MaxDate := (
SELECT FROM_UNIXTIME( MAX(ac.date_added))
FROM app_comments ac
LEFT JOIN app_comments_history ach ON ach.comments_id=ac.id
WHERE ac.entities_id=22 AND ac.items_id=Task_id
AND ach.fields_id=169 AND ach.fields_value=Complite_id
);
-- Комментарии с флагом Исполнено отсутствуют, задача считается выполненной в плановый срок
IF (ISNULL(@MaxDate)) THEN
set @over := 0;
-- Есть комментарии с флагами, просрочка расчитывается как разница между плановой датой окончания и датой последнего комментария с флагом Исполнено
ELSE
set @over := DATEDIFF( @MaxDate, FROM_UNIXTIME(DateStop) );
set @over := if(@over>0, @over, 0);
END IF;
END IF;
RETURN @over;
END
Если флаг Исполнено установлен, то Проверяющий может либо закрыть задачу, либо снять флаг Исполнено и вернуть задачу в работу. В последнем случае датой исполнения считается дата самого последнего по времени комментария, в котором исполнитель выставил флаг Исполнено. Таких итераций "Доклад об исполнении -- Работа не выполнена, делай дальше" может быть несколько. Исполнитель не проверил свою работу, но бодро отчитался что всё готово - тогда переделывает по второму кругу, но уже с нарушением установленного срока.
Редактировать задачу может только Постановщик (проверяющий). Для исполнителей содержимое задачи доступно только для чтения, всё общение с Постановщиком происходит только через комментарии. В комментарии же исполнитель выставляет флаг Исполнено.
К сожалению, Руководитель в текущей версии пока не позволяет ограничивать доступ пользователей к различным значениям списков. Поэтому пришлось отказаться от одного глобального списка Статус, в котором перечислены все этапы рабочего потока задачи (В работе/Отложено/Исполнено/Закрыто), иначе исполнитель сможет самостоятельно выставить себе сразу статус Закрыто, и попробуй отследи эту задачу. У меня поле Статус имеет только один элемент - Исполнено. А закрытие исполненных задач производится через другое поле с отдельным флагом.
Когда придумаю как обойти это ограничение, то можно будет сильно упростить логику.
