import("system.vars"); import("system.util"); import("system.datetime"); import("system.text"); import("system.neon"); import("system.db"); import("system.translate"); import("system.eMath"); import("Util_lib"); import("Sql_lib"); import("Keyword_lib"); import("Product_lib"); import("Report_lib"); import("OfferOrder_lib"); import("PostalAddress_lib"); /** * Methods used by Offer. * Do not create an instance of this! * * @class */ function OfferUtils() {} /** * Delivers the next valid offer number (has to be unique) * * @return {String} next valid offer number */ OfferUtils.getNextOfferNumber = function() { return NumberSequencingUtils.getNextUniqueNumber("OFFERCODE", "OFFER"); } /** * Delivers the next valid offer version number * * @return {String} offerCode next valid offer version number */ OfferUtils.getNextOfferVersionNumber = function(offerCode) { return NumberSequencingUtils.getNextUniqueNumber("VERSNR", "OFFER", 1, "OFFERCODE = " + offerCode); } /** * Checks if the passed offer number is valid (has to be unique) * * @param {String} offerNumber offer number to check * * @return {Boolean} passed number is valid */ OfferUtils.validateOfferNumber = function(offerNumber) { return NumberSequencingUtils.validateUniqueNumber(offerNumber, "OFFERCODE", "OFFER"); } OfferUtils.getOfferNumberValidationFailString = function() { return translate.text("The offer number already exists!"); } OfferUtils.isEditable = function(status) { // TODO: Administrator darf immer ändern, warten auf neue Berechtigungslogik? // Offer should be editable if offer state not equals "Sent", "Won" or "Lost" return status != "2" && status != "3" && status != "4"; } /** * Create a new offer and open the offer context in NEW-mode */ OfferUtils.createNewOffer = function(pSalesprojectId, pRelationId) { var params = {}; if (pSalesprojectId) params["SalesprojectId_param"] = pSalesprojectId; if (pRelationId) params["RelationId_param"] = pRelationId; neon.openContext("Offer_context", null, null, neon.OPERATINGSTATE_NEW, params); } /* * Open Offer report * * @param {String} pOfferID * * @return {[]} */ OfferUtils.openOfferReport = function(pOfferID) { var offerReport = new Report("RPTJ_OFFER"); // get data from DB // TODO: OFFER.ADDRESS var fields = [/*"OFFER.ADDRESS"*/ "''", "OFFER.RELATION_ID", "OFFER.LANGUAGE", /*"OFFER.PAYMENTTERMS"*/ "'DUMMY_OFFER.PAYMENTTERMS'", //0 - 3 /*"OFFER.DELIVERYTERMS"*/ "'DUMMY_OFFER.DELIVERYTERMS'", "OFFER.OFFERCODE", "OFFER.CURRENCY", "OFFER.OFFERDATE", // 4 - 7 "OFFER.OFFERID", "OFFERITEM.OFFER_ID", "OFFERITEM.INFO", "OFFERITEM.ASSIGNEDTO", // 11 "OFFERITEM.PRODUCT_ID","OFFERITEM.ITEMNAME" , // 13 "OFFERITEM.OPTIONAL", "OFFERITEM.ITEMPOSITION", // 15 "PRODUCT.PRODUCTCODE", "PRODUCT.PRODUCTID", "OFFER.FOOTER", "OFFER.HEADER", "OFFERITEM.UNIT", "OFFER.VAT", // 21 "COALESCE(OFFERITEM.QUANTITY,0)","COALESCE(OFFERITEM.PRICE,0)", "COALESCE(OFFERITEM.DISCOUNT,0)", // 24 "COALESCE(OFFER.VERSNR, 0)", "COALESCE(OFFER.OFFERCODE,0)", "COALESCE(OFFERITEM.VAT, 0)", "0", "''", "SALESPROJECT_ID" ]; // 30 var offerFromSql = " from PRODUCT" + " inner join OFFERITEM on (PRODUCT.PRODUCTID = OFFERITEM.PRODUCT_ID) " + " inner join OFFER on (OFFERITEM.OFFER_ID = OFFER.OFFERID)"; var offerCondition = SqlCondition.begin().andPrepare("OFFER.OFFERID", pOfferID); var rptdata = db.table(offerCondition.buildSelect("select " + fields.join(", ") + offerFromSql, "1 = 0")); var language = KeywordUtils.get("LANGUAGE", rptdata[0][2])[1]; var relid = rptdata[0][1]; // TODO: AddrObject implementieren //var addrobj = new AddrObject(relid); // new logik: Relationid from Org is always also the OrgId var orgrelid = relid; var fullPrice= 0; var itemSum = 0; var sumItemSum = 0; var total = 0; var sums = []; var vatsum = 0; // discount-condtion = offerCondition + additional condition. So we can reuse the previous object offerCondition.andPrepare("OFFERITEM.DISCOUNT", 0, "# <> ?"); var countDiscounts = db.cell(SqlCondition.begin() .andPrepare("OFFER.OFFERID", pOfferID) .buildSelect("select count(OFFERITEM.DISCOUNT)" + offerFromSql, "1 = 0")); for(var i = 0; i < rptdata.length; i++) { var optional = rptdata[i][14]; // calculate: // "OFFERITEM_QUANTITY" * "OFFERITEM_PRICE" fullPrice = eMath.mulDec(parseFloat(rptdata[i][22]), parseFloat(rptdata[i][23]) ); // ( fullPrice * ( 100 - "OFFERITEM_DISCOUNT" ) ) / 100 if(optional) { itemSum = eMath.roundDec(eMath.divDec(eMath.mulDec(fullPrice, eMath.subDec(100, rptdata[i][24]) ), 100), 2, eMath.ROUND_HALF_EVEN); //Summe je Artikel sumItemSum += itemSum; //Gesamtsumme aller Artikel } // itemSum * "OFFERITEM_VAT" / 100 vatsum = (eMath.divDec(eMath.mulDec(itemSum, rptdata[i][27] ), 100)); //Steuerbetrag in Euro je Artikel if(rptdata[i][27] > 0) sums.push([rptdata[i][27], vatsum]); //MWSteuerwerte für Map vorbereiten // sumItemSum + "OFFER_VAT" total = eMath.addDec(sumItemSum, rptdata[i][21]); //Gesamtsumme zzgl. MwSt. total = text.formatDouble(total, translate.text("#,##0.00"), true) // format date rptdata[i][7] = datetime.toDate(rptdata[i][7], translate.text("dd.MM.yyyy", language)); // format numbers rptdata[i][23] = text.formatDouble(rptdata[i][23], translate.text("#,##0.00"), true); rptdata[i][24] = text.formatDouble(rptdata[i][24], translate.text("0.00"), true); rptdata[i][22] = text.formatDouble(rptdata[i][22], translate.text("#,##0"), true); rptdata[i][27] = text.formatDouble(rptdata[i][27], translate.text("#,##0.00"), true); rptdata[i][28] = text.formatDouble(itemSum, translate.text("#,##0.00"), true); //Immer zwei Nachkommastellen und ',' statt '.' rptdata[i][29] = KeywordUtils.get("UNIT", rptdata[i][20])[1]; } // TODO: get Images implementieren var imgData = ["meineFirma | Konrad-Zuse-Straße 4 | DE 84144 Geisenhausen", "base64:iVBORw0KGgoAAAANSUhEUgAAAM4AAABRCAYAAACaL5lSAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDA4QzAyM0IwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDA4QzAyM0MwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMDhDMDIzOTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMDhDMDIzQTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhF3nYoAAAlvSURBVHja7J1fjBXV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"] // getMyASYS_ICONSdata(); var params = {}; params["myAddr"] = imgData[0]; params["Pos"] = translate.text("Pos.", language); params["Artikelbezeichnung"] = translate.text("Artikelbezeichnung", language); params["Artikel-Nr"] = translate.text("Artikel-Nr", language); params["Einzelpreis"] = translate.text("Einzelpreis", language); params["Menge"] = translate.text("Menge", language); params["UMSt"] = translate.text("UMSt", language); params["Datum"] = translate.text("Datum", language); params["Nummer"] = translate.text("Nummer", language); params["Zahlungsbedingung"] = translate.text("Zahlungsbedingung", language); params["Lieferbedingung"] = translate.text("Lieferbedingung", language); params["Rabatt"] = translate.text("Rabatt", language); params["Gesamt"] = translate.text("Gesamt", language); params["Summe"] = translate.text("Summe", language); params["zzglUMST"] = translate.text("zzgl. Summe UmSt", language); // TODO: OFFER.ADDRESS params["OFFERAddr"] = AddressUtils.getAddress(relid).toString(); //rptdata[0][0]; // TODO: AddrObject implementieren params["OFFERPers"] = (AddressUtils.getLetterSalutation() + ",").toString(); //addrobj.formatAddress("{ls},"); // TODO: payment / delivery-Terms implement (if needed) params["OFFERPay"] = ""//getKeyName(rptdata[0][3] , "PAYMENTTERMS", "KEYNAME1", language); params["OFFERDel"] = ""//getKeyName(rptdata[0][4] , "DELIVERYTERMS", "KEYNAME1", language); // TODO: implementieren wenn Attribute möglich sind var adma = "" /*var adm = getAddressData( [GetAttributeKey( "Aussendienst", "1", orgrelid, pUser )[0]], [["Person","function", "concat( ['SALUTATION', 'TITLE', 'FIRSTNAME','LASTNAME'])"], ["Telefon", "function", "getCommAddrSQL('Telefon', 'RELATION.RELATIONID')"], ["Email", "function", "getCommAddrSQL('E-Mail', 'RELATION.RELATIONID')"] ] ); var adma = ""; if (adm[1] != undefined) adma = adm[1].join("\n");*/ params["AD_Name"] = adma; params["SUMITEMSUM"] = sumItemSum; params["TOTAL"] = total; params["anzahl"] = countDiscounts; offerReport.addImage("myLogo", imgData[1]); offerReport.addSubReportData("subdata", ReportData.begin(["VAT","WERT"]).add(sums)); offerReport.addReportParams(params); var data = []; for( i = 0; i < rptdata.length; i++) { data[i] = [rptdata[i][6], rptdata[i][7], rptdata[i][8], rptdata[i][10], rptdata[i][11], rptdata[i][13], rptdata[i][14], rptdata[i][15], rptdata[i][16], rptdata[i][18], rptdata[i][19], //10 rptdata[i][22], rptdata[i][23], rptdata[i][24], rptdata[i][25], rptdata[i][26], rptdata[i][27], rptdata[i][28], rptdata[i][29]]; } // 0 1 2 3 4 offerReport.setReportData(ReportData.begin(["OFFER_CURRENCY", "OFFER_OFFERDATE", "OFFER_OFFERID", "OFFERITEM_INFO", "OFFERITEM_ASSIGNEDTO", "OFFERITEM_ITEMNAME" , "OFFERITEM_OPTIONAL", "OFFERITEM_ITEMPOSITION", "PRODUCT_PRODUCTCODE", "OFFER_FOOTER", "OFFER_HEADER", // 10 "OFFERITEM_QUANTITY", "OFFERITEM_PRICE", "OFFERITEM_DISCOUNT", "OFFER_VERSNR", "OFFER_OFFERCODE", "OFFERITEM_VAT", "ITEMSUM", // 17 "OFFERITEM_UNITTEXT"]) // 18 .add(data)); offerReport.openReport(); } /******************************************************************************/ /** * Provides methods for dealing with offer items. * Inherits methods from abstract class ItemUtils. * For documentation, see class ItemUtils. * * @class */ function OfferItemUtils(pOfferId) { // extends ItemUtils ItemUtils.apply(this, [pOfferId, "OFFER"]); OfferItemUtils.prototype = Object.create(ItemUtils.prototype); OfferItemUtils.prototype.constructor = OfferItemUtils; } OfferItemUtils.prototype.getNetAndVat = function(offeritemIdsToDel) { return ItemUtils.prototype.getNetAndVat.apply(this, [offeritemIdsToDel]); } OfferItemUtils.prototype.initItemTree = function() { ItemUtils.prototype.initItemTree.apply(this); } OfferItemUtils.prototype.getItemSum = function(pQuantity, pPrice, pDiscount, pOptional) { return ItemUtils.prototype.getItemSum.apply(this, [pQuantity, pPrice, pDiscount, pOptional]); } OfferItemUtils.prototype.getItemVAT = function(pQuantity, pPrice, pDiscount, pVAT, pOptional) { return ItemUtils.prototype.getItemVAT.apply(this, [pQuantity, pPrice, pDiscount, pVAT, pOptional]); } OfferItemUtils.prototype.roundPrice = function(pPrice) { return ItemUtils.prototype.roundPrice.apply(this, [pPrice]); } OfferItemUtils.prototype.insertPartsList = function(pProductId, pAssignedTo, pCurrency, pRelationId) { this.initItemTree(); var cols = ["OFFERITEMID" , "OFFER_ID" , "PRODUCT_ID" , "GROUPCODEID" , "ASSIGNEDTO" , "ITEMNAME" , "UNIT" , "PRICE" , "VAT" , "QUANTITY" , "OPTIONAL" , "ITEMPOSITION" , "ITEMSORT" , "DATE_NEW" , "USER_NEW"]; return ItemUtils.prototype.insertPartsList.apply(this, [cols, pProductId, pAssignedTo, pCurrency, pRelationId, [["INFO", "INFO"]]]); } OfferItemUtils.prototype.deletePartsList = function(pItemId) { this.initItemTree(); return ItemUtils.prototype.deletePartsList.apply(this, [pItemId]); } OfferItemUtils.prototype.getNextItemSort = function(pIds) { this.initItemTree(); return ItemUtils.prototype.getNextItemSort.apply(this, [pIds]); } OfferItemUtils.prototype.getNextItemPosition = function(pAssignedTo, pTree, pIds) { this.initItemTree(); return ItemUtils.prototype.getNextItemPosition.apply(this, [pAssignedTo, pTree, pIds]); } OfferItemUtils.prototype.reOrgItems = function() { this.initItemTree(); ItemUtils.prototype.reOrgItems.apply(this); }