Вычисление срока выполнения задания с учетом обеденного перерыва

3 2

Действует для версии: DIRECTUM 4.3 (IS-Builder 7.5.1) и выше.

Введение

На предприятиях с жестко формализованными бизнес-процессами бывает важно при определении сроков выполнения каждого этапа бизнес-процесса учитывать регламентированное время обеденного перерыва сотрудников.

В стандартной версии системы DIRECTUM этого сделать нельзя, но есть возможность решить эту задачу с помощью предметно-ориентированного инструмента разработки IS-Builder.

Решение заключается в задании в системе времени обеденного перерыва. Обеденный перерыв задается в виде двух констант, определяющих начало и конец обеденного перерыва, значения которых устанавливается при помощи сценария. В блоке типового маршрута вызывается функция, которая вычисляет срок выполнения задания типового маршрута с учетом обеденного перерыва.

 

Разработка решения

Константы и их установка

Для определения в системе обеденного времени потребуется создать константы:

  • DinnerTimeStart – время начала обеденного перерыва, формат ЧЧ:ММ;
  • DinnerTimeEnd – время конца обеденного перерыва, формат ЧЧ:ММ.

Для задания значений этих констант необходимо создать сценарий SetupDinnerTime.

В вычислениях сценария необходимо указать следующий код:

 // Список констант
  !ConstList = "DinnerTimeStart|DinnerTimeEnd"
 // Типы констант
  !TypeList = "Строка:5|Строка:5"
 // Список наименований 
  !NameList = "Время начала обеденного перерыва|Время конца обеденного перерыва"
 // Заголовок окна 
  !WindowTitle = "Установка времени обеденного перерыва"
 
  УстановкиКонстант(!ConstList; !NameList; !TypeList; !WindowTitle)

 

Функция ТМУстановитьСрокУчитываяОбед()

Для вычисления срока выполнения задания типового маршрута с учетом обеденного перерыва необходимо создать функцию ТМУстановитьСрокУчитываяОбед().

Функция обрабатывает только относительный срок, указанный в часах. Если указан абсолютный срок, функция выполняется корректно, но обработку срока не производит.

Параметры функции:

  • Блок – указатель на текущий блок.

