211 lines
6.3 KiB
JavaScript
211 lines
6.3 KiB
JavaScript
const path = require("path");
|
|
const DineroQbFormat = require("../accounting-constants").DineroQbFormat;
|
|
const queries = require("../../graphql-client/queries");
|
|
const Dinero = require("dinero.js");
|
|
const builder = require("xmlbuilder2");
|
|
const moment = require("moment-timezone");
|
|
const QbXmlUtils = require("./qbxml-utils");
|
|
const QbxmlReceivables = require("./qbxml-receivables");
|
|
const logger = require('../../utils/logger');
|
|
|
|
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 { payments: paymentsToQuery } = req.body;
|
|
|
|
const BearerToken = req.BearerToken;
|
|
const client = req.userGraphQLClient;
|
|
|
|
try {
|
|
logger.log(
|
|
"qbxml-payments-create",
|
|
"DEBUG",
|
|
req.user.email,
|
|
req.body.paymentsToQuery,
|
|
null
|
|
);
|
|
|
|
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, bodyshop),
|
|
});
|
|
});
|
|
|
|
res.status(200).json(QbXmlToExecute);
|
|
} catch (error) {
|
|
logger.log(
|
|
"qbxml-payments-error",
|
|
"error",
|
|
req.user.email,
|
|
req.body.paymentsToQuery,
|
|
{ error: error.message, stack: error.stack }
|
|
);
|
|
res.status(400).send(JSON.stringify(error));
|
|
}
|
|
};
|
|
|
|
const generatePayment = (payment, isThreeTier, twoTierPref, bodyshop) => {
|
|
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)}`
|
|
).trim(),
|
|
},
|
|
ARAccountRef: {
|
|
FullName:
|
|
payment.job.bodyshop.md_responsibility_centers.ar.accountname,
|
|
},
|
|
TxnDate: moment(payment.date)
|
|
// .tz(bodyshop.timezone)
|
|
.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,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
} 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)}`
|
|
).trim(),
|
|
},
|
|
ARAccountRef: {
|
|
FullName:
|
|
payment.job.bodyshop.md_responsibility_centers.ar.accountname,
|
|
},
|
|
TxnDate: moment(payment.date)
|
|
//.tz(bodyshop.timezone)
|
|
.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);
|
|
|
|
return paymentQbxmlFull;
|
|
};
|