Страница 1 из 1

Счетчик просроченных дней

Добавлено: 07 фев 2017, 02:15
Евгений
Выношу сюда из темы https://www.rukovoditel.net/forum/ru/vi ... ?f=2&t=761

В рамках обмена опытом, представляю настройки своей системы.
$Expert писал(а):Евгений! Здравствуйте! Вопрос немного не в тему, но помогите, пожалуйста, разобраться в вопросе на примере вашего вложения (Гант 2 фильтр). Вижу, что у Вас в колонке "Просрочено дней" посчитано количество дней просрочки от плановой даты окончания до фактической (в 1 и 2 строках одна дата окончания, но разное количество дней просрочки). Может где то не там "копал", но перерыл весь форум и сайт и так и не разобрался, как "останавливать" счётчик просроченных дней при фактическом выполнении задачи. Заранее благодарю.
Вот картинка, по которой возник вопрос -
Гант 2 фильтр.JPG
Конкретно по этим двум задачам, которые имеют одинаковую плановую дату окончания. Обе задачи имеют статус Исполнено. Но задача с ИД=22 была выполнен 02.11.2016, а задача с ИД=24 выполнена 08.12.2016. Поэтому разное число просроченных дней.

В сущность Задача добавлено поле "Просрочено дней" типа Формула -
формула.JPG
В настройках поля видно, что значение вычисляется путём вызова пользовательской функции из БД, с передачей параметров. Вот код самой функции -

Код: Выделить всё

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
Логика такая - если в поле Статус не установлено значение Исполнено, то число дней просрочки считается как разница между плановой датой и сегодня.
Если флаг Исполнено установлен, то Проверяющий может либо закрыть задачу, либо снять флаг Исполнено и вернуть задачу в работу. В последнем случае датой исполнения считается дата самого последнего по времени комментария, в котором исполнитель выставил флаг Исполнено. Таких итераций "Доклад об исполнении -- Работа не выполнена, делай дальше" может быть несколько. Исполнитель не проверил свою работу, но бодро отчитался что всё готово - тогда переделывает по второму кругу, но уже с нарушением установленного срока.

Редактировать задачу может только Постановщик (проверяющий). Для исполнителей содержимое задачи доступно только для чтения, всё общение с Постановщиком происходит только через комментарии. В комментарии же исполнитель выставляет флаг Исполнено.
коммент.jpg
К сожалению, Руководитель в текущей версии пока не позволяет ограничивать доступ пользователей к различным значениям списков. Поэтому пришлось отказаться от одного глобального списка Статус, в котором перечислены все этапы рабочего потока задачи (В работе/Отложено/Исполнено/Закрыто), иначе исполнитель сможет самостоятельно выставить себе сразу статус Закрыто, и попробуй отследи эту задачу. У меня поле Статус имеет только один элемент - Исполнено. А закрытие исполненных задач производится через другое поле с отдельным флагом.

Когда придумаю как обойти это ограничение, то можно будет сильно упростить логику.

Re: Счетчик просроченных дней

Добавлено: 07 фев 2017, 11:04
$Expert
Евгений! Огроменное спасибо!
Это именно то, что "доктор прописал", иду по Вашим шагам.

Re: Счетчик просроченных дней

Добавлено: 13 фев 2017, 22:42
$Expert
Приветствую! Подскажите, может у кого есть мысли по дальнейшему развитию данной темы. С подсказками Евгения решил вопрос с расчётом количества просроченных дней по каждой задаче:
1.png
А вот в списке проектов нужно показать общее количество задач, количество открытых задач и количество просроченных задач. Первые два пункта решил с помощью функций, а вот количество просроченных задач победить не удаётся. Ясно, что связано это с тем, что значение вычисляется запросом с БД и при открытии сущности проекты этого запроса не происходит, но может у кого есть мысли, как это можно сделать?
2.png

Re: Счетчик просроченных дней

Добавлено: 21 фев 2017, 06:29
Евгений
Тоже вызывать из БД пользовательскую функцию, которая сделает эти расчеты.