Compare commits
32 Commits
d8edfaf05f
...
6665b77e09
| Author | SHA1 | Date | |
|---|---|---|---|
| 6665b77e09 | |||
| 2e2699ab3c | |||
| bad390ec17 | |||
| efc630f5f8 | |||
| ded074a1ce | |||
| ca0b027e67 | |||
| 1282f5efe4 | |||
| 77988477f6 | |||
| 37b26c4c92 | |||
| 72e2c6ea6a | |||
| ffe80d6a58 | |||
| 9dcd07bf2a | |||
| 4a36107ebb | |||
| fb03fc83e6 | |||
| 8c522c5b72 | |||
| e9c9a84a82 | |||
| ff2ecff146 | |||
| 3757b367d5 | |||
| 4d979089cb | |||
| b1e611c7b8 | |||
| 02fdc14769 | |||
| a794943740 | |||
| c2ad046fb0 | |||
| ba2b8036b8 | |||
| 26aa9d8f80 | |||
| 663f2f436c | |||
| 88f05eaf65 | |||
| b84d6f5186 | |||
| 410790e693 | |||
| f847ce423d | |||
| 27126cca35 | |||
| 04f524419d |
@@ -1,6 +1,15 @@
|
|||||||
import {text, pgTable, numeric, index, timestamp, boolean, uuid, uniqueIndex} from "drizzle-orm/pg-core";
|
import {
|
||||||
import {createInsertSchema, createSelectSchema} from "drizzle-zod";
|
text,
|
||||||
import {z} from "zod";
|
pgTable,
|
||||||
|
numeric,
|
||||||
|
index,
|
||||||
|
timestamp,
|
||||||
|
boolean,
|
||||||
|
uuid,
|
||||||
|
uniqueIndex,
|
||||||
|
} from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
export const logs = pgTable(
|
export const logs = pgTable(
|
||||||
"logs",
|
"logs",
|
||||||
@@ -11,7 +20,7 @@ export const logs = pgTable(
|
|||||||
service: text("service").notNull().default("system"),
|
service: text("service").notNull().default("system"),
|
||||||
message: text("message").notNull(),
|
message: text("message").notNull(),
|
||||||
checked: boolean("checked").default(false),
|
checked: boolean("checked").default(false),
|
||||||
checkedAt: timestamp("checkedAt"),
|
//checkedAt: timestamp("checkedAt"),
|
||||||
created_at: timestamp("add_Date").defaultNow(),
|
created_at: timestamp("add_Date").defaultNow(),
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export type Servers = {
|
|||||||
idAddress: string;
|
idAddress: string;
|
||||||
lastUpdated: string;
|
lastUpdated: string;
|
||||||
isUpgrading: boolean;
|
isUpgrading: boolean;
|
||||||
|
lstServerPort: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ServerPage() {
|
export default function ServerPage() {
|
||||||
@@ -144,7 +145,12 @@ export default function ServerPage() {
|
|||||||
return (
|
return (
|
||||||
<TableRow key={server.server_id}>
|
<TableRow key={server.server_id}>
|
||||||
<TableCell className="font-medium">
|
<TableCell className="font-medium">
|
||||||
{server.sName}
|
<a
|
||||||
|
href={`http://${server.serverDNS}:${server.lstServerPort}`}
|
||||||
|
target={"_blank"}
|
||||||
|
>
|
||||||
|
<span>{server.sName}</span>
|
||||||
|
</a>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="font-medium">
|
<TableCell className="font-medium">
|
||||||
{server.serverDNS}
|
{server.serverDNS}
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
import {
|
|
||||||
Accordion,
|
|
||||||
AccordionContent,
|
|
||||||
AccordionItem,
|
|
||||||
AccordionTrigger,
|
|
||||||
} from "@/components/ui/accordion";
|
|
||||||
import { getUsers } from "@/utils/querys/admin/users";
|
import { getUsers } from "@/utils/querys/admin/users";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import UserCard from "./components/UserCard";
|
import UserCard from "./components/UserCard";
|
||||||
@@ -22,22 +16,13 @@ export default function UserPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="m-2 w-dvw">
|
<div className="m-2 w-dvw">
|
||||||
<Accordion type="single" collapsible>
|
{data.map((u: any) => {
|
||||||
{data.map((u: any) => {
|
return (
|
||||||
return (
|
<div>
|
||||||
<AccordionItem key={u.user_id} value={u.user_id}>
|
<UserCard user={u} />
|
||||||
<AccordionTrigger>
|
</div>
|
||||||
<span>{u.username}</span>
|
);
|
||||||
</AccordionTrigger>
|
})}
|
||||||
<AccordionContent>
|
|
||||||
<div>
|
|
||||||
<UserCard user={u} />
|
|
||||||
</div>
|
|
||||||
</AccordionContent>
|
|
||||||
</AccordionItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Accordion>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ export default function ModuleAccess(data: any) {
|
|||||||
<div className="flex flex-row flex-wrap">
|
<div className="flex flex-row flex-wrap">
|
||||||
{modules?.map((m: any) => {
|
{modules?.map((m: any) => {
|
||||||
return (
|
return (
|
||||||
<ModuleForm
|
<div key={m.module_id}>
|
||||||
key={m.module_id}
|
<ModuleForm
|
||||||
i={m}
|
module={m}
|
||||||
username={data.user.username}
|
user={data.user}
|
||||||
/>
|
refetch={data.refetch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import {
|
import {
|
||||||
@@ -10,21 +9,26 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { getUserRoles } from "@/utils/querys/admin/userRoles";
|
|
||||||
import { useForm } from "@tanstack/react-form";
|
import { useForm } from "@tanstack/react-form";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export default function ModuleForm(props: any) {
|
export default function ModuleForm(props: any) {
|
||||||
const { refetch } = useQuery(getUserRoles());
|
|
||||||
const token = localStorage.getItem("auth_token");
|
const token = localStorage.getItem("auth_token");
|
||||||
|
const role =
|
||||||
|
props.user?.moduleRoles?.filter(
|
||||||
|
(m: any) => m.module_id === props.module.module_id
|
||||||
|
)[0]?.role ?? " ";
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
defaultValues: { role: props.i.role },
|
defaultValues: {
|
||||||
|
role: role,
|
||||||
|
},
|
||||||
onSubmit: async ({ value }) => {
|
onSubmit: async ({ value }) => {
|
||||||
const data = {
|
const data: any = {
|
||||||
username: props.username,
|
username: props.user.username,
|
||||||
module: props.i.name,
|
module: props.module.name,
|
||||||
role: value.role,
|
role: value.role,
|
||||||
};
|
};
|
||||||
console.log(data);
|
console.log(data);
|
||||||
@@ -37,7 +41,7 @@ export default function ModuleForm(props: any) {
|
|||||||
|
|
||||||
if (res.data.success) {
|
if (res.data.success) {
|
||||||
toast.success(res.data.message);
|
toast.success(res.data.message);
|
||||||
refetch();
|
props.refetch();
|
||||||
form.reset();
|
form.reset();
|
||||||
} else {
|
} else {
|
||||||
res.data.message;
|
res.data.message;
|
||||||
@@ -49,71 +53,67 @@ export default function ModuleForm(props: any) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="m-2 p-1">
|
<div className="">
|
||||||
<LstCard>
|
<form
|
||||||
<p className="text-center">Module: {props.i.name}</p>
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
<p className="p-1">Current role: </p>
|
e.stopPropagation();
|
||||||
<form
|
}}
|
||||||
onSubmit={(e) => {
|
className="flex flex-row"
|
||||||
e.preventDefault();
|
>
|
||||||
e.stopPropagation();
|
<form.Field
|
||||||
|
name="role"
|
||||||
|
//listeners={{onChange: ({value})=>{}}}
|
||||||
|
children={(field) => {
|
||||||
|
return (
|
||||||
|
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||||
|
<Label htmlFor={field.name}>
|
||||||
|
Module: {props.module.name}
|
||||||
|
</Label>
|
||||||
|
<Select
|
||||||
|
value={field.state.value}
|
||||||
|
onValueChange={field.handleChange}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<SelectValue
|
||||||
|
id={field.name}
|
||||||
|
placeholder="Select Role"
|
||||||
|
/>
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>Roles</SelectLabel>
|
||||||
|
<SelectItem value="viewer">
|
||||||
|
Viewer
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="technician">
|
||||||
|
Technician
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="supervisor">
|
||||||
|
Supervisor
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="manager">
|
||||||
|
Manager
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="tester">
|
||||||
|
Tester
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="admin">
|
||||||
|
Admin
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<form.Field
|
<div className="mt-4">
|
||||||
name="role"
|
<Button type="submit" onClick={form.handleSubmit}>
|
||||||
//listeners={{onChange: ({value})=>{}}}
|
Save
|
||||||
children={(field) => {
|
</Button>
|
||||||
return (
|
</div>
|
||||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
</form>
|
||||||
<Label htmlFor={field.name}>
|
|
||||||
Select role
|
|
||||||
</Label>
|
|
||||||
<Select
|
|
||||||
value={field.state.value}
|
|
||||||
onValueChange={field.handleChange}
|
|
||||||
>
|
|
||||||
<SelectTrigger className="w-[180px]">
|
|
||||||
<SelectValue
|
|
||||||
id={field.name}
|
|
||||||
placeholder="Select Role"
|
|
||||||
/>
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Roles</SelectLabel>
|
|
||||||
<SelectItem value="viewer">
|
|
||||||
Viewer
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="technician">
|
|
||||||
Technician
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="supervisor">
|
|
||||||
Supervisor
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="manager">
|
|
||||||
Manager
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="tester">
|
|
||||||
Tester
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="admin">
|
|
||||||
Admin
|
|
||||||
</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="mt-4">
|
|
||||||
<Button type="submit" onClick={form.handleSubmit}>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</LstCard>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,12 @@ import axios from "axios";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
import { CardHeader } from "@/components/ui/card";
|
import { CardHeader } from "@/components/ui/card";
|
||||||
|
import ModuleAccess from "./ModuleAccess";
|
||||||
|
|
||||||
export default function UserCard(data: any) {
|
export default function UserCard(data: any) {
|
||||||
const token = localStorage.getItem("auth_token");
|
const token = localStorage.getItem("auth_token");
|
||||||
const { refetch } = useQuery(getUsers());
|
const { refetch } = useQuery(getUsers());
|
||||||
|
|
||||||
//console.log(modules);
|
|
||||||
//console.log(data.user);
|
|
||||||
//console.log(userRoles);
|
//console.log(userRoles);
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
...userFormOptions(data.user),
|
...userFormOptions(data.user),
|
||||||
@@ -268,13 +267,17 @@ export default function UserCard(data: any) {
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<div className="mt-4 ml-4">
|
||||||
|
<Button onClick={form.handleSubmit}>Save</Button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
<div className="mt-4">
|
|
||||||
<Button onClick={form.handleSubmit}>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col"></div>
|
<div>
|
||||||
|
<LstCard>
|
||||||
|
<ModuleAccess user={data.user} refetch={refetch} />
|
||||||
|
</LstCard>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
import {Sidebar, SidebarContent, SidebarFooter, SidebarTrigger} from "../ui/sidebar";
|
import {
|
||||||
import {ProductionSideBar} from "./side-components/production";
|
Sidebar,
|
||||||
import {Header} from "./side-components/header";
|
SidebarContent,
|
||||||
import {LogisticsSideBar} from "./side-components/logistics";
|
SidebarFooter,
|
||||||
import {QualitySideBar} from "./side-components/quality";
|
SidebarTrigger,
|
||||||
import {ForkliftSideBar} from "./side-components/forklift";
|
} from "../ui/sidebar";
|
||||||
import {EomSideBar} from "./side-components/eom";
|
import { ProductionSideBar } from "./side-components/production";
|
||||||
import {AdminSideBar} from "./side-components/admin";
|
import { Header } from "./side-components/header";
|
||||||
import {useSessionStore} from "../../lib/store/sessionStore";
|
import { LogisticsSideBar } from "./side-components/logistics";
|
||||||
import {hasAccess} from "../../utils/userAccess";
|
import { QualitySideBar } from "./side-components/quality";
|
||||||
import {moduleActive} from "../../utils/moduleActive";
|
import { ForkliftSideBar } from "./side-components/forklift";
|
||||||
import {useModuleStore} from "../../lib/store/useModuleStore";
|
import { EomSideBar } from "./side-components/eom";
|
||||||
|
import { AdminSideBar } from "./side-components/admin";
|
||||||
|
import { useSessionStore } from "../../lib/store/sessionStore";
|
||||||
|
import { hasAccess } from "../../utils/userAccess";
|
||||||
|
import { moduleActive } from "../../utils/moduleActive";
|
||||||
|
import { useModuleStore } from "../../lib/store/useModuleStore";
|
||||||
|
|
||||||
export function AppSidebar() {
|
export function AppSidebar() {
|
||||||
const {user} = useSessionStore();
|
const { user } = useSessionStore();
|
||||||
const {modules} = useModuleStore();
|
const { modules } = useModuleStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar collapsible="icon">
|
<Sidebar collapsible="icon">
|
||||||
@@ -22,19 +27,31 @@ export function AppSidebar() {
|
|||||||
{moduleActive("production") && (
|
{moduleActive("production") && (
|
||||||
<ProductionSideBar
|
<ProductionSideBar
|
||||||
user={user}
|
user={user}
|
||||||
moduleID={modules.filter((n) => n.name === "production")[0].module_id as string}
|
moduleID={
|
||||||
|
modules.filter((n) => n.name === "production")[0]
|
||||||
|
.module_id as string
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{moduleActive("logistics") && (
|
{moduleActive("logistics") && (
|
||||||
<LogisticsSideBar
|
<LogisticsSideBar
|
||||||
user={user}
|
user={user}
|
||||||
moduleID={modules.filter((n) => n.name === "logistics")[0].module_id as string}
|
moduleID={
|
||||||
|
modules.filter((n) => n.name === "logistics")[0]
|
||||||
|
.module_id as string
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{moduleActive("forklift") && hasAccess(user, "forklift", modules) && <ForkliftSideBar />}
|
{moduleActive("forklift") &&
|
||||||
{moduleActive("eom") && hasAccess(user, "eom", modules) && <EomSideBar />}
|
hasAccess(user, "forklift", modules) && <ForkliftSideBar />}
|
||||||
{moduleActive("quality") && hasAccess(user, "quality", modules) && <QualitySideBar />}
|
{moduleActive("eom") && hasAccess(user, "eom", modules) && (
|
||||||
{moduleActive("admin") && hasAccess(user, "admin", modules) && <AdminSideBar />}
|
<EomSideBar />
|
||||||
|
)}
|
||||||
|
{moduleActive("quality") &&
|
||||||
|
hasAccess(user, "quality", modules) && <QualitySideBar />}
|
||||||
|
{moduleActive("admin") && hasAccess(user, "admin", modules) && (
|
||||||
|
<AdminSideBar />
|
||||||
|
)}
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
<SidebarFooter>
|
<SidebarFooter>
|
||||||
<SidebarTrigger />
|
<SidebarTrigger />
|
||||||
|
|||||||
113
frontend/src/components/logistics/siloAdjustments/ChartData.tsx
Normal file
113
frontend/src/components/logistics/siloAdjustments/ChartData.tsx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
|
||||||
|
|
||||||
|
import { CardContent } from "@/components/ui/card";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChartConfig,
|
||||||
|
ChartContainer,
|
||||||
|
ChartTooltip,
|
||||||
|
ChartTooltipContent,
|
||||||
|
} from "@/components/ui/chart";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { getAdjustments } from "@/utils/querys/logistics/siloAdjustments/getAdjustments";
|
||||||
|
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
|
||||||
|
export default function ChartData(props: any) {
|
||||||
|
const { data, isError, isLoading } = useQuery(getAdjustments());
|
||||||
|
const chartConfig = {
|
||||||
|
stock: {
|
||||||
|
label: "Stock",
|
||||||
|
color: "rgb(255, 99, 132)",
|
||||||
|
},
|
||||||
|
actual: {
|
||||||
|
label: "Actual",
|
||||||
|
color: "rgb(53, 162, 235)",
|
||||||
|
},
|
||||||
|
} satisfies ChartConfig;
|
||||||
|
|
||||||
|
if (isLoading) return <div>Loading chart data</div>;
|
||||||
|
if (isError) return <div>Error in loading chart data</div>;
|
||||||
|
|
||||||
|
let adjustments: any = data.filter(
|
||||||
|
(l: any) => l.locationID === props.laneId
|
||||||
|
);
|
||||||
|
adjustments = adjustments.splice(0, 10).map((s: any) => {
|
||||||
|
return {
|
||||||
|
date: format(s.dateAdjusted.replace("Z", ""), "M/d/yyyy hh:mm"),
|
||||||
|
stock: s.currentStockLevel,
|
||||||
|
actual: s.newLevel,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LstCard className="w-[425px] h-[250px] m-1">
|
||||||
|
<CardContent>
|
||||||
|
{adjustments.length === 0 ? (
|
||||||
|
<span>No silo data has been entered for this silo.</span>
|
||||||
|
) : (
|
||||||
|
<ChartContainer config={chartConfig}>
|
||||||
|
<AreaChart
|
||||||
|
accessibilityLayer
|
||||||
|
data={adjustments}
|
||||||
|
margin={{
|
||||||
|
left: 35,
|
||||||
|
right: 45,
|
||||||
|
bottom: 50,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CartesianGrid vertical={false} />
|
||||||
|
<XAxis
|
||||||
|
dataKey="date"
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
tickMargin={14}
|
||||||
|
angle={-45}
|
||||||
|
textAnchor="end"
|
||||||
|
dy={10}
|
||||||
|
tickFormatter={(value) =>
|
||||||
|
format(value, "M/d/yyyy")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ChartTooltip
|
||||||
|
cursor={false}
|
||||||
|
content={
|
||||||
|
<ChartTooltipContent indicator="dot" />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Area
|
||||||
|
dataKey="stock"
|
||||||
|
type="natural"
|
||||||
|
fill="rgba(53, 162, 235, 0.5)"
|
||||||
|
fillOpacity={0.4}
|
||||||
|
stroke="rgba(53, 162, 235, 0.5)"
|
||||||
|
stackId="a"
|
||||||
|
/>
|
||||||
|
<Area
|
||||||
|
dataKey="actual"
|
||||||
|
type="natural"
|
||||||
|
fill="rgba(255, 99, 132, 0.5)"
|
||||||
|
fillOpacity={0.4}
|
||||||
|
stroke="rgba(255, 99, 132, 0.5)"
|
||||||
|
stackId="a"
|
||||||
|
/>
|
||||||
|
</AreaChart>
|
||||||
|
</ChartContainer>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
{/* <CardFooter>
|
||||||
|
<div className="flex w-full items-start gap-2 text-sm">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<div className="flex items-center gap-2 font-medium leading-none">
|
||||||
|
Trending up by 5.2% this month{" "}
|
||||||
|
<TrendingUp className="h-4 w-4" />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||||
|
January - June 2024
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardFooter> */}
|
||||||
|
</LstCard>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { getAdjustments } from "@/utils/querys/logistics/siloAdjustments/getAdjustments";
|
||||||
|
import { columns } from "@/utils/tableData/siloAdjustmentHist/siloAdjHist";
|
||||||
|
import { DataTable } from "@/utils/tableData/siloAdjustmentHist/siloDate";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
export default function HistoricalData(props: any) {
|
||||||
|
const { data, isError, isLoading } = useQuery(getAdjustments());
|
||||||
|
|
||||||
|
if (isLoading) return <div>Loading adjustmnet data...</div>;
|
||||||
|
if (isError) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>There was an error getting the adjustments.</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//console.log(data[0].locationID, parseInt(props.laneId));
|
||||||
|
const adjustments: any = data.filter(
|
||||||
|
(l: any) => l.locationID === parseInt(props.laneId)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(adjustments);
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto py-10">
|
||||||
|
<DataTable columns={columns} data={adjustments} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import {
|
|||||||
import { getStockSilo } from "@/utils/querys/logistics/siloAdjustments/getStockSilo";
|
import { getStockSilo } from "@/utils/querys/logistics/siloAdjustments/getStockSilo";
|
||||||
import { useForm } from "@tanstack/react-form";
|
import { useForm } from "@tanstack/react-form";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { CircleAlert } from "lucide-react";
|
import { CircleAlert } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import ChartData from "./ChartData";
|
||||||
|
|
||||||
export default function SiloCard(data: any) {
|
export default function SiloCard(data: any) {
|
||||||
const token = localStorage.getItem("auth_token");
|
const token = localStorage.getItem("auth_token");
|
||||||
@@ -183,9 +185,17 @@ export default function SiloCard(data: any) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
<div className="grow max-w-[400px]">
|
<div className="grow max-w-[600px]">
|
||||||
<LstCard className="m-1 ">charts go here</LstCard>
|
<ChartData laneId={silo.LocationID} />
|
||||||
<LstCard className="m-1">extra options here</LstCard>
|
|
||||||
|
<div className="flex justify-end m-1">
|
||||||
|
<Link
|
||||||
|
to={"/siloAdjustments/$hist"}
|
||||||
|
params={{ hist: silo.LocationID }}
|
||||||
|
>
|
||||||
|
Historical Data
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
|
|||||||
@@ -12,23 +12,28 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
} from "../ui/table";
|
} from "../ui/table";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { getOcmeInfo } from "@/utils/querys/production/getOcmeInfo";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { Trash } from "lucide-react";
|
||||||
|
|
||||||
const currentPallets = [
|
const currentPallets = [
|
||||||
{ key: "line", label: "Line" },
|
{ key: "line", label: "Line" },
|
||||||
{ key: "runningNr", label: "Running #" },
|
{ key: "runningNumber", label: "Running #" },
|
||||||
{ key: "upd_date", label: "Date Scanned" },
|
{ key: "upd_date", label: "Date Scanned" },
|
||||||
{ key: "waitingfor", label: "Waiting For" },
|
{ key: "waitingfor", label: "Waiting For" },
|
||||||
{ key: "clear", label: "Clear" },
|
{ key: "clear", label: "Clear" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const currentTags = [
|
// const currentTags = [
|
||||||
{ key: "line", label: "Line" },
|
// { key: "line", label: "Line" },
|
||||||
{ key: "printerName", label: "Printer" },
|
// { key: "printerName", label: "Printer" },
|
||||||
{ key: "runningNr", label: "Running #" },
|
// { key: "runningNr", label: "Running #" },
|
||||||
{ key: "upd_date", label: "Label date" },
|
// { key: "upd_date", label: "Label date" },
|
||||||
{ key: "status", label: "Label Status" },
|
// { key: "status", label: "Label Status" },
|
||||||
];
|
// ];
|
||||||
export default function WrapperManualTrigger() {
|
export default function WrapperManualTrigger() {
|
||||||
|
const { data, isError, isLoading } = useQuery(getOcmeInfo());
|
||||||
const cameraTrigger = async () => {
|
const cameraTrigger = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get("/ocme/api/v1/manualCameraTrigger");
|
const res = await axios.get("/ocme/api/v1/manualCameraTrigger");
|
||||||
@@ -46,6 +51,42 @@ export default function WrapperManualTrigger() {
|
|||||||
//stoast.success(error.data.message);
|
//stoast.success(error.data.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearLabel = async (d: any) => {
|
||||||
|
const data = {
|
||||||
|
runningNr: d.runningNr,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await axios.patch("/ocme/api/v1/pickedUp", data);
|
||||||
|
|
||||||
|
if (res.data.success) {
|
||||||
|
toast.success(
|
||||||
|
`${d.runningNr} was just removed from being picked up.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res.data.success) {
|
||||||
|
toast.error(res.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
//stoast.success(error.data.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p className="text-center text-pretty">
|
||||||
|
There was an error getting wrapper scans
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const info = data?.filter((r: any) => r.areaFrom === "wrapper_1");
|
||||||
return (
|
return (
|
||||||
<LstCard className="m-2 p-2">
|
<LstCard className="m-2 p-2">
|
||||||
<ScrollArea className="max-h-[200px]">
|
<ScrollArea className="max-h-[200px]">
|
||||||
@@ -59,71 +100,66 @@ export default function WrapperManualTrigger() {
|
|||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
{isLoading ? (
|
||||||
{Array(3)
|
<TableBody>
|
||||||
.fill(0)
|
{Array(3)
|
||||||
.map((_, i) => (
|
.fill(0)
|
||||||
<TableRow key={i}>
|
.map((_, i) => (
|
||||||
|
<TableRow key={i}>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
<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>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
<TableBody>
|
||||||
|
{info.map((i: any) => (
|
||||||
|
<TableRow key={i.runningNr}>
|
||||||
<TableCell className="font-medium">
|
<TableCell className="font-medium">
|
||||||
<Skeleton className="h-4" />
|
{i.lineNum}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>{i.runningNr}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Skeleton className="h-4" />
|
{format(
|
||||||
|
i?.upd_date.replace("Z", ""),
|
||||||
|
"M/d/yyyy hh:mm"
|
||||||
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>{i.waitingFor}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Skeleton className="h-4" />
|
<Button
|
||||||
</TableCell>
|
variant="destructive"
|
||||||
<TableCell>
|
size="icon"
|
||||||
<Skeleton className="h-4" />
|
onClick={() => clearLabel(i)}
|
||||||
</TableCell>
|
>
|
||||||
<TableCell>
|
<Trash />
|
||||||
<Skeleton className="h-4" />
|
</Button>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
)}
|
||||||
</ScrollArea>
|
|
||||||
<ScrollArea className="max-h-[200px]">
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
{currentTags.map((l) => (
|
|
||||||
<TableHead key={l.key}>{l.label}</TableHead>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{Array(3)
|
|
||||||
.fill(0)
|
|
||||||
.map((_, i) => (
|
|
||||||
<TableRow key={i}>
|
|
||||||
<TableCell className="font-medium">
|
|
||||||
<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>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
</Table>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<hr />
|
<hr />
|
||||||
<p className="text-center mb-3">Manual Triggers</p>
|
<p className="text-center mb-3">Manual Trigger</p>
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex flex-row justify-between">
|
||||||
<Button onClick={cameraTrigger}>Camera</Button>
|
<Button onClick={cameraTrigger}>Camera</Button>
|
||||||
<Button>Rfid</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ export default function OcmeCycleCount() {
|
|||||||
{data.map((i: any) => {
|
{data.map((i: any) => {
|
||||||
let classname = ``;
|
let classname = ``;
|
||||||
if (
|
if (
|
||||||
i.info === "Quality Check Required"
|
i.info === "Validate pallet is ok."
|
||||||
) {
|
) {
|
||||||
classname = `bg-red-500`;
|
classname = `bg-red-500`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
TableFooter,
|
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
@@ -26,17 +25,13 @@ const labelLogs = [
|
|||||||
];
|
];
|
||||||
export default function LabelLog() {
|
export default function LabelLog() {
|
||||||
const { data, isError, isLoading } = useQuery(getlabels("4"));
|
const { data, isError, isLoading } = useQuery(getlabels("4"));
|
||||||
//const {user} = useSessionStore();
|
|
||||||
//const {settings} = useSettingStore();
|
|
||||||
//const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
|
||||||
|
|
||||||
//const roles = ["admin", "manager", "operator"];
|
|
||||||
|
|
||||||
if (isError) {
|
if (isError) {
|
||||||
return (
|
return (
|
||||||
<div className="m-2 p-2 min-h-2/5">
|
<div className="m-2 p-2 min-h-2/5">
|
||||||
<LstCard>
|
<LstCard>
|
||||||
<p className="text-center">Labels for the last 2 hours</p>
|
<p className="text-center">Labels for the last 2 hours</p>
|
||||||
|
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
@@ -77,7 +72,13 @@ export default function LabelLog() {
|
|||||||
const labelData = data ? data : [];
|
const labelData = data ? data : [];
|
||||||
return (
|
return (
|
||||||
<LstCard className="m-2 p-2 min-h-2/5">
|
<LstCard className="m-2 p-2 min-h-2/5">
|
||||||
<p className="text-center">Labels for the last 2 hours</p>
|
<p className="text-center">
|
||||||
|
{labelData.length === 0 ? (
|
||||||
|
<span>No labels have been printed in the last 2 hours</span>
|
||||||
|
) : (
|
||||||
|
<span>Labels for the last 2 hours</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
@@ -115,7 +116,7 @@ export default function LabelLog() {
|
|||||||
) : (
|
) : (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{labelData.map((label: any) => (
|
{labelData.map((label: any) => (
|
||||||
<TableRow key={label.runningNr}>
|
<TableRow key={label.label_id}>
|
||||||
<TableCell className="font-medium">
|
<TableCell className="font-medium">
|
||||||
{label.line}
|
{label.line}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -139,15 +140,15 @@ export default function LabelLog() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TableFooter>
|
{/* <TableFooter>
|
||||||
{labelData.length === 0 && (
|
{labelData.length === 0 && (
|
||||||
<div>
|
<div className="flex justify-center">
|
||||||
<h2 className="text-center text-2xl">
|
<h2 className="text-center text-2xl">
|
||||||
No labels have been printed in the last 2 hours
|
No labels have been printed in the last 2 hours
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</TableFooter>
|
</TableFooter> */}
|
||||||
</Table>
|
</Table>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,31 +1,43 @@
|
|||||||
import {Button} from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {useSessionStore} from "@/lib/store/sessionStore";
|
import { useSessionStore } from "@/lib/store/sessionStore";
|
||||||
//import {useSettingStore} from "@/lib/store/useSettings";
|
//import {useSettingStore} from "@/lib/store/useSettings";
|
||||||
import {LotType} from "@/types/lots";
|
import { LotType } from "@/types/lots";
|
||||||
import {Tag} from "lucide-react";
|
import { Tag } from "lucide-react";
|
||||||
import {toast} from "sonner";
|
import { toast } from "sonner";
|
||||||
import {manualPrintLabels} from "./ManualPrintLabel";
|
import { manualPrintLabels } from "./ManualPrintLabel";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
export default function ManualPrint({lot}: {lot: LotType}) {
|
export default function ManualPrint({ lot }: { lot: LotType }) {
|
||||||
const {user} = useSessionStore();
|
const { user } = useSessionStore();
|
||||||
|
const [printing, setPrinting] = useState(false);
|
||||||
//const {settings} = useSettingStore();
|
//const {settings} = useSettingStore();
|
||||||
//const server = settings.filter((n) => n.name === "server")[0]?.value;
|
//const server = settings.filter((n) => n.name === "server")[0]?.value;
|
||||||
//const serverPort = settings.filter((n) => n.name === "serverPort")[0]?.value;
|
//const serverPort = settings.filter((n) => n.name === "serverPort")[0]?.value;
|
||||||
//const serverUrl = `http://${server}:${serverPort}`;
|
//const serverUrl = `http://${server}:${serverPort}`;
|
||||||
|
|
||||||
const handlePrintLabel = async (lot: LotType) => {
|
const handlePrintLabel = async (lot: LotType) => {
|
||||||
//console.log(lot);
|
|
||||||
|
|
||||||
const labels: any = await manualPrintLabels(lot, user);
|
const labels: any = await manualPrintLabels(lot, user);
|
||||||
|
|
||||||
if (labels.success) {
|
if (labels.success) {
|
||||||
toast.success(labels.message);
|
toast.success(labels.message);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPrinting(false);
|
||||||
|
}, 5 * 1000);
|
||||||
|
setPrinting(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error(labels.message);
|
toast.error(labels.message);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPrinting(false);
|
||||||
|
}, 5 * 1000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Button variant="outline" size="icon" onClick={() => handlePrintLabel(lot)}>
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => handlePrintLabel(lot)}
|
||||||
|
disabled={printing}
|
||||||
|
>
|
||||||
<Tag className="h-[16px] w-[16px]" />
|
<Tag className="h-[16px] w-[16px]" />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -86,7 +86,13 @@ export default function OcpLogs() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<LstCard className="m-2 p-2 min-h-2/5">
|
<LstCard className="m-2 p-2 min-h-2/5">
|
||||||
<p className="text-center">Labels for the last 2 hours</p>
|
<p className="text-center">
|
||||||
|
{data?.length === 0 ? (
|
||||||
|
<span>No errors in the last 4 hours</span>
|
||||||
|
) : (
|
||||||
|
<span>Logs for the last 4 hours</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import WrapperManualTrigger from "@/components/ocme/WrapperCard";
|
import WrapperManualTrigger from "@/components/ocme/WrapperCard";
|
||||||
import LabelLog from "./LabelLog";
|
|
||||||
import Lots from "./Lots";
|
import Lots from "./Lots";
|
||||||
import OcpLogs from "./OcpLogs";
|
import OcpLogs from "./OcpLogs";
|
||||||
import PrinterStatus from "./PrinterStatus";
|
import PrinterStatus from "./PrinterStatus";
|
||||||
import { useSettingStore } from "@/lib/store/useSettings";
|
import { useSettingStore } from "@/lib/store/useSettings";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import LabelLog from "./LabelLog";
|
||||||
|
|
||||||
export default function OCPPage() {
|
export default function OCPPage() {
|
||||||
const { settings } = useSettingStore();
|
const { settings } = useSettingStore();
|
||||||
|
|
||||||
const server = settings.filter((n) => n.plantToken === "usday1");
|
let server = settings.filter((n) => n.name === "server");
|
||||||
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-row gap-2">
|
||||||
<div className="flex flex-col w-4/5 h-dvh">
|
<div className="flex flex-col w-4/5 h-dvh">
|
||||||
<div className="">
|
<div className="">
|
||||||
<Lots />
|
<Lots />
|
||||||
@@ -33,15 +33,18 @@ export default function OCPPage() {
|
|||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="labels">
|
<TabsContent value="labels">
|
||||||
<div className="w-full">
|
<LabelLog />
|
||||||
<LabelLog />
|
|
||||||
</div>
|
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-1/6 flex flex-col">
|
<div className="flex flex-col">
|
||||||
{server.length >= 1 && (
|
{server[0].value === "usday1vms006" && (
|
||||||
|
<div>
|
||||||
|
<WrapperManualTrigger />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{server[0].value === "localhost" && (
|
||||||
<div>
|
<div>
|
||||||
<WrapperManualTrigger />
|
<WrapperManualTrigger />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default function PrinterStatus() {
|
|||||||
<TableHead key={l.key}>{l.label}</TableHead>
|
<TableHead key={l.key}>{l.label}</TableHead>
|
||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>{" "}
|
</TableHeader>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{Array(5)
|
{Array(5)
|
||||||
|
|||||||
@@ -19,12 +19,18 @@ export const useGetUserRoles = create<SettingState>()((set) => ({
|
|||||||
try {
|
try {
|
||||||
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
|
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
|
||||||
const token = localStorage.getItem("auth_token");
|
const token = localStorage.getItem("auth_token");
|
||||||
const response = await axios.get("/api/auth/getuseraccess", {
|
if (token) {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
const response = await axios.get("/api/auth/getuseraccess", {
|
||||||
});
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
const data: FetchModulesResponse = response.data; //await response.json();
|
});
|
||||||
//console.log(data);
|
const data: FetchModulesResponse = response.data; //await response.json();
|
||||||
set({ userRoles: data.data });
|
|
||||||
|
//console.log(data);
|
||||||
|
set({ userRoles: data.data });
|
||||||
|
} else {
|
||||||
|
//console.log(data);
|
||||||
|
set({ userRoles: [] });
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch settings:", error);
|
console.error("Failed to fetch settings:", error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import HistoricalData from "@/components/logistics/siloAdjustments/HistoricalData";
|
||||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||||
|
|
||||||
export const Route = createFileRoute("/(logistics)/siloAdjustments/$hist")({
|
export const Route = createFileRoute("/(logistics)/siloAdjustments/$hist")({
|
||||||
@@ -22,10 +23,10 @@ export const Route = createFileRoute("/(logistics)/siloAdjustments/$hist")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function RouteComponent() {
|
function RouteComponent() {
|
||||||
|
const { hist } = Route.useParams();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
Hello "/(logistics)/siloAdjustments/$hist"! where the historical
|
<HistoricalData laneId={hist} />
|
||||||
data will be shown in a table alone with a graph
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export function getUsers() {
|
|||||||
queryFn: () => fetchUsers(token),
|
queryFn: () => fetchUsers(token),
|
||||||
enabled: !!token, // Prevents query if token is null
|
enabled: !!token, // Prevents query if token is null
|
||||||
staleTime: 1000,
|
staleTime: 1000,
|
||||||
//refetchInterval: 2 * 2000,
|
refetchInterval: 2 * 2000,
|
||||||
refetchOnWindowFocus: true,
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { queryOptions } from "@tanstack/react-query";
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export function getStockSilo() {
|
export function getAdjustments() {
|
||||||
const token = localStorage.getItem("auth_token");
|
const token = localStorage.getItem("auth_token");
|
||||||
return queryOptions({
|
return queryOptions({
|
||||||
queryKey: ["getUsers"],
|
queryKey: ["getAdjustments"],
|
||||||
queryFn: () => fetchStockSilo(token),
|
queryFn: () => fetchStockSilo(token),
|
||||||
enabled: !!token, // Prevents query if token is null
|
enabled: !!token, // Prevents query if token is null
|
||||||
staleTime: 1000,
|
staleTime: 1000,
|
||||||
//refetchInterval: 2 * 2000,
|
refetchInterval: 2 * 2000,
|
||||||
refetchOnWindowFocus: true,
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
19
frontend/src/utils/querys/production/getOcmeInfo.tsx
Normal file
19
frontend/src/utils/querys/production/getOcmeInfo.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export function getOcmeInfo() {
|
||||||
|
return queryOptions({
|
||||||
|
queryKey: ["ocmeInfo"],
|
||||||
|
queryFn: () => fetchSettings(),
|
||||||
|
staleTime: 1000,
|
||||||
|
refetchInterval: 2 * 2000,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchSettings = async () => {
|
||||||
|
const { data } = await axios.get(`/ocme/api/v1/getInfo`);
|
||||||
|
// if we are not localhost ignore the devDir setting.
|
||||||
|
//const url: string = window.location.host.split(":")[0];
|
||||||
|
return data.data ?? [];
|
||||||
|
};
|
||||||
@@ -6,7 +6,7 @@ export function getlabels(hours: string) {
|
|||||||
queryKey: ["labels"],
|
queryKey: ["labels"],
|
||||||
queryFn: () => fetchSettings(hours),
|
queryFn: () => fetchSettings(hours),
|
||||||
|
|
||||||
staleTime: 1000,
|
//staleTime: 1000,
|
||||||
refetchInterval: 2 * 2000,
|
refetchInterval: 2 * 2000,
|
||||||
refetchOnWindowFocus: true,
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function getOcpLogs(hours: string) {
|
|||||||
|
|
||||||
const fetchSettings = async (hours: string) => {
|
const fetchSettings = async (hours: string) => {
|
||||||
const { data } = await axios.get(
|
const { data } = await axios.get(
|
||||||
`/api/logger/logs?service=ocp&service=rfid&level=error&level=warn&hours=${hours}`
|
`/api/logger/logs?service=ocp&service=rfid&service=dyco&level=error&level=warn&hours=${hours}`
|
||||||
);
|
);
|
||||||
// if we are not localhost ignore the devDir setting.
|
// if we are not localhost ignore the devDir setting.
|
||||||
//const url: string = window.location.host.split(":")[0];
|
//const url: string = window.location.host.split(":")[0];
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import { ColumnDef } from "@tanstack/react-table";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
|
||||||
|
// This type is used to define the shape of our data.
|
||||||
|
// You can use a Zod schema here if you want.
|
||||||
|
export type Adjustmnets = {
|
||||||
|
siloAdjust_id: string;
|
||||||
|
currentStockLevel: string;
|
||||||
|
newLevel: number;
|
||||||
|
dateAdjusted: string;
|
||||||
|
lastDateAdjusted: string;
|
||||||
|
comment: string;
|
||||||
|
commentAddedBy: string;
|
||||||
|
commentDate: string;
|
||||||
|
add_user: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columns: ColumnDef<Adjustmnets>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "currentStockLevel",
|
||||||
|
header: () => <div className="text-right">Stock At Post</div>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "newLevel",
|
||||||
|
header: "Level Entered",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "dateAdjusted",
|
||||||
|
header: "Adjustmnet",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
if (row.getValue("dateAdjusted")) {
|
||||||
|
const correctDate = format(
|
||||||
|
row.original.dateAdjusted?.replace("Z", ""),
|
||||||
|
"M/d/yyyy hh:mm"
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div className="text-right font-medium">{correctDate}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "lastDateAdjusted",
|
||||||
|
header: "Last Adjusted",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
if (row.getValue("lastDateAdjusted")) {
|
||||||
|
const correctDate = format(
|
||||||
|
row.original.lastDateAdjusted?.replace("Z", ""),
|
||||||
|
"M/d/yyyy hh:mm"
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div className="text-right font-medium">{correctDate}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "comment",
|
||||||
|
header: "Comment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "commentAddedBy",
|
||||||
|
header: "Commenter ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "commentDate",
|
||||||
|
header: "Comment Date ",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
if (row.getValue("commentDate")) {
|
||||||
|
const correctDate = format(
|
||||||
|
row.original.commentDate?.replace("Z", ""),
|
||||||
|
"M/d/yyyy hh:mm"
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div className="text-right font-medium">{correctDate}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "add_user",
|
||||||
|
header: "Creator",
|
||||||
|
},
|
||||||
|
];
|
||||||
110
frontend/src/utils/tableData/siloAdjustmentHist/siloDate.tsx
Normal file
110
frontend/src/utils/tableData/siloAdjustmentHist/siloDate.tsx
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import {
|
||||||
|
ColumnDef,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
useReactTable,
|
||||||
|
getPaginationRowModel,
|
||||||
|
} from "@tanstack/react-table";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
interface DataTableProps<TData, TValue> {
|
||||||
|
columns: ColumnDef<TData, TValue>[];
|
||||||
|
data: TData[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DataTable<TData, TValue>({
|
||||||
|
columns,
|
||||||
|
data,
|
||||||
|
}: DataTableProps<TData, TValue>) {
|
||||||
|
const table = useReactTable({
|
||||||
|
data,
|
||||||
|
columns,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
});
|
||||||
|
//console.log(data);
|
||||||
|
return (
|
||||||
|
<div className="rounded-md border w-[1028px]">
|
||||||
|
<div>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
<TableRow key={headerGroup.id}>
|
||||||
|
{headerGroup.headers.map((header) => {
|
||||||
|
return (
|
||||||
|
<TableHead key={header.id}>
|
||||||
|
{header.isPlaceholder
|
||||||
|
? null
|
||||||
|
: flexRender(
|
||||||
|
header.column.columnDef
|
||||||
|
.header,
|
||||||
|
header.getContext()
|
||||||
|
)}
|
||||||
|
</TableHead>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{table.getRowModel().rows?.length ? (
|
||||||
|
table.getRowModel().rows.map((row) => (
|
||||||
|
<TableRow
|
||||||
|
key={row.id}
|
||||||
|
data-state={
|
||||||
|
row.getIsSelected() && "selected"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCell key={cell.id}>
|
||||||
|
{flexRender(
|
||||||
|
cell.column.columnDef.cell,
|
||||||
|
cell.getContext()
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell
|
||||||
|
colSpan={columns.length}
|
||||||
|
className="h-24 text-center"
|
||||||
|
>
|
||||||
|
No results.
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-end space-x-2 py-4">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => table.previousPage()}
|
||||||
|
disabled={!table.getCanPreviousPage()}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,25 +1,44 @@
|
|||||||
import {Modules} from "@/types/modules";
|
import { Modules } from "@/types/modules";
|
||||||
import {User} from "@/types/users";
|
import { User } from "@/types/users";
|
||||||
|
|
||||||
// user will need access to the module.
|
// user will need access to the module.
|
||||||
// users role will determine there visual access
|
// users role will determine there visual access
|
||||||
export function hasAccess(user: User | null, moduleName: string | null, modules: Modules[]): boolean {
|
export function hasAccess(
|
||||||
|
user: User | null,
|
||||||
|
moduleName: string | null,
|
||||||
|
modules: Modules[]
|
||||||
|
): boolean {
|
||||||
// get the modules for the id
|
// get the modules for the id
|
||||||
const filteredModule = modules?.filter((f) => f.name === moduleName);
|
const filteredModule = modules?.filter((f) => f.name === moduleName);
|
||||||
//console.log(filteredModule[0].module_id);
|
//console.log(filteredModule[0]);
|
||||||
// userroles and filter out by the module id,
|
// userroles and filter out by the module id,
|
||||||
|
|
||||||
return user?.roles.find((role) => role.module_id === filteredModule[0].module_id) ? true : false;
|
const roleCheck: any = user?.roles.find(
|
||||||
|
(role) => role.module_id === filteredModule[0].module_id
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filteredModule[0].roles.includes(roleCheck?.role)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//if(filteredModule[0].roles.includes(roleCheck.))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasPageAccess(user: User | null, role: any, module_id: string): boolean {
|
export function hasPageAccess(
|
||||||
|
user: User | null,
|
||||||
|
role: any,
|
||||||
|
module_id: string
|
||||||
|
): boolean {
|
||||||
if (role.includes("viewer")) return true;
|
if (role.includes("viewer")) return true;
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
|
|
||||||
// get only the module in the user profile
|
// get only the module in the user profile
|
||||||
|
//console.log(user);
|
||||||
const userRole = user?.roles.filter((role) => role.module_id === module_id);
|
const userRole = user?.roles.filter((role) => role.module_id === module_id);
|
||||||
|
console.log(userRole[0]?.role);
|
||||||
|
// if (role.includes(userRole[0]?.role)) {
|
||||||
|
|
||||||
if (role.includes(userRole[0]?.role)) return true;
|
// return true};
|
||||||
|
if (userRole.length !== 0) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
34
package-lock.json
generated
34
package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"@hono/zod-openapi": "^0.19.2",
|
"@hono/zod-openapi": "^0.19.2",
|
||||||
"@scalar/hono-api-reference": "^0.7.2",
|
"@scalar/hono-api-reference": "^0.7.2",
|
||||||
"@tanstack/react-form": "^1.2.1",
|
"@tanstack/react-form": "^1.2.1",
|
||||||
|
"@tanstack/react-table": "^8.21.2",
|
||||||
"@types/jsonwebtoken": "^9.0.9",
|
"@types/jsonwebtoken": "^9.0.9",
|
||||||
"@types/nodemailer-express-handlebars": "^4.0.5",
|
"@types/nodemailer-express-handlebars": "^4.0.5",
|
||||||
"adm-zip": "^0.5.16",
|
"adm-zip": "^0.5.16",
|
||||||
@@ -1788,6 +1789,26 @@
|
|||||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tanstack/react-table": {
|
||||||
|
"version": "8.21.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
|
||||||
|
"integrity": "sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@tanstack/table-core": "8.21.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tanstack/store": {
|
"node_modules/@tanstack/store": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.0.tgz",
|
||||||
@@ -1798,6 +1819,19 @@
|
|||||||
"url": "https://github.com/sponsors/tannerlinsley"
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tanstack/table-core": {
|
||||||
|
"version": "8.21.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.2.tgz",
|
||||||
|
"integrity": "sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tediousjs/connection-string": {
|
"node_modules/@tediousjs/connection-string": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-0.5.0.tgz",
|
||||||
|
|||||||
177
package.json
177
package.json
@@ -1,91 +1,92 @@
|
|||||||
{
|
{
|
||||||
"name": "lstv2",
|
"name": "lstv2",
|
||||||
"version": "2.13.0",
|
"version": "2.13.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
||||||
"dev:server": "dotenvx run -f .env -- tsx watch server/index.ts",
|
"dev:server": "dotenvx run -f .env -- tsx watch server/index.ts",
|
||||||
"dev:frontend": "cd frontend && npm run dev",
|
"dev:frontend": "cd frontend && npm run dev",
|
||||||
"dev:dbgen": " drizzle-kit generate --config=drizzle-dev.config.ts",
|
"dev:dbgen": " drizzle-kit generate --config=drizzle-dev.config.ts",
|
||||||
"dev:dbmigrate": " drizzle-kit migrate --config=drizzle-dev.config.ts",
|
"dev:dbmigrate": " drizzle-kit migrate --config=drizzle-dev.config.ts",
|
||||||
"build": "npm run build:server && npm run build:frontend",
|
"build": "npm run build:server && npm run build:frontend",
|
||||||
"build:server": "rimraf dist && tsc --build && npm run copy:scripts && xcopy server\\services\\notifications\\utils\\views\\ dist\\server\\services\\notifications\\utils\\views\\ /E /I /Y",
|
"build:server": "rimraf dist && tsc --build && npm run copy:scripts && xcopy server\\services\\notifications\\utils\\views\\ dist\\server\\services\\notifications\\utils\\views\\ /E /I /Y",
|
||||||
"build:frontend": "cd frontend && npm run build",
|
"build:frontend": "cd frontend && npm run build",
|
||||||
"copy:scripts": "tsx server/scripts/copyScripts.ts",
|
"copy:scripts": "tsx server/scripts/copyScripts.ts",
|
||||||
"copy:servers": "xcopy server\\services\\server\\utils\\serverData.json dist\\server\\services\\server\\utils /E /I /Y",
|
"copy:servers": "xcopy server\\services\\server\\utils\\serverData.json dist\\server\\services\\server\\utils /E /I /Y",
|
||||||
"start": "set NODE_ENV=production && npm run start:server",
|
"start": "set NODE_ENV=production && npm run start:server",
|
||||||
"start:server": "dotenvx run -f .env -- node dist/server/index.js",
|
"start:server": "dotenvx run -f .env -- node dist/server/index.js",
|
||||||
"db:generate": "npx drizzle-kit generate",
|
"db:generate": "npx drizzle-kit generate",
|
||||||
"db:migrate": "npx drizzle-kit push",
|
"db:migrate": "npx drizzle-kit push",
|
||||||
"db:dev": "npm run build && npm run db:generate && npm run db:migrate",
|
"db:dev": "npm run build && npm run db:generate && npm run db:migrate",
|
||||||
"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",
|
||||||
"scriptBuild": "powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\"",
|
"scriptBuild": "powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\"",
|
||||||
"removeOld": "rimraf dist && rimraf frontend/dist",
|
"removeOld": "rimraf dist && rimraf frontend/dist",
|
||||||
"prodBuild": "npm run v1Build && npm run build && npm run zipServer && npm run dev",
|
"prodBuild": "npm run v1Build && npm run build && npm run zipServer && npm run dev",
|
||||||
"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",
|
||||||
"testingCode": "dotenvx run -f .env -- tsx watch server/services/logistics/controller/siloAdjustments/migrateAdjustments.ts"
|
"testingCode": "dotenvx run -f .env -- tsx watch server/services/logistics/controller/warehouse/cycleCountChecks/cyclecountCheck.ts"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"commitizen": {
|
"commitizen": {
|
||||||
"path": "./node_modules/cz-conventional-changelog"
|
"path": "./node_modules/cz-conventional-changelog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admConfig": {
|
||||||
|
"build": 207,
|
||||||
|
"oldBuild": "backend-0.1.3.zip"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/adm-zip": "^0.5.7",
|
||||||
|
"@types/bcrypt": "^5.0.2",
|
||||||
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
"@types/mssql": "^9.1.7",
|
||||||
|
"@types/node": "^22.13.11",
|
||||||
|
"@types/node-cron": "^3.0.11",
|
||||||
|
"@types/nodemailer": "^6.4.17",
|
||||||
|
"@types/pg": "^8.11.11",
|
||||||
|
"@types/ws": "^8.18.0",
|
||||||
|
"concurrently": "^9.1.2",
|
||||||
|
"cz-conventional-changelog": "^3.3.0",
|
||||||
|
"standard-version": "^9.5.0",
|
||||||
|
"tsx": "^4.19.3",
|
||||||
|
"typescript": "^5.8.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dotenvx/dotenvx": "^1.39.0",
|
||||||
|
"@hono/node-server": "^1.14.0",
|
||||||
|
"@hono/zod-openapi": "^0.19.2",
|
||||||
|
"@scalar/hono-api-reference": "^0.7.2",
|
||||||
|
"@tanstack/react-form": "^1.2.1",
|
||||||
|
"@tanstack/react-table": "^8.21.2",
|
||||||
|
"@types/jsonwebtoken": "^9.0.9",
|
||||||
|
"@types/nodemailer-express-handlebars": "^4.0.5",
|
||||||
|
"adm-zip": "^0.5.16",
|
||||||
|
"axios": "^1.8.4",
|
||||||
|
"bcryptjs": "^3.0.2",
|
||||||
|
"croner": "^9.0.0",
|
||||||
|
"date-fns": "^4.1.0",
|
||||||
|
"date-fns-tz": "^3.2.0",
|
||||||
|
"drizzle-kit": "^0.30.5",
|
||||||
|
"drizzle-orm": "^0.41.0",
|
||||||
|
"drizzle-zod": "^0.7.0",
|
||||||
|
"fast-xml-parser": "^5.0.9",
|
||||||
|
"fs-extra": "^11.3.0",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"mssql": "^11.0.1",
|
||||||
|
"nodemailer": "^6.10.0",
|
||||||
|
"nodemailer-express-handlebars": "^7.0.0",
|
||||||
|
"pg": "^8.14.1",
|
||||||
|
"pino": "^9.6.0",
|
||||||
|
"pino-abstract-transport": "^2.0.0",
|
||||||
|
"pino-pretty": "^13.0.0",
|
||||||
|
"postgres": "^3.4.5",
|
||||||
|
"rimraf": "^6.0.1",
|
||||||
|
"st-ethernet-ip": "^2.7.3",
|
||||||
|
"ws": "^8.18.1",
|
||||||
|
"zod": "^3.24.2"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"admConfig": {
|
|
||||||
"build": 181,
|
|
||||||
"oldBuild": "backend-0.1.3.zip"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/adm-zip": "^0.5.7",
|
|
||||||
"@types/bcrypt": "^5.0.2",
|
|
||||||
"@types/fs-extra": "^11.0.4",
|
|
||||||
"@types/js-cookie": "^3.0.6",
|
|
||||||
"@types/mssql": "^9.1.7",
|
|
||||||
"@types/node": "^22.13.11",
|
|
||||||
"@types/node-cron": "^3.0.11",
|
|
||||||
"@types/nodemailer": "^6.4.17",
|
|
||||||
"@types/pg": "^8.11.11",
|
|
||||||
"@types/ws": "^8.18.0",
|
|
||||||
"concurrently": "^9.1.2",
|
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
|
||||||
"standard-version": "^9.5.0",
|
|
||||||
"tsx": "^4.19.3",
|
|
||||||
"typescript": "^5.8.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@dotenvx/dotenvx": "^1.39.0",
|
|
||||||
"@hono/node-server": "^1.14.0",
|
|
||||||
"@hono/zod-openapi": "^0.19.2",
|
|
||||||
"@scalar/hono-api-reference": "^0.7.2",
|
|
||||||
"@tanstack/react-form": "^1.2.1",
|
|
||||||
"@types/jsonwebtoken": "^9.0.9",
|
|
||||||
"@types/nodemailer-express-handlebars": "^4.0.5",
|
|
||||||
"adm-zip": "^0.5.16",
|
|
||||||
"axios": "^1.8.4",
|
|
||||||
"bcryptjs": "^3.0.2",
|
|
||||||
"croner": "^9.0.0",
|
|
||||||
"date-fns": "^4.1.0",
|
|
||||||
"date-fns-tz": "^3.2.0",
|
|
||||||
"drizzle-kit": "^0.30.5",
|
|
||||||
"drizzle-orm": "^0.41.0",
|
|
||||||
"drizzle-zod": "^0.7.0",
|
|
||||||
"fast-xml-parser": "^5.0.9",
|
|
||||||
"fs-extra": "^11.3.0",
|
|
||||||
"jsonwebtoken": "^9.0.2",
|
|
||||||
"mssql": "^11.0.1",
|
|
||||||
"nodemailer": "^6.10.0",
|
|
||||||
"nodemailer-express-handlebars": "^7.0.0",
|
|
||||||
"pg": "^8.14.1",
|
|
||||||
"pino": "^9.6.0",
|
|
||||||
"pino-abstract-transport": "^2.0.0",
|
|
||||||
"pino-pretty": "^13.0.0",
|
|
||||||
"postgres": "^3.4.5",
|
|
||||||
"rimraf": "^6.0.1",
|
|
||||||
"st-ethernet-ip": "^2.7.3",
|
|
||||||
"ws": "^8.18.1",
|
|
||||||
"zod": "^3.24.2"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,42 @@
|
|||||||
import { db } from "../../../../../database/dbclient.js";
|
import { db } from "../../../../../database/dbclient.js";
|
||||||
|
import { userRoles } from "../../../../../database/schema/userRoles.js";
|
||||||
import { users } from "../../../../../database/schema/users.js";
|
import { users } from "../../../../../database/schema/users.js";
|
||||||
import { returnRes } from "../../../../globalUtils/routeDefs/returnRes.js";
|
import { returnRes } from "../../../../globalUtils/routeDefs/returnRes.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";
|
||||||
|
|
||||||
export const getAllUsers = async () => {
|
export const getAllUsers = async () => {
|
||||||
/**
|
/**
|
||||||
* returns all users that are in lst
|
* returns all users that are in lst
|
||||||
*/
|
*/
|
||||||
createLog("info", "apiAuthedRoute", "auth", "Get all users");
|
createLog("info", "apiAuthedRoute", "auth", "Get all users");
|
||||||
const { data, error } = await tryCatch(db.select().from(users));
|
|
||||||
|
|
||||||
if (error) {
|
// get all users
|
||||||
returnRes(
|
const { data, error } = await tryCatch(db.select().from(users));
|
||||||
false,
|
|
||||||
"There was an error getting users",
|
|
||||||
new Error("No user exists.")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
returnRes(true, "All users.", data);
|
// add there modules they are in
|
||||||
return { success: true, message: "All users", data };
|
const { data: m, error: em } = await tryCatch(db.select().from(userRoles));
|
||||||
|
|
||||||
|
const user: any = data;
|
||||||
|
const userData = user.map((i: any) => {
|
||||||
|
// module in
|
||||||
|
const module = m?.filter((x: any) => x.user_id === i.user_id);
|
||||||
|
|
||||||
|
if (module) {
|
||||||
|
return { ...i, moduleRoles: module };
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
returnRes(
|
||||||
|
false,
|
||||||
|
"There was an error getting users",
|
||||||
|
new Error("No user exists.")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//returnRes(true, "All users.", data);
|
||||||
|
return { success: true, message: "All users", data: userData };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,12 +54,18 @@ export const setUserAccess = async (
|
|||||||
|
|
||||||
// set the user
|
// set the user
|
||||||
try {
|
try {
|
||||||
const userRole = await db.insert(userRoles).values({
|
const userRole = await db
|
||||||
user_id: user[0].user_id,
|
.insert(userRoles)
|
||||||
role_id: role[0].role_id,
|
.values({
|
||||||
module_id: module[0].module_id,
|
user_id: user[0].user_id,
|
||||||
role: roleName,
|
role_id: role[0].role_id,
|
||||||
});
|
module_id: module[0].module_id,
|
||||||
|
role: roleName,
|
||||||
|
})
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: userRoles.user_id,
|
||||||
|
set: { role_id: role[0].role_id, role: roleName },
|
||||||
|
});
|
||||||
//.returning({user: users.username, email: users.email});
|
//.returning({user: users.username, email: users.email});
|
||||||
|
|
||||||
// return c.json({message: "User Registered", user}, 200);
|
// return c.json({message: "User Registered", user}, 200);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ app.openapi(
|
|||||||
{
|
{
|
||||||
success: access.success,
|
success: access.success,
|
||||||
message: access.message,
|
message: access.message,
|
||||||
data: access.data,
|
data: [], //access?.data,
|
||||||
},
|
},
|
||||||
200
|
200
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {eq, sql} from "drizzle-orm";
|
import { eq, sql } from "drizzle-orm";
|
||||||
import {db} from "../../../../database/dbclient.js";
|
import { db } from "../../../../database/dbclient.js";
|
||||||
import {logs} from "../../../../database/schema/logs.js";
|
import { logs } from "../../../../database/schema/logs.js";
|
||||||
import {createLog} from "../logger.js";
|
import { createLog } from "../logger.js";
|
||||||
|
|
||||||
export const clearLog = async (id: string) => {
|
export const clearLog = async (id: string) => {
|
||||||
/**
|
/**
|
||||||
@@ -10,13 +10,21 @@ export const clearLog = async (id: string) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const clear = await db
|
const clear = await db
|
||||||
.update(logs)
|
.update(logs)
|
||||||
.set({checked: true, checkedAt: sql`NOW()`})
|
.set({ checked: true, created_at: sql`NOW()` })
|
||||||
.where(eq(logs.log_id, id));
|
.where(eq(logs.log_id, id));
|
||||||
createLog("info", "lst", "logger", "Log just cleared.");
|
createLog("info", "lst", "logger", "Log just cleared.");
|
||||||
return {success: true, message: "Log was just cleared."};
|
return { success: true, message: "Log was just cleared." };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createLog("error", "lst", "logger", "There was an error clearing the log.");
|
createLog(
|
||||||
return {success: false, message: "There was an error clearing the log."};
|
"error",
|
||||||
|
"lst",
|
||||||
|
"logger",
|
||||||
|
"There was an error clearing the log."
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "There was an error clearing the log.",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, eq, gte, inArray, lte, sql } from "drizzle-orm";
|
import { and, desc, eq, gte, inArray, lte, sql } from "drizzle-orm";
|
||||||
import { db } from "../../../../database/dbclient.js";
|
import { db } from "../../../../database/dbclient.js";
|
||||||
import { logs } from "../../../../database/schema/logs.js";
|
import { logs } from "../../../../database/schema/logs.js";
|
||||||
import { createLog } from "../logger.js";
|
import { createLog } from "../logger.js";
|
||||||
@@ -21,7 +21,8 @@ export const getLogs = async (data: any) => {
|
|||||||
inArray(logs.level, data.level),
|
inArray(logs.level, data.level),
|
||||||
eq(logs.checked, checked)
|
eq(logs.checked, checked)
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
|
.orderBy(desc(logs.created_at));
|
||||||
|
|
||||||
return { success: true, message: "logs returned", data: logData };
|
return { success: true, message: "logs returned", data: logData };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -56,17 +56,17 @@ export const migrateAdjustments = async () => {
|
|||||||
/**
|
/**
|
||||||
* Migrate all the silo adjustments :D
|
* Migrate all the silo adjustments :D
|
||||||
*/
|
*/
|
||||||
const silo: any = s?.data;
|
const silo: any = s?.data.data;
|
||||||
createLog("info", "silo", "logistics", "Starting migration.");
|
createLog("info", "silo", "logistics", "Starting migration.");
|
||||||
for (let i = 0; i < silo.length; i++) {
|
for (let i = 0; i < silo.length; i++) {
|
||||||
const migrate = await db.insert(siloAdjustments).values({
|
const migrate = await db.insert(siloAdjustments).values({
|
||||||
warehouseID: silo[0].warehouseID,
|
warehouseID: silo[i].warehouseID,
|
||||||
locationID: silo[0].locationID,
|
locationID: silo[i].locationID,
|
||||||
currentStockLevel: silo[0].currentStockLevel,
|
currentStockLevel: silo[i].currentStockLevel,
|
||||||
newLevel: silo[0].newLevel,
|
newLevel: silo[i].newLevel,
|
||||||
dateAdjusted: new Date(silo[0].dateAdjusted),
|
dateAdjusted: new Date(silo[i].dateAdjusted),
|
||||||
lastDateAdjusted: new Date(silo[0].lastDateAdjusted),
|
lastDateAdjusted: new Date(silo[i].lastDateAdjusted),
|
||||||
add_user: silo[0].add_user,
|
add_user: silo[i].add_user,
|
||||||
});
|
});
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
@@ -87,5 +87,3 @@ export const migrateAdjustments = async () => {
|
|||||||
.where(eq(settings.name, "siloAdjMigrations"));
|
.where(eq(settings.name, "siloAdjMigrations"));
|
||||||
createLog("info", "silo", "logistics", "Migration completed.");
|
createLog("info", "silo", "logistics", "Migration completed.");
|
||||||
};
|
};
|
||||||
|
|
||||||
migrateAdjustments();
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { differenceInDays, differenceInSeconds, format } from "date-fns";
|
||||||
|
import { timeZoneFix } from "../../../../../globalUtils/timeZoneFix.js";
|
||||||
|
import { createLog } from "../../../../logger/logger.js";
|
||||||
|
import { delay } from "../../../../../globalUtils/delay.js";
|
||||||
|
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||||
|
import { query } from "../../../../sqlServer/prodSqlServer.js";
|
||||||
|
import { cycleCountCheck } from "../../../../sqlServer/querys/warehouse/cycleCountCheck.js";
|
||||||
|
|
||||||
|
// setting timer for updating stockCheck on a restart will always check.
|
||||||
|
let lastCheck = 0;
|
||||||
|
|
||||||
|
export const lanes: any = [];
|
||||||
|
|
||||||
|
export const getLanesToCycleCount = async () => {
|
||||||
|
const currentTime: any = timeZoneFix();
|
||||||
|
// store the lanes in memeory
|
||||||
|
createLog("info", "warehouse", "logistics", "Empty lane triggered update.");
|
||||||
|
lastCheck = currentTime;
|
||||||
|
const ageQuery = cycleCountCheck.replaceAll("[ageOfRow]", `1000`);
|
||||||
|
const { data: prodLanes, error: pl } = await tryCatch(
|
||||||
|
query(ageQuery, "Get Stock lane date.")
|
||||||
|
);
|
||||||
|
|
||||||
|
// run the update on the lanes
|
||||||
|
for (let i = 0; i < prodLanes.length; i++) {
|
||||||
|
const createLane = {
|
||||||
|
laneID: prodLanes[i]?.laneID,
|
||||||
|
warehouseID: prodLanes[i]?.warehouseID,
|
||||||
|
warehouseName: prodLanes[i]?.warehouseName || "na",
|
||||||
|
Description: prodLanes[i]?.Description,
|
||||||
|
LastMoveDate: prodLanes[i]?.LastMoveDate
|
||||||
|
? format(prodLanes[i]?.LastInv, "M/d/yyyy")
|
||||||
|
: undefined,
|
||||||
|
LastInv: format(prodLanes[i]?.LastInv, "M/d/yyyy"),
|
||||||
|
rowType: prodLanes[i].rowType,
|
||||||
|
DaysSinceLast:
|
||||||
|
differenceInDays(
|
||||||
|
new Date(prodLanes[i].LastInv),
|
||||||
|
new Date(prodLanes[i].LastMoveDate)
|
||||||
|
) <= 0
|
||||||
|
? 0
|
||||||
|
: differenceInDays(
|
||||||
|
new Date(prodLanes[i].LastInv),
|
||||||
|
new Date(prodLanes[i].LastMoveDate)
|
||||||
|
),
|
||||||
|
upd_date: format(new Date(Date.now()), "M/d/yyyy"),
|
||||||
|
};
|
||||||
|
|
||||||
|
lanes.push(createLane);
|
||||||
|
createLog(
|
||||||
|
"debug",
|
||||||
|
"warehouse",
|
||||||
|
"logistics",
|
||||||
|
`${lanes[i].Description} was just added`
|
||||||
|
);
|
||||||
|
await delay(10);
|
||||||
|
//delay to slow this thing down
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { lanes } from "./cyclecountCheck.js";
|
||||||
|
|
||||||
|
export const getCycleCountCheck = async (
|
||||||
|
age: number = 1000,
|
||||||
|
type: string = ""
|
||||||
|
) => {
|
||||||
|
/**
|
||||||
|
* Get the lane data based on the age and type
|
||||||
|
*/
|
||||||
|
|
||||||
|
let filteredLanes = lanes.filter((t: any) => t.DaysSinceLast >= age);
|
||||||
|
|
||||||
|
if (type != "") {
|
||||||
|
return {
|
||||||
|
sucess: true,
|
||||||
|
message: `${filteredLanes.length} lanes that are of type ${type} and have not been cycle counted in the last ${age} days.`,
|
||||||
|
data: filteredLanes.filter(
|
||||||
|
(t: any) => t.rowType === type.toUpperCase()
|
||||||
|
),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: `${filteredLanes.length} lanes grabed that have not been cycle counted in the last ${age} days.`,
|
||||||
|
data: filteredLanes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -7,6 +7,8 @@ import postComment from "./route/siloAdjustments/postComment.js";
|
|||||||
import getStockSilo from "./route/siloAdjustments/getStockData.js";
|
import getStockSilo from "./route/siloAdjustments/getStockData.js";
|
||||||
import { migrateAdjustments } from "./controller/siloAdjustments/migrateAdjustments.js";
|
import { migrateAdjustments } from "./controller/siloAdjustments/migrateAdjustments.js";
|
||||||
import getSiloAdjustments from "./route/siloAdjustments/getSiloAdjustments.js";
|
import getSiloAdjustments from "./route/siloAdjustments/getSiloAdjustments.js";
|
||||||
|
import { getLanesToCycleCount } from "./controller/warehouse/cycleCountChecks/cyclecountCheck.js";
|
||||||
|
import getCycleCountCheck from "./route/getCycleCountChecks.js";
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -19,6 +21,8 @@ const routes = [
|
|||||||
postComment,
|
postComment,
|
||||||
getStockSilo,
|
getStockSilo,
|
||||||
getSiloAdjustments,
|
getSiloAdjustments,
|
||||||
|
//lanes
|
||||||
|
getCycleCountCheck,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
// app.route("/server", modules);
|
// app.route("/server", modules);
|
||||||
@@ -28,6 +32,17 @@ const appRoutes = routes.forEach((route) => {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
migrateAdjustments();
|
migrateAdjustments();
|
||||||
}, 10 * 1000);
|
}, 120 * 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the cycle count check
|
||||||
|
*/
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
getLanesToCycleCount();
|
||||||
|
}, 5 * 1000);
|
||||||
|
setInterval(async () => {
|
||||||
|
getLanesToCycleCount();
|
||||||
|
}, 15 * 60 * 1000);
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
60
server/services/logistics/route/getCycleCountChecks.ts
Normal file
60
server/services/logistics/route/getCycleCountChecks.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||||
|
import { getCycleCountCheck } from "../controller/warehouse/cycleCountChecks/getCycleCountCheck.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: "Returns lanes that need cycle counted",
|
||||||
|
method: "post",
|
||||||
|
path: "/cyclecountcheck",
|
||||||
|
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 { data: body, error: be } = await tryCatch(c.req.json());
|
||||||
|
|
||||||
|
if (be) {
|
||||||
|
return c.json({ success: false, message: "Missing Data." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const check: any = body;
|
||||||
|
const { data: lanes, error: le } = await tryCatch(
|
||||||
|
getCycleCountCheck(check.age, check.type)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (le) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error getting lane data.",
|
||||||
|
data: le,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
success: lanes.success,
|
||||||
|
message: lanes.message,
|
||||||
|
data: lanes.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
@@ -3,6 +3,7 @@ import { ocmeData } from "../../../../database/schema/ocme.js";
|
|||||||
import { differenceInMinutes } from "date-fns";
|
import { differenceInMinutes } from "date-fns";
|
||||||
import { createLog } from "../../logger/logger.js";
|
import { createLog } from "../../logger/logger.js";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
import { timeZoneFix } from "../../../globalUtils/timeZoneFix.js";
|
||||||
|
|
||||||
export const getInfo = async () => {
|
export const getInfo = async () => {
|
||||||
let ocmeInfo: any = [];
|
let ocmeInfo: any = [];
|
||||||
@@ -16,7 +17,7 @@ export const getInfo = async () => {
|
|||||||
ocmeInfo = ocmeInfo.map((o: any) => {
|
ocmeInfo = ocmeInfo.map((o: any) => {
|
||||||
const now = new Date(Date.now());
|
const now = new Date(Date.now());
|
||||||
//const strippedDate = o.add_Date.replace("Z", "");
|
//const strippedDate = o.add_Date.replace("Z", "");
|
||||||
const diff = differenceInMinutes(now, o.add_Date);
|
const diff = differenceInMinutes(timeZoneFix(), o.add_Date);
|
||||||
return { ...o, waitingFor: diff };
|
return { ...o, waitingFor: diff };
|
||||||
});
|
});
|
||||||
createLog(
|
createLog(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const createLabel = async (data: any, userPrinted: any) => {
|
|||||||
if (settingsError) {
|
if (settingsError) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "There was an error getting the printer.",
|
message: "There was an error getting the settings.",
|
||||||
settingsError,
|
settingsError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ export const labelingProcess = async ({
|
|||||||
"error",
|
"error",
|
||||||
"labeling",
|
"labeling",
|
||||||
"ocp",
|
"ocp",
|
||||||
`There is not a lot assigned to ${macId[0]?.Name}.`
|
`There is not a lot assigned to ${line}.`
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: `There is not a lot assigned to ${macId[0]?.Name}.`,
|
message: `There is not a lot assigned to ${line}.`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ export const labelingProcess = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if there are more than 2 lots it might be an auto labeler, autolabeler will be defined by its id for now only dayton
|
// if there are more than 2 lots it might be an auto labeler, autolabeler will be defined by its id for now only dayton
|
||||||
if (filteredLot.length > 2 && plantToken[0].value !== "usday1") {
|
if (filteredLot?.length > 2 && plantToken[0].value !== "usday1") {
|
||||||
createLog(
|
createLog(
|
||||||
"error",
|
"error",
|
||||||
"labeling",
|
"labeling",
|
||||||
@@ -214,15 +214,15 @@ export const labelingProcess = async ({
|
|||||||
// create the label
|
// create the label
|
||||||
const label = await createLabel(filteredLot[0], userPrinted);
|
const label = await createLabel(filteredLot[0], userPrinted);
|
||||||
|
|
||||||
if (!label.success) {
|
// if (!label.success) {
|
||||||
createLog(
|
// createLog(
|
||||||
"error",
|
// "error",
|
||||||
"labeling",
|
// "labeling",
|
||||||
"ocp",
|
// "ocp",
|
||||||
`There was an error creating the label: ${label.message}`
|
// `There was an error creating the label: ${label.message}`
|
||||||
);
|
// );
|
||||||
return { sucess: false, message: label.message, data: label.data };
|
// return { sucess: false, message: label.message, data: label.data };
|
||||||
}
|
// }
|
||||||
|
|
||||||
// send over to be booked in if we can do it.
|
// send over to be booked in if we can do it.
|
||||||
const bookin = settingData.filter((s) => s.name === "bookin");
|
const bookin = settingData.filter((s) => s.name === "bookin");
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { db } from "../../../../../database/dbclient.js";
|
||||||
|
import { settings } from "../../../../../database/schema/settings.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { createLog } from "../../../logger/logger.js";
|
||||||
|
import { getPrinters } from "./getPrinters.js";
|
||||||
|
import { autoLabelingStats } from "./printerStatus.js";
|
||||||
|
|
||||||
|
let isPrinterCycling = false;
|
||||||
|
let actualPrinterCycle: any;
|
||||||
|
|
||||||
|
export const printerCycleAutoLabelers = async () => {
|
||||||
|
/**
|
||||||
|
* Will only check the auto labelers for status updates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (isPrinterCycling)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Printers are already being cycled.",
|
||||||
|
};
|
||||||
|
|
||||||
|
createLog("info", "ocp", "ocp", "AutoLabeling cycle has started.");
|
||||||
|
// get the printers
|
||||||
|
const { data: s, error: se } = await tryCatch(
|
||||||
|
db.select().from(settings).where(eq(settings.name, "ocpCycleDelay"))
|
||||||
|
);
|
||||||
|
if (se) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"ocp",
|
||||||
|
"ocp",
|
||||||
|
"There was an error getting the ocpCycleDelay."
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Error getting printers.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const ocpDelay: any = s;
|
||||||
|
isPrinterCycling = true;
|
||||||
|
// start the actual printer cycle
|
||||||
|
actualPrinterCycle = setInterval(async () => {
|
||||||
|
const { data, error } = await tryCatch(getPrinters());
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"ocp",
|
||||||
|
"ocp",
|
||||||
|
"There was an error getting the printers."
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Error getting printers.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let printers: any = data.data;
|
||||||
|
|
||||||
|
// only keep the assigned ones
|
||||||
|
printers = printers.filter((p: any) => p.assigned === true);
|
||||||
|
|
||||||
|
// for printers we want to ignore there must be a remark stateing to ignore.
|
||||||
|
printers = printers.filter((p: any) => !p.remark.includes("ignore"));
|
||||||
|
|
||||||
|
printers.forEach(async (p: any) => {
|
||||||
|
/**
|
||||||
|
* if the last timeprinted would be greater than x well just change the status to idle and extended based on the 2 times.
|
||||||
|
*
|
||||||
|
* to get a printer going again label will need to come from the front end as that will just unpause the printer and start the labeling, or the api for manual print
|
||||||
|
* well need to adjust this to actually print the label then unpause it.
|
||||||
|
*
|
||||||
|
* it will be
|
||||||
|
*
|
||||||
|
* less than x since time printed run the printer status
|
||||||
|
* greater than x but less than y change the status to idle, but ping to make sure its online,
|
||||||
|
* if greater than y change to extended idle but stil also ping to make sure its online.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ignore pdf printer as we want it here for testing purposes
|
||||||
|
if (p.name.toLowerCase() === "pdf24") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.name === "Autolabeler") {
|
||||||
|
await autoLabelingStats(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, parseInt(ocpDelay[0]?.value) * 2 * 1000);
|
||||||
|
|
||||||
|
return { success: true, message: "AutoLabeling 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", "AutoLabeling cycle is being stopped.");
|
||||||
|
clearInterval(actualPrinterCycle);
|
||||||
|
isPrinterCycling = false;
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "AutoLabeling cycle has been stopped.",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"ocp",
|
||||||
|
"ocp",
|
||||||
|
"AutoLabeling cycle is already stopped."
|
||||||
|
);
|
||||||
|
isPrinterCycling = false;
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "AutoLabeling cycle is already Stopped.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -75,8 +75,16 @@ export const labelerTagRead = async (tagData: any) => {
|
|||||||
|
|
||||||
// check if we need to manual check due to 20 pallets.
|
// check if we need to manual check due to 20 pallets.
|
||||||
if (currentPalletCheck <= cameraPalletCheck) {
|
if (currentPalletCheck <= cameraPalletCheck) {
|
||||||
currentPalletCheck = currentPalletCheck + 1;
|
currentPalletCheck++;
|
||||||
labelingProcess({ line: numericString });
|
labelingProcess({ line: numericString });
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"dyco",
|
||||||
|
"ocp",
|
||||||
|
`You have printed ${currentPalletCheck} pallets, remaining until ${
|
||||||
|
cameraPalletCheck - currentPalletCheck
|
||||||
|
}.`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
currentPalletCheck = 0;
|
currentPalletCheck = 0;
|
||||||
createLog(
|
createLog(
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import { assignedPrinters } from "./utils/checkAssignments.js";
|
|||||||
import { printerCycle } from "./controller/printers/printerCycle.js";
|
import { printerCycle } from "./controller/printers/printerCycle.js";
|
||||||
import stopPrinterCycle from "./routes/printers/stopCycle.js";
|
import stopPrinterCycle from "./routes/printers/stopCycle.js";
|
||||||
import startPrinterCycle from "./routes/printers/startCycle.js";
|
import startPrinterCycle from "./routes/printers/startCycle.js";
|
||||||
|
import { printerCycleAutoLabelers } from "./controller/printers/printerCycleAutoLabelers.js";
|
||||||
|
import AutostartPrinterCycle from "./routes/printers/autoLabelerStart.js";
|
||||||
|
import AutostopPrinterCycle from "./routes/printers/autoLabelerStop.js";
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -27,6 +30,8 @@ const routes = [
|
|||||||
updateprinters,
|
updateprinters,
|
||||||
startPrinterCycle,
|
startPrinterCycle,
|
||||||
stopPrinterCycle,
|
stopPrinterCycle,
|
||||||
|
AutostartPrinterCycle,
|
||||||
|
AutostopPrinterCycle,
|
||||||
// lots
|
// lots
|
||||||
getLots,
|
getLots,
|
||||||
// labeling
|
// labeling
|
||||||
@@ -76,6 +81,7 @@ setTimeout(async () => {
|
|||||||
await updatePrinters();
|
await updatePrinters();
|
||||||
await assignedPrinters();
|
await assignedPrinters();
|
||||||
printerCycle();
|
printerCycle();
|
||||||
|
printerCycleAutoLabelers();
|
||||||
}
|
}
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
|||||||
41
server/services/ocp/routes/printers/autoLabelerStart.ts
Normal file
41
server/services/ocp/routes/printers/autoLabelerStart.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/autoLabelerStop.ts
Normal file
41
server/services/ocp/routes/printers/autoLabelerStop.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;
|
||||||
@@ -49,7 +49,7 @@ app.openapi(
|
|||||||
return c.json({
|
return c.json({
|
||||||
success: getData?.success,
|
success: getData?.success,
|
||||||
message: getData?.message,
|
message: getData?.message,
|
||||||
data: getData.data ?? [],
|
data: getData?.data ?? [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export const assignedPrinters = async () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const printers: any = print.data;
|
const printers: any = print.data ?? [];
|
||||||
const lots: any = l.data;
|
const lots: any = l.data ?? [];
|
||||||
|
|
||||||
for (let i = 0; i < printers.length; i++) {
|
for (let i = 0; i < printers.length; i++) {
|
||||||
// is the printer assinged in alplalabel online?
|
// is the printer assinged in alplalabel online?
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
import { z, createRoute, OpenAPIHono } from "@hono/zod-openapi";
|
||||||
import {modules} from "../../../../../database/schema/modules.js";
|
import { modules } from "../../../../../database/schema/modules.js";
|
||||||
import {db} from "../../../../../database/dbclient.js";
|
import { db } from "../../../../../database/dbclient.js";
|
||||||
|
import { desc } from "drizzle-orm";
|
||||||
|
|
||||||
// Define the request body schema
|
// Define the request body schema
|
||||||
const requestSchema = z.object({
|
const requestSchema = z.object({
|
||||||
@@ -13,10 +14,16 @@ const requestSchema = z.object({
|
|||||||
// Define the response schema
|
// Define the response schema
|
||||||
const responseSchema = z.object({
|
const responseSchema = z.object({
|
||||||
message: z.string().optional(),
|
message: z.string().optional(),
|
||||||
module_id: z.string().openapi({example: "6c922c6c-7de3-4ec4-acb0-f068abdc"}).optional(),
|
module_id: z
|
||||||
name: z.string().openapi({example: "Production"}).optional(),
|
.string()
|
||||||
active: z.boolean().openapi({example: true}).optional(),
|
.openapi({ example: "6c922c6c-7de3-4ec4-acb0-f068abdc" })
|
||||||
roles: z.string().openapi({example: `["viewer","technician"]`}).optional(),
|
.optional(),
|
||||||
|
name: z.string().openapi({ example: "Production" }).optional(),
|
||||||
|
active: z.boolean().openapi({ example: true }).optional(),
|
||||||
|
roles: z
|
||||||
|
.string()
|
||||||
|
.openapi({ example: `["viewer","technician"]` })
|
||||||
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
@@ -30,7 +37,7 @@ app.openapi(
|
|||||||
responses: {
|
responses: {
|
||||||
200: {
|
200: {
|
||||||
content: {
|
content: {
|
||||||
"application/json": {schema: responseSchema},
|
"application/json": { schema: responseSchema },
|
||||||
},
|
},
|
||||||
description: "Response message",
|
description: "Response message",
|
||||||
},
|
},
|
||||||
@@ -40,7 +47,7 @@ app.openapi(
|
|||||||
//console.log("system modules");
|
//console.log("system modules");
|
||||||
let module: any = [];
|
let module: any = [];
|
||||||
try {
|
try {
|
||||||
module = await db.select().from(modules); // .where(eq(modules.active, true));
|
module = await db.select().from(modules).orderBy(modules.name); // .where(eq(modules.active, true));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
module = [];
|
module = [];
|
||||||
@@ -49,7 +56,7 @@ app.openapi(
|
|||||||
// parse the roles
|
// parse the roles
|
||||||
const updateModules = module.map((m: any) => {
|
const updateModules = module.map((m: any) => {
|
||||||
if (m.roles) {
|
if (m.roles) {
|
||||||
return {...m, roles: m?.roles};
|
return { ...m, roles: m?.roles };
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}); //JSON.parse(module[0]?.roles);
|
}); //JSON.parse(module[0]?.roles);
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ app.openapi(
|
|||||||
//console.log("system modules");
|
//console.log("system modules");
|
||||||
let module: any = [];
|
let module: any = [];
|
||||||
try {
|
try {
|
||||||
module = await db.select().from(subModules); // .where(eq(modules.active, true));
|
module = await db
|
||||||
|
.select()
|
||||||
|
.from(subModules)
|
||||||
|
.orderBy(subModules.name); // .where(eq(modules.active, true));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
module = [];
|
module = [];
|
||||||
|
|||||||
@@ -3,42 +3,69 @@
|
|||||||
* this will only run on a server start up
|
* this will only run on a server start up
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {db} from "../../../../database/dbclient.js";
|
import { db } from "../../../../database/dbclient.js";
|
||||||
import {modules} from "../../../../database/schema/modules.js";
|
import { modules } from "../../../../database/schema/modules.js";
|
||||||
import {createLog} from "../../logger/logger.js";
|
import { createLog } from "../../logger/logger.js";
|
||||||
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
||||||
const newModules = [
|
const newModules: any = [
|
||||||
{name: "production", active: true, roles: ["viewer", "tester", "systemAdmin"]},
|
{
|
||||||
{name: "logistics", active: false, roles: ["viewer", "tester", "systemAdmin"]},
|
name: "production",
|
||||||
{name: "quality", active: false, roles: ["viewer", "manager", "tester", "systemAdmin"]},
|
active: true,
|
||||||
{name: "forklift", active: false, roles: ["manager", "admin", "tester", "systemAdmin"]},
|
roles: ["viewer", "tester", "systemAdmin"],
|
||||||
{name: "eom", active: false, roles: ["manager", "admin", "tester", "systemAdmin"]},
|
},
|
||||||
{name: "admin", active: true, roles: ["admin", "systemAdmin"]},
|
{
|
||||||
{name: "ocp", active: false, roles: ["viewer", "admin", "tester", "systemAdmin"]},
|
name: "logistics",
|
||||||
|
active: false,
|
||||||
|
roles: ["viewer", "manager", "supervisor", "tester", "systemAdmin"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "quality",
|
||||||
|
active: false,
|
||||||
|
roles: ["viewer", "manager", "tester", "systemAdmin"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "forklift",
|
||||||
|
active: false,
|
||||||
|
roles: ["manager", "admin", "tester", "systemAdmin"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "eom",
|
||||||
|
active: false,
|
||||||
|
roles: ["manager", "admin", "tester", "systemAdmin"],
|
||||||
|
},
|
||||||
|
{ name: "admin", active: true, roles: ["admin", "systemAdmin"] },
|
||||||
|
{
|
||||||
|
name: "ocp",
|
||||||
|
active: false,
|
||||||
|
roles: ["viewer", "admin", "tester", "systemAdmin"],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
export const areModulesIn = async () => {
|
export const areModulesIn = async () => {
|
||||||
// get the roles
|
// get the roles
|
||||||
try {
|
for (let i = 0; i < newModules.length; i++) {
|
||||||
const moduleCheck = await db.select().from(modules);
|
try {
|
||||||
|
const newRole = await db
|
||||||
if (moduleCheck.length !== newModules.length) {
|
|
||||||
try {
|
|
||||||
const newRole = await db
|
|
||||||
.insert(modules)
|
.insert(modules)
|
||||||
.values(newModules)
|
.values(newModules[i])
|
||||||
.onConflictDoNothing() // this will only update the ones that are new :D
|
.onConflictDoUpdate({
|
||||||
.returning({name: modules.name});
|
target: modules.name,
|
||||||
createLog("info", "lst", "server", "Roles were just added due to missing them on server startup");
|
set: { roles: newModules[i].roles },
|
||||||
} catch (error) {
|
}) // this will only update the ones that are new :D
|
||||||
createLog("error", "lst", "server", "There was an error adding new roles to the db");
|
.returning({ name: modules.name });
|
||||||
}
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"lst",
|
||||||
|
"server",
|
||||||
|
"There was an error adding new modules to the db"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
createLog(
|
|
||||||
"error",
|
|
||||||
"lst",
|
|
||||||
"server",
|
|
||||||
`Error: ${JSON.stringify(error)}"There was an error getting or adding new roles"`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"lst",
|
||||||
|
"server",
|
||||||
|
"Modules were just added due to missing them on server startup"
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const newSubModules = [
|
|||||||
link: "/siloAdjustments",
|
link: "/siloAdjustments",
|
||||||
icon: "Cylinder",
|
icon: "Cylinder",
|
||||||
active: false,
|
active: false,
|
||||||
roles: ["tester", "systemAdmin"],
|
roles: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
||||||
subSubModule: [],
|
subSubModule: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -38,16 +38,6 @@ const newSubModules = [
|
|||||||
active: false,
|
active: false,
|
||||||
subSubModule: [],
|
subSubModule: [],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Ocme cycle counts",
|
|
||||||
moduleName: "logistics",
|
|
||||||
description: "",
|
|
||||||
link: "#",
|
|
||||||
icon: "Package",
|
|
||||||
role: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
|
||||||
active: false,
|
|
||||||
subSubModule: [],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Material Helper",
|
name: "Material Helper",
|
||||||
moduleName: "logistics",
|
moduleName: "logistics",
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
export const cycleCountCheck = `
|
||||||
|
-- Define the structure of the result set from the stored procedure
|
||||||
|
DECLARE @results TABLE (
|
||||||
|
IdLocation INT,
|
||||||
|
LastMoveDate Date
|
||||||
|
|
||||||
|
)
|
||||||
|
-- insert into the temp table
|
||||||
|
insert into @results
|
||||||
|
select IdLagerAbteilung, MAX(CaSE WHEN CONVERT(char(10), Buchungsdatum, 120) IS NULL THEN '1900-01-01' ELSE CONVERT(char(10), Buchungsdatum, 120) END) AS LastLocMov
|
||||||
|
from AlplaPROD_test1.dbo.V_LagerBuchungen x(nolock)
|
||||||
|
|
||||||
|
group by IdLagerAbteilung
|
||||||
|
|
||||||
|
select * from (
|
||||||
|
select x.IdLagerAbteilung as laneID,
|
||||||
|
x.IdWarenLager as warehouseID,
|
||||||
|
w.Bezeichnung as warehouseName,
|
||||||
|
w.LagerTyp as warehouseIDTyp,
|
||||||
|
w.Standort as warehouseLocation,
|
||||||
|
x.Bezeichnung as Description,
|
||||||
|
LastMoveDate,
|
||||||
|
CASE WHEN CONVERT(char(10), i.Datum, 120) is null then getdate() - 365 else CONVERT(char(10), i.Datum, 120) end as LastInv,
|
||||||
|
--create the types of warehouses to choose from
|
||||||
|
case
|
||||||
|
-- empty
|
||||||
|
when (sum(EinlagerungsMengeSum) is null and Datum < LastMoveDate) or (
|
||||||
|
(sum(EinlagerungsMengeSum) is null and Datum < DATEADD(day, -[ageOfRow], getdate()))
|
||||||
|
) then 'EMPTY'
|
||||||
|
-- finished goods
|
||||||
|
when w.LagerTyp = 2 and w.Standort = 10 then 'FG'
|
||||||
|
-- external finished goods
|
||||||
|
when w.LagerTyp = 2 and w.Standort = 20 then 'EXTERNAL'
|
||||||
|
-- silos
|
||||||
|
when w.LagerTyp in (3) and x.MaterialSilo = 1 then 'BULK'
|
||||||
|
-- MATERIALS
|
||||||
|
when w.LagerTyp = 3 and x.MaterialSilo = 0 then 'MATERIALS'
|
||||||
|
|
||||||
|
-- MATERIALS
|
||||||
|
when w.LagerTyp = 11 then 'WASTE'
|
||||||
|
-- MATERIALS
|
||||||
|
when w.LagerTyp = 9 then 'PACKAGING'
|
||||||
|
|
||||||
|
end as rowType,
|
||||||
|
CASE WHEN DateDiff(DAY,i.Datum,getDate()) is null then 1000 else DateDiff(DAY,i.Datum,getDate()) end as DaysSinceLast
|
||||||
|
|
||||||
|
from AlplaPROD_test1.dbo.T_LagerAbteilungen as x (NOLOCK)
|
||||||
|
|
||||||
|
-- last move
|
||||||
|
left join
|
||||||
|
@results as b on
|
||||||
|
x.IdLagerAbteilung = b.IdLocation
|
||||||
|
|
||||||
|
-- last inv
|
||||||
|
left join
|
||||||
|
(select * from [AlplaPROD_test1].[dbo].[T_LagerAbteilungenInventuren] (nolock)) as i on x.IdLagerAbteilung =
|
||||||
|
i.IdLagerAbteilung
|
||||||
|
|
||||||
|
-- useing this to determin only if the lane is empty
|
||||||
|
left join
|
||||||
|
(select * from [AlplaPROD_test1].dbo.V_LagerPositionenBarcodes (nolock)) as y on x.IdLagerAbteilung =
|
||||||
|
y.IdLagerAbteilung
|
||||||
|
|
||||||
|
-- get the warehosue type
|
||||||
|
left join
|
||||||
|
(select * from [AlplaPROD_test1].dbo.T_WarenLager (nolock)) as w on x.IdWarenLager = w.IdWarenLager
|
||||||
|
|
||||||
|
where x.aktiv = 1 and x.IdWarenLager not in (1,5,6)
|
||||||
|
|
||||||
|
group by x.IdLagerAbteilung,
|
||||||
|
x.IdWarenLager,
|
||||||
|
w.LagerTyp,
|
||||||
|
w.Standort,
|
||||||
|
x.Bezeichnung,
|
||||||
|
LastMoveDate,
|
||||||
|
i.Datum,
|
||||||
|
x.MaterialSilo,
|
||||||
|
w.Bezeichnung
|
||||||
|
) xb
|
||||||
|
`;
|
||||||
Reference in New Issue
Block a user