// 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 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 = "nice.v1.setinvoice.xsjs"; var serviceVersion = '3.2'; 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'))) { myItemLines.ItemCode = getItemCode(DocumentIn.products[g].product_id); myItemLines.ItemDescription = DocumentIn.products[g].product_invoice_title; myItemLines.Quantity = DocumentIn.products[g].amount; // 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')) { myItemLines.ItemCode = getItemCode(DocumentIn.products[g].product_id); myItemLines.ItemDescription = DocumentIn.products[g].product_invoice_title; myItemLines.Quantity = DocumentIn.products[g].amount; // 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 buildFilesObj(crmAttachments) { var filesObj; outMsg = {}; outMsg.method = "lookup MIME Types"; outMsg.status = 'success'; var conn = $.hdb.getConnection(); filesObj = crmAttachments.map(function(a) { var rs = conn.executeQuery('SELECT T0."Code", T0."Name" FROM "' + UserComp + '"."@UO_MIME_TYPES" T0 WHERE T0."Code" = ?', a.document_mime_type); if (rs.length > 0) { return { contentType: rs[0].Name, fileName: $.util.createUuid() + "_" + a.document_name, b64Content: a.document_content } } else { outMsg.status = "error"; outStatus = "error"; outMsg.message = "MIME Type '" + a.document_mime_type + "' not found"; } }); conn.close(); if (debugLevel > 0) { outMsg.filesObj = filesObj; } if (debugLevel > 0 || outMsg.status == "error") { 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) { // 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: a.document_mime_type, 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();