This commit is contained in:
2025-03-25 07:57:55 -05:00
5 changed files with 421 additions and 254 deletions

View File

@@ -3,211 +3,239 @@ import { LstCard } from "../extendedUI/LstCard";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
import { Input } from "../ui/input"; import { Input } from "../ui/input";
import { import {
Table, Table,
TableBody, TableBody,
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow,
} from "../ui/table"; } from "../ui/table";
import { Skeleton } from "../ui/skeleton"; import { Skeleton } from "../ui/skeleton";
//import CycleCountLog from "./CycleCountLog"; //import CycleCountLog from "./CycleCountLog";
import { import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "../ui/select"; } from "../ui/select";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import axios from "axios"; import axios from "axios";
import { useState } from "react"; import { useState } from "react";
export default function OcmeCycleCount() { export default function OcmeCycleCount() {
const token = localStorage.getItem("auth_token"); const token = localStorage.getItem("auth_token");
const [data, setData] = useState([]); const [data, setData] = useState([]);
const [counting, setCounting] = useState(false); const [counting, setCounting] = useState(false);
const { const {
register, register,
handleSubmit, handleSubmit,
//watch, //watch,
formState: { errors }, formState: { errors },
reset, reset,
control, control,
} = useForm(); } = useForm();
const onSubmit = async (data: any) => { const onSubmit = async (data: any) => {
setData([]); setData([]);
setCounting(true); setCounting(true);
toast.success(`Cycle count started`); toast.success(`Cycle count started`);
try { try {
const res = await axios.post("/ocme/api/v1/cycleCount", data, { const res = await axios.post("/ocme/api/v1/cyclecount", data, {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
console.log(data); toast.success(res.data.message);
toast.success(res.data.message); setData(res.data.data);
setData(res.data.data); setCounting(false);
setCounting(false); reset();
reset(); } catch (error) {
} catch (error) { toast.error("There was an error cycle counting");
console.log(error); setCounting(false);
toast.error("There was an error cycle counting"); reset();
setCounting(false); }
reset(); };
} return (
}; <div className="flex flex-row w-screen">
<div className="m-2 w-5/6">
return ( <LstCard>
<div className="flex flex-row w-screen"> <p className="ml-2">
<div className="m-2 w-5/6"> Please enter the name or laneID you want to cycle count.
<LstCard> </p>
<p className="ml-2"> <div>
Please enter the name or laneID you want to cycle count. <form onSubmit={handleSubmit(onSubmit)}>
</p> <div className="flex justify-between">
<div> <div className="m-2 flex flex-row">
<form onSubmit={handleSubmit(onSubmit)}> <Input
<div className="flex justify-between"> placeholder="enter lane: L064"
<div className="m-2 flex flex-row"> className={
<Input errors.lane ? "border-red-500" : ""
placeholder="enter lane: L064" }
className={errors.lane ? "border-red-500" : ""} aria-invalid={!!errors.lane}
aria-invalid={!!errors.lane} {...register("lane", {
{...register("lane", { required: true,
required: true, minLength: {
minLength: { value: 3,
value: 3, message:
message: "The lane is too short!", "The lane is too short!",
}, },
})} })}
/> />
<div className="ml-2"> <div className="ml-2">
<Controller <Controller
control={control} control={control}
name="laneType" name="laneType"
defaultValue={""} defaultValue={""}
render={({ render={({
field: { onChange }, field: { onChange },
fieldState: {}, fieldState: {},
//formState, //formState,
}) => ( }) => (
<Select onValueChange={onChange}> <Select
<SelectTrigger className="w-[180px]"> onValueChange={onChange}
<SelectValue placeholder="Select name or id" /> >
</SelectTrigger> <SelectTrigger className="w-[180px]">
<SelectContent> <SelectValue placeholder="Select name or id" />
<SelectItem value="name">Name</SelectItem> </SelectTrigger>
<SelectItem value="laneID">Lane ID</SelectItem> <SelectContent>
</SelectContent> <SelectItem value="name">
</Select> Name
)} </SelectItem>
/> <SelectItem value="laneId">
</div> Lane ID
</div> </SelectItem>
<Button className="m-2" type="submit" disabled={counting}> </SelectContent>
{counting ? ( </Select>
<span>Counting...</span> )}
) : ( />
<span>CycleCount</span> </div>
)} </div>
</Button> <Button
</div> className="m-2"
</form> type="submit"
</div> disabled={counting}
<div> >
<Table> {counting ? (
<TableHeader> <span>Counting...</span>
<TableRow> ) : (
<TableHead>LaneID</TableHead> <span>CycleCount</span>
<TableHead>Lane</TableHead> )}
<TableHead>AV</TableHead> </Button>
<TableHead>Description</TableHead> </div>
<TableHead>Running Number</TableHead> </form>
<TableHead>In Ocme</TableHead> </div>
<TableHead>In Stock</TableHead> <div>
<TableHead>Result</TableHead> <Table>
</TableRow> <TableHeader>
</TableHeader> <TableRow>
{data?.length === 0 ? ( <TableHead>LaneID</TableHead>
<TableBody> <TableHead>Lane</TableHead>
{Array(10) <TableHead>AV</TableHead>
.fill(0) <TableHead>Description</TableHead>
.map((_, i) => ( <TableHead>Running Number</TableHead>
<TableRow key={i}> <TableHead>In Ocme</TableHead>
<TableCell className="font-medium"> <TableHead>In Stock</TableHead>
<Skeleton className="h-4" /> <TableHead>Result</TableHead>
</TableCell> </TableRow>
<TableCell> </TableHeader>
<Skeleton className="h-4" /> {data.length === 0 ? (
</TableCell> <TableBody>
<TableCell> {Array(10)
<Skeleton className="h-4" /> .fill(0)
</TableCell> .map((_, i) => (
<TableCell> <TableRow key={i}>
<Skeleton className="h-4" /> <TableCell className="font-medium">
</TableCell> <Skeleton className="h-4" />
<TableCell> </TableCell>
<Skeleton className="h-4" /> <TableCell>
</TableCell> <Skeleton className="h-4" />
<TableCell> </TableCell>
<Skeleton className="h-4" /> <TableCell>
</TableCell> <Skeleton className="h-4" />
<TableCell> </TableCell>
<Skeleton className="h-4" /> <TableCell>
</TableCell> <Skeleton className="h-4" />
<TableCell> </TableCell>
<Skeleton className="h-4" /> <TableCell>
</TableCell> <Skeleton className="h-4" />
</TableRow> </TableCell>
))} <TableCell>
</TableBody> <Skeleton className="h-4" />
) : ( </TableCell>
<> <TableCell>
{data?.map((i: any) => { <Skeleton className="h-4" />
let classname = ``; </TableCell>
if (i.info === "Quality Check Required") { <TableCell>
classname = `bg-red-500`; <Skeleton className="h-4" />
} </TableCell>
if (i.info === "Sent to Inv") { </TableRow>
classname = `bg-amber-700`; ))}
} </TableBody>
return ( ) : (
<TableRow key={i.runningNumber}> <>
<TableCell className={`font-medium ${classname}`}> {data.map((i: any) => {
{i.alpla_laneID} let classname = ``;
</TableCell> if (
<TableCell className={`font-medium ${classname}`}> i.info === "Quality Check Required"
{i.alpla_laneDescription} ) {
</TableCell> classname = `bg-red-500`;
<TableCell className={`font-medium ${classname}`}> }
{i.Article} if (i.info === "Sent to Inv") {
</TableCell> classname = `bg-amber-700`;
<TableCell className={`font-medium ${classname}`}> }
{i.alpla_laneDescription} return (
</TableCell> <TableRow key={i.runningNumber}>
<TableCell className={`font-medium ${classname}`}> <TableCell
{i.runningNumber} className={`font-medium ${classname}`}
</TableCell> >
<TableCell className={`font-medium ${classname}`}> {i.alpla_laneID}
{i.ocme} </TableCell>
</TableCell> <TableCell
<TableCell className={`font-medium ${classname}`}> className={`font-medium ${classname}`}
{i.stock} >
</TableCell> {i.alpla_laneDescription}
<TableCell className={`font-medium ${classname}`}> </TableCell>
{i.info} <TableCell
</TableCell> className={`font-medium ${classname}`}
</TableRow> >
); {i.Article}
})} </TableCell>
</> <TableCell
)} className={`font-medium ${classname}`}
</Table> >
</div> {i.alpla_laneDescription}
</LstCard> </TableCell>
</div> <TableCell
{/* <div className="m-2"> className={`font-medium ${classname}`}
>
{i.runningNumber}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.ocme}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.stock}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.info}
</TableCell>
</TableRow>
);
})}
</>
)}
</Table>
</div>
</LstCard>
</div>
{/* <div className="m-2">
<CycleCountLog /> <CycleCountLog />
</div> */} </div> */}
</div> </div>
); );
} }

View File

@@ -21,7 +21,7 @@
"deploy": "standard-version --conventional-commits && npm run prodBuild", "deploy": "standard-version --conventional-commits && npm run prodBuild",
"zipServer": "dotenvx run -f .env -- tsx server/scripts/zipUpBuild.ts \"C:\\Users\\matthes01\\Documents\\lstv2\"", "zipServer": "dotenvx run -f .env -- tsx server/scripts/zipUpBuild.ts \"C:\\Users\\matthes01\\Documents\\lstv2\"",
"v1Build": "cd C:\\Users\\matthes01\\Documents\\logisticsSupportTool && npm run oldBuilder", "v1Build": "cd C:\\Users\\matthes01\\Documents\\logisticsSupportTool && npm run oldBuilder",
"prodBuild": "npm run v1Build && powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\" && npm run zipServer", "prodBuild": "npm run v1Build && powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2-dev\" && npm run zipServer",
"commit": "cz", "commit": "cz",
"prodinstall": "npm i --omit=dev && npm run db:migrate", "prodinstall": "npm i --omit=dev && npm run db:migrate",
"checkupdates": "npx npm-check-updates" "checkupdates": "npx npm-check-updates"

View File

@@ -31,28 +31,28 @@ export const lstAuth = btoa(`${username}:${password}`);
// checking to make sure we have the settings intialized // checking to make sure we have the settings intialized
const serverIntialized = await db.select({ count: count() }).from(settings); const serverIntialized = await db.select({ count: count() }).from(settings);
export const installed = export const installed =
serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development" serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development"
? false ? false
: true; : true;
createLog("info", "LST", "server", `Server is installed: ${installed}`); createLog("info", "LST", "server", `Server is installed: ${installed}`);
const app = new OpenAPIHono({ strict: false }); const app = new OpenAPIHono({ strict: false });
// middle ware // middle ware
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
app.use("*", logger()); app.use("*", logger());
} }
app.use( app.use(
"*", "*",
cors({ cors({
origin: "*", // Allow all origins origin: "*", // Allow all origins
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"], allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
//exposeHeaders: ["Content-Length", "X-Kuma-Revision"], //exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
credentials: true, // Allow credentials if needed credentials: true, // Allow credentials if needed
maxAge: 600, maxAge: 600,
}) })
); );
// Middleware to normalize route case // Middleware to normalize route case
@@ -69,29 +69,29 @@ app.use(
// }); // });
app.doc("/api/ref", { app.doc("/api/ref", {
openapi: "3.0.0", openapi: "3.0.0",
info: { info: {
version: "2.0.0", version: "2.0.0",
title: "LST API", title: "LST API",
}, },
}); });
const routes = [ const routes = [
scalar, scalar,
auth, auth,
// apiHits, // apiHits,
system, system,
tcpServer, tcpServer,
sqlService, sqlService,
logistics, logistics,
rfid, rfid,
printers, printers,
loggerService, loggerService,
ocpService, ocpService,
] as const; ] as const;
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/api/", route); app.route("/api/", route);
}); });
app.route("/ocme/", ocme); app.route("/ocme/", ocme);
@@ -132,48 +132,48 @@ app.use("*", serveStatic({ path: "./frontend/dist/index.html" }));
// Handle app exit signals // Handle app exit signals
process.on("SIGINT", async () => { process.on("SIGINT", async () => {
console.log("\nGracefully shutting down..."); console.log("\nGracefully shutting down...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
process.on("SIGTERM", async () => { process.on("SIGTERM", async () => {
console.log("Received termination signal, closing database..."); console.log("Received termination signal, closing database...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
process.on("uncaughtException", async (err) => { process.on("uncaughtException", async (err) => {
console.log("Uncaught Exception:", err); console.log("Uncaught Exception:", err);
//await closePool(); //await closePool();
process.exit(1); process.exit(1);
}); });
process.on("beforeExit", async () => { process.on("beforeExit", async () => {
console.log("Process is about to exit..."); console.log("Process is about to exit...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
const port = const port =
process.env.NODE_ENV === "development" process.env.NODE_ENV === "development"
? process.env.VITE_SERVER_PORT ? process.env.VITE_SERVER_PORT
: process.env.PROD_PORT; : process.env.PROD_PORT;
serve( serve(
{ {
fetch: app.fetch, fetch: app.fetch,
port: Number(port), port: Number(port),
hostname: "0.0.0.0", hostname: "0.0.0.0",
}, },
(info) => { (info) => {
createLog( createLog(
"info", "info",
"LST", "LST",
"server", "server",
`Server is running on http://${info.address}:${info.port}` `Server is running on http://${info.address}:${info.port}`
); );
} }
); );
export type AppRoutes = typeof appRoutes; export type AppRoutes = typeof appRoutes;

View File

@@ -4,12 +4,26 @@ import { db } from "../../database/dbclient.js";
import { serverData } from "../../database/schema/serverData.js"; import { serverData } from "../../database/schema/serverData.js";
import { eq, sql } from "drizzle-orm"; import { eq, sql } from "drizzle-orm";
import { createLog } from "../services/logger/logger.js"; import { createLog } from "../services/logger/logger.js";
import { spawn } from "child_process";
import { getAppInfo } from "../globalUtils/appInfo.js";
import { db } from "../../database/dbclient.js";
import { serverData } from "../../database/schema/serverData.js";
import { eq, sql } from "drizzle-orm";
import { createLog } from "../services/logger/logger.js";
type UpdateServerResponse = { type UpdateServerResponse = {
success: boolean; success: boolean;
message: string; message: string;
success: boolean;
message: string;
}; };
export const updateServer = async (
devApp: string,
server: string | null
): Promise<UpdateServerResponse> => {
const app = await getAppInfo(devApp);
const serverInfo = await db
export const updateServer = async ( export const updateServer = async (
devApp: string, devApp: string,
server: string | null server: string | null
@@ -33,7 +47,32 @@ export const updateServer = async (
"Looks like you are missing the plant token or have entered an incorrect one please try again.", "Looks like you are missing the plant token or have entered an incorrect one please try again.",
}; };
} }
if (serverInfo.length === 0) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like you are missing the plant token or have entered an incorrect one please try again.`
);
return {
success: false,
message:
"Looks like you are missing the plant token or have entered an incorrect one please try again.",
};
}
if (serverInfo[0].isUpgrading) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`
);
return {
success: false,
message: `Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`,
};
}
if (serverInfo[0].isUpgrading) { if (serverInfo[0].isUpgrading) {
createLog( createLog(
"error", "error",
@@ -77,6 +116,15 @@ export const updateServer = async (
, ,
]; ];
return new Promise(async (resolve, reject) => {
const process = spawn("powershell", args);
// change the server to upgradeing
await db
.update(serverData)
.set({ isUpgrading: true })
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
//let stdout = "";
//let stderr = "";
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const process = spawn("powershell", args); const process = spawn("powershell", args);
// change the server to upgradeing // change the server to upgradeing
@@ -87,6 +135,12 @@ export const updateServer = async (
//let stdout = ""; //let stdout = "";
//let stderr = ""; //let stderr = "";
// Collect stdout data
process.stdout.on("data", (data) => {
const output = data.toString().trim();
createLog("info", "lst", "serverUpdater", `${output}`);
//onData(output);
});
// Collect stdout data // Collect stdout data
process.stdout.on("data", (data) => { process.stdout.on("data", (data) => {
const output = data.toString().trim(); const output = data.toString().trim();
@@ -94,6 +148,12 @@ export const updateServer = async (
//onData(output); //onData(output);
}); });
// Collect stderr data
process.stderr.on("data", (data) => {
const output = data.toString().trim();
createLog("info", "lst", "serverUpdater", `${output}`);
//onData(output);
});
// Collect stderr data // Collect stderr data
process.stderr.on("data", (data) => { process.stderr.on("data", (data) => {
const output = data.toString().trim(); const output = data.toString().trim();
@@ -101,6 +161,13 @@ export const updateServer = async (
//onData(output); //onData(output);
}); });
// Handle process close
process.on("close", async (code) => {
if (code === 0) {
// if (count >= servers) {
// //onClose(`Server completed with code: ${code}`);
// }
createLog("info", "lst", "serverUpdater", `${server}`);
// Handle process close // Handle process close
process.on("close", async (code) => { process.on("close", async (code) => {
if (code === 0) { if (code === 0) {
@@ -109,6 +176,26 @@ export const updateServer = async (
// } // }
createLog("info", "lst", "serverUpdater", `${server}`); createLog("info", "lst", "serverUpdater", `${server}`);
//update the last build.
try {
await db
.update(serverData)
.set({ lastUpdated: sql`NOW()`, isUpgrading: false })
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
createLog(
"info",
"lst",
"serverUpdater",
`${server?.toLowerCase()}, has been updated and can now be used again.`
);
} catch (error) {
createLog(
"error",
"lst",
"serverUpdater",
`There was an error updating the last time the server was updated: ${error}`
);
}
//update the last build. //update the last build.
try { try {
await db await db
@@ -130,6 +217,12 @@ export const updateServer = async (
); );
} }
resolve({
success: true,
message: `${server?.toLowerCase()}, has been updated and can now be used again.`,
});
} else {
const errorMessage = `Process exited with code ${code}`;
resolve({ resolve({
success: true, success: true,
message: `${server?.toLowerCase()}, has been updated and can now be used again.`, message: `${server?.toLowerCase()}, has been updated and can now be used again.`,
@@ -137,6 +230,9 @@ export const updateServer = async (
} else { } else {
const errorMessage = `Process exited with code ${code}`; const errorMessage = `Process exited with code ${code}`;
// if (count >= servers) {
// //onClose(code);
// }
// if (count >= servers) { // if (count >= servers) {
// //onClose(code); // //onClose(code);
// } // }
@@ -147,6 +243,12 @@ export const updateServer = async (
}); });
} }
}); });
reject({
success: false,
message: `${server?.toLowerCase()}, Has encounted an error while updating.`,
});
}
});
// Handle errors with the process itself // Handle errors with the process itself
process.on("error", (error) => { process.on("error", (error) => {
@@ -155,11 +257,31 @@ export const updateServer = async (
reject(error); reject(error);
}); });
}); });
// Handle errors with the process itself
process.on("error", (error) => {
//onError(err.message);
createLog("error", "lst", "serverUpdater", `${error}`);
reject(error);
});
});
}; };
export async function processAllServers(devApp: string) { export async function processAllServers(devApp: string) {
const servers = await db.select().from(serverData); const servers = await db.select().from(serverData);
const servers = await db.select().from(serverData);
createLog(
"info",
"lst",
"serverUpdater",
`Running the update on all servers`
);
let count = 1;
for (const server of servers) {
try {
const updateToServer = await updateServer(devApp, server.plantToken);
createLog("info", "lst", "serverUpdater", `${server.sName} was updated.`);
count = count + 1;
createLog( createLog(
"info", "info",
"lst", "lst",
@@ -184,4 +306,15 @@ export async function processAllServers(devApp: string) {
//return {success: false, message: `Error updating ${server.sName}: ${error.message}`}; //return {success: false, message: `Error updating ${server.sName}: ${error.message}`};
} }
} }
//return {success: true, message: `${server.sName} was updated.`, data: updateToServer};
} catch (error: any) {
createLog(
"info",
"lst",
"serverUpdater",
`Error updating ${server.sName}: ${error.message}`
);
//return {success: false, message: `Error updating ${server.sName}: ${error.message}`};
}
}
} }

View File

@@ -4,6 +4,12 @@ import { createSSCC } from "../../../globalUtils/createSSCC.js";
import { createLog } from "../../logger/logger.js"; import { createLog } from "../../logger/logger.js";
import { query } from "../../sqlServer/prodSqlServer.js"; import { query } from "../../sqlServer/prodSqlServer.js";
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js"; import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
import { db } from "../../../../database/dbclient.js";
import { ocmeData } from "../../../../database/schema/ocme.js";
import { createSSCC } from "../../../globalUtils/createSSCC.js";
import { createLog } from "../../logger/logger.js";
import { query } from "../../sqlServer/prodSqlServer.js";
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
export const postLabelData = async (data: any) => { export const postLabelData = async (data: any) => {
console.log(data); console.log(data);