const GraphQLClient = require("graphql-request").GraphQLClient; const path = require("path"); const DineroQbFormat = require("../accounting-constants").DineroQbFormat; const queries = require("../../graphql-client/queries"); const Dinero = require("dinero.js"); var builder = require("xmlbuilder2"); const moment = require("moment"); const QbXmlUtils = require("./qbxml-utils"); const QbxmlReceivables = require("./qbxml-receivables"); require("dotenv").config({ path: path.resolve( process.cwd(), `.env.${process.env.NODE_ENV || "development"}` ), }); const { generateJobTier, generateOwnerTier, generateSourceTier } = QbXmlUtils; exports.default = async (req, res) => { const BearerToken = req.headers.authorization; const { payments: paymentsToQuery } = req.body; const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, { headers: { Authorization: BearerToken, }, }); try { const result = await client .setHeaders({ Authorization: BearerToken }) .request(queries.QUERY_PAYMENTS_FOR_EXPORT, { payments: paymentsToQuery, }); const { payments, bodyshops } = result; const bodyshop = bodyshops[0]; const isThreeTier = bodyshop.accountingconfig.tiers === 3; const twoTierPref = bodyshop.accountingconfig.twotierpref; const QbXmlToExecute = []; payments.map((i) => { if (isThreeTier) { QbXmlToExecute.push({ id: i.id, okStatusCodes: ["0", "3100"], qbxml: QbxmlReceivables.generateSourceCustomerQbxml(i.job, bodyshop), // Create the source customer. }); } QbXmlToExecute.push({ id: i.id, okStatusCodes: ["0", "3100"], qbxml: QbxmlReceivables.generateJobQbxml( i.job, bodyshop, isThreeTier, 2, twoTierPref ), }); QbXmlToExecute.push({ id: i.id, okStatusCodes: ["0", "3100"], qbxml: QbxmlReceivables.generateJobQbxml( i.job, bodyshop, isThreeTier, 3, twoTierPref ), }); QbXmlToExecute.push({ id: i.id, okStatusCodes: ["0"], qbxml: generatePayment(i, isThreeTier, twoTierPref), }); }); res.status(200).json(QbXmlToExecute); } catch (error) { console.log("error", error); res.status(400).send(JSON.stringify(error)); } }; const generatePayment = (payment, isThreeTier, twoTierPref) => { console.log("generatePayment -> payment", payment); let paymentQbxmlObj; if (payment.amount > 0) { paymentQbxmlObj = { QBXML: { QBXMLMsgsRq: { "@onError": "continueOnError", ReceivePaymentAddRq: { ReceivePaymentAdd: { CustomerRef: { FullName: payment.job.bodyshop.accountingconfig.tiers === 3 ? `${generateSourceTier(payment.job)}:${generateOwnerTier( payment.job, isThreeTier, twoTierPref )}:${generateJobTier(payment.job)}` : `${generateOwnerTier( payment.job, isThreeTier, twoTierPref )}:${generateJobTier(payment.job)}`, }, ARAccountRef: { FullName: payment.job.bodyshop.md_responsibility_centers.ar.accountname, }, TxnDate: moment(payment.date).format("YYYY-MM-DD"), //Trim String RefNumber: payment.paymentnum || payment.transactionid, TotalAmount: Dinero({ amount: Math.round(payment.amount * 100), }).toFormat(DineroQbFormat), PaymentMethodRef: { FullName: payment.type, }, Memo: `RO ${payment.job.ro_number || ""} OWNER ${ payment.job.ownr_fn || "" } ${payment.job.ownr_ln || ""} ${payment.job.ownr_co_nm || ""} ${ payment.stripeid || "" } ${payment.payer ? ` PAID BY ${payment.payer}` : ""}`, IsAutoApply: true, // AppliedToTxnAdd:{ // T // } }, }, }, }, }; } else { paymentQbxmlObj = { QBXML: { QBXMLMsgsRq: { "@onError": "continueOnError", CreditMemoAddRq: { CreditMemoAdd: { CustomerRef: { FullName: payment.job.bodyshop.accountingconfig.tiers === 3 ? `${generateSourceTier(payment.job)}:${generateOwnerTier( payment.job, isThreeTier, twoTierPref )}:${generateJobTier(payment.job)}` : `${generateOwnerTier( payment.job, isThreeTier, twoTierPref )}:${generateJobTier(payment.job)}`, }, ARAccountRef: { FullName: payment.job.bodyshop.md_responsibility_centers.ar.accountname, }, TxnDate: moment(payment.date).format("YYYY-MM-DD"), //Trim String RefNumber: payment.paymentnum || payment.stripeid || payment.transactionid, CreditMemoLineAdd: [ { ItemRef: { FullName: payment.job.bodyshop.md_responsibility_centers.refund .accountitem, }, Desc: payment.memo, Amount: Dinero({ amount: Math.round(payment.amount * 100 * -1), }).toFormat(DineroQbFormat), SalesTaxCodeRef: { FullName: "E" }, }, ], }, }, }, }, }; } var paymentQbxmlPartial = builder .create(paymentQbxmlObj, { version: "1.30", encoding: "UTF-8", headless: true, }) .end({ pretty: true }); const paymentQbxmlFull = QbXmlUtils.addQbxmlHeader(paymentQbxmlPartial); console.log("generateBill -> paymentQbxmlFull", paymentQbxmlFull); return paymentQbxmlFull; };