From bbbd1d08d43b836e44cdde45802022d5508f606d Mon Sep 17 00:00:00 2001 From: Thorsten Schmitz Date: Thu, 9 Jul 2026 11:57:19 +0200 Subject: [PATCH] Correct export of Delivery Unit EON_CRM_INVOICE (2 files, replaces incomplete initial export) --- .../invoice/metadata/UO_DOCUMENTS_RAWCALL.sql | 4 +- uniorg/eon/crm/invoice/v1/post-invoice.xsjs | 1105 ++++++++++++++++- 2 files changed, 1106 insertions(+), 3 deletions(-) diff --git a/uniorg/eon/crm/invoice/metadata/UO_DOCUMENTS_RAWCALL.sql b/uniorg/eon/crm/invoice/metadata/UO_DOCUMENTS_RAWCALL.sql index f912928..92561a3 100644 --- a/uniorg/eon/crm/invoice/metadata/UO_DOCUMENTS_RAWCALL.sql +++ b/uniorg/eon/crm/invoice/metadata/UO_DOCUMENTS_RAWCALL.sql @@ -1,4 +1,4 @@ -CREATE COLUMN TABLE "INTEGRATION_DATA"."UO_DOCUMENTS_RAWCALL" ("ID" BIGINT CS_FIXED NOT NULL , +CREATE COLUMN TABLE "INTEGRATION_DATA"."UO_DOCUMENTS_RAWCALL" ("ID" BIGINT CS_FIXED NOT NULL , "DOCTYPE" VARCHAR(50), "XSINTERFACE" VARCHAR(50), "JSONRAW" NCLOB MEMORY THRESHOLD 1000, @@ -6,4 +6,4 @@ "B1_OBJ" NCLOB MEMORY THRESHOLD 1000, "CREATE_TS" LONGDATE CS_LONGDATE DEFAULT CURRENT_TIMESTAMP NOT NULL , "UPDATE_TS" LONGDATE CS_LONGDATE NOT NULL , - PRIMARY KEY ("ID")) UNLOAD PRIORITY 5 AUTO MERGE + PRIMARY KEY ("ID")) UNLOAD PRIORITY 5 AUTO MERGE \ No newline at end of file diff --git a/uniorg/eon/crm/invoice/v1/post-invoice.xsjs b/uniorg/eon/crm/invoice/v1/post-invoice.xsjs index 7c1a11e..13ac02e 100644 --- a/uniorg/eon/crm/invoice/v1/post-invoice.xsjs +++ b/uniorg/eon/crm/invoice/v1/post-invoice.xsjs @@ -1 +1,1104 @@ -// post-invoice.xsjs - Service for CRM Invoice integration +// Changelog +// 2022-11-23: EMPEPI1-141: Ablehnung von Rechnungen im Entwurfsmodus ab 25.11.2022 +// EMPEPI1-148: eMobility PEPI Anpassung des Mappings API-Einmalabrechnung +// 2023-01-18: EMPEPI1-193: Korrektur aperiodische Buchungen +// 2023-02-22: EMPEPI1-157: Zeilenerweiterung per SST auf Rechnung +// 2023-03-07: EMPEPI1-230: Anpassungen der Schnittstellen-Fehlermeldungen +// 2023-08-07: EMPEPI1-273: Anpassungen Invoice Adresse +// 2023-11-29: EMPEPI1-329: Struktur Haupt-/Zusatzartikel +// 2023-12-07: EMPEPI1-341: Korrektur Adressmapping +// 2024-09-13: BUS-6987: Feld Firmenname auf 50 Zeichen begrenzt, führt zu inkonsitenten Rechnungsadressen +// 2025-04-15: BUS-11743: Feld Comments begrenzen auf 254 Zeichen +// 2025-05-19: BUS-12136: Erweiterung CRM Invoice Schnittstelle für rechnungsbegleitende Unterlagen +// 2025-06-03: BUS-12296: New Endpoint URLs for CRM interfaces +// 2025-07-15: BUS-11774: Erweiterung der API-Einmalabrechnung um Einheiten pro Produkt +// 2025-12-11: PFT-790: Mapping Artikelnummer angepasst + +var slib = $.import("uniorg.ServiceLayer", "B1SLLogic"); +var datetimelib = $.import("uniorg.libs", "datetime"); +var logginglib = $.import("uniorg.libs", "uologging"); +var slDest = $.import("uniorg.destinations", "uodestlib"); +var slfwlib = $.import("uniorg.ServiceLayer", "B1SLFramework"); + +var serviceName = "uniorg.eon.crm.invoice.v1.post-invoice.xsjs"; +var serviceVersion = '3.4'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var logTableId = 0; +var logDocEntry = -1; + +var objecttype = "13"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +var draftMode = true; + +function updateLogEntry(id, docEntry, b1Obj) { + var conn = $.hdb.getConnection(); + try { + conn.executeUpdate( + "UPDATE \"INTEGRATION_DATA\".\"UO_DOCUMENTS_RAWCALL\" SET \"B1_PK\" = ?, \"B1_OBJ\" = ?, \"UPDATE_TS\" = CURRENT_TIMESTAMP WHERE \"ID\" = ?", + docEntry, b1Obj, id); + conn.commit(); + } catch (e) { + exceptionHandler(e); + return; + } +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + $.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method) { + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + //$.response.status = $.net.http.INTERNAL_SERVER_ERROR; + // Workaround, weil CRM scheinbar Probleme mit anderen Statuscodes hat + $.response.status = $.net.http.OK; + + try { + if (slLoggedIn) { + slib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function setConnectionParams(sfcall) { + var jsonSFCall = JSON.parse(sfcall); + + var idValue = "A19753_EON_P01"; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = slDest.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = slDest.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "ERPInstanceName is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function checkItemCode(inItemCode) { + var ItemCode = ""; // return value if document doesn't exist + outMsg = {}; + outMsg.method = "checkItemCodeExistsinSAP"; + outMsg.ItemCode = inItemCode; + outMsg.status = "success"; + outMsg.message = "not exists"; + if (inItemCode !== "") { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"ItemCode\" FROM \"XXREPXX\".\"OITM\" T0 WHERE T0.\"ItemCode\"= ?"; + + query = query.replace(/XXREPXX/g, UserComp); + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, inItemCode); + + try { + var rs = pstmt.executeQuery(); + var Documents = []; + while (rs.next()) { + var Document = {}; + Document.ItemCode = rs.getNString(1); + Documents.push(Document); + // return AbsId from last result + ItemCode = Document.ItemCode; + outMsg.ItemCode = ItemCode; + outMsg.message = "exists"; + } + outMsg.Document = Documents; + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0) { + outMsg.Query = query; + outMessages.push(outMsg); + } + } + } else { + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "ItemCode: " + inItemCode + " not exists in SAP (OITM)"; + outMessages.push(outMsg); + } + return ItemCode; +} + +function getItemCode(product_id) { + var ItemCode = ""; // return value if product doesn't exist + outMsg = {}; + outMsg.method = "checkProductIdExistsinMappingTable"; + outMsg.product_id = product_id; + outMsg.status = "error"; + outMsg.message = "not exists"; + if (product_id) { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"U_ITEMCODE\" FROM \"XXREPXX\".\"@UO_CRM_PRODUCT\" T0 WHERE T0.\"U_CRM_PRODUCT_ID\"= ?"; + + query = query.replace(/XXREPXX/g, UserComp); + + if (debugLevel > 0) { + outMsg.Query = query; + } + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, product_id); + + try { + var rs = pstmt.executeQuery(); + var Products = []; + while (rs.next()) { + var Product = {}; + Product.ItemCode = rs.getNString(1); + Products.push(Product); + ItemCode = Product.ItemCode; + outMsg.ItemCode = ItemCode; + outMsg.status = "success"; + outMsg.message = "exists"; + } + if (debugLevel > 0) { + outMsg.Products = Products; + } + rs.close(); + } finally { + pstmt.close(); + conn.close(); + if (outMsg.status === 'error') { + throw new Error("Product not found in mapping table: " + product_id); + } + if (debugLevel > 0) { + outMessages.push(outMsg); + } + } + } else { + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "Mandatory parameter is missing in payload (product_id)"; + //outMessages.push(outMsg); + throw new Error(outMsg.message); + } + checkItemCode(ItemCode); + return ItemCode; +} + +function getDocEntry(invoiceGUID) { + var DocEntry = -1; // return value if document doesn't exist + outMsg = {}; + outMsg.method = "checkDocumentExists"; + outMsg.invoiceGUID = invoiceGUID; + //outMsg.CardCode = CardCode; + outMsg.status = "success"; + outMsg.message = "not exists"; + if (invoiceGUID) { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"DocEntry\", T0.\"DocNum\", T0.\"NumAtCard\", T0.\"CardCode\", T0.\"DocStatus\", T0.\"U_EON_SRC_ID\" FROM \"XXREPXX\".\"OINV\" T0 WHERE T0.\"U_EON_SRC_GUID\"= ? AND T0.\"U_EON_SRC_SYSTEM\"= 'crm' "; + + query = query.replace(/XXREPXX/g, UserComp); + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, invoiceGUID); + //pstmt.setNString(2, CardCode.toString()); + + try { + var rs = pstmt.executeQuery(); + var Documents = []; + while (rs.next()) { + var Document = {}; + Document.DocEntry = rs.getInteger(1); + Document.DocNum = rs.getNString(2); + Document.NumAtCard = rs.getNString(3); + Document.CardCode = rs.getNString(4); + Document.DocStatus = rs.getNString(5); + Document.U_EON_SRC_ID = rs.getNString(6); + Document.U_EON_SRC_GUID = invoiceGUID; + Documents.push(Document); + // return AbsId from last result + DocEntry = Document.DocEntry; + outMsg.DocEntry = DocEntry; + outMsg.message = "exists"; + outMsg.status = "error"; + outStatus = "error"; + } + outMsg.Document = Documents; + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0 || outMsg.status === "error") { + //outMsg.Query = query; + outMessages.push(outMsg); + } + } + } else { + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "Mandatory parameter is missing in payload (invoice_crm_guid)"; + outMessages.push(outMsg); + } + + return DocEntry; +} + +function getCardCode(CRMID) { + var CardCode = ""; // return value if customer doesn't exist + outMsg = {}; + outMsg.method = "getCardCode"; + outMsg.CRMID = CRMID; + outMsg.status = "error"; + outMsg.message = "customer not found"; + if (CRMID) { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"CardCode\",T0.\"U_EON_PGN\" FROM \"XXREPXX\".\"OCRD\" T0 WHERE T0.\"CardType\"=\'C\' AND T0.\"U_EON_ID_CRM\"= ?"; + + query = query.replace(/XXREPXX/g, UserComp); + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, CRMID); + + try { + var rs = pstmt.executeQuery(); + while (rs.next()) { + CardCode = rs.getNString(1); + outMsg.CardCode = CardCode; + outMsg.U_EON_PGN = rs.getNString(2); + outMsg.status = "success"; + outMsg.message = "exists"; + } + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0 || CardCode === "") { + if (debugLevel > 0) { + outMsg.Query = query; + } + outMessages.push(outMsg); + } + } + } else { + //outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "Mandatory parameter is missing in payload (CRM ID)"; + outMessages.push(outMsg); + } + if (CardCode === "") { + outStatus = "error"; + } + return CardCode; +} + +function getSignatureDate(ContractID) { + var sigdate; + outMsg = {}; + outMsg.method = "getSignatureDate"; + outMsg.ContractID = ContractID; + outMsg.status = "error"; + outMsg.message = "invalid ContractID"; + if (ContractID) { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"U_SIGNATURE_DATE\" FROM \"XXREPXX\".\"@EON_CONTRACT\" T0 WHERE T0.\"U_EXT_ID_CRM\"= ?"; + + query = query.replace(/XXREPXX/g, UserComp); + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, ContractID); + + try { + var rs = pstmt.executeQuery(); + while (rs.next()) { + sigdate = rs.getNString(1); + outMsg.sigdate = sigdate; + outMsg.ContractID = ContractID; + outMsg.status = "success"; + outMsg.message = "exists"; + } + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0 || sigdate === "") { + if (debugLevel > 0) { + outMsg.Query = query; + } + outMessages.push(outMsg); + } + } + } else { + //outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "Mandatory parameter is missing in payload (ContractID)"; + outMessages.push(outMsg); + } + if (sigdate === "") { + outStatus = "error"; + } + return sigdate; +} + +function getSeries(objectCode, seriesName) { + var series = 0; // return value if series doesn't exist + outMsg = {}; + outMsg.method = "getSeries"; + outMsg.seriesName = seriesName; + outMsg.status = "error"; + outMsg.message = "invalid document series"; + if (seriesName) { + var conn = $.db.getConnection(); + var pstmt; + var query = + "SELECT T0.\"Series\" FROM \"XXREPXX\".\"NNM1\" T0 WHERE T0.\"ObjectCode\"= ? AND T0.\"SeriesName\"= ?"; + + query = query.replace(/XXREPXX/g, UserComp); + + pstmt = conn.prepareStatement(query); + + pstmt.setNString(1, objectCode); + pstmt.setNString(2, seriesName); + + try { + var rs = pstmt.executeQuery(); + while (rs.next()) { + series = rs.getInteger(1); + outMsg.series = series; + outMsg.status = "success"; + outMsg.message = "exists"; + } + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0 || series === 0) { + if (debugLevel > 0) { + outMsg.Query = query; + } + outMessages.push(outMsg); + } + } + } else { + //outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "Mandatory parameter is missing in payload (OrderType)"; + outMessages.push(outMsg); + } + if (series === 0) { + outStatus = "error"; + } + return series; +} + +function getDocDates() { + var docDate, taxDate; + outMsg = {}; + outMsg.method = "getDocDates"; + outMsg.status = "error"; + var conn = $.db.getConnection(); + var pstmt; + var query = + 'with currentPeriod as (select * from "XXREPXX".OFPR where current_date between "F_RefDate" and "T_RefDate"), \ +nextPeriod as (select top 1 * from "XXREPXX".OFPR where "F_RefDate" > current_date order by "F_RefDate") \ +select case when currentPeriod."PeriodStat"=\'N\' then current_date \ +else to_date(nextPeriod."F_RefDate") end "DocDate", current_date as "TaxDate" \ +from currentPeriod left join nextPeriod on 1=1'; + query = query.replace(/XXREPXX/g, UserComp); + pstmt = conn.prepareStatement(query); + + try { + var rs = pstmt.executeQuery(); + while (rs.next()) { + docDate = rs.getDate(1); + taxDate = rs.getDate(2); + outMsg.docDate = docDate; + outMsg.taxDate = taxDate; + outMsg.status = "success"; + } + + rs.close(); + } finally { + pstmt.close(); + conn.close(); + + if (debugLevel > 0) { + if (debugLevel > 0) { + outMsg.Query = query; + } + outMessages.push(outMsg); + } + } + return { + docDate: docDate, + taxDate: taxDate + }; +} + +function splitcardname(mycardname) { + var mycardnamenew = []; + if (mycardname.length > 50) { + var mycardname1 = mycardname.substring(0, 50); + var mylastindex1 = mycardname1.lastIndexOf(' '); + var mylastindex2 = mycardname1.lastIndexOf('-'); + var mylastindex3 = mycardname1.lastIndexOf('&'); + var mylastindex = Math.max(mylastindex1, mylastindex2, mylastindex3); + mycardname1 = mycardname.substring(0, mylastindex); + var mycardname2 = mycardname.substring(mylastindex + 1, 100); + mycardnamenew.push(mycardname1); + mycardnamenew.push(mycardname2); + } else { + mycardnamenew.push(mycardname); + mycardnamenew.push(""); + } + return mycardnamenew; +} + +function buildDocument(DocumentIn, AttachmentEntry) { + var DocumentNew = {}; + draftMode = DocumentIn.draft_state; + myDebug.draftMode = draftMode; + if (draftMode) { + DocumentNew.DocObjectCode = objecttype; + } + myDebug.MapperMode = "CREATE"; + DocumentNew.CardCode = getCardCode(DocumentIn.account.gp_number); + const { + docDate, taxDate + } = getDocDates(); + DocumentNew.DocDate = datetimelib.convertToISODate(docDate); + DocumentNew.TaxDate = datetimelib.convertToISODate(taxDate); + DocumentNew.NumAtCard = DocumentIn.web_orderid; + //: DocumentIn.invoice_crm_id; + DocumentNew.DocCurrency = DocumentIn.CurrencyISOCode; + DocumentNew.Comments = DocumentIn.ShippingComments; + DocumentNew.U_EON_CRM_REF = DocumentIn.contract_id; + DocumentNew.TransportationCode = DocumentIn.TransportMethod; + if (DocumentIn.invoicetype === 'Sammelrechnung') { + DocumentNew.U_EON_PERIOD_FROM = datetimelib.convertToISODate(DocumentIn.billing_period.start); + DocumentNew.U_EON_PERIOD_TO = datetimelib.convertToISODate(DocumentIn.billing_period.end); + //Muss aus Vertrag gezogen werden... + //DocumentNew.U_EON_SIGNATURE_DATE = datetimelib.convertToISODate(new Date()); + DocumentNew.U_EON_SIGNATURE_DATE = getSignatureDate(DocumentIn.contract_id); + DocumentNew.U_EON_CRM_REF = DocumentIn.contract_id; + } else { + DocumentNew.U_EON_PERIOD_FROM = DocumentIn.order_completed.substring(0, 10); + DocumentNew.U_EON_PERIOD_TO = DocumentIn.order_completed.substring(0, 10); + DocumentNew.U_EON_SIGNATURE_DATE = datetimelib.convertToISODate(DocumentIn.signature_date); + } + DocumentNew.U_EON_SRC_SYSTEM = 'crm'; + DocumentNew.U_EON_SRC_ID = DocumentIn.invoice_crm_id; + DocumentNew.U_EON_SRC_GUID = DocumentIn.invoice_crm_guid; + DocumentNew.AttachmentEntry = AttachmentEntry; + var invoiceAddressExists = DocumentIn.invoice_address && DocumentIn.invoice_address.address && DocumentIn.invoice_address.address.city; + var shippingAddressExists = DocumentIn.shipping_address && DocumentIn.shipping_address.address && DocumentIn.shipping_address.address.city; + if (invoiceAddressExists && DocumentIn.invoice_address.person.name) { + DocumentNew.ContactPersonCode = 0; + } + if (DocumentIn.description) { + DocumentNew.Comments = DocumentIn.description.substring(0, 254); + } + DocumentNew.DocumentReferences = [ + { + RefObjType: 'rot_ExternalDocument', + ExtDocNum: logTableId.toString(), + Remark: 'UO_DOCUMENTS_RAWCALL' + } + ]; + if (invoiceAddressExists || shippingAddressExists) { + DocumentNew.AddressExtension = {}; + if (invoiceAddressExists) { + DocumentNew.AddressExtension.BillToAddress2 = splitcardname(DocumentIn.invoice_address.person.company_name)[0]; + DocumentNew.AddressExtension.U_CompanyName2B = splitcardname(DocumentIn.invoice_address.person.company_name)[1].substring(0, 50); + DocumentNew.AddressExtension.BillToBuilding = DocumentIn.invoice_address.address.street_addon; + DocumentNew.AddressExtension.BillToAddress3 = DocumentIn.invoice_address.person.salutation + " " + DocumentIn.invoice_address.person.name; + DocumentNew.AddressExtension.BillToStreet = DocumentIn.invoice_address.address.street_name; + DocumentNew.AddressExtension.BillToStreetNo = DocumentIn.invoice_address.address.housenumber; + DocumentNew.AddressExtension.BillToZipCode = DocumentIn.invoice_address.address.postalcode; + DocumentNew.AddressExtension.BillToCity = DocumentIn.invoice_address.address.city; + DocumentNew.AddressExtension.BillToCountry = DocumentIn.invoice_address.address.country; + + } + if (shippingAddressExists) { + DocumentNew.AddressExtension.ShipToAddress2 = splitcardname(DocumentIn.shipping_address.person.company_name)[0]; + DocumentNew.AddressExtension.U_CompanyName2S = splitcardname(DocumentIn.shipping_address.person.company_name)[1].substring(0, 50); + DocumentNew.AddressExtension.ShipToAddress3 = DocumentIn.shipping_address.person.salutation + " " + DocumentIn.shipping_address.person.name; + DocumentNew.AddressExtension.ShipToStreet = DocumentIn.shipping_address.address.street_name; + DocumentNew.AddressExtension.ShipToStreetNo = DocumentIn.shipping_address.address.housenumber; + DocumentNew.AddressExtension.ShipToZipCode = DocumentIn.shipping_address.address.postalcode; + DocumentNew.AddressExtension.ShipToCity = DocumentIn.shipping_address.address.city; + DocumentNew.AddressExtension.ShipToCountry = DocumentIn.shipping_address.address.country; + DocumentNew.AddressExtension.ShipToBuilding = DocumentIn.shipping_address.address.street_addon; + } + } + + DocumentNew.DocumentLines = []; + var needsSpecialLines = DocumentIn.products.findIndex(function(p) { + return p.product_crm_title && p.product_crm_title.startsWith('IN_ZUS'); + }) > -1; + if (needsSpecialLines) { + DocumentNew.DocumentSpecialLines = []; + DocumentNew.DocumentSpecialLines.push({ + AfterLineNumber: -1, + LineType: "dslt_Text", + LineText: "Im Paket enthalten:" + }); + } + // Hauptprodukte + for (var g in DocumentIn.products) { + var myItemLines = {}; + if (!(DocumentIn.products[g].product_crm_title && DocumentIn.products[g].product_crm_title.startsWith('IN_ZUS'))) { + // PFT-790: vor 11.12.2025 myItemLines.ItemCode = getItemCode(DocumentIn.products[g].product_id); + myItemLines.ItemCode = DocumentIn.products[g].product_b1_articlenumber; + myItemLines.ItemDescription = DocumentIn.products[g].product_invoice_title; + myItemLines.Quantity = DocumentIn.products[g].amount; + myItemLines.MeasureUnit = DocumentIn.products[g].unit; + // myItemLines.WarehouseCode = DocumentIn.products[g].Warehouse; + myItemLines.UnitPrice = DocumentIn.products[g].discounted_single_price; + myItemLines.U_EON_PERIOD_FROM = DocumentIn.invoicetype === 'Sammelrechnung' ? datetimelib.convertToISODate(DocumentIn.billing_period.start) : + DocumentIn.order_completed.substring(0, 10); + myItemLines.U_EON_PERIOD_TO = DocumentIn.invoicetype === 'Sammelrechnung' ? datetimelib.convertToISODate(DocumentIn.billing_period.end) : + DocumentIn.order_completed.substring(0, 10); + // myItemLines.DiscountPercent = DocumentIn.OrderLineItems[g].RowDiscount; + myItemLines.ProjectCode = DocumentIn.products[g].orderid; + /*var locationsAdressExists = DocumentIn.locations && DocumentIn.locations[0].address && DocumentIn.locations[0].address.city; + + // myItemLines.U_KU_SONumber = DocumentIn.OrderLineItems[g].RelatedSalesOrder ? DocumentIn.OrderLineItems[g].RelatedSalesOrder : null; + if (g==='0' && locationsAdressExists) + { + var locationsText = "Standort:"; + DocumentIn.locations.forEach(function (loc) { + locationsText += "\n" + loc.address.street_name + " " + loc.address.housenumber + "\n" + loc.address.postalcode + " " + loc.address.city; + }); + myItemLines.ItemDetails = locationsText; + }*/ + if (DocumentIn.products[g].service_description) { + myItemLines.ItemDetails = DocumentIn.products[g].service_description; + } + DocumentNew.DocumentLines.push(myItemLines); + } + } + if (needsSpecialLines) { + DocumentNew.DocumentSpecialLines.push({ + AfterLineNumber: DocumentNew.DocumentLines.length - 1, + LineType: "dslt_Subtotal", + LineText: "Zwischensumme" + }); + DocumentNew.DocumentSpecialLines.push({ + AfterLineNumber: DocumentNew.DocumentLines.length - 1, + LineType: "dslt_Text", + LineText: "Zusatzleistungen:" + }); + } + // Zusatzprodukte + for (var g in DocumentIn.products) { + var myItemLines = {}; + if (DocumentIn.products[g].product_crm_title && DocumentIn.products[g].product_crm_title.startsWith('IN_ZUS')) { + //PFT 790 myItemLines.ItemCode = getItemCode(DocumentIn.products[g].product_id); + myItemLines.ItemCode = DocumentIn.products[g].product_b1_articlenumber; + myItemLines.ItemDescription = DocumentIn.products[g].product_invoice_title; + myItemLines.Quantity = DocumentIn.products[g].amount; + myItemLines.MeasureUnit = DocumentIn.products[g].unit; + // myItemLines.WarehouseCode = DocumentIn.products[g].Warehouse; + myItemLines.UnitPrice = DocumentIn.products[g].discounted_single_price; + myItemLines.U_EON_PERIOD_FROM = DocumentIn.invoicetype === 'Sammelrechnung' ? datetimelib.convertToISODate(DocumentIn.billing_period.start) : + DocumentIn.order_completed.substring(0, 10); + myItemLines.U_EON_PERIOD_TO = DocumentIn.invoicetype === 'Sammelrechnung' ? datetimelib.convertToISODate(DocumentIn.billing_period.end) : + DocumentIn.order_completed.substring(0, 10); + // myItemLines.DiscountPercent = DocumentIn.OrderLineItems[g].RowDiscount; + myItemLines.ProjectCode = DocumentIn.products[g].orderid; + /*var locationsAdressExists = DocumentIn.locations && DocumentIn.locations[0].address && DocumentIn.locations[0].address.city; + + // myItemLines.U_KU_SONumber = DocumentIn.OrderLineItems[g].RelatedSalesOrder ? DocumentIn.OrderLineItems[g].RelatedSalesOrder : null; + if (g==='0' && locationsAdressExists) + { + var locationsText = "Standort:"; + DocumentIn.locations.forEach(function (loc) { + locationsText += "\n" + loc.address.street_name + " " + loc.address.housenumber + "\n" + loc.address.postalcode + " " + loc.address.city; + }); + myItemLines.ItemDetails = locationsText; + }*/ + if (DocumentIn.products[g].service_description) { + myItemLines.ItemDetails = DocumentIn.products[g].service_description; + } + DocumentNew.DocumentLines.push(myItemLines); + } + } + if (needsSpecialLines) { + DocumentNew.DocumentSpecialLines.push({ + AfterLineNumber: DocumentNew.DocumentLines.length - 1, + LineType: "dslt_Subtotal", + LineText: "Zwischensumme" + }); + } + + return DocumentNew; +} + +function setAperiodicAccounts(createBody) { + var newBody = JSON.parse(JSON.stringify(createBody)); + var accountList = []; + var aperiodicAccountAssignment = []; + outMsg = {}; + outMsg.method = "setAperiodicAccounts.previewInvoice"; + outMsg.status = "error"; + + //create preview invoice + var responsePreview = slib.previewInvoice(JSON.stringify({ + Document: createBody + }), SESSIONID, NODEID); + myDebug.statusPreview = responsePreview.status; + outMsg.statuscode = responsePreview.status; + myDebug.responsePreview = JSON.parse(responsePreview.body.asString()); + if (responsePreview.status >= 200 && responsePreview.status < 300) { + outMsg.status = "success"; + var previewInvObj = JSON.parse(responsePreview.body.asString()); + // erstelle eine eindeutige Liste von Konten, basierend auf Zeilen mit aperiodischem Zeitraum + accountList = previewInvObj.DocumentLines.filter(function(dl) { + return dl.U_EON_PERIOD_TO.substring(0, 4) < createBody.DocDate.substring(0, 4) + }) + .map(function(al) { + return al.AccountCode + }) + .filter(function(account, index, inputArray) { + return inputArray.indexOf(account) == index; + }); + myDebug.accountListOfAperiodicLines = accountList; + if (debugLevel > 0) { + outMessages.push(outMsg); + } + //lookup aperiodic accounts + outMsg = {}; + outMsg.method = "setAperiodicAccounts.lookupAccounts"; + outMsg.status = "error"; + //"SELECT T0.\"U_EON_ACCAPER\", T0.\"AcctName\" FROM OACT T0 WHERE T0.\"AcctCode\" = ? + var conn = $.hdb.getConnection(); + accountList.forEach(function(accountCode) { + var rs = conn.executeQuery('SELECT T0."U_EON_ACCAPER", T0."AcctCode", T0."AcctName" FROM "' + UserComp + + '".OACT T0 WHERE T0."AcctCode" = ?', accountCode); + if (rs[0].U_EON_ACCAPER) { + aperiodicAccountAssignment.push({ + accountCode: rs[0].AcctCode, + aperiodicAccountCode: rs[0].U_EON_ACCAPER + }) + } + }); + conn.close(); + outMsg.aperiodicAccountAssignment = aperiodicAccountAssignment; + // aperiodische Konten in Belegzeilen setzen + for (var i = 0; i < previewInvObj.DocumentLines.length; i++) { + var oldAccount = previewInvObj.DocumentLines[i].AccountCode; + var accountMapping = aperiodicAccountAssignment.find(function(a) { + return a.accountCode === oldAccount + }); + if (accountMapping && accountMapping.aperiodicAccountCode) { + newBody.DocumentLines[i].AccountCode = accountMapping.aperiodicAccountCode; + } + } + outMsg.status = "success"; + } else { + outMsg.status = "error"; + //outMsg.message = myDebug.responsePreview; + outStatus = "error"; + var slError = myDebug.responsePreview.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.responsePreview); + } + outMsg.response = myDebug.responsePreview; + } + if (debugLevel > 0 || outMsg.status == "error") { + outMessages.push(outMsg); + } + return newBody; +} + +function lookupMimeTypes(crmAttachments) { + var mimeTypeList = []; + outMsg = {}; + outMsg.method = "lookup MIME Types"; + outMsg.status = 'success'; + var conn = $.hdb.getConnection(); + mimeTypeList = crmAttachments.map(function(a) { + var rs = conn.executeQuery('SELECT T0."Code", T0."Name" FROM "' + UserComp + '"."@UO_MIME_TYPES" T0 WHERE T0."Name" = ?', a.document_mime_type); + if (rs.length > 0) { + return { + mimeTypeCode: rs[0].Code, + mimeType: rs[0].Name + } + } else { + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "MIME Type '" + a.document_mime_type + "' not found"; + } + }); + conn.close(); + if (debugLevel > 0) { + outMsg.mimeTypeList = mimeTypeList; + } + if (debugLevel > 0 || outMsg.status == "error") { + outMessages.push(outMsg); + } + return mimeTypeList; +} + +function buildFilesObj(crmAttachments) { + var filesObj = []; + outMsg = {}; + outMsg.method = "build files object"; + outMsg.status = 'success'; + filesObj = crmAttachments.map(function(a) { + return { + contentType: a.document_mime_type, + fileName: $.util.createUuid() + "_" + a.document_name, + b64Content: a.document_content + }; + }); + if (debugLevel > 0) { + outMsg.filesObj = filesObj; + outMessages.push(outMsg); + } + return filesObj; +} + +function upsertDocument(inObj) { + try { + var DocumentIn = JSON.parse(inObj); + var DocEntry = getDocEntry(DocumentIn.invoice_crm_guid); + var attachmentEntry = -1; + + if (outStatus !== "error") { + slLoggedIn = slLogin(); + if (outStatus !== "error" && outStatus !== "exists" && DocumentIn.attachments) { + var mimeTypeList = lookupMimeTypes(DocumentIn.attachments); + } + if (outStatus !== "error" && outStatus !== "exists" && DocumentIn.attachments) { + // Erstellung des Attachments Objekt inkl. Hochladen der Dateien - POST /b1s/v1/Attachments2 + var filesObj = buildFilesObj(DocumentIn.attachments); + if (outStatus !== "error") { + outMsg = {}; + outMsg.method = "uploadAttachments"; + outMsg.status = "error"; + var response = slib.callServiceLayerFileUpload('/b1s/v1/Attachments2', $.net.http.POST, filesObj, SESSIONID, NODEID); + outMsg.statuscode = response.status; + var parsedResponseUpload = response.body ? JSON.parse(response.body.asString()) : {}; + if (response.status >= 200 && response.status < 300) { + outMsg.status = "success"; + var attachmentObjResponse = parsedResponseUpload; + // attachmentEntry = AbsoluteEntry aus Response + if (attachmentObjResponse.AbsoluteEntry > 0) { + attachmentEntry = attachmentObjResponse.AbsoluteEntry; + outMsg.AttachmentEntry = attachmentEntry; + } + } else if (response.exception) { + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = response.exception; + } else { + outStatus = "error"; + outMsg.status = "error"; + var slError = parsedResponseUpload.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(parsedResponseUpload); + } + } + if (debugLevel > 0 || outMsg.status == "error") { + outMessages.push(outMsg); + } + } + // Anreicherung der UDFs - PATCH /b1s/v1/Attachments2 + if (outStatus !== 'error') { + outMsg = {}; + outMsg.method = "updateAttachments"; + outMsg.status = "error"; + var attachmentPatchBody = { + AbsoluteEntry: attachmentEntry, + Attachments2_Lines: DocumentIn.attachments.map(function(a, idx) { + return { + AbsoluteEntry: attachmentEntry, + LineNum: idx + 1, + Override: 'tYES', + U_EON_EDOC_REL: 'Y', + U_EON_ORIG_FILE: a.document_name, + U_EON_MIME_TYPE: mimeTypeList.find(function(mt) {return mt.mimeType === a.document_mime_type;}).mimeTypeCode, + U_EON_DOC_GUID: a.document_guid, + U_EON_TRANS_KEY: a.transmission_key + }; + }) + }; + if (debugLevel > 0) { + outMsg.requestBody = attachmentPatchBody; + } + var response = slib.patchDynamicEntity('Attachments2', attachmentEntry, JSON.stringify(attachmentPatchBody), SESSIONID, NODEID, false); + + outMsg.statuscode = response.status; + var parsedResponseUpdate = response.body ? JSON.parse(response.body.asString()) : {}; + if (response.status >= 200 && response.status < 300) { + outMsg.status = "success"; + } else if (response.exception) { + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = response.exception; + } else { + outStatus = "error"; + outMsg.status = "error"; + var slError = parsedResponseUpdate.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(parsedResponseUpdate); + } + } + if (debugLevel > 0 || outMsg.status == "error") { + outMessages.push(outMsg); + } + } + } + if (outStatus !== "error" && outStatus !== "exists") { + //myDebug.CreateCode = "activated"; + var createBody = buildDocument(DocumentIn, attachmentEntry); + myDebug.CreateObj = createBody; + var aperiodicLines = createBody.DocumentLines.filter(function(dl) { + return dl.U_EON_PERIOD_TO.substring(0, 4) < createBody.DocDate.substring(0, 4) + }); + if (aperiodicLines.length > 0) { + createBody = setAperiodicAccounts(createBody); + } + // EMPEPI1-141: Ablehnung von Rechnungen im Entwurfsmodus ab 25.11.2022 + const today = new Date(); + const draftNotAllowedFrom = new Date('2022-11-28T00:00:00+01:00'); + const draftNotAllowedUntil = new Date('2022-12-06T23:59:59+01:00'); + if (draftMode && today >= draftNotAllowedFrom && today <= draftNotAllowedUntil) { + outMsg = {}; + outMsg.method = "checkDraft"; + outMsg.status = "error"; + outMsg.message = "Draft documents are currently not allowed"; + outMessages.push(outMsg); + outStatus = "error"; + } else { + outMsg = {}; + outMsg.method = "create"; + //consDoc = buildSCObj(jsonSFCall, currentSC, addrObj, output.method); + //outMsg.CreateObj = createBody; + + var responseCreate; + if (draftMode) { + responseCreate = slib.createDraft(JSON.stringify(createBody), SESSIONID, NODEID); + } else { + responseCreate = slib.createInvoice(JSON.stringify(createBody), SESSIONID, NODEID); + } + myDebug.statusCreate = responseCreate.status; + outMsg.statuscode = responseCreate.status; + myDebug.responseCreate = JSON.parse(responseCreate.body.asString()); + if (responseCreate.status >= 200 && responseCreate.status < 300) { + myDebug.Createmessage = "Create sucessfull"; + outMsg.status = "success"; + var createdInvObj = JSON.parse(responseCreate.body.asString()); + outMsg.DocEntry = createdInvObj.DocEntry; + logDocEntry = createdInvObj.DocEntry; + outMsg.DocNum = createdInvObj.DocNum; + //outMsg.currentOBJECT = createdInvObj; + } else { + myDebug.Createmessage = "Create error occured"; + //output.errorCreatestatus = myDebug.Createmessage; + outStatus = "error"; + outMsg.status = "error"; + var slError = myDebug.responseCreate.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.responseCreate); + } + outMsg.response = myDebug.responseCreate; + } + outMessages.push(outMsg); + } + } + } + + // } + } catch (e) { + exceptionHandler(e); + return; + } + + if (slLoggedIn) { + slib.SLLogout(SESSIONID, NODEID); + } +} +var content = $.request.body.asString(); +try { + outMsg = {}; + outMsg.method = "logRequest"; + outMsg.status = "error"; + logTableId = logginglib.logCall2Table(content, "UO_DOCUMENTS_RAWCALL", objecttype, serviceName, true); + outMsg.logTableId = logTableId; + if (logTableId > 0) { + outMsg.status = "success"; + } + if (debugLevel > 0) { + outMessages.push(outMsg); + } +} catch (e) { + outStatus = "error"; + exceptionHandler(e); +} +setConnectionParams(content); +if (outStatus !== "error") { + upsertDocument(content); +} + +updateLogEntry(logTableId, logDocEntry, draftMode ? '112' : objecttype); + +setOutputMessage(); \ No newline at end of file