feat(loreal): vmi file can be sent over now

This commit is contained in:
2025-05-02 07:51:16 -05:00
parent 2921792c0a
commit a709be838f
3 changed files with 159 additions and 37 deletions

View File

@@ -1,3 +1,4 @@
import ForecastImport from "./ForecastImport";
import OrderImport from "./OrderImport";
import { useSettingStore } from "@/lib/store/useSettings";
@@ -20,6 +21,7 @@ export default function DMButtons() {
fileType={"energizer"}
name={"Energizer Truck List"}
/>
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usday1" && (
@@ -35,7 +37,9 @@ export default function DMButtons() {
</div>
)}
{plantToken[0]?.value === "usflo1" && (
<div className="flex flex-row gap-2"></div>
<div className="flex flex-row gap-2">
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usstp1" && (
<div className="flex flex-row gap-2"></div>

View File

@@ -21,7 +21,7 @@ export default function ForecastImport(props: any) {
formData.append("postForecast", e.target.files[0]);
formData.append("fileType", props.fileType); // extra field
// console.log(formData);
toast.success("Import started.");
try {
const response = await axios.post(
"/api/logistics/postforecastin",

View File

@@ -4,6 +4,9 @@ import { tryCatch } from "../../../../../../globalUtils/tryCatch.js";
import XLSX from "xlsx";
import { excelDateStuff } from "../../../../utils/excelDateStuff.js";
import { postForecast } from "../postForecast.js";
import { query } from "../../../../../sqlServer/prodSqlServer.js";
import { activeArticle } from "../../../../../sqlServer/querys/dataMart/article.js";
import { addDays } from "date-fns";
let customerID = 4;
export const lorealForecast = async (data: any, user: any) => {
@@ -31,59 +34,163 @@ export const lorealForecast = async (data: any, user: any) => {
const sheet: any = workbook.Sheets["Alpla HDPE"];
const range = XLSX.utils.decode_range(sheet["!ref"]);
const psheet: any = workbook.Sheets["Alpla PET"];
const prange = XLSX.utils.decode_range(psheet["!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 cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
const cell = sheet[cellAddress];
headers.push(cell ? cell.v : undefined);
}
const forecastData: any = XLSX.utils.sheet_to_json(sheet, {
const pheaders = [];
for (let C = prange.s.c; C <= prange.e.c; ++C) {
const cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
const cell = psheet[cellAddress];
pheaders.push(cell ? cell.v : undefined);
}
const ebmForeCastData: any = XLSX.utils.sheet_to_json(sheet, {
defval: "",
header: headers,
range: 2,
range: 3,
});
// Extract the customer code (assuming it's always present)
const customerCode = forecastData["NORTH HDPE BOTTLES"];
const petForeCastData: any = XLSX.utils.sheet_to_json(psheet, {
defval: "",
header: pheaders,
range: 3,
});
// Filter out non-date properties (these are your metadata fields)
const metadataFields = [
"NORTH HDPE BOTTLES",
"BLOCKED",
"INVENTORY",
"CALL-OFF",
"PALLET CONSUMPTION",
];
const ebmForecastData: any = [];
const missingSku: any = [];
const foreCastData: any = [];
const { data: a, error: ae } = await tryCatch(
query(activeArticle, "Loreal calling active av")
);
// process the forcast
forecastData.forEach((item: any, index: any) => {
//console.log(`Processing item ${index + 1} of ${forecastData.length}`);
if (ae) {
return {
success: false,
message: "Error getting active av",
data: [],
};
}
// Extract the customer code
const customerCode = item["NORTH HDPE BOTTLES"];
const article: any = a?.data;
// Process each date in the current object
for (const [date, qty] of Object.entries(item)) {
// Skip metadata fields
if (metadataFields.includes(date)) continue;
// process the ebm forcast
for (let i = 0; i < ebmForeCastData.length; i++) {
// bottle code
const sku = ebmForeCastData[i]["HDPE Bottle Code"];
if (qty === 0) continue;
// ignore the blanks
if (sku === "") continue;
// Create your transformed record
const record = {
customerArticleNo: customerCode,
requirementDate: excelDateStuff(parseInt(date)),
quantity: qty,
// ignore zero qty
// if (ebmForeCastData[i][`Day ${i}`]) continue;
for (let f = 0; f <= 90; f++) {
const day = `Day ${f + 1}`;
// if (ebmForeCastData[i][day] === 0) continue;
const forcast = {
customerArticleNo: sku,
requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
quantity: ebmForeCastData[i][day] ?? 0,
};
// Do something with this record
foreCastData.push(record);
}
});
if (forcast.quantity === 0) continue;
// checking to make sure there is a real av to add to.
const activeAV = article.filter(
(c: any) =>
c?.CustomerArticleNumber ===
forcast.customerArticleNo.toString()
);
if (activeAV.length === 0) {
continue;
}
ebmForecastData.push(forcast);
}
//console.log(ebmForeCastData.length);
}
// petForeCastData.forEach((item: any, index: any) => {
// //console.log(`Processing item ${index + 1} of ${forecastData.length}`);
// // Extract the customer code
// const customerCode = item["SOUTH PET BOTTLES"];
// // Process each date in the current object
// for (const [date, qty] of Object.entries(item)) {
// // Skip metadata fields
// if (petMetadataFields.includes(date)) continue;
// if (qty === 0) continue;
// // Create your transformed record
// const record = {
// customerArticleNo: customerCode,
// requirementDate: excelDateStuff(parseInt(date)),
// quantity: qty,
// };
// // Do something with this record
// petForecastData.push(record);
// }
// });
// pet forecast
for (let i = 0; i < petForeCastData.length; i++) {
// bottle code
const sku = petForeCastData[i]["South PET Bottle Code"];
// ignore the blanks
if (sku === "") continue;
// ignore zero qty
// if (ebmForeCastData[i][`Day ${i}`]) continue;
for (let f = 0; f <= 90; f++) {
const day = `Day ${f + 1}`;
// if (ebmForeCastData[i][day] === 0) continue;
const forcast = {
customerArticleNo: sku,
requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
quantity: petForeCastData[i][day] ?? 0,
};
if (forcast.quantity === 0 || forcast.quantity === "") continue;
if (forcast.customerArticleNo < 99999) {
//console.log(`Sku a normal av ${forcast.customerArticleNo}`);
continue;
}
// checking to make sure there is a real av to add to.
const activeAV = article.filter(
(c: any) =>
c?.CustomerArticleNumber ===
forcast.customerArticleNo.toString()
);
if (activeAV.length === 0) {
continue;
}
ebmForecastData.push(forcast);
}
}
//console.log(comForecast);
// if the customerarticle number is not matching just ignore it
const predefinedObject = {
receivingPlantId: plantToken[0].value,
documentName: `ForecastFromLST-${new Date(Date.now()).toLocaleString(
@@ -98,13 +205,24 @@ export const lorealForecast = async (data: any, user: any) => {
...predefinedObject,
positions: [
...predefinedObject.positions,
...foreCastData.filter((q: any) => q.customerArticleNo != ""),
...ebmForecastData,
// ...ebmForecastData.filter(
// (q: any) =>
// q.customerArticleNo != "" && q.customerArticleNo != "Total"
// ),
// ...petForecastData.filter(
// (q: any) =>
// q.customerArticleNo != "" && q.customerArticleNo != "Total"
// ),
],
};
// console.log(updatedPredefinedObject);
const posting: any = await postForecast(updatedPredefinedObject, user);
return {
success: posting.success,
message: posting.message,
data: posting.data,
data: posting.data === "" ? ebmForecastData : posting.data,
};
};