Текст вычислений функции:

  !ServiceFactory = GetComponent().Application.ServiceFactory
  !Properties = !Block.Properties

 // Проверить существование свойства Срок исполнения
  !DateIndex = !Properties.IndexOfName(JOB_BLOCK_DEADLINE_PROPERTY)
  if !DateIndex <> -1
    !Date = !Properties.Values(!DateIndex)
    !DeadlineValue = !Date.Value
   // Относительный срок
    !IsRelativeDeadline = !Properties.ValueByName(JOB_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY).Value
   // Единицы измерения срока
    !RelativeDeadlineType = !Properties.ValueByName(JOB_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY).Value
   // Если срок относительный и единицы измерения - часы, то вычисляем срок с учётом обеденного перерыва
    if !IsRelativeDeadline and !RelativeDeadlineType == "Часы"
      !Today = Today()
      !CurrentYear = FormatDate("YY"; !Today)
      !Time = Time()
      !CurrentTime = FormatDate("H:N"; !Time)
      !DateTime = Format("%s %s"; ArrayOf(!Time; !Today))

     // Получить календарь рабочего времени на текущий год
      !Calendar = CreateReference("КРВ").DataSet
      !Calendar.Open()
      if !Calendar.Locate("ISBIntNumber"; !CurrentYear) 

       // Найти в табличной части текущий день
       !Calendar.OpenRecord()
       !CalendarDays = !Calendar.DetailDataSet(1)
        if !CalendarDays.Locate("ISBDate"; !Today)
         // Получить время обеденного перерыва
          !DinnerTimeStart = Конст("DinnerTimeStart")
          !DinnerTimeEnd = Конст("DinnerTimeEnd")
         // Длительность обеденного перерыва в часах
          !DinnerTimeLength = TimeDiff("H"; !DinnerTimeStart; !DinnerTimeEnd)
         // Получить текущее значение срока
          !Number = !Date.Value
          !NumberType = 1 //Часы
          !Deadline = !ServiceFactory.GetRelativeDate(!DateTime; !Number; !NumberType)
          !DeadlineTime = FormatDate("H:N"; !Deadline)
          !DeadlineDate = FormatDate("D.M.YY"; !Deadline)

         // Срок выполнения больше одного дня?
          !IsCurrentDay = TRUE
          !DaysNumber = DateDiff("D"; !Today; !DeadlineDate)
          if !DaysNumber > 0
            !IsCurrentDay = FALSE
          endif         

         // Если время получения задания и время выполнения в одной половине дня 
          if (TimeDiff("M"; !DinnerTimeStart; !CurrentTime) <= 0 and TimeDiff("M"; !DinnerTimeStart; !DeadlineTime) <= 0)
             or (TimeDiff("M"; !DinnerTimeEnd; !CurrentTime) >= 0 and TimeDiff("M"; !DinnerTimeEnd; !DeadlineTime) >= 0)
            if not !IsCurrentDay
              !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * !DaysNumber)
            endif
          endif         

         // Если время выполнения попадает в обеденный перерыв
          if TimeDiff("M"; !DinnerTimeStart; !DeadlineTime) >= 0 and TimeDiff("M"; !DinnerTimeEnd; !DeadlineTime) <= 0
            if !IsCurrentDay
              !DeadlineValue = !DeadlineValue + !DinnerTimeLength
            else
              if (TimeDiff("M"; !DinnerTimeEnd; !CurrentTime) >= 0)
                !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * !DaysNumber)
              endif
              if (TimeDiff("M"; !DinnerTimeStart; !CurrentTime) <= 0)
                !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * (!DaysNumber + 1))
              endif
            endif
          endif         

         // Если время получения задания в первой половине дня, а время выполнения - во второй
          if (TimeDiff("M"; !DinnerTimeStart; !CurrentTime) <= 0 and TimeDiff("M"; !DinnerTimeEnd; !DeadlineTime) >= 0)
            !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * (!DaysNumber + 1))
          endif         

         // Если время получения задания попадает в обеденный перерыв 
          if (TimeDiff("M"; !DinnerTimeStart; !CurrentTime) >= 0 and TimeDiff("M"; !DinnerTimeEnd; !CurrentTime) <= 0)
            if !IsCurrentDay
              !DeadlineValue = !DeadlineValue + !DinnerTimeLength
            else
              if (TimeDiff("M"; !DinnerTimeEnd; !DeadlineTime) >= 0)
                !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * (!DaysNumber + 1))
              endif
              if (TimeDiff("M"; !DinnerTimeStart; !DeadlineTime) <= 0)
                !DeadlineValue = !DeadlineValue + (!DinnerTimeLength * !DaysNumber)
              endif
            endif
          endif       

         // Установить новый срок выполнения задания
          !Date.Value = !DeadlineValue
 
        endif // !CalendarDays.Locate("ISBDate"; !Today)
      endif // !Calendar.Locate("ISBIntNumber"; !CurrentYear)
    endif // !IsRelativeDeadline and !RelativeDeadlineType == "Часы"
  else 
   // Свойство %s не найдено!
    !Message = Format(LoadString('DIRSTR_761'; 'COMMON'); ArrayOf(JOB_BLOCK_DEADLINE_PROPERTY)) 
    Raise(CreateException(''; !Message; ecException))
  endif 

 

Настройка и использование

Перед началом использования функции ТМУстановитьСрокУчитываяОбед() необходимо запустить сценарий SetupDinnerTime и установить время обеденного перерыва.

Вызов функции ТМУстановитьСрокУчитываяОбед() необходимо осуществлять в событии «Старт» блока типового маршрута, для которого требуется вычислить срок.

Пример вызова функции:

ТМУстановитьСрокУчитываяОбед(!Sender)

3
Авторизуйтесь, чтобы оценить материал.
Илья Зацарный

скрипт не работает, ну по карйней мере у меня, я его ставлю на версию 4.8 (может в этом проблема)

!Deadline = !ServiceFactory.GetRelativeDate(!DateTime; !Number; !NumberType)

методу GetRelativeDate нельзя передавать строку !DateTime = Format("%s %s"; ArrayOf(!Time; !Today)), я передаю просто переменную с датой !Deadline = !ServiceFactory.GetRelativeDate(!Today; !Number; !NumberType), ошибок не выбивает, скрипт запускается,считает правильно, но обед не учитывает...

 


 

Сергей Мищенко

не срабатывает, например, в таком случае:

старт задания в 12:30, срок - 12 часов. Результат функции - 13:30.

 

Вставил вот такой блок перед присваиванием нового срока:

         // Если все таки попало на обед - добавить время обеда
         !NewDeadLineValue = !ServiceFactory.GetRelativeDate(!DateTime; !DeadlineValue; !NumberType)
         !DeadLineValueTimeNew = FormatDate("H:N"; !NewDeadLineValue)
         if (TimeDiff("M"; !DinnerTimeStart; !DeadLineValueTimeNew) >= 0 and TimeDiff("M"; !DinnerTimeEnd; !DeadLineValueTimeNew) <= 0) 
          !DeadLineValue = !DeadLineValue + !DinnerTimeLength         
         endif

Авторизуйтесь, чтобы написать комментарий