' Скрипт запуска бизнес-процесса по нажатию кнопки
'
' v 1.0.0

' Константы
Const TEMPLATE_ID = "{5B78F617-5FEB-4BE4-B299-811B0EE0A088}" ' - идентификтор шаблона процесса
Const FOLDER_ID = "{8104D728-6786-4DF9-9374-9C4A6886054E}" ' - идентификатор папки, в которую помещается созданный процесс
Const CARD_VARIABLE_NAME = "Карточка заявки" ' - название переменной процесса, в которую запишется карточка, из которой запустили процесс
Const PROCESS_NAME = "Рассмотрение заявки" ' - название экземпляра процесса

Dim QUESTION_TEXT: QUESTION_TEXT = "Вы хотите запустить бизнес-процесс рассмотрения заявки?" ' - Текст вопроса
Dim QUESTION_TITLE: QUESTION_TITLE = "Запуск бизнес-процесса" ' - Заголовок вопроса

Const FLAG_PROP_NAME = "Флаг запуска" ' - Название свойства, содержащего признак того, что процесс уже запущен
Dim WARNING_TEXT: WARNING_TEXT = "Процесс уже запущен" ' - Текст предупреждения о том, что процесс уже запущен
Dim WARNING_TITLE: WARNING_TITLE = "Предупреждение" ' - Заголовок предупреждения о том, что процесс уже запущен


' Основная функция скрипта
Function DoEvent(UserSession, CardFrame, CardData, ActivateFlags, ModeID, FolderID)

    ' Проверить значение флага запуска
    If GetProp(CardData, FLAG_PROP_NAME, 0) > 0 Then

        ' Вывести предупреждение
        MsgBox WARNING_TEXT, vbOK Or vbExclamation, WARNING_TITLE

        ' Заблокировать кнопку и выйти
        DoEvent = 1
        Exit Function

    End If

    ' Задать вопрос пользоватею
    If MsgBox(QUESTION_TEXT, vbYesNo Or vbInformation, QUESTION_TITLE) = vbYes Then

        ' Создать процесс WF по шаблону
        Dim Process, ProcessName
        Set Process = WFProcessByTemplate(UserSession, TEMPLATE_ID, FOLDER_ID, PROCESS_NAME)

        ' Записать текущую карточку в переменную
        Process.Variable(CARD_VARIABLE_NAME) = CardData.ID

        ' Запуск процесса
        Process.Start

        ' Установить флаг запуска
        SetProp CardData, FLAG_PROP_NAME, 1, "1"

        ' Выйти и закрыть карточку
        DoEvent = 8 Or 16 Or 64
        Exit Function

    End If

    DoEvent = 0

End Function

' Создать WFProcess по шаблону
Function WFProcessByTemplate(UserSession, TemplateID, FolderID, ProcessName)
    Dim Process, Folder
    Set Process = UserSession.CardManager.CardData(TemplateID).Copy
    Process.IsTemplate = False
    Process.Description = ProcessName
    With MainInfo(Process)
        .Value("Name") = ProcessName
        .Value("State") = 0
    End With
    Set Folder = FolderCard(UserSession).GetFolder(FolderID)
    Folder.Shortcuts.AddNew Process.ID, True
    Set WFProcessByTemplate = New WFProcess
    Set WFProcessByTemplate.UserSession = UserSession
    WFProcessByTemplate.ProcessID = Process.ID
End Function

' Класс: процесс WF
Class WFProcess

    Public UserSession, ProcessID

    ' Получить значение переменной WF
    Property Get Variable(VarName)
        Variable = GetVarRow(VarName).Value("Value")
    End Property

    ' Установить значение переменной WF
    Property Let Variable(VarName, VarValue)
        GetVarRow(VarName).Value("Value") = VarValue
    End Property

    ' Запустить процесс
    Sub Start
        Dim StartID, Process, Row, ProcessName
        StartID = GetStartID
        Set Process = UserSession.CardManager.CardData(ProcessID)
        With MainInfo(Process)
            .Value("Prepared") = True
            .Value("State") = 1
            ProcessName = .Value("Name")
        End With
        Process.Description = ProcessName & " (активен)"
        For Each Row In Sect(Process, "Functions").Rows
            If Row.Value("TypeID") = StartID Then
                SubSect(Row, "States").FirstRow.Value("State") = 2
            End If
        Next
    End Sub

    Private Function GetVarRow(VarName)
        Dim Vars, VarRow
        Set Vars = Sect(UserSession.CardManager.CardData(ProcessID), "Variables")
        For Each VarRow In Vars.Rows
            If VarRow.Value("Name") = VarName Then
                Set GetVarRow = VarRow
                Exit Function
            End If
        Next
        Set GetVarRow = Nothing
    End Function

    Private Function GetStartID()
        Dim MainInfo, Row
        Set MainInfo = Sect(FunctionList(UserSession), "MainInfo")
        For Each Row In MainInfo.Rows
            If Row.Value("IsStart") = True Then
                GetStartID = Row.Value("ID")
                Exit Function
            End If
        Next
        GetStartID = vbNullString
    End Function

End Class

' Получение секции карточки по имени
Function Sect(CardData, Alias)
    Set Sect = CardData.Sections(CardData.Type.Sections.GetByAlias(Alias).ID)
End Function

' Получение подчиненной секции по имени
Function SubSect(RowData, Alias)
    Set SubSect = RowData.ChildSections(RowData.Section.Type.ChildSections.GetByAlias(Alias).ID)
End Function

' Нулевая строка секции MainInfo
Function MainInfo(CardData)
    Set MainInfo = Sect(CardData, "MainInfo").FirstRow
End Function

' Справочник сотрудников
Function FunctionList(UserSession)
    Set FunctionList = UserSession.CardManager.DictionaryData("{BDB73D05-8DE1-41B2-9F3C-AA76C4D9CD64}")
End Function

' Получение карточки папок
Function FolderCard(UserSession)
    Set FolderCard = UserSession.CardManager.Dictionary("{DA86FABF-4DD7-4A86-B6FF-C58C24D12DE2}")
End Function

' Строка свойства
Function Prop(CardData, Alias)
    Set Prop = Nothing
    Dim Row: For Each Row In Sect(CardData, "Properties").Rows
        If Row.Value("Name") = Alias Then
            Set Prop = Row
            Exit Function
        End If
    Next
End Function

' Получение значения свойства
Function GetProp(CardData, Alias, DefaultValue)
    Dim Row: Set Row = Prop(CardData, Alias)
    If Row Is Nothing Then
        GetProp = DefaultValue
    Else
        GetProp = Row.Value("Value")
        If IsNull(GetProp) Then GetProp = DefaultValue
    End If
End Function

' Установка значения свойства
Sub SetProp(CardData, Alias, Value, DisplayValue)
    With Prop(CardData, Alias)
        .Value("Value") = Value
        .Value("DisplayValue") = DisplayValue
    End With
End Sub