feat(forecast): migrated forecast over
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
import * as XLSX from "xlsx";
|
||||||
|
|
||||||
|
export const standardForCastTemplate = async () => {
|
||||||
|
/**
|
||||||
|
* Creates the standard Template for bulk orders in
|
||||||
|
*/
|
||||||
|
|
||||||
|
const headers = [
|
||||||
|
["CustomerArticleNumber", "Quantity", "RequirementDate", "CustomerID"],
|
||||||
|
];
|
||||||
|
|
||||||
|
// create a new workbook
|
||||||
|
const wb = XLSX.utils.book_new();
|
||||||
|
const ws = XLSX.utils.aoa_to_sheet(headers);
|
||||||
|
//const ws2 = XLSX.utils.aoa_to_sheet(headers2);
|
||||||
|
|
||||||
|
const columnWidths = headers[0].map((header) => ({
|
||||||
|
width: header.length + 2,
|
||||||
|
}));
|
||||||
|
|
||||||
|
ws["!cols"] = columnWidths;
|
||||||
|
|
||||||
|
// append the worksheet to the workbook
|
||||||
|
XLSX.utils.book_append_sheet(wb, ws, `Sheet1`);
|
||||||
|
//XLSX.utils.book_append_sheet(wb, ws2, `Sheet2`);
|
||||||
|
|
||||||
|
// Write the excel file and trigger the download'
|
||||||
|
XLSX.writeFile(wb, "BulkForecastTemplate");
|
||||||
|
|
||||||
|
// Write the workbook to a buffer and return it
|
||||||
|
const excelBuffer = XLSX.write(wb, { bookType: "xlsx", type: "buffer" });
|
||||||
|
|
||||||
|
return excelBuffer;
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { standardForecast } from "./mappings/standardForcast.js";
|
||||||
|
|
||||||
|
export const forecastIn = async (data: any, user: any) => {
|
||||||
|
/**
|
||||||
|
* Bulk orders in, and custom file parsing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
let success = true;
|
||||||
|
let message = "";
|
||||||
|
let orderData: any = [];
|
||||||
|
|
||||||
|
// what type of order are we dealing with?
|
||||||
|
if (data["fileType"] === "standard") {
|
||||||
|
//run the standard forecast in
|
||||||
|
const standard = await standardForecast(data["postPostForecast"], user);
|
||||||
|
success = standard.success ?? false;
|
||||||
|
message = standard.message ?? "Error posting standard forecast";
|
||||||
|
orderData = standard.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data["fileType"] === "energizer") {
|
||||||
|
// orders in
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data["fileType"] === "loreal") {
|
||||||
|
// orders in
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data["fileType"] === "pg") {
|
||||||
|
// orders in
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success,
|
||||||
|
message,
|
||||||
|
data: orderData,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export const standardForecast = async (data: any, user: any) => {
|
||||||
|
/**
|
||||||
|
* Post a standard forecast based on the standard template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Forecast Posted",
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import { prodEndpointCreation } from "../../../../../globalUtils/createUrl.js";
|
||||||
|
import { createLog } from "../../../../logger/logger.js";
|
||||||
|
|
||||||
|
export const postForecast = async (data: any, user: any) => {
|
||||||
|
let endpoint = await prodEndpointCreation(
|
||||||
|
"/public/v1.0/DemandManagement/DELFOR"
|
||||||
|
);
|
||||||
|
|
||||||
|
//console.log(endpoint);
|
||||||
|
//console.log(req.body.orders[0]);
|
||||||
|
try {
|
||||||
|
const results = await axios({
|
||||||
|
url: endpoint,
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Basic ${user.prod}`,
|
||||||
|
},
|
||||||
|
// if a body is sent over it would be like below
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
//console.log(results.data);
|
||||||
|
//console.log(results.status);
|
||||||
|
if (results.data.errors) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"forecast",
|
||||||
|
"logistics",
|
||||||
|
`There was an error posting the Forecast: ${JSON.stringify(
|
||||||
|
results.data.errors
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Error processing forecast",
|
||||||
|
data: results.data.errors[0].message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.status === 200) {
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"forecast",
|
||||||
|
"logistics",
|
||||||
|
`Forcast was successfully posted: ${JSON.stringify(
|
||||||
|
results.data
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Success on posting forecast",
|
||||||
|
data: results.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
//console.log(`There is an error`, error);
|
||||||
|
if (error) {
|
||||||
|
//console.log(error.response.data);
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"forecast",
|
||||||
|
"logistics",
|
||||||
|
`There was an error posting the Forecast: ${JSON.stringify(
|
||||||
|
error.response.data
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "There was an error posting the Forecast",
|
||||||
|
data: error.response.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -13,6 +13,8 @@ import getPPOO from "./route/getPPOO.js";
|
|||||||
import getcyclecount from "./route/getCycleCountLanes.js";
|
import getcyclecount from "./route/getCycleCountLanes.js";
|
||||||
import postBulkOrders from "./route/dm/bulkOrdersIn.js";
|
import postBulkOrders from "./route/dm/bulkOrdersIn.js";
|
||||||
import standardTemplate from "./route/dm/getStandardTemplate.js";
|
import standardTemplate from "./route/dm/getStandardTemplate.js";
|
||||||
|
import standardForcasttemplate from "./route/dm/getStandardForecastTemplate.js";
|
||||||
|
import postForecast from "./route/dm/forecastIn.js";
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -33,6 +35,8 @@ const routes = [
|
|||||||
//DM
|
//DM
|
||||||
postBulkOrders,
|
postBulkOrders,
|
||||||
standardTemplate,
|
standardTemplate,
|
||||||
|
postForecast,
|
||||||
|
standardForcasttemplate,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
// app.route("/server", modules);
|
// app.route("/server", modules);
|
||||||
|
|||||||
74
server/services/logistics/route/dm/forecastIn.ts
Normal file
74
server/services/logistics/route/dm/forecastIn.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { ordersIn } from "../../controller/dm/ordersIn/ordersIn.js";
|
||||||
|
import { verify } from "hono/jwt";
|
||||||
|
import { forecastIn } from "../../controller/dm/forecast/forecastIn.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
// const Body = z
|
||||||
|
// .object({
|
||||||
|
// age: z.number().optional().openapi({ example: 90 }),
|
||||||
|
// //email: z.string().optional().openapi({example: "s.smith@example.com"}),
|
||||||
|
// type: z.string().optional().openapi({ example: "fg" }),
|
||||||
|
// })
|
||||||
|
// .openapi("User");
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["logistics"],
|
||||||
|
summary: "Post forecast to DM",
|
||||||
|
method: "post",
|
||||||
|
path: "/postforecastin",
|
||||||
|
// request: {
|
||||||
|
// body: {
|
||||||
|
// content: {
|
||||||
|
// "application/json": { schema: Body },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// description:
|
||||||
|
// "Provided a running number and lot number you can consume material.",
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
//apiHit(c, { endpoint: "api/sqlProd/close" });
|
||||||
|
const body = await c.req.parseBody();
|
||||||
|
const authHeader = c.req.header("Authorization");
|
||||||
|
const token = authHeader?.split("Bearer ")[1] || "";
|
||||||
|
//console.log(body); // File | string
|
||||||
|
|
||||||
|
// if (body["fileType"] === "standard") {
|
||||||
|
// console.log(`doing standard orders in.`);
|
||||||
|
// }
|
||||||
|
const { data: payload, error: pe } = await tryCatch(
|
||||||
|
verify(token, process.env.JWT_SECRET!)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pe) {
|
||||||
|
return c.json({ success: false, message: "Unauthorized" }, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: orders, error } = await tryCatch(
|
||||||
|
forecastIn(body, payload.user)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return c.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error posting forecast",
|
||||||
|
data: error,
|
||||||
|
},
|
||||||
|
400
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
success: orders?.success ?? false,
|
||||||
|
message: orders?.message ?? "Error posting forecast",
|
||||||
|
data: orders?.data ?? [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { standardTemplate } from "../../controller/dm/ordersIn/createTemplate.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { standardForCastTemplate } from "../../controller/dm/forecast/createTemplate.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
// const Body = z
|
||||||
|
// .object({
|
||||||
|
// age: z.number().optional().openapi({ example: 90 }),
|
||||||
|
// //email: z.string().optional().openapi({example: "s.smith@example.com"}),
|
||||||
|
// type: z.string().optional().openapi({ example: "fg" }),
|
||||||
|
// })
|
||||||
|
// .openapi("User");
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["logistics"],
|
||||||
|
summary: "Gets the standard Forecast Template",
|
||||||
|
method: "get",
|
||||||
|
path: "/bulkforcasttemplate",
|
||||||
|
// request: {
|
||||||
|
// body: {
|
||||||
|
// content: {
|
||||||
|
// "application/json": { schema: Body },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// description:
|
||||||
|
// "Provided a running number and lot number you can consume material.",
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c: any) => {
|
||||||
|
//apiHit(c, { endpoint: "api/sqlProd/close" });
|
||||||
|
const defaultFilename = `bulkForcastTemplate-${format(
|
||||||
|
new Date(Date.now()),
|
||||||
|
"M-d-yyyy"
|
||||||
|
)}.xlsx`;
|
||||||
|
const filename = c.req.query("filename") || defaultFilename;
|
||||||
|
const { data, error } = await tryCatch(standardForCastTemplate());
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error creating template",
|
||||||
|
data: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(data, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type":
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
"Content-Disposition": `attachment; filename="${filename}"`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// return c.json({
|
||||||
|
// success: data.success,
|
||||||
|
// message: data.message,
|
||||||
|
// data: data.data,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
Reference in New Issue
Block a user