From a72154b9861824f66e79c7ee8c15aa3bd41c8b23 Mon Sep 17 00:00:00 2001 From: Pascal Neub <p.neub@adito.de> Date: Fri, 5 Nov 2021 14:41:29 +0100 Subject: [PATCH] [Projekt: xRM-Sales][TicketNr.: 2001370][Angebot/Beleg Summen berechnen Aktion] --- entity/Offeritem_entity/Offeritem_entity.aod | 5 ++ .../calculateprices/onActionProcess.js | 8 +++ .../recordcontainers/db/onDBInsert.js | 33 ++-------- entity/Order_entity/Order_entity.aod | 3 + entity/Orderitem_entity/Orderitem_entity.aod | 5 ++ .../calculateprices/onActionProcess.js | 8 +++ .../recordcontainers/db/onDBInsert.js | 29 ++------- .../_____LANGUAGE_de/_____LANGUAGE_de.aod | 4 ++ .../OrderitemFilter_view.aod | 1 + process/OfferOrder_lib/process.js | 61 ++++++++++++++++++- process/Offer_lib/process.js | 31 +++++++++- process/Order_lib/process.js | 30 +++++++++ 12 files changed, 163 insertions(+), 55 deletions(-) create mode 100644 entity/Offeritem_entity/entityfields/group/children/calculateprices/onActionProcess.js create mode 100644 entity/Orderitem_entity/entityfields/group/children/calculateprices/onActionProcess.js diff --git a/entity/Offeritem_entity/Offeritem_entity.aod b/entity/Offeritem_entity/Offeritem_entity.aod index 87a0d3f6cae..f62154dc493 100644 --- a/entity/Offeritem_entity/Offeritem_entity.aod +++ b/entity/Offeritem_entity/Offeritem_entity.aod @@ -284,6 +284,11 @@ <state>DISABLED</state> <stateProcess>%aditoprj%/entity/Offeritem_entity/entityfields/group/children/movedown/stateProcess.js</stateProcess> </entityActionField> + <entityActionField> + <name>calculatePrices</name> + <title>Calculate sum</title> + <onActionProcess>%aditoprj%/entity/Offeritem_entity/entityfields/group/children/calculateprices/onActionProcess.js</onActionProcess> + </entityActionField> </children> </entityActionGroup> <entityField> diff --git a/entity/Offeritem_entity/entityfields/group/children/calculateprices/onActionProcess.js b/entity/Offeritem_entity/entityfields/group/children/calculateprices/onActionProcess.js new file mode 100644 index 00000000000..84e65c7263c --- /dev/null +++ b/entity/Offeritem_entity/entityfields/group/children/calculateprices/onActionProcess.js @@ -0,0 +1,8 @@ +import("system.neon"); +import("system.vars"); +import("Offer_lib"); + +var oiUtils = new OfferItemUtils(vars.get("$field.OFFER_ID")); +oiUtils.recalculatePrices(vars.get("$sys.selection")); +OfferItemUtils.updateOfferNet(vars.get("$field.OFFER_ID")); +neon.refreshAll(); diff --git a/entity/Offeritem_entity/recordcontainers/db/onDBInsert.js b/entity/Offeritem_entity/recordcontainers/db/onDBInsert.js index f9d76609118..1c643431550 100644 --- a/entity/Offeritem_entity/recordcontainers/db/onDBInsert.js +++ b/entity/Offeritem_entity/recordcontainers/db/onDBInsert.js @@ -1,40 +1,17 @@ import("system.db"); -import("system.entities"); -import("system.neon"); import("system.vars"); import("Offer_lib"); -import("Product_lib"); -import("Sql_lib"); var rowdata = vars.get("$local.rowdata"); var oid = rowdata["OFFERITEM.OFFER_ID"]; if(oid != "") { - var discount = vars.exists("$param.Discount_param") ? vars.get("$param.Discount_param"): ""; - var oiUtils = new OfferItemUtils(rowdata["OFFERITEM.OFFER_ID"]); + OfferItemUtils.updateOfferNet(oid, vars.get("$param.Discount_param")); - var insertStatements = JSON.parse(vars.get("$field.itemInsertStatements"));//insert statements get set by insertPartsList in the onvalueChanges of product_id and quantity - var statements = []; - - //update offer price - var vals = oiUtils.getNetAndVat(); - var discountedVals = OfferItemUtils.getDiscountedNet(null, oid, discount); - if(discountedVals) - { - statements.push( - newWhere("OFFER.OFFERID", rowdata["OFFERITEM.OFFER_ID"]).buildUpdateStatement({ - "NET": vals[0], - "VAT": vals[1], - "DISCOUNTED_NET": discountedVals[0], - "DISCOUNTED_VAT": discountedVals[1] - }) - ) - } - + //insert statements get set by insertPartsList in the onvalueChanges of product_id and quantity + var insertStatements = JSON.parse(vars.get("$field.itemInsertStatements")); if(insertStatements) { - statements = statements.concat(insertStatements); + db.execute(insertStatements, "Data_alias", 10000000); } - - db.execute(statements, "Data_alias", 10000000); -} \ No newline at end of file +} diff --git a/entity/Order_entity/Order_entity.aod b/entity/Order_entity/Order_entity.aod index 399419f16b3..009030c5970 100644 --- a/entity/Order_entity/Order_entity.aod +++ b/entity/Order_entity/Order_entity.aod @@ -4,6 +4,9 @@ <title>Receipt</title> <majorModelMode>DISTRIBUTED</majorModelMode> <documentation>%aditoprj%/entity/Order_entity/documentation.adoc</documentation> + <siblings> + <element>Orderitem_entity</element> + </siblings> <grantUpdateProcess>%aditoprj%/entity/Order_entity/grantUpdateProcess.js</grantUpdateProcess> <grantDeleteProcess>%aditoprj%/entity/Order_entity/grantDeleteProcess.js</grantDeleteProcess> <contentTitleProcess>%aditoprj%/entity/Order_entity/contentTitleProcess.js</contentTitleProcess> diff --git a/entity/Orderitem_entity/Orderitem_entity.aod b/entity/Orderitem_entity/Orderitem_entity.aod index b6f5ec9513c..5fc63065077 100644 --- a/entity/Orderitem_entity/Orderitem_entity.aod +++ b/entity/Orderitem_entity/Orderitem_entity.aod @@ -261,6 +261,11 @@ <state>DISABLED</state> <stateProcess>%aditoprj%/entity/Orderitem_entity/entityfields/group/children/movedown/stateProcess.js</stateProcess> </entityActionField> + <entityActionField> + <name>calculatePrices</name> + <title>Calculate sum</title> + <onActionProcess>%aditoprj%/entity/Orderitem_entity/entityfields/group/children/calculateprices/onActionProcess.js</onActionProcess> + </entityActionField> </children> </entityActionGroup> <entityParameter> diff --git a/entity/Orderitem_entity/entityfields/group/children/calculateprices/onActionProcess.js b/entity/Orderitem_entity/entityfields/group/children/calculateprices/onActionProcess.js new file mode 100644 index 00000000000..83922ee37c9 --- /dev/null +++ b/entity/Orderitem_entity/entityfields/group/children/calculateprices/onActionProcess.js @@ -0,0 +1,8 @@ +import("system.neon"); +import("system.vars"); +import("Order_lib"); + +var oiUtils = new OrderItemUtils(vars.get("$field.SALESORDER_ID")); +oiUtils.recalculatePrices(vars.get("$sys.selection")); +OrderItemUtils.updateOrderNet(vars.get("$field.SALESORDER_ID")); +neon.refreshAll(); diff --git a/entity/Orderitem_entity/recordcontainers/db/onDBInsert.js b/entity/Orderitem_entity/recordcontainers/db/onDBInsert.js index 1e9a6cdb99b..b5ccd5df970 100644 --- a/entity/Orderitem_entity/recordcontainers/db/onDBInsert.js +++ b/entity/Orderitem_entity/recordcontainers/db/onDBInsert.js @@ -10,31 +10,12 @@ var rowdata = vars.get("$local.rowdata"); var oid = rowdata["SALESORDERITEM.SALESORDER_ID"]; if(oid != "") { - var discount = vars.exists("$param.Discount_param") ? vars.get("$param.Discount_param"): ""; - var oiUtils = new OrderItemUtils(oid); - - var insertStatements = JSON.parse(vars.get("$field.itemInsertStatements"));//insert statements get set by insertPartsList in the onvalueChanges of product_id and quantity - var statements = []; - - //update offer price - var vals = oiUtils.getNetAndVat(); - var discountedVals = OrderItemUtils.getDiscountedNet(null, oid, discount); - if(discountedVals) - { - statements.push( - newWhere("SALESORDER.SALESORDERID", oid).buildUpdateStatement({ - "NET": vals[0], - "VAT": vals[1], - "DISCOUNTED_NET": discountedVals[0], - "DISCOUNTED_VAT": discountedVals[1] - }) - ) - } + OrderItemUtils.updateOrderNet(oid, vars.get("$param.Discount_param")); + // insert statements get set by insertPartsList in the onvalueChanges of product_id and quantity + var insertStatements = JSON.parse(vars.get("$field.itemInsertStatements")); if(insertStatements) { - statements = statements.concat(insertStatements); + db.execute(insertStatements, "Data_alias", 10000000); } - - db.execute(statements, "Data_alias", 10000000); -} \ No newline at end of file +} diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod index 2faf905b45a..7ae71eff92c 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -14624,6 +14624,10 @@ Bitte Datumseingabe prüfen</value> <key>Manual resynchronization</key> <value>Manuelle Neusynchronisation</value> </entry> + <entry> + <key>Calculate sum</key> + <value>Summe berechnen</value> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/neonView/OrderitemFilter_view/OrderitemFilter_view.aod b/neonView/OrderitemFilter_view/OrderitemFilter_view.aod index 289133336b7..8d4a407dd44 100644 --- a/neonView/OrderitemFilter_view/OrderitemFilter_view.aod +++ b/neonView/OrderitemFilter_view/OrderitemFilter_view.aod @@ -114,6 +114,7 @@ <element>DISCOUNT</element> <element>INFO</element> </editableColumns> + <favoriteActionGroup1>group</favoriteActionGroup1> <columns> <neonTableColumn> <name>85d30b0c-1e03-4b46-a4d1-caa3e2e7e589</name> diff --git a/process/OfferOrder_lib/process.js b/process/OfferOrder_lib/process.js index 7200a549076..b65c2293ba6 100644 --- a/process/OfferOrder_lib/process.js +++ b/process/OfferOrder_lib/process.js @@ -25,8 +25,6 @@ import("Sql_lib"); function ItemUtils(pOfferOrderId, pTableName) { if (this.constructor === ItemUtils) throw new Error("Can't instantiate abstract class ItemUtils!"); - - this.offerOrderId = pOfferOrderId; this.ItemTree = undefined; // object for dealing with hierarchical structure of Items, item position and item order this.ItemIds = undefined; // contains all ItemIDs to save the order @@ -98,6 +96,65 @@ function ItemUtils(pOfferOrderId, pTableName) { } } +/** + * Recalculates the prices of the given items + * If no items were passed, all elements of the offer/order will be recalculated + * The items are updated directly in the database + * + * @params {String[]} pItemIds the item ids + */ +ItemUtils.prototype.recalculatePrices = function(pItemIds) +{ + if(!pItemIds || !pItemIds.length) + { + pItemIds = this.ItemIds; + } + + var idsSet = new Set(pItemIds); + var data = new Map(); + newSelect([this.tableName + "ITEMID", "QUANTITY", "PRICE", "DISCOUNT"]).from(this.tableName + "ITEM") + .where(this.tableName + "ITEM." + this.tableName + "_ID", this.offerOrderId) + .table().forEach(function(row) + { + data.set(row[0], {quantity: row[1], price: row[2], discount: row[3]}); + }); + var prices = new Map(); + + // TODO: replace with a lambda function as soon as they are supported + var that = this; + _traverse(pItemIds); + function _traverse(pIds) + { + pIds.forEach(function(id) + { + var childIds = that.ItemTree[id].ids; + if(!childIds.length) + { + return; + } + _traverse(childIds.filter(function(childId){return idsSet.has(childId)})); + var price = childIds.reduce(function(curr, childId) + { + var entry = data.get(childId); + var price = prices.get(childId) || entry.price; + return curr + price * entry.quantity * (1 - entry.discount / 100); + }, 0); + if(data.get(id).price != price) + { + prices.set(id, price); + } + }); + } + + // TODO: use a "for of" loop to iterate through the enties iterator + var stmts = Array.from(prices.entries()).map(function([rowId, rowPrice]) + { + var cond = newWhere(that.tableName + "ITEM." + that.tableName + "ITEMID", rowId).toString() + return [that.tableName + "ITEM", ["PRICE"], null, [rowPrice], cond]; + }); + db.updates(stmts); +} + /** * get netto and vat for all items excluding the provided ones. * diff --git a/process/Offer_lib/process.js b/process/Offer_lib/process.js index 03b4b6e521c..2e3e4109529 100644 --- a/process/Offer_lib/process.js +++ b/process/Offer_lib/process.js @@ -535,6 +535,15 @@ function OfferItemUtils(pOfferId) { OfferItemUtils.prototype.constructor = OfferItemUtils; } +/** + * For documentation, see class ItemUtils. + */ +OfferItemUtils.prototype.recalculatePrices = function(pItemIds) +{ + this.initItemTree(); + ItemUtils.prototype.recalculatePrices.apply(this, Array.from(arguments)); +} + /** * For documentation, see class ItemUtils. */ @@ -636,7 +645,27 @@ OfferItemUtils.prototype.reOrgItems = function() { ItemUtils.prototype.reOrgItems.apply(this); } - +/* + * Recalculates the offer net and vat based on the offer items + * and writes the result into the database + * + * @params {String} pOfferId the offer id + * @params {Number} pDiscount overrides the discount (if set) + */ +OfferItemUtils.updateOfferNet = function(pOfferId, pDiscount) +{ + var oiUtils = new OfferItemUtils(pOfferId) + var vals = oiUtils.getNetAndVat(); + var discountedVals = OfferItemUtils.getDiscountedNet(null, pOfferId, pDiscount); + if(discountedVals) + { + newWhere("OFFER.OFFERID", pOfferId).updateFields({ + NET: vals[0], VAT: vals[1], + DISCOUNTED_NET: discountedVals[0], + DISCOUNTED_VAT: discountedVals[1] + }); + } +} OfferItemUtils.getDiscountedNet = function(pExcludedIs, pOfferId, pDiscount, pExcludedProductgroups){ pDiscount = pDiscount ? pDiscount : 0; diff --git a/process/Order_lib/process.js b/process/Order_lib/process.js index 09648dec1ca..db4ee6805e7 100644 --- a/process/Order_lib/process.js +++ b/process/Order_lib/process.js @@ -683,6 +683,15 @@ function OrderItemUtils(pSourceOfferId) { OrderItemUtils.prototype.constructor = OrderItemUtils; } +/** + * For documentation, see class ItemUtils. + */ +OrderItemUtils.prototype.recalculatePrices = function(pItemIds) +{ + this.initItemTree(); + ItemUtils.prototype.recalculatePrices.apply(this, Array.from(arguments)); +} + /** * For documentation, see class ItemUtils. */ @@ -776,6 +785,27 @@ OrderItemUtils.prototype.reOrgItems = function() { ItemUtils.prototype.reOrgItems.apply(this); } +/* + * Recalculates the order net and vat based on the order items + * and writes the result into the database + * + * @params {String} pOrderId the order id + * @params {Number} pDiscount overrides the discount (if set) + */ +OrderItemUtils.updateOrderNet = function(pOrderId, pDiscount) +{ + var oiUtils = new OrderItemUtils(pOrderId); + var vals = oiUtils.getNetAndVat(); + var discountedVals = OrderItemUtils.getDiscountedNet(null, pOrderId, pDiscount); + if(discountedVals) + { + newWhere("SALESORDER.SALESORDERID", pOrderId).updateFields({ + NET: vals[0], VAT: vals[1], + DISCOUNTED_NET: discountedVals[0], + DISCOUNTED_VAT: discountedVals[1] + }); + } +} OrderItemUtils.getDiscountedNet = function(pExcludedIs, pOrderId, pDiscount, pExcludedProductgroups){ pDiscount = pDiscount || 0; -- GitLab