Skip to content
Snippets Groups Projects
Commit 60053b35 authored by Benjamin Ulrich's avatar Benjamin Ulrich :speech_balloon: Committed by Sebastian Listl
Browse files

1053950 fix product prices

parent 24fb6619
No related branches found
No related tags found
No related merge requests found
Showing
with 263 additions and 32 deletions
......@@ -2,7 +2,10 @@ import("system.vars");
import("OfferOrder_lib");
var pId = vars.get("$local.value");
var uid = vars.get("$field.OFFERITEMID");
var entity = vars.get("$sys.currententityname");
if(pId != "")
{
ItemUtils.product_IdOnValueChange(pId);
ItemUtils.product_IdOnValueChange(pId, uid, entity);
}
\ No newline at end of file
......@@ -5,4 +5,4 @@ import("Offer_lib");
var oiUtils = new OfferItemUtils(vars.get("$field.OFFER_ID"));
result.string(oiUtils.roundPrice(oiUtils.getItemSum(vars.get("$field.QUANTITY"), vars.get("$field.PRICE")
, vars.get("$field.DISCOUNT"), vars.get("$field.OPTIONAL"))));
, vars.get("$field.DISCOUNT"), vars.get("$field.OPTIONAL"))));
\ No newline at end of file
import("system.eMath");
import("system.entities");
import("system.datetime");
import("system.neon");
......@@ -18,8 +19,38 @@ if(oid != "")
var discount = vars.exists("$param.Discount_param") ? vars.get("$param.Discount_param"): "";
var quantity = vars.get("$field.QUANTITY");
var oiUtils = new OfferItemUtils(rowdata["OFFERITEM.OFFER_ID"]);
oiUtils.insertPartsList(rowdata["OFFERITEM.PRODUCT_ID"], vars.get("$local.uid"), curr, contactid, vars.get("$param.Language_param"), quantity);
var insertParts = oiUtils.insertPartsList(rowdata["OFFERITEM.PRODUCT_ID"], vars.get("$local.uid"), curr, contactid, vars.get("$param.Language_param"), quantity, true);
oiUtils.reOrgItems();
var calculatedPrices = {};
var priceObj = insertParts["priceObject"];
var treeStructure = insertParts["treeStructure"][rowdata["OFFERITEM.OFFERITEMID"]];
var productsWithSumUpPrices = insertParts["productsWithSumUpPrices"]
var correctOrder = insertParts["insertedItemIds"];
_handleSumUpPricesOfItems(correctOrder, treeStructure, productsWithSumUpPrices, priceObj);
var price = rowdata["OFFERITEM.PRICE"];
if(price === "" || price === undefined || price === null)
{
var calcPrice = 0;
var vat = 0;
for(var id in treeStructure)
{
calcPrice = eMath.addDec(priceObj[id]["price"], calcPrice);
if(priceObj[id]["vat"] !== null && priceObj[id]["vat"] !== undefined && priceObj[id]["vat"] > 0)
{
vat = priceObj[id]["vat"];
}
}
var config = entities.createConfigForUpdatingRows()
.entity("Offeritem_entity")
.addParameter("OfferId_param", oid)
.addParameter("IgnoreOnUpdateProcess_param", true)
.uid(rowdata["OFFERITEM.OFFERITEMID"])
.fieldValues({
"PRICE": calcPrice,
"VAT": vat
});
entities.updateRow(config);
}
//update offer price
var vals = oiUtils.getNetAndVat();
......@@ -28,7 +59,8 @@ if(oid != "")
let config = entities.createConfigForUpdatingRows()
config.entity("Offer_entity");
if(discountedVals){
if(discountedVals)
{
config.fieldValues({
"NET": vals[0],
"VAT": vals[1],
......@@ -36,7 +68,8 @@ if(oid != "")
"DISCOUNTED_VAT": discountedVals[1]
});
}
else{
else
{
config.fieldValues({
"NET": vals[0],
"VAT": vals[1]
......@@ -45,5 +78,95 @@ if(oid != "")
}
config.uid(oid);
entities.updateRow(config);
}
//We want to sum up the prices directly under the current item to calculate the price if we don't have an valid price for them
function _handleSumUpPricesOfItems(pOrder, pTreestruct, pSumUpPrices, pPriceObj)
{
var currentStruc = pTreestruct;
var sumUpPrices = pSumUpPrices;
var order = pOrder;
var summandObject = {};
for (var i = order.length; i > -1; i--)//we do this backwards because otherwiese we would run into problems when trying to build the sum (we could have items without an price yet)
{
if(sumUpPrices.hasOwnProperty(order[i]))
{
summandObject[order[i]] = _getNode(pTreestruct, order[i], Object.keys(pTreestruct)[0]);
}
}
for(var offerItem in summandObject)
{
var calcPrice = 0;
var vat = null;
for (var child in summandObject[offerItem])
{
var childPrice;
if(priceObj[child] != undefined)
{
childPrice = priceObj[child]["price"]
}
else if(summandObject[child][child] != undefined)
{
childPrice = priceObj[Object.keys(summandObject[child][child])[0]]["price"]
vat = priceObj[Object.keys(summandObject[child][child])[0]]["vat"]
}
else
{
childPrice = 0;
vat = 0;
}
calcPrice = eMath.addDec(childPrice, calcPrice);
if(!vat)
{
vat = priceObj[child]["vat"];
}
}
calculatedPrices[offerItem] = {};
calculatedPrices[offerItem]["price"] = calcPrice;
calculatedPrices[offerItem]["vat"] = vat;
priceObj[offerItem] = {};
priceObj[offerItem]["price"] = calcPrice;
priceObj[offerItem]["vat"] = vat;
}
//ToDo: Document
function _getNode(pObject, pName, pCurrName){
if(pCurrName == pName)
{
return pObject;
}
else if (pObject != undefined)
{
let x;
let res = null;
for(var obj in pObject)
{
if(res == null)
{
res = _getNode(pObject[obj], pName, obj);
}
else
{
break;
}
}
return res;
}
return null;
}
var config = entities.createConfigForUpdatingRows().entity("Offeritem_entity").addParameter("OfferId_param", oid).addParameter("IgnoreOnUpdateProcess_param", true);
for(var oiId in productsWithSumUpPrices)
{
config.uid(oiId)
.fieldValues({
"PRICE": priceObj[oiId]["price"],
"VAT": priceObj[oiId]["vat"]
});
entities.updateRow(config);
}
}
\ No newline at end of file
......@@ -34,7 +34,6 @@ if(oid != "")
}
config.uid(oid);
entities.updateRow(config);
//this process get's executed for every child of this offerItem since we use writeEntiy, so we use the param to make sure we don't execute it for the children
if(vars.getString("$param.IgnoreOnUpdateProcess_param") != "true")
{
......
......@@ -21,6 +21,7 @@
<title>Optional</title>
<contentType>BOOLEAN</contentType>
<valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/optional/valueProcess.js</valueProcess>
<onValueChange>%aditoprj%/entity/Prod2prod_entity/entityfields/optional/onValueChange.js</onValueChange>
</entityField>
<entityField>
<name>UID</name>
......@@ -41,6 +42,7 @@
<title>Product</title>
<consumer>Products</consumer>
<mandatory v="true" />
<valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/source_id/valueProcess.js</valueProcess>
<onValueChange>%aditoprj%/entity/Prod2prod_entity/entityfields/source_id/onValueChange.js</onValueChange>
</entityField>
<entityField>
......@@ -48,6 +50,7 @@
<documentation>%aditoprj%/entity/Prod2prod_entity/entityfields/takeprice/documentation.adoc</documentation>
<title>Take price</title>
<contentType>BOOLEAN</contentType>
<stateProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/takeprice/stateProcess.js</stateProcess>
<valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/takeprice/valueProcess.js</valueProcess>
</entityField>
<entityParameter>
......@@ -186,7 +189,7 @@
<name>OPTIONAL.value</name>
</jDitoRecordFieldMapping>
<jDitoRecordFieldMapping>
<name>TAKEPRICE.displayValue</name>
<name>TAKEPRICE.value</name>
</jDitoRecordFieldMapping>
<jDitoRecordFieldMapping>
<name>SOURCE_ID.displayValue</name>
......
import("system.neon");
import("system.vars");
var optional = vars.get("$local.value");
if(optional == 1)
{
neon.setFieldValue("$field.TAKEPRICE", 0);
}
\ No newline at end of file
import("system.result");
import("system.vars");
import("system.neon");
if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW || vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT)
{
var takePrice = vars.get("$field.TAKEPRICE");
var optional = vars.get("$field.OPTIONAL");
if(optional == 1 && takePrice == 0)
{
result.string(neon.COMPONENTSTATE_READONLY);
}
else
{
result.string(neon.COMPONENTSTATE_EDITABLE);
}
}
else
{
result.string(neon.COMPONENTSTATE_READONLY);
}
\ No newline at end of file
import("Util_lib");
import("system.entities");
import("system.logging");
import("Contact_lib");
import("AttributeRegistry_basic");
import("system.neon");
......@@ -201,12 +204,12 @@ ItemUtils.prototype.roundPrice = function(pPrice) {
* @param {String[][]} additionalProductInfo additional product info, which has to be copied from the product. (e.g. INFO field is only used by offer)
* has to be in the form: [[["identifier1", "DESTINATION-DB-FIELD"], ["identifier2", "PRODUCT-DB-SUBSELECT-OR-FIELD"]], ...]
* @param {String} pQuantity opt quantity
*
* @param {Boolean} pSumUpPrices If true: Prices of items get summed up if no valid price exists
* @return {String[]} Array of inserted ItemIDs
*
* @abstract
*/
ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, currency, contactId, additionalProductInfo, pQuantity) {
ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, currency, contactId, additionalProductInfo, pQuantity, pSumUpPrices) {
if (additionalProductInfo == undefined)
{
additionalProductInfo = []
......@@ -231,7 +234,8 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
}
var rootProdId = productId;
if (rootProdId != "") {
if (rootProdId != "")
{
var p2pUtils = new Prod2ProdUtils(rootProdId);
var partsList = p2pUtils.getPartsListObject();
......@@ -249,7 +253,9 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
}
columns = columns.concat(additionalProductInfo.map(function(item) {return item[0][1]}));
var treeStructure = {};
var productsWithSumUpPrices = {};
var priceObject = {};
if (partsList.root != undefined) // if product has a parts list
{
__itemInsertStatement(partsList.root, assignedTo, currency, contactId);
......@@ -258,8 +264,17 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
if (statements.length > 0)
db.inserts(statements);
}
return insertedItemIds;
if(pSumUpPrices == true)
{
return{"insertedItemIds": insertedItemIds,
"treeStructure": treeStructure,
"productsWithSumUpPrices": productsWithSumUpPrices,
"priceObject": priceObject}
}
else
{
return insertedItemIds;
}
//recursive function for building item insert statements
function __itemInsertStatement(partsListObj, assignedTo, currency, contactId) {
......@@ -279,11 +294,35 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
var price = "";
var vat = "";
if (P2pObject.takeprice && ProductDetails.productId && ProductDetails.PriceListToUse) {
price = ProductDetails.PriceListToUse.price;
vat = ProductDetails.PriceListToUse.vat;
if(P2pObject.takeprice == 1 && ProductDetails.productId)
{
if (ProductDetails.PriceListToUse)
{
price = ProductDetails.PriceListToUse.price;
vat = ProductDetails.PriceListToUse.vat;
if(pSumUpPrices)
{
priceObject[newid] = {};
priceObject[newid]["price"] = price;
priceObject[newid]["vat"] = vat;
}
}
else if(pSumUpPrices)
{
productsWithSumUpPrices[newid] = "";
}
}
var stop = false;
var checkedElements;
var amuntOfKeys;
var itemAdded;
if(pSumUpPrices)
{
treeStructure = _buildTreeStructure(treeStructure, assignedTo, newid);
}
var vals = [newid
, self.offerOrderId
, prodid
......@@ -303,7 +342,35 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
statements.push([table, columns, null, vals]);
insertedItemIds.push(newid);
__itemInsertStatement(partsList[p2pid], newid);
__itemInsertStatement(partsList[p2pid], newid, currency, contactId);
}
// helper function to build the tree structure so we can later sum up the prices accordingly
function _buildTreeStructure(treeObj, assignedTo, newid)
{
for (var id in treeObj)
{
if (typeof treeObj[id] == "object" && treeObj[id] !== null && id != assignedTo)
_buildTreeStructure(treeObj[id], assignedTo, newid);
else
{
if(id == assignedTo)
{
if(!treeObj.hasOwnProperty(assignedTo))
{
treeObj[assignedTo] = {};
}
treeObj[assignedTo][newid] = {};
return treeObj;
}
}
}
if(Utils.isEmpty(treeObj))
{
treeObj[assignedTo] = {};
treeObj[assignedTo][newid] = {};
}
return treeObj;
}
}
}
......@@ -465,11 +532,12 @@ ItemUtils.prototype.reOrgItems = function() {
*
*
* @param {String} pProductId <p/> product Id
*
* @param {String} pUid <p/> product Id
* @param {String} pEntity <p/> product Id
* @return {void}
* @static
*/
ItemUtils.product_IdOnValueChange = function (pProductId)
ItemUtils.product_IdOnValueChange = function (pProductId, pUid, pEntity)
{
var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
var contactid = vars.exists("$param.ContactId_param") ? vars.get("$param.ContactId_param") : "";
......@@ -513,5 +581,5 @@ ItemUtils.product_IdOnValueChange = function (pProductId)
neon.setFieldValue("$field.PRICE", ProductDetails.PriceListToUse.price);
neon.setFieldValue("$field.VAT", ProductDetails.PriceListToUse.vat);
}
}
}
};
\ No newline at end of file
......@@ -222,17 +222,18 @@ OfferUtils.buildOfferReport = function (pOfferID, pExclDiscountGroupcodes)
itemData = itemData.map(function (item)
{
//quantity * price
fullPrice = eMath.mulDec(parseFloat(item[9]), parseFloat(item[10])); //price without discount
if (item[4] != "1") //optional
if (!item[5].includes(".") && item[4] != "1") //only if it's no child and its not optional
{
//quantity * price
fullPrice = eMath.mulDec(parseFloat(item[9]), parseFloat(item[10])); //price without discount
//itemSum = (fullPrice * (100 - discount)) / 100
itemSum = eMath.roundDec(eMath.divDec(eMath.mulDec(fullPrice, eMath.subDec(100, item[11])), 100), 2, eMath.ROUND_HALF_EVEN); //sum of the item (with discount)
sumItemSum += itemSum; //total sum (without vat)
let excluded = -1
if(pExclDiscountGroupcodes){
if(pExclDiscountGroupcodes)
{
excluded = pExclDiscountGroupcodes.indexOf(item[15])
}
//vatsum = itemSum * vat / 100
......@@ -242,7 +243,9 @@ OfferUtils.buildOfferReport = function (pOfferID, pExclDiscountGroupcodes)
vatsum = eMath.subDec(vatsum, eMath.divDec(eMath.mulDec(vatsum, offerData[16]), "100"));
}
else
{
vatsum = ItemUtils.prototype.getItemVAT(item[9], item[10], item[11], item[12], item[4])
}
if (item[12] > 0)
sums.push([item[12], vatsum]); //MWSteuerwerte für Map vorbereiten
......@@ -251,7 +254,7 @@ OfferUtils.buildOfferReport = function (pOfferID, pExclDiscountGroupcodes)
// sumItemSum + vat
if(!printHeadDiscount)
total = eMath.addDec(sumItemSum, offerData[9]); //total sum with vat
total = eMath.addDec(sumItemSum, vatsum); //total sum with vat
if (!printDiscount && item[11] > 0)
printDiscount = true;
......@@ -554,7 +557,7 @@ OfferItemUtils.prototype.roundPrice = function(pPrice) {
/**
* For documentation, see class ItemUtils.
*/
OfferItemUtils.prototype.insertPartsList = function(pProductId, pAssignedTo, pCurrency, pContactId, pLanguage, pQuantity) {
OfferItemUtils.prototype.insertPartsList = function(pProductId, pAssignedTo, pCurrency, pContactId, pLanguage, pQuantity, pSumUpPrices) {
this.initItemTree();
var cols = ["OFFERITEMID"
......@@ -577,7 +580,7 @@ OfferItemUtils.prototype.insertPartsList = function(pProductId, pAssignedTo, pCu
.where("DESCRIPTIONTRANSLATION.OBJECT_ROWID = PRODUCT.PRODUCTID")
.and("DESCRIPTIONTRANSLATION.OBJECT_TYPE", "Product")
.and("DESCRIPTIONTRANSLATION.LANG", pLanguage)
.toString() + ")"]]], pQuantity]);
.toString() + ")"]]], pQuantity, pSumUpPrices]);
}
......
......@@ -287,7 +287,7 @@ ProductUtils.getProductDetails = function(pid, pPriceListFilter, pAdditionalProd
//infividual pricelists always have the highest priority, so we loop trough and use the first one we find regardles of the rest
for (var indivList in priceLists)
{
if(priceLists[indivList]["relationId"] != "")
if(priceLists[indivList]["priceList"] == $KeywordRegistry.productPricelist$specialList())
{
return priceLists[indivList];
}
......
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report1" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e7a916c8-3f9a-497d-84bb-3909b15271ea">
<property name="ireport.zoom" value="1.7715610000000064"/>
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="279"/>
<property name="ireport.y" value="0"/>
<parameter name="myAddr" class="java.lang.String"/>
<parameter name="Pos" class="java.lang.String"/>
<parameter name="Articledescription" class="java.lang.String"/>
......@@ -24,7 +24,7 @@
<parameter name="OfferDeliveryTerm" class="java.lang.String"/>
<parameter name="responsible" class="java.lang.String"/>
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA["C:\\Users\\s.neumaier\\Documents\\AditoProjects\\basic_2020.2\\report\\Offer_report\\"]]></defaultValueExpression>
<defaultValueExpression><![CDATA["C:\\Entwicklung\\0.0\\project\\basic2\\report\\Offer_report\\"]]></defaultValueExpression>
</parameter>
<parameter name="adito.datasource.subdata" class="java.lang.Object"/>
<parameter name="SUMITEMSUM" class="java.lang.Double"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment