diff --git a/entity/Offer_entity/entityfields/deliveryterms/valueProcess.js b/entity/Offer_entity/entityfields/deliveryterms/valueProcess.js index 9d4288fee2165c91476d90ec0f0d636bde33d4a6..ff143a3b866db9b739ae9532997d6dd4041b5a89 100644 --- a/entity/Offer_entity/entityfields/deliveryterms/valueProcess.js +++ b/entity/Offer_entity/entityfields/deliveryterms/valueProcess.js @@ -20,7 +20,7 @@ else if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) var orgContactId = ContactUtils.getOrgContactId(contactIds[2]); if (orgContactId) { - presetValue = AttributeRelationUtils.getAttribute($AttributeRegistry.deliveryTerm(), orgContactId); + presetValue = new AttributeRelationQuery(orgContactId, $AttributeRegistry.deliveryTerm()).getSingleAttributeValue(); } } diff --git a/entity/Offer_entity/entityfields/paymentterms/valueProcess.js b/entity/Offer_entity/entityfields/paymentterms/valueProcess.js index 98081578fa2e983e3da8bcc77d81645252d65a20..4b13796a10e4c66b70d7abe004fa7369b3c515b3 100644 --- a/entity/Offer_entity/entityfields/paymentterms/valueProcess.js +++ b/entity/Offer_entity/entityfields/paymentterms/valueProcess.js @@ -20,7 +20,7 @@ else if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) var orgContactId = ContactUtils.getOrgContactId(contactIds[2]); if (orgContactId) { - presetValue = AttributeRelationUtils.getAttribute($AttributeRegistry.paymentTerm(), orgContactId); + presetValue = new AttributeRelationQuery(orgContactId, $AttributeRegistry.paymentTerm()).getSingleAttributeValue(); } } diff --git a/entity/Offeritem_entity/entityfields/product_id/onValueChange.js b/entity/Offeritem_entity/entityfields/product_id/onValueChange.js index 3bad73db28fa32f6f74a7faca5e8767c1e54dc3b..5a3438e82a94699eed10690721bc6364747ade2b 100644 --- a/entity/Offeritem_entity/entityfields/product_id/onValueChange.js +++ b/entity/Offeritem_entity/entityfields/product_id/onValueChange.js @@ -13,7 +13,7 @@ if(pid != "") { var currency = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : ""; var contactid = vars.exists("$param.ContactId_param") ? vars.get("$param.ContactId_param") : ""; - var pricelist = AttributeRelationUtils.getAttribute($AttributeRegistry.pricelist(), contactid) || ""; + var pricelist = new AttributeRelationQuery(contactid, $AttributeRegistry.pricelist()).getSingleAttributeValue() || ""; var PriceListFilter = { currency: currency, quantity: vars.get("$field.QUANTITY"), relationId: contactid, priceList: pricelist }; diff --git a/entity/Offeritem_entity/entityfields/quantity/onValueChange.js b/entity/Offeritem_entity/entityfields/quantity/onValueChange.js index 5098743ffb034230fa82e48dac7a1849814e7a93..051fa52ad7aebb44ad62ec755fa776f4232cc9bd 100644 --- a/entity/Offeritem_entity/entityfields/quantity/onValueChange.js +++ b/entity/Offeritem_entity/entityfields/quantity/onValueChange.js @@ -12,7 +12,7 @@ if(pid != "" && newQuantity != "") { var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : ""; var contactid = vars.exists("$param.ContactId_param") ? vars.get("$param.ContactId_param") : ""; - var pricelist = AttributeRelationUtils.getAttribute($AttributeRegistry.pricelist(), contactid) || ""; + var pricelist = new AttributeRelationQuery(contactid, $AttributeRegistry.pricelist()).getSingleAttributeValue() || ""; var PriceListFilter = { currency: curr, quantity: newQuantity, relationId: contactid, priceList: pricelist }; diff --git a/entity/Order_entity/entityfields/deliveryterms/valueProcess.js b/entity/Order_entity/entityfields/deliveryterms/valueProcess.js index 35c2c1c5d5d22158f534b0022173bdaa4a225abb..99fd7d0b2246eec03bd23438043c005ae5bc16c7 100644 --- a/entity/Order_entity/entityfields/deliveryterms/valueProcess.js +++ b/entity/Order_entity/entityfields/deliveryterms/valueProcess.js @@ -22,7 +22,7 @@ else if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW && vars.get("$t var orgContactId = ContactUtils.getOrgContactId(contactIds[2]); if (orgContactId) { - presetValue = AttributeRelationUtils.getAttribute($AttributeRegistry.deliveryTerm(), orgContactId); + presetValue = new AttributeRelationQuery(orgContactId, $AttributeRegistry.deliveryTerm()).getSingleAttributeValue(); } } diff --git a/entity/Order_entity/entityfields/paymentterms/valueProcess.js b/entity/Order_entity/entityfields/paymentterms/valueProcess.js index 8e1009ab59b81a1239a3aabab00bae72f0399aea..7f0d5a1cab9400e5de82cdb30f175dbab3f4ed59 100644 --- a/entity/Order_entity/entityfields/paymentterms/valueProcess.js +++ b/entity/Order_entity/entityfields/paymentterms/valueProcess.js @@ -21,7 +21,7 @@ if (vars.get("$this.value") == null) { var orgContactId = ContactUtils.getOrgContactId(contactIds[2]); if (orgContactId) { - presetValue = AttributeRelationUtils.getAttribute($AttributeRegistry.paymentTerm(), orgContactId); + presetValue = new AttributeRelationQuery(orgContactId, $AttributeRegistry.paymentTerm()).getSingleAttributeValue(); } } diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js index 51bd26c91d3e467fb68bee4ec454597d5cf1eee2..94ddda7c7683d875a4d73309038585e3ae51600f 100644 --- a/process/Attribute_lib/process.js +++ b/process/Attribute_lib/process.js @@ -308,10 +308,9 @@ AttributeUtil.hasRelations = function (pAttributeId) { if (!pAttributeId) return false; - return newSelect("count(*)") - .from("AB_ATTRIBUTERELATION") - .where("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId) - .cell() != "0"; //TODO: is there a way exists could be used? + return new AttributeRelationQuery() + .attributeId(pAttributeId) + .getAttributeCount() != 0; } /** @@ -358,7 +357,7 @@ AttributeUtil.hasAttributes = function (pObjectType) function AttributeRelationUtils () {} /** - * @deprecated use getAttributeValue and getAttributeValues instead + * @deprecated use AttributeRelationQuery * * gets the value of an attributeRelation for one dataset (e. g. a person) * @@ -372,110 +371,17 @@ function AttributeRelationUtils () {} */ AttributeRelationUtils.getAttribute = function (pAttributeId, pObjectRowId, pObjectType, pGetViewValue, pGetAttrname) { - var defaultFields = [ - "AB_ATTRIBUTE.ATTRIBUTE_TYPE", - "AB_ATTRIBUTE.DROPDOWNDEFINITION", - "COMBOVAL.ATTRIBUTE_NAME" - ]; + var attributeQuery = new AttributeRelationQuery(pObjectRowId, pAttributeId, pObjectType); + if (pGetViewValue) + attributeQuery.includeDisplayValue(); if (pGetAttrname) - defaultFields.push("AB_ATTRIBUTE.ATTRIBUTE_NAME"); + attributeQuery.includeFullAttributeName(); - var valueFields = AttributeTypeUtil.getAllDatabaseFields(); - - var attributeValues = AttributeRelationUtils.getAttributeSqlBuilder(defaultFields.concat(valueFields), pObjectRowId, pObjectType) - .and("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId) - .arrayRow(); - - if (!attributeValues.length) - return null; + var attribute = attributeQuery.getSingleAttribute(); + var value = pGetViewValue ? attribute.displayValue : attribute.value; - let value = attributeValues[AttributeTypeUtil.getTypeColumnIndex(attributeValues[0]) + defaultFields.length]; - if (pGetViewValue && attributeValues[1].trim() == $AttributeTypes.COMBO) - value = attributeValues[2]; - else if (pGetViewValue) - value = AttributeTypeUtil.getAttributeViewValue(attributeValues[0].trim(), value, attributeValues[1]); - - if (pGetAttrname) - value = [attributeValues[3], value]; - - return value; -} - -/** - * gets the values of an attributeRelation for one dataset as array (because multiple usages are possible) - * - * @param {String} pAttributeId attribute-id - * @param {String} pObjectRowId row-id of the dataset - * @param {String} [pObjectType=null] object-type - * @param {String} [pGetExtraProperties=false] If true, the rows of the result are objects with the properties - * value, displayValue and attributeName. Otherwise it would just be the value as string. - * - * @return {Array} the values of the attribute, it's a String[] if pGetExtraProperties is false and - * an Object[] if it's true - */ -AttributeRelationUtils.getAttributeValues = function (pAttributeId, pObjectRowId, pObjectType, pGetExtraProperties) -{ - var defaultFields = [ - "AB_ATTRIBUTE.ATTRIBUTE_TYPE", - "AB_ATTRIBUTE.DROPDOWNDEFINITION", - "AB_ATTRIBUTE.ATTRIBUTE_NAME", - "COMBOVAL.ATTRIBUTE_NAME" - ]; - - var valueFields = AttributeTypeUtil.getAllDatabaseFields(); - - var attributeValues = AttributeRelationUtils.getAttributeSqlBuilder(defaultFields.concat(valueFields), pObjectRowId, pObjectType) - .and("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId) - .table(); - - if (attributeValues.length == 0) - return []; - - var valueIndex = AttributeTypeUtil.getTypeColumnIndex(attributeValues[0][0]) + defaultFields.length; - var stdMappingFn = function (row) - { - return row[valueIndex]; - } - - var extraPropMappingFn = function (row) - { - var value = stdMappingFn(row); - - var displayValue; - if (row[0].trim() == $AttributeTypes.COMBO) - displayValue = row[3]; - else - displayValue = AttributeTypeUtil.getAttributeViewValue(row[0].trim(), value, row[1]); - - return { - value : value, - displayValue : displayValue, - attributeName : row[2] - }; - } - - return attributeValues.map(pGetExtraProperties ? extraPropMappingFn : stdMappingFn); -} - -/** - * Gets the value of an attributeRelation for one dataset. You should use this - * only for attributes with a maximal usage count of 1, because if the attribute is set - * multiple times, it is undetermined which value this function returns. - * - * @param {String} pAttributeId attribute-id - * @param {String} pObjectRowId row-id of the dataset - * @param {String} [pObjectType=null] object-type - * @param {String} [pGetExtraProperties=false] If true, the result is an object with the properties - * value, displayValue and attributeName. Otherwise it would just be the value as string. - * - * @return {String|Object} the value of the attribute, it's a String if pGetExtraProperties is false and - * an Object if it's true - */ -AttributeRelationUtils.getAttributeValue = function (pAttributeId, pObjectRowId, pObjectType, pGetExtraProperties) -{ - var values = AttributeRelationUtils.getAttributeValues(pAttributeId, pObjectRowId, pObjectType, pGetExtraProperties); - return values[0] || null; + return pGetAttrName ? [attribute.fullAttributeName, value] : value; } /** @@ -492,11 +398,12 @@ AttributeRelationUtils.getAttributeSqlBuilder = function (pFields, pObjectRowId, .from("AB_ATTRIBUTERELATION") .join("AB_ATTRIBUTE", "AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID") .leftJoin("AB_ATTRIBUTE COMBOVAL", $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID") - .where("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId) + .whereIfSet("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId) .andIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); } /** + * @deprecated use AttributeRelationQuery * gets all attributes for a dataset * * @param {String} pObjectRowId object rowid @@ -510,57 +417,27 @@ AttributeRelationUtils.getAttributeSqlBuilder = function (pFields, pObjectRowId, */ AttributeRelationUtils.getAllAttributes = function (pObjectRowId, pObjectType, pUseAttributeIds, pUseIdValues) { - var defaultFields = [ - "AB_ATTRIBUTE_ID", - "AB_ATTRIBUTE.ATTRIBUTE_TYPE", - "AB_ATTRIBUTE.DROPDOWNDEFINITION", - "COMBOVAL.ATTRIBUTE_NAME" - ]; - var valueFields = AttributeTypeUtil.getAllDatabaseFields(); + var attributeQuery = new AttributeRelationQuery(pObjectRowId, pObjectType); - var attributeNameMap = {}; + if (!pUseAttributeIds || pUseAttributeIds == 2) + attributeQuery.includeFullAttributeName(); + if (!pUseIdValues) + attributeQuery.includeDisplayValue(); - var attributeValues = AttributeRelationUtils.getAttributeSqlBuilder(defaultFields.concat(valueFields), pObjectRowId, pObjectType) - .table(); - - attributeValues = attributeValues.map(function (row) + return attributeQuery.getAttributes().map(function (row) { - let attribute = row[0]; - let attrname; - if (pUseAttributeIds == 0 || pUseAttributeIds == 2) + var value = pUseIdValues ? row.value : row.displayValue; + switch (pUseAttributeIds) { - var tmpAttrname = ""; - if (!(attribute in attributeNameMap)) - attributeNameMap[attribute] = AttributeUtil.getFullAttributeName(attribute); - tmpAttrname = attributeNameMap[attribute]; - - // if mode 0, return only the name - if (pUseAttributeIds == 0) - attribute = tmpAttrname - - // if mode 2 return both - if (pUseAttributeIds == 2) - attrname = tmpAttrname + case 1: + return [row.attributeId, value]; + case 2: + return [row.attributeId, row.fullAttributeName, value]; + case 0: + default: + return [row.fullAttributeName, value]; } - let value = row[AttributeTypeUtil.getTypeColumnIndex(row[1]) + defaultFields.length]; - if (!pUseIdValues && row[1].trim() == $AttributeTypes.COMBO) - value = row[3]; - else if (!pUseIdValues) - value = AttributeTypeUtil.getAttributeViewValue(row[1].trim(), value, row[2]); - - // add attrname only if id AND attrname is needed - var data = []; - - data.push(attribute); - - if (attrname) - data.push(attrname); - - data.push(value); - return data; }); - - return attributeValues; } /** @@ -618,7 +495,7 @@ AttributeRelationUtils.setAttribute = function (pRowId, pObjectType, pAttributeI maxCount = maxCount[0]; if (maxCount && maxCount != 0) { - let timesUsed = AttributeRelationUtils.getAttributeValues(pAttributeId, pRowId, pObjectType).length; + let timesUsed = new AttributeRelationQuery(pRowId, pObjectType, pAttributeId).getAttributeCount(); if (timesUsed >= maxCount) return false; } @@ -818,13 +695,14 @@ AttributeRelationUtils.countAttributeRelations = function (pRowId, pObjectType, //unchanged (already stored) row ==> increase count var countObj = {}; - var storedAttributeRelations = newSelect("AB_ATTRIBUTERELATIONID, AB_ATTRIBUTE_ID") - .from("AB_ATTRIBUTERELATION") - .where("AB_ATTRIBUTERELATION.OBJECT_ROWID", pRowId) - .andIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType) - .table(); + storedAttributeRelations = new AttributeRelationQuery() + .objectRowId(pRowId) + .objectType(pObjectType) + .getAttributes(); - storedAttributeRelations.forEach(function ([storedAttrRelationId, storedAttributeId]) { + storedAttributeRelations.forEach(function (storedRow) { + var storedAttributeId = storedRow.attributeId; + var storedAttrRelationId = storedRow.attributeRelationId; var currentAttributeId = storedAttributeId; //merging the data that is stored in the DB and the provided changes if (pAttributeChanges && storedAttrRelationId in pAttributeChanges) @@ -919,7 +797,17 @@ $AttributeTypes.COMBO = { contentType : "UNKNOWN", databaseField : "ID_VALUE", isGroup : true, - possibleChildren : ["COMBOVALUE"] + possibleChildren : ["COMBOVALUE"], + //in most cases the view value of this attribute type is loaded via a direct sql join for less queries and better performance + getViewValue : function (pValue) + { + var viewValue = newSelect("AB_ATTRIBUTE.ATTRIBUTE_NAME") + .from("AB_ATTRIBUTE") + .where("AB_ATTRIBUTE.AB_ATTRIBUTEID", pValue) + .and("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE) + .cell(); + return viewValue ? translate.text(viewValue) : viewValue; + } }; $AttributeTypes.COMBOVALUE = { toString : function () {return "COMBOVALUE";}, @@ -1348,4 +1236,175 @@ AttributeUsageUtil.removeDuplicates = function (pAttributeId) }, usageObj); deleteCond.deleteData(); -} \ No newline at end of file +} + +/*************************************************************************************************/ + +/** + * @class + * + * An AttributeRelationQuery can be used for getting the value and other properties + * of an AttributeRelation. You have to instanciate it with "new". + */ +function AttributeRelationQuery (pObjectRowId, pAttributeId, pObjectType) +{ + this._rowId = pObjectRowId || null; + this._objectType = pObjectType || null; + this._attributeIds = pAttributeId ? [pAttributeId] : null; + this._attributeTypes = null; + this._includeFullAttributeName = false; + this._includeDisplayValue = false; + + return this; +} + +/** + * sets the object-row-id for the query + */ +AttributeRelationQuery.prototype.objectRowId = function (pObjectRowId) +{ + this._rowId = pObjectRowId; + return this; +} + +/** + * sets the object-type for the query + */ +AttributeRelationQuery.prototype.objectType = function (pObjectType) +{ + this._objectType = pObjectType; + return this; +} + +/** + * sets the attribute id for the query + */ +AttributeRelationQuery.prototype.attributeId = function (pAttributeId) +{ + this._attributeIds = [pAttributeId]; + return this; +} + +/** + * sets the attribute ids for the query + */ +AttributeRelationQuery.prototype.attributeIds = function (pAttributeIds) +{ + this._attributeIds = pAttributeIds; + return this; +} + +/** + * sets the attribute type for the query + */ +AttributeRelationQuery.prototype.attributeTypes = function (pAttributeTypes) +{ + this._attributeTypes = pAttributeTypes; + return this; +} + +/** + * if this method was called, the query result will contain the fullAttributeName + */ +AttributeRelationQuery.prototype.includeFullAttributeName = function () +{ + this._includeFullAttributeName = true; + return this; +} + +/** + * if this method was called, the query result will contain the displayValue + */ +AttributeRelationQuery.prototype.includeDisplayValue = function () +{ + this._includeDisplayValue = true; + return this; +} + +/** + * @TODO: document object structure + * executes the query and returns the result + * + * @return {Object[]} array of objects + */ +AttributeRelationQuery.prototype.getAttributes = function () +{ + var defaultFields = [ + "AB_ATTRIBUTE.ATTRIBUTE_TYPE", + "AB_ATTRIBUTE.DROPDOWNDEFINITION", + "AB_ATTRIBUTE.ATTRIBUTE_NAME", + "COMBOVAL.ATTRIBUTE_NAME", + "AB_ATTRIBUTE.AB_ATTRIBUTEID", + "AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID" + ]; + + var valueFields = AttributeTypeUtil.getAllDatabaseFields(); + + var attributeValues = AttributeRelationUtils.getAttributeSqlBuilder(defaultFields.concat(valueFields), this._rowId, this._objectType) + .andIfSet("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", this._attributeIds, SqlBuilder.IN()) + .andIfSet("AB_ATTRIBUTE.ATTRIBUTE_TYPE", this._attributeTypes, SqlBuilder.IN()) + .table(); + + if (attributeValues.length == 0) + return []; + + var mappingFn = function (row) + { + var attrObj = { + attributeId : row[4], + value : row[AttributeTypeUtil.getTypeColumnIndex(row[0]) + defaultFields.length], + attributeRelationId : row[5], + attributeName : row[2], + attributeType : row[0] + }; + + if (this._includeDisplayValue) + { + if (row[0].trim() == $AttributeTypes.COMBO) + attrObj.displayValue = translate.text(row[3]); + else + attrObj.displayValue = AttributeTypeUtil.getAttributeViewValue(row[0].trim(), attrObj.value, row[1]); + } + if (this._includeFullAttributeName) + { + attrObj.fullAttributeName = AttributeUtil.getFullAttributeName(row[4]); + } + + return attrObj; + } + + return attributeValues.map(mappingFn, this); +} + +/** + * @return {Object} + */ +AttributeRelationQuery.prototype.getSingleAttribute = function () +{ + if (!this._attributeIds || this._attributeIds.length !== 1) + throw new Error("You have to specify a single attribute id"); + return this.getAttributes()[0] || null; +} + +/** + * Executes the query and returns a single value. For this, there must be a attribute id set. + * + * @return {String} + */ +AttributeRelationQuery.prototype.getSingleAttributeValue = function () +{ + var attribute = this.getSingleAttributes(); + return attribute ? attribute.value : null; +} + +/** + * Executes the query and returns the count of datasets. + * + * @return {Number} the number of attribute relations + */ +AttributeRelationQuery.prototype.getAttributeCount = function () +{ + return parseInt(AttributeRelationUtils.getAttributeSqlBuilder("count(*)", this._rowId, this._objectType) + .andIfSet("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", this._attributeId) + .cell() || 0); +} diff --git a/process/DataPrivacy_lib/process.js b/process/DataPrivacy_lib/process.js index 573d623a41ee4ef923979c4f72c02ba3ca6b0d85..3597ce7e54fcf7c0d3a9d73ad5e641ffdb0cf39d 100644 --- a/process/DataPrivacy_lib/process.js +++ b/process/DataPrivacy_lib/process.js @@ -265,20 +265,23 @@ DataPrivacyType.get = function(pKey) var attributeData = []; if (pContactId) { - attributeData = AttributeRelationUtils.getAllAttributes(pContactId, "Person", 2); - } - else if(pAttributeId) - { - attributeData = AttributeRelationUtils.getAttribute(pAttributeId, pContactId, "Person", true, true); - if (attributeData) - attributeData = [[pAttributeId].concat(attributeData)] + var attributeQuery = new AttributeRelationQuery() + .objectRowId(pContactId) + .objectType("Person") + .includeDisplayValue() + .includeFullAttributeName(); + + if (pAttributeId) + attributeQuery.attributeId(pAttributeId); + + attributeData = attributeQuery.getAttributes(); } return attributeData.map(function(pAttr) { return { - value: pAttr[1] + ": " + translate.text(pAttr[2]), - id: pAttr[0] + value: pAttr.fullAttributeName + ": " + pAttr.displayValue, + id: pAttr.attributeId } }); } diff --git a/process/Organisation_lib/process.js b/process/Organisation_lib/process.js index a5500b246465d5d168849d0303d1da8d6c96e1cc..5ca14d0407276d79fc056d24033f53c9351cbb7b 100644 --- a/process/Organisation_lib/process.js +++ b/process/Organisation_lib/process.js @@ -152,8 +152,11 @@ OrgUtils.openOrgReport = function(pOrgId) }); histData = ReportData.begin(["ENTRYDATE", "MEDIUM", "LOGIN", "INFO"]).add(histData); - var attr = AttributeRelationUtils.getAllAttributes(pOrgId) - .map(function (row) {return row[1] ? row.join(": ") : row[0]}) + var attr = new AttributeRelationQuery(pOrgId) + .includeDisplayValue() + .includeFullAttributeName() + .getAttributes() + .map(function (row) {return row.value ? row.fullAttributeName + ": " + row.displayValue : row.fullAttributeName}) .join("\n"); //tasks