diff --git a/entity/Offeritem_entity/Offeritem_entity.aod b/entity/Offeritem_entity/Offeritem_entity.aod index 87a0d3f6cae67df525e62259afd9f120e5d84ef5..f62154dc4936f16519f6fbd5f5b06d521ccebcb8 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 0000000000000000000000000000000000000000..84e65c7263c2f3260ac24ae80e39d3dd8fd466a4 --- /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 f9d76609118533ccdb459ac195658158c2a35c26..1c64343155050e9201a897a0e05c0c6b36e86d15 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 399419f16b384223b203e8c99c2f502e6b0bd1e3..009030c597027c4e0639d914222e7789da0703bb 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 b6f5ec9513c092d2287bed81eb534a94eca65062..5fc63065077dc806467c8fc3444b4e5b7a98fc6c 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 0000000000000000000000000000000000000000..83922ee37c9bc8fed5234eae1555a94aa31b6827 --- /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 1e9a6cdb99b8eefdec57218621fa4b1592ac90de..b5ccd5df970c223f9ddc09a71da3bb13019d7fb0 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 2faf905b45ab22ec4f55c5b78396daf8f1b88e82..7ae71eff92c7ce29eff949640c4c97d327d221f6 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 289133336b731e7e6cbd596cfefd5516854d8e72..8d4a407dd4469e08d76ccc511d9587d662111bc5 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 7200a5490765ae43b144b07d8398780361a0b682..b65c2293ba634f8f8cf28c9b281c74ee93faedb7 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 03b4b6e521ceeb65f358c6f7eaff603ebf27cab1..2e3e41095297cf1ec3cb18774430273df1279ab4 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 09648dec1ca49c4584b6912a7ecb12a4e76b2e00..db4ee6805e7cb51a9c462099c9851bb779565b12 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;