diff --git a/.liquibase/Data_alias/basic/2019.2.1/alter_SerialLetter.xml b/.liquibase/Data_alias/basic/2019.2.1/alter_SerialLetter.xml new file mode 100644 index 0000000000000000000000000000000000000000..de3d63640b8f58836f30da4224ea3637ef577529 --- /dev/null +++ b/.liquibase/Data_alias/basic/2019.2.1/alter_SerialLetter.xml @@ -0,0 +1,9 @@ +<?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="f1a65325-8a60-409e-9271-512c14b5e1b7"> + <addColumn tableName="SERIALLETTER"> + <column name="STATUS" type="CHAR(36)"/> + </addColumn> + </changeSet> +</databaseChangeLog> diff --git a/.liquibase/Data_alias/basic/2019.2.1/changelog.xml b/.liquibase/Data_alias/basic/2019.2.1/changelog.xml index 760c8f453f66ed38fd346408e1f3473bfd6ddc4f..9320c36971e495d855c24727aa2c7e85d21d5a7b 100644 --- a/.liquibase/Data_alias/basic/2019.2.1/changelog.xml +++ b/.liquibase/Data_alias/basic/2019.2.1/changelog.xml @@ -2,4 +2,6 @@ <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 relativeToChangelogFile="true" file="update_attribute_Ticket_Support_Product.xml"/> + + <include relativeToChangelogFile="true" file="alter_SerialLetter.xml"/> </databaseChangeLog> diff --git a/entity/BulkMail_entity/BulkMail_entity.aod b/entity/BulkMail_entity/BulkMail_entity.aod index fab79de45c56b332b8703adb7ab831d879ced62b..3c902dff3f227405316889f9680bf5752e69dbb7 100644 --- a/entity/BulkMail_entity/BulkMail_entity.aod +++ b/entity/BulkMail_entity/BulkMail_entity.aod @@ -27,6 +27,7 @@ <name>NAME</name> <title>Name</title> <mandatory v="true" /> + <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/name/valueProcess.js</valueProcess> </entityField> <entityField> <name>SUBJECT</name> @@ -36,6 +37,7 @@ <entityField> <name>DESCRIPTION</name> <title>Description</title> + <contentType>LONG_TEXT</contentType> </entityField> <entityField> <name>DOCUMENTTEMPLATE_ID</name> diff --git a/entity/BulkMail_entity/entityfields/name/valueProcess.js b/entity/BulkMail_entity/entityfields/name/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..94a33c3fc3288465e8959ea57f74eb9b983d1787 --- /dev/null +++ b/entity/BulkMail_entity/entityfields/name/valueProcess.js @@ -0,0 +1,14 @@ +import("system.result"); +import("Document_lib"); +import("system.neon"); +import("system.vars"); + +if (vars.get("$this.value") == null && vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) +{ + var upload = vars.get("$field.bindata"); + if (upload) + { + var filename = DocumentUtil.getFilenameFromUpload(upload); + result.string(filename.split(".")[0]); + } +} \ No newline at end of file diff --git a/entity/BulkMail_entity/entityfields/subject/valueProcess.js b/entity/BulkMail_entity/entityfields/subject/valueProcess.js index 792f903d2c5b5063b787295c49e860af90110a06..fb6c668dc4b4fdf20757a7a5db45de16f8ed8392 100644 --- a/entity/BulkMail_entity/entityfields/subject/valueProcess.js +++ b/entity/BulkMail_entity/entityfields/subject/valueProcess.js @@ -8,7 +8,6 @@ import("system.vars"); if (vars.get("$this.value") == null && vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) { var upload = vars.get("$field.bindata"); - var template; if (upload) { var binData = DocumentUtil.getBindataFromUpload(upload); diff --git a/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js b/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js index 07aa5246ddaa79bf9f78d08a16c9da6dbfb48de5..71625c5c712cab7e76569fb406a17ae5a47fbce8 100644 --- a/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js +++ b/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js @@ -3,7 +3,7 @@ import("Sql_lib"); import("system.db"); db.deleteData("BULKMAILRECIPIENT", SqlCondition.equals("BULKMAILRECIPIENT.BULKMAIL_ID", vars.get("$local.uid"), "1=2")); -var SYSALIAS = "_____SYSTEMALIAS"; +var SYSALIAS = SqlUtils.getSystemAlias(); var binaryId = db.cell(SqlCondition.begin(SYSALIAS) .andPrepareVars("ASYS_BINARIES.ROW_ID", "$local.uid") .buildSql("select ID from ASYS_BINARIES"), SYSALIAS); diff --git a/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js b/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js index 7858a68158c8063c37e1149f4c6debec17a97927..124d083b49c0f9e023aaa6f730b170fc427a550f 100644 --- a/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js +++ b/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js @@ -1,3 +1,4 @@ +import("Sql_lib"); import("DocumentTemplate_lib"); import("system.result"); import("system.vars"); @@ -20,7 +21,7 @@ if (template.content) if (!template.filename) template.filename = bulkMailName + ".html"; db.insertBinary("BULKMAIL", "DOCUMENT", bulkMailId, - "", template.content, template.filename, "", "", "_____SYSTEMALIAS"); + "", template.content, template.filename, "", "", SqlUtils.getSystemAlias()); } var contactIds = JSON.parse(vars.getString("$param.PresetRecipients_param")); diff --git a/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js b/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js index 0a211da13f41be1fdb027c0a3437b3b2350b412a..e6ca5e9a03194feedeba892cd5c5359deb0e9894 100644 --- a/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js +++ b/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js @@ -20,7 +20,7 @@ if (template.content) { if (!template.filename) template.filename = bulkMailName + ".html"; - let sysAlias = "_____SYSTEMALIAS"; + let sysAlias = SqlUtils.getSystemAlias(); var binaryId = db.cell(SqlCondition.begin(sysAlias) .andPrepareVars("ASYS_BINARIES.ROW_ID", "$local.uid") .buildSql("select ID from ASYS_BINARIES", "1=2"), sysAlias); diff --git a/entity/DocumentTemplateLink_entity/entityfields/opendocument/onActionProcess.js b/entity/DocumentTemplateLink_entity/entityfields/opendocument/onActionProcess.js index 1b78adcb2e7eaa40ed24326ae14f942607602bf2..c943e852369cd24ce58978071cd6917b197414e1 100644 --- a/entity/DocumentTemplateLink_entity/entityfields/opendocument/onActionProcess.js +++ b/entity/DocumentTemplateLink_entity/entityfields/opendocument/onActionProcess.js @@ -1,15 +1,15 @@ -import("Sql_lib"); -import("system.db"); -import("system.vars"); -import("system.neon"); - -var fileInformation = db.array(db.ROW, SqlCondition.begin() - .andPrepareVars("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATE_ID_CHILD") - .buildSql("select ID, FILENAME from ASYS_BINARIES"), "_____SYSTEMALIAS"); -var data = db.getBinaryContent(fileInformation[0], "_____SYSTEMALIAS"); -neon.download(data, fileInformation[1]); - - - - - +import("Sql_lib"); +import("system.db"); +import("system.vars"); +import("system.neon"); + +var fileInformation = db.array(db.ROW, SqlCondition.begin() + .andPrepareVars("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATE_ID_CHILD") + .buildSql("select ID, FILENAME from ASYS_BINARIES"), SqlUtils.getSystemAlias()); +var data = db.getBinaryContent(fileInformation[0], SqlUtils.getSystemAlias()); +neon.download(data, fileInformation[1]); + + + + + diff --git a/entity/DocumentTemplate_entity/entityfields/textext/valueProcess.js b/entity/DocumentTemplate_entity/entityfields/textext/valueProcess.js index 7c52687169d59f207a63f94857ffd60137a12fba..4723c73981af398bf75eb3cb0f4b5a440bc2ef03 100644 --- a/entity/DocumentTemplate_entity/entityfields/textext/valueProcess.js +++ b/entity/DocumentTemplate_entity/entityfields/textext/valueProcess.js @@ -1,20 +1,20 @@ -import("Sql_lib"); -import("Document_lib"); -import("system.util"); -import("system.db"); -import("system.neon"); -import("system.result"); -import("system.vars"); - -if(vars.get("$field.KIND").trim() == "TEX" && vars.get("$field.BINDATA") == "" && vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT) -{ - var fileExtension = DocumentUtil.getFileExtensionFromUpload(vars.get("$field.NAME")); - - if(fileExtension == "txt") - { - var binaryId = db.cell(SqlCondition.begin() - .andPrepareVars("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATEID") - .buildSql("select ID from ASYS_BINARIES"), "_____SYSTEMALIAS"); - result.string(util.decodeBase64String(db.getBinaryContent(binaryId, "_____SYSTEMALIAS"))); - } +import("Sql_lib"); +import("Document_lib"); +import("system.util"); +import("system.db"); +import("system.neon"); +import("system.result"); +import("system.vars"); + +if(vars.get("$field.KIND").trim() == "TEX" && vars.get("$field.BINDATA") == "" && vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT) +{ + var fileExtension = DocumentUtil.getFileExtensionFromUpload(vars.get("$field.NAME")); + + if(fileExtension == "txt") + { + var binaryId = db.cell(SqlCondition.begin() + .andPrepareVars("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATEID") + .buildSql("select ID from ASYS_BINARIES"), SqlUtils.getSystemAlias()); + result.string(util.decodeBase64String(db.getBinaryContent(binaryId, SqlUtils.getSystemAlias()))); + } } \ No newline at end of file diff --git a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js index 8936ad8b3e3fe2373001a1fab17e4833577efcef..95cf3f9a66491bacbe72d4968928043043d2445c 100644 --- a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js +++ b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js @@ -4,6 +4,6 @@ import("system.db"); var binaryId = db.cell(SqlCondition.begin() .andPrepareVars("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATEID") - .buildSql("select ID from ASYS_BINARIES"), "_____SYSTEMALIAS"); + .buildSql("select ID from ASYS_BINARIES"), SqlUtils.getSystemAlias()); -db.deleteBinary(binaryId, "_____SYSTEMALIAS"); \ No newline at end of file +db.deleteBinary(binaryId, SqlUtils.getSystemAlias()); \ No newline at end of file diff --git a/entity/Offer_entity/entityfields/footer/valueProcess.js b/entity/Offer_entity/entityfields/footer/valueProcess.js index e064cf46a63fdb4be84aff8ec90abb3a711874a7..002d6afd22e0e8bede80b076b0c08bda6d3cb458 100644 --- a/entity/Offer_entity/entityfields/footer/valueProcess.js +++ b/entity/Offer_entity/entityfields/footer/valueProcess.js @@ -1,20 +1,21 @@ -import("system.result"); -import("system.vars"); -import("system.neon"); -import("system.db"); -import("system.util"); - -if(vars.exists("$param.OfferFooter_param") && vars.get("$param.OfferFooter_param")) - result.string(vars.get("$param.OfferFooter_param")); - -else if(vars.get("$this.value")) - result.string(vars.get("$this.value")); - -else if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) - result.string("Vielen Dank!") - -if (vars.get("$field.ChoosenTEXFooter") != "") -{ - var binaryId = db.cell("select ID from ASYS_BINARIES where ROW_ID = '" + vars.get("$field.ChoosenTEXFooter") + "'", "_____SYSTEMALIAS"); - result.string(util.decodeBase64String(db.getBinaryContent(binaryId, "_____SYSTEMALIAS"))); +import("Sql_lib"); +import("system.result"); +import("system.vars"); +import("system.neon"); +import("system.db"); +import("system.util"); + +if(vars.exists("$param.OfferFooter_param") && vars.get("$param.OfferFooter_param")) + result.string(vars.get("$param.OfferFooter_param")); + +else if(vars.get("$this.value")) + result.string(vars.get("$this.value")); + +else if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) + result.string("Vielen Dank!") + +if (vars.get("$field.ChoosenTEXFooter") != "") +{ + var binaryId = db.cell("select ID from ASYS_BINARIES where ROW_ID = '" + vars.get("$field.ChoosenTEXFooter") + "'", SqlUtils.getSystemAlias()); + result.string(util.decodeBase64String(db.getBinaryContent(binaryId, SqlUtils.getSystemAlias()))); } \ No newline at end of file diff --git a/entity/PermissionAction_entity/onValidation.js b/entity/PermissionAction_entity/onValidation.js index e97725af0b6c953e10fdabce940ff4bead540594..47c7fa03520ed8ae10eccbaa3c1002bf4609384e 100644 --- a/entity/PermissionAction_entity/onValidation.js +++ b/entity/PermissionAction_entity/onValidation.js @@ -1,10 +1,11 @@ +import("Sql_lib"); import("system.db"); import("system.vars"); import("system.translate"); import("system.result"); import("Permission_lib"); -var alias = "_____SYSTEMALIAS"; +var alias = SqlUtils.getSystemAlias(); var actionTitle = vars.get("$field.ACTION"); var permissionId = vars.get("$param.PermissionId_param"); var permCondInput = vars.get("$param.PermissionCondition_param"); diff --git a/entity/PermissionAction_entity/recordcontainers/jdito/onInsert.js b/entity/PermissionAction_entity/recordcontainers/jdito/onInsert.js index 3acce8156ad069e0f495f8793e8e202a86b8c4db..eaa90d0cb8597dc1a3374c82d563eb6ada68ab90 100644 --- a/entity/PermissionAction_entity/recordcontainers/jdito/onInsert.js +++ b/entity/PermissionAction_entity/recordcontainers/jdito/onInsert.js @@ -1,10 +1,11 @@ +import("Sql_lib"); import("system.db"); import("system.tools"); import("system.result"); import("system.vars"); import("Permission_lib"); -var alias = "_____SYSTEMALIAS"; +var alias = SqlUtils.getSystemAlias(); var permissionId = vars.exists("$param.PermissionId_param") && vars.get("$param.PermissionId_param"); if (permissionId) { diff --git a/entity/PermissionDetail_entity/recordcontainers/jdito/contentProcess.js b/entity/PermissionDetail_entity/recordcontainers/jdito/contentProcess.js index 44edb699f0c0827f4ce776f34e4f3875a478b061..aecbbceea0b47cf2a04eab49eb7815db75ea3efa 100644 --- a/entity/PermissionDetail_entity/recordcontainers/jdito/contentProcess.js +++ b/entity/PermissionDetail_entity/recordcontainers/jdito/contentProcess.js @@ -1,146 +1,147 @@ -import("system.util"); -import("system.vars"); -import("system.db"); -import("system.result"); -import("Permission_lib"); -import("system.project"); - -var selectedPermission = vars.get("$local.idvalues"); -var sqlStr; -var whereCond = " where"; -var alias = "_____SYSTEMALIAS"; -var entitiesMetaData = project.getDataModels(project.DATAMODEL_KIND_ENTITY); -var entityStructure; -var entitiesUsePermFlagSet = []; -var fieldsUsePermFlagSet = []; - -// gets all names of the entites which have the 'usePermission'-flag set (positive list) -// gets all names of the fields which have the 'usePermission'-flag set (positive list) -for each (let entityMetaData in entitiesMetaData) { - if (entityMetaData[6] == "true") { - entitiesUsePermFlagSet.push(entityMetaData[0]) - entityStructure = project.getEntityStructure(entityMetaData[0]); - for (fieldname in entityStructure.fields) { - field = entityStructure.fields[fieldname]; - if (field.usePermissions == true) { - fieldsUsePermFlagSet.push(field.name); - } - } - } -} - -whereCond += " ENTITY_ID in ('" + entitiesUsePermFlagSet.join("','") + "')"; -whereCond += " and (FIELD_ID in ('" + fieldsUsePermFlagSet.join("','") + "') or FIELD_ID is NULL)"; - -if (vars.exists("$param.RoleTitle_param") && vars.get("$param.RoleTitle_param")) { - whereCond += " and ASYS_PERMISSIONSET.ROLE_ID = '" + vars.getString("$param.RoleTitle_param") + "'"; -} else if (vars.exists("$param.EntityTitle_param") && vars.get("$param.EntityTitle_param")) { - whereCond += " and ASYS_PERMISSIONSET.ENTITY_ID = '" + vars.getString("$param.EntityTitle_param") + "'"; -} - -sqlStr = - "select ASYS_PERMISSION.ASYS_PERMISSIONID, ASYS_PERMISSIONSET.ENTITY_ID, ASYS_PERMISSIONSET.ROLE_ID," - + " ASYS_PERMISSIONSET.FIELD_ID, ASYS_PERMISSION.COND, ASYS_PERMISSIONACTION.ACTION, ASYS_PERMISSIONSET.ACCESSTYPE, ASYS_PERMISSION.CONDTYPE from ASYS_PERMISSIONSET" - + " join ASYS_PERMISSION on ASYS_PERMISSION.ASYS_PERMISSIONSET_ID = ASYS_PERMISSIONSET.ASYS_PERMISSIONSETID" - + " join ASYS_PERMISSIONACTION on ASYS_PERMISSIONACTION.ASYS_PERMISSION_ID = ASYS_PERMISSION.ASYS_PERMISSIONID" - + whereCond - + " order by ASYS_PERMISSION.ASYS_PERMISSIONID"; - -var sqlRes = db.table(sqlStr, alias); -var permissionTable = PermissionUtil.convertArrToObj(sqlRes); - -// group all permissions by permissionid and condition, concat actions -var groupedPermissionTable = [], concatAction; -for (let i = 0; i < permissionTable.length - 1; i++) { - for (let j = i + 1; j < permissionTable.length; j++) { - if (permissionTable[i].permissionid == permissionTable[j].permissionid && permissionTable[i].cond == permissionTable[j].cond) { - var currPermId = permissionTable[i].permissionid; - var indexCurrPermGrouped = PermissionUtil.indexOfPermId(groupedPermissionTable, currPermId); - if (indexCurrPermGrouped > -1) { - // permissionset got already grouped before - // concat current action with the actions which got already grouped - concatAction = groupedPermissionTable[indexCurrPermGrouped].action + "," + permissionTable[j].action; - groupedPermissionTable[indexCurrPermGrouped].action = concatAction; - break; - } else { - concatAction = permissionTable[i].action + "," + permissionTable[j].action; - groupedPermissionTable.push(permissionTable[i]); - groupedPermissionTable[groupedPermissionTable.length-1].action = concatAction; - break; - } - } - } -} - -var res = []; -var permissionTableOrigin = PermissionUtil.convertArrToObj(sqlRes); - -// no permission selected, return all permission entrys -if (selectedPermission == null) { - for each (let entry in groupedPermissionTable) { - res = prepareResultArray(entry, res); - } - - for each (let entry in permissionTableOrigin) { - if (PermissionUtil.indexOfPermId(PermissionUtil.convertArrToObj(res), entry.permissionid) == -1) { - res = prepareResultArray(entry, res); - } - } -} else { // permission selected, return only the selected permission entry - for each (let entry in groupedPermissionTable) { - if (selectedPermission == entry.permissionid) { - res = prepareResultArray(entry, res); - break; - } - } - - for each (let entry in permissionTableOrigin) { - if (selectedPermission == entry.permissionid) { - if (PermissionUtil.indexOfPermId(PermissionUtil.convertArrToObj(res), entry.permissionid) == -1) { - res = prepareResultArray(entry, res); - break; - } - } - } -} - -result.object(res.sort(sortFunction)); - -function prepareResultArray(pEntry, pRes) { - var rootPermission = ""; - if (pEntry.accesstype != "E") { - if (pEntry.accesstype == "F" && pEntry.cond != "") { - rootPermission = PermissionUtil.getRootFieldPermission(pEntry.permissionid); - if (rootPermission == "") { - rootPermission = PermissionUtil.getRootPermission(pEntry.permissionid); - } - } else - rootPermission = PermissionUtil.getRootPermission(pEntry.permissionid); - } - pRes.push([pEntry.permissionid, pEntry.entity, pEntry.role, pEntry.field, pEntry.cond, pEntry.action, pEntry.accesstype, pEntry.condtype, rootPermission]); - return pRes; -} - -// used to sort result array: Entity -> Records -> Fields -function sortFunction(a, b) { - if (a[6] == b[6] && a[6] != "F" && a[6] != "R") - return 0; - else if (a[6] == "E") - return -1; - else if (b[6] == "E") - return 1; - else if (a[6] == "R" && b[6] == "F") - return -1; - else if (a[6] == "F" && b[6] == "R") - return 1; - else if (a[6] == "R" && b[6] == "R" && a[4] == "") - return -1; - else if (a[6] == "R" && b[6] == "R" && b[4] == "") - return 1; - else if (a[6] == "F" && b[6] == "F" && a[4] == "") - return -1; - else if (a[6] == "F" && b[6] == "F" && b[4] == "") - return 1; - else - return 0; +import("Sql_lib"); +import("system.util"); +import("system.vars"); +import("system.db"); +import("system.result"); +import("Permission_lib"); +import("system.project"); + +var selectedPermission = vars.get("$local.idvalues"); +var sqlStr; +var whereCond = " where"; +var alias = SqlUtils.getSystemAlias(); +var entitiesMetaData = project.getDataModels(project.DATAMODEL_KIND_ENTITY); +var entityStructure; +var entitiesUsePermFlagSet = []; +var fieldsUsePermFlagSet = []; + +// gets all names of the entites which have the 'usePermission'-flag set (positive list) +// gets all names of the fields which have the 'usePermission'-flag set (positive list) +for each (let entityMetaData in entitiesMetaData) { + if (entityMetaData[6] == "true") { + entitiesUsePermFlagSet.push(entityMetaData[0]) + entityStructure = project.getEntityStructure(entityMetaData[0]); + for (fieldname in entityStructure.fields) { + field = entityStructure.fields[fieldname]; + if (field.usePermissions == true) { + fieldsUsePermFlagSet.push(field.name); + } + } + } +} + +whereCond += " ENTITY_ID in ('" + entitiesUsePermFlagSet.join("','") + "')"; +whereCond += " and (FIELD_ID in ('" + fieldsUsePermFlagSet.join("','") + "') or FIELD_ID is NULL)"; + +if (vars.exists("$param.RoleTitle_param") && vars.get("$param.RoleTitle_param")) { + whereCond += " and ASYS_PERMISSIONSET.ROLE_ID = '" + vars.getString("$param.RoleTitle_param") + "'"; +} else if (vars.exists("$param.EntityTitle_param") && vars.get("$param.EntityTitle_param")) { + whereCond += " and ASYS_PERMISSIONSET.ENTITY_ID = '" + vars.getString("$param.EntityTitle_param") + "'"; +} + +sqlStr = + "select ASYS_PERMISSION.ASYS_PERMISSIONID, ASYS_PERMISSIONSET.ENTITY_ID, ASYS_PERMISSIONSET.ROLE_ID," + + " ASYS_PERMISSIONSET.FIELD_ID, ASYS_PERMISSION.COND, ASYS_PERMISSIONACTION.ACTION, ASYS_PERMISSIONSET.ACCESSTYPE, ASYS_PERMISSION.CONDTYPE from ASYS_PERMISSIONSET" + + " join ASYS_PERMISSION on ASYS_PERMISSION.ASYS_PERMISSIONSET_ID = ASYS_PERMISSIONSET.ASYS_PERMISSIONSETID" + + " join ASYS_PERMISSIONACTION on ASYS_PERMISSIONACTION.ASYS_PERMISSION_ID = ASYS_PERMISSION.ASYS_PERMISSIONID" + + whereCond + + " order by ASYS_PERMISSION.ASYS_PERMISSIONID"; + +var sqlRes = db.table(sqlStr, alias); +var permissionTable = PermissionUtil.convertArrToObj(sqlRes); + +// group all permissions by permissionid and condition, concat actions +var groupedPermissionTable = [], concatAction; +for (let i = 0; i < permissionTable.length - 1; i++) { + for (let j = i + 1; j < permissionTable.length; j++) { + if (permissionTable[i].permissionid == permissionTable[j].permissionid && permissionTable[i].cond == permissionTable[j].cond) { + var currPermId = permissionTable[i].permissionid; + var indexCurrPermGrouped = PermissionUtil.indexOfPermId(groupedPermissionTable, currPermId); + if (indexCurrPermGrouped > -1) { + // permissionset got already grouped before + // concat current action with the actions which got already grouped + concatAction = groupedPermissionTable[indexCurrPermGrouped].action + "," + permissionTable[j].action; + groupedPermissionTable[indexCurrPermGrouped].action = concatAction; + break; + } else { + concatAction = permissionTable[i].action + "," + permissionTable[j].action; + groupedPermissionTable.push(permissionTable[i]); + groupedPermissionTable[groupedPermissionTable.length-1].action = concatAction; + break; + } + } + } +} + +var res = []; +var permissionTableOrigin = PermissionUtil.convertArrToObj(sqlRes); + +// no permission selected, return all permission entrys +if (selectedPermission == null) { + for each (let entry in groupedPermissionTable) { + res = prepareResultArray(entry, res); + } + + for each (let entry in permissionTableOrigin) { + if (PermissionUtil.indexOfPermId(PermissionUtil.convertArrToObj(res), entry.permissionid) == -1) { + res = prepareResultArray(entry, res); + } + } +} else { // permission selected, return only the selected permission entry + for each (let entry in groupedPermissionTable) { + if (selectedPermission == entry.permissionid) { + res = prepareResultArray(entry, res); + break; + } + } + + for each (let entry in permissionTableOrigin) { + if (selectedPermission == entry.permissionid) { + if (PermissionUtil.indexOfPermId(PermissionUtil.convertArrToObj(res), entry.permissionid) == -1) { + res = prepareResultArray(entry, res); + break; + } + } + } +} + +result.object(res.sort(sortFunction)); + +function prepareResultArray(pEntry, pRes) { + var rootPermission = ""; + if (pEntry.accesstype != "E") { + if (pEntry.accesstype == "F" && pEntry.cond != "") { + rootPermission = PermissionUtil.getRootFieldPermission(pEntry.permissionid); + if (rootPermission == "") { + rootPermission = PermissionUtil.getRootPermission(pEntry.permissionid); + } + } else + rootPermission = PermissionUtil.getRootPermission(pEntry.permissionid); + } + pRes.push([pEntry.permissionid, pEntry.entity, pEntry.role, pEntry.field, pEntry.cond, pEntry.action, pEntry.accesstype, pEntry.condtype, rootPermission]); + return pRes; +} + +// used to sort result array: Entity -> Records -> Fields +function sortFunction(a, b) { + if (a[6] == b[6] && a[6] != "F" && a[6] != "R") + return 0; + else if (a[6] == "E") + return -1; + else if (b[6] == "E") + return 1; + else if (a[6] == "R" && b[6] == "F") + return -1; + else if (a[6] == "F" && b[6] == "R") + return 1; + else if (a[6] == "R" && b[6] == "R" && a[4] == "") + return -1; + else if (a[6] == "R" && b[6] == "R" && b[4] == "") + return 1; + else if (a[6] == "F" && b[6] == "F" && a[4] == "") + return -1; + else if (a[6] == "F" && b[6] == "F" && b[4] == "") + return 1; + else + return 0; } \ No newline at end of file diff --git a/entity/PermissionDetail_entity/recordcontainers/jdito/onDelete.js b/entity/PermissionDetail_entity/recordcontainers/jdito/onDelete.js index a53b540b0027aaf55679b569d9433362fb35c4d2..03032f4d74eaf6b7a7e38ddc8c66c55e8fcfd3c1 100644 --- a/entity/PermissionDetail_entity/recordcontainers/jdito/onDelete.js +++ b/entity/PermissionDetail_entity/recordcontainers/jdito/onDelete.js @@ -9,7 +9,7 @@ var permId = vars.get("$field.UID"); var accessType = vars.get("$field.ACCESSTYPE"); var parentPermSetId = PermissionUtil.getParentPermissionSet(permId); var linkedActions = PermissionUtil.getAllChildPermissionActions(permId); -var alias = "_____SYSTEMALIAS"; +var alias = SqlUtils.getSystemAlias(); var sqlCondDelAction = SqlCondition.begin() .and("ASYS_PERMISSIONACTION.ASYS_PERMISSIONACTIONID in ('" + linkedActions.join("','") + "')") diff --git a/entity/PermissionDetail_entity/recordcontainers/jdito/onInsert.js b/entity/PermissionDetail_entity/recordcontainers/jdito/onInsert.js index 00b1e28b28b5c0d5810eea6ab9c4330f9a43d434..d74cc3ec7c6b9b91038fb9cf8c52c7793098061a 100644 --- a/entity/PermissionDetail_entity/recordcontainers/jdito/onInsert.js +++ b/entity/PermissionDetail_entity/recordcontainers/jdito/onInsert.js @@ -1,3 +1,4 @@ +import("Sql_lib"); import("Permission_lib"); import("system.neon"); import("system.util"); @@ -7,7 +8,7 @@ import("system.tools"); import("Permission_lib"); import("Entity_lib"); -var alias = "_____SYSTEMALIAS"; +var alias = SqlUtils.getSystemAlias(); var tablename = "ASYS_PERMISSION"; var sqlExt = ""; var permissionid = vars.get("$field.UID"); diff --git a/entity/PermissionDetail_entity/recordcontainers/jdito/onUpdate.js b/entity/PermissionDetail_entity/recordcontainers/jdito/onUpdate.js index 0bac6c05f928b15b692f05e9d7d286da7979301e..d45ba525a2cd7a43f2ca2710b0038ba6f70b388d 100644 --- a/entity/PermissionDetail_entity/recordcontainers/jdito/onUpdate.js +++ b/entity/PermissionDetail_entity/recordcontainers/jdito/onUpdate.js @@ -8,7 +8,7 @@ import("Permission_lib"); var table, cols, vals, cond; -var alias = "_____SYSTEMALIAS"; +var alias = SqlUtils.getSystemAlias(); var permissionid = vars.get("$field.UID"); var actionNew = vars.get("$field.ACTION").split(","); var entityNew = vars.get("$field.ENTITY"); diff --git a/entity/SerialLetter_entity/SerialLetter_entity.aod b/entity/SerialLetter_entity/SerialLetter_entity.aod index 37cbad61dc3b8475cb02d5d8f4b5a5a9672b465c..dd4c7fd86fed7fb40f753c34fa643f5b2dad3db8 100644 --- a/entity/SerialLetter_entity/SerialLetter_entity.aod +++ b/entity/SerialLetter_entity/SerialLetter_entity.aod @@ -66,6 +66,7 @@ <name>TITLE</name> <title>Title</title> <mandatory v="true" /> + <valueProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/title/valueProcess.js</valueProcess> </entityField> <entityField> <name>DESCRIPTION</name> @@ -97,6 +98,17 @@ <name>bindata</name> <contentType>FILE</contentType> </entityField> + <entityField> + <name>STATUS</name> + <title>Status</title> + </entityField> + <entityActionField> + <name>downloadTemplate</name> + <title>Download template</title> + <onActionProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/downloadtemplate/onActionProcess.js</onActionProcess> + <iconId>VAADIN:FILE_FONT</iconId> + <stateProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/downloadtemplate/stateProcess.js</stateProcess> + </entityActionField> </entityFields> <recordContainers> <dbRecordContainer> @@ -146,6 +158,10 @@ <recordfield>SERIALLETTER.DESCRIPTION</recordfield> <isFilterable v="true" /> </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>STATUS.value</name> + <recordfield>SERIALLETTER.STATUS</recordfield> + </dbRecordFieldMapping> </recordFieldMappings> </dbRecordContainer> </recordContainers> diff --git a/entity/SerialLetter_entity/entityfields/downloadtemplate/onActionProcess.js b/entity/SerialLetter_entity/entityfields/downloadtemplate/onActionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..08f18726798d5059a50a4559b66dce881dd40b4b --- /dev/null +++ b/entity/SerialLetter_entity/entityfields/downloadtemplate/onActionProcess.js @@ -0,0 +1,7 @@ +import("system.neon"); +import("system.vars"); +import("DocumentTemplate_lib"); + +var template = DocumentTemplate.loadTemplate(vars.get("$field.DOCUMENTTEMPLATE_ID")); +if (template.type) + neon.download(template.content, template.filename); \ No newline at end of file diff --git a/entity/SerialLetter_entity/entityfields/downloadtemplate/stateProcess.js b/entity/SerialLetter_entity/entityfields/downloadtemplate/stateProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..5d14adc883f77e859201d92eeded2a5de21a8d97 --- /dev/null +++ b/entity/SerialLetter_entity/entityfields/downloadtemplate/stateProcess.js @@ -0,0 +1,8 @@ +import("system.neon"); +import("system.vars"); +import("system.result"); + +if (vars.get("$field.DOCUMENTTEMPLATE_ID")) + result.string(neon.COMPONENTSTATE_EDITABLE); +else + result.string(neon.COMPONENTSTATE_DISABLED); \ No newline at end of file diff --git a/entity/SerialLetter_entity/entityfields/title/valueProcess.js b/entity/SerialLetter_entity/entityfields/title/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..94a33c3fc3288465e8959ea57f74eb9b983d1787 --- /dev/null +++ b/entity/SerialLetter_entity/entityfields/title/valueProcess.js @@ -0,0 +1,14 @@ +import("system.result"); +import("Document_lib"); +import("system.neon"); +import("system.vars"); + +if (vars.get("$this.value") == null && vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) +{ + var upload = vars.get("$field.bindata"); + if (upload) + { + var filename = DocumentUtil.getFilenameFromUpload(upload); + result.string(filename.split(".")[0]); + } +} \ No newline at end of file diff --git a/entity/SerialLetter_entity/recordcontainers/db/onDBDelete.js b/entity/SerialLetter_entity/recordcontainers/db/onDBDelete.js index 34979b2969fbf69d73958e88c10b9d7c378fba3e..55085a49c3ce5eaca03b0a37dac814b5cf0e706c 100644 --- a/entity/SerialLetter_entity/recordcontainers/db/onDBDelete.js +++ b/entity/SerialLetter_entity/recordcontainers/db/onDBDelete.js @@ -3,7 +3,7 @@ import("Sql_lib"); import("system.db"); db.deleteData("LETTERRECIPIENT", SqlCondition.equals("LETTERRECIPIENT.SERIALLETTER_ID", vars.get("$local.uid"), "1=2")); -var SYSALIAS = "_____SYSTEMALIAS"; +var SYSALIAS = SqlUtils.getSystemAlias(); var binaryId = db.cell(SqlCondition.begin(SYSALIAS) .andPrepareVars("ASYS_BINARIES.ROW_ID", "$local.uid") .buildSql("select ID from ASYS_BINARIES"), SYSALIAS); diff --git a/entity/SerialLetter_entity/recordcontainers/db/onDBInsert.js b/entity/SerialLetter_entity/recordcontainers/db/onDBInsert.js index 1224558a36e2187d2432748cb0fd69cc1955f923..9b692c8c7d8c4c8588788f61f16a1e048c351481 100644 --- a/entity/SerialLetter_entity/recordcontainers/db/onDBInsert.js +++ b/entity/SerialLetter_entity/recordcontainers/db/onDBInsert.js @@ -1,3 +1,4 @@ +import("Sql_lib"); import("DocumentTemplate_lib"); import("system.result"); import("system.vars"); @@ -14,5 +15,5 @@ var template = DocumentTemplate.fromUpload(bindata); if (template.content) { db.insertBinary("SERIALLETTER", "DOCUMENT", letterId, - "", template.content, template.filename, "", "", "_____SYSTEMALIAS"); + "", template.content, template.filename, "", "", SqlUtils.getSystemAlias()); } \ No newline at end of file diff --git a/entity/SerialLetter_entity/recordcontainers/db/onDBUpdate.js b/entity/SerialLetter_entity/recordcontainers/db/onDBUpdate.js index 5f84c9de4f1bce2553c114c6c07230ed97c39c67..8f8d362bc8c35d28fc77c9d00a5b192e016c411e 100644 --- a/entity/SerialLetter_entity/recordcontainers/db/onDBUpdate.js +++ b/entity/SerialLetter_entity/recordcontainers/db/onDBUpdate.js @@ -15,9 +15,7 @@ var template = DocumentTemplate.fromUpload(bindata); if (template.content) { - if (!template.filename) - template.filename = bulkMailName + ".html"; - let sysAlias = "_____SYSTEMALIAS"; + let sysAlias = SqlUtils.getSystemAlias(); var binaryId = db.cell(SqlCondition.begin(sysAlias) .andPrepareVars("ASYS_BINARIES.ROW_ID", "$local.uid") .buildSql("select ID from ASYS_BINARIES", "1=2"), sysAlias); @@ -26,6 +24,6 @@ if (template.content) db.updateBinary(binaryId, "", template.content, template.filename, "", "", sysAlias); else db.insertBinary("SERIALLETTER", "DOCUMENT", letterId, - "", template.content, template.filename, "", "", "_____SYSTEMALIAS"); + "", template.content, template.filename, "", "", sysAlias); neon.refresh(["$field.content"]); } diff --git a/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js b/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js index d03f1ac83c31d9c93fe323c495011bfc9406a7b8..2d6454962cde27463f1b856741dbbc508adbe9ca 100644 --- a/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js +++ b/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js @@ -1,6 +1,6 @@ -import("Util_lib"); -import("system.vars"); -import("system.db"); -import("ActivityTask_lib") - -CodeUtils.setCode(vars.get("$local.uid"), "TICKET", "TICKETID", "CODE"); \ No newline at end of file +import("Util_lib"); +import("system.vars"); +import("system.db"); +import("ActivityTask_lib") + +ConsecutiveCodeUtils.setCode(vars.get("$local.uid"), "TICKET", "TICKETID", "CODE"); \ No newline at end of file diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod index 26fe539ab9a1e570435dca64c7c27d1b8ec5bef0..a01ee589caea77a5589eb33ffbe27037134b2083 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -1831,7 +1831,7 @@ </entry> <entry> <key>New receipt version</key> - <value>Neue Belegsversion</value> + <value>Neue Quittungsversion</value> </entry> <entry> <key>Orderitems</key> diff --git a/neonView/BulkMailEdit_view/BulkMailEdit_view.aod b/neonView/BulkMailEdit_view/BulkMailEdit_view.aod index bd325868668ac981312ce976c7c53f0bc7e1d945..6673a4671bd569e5f51055fce543bea35d3ca5b7 100644 --- a/neonView/BulkMailEdit_view/BulkMailEdit_view.aod +++ b/neonView/BulkMailEdit_view/BulkMailEdit_view.aod @@ -25,10 +25,6 @@ <name>e363bda2-d8bf-456e-bcae-d1870408022a</name> <entityField>NAME</entityField> </entityFieldLink> - <entityFieldLink> - <name>06f08869-5a81-41cb-8c7e-51be6a7041a7</name> - <entityField>DESCRIPTION</entityField> - </entityFieldLink> <entityFieldLink> <name>c73d0fb7-b740-48ac-8f3e-fd4199f169da</name> <entityField>SUBJECT</entityField> @@ -41,6 +37,10 @@ <name>d9b91083-948e-4a0f-a29c-4962ddd78b41</name> <entityField>CREATEACTIVITIES</entityField> </entityFieldLink> + <entityFieldLink> + <name>06f08869-5a81-41cb-8c7e-51be6a7041a7</name> + <entityField>DESCRIPTION</entityField> + </entityFieldLink> <entityFieldLink> <name>0a67f430-dbcd-4605-b626-ee6d715ab248</name> <entityField>content</entityField> diff --git a/neonView/BulkMailPreview_view/BulkMailPreview_view.aod b/neonView/BulkMailPreview_view/BulkMailPreview_view.aod index a9bdee7f245a104ebe54b6a5fd5d47fbaa9f6189..a635308c73c5387c3fe6c607f3f664749b7a26fc 100644 --- a/neonView/BulkMailPreview_view/BulkMailPreview_view.aod +++ b/neonView/BulkMailPreview_view/BulkMailPreview_view.aod @@ -1,68 +1,68 @@ -<?xml version="1.0" encoding="UTF-8"?> -<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> - <name>BulkMailPreview_view</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <layout> - <headerFooterLayout> - <name>layout</name> - <header>Card</header> - </headerFooterLayout> - </layout> - <children> - <cardViewTemplate> - <name>Card</name> - <iconField>ICON</iconField> - <titleField>NAME</titleField> - <descriptionField>STATUS</descriptionField> - <favoriteAction1>sendMail</favoriteAction1> - <entityField>#ENTITY</entityField> - </cardViewTemplate> - <genericViewTemplate> - <name>Generic</name> - <showDrawer v="true" /> - <entityField>#ENTITY</entityField> - <fields> - <entityFieldLink> - <name>524c32f8-99d8-453d-afe5-b72a322a4555</name> - <entityField>SUBJECT</entityField> - </entityFieldLink> - <entityFieldLink> - <name>9ef1ecd4-063a-4c18-9def-d395f59a64dc</name> - <entityField>SENDER</entityField> - </entityFieldLink> - <entityFieldLink> - <name>28c1e091-0fea-4324-8fb8-1893388354b7</name> - <entityField>STATUS</entityField> - </entityFieldLink> - <entityFieldLink> - <name>edbeea4d-019f-4661-b0d7-c07468e747cc</name> - <entityField>DOCUMENTTEMPLATE_ID</entityField> - </entityFieldLink> - <entityFieldLink> - <name>8bb72d39-3348-4bd6-b57d-f7f5ae573e73</name> - <entityField>DESCRIPTION</entityField> - </entityFieldLink> - <entityFieldLink> - <name>514d0861-ad00-4d32-9c56-6be0443e03e3</name> - <entityField>CREATEACTIVITIES</entityField> - </entityFieldLink> - </fields> - </genericViewTemplate> - <genericViewTemplate> - <name>Testing</name> - <showDrawer v="true" /> - <drawerCaption>Testing</drawerCaption> - <entityField>#ENTITY</entityField> - <fields> - <entityFieldLink> - <name>ea406803-6189-4de0-aa41-f09f7e1b2336</name> - <entityField>TESTING_CONTACT_ID</entityField> - </entityFieldLink> - <entityFieldLink> - <name>f8963199-c89b-48e5-a92c-8f655c05acab</name> - <entityField>TESTING_EMAIL_ADDRESS</entityField> - </entityFieldLink> - </fields> - </genericViewTemplate> - </children> -</neonView> +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> + <name>BulkMailPreview_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <headerFooterLayout> + <name>layout</name> + <header>Card</header> + </headerFooterLayout> + </layout> + <children> + <cardViewTemplate> + <name>Card</name> + <iconField>ICON</iconField> + <titleField>NAME</titleField> + <descriptionField>STATUS</descriptionField> + <favoriteAction1>sendMail</favoriteAction1> + <entityField>#ENTITY</entityField> + </cardViewTemplate> + <genericViewTemplate> + <name>Generic</name> + <showDrawer v="true" /> + <entityField>#ENTITY</entityField> + <fields> + <entityFieldLink> + <name>524c32f8-99d8-453d-afe5-b72a322a4555</name> + <entityField>SUBJECT</entityField> + </entityFieldLink> + <entityFieldLink> + <name>9ef1ecd4-063a-4c18-9def-d395f59a64dc</name> + <entityField>SENDER</entityField> + </entityFieldLink> + <entityFieldLink> + <name>28c1e091-0fea-4324-8fb8-1893388354b7</name> + <entityField>STATUS</entityField> + </entityFieldLink> + <entityFieldLink> + <name>edbeea4d-019f-4661-b0d7-c07468e747cc</name> + <entityField>DOCUMENTTEMPLATE_ID</entityField> + </entityFieldLink> + <entityFieldLink> + <name>514d0861-ad00-4d32-9c56-6be0443e03e3</name> + <entityField>CREATEACTIVITIES</entityField> + </entityFieldLink> + <entityFieldLink> + <name>8bb72d39-3348-4bd6-b57d-f7f5ae573e73</name> + <entityField>DESCRIPTION</entityField> + </entityFieldLink> + </fields> + </genericViewTemplate> + <genericViewTemplate> + <name>Testing</name> + <showDrawer v="true" /> + <drawerCaption>Testing</drawerCaption> + <entityField>#ENTITY</entityField> + <fields> + <entityFieldLink> + <name>ea406803-6189-4de0-aa41-f09f7e1b2336</name> + <entityField>TESTING_CONTACT_ID</entityField> + </entityFieldLink> + <entityFieldLink> + <name>f8963199-c89b-48e5-a92c-8f655c05acab</name> + <entityField>TESTING_EMAIL_ADDRESS</entityField> + </entityFieldLink> + </fields> + </genericViewTemplate> + </children> +</neonView> diff --git a/neonView/SerialLetterEdit_view/SerialLetterEdit_view.aod b/neonView/SerialLetterEdit_view/SerialLetterEdit_view.aod index 587a9aeb2e2d76da75d8f38527ecc0f64a46e9a0..a7414e5f2776ac45060fb932612b6b6407723d8e 100644 --- a/neonView/SerialLetterEdit_view/SerialLetterEdit_view.aod +++ b/neonView/SerialLetterEdit_view/SerialLetterEdit_view.aod @@ -13,10 +13,6 @@ <editMode v="true" /> <entityField>#ENTITY</entityField> <fields> - <entityFieldLink> - <name>b33a8886-75b0-4644-890d-97a8133079ea</name> - <entityField>TITLE</entityField> - </entityFieldLink> <entityFieldLink> <name>98b1c32e-8f7e-45f9-bbc8-048851133048</name> <entityField>DOCUMENTTEMPLATE_ID</entityField> @@ -25,6 +21,10 @@ <name>057f064d-53fd-4d80-a43e-20a4a40d4ffb</name> <entityField>bindata</entityField> </entityFieldLink> + <entityFieldLink> + <name>b33a8886-75b0-4644-890d-97a8133079ea</name> + <entityField>TITLE</entityField> + </entityFieldLink> <entityFieldLink> <name>1845ae78-7132-4efc-aba0-737dc4d7fc9b</name> <entityField>DESCRIPTION</entityField> diff --git a/process/Calendar_lib/process.js b/process/Calendar_lib/process.js index 38539e6ee4e3d85bbc6110a9453e60414fbbccfc..fddc0663aa181607e49b22260d9d67d504705686 100644 --- a/process/Calendar_lib/process.js +++ b/process/Calendar_lib/process.js @@ -1,1935 +1,1935 @@ -import("system.neon"); -import("system.vars"); -import("system.db"); -import("system.translate"); -import("system.datetime"); -import("system.swing"); -import("system.eMath"); -import("system.calendars"); -import("system.logging"); -import("system.tools"); -import("system.text"); -import("system.question"); -import("system.SQLTYPES"); -import("system.result"); -import("Util_lib"); -import("system.util") - - -/** - * @class - **/ -function CalendarUtil(){} - - -/* - * Erzeugt und öffnet ein neues Aufgabenobjekt (mit einem Link). - * - * @param {String} pSummary opt die Zusammenfassung - * @param {String} pDescription opt die Beschreibung - * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable - * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames - * pWithLink[1]: ID des angezeigten Datensatzes - * pWithLink[2]: Verknüpfungstitel - * @param {String} pUser opt der Benutzer ( Login ) - * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) - * @param {date} pStart opt Beginn der Aufgabe - * @param {date} pDuration opt Dauer - * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) - * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) - * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten - * - * @return {void} - */ -CalendarUtil.newTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh) -{ - var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus ); - var prompts = []; - prompts["comp4refresh"] = []; - - if (pComps4Refresh == undefined) - pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Aufgabe"]; - - for (var i = 0; i < pComps4Refresh.length; i++) - { - if ( vars.exists(pComps4Refresh[i])) prompts["comp4refresh"].push(pComps4Refresh[i]); - } - if(vars.getString("$sys.scope") == "vaadin") - neon.openCalendarEntry([todo], null, neon.OPERATINGSTATE_NEW, null) - else - { - if (vars.exists("$sys.currentwindow")) - prompts["window"] = vars.getString("$sys.currentwindow"); - if (vars.exists("$sys.currentimage")) - prompts["image"] = vars.getString("$sys.currentimage"); - - swing.openCalendarEntry([todo], null, false, prompts); - } -} - - -/** - * Finds the effective calendarId of an user in the same attribute order like the ADITO core, which is exchangeEmail -> calendarID -> email - * DO NOT CHANGE THIS ORDER - * - * @param {String} user to check - * @return effective calendar id - */ -CalendarUtil.getEffectiveCalendarIdFromUser = function(pUser) -{ - var userParams = pUser["params"]; - - var resolvedCurrentUser; - var exchangeEmail = userParams["exchangeEMail"]; - var calendarId = userParams["calendarID"]; - var email = userParams["email"]; - - if(exchangeEmail) - return exhangeEmail; - else if(calendarId) - return calendarId; - else if(email) - return email; - else - return ""; -} - -/* - * Erzeugt eine neue Aufgabe (mit einem Link). - * - * @param {String} pSummary opt die Zusammenfassung - * @param {String} pDescription opt die Beschreibung - * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable - * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames - * pWithLink[1]: ID des angezeigten Datensatzes - * pWithLink[2]: Verknüpfungstitel - * @param {String} pUser opt der Benutzer ( Login ) - * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) - * @param {date} pStart opt Beginn der Aufagebe - * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI ) - * @param {date} pDuration opt Dauer - * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) - * @param {String} pStatus opt Status der Aufgabe ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) - * @param {String} pPriority opt Priorität der Aufgabe - * @param {String} pReminder opt Erinnerung der Aufgabe - * - * @return {void} - */ - -CalendarUtil.newSilentTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pPriority, pReminder) -{ - if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE; - var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder ); - - return calendars.insert([todo],calendars.GROUP_SINGLE); -} - -/* - * Erzeugt und öffnet ein neues Terminnobjekt mit einem Link. - * - * @param {String} pSummary opt die Zusammenfassung - * @param {String} pDescription opt die Beschreibung - * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable - * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames - * pWithLink[1]: ID des angezeigten Datensatzes - * pWithLink[2]: Verknüpfungstitel - * @param {String} pUser opt der Benutzer ( Login ) - * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) - * @param {date} pStart opt Beginn der Aufagebe - * @param {date} pDuration opt Dauer - * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) - * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) - * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten - * - * @return {void} - */ -CalendarUtil.newEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh, pWorklistId) -{ - var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus ); - - var prompts = []; - prompts["comp4refresh"] = []; - if (pComps4Refresh == undefined) - pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Termine"]; - for (i = 0; i < pComps4Refresh.length; i++) - { - if ( vars.exists(pComps4Refresh[i])) prompts["comp4refresh"].push(pComps4Refresh[i]); - } - - if(vars.getString("$sys.scope") == "vaadin") - neon.openCalendarEntry([event],"", neon.OPERATINGSTATE_NEW, null) - else - { - prompts["window"] = vars.getString("$sys.currentwindow"); - prompts["image"] = vars.getString("$sys.currentimage"); - if (pWorklistId != undefined) - prompts["worklistId"] = pWorklistId; - swing.openCalendarEntry([event], null, false, prompts); - } -} - - -/* - * Erzeugt einen neuen Termineintrag (mit einem Link). - * - * @param {String} pSummary opt die Zusammenfassung - * @param {String} pDescription opt die Beschreibung - * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable - * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames - * pWithLink[1]: ID des angezeigten Datensatzes - * pWithLink[2]: Verknüpfungstitel - * @param {String} pUser opt der Benutzer ( Login ) - * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) - * @param {date} pStart opt Beginn des Termins - * @param {date} pDuration opt Dauer - * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI ) - * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) - * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) - * @param {String} pReminder opt Erinnerung des Termins - * - * @return {void} - */ -CalendarUtil.newSilentEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pReminder) -{ - if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE; - var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, undefined, pReminder ); - return calendars.insert( [event] , pGroupType ); -} - -/* - * Erzeugt ein neues Aufgaben- / Termin-Objekt (mit einem Link). - * - * @param {date} pType req Augabe oder Termin ( calendars.VTODO, calendars.VEVENT ) - * @param {String} pSummary opt die Zusammenfassung - * @param {String} pDescription opt die Beschreibung - * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable - * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames - * pWithLink[1]: ID des angezeigten Datensatzes - * pWithLink[2]: Verknüpfungstitel - * @param {String} pUser opt der Benutzer ( Login ) - * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( [ Login ] ) - * @param {date} pStart opt Beginn - * @param {date} pDuration opt Dauer - * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) - * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) - * @param {String} pPriority opt Priorität - * @param {String} pReminder opt Erinnerung - * -@return {Object} das EntryObjekt - */ -CalendarUtil.createEntry = function( pType, pSummary, pDescription, pWithLink, pAppLinkContext, pAppLinkId, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder ) -{ - var Entry = {}; - var framename; - var framdata; - var dbid; - var linktitle; - if ( pSummary == undefined || pSummary == null ) pSummary = ""; - if ( pDescription == undefined || pDescription == null ) - { - if(vars.getString("$sys.scope") == "vaadin") - pDescription = neon.getImageContent(vars.getString("$sys.currententityname")); - else - pDescription = swing.getImageContent(); - } - if ( pUser == undefined || pUser == null ) pUser = vars.getString("$sys.user"); - //kein translate.key hier, weil es sich um einen rein technischen Wert handelt: - if ( pStart == undefined ) pStart = datetime.toLong(datetime.toDate(parseInt(vars.getString("$sys.date")) + datetime.ONE_HOUR, "dd.MM.yyyy HH:00"), "dd.MM.yyyy HH:mm"); - if ( pCategory == undefined || pCategory == null ) pCategory = ""; - - if (pAffectedUsers == null || pAffectedUsers == undefined ) - { - Entry[calendars.AFFECTEDUSERS] = ""; - } - else - { - Entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(pAffectedUsers)); - } - Entry[calendars.TYPE] = pType; - Entry[calendars.DTSTART] = pStart; - if ( pType == calendars.VEVENT ) - { - if ( pDuration == undefined ) - pDuration = datetime.ONE_HOUR; - - Entry[calendars.DTEND] = String ( eMath.addInt( pStart, pDuration) ); - - if ( pStatus == undefined ) - pStatus = calendars.STATUS_CONFIRMED; - - pStatus = mapCalendarStatus(pStatus, calendars.getBackendType() ); - } - else if ( pType == calendars.VTODO ) - { - //kein translate.key hier, weil es sich um einen rein technischen Wert handelt: - if ( pDuration != undefined ) - Entry[calendars.DUE] = String ( eMath.addInt( pStart, pDuration) ); - else - Entry[calendars.DUE] = datetime.toLong(datetime.toDate(pStart, "dd.MM.yyyy 23:59") - ,"dd.MM.yyyy HH:mm"); - - if ( pStatus == undefined ) - pStatus = calendars.STATUS_NEEDSACTION; - - pStatus = mapCalendarStatus(pStatus, calendars.getBackendTypeTasks() ); - - } - - Entry[calendars.USER] = calendars.getCalendarUser(pUser); - Entry[calendars.DESCRIPTION] = pDescription; - Entry[calendars.SUMMARY] = pSummary; - Entry[calendars.STATUS] = pStatus; - Entry[calendars.CLASSIFICATION] = calendars.CLASSIFICATION_PUBLIC; - Entry[calendars.CATEGORIES] = pCategory; - Entry[calendars.TRANSPARENCY] = "OPAQUE"; - - - if( pPriority != undefined ) - { - Entry[calendars.PRIORITY] = pPriority; - } - - if( pReminder != undefined) - { - Entry[calendars.HASREMINDER] = "true"; - Entry[calendars.REMINDER_DURATION] = pReminder; - } - else - Entry[calendars.HASREMINDER] = "false"; - - - if (pWithLink == false) - { - Entry[calendars.LINKS] = "0"; - } - else - { - var fd = new FrameData(); - if ( typeof(pWithLink) == "object" ) - { - for ( var li = 0; li < pWithLink.length; li++ ) - { - framename = pWithLink[li][0]; - framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0]; - dbid = pWithLink[li][1]; - linktitle = framdata[2] + " - " + pWithLink[li][2]; - - Entry["LINK_ALIAS_" + ( li + 1 )] = vars.getString("$sys.dbalias"); - Entry["LINK_TABLE_" + ( li + 1 )] = framdata[0]; - Entry["LINK_IDCOLUMN_" + ( li + 1 )] = framdata[1]; - Entry["LINK_DBID_" + ( li + 1 )] = dbid; - Entry["LINK_FRAME_" + ( li + 1 )] = "comp." + framename; - Entry["LINK_TITLE_" + ( li + 1 )] = linktitle; - } - Entry[calendars.LINKS] = pWithLink.length.toString(); - } - else - { - if ( pWithLink == true || pWithLink == undefined ) - { - framename = vars.getString("$sys.currentimagename"); - framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0]; - dbid = vars.getString("$comp.idcolumn"); - linktitle = framdata[2] + " - " + swing.getImageContent(); - } - Entry[calendars.LINKS] = "1"; - Entry["LINK_ALIAS_1"] = vars.getString("$sys.dbalias"); - Entry["LINK_TABLE_1"] = framdata[0]; - Entry["LINK_IDCOLUMN_1"] = framdata[1]; - Entry["LINK_DBID_1"] = dbid; - Entry["LINK_FRAME_1"] = "comp." + framename; - Entry["LINK_TITLE_1"] = linktitle; - } - } - - -if(pAppLinkContext && pAppLinkId) -{ - Entry["AppLinkContext"] = pAppLinkContext; - Entry["AppLinkId"] = pAppLinkId; -} - return Entry; -} - -/* - * Liefert den CalendarStatus übersetzt zurück. - * @param {String} pStatus req Status - * @param {String} pLanguage opt Sprache - * @param {String} pKind opt ToDo oder Event - * - * @return {String} übersetzte Status - */ -function getCalendarStatus( pStatus, pLanguage, pKind) -{ - //kein mappen des Status, da wirklich verschiedene Dinge angezeigt werden sollen - switch ( pStatus ) - { - case calendars.STATUS_BUSY: - return translate.text("Gebucht", pLanguage); - case calendars.STATUS_CANCELLED: - if(pKind == "ToDo" && pKind != undefined) return translate.text("Zurückgestellt", pLanguage) - return translate.text("Abgesagt", pLanguage); - case calendars.STATUS_COMPLETED: - return translate.text("Erledigt", pLanguage); - case calendars.STATUS_CONFIRMED: - return translate.text("Bestätigt", pLanguage); - case calendars.STATUS_FREE: - return translate.text("frei", pLanguage); - case calendars.STATUS_INPROCESS: - return translate.text("In Bearbeitung", pLanguage); - case calendars.STATUS_NEEDSACTION: - return translate.text("Nicht begonnen", pLanguage); - case calendars.STATUS_OOF: - return translate.text("Außer Haus", pLanguage); - case calendars.STATUS_TENTATIVE: - return translate.text("Vorläufig", pLanguage); - default: - return ""; - } -} - -/* - * Zu einer übergebenen Priorität wird ihre Bedeutung übersetzt und zurückgegeben. - * - * @param {String} pPriority req Priorität - * @param {String} pLanguage opt Sprache - * - * @return (String) übersetzte Bedeutung einer Priorität - */ -function getCalendarPriority(pPriority, pLanguage) -{ - switch(pPriority) - { - case "9": - return translate.text("niedrig", pLanguage); - break; - case "5": - return translate.text("normal", pLanguage); - break; - case "1": - return translate.text("hoch", pLanguage); - break; - default: - return translate.text("keine", pLanguage); - break; - } -} - -/* - * Liefert zum Objekt verknüpfte Aufgaben aus dem Kalender. - * - * @param {String} pFrame req Name des Frames - * @param {String} pDBID req ID des verknüpften Datensatzes - * @param {String} pAlias opt - * @param {String} pLanguage opt Sprache - * - * @return {[]} mit Aufgaben aus Kalender - */ -function getLinkedToDos (pFrame, pDBID, pAlias, pLanguage ) -{ - if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias"); - var tab = []; - var status = " and STATUS in ('NEEDS-ACTION', 'IN-PROCESS')"; - var exists = []; - var zustaendig = ""; - var today = getDate(vars.getString("$sys.date")); - var filtervalues = ["", "false"]; - if ( vars.exists("$image.FilterValuesT") ) - { - filtervalues = vars.get("$image.FilterValuesT"); - zustaendig = filtervalues[0] - if (filtervalues[1] == "true") status = " and STATUS in ('COMPLETED', 'CANCELLED')"; - } - - var entryids = db.table("select ENTRYID, OWNER from ASYS_CALENDARLINK " - + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." + pFrame + "' " - + "and ENTRYID is not null " - + "and ENTRYTYPE = " + calendars.VTODO + " " - + "and DBID = '" + pDBID + "' " - + status, pAlias); - - for (var i = 0; i < entryids.length; i++) - { - if ( exists.indexOf(entryids[i][0]) == -1) - { - try - { - var entry = calendars.getEntry(entryids[i][0], null, getTitleCalenderUser( entryids[i][1] ), calendars.VTODO); - var entr = new Array; - status = ""; - var user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) - if(user == null) user = entry[calendars.USER2]["cn"]; - else user = user[tools.TITLE] - if ((user == zustaendig || zustaendig == "")) - { - entr[0] = text.encodeMS([entry[calendars.ID], user]); - var due = getDate(entry[calendars.DUE]); - if (due < today ) entr[1] = "-1769402"; - else if (due > today) entr[1] = "-16777216"; else entr[1] = "-16744020"; - entr[2] = "-1"; // Hintergrundfarbe - entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length; - entr[4] = entry[calendars.DUE] - entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo"); - entr[6] = entry[calendars.SUMMARY] - entr[7] = getRealName([entry[calendars.ORGANIZER2]]); - entr[8] = getRealName(entry[calendars.ATTENDEES]); - entr[9] = entry[calendars.DESCRIPTION]; - entr[10] = entry[calendars.PRIORITY]; - tab.push(entr); - exists.push(entryids[i][0]); - } - } - catch (ex) - { - logging.log(ex); - } - } - } - array_mDimSort(tab, 4, false); //Sortierung nach Fälligkeitsdatum - return tab; -} - -/* - * Anzeige des Aufgaben-Filter - * - * @param {Object} pFilter req - * - * @return string Anzeige - */ -function show_filterLinkedToDos(pFilter) -{ - var retstring = ""; - if (pFilter[0] != "") - { - var userp = tools.getUser( pFilter[0] )[tools.PARAMS]; - retstring = translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]; - } - if (pFilter[1] == "true") retstring += ", " + translate.text("erledigt / zurückgestellt"); - - return retstring -} - -/* - * Liefert zum Objekt verknüpfte Events aus dem Kalender. - * - * @param {String} pFrame req Name des Frames - * @param {String} pDBID req ID des verknüpften Datensatzes - * @param {Object} pFilter opt - * @param {String} pAlias opt - * @param {String} pUser opt Benutzer - * - * @return {[]} mit Events aus Kalender - */ -function getLinkedEvents (pFrame, pDBID, pFilter, pAlias, pUser ) -{ - if ( pFilter == "" || pFilter == undefined) - pFilter = reset_filterEvent(); - - var tab = []; - var exists = []; - var conditions = []; - var today = getDate(vars.getString("$sys.date")); - var conditioncount = 0; - var stati = []; - - if ( pFilter.tentative == "true" ) - stati.push(mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() )); - - if ( pFilter.cancelled == "true" ) - stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendType() )); - - if ( pFilter.confirmed == "true" ) - stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )); - - if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS) - stati.push(calendars.STATUS_FREE); - - if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias"); - - var entryids = db.table(["select ENTRYID, OWNER " - + "from ASYS_CALENDARLINK " - + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." - + pFrame + "' and ENTRYID is not null and ENTRYTYPE = " + calendars.VEVENT - + " and DBID = '" + pDBID + "' and DTSTART >= ?", - [ [ String(pFilter.datefrom - datetime.ONE_WEEK), SQLTYPES.DATE ]]], pAlias ); - - /* - * Check for rights before constructing condition otherwise you'll get an error by opening linked Data - */ - var userToRead = [] - if(pUser != undefined) - { - userToRead = getCalendarUsers( calendars.RIGHT_READ_APPOINTMENT, pUser ); - } - else - { - userToRead = calendars.getDisplayCalendarUsers(calendars.RIGHT_READ_APPOINTMENT); - } - var userMap = {}; - for (let i = 0; i < userToRead.length; i++) - { - userMap[userToRead[i][1]] = true; - } - - for ( var i = 0;i < entryids.length; i++) - { - var user = getTitleCalenderUser(entryids[i][1]); - if(userMap[user]) - { - for ( var z = 0; z < stati.length; z++ ) - _addEntryCondition(conditions, String(++conditioncount), - { - TYPE: calendars.VEVENT, - START: pFilter.datefrom, - END: pFilter.dateto, - USER: user, - STATUS: stati[z], - UID: entryids[i][0] - }); - } else continue - } - conditions["COUNT"] = String(conditioncount); - - var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto); - for ( let i = 0; i < entries.length; i++) - { - for (var j = 0; j < entries[i].length; j++) - { - var entry = entries[i][j]; - if( exists.indexOf(entry[calendars.ID]) == -1 && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > 0)) - { - var entr = new Array; - var start = getDate(entry[calendars.DTSTART]); - var end = getDate(entry[calendars.DTEND]); - user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) - if(user == null) user = entry[calendars.USER2]["cn"]; - else user = user[tools.TITLE] - entr[0] = text.encodeMS([entry[calendars.ID], user , entry[calendars.RECURRENCEID]]); - if (end < today) entr[1] = "-6710887" ; - else if (start <= today && end >= today ) entr[1] = "-16744020" ; - else entr[1] = "-16777216"; - entr[2] = "-1" - entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length; - entr[4] = entry[calendars.DTSTART] - entr[5] = entry[calendars.DTEND] - entr[6] = entry[calendars.SUMMARY] - entr[7] = getRealName([entry[calendars.ORGANIZER2]]); - entr[8] = getRealName(entry[calendars.ATTENDEES]); - entr[9] = entry[calendars.DESCRIPTION] - tab.push(entr); - exists.push(entry[calendars.ID]); - } - } - } - array_mDimSort(tab, 4, false); - return tab; -} - -/* - * Liefert Aufgaben aus dem Kalender. - * - * @param {Object} pFilter req - * @param {String} pLanguage opt - * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen - * - * @return {[]} mit allen aufgaben aus dem Kalender - */ -function getTodos( pFilter, pLanguage, pShortForm ) -{ - if ( pFilter == "" ) pFilter = reset_filterToDo(); - var tab = []; - var today = getDate (vars.getString("$sys.date")); - var conditions = []; - var conditioncount = 0; - var user = pFilter.user; - var stati = []; - var status = []; - var exists = []; - var entries = []; - - if ( pFilter.needs_action == "true" ) - { - stati.push(mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() )); - status.push("NEEDS-ACTION"); - } - if ( pFilter.in_process == "true" ) - { - stati.push(mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() )); - status.push("IN-PROCESS"); - } - if ( pFilter.completed == "true" ) - { - stati.push(mapCalendarStatus(calendars.STATUS_COMPLETED, calendars.getBackendTypeTasks() )); - status.push("COMPLETED"); - } - if ( pFilter.cancelled == "true" ) - { - stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendTypeTasks() )); - status.push("CANCELLED"); - } - if (pFilter.delegated == "true" ) - { - var from = [pFilter.datefrom, SQLTYPES.TIMESTAMP]; - var to = [pFilter.dateto, SQLTYPES.TIMESTAMP]; - setAllCalendarGrant(); - user = calendars.getCalendarUser(user); - user = db.table(["select ELEMENTUID, OWNER from ASYS_CALENDARBACKEND where ENTRYTYPE = 2 and OWNER != '" + user + "' and ORGANIZER = '" - + user + "' and STATUS in ('" + status.join("', '") + "') and (( STARTTIME >= ? and STARTTIME <= ?) or " - + "( ENDTIME >= ? and ENDTIME <= ? ) or ( STARTTIME >= ? and ENDTIME <= ? ))", [from, to, from, to, from, to]] ); - - for (let i = 0; i < user.length; i++ ) - { - try - { - entries.push([calendars.getEntry(user[i][0], null, getTitleCalenderUser(user[i][1]), calendars.VTODO)]); - } - catch(err){ - logging.log(err); - } - } - setCalendarGrant(); - } - else - { - if ( typeof( pFilter.user ) != "object" ) user = [user.trim()]; - for (let i = 0; i < user.length; i++ ) - for ( var z = 0; z < stati.length; z++ ) - _addEntryCondition(conditions, ++conditioncount, - { - TYPE: calendars.VTODO, - START: pFilter.datefrom, - END: pFilter.dateto, - USER: user[i], - STATUS: stati[z] - }); - - conditions["COUNT"] = String(conditioncount); - entries = calendars.getEntries(conditions); - } - - for (i = 0; i < entries.length; i++) - { - var entry = entries[i][0]; - user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) - if (user == null) user = entry[calendars.USER2]["cn"]; - else user = user[tools.TITLE] - if ( !(user != vars.getString("$sys.user") && entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) // no privat - && !( pFilter.delegated == "true" && ( isAffectedUser( entry, pFilter.user) || exists.indexOf(entry[calendars.ID]) > -1 ) ) // no duplicate - && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf( pFilter.category ) > -1 ) ) // Filter category - { - var entr = []; - var links = entry[calendars.LINKS]; - var due = entry[calendars.DUE] != "" ? getDate(entry[calendars.DUE]) : ""; - entr[0] = text.encodeMS([entry[calendars.ID], user]); - if (due == today ) entr[1] = "-16744020" ; - else if(due == "") entr[1] = "-13395712"; - else if (due > today ) entr[1] = "-16777216"; - else entr[1] = "-1769402"; - if (entry[calendars.PRIORITY] == "1") entr[2] = "-100"; - entr[3] = entry[calendars.ATTENDEES].length; - entr[4] = entry[calendars.DUE]; - - if (pShortForm) - { - entr[5] = entry[calendars.SUMMARY]; - entr[6] = entry[calendars.DESCRIPTION]; - } - else - { - entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo"); - entr[6] = getCalendarPriority( entry[calendars.PRIORITY], pLanguage); - entr[7] = entry[calendars.SUMMARY]; - entr[8] = getRealName( [ entry[calendars.ORGANIZER2] ] ); - entr[9] = getRealName( entry[calendars.ATTENDEES] ); - if (links == undefined) entr[10] = ""; else entr[10] = links; - entr[11] = entry[calendars.DESCRIPTION]; - entr[12] = entry[calendars.CREATED]; - } - - tab.push(entr); - if ( pFilter.delegated == "true" ) exists.push(entry[calendars.ID]); - } - } - - if (pShortForm) - sortArray(tab, -1, 4, 1, 5); - else - sortArray(tab, -1, 4, 1, 12 ); - - return tab; -} - -/* - * Fügt eine Condition hinzu - * - * @param {[]} pConditions req die Conditions - * @param {Integer} pIndex req Index der Condition - * @param {Object} pValues req - * - * @return {void} - */ -function _addEntryCondition(pConditions, pIndex, pValues) -{ - var params = ["TYPE", "START", "END", "USER", "STATUS", "UID"]; - - for (var i = 0; i < params.length; i++) - if (pValues[params[i]] != undefined) pConditions[params[i] + "_" + pIndex] = pValues[params[i]]; -} -CalendarUtil.addEntryCondition = function(pConditions, pIndex, pValues) -{ - _addEntryCondition(pConditions, pIndex, pValues); -} - -/* - * Liefert Events zu bestimmten Usern/Daten in einem Array. - * - * @param {Object} pFilter req - * @param {String} pLanguage opt - * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen - * - * @return {[]} - * [0] ID - * [1] Vordergrundfarbe - * [2] Hintergrundfarbe - * [3] Start - * [4] Ende - * [5] Betreff - * [6] Inhalt - * [7] User - * [8] Anzahl Verknüpfungen - * [9] Klassifikation (privat/öffentlich) - */ -function getEvents( pFilter, pLanguage, pShortForm ) -{ - if ( pFilter == "" ) pFilter = reset_filterEvent(); - var tab = []; - var conditions = []; - var today = getDate(vars.getString("$sys.date")); - var conditioncount = 0; - var stati = []; - var user = undefined; - if ( pFilter.tentative == "true" ) stati.push(calendars.STATUS_TENTATIVE); - if ( pFilter.cancelled == "true" ) stati.push(calendars.STATUS_CANCELLED); - if ( pFilter.confirmed == "true" ) - stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )); - - if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true") - stati.push(calendars.STATUS_FREE); - - if ( pFilter.user != "" ) user = (pFilter.user).trim(); - - for ( var z = 0; z < stati.length; z++ ) - _addEntryCondition(conditions, String(++conditioncount), - { - TYPE: calendars.VEVENT, - START: pFilter.datefrom, - END: pFilter.dateto, - USER: user, - STATUS: stati[z] - }); - - conditions["COUNT"] = String(conditioncount); - - var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto); - for ( var i = 0;i < entries.length; i++) - { - for (var j = 0; j < entries[i].length; j++) - { - var entry = entries[i][j]; - if( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > -1 ) - { - var entr = new Array; - var start = getDate(entry[calendars.DTSTART]); - var end = getDate(entry[calendars.DTEND]); - - user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) - if(user == null) user = entry[calendars.USER2]["cn"]; - else user = user[tools.TITLE] - entr[0] = text.encodeMS([ entry[calendars.ID], user, entry[calendars.RECURRENCEID]]); - if (end < today ) entr[1] ="-6710887" ; - else if (start > today) entr[1] = "-16777216"; - else entr[1] = "-16744020" ; - entr[2] = "-1" - entr[3] = entry[calendars.ATTENDEES].length; - entr[4] = entry[calendars.DTSTART]; - entr[5] = entry[calendars.DTEND]; - entr[6] = entry[calendars.SUMMARY]; - - if (!pShortForm) - { - entr[7] = getRealName([entry[calendars.ORGANIZER2]]); - entr[8] = getRealName(entry[calendars.ATTENDEES]); - entr[9] = getCalendarStatus( entry[calendars.STATUS], pLanguage ); - if (entry[calendars.LINKS] == undefined) entr[10] = ""; - else entr[10] = entry[calendars.LINKS]; - entr[11] = entry[calendars.DESCRIPTION]; - } - tab.push( entr ); - } - } - } - sortArray(tab, -1, 4, 1, 6 ); - return tab; -} - -/* - * Liefert den echten Namen anhand des Logins zurück - * - * @param {Array}[]} pUserMap req pUserMap - * - * @return String - */ -function getRealName(pUserMap) -{ - var resultName = []; - var RealNames = getRealNameObject(pUserMap); - - for ( var realname in RealNames ) resultName.push(RealNames[realname]); - return resultName.join(", \n"); -} - -/* - * Liefert den echten Namen anhand des Logins zurück - * - * @param {Array}[]} pUserMap req pUserMap - * - * @return Object - */ -function getRealNameObject(pUserMap) -{ - var resultObject = {}; - var realname = ""; - - for ( let i = 0; i < pUserMap.length; i++ ) - { - let user = tools.getUserByAttribute(tools.CALENDARID, [pUserMap[i]["paramvalue"].substr("mailto:".length)]) - if ( user != null ) - { - if(vars.exists("$global.firstLastName") && vars.get("$global.firstLastName")) - realname = user[tools.PARAMS][tools.LASTNAME] + " " + user[tools.PARAMS][tools.FIRSTNAME]; - else realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME]; - } - else //Der User existiert nicht im System - { - realname = pUserMap[i]["cn"] + " " + pUserMap[i]["paramvalue"]; - } - resultObject[pUserMap[i]["cn"]] = realname; - } - return resultObject; -} - - -/* - * Gibt an ob der User im Calendarobject vorhanden ist - * - * @param {Object} pEntry req Calendarobject - * @param {String} pUser req Title - * - * @return Object - */ -function isAffectedUser( pEntry, pUser) -{ - var usermap = pEntry[calendars.ATTENDEES]; - - for ( var i = 0; i < usermap.length; i++ ) - if( usermap[i]["cn"] == pUser ) - return true; - return false; -} - -/* - * Liefert das Datum ohne Urzeit zurück - * - * @param {String} datetimeIn req DatumZeit - * - * @return {date} - */ -function getDate( datetimeIn ) -{ - if ( datetimeIn != "") - return datetime.clearTime(datetimeIn); - else return ""; -} - -/* - * Setzt den Aufgaben-Filter - * - * @param {Object} pFilter req - * - * @return {image} - */ -function filterToDo( pFilter ) -{ - var error = true; - var von = pFilter.datefrom; - var bis = pFilter.dateto; - if ( pFilter == "" ) pFilter = reset_filterToDo(); - do - { - vars.set("$local.relation_id", pFilter.user); - vars.set("$local.edt_von", pFilter.datefrom); - vars.set("$local.edt_bis", pFilter.dateto); - vars.set("$local.category", pFilter.category); - vars.set("$local.delegated", pFilter.delegated); - vars.set("$local.needs_action", pFilter.needs_action); - vars.set("$local.in_process", pFilter.in_process); - vars.set("$local.completed", pFilter.completed); - vars.set("$local.cancelled", pFilter.cancelled); - var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_FILTER"); - if( res != null ) - { - pFilter.user = res["DLG_TASK_FILTER.relation_id"]; - pFilter.datefrom = res["DLG_TASK_FILTER.edt_von"]; - pFilter.dateto = res["DLG_TASK_FILTER.edt_bis"]; - pFilter.category = res["DLG_TASK_FILTER.category"]; - pFilter.delegated = res["DLG_TASK_FILTER.delegated"]; - pFilter.needs_action = res["DLG_TASK_FILTER.needs_action"]; - pFilter.in_process = res["DLG_TASK_FILTER.in_process"]; - pFilter.completed = res["DLG_TASK_FILTER.completed"]; - pFilter.cancelled = res["DLG_TASK_FILTER.cancelled"]; - if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; - else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) - } - else - { - pFilter.datefrom = von; - pFilter.dateto = bis; - error = false; - } - } - while ( error ) - return pFilter; -} - -/* - * Setzt den Aufgaben-Filter - * - * @param {Object} pFilter req - * - * @return {image} - */ -function filterToDo_Neon( pFilter ) -{ - var error = true; - var von = pFilter.datefrom; - var bis = pFilter.dateto; - if ( pFilter == "" ) pFilter = reset_filterToDo(); - do - { - var prompts = { - FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"), - RESPONSIBLE: pFilter.user, - DATE_FROM: pFilter.datefrom, - DATE_TO: pFilter.dateto, - CATEGORY_TODO: pFilter.category, - DELEGATED: pFilter.delegated, - NEEDS_ACTION: pFilter.needs_action, - IN_PROCESS: pFilter.in_process, - COMPLETED: pFilter.completed, - CANCELLED: pFilter.cancelled - } - - var buttons = { - "ok" : translate.text("OK"), - "": translate.text("Abbrechen") - }; - var defaultButton = "ok"; - - var res = question.openDialog("DLG_FILTER_TODO_Neon", prompts, buttons, defaultButton); - - if( res.button != null ) - { - pFilter.user = res.RESPONSIBLE; - pFilter.datefrom = res.DATE_FROM; - pFilter.dateto = res.DATE_TO; - pFilter.category = res.CATEGORY_TODO; - pFilter.delegated = res.DELEGATED; - pFilter.needs_action = res.NEEDS_ACTION; - pFilter.in_process = res.IN_PROCESS; - pFilter.completed = res.COMPLETED; - pFilter.cancelled = res.CANCELLED; - if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; - else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) - } - else - { - pFilter.datefrom = von; - pFilter.dateto = bis; - error = false; - } - } - while ( error ) - return pFilter; -} - - -/* - * Anzeige des Aufgaben-Filter - * - * @param {Object} pFilter req - * - * @return string Anzeige - */ -function show_filterToDo(pFilter) -{ - var retstring = ""; - var userp = tools.getUser( pFilter.user )[tools.PARAMS]; - if (pFilter.user != "") retstring = (translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]); - if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy")); - if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy")); - if (pFilter.category != "") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category; - if (pFilter.delegated == "true") retstring += ", " + translate.text("delegiert"); - if (pFilter.needs_action == "true") retstring += ", " + translate.text("Nicht begonnen"); - if (pFilter.in_process == "true") retstring += ", " + translate.text("In Bearbeitung"); - if (pFilter.completed == "true") retstring += ", " + translate.text("Erledigt"); - if (pFilter.cancelled == "true") retstring += ", " + translate.text("Zurückgestellt"); - - return retstring -} - -/* - * Setzt den Aufgaben-Filter zurück - * - * @return {filter} - */ -function reset_filterToDo() -{ - var today = getDate (vars.getString("$sys.date")); - - return pFilter = { - user: vars.getString("$sys.user"), - datefrom: String(eMath.subInt(today, 720 * datetime.ONE_DAY)), - dateto: String(eMath.addInt(eMath.addInt(today, 3 * datetime.ONE_DAY) - ,datetime.ONE_DAY - datetime.ONE_MINUTE)), - category: "", - delegated: "", - needs_action: "true", - in_process: "true", - completed: "", - cancelled: "" - }; -} - -/* - * Setzt den Event-Filter - * - * @param {Object} pFilter req - * - * @return {image} - */ -function filterEvent( pFilter ) -{ - var error = true; - var von = pFilter.datefrom; - var bis = pFilter.dateto; - if ( pFilter == "" ) pFilter = reset_filterEvent(); - do - { - vars.set("$local.relation_id", pFilter.user); - vars.set("$local.edt_von", pFilter.datefrom); - vars.set("$local.edt_bis", pFilter.dateto); - vars.set("$local.category", pFilter.category); - vars.set("$local.tentative", pFilter.tentative); - vars.set("$local.confirmed", pFilter.confirmed); - vars.set("$local.cancelled", pFilter.cancelled); - vars.set("$local.free", pFilter.free); - var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_EVENT_FILTER"); - if( res != null ) - { - pFilter.user = res["DLG_EVENT_FILTER.relation_id"]; - pFilter.datefrom = res["DLG_EVENT_FILTER.edt_von"]; - pFilter.dateto = res["DLG_EVENT_FILTER.edt_bis"]; - pFilter.category = res["DLG_EVENT_FILTER.category"]; - pFilter.tentative = res["DLG_EVENT_FILTER.tentative"]; - pFilter.confirmed = res["DLG_EVENT_FILTER.confirmed"]; - pFilter.cancelled = res["DLG_EVENT_FILTER.cancelled"]; - pFilter.free = res["DLG_EVENT_FILTER.free"]; - if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; - else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) - } - else - { - pFilter.datefrom = von; - pFilter.dateto = bis; - error = false; - } - } - while ( error ) - return pFilter; -} - -/* - * Setzt den Event-Filter - * - * @param {Object} pFilter req - * - * @return {image} - */ -function filterEvent_Neon( pFilter ) -{ - var error = true; - var von = pFilter.datefrom; - var bis = pFilter.dateto; - if ( pFilter == "" ) pFilter = reset_filterEvent(); - do - { - var buttons = { - "ok" : translate.text("OK"), - "": translate.text("Abbrechen") - }; - var defaultButton = "ok"; - - var prompts = { - FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"), - RESPONSIBLE_APPOINTMENT: pFilter.user, - DATE_FROM: pFilter.datefrom, - DATE_TO: pFilter.dateto, - CATEGORY_APPOINTMENT: pFilter.category, - TENTATIVE: pFilter.tentative, - CONFIRMED: pFilter.confirmed, - CANCELLED: pFilter.cancelled - } - var res = question.openDialog("DLG_FILTER_APPOINTMENT_Neon", prompts, buttons, defaultButton); - if( res.button != null ) - { - pFilter.user = res.RESPONSIBLE_APPOINTMENT; - pFilter.datefrom = res.DATE_FROM; - pFilter.dateto = res.DATE_TO; - pFilter.category = res.CATEGORY_APPOINTMENT; - pFilter.tentative = res.TENTATIVE; - pFilter.confirmed = res.CONFIRMED; - pFilter.cancelled = res.CANCELLED; - if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; - else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) - } - else - { - pFilter.datefrom = von; - pFilter.dateto = bis; - error = false; - } - } - while ( error ) - return pFilter; -} - -/* - * Anzeige des Event-Filter - * - * @param {Object} pFilter req - * - * @return string Anzeige - */ -function show_filterEvent(pFilter) -{ - var retstring = ""; - - var userp = tools.getUser( pFilter.user )[tools.PARAMS]; - if (pFilter.user != "") retstring = translate.text("Termine von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]; - if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy")); - if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy")); - if (pFilter.category == "true") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category; - if (pFilter.tentative == "true") retstring += ", " + translate.text("Vorläufig"); - if (pFilter.confirmed == "true") retstring += ", " + translate.text("Bestätigt"); - if (pFilter.cancelled == "true") retstring += ", " + translate.text("Abgesagt"); - - return retstring -} - -/* - * Setzt den Event-Filter zurück - * - * @return {filter} - */ -function reset_filterEvent() -{ - var today = getDate (vars.getString("$sys.date")); - - return pFilter = { - user: vars.getString("$sys.user"), - datefrom: String(today), //nur die Termine ab heute anzeigen, - //die von vor einer Woche sind uninteressant - dateto: String(eMath.addInt(eMath.addInt(today, datetime.ONE_WEEK) - ,datetime.ONE_DAY - datetime.ONE_MINUTE)), - category: "", - tentative: "true", - confirmed: "true", - cancelled: "", - free: "true" - }; -} - -/* - * Setzt den Aufgaben-Filter in Tab Aufgaben - * - * @return {image} - */ -function filterLinkedToDo() -{ - var filtervalues = ["", "false"]; - vars.set("$local.CalenderUser", getCalenderUser( calendars.RIGHT_READ_TASK )); - - //Vorbelegen der Werte, wenn bereits gewählt wurde: - if(vars.exists("$image.FilterValuesT")) - { - filtervalues = vars.get("$image.FilterValuesT"); - vars.set("$local.relation_id", filtervalues[0]); - vars.set("$local.done", filtervalues[1]); - } - - var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_DATE_LINKED_FILTER"); - - if( res != null && res != undefined && res != "") - { - filtervalues[0] = res["DLG_TASK_DATE_LINKED_FILTER.relation_id"]; - filtervalues[1] = res["DLG_TASK_DATE_LINKED_FILTER.done"] - } - vars.set("$image.FilterValuesT", filtervalues ); - - return(filtervalues); -} - -/* - * Setzt den Aufgabe-Filter zurück - * - * @return {image} - */ -function resetfilterLinkedToDo() -{ - var filtervalues = ["", "false"]; - - vars.set("$image.FilterValuesT", filtervalues ); - -} - -/* - * setzt die Kalenderrechte - * - * @return {void} - */ -function setCalendarGrant() -{ - calendars.resetCalendarUser(); - var user_read_todo = []; - var user_write_todo = []; // ["Admin"] - var user_read_event = []; - var user_write_event = []; - var tree = {}; - var data = db.table("select THEMEID, THEME.THEME_ID, LOGIN, STATUS from THEME " - + " left join EMPLOYEE on EMPLOYEE.THEME_ID = THEMEID left join RELATION on RELATION_ID = RELATIONID and STATUS = 1" - +" where KIND = 2"); - for ( let i = 0; i < data.length; i++) - { - if ( tree[data[i][0]] == undefined ) tree[data[i][0]] = { - pid: data[i][1], - isuser: false - }; - if ( data[i][2] != "" && data[i][3] != "" ) tree[data[i][2]] = { - pid: data[i][0], - isuser: true - }; - } - - var user = vars.getString("$sys.user"); - // Lese- und Schreibrechte auf Kalender aus Datentabelle holen - data = db.table("select HASRIGHTFOR, TODO_RIGHTS, EVENT_RIGHTS from AOSYS_CALENDAR_RIGHTS where LOGIN = '" + user + "'"); - for ( var i = 0; i < data.length; i++ ) - if(tree[data[i][0]] != undefined) - tree[data[i][0]].grants = data[i].slice(1); - - for ( login in tree ) - { - if( tree[login].isuser ) - { - var grantstodo = __getGrants( login, 0 ); - var grantsevent = __getGrants( login, 1 ); - if ( grantstodo.length + grantsevent.length > 0 ) - { - if ( grantstodo == "1" || grantstodo == "3") user_read_todo.push(login); - if ( grantstodo == "2" || grantstodo == "3") user_write_todo.push(login); - if ( grantsevent == "1" || grantsevent == "3") user_read_event.push(login); - if ( grantsevent == "2" || grantsevent == "3") user_write_event.push(login); - } - } - } - calendars.setCalendarUser(user_read_todo, calendars.RIGHT_READ_TASK, true, calendars.SORTSTRATEGY_NATURAL ); - calendars.setCalendarUser(user_write_todo, calendars.RIGHT_WRITE_TASK, true, calendars.SORTSTRATEGY_NATURAL ); - calendars.setCalendarUser(user_read_event, calendars.RIGHT_READ_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL ); - calendars.setCalendarUser(user_write_event, calendars.RIGHT_WRITE_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL ); - - //********** Ressourcen in Kalender einfügen ************ - var ressource = tools.getUsersWithRole("PROJECT_Ressource"); - calendars.setCalendarUser( ressource, calendars.RIGHT_READ_APPOINTMENT | calendars.RIGHT_WRITE_APPOINTMENT ); - - //add all users from support-role since support-action-tasks (sp_supportAktionen) generates tasks for all support-role members - //and if you're a member you are allowed to edit these - if (tools.hasRole(user, "PROJECT_Support")) - { - var support = tools.getUsersWithRole("PROJECT_Support"); - calendars.setCalendarUser( support, calendars.RIGHT_WRITE_TASK | calendars.RIGHT_READ_TASK ); - } - - function __getGrants( pKey, pIndex ) - { - var grants = []; - if ( tree[pKey].grants != undefined && tree[pKey].grants[pIndex]) grants = tree[pKey].grants[pIndex]; - else if ( tree[pKey].pid != "" ) grants = __getGrants( tree[pKey].pid, pIndex ); - return grants; - } -} - -/* - * setzt Recht für alle Kalender - * - * @return {void} - */ -function setAllCalendarGrant() -{ - calendars.resetCalendarUser(); - var users = tools.getStoredUsers(); - var calendar_user = []; - for ( var i = 0; i < users.length; i++ ) calendar_user.push( users[i][1] ); - calendars.setCalendarUser(calendar_user, calendars.RIGHT_READ_TASK | calendars.RIGHT_WRITE_TASK, false, calendars.SORTSTRATEGY_NATURAL ); -} - -/* - * gibt die Logins der user, die den übergebenen User als Attribute eingetragen haben, zurück - * - * @param {[]} pUsers req Logins - * @param {String []} pAttrName req AttributeName für Employee - * @param {String []} pFields opt - * - * @return {String []} Logins - */ -function getUsersbyAttr( pUsers, pAttrName, pFields ) -{ - if (typeof(pAttrName) == "string") pAttrName = [pAttrName] - - if ( pFields == undefined ) - { - pFields = ["LOGIN"]; - } - - var sqlstr = "select " + pFields.join(", ") + " from ATTRLINK join ATTR on ATTRLINK.ATTR_ID = ATTRID and OBJECT_ID = 12 " - + "and ATTRNAME in ('" + pAttrName.join("','") + "') " - + " join EMPLOYEE on EMPLOYEEID = ATTRLINK.ROW_ID join RELATION on RELATION_ID = RELATIONID join PERS on PERS_ID = PERSID" - + " where VALUE_ID in (select EMPLOYEEID from EMPLOYEE where LOGIN in ('" + pUsers.join("','") + "'))" - + ""; - - if(pFields.length == 1) - return db.array(db.COLUMN, sqlstr); - else - return db.table(sqlstr); -} - -/* - * Gibt die Anzahl der verknüpften Aufgaben und Termine zurück. - * - * @param {String} pID req - * @param {String} pFrame req - * - * @return {String} text - */ -function countLinkedTodoEvent(pID, pFrame) -{ - var today = getDate (vars.getString("$sys.date")); - var datefrom = String(today); - var dateto = String(eMath.addInt(today, datetime.ONE_WEEK)); - - var str = "select count(distinct ELEMENTUID) from ASYS_CALENDARLINK join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID " - + " where FRAME = 'comp." + pFrame + "' and ELEMENTUID is not null and DBID = '" + pID + "'"; - var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO + " and STATUS in ('" - + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '" - + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')"); - - var eventStatusList = [ - mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ) - ,mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() ) - ]; - - if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS) - eventStatusList.push(calendars.STATUS_FREE); - - var retevent = db.cell([str + " and ENTRYTYPE = " + calendars.VEVENT + " and STATUS in ('" + eventStatusList.join("', '") + "')" - + " and DTSTART >= ? and DTEND <= ?", - [ [ String(datefrom), SQLTYPES.DATE ], [String(dateto), SQLTYPES.DATE ] ]]); - - result.string(translate.withArguments("&Aufg / Term (%0/%1)", [rettask, retevent])); -} - -/* - * Gibt die Anzahl der verknüpften Aufgaben zurück. - * - * @param {String} pID req - * @param {String} pFrame req - * - * @return {String} text - */ -function countLinkedTodo(pID, pFrame) -{ - var str = "select count(distinct ELEMENTUID) " - + "from ASYS_CALENDARLINK " - + "join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID " - + " where FRAME = 'comp." + pFrame + "' " - + "and ELEMENTUID is not null and DBID = '" + pID + "'"; - - var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO - + " and STATUS in ('" - + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '" - + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')" - + ""); - - result.string(translate.withArguments("&Aufgaben (%0)", [rettask])); -} - -/* - * Gibt die Überschneidungen von Termine zurück. - * - * @param {Date} pStart req - * @param {Date} pEnd req - * @param {Array} pUsers req - * - * @return {String Array} Termine - */ -function getOverlappingEvents(pStart, pEnd, pUsers ) -{ - var resultEvents = new Array(); - var users = pUsers; - if (calendars.getBackendType() == calendars.BACKEND_DB && pStart != "" && pEnd != "" && users.length > 0) - { - calendars.clearCache(); - for (var u = 0; u < users.length; u++) - { - var localuid = vars.get("$image.entry")[calendars.ID] - var condition = new Array(); - condition["COUNT"] = "1"; - condition["TYPE_1"] = calendars.VFREEBUSY; - condition["USER_1"] = users[u][0]; - condition["START_1"] = pStart; - condition["END_1"] = pEnd; - - var fbsall = calendars.getEntries(condition); - for (var j = 0; j < fbsall.length; j++) - { - var fbs = fbsall[j]; - for (var i = 0; i < fbs.length; i++) - { - var next = fbs[i]; - var uid = next[calendars.ID]; - var sum = next[calendars.SUMMARY]; - if (uid != localuid) - { - var freebusy = next[calendars.FREEBUSY]; - var freebusyDec = text.decodeMS(freebusy); - var match = false; - for (var k = 0; k < freebusyDec.length; k++) - { - var freebusyInstance = text.decodeMS(freebusyDec[k]); - if (!freebusyInstance[0].equals("FREE")) - { - match = true; - } - } - if (match) resultEvents.push([users[u][2], sum != null && sum.length > 0 ? sum : "?", uid]); - } - } - } - } - } - return resultEvents; -} - -/* - * Überprüft den Eintrag, wenn eine neue Aufgaben angelegt wird darauf, ob private Aufgaben für andere erstellt werden - * - * @param {String[]} pUser die Liste der User, denen die Aufgabe zugewiesen werden soll - * @param {String} pClassification die Klassifizierung der Aufgabe - "PRIVATE" - * - * @return {Boolean} ob der Eintrag in der Konstellation möglich ist, wenn nicht wird eine Meldung ausgegeben - */ -function checkEntry(pUser, pClassification ) -{ - if( pClassification == "PRIVATE" && - ( pUser.length > 1 || text.decodeMS(pUser[0][0])[1] != "CN:" + vars.getString("$sys.user"))) - { - question.showMessage(translate.text("Eine private Aufgabe kann nicht jemand anderem zugewiesen werden.")); - return false; - } - else - { - return true; - } -} - -/* - * Verschiebt ein Calendareintrag - * - * @param {String[]} pIDs req die zu verschiebenden Ids mit den Calenderinformationen (Multistring) - * @param {String} pTblCompName opt die Komponente die aktualisiert werden soll - * - * @return {void} - */ -function shiftEntry(pIDs, pTblCompName) -{ - var datenew = swing.askUserQuestion(translate.text("Verschieben auf Datum?"), "DLG_DATE"); - if (datenew != null ) - { - var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK); - var usermap = {}; - var granted = true; - for (let i = 0; i < grantedUsers.length; i++) - { - usermap[grantedUsers[i][1]] = true; - } - - datenew = datetime.clearTime(datenew["DLG_DATE.Edit_date"]); - if (datenew <= vars.getString("$sys.today")) - question.showMessage(translate.text("nur Verschiebung in die Zukunft erlaubt!")); - else - { - for (var i = 0, j = pIDs.length; i < j; i++) - { - var id = text.decodeMS(pIDs[i]); - var entry = calendars.getEntry(id[0], null, id [1], calendars.VTODO); - var affectedUsers = entry[calendars.ATTENDEES]; - - granted = hasGrantForEntryByObject(affectedUsers, usermap); - if(granted) - { - //Zeitdifferenz von Aufgabenstart und -ende - var dateDiff = eMath.subInt(entry[calendars.DUE], entry[calendars.DTSTART]); - - //Startzeit der Aufgabe - var startTime = eMath.subInt(entry[calendars.DTSTART] - , datetime.clearTime(entry[calendars.DTSTART])); - - entry[calendars.DTSTART] = eMath.addInt(datenew, startTime); - entry[calendars.DUE] = eMath.addInt(entry[calendars.DTSTART], dateDiff); - calendars.update( [ entry ] ); - } - else - question.showMessage(translate.text("Keine Berechtigung zum Verschieben der Aufgabe")); - } - } - } -} - -/* - * Gibt eine Aufgabe weiter - * - * @param {String} pIDs die ID der Aufgabe, welche weitergegeben werden soll - * @param {String} pTblCompName die Komponente der Aufgaben, die aktualisiert werden soll - * - * @return {void} - */ -function handOverToDo(pIDs, pTblCompName) -{ - var calendar_user = ""; - var users = getCalenderUser( calendars.RIGHT_WRITE_TASK ); - var publicCount = 0; - var privateCount = 0; - var notGrantedCount = 0; - - var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK); - var userMap = {}; - var granted = true; - for (let i = 0; i < grantedUsers.length; i++) - { - userMap[grantedUsers[i][1]] = true; - } - - if (pIDs.length == 1) // only one todo and private - { - var id = text.decodeMS( pIDs[0] ); - var entry = calendars.getEntry( id[0], null, id[1] ); - if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) - { - question.showMessage(translate.text("Kein Weitergeben von privaten Aufgaben möglich!")); - return; - } - } - - for ( let i = 0; i < users.length; i++) if (pIDs.length > 0 || users[i][0] != id[1]) calendar_user += "|" + users[i][1]; - var selection = swing.askQuestion(translate.text("Benutzer auswählen"), swing.QUESTION_COMBOBOX, calendar_user); - if (selection != null) - { - for ( let i = 0; i < users.length; i++) - { - if ( selection == users[i][1] ) - { - selection = users[i]; - break; - } - } - for( let i = 0; i < pIDs.length; i++) - { - let id = text.decodeMS( pIDs[i] ); - let entry = calendars.getEntry( id[0], null, id[1] ); - if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) privateCount++; - else //Nur öffentliche Aufgabe kann weiter gegeben werden. - { - // User austauschen - var usermap = entry[calendars.ATTENDEES]; - var affectedusers = []; - - granted = hasGrantForEntryByObject(usermap, userMap); - - for (var ui = 0; ui < usermap.length; ui++) - { - var login_cn = usermap[ui]["cn"]; - var user = tools.getUserByAttribute(tools.CALENDARID, usermap[ui]["paramvalue"].substr("mailto:".length)) - if (user == null) user = login_cn; - else user = user[tools.TITLE] - - if ( user == id[1] ) affectedusers.push(selection[0]); - else if ( user != selection[0] ) affectedusers.push(user); - } - if(granted) - { - entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(affectedusers)); - calendars.update([entry]); - publicCount++; - } - else notGrantedCount++ - } - } - question.showMessage(translate.withArguments("%0 Aufgabe(n) erfolgreich weitergegeben an: %1" - + (privateCount == 0 ? "" : "\n%2 private Aufgabe(n) können nicht weitergegeben werden.") - +(notGrantedCount == 0 ? "" : "\n%3 Aufgabe(n) können aufgrund fehlender Berechtigung nicht weitergegeben werden."), - [publicCount, selection[1], privateCount, notGrantedCount])); - - } -} - -// ToDo prüfen !! -/* - * Verschiebt die Kalendereinträge bei Login-Änderung - * - * @param {String} pNewlogin req - * @param {String} pOldlogin req - * @param {String} pNewCalendarID req - * @param {String} pOldCalendarID req - * - * @return {void} - */ -function moveCalendarData ( pNewlogin, pOldlogin, pNewCalendarID, pOldCalendarID ) -{ - var newcaluser = text.encodeMS(["mailto:" + pNewCalendarID, "CN:" + pNewlogin]); - var oldcaluser = text.encodeMS(["mailto:" + pOldCalendarID, "CN:" + pOldlogin]); - db.runStatement("update ASYS_CALENDARBACKEND set OWNER = '" + newcaluser + "' where OWNER = '" + oldcaluser + "'"); - db.runStatement("update ASYS_CALENDARBACKEND set ORGANIZER = '" + newcaluser + "' where ORGANIZER = '" + oldcaluser + "'"); - - if(pNewCalendarID != pOldCalendarID) //Nur wenn sich die E-Mailadresse geändert hat - { - //Messenger-Historien - db.runStatement("update ASYS_XMPP_HISTORY set JID_FROM = '" + pNewCalendarID +"' where JID_FROM = '" + pOldCalendarID +"'", "_____SYSTEMALIAS"); - db.runStatement("update ASYS_XMPP_HISTORY set JID_TO = '" + pNewCalendarID +"' where JID_TO = '" + pOldCalendarID +"'", "_____SYSTEMALIAS"); - } -} - -/* - * Löst den CalenderUser in lesbarer From auf - * - * @param {String} pValue req - * - * @return {String} übersetzten Wert - */ -function getCalUser( pValue ) -{ - var realname = pValue; - var user = tools.getUser( text.decodeMS(pValue)[1].split(":")[1] ); - if ( user != null ) - { - realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME]; - } - return realname; -} - -/* - * Gibt den Login eines CalenderUser zurück - * - * @param {String} pCalendarUser req - * - * @return {String} Title - */ -function getTitleCalenderUser( pCalendarUser ) -{ - var data = text.decodeMS(pCalendarUser) - for ( var i = 0; i < data.length; i++ ) - { - //if login changes we have to check calendarid - if ( data[i].substr(0, "mailto:".length).toUpperCase() == "MAILTO:" ) - { - var user = tools.getUserByAttribute(tools.CALENDARID, [data[i].substr("mailto:".length)]); - if (user != null ) - return user[tools.TITLE]; - } - - if ( data[i].substr(0, 3).toUpperCase() == "CN:" ) - return data[i].substr(3); - } - return ""; -} - - -/* - * Gibt den richtigen Status zum Prüfen je nach Backend zurück - * - * - * @param {String} pStatus req die konstante für den zu prüfenden status, - * z.B. calendars.STATUS_INPROCESS - * - * @param {String} pCalendarType req die konstante für den typen des Termin- oder Aufgabenbackends, - * z.B. calendars.BACKEND_DB - * - * @return {String} Konstanten für den Kalender (Backend-Typen), gibt es den status im backend nicht - * wird null geliefert - */ -function mapCalendarStatus(pStatus, pCalendarType) -{ - switch (pCalendarType) - { - //case calendars.BACKEND_EXCHANGE: - case calendars.BACKEND_EXCHANGEWS: - if (pStatus == calendars.STATUS_CONFIRMED) - return calendars.STATUS_BUSY; - else - return pStatus; - default: - if (pStatus == calendars.STATUS_OOF)//nur bei exchange - return null; - else - return pStatus; - } -} - -/* - * Sets the imagevariable with affectedusers - * - * @param {Object} pEntry req the Entry of Tasks or Appointments - * - * @return {void} - * - */ -function setAffectedUsersImage(pEntry) -{ - var affectedUsers = []; - var usermap = pEntry[calendars.ATTENDEES]; - var realnames = getRealNameObject(usermap); - - for ( var i = 0; i < usermap.length; i++ ) - { - affectedUsers.push([ text.encodeMS( [usermap[i]["paramvalue"], "CN:" + usermap[i]["cn"]] ), realnames[usermap[i]["cn"]] ]); - } - - vars.set("$image.affectedusers", affectedUsers); - return affectedUsers; -} - -/* - * Opens calendar links - * - * @param {String} pEntryID req the ID of the link - * - * @return {void} - * - */ -function openCalendarLinks(pEntryID) -{ - var openFramesObj = {}; - if (typeof(pEntryID) == "object") - openFramesObj = pEntryID; - else - { - var links = db.table("SELECT FRAME, DBIDCOLUMN, DBID FROM ASYS_CALENDARLINK WHERE ENTRYID = '" + pEntryID + "'"); - for (var i = 0; i < links.length; i++) - { - var frame = links[i][0].substr( 5 );//remove comp. so the frame can be opened with openFrame - if ( openFramesObj[frame] == undefined ) openFramesObj[frame] = { - IDField: links[i][1], - IDs: [] - }; - openFramesObj[frame].IDs.push(links[i][2]); - } - } - - for ( frame in openFramesObj) - { - var condition = openFramesObj[frame].IDField + " in ('" + openFramesObj[frame].IDs.join("', '") + "')"; - var framemode = openFramesObj[frame].IDs.length > 1 ? swing.FRAMEMODE_TABLE_SELECTION : swing.FRAMEMODE_SHOW; - - if ( vars.getString("$global.upwardLink") == "link") - { - swing.openLinkedFrame(frame, condition, swing.WINDOW_CURRENT, framemode, "", null, false, { - autoclose: true - } ); - } - else - { - swing.openFrame(frame, condition, swing.WINDOW_CURRENT, framemode, null, false); - } - } -} - -/** - * Returns the "real" calendar system/backend type (BackendType & SyncBackendType) - * - * @param {Number} pScope - The needed scope (e.g. "calendars.VEVENT", "calendars.VTODO") - * @return {Number} - The backend type (calendars.BACKEND_*) - */ -function getCalendarSystemType (pScope) -{ - // Check sync backend type - if (calendars.getSyncBackendType() != calendars.BACKEND_NONE && calendars.getSyncBackendType() != 3) - { - var scope = calendars.getSyncBackendTypeScope(); - if (scope.length == 1 && scope[0] == pScope) // Scope.length = 1 -> VEVENT *OR* VTODO - return calendars.getSyncBackendType(); - else if (scope.length == 2) // Scope.length = 2 -> Both - return calendars.getSyncBackendType(); - // Scope.length = 0 -> Nothing selected -> Skip this block - } - - // Fallback to backend type (event) - if (calendars.getBackendType() != calendars.BACKEND_NONE && pScope === calendars.VEVENT) - return calendars.getBackendType(); - - // Second fallback to backend type (todo) - if (calendars.getBackendTypeTasks() != calendars.BACKEND_NONE && pScope === calendars.VTODO) - return calendars.getBackendTypeTasks(); - - // Everything is none - return calendars.BACKEND_NONE; -} - -function hasGrantForEntryByMS(pAffectedUsers, pUserMap) -{ - for (let i = 0; i < pAffectedUsers.length; i++) - { - var calUser = getTitleCalenderUser( pAffectedUsers[i][0]); - if(pUserMap[calUser] == undefined) - { - return false; - break; - } - else - return true; - } -} - -function hasGrantForEntryByObject(pAffectedUsers, pUserMap) -{ - for (let i = 0; i < pAffectedUsers.length; i++) - { - calUser = tools.getUserByAttribute(tools.CALENDARID, pAffectedUsers[i]["paramvalue"].substr("mailto:".length)) - if (calUser == null) calUser = pAffectedUsers[i]["cn"]; - else calUser = calUser[tools.TITLE] - if(pUserMap[calUser] == undefined) - { - return false; - break; - } - else - return true; - } -} +import("system.neon"); +import("system.vars"); +import("system.db"); +import("system.translate"); +import("system.datetime"); +import("system.swing"); +import("system.eMath"); +import("system.calendars"); +import("system.logging"); +import("system.tools"); +import("system.text"); +import("system.question"); +import("system.SQLTYPES"); +import("system.result"); +import("Util_lib"); +import("system.util") + + +/** + * @class + **/ +function CalendarUtil(){} + + +/* + * Erzeugt und öffnet ein neues Aufgabenobjekt (mit einem Link). + * + * @param {String} pSummary opt die Zusammenfassung + * @param {String} pDescription opt die Beschreibung + * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable + * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames + * pWithLink[1]: ID des angezeigten Datensatzes + * pWithLink[2]: Verknüpfungstitel + * @param {String} pUser opt der Benutzer ( Login ) + * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) + * @param {date} pStart opt Beginn der Aufgabe + * @param {date} pDuration opt Dauer + * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) + * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) + * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten + * + * @return {void} + */ +CalendarUtil.newTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh) +{ + var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus ); + var prompts = []; + prompts["comp4refresh"] = []; + + if (pComps4Refresh == undefined) + pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Aufgabe"]; + + for (var i = 0; i < pComps4Refresh.length; i++) + { + if ( vars.exists(pComps4Refresh[i])) prompts["comp4refresh"].push(pComps4Refresh[i]); + } + if(vars.getString("$sys.scope") == "vaadin") + neon.openCalendarEntry([todo], null, neon.OPERATINGSTATE_NEW, null) + else + { + if (vars.exists("$sys.currentwindow")) + prompts["window"] = vars.getString("$sys.currentwindow"); + if (vars.exists("$sys.currentimage")) + prompts["image"] = vars.getString("$sys.currentimage"); + + swing.openCalendarEntry([todo], null, false, prompts); + } +} + + +/** + * Finds the effective calendarId of an user in the same attribute order like the ADITO core, which is exchangeEmail -> calendarID -> email + * DO NOT CHANGE THIS ORDER + * + * @param {String} user to check + * @return effective calendar id + */ +CalendarUtil.getEffectiveCalendarIdFromUser = function(pUser) +{ + var userParams = pUser["params"]; + + var resolvedCurrentUser; + var exchangeEmail = userParams["exchangeEMail"]; + var calendarId = userParams["calendarID"]; + var email = userParams["email"]; + + if(exchangeEmail) + return exhangeEmail; + else if(calendarId) + return calendarId; + else if(email) + return email; + else + return ""; +} + +/* + * Erzeugt eine neue Aufgabe (mit einem Link). + * + * @param {String} pSummary opt die Zusammenfassung + * @param {String} pDescription opt die Beschreibung + * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable + * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames + * pWithLink[1]: ID des angezeigten Datensatzes + * pWithLink[2]: Verknüpfungstitel + * @param {String} pUser opt der Benutzer ( Login ) + * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) + * @param {date} pStart opt Beginn der Aufagebe + * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI ) + * @param {date} pDuration opt Dauer + * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) + * @param {String} pStatus opt Status der Aufgabe ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) + * @param {String} pPriority opt Priorität der Aufgabe + * @param {String} pReminder opt Erinnerung der Aufgabe + * + * @return {void} + */ + +CalendarUtil.newSilentTodo = function(pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pPriority, pReminder) +{ + if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE; + var todo = createEntry( calendars.VTODO, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder ); + + return calendars.insert([todo],calendars.GROUP_SINGLE); +} + +/* + * Erzeugt und öffnet ein neues Terminnobjekt mit einem Link. + * + * @param {String} pSummary opt die Zusammenfassung + * @param {String} pDescription opt die Beschreibung + * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable + * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames + * pWithLink[1]: ID des angezeigten Datensatzes + * pWithLink[2]: Verknüpfungstitel + * @param {String} pUser opt der Benutzer ( Login ) + * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) + * @param {date} pStart opt Beginn der Aufagebe + * @param {date} pDuration opt Dauer + * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) + * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) + * @param {Array{[]} pComps4Refresh opt die zu aktualisierenden Komponenten + * + * @return {void} + */ +CalendarUtil.newEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pComps4Refresh, pWorklistId) +{ + var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus ); + + var prompts = []; + prompts["comp4refresh"] = []; + if (pComps4Refresh == undefined) + pComps4Refresh = ["$comp.Aufgabe", "$comp.tbl_Termine"]; + for (i = 0; i < pComps4Refresh.length; i++) + { + if ( vars.exists(pComps4Refresh[i])) prompts["comp4refresh"].push(pComps4Refresh[i]); + } + + if(vars.getString("$sys.scope") == "vaadin") + neon.openCalendarEntry([event],"", neon.OPERATINGSTATE_NEW, null) + else + { + prompts["window"] = vars.getString("$sys.currentwindow"); + prompts["image"] = vars.getString("$sys.currentimage"); + if (pWorklistId != undefined) + prompts["worklistId"] = pWorklistId; + swing.openCalendarEntry([event], null, false, prompts); + } +} + + +/* + * Erzeugt einen neuen Termineintrag (mit einem Link). + * + * @param {String} pSummary opt die Zusammenfassung + * @param {String} pDescription opt die Beschreibung + * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable + * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames + * pWithLink[1]: ID des angezeigten Datensatzes + * pWithLink[2]: Verknüpfungstitel + * @param {String} pUser opt der Benutzer ( Login ) + * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( Login ) + * @param {date} pStart opt Beginn des Termins + * @param {date} pDuration opt Dauer + * @param {integer} pGroupType opt ( calendars.GROUP_SINGLE , calendars.GROUP_MULTI ) + * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) + * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) + * @param {String} pReminder opt Erinnerung des Termins + * + * @return {void} + */ +CalendarUtil.newSilentEvent = function( pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pGroupType, pCategory, pStatus, pReminder) +{ + if ( pGroupType == undefined ) pGroupType = calendars.GROUP_SINGLE; + var event = createEntry( calendars.VEVENT, pSummary, pDescription, pWithLink, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, undefined, pReminder ); + return calendars.insert( [event] , pGroupType ); +} + +/* + * Erzeugt ein neues Aufgaben- / Termin-Objekt (mit einem Link). + * + * @param {date} pType req Augabe oder Termin ( calendars.VTODO, calendars.VEVENT ) + * @param {String} pSummary opt die Zusammenfassung + * @param {String} pDescription opt die Beschreibung + * @param {Boolean} pWithLink opt TRUE legt eine Verknüpfung zu $image.frametable + * @param {String[][]} pWithLink opt pWithLink[0]: Name des Frames + * pWithLink[1]: ID des angezeigten Datensatzes + * pWithLink[2]: Verknüpfungstitel + * @param {String} pUser opt der Benutzer ( Login ) + * @param {[]} pAffectedUsers opt die betroffenen Benutzer ( [ Login ] ) + * @param {date} pStart opt Beginn + * @param {date} pDuration opt Dauer + * @param {integer} pCategory opt ( calendars.CATEGORIES , encoded(String) z.B.: text.encodeMS(["Service"]) ) + * @param {String} pStatus opt Status des Termins ( calendars.STATUS_TENTATIVE, calendars.STATUS_CONFIRMED, calendars.STATUS_CANCELLED ) + * @param {String} pPriority opt Priorität + * @param {String} pReminder opt Erinnerung + * +@return {Object} das EntryObjekt + */ +CalendarUtil.createEntry = function( pType, pSummary, pDescription, pWithLink, pAppLinkContext, pAppLinkId, pUser, pAffectedUsers, pStart, pDuration, pCategory, pStatus, pPriority, pReminder ) +{ + var Entry = {}; + var framename; + var framdata; + var dbid; + var linktitle; + if ( pSummary == undefined || pSummary == null ) pSummary = ""; + if ( pDescription == undefined || pDescription == null ) + { + if(vars.getString("$sys.scope") == "vaadin") + pDescription = neon.getImageContent(vars.getString("$sys.currententityname")); + else + pDescription = swing.getImageContent(); + } + if ( pUser == undefined || pUser == null ) pUser = vars.getString("$sys.user"); + //kein translate.key hier, weil es sich um einen rein technischen Wert handelt: + if ( pStart == undefined ) pStart = datetime.toLong(datetime.toDate(parseInt(vars.getString("$sys.date")) + datetime.ONE_HOUR, "dd.MM.yyyy HH:00"), "dd.MM.yyyy HH:mm"); + if ( pCategory == undefined || pCategory == null ) pCategory = ""; + + if (pAffectedUsers == null || pAffectedUsers == undefined ) + { + Entry[calendars.AFFECTEDUSERS] = ""; + } + else + { + Entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(pAffectedUsers)); + } + Entry[calendars.TYPE] = pType; + Entry[calendars.DTSTART] = pStart; + if ( pType == calendars.VEVENT ) + { + if ( pDuration == undefined ) + pDuration = datetime.ONE_HOUR; + + Entry[calendars.DTEND] = String ( eMath.addInt( pStart, pDuration) ); + + if ( pStatus == undefined ) + pStatus = calendars.STATUS_CONFIRMED; + + pStatus = mapCalendarStatus(pStatus, calendars.getBackendType() ); + } + else if ( pType == calendars.VTODO ) + { + //kein translate.key hier, weil es sich um einen rein technischen Wert handelt: + if ( pDuration != undefined ) + Entry[calendars.DUE] = String ( eMath.addInt( pStart, pDuration) ); + else + Entry[calendars.DUE] = datetime.toLong(datetime.toDate(pStart, "dd.MM.yyyy 23:59") + ,"dd.MM.yyyy HH:mm"); + + if ( pStatus == undefined ) + pStatus = calendars.STATUS_NEEDSACTION; + + pStatus = mapCalendarStatus(pStatus, calendars.getBackendTypeTasks() ); + + } + + Entry[calendars.USER] = calendars.getCalendarUser(pUser); + Entry[calendars.DESCRIPTION] = pDescription; + Entry[calendars.SUMMARY] = pSummary; + Entry[calendars.STATUS] = pStatus; + Entry[calendars.CLASSIFICATION] = calendars.CLASSIFICATION_PUBLIC; + Entry[calendars.CATEGORIES] = pCategory; + Entry[calendars.TRANSPARENCY] = "OPAQUE"; + + + if( pPriority != undefined ) + { + Entry[calendars.PRIORITY] = pPriority; + } + + if( pReminder != undefined) + { + Entry[calendars.HASREMINDER] = "true"; + Entry[calendars.REMINDER_DURATION] = pReminder; + } + else + Entry[calendars.HASREMINDER] = "false"; + + + if (pWithLink == false) + { + Entry[calendars.LINKS] = "0"; + } + else + { + var fd = new FrameData(); + if ( typeof(pWithLink) == "object" ) + { + for ( var li = 0; li < pWithLink.length; li++ ) + { + framename = pWithLink[li][0]; + framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0]; + dbid = pWithLink[li][1]; + linktitle = framdata[2] + " - " + pWithLink[li][2]; + + Entry["LINK_ALIAS_" + ( li + 1 )] = vars.getString("$sys.dbalias"); + Entry["LINK_TABLE_" + ( li + 1 )] = framdata[0]; + Entry["LINK_IDCOLUMN_" + ( li + 1 )] = framdata[1]; + Entry["LINK_DBID_" + ( li + 1 )] = dbid; + Entry["LINK_FRAME_" + ( li + 1 )] = "comp." + framename; + Entry["LINK_TITLE_" + ( li + 1 )] = linktitle; + } + Entry[calendars.LINKS] = pWithLink.length.toString(); + } + else + { + if ( pWithLink == true || pWithLink == undefined ) + { + framename = vars.getString("$sys.currentimagename"); + framdata = fd.getData("name", framename, ["table","idcolumn","title"])[0]; + dbid = vars.getString("$comp.idcolumn"); + linktitle = framdata[2] + " - " + swing.getImageContent(); + } + Entry[calendars.LINKS] = "1"; + Entry["LINK_ALIAS_1"] = vars.getString("$sys.dbalias"); + Entry["LINK_TABLE_1"] = framdata[0]; + Entry["LINK_IDCOLUMN_1"] = framdata[1]; + Entry["LINK_DBID_1"] = dbid; + Entry["LINK_FRAME_1"] = "comp." + framename; + Entry["LINK_TITLE_1"] = linktitle; + } + } + + +if(pAppLinkContext && pAppLinkId) +{ + Entry["AppLinkContext"] = pAppLinkContext; + Entry["AppLinkId"] = pAppLinkId; +} + return Entry; +} + +/* + * Liefert den CalendarStatus übersetzt zurück. + * @param {String} pStatus req Status + * @param {String} pLanguage opt Sprache + * @param {String} pKind opt ToDo oder Event + * + * @return {String} übersetzte Status + */ +function getCalendarStatus( pStatus, pLanguage, pKind) +{ + //kein mappen des Status, da wirklich verschiedene Dinge angezeigt werden sollen + switch ( pStatus ) + { + case calendars.STATUS_BUSY: + return translate.text("Gebucht", pLanguage); + case calendars.STATUS_CANCELLED: + if(pKind == "ToDo" && pKind != undefined) return translate.text("Zurückgestellt", pLanguage) + return translate.text("Abgesagt", pLanguage); + case calendars.STATUS_COMPLETED: + return translate.text("Erledigt", pLanguage); + case calendars.STATUS_CONFIRMED: + return translate.text("Bestätigt", pLanguage); + case calendars.STATUS_FREE: + return translate.text("frei", pLanguage); + case calendars.STATUS_INPROCESS: + return translate.text("In Bearbeitung", pLanguage); + case calendars.STATUS_NEEDSACTION: + return translate.text("Nicht begonnen", pLanguage); + case calendars.STATUS_OOF: + return translate.text("Außer Haus", pLanguage); + case calendars.STATUS_TENTATIVE: + return translate.text("Vorläufig", pLanguage); + default: + return ""; + } +} + +/* + * Zu einer übergebenen Priorität wird ihre Bedeutung übersetzt und zurückgegeben. + * + * @param {String} pPriority req Priorität + * @param {String} pLanguage opt Sprache + * + * @return (String) übersetzte Bedeutung einer Priorität + */ +function getCalendarPriority(pPriority, pLanguage) +{ + switch(pPriority) + { + case "9": + return translate.text("niedrig", pLanguage); + break; + case "5": + return translate.text("normal", pLanguage); + break; + case "1": + return translate.text("hoch", pLanguage); + break; + default: + return translate.text("keine", pLanguage); + break; + } +} + +/* + * Liefert zum Objekt verknüpfte Aufgaben aus dem Kalender. + * + * @param {String} pFrame req Name des Frames + * @param {String} pDBID req ID des verknüpften Datensatzes + * @param {String} pAlias opt + * @param {String} pLanguage opt Sprache + * + * @return {[]} mit Aufgaben aus Kalender + */ +function getLinkedToDos (pFrame, pDBID, pAlias, pLanguage ) +{ + if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias"); + var tab = []; + var status = " and STATUS in ('NEEDS-ACTION', 'IN-PROCESS')"; + var exists = []; + var zustaendig = ""; + var today = getDate(vars.getString("$sys.date")); + var filtervalues = ["", "false"]; + if ( vars.exists("$image.FilterValuesT") ) + { + filtervalues = vars.get("$image.FilterValuesT"); + zustaendig = filtervalues[0] + if (filtervalues[1] == "true") status = " and STATUS in ('COMPLETED', 'CANCELLED')"; + } + + var entryids = db.table("select ENTRYID, OWNER from ASYS_CALENDARLINK " + + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." + pFrame + "' " + + "and ENTRYID is not null " + + "and ENTRYTYPE = " + calendars.VTODO + " " + + "and DBID = '" + pDBID + "' " + + status, pAlias); + + for (var i = 0; i < entryids.length; i++) + { + if ( exists.indexOf(entryids[i][0]) == -1) + { + try + { + var entry = calendars.getEntry(entryids[i][0], null, getTitleCalenderUser( entryids[i][1] ), calendars.VTODO); + var entr = new Array; + status = ""; + var user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) + if(user == null) user = entry[calendars.USER2]["cn"]; + else user = user[tools.TITLE] + if ((user == zustaendig || zustaendig == "")) + { + entr[0] = text.encodeMS([entry[calendars.ID], user]); + var due = getDate(entry[calendars.DUE]); + if (due < today ) entr[1] = "-1769402"; + else if (due > today) entr[1] = "-16777216"; else entr[1] = "-16744020"; + entr[2] = "-1"; // Hintergrundfarbe + entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length; + entr[4] = entry[calendars.DUE] + entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo"); + entr[6] = entry[calendars.SUMMARY] + entr[7] = getRealName([entry[calendars.ORGANIZER2]]); + entr[8] = getRealName(entry[calendars.ATTENDEES]); + entr[9] = entry[calendars.DESCRIPTION]; + entr[10] = entry[calendars.PRIORITY]; + tab.push(entr); + exists.push(entryids[i][0]); + } + } + catch (ex) + { + logging.log(ex); + } + } + } + array_mDimSort(tab, 4, false); //Sortierung nach Fälligkeitsdatum + return tab; +} + +/* + * Anzeige des Aufgaben-Filter + * + * @param {Object} pFilter req + * + * @return string Anzeige + */ +function show_filterLinkedToDos(pFilter) +{ + var retstring = ""; + if (pFilter[0] != "") + { + var userp = tools.getUser( pFilter[0] )[tools.PARAMS]; + retstring = translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]; + } + if (pFilter[1] == "true") retstring += ", " + translate.text("erledigt / zurückgestellt"); + + return retstring +} + +/* + * Liefert zum Objekt verknüpfte Events aus dem Kalender. + * + * @param {String} pFrame req Name des Frames + * @param {String} pDBID req ID des verknüpften Datensatzes + * @param {Object} pFilter opt + * @param {String} pAlias opt + * @param {String} pUser opt Benutzer + * + * @return {[]} mit Events aus Kalender + */ +function getLinkedEvents (pFrame, pDBID, pFilter, pAlias, pUser ) +{ + if ( pFilter == "" || pFilter == undefined) + pFilter = reset_filterEvent(); + + var tab = []; + var exists = []; + var conditions = []; + var today = getDate(vars.getString("$sys.date")); + var conditioncount = 0; + var stati = []; + + if ( pFilter.tentative == "true" ) + stati.push(mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() )); + + if ( pFilter.cancelled == "true" ) + stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendType() )); + + if ( pFilter.confirmed == "true" ) + stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )); + + if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS) + stati.push(calendars.STATUS_FREE); + + if (pAlias == undefined ) pAlias = vars.getString("$sys.dbalias"); + + var entryids = db.table(["select ENTRYID, OWNER " + + "from ASYS_CALENDARLINK " + + "join ASYS_CALENDARBACKEND on ELEMENTUID = ENTRYID where FRAME = 'comp." + + pFrame + "' and ENTRYID is not null and ENTRYTYPE = " + calendars.VEVENT + + " and DBID = '" + pDBID + "' and DTSTART >= ?", + [ [ String(pFilter.datefrom - datetime.ONE_WEEK), SQLTYPES.DATE ]]], pAlias ); + + /* + * Check for rights before constructing condition otherwise you'll get an error by opening linked Data + */ + var userToRead = [] + if(pUser != undefined) + { + userToRead = getCalendarUsers( calendars.RIGHT_READ_APPOINTMENT, pUser ); + } + else + { + userToRead = calendars.getDisplayCalendarUsers(calendars.RIGHT_READ_APPOINTMENT); + } + var userMap = {}; + for (let i = 0; i < userToRead.length; i++) + { + userMap[userToRead[i][1]] = true; + } + + for ( var i = 0;i < entryids.length; i++) + { + var user = getTitleCalenderUser(entryids[i][1]); + if(userMap[user]) + { + for ( var z = 0; z < stati.length; z++ ) + _addEntryCondition(conditions, String(++conditioncount), + { + TYPE: calendars.VEVENT, + START: pFilter.datefrom, + END: pFilter.dateto, + USER: user, + STATUS: stati[z], + UID: entryids[i][0] + }); + } else continue + } + conditions["COUNT"] = String(conditioncount); + + var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto); + for ( let i = 0; i < entries.length; i++) + { + for (var j = 0; j < entries[i].length; j++) + { + var entry = entries[i][j]; + if( exists.indexOf(entry[calendars.ID]) == -1 && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > 0)) + { + var entr = new Array; + var start = getDate(entry[calendars.DTSTART]); + var end = getDate(entry[calendars.DTEND]); + user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) + if(user == null) user = entry[calendars.USER2]["cn"]; + else user = user[tools.TITLE] + entr[0] = text.encodeMS([entry[calendars.ID], user , entry[calendars.RECURRENCEID]]); + if (end < today) entr[1] = "-6710887" ; + else if (start <= today && end >= today ) entr[1] = "-16744020" ; + else entr[1] = "-16777216"; + entr[2] = "-1" + entr[3] = text.decodeMS(entry[calendars.AFFECTEDUSERS]).length; + entr[4] = entry[calendars.DTSTART] + entr[5] = entry[calendars.DTEND] + entr[6] = entry[calendars.SUMMARY] + entr[7] = getRealName([entry[calendars.ORGANIZER2]]); + entr[8] = getRealName(entry[calendars.ATTENDEES]); + entr[9] = entry[calendars.DESCRIPTION] + tab.push(entr); + exists.push(entry[calendars.ID]); + } + } + } + array_mDimSort(tab, 4, false); + return tab; +} + +/* + * Liefert Aufgaben aus dem Kalender. + * + * @param {Object} pFilter req + * @param {String} pLanguage opt + * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen + * + * @return {[]} mit allen aufgaben aus dem Kalender + */ +function getTodos( pFilter, pLanguage, pShortForm ) +{ + if ( pFilter == "" ) pFilter = reset_filterToDo(); + var tab = []; + var today = getDate (vars.getString("$sys.date")); + var conditions = []; + var conditioncount = 0; + var user = pFilter.user; + var stati = []; + var status = []; + var exists = []; + var entries = []; + + if ( pFilter.needs_action == "true" ) + { + stati.push(mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() )); + status.push("NEEDS-ACTION"); + } + if ( pFilter.in_process == "true" ) + { + stati.push(mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() )); + status.push("IN-PROCESS"); + } + if ( pFilter.completed == "true" ) + { + stati.push(mapCalendarStatus(calendars.STATUS_COMPLETED, calendars.getBackendTypeTasks() )); + status.push("COMPLETED"); + } + if ( pFilter.cancelled == "true" ) + { + stati.push(mapCalendarStatus(calendars.STATUS_CANCELLED, calendars.getBackendTypeTasks() )); + status.push("CANCELLED"); + } + if (pFilter.delegated == "true" ) + { + var from = [pFilter.datefrom, SQLTYPES.TIMESTAMP]; + var to = [pFilter.dateto, SQLTYPES.TIMESTAMP]; + setAllCalendarGrant(); + user = calendars.getCalendarUser(user); + user = db.table(["select ELEMENTUID, OWNER from ASYS_CALENDARBACKEND where ENTRYTYPE = 2 and OWNER != '" + user + "' and ORGANIZER = '" + + user + "' and STATUS in ('" + status.join("', '") + "') and (( STARTTIME >= ? and STARTTIME <= ?) or " + + "( ENDTIME >= ? and ENDTIME <= ? ) or ( STARTTIME >= ? and ENDTIME <= ? ))", [from, to, from, to, from, to]] ); + + for (let i = 0; i < user.length; i++ ) + { + try + { + entries.push([calendars.getEntry(user[i][0], null, getTitleCalenderUser(user[i][1]), calendars.VTODO)]); + } + catch(err){ + logging.log(err); + } + } + setCalendarGrant(); + } + else + { + if ( typeof( pFilter.user ) != "object" ) user = [user.trim()]; + for (let i = 0; i < user.length; i++ ) + for ( var z = 0; z < stati.length; z++ ) + _addEntryCondition(conditions, ++conditioncount, + { + TYPE: calendars.VTODO, + START: pFilter.datefrom, + END: pFilter.dateto, + USER: user[i], + STATUS: stati[z] + }); + + conditions["COUNT"] = String(conditioncount); + entries = calendars.getEntries(conditions); + } + + for (i = 0; i < entries.length; i++) + { + var entry = entries[i][0]; + user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) + if (user == null) user = entry[calendars.USER2]["cn"]; + else user = user[tools.TITLE] + if ( !(user != vars.getString("$sys.user") && entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) // no privat + && !( pFilter.delegated == "true" && ( isAffectedUser( entry, pFilter.user) || exists.indexOf(entry[calendars.ID]) > -1 ) ) // no duplicate + && ( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf( pFilter.category ) > -1 ) ) // Filter category + { + var entr = []; + var links = entry[calendars.LINKS]; + var due = entry[calendars.DUE] != "" ? getDate(entry[calendars.DUE]) : ""; + entr[0] = text.encodeMS([entry[calendars.ID], user]); + if (due == today ) entr[1] = "-16744020" ; + else if(due == "") entr[1] = "-13395712"; + else if (due > today ) entr[1] = "-16777216"; + else entr[1] = "-1769402"; + if (entry[calendars.PRIORITY] == "1") entr[2] = "-100"; + entr[3] = entry[calendars.ATTENDEES].length; + entr[4] = entry[calendars.DUE]; + + if (pShortForm) + { + entr[5] = entry[calendars.SUMMARY]; + entr[6] = entry[calendars.DESCRIPTION]; + } + else + { + entr[5] = getCalendarStatus( entry[calendars.STATUS], pLanguage, "ToDo"); + entr[6] = getCalendarPriority( entry[calendars.PRIORITY], pLanguage); + entr[7] = entry[calendars.SUMMARY]; + entr[8] = getRealName( [ entry[calendars.ORGANIZER2] ] ); + entr[9] = getRealName( entry[calendars.ATTENDEES] ); + if (links == undefined) entr[10] = ""; else entr[10] = links; + entr[11] = entry[calendars.DESCRIPTION]; + entr[12] = entry[calendars.CREATED]; + } + + tab.push(entr); + if ( pFilter.delegated == "true" ) exists.push(entry[calendars.ID]); + } + } + + if (pShortForm) + sortArray(tab, -1, 4, 1, 5); + else + sortArray(tab, -1, 4, 1, 12 ); + + return tab; +} + +/* + * Fügt eine Condition hinzu + * + * @param {[]} pConditions req die Conditions + * @param {Integer} pIndex req Index der Condition + * @param {Object} pValues req + * + * @return {void} + */ +function _addEntryCondition(pConditions, pIndex, pValues) +{ + var params = ["TYPE", "START", "END", "USER", "STATUS", "UID"]; + + for (var i = 0; i < params.length; i++) + if (pValues[params[i]] != undefined) pConditions[params[i] + "_" + pIndex] = pValues[params[i]]; +} +CalendarUtil.addEntryCondition = function(pConditions, pIndex, pValues) +{ + _addEntryCondition(pConditions, pIndex, pValues); +} + +/* + * Liefert Events zu bestimmten Usern/Daten in einem Array. + * + * @param {Object} pFilter req + * @param {String} pLanguage opt + * @param {bool} pShortForm opt wenn true wird nur die kurzversion geladen + * + * @return {[]} + * [0] ID + * [1] Vordergrundfarbe + * [2] Hintergrundfarbe + * [3] Start + * [4] Ende + * [5] Betreff + * [6] Inhalt + * [7] User + * [8] Anzahl Verknüpfungen + * [9] Klassifikation (privat/öffentlich) + */ +function getEvents( pFilter, pLanguage, pShortForm ) +{ + if ( pFilter == "" ) pFilter = reset_filterEvent(); + var tab = []; + var conditions = []; + var today = getDate(vars.getString("$sys.date")); + var conditioncount = 0; + var stati = []; + var user = undefined; + if ( pFilter.tentative == "true" ) stati.push(calendars.STATUS_TENTATIVE); + if ( pFilter.cancelled == "true" ) stati.push(calendars.STATUS_CANCELLED); + if ( pFilter.confirmed == "true" ) + stati.push(mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() )); + + if (getCalendarSystemType(calendars.VEVENT) == calendars.BACKEND_EXCHANGEWS && pFilter.free == "true") + stati.push(calendars.STATUS_FREE); + + if ( pFilter.user != "" ) user = (pFilter.user).trim(); + + for ( var z = 0; z < stati.length; z++ ) + _addEntryCondition(conditions, String(++conditioncount), + { + TYPE: calendars.VEVENT, + START: pFilter.datefrom, + END: pFilter.dateto, + USER: user, + STATUS: stati[z] + }); + + conditions["COUNT"] = String(conditioncount); + + var entries = calendars.getExpandedEntries(conditions, pFilter.datefrom, pFilter.dateto); + for ( var i = 0;i < entries.length; i++) + { + for (var j = 0; j < entries[i].length; j++) + { + var entry = entries[i][j]; + if( pFilter.category == "" || text.decodeMS(entry[calendars.CATEGORIES]).indexOf(pFilter.category) > -1 ) + { + var entr = new Array; + var start = getDate(entry[calendars.DTSTART]); + var end = getDate(entry[calendars.DTEND]); + + user = tools.getUserByAttribute(tools.CALENDARID, entry[calendars.USER2]["paramvalue"].substr("mailto:".length)) + if(user == null) user = entry[calendars.USER2]["cn"]; + else user = user[tools.TITLE] + entr[0] = text.encodeMS([ entry[calendars.ID], user, entry[calendars.RECURRENCEID]]); + if (end < today ) entr[1] ="-6710887" ; + else if (start > today) entr[1] = "-16777216"; + else entr[1] = "-16744020" ; + entr[2] = "-1" + entr[3] = entry[calendars.ATTENDEES].length; + entr[4] = entry[calendars.DTSTART]; + entr[5] = entry[calendars.DTEND]; + entr[6] = entry[calendars.SUMMARY]; + + if (!pShortForm) + { + entr[7] = getRealName([entry[calendars.ORGANIZER2]]); + entr[8] = getRealName(entry[calendars.ATTENDEES]); + entr[9] = getCalendarStatus( entry[calendars.STATUS], pLanguage ); + if (entry[calendars.LINKS] == undefined) entr[10] = ""; + else entr[10] = entry[calendars.LINKS]; + entr[11] = entry[calendars.DESCRIPTION]; + } + tab.push( entr ); + } + } + } + sortArray(tab, -1, 4, 1, 6 ); + return tab; +} + +/* + * Liefert den echten Namen anhand des Logins zurück + * + * @param {Array}[]} pUserMap req pUserMap + * + * @return String + */ +function getRealName(pUserMap) +{ + var resultName = []; + var RealNames = getRealNameObject(pUserMap); + + for ( var realname in RealNames ) resultName.push(RealNames[realname]); + return resultName.join(", \n"); +} + +/* + * Liefert den echten Namen anhand des Logins zurück + * + * @param {Array}[]} pUserMap req pUserMap + * + * @return Object + */ +function getRealNameObject(pUserMap) +{ + var resultObject = {}; + var realname = ""; + + for ( let i = 0; i < pUserMap.length; i++ ) + { + let user = tools.getUserByAttribute(tools.CALENDARID, [pUserMap[i]["paramvalue"].substr("mailto:".length)]) + if ( user != null ) + { + if(vars.exists("$global.firstLastName") && vars.get("$global.firstLastName")) + realname = user[tools.PARAMS][tools.LASTNAME] + " " + user[tools.PARAMS][tools.FIRSTNAME]; + else realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME]; + } + else //Der User existiert nicht im System + { + realname = pUserMap[i]["cn"] + " " + pUserMap[i]["paramvalue"]; + } + resultObject[pUserMap[i]["cn"]] = realname; + } + return resultObject; +} + + +/* + * Gibt an ob der User im Calendarobject vorhanden ist + * + * @param {Object} pEntry req Calendarobject + * @param {String} pUser req Title + * + * @return Object + */ +function isAffectedUser( pEntry, pUser) +{ + var usermap = pEntry[calendars.ATTENDEES]; + + for ( var i = 0; i < usermap.length; i++ ) + if( usermap[i]["cn"] == pUser ) + return true; + return false; +} + +/* + * Liefert das Datum ohne Urzeit zurück + * + * @param {String} datetimeIn req DatumZeit + * + * @return {date} + */ +function getDate( datetimeIn ) +{ + if ( datetimeIn != "") + return datetime.clearTime(datetimeIn); + else return ""; +} + +/* + * Setzt den Aufgaben-Filter + * + * @param {Object} pFilter req + * + * @return {image} + */ +function filterToDo( pFilter ) +{ + var error = true; + var von = pFilter.datefrom; + var bis = pFilter.dateto; + if ( pFilter == "" ) pFilter = reset_filterToDo(); + do + { + vars.set("$local.relation_id", pFilter.user); + vars.set("$local.edt_von", pFilter.datefrom); + vars.set("$local.edt_bis", pFilter.dateto); + vars.set("$local.category", pFilter.category); + vars.set("$local.delegated", pFilter.delegated); + vars.set("$local.needs_action", pFilter.needs_action); + vars.set("$local.in_process", pFilter.in_process); + vars.set("$local.completed", pFilter.completed); + vars.set("$local.cancelled", pFilter.cancelled); + var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_FILTER"); + if( res != null ) + { + pFilter.user = res["DLG_TASK_FILTER.relation_id"]; + pFilter.datefrom = res["DLG_TASK_FILTER.edt_von"]; + pFilter.dateto = res["DLG_TASK_FILTER.edt_bis"]; + pFilter.category = res["DLG_TASK_FILTER.category"]; + pFilter.delegated = res["DLG_TASK_FILTER.delegated"]; + pFilter.needs_action = res["DLG_TASK_FILTER.needs_action"]; + pFilter.in_process = res["DLG_TASK_FILTER.in_process"]; + pFilter.completed = res["DLG_TASK_FILTER.completed"]; + pFilter.cancelled = res["DLG_TASK_FILTER.cancelled"]; + if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; + else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) + } + else + { + pFilter.datefrom = von; + pFilter.dateto = bis; + error = false; + } + } + while ( error ) + return pFilter; +} + +/* + * Setzt den Aufgaben-Filter + * + * @param {Object} pFilter req + * + * @return {image} + */ +function filterToDo_Neon( pFilter ) +{ + var error = true; + var von = pFilter.datefrom; + var bis = pFilter.dateto; + if ( pFilter == "" ) pFilter = reset_filterToDo(); + do + { + var prompts = { + FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"), + RESPONSIBLE: pFilter.user, + DATE_FROM: pFilter.datefrom, + DATE_TO: pFilter.dateto, + CATEGORY_TODO: pFilter.category, + DELEGATED: pFilter.delegated, + NEEDS_ACTION: pFilter.needs_action, + IN_PROCESS: pFilter.in_process, + COMPLETED: pFilter.completed, + CANCELLED: pFilter.cancelled + } + + var buttons = { + "ok" : translate.text("OK"), + "": translate.text("Abbrechen") + }; + var defaultButton = "ok"; + + var res = question.openDialog("DLG_FILTER_TODO_Neon", prompts, buttons, defaultButton); + + if( res.button != null ) + { + pFilter.user = res.RESPONSIBLE; + pFilter.datefrom = res.DATE_FROM; + pFilter.dateto = res.DATE_TO; + pFilter.category = res.CATEGORY_TODO; + pFilter.delegated = res.DELEGATED; + pFilter.needs_action = res.NEEDS_ACTION; + pFilter.in_process = res.IN_PROCESS; + pFilter.completed = res.COMPLETED; + pFilter.cancelled = res.CANCELLED; + if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; + else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) + } + else + { + pFilter.datefrom = von; + pFilter.dateto = bis; + error = false; + } + } + while ( error ) + return pFilter; +} + + +/* + * Anzeige des Aufgaben-Filter + * + * @param {Object} pFilter req + * + * @return string Anzeige + */ +function show_filterToDo(pFilter) +{ + var retstring = ""; + var userp = tools.getUser( pFilter.user )[tools.PARAMS]; + if (pFilter.user != "") retstring = (translate.text("Aufgaben von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]); + if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy")); + if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy")); + if (pFilter.category != "") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category; + if (pFilter.delegated == "true") retstring += ", " + translate.text("delegiert"); + if (pFilter.needs_action == "true") retstring += ", " + translate.text("Nicht begonnen"); + if (pFilter.in_process == "true") retstring += ", " + translate.text("In Bearbeitung"); + if (pFilter.completed == "true") retstring += ", " + translate.text("Erledigt"); + if (pFilter.cancelled == "true") retstring += ", " + translate.text("Zurückgestellt"); + + return retstring +} + +/* + * Setzt den Aufgaben-Filter zurück + * + * @return {filter} + */ +function reset_filterToDo() +{ + var today = getDate (vars.getString("$sys.date")); + + return pFilter = { + user: vars.getString("$sys.user"), + datefrom: String(eMath.subInt(today, 720 * datetime.ONE_DAY)), + dateto: String(eMath.addInt(eMath.addInt(today, 3 * datetime.ONE_DAY) + ,datetime.ONE_DAY - datetime.ONE_MINUTE)), + category: "", + delegated: "", + needs_action: "true", + in_process: "true", + completed: "", + cancelled: "" + }; +} + +/* + * Setzt den Event-Filter + * + * @param {Object} pFilter req + * + * @return {image} + */ +function filterEvent( pFilter ) +{ + var error = true; + var von = pFilter.datefrom; + var bis = pFilter.dateto; + if ( pFilter == "" ) pFilter = reset_filterEvent(); + do + { + vars.set("$local.relation_id", pFilter.user); + vars.set("$local.edt_von", pFilter.datefrom); + vars.set("$local.edt_bis", pFilter.dateto); + vars.set("$local.category", pFilter.category); + vars.set("$local.tentative", pFilter.tentative); + vars.set("$local.confirmed", pFilter.confirmed); + vars.set("$local.cancelled", pFilter.cancelled); + vars.set("$local.free", pFilter.free); + var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_EVENT_FILTER"); + if( res != null ) + { + pFilter.user = res["DLG_EVENT_FILTER.relation_id"]; + pFilter.datefrom = res["DLG_EVENT_FILTER.edt_von"]; + pFilter.dateto = res["DLG_EVENT_FILTER.edt_bis"]; + pFilter.category = res["DLG_EVENT_FILTER.category"]; + pFilter.tentative = res["DLG_EVENT_FILTER.tentative"]; + pFilter.confirmed = res["DLG_EVENT_FILTER.confirmed"]; + pFilter.cancelled = res["DLG_EVENT_FILTER.cancelled"]; + pFilter.free = res["DLG_EVENT_FILTER.free"]; + if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; + else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) + } + else + { + pFilter.datefrom = von; + pFilter.dateto = bis; + error = false; + } + } + while ( error ) + return pFilter; +} + +/* + * Setzt den Event-Filter + * + * @param {Object} pFilter req + * + * @return {image} + */ +function filterEvent_Neon( pFilter ) +{ + var error = true; + var von = pFilter.datefrom; + var bis = pFilter.dateto; + if ( pFilter == "" ) pFilter = reset_filterEvent(); + do + { + var buttons = { + "ok" : translate.text("OK"), + "": translate.text("Abbrechen") + }; + var defaultButton = "ok"; + + var prompts = { + FILTER_TEXT: translate.text("Bitte Filterbedingungen setzen"), + RESPONSIBLE_APPOINTMENT: pFilter.user, + DATE_FROM: pFilter.datefrom, + DATE_TO: pFilter.dateto, + CATEGORY_APPOINTMENT: pFilter.category, + TENTATIVE: pFilter.tentative, + CONFIRMED: pFilter.confirmed, + CANCELLED: pFilter.cancelled + } + var res = question.openDialog("DLG_FILTER_APPOINTMENT_Neon", prompts, buttons, defaultButton); + if( res.button != null ) + { + pFilter.user = res.RESPONSIBLE_APPOINTMENT; + pFilter.datefrom = res.DATE_FROM; + pFilter.dateto = res.DATE_TO; + pFilter.category = res.CATEGORY_APPOINTMENT; + pFilter.tentative = res.TENTATIVE; + pFilter.confirmed = res.CONFIRMED; + pFilter.cancelled = res.CANCELLED; + if (pFilter.datefrom != "" && pFilter.dateto != "" && pFilter.dateto >= pFilter.datefrom ) error = false; + else question.showMessage(translate.text("Bitte Datumseingabe prüfen!")) + } + else + { + pFilter.datefrom = von; + pFilter.dateto = bis; + error = false; + } + } + while ( error ) + return pFilter; +} + +/* + * Anzeige des Event-Filter + * + * @param {Object} pFilter req + * + * @return string Anzeige + */ +function show_filterEvent(pFilter) +{ + var retstring = ""; + + var userp = tools.getUser( pFilter.user )[tools.PARAMS]; + if (pFilter.user != "") retstring = translate.text("Termine von") + " " + userp[tools.FIRSTNAME] + " " + userp[tools.LASTNAME]; + if (pFilter.datefrom != "") retstring += ", " + datetime.toDate(pFilter.datefrom, translate.text("dd.MM.yyyy")); + if (pFilter.dateto != "") retstring += " - " + datetime.toDate(pFilter.dateto, translate.text("dd.MM.yyyy")); + if (pFilter.category == "true") retstring += ", " + translate.text("Kategorie") + " " + pFilter.category; + if (pFilter.tentative == "true") retstring += ", " + translate.text("Vorläufig"); + if (pFilter.confirmed == "true") retstring += ", " + translate.text("Bestätigt"); + if (pFilter.cancelled == "true") retstring += ", " + translate.text("Abgesagt"); + + return retstring +} + +/* + * Setzt den Event-Filter zurück + * + * @return {filter} + */ +function reset_filterEvent() +{ + var today = getDate (vars.getString("$sys.date")); + + return pFilter = { + user: vars.getString("$sys.user"), + datefrom: String(today), //nur die Termine ab heute anzeigen, + //die von vor einer Woche sind uninteressant + dateto: String(eMath.addInt(eMath.addInt(today, datetime.ONE_WEEK) + ,datetime.ONE_DAY - datetime.ONE_MINUTE)), + category: "", + tentative: "true", + confirmed: "true", + cancelled: "", + free: "true" + }; +} + +/* + * Setzt den Aufgaben-Filter in Tab Aufgaben + * + * @return {image} + */ +function filterLinkedToDo() +{ + var filtervalues = ["", "false"]; + vars.set("$local.CalenderUser", getCalenderUser( calendars.RIGHT_READ_TASK )); + + //Vorbelegen der Werte, wenn bereits gewählt wurde: + if(vars.exists("$image.FilterValuesT")) + { + filtervalues = vars.get("$image.FilterValuesT"); + vars.set("$local.relation_id", filtervalues[0]); + vars.set("$local.done", filtervalues[1]); + } + + var res = swing.askUserQuestion(translate.text("Bitte Filterbedingungen setzen"), "DLG_TASK_DATE_LINKED_FILTER"); + + if( res != null && res != undefined && res != "") + { + filtervalues[0] = res["DLG_TASK_DATE_LINKED_FILTER.relation_id"]; + filtervalues[1] = res["DLG_TASK_DATE_LINKED_FILTER.done"] + } + vars.set("$image.FilterValuesT", filtervalues ); + + return(filtervalues); +} + +/* + * Setzt den Aufgabe-Filter zurück + * + * @return {image} + */ +function resetfilterLinkedToDo() +{ + var filtervalues = ["", "false"]; + + vars.set("$image.FilterValuesT", filtervalues ); + +} + +/* + * setzt die Kalenderrechte + * + * @return {void} + */ +function setCalendarGrant() +{ + calendars.resetCalendarUser(); + var user_read_todo = []; + var user_write_todo = []; // ["Admin"] + var user_read_event = []; + var user_write_event = []; + var tree = {}; + var data = db.table("select THEMEID, THEME.THEME_ID, LOGIN, STATUS from THEME " + + " left join EMPLOYEE on EMPLOYEE.THEME_ID = THEMEID left join RELATION on RELATION_ID = RELATIONID and STATUS = 1" + +" where KIND = 2"); + for ( let i = 0; i < data.length; i++) + { + if ( tree[data[i][0]] == undefined ) tree[data[i][0]] = { + pid: data[i][1], + isuser: false + }; + if ( data[i][2] != "" && data[i][3] != "" ) tree[data[i][2]] = { + pid: data[i][0], + isuser: true + }; + } + + var user = vars.getString("$sys.user"); + // Lese- und Schreibrechte auf Kalender aus Datentabelle holen + data = db.table("select HASRIGHTFOR, TODO_RIGHTS, EVENT_RIGHTS from AOSYS_CALENDAR_RIGHTS where LOGIN = '" + user + "'"); + for ( var i = 0; i < data.length; i++ ) + if(tree[data[i][0]] != undefined) + tree[data[i][0]].grants = data[i].slice(1); + + for ( login in tree ) + { + if( tree[login].isuser ) + { + var grantstodo = __getGrants( login, 0 ); + var grantsevent = __getGrants( login, 1 ); + if ( grantstodo.length + grantsevent.length > 0 ) + { + if ( grantstodo == "1" || grantstodo == "3") user_read_todo.push(login); + if ( grantstodo == "2" || grantstodo == "3") user_write_todo.push(login); + if ( grantsevent == "1" || grantsevent == "3") user_read_event.push(login); + if ( grantsevent == "2" || grantsevent == "3") user_write_event.push(login); + } + } + } + calendars.setCalendarUser(user_read_todo, calendars.RIGHT_READ_TASK, true, calendars.SORTSTRATEGY_NATURAL ); + calendars.setCalendarUser(user_write_todo, calendars.RIGHT_WRITE_TASK, true, calendars.SORTSTRATEGY_NATURAL ); + calendars.setCalendarUser(user_read_event, calendars.RIGHT_READ_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL ); + calendars.setCalendarUser(user_write_event, calendars.RIGHT_WRITE_APPOINTMENT, true, calendars.SORTSTRATEGY_NATURAL ); + + //********** Ressourcen in Kalender einfügen ************ + var ressource = tools.getUsersWithRole("PROJECT_Ressource"); + calendars.setCalendarUser( ressource, calendars.RIGHT_READ_APPOINTMENT | calendars.RIGHT_WRITE_APPOINTMENT ); + + //add all users from support-role since support-action-tasks (sp_supportAktionen) generates tasks for all support-role members + //and if you're a member you are allowed to edit these + if (tools.hasRole(user, "PROJECT_Support")) + { + var support = tools.getUsersWithRole("PROJECT_Support"); + calendars.setCalendarUser( support, calendars.RIGHT_WRITE_TASK | calendars.RIGHT_READ_TASK ); + } + + function __getGrants( pKey, pIndex ) + { + var grants = []; + if ( tree[pKey].grants != undefined && tree[pKey].grants[pIndex]) grants = tree[pKey].grants[pIndex]; + else if ( tree[pKey].pid != "" ) grants = __getGrants( tree[pKey].pid, pIndex ); + return grants; + } +} + +/* + * setzt Recht für alle Kalender + * + * @return {void} + */ +function setAllCalendarGrant() +{ + calendars.resetCalendarUser(); + var users = tools.getStoredUsers(); + var calendar_user = []; + for ( var i = 0; i < users.length; i++ ) calendar_user.push( users[i][1] ); + calendars.setCalendarUser(calendar_user, calendars.RIGHT_READ_TASK | calendars.RIGHT_WRITE_TASK, false, calendars.SORTSTRATEGY_NATURAL ); +} + +/* + * gibt die Logins der user, die den übergebenen User als Attribute eingetragen haben, zurück + * + * @param {[]} pUsers req Logins + * @param {String []} pAttrName req AttributeName für Employee + * @param {String []} pFields opt + * + * @return {String []} Logins + */ +function getUsersbyAttr( pUsers, pAttrName, pFields ) +{ + if (typeof(pAttrName) == "string") pAttrName = [pAttrName] + + if ( pFields == undefined ) + { + pFields = ["LOGIN"]; + } + + var sqlstr = "select " + pFields.join(", ") + " from ATTRLINK join ATTR on ATTRLINK.ATTR_ID = ATTRID and OBJECT_ID = 12 " + + "and ATTRNAME in ('" + pAttrName.join("','") + "') " + + " join EMPLOYEE on EMPLOYEEID = ATTRLINK.ROW_ID join RELATION on RELATION_ID = RELATIONID join PERS on PERS_ID = PERSID" + + " where VALUE_ID in (select EMPLOYEEID from EMPLOYEE where LOGIN in ('" + pUsers.join("','") + "'))" + + ""; + + if(pFields.length == 1) + return db.array(db.COLUMN, sqlstr); + else + return db.table(sqlstr); +} + +/* + * Gibt die Anzahl der verknüpften Aufgaben und Termine zurück. + * + * @param {String} pID req + * @param {String} pFrame req + * + * @return {String} text + */ +function countLinkedTodoEvent(pID, pFrame) +{ + var today = getDate (vars.getString("$sys.date")); + var datefrom = String(today); + var dateto = String(eMath.addInt(today, datetime.ONE_WEEK)); + + var str = "select count(distinct ELEMENTUID) from ASYS_CALENDARLINK join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID " + + " where FRAME = 'comp." + pFrame + "' and ELEMENTUID is not null and DBID = '" + pID + "'"; + var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO + " and STATUS in ('" + + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '" + + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')"); + + var eventStatusList = [ + mapCalendarStatus(calendars.STATUS_CONFIRMED, calendars.getBackendType() ) + ,mapCalendarStatus(calendars.STATUS_TENTATIVE, calendars.getBackendType() ) + ]; + + if (calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS) + eventStatusList.push(calendars.STATUS_FREE); + + var retevent = db.cell([str + " and ENTRYTYPE = " + calendars.VEVENT + " and STATUS in ('" + eventStatusList.join("', '") + "')" + + " and DTSTART >= ? and DTEND <= ?", + [ [ String(datefrom), SQLTYPES.DATE ], [String(dateto), SQLTYPES.DATE ] ]]); + + result.string(translate.withArguments("&Aufg / Term (%0/%1)", [rettask, retevent])); +} + +/* + * Gibt die Anzahl der verknüpften Aufgaben zurück. + * + * @param {String} pID req + * @param {String} pFrame req + * + * @return {String} text + */ +function countLinkedTodo(pID, pFrame) +{ + var str = "select count(distinct ELEMENTUID) " + + "from ASYS_CALENDARLINK " + + "join ASYS_CALENDARBACKEND on ELEMENTUID = ASYS_CALENDARLINK.ENTRYID " + + " where FRAME = 'comp." + pFrame + "' " + + "and ELEMENTUID is not null and DBID = '" + pID + "'"; + + var rettask = db.cell(str + "and ENTRYTYPE = " + calendars.VTODO + + " and STATUS in ('" + + mapCalendarStatus(calendars.STATUS_NEEDSACTION, calendars.getBackendTypeTasks() ) + "', '" + + mapCalendarStatus(calendars.STATUS_INPROCESS, calendars.getBackendTypeTasks() ) + "')" + + ""); + + result.string(translate.withArguments("&Aufgaben (%0)", [rettask])); +} + +/* + * Gibt die Überschneidungen von Termine zurück. + * + * @param {Date} pStart req + * @param {Date} pEnd req + * @param {Array} pUsers req + * + * @return {String Array} Termine + */ +function getOverlappingEvents(pStart, pEnd, pUsers ) +{ + var resultEvents = new Array(); + var users = pUsers; + if (calendars.getBackendType() == calendars.BACKEND_DB && pStart != "" && pEnd != "" && users.length > 0) + { + calendars.clearCache(); + for (var u = 0; u < users.length; u++) + { + var localuid = vars.get("$image.entry")[calendars.ID] + var condition = new Array(); + condition["COUNT"] = "1"; + condition["TYPE_1"] = calendars.VFREEBUSY; + condition["USER_1"] = users[u][0]; + condition["START_1"] = pStart; + condition["END_1"] = pEnd; + + var fbsall = calendars.getEntries(condition); + for (var j = 0; j < fbsall.length; j++) + { + var fbs = fbsall[j]; + for (var i = 0; i < fbs.length; i++) + { + var next = fbs[i]; + var uid = next[calendars.ID]; + var sum = next[calendars.SUMMARY]; + if (uid != localuid) + { + var freebusy = next[calendars.FREEBUSY]; + var freebusyDec = text.decodeMS(freebusy); + var match = false; + for (var k = 0; k < freebusyDec.length; k++) + { + var freebusyInstance = text.decodeMS(freebusyDec[k]); + if (!freebusyInstance[0].equals("FREE")) + { + match = true; + } + } + if (match) resultEvents.push([users[u][2], sum != null && sum.length > 0 ? sum : "?", uid]); + } + } + } + } + } + return resultEvents; +} + +/* + * Überprüft den Eintrag, wenn eine neue Aufgaben angelegt wird darauf, ob private Aufgaben für andere erstellt werden + * + * @param {String[]} pUser die Liste der User, denen die Aufgabe zugewiesen werden soll + * @param {String} pClassification die Klassifizierung der Aufgabe - "PRIVATE" + * + * @return {Boolean} ob der Eintrag in der Konstellation möglich ist, wenn nicht wird eine Meldung ausgegeben + */ +function checkEntry(pUser, pClassification ) +{ + if( pClassification == "PRIVATE" && + ( pUser.length > 1 || text.decodeMS(pUser[0][0])[1] != "CN:" + vars.getString("$sys.user"))) + { + question.showMessage(translate.text("Eine private Aufgabe kann nicht jemand anderem zugewiesen werden.")); + return false; + } + else + { + return true; + } +} + +/* + * Verschiebt ein Calendareintrag + * + * @param {String[]} pIDs req die zu verschiebenden Ids mit den Calenderinformationen (Multistring) + * @param {String} pTblCompName opt die Komponente die aktualisiert werden soll + * + * @return {void} + */ +function shiftEntry(pIDs, pTblCompName) +{ + var datenew = swing.askUserQuestion(translate.text("Verschieben auf Datum?"), "DLG_DATE"); + if (datenew != null ) + { + var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK); + var usermap = {}; + var granted = true; + for (let i = 0; i < grantedUsers.length; i++) + { + usermap[grantedUsers[i][1]] = true; + } + + datenew = datetime.clearTime(datenew["DLG_DATE.Edit_date"]); + if (datenew <= vars.getString("$sys.today")) + question.showMessage(translate.text("nur Verschiebung in die Zukunft erlaubt!")); + else + { + for (var i = 0, j = pIDs.length; i < j; i++) + { + var id = text.decodeMS(pIDs[i]); + var entry = calendars.getEntry(id[0], null, id [1], calendars.VTODO); + var affectedUsers = entry[calendars.ATTENDEES]; + + granted = hasGrantForEntryByObject(affectedUsers, usermap); + if(granted) + { + //Zeitdifferenz von Aufgabenstart und -ende + var dateDiff = eMath.subInt(entry[calendars.DUE], entry[calendars.DTSTART]); + + //Startzeit der Aufgabe + var startTime = eMath.subInt(entry[calendars.DTSTART] + , datetime.clearTime(entry[calendars.DTSTART])); + + entry[calendars.DTSTART] = eMath.addInt(datenew, startTime); + entry[calendars.DUE] = eMath.addInt(entry[calendars.DTSTART], dateDiff); + calendars.update( [ entry ] ); + } + else + question.showMessage(translate.text("Keine Berechtigung zum Verschieben der Aufgabe")); + } + } + } +} + +/* + * Gibt eine Aufgabe weiter + * + * @param {String} pIDs die ID der Aufgabe, welche weitergegeben werden soll + * @param {String} pTblCompName die Komponente der Aufgaben, die aktualisiert werden soll + * + * @return {void} + */ +function handOverToDo(pIDs, pTblCompName) +{ + var calendar_user = ""; + var users = getCalenderUser( calendars.RIGHT_WRITE_TASK ); + var publicCount = 0; + var privateCount = 0; + var notGrantedCount = 0; + + var grantedUsers = calendars.getDisplayCalendarUsers(calendars.RIGHT_WRITE_TASK); + var userMap = {}; + var granted = true; + for (let i = 0; i < grantedUsers.length; i++) + { + userMap[grantedUsers[i][1]] = true; + } + + if (pIDs.length == 1) // only one todo and private + { + var id = text.decodeMS( pIDs[0] ); + var entry = calendars.getEntry( id[0], null, id[1] ); + if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) + { + question.showMessage(translate.text("Kein Weitergeben von privaten Aufgaben möglich!")); + return; + } + } + + for ( let i = 0; i < users.length; i++) if (pIDs.length > 0 || users[i][0] != id[1]) calendar_user += "|" + users[i][1]; + var selection = swing.askQuestion(translate.text("Benutzer auswählen"), swing.QUESTION_COMBOBOX, calendar_user); + if (selection != null) + { + for ( let i = 0; i < users.length; i++) + { + if ( selection == users[i][1] ) + { + selection = users[i]; + break; + } + } + for( let i = 0; i < pIDs.length; i++) + { + let id = text.decodeMS( pIDs[i] ); + let entry = calendars.getEntry( id[0], null, id[1] ); + if(entry[calendars.CLASSIFICATION] == calendars.CLASSIFICATION_PRIVATE) privateCount++; + else //Nur öffentliche Aufgabe kann weiter gegeben werden. + { + // User austauschen + var usermap = entry[calendars.ATTENDEES]; + var affectedusers = []; + + granted = hasGrantForEntryByObject(usermap, userMap); + + for (var ui = 0; ui < usermap.length; ui++) + { + var login_cn = usermap[ui]["cn"]; + var user = tools.getUserByAttribute(tools.CALENDARID, usermap[ui]["paramvalue"].substr("mailto:".length)) + if (user == null) user = login_cn; + else user = user[tools.TITLE] + + if ( user == id[1] ) affectedusers.push(selection[0]); + else if ( user != selection[0] ) affectedusers.push(user); + } + if(granted) + { + entry[calendars.AFFECTEDUSERS] = text.encodeMS(calendars.getCalendarUsers(affectedusers)); + calendars.update([entry]); + publicCount++; + } + else notGrantedCount++ + } + } + question.showMessage(translate.withArguments("%0 Aufgabe(n) erfolgreich weitergegeben an: %1" + + (privateCount == 0 ? "" : "\n%2 private Aufgabe(n) können nicht weitergegeben werden.") + +(notGrantedCount == 0 ? "" : "\n%3 Aufgabe(n) können aufgrund fehlender Berechtigung nicht weitergegeben werden."), + [publicCount, selection[1], privateCount, notGrantedCount])); + + } +} + +// ToDo prüfen !! +/* + * Verschiebt die Kalendereinträge bei Login-Änderung + * + * @param {String} pNewlogin req + * @param {String} pOldlogin req + * @param {String} pNewCalendarID req + * @param {String} pOldCalendarID req + * + * @return {void} + */ +function moveCalendarData ( pNewlogin, pOldlogin, pNewCalendarID, pOldCalendarID ) +{ + var newcaluser = text.encodeMS(["mailto:" + pNewCalendarID, "CN:" + pNewlogin]); + var oldcaluser = text.encodeMS(["mailto:" + pOldCalendarID, "CN:" + pOldlogin]); + db.runStatement("update ASYS_CALENDARBACKEND set OWNER = '" + newcaluser + "' where OWNER = '" + oldcaluser + "'"); + db.runStatement("update ASYS_CALENDARBACKEND set ORGANIZER = '" + newcaluser + "' where ORGANIZER = '" + oldcaluser + "'"); + + if(pNewCalendarID != pOldCalendarID) //Nur wenn sich die E-Mailadresse geändert hat + { + //Messenger-Historien + db.runStatement("update ASYS_XMPP_HISTORY set JID_FROM = '" + pNewCalendarID +"' where JID_FROM = '" + pOldCalendarID +"'", SqlUtils.getSystemAlias()); + db.runStatement("update ASYS_XMPP_HISTORY set JID_TO = '" + pNewCalendarID +"' where JID_TO = '" + pOldCalendarID +"'", SqlUtils.getSystemAlias()); + } +} + +/* + * Löst den CalenderUser in lesbarer From auf + * + * @param {String} pValue req + * + * @return {String} übersetzten Wert + */ +function getCalUser( pValue ) +{ + var realname = pValue; + var user = tools.getUser( text.decodeMS(pValue)[1].split(":")[1] ); + if ( user != null ) + { + realname = user[tools.PARAMS][tools.FIRSTNAME] + " " + user[tools.PARAMS][tools.LASTNAME]; + } + return realname; +} + +/* + * Gibt den Login eines CalenderUser zurück + * + * @param {String} pCalendarUser req + * + * @return {String} Title + */ +function getTitleCalenderUser( pCalendarUser ) +{ + var data = text.decodeMS(pCalendarUser) + for ( var i = 0; i < data.length; i++ ) + { + //if login changes we have to check calendarid + if ( data[i].substr(0, "mailto:".length).toUpperCase() == "MAILTO:" ) + { + var user = tools.getUserByAttribute(tools.CALENDARID, [data[i].substr("mailto:".length)]); + if (user != null ) + return user[tools.TITLE]; + } + + if ( data[i].substr(0, 3).toUpperCase() == "CN:" ) + return data[i].substr(3); + } + return ""; +} + + +/* + * Gibt den richtigen Status zum Prüfen je nach Backend zurück + * + * + * @param {String} pStatus req die konstante für den zu prüfenden status, + * z.B. calendars.STATUS_INPROCESS + * + * @param {String} pCalendarType req die konstante für den typen des Termin- oder Aufgabenbackends, + * z.B. calendars.BACKEND_DB + * + * @return {String} Konstanten für den Kalender (Backend-Typen), gibt es den status im backend nicht + * wird null geliefert + */ +function mapCalendarStatus(pStatus, pCalendarType) +{ + switch (pCalendarType) + { + //case calendars.BACKEND_EXCHANGE: + case calendars.BACKEND_EXCHANGEWS: + if (pStatus == calendars.STATUS_CONFIRMED) + return calendars.STATUS_BUSY; + else + return pStatus; + default: + if (pStatus == calendars.STATUS_OOF)//nur bei exchange + return null; + else + return pStatus; + } +} + +/* + * Sets the imagevariable with affectedusers + * + * @param {Object} pEntry req the Entry of Tasks or Appointments + * + * @return {void} + * + */ +function setAffectedUsersImage(pEntry) +{ + var affectedUsers = []; + var usermap = pEntry[calendars.ATTENDEES]; + var realnames = getRealNameObject(usermap); + + for ( var i = 0; i < usermap.length; i++ ) + { + affectedUsers.push([ text.encodeMS( [usermap[i]["paramvalue"], "CN:" + usermap[i]["cn"]] ), realnames[usermap[i]["cn"]] ]); + } + + vars.set("$image.affectedusers", affectedUsers); + return affectedUsers; +} + +/* + * Opens calendar links + * + * @param {String} pEntryID req the ID of the link + * + * @return {void} + * + */ +function openCalendarLinks(pEntryID) +{ + var openFramesObj = {}; + if (typeof(pEntryID) == "object") + openFramesObj = pEntryID; + else + { + var links = db.table("SELECT FRAME, DBIDCOLUMN, DBID FROM ASYS_CALENDARLINK WHERE ENTRYID = '" + pEntryID + "'"); + for (var i = 0; i < links.length; i++) + { + var frame = links[i][0].substr( 5 );//remove comp. so the frame can be opened with openFrame + if ( openFramesObj[frame] == undefined ) openFramesObj[frame] = { + IDField: links[i][1], + IDs: [] + }; + openFramesObj[frame].IDs.push(links[i][2]); + } + } + + for ( frame in openFramesObj) + { + var condition = openFramesObj[frame].IDField + " in ('" + openFramesObj[frame].IDs.join("', '") + "')"; + var framemode = openFramesObj[frame].IDs.length > 1 ? swing.FRAMEMODE_TABLE_SELECTION : swing.FRAMEMODE_SHOW; + + if ( vars.getString("$global.upwardLink") == "link") + { + swing.openLinkedFrame(frame, condition, swing.WINDOW_CURRENT, framemode, "", null, false, { + autoclose: true + } ); + } + else + { + swing.openFrame(frame, condition, swing.WINDOW_CURRENT, framemode, null, false); + } + } +} + +/** + * Returns the "real" calendar system/backend type (BackendType & SyncBackendType) + * + * @param {Number} pScope - The needed scope (e.g. "calendars.VEVENT", "calendars.VTODO") + * @return {Number} - The backend type (calendars.BACKEND_*) + */ +function getCalendarSystemType (pScope) +{ + // Check sync backend type + if (calendars.getSyncBackendType() != calendars.BACKEND_NONE && calendars.getSyncBackendType() != 3) + { + var scope = calendars.getSyncBackendTypeScope(); + if (scope.length == 1 && scope[0] == pScope) // Scope.length = 1 -> VEVENT *OR* VTODO + return calendars.getSyncBackendType(); + else if (scope.length == 2) // Scope.length = 2 -> Both + return calendars.getSyncBackendType(); + // Scope.length = 0 -> Nothing selected -> Skip this block + } + + // Fallback to backend type (event) + if (calendars.getBackendType() != calendars.BACKEND_NONE && pScope === calendars.VEVENT) + return calendars.getBackendType(); + + // Second fallback to backend type (todo) + if (calendars.getBackendTypeTasks() != calendars.BACKEND_NONE && pScope === calendars.VTODO) + return calendars.getBackendTypeTasks(); + + // Everything is none + return calendars.BACKEND_NONE; +} + +function hasGrantForEntryByMS(pAffectedUsers, pUserMap) +{ + for (let i = 0; i < pAffectedUsers.length; i++) + { + var calUser = getTitleCalenderUser( pAffectedUsers[i][0]); + if(pUserMap[calUser] == undefined) + { + return false; + break; + } + else + return true; + } +} + +function hasGrantForEntryByObject(pAffectedUsers, pUserMap) +{ + for (let i = 0; i < pAffectedUsers.length; i++) + { + calUser = tools.getUserByAttribute(tools.CALENDARID, pAffectedUsers[i]["paramvalue"].substr("mailto:".length)) + if (calUser == null) calUser = pAffectedUsers[i]["cn"]; + else calUser = calUser[tools.TITLE] + if(pUserMap[calUser] == undefined) + { + return false; + break; + } + else + return true; + } +} diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js index beefa84e98a8831b674bc7d235abae67ecf1f185..771323e40270864ef0b87041c3291aac368e57f7 100644 --- a/process/DocumentTemplate_lib/process.js +++ b/process/DocumentTemplate_lib/process.js @@ -113,7 +113,7 @@ DocumentTemplate.types = { */ DocumentTemplate.loadTemplate = function (pAssignmentRowId, pAssignmentTable) { - var alias = "_____SYSTEMALIAS"; + var alias = SqlUtils.getSystemAlias(); if (!pAssignmentTable) pAssignmentTable = "DOCUMENTTEMPLATE"; var templateDocument = db.getBinaryMetadata(pAssignmentTable, "DOCUMENT", pAssignmentRowId, false, alias, null); diff --git a/process/Permission_lib/process.js b/process/Permission_lib/process.js index bec5de949e05a8cad27e1e644de9705220b7630b..d5b1425935b6eb7eeef19f148ddb419b8671781d 100644 --- a/process/Permission_lib/process.js +++ b/process/Permission_lib/process.js @@ -10,7 +10,9 @@ import("Sql_lib"); */ function PermissionUtil () {} -var alias = "_____SYSTEMALIAS"; +{ //block where variables declared with let are available to avoid unexpected side-effects + +let alias = SqlUtils.getSystemAlias(); /** * Returns the ids of all subordinated permission sets of a given parent permission set. @@ -590,6 +592,8 @@ PermissionUtil.deletePermissionAction = function(pPermActionId) { return db.deleteData(table, cond, alias); } +} //end of block + // arrDiff calculates different elements of two arrays and returns them as array, otherwise empty array function arrDiff (arr1, arr2) { diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js index de713fa6707bd85988ac250dc3873bb6006970c4..250a95ee13ddaee794ae0aee7592e8c6a8bbff6e 100644 --- a/process/Util_lib/process.js +++ b/process/Util_lib/process.js @@ -1,615 +1,615 @@ -import("Sql_lib"); -import("system.neon"); -import("system.project"); -import("system.process"); -import("system.db"); -import("system.util"); -import("system.translate"); -import("system.text"); -import("system.vars"); -import("system.swing"); -import("system.question"); -import("system.eMath"); -import("system.datetime"); -import("Offer_lib"); -import("Date_lib"); - -/** - * Class containing static utility functions for string-actions - * Do not create an instance of this - * - * @class - */ -function StringUtils(){} - -/** - * concats severel elements by a separator; the separator is only applied if a element is not null and not an empty string ""; - * - * @param {String} pSeparator specifies how the not empty elements shall be concatenated - * @param {String[]} pElements elements that shall be joined by the separator - * - * @return {String} concatenated string; if all elements are empty an emtpy string is returned - * - */ -StringUtils.concat = function(pSeparator, pElements) -{ - var res = pElements.filter(function(e){ - return e != null && e != ""; - }).join(pSeparator); - return res; -}; - - -/** - * converts a string to a string of always 36 chars. Whitespaces are added at the end if needed. - */ -StringUtils.pad36 = function(pValue) -{ - return (pValue + " ").slice(0, 36); -} - -/** - * Class containing static utility functions for numbers - * Do not create an instance of this - * - * @class - */ -function NumberUtils(){} - -/** - * Check iv the value is inside of the min / max values. - * INCLUDING min / max - * - * @param {Number} pValue value to check - * @param {Number} pMin min value INCLUSIVE - * @param {Number} pMax max value INCLUSIVE - * @param {Boolean} [pIgnoreNull=true] return True if pValue is null - * - * @return {Boolean} - */ -NumberUtils.isInside = function(pValue, pMin, pMax, pIgnoreNull) -{ - if (pIgnoreNull == undefined) - pIgnoreNull = true; - - return pValue >= pMin && pValue <= pMax || pIgnoreNull && (pValue == null || isNaN(pValue)); -}; - -/** - * For use in validationProcess. Calls result.string(...) with error message, if number is not inside of the given values - * INCLUDING min / max. - * - * @param {Number} pTitle title to display in error message. Should be the name of the field and it will be translated. - * @param {Number} pValue value to check - * @param {Number} pMin min value INCLUSIVE - * @param {Number} pMax max value INCLUSIVE - * @param {Boolean} [pIgnoreNull=true] return True if pValue is null - * - * @return {String|False} returns the error message or false - * - * @example - * var value = vars.get("local.value"); <br> - * <br> - * var validationResult = NumberUtils.validateIsBetweenFloat("Discount", value, 0, 100); <br> - * <br> - * if (validationResult) <br> - * { <br> - * result.string(validationResult); <br> - * } <br> - */ -NumberUtils.validateIsBetweenFloat = function(pTitle, pValue, pMin, pMax, pIgnoreNull) -{ - if(pValue.includes(",")) - pValue = pValue.replace(",", "."); - - var discount = parseFloat(pValue); - - if(isNaN(discount)) - return false; - - if (!NumberUtils.isInside(discount, 0, 100, pIgnoreNull)) - { - return (translate.withArguments("${MIN_MAX_ERROR} field: %0, value: %1, min: %2, max: %3", [translate.text(pTitle), discount, pMin, pMax])); - } - return false; -} - -/** - * format Numbers with currency - */ -NumberUtils.formatWithCurrency = function(pNumber, pPattern, pCurrency) -{ - if (pNumber && pPattern) - return text.formatDouble(pNumber, pPattern + " " + pCurrency); - return "0 " + pCurrency; -} - -/** - * Class containing static utility functions for use with arrays - * Do not create an instance of this! - * - * @class - */ -function ArrayUtils() {} - -/** - * returns a distinct list of a two dimensional array - * - * @param {Array} p2dArray the Array where duplicate keys shall be removed - * - * @return 2D-Array that only contains unique entries - */ -ArrayUtils.distinct2d = function(p2dArray) -{ - var tempKeys = {}; - return p2dArray.filter(function(row){ - var key = row.join("-"); - return !(tempKeys[key] = ++tempKeys[key]|0) - }); -}; - -/** - * sorts a two dimensional array by the given index - * - * @param {Array} targetArray the Array to be sorted - * @param {String} index the index of the field to sort by - * @param {Boolean} [sortAsc=false] TRUE sorts ascending, FALSE sorts decending - * @param {Boolean} [isNumber=false] TRUE sorts numerical, FALSE or undefined sorts alphanumerical - * - * @return targetArray - * - * @throws {RangeError} if index is outside pArray.length - */ -ArrayUtils.sort2d = function(targetArray, index, sortAsc, isNumber) { - if (targetArray.length == 0) - return targetArray; - if (targetArray[0].length == 0) - return targetArray; - if (index >= targetArray[0].length) - throw new RangeError("Index Out Of Bounds: " + index + " >= " + targetArray[0].length); - - var sortFn = function (x, y) { - if ( isNumber ) { - xx = Number(x[index]); - yy = Number(y[index]); - } - else { - xx = x[index]; - yy = y[index]; - - xx = xx.toLowerCase(); - xx = xx.replace(/ä/g,"ae"); - xx = xx.replace(/ö/g,"oe"); - xx = xx.replace(/ü/g,"ue"); - xx = xx.replace(/ß/g,"ss"); - - yy = yy.toLowerCase(); - yy = yy.replace(/ä/g,"ae"); - yy = yy.replace(/ö/g,"oe"); - yy = yy.replace(/ü/g,"ue"); - yy = yy.replace(/ß/g,"ss"); - } - if (xx == yy) - return 0; - if (xx < yy) - return (sortAsc ? -1 : 1); - return (sortAsc ? 1 : -1); - } - - targetArray.sort(sortFn); - return targetArray -} - -/** -* sorts an array with columns -* -* @param {Array} targetArray the array with data -* @param {Array} sortOrder array with the format [columnIndex1, sortDescending1, columnIndex2, sortDescending2, ...], -* the columnIndex must be an integer, sortDescending must be boolean (true -> descending, just like db.DESCENDING) -* @example -* ArrayUtils.sortMulti(rows, [1, true, 2, true, 5, false]); -* -* @return {void} -*/ -ArrayUtils.sortMulti = function(targetArray, sortOrder) { - /* - * @param {String} a req value 1, first compared element - * @param {String} b req value 2, sencond compared element - * - * @return {Integer} -1 - set a below b, 0 - equal, 1 - set b below a - */ - var sortFn = function(a, b) { - var stringComparison = function(a, b) { - a = a.toLowerCase(); - a = a.replace(/ä/g,"ae"); - a = a.replace(/ö/g,"oe"); - a = a.replace(/ü/g,"ue"); - a = a.replace(/ß/g,"ss"); - - b = b.toLowerCase(); - b = b.replace(/ä/g,"ae"); - b = b.replace(/ö/g,"oe"); - b = b.replace(/ü/g,"ue"); - b = b.replace(/ß/g,"ss"); - - return( a == b ) ? 0 : ( a > b ) ? 1 : -1; - } - - var swap = 0; - - for (let i = 0, l = sortOrder.length; i < l; i += 2) - { - let colIndex = sortOrder[i]; - let sortDesc = sortOrder[i+1]; - if (swap || colIndex == undefined || sortDesc == undefined) - return swap; - - if (isNaN(a[colIndex] - b[colIndex])) - if ((isNaN(a[colIndex])) && (isNaN(b[colIndex]))) - swap = stringComparison(a[colIndex], b[colIndex]); - else - swap = (isNaN(a[colIndex]) ? 1 : -1); - else - swap = (a[colIndex] - b[colIndex]); - - swap *= (sortDesc ? -1 : 1); - } - return swap; - } - - targetArray.sort(sortFn); - return targetArray; -} - -/** -* removes an specific element from an array -* -* @param {Array} targetArray Array from which the element should be removed -* @param {String} elementPos index of the element which should be removed -* -* @return {Array} array containing the deleted element -*/ -ArrayUtils.removeElement = function(targetArray, elementPos) { - return targetArray.splice(elementPos, 1); -} - -/** - * concats arrays column by column; - * see example for more details - * - * @param {Array} array1 you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want - * @param {Array} arrayN you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want - * - * @return {Array} concatenated array - * - * @example - * var a = ["a", "b", "c"]; - * var b = ["A", "B", "C"]; - * logging.show(JSON.stringify(concatArrayColumns(a, b))); - * //[["a","A"],["b","B"],["c","C"]] - * - * logging.show(JSON.stringify(a.concat(b))); - * //["a","b","c","A","B","C"] - */ -ArrayUtils.concatColumns = function(array1, arrayN) { - var res, i, ii, l, ll, inpArr; - res = []; - - for (i = 0, l = arguments.length; i < l; i++) {//this function can handle an "unlimited" amount of functionparams - inpArr = arguments[i]; - for (ii = 0, ll = inpArr.length; ii < ll; ii++) { - if (res[ii] == undefined) - res[ii] = []; - - res[ii] = res[ii].concat(inpArr[ii]); - } - } - return res; -} - - -/** - * returns if an element is in an array; - * this is needed because there is currently no support for Array.prototype.includes() and we cannot easily use a polyfill and extend the Array.prototype - * - * @param {Array} targetArray array where the element should be searched in - * @param {AnyPrimitiveType} element the element which should be looked for - * @param {Boolean} [ignoreStringCase=false] if you've got a string array y - * - * @return {Boolean} true if it has the element - */ -ArrayUtils.hasElement = function(targetArray, element, ignoreStringCase) { - var i, l; - if (ignoreStringCase)//do only once to save ressources and not for every array element - element = element.toString().toLowerCase(); - for (i = 0, l = targetArray.length; i < l; i++) { - if (ignoreStringCase) { - if (targetArray[i].toString().toLowerCase() == element) - return true; - } - else { - if (targetArray[i] == element) - return true; - } - } - return false; -} - -/** - * joins an array but skips empty elements (null, undefined, "") - * - * @param {Array} pArray the array to join - * @param {String} [pSeparator=", "] the separator - * - * @return {String} the resulting string - */ -ArrayUtils.joinNonEmptyFields = function (pArray, pSeparator) -{ - return pArray.filter(function (element) - { - return element !== null && element !== undefined && element !== ""; - }).join(pSeparator); -} - -/** - * Class containing utility functions for use with JSON - * @class - */ -function JSONUtils() { -} - -/** - * A custom JSON.stringify() to - * - keep the functions as string - * - stringify JavaArrays - * - stringify undefined as undefined and not as null - * - * @param {Object} obj the object to stringify - * - * @return {String} the stringified object as string representation - */ -JSONUtils.customStringify = function(obj) { - //stringify part from JSON polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON - var toString = Object.prototype.toString; - var escMap = { - '"': '\\"', - '\\': '\\\\', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t' - }; - var escFunc = function (m) { - return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); - }; - var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g; - - var stringify = function (value){ - //because: "undefined == null" is true - if (value === undefined) { - return 'undefined'; - } else if (value == null) { - return 'null'; - } else if (typeof value === 'number') { - return isFinite(value) ? value.toString() : 'null'; - } else if (typeof value === 'boolean') { - return value.toString(); - } else if (typeof value === 'object') -{ - //check with "hasOwnProperty" because in JavaArrays using value.toJSON would cause an exception - if (toString.call(value) != '[object Map]' && value.hasOwnProperty("toJSON") && typeof value.toJSON === 'function') { - return value.toString(); - } else if (toString.call(value) === '[object Array]') { - var res = '['; - for (var i = 0; i < value.length; i++) - res += (i ? ', ' : '') + stringify(value[i]); - return res + ']'; - } else if (toString.call(value) === '[object Object]' || toString.call(value) === '[object Map]') { - var tmp = []; - for (var k in value) { - if (hasOwnProperty.call(value, k)) - tmp.push(stringify(k) + ': ' + stringify(value[k])); - } - return '{' + tmp.join(', ') + '}'; - //custom addition to stringify Rhino JavaArrays - } else if (toString.call(value) === '[object JavaArray]') { - return value.toSource().toString(); - } - } - //custom addition for function transform - //JSON.stringify returns null on functions (default) - //instead return source code of funciton for callback-functions - else if (typeof value === 'function') - { - return value.toString(); - } - - return '"' + value.toString().replace(escRE, escFunc) + '"'; - } - - return stringify(obj); -} - -/** - * Class containing functions for Javascript-Objects - * Do not create an instance of this - * - * @class - */ -function ObjectUtils(){} - -/** - * checks if a value exists in the object - * mostly usefull for primitve datatypes - * - * @param pObject {Object} the object where the value is searched - * @param pValue {Boolean|Number|String} the value that is searched - * - * @return {Boolean} true if the value was found, false if not - */ -ObjectUtils.existsValue = function(pObject, pValue) -{ - for (var key in pObject) - { - if (pObject[key] === pValue) - return true; - } - return false; -}; - -/** - * Class containing functions for sequential numbers - * Do not create an instance of this! - * - * @class - */ -function NumberSequencingUtils() {} - -/** - * Delivers the next unique number - * - * @param {String} pColumn database column that contains unique numbers - * @param {String} pTable database table - * @param {Number} [pStartNumber=1000] number to start numeration - * @param {String} [pCondition=no condition] SQL Where Conditon - * - * @result {String} next valid number - */ -NumberSequencingUtils.getNextUniqueNumber = function(pColumn, pTable, pStartNumber, pCondition) { - var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition); - if(maxNum == "0") { - if(pStartNumber == undefined) pStartNumber = 1000; - return pStartNumber; - } - return eMath.addInt(maxNum, "1");//increment currently highest number -} - -/** - * Checks if the passed number is valid (has to be unique) - * - * @param {String} pNumber number to check - * @param {String} pColumn req database column that contains unique numbers - * @param {String} pTable req database table - * @param {String} pCondition opt SQL Where Conditon - * - * @result {boolean} passed number is valid - */ -NumberSequencingUtils.validateUniqueNumber = function(pNumber, pColumn, pTable, pCondition) { - var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition); - return Number(pNumber) > Number(maxNum); -} - -/** - * Delivers the hightest number currently stored in database - * - * @param {String} pColumn req database column that contains unique numbers - * @param {String} pTable req database table - * @param {String} pCondition opt SQL Where Conditon - * - * @result {String} hightest number - */ -NumberSequencingUtils.getMaxUniqueNumber = function(pColumn, pTable, pCondition) { - var condition = ""; - if(pCondition != undefined) - condition += " where " + pCondition; - var maxNum = db.cell("select max(" + pColumn + ") from " + pTable + condition); - return maxNum == "" ? "0" : maxNum; -} - -/** - * functions for trees - * Do not create an instance of this! - * - * @class - */ -function TreeUtils () {} - -/** - * sorts an array in a way that a tree(-table) can be built (parents are added before children) - * This function does not garantee that the order of the children stays the same. If you need this, use TreeUtils.treeOrderBy - * - * consider the use of TreeUtils.treeOrderBy as it may be more performant, but it needs the layernumber of each row. - * - * @param {Array} pArray two-dimensional array to sort - * @param {Number} pUidIndex the index of the uid in a row - * @param {Number} pParentIdIndex the index of the parent id in a row - * - * @return {Array} the sorted array - */ -TreeUtils.sortArrayForTree = function (pArray, pUidIndex, pParentIdIndex) -{ - if (pArray.length <= 1) - return pArray; - var rows = {}; - var allIds = {}; - - pArray.forEach(function (row) {allIds[row[pUidIndex]] = true;}); - var index = 0; - - do { - var oldIndex = index; - pArray.forEach(function (row) - { - if (!(row[pUidIndex] in this) && (row[pParentIdIndex] in this || !allIds[row[pParentIdIndex]])) - this[row[pUidIndex]] = { - data : row, - index : index++ - }; - }, rows); - - /* stop if no new items were added, otherwise incorrect data (for instance - an item that is it's own parent) could cause an infinite loop */ - } while (oldIndex != index); - var sortedArray = new Array(index); - for (let i in rows) - sortedArray[rows[i].index] = rows[i].data; - return sortedArray; -} - -/** - * like TreeUtils.sortArrayForTree, this function garantees that parents are added before children - * But it works in a different way based on the layer number. - * - * It can also sort all children based on the given orderBys. For this you can Probvide an array of Indexes and direction (pOrderByIndexes) - * - * @param {Array} pData two-dimensional array to sort - * @param {Number} pLayerIndex The index of the layernumber-Field - * @param {Array[][]} pOrderByIndexes Array containing arrays of [field-index, direction]. The direction can be true (desc) or false (asc). - * - * @return {Array} the sorted array - */ -TreeUtils.treeOrderBy = function(pData, pLayerIndex, pOrderByIndexes) -{ - pOrderByIndexes = [[pLayerIndex, false]].concat(pOrderByIndexes) - - return pData.sort(function(pRow1, pRow2) - { - for (let i = 0; i < pOrderByIndexes.length; i++) { - var orderBy = pOrderByIndexes[i]; - if (pRow1[orderBy[0]] > pRow2[orderBy[0]]) return (orderBy[1] ? -1 : 1); - if (pRow1[orderBy[0]] < pRow2[orderBy[0]]) return (orderBy[1] ? 1 : -1); - } - - return 0; - }) -} - -/** - * functions for numbered codes - * Do not create an instance of this! - * - * @class - */ -function CodeUtils () {} -/** - * Sets the code of the given Table to the current max-code + 1 - */ -CodeUtils.setCode = function(pId, pTable, pIdCol, pCodeCol) -{ - var max = db.cell("select max(" + pCodeCol + ") from " + pTable); - if (!max) - max = -1; - - db.updateData(pTable, [pCodeCol], null, [parseInt(max)+1], SqlCondition.equals(pTable + "." + pIdCol, pId, "1=2")); +import("Sql_lib"); +import("system.neon"); +import("system.project"); +import("system.process"); +import("system.db"); +import("system.util"); +import("system.translate"); +import("system.text"); +import("system.vars"); +import("system.swing"); +import("system.question"); +import("system.eMath"); +import("system.datetime"); +import("Offer_lib"); +import("Date_lib"); + +/** + * Class containing static utility functions for string-actions + * Do not create an instance of this + * + * @class + */ +function StringUtils(){} + +/** + * concats severel elements by a separator; the separator is only applied if a element is not null and not an empty string ""; + * + * @param {String} pSeparator specifies how the not empty elements shall be concatenated + * @param {String[]} pElements elements that shall be joined by the separator + * + * @return {String} concatenated string; if all elements are empty an emtpy string is returned + * + */ +StringUtils.concat = function(pSeparator, pElements) +{ + var res = pElements.filter(function(e){ + return e != null && e != ""; + }).join(pSeparator); + return res; +}; + + +/** + * converts a string to a string of always 36 chars. Whitespaces are added at the end if needed. + */ +StringUtils.pad36 = function(pValue) +{ + return (pValue + " ").slice(0, 36); +} + +/** + * Class containing static utility functions for numbers + * Do not create an instance of this + * + * @class + */ +function NumberUtils(){} + +/** + * Check iv the value is inside of the min / max values. + * INCLUDING min / max + * + * @param {Number} pValue value to check + * @param {Number} pMin min value INCLUSIVE + * @param {Number} pMax max value INCLUSIVE + * @param {Boolean} [pIgnoreNull=true] return True if pValue is null + * + * @return {Boolean} + */ +NumberUtils.isInside = function(pValue, pMin, pMax, pIgnoreNull) +{ + if (pIgnoreNull == undefined) + pIgnoreNull = true; + + return pValue >= pMin && pValue <= pMax || pIgnoreNull && (pValue == null || isNaN(pValue)); +}; + +/** + * For use in validationProcess. Calls result.string(...) with error message, if number is not inside of the given values + * INCLUDING min / max. + * + * @param {Number} pTitle title to display in error message. Should be the name of the field and it will be translated. + * @param {Number} pValue value to check + * @param {Number} pMin min value INCLUSIVE + * @param {Number} pMax max value INCLUSIVE + * @param {Boolean} [pIgnoreNull=true] return True if pValue is null + * + * @return {String|False} returns the error message or false + * + * @example + * var value = vars.get("local.value"); <br> + * <br> + * var validationResult = NumberUtils.validateIsBetweenFloat("Discount", value, 0, 100); <br> + * <br> + * if (validationResult) <br> + * { <br> + * result.string(validationResult); <br> + * } <br> + */ +NumberUtils.validateIsBetweenFloat = function(pTitle, pValue, pMin, pMax, pIgnoreNull) +{ + if(pValue.includes(",")) + pValue = pValue.replace(",", "."); + + var discount = parseFloat(pValue); + + if(isNaN(discount)) + return false; + + if (!NumberUtils.isInside(discount, 0, 100, pIgnoreNull)) + { + return (translate.withArguments("${MIN_MAX_ERROR} field: %0, value: %1, min: %2, max: %3", [translate.text(pTitle), discount, pMin, pMax])); + } + return false; +} + +/** + * format Numbers with currency + */ +NumberUtils.formatWithCurrency = function(pNumber, pPattern, pCurrency) +{ + if (pNumber && pPattern) + return text.formatDouble(pNumber, pPattern + " " + pCurrency); + return "0 " + pCurrency; +} + +/** + * Class containing static utility functions for use with arrays + * Do not create an instance of this! + * + * @class + */ +function ArrayUtils() {} + +/** + * returns a distinct list of a two dimensional array + * + * @param {Array} p2dArray the Array where duplicate keys shall be removed + * + * @return 2D-Array that only contains unique entries + */ +ArrayUtils.distinct2d = function(p2dArray) +{ + var tempKeys = {}; + return p2dArray.filter(function(row){ + var key = row.join("-"); + return !(tempKeys[key] = ++tempKeys[key]|0) + }); +}; + +/** + * sorts a two dimensional array by the given index + * + * @param {Array} targetArray the Array to be sorted + * @param {String} index the index of the field to sort by + * @param {Boolean} [sortAsc=false] TRUE sorts ascending, FALSE sorts decending + * @param {Boolean} [isNumber=false] TRUE sorts numerical, FALSE or undefined sorts alphanumerical + * + * @return targetArray + * + * @throws {RangeError} if index is outside pArray.length + */ +ArrayUtils.sort2d = function(targetArray, index, sortAsc, isNumber) { + if (targetArray.length == 0) + return targetArray; + if (targetArray[0].length == 0) + return targetArray; + if (index >= targetArray[0].length) + throw new RangeError("Index Out Of Bounds: " + index + " >= " + targetArray[0].length); + + var sortFn = function (x, y) { + if ( isNumber ) { + xx = Number(x[index]); + yy = Number(y[index]); + } + else { + xx = x[index]; + yy = y[index]; + + xx = xx.toLowerCase(); + xx = xx.replace(/ä/g,"ae"); + xx = xx.replace(/ö/g,"oe"); + xx = xx.replace(/ü/g,"ue"); + xx = xx.replace(/ß/g,"ss"); + + yy = yy.toLowerCase(); + yy = yy.replace(/ä/g,"ae"); + yy = yy.replace(/ö/g,"oe"); + yy = yy.replace(/ü/g,"ue"); + yy = yy.replace(/ß/g,"ss"); + } + if (xx == yy) + return 0; + if (xx < yy) + return (sortAsc ? -1 : 1); + return (sortAsc ? 1 : -1); + } + + targetArray.sort(sortFn); + return targetArray +} + +/** +* sorts an array with columns +* +* @param {Array} targetArray the array with data +* @param {Array} sortOrder array with the format [columnIndex1, sortDescending1, columnIndex2, sortDescending2, ...], +* the columnIndex must be an integer, sortDescending must be boolean (true -> descending, just like db.DESCENDING) +* @example +* ArrayUtils.sortMulti(rows, [1, true, 2, true, 5, false]); +* +* @return {void} +*/ +ArrayUtils.sortMulti = function(targetArray, sortOrder) { + /* + * @param {String} a req value 1, first compared element + * @param {String} b req value 2, sencond compared element + * + * @return {Integer} -1 - set a below b, 0 - equal, 1 - set b below a + */ + var sortFn = function(a, b) { + var stringComparison = function(a, b) { + a = a.toLowerCase(); + a = a.replace(/ä/g,"ae"); + a = a.replace(/ö/g,"oe"); + a = a.replace(/ü/g,"ue"); + a = a.replace(/ß/g,"ss"); + + b = b.toLowerCase(); + b = b.replace(/ä/g,"ae"); + b = b.replace(/ö/g,"oe"); + b = b.replace(/ü/g,"ue"); + b = b.replace(/ß/g,"ss"); + + return( a == b ) ? 0 : ( a > b ) ? 1 : -1; + } + + var swap = 0; + + for (let i = 0, l = sortOrder.length; i < l; i += 2) + { + let colIndex = sortOrder[i]; + let sortDesc = sortOrder[i+1]; + if (swap || colIndex == undefined || sortDesc == undefined) + return swap; + + if (isNaN(a[colIndex] - b[colIndex])) + if ((isNaN(a[colIndex])) && (isNaN(b[colIndex]))) + swap = stringComparison(a[colIndex], b[colIndex]); + else + swap = (isNaN(a[colIndex]) ? 1 : -1); + else + swap = (a[colIndex] - b[colIndex]); + + swap *= (sortDesc ? -1 : 1); + } + return swap; + } + + targetArray.sort(sortFn); + return targetArray; +} + +/** +* removes an specific element from an array +* +* @param {Array} targetArray Array from which the element should be removed +* @param {String} elementPos index of the element which should be removed +* +* @return {Array} array containing the deleted element +*/ +ArrayUtils.removeElement = function(targetArray, elementPos) { + return targetArray.splice(elementPos, 1); +} + +/** + * concats arrays column by column; + * see example for more details + * + * @param {Array} array1 you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want + * @param {Array} arrayN you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want + * + * @return {Array} concatenated array + * + * @example + * var a = ["a", "b", "c"]; + * var b = ["A", "B", "C"]; + * logging.show(JSON.stringify(concatArrayColumns(a, b))); + * //[["a","A"],["b","B"],["c","C"]] + * + * logging.show(JSON.stringify(a.concat(b))); + * //["a","b","c","A","B","C"] + */ +ArrayUtils.concatColumns = function(array1, arrayN) { + var res, i, ii, l, ll, inpArr; + res = []; + + for (i = 0, l = arguments.length; i < l; i++) {//this function can handle an "unlimited" amount of functionparams + inpArr = arguments[i]; + for (ii = 0, ll = inpArr.length; ii < ll; ii++) { + if (res[ii] == undefined) + res[ii] = []; + + res[ii] = res[ii].concat(inpArr[ii]); + } + } + return res; +} + + +/** + * returns if an element is in an array; + * this is needed because there is currently no support for Array.prototype.includes() and we cannot easily use a polyfill and extend the Array.prototype + * + * @param {Array} targetArray array where the element should be searched in + * @param {AnyPrimitiveType} element the element which should be looked for + * @param {Boolean} [ignoreStringCase=false] if you've got a string array y + * + * @return {Boolean} true if it has the element + */ +ArrayUtils.hasElement = function(targetArray, element, ignoreStringCase) { + var i, l; + if (ignoreStringCase)//do only once to save ressources and not for every array element + element = element.toString().toLowerCase(); + for (i = 0, l = targetArray.length; i < l; i++) { + if (ignoreStringCase) { + if (targetArray[i].toString().toLowerCase() == element) + return true; + } + else { + if (targetArray[i] == element) + return true; + } + } + return false; +} + +/** + * joins an array but skips empty elements (null, undefined, "") + * + * @param {Array} pArray the array to join + * @param {String} [pSeparator=", "] the separator + * + * @return {String} the resulting string + */ +ArrayUtils.joinNonEmptyFields = function (pArray, pSeparator) +{ + return pArray.filter(function (element) + { + return element !== null && element !== undefined && element !== ""; + }).join(pSeparator); +} + +/** + * Class containing utility functions for use with JSON + * @class + */ +function JSONUtils() { +} + +/** + * A custom JSON.stringify() to + * - keep the functions as string + * - stringify JavaArrays + * - stringify undefined as undefined and not as null + * + * @param {Object} obj the object to stringify + * + * @return {String} the stringified object as string representation + */ +JSONUtils.customStringify = function(obj) { + //stringify part from JSON polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON + var toString = Object.prototype.toString; + var escMap = { + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t' + }; + var escFunc = function (m) { + return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); + }; + var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g; + + var stringify = function (value){ + //because: "undefined == null" is true + if (value === undefined) { + return 'undefined'; + } else if (value == null) { + return 'null'; + } else if (typeof value === 'number') { + return isFinite(value) ? value.toString() : 'null'; + } else if (typeof value === 'boolean') { + return value.toString(); + } else if (typeof value === 'object') +{ + //check with "hasOwnProperty" because in JavaArrays using value.toJSON would cause an exception + if (toString.call(value) != '[object Map]' && value.hasOwnProperty("toJSON") && typeof value.toJSON === 'function') { + return value.toString(); + } else if (toString.call(value) === '[object Array]') { + var res = '['; + for (var i = 0; i < value.length; i++) + res += (i ? ', ' : '') + stringify(value[i]); + return res + ']'; + } else if (toString.call(value) === '[object Object]' || toString.call(value) === '[object Map]') { + var tmp = []; + for (var k in value) { + if (hasOwnProperty.call(value, k)) + tmp.push(stringify(k) + ': ' + stringify(value[k])); + } + return '{' + tmp.join(', ') + '}'; + //custom addition to stringify Rhino JavaArrays + } else if (toString.call(value) === '[object JavaArray]') { + return value.toSource().toString(); + } + } + //custom addition for function transform + //JSON.stringify returns null on functions (default) + //instead return source code of funciton for callback-functions + else if (typeof value === 'function') + { + return value.toString(); + } + + return '"' + value.toString().replace(escRE, escFunc) + '"'; + } + + return stringify(obj); +} + +/** + * Class containing functions for Javascript-Objects + * Do not create an instance of this + * + * @class + */ +function ObjectUtils(){} + +/** + * checks if a value exists in the object + * mostly usefull for primitve datatypes + * + * @param pObject {Object} the object where the value is searched + * @param pValue {Boolean|Number|String} the value that is searched + * + * @return {Boolean} true if the value was found, false if not + */ +ObjectUtils.existsValue = function(pObject, pValue) +{ + for (var key in pObject) + { + if (pObject[key] === pValue) + return true; + } + return false; +}; + +/** + * Class containing functions for sequential numbers + * Do not create an instance of this! + * + * @class + */ +function NumberSequencingUtils() {} + +/** + * Delivers the next unique number + * + * @param {String} pColumn database column that contains unique numbers + * @param {String} pTable database table + * @param {Number} [pStartNumber=1000] number to start numeration + * @param {String} [pCondition=no condition] SQL Where Conditon + * + * @result {String} next valid number + */ +NumberSequencingUtils.getNextUniqueNumber = function(pColumn, pTable, pStartNumber, pCondition) { + var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition); + if(maxNum == "0") { + if(pStartNumber == undefined) pStartNumber = 1000; + return pStartNumber; + } + return eMath.addInt(maxNum, "1");//increment currently highest number +} + +/** + * Checks if the passed number is valid (has to be unique) + * + * @param {String} pNumber number to check + * @param {String} pColumn req database column that contains unique numbers + * @param {String} pTable req database table + * @param {String} pCondition opt SQL Where Conditon + * + * @result {boolean} passed number is valid + */ +NumberSequencingUtils.validateUniqueNumber = function(pNumber, pColumn, pTable, pCondition) { + var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition); + return Number(pNumber) > Number(maxNum); +} + +/** + * Delivers the hightest number currently stored in database + * + * @param {String} pColumn req database column that contains unique numbers + * @param {String} pTable req database table + * @param {String} pCondition opt SQL Where Conditon + * + * @result {String} hightest number + */ +NumberSequencingUtils.getMaxUniqueNumber = function(pColumn, pTable, pCondition) { + var condition = ""; + if(pCondition != undefined) + condition += " where " + pCondition; + var maxNum = db.cell("select max(" + pColumn + ") from " + pTable + condition); + return maxNum == "" ? "0" : maxNum; +} + +/** + * functions for trees + * Do not create an instance of this! + * + * @class + */ +function TreeUtils () {} + +/** + * sorts an array in a way that a tree(-table) can be built (parents are added before children) + * This function does not garantee that the order of the children stays the same. If you need this, use TreeUtils.treeOrderBy + * + * consider the use of TreeUtils.treeOrderBy as it may be more performant, but it needs the layernumber of each row. + * + * @param {Array} pArray two-dimensional array to sort + * @param {Number} pUidIndex the index of the uid in a row + * @param {Number} pParentIdIndex the index of the parent id in a row + * + * @return {Array} the sorted array + */ +TreeUtils.sortArrayForTree = function (pArray, pUidIndex, pParentIdIndex) +{ + if (pArray.length <= 1) + return pArray; + var rows = {}; + var allIds = {}; + + pArray.forEach(function (row) {allIds[row[pUidIndex]] = true;}); + var index = 0; + + do { + var oldIndex = index; + pArray.forEach(function (row) + { + if (!(row[pUidIndex] in this) && (row[pParentIdIndex] in this || !allIds[row[pParentIdIndex]])) + this[row[pUidIndex]] = { + data : row, + index : index++ + }; + }, rows); + + /* stop if no new items were added, otherwise incorrect data (for instance + an item that is it's own parent) could cause an infinite loop */ + } while (oldIndex != index); + var sortedArray = new Array(index); + for (let i in rows) + sortedArray[rows[i].index] = rows[i].data; + return sortedArray; +} + +/** + * like TreeUtils.sortArrayForTree, this function garantees that parents are added before children + * But it works in a different way based on the layer number. + * + * It can also sort all children based on the given orderBys. For this you can Probvide an array of Indexes and direction (pOrderByIndexes) + * + * @param {Array} pData two-dimensional array to sort + * @param {Number} pLayerIndex The index of the layernumber-Field + * @param {Array[][]} pOrderByIndexes Array containing arrays of [field-index, direction]. The direction can be true (desc) or false (asc). + * + * @return {Array} the sorted array + */ +TreeUtils.treeOrderBy = function(pData, pLayerIndex, pOrderByIndexes) +{ + pOrderByIndexes = [[pLayerIndex, false]].concat(pOrderByIndexes) + + return pData.sort(function(pRow1, pRow2) + { + for (let i = 0; i < pOrderByIndexes.length; i++) { + var orderBy = pOrderByIndexes[i]; + if (pRow1[orderBy[0]] > pRow2[orderBy[0]]) return (orderBy[1] ? -1 : 1); + if (pRow1[orderBy[0]] < pRow2[orderBy[0]]) return (orderBy[1] ? 1 : -1); + } + + return 0; + }) +} + +/** + * functions for numbered codes + * Do not create an instance of this! + * + * @class + */ +function ConsecutiveCodeUtils () {} +/** + * Sets the code of the given Table to the current max-code + 1 + */ +ConsecutiveCodeUtils.setCode = function(pId, pTable, pIdCol, pCodeCol) +{ + var max = db.cell("select max(" + pCodeCol + ") from " + pTable); + if (!max) + max = -1; + + db.updateData(pTable, [pCodeCol], null, [parseInt(max)+1], SqlCondition.equals(pTable + "." + pIdCol, pId, "1=2")); } \ No newline at end of file diff --git a/process/_test_clientProcess/process.js b/process/_test_clientProcess/process.js index 9161a9a2bede588a70ca5152ecd6bf9e7e70bede..273b7362004c369f828a237f97eafb777ee393d7 100644 --- a/process/_test_clientProcess/process.js +++ b/process/_test_clientProcess/process.js @@ -1,20 +1,21 @@ -import("system.datetime"); -import("system.util"); -import("system.logging"); -import("Liquibase_lib"); -import("system.db"); -import("system.fileIO"); - -var alias = "_____SYSTEMALIAS"; -//var alias = "betterDataSys"; -//var alias = "betterData"; -//var alias = db.getCurrentAlias(); -var outFolderPath = "C:\\temp\\generatedData\\" + alias + "\\"; - -var excludedTables = ["AB_COUNTRYINFO", "AB_LANGUAGE"]; -//LiquiUtils.exportAllTablesAsLiquibaseFiles(outFolderPath, null, alias, excludedTables, true); - -alias = "_____SYSTEMALIAS"; -outFolderPath = "C:\\temp\\generatedData\\" + alias + "\\"; -LiquiUtils.exportTableAsLiquibaseFiles(outFolderPath, "ASYS_USERS", null, "PROPKEY in ('mailserverAlias', 'userserverEnabled') ", null, false, alias); +import("Sql_lib"); +import("system.datetime"); +import("system.util"); +import("system.logging"); +import("Liquibase_lib"); +import("system.db"); +import("system.fileIO"); + +var alias = SqlUtils.getSystemAlias(); +//var alias = "betterDataSys"; +//var alias = "betterData"; +//var alias = db.getCurrentAlias(); +var outFolderPath = "C:\\temp\\generatedData\\" + alias + "\\"; + +var excludedTables = ["AB_COUNTRYINFO", "AB_LANGUAGE"]; +//LiquiUtils.exportAllTablesAsLiquibaseFiles(outFolderPath, null, alias, excludedTables, true); + +alias = SqlUtils.getSystemAlias(); +outFolderPath = "C:\\temp\\generatedData\\" + alias + "\\"; +LiquiUtils.exportTableAsLiquibaseFiles(outFolderPath, "ASYS_USERS", null, "PROPKEY in ('mailserverAlias', 'userserverEnabled') ", null, false, alias); logging.log("finish"); \ No newline at end of file