feat(mobile): dock door scanning backend added

ref #12
This commit is contained in:
2026-05-27 20:54:47 -05:00
parent 9c0ef1f5df
commit fe0b1573f3
18 changed files with 573 additions and 5 deletions

View File

@@ -0,0 +1,35 @@
import { addDays, subDays } from "date-fns";
import { format } from "date-fns-tz";
import { Router } from "express";
import { runProdApi } from "../utils/prodEndpoint.utils.js";
import { apiReturn } from "../utils/returnHelper.utils.js";
const r = Router();
r.get("/", async (_, res) => {
const orders = await runProdApi({
method: "post",
endpoint: "/public/v1.0/OutboundDeliveries/LoadingOrders/Search",
data: [
{
loadingDateFrom: format(subDays(new Date(Date.now()), 3), "yyyy-MM-dd"),
loadingDateTo: format(addDays(new Date(Date.now()), 3), "yyyy-MM-dd"),
states: [
1, // planned
],
//isCommissioned: true,
},
],
});
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "current Active loading orders",
message: `Current active loading loaders.`,
data: orders?.data ?? [],
status: 200,
});
});
export default r;

View File

@@ -0,0 +1,18 @@
import { Router } from "express";
import { apiReturn } from "../utils/returnHelper.utils.js";
const r = Router();
r.post("/", async (req, res) => {
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "lane check",
message: `Release x is being closed now. the bol should come out at the default printer.`,
data: req.body ?? [],
status: 200,
});
});
export default r;

View File

@@ -0,0 +1,89 @@
// sends the units from the dock door scanner here.
import { eq } from "drizzle-orm";
import { db } from "../db/db.controller.js";
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
import { runProdApi } from "../utils/prodEndpoint.utils.js";
import { returnFunc } from "../utils/returnHelper.utils.js";
// validate we are active
type Data = {
dockId?: string;
sscc?: string;
runningNr?: string;
};
export const loadUnit = async (data: Data) => {
// are we even active at this time?
const dockDoorActive = await db.query.settings.findFirst({
where: (u, { eq }) => eq(u.name, "dockDoorScanning"),
});
if (!dockDoorActive?.active) {
return returnFunc({
success: false,
level: "error",
module: "dockdoor",
subModule: "loadunit",
message: "Dock door scanning feature is not active.",
data: [],
notify: false,
room: "",
});
}
// check if its a valids an sscc
if (data.sscc === "noread") {
return returnFunc({
success: false,
level: "error",
module: "dockdoor",
subModule: "loadUnit",
message:
"Failed to load the unit to the truck, there was no pallet read.",
data: [],
notify: false,
room: `dockDoorLoading${data.dockId}`,
});
}
// check if we currently have a loading order attached to the dock door.
const dock = await db
.select()
.from(dockDoorScanners)
.where(eq(dockDoorScanners.dockId, data.dockId as string));
if (dock[0]?.currentLoadingOrder === "") {
return returnFunc({
success: true,
level: "error",
module: "dockdoor",
subModule: "loadingOrders",
message:
"There are know current active loading orders please start one and try again.",
data: [],
notify: false,
room: `dockDoorLoading${data.dockId}`,
});
}
// TODO: pallet validation, check if we are on hold, then check if we have been in the staging warehouse for more than x time.
// if on hold stop the scan and send a bad read with the reason its on hold and what its on hold for, including coa.
// if precheck is active then check if we have a warehouse, then check if the pallet was in the warehouse for greater than the define min, all fails send a warning and still do the scan
// add the loading units
try {
const prod = await runProdApi({
method: "post",
endpoint: `/public/v1.0/OutboundDeliveries/LoadingOrders/${dock[0]?.currentLoadingOrder}/LoadUnit`,
data: [{ sscc: data.sscc?.slice(2) }],
});
console.log(prod?.data);
} catch (error) {
console.log(error);
}
};

View File

