feat(app): order schdeuler
This commit is contained in:
11
app/main.ts
11
app/main.ts
@@ -19,10 +19,13 @@ import { sendNotify } from "./src/pkg/utils/notify.js";
|
|||||||
import { toNodeHandler } from "better-auth/node";
|
import { toNodeHandler } from "better-auth/node";
|
||||||
import { auth } from "./src/pkg/auth/auth.js";
|
import { auth } from "./src/pkg/auth/auth.js";
|
||||||
import { apiHitMiddleware } from "./src/pkg/middleware/apiHits.js";
|
import { apiHitMiddleware } from "./src/pkg/middleware/apiHits.js";
|
||||||
|
import { setupIoServer } from "./src/ws/server.js";
|
||||||
|
import { schedulerManager } from "./src/internal/logistics/controller/schedulerManager.js";
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const env = validateEnv(process.env);
|
const env = validateEnv(process.env);
|
||||||
const PORT = Number(env.VITE_PORT) || 4200;
|
const PORT = Number(env.VITE_PORT) || 4200;
|
||||||
|
|
||||||
//create the logger
|
//create the logger
|
||||||
const log = createLogger({ module: "system", subModule: "main start" });
|
const log = createLogger({ module: "system", subModule: "main start" });
|
||||||
|
|
||||||
@@ -130,16 +133,18 @@ const main = async () => {
|
|||||||
express.static(join(__dirname, "../frontend/dist"))
|
express.static(join(__dirname, "../frontend/dist"))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// server setup
|
||||||
|
const server = createServer(app);
|
||||||
|
|
||||||
// register app
|
// register app
|
||||||
setupRoutes(app, basePath);
|
setupRoutes(app, basePath);
|
||||||
|
|
||||||
// ws stuff
|
// ws stuff
|
||||||
|
setupIoServer(server, basePath);
|
||||||
// ws + server stuff
|
|
||||||
const server = createServer(app);
|
|
||||||
|
|
||||||
// sub systems
|
// sub systems
|
||||||
printers();
|
printers();
|
||||||
|
schedulerManager();
|
||||||
|
|
||||||
// start the server up
|
// start the server up
|
||||||
server.listen(PORT, "0.0.0.0", () =>
|
server.listen(PORT, "0.0.0.0", () =>
|
||||||
|
|||||||
122
app/src/internal/logistics/controller/schedulerManager.ts
Normal file
122
app/src/internal/logistics/controller/schedulerManager.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import { subMinutes } from "date-fns";
|
||||||
|
import { format, formatInTimeZone } from "date-fns-tz";
|
||||||
|
import { sql } from "drizzle-orm";
|
||||||
|
import { db } from "../../../pkg/db/db.js";
|
||||||
|
import {
|
||||||
|
type OrderScheduler,
|
||||||
|
orderScheduler,
|
||||||
|
} from "../../../pkg/db/schema/orderScheduler.js";
|
||||||
|
import { createLogger } from "../../../pkg/logger/logger.js";
|
||||||
|
import { prodQuery } from "../../../pkg/prodSql/prodQuery.js";
|
||||||
|
import { scheduler } from "../../../pkg/prodSql/querys/scheduler/scheduler.js";
|
||||||
|
import { tryCatch } from "../../../pkg/utils/tryCatch.js";
|
||||||
|
|
||||||
|
/*
|
||||||
|
will monitor the incoming goods and the orders and update lst as they change or get updated.
|
||||||
|
*/
|
||||||
|
export const schedulerManager = async () => {
|
||||||
|
const log = createLogger({
|
||||||
|
module: "logistics",
|
||||||
|
subModule: "scheduleManager",
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info({}, "Starting the scheduler manager up.");
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
const targetTimeZone = "America/New_York";
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// console.log(formatInTimeZone(now, targetTimeZone, "yyyy-M-d HH:mm"));
|
||||||
|
// console.log(format(now, "yyyy-M-d HH:mm"));
|
||||||
|
const { data, error } = (await tryCatch(
|
||||||
|
prodQuery(
|
||||||
|
scheduler.replace(
|
||||||
|
"[dateCheck]",
|
||||||
|
formatInTimeZone(
|
||||||
|
subMinutes(now, 1), // dealing with the 1 min difference in case we have something missed.
|
||||||
|
targetTimeZone,
|
||||||
|
"yyyy-M-d HH:mm",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"scheduler",
|
||||||
|
),
|
||||||
|
)) as any;
|
||||||
|
// do the updates to the db so we can pull the info up to the frontend
|
||||||
|
if (error) {
|
||||||
|
log.error({ error: error }, "there was an error getting the data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const orderData = data.data || ([] as OrderScheduler);
|
||||||
|
//console.log(data);
|
||||||
|
|
||||||
|
if (orderData.length === 0) {
|
||||||
|
log.info({}, "There are no new orders or incoming to be updated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < orderData.length; i++) {
|
||||||
|
const { data, error } = await tryCatch(
|
||||||
|
db
|
||||||
|
.insert(orderScheduler)
|
||||||
|
.values({
|
||||||
|
av: orderData[i].av,
|
||||||
|
description: orderData[i].description,
|
||||||
|
orderType: orderData[i].type, //orders || incoming
|
||||||
|
orderNumber: orderData[i].orderNumber,
|
||||||
|
header: orderData[i].av,
|
||||||
|
lineItemNumber: orderData[i].lineItemNumber,
|
||||||
|
customerReleaseNumber: orderData[i].customerReleaseNumber,
|
||||||
|
deliveryDate: new Date(orderData[i].deliveryDate),
|
||||||
|
loadingDate: new Date(orderData[i].loadingDate),
|
||||||
|
orderQTY: orderData[i].orderQTY,
|
||||||
|
orderLu: orderData[i].orderLu,
|
||||||
|
deliveredQTY: orderData[i].deliveredQTY,
|
||||||
|
deliveredLu: orderData[i].deliveredLu,
|
||||||
|
remark: orderData[i].remark,
|
||||||
|
createdAsEDI: orderData[i].createdAsEDI,
|
||||||
|
currentState: orderData[i].currentState,
|
||||||
|
lstDateCheck: new Date(orderData[i].deliveryDate), //this will match the delivery date to start
|
||||||
|
customerAddressId: orderData[i].customerAddressId,
|
||||||
|
customerDescription: orderData[i].customerDescription,
|
||||||
|
orderFrom: "prod", // manual or prod.
|
||||||
|
// being edited change to true so it will essential lock all others from editing
|
||||||
|
// carrier
|
||||||
|
// carrier email. -- when dropped we can email the carrier this could be considered there confirmation.
|
||||||
|
addDate: sql`NOW()`,
|
||||||
|
updDate: sql`NOW()`,
|
||||||
|
})
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: orderScheduler.orderNumber,
|
||||||
|
set: {
|
||||||
|
deliveryDate: new Date(orderData[i].deliveryDate),
|
||||||
|
loadingDate: new Date(orderData[i].loadingDate),
|
||||||
|
orderQTY: orderData[i].orderQTY,
|
||||||
|
orderLu: orderData[i].orderLu,
|
||||||
|
remark: orderData[i].remark,
|
||||||
|
currentState: orderData[i].currentState,
|
||||||
|
deliveredQTY: orderData[i].deliveredQTY,
|
||||||
|
deliveredLu: orderData[i].deliveredLu,
|
||||||
|
lstDateCheck: new Date(orderData[i].deliveryDate),
|
||||||
|
updDate: sql`NOW()`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.log(error);
|
||||||
|
log.error(
|
||||||
|
{ error: error },
|
||||||
|
`There was an error inserting/updating the order ${orderData[i].orderNumber}`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
{ data: data },
|
||||||
|
`${orderData[i].orderNumber} was inserted or updated`,
|
||||||
|
);
|
||||||
|
|
||||||
|
//await delay
|
||||||
|
}
|
||||||
|
}, 60 * 1000);
|
||||||
|
};
|
||||||
16
app/src/internal/logistics/routes.ts
Normal file
16
app/src/internal/logistics/routes.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { Express, Request, Response } from "express";
|
||||||
|
import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
|
||||||
|
import schedule from "./routes/scheduler/scheduleRoutes.js";
|
||||||
|
|
||||||
|
export const setupLogisticsRoutes = (app: Express, basePath: string) => {
|
||||||
|
app.use(basePath + "/api/logistics/schedule", schedule);
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
basePath + "/api/admin/users",
|
||||||
|
requireAuth("user", ["systemAdmin"]) // will pass bc system admin but this is just telling us we need this
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
basePath + "/api/admin",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]) // will pass bc system admin but this is just telling us we need this
|
||||||
|
);
|
||||||
|
};
|
||||||
12
app/src/internal/logistics/routes/scheduler/getSchedule.ts
Normal file
12
app/src/internal/logistics/routes/scheduler/getSchedule.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
import type { Request, Response } from "express";
|
||||||
|
import { schedulerChange } from "../../../../ws/channels/scheduler.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/", async (req: Request, res: Response) => {
|
||||||
|
schedulerChange({ name: "something" });
|
||||||
|
res.status(200).json({ message: "Something " });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
|
||||||
|
import getSchedule from "./getSchedule.js";
|
||||||
|
|
||||||
|
import { restrictToHosts } from "../../../../pkg/middleware/restrictToHosts.js";
|
||||||
|
import { requireAuth } from "../../../../pkg/middleware/authMiddleware.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.use("/", getSchedule);
|
||||||
|
// router.use(
|
||||||
|
// "/",
|
||||||
|
// requireAuth("user", ["systemAdmin", "admin"]),
|
||||||
|
// restrictToHosts([
|
||||||
|
// "usmcd1vms036.alpla.net",
|
||||||
|
// "USMCD1VMS036.alpla.net",
|
||||||
|
// "https://usmcd1vms036.alpla.net",
|
||||||
|
// ]),
|
||||||
|
// addServer
|
||||||
|
// );
|
||||||
|
// router.use(
|
||||||
|
// "/",
|
||||||
|
// requireAuth("user", ["systemAdmin", "admin"]),
|
||||||
|
// restrictToHosts([
|
||||||
|
// "usmcd1vms036.alpla.net",
|
||||||
|
// "USMCD1VMS036.alpla.net",
|
||||||
|
// "https://usmcd1vms036.alpla.net",
|
||||||
|
// ]),
|
||||||
|
// updateServer
|
||||||
|
// );
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -2,12 +2,14 @@ import type { Express, Request, Response } from "express";
|
|||||||
import { setupAuthRoutes } from "../auth/routes/routes.js";
|
import { setupAuthRoutes } from "../auth/routes/routes.js";
|
||||||
import { setupAdminRoutes } from "../admin/routes.js";
|
import { setupAdminRoutes } from "../admin/routes.js";
|
||||||
import { setupSystemRoutes } from "../system/routes.js";
|
import { setupSystemRoutes } from "../system/routes.js";
|
||||||
|
import { setupLogisticsRoutes } from "../logistics/routes.js";
|
||||||
|
|
||||||
export const setupRoutes = (app: Express, basePath: string) => {
|
export const setupRoutes = (app: Express, basePath: string) => {
|
||||||
// all routes
|
// all routes
|
||||||
setupAuthRoutes(app, basePath);
|
setupAuthRoutes(app, basePath);
|
||||||
setupAdminRoutes(app, basePath);
|
setupAdminRoutes(app, basePath);
|
||||||
setupSystemRoutes(app, basePath);
|
setupSystemRoutes(app, basePath);
|
||||||
|
setupLogisticsRoutes(app, basePath);
|
||||||
|
|
||||||
// always try to go to the app weather we are in dev or in production.
|
// always try to go to the app weather we are in dev or in production.
|
||||||
app.get(basePath + "/", (req: Request, res: Response) => {
|
app.get(basePath + "/", (req: Request, res: Response) => {
|
||||||
|
|||||||
51
app/src/pkg/db/schema/orderScheduler.ts
Normal file
51
app/src/pkg/db/schema/orderScheduler.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import {
|
||||||
|
boolean,
|
||||||
|
date,
|
||||||
|
integer,
|
||||||
|
pgTable,
|
||||||
|
real,
|
||||||
|
text,
|
||||||
|
timestamp,
|
||||||
|
uniqueIndex,
|
||||||
|
uuid,
|
||||||
|
} from "drizzle-orm/pg-core";
|
||||||
|
import type z from "zod";
|
||||||
|
|
||||||
|
export const orderScheduler = pgTable(
|
||||||
|
"orderScheduler",
|
||||||
|
{
|
||||||
|
schedule_id: uuid("schedule_id").defaultRandom().primaryKey(),
|
||||||
|
av: integer("av"),
|
||||||
|
description: text("description"),
|
||||||
|
orderType: text("order_type").notNull(), //orders || incoming
|
||||||
|
orderNumber: integer("order_number").notNull(),
|
||||||
|
header: text("header").notNull(),
|
||||||
|
lineItemNumber: text("line_item_number"),
|
||||||
|
customerReleaseNumber: text("customer_release_number"),
|
||||||
|
deliveryDate: timestamp("delivery_date").notNull(),
|
||||||
|
loadingDate: timestamp("loading_date"),
|
||||||
|
orderQTY: real("order_qty").notNull(),
|
||||||
|
orderLu: real("order_lu").notNull(),
|
||||||
|
deliveredQTY: real("delivered_qty").default(0.0),
|
||||||
|
deliveredLu: real("delivered_lu").default(0.0),
|
||||||
|
remark: text("remark"),
|
||||||
|
createdAsEDI: boolean("created_as_EDI"),
|
||||||
|
currentState: integer("current_state"),
|
||||||
|
lstDateCheck: timestamp("lst_date_check"), //this will match the delivery date to start and when moved in the front end run a function to alert or update via api
|
||||||
|
customerAddressId: integer("customer_address_id"),
|
||||||
|
customerDescription: text("customer_description"),
|
||||||
|
dock: text("dock"),
|
||||||
|
orderFrom: text("order_from"), // manual or prod.
|
||||||
|
// being edited change to true so it will essential lock all others from editing
|
||||||
|
// carrier
|
||||||
|
// carrier email. -- when dropped we can email the carrier this could be considered there confirmation.
|
||||||
|
addDate: timestamp("add_date").defaultNow(),
|
||||||
|
updDate: timestamp("upd_date").defaultNow(),
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
||||||
|
uniqueIndex("orderNumber").on(table.orderNumber),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
export type OrderScheduler = z.infer<typeof orderScheduler>;
|
||||||
Reference in New Issue
Block a user