From ffda8a39d76efc73e42a59fd99b7b4d5517437d5 Mon Sep 17 00:00:00 2001 From: Marcel Bourseau Date: Thu, 22 Jun 2023 19:27:42 +0000 Subject: [PATCH] MARX#74747 Voor T365 de Facturen via de Saxton/JSON koppeling svn path=/Mareon/trunk/; revision=60914 --- ax/SRC/AxFacilitor.js | 15 +- ax/SRC/F_GetFacturen.js | 374 +++++++++++++++++++++++++++++++++++----- 2 files changed, 343 insertions(+), 46 deletions(-) diff --git a/ax/SRC/AxFacilitor.js b/ax/SRC/AxFacilitor.js index 1e4eca6..e9ea287 100644 --- a/ax/SRC/AxFacilitor.js +++ b/ax/SRC/AxFacilitor.js @@ -447,9 +447,14 @@ function AX365_2_FACILITOR() FCLT_2_AX365_OpdrachtStatus_Bijlagen(); __Log("*** END", 2); + if (G_ID_ax365_supplierservice_url == ""){ + // MARX#74747 Voor T365 de Facturen via de Saxton/JSON koppeling, als supplier-url leeg is, dan laten we facturen over deze as lopen... + __Log("*** AX365: Facturen via Saxton", 2) + FACILITOR_2_Xtractor(); + } } else{ - __Log("*** AX365: Status berichten NIET ingesteld", 2) + __Log("*** AX365: Saxton NIET ingesteld", 2) } if (G_ID_ax365_supplierservice_url != "") @@ -465,13 +470,12 @@ function AX365_2_FACILITOR() __Log("*** END Get Supplierservice Token", 2); // Facturen van Mareon -> AX365, in de functie FACILITOR_2_Xtractor wordt zelf bekeken of dit WEL/NIET via pushnotificatie verloopt... + __Log("*** AX365: Facturen via SupplierService", 2) FACILITOR_2_Xtractor(); } else{ - __Log("*** AX365: Facturen koppeling NIET ingesteld", 2); + __Log("*** AX365: Supplierservice NIET ingesteld", 2); } - - } function Tobias_2_FACILITOR() @@ -736,9 +740,10 @@ function FACILITOR_2_Xtractor() // 1.72 -- MARX#77225: Bugje statusbericht naar 3RD party Viewpoint/Itris + MARX#76900 Mareon Universele Opdracht API // 1.73 -- MARX#76390: Kan oude logging van de SYNC adapter automatisch opgeruimd worden + MARX#76891: Registratie in AX2012 of inkooporder aanwezig is in Mareon // 1.74 -- MARX#78797: Premium Ter Steege met woco "Mijande Wonen" (Viewpoint/Itris) - soapaction toegevoegd, contenttype aangepast en timestamp in MsgDateTime verbeterd +// 1.75 -- MARX#74747: Voor T365 de Facturen via de Saxton/JSON koppeling -var G_Mareon_Adapter = "1.74"; +var G_Mareon_Adapter = "1.75"; //MARX#56643: Test Haagwonen inkoopordernummer ontbreekt in Mareon ION001753 var G_new_date = new Date(); //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/ax/SRC/F_GetFacturen.js b/ax/SRC/F_GetFacturen.js index 7ecf226..ae4c785 100644 --- a/ax/SRC/F_GetFacturen.js +++ b/ax/SRC/F_GetFacturen.js @@ -486,6 +486,277 @@ function F_Get_Base64_FactuurFile(p_fin_factuur_key) return l_base64; } +// Bepaalt uit de Xtractor-XML de company-ID waar de factuur naar toe gestuurd moet worden (dwz AX-nr waarvoor de factuur bestemd is) +function Xtractor_2_CompanyID (p_xml) +{ + var strQuery_document = "//document/fields/DOCUMENT"; + var v_buyer_axid = p_xml.selectSingleNode(strQuery_document + "/EX_SGBDR").text; + return v_buyer_axid; +} + +function Xtractor_2_PreInvoice (p_xml, p_pdf_base64) +{ + +// Voorbeeld van PreInvoice JSON structuur +//{ +// "amountHigh": 0, +// "amountLow": 0, +// "amountNoTax": 0, +// "autoIncasso": true, +// "bankAccountId": "string", +// "bookDate": "2023-06-19T10:42:49.281Z", +// "buyer": { +// "address": "string", +// "city": "string", +// "name": "string", +// "zipCode": "string" +// }, +// "chamberOfCommerceNumber": "string", +// "deliveryDate": "2023-06-19T10:42:49.281Z", +// "description": "string", +// "documentFileName": "string", +// "g_Account": "string", +// "g_Amount": 0, +// "invoiceAmount": 0, +// "invoiceBase64": "string", +// "invoiceDate": "2023-06-19T10:42:49.281Z", +// "invoiceNumber": "string", +// "invoiceSource": "string", +// "specs": [ +// { +// "amount": 0, +// "articleId": "string", +// "chargedTo": "string", +// "id": "string", +// "lineNum": 0, +// "lineQuanity": 0, +// "location": "string", +// "typeId": "string", +// "unit": "string", +// "vatIndicator": "string" +// } +// ], +// "taxAmountHigh": 0, +// "taxAmountLow": 0, +// "taxDate": "2023-06-19T10:42:49.281Z", +// "taxShifted": true, +// "vatNumber": "string", +// "vendor": { +// "address": "string", +// "city": "string", +// "name": "string", +// "zipCode": "string" +// } +//} + + var strQuery_amount = "//document/fields/AMOUNT"; + var strQuery_document = "//document/fields/DOCUMENT"; + var strQuery_corsa = "//document/fields/CORSA"; + var strQuery_docfile = "//document/docfile"; + + + var v_amountHigh_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_SGGHOOG").text; + var v_amountHigh = 0; + if (v_amountHigh_txt != "") + { + v_amountHigh = parseFloat(v_amountHigh_txt.replace(/,/,'.')); + } + + var v_amountLow_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_SGGLAAG").text; + var v_amountLow = 0; + if (v_amountLow_txt != "") + { + v_amountLow = parseFloat(v_amountLow_txt.replace(/,/,'.')); + } + + var v_amountNoTax_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_SGGONBEL").text; + var v_amountNoTax = 0; + if (v_amountNoTax_txt != "") + { + var v_amountNoTax = parseFloat(v_amountNoTax_txt.replace(/,/,'.')); + } + + var v_autoIncasso_txt = p_xml.selectSingleNode(strQuery_document + "/EX_SGAINC").text; + var v_autoIncasso = Boolean(v_autoIncasso_txt == "Ja"); + + var v_bankAccountId = p_xml.selectSingleNode(strQuery_corsa + "/EX_BANKACC_1").text; + + var v_invoiceDate_txt = p_xml.selectSingleNode(strQuery_document + "/EX_INVOICEDATE").text; + var v_invoiceDate = v_invoiceDate_txt.substr(6,4) + "-" + v_invoiceDate_txt.substr(3,2) + "-" + v_invoiceDate_txt.substr(0,2) + "T12:00:00Z"; // Knetterhard ergens midden op de dag (is toch dont care) + var v_bookDate = v_invoiceDate; + var v_taxDate = v_invoiceDate; + + + var v_buyer_address = p_xml.selectSingleNode(strQuery_document + "/EX_SGBDR_ADRES").text; + var v_buyer_city = p_xml.selectSingleNode(strQuery_document + "/EX_SGBDR_PLAATS").text; + var v_buyer_name = p_xml.selectSingleNode(strQuery_document + "/EX_SGBDR_NAAM").text; + var v_buyer_zipcode = p_xml.selectSingleNode(strQuery_document + "/EX_SGBDR_POSTCODE").text; + + var v_chamberOfCommerceNumber = p_xml.selectSingleNode(strQuery_document + "/EX_KVKNUMMER").text; + var v_deliveryDate_txt = p_xml.selectSingleNode(strQuery_document + "/EX_DELIVERYDATE").text; + var v_deliveryDate = v_deliveryDate_txt.substr(6,4) + "-" + v_deliveryDate_txt.substr(3,2) + "-" + v_deliveryDate_txt.substr(0,2) + "T12:00:00Z"; // Knetterhard ergens midden op de dag (is toch dont care) + + var v_description = p_xml.selectSingleNode(strQuery_document + "/EX_OND").text; + var v_documentFileName = p_xml.selectSingleNode(strQuery_docfile + "/pdf_img_file").text; + + var v_g_Account = p_xml.selectSingleNode(strQuery_amount + "/EX_GREKNR").text; + + var v_g_Amount_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_GREKBDR").text; + var v_g_Amount = 0; + if (v_g_Amount_txt != "") + { + v_g_Amount = parseFloat(v_g_Amount_txt.replace(/,/,'.')); + } + + var v_invoiceAmount_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_TOTAL_INCL").text; + var v_invoiceAmount = 0; + if (v_invoiceAmount_txt != "") + { + v_invoiceAmount = parseFloat(v_invoiceAmount_txt.replace(/,/,'.')); + } + var v_invoiceBase64 = p_pdf_base64; + + var v_invoiceNumber = p_xml.selectSingleNode(strQuery_document + "/EX_INVOICENR").text; + var v_invoiceSource = p_xml.selectSingleNode(strQuery_document + "/EX_INVOICE_BRON").text; + + var i = 1; + var strQuery_tableROW = "//document/fields/TABLE/EX_TABLE/row[" + i + "]"; + l_tableROW_xml = p_xml.selectSingleNode(strQuery_tableROW); + var v_array_resulttableROW = []; + while (l_tableROW_xml) + { + var v_ART = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='1']").text; + //omschrijving van factuurregel wordt in T365 (nog) niet gebruikt... + //var v_DESCR = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='2']").text; + var v_AMNT = 0; + var v_AMNT_txt = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='3']").text; + if (v_AMNT_txt != "") + { + v_AMNT = parseFloat(v_AMNT_txt.replace(/,/,'.')); + } + var v_BTW = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='4']").text; + + var v_BTWAMNT =0; + var v_BTWAMNT_txt = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='5']").text; + if (v_BTWAMNT_txt != "") + { + v_BTWAMNT = parseFloat(v_BTWAMNT_txt.replace(/,/,'.')); + } + + var v_PRICEUNIT = 0; + var v_PRICEUNIT_txt = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='6']").text; + if (v_PRICEUNIT_txt != "") + { + v_PRICEUNIT = parseFloat(v_PRICEUNIT_txt.replace(/,/,'.')); + } + + var v_LINENUM = 0; + var v_LINENUM_txt = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='7']").text; + if (v_LINENUM_txt != "") + { + v_LINENUM = parseInt(v_LINENUM_txt); + } + + var v_ARTNR = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='8']").text; + + var v_ARTNRAMNT = 0; + var v_ARTNRAMNT_txt = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='9']").text; + if (v_ARTNRAMNT_txt != "") + { + v_ARTNRAMNT = parseInt(v_ARTNRAMNT_txt); + } + + var v_ARTNRUNIT = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='10']").text; + var v_ARTNRLOC = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='11']").text; + var v_ARTNRCOST = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='12']").text; + var v_ARTSPEC = p_xml.selectSingleNode(strQuery_tableROW + "/col[@nr='13']").text; + + var l_row_data = + { + "amount": v_AMNT, + "articleId": v_ARTNR, + "chargedTo": v_ARTNRCOST, + "id": v_ART, + "lineNum": v_LINENUM, + "lineQuanity": v_ARTNRAMNT, + "location": v_ARTNRLOC, + "typeId": v_ARTSPEC, + "unit": v_ARTNRUNIT, + "vatIndicator": v_BTW + } + + v_array_resulttableROW.push(l_row_data); + + i = i + 1; + var strQuery_tableROW = "//document/fields/TABLE/EX_TABLE/row[" + i + "]"; + l_tableROW_xml = p_xml.selectSingleNode(strQuery_tableROW); + } + + var v_taxAmountHigh_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_VAT_HIGH").text; + var v_taxAmountHigh = 0; + if (v_taxAmountHigh_txt != "") + { + v_taxAmountHigh = parseFloat(v_taxAmountHigh_txt.replace(/,/,'.')); + } + var v_taxAmountLow_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_VAT_LOW").text; + var v_taxAmountLow = 0; + if (v_taxAmountLow_txt != "") + { + v_taxAmountLow = parseFloat(v_taxAmountLow_txt.replace(/,/,'.')); + } + + var v_taxShifted_txt = p_xml.selectSingleNode(strQuery_amount + "/EX_BTWVERL").text; + var v_taxShifted = Boolean(v_taxShifted_txt == "Ja"); + + var v_vatNumber = p_xml.selectSingleNode(strQuery_corsa + "/EX_VATNR_1").text; + + var v_vendor_address = p_xml.selectSingleNode(strQuery_document + "/EX_EXBDR_ADRES").text; + var v_vendor_city = p_xml.selectSingleNode(strQuery_document + "/EX_EXBDR_PLAATS").text; + var v_vendor_name = p_xml.selectSingleNode(strQuery_document + "/EX_EXBDR_NAAM").text; + var v_vendor_zipcode = p_xml.selectSingleNode(strQuery_document + "/EX_EXBDR_POSTCODE").text; + + + var l_json_data = + { + "amountHigh": v_amountHigh, + "amountLow": v_amountLow, + "amountNoTax": v_amountNoTax, + "autoIncasso": v_autoIncasso, + "bankAccountId": v_bankAccountId, + "bookDate": v_bookDate, + "buyer": { + "address": v_buyer_address, + "city": v_buyer_city, + "name": v_buyer_name, + "zipCode": v_buyer_zipcode + }, + "chamberOfCommerceNumber": v_chamberOfCommerceNumber, + "deliveryDate": v_deliveryDate, + "description": v_description, + "documentFileName": v_documentFileName, + "g_Account": v_g_Account, + "g_Amount": v_g_Amount, + "invoiceAmount": v_invoiceAmount, + "invoiceBase64": v_invoiceBase64, + "invoiceDate": v_invoiceDate, + "invoiceNumber": v_invoiceNumber, + "invoiceSource": v_invoiceSource, + "specs": v_array_resulttableROW, + "taxAmountHigh": v_taxAmountHigh, + "taxAmountLow": v_taxAmountLow, + "taxDate": v_taxDate, + "taxShifted": v_taxShifted, + "vatNumber": v_vatNumber, + "vendor": { + "address": v_vendor_address, + "city": v_vendor_city, + "name": v_vendor_name, + "zipCode": v_vendor_zipcode + } + }; + return l_json_data; +} + function A2012_Xtractor2AX(v_xml, xtractFile) { var v_API = "PreInvoiceServiceAddPreInvoiceFromXtractorRequest"; var v_req = ' "; @@ -517,51 +788,72 @@ function A365_Xtractor2AX(v_resp, i, v_deelxml, v_factuur_key, v_notification_ke { // Factuur WEL naar opdrachtgever sturen, is erg gewenst aldaar! De factuur wordt dus WEL verwerkt (door opdrachtgever). var l_pdf_base64 = F_Get_Base64_FactuurFile(v_factuur_key); - if (l_pdf_base64 != ""){ - // De node Attachment in de XML. - var node_attachment = v_deelxml.getElementsByTagName("docfile"); - if (node_attachment.length != 0){ - // De node docfile in de XML bestaat dus. - __Log("XML node docfile exists", 3); - // De node pdf_base64 in XMLResult gaat inhoud krijgen met de base64 tekenreeks. - var node_attached_data = v_deelxml.getElementsByTagName("pdf_base64"); - if (node_attached_data.length != 0){ - __Log("XML node pdf_base64 exists", 3); - var y = node_attached_data.childNodes[0]; - if (y != null){ - y.nodeValue = l_pdf_base64; + + // MARX#74747 Voor T365 de Facturen via de Saxton/JSON koppeling + if (G_ax365_url_supplierservice != "") + { // XML via de 'oude' supplierservice + if (l_pdf_base64 != ""){ + // De node Attachment in de XML. + var node_attachment = v_deelxml.getElementsByTagName("docfile"); + if (node_attachment.length != 0){ + // De node docfile in de XML bestaat dus. + __Log("XML node docfile exists", 3); + // De node pdf_base64 in XMLResult gaat inhoud krijgen met de base64 tekenreeks. + var node_attached_data = v_deelxml.getElementsByTagName("pdf_base64"); + if (node_attached_data.length != 0){ + __Log("XML node pdf_base64 exists", 3); + var y = node_attached_data.childNodes[0]; + if (y != null){ + y.nodeValue = l_pdf_base64; + } + } + else { + __Log("XML node pdf_base64 does NOT exist",2); + + newEle = v_resp.createElement("pdf_base64"); + __Log("XML element pdf_base64 created",3); + newTxt = v_resp.createTextNode(l_pdf_base64); + __Log("XML textnode with base64 data created",3); + newEle.appendChild(newTxt); + __Log("XML element pdf_base64 with textnode",3); + node_attachment[0].appendChild(newEle); + __Log("XML element added to XML",3); } - } - else { - __Log("XML node pdf_base64 does NOT exist",2); - - newEle = v_resp.createElement("pdf_base64"); - __Log("XML element pdf_base64 created",3); - newTxt = v_resp.createTextNode(l_pdf_base64); - __Log("XML textnode with base64 data created",3); - newEle.appendChild(newTxt); - __Log("XML element pdf_base64 with textnode",3); - node_attachment[0].appendChild(newEle); - __Log("XML element added to XML",3); } } - } - - var XMLResult = "" + v_deelxml.xml; - - if (G_log_level >= 4){ - var l_log_folder = GetLogFolder() + "/"; - WriteText2File(l_log_folder, "invoice_ax365[" + i + "]" , "xml" , XMLResult, 1, 1); - } - - // Send factuur-XML to AX365 + + var XMLResult = "" + v_deelxml.xml; - var v_API = ""; // dont care in AX365 Factuur-webservice - var v_req = ' "; - var v_type = 0; - var v_soapAction = "PreInvoiceService/addPreInvoiceFromXtractor"; - var v_soort_api = 1; // (nav MARX#61048: Documenten versturen van Mareon naar AX) is waarde 1 (oude/huidige api via SupplierService) of waarde 2 (nieuwe api via CustomerPortalAX) - var v_result = apiAX_GENERAL (v_API, v_req, v_type, v_soapAction, 1, v_soort_api); + if (G_log_level >= 4){ + var l_log_folder = GetLogFolder() + "/"; + WriteText2File(l_log_folder, "invoice_ax365[" + i + "]" , "xml" , XMLResult, 1, 1); + } + + var v_API = ""; // dont care in AX365 Factuur-webservice + var v_req = ' "; + var v_type = 0; + var v_soapAction = "PreInvoiceService/addPreInvoiceFromXtractor"; + var v_discard_active_abort = 1; //In geval van 500-error, geen active abort... + var v_soort_api = 1; // (nav MARX#61048: Documenten versturen van Mareon naar AX) is waarde 1 (oude/huidige api via SupplierService) of waarde 2 (nieuwe api via CustomerPortalAX) + } + else + { + // JSON via Saxton/ AX webservice + + // Gedeelte van het URL pad naar de webservice "PreInvoice" + var v_company_id = Xtractor_2_CompanyID(v_deelxml); + var v_API = "api/v0.1/" + v_company_id + "/Suppliers/PreInvoice"; + // Conversie van Xtractor-XML naar Preinvoice-JSON + var l_json_data = Xtractor_2_PreInvoice(v_deelxml, l_pdf_base64); + var v_req = JSON.stringify(l_json_data, null, 2); + var v_type = 0; + var v_soapAction = ""; + var v_discard_active_abort = 1; //In geval van 500-error, geen active abort... + var v_soort_api = 2; + } + + // Send factuur-XML of factuur-JSON to AX365 + var v_result = apiAX_GENERAL (v_API, v_req, v_type, v_soapAction, v_discard_active_abort, v_soort_api); var l_statuscode = v_result.api_status_code; var l_statustekst = v_result.api_status_message;