Примечание | ||
---|---|---|
| ||
Необходимо сначало выполнить Старт процесса |
Создать handler (JS-Обработчик операций)
Блок кода | ||||
---|---|---|---|---|
| ||||
<?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.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.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); function process(paramsResource, returnResource) { if (paramsResource == null) { throw new IllegalArgumentException("paramsResource must no be null."); } var dialogNameList = new ArrayList(); dialogNameList.add("ClientContextRequest"); dialogNameList.add("ExampleDialogStandartWFDialogStandart"); dialogNameList.add("ExampleDialogInfoWFDialogInfo"); paramPackageId = ""; paramSchemaName = paramsResource.tuning().getSchema().getName(); if (dialogNameList.contains(paramSchemaName)) { paramPackageId = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("counter")); } else { paramPackageId = "contextWithResource"; } if (paramPackageId.equals("context")) { createContextResourceRequest(returnResource); } else if (paramPackageId.equals("contextWithResource")) { process_dialog(paramsResource, returnResource); } else if (paramPackageId.equals("answer")) { process_context(paramsResource, returnResource); } else if (paramPackageId.equals("exit_update")) { process_refresh(paramsResource, returnResource); } else if (paramPackageId.equals("exit")) { return process_exit(paramsResource, returnResource); } } /** * Обработка первого пакета данных с клиента. * @return возвращение контекста открытого документа */ function createContextResourceRequest(returnResource) { var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var afObjectContextRequest = appTNObject.createClientContextRequest(TunableObjectApplication.ClientContextKey.resourceid, TunableObjectApplication.ClientContextKey.resource); TunableObjectHelper.putAFInstanceValue(afObjectContextRequest, "counter", "contextWithResource"); returnResource.setResource(TunableObjectREST.Resource.create(afObjectContextRequest)); } /** * Обновление объекта * @param paramsResource * @return ресурс первого диалога сценария */ function process_refresh(paramsResource, returnResource) { var ids = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("selectIds")); var appdp = AFSession.get().getApplication(DPApplication.class); var obj = appdp.getEntityByUNID(ids.get(0)); var res = RkkResource.valueOf(obj); returnResource.setResource(res); } /** * Завершение обработки в случае ошибки * @param paramsResource * @return ресурс первого диалога сценария */ function process_exit(paramsResource, returnResource) { var ids = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("selectIds")); var appdp = AFSession.get().getApplication(DPApplication.class); var obj = appdp.getEntityByUNID(ids.get(0)); returnResource.setResource(null); } /** * Диалог Информации c обновлением документа * @ids текущий идентификатор документа * @resultMessage сообщение * @return ресурс */ function process_dlginfo_refresh(ids, resultMessage,returnResource){ var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var message = appTNObject.composeDialog("ExampleDialogInfoWFDialogInfo", null, null, null); TunableObjectHelper.putAFInstanceValue(message.tuning(), "message", resultMessage); TunableObjectHelper.putAFInstanceValue(message.tuning(), "selectIds", ids); TunableObjectHelper.putAFInstanceValue(message, "counter", "exit_update"); returnResource.resource = TunableObjectREST.Resource.create(message); return returnResource.resource; } /** * Диалог Информации c обновлением документа * @ids текущий идентификатор документа * @resultMessage сообщение * @return ресурс */ function process_dlginfo(ids, resultMessage,returnResource){ var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var message = appTNObject.composeDialog("ExampleDialogInfoWFDialogInfo", null, null, null); TunableObjectHelper.putAFInstanceValue(message.tuning(), "message", resultMessage); TunableObjectHelper.putAFInstanceValue(message.tuning(), "selectIds", ids); TunableObjectHelper.putAFInstanceValue(message, "counter", "exit"); returnResource.resource = TunableObjectREST.Resource.create(message); return returnResource.resource; } /** * Обработка первого пакета данных с клиента. * @param paramsResource * @return ресурс первого диалога сценария */ function process_dialog(paramsResource, returnResource) { var appTNObject = AFSession.get().getApplication(TunableObjectApplication.class); var id = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("$id")); var ids = Utils.newArrayList(); ids.add(id); var appdp = AFSession.get().getApplication(DPApplication.class); var obj = appdp.getEntityByUNID(id); //Проверка на актуальность документа var version = paramsResource.getVersion(); var versionParts = version.split('$$'); var versionContext = versionParts[0]; var versionCurrent = ''; try { versionCurrent = obj.getVersionStamp().toString(); } catch (e) { versionCurrent = versionContext; } if (versionContext != versionCurrent){ process_dlginfo(ids,"Данная версия объекта/документа была изменена. Требуется обновить!",returnResource); return returnResource.resource; } var message = appTNObject.composeDialog("ExampleDialogStandartWFDialogStandart", null, null, null); TunableObjectHelper.putAFInstanceValue(message.tuning(), "message", "Комментарий:"); TunableObjectHelper.putAFInstanceValue(message.tuning(), "selectIds", ids); TunableObjectHelper.putAFInstanceValue(message.tuning(), "versionContext", versionContext); TunableObjectHelper.putAFInstanceValue(message, "counter", "answer"); returnResource.setResource(TunableObjectREST.Resource.create(message)); } /** * Обработка данных первого диалога сценария * @param paramsResource * @return ресурс */ function process_context(paramsResource, returnResource) { var ids = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("selectIds")); var comment = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("comment")); var versionContext = TunableObjectHelper.getAFInstanceValue(paramsResource.tuning().getValues().get("versionContext")); var appdp = AFSession.get().getApplication(DPApplication.class); var obj = appdp.getEntityByUNID(ids.get(0)); var versionCurrent = ''; try { versionCurrent = obj.getVersionStamp().toString(); } catch (e) { versionCurrent = versionContext; } if (versionContext != versionCurrent){ process_dlginfo(ids,"Данная версия объекта/документа была изменена. Требуется обновить!",returnResource); return returnResource.resource; } if (obj.tuning().getValues().containsKey("wf") && obj.tuning().getValues().get("wf") != null) { var wf = obj.tuning().getValues().get("wf"); var task_name = wf.getValues().get("task").getValue(); var wf_status = "-";// Получаем задачу ifvar taskId = (wf.getValues().containsKeyget("statustask_id").getValue(); var workflowProcessService &&= wfBeansUtils.getValuesgetBean().get("statusworkflowProcessServiceImpl") != null ) { wf_status = wf.getValues().get("status").getValue(); } var wf_starttime = new AFDateTime(Calendar.getInstance());; var task = workflowProcessService.getTaskById(taskId); // Должна быть только одна задача, завершаем ее, установив переменную if (wf.getValues().containsKey("actiontime") && wf.getValues().get("actiontime") != null ) { wf_starttime = wf.getValues().get("actiontime").getValue(); } else if (wf.getValues().containsKey("starttime") && wf.getValues().get("starttime") != null ){ wf_starttime = wf.getValues().get("starttime").getValue(); } // Получаем задачу var taskId = wf.getValues().get("task_id").getValue(); var workflowProcessService = BeansUtils.getBean("workflowProcessServiceImpl"); var task = workflowProcessService.getTaskById(taskId); // Должна быть только одна задача, завершаем ее, установив переменную if (task != null){ //Запускаем WF task.getTaskVariables().put(task_name + "Result", truetask != null){ //Запускаем WF task.getTaskVariables().put(task_name + "Result", true); task.getTaskVariables().put("result", "<Статус>"); task.getTaskVariables().put("information", comment); var ProcessActionResult = workflowProcessService.completeUserTask(task); if (ProcessActionResult.hasError()) { var exception = ProcessActionResult.getException(); var stacktrace = ExceptionUtils.getStackTrace(exception); throw new RuntimeException("Не удалось продолжить процесс. Обратитесь к администратору. Ошибка: " + stacktrace); } obj = appdp.getEntityByUNID(ids.get(0)); var ProcessActionResultres = workflowProcessServiceRkkResource.completeUserTask(task); if (ProcessActionResult.hasError()) { rollbackWF(appdp, ids.get(0), valueOf(obj); var exception = ProcessActionResult.getException(returnResource.setResource(res); var} stacktrace = ExceptionUtils.getStackTrace(exception);else { throw new RuntimeException("Не удалосьнайдена продолжитьзадача. процесс. Обратитесь к администратору. ОшибкаИдентификатор: " + stacktracetaskId); } } else { objthrow =new appdp.getEntityByUNID(ids.get(0)); //запись в Жизненный цикл var currentUser = AFSession.get().currentUser().getBeard(); var executors = wf.getValues().get("assignee").getValues(); var executor = executors.get(0).getValue(); var startDate = wf_starttime; var endDate = new AFDateTime(Calendar.getInstance()); var result = "Исполнено"; var information = comment; setLifeCycle(obj, startDate, endDate, wf_status, executor, currentUser, result, information); RuntimeException("Не запущен процесс согласования. Обратитесь к администратору. Идентификатор: " + ids.get(0)); } } |
Добавить кастомную кнопку и подключить кастомную операцию
- В форме создать секцию RootMenu
В 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"/> var time = new AFDateTime(Calendar.getInstance()); <action> TunableObjectHelper.putAFInstanceValue(obj.tuning(), "wf.actiontime",time); try { <custom> obj.save(); } catch (e) {<operation> var resultMessage = "При сохранении произошел конфликт, сохранение изменений невозможно.\nБудет переоткрыт в актуальном состоянии." <handler-ref ref="WFCustomHandlerName"/> process_dlginfo(ids,resultMessage,returnResource); return returnResource.resource; </operation> } obj = appdp.getEntityByUNID(ids.get(0)); var res = RkkResource.valueOf(obj); returnResource.setResource(res); } else { throw new RuntimeException("Не найдена задача. Обратитесь к администратору. Идентификатор: " + taskId); } } else { throw new RuntimeException("Не запущен процесс согласования. Обратитесь к администратору. Идентификатор: " + ids.get(0)); } } /** * Откатить статусное состояние 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 = wf.getValues().get("status").getValue(); 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(); if (wf.getValues().get("finishtime") != null) { 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("wfLifeCycle").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
В 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> </custom> </action> </button> </component> </section> |
Подключить скрипт в WF-процесс
Скрипт устанавливает статус и заполняет жизненный цикл.
Блок кода | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
load("nashorn:mozilla_compat.js");
importClass(Packages.ru.intertrust.cmj.af.core.AFSession);
importClass(Packages.ru.intertrust.cmj.dp.DPApplication);
importClass(Packages.ru.intertrust.cmj.rest.tuning.TuningHelper);
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.af.misc.AFDateTime);
importClass(Packages.ru.intertrust.cmj.af.utils.Utils);
importClass(Packages.java.util.Calendar);
importClass(Packages.java.util.ArrayList);
importClass(Packages.ru.intertrust.cmj.af.tuning.impl.AFInstanceObjectImpl);
importClass(Packages.ru.intertrust.cmj.af.tuning.impl.AFInstanceArrayImpl);
importClass(Packages.ru.intertrust.cmj.admin.AdminApplicationImpl);
importClass(Packages.ru.intertrust.cmj.af.so.SOBeard);
importClass(Packages.ru.intertrust.cmj.af.utils.BeansUtils);
importClass(Packages.ru.intertrust.cmj.af.so.SOUnitPost);
importClass(Packages.org.slf4j.LoggerFactory);
var appDp = AFSession.get().getApplication(DPApplication.class);
var document = appDp.getEntityByUNID(contextId);
//Статус
var stage = "<Название статуса>";
var wf = document.tuning().getValues().get('wf');
var wf_prevstage = "";
if (wf.getValues().containsKey("stage") && wf.getValues().get("stage") != null ) {
wf_prevstage = wf.getValues().get("stage").getValue();
}
var propertyStage = wf.getSchema().getProperty("stage");
var stageValue = TuningHelper.createPropertyValue(stage,propertyStage);
wf.getValues().put("stage", stageValue);
//Заполнение ЖЦ
var wf_starttime = new AFDateTime(Calendar.getInstance());
if (wf.getValues().containsKey("actiontime") && wf.getValues().get("actiontime") != null ) {
wf_starttime = wf.getValues().get("actiontime").getValue();
} else if (wf.getValues().containsKey("starttime") && wf.getValues().get("starttime") != null ){
wf_starttime = wf.getValues().get("starttime").getValue();
}
var currentUser = AFSession.get().currentUser().getBeard();
var executors = wf.getValues().get("assignee").getValues();
var assignee = executors.get(0).getValue();
var startDate = wf_starttime;
var endDate = new AFDateTime(Calendar.getInstance());
var action = wf_prevstage;
var result = execution.getVariable("result");
var information = execution.getVariable("information");
var time = new AFDateTime(Calendar.getInstance());
TunableObjectHelper.putAFInstanceValue(document.tuning(), "wf.actiontime", time);
var propertyLifecycle = document.tuning().getSchema().getProperty("wfLifeCycle");
var lifecycle = null;
if (document.tuning().getValues().containsKey("wfLifeCycle") && document.tuning().getValues().get("wfLifeCycle") != null) {
lifecycle = document.tuning().getValues().get("wfLifeCycle").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);
document.tuning().getValues().put("wfLifeCycle", lifecycleValue);
//Сохранение
document.save(); |