From 74c19d98759093294272635c6b63dc79b421d70d Mon Sep 17 00:00:00 2001 From: "j.goderbauer" <j.goderbauer@adito.de> Date: Mon, 20 May 2019 13:46:00 +0200 Subject: [PATCH] DataCaching: Keyword --- process/DataCaching_lib/process.js | 37 +- process/KeywordData_lib/KeywordData_lib.aod | 9 + process/KeywordData_lib/process.js | 63 + process/Keyword_lib/process.js | 1387 +++++++++---------- 4 files changed, 766 insertions(+), 730 deletions(-) create mode 100644 process/KeywordData_lib/KeywordData_lib.aod create mode 100644 process/KeywordData_lib/process.js diff --git a/process/DataCaching_lib/process.js b/process/DataCaching_lib/process.js index 7bbcf1d23c..715ad6e2fd 100644 --- a/process/DataCaching_lib/process.js +++ b/process/DataCaching_lib/process.js @@ -10,7 +10,7 @@ function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride) if (pLocaleOverride) this.locale = pLocaleOverride; else if (this.runningOnServer) - this.locale = vars.get("$sys.serverlocale"); + this.locale = null;//Server has currently no caching so there is no need to detect the language since there does nothing exist like language-dependent caching on the server-side else this.locale = (this.keepPerLanguage ? vars.get("$sys.clientlocale") : "_anyLanguage_"); } @@ -67,13 +67,8 @@ CachedData.prototype.getVariableName = function() }; //functions for registry of variables; reserver for later functionality -CachedData.prototype._register = function() -{ - var reg = CachedData.getRegistry(); - reg.push(this.getVariableName()); - vars.set(CachedData.getRegistryName(), reg); -} -//CachedData.prototype._unregister = function(){} +CachedData.prototype._register = function(){}; +CachedData.prototype._unregister = function(){}; CachedData.getRegistryName = function() { @@ -87,28 +82,4 @@ CachedData.getRegistry = function() return vars.get(registryVarname); else return []; -}; -// -//CachedData.prototype._register = function() -//{ -// var registry = CachedData.getRegistry(); -// -// if (registry[this.getVariableIdentifier()]) -// -// if (registry[this.getVariableName()] != undefined) -// throw new Error("Already registered. cannot register the same object twice");//TODO: message -// else -// registry[this.getVariableName()] = {keepPerLanguage: this.keepPerLanguage}; -// vars.set(CachedData.getRegistryName(), registry); -//}; -// -//CachedData.prototype._unregister = function() -//{ -// var varname = this.getVariableName(); -// var registry = CachedData.getRegistry(); -// if (registry[varname] == undefined) -// throw new Error("Item not found. cannot unregister");//TODO: message -// else -// delete registry[varname]; -// vars.set(CachedData.getRegistryName(), registry); -//}; +}; \ No newline at end of file diff --git a/process/KeywordData_lib/KeywordData_lib.aod b/process/KeywordData_lib/KeywordData_lib.aod new file mode 100644 index 0000000000..a4aab38ec5 --- /dev/null +++ b/process/KeywordData_lib/KeywordData_lib.aod @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1"> + <name>KeywordData_lib</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/KeywordData_lib/process.js</process> + <variants> + <element>LIBRARY</element> + </variants> +</process> diff --git a/process/KeywordData_lib/process.js b/process/KeywordData_lib/process.js new file mode 100644 index 0000000000..dc4ad29070 --- /dev/null +++ b/process/KeywordData_lib/process.js @@ -0,0 +1,63 @@ +import("system.translate"); +import("system.db"); +import("DataCaching_lib"); + +function KeywordData(){} + +KeywordData.getSimpleData = function (pKeywordContainer, pLocale) +{ + var cache = new CachedData("KeywordSimpleData_" + pKeywordContainer, true, pLocale); + return cache.load(function (pTranslationNecessary, pLocale){ + var cond = SqlCondition.begin().andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pKeywordContainer); + var keywordData = db.table(cond.buildSql(("select AB_KEYWORD_ENTRY.KEYID, AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY"))); + + for (var i = 0, l = keywordData.length; i < l; i++) + { + keywordData[i][1] = translate.text(keywordData[i][1], pLocale); + } + return keywordData.slice(0); + }); +}; + +KeywordData.getKeyIdMap = function (pKeywordContainer, pLocale) +{ + var cache = new CachedData("KeywordKeyidMap_" + pKeywordContainer, true, pLocale); + return cache.load(function (pTranslationNecessary, pLocale){ + var keywordData = KeywordData.getSimpleData(pKeywordContainer, pLocale) + var res = {}; + var keyid, title; + for (var i = 0, l = keywordData.length; i < l; i++) + { + [keyid, title] = keywordData[i]; + res[keyid] = title;//title comes already translated through the getData-function + } + return res; + }); +}; + +function LanguageData(){} + +LanguageData.getData = function() +{ + var cache = new CachedData("LanguagesData", false); + return cache.load(function (pTranslationNecessary, pLocale){ + var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE"); + return data; + }); +}; + +LanguageData.getIso3Map = function(pLocale) +{ + var cache = new CachedData("LanguagesISO3Map", true, pLocale); + return cache.load(function (pTranslationNecessary, pLocale){ + var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE"); + var res = {}; + var iso3, countryName; + for (var i = 0, l = data.length; i < l; i++) + { + [iso3, countryName] = data[i]; + res[iso3] = translate.text(countryName, pLocale); + } + return res; + }); +}; \ No newline at end of file diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js index 3fc2480b3e..6da81f3e14 100644 --- a/process/Keyword_lib/process.js +++ b/process/Keyword_lib/process.js @@ -1,697 +1,690 @@ -import("system.vars"); -import("system.SQLTYPES"); -import("system.db"); -import("system.translate"); -import("system.neon"); -import("Sql_lib"); - -/** - * provides methods for interactions with keywords - * - * @class - */ -function KeywordUtils(){} - -/** -* resolves KEYIDs of a keywordentry into the specific title -* -* @param {String} pContainerName name of the keyword container that shall be resolved -* @param {String} pDbFieldName name fo the database field where the KEYID-value is stored -* @param {String} [pLocale=current client language] specifies the locale for translating the title; can be false if nothing shalle be translated -* -* @return {String} a SQL-expression (case-when-statement) that resolves the KEYID into the title -*/ -KeywordUtils.getResolvedTitleSqlPart = function(pContainerName, pDbFieldName, pLocale) -{ - var cond = SqlCondition.begin().andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName); - var keywordData = db.table(cond.buildSql(("select AB_KEYWORD_ENTRY.KEYID, AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY"))); - var resSql = SqlUtils.getResolvingCaseWhen(keywordData, pDbFieldName, pLocale); - return db.translateStatement(resSql); -}; - -/** - * returns a specific name (translated) - this is normally the view-value - of a given keyword; - * <br/>if the key could not be found an empty string "" is returned - * @param {String} keywordContainer specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @param {String} key id value of the keyword where the view-value shall be searched - * @param {String} [locale=locale depending on current client/servercontext] Language-value for translations - * @return {String} representation of the translated name of the keyword-key - * @example - * var histMedium; - * histMedium = vars.get("$field.MEDIUM"); - * if (histMedium){ - * result.string(vars.get("$field.SUBJECT") + " (" + LegacyKeywordUtils.getViewValue("ACTIVITY.MEDIUM", histMedium) + ")"); - * } - */ -KeywordUtils.getViewValue = function(keywordContainer, key, locale) -{ - if (!key) - return ""; - - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", keywordContainer) - .andPrepare("AB_KEYWORD_ENTRY.KEYID", key) - .buildSql("select AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY"); - var originalTitle = db.cell(sql); - if (originalTitle == "") - return ""; - var translatedTitle = locale ? translate.text(originalTitle, locale) : translate.text(originalTitle); - return translatedTitle; -}; - -/** - * collects possible and defined keyword-attributes per keyword entry and returns them - * - * @param {String} pEntryId id that identifies the keyword-entry whoes attributes are collected - * @return {Object} key-value-pair of the keyword-attributes; contains all attribute-keys for the keywords-entries container; - * if there is no value set for a key the null-value is given - */ -KeywordUtils.getAttributeRelationsByEntryId = function(pEntryId) -{ - var cond = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID", pEntryId); - - return KeywordUtils._getKeywordAttributeRelations(cond); -}; - -/** - * collects possible and defined keyword-attributes per keyword entry and returns them - * - * @param {String} pKeyId the key of an element within a containerName - this is the value that is stored in the reference-table (e.g. "DE") - * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; - * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here - * @return {Object} key-value-pair of the keyword-attributes; contains all attribute-keys for the keywords-entries container; - * if there is no value set for a key the null-value is given - */ -KeywordUtils.getAttributeRelationsByKey = function(pKeyId, pContainerName) -{ - var cond = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName); - - return KeywordUtils._getKeywordAttributeRelations(cond); -}; - -/** - * internal function that collects possible and defined keyword-attributes per keyword entry and returns them - * - * @param {SqlCondition} pSqlCondition condition that shrinks a resultset to one AB_KEYWORD_ENTRY - * @return {Object} SQL-Condition object that filters - */ -KeywordUtils._getKeywordAttributeRelations = function (pSqlCondition) -{ - var cond = pSqlCondition; - var sql = cond.buildSql("select AB_KEYWORD_ATTRIBUTE.NAME, AB_KEYWORD_ATTRIBUTE.TYPE, \n\ - AB_KEYWORD_ATTRIBUTERELATION.CHAR_VALUE, AB_KEYWORD_ATTRIBUTERELATION.NUMBER_VALUE, AB_KEYWORD_ATTRIBUTERELATION.BOOL_VALUE \n\ - from AB_KEYWORD_ENTRY \n\ - join AB_KEYWORD_ATTRIBUTE on (AB_KEYWORD_ATTRIBUTE.CONTAINER = AB_KEYWORD_ENTRY.CONTAINER) \n\ - left join AB_KEYWORD_ATTRIBUTERELATION \n\ - on (AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID = AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID\n\ - and AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID = AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID)"); - - var data = db.table(sql); - var res = {}; - var name, type, charVal, numVal, boolVal; - - for (var i = 0, l = data.length; i < l; i++) - { - [name, type, charVal, numVal, boolVal] = data[i]; - name = name.trim(); - type = type.trim(); - var parsedValue = null; - switch(type) - { - case "NUMBER_VALUE": - parsedValue = numVal == "" ? null : Number(numVal); - break; - case "BOOL_VALUE": - parsedValue = boolVal == "" ? null : (boolVal == "1"); - break; - case "CHAR_VALUE": - parsedValue = charVal == "" ? null : charVal; - break; - } - - res[name] = parsedValue; - } - return res; -}; - -/** -* provides a distinctive list of all keyword-container-names in the system -* -* @return {String[]} containerNames as 1D-Array -*/ -KeywordUtils.getContainerNames = function() -{ - var list = db.array(db.COLUMN, "select distinct AB_KEYWORD_ENTRY.CONTAINER from AB_KEYWORD_ENTRY order by AB_KEYWORD_ENTRY.CONTAINER asc"); - return list; -}; - -/** -* provides a translated list of keyword-entry-titles in the system filtered by a containerName; -* usefull for lists where the key is the name which is then a editable displayValue -* -* @param {String} pContainerName name of the keyword container for filtering -* @param {String} [pLocale=locale depending on current client/servercontext] Language-value for translations -* -* @return {String[]} translated titles as 1D-Array -*/ -KeywordUtils.getEntryNamesByContainer = function(pContainerName, pLocale) -{ - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) - .buildSql("select AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY", null, "order by AB_KEYWORD_ENTRY.SORTING asc, AB_KEYWORD_ENTRY.TITLE asc") - var list = db.array(db.COLUMN, sql).map(function (v){ - return pLocale ? translate.text(v, pLocale) : translate.text(v); - }); - return list; -}; - - -/** -* provides a translated list of keyword-entry-titles and its ids in the system filtered by a containerName; -* usefull for lists where the key is the name which is then a editable displayValue -* -* @param {String} pContainerName name of the keyword container for filtering -* * @param {String} [pLocale=locale depending on current client/servercontext] Language-value for translations -* -* @return {String[]} 2D-Array in the form of [[id1, translatedTitle1], [idN, translatedTitleN]] -*/ -KeywordUtils.getEntryNamesAndIdsByContainer = function(pContainerName, pLocale) -{ - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) - .buildSql("select AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID, AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY", null, "order by AB_KEYWORD_ENTRY.SORTING asc, AB_KEYWORD_ENTRY.TITLE asc") - - var list = db.table(sql).map(function (elem){ - elem[1] = pLocale ? translate.text(elem[1], pLocale) : translate.text(elem[1]); - return elem; - }); - return list; -}; - -/** - * checks, if a specific keyword exists - * - * @param {String} pKeyId the key of an element within a containerName - this is the value that is stored in the reference-table (e.g. "DE") - * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; - * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here - * - * @return {Boolean} - */ -KeywordUtils.exists = function(pKeyId, pContainerName) -{ - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) - .buildSql("select count(*) from AB_KEYWORD_ENTRY", "1=2") - return parseInt(db.cell(sql)) > 0; -}; - -/** - * get the translated container name. - * - * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; - * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here - * @return translated name, if it exists in the switch case - */ -KeywordUtils.getTranslatedContainer = function(pContainerName) -{ - switch (pContainerName) - { - case "SalesprojectPhase": - return translate.text("Phase"); - case "SalesprojectState": - return translate.text("State"); - break; - default: - return "Please add " + pContainerName + " to the switch case in Salesproject_lib"; - } - -} - -/** - * object that provides featrues for a single keyword attribute; initalizes itself on creation with a specific keyword-attribute - * - * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; - * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here - * @param {String} pAttributeName the name of the keyword attribute that shall be initalized - * - * @class - */ -function KeywordAttribute(pContainerName, pAttributeName) -{ - this.container = pContainerName; - this.attribute = pAttributeName; - - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ATTRIBUTE.CONTAINER", pContainerName) - .andPrepare("AB_KEYWORD_ATTRIBUTE.NAME", pAttributeName) - .buildSql("select AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID, AB_KEYWORD_ATTRIBUTE.TYPE from AB_KEYWORD_ATTRIBUTE"); - - var keywordAttrData = db.array(db.ROW, sql); - - if (keywordAttrData.length == 0) - throw new Error(translate.withArguments("no keyword attribute \"%0\" found in keyword container \"%1\"", [this.attribute, this.container])); - - this.id = keywordAttrData[0]; - this.type = keywordAttrData[1]; - this.dbField = this.type.trim(); -} - -KeywordAttribute.prototype.getValue = function(pKeyId) -{ - var sql = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", this.container) - .andPrepare("AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID", this.id) - .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) - .buildSql("select " + this.dbField + " from AB_KEYWORD_ENTRY join AB_KEYWORD_ATTRIBUTERELATION on AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID = AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID"); - - return db.cell(sql); -} - -/** - * provides methods for interactions with the sepcial-keywords "LANGUAGE" - * - * @class - */ -function LanguageKeywordUtils(){} - -/** -* resolves Languagecode into the latin name -* -* @param {String} pDbFieldName name fo the database field where the ISO3-value is stored -* @param {String} [pLocale=current client language] specifies the locale for translating the title; can be false if nothing shalle be translated -* -* @return {String} a SQL-expression (case-when-statement) -*/ -LanguageKeywordUtils.getResolvedTitleSqlPart = function(pDbFieldName, pLocale) -{ - var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE"); - var resSql = SqlUtils.getResolvingCaseWhen(data, pDbFieldName, pLocale); - return db.translateStatement(resSql); -}; - -/** - * returns a specific name (translated) - this is normally the view-value of a language - * - * @param {String} key id value of the language where the view-value shall be searched - * @param {String} [locale=locale depending on current client/servercontext] Language-value for translations - * - * @return {String} representation of the translated name - * - */ -LanguageKeywordUtils.getViewValue = function(key, locale) -{ - if (!key) - return ""; - - var sql = SqlCondition.begin() - .andPrepare("AB_LANGUAGE.ISO3", key) - .buildSql("select AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE"); - var originalTitle = db.cell(sql); - if (originalTitle == "") - return ""; - var translatedTitle = locale ? translate.text(originalTitle, locale) : translate.text(originalTitle); - return translatedTitle; -}; - - -/** - * provides methods for interactions with legcy keywords - * @deprecated use instead the new meachanism via the KeywordUtils - * - * @class - */ -function LegacyKeywordUtils(){} - -(function(){//scope for private functions - - - /** - * returns the default case for keyword-arrays (id and translated name) - * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @return {Array} a 2D array in form of [["id1", "name1"], ["idN", "nameN"]] - * @example - * var items; - * - * items = LegacyKeywordUtils.getStandardArray("ADDRESS.TYPE"); - * result.object(items); - */ - LegacyKeywordUtils.getStandardArray = function(keywordType){ - return LegacyKeywordUtils.createKeyword(keywordType).toArray(["id", "name"]); - } - - /** - * same as getStandardArray but also returns the custom properties - * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @return {Array} a 2D array in form of [["id1", "name1", {"prop1":"prop"}], ["idN", "nameN", {"prop1":"prop"}]] - * @example - * var items; - * - * items = LegacyKeywordUtils.getStandardArray("ADDRESS.TYPE"); - * result.object(items); - */ - LegacyKeywordUtils.getStandardArrayProps = function(keywordType){ - return LegacyKeywordUtils.createKeyword(keywordType).toArray(["id", "name", "customProperties"]); - } - - /** - * get a Keyword by type and key - * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @param {String} key the key for the keyword ("1", "2", "3", etc.) - * @return {Array} a 2D array in form of [["id1", "name1", properties1], ["idN", "nameN", propertiesN]] - * @example - * var item = LegacyKeywordUtils.get("ADDRESS.TYPE", "1"); - * result.object(item); - */ - LegacyKeywordUtils.get = function(keywordType, key){ - return LegacyKeywordUtils.createKeyword(keywordType).getPropsForKey(key, ["id", "name", "customProperties"]); - } - - /** - * returns a specific name (translated) - this is normally the view-value - of a given keyword; - * <br/>if the key could not be found an empty string "" is returned - * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @param {String} key id value of the keyword where the view-value shall be searched - * @return {String} representation of the translated name of the keyword-key - * @example - * var histMedium; - * histMedium = vars.get("$field.MEDIUM"); - * if (histMedium){ - * result.string(vars.get("$field.SUBJECT") + " (" + LegacyKeywordUtils.getViewValue("ACTIVITY.MEDIUM", histMedium) + ")"); - * } - */ - LegacyKeywordUtils.getViewValue = function(keywordType, key){ - var k = LegacyKeywordUtils.createKeyword(keywordType); - return k.getPropForKey(key, "name") || ""; - } - - /** - * creates an object with methods for interacting with an specific keyword - * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" - * @param {String} translationLocale locale (like e.g. "de_DE") for translation of the keywordtitle - * @return {Object} object with the following methods: - * <br/>- toArray - * <br/>- get - * <br/>- getPropForKey - * <br/>- getPropsForKey - * <br/>- filter - */ - LegacyKeywordUtils.createKeyword = function(keywordType, translationLocale){ - var valueContainer, _toArrayFn, _getPropForKeyFn, _getPropsForKeyFn; - - var locale; - if (translationLocale) - locale = translationLocale; - else - { - var lang = vars.get("$sys.clientlanguage");//e.g. "de" - var country = vars.get("$sys.clientcountry");//e.g. "DE" - locale = country ? lang + "_" + country : lang; - } - - switch (keywordType){ - case "ACTIVITY.CATEGORY": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("0", translate.text("Visit", locale), null, {defaultAvatarRepresentation: "VAADIN:TRAIN"}) - ,_createKeywordEntry("1", translate.text("E-Mail", locale), null, {defaultAvatarRepresentation: "VAADIN:AT"}) - ,_createKeywordEntry("2", translate.text("Phone", locale), null, {defaultAvatarRepresentation: "VAADIN:PHONE"}) - ,_createKeywordEntry("3", translate.text("Online-Meeting", locale), null, {defaultAvatarRepresentation: "VAADIN:GLOBE_WIRE"}) - ]); - break; - case "COMMUNICATION.MEDIUM": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("0", translate.text("Mobile", locale), null, {category: "PHONE", contentType: "TELEPHONE"}) - ,_createKeywordEntry("1", translate.text("E-Mail", locale), null, {category: "EMAIL", contentType: "EMAIL"}) - ,_createKeywordEntry("2", translate.text("Phone", locale), null, {category: "PHONE", contentType: "TELEPHONE"}) - ,_createKeywordEntry("3", translate.text("Internet", locale), null, {category: "OTHER", contentType: "LINK"}) - ]); - break; - case "ADDRESS.TYPE": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Office address", locale), null, {org: true, person: false}) - ,_createKeywordEntry("2", translate.text("Home address", locale), null, {org: false, person: true}) - ,_createKeywordEntry("3", translate.text("Delivery address", locale), null, {org: true, person: true}) - ,_createKeywordEntry("4", translate.text("Post office box", locale), null, {org: true, person: true}) - ]); - break; - case "SALESPROJECT.PRICE_POLITICS": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Abomodel", locale)) - ,_createKeywordEntry("2", translate.text("High price strategy", locale)) - ,_createKeywordEntry("3", translate.text("Low price strategy", locale)) - ]); - break; - case "SALESPROJECT.STRENGTH": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Strength 1", locale)) - ,_createKeywordEntry("2", translate.text("Strength 2", locale)) - ,_createKeywordEntry("3", translate.text("Strength 3", locale)) - ]); - break; - case "SALESPROJECT.WEAKNESS": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Weakness 1", locale)) - ,_createKeywordEntry("2", translate.text("Weakness 2", locale)) - ,_createKeywordEntry("3", translate.text("Weakness 3", locale)) - ]); - break; - case "SALESPROJECT.STATE": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Open", locale)) - ,_createKeywordEntry("2", translate.text("Postponed", locale)) - ,_createKeywordEntry("3", translate.text("Aborted", locale)) - ,_createKeywordEntry("4", translate.text("Partial order", locale)) - ,_createKeywordEntry("5", translate.text("Order", locale)) - ,_createKeywordEntry("6", translate.text("Lost", locale)) - ]); - break; - case "SALESPROJECT.PHASE": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("NQC", locale)) - ,_createKeywordEntry("2", translate.text("MAL", locale)) - ,_createKeywordEntry("3", translate.text("MQL", locale)) - ,_createKeywordEntry("4", translate.text("SAL", locale)) - ,_createKeywordEntry("5", translate.text("SQO", locale)) - ,_createKeywordEntry("6", translate.text("Offer", locale)) - ,_createKeywordEntry("7", translate.text("Negotiation", locale)) - ,_createKeywordEntry("8", translate.text("Project decision", locale)) - ,_createKeywordEntry("9", translate.text("Negotiation", locale)) - ,_createKeywordEntry("10", translate.text("Workshop", locale)) - ,_createKeywordEntry("11", translate.text("Presentation follow-up", locale)) - ,_createKeywordEntry("12", translate.text("Presentation preparation", locale)) - ,_createKeywordEntry("13", translate.text("Deliver opinion", locale)) - ,_createKeywordEntry("14", translate.text("Specifications in progress", locale)) - ,_createKeywordEntry("15", translate.text("Waiting for requirements", locale)) - ,_createKeywordEntry("16", translate.text("Lead", locale)) - ]); - break; - case "SALESPROJECT.MILESTONE.TYPE": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Phase", locale), null, {keyword: "SALESPROJECT.PHASE"}) - ,_createKeywordEntry("2", translate.text("State", locale), null, {keyword: "SALESPROJECT.STATE"}) - ]); - break; - case "SALESPROJECT.CLASS": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Class A", locale), null, { - keywords: - [["CLASS.BRANCHE", translate.text("Industry", locale)], - ["CLASS.BASED", translate.text("Base", locale)]] - }) - ,_createKeywordEntry("2", translate.text("Class B", locale), null, { - keywords: - [["CLASS.BUDGET", translate.text("Budget (Project)", locale)], - ["CLASS.STANDARD", translate.text("Standard / Individual", locale)]] - }) - ,_createKeywordEntry("3", translate.text("Class C", locale), null, { - keywords: - [["CLASS.PROJSTART", translate.text("Projectstart", locale)]] - }) - ]); - break; - case "CLASS.BRANCHE": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Industry 1", locale), null, {points: 50}) - ,_createKeywordEntry("2", translate.text("Industry 2", locale), null, {points: 16.6}) - ,_createKeywordEntry("3", translate.text("Industry 3", locale), null, {points: 50}) - ]); - break; - case "CLASS.BASED": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Germany", locale), null, {points: 20}) - ,_createKeywordEntry("2", translate.text("Austria", locale), null, {points: 7.5}) - ,_createKeywordEntry("3", translate.text("Other", locale), null, {points: 0}) - ]); - break; - case "CLASS.BUDGET": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("From", locale) + "350T\u20ac", null, {points: 50}) - ,_createKeywordEntry("2", "200" + translate.text("to", locale) + "349T\u20ac", null, {points: 30}) - ,_createKeywordEntry("3", "0" + translate.text("to", locale) + "3199T\u20ac", null, {points: 0}) - ]); - break; - case "CLASS.STANDARD": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("Individual", locale), null, {points: 25}) - ,_createKeywordEntry("2", translate.text("Standard", locale), null, {points: 12.5}) - ]); - break; - case "CLASS.PROJSTART": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("in 6 Months", locale), null, {points: 30}) - ,_createKeywordEntry("2", translate.text("in 12 Months", locale), null, {points: 20}) - ,_createKeywordEntry("3", translate.text("no Project planned", locale), null, {points: 0}) - ]); - break; - case "OFFER.PROBABILITY": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("1", translate.text("0 %", locale), null, {percentValue: 0}) - ,_createKeywordEntry("2", translate.text("25 %", locale), null, {percentValue: 25}) - ,_createKeywordEntry("3", translate.text("50 %", locale), null, {percentValue: 50}) - ,_createKeywordEntry("4", translate.text("75 %", locale), null, {percentValue: 75}) - ,_createKeywordEntry("5", translate.text("100 %", locale), null, {percentValue: 100}) - ]); - break; - case "TASK.PRIORITY": - valueContainer = _createKeywordEntriesContainer([ - _createKeywordEntry("0", translate.text("{$TASK_PRIORITY_NONE}", locale), null, {defaultAvatarRepresentation: null}) - ,_createKeywordEntry("1", translate.text("{$TASK_PRIORITY_LOW}", locale), null, {defaultAvatarRepresentation: "VAADIN:ARROW_DOWN"}) - ,_createKeywordEntry("2", translate.text("{$TASK_PRIORITY_NORMAL}", locale), null, {defaultAvatarRepresentation: null}) - ,_createKeywordEntry("3", translate.text("{$TASK_PRIORITY_HIGH}", locale), null, {defaultAvatarRepresentation: "VAADIN:EXCLAMATION"}) - ]); - break; - default: - throw new Error(translate.withArguments("[%0]the given keyword \"%1\" has no match with the possible keywordlist", [ - arguments.callee.name, keywordType - ])); - break; - } - - - _getPropForKeyFn = function(key, field, isCustom) { - var keyObject; - if (valueContainer[key] == undefined) - return undefined; - if (isCustom) - keyObject = valueContainer[key]["customProperties"]; - else - keyObject = valueContainer[key]; - - if (keyObject == undefined) - return undefined; - return keyObject[field]; - }; - - _getPropsForKeyFn = function(key, fields) { - var keyObject, i, currentRow, currentField; - - keyObject = valueContainer[key]; - if (keyObject == undefined) - return [];//TODO: throw error instead? - currentRow = []; - for (i = 0; i < fields.length; i++){ - currentField = fields[i]; - //check if the passed fieldnames match the existing fieldnames (<=> properties in the object) - //to prevent errors and unexpected behaviour - if (keyObject[currentField]) - currentRow.push(keyObject[currentField]); - else - currentRow.push(""); - } - return currentRow; - }; - - _toArrayFn = function(fields){ - var res, id, currentRow; - - res = []; - if (!fields) - fields = ["id", "name"]; - else if (typeof(fields) == "string"){ - for (id in valueContainer){ - res.push(_getPropForKeyFn(id, fields)); - } - return res; - } - - for (id in valueContainer){ - currentRow = _getPropsForKeyFn(id, fields); - res.push(currentRow); - } - return res; - }; - - _existsFn = function(key){ - return (valueContainer[key] != undefined); - }; - - return { - /** - * toArray - * @ignore - */ - toArray: _toArrayFn - ,getPropForKey: _getPropForKeyFn - ,getPropsForKey: _getPropsForKeyFn - ,filter: function (callbackFn, thisArg){ - for (id in valueContainer){ - if (false == callbackFn.call(thisArg, valueContainer[id].id, valueContainer[id].name, valueContainer[id].customProperties, - valueContainer[id], valueContainer)){ - delete valueContainer[id]; - } - } - return this; - } - ,exists: _existsFn - }; - }; - - /** - * internal function for creating an object that represents a keyword entry - * @param {String} id represents the key of an entry; a KeywordEntriesContainer can contain the same key only once - * @param {String} name represents the translated name of an entry; this is in most cases the view-value - * @param {String} [description=""] description text for describing the keyword - * @param {Object} [customProperties=null] an Object with additional properties; these can be virtually anything - * @return {Object} object that represents a single keyword entry; normally severel entries are cumulated in a "keywordEntriesContainer" - */ - function _createKeywordEntry(id, name, description, customProperties){ - //TODO: verify if mandatory-checks are really that usefull or can at least be made easier - if (!id) - throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [ - "id", arguments.callee.name - ])); - if (!name) - throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [ - "name", arguments.callee.name - ])); - - return { - id: id - ,name: name - ,description: description || "" - ,customProperties: customProperties - }; - } - - /** - * internal function for creating an object that represents a container of several keywordEntries - * @param {Array} keywordEntries an Array of keywordEntry-objects (as they are created by "_createKeywordEntry" - * @return {Object} object that contains several keywordEntries - */ - function _createKeywordEntriesContainer(keywordEntries){ - var res, i, l, id; - - res = {}; - for (i = 0, l = keywordEntries.length; i < l; i++){ - id = keywordEntries[i].id; - if (res[id] != undefined){ - throw new Error("the given id is not unique since it already exists"); - } - res[id] = keywordEntries[i]; - } - return res; - } -})(); +import("KeywordData_lib"); +import("system.vars"); +import("system.SQLTYPES"); +import("system.db"); +import("system.translate"); +import("system.neon"); +import("Sql_lib"); + +/** + * provides methods for interactions with keywords + * + * @class + */ +function KeywordUtils(){} + +/** +* resolves KEYIDs of a keywordentry into the specific title +* +* @param {String} pContainerName name of the keyword container that shall be resolved +* @param {String} pDbFieldName name fo the database field where the KEYID-value is stored +* @param {String} [pLocale=current client language] specifies the locale for translating the title; can be false if nothing shalle be translated +* +* @return {String} a SQL-expression (case-when-statement) that resolves the KEYID into the title +*/ +KeywordUtils.getResolvedTitleSqlPart = function(pContainerName, pDbFieldName, pLocale) +{ + var keywordData = KeywordData.getSimpleData(pContainerName, pLocale); + var resSql = SqlUtils.getResolvingCaseWhen(keywordData, pDbFieldName, pLocale); + return db.translateStatement(resSql); +}; + +/** + * returns a specific name (translated) - this is normally the view-value - of a given keyword; + * <br/>if the key could not be found an empty string "" is returned + * @param {String} keywordContainer specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @param {String} key id value of the keyword where the view-value shall be searched + * @param {String} [locale=locale depending on current client/servercontext] Language-value for translations + * @return {String} representation of the translated name of the keyword-key + * @example + * var histMedium; + * histMedium = vars.get("$field.MEDIUM"); + * if (histMedium){ + * result.string(vars.get("$field.SUBJECT") + " (" + LegacyKeywordUtils.getViewValue("ACTIVITY.MEDIUM", histMedium) + ")"); + * } + */ +KeywordUtils.getViewValue = function(keywordContainer, key, locale) +{ + if (!key) + return ""; + + var data = KeywordData.getKeyIdMap(keywordContainer, locale); + if (data[key] == undefined) + return ""; + return data[key]; +}; + + +/** + * collects possible and defined keyword-attributes per keyword entry and returns them + * + * @param {String} pEntryId id that identifies the keyword-entry whoes attributes are collected + * @return {Object} key-value-pair of the keyword-attributes; contains all attribute-keys for the keywords-entries container; + * if there is no value set for a key the null-value is given + */ +KeywordUtils.getAttributeRelationsByEntryId = function(pEntryId) +{ + var cond = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID", pEntryId); + + return KeywordUtils._getKeywordAttributeRelations(cond); +}; + +/** + * collects possible and defined keyword-attributes per keyword entry and returns them + * + * @param {String} pKeyId the key of an element within a containerName - this is the value that is stored in the reference-table (e.g. "DE") + * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; + * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here + * @return {Object} key-value-pair of the keyword-attributes; contains all attribute-keys for the keywords-entries container; + * if there is no value set for a key the null-value is given + */ +KeywordUtils.getAttributeRelationsByKey = function(pKeyId, pContainerName) +{ + var cond = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) + .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName); + + return KeywordUtils._getKeywordAttributeRelations(cond); +}; + +/** + * internal function that collects possible and defined keyword-attributes per keyword entry and returns them + * + * @param {SqlCondition} pSqlCondition condition that shrinks a resultset to one AB_KEYWORD_ENTRY + * @return {Object} SQL-Condition object that filters + */ +KeywordUtils._getKeywordAttributeRelations = function (pSqlCondition) +{ + var cond = pSqlCondition; + var sql = cond.buildSql("select AB_KEYWORD_ATTRIBUTE.NAME, AB_KEYWORD_ATTRIBUTE.TYPE, \n\ + AB_KEYWORD_ATTRIBUTERELATION.CHAR_VALUE, AB_KEYWORD_ATTRIBUTERELATION.NUMBER_VALUE, AB_KEYWORD_ATTRIBUTERELATION.BOOL_VALUE \n\ + from AB_KEYWORD_ENTRY \n\ + join AB_KEYWORD_ATTRIBUTE on (AB_KEYWORD_ATTRIBUTE.CONTAINER = AB_KEYWORD_ENTRY.CONTAINER) \n\ + left join AB_KEYWORD_ATTRIBUTERELATION \n\ + on (AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID = AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID\n\ + and AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID = AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID)"); + + var data = db.table(sql); + var res = {}; + var name, type, charVal, numVal, boolVal; + + for (var i = 0, l = data.length; i < l; i++) + { + [name, type, charVal, numVal, boolVal] = data[i]; + name = name.trim(); + type = type.trim(); + var parsedValue = null; + switch(type) + { + case "NUMBER_VALUE": + parsedValue = numVal == "" ? null : Number(numVal); + break; + case "BOOL_VALUE": + parsedValue = boolVal == "" ? null : (boolVal == "1"); + break; + case "CHAR_VALUE": + parsedValue = charVal == "" ? null : charVal; + break; + } + + res[name] = parsedValue; + } + return res; +}; + +/** +* provides a distinctive list of all keyword-container-names in the system +* +* @return {String[]} containerNames as 1D-Array +*/ +KeywordUtils.getContainerNames = function() +{ + var list = db.array(db.COLUMN, "select distinct AB_KEYWORD_ENTRY.CONTAINER from AB_KEYWORD_ENTRY order by AB_KEYWORD_ENTRY.CONTAINER asc"); + return list; +}; + +/** +* provides a translated list of keyword-entry-titles in the system filtered by a containerName; +* usefull for lists where the key is the name which is then a editable displayValue +* +* @param {String} pContainerName name of the keyword container for filtering +* @param {String} [pLocale=locale depending on current client/servercontext] Language-value for translations +* +* @return {String[]} translated titles as 1D-Array +*/ +KeywordUtils.getEntryNamesByContainer = function(pContainerName, pLocale) +{ + var sql = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) + .buildSql("select AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY", null, "order by AB_KEYWORD_ENTRY.SORTING asc, AB_KEYWORD_ENTRY.TITLE asc") + var list = db.array(db.COLUMN, sql).map(function (v){ + return pLocale ? translate.text(v, pLocale) : translate.text(v); + }); + return list; +}; + + +/** +* provides a translated list of keyword-entry-titles and its ids in the system filtered by a containerName; +* usefull for lists where the key is the name which is then a editable displayValue +* +* @param {String} pContainerName name of the keyword container for filtering +* * @param {String} [pLocale=locale depending on current client/servercontext] Language-value for translations +* +* @return {String[]} 2D-Array in the form of [[id1, translatedTitle1], [idN, translatedTitleN]] +*/ +KeywordUtils.getEntryNamesAndIdsByContainer = function(pContainerName, pLocale) +{ + var sql = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) + .buildSql("select AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID, AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY", null, "order by AB_KEYWORD_ENTRY.SORTING asc, AB_KEYWORD_ENTRY.TITLE asc") + + var list = db.table(sql).map(function (elem){ + elem[1] = pLocale ? translate.text(elem[1], pLocale) : translate.text(elem[1]); + return elem; + }); + return list; +}; + +/** + * checks, if a specific keyword exists + * + * @param {String} pKeyId the key of an element within a containerName - this is the value that is stored in the reference-table (e.g. "DE") + * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; + * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here + * + * @return {Boolean} + */ +KeywordUtils.exists = function(pKeyId, pContainerName) +{ + var sql = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) + .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", pContainerName) + .buildSql("select count(*) from AB_KEYWORD_ENTRY", "1=2") + return parseInt(db.cell(sql)) > 0; +}; + +/** + * get the translated container name. + * + * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; + * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here + * @return translated name, if it exists in the switch case + */ +KeywordUtils.getTranslatedContainer = function(pContainerName) +{ + switch (pContainerName) + { + case "SalesprojectPhase": + return translate.text("Phase"); + case "SalesprojectState": + return translate.text("State"); + break; + default: + return "Please add " + pContainerName + " to the switch case in Salesproject_lib"; + } + +} + +/** + * object that provides featrues for a single keyword attribute; initalizes itself on creation with a specific keyword-attribute + * + * @param {String} pContainerName specifies the type of the keyword and therefore the list elements; + * e.g. "COUNTRY"; use an entry of the $KeywordRegistry here + * @param {String} pAttributeName the name of the keyword attribute that shall be initalized + * + * @class + */ +function KeywordAttribute(pContainerName, pAttributeName) +{ + this.container = pContainerName; + this.attribute = pAttributeName; + + var sql = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ATTRIBUTE.CONTAINER", pContainerName) + .andPrepare("AB_KEYWORD_ATTRIBUTE.NAME", pAttributeName) + .buildSql("select AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID, AB_KEYWORD_ATTRIBUTE.TYPE from AB_KEYWORD_ATTRIBUTE"); + + var keywordAttrData = db.array(db.ROW, sql); + + if (keywordAttrData.length == 0) + throw new Error(translate.withArguments("no keyword attribute \"%0\" found in keyword container \"%1\"", [this.attribute, this.container])); + + this.id = keywordAttrData[0]; + this.type = keywordAttrData[1]; + this.dbField = this.type.trim(); +} + +KeywordAttribute.prototype.getValue = function(pKeyId) +{ + var sql = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", this.container) + .andPrepare("AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID", this.id) + .andPrepare("AB_KEYWORD_ENTRY.KEYID", pKeyId) + .buildSql("select " + this.dbField + " from AB_KEYWORD_ENTRY join AB_KEYWORD_ATTRIBUTERELATION on AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID = AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID"); + + return db.cell(sql); +} + +/** + * provides methods for interactions with the sepcial-keywords "LANGUAGE" + * + * @class + */ +function LanguageKeywordUtils(){} + +/** +* resolves Languagecode into the latin name +* +* @param {String} pDbFieldName name fo the database field where the ISO3-value is stored +* @param {String} [pLocale=current client language] specifies the locale for translating the title; can be false if nothing shalle be translated +* +* @return {String} a SQL-expression (case-when-statement) +*/ +LanguageKeywordUtils.getResolvedTitleSqlPart = function(pDbFieldName, pLocale) +{ + var data = LanguageData.getData(); + var resSql = SqlUtils.getResolvingCaseWhen(data, pDbFieldName, pLocale); + return db.translateStatement(resSql); +}; + +/** + * returns a specific name (translated) - this is normally the view-value of a language + * + * @param {String} key id value of the language where the view-value shall be searched + * @param {String} [locale=locale depending on current client/servercontext] Language-value for translations + * + * @return {String} representation of the translated name + * + */ +LanguageKeywordUtils.getViewValue = function(key, locale) +{ + if (!key) + return ""; + + var languageMap = LanguageData.getIso3Map(locale); + var title = languageMap[key]; + if (title == undefined) + return ""; + return title; +}; + + +/** + * provides methods for interactions with legcy keywords + * @deprecated use instead the new meachanism via the KeywordUtils + * + * @class + */ +function LegacyKeywordUtils(){} + +(function(){//scope for private functions + + + /** + * returns the default case for keyword-arrays (id and translated name) + * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @return {Array} a 2D array in form of [["id1", "name1"], ["idN", "nameN"]] + * @example + * var items; + * + * items = LegacyKeywordUtils.getStandardArray("ADDRESS.TYPE"); + * result.object(items); + */ + LegacyKeywordUtils.getStandardArray = function(keywordType){ + return LegacyKeywordUtils.createKeyword(keywordType).toArray(["id", "name"]); + } + + /** + * same as getStandardArray but also returns the custom properties + * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @return {Array} a 2D array in form of [["id1", "name1", {"prop1":"prop"}], ["idN", "nameN", {"prop1":"prop"}]] + * @example + * var items; + * + * items = LegacyKeywordUtils.getStandardArray("ADDRESS.TYPE"); + * result.object(items); + */ + LegacyKeywordUtils.getStandardArrayProps = function(keywordType){ + return LegacyKeywordUtils.createKeyword(keywordType).toArray(["id", "name", "customProperties"]); + } + + /** + * get a Keyword by type and key + * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @param {String} key the key for the keyword ("1", "2", "3", etc.) + * @return {Array} a 2D array in form of [["id1", "name1", properties1], ["idN", "nameN", propertiesN]] + * @example + * var item = LegacyKeywordUtils.get("ADDRESS.TYPE", "1"); + * result.object(item); + */ + LegacyKeywordUtils.get = function(keywordType, key){ + return LegacyKeywordUtils.createKeyword(keywordType).getPropsForKey(key, ["id", "name", "customProperties"]); + } + + /** + * returns a specific name (translated) - this is normally the view-value - of a given keyword; + * <br/>if the key could not be found an empty string "" is returned + * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @param {String} key id value of the keyword where the view-value shall be searched + * @return {String} representation of the translated name of the keyword-key + * @example + * var histMedium; + * histMedium = vars.get("$field.MEDIUM"); + * if (histMedium){ + * result.string(vars.get("$field.SUBJECT") + " (" + LegacyKeywordUtils.getViewValue("ACTIVITY.MEDIUM", histMedium) + ")"); + * } + */ + LegacyKeywordUtils.getViewValue = function(keywordType, key){ + var k = LegacyKeywordUtils.createKeyword(keywordType); + return k.getPropForKey(key, "name") || ""; + } + + /** + * creates an object with methods for interacting with an specific keyword + * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY" + * @param {String} translationLocale locale (like e.g. "de_DE") for translation of the keywordtitle + * @return {Object} object with the following methods: + * <br/>- toArray + * <br/>- get + * <br/>- getPropForKey + * <br/>- getPropsForKey + * <br/>- filter + */ + LegacyKeywordUtils.createKeyword = function(keywordType, translationLocale){ + var valueContainer, _toArrayFn, _getPropForKeyFn, _getPropsForKeyFn; + + var locale; + if (translationLocale) + locale = translationLocale; + else + { + var lang = vars.get("$sys.clientlanguage");//e.g. "de" + var country = vars.get("$sys.clientcountry");//e.g. "DE" + locale = country ? lang + "_" + country : lang; + } + + switch (keywordType){ + case "ACTIVITY.CATEGORY": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("0", translate.text("Visit", locale), null, {defaultAvatarRepresentation: "VAADIN:TRAIN"}) + ,_createKeywordEntry("1", translate.text("E-Mail", locale), null, {defaultAvatarRepresentation: "VAADIN:AT"}) + ,_createKeywordEntry("2", translate.text("Phone", locale), null, {defaultAvatarRepresentation: "VAADIN:PHONE"}) + ,_createKeywordEntry("3", translate.text("Online-Meeting", locale), null, {defaultAvatarRepresentation: "VAADIN:GLOBE_WIRE"}) + ]); + break; + case "COMMUNICATION.MEDIUM": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("0", translate.text("Mobile", locale), null, {category: "PHONE", contentType: "TELEPHONE"}) + ,_createKeywordEntry("1", translate.text("E-Mail", locale), null, {category: "EMAIL", contentType: "EMAIL"}) + ,_createKeywordEntry("2", translate.text("Phone", locale), null, {category: "PHONE", contentType: "TELEPHONE"}) + ,_createKeywordEntry("3", translate.text("Internet", locale), null, {category: "OTHER", contentType: "LINK"}) + ]); + break; + case "ADDRESS.TYPE": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Office address", locale), null, {org: true, person: false}) + ,_createKeywordEntry("2", translate.text("Home address", locale), null, {org: false, person: true}) + ,_createKeywordEntry("3", translate.text("Delivery address", locale), null, {org: true, person: true}) + ,_createKeywordEntry("4", translate.text("Post office box", locale), null, {org: true, person: true}) + ]); + break; + case "SALESPROJECT.PRICE_POLITICS": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Abomodel", locale)) + ,_createKeywordEntry("2", translate.text("High price strategy", locale)) + ,_createKeywordEntry("3", translate.text("Low price strategy", locale)) + ]); + break; + case "SALESPROJECT.STRENGTH": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Strength 1", locale)) + ,_createKeywordEntry("2", translate.text("Strength 2", locale)) + ,_createKeywordEntry("3", translate.text("Strength 3", locale)) + ]); + break; + case "SALESPROJECT.WEAKNESS": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Weakness 1", locale)) + ,_createKeywordEntry("2", translate.text("Weakness 2", locale)) + ,_createKeywordEntry("3", translate.text("Weakness 3", locale)) + ]); + break; + case "SALESPROJECT.STATE": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Open", locale)) + ,_createKeywordEntry("2", translate.text("Postponed", locale)) + ,_createKeywordEntry("3", translate.text("Aborted", locale)) + ,_createKeywordEntry("4", translate.text("Partial order", locale)) + ,_createKeywordEntry("5", translate.text("Order", locale)) + ,_createKeywordEntry("6", translate.text("Lost", locale)) + ]); + break; + case "SALESPROJECT.PHASE": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("NQC", locale)) + ,_createKeywordEntry("2", translate.text("MAL", locale)) + ,_createKeywordEntry("3", translate.text("MQL", locale)) + ,_createKeywordEntry("4", translate.text("SAL", locale)) + ,_createKeywordEntry("5", translate.text("SQO", locale)) + ,_createKeywordEntry("6", translate.text("Offer", locale)) + ,_createKeywordEntry("7", translate.text("Negotiation", locale)) + ,_createKeywordEntry("8", translate.text("Project decision", locale)) + ,_createKeywordEntry("9", translate.text("Negotiation", locale)) + ,_createKeywordEntry("10", translate.text("Workshop", locale)) + ,_createKeywordEntry("11", translate.text("Presentation follow-up", locale)) + ,_createKeywordEntry("12", translate.text("Presentation preparation", locale)) + ,_createKeywordEntry("13", translate.text("Deliver opinion", locale)) + ,_createKeywordEntry("14", translate.text("Specifications in progress", locale)) + ,_createKeywordEntry("15", translate.text("Waiting for requirements", locale)) + ,_createKeywordEntry("16", translate.text("Lead", locale)) + ]); + break; + case "SALESPROJECT.MILESTONE.TYPE": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Phase", locale), null, {keyword: "SALESPROJECT.PHASE"}) + ,_createKeywordEntry("2", translate.text("State", locale), null, {keyword: "SALESPROJECT.STATE"}) + ]); + break; + case "SALESPROJECT.CLASS": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Class A", locale), null, { + keywords: + [["CLASS.BRANCHE", translate.text("Industry", locale)], + ["CLASS.BASED", translate.text("Base", locale)]] + }) + ,_createKeywordEntry("2", translate.text("Class B", locale), null, { + keywords: + [["CLASS.BUDGET", translate.text("Budget (Project)", locale)], + ["CLASS.STANDARD", translate.text("Standard / Individual", locale)]] + }) + ,_createKeywordEntry("3", translate.text("Class C", locale), null, { + keywords: + [["CLASS.PROJSTART", translate.text("Projectstart", locale)]] + }) + ]); + break; + case "CLASS.BRANCHE": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Industry 1", locale), null, {points: 50}) + ,_createKeywordEntry("2", translate.text("Industry 2", locale), null, {points: 16.6}) + ,_createKeywordEntry("3", translate.text("Industry 3", locale), null, {points: 50}) + ]); + break; + case "CLASS.BASED": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Germany", locale), null, {points: 20}) + ,_createKeywordEntry("2", translate.text("Austria", locale), null, {points: 7.5}) + ,_createKeywordEntry("3", translate.text("Other", locale), null, {points: 0}) + ]); + break; + case "CLASS.BUDGET": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("From", locale) + "350T\u20ac", null, {points: 50}) + ,_createKeywordEntry("2", "200" + translate.text("to", locale) + "349T\u20ac", null, {points: 30}) + ,_createKeywordEntry("3", "0" + translate.text("to", locale) + "3199T\u20ac", null, {points: 0}) + ]); + break; + case "CLASS.STANDARD": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("Individual", locale), null, {points: 25}) + ,_createKeywordEntry("2", translate.text("Standard", locale), null, {points: 12.5}) + ]); + break; + case "CLASS.PROJSTART": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("in 6 Months", locale), null, {points: 30}) + ,_createKeywordEntry("2", translate.text("in 12 Months", locale), null, {points: 20}) + ,_createKeywordEntry("3", translate.text("no Project planned", locale), null, {points: 0}) + ]); + break; + case "OFFER.PROBABILITY": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("1", translate.text("0 %", locale), null, {percentValue: 0}) + ,_createKeywordEntry("2", translate.text("25 %", locale), null, {percentValue: 25}) + ,_createKeywordEntry("3", translate.text("50 %", locale), null, {percentValue: 50}) + ,_createKeywordEntry("4", translate.text("75 %", locale), null, {percentValue: 75}) + ,_createKeywordEntry("5", translate.text("100 %", locale), null, {percentValue: 100}) + ]); + break; + case "TASK.PRIORITY": + valueContainer = _createKeywordEntriesContainer([ + _createKeywordEntry("0", translate.text("{$TASK_PRIORITY_NONE}", locale), null, {defaultAvatarRepresentation: null}) + ,_createKeywordEntry("1", translate.text("{$TASK_PRIORITY_LOW}", locale), null, {defaultAvatarRepresentation: "VAADIN:ARROW_DOWN"}) + ,_createKeywordEntry("2", translate.text("{$TASK_PRIORITY_NORMAL}", locale), null, {defaultAvatarRepresentation: null}) + ,_createKeywordEntry("3", translate.text("{$TASK_PRIORITY_HIGH}", locale), null, {defaultAvatarRepresentation: "VAADIN:EXCLAMATION"}) + ]); + break; + default: + throw new Error(translate.withArguments("[%0]the given keyword \"%1\" has no match with the possible keywordlist", [ + arguments.callee.name, keywordType + ])); + break; + } + + + _getPropForKeyFn = function(key, field, isCustom) { + var keyObject; + if (valueContainer[key] == undefined) + return undefined; + if (isCustom) + keyObject = valueContainer[key]["customProperties"]; + else + keyObject = valueContainer[key]; + + if (keyObject == undefined) + return undefined; + return keyObject[field]; + }; + + _getPropsForKeyFn = function(key, fields) { + var keyObject, i, currentRow, currentField; + + keyObject = valueContainer[key]; + if (keyObject == undefined) + return [];//TODO: throw error instead? + currentRow = []; + for (i = 0; i < fields.length; i++){ + currentField = fields[i]; + //check if the passed fieldnames match the existing fieldnames (<=> properties in the object) + //to prevent errors and unexpected behaviour + if (keyObject[currentField]) + currentRow.push(keyObject[currentField]); + else + currentRow.push(""); + } + return currentRow; + }; + + _toArrayFn = function(fields){ + var res, id, currentRow; + + res = []; + if (!fields) + fields = ["id", "name"]; + else if (typeof(fields) == "string"){ + for (id in valueContainer){ + res.push(_getPropForKeyFn(id, fields)); + } + return res; + } + + for (id in valueContainer){ + currentRow = _getPropsForKeyFn(id, fields); + res.push(currentRow); + } + return res; + }; + + _existsFn = function(key){ + return (valueContainer[key] != undefined); + }; + + return { + /** + * toArray + * @ignore + */ + toArray: _toArrayFn + ,getPropForKey: _getPropForKeyFn + ,getPropsForKey: _getPropsForKeyFn + ,filter: function (callbackFn, thisArg){ + for (id in valueContainer){ + if (false == callbackFn.call(thisArg, valueContainer[id].id, valueContainer[id].name, valueContainer[id].customProperties, + valueContainer[id], valueContainer)){ + delete valueContainer[id]; + } + } + return this; + } + ,exists: _existsFn + }; + }; + + /** + * internal function for creating an object that represents a keyword entry + * @param {String} id represents the key of an entry; a KeywordEntriesContainer can contain the same key only once + * @param {String} name represents the translated name of an entry; this is in most cases the view-value + * @param {String} [description=""] description text for describing the keyword + * @param {Object} [customProperties=null] an Object with additional properties; these can be virtually anything + * @return {Object} object that represents a single keyword entry; normally severel entries are cumulated in a "keywordEntriesContainer" + */ + function _createKeywordEntry(id, name, description, customProperties){ + //TODO: verify if mandatory-checks are really that usefull or can at least be made easier + if (!id) + throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [ + "id", arguments.callee.name + ])); + if (!name) + throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [ + "name", arguments.callee.name + ])); + + return { + id: id + ,name: name + ,description: description || "" + ,customProperties: customProperties + }; + } + + /** + * internal function for creating an object that represents a container of several keywordEntries + * @param {Array} keywordEntries an Array of keywordEntry-objects (as they are created by "_createKeywordEntry" + * @return {Object} object that contains several keywordEntries + */ + function _createKeywordEntriesContainer(keywordEntries){ + var res, i, l, id; + + res = {}; + for (i = 0, l = keywordEntries.length; i < l; i++){ + id = keywordEntries[i].id; + if (res[id] != undefined){ + throw new Error("the given id is not unique since it already exists"); + } + res[id] = keywordEntries[i]; + } + return res; + } +})(); -- GitLab