139 lines
4.5 KiB
JavaScript
139 lines
4.5 KiB
JavaScript
const path = require("path");
|
|
require("dotenv").config({
|
|
path: path.resolve(
|
|
process.cwd(),
|
|
`.env.${process.env.NODE_ENV || "development"}`
|
|
),
|
|
});
|
|
const GraphQLClient = require("graphql-request").GraphQLClient;
|
|
|
|
const queries = require("../../graphql-client/queries");
|
|
const CdkBase = require("../../web-sockets/web-socket");
|
|
const moment = require("moment");
|
|
const Dinero = require("dinero.js");
|
|
|
|
exports.default = async function (socket, billids) {
|
|
try {
|
|
CdkBase.createLogEvent(
|
|
socket,
|
|
"DEBUG",
|
|
`Received request to calculate allocations for ${billids}`
|
|
);
|
|
const { bills, bodyshops } = await QueryBillData(socket, billids);
|
|
const bodyshop = bodyshops[0];
|
|
const transactionLines = [];
|
|
|
|
bills.forEach((bill) => {
|
|
//Keep the allocations at the bill level.
|
|
const billHash = {
|
|
[bodyshop.md_responsibility_centers.taxes.federal_itc.name]: {
|
|
Account:
|
|
bodyshop.md_responsibility_centers.taxes.federal_itc.dms_acctnumber,
|
|
//ControlNumber: "String", //need to figure this out still?
|
|
Amount: Dinero(),
|
|
// Comment: "String",
|
|
//AdditionalInfo: "String",
|
|
InvoiceNumber: bill.invoice_number,
|
|
InvoiceDate: moment(bill.date).tz(bodyshop.timezone).toISOString(),
|
|
},
|
|
[bodyshop.md_responsibility_centers.taxes.state.name]: {
|
|
Account:
|
|
bodyshop.md_responsibility_centers.taxes.state.dms_acctnumber,
|
|
//ControlNumber: "String", //need to figure this out still?
|
|
Amount: Dinero(),
|
|
// Comment: "String",
|
|
//AdditionalInfo: "String",
|
|
InvoiceNumber: bill.invoice_number,
|
|
InvoiceDate: moment(bill.date).tz(bodyshop.timezone).toISOString(),
|
|
},
|
|
};
|
|
|
|
bill.billlines.forEach((bl) => {
|
|
let lineDinero = Dinero({
|
|
amount: Math.round((bl.actual_cost || 0) * 100),
|
|
})
|
|
.multiply(bl.quantity)
|
|
.multiply(bill.is_credit_memo ? -1 : 1);
|
|
const cc = getCostAccount(bl, bodyshop.md_responsibility_centers);
|
|
|
|
if (!billHash[cc.name]) {
|
|
billHash[cc.name] = {
|
|
Account: cc.dms_acctnumber,
|
|
//ControlNumber: "String", //need to figure this out still?
|
|
Amount: Dinero(),
|
|
// Comment: "String",
|
|
//AdditionalInfo: "String",
|
|
InvoiceNumber: bill.invoice_number,
|
|
InvoiceDate: moment(bill.date).tz(bodyshop.timezone).toISOString(),
|
|
};
|
|
}
|
|
|
|
//Add the line amount.
|
|
|
|
billHash[cc.name] = {
|
|
...billHash[cc.name],
|
|
Amount: billHash[cc.name].Amount.add(lineDinero),
|
|
};
|
|
|
|
//Does the line have taxes?
|
|
if (bl.applicable_taxes.federal) {
|
|
billHash[bodyshop.md_responsibility_centers.taxes.federal_itc.name] =
|
|
{
|
|
...bodyshop.md_responsibility_centers.taxes.federal_itc.name,
|
|
Amount: billHash[
|
|
bodyshop.md_responsibility_centers.taxes.federal_itc.name
|
|
].Amount.add(lineDinero.percentage(bl.federal_tax_rate || 0)),
|
|
};
|
|
}
|
|
if (bl.applicable_taxes.state) {
|
|
billHash[bodyshop.md_responsibility_centers.taxes.state.name] = {
|
|
...bodyshop.md_responsibility_centers.taxes.state.name,
|
|
Amount: billHash[
|
|
bodyshop.md_responsibility_centers.taxes.state.name
|
|
].Amount.add(lineDinero.percentage(bl.state_tax_rate || 0)),
|
|
};
|
|
}
|
|
});
|
|
|
|
Object.keys(billHash).map((key) => {
|
|
transactionLines.push(billHash[key]);
|
|
});
|
|
});
|
|
|
|
return transactionLines;
|
|
} catch (error) {
|
|
CdkBase.createLogEvent(
|
|
socket,
|
|
"ERROR",
|
|
`Error encountered in CdkCalculateAllocations. ${error}`
|
|
);
|
|
}
|
|
};
|
|
|
|
async function QueryBillData(socket, billids) {
|
|
CdkBase.createLogEvent(
|
|
socket,
|
|
"DEBUG",
|
|
`Querying bill data for id(s) ${billids}`
|
|
);
|
|
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
|
const result = await client
|
|
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
|
.request(queries.GET_PBS_AP_ALLOCATIONS, { billids: billids });
|
|
CdkBase.createLogEvent(
|
|
socket,
|
|
"TRACE",
|
|
`Bill data query result ${JSON.stringify(result, null, 2)}`
|
|
);
|
|
return result;
|
|
}
|
|
|
|
//@returns the account object.
|
|
function getCostAccount(billline, respcenters) {
|
|
if (!billline.cost_center) return null;
|
|
|
|
const acctName = respcenters.defaults.costs[billline.cost_center];
|
|
|
|
return respcenters.costs.find((c) => c.name === acctName);
|
|
}
|