/** * Helper functions for ELOwf forms * * @author MW, ELO Digital Office GmbH * @version 1.0 * * @elowf * @requires sol.common.DateUtils */ sol.define("sol.contract.forms.Utils", { singleton: true, unitSuffix: "_UNIT", localizedKwlSeparator: "-", /** * Iterates over a table. * @param {String} indicatorColumnName Name of a column to check if the line exists. * @param {Function} func Callback function for the iteration. * @param {Object} ctx Execution context. */ forEachRow: function (indicatorColumnName, func, ctx) { if (!indicatorColumnName) { throw "The indicator column name is empty."; } if (!func) { throw "The function parameter is emtpy."; } var i = 1; while ($var(indicatorColumnName + i)) { func.call(ctx, i++); } }, /** * Checks if the specific field has been changed or the form is loaded * @param {Object} source Changed HTML element. * @param {Array} fieldNames Array of field names. * @return {undefined} */ isFieldChangedOrFormLoaded: function (source, fieldNames) { var me = this; if (!me.checkSource(source)) { return true; } return me.isFieldChanged(source, fieldNames); }, /** * Checks if the specific field has been changed * @param {Object} source Changed HTML element. * @param {Array} fieldNames Array of field names. * @return {undefined} */ isFieldChanged: function (source, fieldNames) { var me = this; if (!source) { return false; } return fieldNames.some(function (fieldName) { var fieldBaseName = me.getBaseFieldName(source.name); return ((fieldBaseName == fieldName) || (fieldBaseName + me.unitSuffix == fieldName)); }); }, /** * Checks if the changed input field es set * @param {Object} source Changed input field * @return {Boolean} */ checkSource: function (source) { return (source && source.name); }, /** * Returns the field name without unit suffix and trailing numbers * @param {Object|String} source Source element or field name * @returns {String} */ getBaseFieldName: function (source) { var me = this, fieldName, unitSuffixRegExp; if (me.checkSource(source)) { fieldName = source.name; } else { fieldName = source; } if (!fieldName) { return ""; } fieldName = fieldName.replace(/\d*$/g, ""); unitSuffixRegExp = new RegExp(me.unitSuffix + "$"); fieldName = fieldName.replace(unitSuffixRegExp, ""); return fieldName; }, /** * Returns the field index * @param {String} fieldName Field name * @returns {String} */ getFieldNameIndex: function (fieldName) { if (!fieldName) { return ""; } var pos = fieldName.search(/\d+$/); if (pos > 0) { return parseInt(fieldName.substring(pos), 10); } return ""; }, /** * Returns the first part of a string * @param {String} str String * @param {String} separator Separator * @return {String} */ getFirstStringPart: function (str, separator) { var separatorPos; if (!str) { return ""; } separator = separator || "-"; separatorPos = str.indexOf(separator); if (separatorPos < 0) { return str; } return str.substring(0, separatorPos).trim(); }, /** * Calculates a date * @param {String} srcDateFieldName Source date field name * @param {String} durationFieldName Duration field name * @param {String} dstDateFieldName Destination date field name * @param {Object} params Parameters * @param {String} params.minTermStartFieldName * @param {String} params.minTermNumberFieldName * @param {String} params.endOfFieldName * @param {String} params.endOfUnit * @param {String} params.substractOneDay * @param {String} params.dontSetIfDurationIsEmpty * @param {String} params.minToday */ setCalculatedDate: function (srcDateFieldName, durationFieldName, dstDateFieldName, params) { var me = this, srcIsoDate, durationNumber, durationUnit, dstIsoDate, minTermNumber, minTermUnit, minTermStartIsoDate, minTermIsoDate, todayIso; params = params || {}; todayIso = sol.common.DateUtils.dateToIso(new Date(), { startOfDay: true }); if (srcDateFieldName == "$NOW") { srcIsoDate = todayIso; } else { srcIsoDate = sol.common.forms.Utils.getIsoDate(srcDateFieldName, { startOfDay: true }); } if (srcIsoDate) { durationNumber = $val(durationFieldName) || 0; if (!durationNumber && params.dontSetIfDurationIsEmpty) { return; } durationUnit = me.getKwlKey(durationFieldName + me.unitSuffix); if (params.endOfFieldName) { params.endOfUnit = me.getKwlKey(params.endOfFieldName) || "d"; } if (params.substractOneDay) { srcIsoDate = sol.contract.DurationUtils.calculateDate(srcIsoDate, -1, "d"); } dstIsoDate = sol.contract.DurationUtils.calculateDate(srcIsoDate, durationNumber, durationUnit, params); if (params.minTermNumberFieldName) { minTermStartIsoDate = sol.common.forms.Utils.getIsoDate(params.minTermStartFieldName, { startOfDay: true }); minTermNumber = $val(params.minTermNumberFieldName) || 0; minTermUnit = me.getKwlKey(params.minTermNumberFieldName + me.unitSuffix); minTermIsoDate = sol.contract.DurationUtils.calculateDate(minTermStartIsoDate, minTermNumber, minTermUnit); if (minTermIsoDate > dstIsoDate) { dstIsoDate = minTermIsoDate; } if (params.minToday && (dstIsoDate < todayIso)) { dstIsoDate = todayIso; } } if (!dstIsoDate) { console.warn("Calculated date is empty"); } sol.common.forms.Utils.setIsoDate(dstDateFieldName, dstIsoDate); } else { $update(dstDateFieldName, ""); } inputChanged($var(dstDateFieldName)); }, /** * Set a destination field writeable if it's empty * @param {String} srcFieldName Source field name * @param {String} dstFieldName Destination field name */ setDstFieldWriteableIfEmpty: function (srcFieldName, dstFieldName) { var me = this; me.setReadOnly(dstFieldName, !!$val(srcFieldName)); }, /** * Sets an input field read-only * @param {String} fieldName * @param {Boolean} readOnly Read-only */ setReadOnly: function (fieldName, readOnly) { if (!fieldName) { throw "Field name is emtpy"; } var field = $var(fieldName); if (!field) { throw "Field not found"; } readOnly = (typeof readOnly == "undefined") ? true : readOnly; field.readOnly = readOnly; if (readOnly) { field.parentElement.setAttribute("isreadonly", readOnly); } else { field.parentElement.removeAttribute("isreadonly"); } }, /** * Returns the keyword list key of a localized keyword list field * @param {String} fieldName Field name * @return {String} */ getKwlKey: function (fieldName) { var me = this, value; value = $val(fieldName); return me.getFirstStringPart(value, me.localizedKwlSeparator); }, /** * Returns the field name of the unit field for the given field name * @param {String} fieldName Field name * @return {String} */ getUnitFieldName: function (fieldName) { var me = this; if (!fieldName) { throw "Field name is empty"; } return me.getBaseFieldName(fieldName) + me.unitSuffix + me.getFieldNameIndex(fieldName); }, /** * @deprecated Use {@link sol.common.forms.Utils#fieldExists} instead (from `common` version `1.01.002`) * Checks wether a field exists * @param {String} fieldName * @return {Boolean} */ fieldExists: function (fieldName) { if (!fieldName) { throw "Field name is empty"; } return !!$var(fieldName); }, /** * Checks wether a field exists * @param {Object|String} source element or current field name * @param {String} fieldName Field name to check * @return {Boolean} */ isField: function (source, fieldName) { var me = this, currentFieldName; if (!fieldName) { return false; } currentFieldName = me.getBaseFieldName(source); return (currentFieldName == fieldName); }, /** * Sets a localized keyword list field * @param {String} fieldName Field name * @param {String} key Key * @param {Object} config Configuration */ setLocalizedKwlField: function (fieldName, key, config) { var field, kwlElement, kwlName; config = config || {}; if (config.onlyIfEmpty && ($val(fieldName) || ELO_PARAMS[fieldName])) { return; } field = $var(fieldName); if (!field) { return; } kwlElement = field.nextSibling; if (!kwlElement) { return; } kwlName = kwlElement.getAttribute("swlname"); if (!kwlName) { return; } if (kwlName.indexOf("DYNSWL_") != 0) { return; } kwlName = kwlName.substring(7); $update(fieldName, key); $listDyn(kwlName, fieldName, undefined, function (data) { var i, cells; if (!data || !data.table || (data.table.length == 0)) { return; } for (i = 0; i < data.table.length; i++) { cells = data.table[i]; if (cells[0] == key) { $update(fieldName, cells[2]); return; } } }, function () { console.warn("Can't load dynamic keyword list '" + kwlName + "'"); } ); }, localCurrencySuffix: "_LOCAL_CURR", /** * Calculates and sets the local currency amount * @param {String} amountFieldName Amount field name * @param {String} exchangeRateFieldName Exchange rate field name * @param {Object} config Configuration * @param {String} config.currencyCodeFieldName Amount field name * @param {String} config.baseCurrencyCode Base currency code * @param {String} config.baseCurrencyCodeFieldName Base currency code field name * @param {String} config.localCurrencyAmountFieldName Local currency amount field name * @param {Array} config.dependentElementNames This fields will be shown resp. hidden */ calcLocalCurrencyAmount: function (amountFieldName, exchangeRateFieldName, config) { var me = this, currencyCode, exchangeRate, localCurrencyAmountFieldName, amount, localCurrencyAmount; if (!amountFieldName) { throw "Amount field name is empty"; } if (!exchangeRateFieldName) { throw "Exchange rate field name is empty"; } config = config || {}; localCurrencyAmountFieldName = config.localCurrencyAmountFieldName || amountFieldName + me.localCurrencySuffix; if (config.currencyCodeFieldName && config.baseCurrencyCode) { currencyCode = $val(config.currencyCodeFieldName); if (!currencyCode || (currencyCode == config.baseCurrencyCode)) { $update(config.currencyCodeFieldName, config.baseCurrencyCode); $update(exchangeRateFieldName, "1"); } } me.updateBaseCurrencyCodeField(config); amount = $num(amountFieldName); exchangeRate = $num(exchangeRateFieldName); localCurrencyAmount = sol.contract.DurationUtils.calcLocalCurrencyAmount(amount, exchangeRate); $update(localCurrencyAmountFieldName, localCurrencyAmount); me.enableElements(config.dependentElementNames, Boolean(exchangeRate != 1), { parentTagName: "td" }); }, /** * Reads base currency code from configuration and writes this to map field * @param {Object} config Configuration * @param {String} config.baseCurrencyCode Base currency code * @param {String} config.baseCurrencyCodeFieldName Base currency code field name */ updateBaseCurrencyCodeField: function (config){ config = config || {}; if (config.baseCurrencyCodeFieldName && config.baseCurrencyCode && sol.common.forms.Utils.fieldExists(config.baseCurrencyCodeFieldName)){ $update(config.baseCurrencyCodeFieldName, config.baseCurrencyCode); } }, /** * Calculates a date by start date an duration * @param {String} startDateBaseFieldName Start date field name without index * @param {String} endDateFieldName */ calcDateByDuration: function (startDateBaseFieldName, endDateFieldName) { var me = this, startDateIso, endDateValue, durationNumber, durationUnit, endDateIso, index; if (!startDateBaseFieldName) { throw "Start date base field name is empty"; } if (!endDateFieldName) { throw "End date field name is empty"; } index = me.getFieldNameIndex(endDateFieldName); startDateIso = sol.common.forms.Utils.getIsoDate(startDateBaseFieldName + index, { startOfDay: true }); if (!startDateIso) { return; } endDateValue = $val(endDateFieldName); if (!me.isValidDurationUnit(endDateValue)) { return; } durationNumber = me.getDurationNumber(endDateValue); durationUnit = me.getDurationUnit(endDateValue); durationUnit = me.normalizeDurationUnit(durationUnit); endDateIso = sol.contract.DurationUtils.calculateDate(startDateIso, durationNumber, durationUnit); endDateIso = sol.contract.DurationUtils.calculateDate(endDateIso, -1, "d"); sol.common.forms.Utils.setIsoDate(endDateFieldName, endDateIso); }, /** * Checks whether a string is a duration * @param {String} str Input string * @return {Boolean} */ isValidDurationUnit: function (str) { return /^\d+[y|m|w|d]$/i.test(str); }, /** * Normalize duration unit * @param {String} durationUnit Duration unit * @return {String} */ normalizeDurationUnit: function (durationUnit) { if (!durationUnit) { return; } if (durationUnit == "m") { return "M"; } else { return durationUnit.toLowerCase(); } }, /** * Returns the duration number of a duration string * @param {String} str Input string * @returns {String} */ getDurationNumber: function (str) { var matches; matches = str.match(/^\d+/); return (matches && (matches.length > 0)) ? matches[0] : ""; }, /** * Returns the duration unit of a duration string * @param {String} str Input string * @returns {String} */ getDurationUnit: function (str) { var matches; matches = str.match(/[y|M|w|d|m|s|ms]$/); return (matches && (matches.length > 0)) ? matches[0] : ""; }, /** * Shows or hides elements * @param {Array} elementNames Array of field names * @param {Boolean} show True if the element should be shown. * @param {Object} config Configuration * @param {String} config.parentTagName Parent tag name */ enableElements: function (elementNames, show, config) { var element, i, elementName; if (!elementNames) { return; } config = config || {}; for (i = 0; i < elementNames.length; i++) { elementName = elementNames[i]; element = $var(elementName); if (!element) { continue; } if (config.parentTagName) { element = sol.common.forms.Utils.getParentByTagName(element, "td"); } if (show) { element.classList.remove("hidden"); } else { element.classList.add("hidden"); } } } });