6 Commits

Author SHA1 Message Date
8fc3129f7d refactor(opend dock): added in default dock so it uses the default setup as a backup
All checks were successful
Build and Push LST Docker Image / docker (push) Successful in 1m40s
This will help the live/drop and dont know what dock
2026-06-09 12:00:50 -05:00
05c553e927 fix(eom): removed un needed imports 2026-06-09 11:59:48 -05:00
6eaae0f537 refactor(dock scanner): more work on dock scanner and semi finished 2026-06-09 11:59:27 -05:00
3ad84dab71 refactor(opendock): added in proper complete and ignore of picksheets 2026-06-09 11:58:25 -05:00
5a7046bacd refactor(opendock): if load type is drop we will not do anything unless its already scanned
this means that if we drag down a bunch of loads we wont instantly change to arrived we will need to
have a single scan before we do this
2026-06-09 11:46:22 -05:00
cfc497c1f2 refactor(opendock): added in check for really using the article link 2026-06-09 11:45:09 -05:00
18 changed files with 3301 additions and 171 deletions

View File

@@ -6,7 +6,7 @@ export const dockDoorScans = pgTable("dock_door_scans", {
id: uuid("id").defaultRandom().primaryKey(),
dockId: text("dock_id").notNull(),
loadingOrder: text("loading_order").notNull(),
loadingUnit: text("loading_Unit").unique(), // can be running number or sscc depending on where it came from
loadingUnit: text("loading_Unit"), // can be running number or sscc depending on where it came from
loadingUnitStatus: text("loading_unit_status").default("loaded"), // TODO: add enums on the status of each load.
message: text("message"), // the response it gave when scanning
status: text("status").default("active"), // TODO: add in enums for this

View File

@@ -16,6 +16,7 @@ r.get("/", async (_, res) => {
loadingDateTo: format(addDays(new Date(Date.now()), 3), "yyyy-MM-dd"),
states: [
1, // planned
2, // loading
],
//isCommissioned: true,
},

View File

@@ -32,13 +32,34 @@ r.post("/", async (req, res) => {
})) as any;
if (orders?.data.errors) {
console.log(orders.data.errors);
//console.log(orders.data.errors);
// if (orders.data.errors[0].code === 20) {
// await db
// .update(dockDoorScanners)
// .set({
// currentLoadingOrder: "",
// upd_date: sql`NOW()`,
// upd_user: req.user?.username ?? "lst-dock-system",
// })
// .where(eq(dockDoorScanners.dockId, validated.dockId));
// return apiReturn(res, {
// success: false,
// level: "warn",
// module: "dockdoor",
// subModule: "loadingOrder",
// message: `Loading order: ${validated.loadingOrder} cleared, It was probable completed by a scanner.. or user...`,
// data: (orders.data.errors as any) ?? [],
// status: 200,
// });
// }
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "loadingOrder",
message: `Failed to finish the order.`,
message: `Failed to finish the order: ${orders.data.errors[0].message}`,
data: (orders.data.errors as any) ?? [],
status: 400,
});
@@ -48,6 +69,7 @@ r.post("/", async (req, res) => {
db
.update(dockDoorScans)
.set({
status: "completed",
upd_date: sql`NOW()`,
upd_user: req.user?.username ?? "lst-dock-system",
})

View File

@@ -19,13 +19,18 @@ type Data = {
const postScan = async (data: any) => {
try {
await db.insert(dockDoorScans).values({
dockId: data.dockId,
loadingOrder: data.loadingOrder,
loadingUnit: data.loadingUnit.sscc ?? data.loadingUnit.runningNo, // can be running number or sscc depending on where it came from
loadingUnitStatus: data.loadingUnitStatus, // TODO: add enums on the status of each load.
message: data.message, // the response it gave when scanning
});
const newScan = (await db
.insert(dockDoorScans)
.values({
dockId: data.dockId,
loadingOrder: data.loadingOrder,
loadingUnit: data.loadingUnit.sscc ?? data.loadingUnit.runningNo, // can be running number or sscc depending on where it came from
loadingUnitStatus: data.loadingUnitStatus, // TODO: add enums on the status of each load.
message: data.message, // the response it gave when scanning
})
.returning()) as any;
emitToRoom(`dockDoorLoading:${data.dockId}`, newScan[0]);
} catch (error) {
console.log("Error: ", error);
}
@@ -133,7 +138,7 @@ const loadUnit = async (data: Data) => {
loadingUnitStatus: "notLoaded",
message: prod?.data.errors[0].message,
});
emitToRoom(`dockDoorLoading:${data.dockId}`, prod?.data.errors[0]);
return returnFunc({
success: false,
level: "error",
@@ -158,7 +163,7 @@ const loadUnit = async (data: Data) => {
loadingUnitStatus: "loaded",
message: emitData.message,
});
emitToRoom(`dockDoorLoading:${data.dockId}`, emitData as any);
return returnFunc({
success: true,
level: "info",

View File

@@ -1,4 +1,3 @@
import { formatInTimeZone } from "date-fns-tz";
import { Router } from "express";
import { prodQuery } from "../prodSql/prodSqlQuery.controller.js";
import {

View File

@@ -1,4 +1,3 @@
import { formatInTimeZone } from "date-fns-tz";
import { Router } from "express";
import { prodQuery } from "../prodSql/prodSqlQuery.controller.js";
import {

View File

@@ -277,7 +277,7 @@ const postRelease = async (release: Releases) => {
(releaseLoadtypeCheck ||
opendDockArticleCheck?.loadType === "drop" ||
defaultDock?.value === "drop") &&
(release.DeliveryState === 0 || release.DeliveryState === 1)
(release.DeliveryState === 0 || release.DeliveryState === 2)
) {
const setArrival = { ...newDockApt, status: "Arrived" };
@@ -391,7 +391,8 @@ const postRelease = async (release: Releases) => {
return;
}
} else {
// changing to only trigger the change if the state is 2 meaning it has a scan to it and already in progress of being loaded.
} else if (release.DeliveryState === 0 || release.DeliveryState === 2) {
try {
const response = await axios.patch(
`${process.env.OPENDOCK_URL}/appointment/${id}`,
@@ -445,6 +446,116 @@ const postRelease = async (release: Releases) => {
return;
}
// if we are finished we need to set to completed
} else if (release.DeliveryState === 3 || release.DeliveryState === 4) {
try {
const response = await axios.patch(
`${process.env.OPENDOCK_URL}/appointment/${id}`,
newDockApt,
{
headers: {
"content-type": "application/json; charset=utf-8",
Authorization: `Bearer ${odToken.odToken}`,
},
},
);
if (response.status === 400) {
log.error({}, response.data.data.message);
return;
}
// update the release in the db leaving as insert just incase something weird happened
try {
await db
.insert(opendockApt)
.values({
release: release.ReleaseNumber,
openDockAptId: response.data.data.id,
appointment: response.data.data,
})
.onConflictDoUpdate({
target: opendockApt.release,
set: {
openDockAptId: response.data.data.id,
appointment: response.data.data,
upd_date: sql`NOW()`,
},
})
.returning();
log.info({}, `${release.ReleaseNumber} was updated`);
} catch (e) {
log.error(
{ stack: e },
`Error updating the release: ${release.ReleaseNumber}`,
);
}
// biome-ignore lint/suspicious/noExplicitAny: to many possibilities
} catch (e: any) {
//console.info(newDockApt);
log.error(
{ stack: e.response.data },
`An error has occurred during patching of the release: ${release.ReleaseNumber}`,
);
return;
}
}
} else if (opendDockArticleCheck?.loadType === "live") {
try {
const response = await axios.post(
`${process.env.OPENDOCK_URL}/appointment`,
newDockApt,
{
headers: {
"content-type": "application/json; charset=utf-8",
Authorization: `Bearer ${odToken.odToken}`,
},
},
);
// we need the id,release#,status from this response, store it in lst, check if we have a release so we can just update it.
// this will be utilized when we are listening for the changes to the apts. that way we can update the state to arrived. we will run our own checks on this guy during the incoming messages.
if (response.status === 400) {
log.error({}, response.data.data.message);
return;
}
// the response to make it simple we want response.data.id, response.data.relNumber, status will be defaulted to Scheduled if we created it here.
// TODO: add this release data to our db. but save it in json format and well parse it out. that way we future proof it and have everything in here vs just a few things
//console.info(response.data.data, "Was Created");
try {
await db
.insert(opendockApt)
.values({
release: release.ReleaseNumber,
openDockAptId: response.data.data.id,
appointment: response.data.data,
})
.onConflictDoUpdate({
target: opendockApt.release,
set: {
openDockAptId: response.data.data.id,
appointment: response.data.data,
upd_date: sql`NOW()`,
},
})
.returning();
log.info({}, `${release.ReleaseNumber} was created`);
} catch (e) {
log.error({ stack: e }, "Error creating new release");
}
// biome-ignore lint/suspicious/noExplicitAny: to many possibilities
} catch (e: any) {
log.error(
{ stack: e?.response?.data },
`Error posting new release to opendock, ${release.ReleaseNumber}`,
);
return;
}
} else if (
(releaseLoadtypeCheck ||

View File

@@ -1,8 +1,8 @@
import { desc, eq } from "drizzle-orm";
import { db } from "../db/db.controller.js";
import { dockDoorScans } from "../db/schema/dockdoor.scans.schema.js";
import { logs } from "../db/schema/logs.schema.js";
import { ppoRun } from "../warehousing/warehousing.ppooMonitor.js";
import { dockDoorScans } from "../db/schema/dockdoor.scans.schema.js";
type RoomDefinition<T = unknown> = {
seed: (limit: number) => Promise<T[]>;
@@ -104,10 +104,12 @@ export const roomDefinition: Record<RoomId, RoomDefinition> = {
"dockDoorLoading:2": {
seed: async (limit) => {
console.log(limit);
console.log("reseeiding");
try {
const rows = await db
.select()
.from(dockDoorScans).where(eq(dockDoorScans.status, "active"))
.from(dockDoorScans)
.where(eq(dockDoorScans.status, "active"))
.orderBy(desc(dockDoorScans.upd_date))
.limit(limit);

View File

@@ -30,7 +30,7 @@ export function useSocketRoom<T>(
setInfo(`Removed item ${id}`);
return;
}
console.log("cleared data from the room");
setData([]);
setInfo("Room data cleared");
},

View File

@@ -24,11 +24,11 @@ import { Route as AdminLogsRouteImport } from './routes/admin/logs'
import { Route as authLoginRouteImport } from './routes/(auth)/login'
import { Route as WarehouseDockdoorscanningIndexRouteImport } from './routes/warehouse/dockdoorscanning/index'
import { Route as TransportationOpendockIndexRouteImport } from './routes/transportation/opendock/index'
import { Route as WarehouseDockdoorscanningDockScansRouteImport } from './routes/warehouse/dockdoorscanning/$dockScans'
import { Route as WarehouseDockdoorscanningDockRouteImport } from './routes/warehouse/dockdoorscanning/$dock'
import { Route as authUserSignupRouteImport } from './routes/(auth)/user.signup'
import { Route as authUserResetpasswordRouteImport } from './routes/(auth)/user.resetpassword'
import { Route as authUserProfileRouteImport } from './routes/(auth)/user.profile'
import { Route as WarehouseDockdoorscanningScansDockScansRouteImport } from './routes/warehouse/dockdoorscanning/scans/$dockScans'
const ForbiddenRoute = ForbiddenRouteImport.update({
id: '/forbidden',
@@ -107,12 +107,6 @@ const TransportationOpendockIndexRoute =
path: '/transportation/opendock/',
getParentRoute: () => rootRouteImport,
} as any)
const WarehouseDockdoorscanningDockScansRoute =
WarehouseDockdoorscanningDockScansRouteImport.update({
id: '/warehouse/dockdoorscanning/$dockScans',
path: '/warehouse/dockdoorscanning/$dockScans',
getParentRoute: () => rootRouteImport,
} as any)
const WarehouseDockdoorscanningDockRoute =
WarehouseDockdoorscanningDockRouteImport.update({
id: '/warehouse/dockdoorscanning/$dock',
@@ -134,6 +128,12 @@ const authUserProfileRoute = authUserProfileRouteImport.update({
path: '/user/profile',
getParentRoute: () => rootRouteImport,
} as any)
const WarehouseDockdoorscanningScansDockScansRoute =
WarehouseDockdoorscanningScansDockScansRouteImport.update({
id: '/warehouse/dockdoorscanning/scans/$dockScans',
path: '/warehouse/dockdoorscanning/scans/$dockScans',
getParentRoute: () => rootRouteImport,
} as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
@@ -153,9 +153,9 @@ export interface FileRoutesByFullPath {
'/user/resetpassword': typeof authUserResetpasswordRoute
'/user/signup': typeof authUserSignupRoute
'/warehouse/dockdoorscanning/$dock': typeof WarehouseDockdoorscanningDockRoute
'/warehouse/dockdoorscanning/$dockScans': typeof WarehouseDockdoorscanningDockScansRoute
'/transportation/opendock/': typeof TransportationOpendockIndexRoute
'/warehouse/dockdoorscanning/': typeof WarehouseDockdoorscanningIndexRoute
'/warehouse/dockdoorscanning/scans/$dockScans': typeof WarehouseDockdoorscanningScansDockScansRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
@@ -175,9 +175,9 @@ export interface FileRoutesByTo {
'/user/resetpassword': typeof authUserResetpasswordRoute
'/user/signup': typeof authUserSignupRoute
'/warehouse/dockdoorscanning/$dock': typeof WarehouseDockdoorscanningDockRoute
'/warehouse/dockdoorscanning/$dockScans': typeof WarehouseDockdoorscanningDockScansRoute
'/transportation/opendock': typeof TransportationOpendockIndexRoute
'/warehouse/dockdoorscanning': typeof WarehouseDockdoorscanningIndexRoute
'/warehouse/dockdoorscanning/scans/$dockScans': typeof WarehouseDockdoorscanningScansDockScansRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
@@ -198,9 +198,9 @@ export interface FileRoutesById {
'/(auth)/user/resetpassword': typeof authUserResetpasswordRoute
'/(auth)/user/signup': typeof authUserSignupRoute
'/warehouse/dockdoorscanning/$dock': typeof WarehouseDockdoorscanningDockRoute
'/warehouse/dockdoorscanning/$dockScans': typeof WarehouseDockdoorscanningDockScansRoute
'/transportation/opendock/': typeof TransportationOpendockIndexRoute
'/warehouse/dockdoorscanning/': typeof WarehouseDockdoorscanningIndexRoute
'/warehouse/dockdoorscanning/scans/$dockScans': typeof WarehouseDockdoorscanningScansDockScansRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
@@ -222,9 +222,9 @@ export interface FileRouteTypes {
| '/user/resetpassword'
| '/user/signup'
| '/warehouse/dockdoorscanning/$dock'
| '/warehouse/dockdoorscanning/$dockScans'
| '/transportation/opendock/'
| '/warehouse/dockdoorscanning/'
| '/warehouse/dockdoorscanning/scans/$dockScans'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
@@ -244,9 +244,9 @@ export interface FileRouteTypes {
| '/user/resetpassword'
| '/user/signup'
| '/warehouse/dockdoorscanning/$dock'
| '/warehouse/dockdoorscanning/$dockScans'
| '/transportation/opendock'
| '/warehouse/dockdoorscanning'
| '/warehouse/dockdoorscanning/scans/$dockScans'
id:
| '__root__'
| '/'
@@ -266,9 +266,9 @@ export interface FileRouteTypes {
| '/(auth)/user/resetpassword'
| '/(auth)/user/signup'
| '/warehouse/dockdoorscanning/$dock'
| '/warehouse/dockdoorscanning/$dockScans'
| '/transportation/opendock/'
| '/warehouse/dockdoorscanning/'
| '/warehouse/dockdoorscanning/scans/$dockScans'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
@@ -289,9 +289,9 @@ export interface RootRouteChildren {
authUserResetpasswordRoute: typeof authUserResetpasswordRoute
authUserSignupRoute: typeof authUserSignupRoute
WarehouseDockdoorscanningDockRoute: typeof WarehouseDockdoorscanningDockRoute
WarehouseDockdoorscanningDockScansRoute: typeof WarehouseDockdoorscanningDockScansRoute
TransportationOpendockIndexRoute: typeof TransportationOpendockIndexRoute
WarehouseDockdoorscanningIndexRoute: typeof WarehouseDockdoorscanningIndexRoute
WarehouseDockdoorscanningScansDockScansRoute: typeof WarehouseDockdoorscanningScansDockScansRoute
}
declare module '@tanstack/react-router' {
@@ -401,13 +401,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof TransportationOpendockIndexRouteImport
parentRoute: typeof rootRouteImport
}
'/warehouse/dockdoorscanning/$dockScans': {
id: '/warehouse/dockdoorscanning/$dockScans'
path: '/warehouse/dockdoorscanning/$dockScans'
fullPath: '/warehouse/dockdoorscanning/$dockScans'
preLoaderRoute: typeof WarehouseDockdoorscanningDockScansRouteImport
parentRoute: typeof rootRouteImport
}
'/warehouse/dockdoorscanning/$dock': {
id: '/warehouse/dockdoorscanning/$dock'
path: '/warehouse/dockdoorscanning/$dock'
@@ -436,6 +429,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof authUserProfileRouteImport
parentRoute: typeof rootRouteImport
}
'/warehouse/dockdoorscanning/scans/$dockScans': {
id: '/warehouse/dockdoorscanning/scans/$dockScans'
path: '/warehouse/dockdoorscanning/scans/$dockScans'
fullPath: '/warehouse/dockdoorscanning/scans/$dockScans'
preLoaderRoute: typeof WarehouseDockdoorscanningScansDockScansRouteImport
parentRoute: typeof rootRouteImport
}
}
}
@@ -457,10 +457,10 @@ const rootRouteChildren: RootRouteChildren = {
authUserResetpasswordRoute: authUserResetpasswordRoute,
authUserSignupRoute: authUserSignupRoute,
WarehouseDockdoorscanningDockRoute: WarehouseDockdoorscanningDockRoute,
WarehouseDockdoorscanningDockScansRoute:
WarehouseDockdoorscanningDockScansRoute,
TransportationOpendockIndexRoute: TransportationOpendockIndexRoute,
WarehouseDockdoorscanningIndexRoute: WarehouseDockdoorscanningIndexRoute,
WarehouseDockdoorscanningScansDockScansRoute:
WarehouseDockdoorscanningScansDockScansRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)

View File

@@ -120,6 +120,10 @@ export default function NewArticleLink({ refetch }: { refetch: any }) {
//TODO: get the docks from lst to help refine and actually link the dock correctly
const dock = [
{
label: "Default",
value: "default",
},
{
label: "Cermac",
value: "cermac",

View File

@@ -1,6 +1,7 @@
import { useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { format } from "date-fns";
import { toast } from "sonner";
import { Button } from "../../../components/ui/button";
import {
Card,
@@ -10,108 +11,155 @@ import {
CardHeader,
} from "../../../components/ui/card";
import { Separator } from "../../../components/ui/separator";
import { api } from "../../../lib/apiHelper";
import { getActiveLoadingOrders } from "../../../lib/queries/getActiveDockScanners";
import { getActiveDockScanners } from "../../../lib/queries/getActiveLoadingOrders";
import { finishLoadingOrder} from './index'
import { api } from "../../../lib/apiHelper";
import { toast } from "sonner";
import { finishLoadingOrder } from "./index";
export const Route = createFileRoute("/warehouse/dockdoorscanning/$dock")({
component: RouteComponent,
});
export const startOrder = async (loadingOrder: string, dockId: string, refetch:any, refetchActiveLoading:any) => {
export const startOrder = async (
loadingOrder: string,
dockId: string,
refetch: any,
refetchActiveLoading: any,
) => {
try {
const res = await api.post("/dockDoor/startLoad", {
"loadingOrder":String(loadingOrder),
"dockId":dockId
},{validateStatus: (status) => status < 500,})
const res = await api.post(
"/dockDoor/startLoad",
{
loadingOrder: String(loadingOrder),
dockId: dockId,
},
{ validateStatus: (status) => status < 500 },
);
if (!res.data.success) {
toast.error(res.data.message)
refetch()
refetchActiveLoading()
return
}
toast.success(res.data.message)
refetch()
refetchActiveLoading()
if (!res.data.success) {
toast.error(res.data.message);
refetch();
refetchActiveLoading();
return;
}
toast.success(res.data.message);
refetch();
refetchActiveLoading();
} catch (error) {
console.log(error)
toast.error(`Encountered error: ${JSON.stringify(error)}`)
console.log(error);
toast.error(`Encountered error: ${JSON.stringify(error)}`);
}
}
};
function RouteComponent() {
const { dock } = Route.useParams();
const { data, refetch } = useSuspenseQuery(getActiveDockScanners());
const { data: loadingPlanItems, refetch: refetchActiveLoading } = useSuspenseQuery(getActiveLoadingOrders());
const { data: loadingPlanItems, refetch: refetchActiveLoading } =
useSuspenseQuery(getActiveLoadingOrders());
const navigate = useNavigate();
const dockData = data.filter((i: any) => i.dockId === dock);
const loadingPlans = loadingPlanItems.filter(
(l: any) => l.dockId === Number(dock),
);
console.log(dockData[0].currentLoadingOrder === "");
return (
<div className="flex flex-col">
<div className="flex justify-center">
<p>Please select an active loading order for {dockData[0].name}</p>
</div>
<div className="flex justify-center mt-5 gap-2">
{loadingPlans &&
loadingPlans.length > 0 &&
loadingPlans.map((i: any) => {
return (
<Card key={i.id} className="max-w-96">
<CardHeader>
Loading order ID: {i.id}{" "}
<p>
Loading Date: {format(i.loadingDate, "MM/dd/yyyy HH:mm")}
</p>
</CardHeader>
<CardDescription className="">
<p className="p-3">
Below are the loading order details please validate the
loading order you are selecting before pressing start.
</p>
</CardDescription>
{/* Mapping the items out so in case we have more than 1 it will display correctly */}
<CardContent>
{i?.loadingPlanItems?.map((l: any) => {
return (
<div key={i.id}>
<p>Loading Sequence {l.loadingSequence}</p>
<p>
Article: {l.articleId} - {l.articleDescription}
</p>
<p>
Current loaded: {l.loadedQuantityLUs}/
{l.plannedQuantityLUs}
</p>
{l.remark !== "" && <p>Remark: {l.remark}</p>}
{loadingPlans && loadingPlans.length > 0 ? (
<div>
{loadingPlans.map((i: any) => {
return (
<Card key={i.id} className="max-w-96">
<CardHeader>
Loading order ID: {i.id}{" "}
<p>
Loading Date: {format(i.loadingDate, "MM/dd/yyyy HH:mm")}
</p>
</CardHeader>
<CardDescription className="">
<p className="p-3">
Below are the loading order details please validate the
loading order you are selecting before pressing start.
</p>
</CardDescription>
{/* Mapping the items out so in case we have more than 1 it will display correctly */}
<CardContent>
{i?.loadingPlanItems?.map((l: any) => {
return (
<div key={i.id}>
<p>Loading Sequence {l.loadingSequence}</p>
<p>
Article: {l.articleId} - {l.articleDescription}
</p>
<p>
Current loaded: {l.loadedQuantityLUs}/
{l.plannedQuantityLUs}
</p>
{l.remark !== "" && <p>Remark: {l.remark}</p>}
{i?.loadingPlanItems.length > 1 && (
<Separator className="m-2" />
)}
</div>
);
})}
</CardContent>
<CardFooter>
<div className="flex flex-row justify-between">
<Button
onClick={()=> startOrder(i.id, dock, refetch, refetchActiveLoading)}
disabled={dockData[0].currentLoadingOrder !== "" ? true : false}>Start Loading</Button>
<Button>Scan progress</Button>
<Button onClick={()=> finishLoadingOrder(String(i.id), dock, refetch, refetchActiveLoading)}
disabled={dockData[0].currentLoadingOrder === "" ? true : false}>Finish Loading</Button>
</div>
</CardFooter>
</Card>
);
})}
{i?.loadingPlanItems.length > 1 && (
<Separator className="m-2" />
)}
</div>
);
})}
</CardContent>
<CardFooter>
<div className="flex flex-row justify-between">
<Button
onClick={() =>
startOrder(i.id, dock, refetch, refetchActiveLoading)
}
disabled={
dockData[0].currentLoadingOrder !== "" ? true : false
}
>
Start Loading
</Button>
<Button
onClick={() =>
navigate({
to: "/warehouse/dockdoorscanning/scans/$dockScans",
params: { dockScans: dock },
})
}
>
Scan progress
</Button>
<Button
onClick={() =>
finishLoadingOrder(
String(i.id),
dock,
refetch,
refetchActiveLoading,
)
}
disabled={
dockData[0].currentLoadingOrder === "" ? true : false
}
>
Finish Loading
</Button>
</div>
</CardFooter>
</Card>
);
})}
</div>
) : (
<div>
<p>There are know loading orders currently active.</p>
<p>
Head over to Outbound deliveries to create a loading order to
start the flow
</p>
</div>
)}
</div>
</div>
);

View File

@@ -1,10 +0,0 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/warehouse/dockdoorscanning/$dockScans")({
component: RouteComponent,
});
function RouteComponent() {
const { dockScans } = Route.useParams();
return <div>Hello "/warehouse/dockdoorscanning/$docScans"! {dockScans}</div>;
}

View File

@@ -1,43 +1,58 @@
import { useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { Card, CardContent, CardDescription, CardHeader } from "../../../components/ui/card";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { toast } from "sonner";
import { Button } from "../../../components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
} from "../../../components/ui/card";
import { api } from "../../../lib/apiHelper";
import { getActiveLoadingOrders } from "../../../lib/queries/getActiveDockScanners";
import { getActiveDockScanners } from "../../../lib/queries/getActiveLoadingOrders";
import { Button } from "../../../components/ui/button";
import { api } from "../../../lib/apiHelper";
import { toast } from "sonner";
export const Route = createFileRoute("/warehouse/dockdoorscanning/")({
component: RouteComponent,
});
export const finishLoadingOrder = async (loadingOrder: string, dockId: string, refetch:any, refetchActiveLoading:any) => {
export const finishLoadingOrder = async (
loadingOrder: string,
dockId: string,
refetch: any,
refetchActiveLoading: any,
) => {
try {
const res = await api.post("/dockDoor/finishOrder", {
"loadingOrder":loadingOrder,
"dockId":dockId
},{validateStatus: (status) => status < 500,})
const res = await api.post(
"/dockDoor/finishOrder",
{
loadingOrder: loadingOrder,
dockId: dockId,
},
{ validateStatus: (status) => status < 500 },
);
if (!res.data.success) {
toast.error(res.data.message)
refetch()
refetchActiveLoading()
return
}
toast.info(res.data.message)
refetch()
refetchActiveLoading()
if (!res.data.success) {
toast.error(res.data.message);
refetch();
refetchActiveLoading();
return;
}
toast.info(res.data.message);
refetch();
refetchActiveLoading();
} catch (error) {
console.log(error)
toast.error(`Encountered error: ${JSON.stringify(error)}`)
console.log(error);
toast.error(`Encountered error: ${JSON.stringify(error)}`);
}
}
};
function RouteComponent() {
const { data, isLoading, refetch } = useSuspenseQuery(getActiveDockScanners());
const { data: loadingPlanItems, refetch : refetchActiveLoading } = useSuspenseQuery(getActiveLoadingOrders());
const { data, isLoading, refetch } = useSuspenseQuery(
getActiveDockScanners(),
);
const { data: loadingPlanItems, refetch: refetchActiveLoading } =
useSuspenseQuery(getActiveLoadingOrders());
const navigate = useNavigate();
if (isLoading) {
@@ -47,6 +62,7 @@ function RouteComponent() {
</div>
);
}
return (
<div className="flex flex-col ">
<div className="flex justify-center-safe">
@@ -64,8 +80,8 @@ function RouteComponent() {
(x: any) => x.id === Number(i.currentLoadingOrder),
)
: [];
console.log(loadingPlan);
console.log(loadingPlanItems);
return (
<Card
key={i.id}
@@ -83,28 +99,66 @@ function RouteComponent() {
}}
>
<CardHeader className="text-center">{i.name}</CardHeader>
<CardDescription>For Abbott loads reminder: 3 lots per load max.</CardDescription>
<CardDescription>
For Abbott loads reminder: 3 lots per load max.
</CardDescription>
{i.currentLoadingOrder !== "" ? (
<CardContent>
<div className="flex flex-col gap-2">
Current loading order: {i.currentLoadingOrder}
</div>
<div>
{loadingPlan && loadingPlan.length !== 0 ? (<>
<p>{`${loadingPlan[0].loadingPlanItems[0].articleId} - ${loadingPlan[0].loadingPlanItems[0].articleDescription}`}</p>
<p>Current Loaded :{" "}
{loadingPlan[0].loadingPlanItems[0].loadedQuantityLUs} /{" "}
{loadingPlan[0].loadingPlanItems[0].plannedQuantityLUs}</p></>
): <><p>The Current Loading order is invalid</p>
<p> It appears it could have been finished via another process</p>
<div className="m-2 flex justify-center">
<Button onClick={()=> finishLoadingOrder(i.currentLoadingOrder, i.dockId, refetch, refetchActiveLoading)}>Clear {i.currentLoadingOrder}</Button></div></>}</div>
<div>
{loadingPlan && loadingPlan.length !== 0 ? (
<>
<p>{`${loadingPlan[0].loadingPlanItems[0].articleId} - ${loadingPlan[0].loadingPlanItems[0].articleDescription}`}</p>
<p>
Current Loaded :{" "}
{
loadingPlan[0].loadingPlanItems[0]
.loadedQuantityLUs
}{" "}
/{" "}
{
loadingPlan[0].loadingPlanItems[0]
.plannedQuantityLUs
}
</p>
Check Scans:{" "}
<Link
to={"/warehouse/dockdoorscanning/scans/$dockScans"}
params={{ dockScans: i.dockId }}
className="underline"
>
CLICK HERE
</Link>
</>
) : (
<>
<p>The Current Loading order is invalid</p>
<p>
{" "}
It appears it could have been finished via another
process
</p>
<div className="m-2 flex justify-center">
<Button
onClick={() =>
finishLoadingOrder(
i.currentLoadingOrder,
i.dockId,
refetch,
refetchActiveLoading,
)
}
>
Clear {i.currentLoadingOrder}
</Button>
</div>
</>
)}
</div>
</CardContent>
) : (
<CardContent>

View File

@@ -0,0 +1,198 @@
import { useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { createColumnHelper } from "@tanstack/react-table";
import { formatInTimeZone } from "date-fns-tz";
import { toast } from "sonner";
import { Button } from "../../../../components/ui/button";
import { useSocketRoom } from "../../../../hooks/socket.io.hook";
import { api } from "../../../../lib/apiHelper";
import { useAppForm } from "../../../../lib/formSutff";
import { getActiveLoadingOrders } from "../../../../lib/queries/getActiveDockScanners";
import { getActiveDockScanners } from "../../../../lib/queries/getActiveLoadingOrders";
import LstTable from "../../../../lib/tableStuff/LstTable";
import SearchableHeader from "../../../../lib/tableStuff/SearchableHeader";
import { finishLoadingOrder } from "..";
export const Route = createFileRoute(
"/warehouse/dockdoorscanning/scans/$dockScans",
)({
component: RouteComponent,
});
function RouteComponent() {
const { dockScans } = Route.useParams();
const { data: logs, clearRoom } = useSocketRoom<any>(
`dockDoorLoading:${dockScans}`,
);
const { data, refetch } = useSuspenseQuery(getActiveDockScanners());
const { data: loadingPlanItems, refetch: refetchActiveLoading } =
useSuspenseQuery(getActiveLoadingOrders());
const columnHelper = createColumnHelper<any>();
const column = [
columnHelper.accessor("loadingOrder", {
header: ({ column }) => (
<SearchableHeader column={column} title="Loading Order" />
),
filterFn: "includesString",
cell: (i) => i.getValue(),
}),
columnHelper.accessor("loadingUnit", {
header: ({ column }) => (
<SearchableHeader column={column} title="Loading Unit" />
),
filterFn: "includesString",
cell: (i) => i.getValue(),
}),
columnHelper.accessor("loadingUnitStatus", {
header: ({ column }) => (
<SearchableHeader column={column} title="Status" />
),
filterFn: "includesString",
cell: (i) => i.getValue(),
}),
columnHelper.accessor("message", {
header: ({ column }) => (
<SearchableHeader column={column} title="Message" />
),
filterFn: "includesString",
cell: (i) => i.getValue(),
}),
columnHelper.accessor("upd_date", {
header: ({ column }) => (
<SearchableHeader column={column} title="Scanned At" />
),
filterFn: "includesString",
cell: (i) => {
function isDateValid(date: any) {
return date instanceof Date && !isNaN(date.getTime());
}
const trueDate = isDateValid(new Date(i.getValue()))
? formatInTimeZone(
i.getValue(),
`${window.LST_CONFIG?.timezone}`,
"MM/dd/yyyy HH:mm:ss",
)
: "invalid time";
return <span>{trueDate}</span>;
},
}),
columnHelper.accessor("status", {
header: ({ column }) => (
<SearchableHeader column={column} title="Status" />
),
filterFn: "includesString",
cell: (i) => i.getValue(),
}),
];
const form = useAppForm({
defaultValues: {
runningNo: "",
dockId: data[0].dockId,
},
onSubmit: async ({ value }) => {
try {
const res = await api.post("/dockDoor/loadUnit", value, {
validateStatus: (status) => status < 500,
});
refetchActiveLoading();
form.reset();
if (!res.data.success) {
toast.error(res.data.data.message);
return;
}
toast.success(res.data.message);
} catch (error) {
console.log(error);
}
},
});
const loadingPlan =
data[0].currentLoadingOrder !== ""
? loadingPlanItems.filter(
(x: any) => x.id === Number(data[0].currentLoadingOrder),
)
: [];
return (
<div>
<div>
<p className="text-2xl text-center">
You are monitoring scans for {data[0].name}
</p>
<p className="text-center">
Current load status:{" "}
{loadingPlan && loadingPlan.length !== 0 ? (
<span>
{loadingPlan[0].loadingPlanItems[0].loadedQuantityLUs} /{" "}
{loadingPlan[0].loadingPlanItems[0].plannedQuantityLUs}
</span>
) : (
<span>"No active loading orders</span>
)}
</p>
</div>
<div className="max-w-1/2 flex flex-col">
<div>
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<div className="flex flex-row">
<div className="mb-2 mr-2 max-w-48">
<form.AppField name="runningNo">
{(field) => (
<field.InputField
label="Running Number"
inputType="text"
required={true}
/>
)}
</form.AppField>
</div>
<div className="flex justify-end mt-8 mr-3 ">
<form.AppForm>
<form.SubmitButton>Submit</form.SubmitButton>
</form.AppForm>
</div>
</div>
</form>
</div>
<div className="flex justify-end mr-3 ">
<Button
type="button"
onClick={() => {
finishLoadingOrder(
String(data[0].currentLoadingOrder),
dockScans,
refetch,
refetchActiveLoading,
);
clearRoom();
}}
disabled={
loadingPlan ||
loadingPlan[0].loadingPlanItems[0].loadedQuantityLUs !==
loadingPlan[0].loadingPlanItems[0].plannedQuantityLUs
}
>
Finish Loading order
</Button>
<Button onClick={() => clearRoom()}>Clear Table</Button>
</div>
</div>
<div>
<LstTable data={logs} columns={column} pageSize={50} />
</div>
</div>
);
}

View File

@@ -0,0 +1 @@
ALTER TABLE "dock_door_scans" DROP CONSTRAINT "dock_door_scans_loading_Unit_unique";

File diff suppressed because it is too large Load Diff

View File

@@ -435,6 +435,13 @@
"when": 1780692629119,
"tag": "0061_wide_marrow",
"breakpoints": true
},
{
"idx": 62,
"version": "7",
"when": 1781009330205,
"tag": "0062_square_harrier",
"breakpoints": true
}
]
}