Обработка результатов выполнения блока ТМ с установками "Прерывать выполнение"

6 6

Собственно суть вопроса:

Мы имеем блок типа задание. В качестве исполнителей по блоку указана роль. Роль в любом случае при вычислении дает IUserList, т.е. в качестве исполнителей мы имеем список пользователей. Имеется два варианта выполнения: "Согласовано", "На доработку". Напротив каждого из двух мы ставим галочку "Прерывать выполенение". В таком случае просиходит следующее:
Один из исполнителей выполняет задание с вариантом "Согласовано", при этом другим исполнителям задания прекращаются. Аналогично при варианте "На доработку". Кроме этого задан крайний срок, нужно обрабатывать вариант выполнения по крайнему сроку.

Исходный вопрос был на форуме:  http://club.directum.ru/forum/messages.aspx?TopicID=496

Как выяснилось при установке галочки "прекращать задание" нет выбора на выходящей стрелке "согласовано" и "на доработку" они просто пропадают из результатов выполнения в свойствах элемента, остается только безусловный и прекращено.

В таком случае нужно программно обрабатывать результаты выполнения заданий. Для этого посмотрим на схему тестового маршрута:

 

 В блоке "Определение результата выполнения" происходит получение всех заданий по блоку, определение состояний этих заданий и результатов выполнения, в зависимоти от этого выбирается реузльтат выполнения здания:

  IN_WORK_JOB_STATE = 'В работе'
  EXECUTED_JOB_STATE = 'Выполнено'
  CANCELED_JOB_STATE = 'Прекращено' 
  
  Properties = Sender.Properties
  WorkflowParams = Work.WorkflowParams
  
  // Имя блока согласования
  ApprovingBlockName = 'Блок согласования'  //Properties.ValueByName('ApprovingBlockName').Value
  CurrentTMCode =  'ARVITest11'                    // Properties.ValueByName('CurrentTMCode').Value
  ApprovingExecutionResultCode = '1'               //Properties.ValueByName('ApprovingExecutionResultCode').Value
  RemakeExecutionResultCode = '2'                  //Properties.ValueByName('RemakeExecutionResultCode').Value

  
  // Найти все задания по блоку согласующих
  JobsID = ICEU_FindJobsOfBlock(CurrentTMCode; ApprovingBlockName; Work.ID)
  if Assigned(JobsID)
    s = ''
    HaveCanceled = FALSE
    NeedRemake = FALSE
    Approved = FALSE
    foreach JobID=CSubString(JobsID; '|')
      CurrentJob = Jobs.GetObjectByID(JobID)
      CurrentJobState = CurrentJob.DetailDataSet(3).Requisites('JobState').Value
      ExecutionResult = CurrentJob.ExecutionResult
      if Assigned(ExecutionResult)
        CurrentExecutionResultCode = ExecutionResult.Code
        if Trim(UpperCase(CurrentExecutionResultCode)) == RemakeExecutionResultCode
          NeedRemake = TRUE
        endif
        if Trim(UpperCase(CurrentExecutionResultCode)) == ApprovingExecutionResultCode
          Approved = TRUE
        endif
      else
        CurrentExecutionResultCode = ''
      endif
      if Trim(UpperCase(CurrentJobState)) == Trim(UpperCase(CANCELED_JOB_STATE))
        HaveCanceled = TRUE
      endif
      s = s & CR & Format('Задание с ИД:%s Состояние:%s Результат выполения %s'; ArrayOf(JobID; CurrentJobState; CurrentExecutionResultCode))
    endforeach
    Work.ActiveText = Work.ActiveText & CR & s
  endif
  
  // Пройтись по всем заданиям согласующих
  // Если согласоно и прекращены = согласовано
  // Если все прекращены = срок истек
  // Если отпрака на доработку, то на доработку  
  if NeedRemake
    // На доработку 
    Result = 'R'
  endif
  if Approved
    // Согласованно 
    Result = 'A'
  endif
  if not NeedRemake and not Approved
    // Все просрочили по крайнему сроку
    Result = 'T'
  endif

  

