Создать модель процесса example_process (создание описано тут)
Загрузка описана тут
<?xml version='1.0' encoding='UTF-8'?> <schemas xmlns="http://www.intertrust.ru/schema/palette/tn-schema"> <schema extends="RkkResource" name="RkkResourceInternal"> <!--...--> <schema-ref name="wf" ref="WorkFlow"/> <schema-ref name="wfLifeCycle" ref="WorkFlowLifeCycle" null-empty="true" array="true"/> <!--...--> </schema> </schemas> |
<?xml version='1.0' encoding='UTF-8'?> <ui xmlns="http://www.intertrust.ru/schema/palette/tn-ui"> <form schema-ref="RkkResourceInternal" id="RkkResourceInternalForm" name="${ui.form.RkkResourceInternalForm.name:}" projection="default" showtabs="true"> <properties> <hide condition-union="AND"> <negative-condition-ref ref="edit"/> <negative-condition-ref ref="read"/> </hide> </properties> <appearance widget="tabs"/> <component> <!--...--> <section id="LifeCycle" name="${ui.form.RkkResourceInternalForm.section.LifeCycle.name:Жизненный цикл}"> <properties> <read-only condition-union="AND"> <condition>true</condition> </read-only> </properties> <component> <field attribute-ref="wfLifeCycle"> <properties> <read-only condition-union="AND"> <condition>true</condition> </read-only> </properties> <appearance location="table" importance="normal"/> </field> </component> </section> <!--...--> </component> </form> </ui> |
<?xml version='1.0' encoding='UTF-8'?> <ui xmlns="http://www.intertrust.ru/schema/palette/tn-ui"> <handler name="WF-кнопка" id="WFCustomHandlerName"> <meta> <documentation></documentation> </meta> <script lang="JavaScript"><![CDATA[код кнопки]]></script> </handler> </ui> |
importClass(Packages.ru.intertrust.cmj.af.core.AFSession); importClass(Packages.ru.intertrust.cmj.af.exceptions.AFDaoBadParameterException); importClass(Packages.ru.intertrust.cmj.rest.tunable.object.TunableObjectREST); importClass(Packages.ru.intertrust.cmj.rest.tunable.object.TunableObjectREST.Resource); importClass(Packages.ru.intertrust.cmj.rest.tunable.object.action.TunableOperation); importClass(Packages.ru.intertrust.cmj.tunable.object.AnyTunableObject); importClass(Packages.ru.intertrust.cmj.tunable.object.TunableObjectApplication); importClass(Packages.ru.intertrust.cmj.tunable.object.TunableObjectApplication.ClientContextKey); importClass(Packages.ru.intertrust.cmj.tunable.object.common.TunableObjectHelper); importClass(Packages.ru.intertrust.cmj.rest.tunable.object.action.OperationJScriptREST); importClass(Packages.ru.intertrust.cmj.rest.tunable.object.action.OperationJScriptREST.ReturnParamsResource); importClass(Packages.ru.intertrust.cmj.af.tuning.impl.PropertyImpl); importClass(Packages.ru.intertrust.cmj.dp.DPApplication); importClass(Packages.ru.intertrust.cmj.rest.rkk.RkkResource); importClass(Packages.ru.intertrust.cmj.af.utils.BeansUtils); importClass(Packages.ru.intertrust.cmj.wf.impl.WorkflowProcessServiceImpl); importClass(Packages.ru.intertrust.cmj.wf.api.ProcessVariables); importClass(Packages.ru.intertrust.cmj.wf.api.ProcessUserTask); importClass(Packages.ru.intertrust.cmj.wf.api.TaskVariables); importClass(Packages.ru.intertrust.cmj.af.misc.AFDateTime); importPackage(Packages.ru.intertrust.cmj.af.utils); importPackage(Packages.ru.intertrust.cmj.af.tuning.impl); importPackage(Packages.ru.intertrust.cmj.af.tuning); importPackage(Packages.ru.intertrust.cmj.rest.tuning); importPackage(Packages.java.util); importPackage(Packages.java.lang); importClass(Packages.org.apache.commons.lang3.exception.ExceptionUtils); importClass(Packages.org.slf4j.LoggerFactory); importClass(Packages.ru.intertrust.cm.core.business.api.dto.Filter); importClass(Packages.java.util.Collections); importClass(Packages.ru.intertrust.cmj.af.so.SOApplication); importClass(Packages.ru.intertrust.cmj.af.core.AFCMDomino); importPackage(Packages.ru.intertrust.cm.core.business.api.dto.ReferenceValue); importClass(Packages.ru.intertrust.cm.core.business.api.dto.StringValue); function process(paramsResource, returnResource) { if (paramsResource == null) { throw new IllegalArgumentException("paramsResource must no be null."); } var paramPackageId = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("counter")); if (paramPackageId.equals("context")) { // обработка первого пакета данных process_context(paramsResource, returnResource); } } /** * Обработка первого пакета данных с клиента. * @param paramsResource * @return ресурс первого диалога сценария */ function process_context(paramsResource, returnResource) { var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var ids = appTNObject.getClientContextIds(paramsResource.tuning()); if (ids.isEmpty()) { throw new AFDaoBadParameterException("Не выбраны документы!"); } var appdp = AFSession.get().getApplication(DPApplication.class); var obj = appdp.getEntityByUNID(ids.get(0)); // Необходимо выдать исключение, если заявка удалена или прекращена в WD if ("Webdocs2.0".equals(AFSession.get().currentUser().extendedAttributes().get("ClientAlias"))) { var isTerminate = obj.tuning().getValues().get("wf") == null ? false : obj.tuning().getValues().get("wf").getValues().get("stage") == null ? false : obj.tuning().getValues().get("wf").getValues().get("stage").getValue().equals("Прекращена") ? true : false; if (obj.isDeleted() || isTerminate) { throw new RuntimeException("Заявка была удалена. Обратитесь к администратору") } } var workflowProcessService = BeansUtils.getBean("workflowProcessServiceImpl"); //запустить процесс var StartProcessResult = workflowProcessService.startProcess("example_process", ids.get(0), null); if (StartProcessResult.hasError()) { rollbackWF(appdp, ids.get(0), obj); throw new RuntimeException("Не удалось запустить процесс. Обратитесь к администратору"); } //переоткрываем документ obj = appdp.getEntityByUNID(ids.get(0)); //запись в Жизненный цикл var currentUser = AFSession.get().currentUser().getBeard(); var executor = currentUser; var startDate = new AFDateTime(Calendar.getInstance()); var endDate = new AFDateTime(Calendar.getInstance()); var wf_status = "Отправка на исполнение"; var stage = "На исполнение"; var information = "-"; setLifeCycle(obj, startDate, endDate, wf_status, executor, currentUser, stage, information); var time = new AFDateTime(Calendar.getInstance()); TunableObjectHelper.putAFInstanceValue(obj.tuning(), "wf.actiontime", time); try { obj.save(); } catch (e) { var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var resultMessage = "При сохранении произошел конфликт, сохранение изменений невозможно.\nОбъект будет переоткрыт в актуальном состоянии." var message = appTNObject.composeDialog("RSHBRequestDialogInfo", null, null, null); TunableObjectHelper.putAFInstanceValue(message.tuning(), "selectIds", ids); TunableObjectHelper.putAFInstanceValue(message.tuning(), "message", resultMessage); TunableObjectHelper.putAFInstanceValue(message, "counter", "exit"); log.error("При сохранении произошел конфликт, сохранение изменений невозможно"); returnResource.resource = TunableObjectREST.Resource.create(message); return returnResource.resource; } obj = appdp.getEntityByUNID(ids.get(0)); var res = RkkResource.valueOf(obj); returnResource.setResource(res); } /** * Откатить статусное состояние WF * @obj объект * id идентификатор объекта * @appdp приложение */ function rollbackWF(appdp, id, obj){ var document = appdp.getEntityByUNID(id); var wf = obj.tuning().getValues().get("wf"); var assignee = null; var task = ""; var status = ""; var stage = "Проект"; var duration = null; var starttime = null; var finishtime = null; if (wf.getValues().get("assignee") != null) { assignee = wf.getValues().get("assignee").getValues(); task = wf.getValues().get("task").getValue(); stage = wf.getValues().get("stage").getValue(); duration = wf.getValues().get("duration").getValue(); starttime = wf.getValues().get("starttime").getValue(); finishtime = wf.getValues().get("finishtime").getValue(); } TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.assignee", assignee); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.task", task); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.status", status); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.stage", stage); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.duration", duration); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.starttime", starttime); TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.finishtime", finishtime); document.save(); } /** * Запись в Жизненный цикл * @obj объект * @startDate дата начала действия * @endDate дата окончания действия * @action действие * @assignee исполнитель * @currentUser пользователь, выполнивший действие * @result Результат * @information Доп. информация */ function setLifeCycle(obj, startDate, endDate, action, assignee, currentUser, result, information) { var propertyLifecycle = obj.tuning().getSchema().getProperty("wfLifeCycle"); var lifecycle = null; if (obj.tuning().getValues().containsKey("wfLifeCycle") && obj.tuning().getValues().get("wfLifeCycle") != null) { lifecycle = obj.tuning().getValues().get("wf_lifecycle").getValues(); } else { lifecycle = Utils.newArrayList(); } var propertyStartDate = propertyLifecycle.getSchema().getProperty("lifecycle_start_date"); var propertyDate = propertyLifecycle.getSchema().getProperty("lifecycle_date"); var propertyAction = propertyLifecycle.getSchema().getProperty("lifecycle_action"); var propertyAssignee = propertyLifecycle.getSchema().getProperty("lifecycle_assignee"); var propertyCurrentUser = propertyLifecycle.getSchema().getProperty("lifecycle_current_user"); var propertyResult = propertyLifecycle.getSchema().getProperty("lifecycle_result"); var propertyInformation = propertyLifecycle.getSchema().getProperty("lifecycle_information"); var startDateValue = TuningHelper.createPropertyValue(startDate, propertyStartDate); var endDateValue = TuningHelper.createPropertyValue(endDate, propertyDate); var actionValue = TuningHelper.createPropertyValue(action, propertyAction); var currentUserValue = TuningHelper.createPropertyValue(currentUser, propertyCurrentUser); var assigneeValue = TuningHelper.createPropertyValue(assignee, propertyAssignee); var resultValue = TuningHelper.createPropertyValue(result, propertyResult); var informationValue = TuningHelper.createPropertyValue(information, propertyInformation); var wf_lifecycle = new AFInstanceObjectImpl(propertyLifecycle.getSchema()); wf_lifecycle.getValues().put("lifecycle_start_date", startDateValue); wf_lifecycle.getValues().put("lifecycle_date", endDateValue); wf_lifecycle.getValues().put("lifecycle_action", actionValue); wf_lifecycle.getValues().put("lifecycle_assignee", assigneeValue); wf_lifecycle.getValues().put("lifecycle_current_user", currentUserValue); wf_lifecycle.getValues().put("lifecycle_result", resultValue); wf_lifecycle.getValues().put("lifecycle_information", informationValue); lifecycle.add(wf_lifecycle); var lifecycleValue = new AFInstanceArrayImpl(propertyLifecycle.getSchema(), lifecycle); obj.tuning().getValues().put("wfLifeCycle", lifecycleValue); } |
В RootMenu создать button и подключить к нему handler
https://conf.inttrust.ru:8443/pages/viewpage.action?pageId=59704445 |
<section id="RootMenu"> <component> <button name="${<Form Name>.RootMenu.button.<Name>:Новая кнопка}"> <icon code="37"/> <action> <custom> <operation> <handler-ref ref="WFCustomHandlerName"/> </operation> </custom> </action> </button> </component> </section> |