@@ -0,0 +1,43 @@
import type { Express } from "express";
import { featureCheck } from "../middleware/featureActive.middleware.js";
import activeLoadingOrders from "./dockdoor.activeLoadingOrders.route.js";
import closeLoadingOrder from "./dockdoor.closeLoadingOrder.route.js";
import startLoad from "./dockdoor.startLoad.route.js";
import prodDocks from "./dockdoors.docks.route.js";
import docks from "./dockdoors.route.js";
export const setupDockDoorRoutes = (baseUrl: string, app: Express) => {
//stats will be like this as we dont need to change this
app.use(
`${baseUrl}/api/dockDoor/scanners`,
featureCheck("dockDoorScanning"),
docks,
);
app.use(
`${baseUrl}/api/dockDoor/closeLoadingOrder`,
featureCheck("dockDoorScanning"),
closeLoadingOrder,
);
app.use(
`${baseUrl}/api/dockDoor/activeLoadingOrders`,
featureCheck("dockDoorScanning"),
activeLoadingOrders,
);
app.use(
`${baseUrl}/api/dockDoor/startLoad`,
featureCheck("dockDoorScanning"),
startLoad,
);
app.use(
`${baseUrl}/api/dockDoor/docks`,
featureCheck("dockDoorScanning"),
prodDocks,
);
// TODO : add manual way to add pallets
// all other system should be under /api/system/*
};

View File

@@ -0,0 +1,65 @@
import { sql } from "drizzle-orm";
import { Router } from "express";
import z from "zod";
import { db } from "../db/db.controller.js";
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
import { apiReturn } from "../utils/returnHelper.utils.js";
import { tryCatch } from "../utils/trycatch.utils.js";
const r = Router();
const startLoading = z.object({
loadingOrder: z.string(),
dockId: z.string(),
});
r.post("/", async (req, res) => {
try {
const validated = startLoading.parse(req.body);
const { data, error } = await tryCatch(
db
.update(dockDoorScanners)
.set({
currentLoadingOrder: validated.loadingOrder,
upd_date: sql`NOW()`,
upd_user: req.user?.username,
})
.returning(),
);
if (error) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "loadingOrder",
message: `Failed to updating the dock.`,
data: (error as any) ?? [],
status: 400,
});
}
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "loadingOrder",
message: `Loading order ${validated.loadingOrder} was just added to dockId ${validated.dockId}.`,
data: data ?? [],
status: 200,
});
} catch (error) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "loadingOrder",
message: `Failed to start loading order.`,
data: (error as any) ?? [],
status: 400,
});
}
});
export default r;

View File

@@ -0,0 +1,54 @@
import { Router } from "express";
import { prodQuery } from "../prodSql/prodSqlQuery.controller.js";
import {
type SqlQuery,
sqlQuerySelector,
} from "../prodSql/prodSqlQuerySelector.utils.js";
import { apiReturn } from "../utils/returnHelper.utils.js";
import { tryCatch } from "../utils/trycatch.utils.js";
const r = Router();
r.get("/", async (_, res) => {
const activeDocks = sqlQuerySelector(`outbound.docks`) as SqlQuery;
if (!activeDocks.success) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "docks",
message: `There was an error getting the docks query.`,
data: [],
status: 400,
});
}
const { data, error } = await tryCatch(
prodQuery(activeDocks.query, "Current Active Docks"),
);
if (error) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "newDock",
message: `There was an error getting the docks.`,
data: (error as any) ?? ([] as any),
status: 400,
});
}
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "docks",
message: `Current active docks.`,
data: (data.data as any) ?? ([] as any),
status: 200,
});
});
export default r;

View File

@@ -0,0 +1,76 @@
import { Router } from "express";
import z from "zod";
import { db } from "../db/db.controller.js";
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
import { requireAuth } from "../middleware/auth.middleware.js";
import { apiReturn } from "../utils/returnHelper.utils.js";
const r = Router();
const newDockScanner = z.object({
ip: z.string(),
name: z.string(),
dockId: z.string(),
});
r.get("/", async (_, res) => {
try {
const docks = await db
.select()
.from(dockDoorScanners)
.orderBy(dockDoorScanners.name);
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "lane check",
message: `All dock Doors.`,
data: docks ?? [],
status: 200,
});
} catch (error) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "newDock",
message: `There was an error adding in the new dock.`,
data: error ?? ([] as any),
status: 200,
});
}
});
r.post("/", requireAuth, async (req, res) => {
try {
const validated = newDockScanner.parse(req.body);
const newDock = await db
.insert(dockDoorScanners)
.values(validated)
.returning();
return apiReturn(res, {
success: true,
level: "info",
module: "dockdoor",
subModule: "lane check",
message: `${validated.name} was just added.`,
data: newDock ?? [],
status: 200,
});
} catch (error) {
return apiReturn(res, {
success: false,
level: "error",
module: "dockdoor",
subModule: "newDock",
message: `There was an error adding in the new dock.`,
data: error ?? ([] as any),
status: 200,
});
}
});
export default r;