diff --git a/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js b/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js index b2db244c25ca2825fed534f0e654f38842b3c929..53fe713f00a837c1931303dc011f49a4af4ee17c 100644 --- a/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js +++ b/entity/UniversalFileProcessor_entity/entityfields/drop_action/onActionProcess.js @@ -20,6 +20,7 @@ var status = { for (var i = 0, l = files.length; i < l; i++) { + vars.set("$field.INFO", translate.withArguments("processing %0/%1", [i.toString(), l.toString()]) + " . . ."); switch (files[i].mimeType) { case "application/octet-stream"://.msg-files will not get any mimetype from the browser so let's use @@ -51,7 +52,7 @@ if (status.activitiesCreated > 0 || status.unlinkedMailsCreated > 0 || status.ot var messages = _getMessages(status); if (messages.length) - vars.set("$field.INFO", messages.join(", ")); + vars.set("$field.INFO", translate.withArguments("processed %0/%1:", [i.toString(), l.toString()]) + "\n" + messages.join(", ")); function _getMailObj(pDroppedFile) { diff --git a/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js b/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js index 1c866cce85e6ee96fb86a86ef55ea0b0503ba232..42654e03c0f48ffa67cc488dcada55d67653f704 100644 --- a/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js +++ b/entity/UnlinkedMailMappingWrapper_entity/recordcontainers/dummyjdito/onUpdate.js @@ -33,9 +33,10 @@ if (changedRows.length > 0) var loadingConfig = entities.createConfigForLoadingRows().entity("AnyContact_entity") .uids(contactIds) .fields(["CONTACTID", "ORGANISATION_ID", "PERSON_ID", "STANDARD_EMAIL_COMMUNICATION"]); + //TODO: ignore grants when available since this is only for techincal decisions (like: does a standard-comm exist?) var contactRows = entities.getRows(loadingConfig); - //decide what to do with the data + //decide what to do with the data for (var i = 0, l = contactRows.length; i < l; i++) { //first create a link @@ -59,7 +60,7 @@ var mailObj = mail.parseRFC(vars.get("$param.MailAsText_param")); var unlinkedMailId = vars.get("$param.UnlinkedMailId_param"); var incomingMailExec = new IncomingEmailExecutor(mailObj); -incomingMailExec.setActivityEmployeeContactId(EmployeeUtils.getCurrentContactId()); +incomingMailExec.setActivityEmployeeContact(vars.get("$field.RESPONSIBLE_ID"));//TODO: language! var activityRes = incomingMailExec.createActivity(activityLinks); incomingMailExec.deleteUnlinkedMail(unlinkedMailId); diff --git a/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js b/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js index 38238664039762ee14eb60459947c46d3e12dd0c..773f204fd3e645dfc9e94e7e5b3f3bf3cdfd05a2 100644 --- a/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js +++ b/entity/UnlinkedMail_entity/entityfields/toactivity_actiongroup/children/toactivity_action/onActionProcess.js @@ -13,7 +13,7 @@ if (incomingMailExec.isUnlinkable()) } else { - incomingMailExec.setActivityEmployeeContactId(EmployeeUtils.getCurrentContactId()); + incomingMailExec.setActivityEmployeeContact(EmployeeUtils.getCurrentContactId()); incomingMailExec.createActivity(); incomingMailExec.deleteUnlinkedMail(vars.get("$sys.uid")); //refresh is needed for the dashboard: other elements are refreshed and display for example a new activity in the filter view while the own record (=ulinked mail) is removed diff --git a/process/DataCaching_lib/process.js b/process/DataCaching_lib/process.js index 62cb7b83ac50df30a5bb853943243e5540622bdb..3965f570fc041d2406b86f27110872a655ae242e 100644 --- a/process/DataCaching_lib/process.js +++ b/process/DataCaching_lib/process.js @@ -1,3 +1,4 @@ +import("system.db"); import("system.vars"); import("system.project"); @@ -11,11 +12,14 @@ import("system.project"); * @param {String} pIdentifiyingName name to identify the DataCache. This MUST be unique for one data representation (e.g. key-value pair for all Languages with key ISO2-code and value the ISO3-Code). this will affect the storage-name (=name of the global variable on the client for example) * @param {bool} [pKeepPerLanguage=false] if true the data is kept per locale (different storing for each requested language), false when not (every language is sharing the same stoarge because only untranslated data is kept) * @param {String} [pLocaleOverride=current language] sometimes a special locale is required, use this parameter to specify it + * @param {String} [pAlias=none] sometimes you want to interact with the database and a specific alias. Whenever this is done you can specify an alias name + * the alias will be part of the storage variable name which means data is cached "per alias" * * @class */ -function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride) +function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride, pAlias) { + this.alias = pAlias; this.identifyingName = pIdentifiyingName; this.keepPerLanguage = (pKeepPerLanguage == true); @@ -42,7 +46,7 @@ function CachedData(pIdentifiyingName, pKeepPerLanguage, pLocaleOverride) CachedData.make = function(pIdentifiyingName, pKeepPerLanguage, pDataCallbackFunction) { return (new CachedData(pIdentifiyingName, pKeepPerLanguage, null)).load(pDataCallbackFunction); -} +}; /** * loads data into a DataCache; @@ -70,8 +74,10 @@ CachedData.prototype.load = function(pDataCallbackFunction) cachingEnabled = false; } + //always pass a aliasname to make it easier in the callback functions (you don't have to check if the alias set or not in the callback functions) + var dbAliasParam = this.alias || db.getCurrentAlias(); if (!cachingEnabled) - return pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale); + return pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale, dbAliasParam); else { var varname = this.getVariableName(); @@ -83,7 +89,7 @@ CachedData.prototype.load = function(pDataCallbackFunction) return data; } - data = pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale); + data = pDataCallbackFunction.call(this, this.keepPerLanguage, this.locale, dbAliasParam); if (data == null) { this.unload(); @@ -131,6 +137,8 @@ CachedData.prototype.getVariableIdentifier = function() CachedData.prototype.getVariableName = function() { var res = this.getVariableIdentifier() + "." + this.locale; + if (this.alias) + res += "." + this.alias; return res; }; diff --git a/process/IncomingEmailExecutor_lib/process.js b/process/IncomingEmailExecutor_lib/process.js index 096ef3111e2f05371f5de193cb0a165db89d412b..a00efeef474cdcddf7580fef63537cee8ef58119 100644 --- a/process/IncomingEmailExecutor_lib/process.js +++ b/process/IncomingEmailExecutor_lib/process.js @@ -1,3 +1,5 @@ +import("system.translate"); +import("Keyword_lib"); import("EmailUtil_lib"); import("Util_lib"); import("system.question"); @@ -20,6 +22,7 @@ function IncomingEmailExecutor(pMail) //whenver this function is called it may not be in a context where a alias is given: the mail-importing-entity for example has no alias. //therefore set it here manually this._alias = null; + this.locale = null;//this is maybe set later when determining an affected user for history this.setAlias(); this.rawMail = pMail; this.mailSubject = this.rawMail[mail.MAIL_SUBJECT] || ""; @@ -47,9 +50,29 @@ function IncomingEmailExecutor(pMail) }; } -IncomingEmailExecutor.prototype.setActivityEmployeeContactId = function (pId) +IncomingEmailExecutor.prototype.setActivityEmployeeContact = function (pContactId, pLanguageIso3, pSetAsFailback) { - this.activityData.employeeContactId = pId; + //autodetect language if not given + if (pLanguageIso3 == undefined) + { + var langSql = SqlCondition.begin(this._alias) + .andPrepare("CONTACT.CONTACTID", pContactId) + .buildSql("select CONTACT.ISOLANGUAGE from CONTACT"); + var lang = db.cell(langSql, this._alias); + if (lang) + pLanguageIso3 = lang; + } + + if (pSetAsFailback) + { + this.failbackActivityData.employeeContactId = pContactId; + this.failbackActivityData.employeeContactLanguage = pLanguageIso3; + } + else + { + this.activityData.employeeContactId = pContactId; + this.activityData.employeeContactLanguage = pLanguageIso3; + } }; IncomingEmailExecutor.prototype.setAlias = function(pAlias) @@ -59,15 +82,44 @@ IncomingEmailExecutor.prototype.setAlias = function(pAlias) IncomingEmailExecutor.prototype.getMailtextAsHtml = function() { - var htmlMailText = this.rawMail[mail.MAIL_ATTACHMENTCOUNT] + " Attachement(s)<br/><br/>\n"; + var textInfos = [ + translate.withArguments("Sender: %0", [this.rawMail[mail.MAIL_SENDER]], this.locale), + translate.withArguments("Recipients: %0", [this.mailRecipients.join(", ")], this.locale) + ]; + + var attachmentInfos = mail.getAttachmentInfos(this.rawMail); + var attachmentCount = attachmentInfos.length; + if (attachmentCount == 0) + textInfos.push(translate.text("no attachments", this.locale)); + else + { + if (attachmentCount == 1) + textInfos.push(translate.withArguments("%0 attachment:", [attachmentCount], this.locale)); + else + textInfos.push(translate.withArguments("%0 attachments:", [attachmentCount], this.locale)); + + var attachmentHtml = ""; + var fileName; + for (var i = 0; i < attachmentCount; i++) + { + //don't use a <ul><li.......</ul> here since it does not look good in the client + [fileName] = text.decodeMS(attachmentInfos[i]); + attachmentHtml += "\n" + (i > 0 ? "<br/>" : "") + "● " + fileName; + } + textInfos.push(attachmentHtml); + } + //since the activity has always and only a HTML-content-field we need to ensure that there will be always a HTML-content if (this.rawMail[mail.MAIL_HTMLTEXT]) - htmlMailText += this.rawMail[mail.MAIL_HTMLTEXT]; + textInfos.push("<br/>\n" + this.rawMail[mail.MAIL_HTMLTEXT]); else - htmlMailText += text.text2html(this.rawMail[mail.MAIL_TEXT], true); - return htmlMailText; + textInfos.push("<br/>\n" + text.text2html(this.rawMail[mail.MAIL_TEXT], true)); + + var res = textInfos.join("<br/>\n"); + return res; }; + IncomingEmailExecutor.prototype.getSenderInfo = function() { if (this._senderInfo == null) @@ -97,7 +149,7 @@ IncomingEmailExecutor.getContactDataByEmail = function (pMailAddress, pAlias) var mailAddress = EmailUtils.extractAddress(pMailAddress).toUpperCase(); var sql = SqlCondition.begin(pAlias) .andPrepare("COMMUNICATION.ADDR", mailAddress, "upper(#) = ?") - .buildSql("select CONTACT.CONTACTID, CONTACT.STATUS, CONTACT.PERSON_ID \n\ + .buildSql("select CONTACT.CONTACTID, CONTACT.STATUS, CONTACT.PERSON_ID, CONTACT.ISOLANGUAGE \n\ from COMMUNICATION \n\ join CONTACT on (COMMUNICATION.CONTACT_ID = CONTACT.CONTACTID)"); var res = db.table(sql, pAlias); @@ -125,6 +177,15 @@ IncomingEmailExecutor.prototype.createActivity = function(pAdditionalLinks) this.activityData.links = this.activityData.links.concat(recipientContacts.prefered.length > 0 ? recipientContacts.prefered : recipientContacts.failback); } + var langIso3 = this.activityData.employeeContactLanguage || this.failbackActivityData.employeeContactLanguage; + var langIso2; + if (langIso3) + { + langIso2 = LanguageKeywordUtils.Iso2FromIso3(langIso3, this._alias); + if (langIso2) + this.locale = langIso2; + } + //collecting all the information and combine it for the creation var activityDataForInsert = { subject: this.mailSubject, @@ -171,8 +232,8 @@ IncomingEmailExecutor.prototype.autoProcess = function(pUnlinkedMailId) IncomingEmailExecutor.prototype._getProcessingFunction = function (pIsSender, pTargetArray) { return function(contactInfoRow) { - var contactId, contactStatus, contactPersonId; - [contactId, contactStatus, contactPersonId] = contactInfoRow; + var contactId, contactStatus, contactPersonId, languageIso3; + [contactId, contactStatus, contactPersonId, languageIso3] = contactInfoRow; //there *should* only exist no or one user per contactid, never two or more - so getUser (not getUsers) should be fine var user = tools.getUserByAttribute(tools.CONTACTID, [contactId]); @@ -185,13 +246,13 @@ IncomingEmailExecutor.prototype._getProcessingFunction = function (pIsSender, pT var direction = pIsSender ? $KeywordRegistry.activityDirection$outgoing() : $KeywordRegistry.activityDirection$incoming(); if (isContactActive) { - this.activityData.employeeContactId = contactId; + this.setActivityEmployeeContact(contactId, languageIso3); this.activityData.direction = direction; } else { //if the user is inactive, we may find a better (=active) user later - this.failbackActivityData.employeeContactId = contactId; + this.setActivityEmployeeContact(contactId, languageIso3, true); this.failbackActivityData.direction = direction; } } diff --git a/process/KeywordData_lib/process.js b/process/KeywordData_lib/process.js index 930d056393a8989f28842af3307d707754773264..3eb97115b302f01e8bbc722a9ad93bb8f19dc631 100644 --- a/process/KeywordData_lib/process.js +++ b/process/KeywordData_lib/process.js @@ -113,18 +113,20 @@ LanguageData.getData = function() }); }; -LanguageData.getIso3Map = function(pLocale) +LanguageData.getIso3Map = function(pLocale, pAlias) { - 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 dbAlias = pAlias || db.getCurrentAlias(); + var cache = new CachedData("LanguagesISO3Map", true, pLocale, dbAlias); + var cachedData = cache.load(function (pTranslationNecessary, pLocale, pAlias){ + var data = db.table("select AB_LANGUAGE.ISO3, AB_LANGUAGE.ISO2, AB_LANGUAGE.NAME_LATIN from AB_LANGUAGE", pAlias); var res = {}; - var iso3, countryName; + var iso3, iso2, countryName; for (var i = 0, l = data.length; i < l; i++) { - [iso3, countryName] = data[i]; - res[iso3] = translate.text(countryName, pLocale); + [iso3, iso2, countryName] = data[i]; + res[iso3] = {name: translate.text(countryName, pLocale), iso2: iso2}; } return res; }); + return cachedData; }; \ No newline at end of file diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js index f0fd2438cb04e50991413362f85f97be8915c96f..ec1d8fbe077302645521473c27d39cb164efe8e7 100644 --- a/process/Keyword_lib/process.js +++ b/process/Keyword_lib/process.js @@ -323,8 +323,36 @@ LanguageKeywordUtils.getViewValue = function(key, locale) return ""; var languageMap = LanguageData.getIso3Map(locale); - var title = languageMap[key]; + var languageInfo = languageMap[key]; + if (languageInfo == undefined) + return ""; + var title = languageInfo.name; if (title == undefined) return ""; return title; +}; + +/** + * deterines on server- and clientside the matching iso2-code to a iso3 by generating a map and then returning the matched result; + * on clientside the map is cached + * + * @param {String} key id value (iso3) of the language where the value shall be searched + * @param {String} [pAlias=the current alias] the database alias where the information shall be retrieved + * + * @return {String} iso2 or "" when nothing was found + * + */ +LanguageKeywordUtils.Iso2FromIso3 = function(key, pAlias) +{ + if (!key) + return ""; + //maybe this should be retrieved by a simple select on the serverside since LanguageData-methods are only cached on the client side + var languageMap = LanguageData.getIso3Map(null, pAlias); + var languageInfo = languageMap[key]; + if (languageInfo == undefined) + return ""; + var res = languageInfo.iso2; + if (res == undefined) + return ""; + return res; }; \ No newline at end of file