Some checks failed
Build and Push LST Docker Image / docker (push) Failing after 40s
the test server wouldnt do the backup so waiting on this one
183 lines
4.6 KiB
TypeScript
183 lines
4.6 KiB
TypeScript
import XLSX from "xlsx";
|
|
import { runDatamartQuery } from "../datamart/datamart.controller.js";
|
|
import { db } from "../db/db.controller.js";
|
|
import { settings } from "../db/schema/settings.schema.js";
|
|
import {
|
|
type SqlQuery,
|
|
sqlQuerySelector,
|
|
} from "../prodSql/prodSqlQuerySelector.utils.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 pNgForecast = async (data: any, user: any) => {
|
|
/**
|
|
* Post a standard forecast based on the standard template.
|
|
*/
|
|
|
|
const { data: s, error: e } = await tryCatch(db.select().from(settings));
|
|
|
|
if (e) {
|
|
return {
|
|
sucess: false,
|
|
message: `Error getting settings`,
|
|
data: e,
|
|
};
|
|
}
|
|
|
|
const pNg = s.filter((n: any) => n.name === "pNgAddress");
|
|
|
|
const avSQLQuery = sqlQuerySelector(`datamart.activeArticles`) as SqlQuery;
|
|
|
|
if (!avSQLQuery.success) {
|
|
return returnFunc({
|
|
success: false,
|
|
level: "error",
|
|
module: "logistics",
|
|
subModule: "forecast",
|
|
message: `Error getting Article info`,
|
|
data: [avSQLQuery.message],
|
|
notify: true,
|
|
});
|
|
}
|
|
|
|
const { data: a, error: ae } = await tryCatch(
|
|
runDatamartQuery({ name: "activeArticles", options: {} }),
|
|
);
|
|
|
|
if (ae) {
|
|
return {
|
|
success: false,
|
|
message: "Error getting active av",
|
|
data: [],
|
|
};
|
|
}
|
|
|
|
const article: any = a?.data;
|
|
|
|
const buffer = Buffer.from(data.buffer);
|
|
|
|
const workbook = XLSX.read(buffer, { type: "buffer" });
|
|
|
|
//const sheet: any = workbook.Sheets[sheetName];
|
|
const sheet: any = workbook.Sheets["SchedAgreementUIConfigSpreadshe"];
|
|
const range = XLSX.utils.decode_range(sheet["!ref"]);
|
|
|
|
const headers = [];
|
|
for (let C = range.s.c; C <= range.e.c; ++C) {
|
|
const cellAddress = XLSX.utils.encode_cell({ r: 0, c: C }); // row 0 = Excel row 1
|
|
const cell = sheet[cellAddress];
|
|
headers.push(cell ? cell.v : undefined);
|
|
}
|
|
|
|
//console.log(headers);
|
|
const forecastData: any = XLSX.utils.sheet_to_json(sheet, {
|
|
defval: "",
|
|
header: headers,
|
|
range: 1,
|
|
});
|
|
|
|
const groupedByCustomer: any = forecastData.reduce((acc: any, item: any) => {
|
|
const id = item.CustomerID;
|
|
if (!acc[id]) {
|
|
acc[id] = [];
|
|
}
|
|
acc[id].push(item);
|
|
return acc;
|
|
}, {});
|
|
|
|
const foreCastData: any = [];
|
|
|
|
for (const [customerID, forecast] of Object.entries(groupedByCustomer)) {
|
|
//console.log(`Running for Customer ID: ${customerID}`);
|
|
const newForecast: any = forecast;
|
|
|
|
const predefinedObject = {
|
|
receivingPlantId: process.env.PROD_PLANT_TOKEN ?? "test1",
|
|
documentName: `ForecastFromLST-${new Date(Date.now()).toLocaleString(
|
|
"en-US",
|
|
)}`,
|
|
sender: user.username || "lst-system",
|
|
customerId: pNg[0]?.value,
|
|
positions: [],
|
|
};
|
|
|
|
// map everything out for each order
|
|
const nForecast = newForecast.map((o: any) => {
|
|
// const invoice = i.filter(
|
|
// (i: any) => i.deliveryAddress === parseInt(customerID)
|
|
// );
|
|
// if (!invoice) {
|
|
// return;
|
|
// }
|
|
|
|
return {
|
|
customerArticleNo: parseInt(o["Customer Item No."]),
|
|
requirementDate: excelDateStuff(parseInt(o["Request Date"])),
|
|
quantity: o["Remaining Qty to be Shipped"],
|
|
};
|
|
});
|
|
|
|
// check to make sure the av belongs in this plant.
|
|
const onlyNumbers = nForecast.filter((n: any) => n.quantity > 0);
|
|
const filteredForecast: any = [];
|
|
|
|
for (let i = 0; i < nForecast.length; i++) {
|
|
//console.log(nForecast[i].customerArticleNo);
|
|
const activeAV = article.filter(
|
|
(c: any) =>
|
|
c?.CustomerArticleNumber ===
|
|
nForecast[i]?.customerArticleNo.toString() &&
|
|
// validate it works via the default address
|
|
c?.IdAdresse === parseInt(pNg[0]?.value ?? "139", 10),
|
|
);
|
|
|
|
if (activeAV.length > 0) {
|
|
filteredForecast.push(onlyNumbers[i]);
|
|
}
|
|
}
|
|
|
|
if (filteredForecast.length === 0) {
|
|
console.log("Nothing to post");
|
|
return {
|
|
success: true,
|
|
message: "No forecast to be posted",
|
|
data: foreCastData,
|
|
};
|
|
}
|
|
|
|
// do that fun combining thing
|
|
const updatedPredefinedObject = {
|
|
...predefinedObject,
|
|
positions: [...predefinedObject.positions, ...filteredForecast],
|
|
};
|
|
|
|
//console.log(updatedPredefinedObject);
|
|
|
|
// post the orders to the server
|
|
const posting: any = await postData(
|
|
{
|
|
type: "forecast",
|
|
endpoint: "/public/v1.0/DemandManagement/DELFOR",
|
|
data: updatedPredefinedObject as any,
|
|
},
|
|
user,
|
|
);
|
|
|
|
foreCastData.push({
|
|
customer: customerID,
|
|
//totalOrders: orders?.length(),
|
|
success: posting.success,
|
|
message: posting.message,
|
|
data: posting.data,
|
|
});
|
|
}
|
|
|
|
return {
|
|
success: foreCastData[0].success,
|
|
message: foreCastData[0].message,
|
|
data: foreCastData,
|
|
};
|
|
};
|