diff --git a/frontend/src/components/layout/side-components/logistics.tsx b/frontend/src/components/layout/side-components/logistics.tsx index 0a191a0..7362477 100644 --- a/frontend/src/components/layout/side-components/logistics.tsx +++ b/frontend/src/components/layout/side-components/logistics.tsx @@ -51,6 +51,14 @@ const items = [ module: "logistics", active: true, }, + { + title: "Ocme Cyclecount", + url: "/cyclecount", + icon: Package, + role: ["technician", "supervisor", "manager", "admin", "systemAdmin"], + module: "logistics", + active: true, + }, ]; export function LogisticsSideBar({user, moduleID}: {user: User | null; moduleID: string}) { diff --git a/frontend/src/components/layout/side-components/production.tsx b/frontend/src/components/layout/side-components/production.tsx index d55bc97..f472d9a 100644 --- a/frontend/src/components/layout/side-components/production.tsx +++ b/frontend/src/components/layout/side-components/production.tsx @@ -15,7 +15,7 @@ const items = [ title: "One Click Print", url: "/ocp", icon: Printer, - role: [], + role: ["viewer"], module: "ocp", active: true, }, diff --git a/frontend/src/components/ocme/CycleCountLog.tsx b/frontend/src/components/ocme/CycleCountLog.tsx new file mode 100644 index 0000000..9bc0e4b --- /dev/null +++ b/frontend/src/components/ocme/CycleCountLog.tsx @@ -0,0 +1,22 @@ +import {LstCard} from "../extendedUI/LstCard"; +import {CardContent, CardHeader} from "../ui/card"; +import {Skeleton} from "../ui/skeleton"; + +export default function CycleCountLog() { + return ( + + + Cycle Count logs + + + {Array(10) + .fill(0) + .map((_, i) => ( +
+ +
+ ))} +
+
+ ); +} diff --git a/frontend/src/components/ocme/ocmeCycleCount.tsx b/frontend/src/components/ocme/ocmeCycleCount.tsx new file mode 100644 index 0000000..7c0f65a --- /dev/null +++ b/frontend/src/components/ocme/ocmeCycleCount.tsx @@ -0,0 +1,81 @@ +import {toast} from "sonner"; +import {LstCard} from "../extendedUI/LstCard"; +import {Button} from "../ui/button"; +import {Input} from "../ui/input"; +import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "../ui/table"; +import {Skeleton} from "../ui/skeleton"; +import CycleCountLog from "./CycleCountLog"; + +export default function OcmeCycleCount() { + return ( +
+
+ +
+
+
+
+ +
+ +
+
+
+
+ + + + LaneID + Lane + AV + Description + Running Number + In Ocme + In Stock + Result + + + + {Array(10) + .fill(0) + .map((_, i) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + ))} + +
+
+
+
+
+ +
+
+ ); +} diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index e8b976f..b63b0e2 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -23,6 +23,7 @@ import { Route as AuthProfileImport } from './routes/_auth/profile' import { Route as AdminSettingsImport } from './routes/_admin/settings' import { Route as AdminServersImport } from './routes/_admin/servers' import { Route as AdminModulesImport } from './routes/_admin/modules' +import { Route as ocmeCyclecountIndexImport } from './routes/(ocme)/cyclecount/index' import { Route as logisticsMaterialHelperIndexImport } from './routes/(logistics)/materialHelper/index' import { Route as EomArticleAvImport } from './routes/_eom/article/$av' import { Route as logisticsMaterialHelperSiloLinkIndexImport } from './routes/(logistics)/materialHelper/siloLink/index' @@ -99,6 +100,12 @@ const AdminModulesRoute = AdminModulesImport.update({ getParentRoute: () => AdminRoute, } as any) +const ocmeCyclecountIndexRoute = ocmeCyclecountIndexImport.update({ + id: '/(ocme)/cyclecount/', + path: '/cyclecount/', + getParentRoute: () => rootRoute, +} as any) + const logisticsMaterialHelperIndexRoute = logisticsMaterialHelperIndexImport.update({ id: '/(logistics)/materialHelper/', @@ -228,6 +235,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof logisticsMaterialHelperIndexImport parentRoute: typeof rootRoute } + '/(ocme)/cyclecount/': { + id: '/(ocme)/cyclecount/' + path: '/cyclecount' + fullPath: '/cyclecount' + preLoaderRoute: typeof ocmeCyclecountIndexImport + parentRoute: typeof rootRoute + } '/(logistics)/materialHelper/consumption/': { id: '/(logistics)/materialHelper/consumption/' path: '/materialHelper/consumption' @@ -296,6 +310,7 @@ export interface FileRoutesByFullPath { '/ocp': typeof OcpIndexRoute '/article/$av': typeof EomArticleAvRoute '/materialHelper': typeof logisticsMaterialHelperIndexRoute + '/cyclecount': typeof ocmeCyclecountIndexRoute '/materialHelper/consumption': typeof logisticsMaterialHelperConsumptionIndexRoute '/materialHelper/siloLink': typeof logisticsMaterialHelperSiloLinkIndexRoute } @@ -313,6 +328,7 @@ export interface FileRoutesByTo { '/ocp': typeof OcpIndexRoute '/article/$av': typeof EomArticleAvRoute '/materialHelper': typeof logisticsMaterialHelperIndexRoute + '/cyclecount': typeof ocmeCyclecountIndexRoute '/materialHelper/consumption': typeof logisticsMaterialHelperConsumptionIndexRoute '/materialHelper/siloLink': typeof logisticsMaterialHelperSiloLinkIndexRoute } @@ -333,6 +349,7 @@ export interface FileRoutesById { '/ocp/': typeof OcpIndexRoute '/_eom/article/$av': typeof EomArticleAvRoute '/(logistics)/materialHelper/': typeof logisticsMaterialHelperIndexRoute + '/(ocme)/cyclecount/': typeof ocmeCyclecountIndexRoute '/(logistics)/materialHelper/consumption/': typeof logisticsMaterialHelperConsumptionIndexRoute '/(logistics)/materialHelper/siloLink/': typeof logisticsMaterialHelperSiloLinkIndexRoute } @@ -352,6 +369,7 @@ export interface FileRouteTypes { | '/ocp' | '/article/$av' | '/materialHelper' + | '/cyclecount' | '/materialHelper/consumption' | '/materialHelper/siloLink' fileRoutesByTo: FileRoutesByTo @@ -368,6 +386,7 @@ export interface FileRouteTypes { | '/ocp' | '/article/$av' | '/materialHelper' + | '/cyclecount' | '/materialHelper/consumption' | '/materialHelper/siloLink' id: @@ -386,6 +405,7 @@ export interface FileRouteTypes { | '/ocp/' | '/_eom/article/$av' | '/(logistics)/materialHelper/' + | '/(ocme)/cyclecount/' | '/(logistics)/materialHelper/consumption/' | '/(logistics)/materialHelper/siloLink/' fileRoutesById: FileRoutesById @@ -400,6 +420,7 @@ export interface RootRouteChildren { LoginRoute: typeof LoginRoute OcpIndexRoute: typeof OcpIndexRoute logisticsMaterialHelperIndexRoute: typeof logisticsMaterialHelperIndexRoute + ocmeCyclecountIndexRoute: typeof ocmeCyclecountIndexRoute logisticsMaterialHelperConsumptionIndexRoute: typeof logisticsMaterialHelperConsumptionIndexRoute logisticsMaterialHelperSiloLinkIndexRoute: typeof logisticsMaterialHelperSiloLinkIndexRoute } @@ -413,6 +434,7 @@ const rootRouteChildren: RootRouteChildren = { LoginRoute: LoginRoute, OcpIndexRoute: OcpIndexRoute, logisticsMaterialHelperIndexRoute: logisticsMaterialHelperIndexRoute, + ocmeCyclecountIndexRoute: ocmeCyclecountIndexRoute, logisticsMaterialHelperConsumptionIndexRoute: logisticsMaterialHelperConsumptionIndexRoute, logisticsMaterialHelperSiloLinkIndexRoute: @@ -437,6 +459,7 @@ export const routeTree = rootRoute "/login", "/ocp/", "/(logistics)/materialHelper/", + "/(ocme)/cyclecount/", "/(logistics)/materialHelper/consumption/", "/(logistics)/materialHelper/siloLink/" ] @@ -501,6 +524,9 @@ export const routeTree = rootRoute "/(logistics)/materialHelper/": { "filePath": "(logistics)/materialHelper/index.tsx" }, + "/(ocme)/cyclecount/": { + "filePath": "(ocme)/cyclecount/index.tsx" + }, "/(logistics)/materialHelper/consumption/": { "filePath": "(logistics)/materialHelper/consumption/index.tsx" }, diff --git a/frontend/src/routes/(ocme)/cyclecount/index.tsx b/frontend/src/routes/(ocme)/cyclecount/index.tsx new file mode 100644 index 0000000..f4263aa --- /dev/null +++ b/frontend/src/routes/(ocme)/cyclecount/index.tsx @@ -0,0 +1,14 @@ +import OcmeCycleCount from "@/components/ocme/ocmeCycleCount"; +import {createFileRoute} from "@tanstack/react-router"; + +export const Route = createFileRoute("/(ocme)/cyclecount/")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ( +
+ +
+ ); +} diff --git a/frontend/src/utils/querys/production/labels.tsx b/frontend/src/utils/querys/production/labels.tsx index b93e2d3..ab658ee 100644 --- a/frontend/src/utils/querys/production/labels.tsx +++ b/frontend/src/utils/querys/production/labels.tsx @@ -7,7 +7,7 @@ export function getlabels(hours: string) { queryFn: () => fetchSettings(hours), staleTime: 1000, - refetchInterval: 2500, + //refetchInterval: 2500, refetchOnWindowFocus: true, }); } @@ -16,5 +16,5 @@ const fetchSettings = async (hours: string) => { const {data} = await axios.get(`/api/v1/ocp/labels?hours=${hours}`); // if we are not localhost ignore the devDir setting. //const url: string = window.location.host.split(":")[0]; - return data.data; + return data.data ?? []; }; diff --git a/frontend/src/utils/querys/production/lots.tsx b/frontend/src/utils/querys/production/lots.tsx index 1b3adbb..c9ce178 100644 --- a/frontend/src/utils/querys/production/lots.tsx +++ b/frontend/src/utils/querys/production/lots.tsx @@ -7,7 +7,7 @@ export function getlots() { queryFn: () => fetchSettings(), staleTime: 10 * 1000, - refetchInterval: 10 * 1000, + //refetchInterval: 10 * 1000, refetchOnWindowFocus: true, }); } @@ -17,5 +17,5 @@ const fetchSettings = async () => { // if we are not localhost ignore the devDir setting. //const url: string = window.location.host.split(":")[0]; let lotData = data.data; - return lotData; + return lotData ?? []; }; diff --git a/frontend/src/utils/userAccess.ts b/frontend/src/utils/userAccess.ts index 4d95af0..7dd7a16 100644 --- a/frontend/src/utils/userAccess.ts +++ b/frontend/src/utils/userAccess.ts @@ -13,15 +13,13 @@ export function hasAccess(user: User | null, moduleName: string | null, modules: } export function hasPageAccess(user: User | null, role: any, module_id: string): boolean { - if (role.length === 0) return true; + if (role.includes("viewer")) return true; if (!user) return false; // get only the module in the user profile const userRole = user?.roles.filter((role) => role.module_id === module_id); - if (role.includes(userRole[0]?.role)) { - return true; - } + if (role.includes(userRole[0]?.role)) return true; return false; } diff --git a/server/index.ts b/server/index.ts index d42fdef..409a7ea 100644 --- a/server/index.ts +++ b/server/index.ts @@ -88,32 +88,32 @@ const appRoutes = routes.forEach((route) => { app.route("/api/", route); }); -app.route("/ocme/*", ocme); +app.route("/ocme/", ocme); //--------------- lst v1 proxy ----------------------\\ -app.all("/api/v1/*", (c) => { - const path = c.req.path.replace("/api/v1/", ""); // Extract the subpath - const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params - return proxy(`http://localhost:4900/${path}${query}`, { - headers: { - ...c.req.header(), - "X-Forwarded-For": "127.0.0.1", - "X-Forwarded-Host": c.req.header("host"), - }, - }); -}); +// app.all("/api/v1/*", (c) => { +// const path = c.req.path.replace("/api/v1/", ""); // Extract the subpath +// const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params +// return proxy(`http://localhost:4900/${path}${query}`, { +// headers: { +// ...c.req.header(), +// "X-Forwarded-For": "127.0.0.1", +// "X-Forwarded-Host": c.req.header("host"), +// }, +// }); +// }); -app.all("/system/*", (c) => { - const path = c.req.path.replace("/system/", ""); // Extract the subpath - const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params - return proxy(`http://localhost:4200/${path}${query}`, { - headers: { - ...c.req.header(), - "X-Forwarded-For": "127.0.0.1", - "X-Forwarded-Host": c.req.header("host"), - }, - }); -}); +// app.all("/system/*", (c) => { +// const path = c.req.path.replace("/system/", ""); // Extract the subpath +// const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params +// return proxy(`http://localhost:4200/${path}${query}`, { +// headers: { +// ...c.req.header(), +// "X-Forwarded-For": "127.0.0.1", +// "X-Forwarded-Host": c.req.header("host"), +// }, +// }); +// }); //---------------------------------------------------\\ diff --git a/server/services/ocme/controller/cycleCount.ts b/server/services/ocme/controller/cycleCount.ts new file mode 100644 index 0000000..d698500 --- /dev/null +++ b/server/services/ocme/controller/cycleCount.ts @@ -0,0 +1,63 @@ +import type {User} from "../../../types/users.js"; +import {alplaStockInv} from "./cycleCount/alplaStockInventory.js"; +import {emptyCount} from "./cycleCount/emptyCycleCount.js"; +import {ocmeInv} from "./cycleCount/ocmeInventory.js"; + +export const prepareLane = "https://usday1prod.alpla.net/application/public/v1.1/Warehousing/PrepareLaneForInventory"; +export const openLane = "https://usday1prod.alpla.net/application/public/v1.0/Warehousing/InventoryOpen"; +export const closeLane = "https://usday1prod.alpla.net/application/public/v1.0/Warehousing/InventoryClose"; +export const releaseLane = "https://usday1prod.alpla.net/application/public/v1.1/Warehousing/ReleaseLaneFromInventory"; +export const scannerID = 500; +export const cycleCount = async (lane: string, user: User) => { + /** + * We will get the inventory from both systems and merge them together, intert it into our db then do the cycle count and update each item + * one it dose it. + */ + + // get ocme data first + const ocme = await ocmeInv(lane); + + // get alpla stock data + const alplaStock = await alplaStockInv(ocme[0].alpla_laneID); + + // create a new array that has the merge happen. + const mergeOcmeData = ocme.map((d) => { + // check if its in the ocme array we add it + const inStock = alplaStock.filter((r: any) => r.runningNumber === d.runningNumber); + //console.log(inStock); + if (inStock.length != 0) { + //console.log(`${d.runningNumber} is good`); + return {...d, ocme: "Yes", stock: "Yes", info: "Good"}; + } else { + //console.log(`${d.runningNumber} is bad`); + return {...d, ocme: "Yes", stock: "No", info: "Quality Check Required"}; + } + }); + + const mergeStockData = alplaStock + .filter((r: any) => !ocme.some((d: any) => d.runningNumber === r.runningNumber)) + .map((r: any) => { + return { + ...r, + ocme_laneLevelID: "", + sscc: "", + ocme: "No", + stock: "Yes", + info: "Sent to Inv", + }; + }); + + const combineBoth = [...mergeOcmeData, ...mergeStockData]; + + // determine what type of count we are doing. + if (ocme.length === 0) { + // do empty count + await emptyCount(user, lane); + } else { + // do the full lane inv + } + + // store in the db so we have a record.... for later when we fully randomize and automate this. + + return combineBoth; +}; diff --git a/server/services/ocme/controller/cycleCount/alplaStockInventory.ts b/server/services/ocme/controller/cycleCount/alplaStockInventory.ts new file mode 100644 index 0000000..b1adfe7 --- /dev/null +++ b/server/services/ocme/controller/cycleCount/alplaStockInventory.ts @@ -0,0 +1,18 @@ +import {query} from "../../../sqlServer/prodSqlServer.js"; +import {alplaStock} from "../../../sqlServer/querys/ocme/alplaStockInvByID.js"; + +export const alplaStockInv = async (laneID: string) => { + /** + * We will get the stock data based on the lane id passed over + */ + + const stock = alplaStock.replaceAll("[laneID]", `${laneID}`); + + try { + const stockData = await query(stock, "Stock Data"); + return stockData; + } catch (error) { + console.log(error); + return []; + } +}; diff --git a/server/services/ocme/controller/cycleCount/emptyCycleCount.ts b/server/services/ocme/controller/cycleCount/emptyCycleCount.ts new file mode 100644 index 0000000..50bc94f --- /dev/null +++ b/server/services/ocme/controller/cycleCount/emptyCycleCount.ts @@ -0,0 +1,91 @@ +import axios from "axios"; +import {closeLane, openLane, prepareLane, releaseLane, scannerID} from "../cycleCount.js"; +import {createLog} from "../../../logger/logger.js"; +import type {User} from "../../../../types/users.js"; + +export const emptyCount = async (user: User, lane: string) => { + try { + const openlane = await axios({ + method: "POST", + url: prepareLane, + headers: { + Authorization: `Basic ${user.prod}`, + "Content-Type": "application/json", + }, + data: { + scannerId: scannerID, + laneId: lane, + }, + }); + + createLog("info", user.username!, "ocme-count", openlane.data.message); + + // start the empty inventory process + if (openlane.data.result === 0) { + try { + const open = await axios({ + method: "POST", + url: openLane, + headers: { + Authorization: `Basic ${user.prod}`, + "Content-Type": "application/json", + }, + data: { + scannerId: scannerID, + laneId: lane, + }, + }); + + createLog("info", user.username!, "ocme-count", openlane.data.message); + + if (open.data.Result === 0) { + //consider the lane empty and close it + try { + const closelane = await axios({ + method: "POST", + url: closeLane, + headers: { + Authorization: `Basic ${user.prod}`, + "Content-Type": "application/json", + }, + data: { + scannerId: scannerID, + laneId: lane, + }, + }); + + createLog("info", user.username!, "ocme-count", openlane.data.message); + + if (closelane.data.Result === 0) { + //release the lane + //---------------------------------------------------- + try { + const close = await axios({ + method: "POST", + url: releaseLane, + headers: { + Authorization: `Basic ${user.prod}`, + "Content-Type": "application/json", + }, + data: { + laneId: lane, + }, + }); + + createLog("info", user.username!, "ocme-count", close.data.message); + } catch (error) { + createLog("error", user.username!, "ocme-count", "Releasing the lane"); + } + } + } catch (error) { + createLog("error", user.username!, "ocme-count", "Closing the lane"); + } + } + } catch (error) { + createLog("error", user.username!, "ocme-count", "Opening the lane"); + } + } + } catch (error) { + createLog("error", user.username!, "ocme-count", "Preparing the lane"); + } +}; diff --git a/server/services/ocme/controller/cycleCount/fullLaneCycleCount.ts b/server/services/ocme/controller/cycleCount/fullLaneCycleCount.ts new file mode 100644 index 0000000..e69de29 diff --git a/server/services/ocme/controller/cycleCount/ocmeInventory.ts b/server/services/ocme/controller/cycleCount/ocmeInventory.ts new file mode 100644 index 0000000..fdb88ac --- /dev/null +++ b/server/services/ocme/controller/cycleCount/ocmeInventory.ts @@ -0,0 +1,284 @@ +import axios from "axios"; +const data = [ + { + ocme_laneLevelID: "P3F36PZ1PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005256402", + runningNumber: "525640", + }, + { + ocme_laneLevelID: "P3F36PZ1PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005402649", + runningNumber: "540264", + }, + { + ocme_laneLevelID: "P3F36PZ1PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005312559", + runningNumber: "531255", + }, + { + ocme_laneLevelID: "P3F36PZ1PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005312658", + runningNumber: "531265", + }, + { + ocme_laneLevelID: "P3F36PZ2PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005404186", + runningNumber: "540418", + }, + { + ocme_laneLevelID: "P3F36PZ2PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005404193", + runningNumber: "540419", + }, + { + ocme_laneLevelID: "P3F36PZ2PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005404155", + runningNumber: "540415", + }, + { + ocme_laneLevelID: "P3F36PZ2PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005404230", + runningNumber: "540423", + }, + { + ocme_laneLevelID: "P3F36PZ3PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "146", + description: "HDPE Trigger 16oz White", + sscc: "090103830005306589", + runningNumber: "530658", + }, + { + ocme_laneLevelID: "P3F36PZ3PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005408634", + runningNumber: "540841", + }, + { + ocme_laneLevelID: "P3F36PZ3PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005836888", + runningNumber: "583688", + }, + { + ocme_laneLevelID: "P3F36PZ3PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005836871", + runningNumber: "583687", + }, + { + ocme_laneLevelID: "P3F36PZ4PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005845279", + runningNumber: "584527", + }, + { + ocme_laneLevelID: "P3F36PZ4PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005845231", + runningNumber: "584523", + }, + { + ocme_laneLevelID: "P3F36PZ4PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005845170", + runningNumber: "584517", + }, + { + ocme_laneLevelID: "P3F36PZ4PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005845156", + runningNumber: "584515", + }, + { + ocme_laneLevelID: "P3F36PZ5PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005870325", + runningNumber: "587032", + }, + { + ocme_laneLevelID: "P3F36PZ5PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005871490", + runningNumber: "587149", + }, + { + ocme_laneLevelID: "P3F36PZ5PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005851782", + runningNumber: "585178", + }, + { + ocme_laneLevelID: "P3F36PZ5PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005855339", + runningNumber: "585533", + }, + { + ocme_laneLevelID: "P3F36PZ6PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005867660", + runningNumber: "586766", + }, + { + ocme_laneLevelID: "P3F36PZ6PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005867622", + runningNumber: "586762", + }, + { + ocme_laneLevelID: "P3F36PZ6PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005865871", + runningNumber: "586587", + }, + { + ocme_laneLevelID: "P3F36PZ6PN4", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005865895", + runningNumber: "586589", + }, + { + ocme_laneLevelID: "P3F36PZ7PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005866052", + runningNumber: "586605", + }, + { + ocme_laneLevelID: "P3F36PZ7PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005865970", + runningNumber: "586597", + }, + { + ocme_laneLevelID: "P3F36PZ7PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005877089", + runningNumber: "587708", + }, + { + ocme_laneLevelID: "P3F36PZ8PN1", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005844975", + runningNumber: "584497", + }, + { + ocme_laneLevelID: "P3F36PZ8PN2", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005844944", + runningNumber: "584494", + }, + { + ocme_laneLevelID: "P3F36PZ8PN3", + alpla_laneID: "30285 ", + alpla_laneDescription: "L064", + Article: "164", + description: "HDPE Trigger 16oz Orange", + sscc: "090103830005844890", + runningNumber: "584489", + }, +]; +export const ocmeInv = async (lane: string) => { + try { + const res = await axios.post("http://usday1vms010:3250/api/v1/getLaneData", {lane: lane}); + console.log(res.data); + + return data; + } catch (error: any) { + console.log(error.code); + return data; + } +}; diff --git a/server/services/ocme/ocmeService.ts b/server/services/ocme/ocmeService.ts index ba70961..9593a87 100644 --- a/server/services/ocme/ocmeService.ts +++ b/server/services/ocme/ocmeService.ts @@ -6,6 +6,7 @@ import postRunningNr from "./route/postRunningNumber.js"; import pickedup from "./route/pickedUp.js"; import postsscc from "./route/postSSCC.js"; import getShipments from "./route/getShipmentPallets.js"; +import cycleCount from "./route/cycleCount.js"; import {serve} from "@hono/node-server"; import {createLog} from "../logger/logger.js"; import {db} from "../../../database/dbclient.js"; @@ -13,7 +14,7 @@ import {settings} from "../../../database/schema/settings.js"; const app = new OpenAPIHono(); const port = process.env.OCME_PORT; -const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments] as const; +const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments, cycleCount] as const; const setting = await db.select().from(settings); const isActive = setting.filter((n) => n.name === "ocmeService"); diff --git a/server/services/ocme/route/cycleCount.ts b/server/services/ocme/route/cycleCount.ts new file mode 100644 index 0000000..e045db3 --- /dev/null +++ b/server/services/ocme/route/cycleCount.ts @@ -0,0 +1,60 @@ +import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi"; + +import {apiHit} from "../../../globalUtils/apiHits.js"; +import {responses} from "../../../globalUtils/routeDefs/responses.js"; +import {authMiddleware} from "../../auth/middleware/authMiddleware.js"; +import {cycleCount} from "../controller/cycleCount.js"; +import type {User} from "../../../types/users.js"; +import {verify} from "hono/jwt"; + +const app = new OpenAPIHono({strict: false}); + +const AddSetting = z.object({ + lane: z.string().openapi({example: "L064"}), +}); + +app.openapi( + createRoute({ + tags: ["ocme"], + summary: "Cycle counts a lane based on the lane Alias", + method: "post", + path: "/cyclecount", + middleware: authMiddleware, + request: { + body: { + content: { + "application/json": {schema: AddSetting}, + }, + }, + }, + responses: responses(), + }), + async (c) => { + apiHit(c, {endpoint: "api/auth/register"}); + // make sure we have a vaid user being accessed thats really logged in + const body = await c.req.json(); + + const authHeader = c.req.header("Authorization"); + + const token = authHeader?.split("Bearer ")[1] || ""; + let user: User; + + try { + const payload = await verify(token, process.env.JWT_SECRET!); + user = payload.user as User; + } catch (error) { + return c.json({message: "Unauthorized"}, 401); + } + + try { + const cycleData = await cycleCount(body, user); + return c.json({success: true, message: `${body.lane} was just cycle counted.`, data: cycleData}, 200); + } catch (error) { + return c.json( + {success: false, message: `There was an error cycle counting ${body.lane}`, data: error}, + 400 + ); + } + } +); +export default app; diff --git a/server/services/sqlServer/querys/ocme/alplaStockInvByID.ts b/server/services/sqlServer/querys/ocme/alplaStockInvByID.ts new file mode 100644 index 0000000..486a763 --- /dev/null +++ b/server/services/sqlServer/querys/ocme/alplaStockInvByID.ts @@ -0,0 +1,9 @@ +export const alplaStock = ` +select IdLagerAbteilung as alpla_laneID, +LagerAbteilungKurzBez as alpla_laneDescription, +IdArtikelVarianten as Article, +ArtikelVariantenBez as description, +lfdnr as runningNumber +from AlplaPROD_test1.dbo.V_LagerPositionenBarcodes +where IdLagerAbteilung = [laneID] +`; diff --git a/server/types/users.ts b/server/types/users.ts index 30c9352..be98bc2 100644 --- a/server/types/users.ts +++ b/server/types/users.ts @@ -6,4 +6,5 @@ export type User = { username?: string; roles?: Roles[]; role?: string; + prod?: string; };