feat(silo): added in charts and historical data
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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();
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
|
||||||
|
|
||||||
if (moduleCheck.length !== newModules.length) {
|
|
||||||
try {
|
try {
|
||||||
const newRole = await db
|
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) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
createLog(
|
createLog(
|
||||||
"error",
|
"error",
|
||||||
"lst",
|
"lst",
|
||||||
"server",
|
"server",
|
||||||
`Error: ${JSON.stringify(error)}"There was an error getting or adding new roles"`
|
"There was an error adding new modules to the db"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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",
|
||||||
|
|||||||
Reference in New Issue
Block a user