diff --git a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js index 6b41c5dc3fba505e3f7b8bcc11293fced7e506a6..d5f8e7904ab14664284c2e53511be8a05485bc44 100644 --- a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js +++ b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js @@ -20,8 +20,6 @@ else users = tools.getUsersByAttribute(tools.ISACTIVE, values, tools.PROFILE_FULL); } -var fetchRoles = vars.getString("$local.filter").indexOf("ROLE_FILTER") !== -1; - users = users.map(function (user) { return [ @@ -37,7 +35,7 @@ users = users.map(function (user) user[tools.PARAMS].department, "", //password "", //confirm_password - fetchRoles ? tools.getRoles(user[tools.TITLE]) : [], //for filtering + user[tools.ROLENAMES], //for filtering EmployeeUtils.sliceUserId(user[tools.NAME]) ]; }); diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js index 40ba6cd3b01d2456fdd3328a3de9e412454f5084..70c52e8d375dadaeef3b17c7dda1b8ac0d1909e1 100644 --- a/process/Attribute_lib/process.js +++ b/process/Attribute_lib/process.js @@ -1383,7 +1383,7 @@ AttributeRelationQuery.prototype.getSingleAttributeValue = function () AttributeRelationQuery.prototype.getAttributeCount = function () { return parseInt(AttributeRelationUtils.getAttributeSqlBuilder("count(*)", this._rowId, this._objectType) - .andIfSet("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", this._attributeIds) + .andIfSet("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", this._attributeIds, SqlBuilder.IN()) .cell() || 0); } @@ -1418,35 +1418,24 @@ AttributeRelationQuery.prototype.insertAttribute = function (pValue, pOmitValida maxCount = maxCount[0]; if (maxCount && maxCount != 0) { - let timesUsed = new AttributeRelationQuery(this._rowId, this._objectType, attributeId).getAttributeCount(); + let timesUsed = this.getAttributeCount(); if (timesUsed >= maxCount) return false; } } - var columns = [ - "AB_ATTRIBUTERELATIONID", - "AB_ATTRIBUTE_ID", - "OBJECT_ROWID", - "OBJECT_TYPE", - "DATE_NEW", - "USER_NEW" - ]; - var values = [ - util.getNewUUID(), - attributeId, - this._rowId, - this._objectType, - vars.get("$sys.date"), - vars.get("$sys.user") - ]; + var attrData = { + "AB_ATTRIBUTE_ID" : attributeId, + "OBJECT_ROWID" : this._rowId, + "OBJECT_TYPE" : this._objectType, + "DATE_NEW" : vars.get("$sys.date"), + "USER_NEW" : vars.get("$sys.user") + }; var type = AttributeUtil.getAttributeType(attributeId); var valueField = AttributeTypeUtil.getDatabaseField(type); if (valueField) - { - columns.push(valueField); - values.push(pValue); - } - db.insertData("AB_ATTRIBUTERELATION", columns, null, values); + attrData[valueField] = pValue; + + new SqlBuilder().insertFields(attrData, "AB_ATTRIBUTERELATION", "AB_ATTRIBUTERELATIONID"); return true; } \ No newline at end of file diff --git a/process/CreateActivity_workflowService/CreateActivity_workflowService.aod b/process/CreateActivity_workflowService/CreateActivity_workflowService.aod index 84cf2710e96eab493955337e3fb52b0d6d8b1f29..1c0a3458bb336faa9361aa8d8104be5eeddb113f 100644 --- a/process/CreateActivity_workflowService/CreateActivity_workflowService.aod +++ b/process/CreateActivity_workflowService/CreateActivity_workflowService.aod @@ -1,6 +1,7 @@ <?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>CreateActivity_workflowService</name> + <title>Create activity</title> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/CreateActivity_workflowService/process.js</process> <alias>Data_alias</alias> diff --git a/process/CreateNotification_workflowService/CreateNotification_workflowService.aod b/process/CreateNotification_workflowService/CreateNotification_workflowService.aod index 30456b5519d02625b79dddd4505ddb9599668e07..15076d303773e5e29c015c4178fce97c31827f95 100644 --- a/process/CreateNotification_workflowService/CreateNotification_workflowService.aod +++ b/process/CreateNotification_workflowService/CreateNotification_workflowService.aod @@ -1,6 +1,7 @@ <?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>CreateNotification_workflowService</name> + <title>Create notification</title> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/CreateNotification_workflowService/process.js</process> <variants> diff --git a/process/SendEmail_workflowService/SendEmail_workflowService.aod b/process/SendEmail_workflowService/SendEmail_workflowService.aod index b83ca696f9ef6b48a6659b81f5f251645b9a9ecd..7fbc304aa8afcf182953a6c379b88c8dce236621 100644 --- a/process/SendEmail_workflowService/SendEmail_workflowService.aod +++ b/process/SendEmail_workflowService/SendEmail_workflowService.aod @@ -1,6 +1,7 @@ <?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>SendEmail_workflowService</name> + <title>Send email</title> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/SendEmail_workflowService/process.js</process> <variants> diff --git a/process/SetAttribute_workflowService/SetAttribute_workflowService.aod b/process/SetAttribute_workflowService/SetAttribute_workflowService.aod index 89b6c76c71c923e07ac8ed70a5dc5306d707670a..9d4e32046bcfd1cc624f7e4b589b24328114aa53 100644 --- a/process/SetAttribute_workflowService/SetAttribute_workflowService.aod +++ b/process/SetAttribute_workflowService/SetAttribute_workflowService.aod @@ -1,6 +1,7 @@ <?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>SetAttribute_workflowService</name> + <title>Set attribute</title> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/SetAttribute_workflowService/process.js</process> <alias>Data_alias</alias> diff --git a/process/Sql_lib/documentation.adoc b/process/Sql_lib/documentation.adoc index 6bf24551ca16887e04b4463d8f61f1ad7deba94d..4330b3af2166a38f050685d472b18d5b0a8daab3 100644 --- a/process/Sql_lib/documentation.adoc +++ b/process/Sql_lib/documentation.adoc @@ -292,6 +292,10 @@ var activitySelect = newSelect("SUBJECT, INFO, personLink.OBJECT_ROWID") `orderBy(pFields)` adds an order by statement to the SQL code. The parameter can be filled the same way as `.select(pFields)`. +=== union + +`union(pSelect)` and `unionAll(pSelect)` can be used to create an union or union all statement. The given parameter can be either a SQL-String or another SqlBuilder with full select clause. + === building the SQL statement ==== prepared array @@ -351,6 +355,40 @@ a default of "0" is more convenient than. [NOTE] You can still use the above `db.` functions outside the SqlBuilder, if you like. +==== paging functions + +The following functions support paging: + +`.arrayPage()` +`.tablePage()` +`.nextTablePage()` +`.forEachPage()` + +The methods `.arrayPage()` and `.tablePage()` are just wrappers for the equivalent `db.`-functions. However, the other functions should make the paging process a bit easier. +Before using them, you have to set the page size with `.pageSize(pPageSize)` and optionally set the start row with `.startRow(pStartRow)`. + +`.nextTablePage()` can be used to iterate over the table pages: +[source,js] +---- +mySqlBuilder.pageSize(400); +var data; +while (mySqlBuilder.hasMoreRows()) +{ + data = mySqlBuilder.nextTablePage(); + ... +} +---- + +You can use `.hasMoreRows()` to check if there are rows left that can be fetched. +Alternatively you can use `.forEachPage()`, this method requires a callback-function that is called for every table page: +[source,js] +---- +mySqlBuilder.pageSize(400) + .forEachPage(function (pData) + { + ... + }); +---- ==== update/delete-functions diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index 5f110cfbef9daebb0456428c11aeed020ca86f0d..a56abb83043e283631ffdaf4d36b89513e075457 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -777,10 +777,10 @@ function newWhereIfSet(pFieldOrCond, pValue, pCondition, pFieldType, pAlias) function SqlBuilder (pAlias) { if(!(this instanceof SqlBuilder)) - throw SqlBuilder.ERROR_INSTANCIATE_WITH_NEW(); + throw SqlBuilder._ERROR_INSTANCIATE_WITH_NEW(); this._select = null; this._from = null; - this._tableName = null; //for update/delete + this._tableName = null; //for insert/update/delete this._joins = []; this._groupBy = null; this._having = null; @@ -788,6 +788,11 @@ function SqlBuilder (pAlias) this._unions = []; this.alias = pAlias; + //for paging + this._startRow = null; + this._pageSize = null; + this._hasMoreRows = true; + this._subselectAlias = null; this._where = {}; @@ -913,6 +918,15 @@ SqlBuilder._ERROR_UPDATE_VALUES_INVALID = function () return new Error(translate.text("SqlBuilder: The provided values object for updateFields is invalid or is not an object.")); } +SqlBuilder._ERROR_PAGESIZE_INVALID = function () +{ + return new Error(translate.text("SqlBuilder: The pagesize is not set or is not a number.")); +} + +SqlBuilder._ERROR_NOT_A_FUNCTION = function () +{ + return new Error(translate.text("SqlBuilder: The provided callback function is not a function.")); +} /** * Alternative way of creating a new SqlBuilder object that allows to use * methods on it directly without having to put brackets around it @@ -1009,6 +1023,18 @@ SqlBuilder.prototype.subselectAlias = function(pSubselectAlias) return this; } +/** + * Sets the table that is used for insert/update/delete functions. + * + * @param {String} pTable + * @return {SqlBuilder} current SqlBuilder object + */ +SqlBuilder.prototype.tableName = function (pTable) +{ + this._tableName = pTable; + return this; +} + /** * Sets the from clause of the sql.<br/> * <br/> @@ -2166,6 +2192,7 @@ SqlBuilder.prototype.clearWhere = function() */ SqlBuilder.prototype._initWhere = function () { + //TODO: maybe put conditions in an object/array for better internal object structure this._where._sqlStorage = ""; this._where.preparedValues = []; this._where._lastWasOr = false; // save, if the last condition was an OR. For better bracket-placement @@ -2487,7 +2514,7 @@ SqlBuilder.prototype.insertFields = function (pFieldValues, pTableName, pAutoUid throw SqlBuilder._ERROR_UPDATE_VALUES_INVALID; if (pAutoUidField) - pFielsValues[pAutoUidField] = util.getNewUUID(); + pFieldValues[pAutoUidField] = util.getNewUUID(); var columns = []; var values = []; @@ -2630,8 +2657,8 @@ SqlBuilder.prototype.arrayPage = function(pType, pStartIndex, pRowCount, pExecut { return db.arrayPage(pType, this.build(), (this.alias ? this.alias : db.getCurrentAlias()), - pStartIndex, - pRowCount, + pStartIndex === undefined ? this._startRow : pStartIndex, + pRowCount === undefined ? this._pageSize : pRowCount, (pTimeout ? pTimeout : -1)); } else @@ -2680,8 +2707,8 @@ SqlBuilder.prototype.tablePage = function(pStartIndex, pRowCount, pExecuteOnlyIf { return db.tablePage(this.build(), (this.alias ? this.alias : db.getCurrentAlias()), - pStartIndex, - pRowCount, + pStartIndex === undefined ? this._startRow : pStartIndex, + pRowCount === undefined ? this._pageSize : pRowCount, (pTimeout ? pTimeout : -1)); } else @@ -2690,6 +2717,87 @@ SqlBuilder.prototype.tablePage = function(pStartIndex, pRowCount, pExecuteOnlyIf } } +/** + * Sets the pagesize for paging + * + * @param {Number} pPageSize + * @return {SqlBuilder} current SqlBuilder object + */ +SqlBuilder.prototype.pageSize = function (pPageSize) +{ + this._pageSize = pPageSize; + return this; +} + +/** + * Sets the start row for paging + * + * @param {Number} pStartRow + * @return {SqlBuilder} current SqlBuilder object + */ +SqlBuilder.prototype.startRow = function (pStartRow) +{ + this._startRow = pStartRow; + return this; +} + +/** + * Executes the SQL and returns the result. The startRow for paging will be increased by the pageSize, so you can use this method + * for iterating over the table pages. You can use SqlBuilder.prototype.hasMoreRows() to check if the end of rows was reached. + * + * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned + * @param {Number} [pTimeout=-1] + * @return {String[][]} the result of the query + */ +SqlBuilder.prototype.nextTablePage = function (pExecuteOnlyIfConditionExists, pTimeout) +{ + if (this._pageSize == null || isNaN(this._pageSize)) + throw SqlBuilder._ERROR_PAGESIZE_INVALID(); + + if (this._startRow == null) + this._startRow = 0; + + if (this._hasMoreRows && this._checkForSelect(pExecuteOnlyIfConditionExists)) + { + var data = this.tablePage(this._startRow, this._pageSize, pExecuteOnlyIfConditionExists, pTimeout); + if (data.length < this._pageSize) + this._hasMoreRows = false; + this._startRow += this._pageSize; + return data; + } + else + { + this._hasMoreRows = false; + return []; + } +} + +/** + * @return {Boolean} whether there are rows left for paging + */ +SqlBuilder.prototype.hasMoreRows = function () +{ + return this._hasMoreRows; +} + +/** + * Executes the SQL with paging and executes the given callback-function for every resultset until the last row has been reached or the function + * returns false. + * + * @param {Function} pCallBackFn CallBack-Function to execute for every page. If the function returns false, the execution will be stopped. + * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned + * @param {Number} [pTimeout=-1] + */ +SqlBuilder.prototype.forEachPage = function (pCallBackFn, pExecuteOnlyIfConditionExists, pTimeout) +{ + if (typeof pCallBackFn !== "function") + throw SqlBuilder._ERROR_NOT_A_FUNCTION(); + + var run = true; + while (run && this.hasMoreRows()) + run = pCallBackFn.call(null, this.nextTablePage(pExecuteOnlyIfConditionExists, pTimeout)) != false; +} + /** * checks if an update /delete statement should be called or not * @return {Boolean} diff --git a/process/UpdateOffer_workflowService/UpdateOffer_workflowService.aod b/process/UpdateOffer_workflowService/UpdateOffer_workflowService.aod index a58c778e5c2597c39271a4d9035caddf4285cdbe..9770a01efb96ef39b5cc8c4cf43f6350ec2474a3 100644 --- a/process/UpdateOffer_workflowService/UpdateOffer_workflowService.aod +++ b/process/UpdateOffer_workflowService/UpdateOffer_workflowService.aod @@ -1,6 +1,7 @@ <?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>UpdateOffer_workflowService</name> + <title>Update offer</title> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/UpdateOffer_workflowService/process.js</process> <alias>Data_alias</alias> diff --git a/process/workflowServiceTasks_rest/process.js b/process/workflowServiceTasks_rest/process.js index f713bc0fe1477587ad20f9122b6a107b75c7da08..967a59c5b8e9a0acfec0c6d168ed615031cd42b2 100644 --- a/process/workflowServiceTasks_rest/process.js +++ b/process/workflowServiceTasks_rest/process.js @@ -1,3 +1,4 @@ +import("Sql_lib"); import("system.project"); import("system.process"); @@ -5,13 +6,20 @@ function restget (pRequest) { let request = JSON.parse(pRequest); - let serviceTasks = project.getDataModels(project.DATAMODEL_KIND_PROCESS).filter(function (row) + let serviceTasks = project.getDataModels(project.DATAMODEL_KIND_PROCESS) + .filter(function (row) { return /.+_workflowService$/.test(row[0]); + }) + .map(function (row) + { + return { + id : row[0], + name : row[1] || row[0] + }; }); - request.response.body = JSON.stringify({}); + request.response.body = JSON.stringify(serviceTasks); return JSON.stringify(request); - } diff --git a/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod b/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod index 1222a5a8a5764760839ed226f403cd3a7546269e..db543d1d50dd750ef6d3e5d0a55f07a59d9952d2 100644 --- a/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod +++ b/process/workflowServiceTasks_rest/workflowServiceTasks_rest.aod @@ -3,8 +3,11 @@ <name>workflowServiceTasks_rest</name> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/workflowServiceTasks_rest/process.js</process> - <publishAsWebservice v="false" /> + <publishAsWebservice v="true" /> <style>REST</style> + <restAcceptedMimeType>application/json</restAcceptedMimeType> + <restDeliveredMimeType>application/json</restDeliveredMimeType> + <jditoWebserviceUser>flowableIdmService</jditoWebserviceUser> <variants> <element>EXECUTABLE</element> </variants>