Files
EON_CRM_INVOICE/uniorg/eon/crm/invoice/v1/post-invoice.xsjs
T

1104 lines
36 KiB
JavaScript

// 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();