Compare commits
8 Commits
51cc4aa370
...
4effb25e9d
| Author | SHA1 | Date | |
|---|---|---|---|
| 4effb25e9d | |||
| dc5ee5b97a | |||
| 75f94eae14 | |||
| 31fbfa4eb3 | |||
| b589bf9724 | |||
| 17ed18669a | |||
| b9f080f130 | |||
| ce546c0d35 |
2
database/migrations/0048_tearful_bushwacker.sql
Normal file
2
database/migrations/0048_tearful_bushwacker.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "siloAdjustments" RENAME COLUMN "lsiloAdjust_id" TO "siloAdjust_id";--> statement-breakpoint
|
||||||
|
ALTER TABLE "printerData" ALTER COLUMN "printDelay" SET DEFAULT '90';
|
||||||
1573
database/migrations/meta/0048_snapshot.json
Normal file
1573
database/migrations/meta/0048_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -337,6 +337,13 @@
|
|||||||
"when": 1743822056329,
|
"when": 1743822056329,
|
||||||
"tag": "0047_silky_starbolt",
|
"tag": "0047_silky_starbolt",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 48,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1743946411873,
|
||||||
|
"tag": "0048_tearful_bushwacker",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import { z } from "zod";
|
|||||||
export const siloAdjustments = pgTable(
|
export const siloAdjustments = pgTable(
|
||||||
"siloAdjustments",
|
"siloAdjustments",
|
||||||
{
|
{
|
||||||
siloAdjust_id: uuid("lsiloAdjust_id").defaultRandom().primaryKey(),
|
siloAdjust_id: uuid("siloAdjust_id").defaultRandom().primaryKey(),
|
||||||
warehouseID: integer("level"),
|
warehouseID: integer("level"),
|
||||||
locationID: integer("locationID"),
|
locationID: integer("locationID"),
|
||||||
currentStockLevel: numeric("currentStockLevel"),
|
currentStockLevel: numeric("currentStockLevel"),
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
jsonb,
|
jsonb,
|
||||||
} from "drizzle-orm/pg-core";
|
} from "drizzle-orm/pg-core";
|
||||||
import { createSelectSchema } from "drizzle-zod";
|
import { createSelectSchema } from "drizzle-zod";
|
||||||
import { modules } from "./modules.js";
|
|
||||||
//import {z} from "zod";
|
//import {z} from "zod";
|
||||||
|
|
||||||
export const subModules = pgTable(
|
export const subModules = pgTable(
|
||||||
|
|||||||
@@ -1,14 +1,181 @@
|
|||||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
import { CardHeader } from "@/components/ui/card";
|
import { CardHeader } from "@/components/ui/card";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@/components/ui/tooltip";
|
||||||
|
import { getStockSilo } from "@/utils/querys/logistics/siloAdjustments/getStockSilo";
|
||||||
|
import { useForm } from "@tanstack/react-form";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import axios from "axios";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { CircleAlert } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export default function SiloCard(data: any) {
|
export default function SiloCard(data: any) {
|
||||||
|
const token = localStorage.getItem("auth_token");
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
const { refetch } = useQuery(getStockSilo());
|
||||||
const silo = data.silo;
|
const silo = data.silo;
|
||||||
|
|
||||||
|
const form = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
newLevel: "",
|
||||||
|
},
|
||||||
|
onSubmit: async ({ value }) => {
|
||||||
|
setSubmitting(true);
|
||||||
|
const dataToSubmit = {
|
||||||
|
quantity: parseFloat(value.newLevel),
|
||||||
|
warehouseId: silo.WarehouseID,
|
||||||
|
laneId: silo.LocationID,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await axios.post(
|
||||||
|
"/api/logistics/createsiloadjustment",
|
||||||
|
dataToSubmit,
|
||||||
|
{ headers: { Authorization: `Bearer ${token}` } }
|
||||||
|
);
|
||||||
|
console.log(res.data);
|
||||||
|
|
||||||
|
if (res.data.success) {
|
||||||
|
toast.success(res.data.message);
|
||||||
|
refetch();
|
||||||
|
form.reset();
|
||||||
|
}
|
||||||
|
if (!res.data.success && res.data.data?.status === 400) {
|
||||||
|
if (res.data.data.status === 400) {
|
||||||
|
toast.error(res.data.data.data.errors[0].message);
|
||||||
|
}
|
||||||
|
} else if (!res.data.success) {
|
||||||
|
toast.error(res.data.message);
|
||||||
|
}
|
||||||
|
setSubmitting(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
//console.log(error);
|
||||||
|
if (error.status === 401) {
|
||||||
|
toast.error(error.response.statusText);
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<LstCard>
|
<LstCard>
|
||||||
<CardHeader>{silo.Description}</CardHeader>
|
<div className="flex flex-row">
|
||||||
<div>
|
<LstCard className="grow m-1 max-w-[400px]">
|
||||||
<hr />
|
<CardHeader>{silo.Description}</CardHeader>
|
||||||
|
<div className="m-1">
|
||||||
|
<hr className="m-2" />
|
||||||
|
<span>Current Stock: </span>
|
||||||
|
{silo.Stock_Total}
|
||||||
|
<hr className="m-2" />
|
||||||
|
<span>Last date adjusted </span>
|
||||||
|
{format(silo.LastAdjustment, "M/dd/yyyy")}
|
||||||
|
<hr className="m-2" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<form.Field
|
||||||
|
name="newLevel"
|
||||||
|
validators={{
|
||||||
|
// We can choose between form-wide and field-specific validators
|
||||||
|
onChange: ({ value }) =>
|
||||||
|
value.length > 1
|
||||||
|
? undefined
|
||||||
|
: "You must enter a value greate than 1",
|
||||||
|
}}
|
||||||
|
children={(field) => {
|
||||||
|
return (
|
||||||
|
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||||
|
<div className="flex flex-row">
|
||||||
|
<Label htmlFor="newLevel">
|
||||||
|
New level
|
||||||
|
</Label>
|
||||||
|
<div>
|
||||||
|
<Disclaimer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row">
|
||||||
|
<Input
|
||||||
|
name={field.name}
|
||||||
|
value={field.state.value}
|
||||||
|
onBlur={field.handleBlur}
|
||||||
|
type="decimal"
|
||||||
|
onChange={(e) =>
|
||||||
|
field.handleChange(
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="ml-1"
|
||||||
|
type="submit"
|
||||||
|
onClick={form.handleSubmit}
|
||||||
|
disabled={submitting}
|
||||||
|
>
|
||||||
|
{submitting ? (
|
||||||
|
<span className="w-24">
|
||||||
|
Submitting...
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="w-24">
|
||||||
|
Submit
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{field.state.meta.errors.length ? (
|
||||||
|
<em>
|
||||||
|
{field.state.meta.errors.join(
|
||||||
|
","
|
||||||
|
)}
|
||||||
|
</em>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</LstCard>
|
||||||
|
<div className="grow max-w-[400px]">
|
||||||
|
<LstCard className="m-1 ">charts go here</LstCard>
|
||||||
|
<LstCard className="m-1">extra options here</LstCard>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Disclaimer = () => {
|
||||||
|
return (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<CircleAlert className="ml-1 w-[14px]" />
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent className="max-w-48">
|
||||||
|
<p className="text-pretty">
|
||||||
|
If you have had this page open for a period of time
|
||||||
|
before submitting your data, there is a chance that the
|
||||||
|
stock levels will be different from the ones you see
|
||||||
|
above
|
||||||
|
</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -19,8 +19,12 @@ export default function SiloPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-wrap">
|
||||||
{data?.map((s: any) => <SiloCard silo={s} />)}
|
{data?.map((s: any) => (
|
||||||
|
<div key={s.LocationID} className="grow m-2 max-w-[800px]">
|
||||||
|
<SiloCard silo={s} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
|
TableFooter,
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
@@ -137,6 +138,16 @@ export default function LabelLog() {
|
|||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<TableFooter>
|
||||||
|
{labelData.length === 0 && (
|
||||||
|
<div>
|
||||||
|
<h2 className="text-center text-2xl">
|
||||||
|
No labels have been printed in the last 2 hours
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export default function Lots() {
|
|||||||
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
||||||
|
|
||||||
const roles = ["admin", "manager", "operator"];
|
const roles = ["admin", "manager", "operator"];
|
||||||
|
const lotdata = data ? data : [];
|
||||||
|
|
||||||
if (user && roles.includes(user.role)) {
|
if (user && roles.includes(user.role)) {
|
||||||
//width = 1280;
|
//width = 1280;
|
||||||
@@ -144,7 +145,6 @@ export default function Lots() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LstCard className="m-2 p-2 min-h-2/5">
|
<LstCard className="m-2 p-2 min-h-2/5">
|
||||||
<ScrollArea className="h-[400px]">
|
<ScrollArea className="h-[400px]">
|
||||||
@@ -197,7 +197,7 @@ export default function Lots() {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data?.map((lot: LotType) => (
|
{lotdata.map((lot: LotType) => (
|
||||||
<TableRow key={lot.LabelOnlineID}>
|
<TableRow key={lot.LabelOnlineID}>
|
||||||
<TableCell className="font-medium">
|
<TableCell className="font-medium">
|
||||||
{lot.MachineLocation}
|
{lot.MachineLocation}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export default function OCPPage() {
|
|||||||
const { settings } = useSettingStore();
|
const { settings } = useSettingStore();
|
||||||
|
|
||||||
const server = settings.filter((n) => n.plantToken === "usday1");
|
const server = settings.filter((n) => n.plantToken === "usday1");
|
||||||
|
console.log(server);
|
||||||
return (
|
return (
|
||||||
<div className="h-screen w-full ">
|
<div className="h-screen w-full ">
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
@@ -40,7 +41,7 @@ export default function OCPPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-1/6 flex flex-col">
|
<div className="w-1/6 flex flex-col">
|
||||||
{server && (
|
{server.length >= 1 && (
|
||||||
<div>
|
<div>
|
||||||
<WrapperManualTrigger />
|
<WrapperManualTrigger />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,12 +9,10 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
|
import { getPrinters } from "@/utils/querys/production/printers";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
let printerCols = [
|
let printerCols = [
|
||||||
{
|
|
||||||
key: "status",
|
|
||||||
label: "Status",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: "printer",
|
key: "printer",
|
||||||
label: "Printer",
|
label: "Printer",
|
||||||
@@ -25,10 +23,12 @@ let printerCols = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
export default function PrinterStatus() {
|
export default function PrinterStatus() {
|
||||||
return (
|
const { data, isError, isLoading } = useQuery(getPrinters());
|
||||||
<LstCard className="m-2 p-2">
|
|
||||||
<ScrollArea className="max-h-[300px]">
|
if (isError) {
|
||||||
<p className="text-center">Printer Status</p>
|
return (
|
||||||
|
<ScrollArea className="h-[400px]">
|
||||||
|
<p className="text-center">Printer Staus error</p>
|
||||||
|
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
@@ -50,14 +50,65 @@ export default function PrinterStatus() {
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<Skeleton className="h-4" />
|
<Skeleton className="h-4" />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
|
||||||
<Skeleton className="h-4" />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* only show the assigned printers
|
||||||
|
*/
|
||||||
|
|
||||||
|
const assigned = data?.filter((a: any) => a.assigned) || [];
|
||||||
|
return (
|
||||||
|
<LstCard className="m-2 p-2">
|
||||||
|
<ScrollArea className="max-h-[800px]">
|
||||||
|
<p className="text-center">
|
||||||
|
{isLoading ? (
|
||||||
|
<span>Printers status loading...</span>
|
||||||
|
) : (
|
||||||
|
<span>Printer Status</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
{printerCols.map((l) => (
|
||||||
|
<TableHead key={l.key}>{l.label}</TableHead>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>{" "}
|
||||||
|
{isLoading ? (
|
||||||
|
<TableBody>
|
||||||
|
{Array(5)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, i) => (
|
||||||
|
<TableRow key={i}>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
<Skeleton className="h-4" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Skeleton className="h-4" />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
<TableBody>
|
||||||
|
{assigned?.map((p: any) => (
|
||||||
|
<TableRow key={p.printer_id}>
|
||||||
|
<TableCell>{p.name}</TableCell>
|
||||||
|
<TableCell>{p.statusText}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
)}
|
||||||
|
</Table>
|
||||||
|
</ScrollArea>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
20
frontend/src/utils/querys/production/printers.tsx
Normal file
20
frontend/src/utils/querys/production/printers.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export function getPrinters() {
|
||||||
|
return queryOptions({
|
||||||
|
queryKey: ["printers"],
|
||||||
|
queryFn: () => fetchSettings(),
|
||||||
|
|
||||||
|
staleTime: 1000,
|
||||||
|
refetchInterval: 2 * 2000,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchSettings = async () => {
|
||||||
|
const { data } = await axios.get(`/api/ocp/getprinters`);
|
||||||
|
// if we are not localhost ignore the devDir setting.
|
||||||
|
//const url: string = window.location.host.split(":")[0];
|
||||||
|
return data.data ?? [];
|
||||||
|
};
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"admConfig": {
|
"admConfig": {
|
||||||
"build": 171,
|
"build": 174,
|
||||||
"oldBuild": "backend-0.1.3.zip"
|
"oldBuild": "backend-0.1.3.zip"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -88,4 +88,4 @@
|
|||||||
"ws": "^8.18.1",
|
"ws": "^8.18.1",
|
||||||
"zod": "^3.24.2"
|
"zod": "^3.24.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@ const transport = pino.transport({
|
|||||||
const log: Logger = pino(
|
const log: Logger = pino(
|
||||||
{
|
{
|
||||||
level: process.env.LOG_LEVEL || logLevel,
|
level: process.env.LOG_LEVEL || logLevel,
|
||||||
|
//level: "debug",
|
||||||
// formatters: {
|
// formatters: {
|
||||||
// level: (label) => {
|
// level: (label) => {
|
||||||
// return {level: label.toUpperCase()};
|
// return {level: label.toUpperCase()};
|
||||||
|
|||||||
@@ -58,6 +58,17 @@ export const createSiloAdjustment = async (
|
|||||||
* Checking to see the difference, and send email if +/- 5% will change later if needed
|
* Checking to see the difference, and send email if +/- 5% will change later if needed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const sa: any = a;
|
||||||
|
|
||||||
|
if (!sa.success) {
|
||||||
|
console.log(`insde error`);
|
||||||
|
return {
|
||||||
|
success: sa.success,
|
||||||
|
message: sa.message,
|
||||||
|
data: sa.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const stockNummy = stock.filter((s: any) => s.LocationID === data.laneId);
|
const stockNummy = stock.filter((s: any) => s.LocationID === data.laneId);
|
||||||
const theDiff =
|
const theDiff =
|
||||||
((data.quantity - stockNummy[0].Stock_Total) /
|
((data.quantity - stockNummy[0].Stock_Total) /
|
||||||
@@ -91,7 +102,7 @@ export const createSiloAdjustment = async (
|
|||||||
data: postAdjError,
|
data: postAdjError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
let adj: any = a;
|
||||||
if (Math.abs(theDiff) > 5) {
|
if (Math.abs(theDiff) > 5) {
|
||||||
// console.log(`Send for comment due to being: ${theDiff.toFixed(2)}%`);
|
// console.log(`Send for comment due to being: ${theDiff.toFixed(2)}%`);
|
||||||
const server = set.filter((n: any) => n.name === "server");
|
const server = set.filter((n: any) => n.name === "server");
|
||||||
@@ -123,8 +134,14 @@ export const createSiloAdjustment = async (
|
|||||||
//console.log(emailSetup);
|
//console.log(emailSetup);
|
||||||
|
|
||||||
await sendEmail(emailSetup);
|
await sendEmail(emailSetup);
|
||||||
|
return {
|
||||||
|
success: adj.success,
|
||||||
|
message: `Silo adjustmnet was completed you will also receive and email due to the adjustment having a variation of ${Math.abs(
|
||||||
|
theDiff
|
||||||
|
).toFixed(2)}%`,
|
||||||
|
data: adj.data,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return { success: adj.success, message: adj.message, data: adj.data };
|
||||||
}
|
}
|
||||||
|
|
||||||
let adj: any = a;
|
|
||||||
return { success: adj.success, message: adj.message, data: adj.data };
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,22 +45,45 @@ export const postAdjustment = async (data: any, prod: any) => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
let e = error as any;
|
let e = error as any;
|
||||||
if (error) {
|
if (e) {
|
||||||
return {
|
if (e.status === 401) {
|
||||||
success: false,
|
const data = {
|
||||||
message: "Error in posting the silo adjustment.",
|
success: false,
|
||||||
data: {
|
message: "Incorrect alpla prod password.",
|
||||||
status: e.response?.status,
|
data: {
|
||||||
statusText: e.response?.statusText,
|
status: e.response?.status,
|
||||||
data: e.response?.data,
|
statusText: e.response?.statusText,
|
||||||
},
|
data: e.response?.data,
|
||||||
};
|
},
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Error in posting the silo adjustment.",
|
||||||
|
data: {
|
||||||
|
status: e.response?.status,
|
||||||
|
statusText: e.response?.statusText,
|
||||||
|
data: e.response?.data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (silo.status !== 200) {
|
if (silo?.status !== 200) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "Error in posting the silo adjustment",
|
message: "Error in posting the silo adjustment",
|
||||||
|
data: {
|
||||||
|
status: silo?.status,
|
||||||
|
statusText: silo?.statusText,
|
||||||
|
data: silo?.data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Adjustment was completed",
|
||||||
data: {
|
data: {
|
||||||
status: silo.status,
|
status: silo.status,
|
||||||
statusText: silo.statusText,
|
statusText: silo.statusText,
|
||||||
@@ -68,14 +91,4 @@ export const postAdjustment = async (data: any, prod: any) => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Adjustment was completed",
|
|
||||||
data: {
|
|
||||||
status: silo.status,
|
|
||||||
statusText: silo.statusText,
|
|
||||||
data: silo.data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ app.openapi(
|
|||||||
data,
|
data,
|
||||||
payload.user
|
payload.user
|
||||||
);
|
);
|
||||||
|
|
||||||
return c.json(
|
return c.json(
|
||||||
{
|
{
|
||||||
success: createSiloAdj.success,
|
success: createSiloAdj.success,
|
||||||
|
|||||||
@@ -4,13 +4,23 @@ import { settings } from "../../../../../database/schema/settings.js";
|
|||||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
import { createLog } from "../../../logger/logger.js";
|
import { createLog } from "../../../logger/logger.js";
|
||||||
import { getPrinters } from "./getPrinters.js";
|
import { getPrinters } from "./getPrinters.js";
|
||||||
import { printerStatus } from "./printerStatus.js";
|
import { autoLabelingStats, printerStatus } from "./printerStatus.js";
|
||||||
|
|
||||||
|
let isPrinterCycling = false;
|
||||||
|
let actualPrinterCycle: any;
|
||||||
|
|
||||||
export const printerCycle = async () => {
|
export const printerCycle = async () => {
|
||||||
/**
|
/**
|
||||||
* We will cycle through the printers to check there states.
|
* We will cycle through the printers to check there states.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (isPrinterCycling)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Printers are already being cycled.",
|
||||||
|
};
|
||||||
|
|
||||||
|
createLog("info", "ocp", "ocp", "Printer cycle has started.");
|
||||||
// get the printers
|
// get the printers
|
||||||
const { data: s, error: se } = await tryCatch(
|
const { data: s, error: se } = await tryCatch(
|
||||||
db.select().from(settings).where(eq(settings.name, "ocpCycleDelay"))
|
db.select().from(settings).where(eq(settings.name, "ocpCycleDelay"))
|
||||||
@@ -29,9 +39,9 @@ export const printerCycle = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ocpDelay: any = s;
|
const ocpDelay: any = s;
|
||||||
|
isPrinterCycling = true;
|
||||||
// start the actual printer cycle
|
// start the actual printer cycle
|
||||||
const actualPrinterCycle = setInterval(async () => {
|
actualPrinterCycle = setInterval(async () => {
|
||||||
const { data, error } = await tryCatch(getPrinters());
|
const { data, error } = await tryCatch(getPrinters());
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -51,10 +61,8 @@ export const printerCycle = async () => {
|
|||||||
// only keep the assigned ones
|
// only keep the assigned ones
|
||||||
printers = printers.filter((p: any) => p.assigned === true);
|
printers = printers.filter((p: any) => p.assigned === true);
|
||||||
|
|
||||||
// for autolabelers like dayton and MCD we want to ignore them from the loop as well.
|
// for printers we want to ignore there must be a remark stateing to ignore.
|
||||||
printers = printers.filter(
|
printers = printers.filter((p: any) => !p.remark.includes("ignore"));
|
||||||
(p: any) => p.name != "Autolabeler" && !p.remark.includes("ignore")
|
|
||||||
);
|
|
||||||
|
|
||||||
printers.forEach(async (p: any) => {
|
printers.forEach(async (p: any) => {
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +83,31 @@ export const printerCycle = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p.name === "Autolabeler") {
|
||||||
|
await autoLabelingStats(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for all other printers
|
||||||
await printerStatus(p);
|
await printerStatus(p);
|
||||||
});
|
});
|
||||||
}, parseInt(ocpDelay[0]?.value) * 1000);
|
}, parseInt(ocpDelay[0]?.value) * 1000);
|
||||||
|
|
||||||
|
return { success: true, message: "Printer cycle has been started." };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stopPrinterCycle = async () => {
|
||||||
|
/**
|
||||||
|
* We will stop the print cylce this is more an emergancy thing.
|
||||||
|
*/
|
||||||
|
if (actualPrinterCycle && !actualPrinterCycle._destroyed) {
|
||||||
|
createLog("info", "ocp", "ocp", "Printer cycle is being stopped.");
|
||||||
|
clearInterval(actualPrinterCycle);
|
||||||
|
isPrinterCycling = false;
|
||||||
|
return { success: true, message: "Printer cycle has been stopped." };
|
||||||
|
} else {
|
||||||
|
createLog("info", "ocp", "ocp", "Printer cycle is already stopped.");
|
||||||
|
isPrinterCycling = false;
|
||||||
|
return { success: true, message: "Printer cycle is already Stopped." };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export const printStatus = [
|
|||||||
{ code: 2, text: "Pending labels" },
|
{ code: 2, text: "Pending labels" },
|
||||||
{ code: 3, text: "Printing to fast" },
|
{ code: 3, text: "Printing to fast" },
|
||||||
{ code: 4, text: "Creating label" },
|
{ code: 4, text: "Creating label" },
|
||||||
|
{ code: 5, text: "Waiting" },
|
||||||
{ code: 6, text: "Printer Paused" },
|
{ code: 6, text: "Printer Paused" },
|
||||||
{ code: 7, text: "Printer error" },
|
{ code: 7, text: "Printer error" },
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,9 +68,9 @@ export const printerStatus = async (p: any) => {
|
|||||||
"debug",
|
"debug",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name}: timeBetween: ${timeBetween}, delay ${
|
`${p.name}: timeBetween: ${timeBetween}, delay ${parseInt(
|
||||||
p.printDelay || 90
|
p.printDelay
|
||||||
}, ${currentTime}... ${lastTime}`
|
)}, ${currentTime}... ${lastTime}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (tmp[2] === "0" && tmp[4] !== "000") {
|
if (tmp[2] === "0" && tmp[4] !== "000") {
|
||||||
@@ -80,7 +80,7 @@ export const printerStatus = async (p: any) => {
|
|||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`Unpaused and printing labels, time remaing ${differenceInSeconds(
|
`Unpaused and printing labels, time remaing ${differenceInSeconds(
|
||||||
p.printDelay || 90,
|
parseInt(p.printDelay),
|
||||||
timeBetween
|
timeBetween
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
@@ -96,7 +96,7 @@ export const printerStatus = async (p: any) => {
|
|||||||
`${
|
`${
|
||||||
p.name
|
p.name
|
||||||
} paused to soon, unpausing, remaining time: ${differenceInSeconds(
|
} paused to soon, unpausing, remaining time: ${differenceInSeconds(
|
||||||
p.printDelay || 90,
|
parseInt(p.printDelay),
|
||||||
timeBetween
|
timeBetween
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
@@ -105,20 +105,20 @@ export const printerStatus = async (p: any) => {
|
|||||||
printerUpdate(p, 2);
|
printerUpdate(p, 2);
|
||||||
|
|
||||||
unPausePrinter(p);
|
unPausePrinter(p);
|
||||||
} else if ((tmp[2] === "0" && timeBetween < p.printDelay) || 90) {
|
} else if (tmp[2] === "0" && timeBetween < parseInt(p.printDelay)) {
|
||||||
// was unpaused to soon so repause it
|
// was unpaused to soon so repause it
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"debug",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name} Unpaused before the time allowed, time left ${
|
`${p.name} Unpaused before the time allowed, time left ${
|
||||||
differenceInSeconds(p.printDelay || 90, timeBetween) //seconds
|
differenceInSeconds(parseInt(p.printDelay), timeBetween) //seconds
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
|
|
||||||
printerUpdate(p, 3);
|
printerUpdate(p, 3);
|
||||||
pausePrinter(p);
|
pausePrinter(p);
|
||||||
} else if ((tmp[2] === "0" && timeBetween > p.printDelay) || 90) {
|
} else if (tmp[2] === "0" && timeBetween > parseInt(p.printDelay)) {
|
||||||
// its been long enough we can print a label
|
// its been long enough we can print a label
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"debug",
|
||||||
@@ -188,3 +188,68 @@ export const printerStatus = async (p: any) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const autoLabelingStats = async (p: any) => {
|
||||||
|
/**
|
||||||
|
* Checks autolabeling printers just to see what they are doing.
|
||||||
|
*/
|
||||||
|
createLog("debug", "ocp", "ocp", `Printer cycling`);
|
||||||
|
|
||||||
|
const printer = new net.Socket();
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// connect to the printer, and check its status
|
||||||
|
printer.connect(p.port, p.ipAddress, async () => {
|
||||||
|
// write the message to the printer below gives us a feedback of the printer
|
||||||
|
printer.write("~HS");
|
||||||
|
});
|
||||||
|
|
||||||
|
// read the data from the printer
|
||||||
|
printer.on("data", async (data) => {
|
||||||
|
const res = data.toString();
|
||||||
|
|
||||||
|
// turn the data into an array to make it more easy to deal with
|
||||||
|
const tmp = res.split(",");
|
||||||
|
|
||||||
|
if (tmp[4] !== "000") {
|
||||||
|
// unpaused and printing labels - reset timer
|
||||||
|
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
||||||
|
|
||||||
|
// update last time printed in the array
|
||||||
|
printerUpdate(p, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp[4] === "000") {
|
||||||
|
// unpaused and printing labels - reset timer
|
||||||
|
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
||||||
|
|
||||||
|
// update last time printed in the array
|
||||||
|
printerUpdate(p, 5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
printer.on("error", async (error) => {
|
||||||
|
// just going to say theres an error with the printer
|
||||||
|
|
||||||
|
if (!errorCheck) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"ocp",
|
||||||
|
"ocp",
|
||||||
|
`${p.name} encountered an error: ${error}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await printerUpdate(p, 7);
|
||||||
|
errorCheck = true;
|
||||||
|
|
||||||
|
// send log data
|
||||||
|
// fake line
|
||||||
|
printer.end();
|
||||||
|
resolve({
|
||||||
|
success: false,
|
||||||
|
message: "There was an error with the printer.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ export const updatePrinters = async () => {
|
|||||||
port: prodPrinterInfo[i].port,
|
port: prodPrinterInfo[i].port,
|
||||||
remark: prodPrinterInfo[i].remark,
|
remark: prodPrinterInfo[i].remark,
|
||||||
upd_date: sql`NOW()`,
|
upd_date: sql`NOW()`,
|
||||||
|
printDelay: "90", // need to remove in a couple weeks
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import dycoClose from "./routes/specialProcesses/dyco/closeConnection.js";
|
|||||||
import manualprint from "./routes/labeling/manualPrint.js";
|
import manualprint from "./routes/labeling/manualPrint.js";
|
||||||
import { assignedPrinters } from "./utils/checkAssignments.js";
|
import { assignedPrinters } from "./utils/checkAssignments.js";
|
||||||
import { printerCycle } from "./controller/printers/printerCycle.js";
|
import { printerCycle } from "./controller/printers/printerCycle.js";
|
||||||
import { tryCatch } from "../../globalUtils/tryCatch.js";
|
import stopPrinterCycle from "./routes/printers/stopCycle.js";
|
||||||
|
import startPrinterCycle from "./routes/printers/startCycle.js";
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -24,6 +25,8 @@ const routes = [
|
|||||||
//printer
|
//printer
|
||||||
getPrinters,
|
getPrinters,
|
||||||
updateprinters,
|
updateprinters,
|
||||||
|
startPrinterCycle,
|
||||||
|
stopPrinterCycle,
|
||||||
// lots
|
// lots
|
||||||
getLots,
|
getLots,
|
||||||
// labeling
|
// labeling
|
||||||
@@ -55,21 +58,21 @@ const ocpActive = setting.filter((n) => n.name === "ocpActive");
|
|||||||
|
|
||||||
// do the intnal connection to the dyco
|
// do the intnal connection to the dyco
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (dycoActive[0].value === "1") {
|
if (dycoActive[0]?.value === "1") {
|
||||||
dycoConnect();
|
dycoConnect();
|
||||||
}
|
}
|
||||||
}, 3 * 1000);
|
}, 3 * 1000);
|
||||||
|
|
||||||
// check for printers being assigned
|
// check for printers being assigned
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (ocpActive[0].value === "1") {
|
if (ocpActive[0]?.value === "1") {
|
||||||
assignedPrinters();
|
assignedPrinters();
|
||||||
}
|
}
|
||||||
}, 60 * 1000);
|
}, 60 * 1000);
|
||||||
|
|
||||||
// start the printer process after everything else is up ad running
|
// start the printer process after everything else is up ad running
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
if (ocpActive[0].value === "1") {
|
if (ocpActive[0]?.value === "1") {
|
||||||
await updatePrinters();
|
await updatePrinters();
|
||||||
await assignedPrinters();
|
await assignedPrinters();
|
||||||
printerCycle();
|
printerCycle();
|
||||||
|
|||||||
41
server/services/ocp/routes/printers/startCycle.ts
Normal file
41
server/services/ocp/routes/printers/startCycle.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// an external way to creating logs
|
||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { authMiddleware } from "../../../auth/middleware/authMiddleware.js";
|
||||||
|
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { printerCycle } from "../../controller/printers/printerCycle.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono({ strict: false });
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["ocp:printers"],
|
||||||
|
summary: "starts the printers cycling.",
|
||||||
|
method: "get",
|
||||||
|
path: "/startsprintercycle",
|
||||||
|
middleware: authMiddleware,
|
||||||
|
//description: "This might be a temp soltuin during the transtion between versions",
|
||||||
|
// request: {
|
||||||
|
// body: {content: {"application/json": {schema: CreateLog}}},
|
||||||
|
// },
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const { data, error } = await tryCatch(printerCycle());
|
||||||
|
const dataError: any = error;
|
||||||
|
if (error) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error in stopping the printer cycle",
|
||||||
|
data: dataError?.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const getData: any = data;
|
||||||
|
return c.json({
|
||||||
|
success: getData?.success,
|
||||||
|
message: getData?.message,
|
||||||
|
data: getData.data ?? [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
41
server/services/ocp/routes/printers/stopCycle.ts
Normal file
41
server/services/ocp/routes/printers/stopCycle.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// an external way to creating logs
|
||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { authMiddleware } from "../../../auth/middleware/authMiddleware.js";
|
||||||
|
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { stopPrinterCycle } from "../../controller/printers/printerCycle.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono({ strict: false });
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["ocp:printers"],
|
||||||
|
summary: "Stops the printers cycling.",
|
||||||
|
method: "get",
|
||||||
|
path: "/stopprintercycle",
|
||||||
|
middleware: authMiddleware,
|
||||||
|
//description: "This might be a temp soltuin during the transtion between versions",
|
||||||
|
// request: {
|
||||||
|
// body: {content: {"application/json": {schema: CreateLog}}},
|
||||||
|
// },
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const { data, error } = await tryCatch(stopPrinterCycle());
|
||||||
|
const dataError: any = error;
|
||||||
|
if (error) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error in stopping the printer cycle",
|
||||||
|
data: dataError?.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const getData: any = data;
|
||||||
|
return c.json({
|
||||||
|
success: getData?.success,
|
||||||
|
message: getData?.message,
|
||||||
|
data: getData.data ?? [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
@@ -8,7 +8,7 @@ import { getPrinters } from "../controller/printers/getPrinters.js";
|
|||||||
import { createLog } from "../../logger/logger.js";
|
import { createLog } from "../../logger/logger.js";
|
||||||
|
|
||||||
export const assignedPrinters = async () => {
|
export const assignedPrinters = async () => {
|
||||||
createLog("info", "ocp", "ocp", "Lot assignment check");
|
createLog("debug", "ocp", "ocp", "Lot assignment check");
|
||||||
const { data: l, error: lotError } = await tryCatch(getLots());
|
const { data: l, error: lotError } = await tryCatch(getLots());
|
||||||
|
|
||||||
if (lotError) {
|
if (lotError) {
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ const newSettings = [
|
|||||||
|
|
||||||
// ocp
|
// ocp
|
||||||
{
|
{
|
||||||
name: "acpActive",
|
name: "ocpActive",
|
||||||
value: `1`,
|
value: `1`,
|
||||||
description: "Are we pritning on demand?",
|
description: "Are we pritning on demand?",
|
||||||
serviceBelowsTo: "ocp",
|
serviceBelowsTo: "ocp",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { createLog } from "../../logger/logger.js";
|
|||||||
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
||||||
const newSubModules = [
|
const newSubModules = [
|
||||||
{
|
{
|
||||||
name: "Silo Adjustmnet",
|
name: "Silo Adjustments",
|
||||||
moduleName: "logistics",
|
moduleName: "logistics",
|
||||||
description: "Do a silo adjustmnet",
|
description: "Do a silo adjustmnet",
|
||||||
link: "/siloAdjustments",
|
link: "/siloAdjustments",
|
||||||
|
|||||||
Reference in New Issue
Block a user