All checks were successful
Build and Push LST Docker Image / docker (push) Successful in 4m26s
259 lines
6.7 KiB
TypeScript
259 lines
6.7 KiB
TypeScript
import * as XLSX from "xlsx";
|
|
import { runDatamartQuery } from "../datamart/datamart.controller.js";
|
|
import { db } from "../db/db.controller.js";
|
|
import { excelDateStuff } from "../utils/excelToDate.utils.js";
|
|
import { returnFunc } from "../utils/returnHelper.utils.js";
|
|
import { tryCatch } from "../utils/trycatch.utils.js";
|
|
import { postData } from "./logistics.dm.postData.js";
|
|
export const standardOrders = async (data: any, user: any) => {
|
|
/**
|
|
* Post a standard forecast based on the standard template.
|
|
*/
|
|
|
|
const plantToken = process.env.PROD_PLANT_TOKEN;
|
|
|
|
/*
|
|
get the order state.
|
|
*/
|
|
|
|
const { data: o, error: oe } = await tryCatch(
|
|
runDatamartQuery({ name: "orderState", options: {} }),
|
|
);
|
|
|
|
if (oe) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "logistics",
|
|
subModule: "orders",
|
|
message: `Error getting Article info`,
|
|
data: [oe.message],
|
|
notify: true,
|
|
});
|
|
}
|
|
|
|
const openOrders: any = o?.data;
|
|
|
|
/*
|
|
get default invoice address
|
|
*/
|
|
const { data: invoice, error: ie } = await tryCatch(
|
|
runDatamartQuery({ name: "invoiceAddress", options: {} }),
|
|
);
|
|
|
|
if (ie) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "logistics",
|
|
subModule: "orders",
|
|
message: `Error getting Article info`,
|
|
data: [ie.message],
|
|
notify: true,
|
|
});
|
|
}
|
|
|
|
const i: any = invoice?.data;
|
|
|
|
//const arrayBuffer = await data.arrayBuffer();
|
|
const buffer = Buffer.from(data.buffer);
|
|
|
|
const workbook = XLSX.read(buffer, { type: "buffer" });
|
|
|
|
const sheetName = workbook.SheetNames[0] as string;
|
|
const sheet = workbook.Sheets[sheetName] as any;
|
|
|
|
// define custom headers
|
|
const headers = [
|
|
"CustomerArticleNumber",
|
|
"CustomerOrderNumber",
|
|
"CustomerLineNumber",
|
|
"CustomerRealeaseNumber",
|
|
"Quantity",
|
|
"DeliveryDate",
|
|
"CustomerID",
|
|
"Remark",
|
|
];
|
|
|
|
const orderData = XLSX.utils.sheet_to_json(sheet, {
|
|
defval: "",
|
|
header: headers,
|
|
range: 1,
|
|
});
|
|
|
|
// the base of the import
|
|
const predefinedObject = {
|
|
receivingPlantId: plantToken ?? "test1",
|
|
documentName: `OrdersFromLST-${new Date(Date.now()).toLocaleString(
|
|
"en-US",
|
|
)}`,
|
|
sender: user.username || "lst-system",
|
|
externalRefNo: `OrdersFromLST-${new Date(Date.now()).toLocaleString(
|
|
"en-US",
|
|
)}`,
|
|
orders: [],
|
|
};
|
|
|
|
// for orders that are in od or managed by od we want to make sure we send out an email on this so we dont over right data that could be already planned with a carrier.
|
|
const odOrders: any = [];
|
|
const okToUpdateOrders: any = [];
|
|
|
|
for (const order of openOrders) {
|
|
if (order.AdditionalInformation1?.includes("od")) {
|
|
odOrders.push(order);
|
|
} else {
|
|
okToUpdateOrders.push(order);
|
|
}
|
|
}
|
|
|
|
if (odOrders.length > 0) {
|
|
console.log("send email for od touched orders", odOrders);
|
|
}
|
|
|
|
if (okToUpdateOrders.length === 0) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "logistics",
|
|
subModule: "orders",
|
|
message: `All orders have been posted to od and releases will not be updated`,
|
|
data: [],
|
|
notify: false,
|
|
});
|
|
}
|
|
|
|
const groupedByCustomer: any = orderData.reduce((acc: any, item: any) => {
|
|
const id = item.CustomerID;
|
|
if (!acc[id]) {
|
|
acc[id] = [];
|
|
}
|
|
acc[id].push(item);
|
|
return acc;
|
|
}, {});
|
|
|
|
const postedOrders: any = [];
|
|
|
|
for (const [customerID, orders] of Object.entries(groupedByCustomer)) {
|
|
// console.log(`Running for Customer ID: ${customerID}`);
|
|
const filterOrders: any = orders;
|
|
const newOrders: any = [];
|
|
//newOrders.filter((oo) => openOrders.some((o) => String(o.CustomerOrderNumber) === String(oo.CustomerOrderNumber)));
|
|
//console.log(newOrders)
|
|
filterOrders.forEach((oo: any) => {
|
|
const isMatch = okToUpdateOrders.some(
|
|
(o: any) =>
|
|
// check the header
|
|
String(o.CustomerOrderNumber).trim() ===
|
|
String(oo.CustomerOrderNumber).trim() &&
|
|
// and check the customer release is not in here.
|
|
String(o.CustomerRealeaseNumber).trim() ===
|
|
String(oo.CustomerRealeaseNumber).trim(),
|
|
);
|
|
if (!isMatch) {
|
|
//console.log(`ok to update: ${oo.CustomerOrderNumber}`);
|
|
|
|
newOrders.push(oo);
|
|
} else {
|
|
//console.log(`Not valid order to update: ${oo.CustomerOrderNumber}`);
|
|
//console.log(oo)
|
|
}
|
|
});
|
|
|
|
// filter out the orders that have already been started just to reduce the risk of errors.
|
|
newOrders.filter((oo: any) =>
|
|
openOrders.some(
|
|
(o: any) => o.CustomerOrderNumber === oo.CustomerOrderNumber,
|
|
),
|
|
);
|
|
|
|
// get the default time to put in here if an order dose not include the date
|
|
const { data: s, error } = await tryCatch(
|
|
db.query.settings.findFirst({
|
|
where: (setting, { eq }) => eq(setting.name, "defaultOrderTime"),
|
|
}),
|
|
);
|
|
|
|
if (error) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "utils",
|
|
subModule: "excelToDate",
|
|
message: "Failed to get the default order time setting.",
|
|
data: [],
|
|
notify: false,
|
|
});
|
|
}
|
|
|
|
const hour = parseInt(s?.value ?? "8", 10);
|
|
|
|
const defaultOrderTime =
|
|
Number.isNaN(hour) || hour < 1 || hour > 23 ? 800 : hour * 100;
|
|
|
|
// map everything out for each order
|
|
const nOrder = newOrders.map((o: any) => {
|
|
const invoice = i.find(
|
|
(inv: any) => inv.deliveryAddress === parseInt(customerID),
|
|
);
|
|
if (!invoice) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "logistics",
|
|
subModule: "orders",
|
|
message: `No invoice address found for ${customerID}`,
|
|
data: [],
|
|
notify: true,
|
|
});
|
|
}
|
|
return {
|
|
customerId: parseInt(customerID),
|
|
invoiceAddressId: invoice.invoiceAddress, // matched to the default invoice address
|
|
customerOrderNo: o.CustomerOrderNumber,
|
|
orderDate: new Date(Date.now()).toLocaleString("en-US"),
|
|
positions: [
|
|
{
|
|
deliveryAddressId: parseInt(customerID),
|
|
customerArticleNo: o.CustomerArticleNumber,
|
|
quantity: parseInt(o.Quantity),
|
|
deliveryDate: excelDateStuff(o.DeliveryDate, defaultOrderTime),
|
|
customerLineItemNo: o.CustomerLineNumber, // this is how it is currently sent over from abbott
|
|
customerReleaseNo: o.CustomerRealeaseNumber, // same as above
|
|
remark: o.Remark === "" ? null : o.Remark,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
// do that fun combining thing
|
|
const updatedPredefinedObject = {
|
|
...predefinedObject,
|
|
orders: [...predefinedObject.orders, ...nOrder],
|
|
};
|
|
|
|
// post the orders to the server
|
|
const posting: any = await postData(
|
|
{
|
|
type: "orders",
|
|
endpoint: "/public/v1.0/DemandManagement/ORDERS",
|
|
data: updatedPredefinedObject as any,
|
|
},
|
|
user,
|
|
);
|
|
|
|
postedOrders.push({
|
|
customer: customerID,
|
|
//totalOrders: orders?.length(),
|
|
success: posting.success,
|
|
message: posting.message,
|
|
data: posting.data,
|
|
});
|
|
}
|
|
|
|
return {
|
|
success: postedOrders[0].success,
|
|
message: postedOrders[0].message,
|
|
data: postedOrders,
|
|
};
|
|
};
|