diff --git a/.liquibase/Data_alias/basic/2020.0.1/WorkflowSignal/insert_WorkflowSignalTrigger_keyword.xml b/.liquibase/Data_alias/basic/2020.0.1/WorkflowSignal/insert_WorkflowSignalTrigger_keyword.xml new file mode 100644 index 0000000000000000000000000000000000000000..5778c73f1788c4963652a0e0bd1068ce382c6dca --- /dev/null +++ b/.liquibase/Data_alias/basic/2020.0.1/WorkflowSignal/insert_WorkflowSignalTrigger_keyword.xml @@ -0,0 +1,33 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + <changeSet author="s.listl" id="989b7d7d-ba1e-40b8-99b0-e4a1c13e9375"> + <insert tableName="AB_KEYWORD_ENTRY"> + <column name="AB_KEYWORD_ENTRYID" value="78367cf3-111a-4852-9a4f-a505ad2953cd"/> + <column name="KEYID" value="TRIGGEREVENTINSERT"/> + <column name="TITLE" value="Creation"/> + <column name="CONTAINER" value="WorkflowSignalTrigger"/> + <column name="SORTING" valueNumeric="1"/> + <column name="ISACTIVE" valueNumeric="1"/> + <column name="ISESSENTIAL" valueNumeric="1"/> + </insert> + <insert tableName="AB_KEYWORD_ENTRY"> + <column name="AB_KEYWORD_ENTRYID" value="94cc11ec-a384-439f-b5c7-70d7168959a5"/> + <column name="KEYID" value="TRIGGEREVENTUPDATE"/> + <column name="TITLE" value="Update"/> + <column name="CONTAINER" value="WorkflowSignalTrigger"/> + <column name="SORTING" valueNumeric="2"/> + <column name="ISACTIVE" valueNumeric="1"/> + <column name="ISESSENTIAL" valueNumeric="1"/> + </insert> + <insert tableName="AB_KEYWORD_ENTRY"> + <column name="AB_KEYWORD_ENTRYID" value="d8b78606-30bf-4633-9aaf-4da691ef6d8f"/> + <column name="KEYID" value="TRIGGEREVENTDELETE"/> + <column name="TITLE" value="Deletion"/> + <column name="CONTAINER" value="WorkflowSignalTrigger"/> + <column name="SORTING" valueNumeric="3"/> + <column name="ISACTIVE" valueNumeric="1"/> + <column name="ISESSENTIAL" valueNumeric="1"/> + </insert> + </changeSet> +</databaseChangeLog> diff --git a/.liquibase/Data_alias/basic/2020.0.1/changelog.xml b/.liquibase/Data_alias/basic/2020.0.1/changelog.xml index c3105c90b71f48e03afbe5a3771cbaaa080040da..b0f00bb80a949280f3458d8b2cabc229aa0b2721 100644 --- a/.liquibase/Data_alias/basic/2020.0.1/changelog.xml +++ b/.liquibase/Data_alias/basic/2020.0.1/changelog.xml @@ -2,4 +2,5 @@ <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> <include file="WorkflowSignal/create_WorkflowSignal.xml" relativeToChangelogFile="true"/> + <include file="WorkflowSignal/insert_WorkflowSignalTrigger_keyword.xml" relativeToChangelogFile="true"/> </databaseChangeLog> diff --git a/entity/Offer_entity/afterOperatingState.js b/entity/Offer_entity/afterOperatingState.js index 9e011dcf5d5d51fd3c9a78e55b9936e2bec21f10..39f9de2bc2a1d5119b5cea692dbc4d6743bd5ca2 100644 --- a/entity/Offer_entity/afterOperatingState.js +++ b/entity/Offer_entity/afterOperatingState.js @@ -7,4 +7,4 @@ if (vars.exists("$context.workflowQueue") && vars.get("$context.workflowQueue")) WorkflowStarter.inserted(vars.get("$context.workflowQueue")); vars.set("$context.workflowQueue", null); } -WorkflowSignalSender.doInsertedOrUpdated(); \ No newline at end of file +WorkflowSignalSender.throwQueuedEvents(); \ No newline at end of file diff --git a/entity/Organisation_entity/afterOperatingState.js b/entity/Organisation_entity/afterOperatingState.js index 1dea5d13d3bc15a4c3ea5d89f6c4bebdc4fd0007..bd1093a1fb8421f6b40a58448063df8ebfaf198d 100644 --- a/entity/Organisation_entity/afterOperatingState.js +++ b/entity/Organisation_entity/afterOperatingState.js @@ -6,4 +6,4 @@ if (vars.exists("$context.workflowQueue") && vars.get("$context.workflowQueue")) WorkflowStarter.inserted(vars.get("$context.workflowQueue")); vars.set("$context.workflowQueue", null); } -WorkflowSignalSender.doInsertedOrUpdated(); +WorkflowSignalSender.throwQueuedEvents(); diff --git a/entity/Person_entity/afterOperatingState.js b/entity/Person_entity/afterOperatingState.js index e793ce58bd20d6ec97ea7fb7f1fc8b645ab6c493..a246813efbc4d207adfa75e5ff9378c4aeaa89ef 100644 --- a/entity/Person_entity/afterOperatingState.js +++ b/entity/Person_entity/afterOperatingState.js @@ -6,4 +6,4 @@ if (vars.exists("$context.workflowQueue") && vars.get("$context.workflowQueue")) WorkflowStarter.inserted(vars.get("$context.workflowQueue")); vars.set("$context.workflowQueue", null); } -WorkflowSignalSender.doInsertedOrUpdated(); \ No newline at end of file +WorkflowSignalSender.throwQueuedEvents(); \ No newline at end of file diff --git a/entity/WorkflowSignal_entity/WorkflowSignal_entity.aod b/entity/WorkflowSignal_entity/WorkflowSignal_entity.aod index ba7132b64300d6f70d888c795b9b908e69693f1a..156d58ba30f7803ee44ded1254743c49c118ab6f 100644 --- a/entity/WorkflowSignal_entity/WorkflowSignal_entity.aod +++ b/entity/WorkflowSignal_entity/WorkflowSignal_entity.aod @@ -2,7 +2,7 @@ <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.13" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.13"> <name>WorkflowSignal_entity</name> <majorModelMode>DISTRIBUTED</majorModelMode> - <title>Workflow signal</title> + <title>Signal</title> <titlePlural>Signals</titlePlural> <recordContainer>db</recordContainer> <entityFields> diff --git a/entity/WorkflowSignal_entity/entityfields/triggerkeyword/children/containername_param/valueProcess.js b/entity/WorkflowSignal_entity/entityfields/triggerkeyword/children/containername_param/valueProcess.js index dee07a7bcce5662c3c52ee83659e3c64fcf52d10..922132616a2ff8035241ce643fcd8d53381fb579 100644 --- a/entity/WorkflowSignal_entity/entityfields/triggerkeyword/children/containername_param/valueProcess.js +++ b/entity/WorkflowSignal_entity/entityfields/triggerkeyword/children/containername_param/valueProcess.js @@ -1,4 +1,4 @@ import("KeywordRegistry_basic"); import("system.result"); -result.string($KeywordRegistry.workflowTrigger()); \ No newline at end of file +result.string($KeywordRegistry.workflowSignalTrigger()); \ No newline at end of file diff --git a/entity/WorkflowSignal_entity/recordcontainers/db/recordfieldmappings/trigger_event.displayvalue/expression.js b/entity/WorkflowSignal_entity/recordcontainers/db/recordfieldmappings/trigger_event.displayvalue/expression.js index f484f92b06795d86a986de789b39f35047dffbef..b3ac0866abcef20a0a6884dd6983ed3414f84969 100644 --- a/entity/WorkflowSignal_entity/recordcontainers/db/recordfieldmappings/trigger_event.displayvalue/expression.js +++ b/entity/WorkflowSignal_entity/recordcontainers/db/recordfieldmappings/trigger_event.displayvalue/expression.js @@ -2,5 +2,5 @@ import("system.result"); import("Keyword_lib"); import("KeywordRegistry_basic"); -var sql = KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.workflowTrigger(), "WORKFLOWSIGNAL.TRIGGER_EVENT"); +var sql = KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.workflowSignalTrigger(), "WORKFLOWSIGNAL.TRIGGER_EVENT"); result.string(sql); \ No newline at end of file diff --git a/entity/WorkflowTask_entity/WorkflowTask_entity.aod b/entity/WorkflowTask_entity/WorkflowTask_entity.aod index 326f57420cfa813f242b21e35904ba0a7a38765b..b065b5f71b49883cb51682443c90645a31035c3b 100644 --- a/entity/WorkflowTask_entity/WorkflowTask_entity.aod +++ b/entity/WorkflowTask_entity/WorkflowTask_entity.aod @@ -35,6 +35,7 @@ </entityField> <entityField> <name>PROCESSDEFINITION_ID</name> + <displayValueProcess>%aditoprj%/entity/WorkflowTask_entity/entityfields/processdefinition_id/displayValueProcess.js</displayValueProcess> </entityField> <entityField> <name>PROCESSINSTANCE_ID</name> @@ -115,6 +116,7 @@ <title>Claim task</title> <onActionProcess>%aditoprj%/entity/WorkflowTask_entity/entityfields/claimtask/onActionProcess.js</onActionProcess> <iconId>VAADIN:CLIPBOARD_USER</iconId> + <stateProcess>%aditoprj%/entity/WorkflowTask_entity/entityfields/claimtask/stateProcess.js</stateProcess> </entityActionField> <entityField> <name>ISACTIVE</name> diff --git a/entity/WorkflowTask_entity/entityfields/claimtask/onActionProcess.js b/entity/WorkflowTask_entity/entityfields/claimtask/onActionProcess.js index c7efdb62d29832c9280837e42b5d03e72c47f33a..9908c42f82ffa1a7857d872108c11dc9e50f3bba 100644 --- a/entity/WorkflowTask_entity/entityfields/claimtask/onActionProcess.js +++ b/entity/WorkflowTask_entity/entityfields/claimtask/onActionProcess.js @@ -1,5 +1,10 @@ +import("system.neon"); import("Employee_lib"); import("system.vars"); import("system.workflow"); -workflow.claimTask(vars.get("$field.UID"), EmployeeUtils.getCurrentUserId()); \ No newline at end of file +if (vars.get("$field.ASSIGNEE") != EmployeeUtils.getCurrentUserId()) +{ + workflow.claimTask(vars.get("$field.UID"), EmployeeUtils.getCurrentUserId()); + neon.refreshAll(); +} \ No newline at end of file diff --git a/entity/WorkflowTask_entity/entityfields/claimtask/stateProcess.js b/entity/WorkflowTask_entity/entityfields/claimtask/stateProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..594cc7db76282f79dec45bc8a5a4c80330f44a84 --- /dev/null +++ b/entity/WorkflowTask_entity/entityfields/claimtask/stateProcess.js @@ -0,0 +1,9 @@ +import("system.neon"); +import("Employee_lib"); +import("system.vars"); +import("system.result"); + +result.string(vars.get("$field.ASSIGNEE") == EmployeeUtils.getCurrentUserId() + ? neon.COMPONENTSTATE_DISABLED + : neon.COMPONENTSTATE_EDITABLE +); \ No newline at end of file diff --git a/entity/WorkflowTask_entity/entityfields/processdefinition_id/displayValueProcess.js b/entity/WorkflowTask_entity/entityfields/processdefinition_id/displayValueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..acb8a4cc88ad3969d8d7b949c7f7d09158b258c9 --- /dev/null +++ b/entity/WorkflowTask_entity/entityfields/processdefinition_id/displayValueProcess.js @@ -0,0 +1,7 @@ +import("Context_lib"); +import("system.result"); +import("system.neon"); +import("system.vars"); + +if (vars.get("$sys.viewmode") == neon.FRAME_VIEWMODE_DATASET) + result.string(ContextUtils.loadContentTitle("WorkflowDefinition_entity", vars.get("$field.PROCESSDEFINITION_ID"))); diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod index 00d7b607eb6d7d4091c752db80066f35724867b9..84872d990b162fc0e49cd6b31bea6cb924a0244e 100644 --- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod +++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod @@ -6080,6 +6080,12 @@ <entry> <key>${CANCELLED}</key> </entry> + <entry> + <key>Signals</key> + </entry> + <entry> + <key>${ORDER_CANCELLED}</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> <sqlModels> diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod index 5fab92102f80050fb46b6a10304c2225ee393d20..6d97607d2ef2dbd735422c7f5849ed5bd46bab0c 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -70,6 +70,10 @@ <key>Data imported. Address could not be read.</key> <value>Daten wurden importiert. Adresse konnte nicht ausgelesen werden.</value> </entry> + <entry> + <key>Claim task</key> + <value>Aufgabe annehmen</value> + </entry> <entry> <key>Data imported.</key> <value>Daten wurden importiert.</value> @@ -7806,6 +7810,9 @@ Bitte Datumseingabe prüfen</value> <entry> <key>Weitere Kontakte</key> </entry> + <entry> + <key>${CANCELLED}</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod index 982fb10ef62a569a307343e26a3c353f01546c2b..4ad089740903b8b4b7f22efa4d1f2bb42d3ee089 100644 --- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod +++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod @@ -6137,6 +6137,12 @@ <key>${CONDITION}</key> <value>Condition</value> </entry> + <entry> + <key>Signals</key> + </entry> + <entry> + <key>${CANCELLED}</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js index df5578df8329e63bfdb8fd0bf15286ced5f2ad13..b5423d3b67494aedc84cfc49575e3b63023bf05f 100644 --- a/process/KeywordRegistry_basic/process.js +++ b/process/KeywordRegistry_basic/process.js @@ -238,4 +238,9 @@ $KeywordRegistry.workflowTrigger = function(){return "WorkflowTrigger";}; $KeywordRegistry.workflowTrigger$manual = function(){return "WORKFLOWTRIGGERMANUAL";}; $KeywordRegistry.workflowTrigger$create = function(){return "WORKFLOWTRIGGERINSERT";}; $KeywordRegistry.workflowTrigger$update = function(){return "WORKFLOWTRIGGERUPDATE";}; -$KeywordRegistry.workflowTrigger$delete = function(){return "WORKFLOWTRIGGERDELETE";}; \ No newline at end of file +$KeywordRegistry.workflowTrigger$delete = function(){return "WORKFLOWTRIGGERDELETE";}; + +$KeywordRegistry.workflowSignalTrigger = function(){return "WorkflowSignalTrigger";}; +$KeywordRegistry.workflowSignalTrigger$create = function(){return "TRIGGEREVENTINSERT";}; +$KeywordRegistry.workflowSignalTrigger$update = function(){return "TRIGGEREVENTUPDATE";}; +$KeywordRegistry.workflowSignalTrigger$delete = function(){return "TRIGGEREVENTDELETE";}; \ No newline at end of file diff --git a/process/Workflow_lib/process.js b/process/Workflow_lib/process.js index 56b195bb0c108d9292c82873635991e99d2985bf..be5681455f21add796204897b5e1e2e24bf7ae2c 100644 --- a/process/Workflow_lib/process.js +++ b/process/Workflow_lib/process.js @@ -88,7 +88,7 @@ WorkflowUtils.engineIsEnabled = function () } /** - * obsolete + * obsolete, use signals */ function WorkflowStarter () {} @@ -134,76 +134,124 @@ WorkflowStarter._startProcessByAction = function (pAction, pVariables, pTargetId }); } - +/** + * provides functions for working with workflow signals + */ function WorkflowSignalSender () {} +/** + * Constant for the event of inserting a dataset, wraps a keyword + */ WorkflowSignalSender.EVENT_INSERT = function () { - return $KeywordRegistry.workflowTrigger$create(); + return $KeywordRegistry.workflowSignalTrigger$create(); } +/** + * Constant for the event of updating a dataset, wraps a keyword + */ WorkflowSignalSender.EVENT_UPDATE = function () { - return $KeywordRegistry.workflowTrigger$update(); + return $KeywordRegistry.workflowSignalTrigger$update(); } +/** + * Constant for the event of deleting a dataset, wraps a keyword + */ WorkflowSignalSender.EVENT_DELETE = function () { - return $KeywordRegistry.workflowTrigger$delete(); + return $KeywordRegistry.workflowSignalTrigger$delete(); } +/** + * Adds an entry to a context-variable that tells a insert happened. The variable is then checked by WorkflowSignalSender.doInsertedOrUpdated, + * where the actual logic is executed. The reason for this approach is that 'inserted' signals should be thrown after the insert finished. + * + * @param {String} pTargetId uid of the inserted dataset + * @param {String} pTargetContext context of the inserted dataset + */ WorkflowSignalSender.markInserted = function (pTargetId, pTargetContext) { + //TODO: is a signal like 'before insert' required? WorkflowSignalSender._addToQueue(WorkflowSignalSender.EVENT_INSERT(), pTargetId, pTargetContext); } +/** + * Adds an entry to a context-variable that tells a update happened. The variable is then checked by WorkflowSignalSender.doInsertedOrUpdated, + * where the actual logic is executed. The reason for this approach is that 'updated' signals should be thrown after the update finished. + * + * @param {String} pTargetId uid of the updated dataset + * @param {String} pTargetContext context of the updated dataset + */ WorkflowSignalSender.markUpdated = function (pTargetId, pTargetContext) { WorkflowSignalSender._addToQueue(WorkflowSignalSender.EVENT_UPDATE(), pTargetId, pTargetContext); } +/** + * constant for the context variable for queueing events + */ WorkflowSignalSender._QUEUE_VARNAME = function () { return "$context.workflowSignalQueue"; } -WorkflowSignalSender._addToQueue = function (pAction, pTargetId, pTargetContext) +/** + * adds events to the queue-context-variable to be evaluated later + */ +WorkflowSignalSender._addToQueue = function (pEvent, pTargetId, pTargetContext) { var contextVar = WorkflowSignalSender._QUEUE_VARNAME(); var queue = []; if (vars.exists(contextVar) && vars.get(contextVar)) queue = vars.get(contextVar); - queue.push([pAction, pTargetId, pTargetContext]); + queue.push([pEvent, pTargetId, pTargetContext]); vars.set(contextVar, queue); } -WorkflowSignalSender.doInsertedOrUpdated = function () +/** + * Evaluates the queued events in the context-variable and throws the events. That can result in workflow signals being thrown. + * This queueing can be used if something happens in a context, but the signal should not be thrown immediately (e. g. in the onInsert process + * of the recordcontainer, when the insert isn't finished). + */ +WorkflowSignalSender.throwQueuedEvents = function () { var contextVar = WorkflowSignalSender._QUEUE_VARNAME(); if (vars.exists(contextVar) && vars.get(contextVar)) { vars.get(contextVar).forEach(function (action) { - WorkflowSignalSender.actionPerformed.apply(null, action); + WorkflowSignalSender.eventHappened.apply(null, action); }); vars.set(contextVar, null); } } +/** + * @param {String} pTargetId uid of the deleted dataset + * @param {String} pTargetContext context of the deleted dataset + */ WorkflowSignalSender.deleted = function (pTargetId, pTargetContext) { WorkflowSignalSender.actionPerformed(WorkflowSignalSender.EVENT_DELETE(), pTargetId, pTargetContext); } -WorkflowSignalSender.actionPerformed = function (pAction, pTargetId, pTargetContext) +/** + * Checks the signal configuration for the given event and then throws signals that were configured to the event. + * + * @param {String} pEvent event + * @param {String} pTargetId uid of the dataset + * @param {String} pTargetContext context of the dataset + */ +WorkflowSignalSender.eventHappened = function (pEvent, pTargetId, pTargetContext) { if (!pTargetId) pTargetId = vars.get("$sys.uid"); if (!pTargetContext) pTargetContext = ContextUtils.getCurrentContextId(); - var signals = WorkflowSignalSender.getSignalConfig(pTargetContext, pAction); + var signals = WorkflowSignalSender.getSignalConfig(pTargetContext, pEvent); signals.forEach(function (signal) { if (_checkCondition(signal.entity, pTargetId, signal.condition)) @@ -224,24 +272,37 @@ WorkflowSignalSender.actionPerformed = function (pAction, pTargetId, pTargetCont } } -WorkflowSignalSender.getSignalConfig = function (pContext, pAction) +/** + * loads signal definitions from the database + * + * @param {String} [pContext] contexts of the signal definitions + * @param {String} [pEvent] event that is defined for the signals + * @return {Object[]} Array of objects, with these properties:<br/> + * <ul> + * <li>name: name of the signal</li> + * <li>event: event that triggers the signal</li> + * <li>entity: entity where the event should happen</li> + * <li>condition: a condition that is checked before the signal is sent, null if there's no condition</li> + * </ul> + */ +WorkflowSignalSender.getSignalConfig = function (pContext, pEvent) { - var entity = ContextUtils.getEntity(pContext); - var signals = newSelect("SIGNAL_NAME, OBJECT_CONDITION") + var signals = newSelect("SIGNAL_NAME, TRIGGER_EVENT, OBJECT_CONDITION, OBJECT_TYPE") .from("WORKFLOWSIGNAL") - .where("WORKFLOWSIGNAL.OBJECT_TYPE", pContext) - .and("WORKFLOWSIGNAL.TRIGGER_EVENT", pAction) + .whereIfSet("WORKFLOWSIGNAL.OBJECT_TYPE", pContext) + .andIfSet("WORKFLOWSIGNAL.TRIGGER_EVENT", pEvent) .table(); return signals.map(function (signal) { - var condition = signal[1] - ? JSON.parse(signal[1]).filter + var condition = signal[2] + ? JSON.parse(signal[2]).filter : null; return { name : signal[0], - entity : entity, + event : signal[1], + entity : ContextUtils.getEntity(signal[3]), condition : condition }; }); diff --git a/process/workflowServiceTasks_rest/process.js b/process/workflowServiceTasks_rest/process.js new file mode 100644 index 0000000000000000000000000000000000000000..f713bc0fe1477587ad20f9122b6a107b75c7da08 --- /dev/null +++ b/process/workflowServiceTasks_rest/process.js @@ -0,0 +1,17 @@ +import("system.project"); +import("system.process"); + +function restget (pRequest) +{ + let request = JSON.parse(pRequest); + + let serviceTasks = project.getDataModels(project.DATAMODEL_KIND_PROCESS).filter(function (row) + { + return /.+_workflowService$/.test(row[0]); + }); + + request.response.body = JSON.stringify({}); + + return JSON.stringify(request); + +} diff --git a/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod b/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod new file mode 100644 index 0000000000000000000000000000000000000000..9aabceafe58bd281940c4ab2067b6c1df83348f0 --- /dev/null +++ b/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1"> + <name>workflowServiceTasks_rest</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/workflowServiceTasks_rest/process.js</process> + <style>REST</style> + <variants> + <element>EXECUTABLE</element> + </variants> +</process> diff --git a/process/workflowUsers_rest/process.js b/process/workflowUsers_rest/process.js new file mode 100644 index 0000000000000000000000000000000000000000..80446eb27dcc1ea6c1c0df268d324ac5569cd157 --- /dev/null +++ b/process/workflowUsers_rest/process.js @@ -0,0 +1,90 @@ +import("system.vars"); +import("system.logging"); +import("system.tools"); + +function restget (pRequest) +{ + //maximum row count of the resultset + const MAX_COUNT = 100; + //minimum required length of the search pattern + const MIN_SEARCHLENGTH = 0; + + let request = JSON.parse(pRequest); + let searchValue = request.header.filter || request.header.Filter; + + request.response.body = JSON.stringify({users : _getUsers(searchValue)}); + + return JSON.stringify(request); + + function _getUsers (pSearch) + { + if (pSearch === undefined || pSearch.trim() < MIN_SEARCHLENGTH) + return []; + + //separate words by spaces + let patterns = pSearch.toUpperCase().split(/\s/).filter(function (pat) {return pat;}); + + let allUsers = tools.getUsersByAttribute(tools.ISACTIVE, ["true"], tools.PROFILE_DEFAULT); + let resultUsers = []; + + for (let i = 0, l = allUsers.length; i < l; i++) + { + let user = allUsers[i]; + let id = user[tools.NAME]; + let firstName = user[tools.PARAMS][tools.FIRSTNAME]; + let lastName = user[tools.PARAMS][tools.LASTNAME]; + let email = user[tools.EMAIL]; + let rating = _getRating(patterns, [firstName.toUpperCase(), lastName.toUpperCase()]); + if (rating !== 0) + { + resultUsers.push({ + id : id, + firstName : firstName, + lastName : lastName, + email : email, + fullName : (firstName + " " + lastName).trim(), + tenantId : null, + groups : [], + privileges : [], + searchRating : rating + }); + } + } + + //sort by result quality + resultUsers.sort(function (a, b) + { + return b.searchRating - a.searchRating; + }); + + return resultUsers.slice(0, MAX_COUNT); + } + + /** + * checks if the pattern is contained in the name + * + * @return {Number} higher number -> better result, 0 if no match + */ + function _getRating (pPatterns, pRow) + { + let rating = 0; + + return pPatterns.every(function (pattern) + { + let patternRating = pRow.reduce(function (patRating, value) + { + let index = value.indexOf(pattern); + if (index !== -1) + patRating++; + if (index === 0) + patRating += 2; + + return patRating; + }, 0); + rating += patternRating; + + //if one word wasn't found, the loop will stop and rating is 0 + return patternRating !== 0; + }) ? rating : 0; + } +} diff --git a/process/workflowUsers_rest/workflowUsers_rest.aod b/process/workflowUsers_rest/workflowUsers_rest.aod new file mode 100644 index 0000000000000000000000000000000000000000..2b745c8a376ee606f3e0c179d39dda94137d1014 --- /dev/null +++ b/process/workflowUsers_rest/workflowUsers_rest.aod @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1"> + <name>workflowUsers_rest</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/workflowUsers_rest/process.js</process> + <publishAsWebservice v="false" /> + <style>REST</style> + <restAcceptedMimeType>application/json</restAcceptedMimeType> + <restDeliveredMimeType>application/json</restDeliveredMimeType> + <loginTypeId>internal.none</loginTypeId> + <restrictedRoles /> + <variants> + <element>EXECUTABLE</element> + </variants> +</process>