Также используется функция поиска заданий по блоку ТМ определенной задачи ICEU_FindJobsOfBlock(CurrentTMCode; ApprovingBlockName; Work.ID) . Ее текст:

Result = ''
// Получить справочник "Типовые маршруты"
TMTReference = References.ТМТ.GetComponent
TMTReference.Open
if TMTReference.Locate(SysReq_CODE; TMCode)
  // Типовой маршрут с заданным кодом найден
  TMTReference.OpenRecord
  // Получить ИД типового маршрута
  TMID = TMTReference.ID
  // Получить XML схему типового маршрута
  TMScheme = TMTReference.Form.View.Component.DataSet.Requisites('ISBSearchCondition').AsString
  TMTReference.CloseRecord
  TMTReference.Close
  XMLDoc = CreateObject("MSXML2.DOMDocument.3.0")
  XMLDoc.async = FALSE
  XMLDoc.loadXML(TMScheme)
  ExceptionsOff()
  FreeException()
  // Получить ИД блока типового маршрута в XML схеме по определенному ранее имени
  BlockID = XmlDoc.documentElement.selectSingleNode("/Settings/Blocks/Block[Properties/Property[@Name = 'Name']/Value/Value = '" & BlockName & "']/@ID").Text
  ExceptionsOn()
  if ExceptionExists()
    // Блок в XML схеме не неайден
    Raise(CreateException(" "; "Блок с именем '" & BlockName & "' не найден"; ecWarning))
  else
    // Блок в XML схеме найден
    // Получить ИД заданий, которые были созданны по данному блоку
    QueryTemplate = "select J.XrecID
                      from SBTaskJob J
                      join SBTask T
                      on J.TaskID = T.XRecID
                      where (T.StandardRoute = %s ) and (J.WorkflowBlockID = %s) and (T.XrecID = %s)"
    JobsID = SQL(Format(QueryTemplate; ArrayOf(TMID; BlockID; TaskID)))
    Result = JobsID
  endif
else
  // Типовой маршрут с заданным кодом не найден
  TMTReference.Close
  Raise(CreateException(" "; "Типовой маршрут с кодом '" & TMCode & "' не найден"; ecWarning))
endif

Таким образом, на данном примере показано как получать и обрабатывать результаты выполнения заданий созданных по определенному блоку определенного типового маршрута определенной задачи.

Прилагаю разработку ТМ и функции, после импорта необходимо заполнить исполнителей блока согласования и исполнителя уведомлений:

function.zip (2,59 Кб)

TM.zip (8,44 Кб)

Андрей Озеров

Артур, большое спасибо за ваш материал, жаль только я его поздно обнаружил )

Я столкнулся с похожей задачей - определить, что задание по блоку было прекращено по конечному сроку. Нюансом было то, что проверку на результат выполнения я делал в самом блоке в событии Завершение.
 

Евгений Резанов

у меня Ваш маршрут не отрабатывается

Евгений Резанов

пишет "Блок выполнился с ошибкой при обработке значения свойства "вычисление" по причине: Блок с именем 'Блок согласования' не найден"

Александр Найденов

Артур, а с какой целью мы ищем все задания по блоку? Если для получения результата выполнения, то можно ведь проще:

Для блока задание в событии "После запроса параметров" получаем результат выполнения блока и пишем в параметр (смысла нет искать все задания, т.к. они прекращены)

  CONFIRM_CODE = "С"  
  if ТМПолучитьРезультатВыполненияБлока() == CONFIRM_CODE       
     ТМУстановитьПараметрЗадачи("Результат"; 'Согласовано')
  else
    ТМУстановитьПараметрЗадачи("Результат"; 'Не согласовано')              
  endif

Александр Найденов

а вместо блока "сценарий" поставить блок "Условие" в котором сравнить параметр

 

Александр Найденов

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