172 lines
5.8 KiB
JavaScript
172 lines
5.8 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;
|
|
};
|