Compare commits
22 Commits
12e15babb4
...
995311c563
| Author | SHA1 | Date | |
|---|---|---|---|
| 995311c563 | |||
| 123d8a09ba | |||
| 4fe400af3b | |||
| 8c31ac723d | |||
| a5cd8433f7 | |||
| c5f12814ea | |||
| e2562768a5 | |||
| 971038b10e | |||
| 1bcb4db328 | |||
| f15afe5c11 | |||
| 0e579c84b5 | |||
| 40b970ef92 | |||
| 0eb60706e4 | |||
| 27d242f4f3 | |||
| cd4109533e | |||
| 8b1c65db4e | |||
| 6d1157a9d0 | |||
| 9df643ce6b | |||
| 6c4e14fad3 | |||
| 22e050ebfa | |||
| 008717b988 | |||
| 65b35bc9a3 |
26
database/schema/apiHits.ts
Normal file
26
database/schema/apiHits.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import {pgTable, text, timestamp} from "drizzle-orm/pg-core";
|
||||
import {createSelectSchema} from "drizzle-zod";
|
||||
|
||||
export const apiHits = pgTable(
|
||||
"apiHits",
|
||||
{
|
||||
ip: text("ip"),
|
||||
endpoint: text("endpoint"),
|
||||
action: text("action"),
|
||||
lastBody: text("lastBody"),
|
||||
stats: text("stats"),
|
||||
add_date: timestamp().defaultNow(),
|
||||
upd_date: timestamp().defaultNow(),
|
||||
}
|
||||
// (table) => [
|
||||
// // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
||||
// uniqueIndex("role_name").on(table.name),
|
||||
// ]
|
||||
);
|
||||
|
||||
// Schema for inserting a user - can be used to validate API requests
|
||||
// export const insertRolesSchema = createInsertSchema(roles, {
|
||||
// name: z.string().min(3, {message: "Role name must be more than 3 letters"}),
|
||||
// });
|
||||
// Schema for selecting a Expenses - can be used to validate API responses
|
||||
export const selectRolesSchema = createSelectSchema(apiHits);
|
||||
14
drizzle-dev.config.ts
Normal file
14
drizzle-dev.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {defineConfig} from "drizzle-kit";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const database = process.env.DATABASE_URL! || "";
|
||||
export default defineConfig({
|
||||
dialect: "postgresql", // 'mysql' | 'sqlite' | 'turso'
|
||||
schema: "database/schema",
|
||||
out: "database/migrations",
|
||||
dbCredentials: {
|
||||
url: database,
|
||||
},
|
||||
});
|
||||
@@ -19,7 +19,12 @@ export function AppSidebar() {
|
||||
<Sidebar collapsible="icon">
|
||||
<SidebarContent>
|
||||
<Header />
|
||||
{moduleActive("production") && <ProductionSideBar />}
|
||||
{moduleActive("production") && (
|
||||
<ProductionSideBar
|
||||
user={user}
|
||||
moduleID={modules.filter((n) => n.name === "production")[0].module_id as string}
|
||||
/>
|
||||
)}
|
||||
{moduleActive("logistics") && (
|
||||
<LogisticsSideBar
|
||||
user={user}
|
||||
|
||||
@@ -15,7 +15,7 @@ const items = [
|
||||
title: "Silo Adjustments",
|
||||
url: "#",
|
||||
icon: Cylinder,
|
||||
role: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
||||
role: ["admin", "systemAdmin"],
|
||||
module: "logistics",
|
||||
active: true,
|
||||
},
|
||||
@@ -23,7 +23,7 @@ const items = [
|
||||
title: "Bulk orders",
|
||||
url: "#",
|
||||
icon: Truck,
|
||||
role: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
||||
role: ["systemAdmin"],
|
||||
module: "logistics",
|
||||
active: true,
|
||||
},
|
||||
@@ -31,7 +31,7 @@ const items = [
|
||||
title: "Forecast",
|
||||
url: "#",
|
||||
icon: Truck,
|
||||
role: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
||||
role: ["systemAdmin"],
|
||||
module: "logistics",
|
||||
active: true,
|
||||
},
|
||||
@@ -43,6 +43,14 @@ const items = [
|
||||
module: "logistics",
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
title: "Material Helper",
|
||||
url: "/materialHelper/consumption",
|
||||
icon: Package,
|
||||
role: ["technician", "supervisor", "manager", "admin", "systemAdmin"],
|
||||
module: "logistics",
|
||||
active: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function LogisticsSideBar({user, moduleID}: {user: User | null; moduleID: string}) {
|
||||
|
||||
@@ -7,16 +7,21 @@ import {
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
} from "../../ui/sidebar";
|
||||
import {hasPageAccess} from "@/utils/userAccess";
|
||||
import {User} from "@/types/users";
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "One Click Print",
|
||||
url: "/ocp",
|
||||
icon: Printer,
|
||||
role: ["systemAdmin"],
|
||||
module: "ocp",
|
||||
active: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function ProductionSideBar() {
|
||||
export function ProductionSideBar({user, moduleID}: {user: User | null; moduleID: string}) {
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Production</SidebarGroupLabel>
|
||||
@@ -24,12 +29,16 @@ export function ProductionSideBar() {
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
<>
|
||||
{hasPageAccess(user, item.role, moduleID) && item.active && (
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
)}
|
||||
</>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {CardHeader} from "@/components/ui/card";
|
||||
import {Input} from "@/components/ui/input";
|
||||
import {Label} from "@/components/ui/label";
|
||||
import axios from "axios";
|
||||
import {useState} from "react";
|
||||
|
||||
import {useForm} from "react-hook-form";
|
||||
import {toast} from "sonner";
|
||||
|
||||
export default function ConsumeMaterial() {
|
||||
const {register: register1, handleSubmit: handleSubmit1, reset} = useForm();
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const token = localStorage.getItem("auth_token");
|
||||
|
||||
const handleConsume = async (data: any) => {
|
||||
setSubmitting(!submitting);
|
||||
try {
|
||||
const result = await axios.post(`/api/logistics/consume`, data, {
|
||||
headers: {Authorization: `Bearer ${token}`},
|
||||
});
|
||||
if (result.data.success) {
|
||||
toast.success(result.data.message);
|
||||
setSubmitting(!submitting);
|
||||
reset();
|
||||
}
|
||||
if (!result.data.success) {
|
||||
//console.log(result.data);
|
||||
setSubmitting(!submitting);
|
||||
toast.error(result.data.message);
|
||||
}
|
||||
} catch (error: any) {
|
||||
//console.log(error);
|
||||
setSubmitting(!submitting);
|
||||
if (error.status === 401) {
|
||||
toast.error("Unauthorized to do this task.");
|
||||
} else {
|
||||
toast.error("Unexpected error if this continues please constact an admin.");
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="m-2">
|
||||
<LstCard>
|
||||
<CardHeader>
|
||||
<p className="text-center text-lg">Consuming Material.</p>
|
||||
</CardHeader>
|
||||
<div className="flex m-1">
|
||||
<div className="w-96 m-1">
|
||||
<LstCard>
|
||||
<form onSubmit={handleSubmit1(handleConsume)}>
|
||||
<div className="m-2">
|
||||
<Label htmlFor="runningNr">Enter unit running number</Label>
|
||||
<Input
|
||||
className="mt-2"
|
||||
//defaultValue="634"
|
||||
type="number"
|
||||
{...register1("runningNr")}
|
||||
/>
|
||||
</div>
|
||||
<div className="m-2">
|
||||
<Label htmlFor="lotNum">Enter lot number</Label>
|
||||
<Input
|
||||
className="mt-2"
|
||||
//defaultValue="634"
|
||||
type="number"
|
||||
{...register1("lotNum")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button className="m-2" color="primary" type="submit" disabled={submitting}>
|
||||
Consume materal
|
||||
</Button>
|
||||
</form>
|
||||
</LstCard>
|
||||
</div>
|
||||
<div className="m-1 p-1">
|
||||
<LstCard>
|
||||
<div className="w-96 p-1">
|
||||
<ol>
|
||||
<li>1. Enter the running number of the material you would like to consume</li>
|
||||
<li>2. Enter the lot number you will be consuming to</li>
|
||||
<li>3. Press consume material</li>
|
||||
</ol>
|
||||
<p className="text-pretty w-96">
|
||||
*This process is only for barcoded material, if it is set to auto consume you will
|
||||
encounter and error.
|
||||
</p>
|
||||
</div>
|
||||
</LstCard>
|
||||
</div>
|
||||
</div>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,25 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import ConsumeMaterial from "@/components/logistics/materialHelper/consumption/ConsumeMaterial";
|
||||
import {createFileRoute} from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
'/(logistics)/materialHelper/consumption/',
|
||||
)({
|
||||
component: RouteComponent,
|
||||
})
|
||||
export const Route = createFileRoute("/(logistics)/materialHelper/consumption/")({
|
||||
component: RouteComponent,
|
||||
head: () => ({
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content: "My App is a web application",
|
||||
},
|
||||
{
|
||||
title: "LST - Logistics",
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return <div>Hello "/(logistics)/materialHelper/consumption/"!</div>
|
||||
return (
|
||||
<div>
|
||||
<ConsumeMaterial />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,17 @@ import {createFileRoute} from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/(logistics)/materialHelper/")({
|
||||
component: RouteComponent,
|
||||
head: () => ({
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content: "My App is a web application",
|
||||
},
|
||||
{
|
||||
title: "LST - Logistics",
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
|
||||
@@ -18,7 +18,7 @@ export function hasPageAccess(user: User | null, role: any, module_id: string):
|
||||
// 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)) {
|
||||
if (role.includes(userRole[0]?.role)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
||||
"dev:server": "dotenvx run -f .env -- tsx watch server/index.ts",
|
||||
"dev:frontend": "cd frontend && npm run dev",
|
||||
"dev:dbgen": " drizzle-kit generate --config=drizzle-dev.config.ts",
|
||||
"dev:dbmigrate": " drizzle-kit migrate --config=drizzle-dev.config.ts",
|
||||
"build": "npm run build:server && npm run build:frontend",
|
||||
"build:server": "rimraf dist && tsc --build && xcopy server\\scripts dist\\server\\scripts /E /I /Y",
|
||||
"build:frontend": "cd frontend && npm run build",
|
||||
|
||||
@@ -6,6 +6,7 @@ const requestSchema = z.object({
|
||||
ip: z.string().optional(),
|
||||
endpoint: z.string(),
|
||||
action: z.string().optional(),
|
||||
lastBody: z.string().optional(),
|
||||
stats: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -13,19 +14,25 @@ type ApiHitData = z.infer<typeof requestSchema>;
|
||||
|
||||
export const apiHit = async (
|
||||
c: Context,
|
||||
data: unknown
|
||||
data: ApiHitData
|
||||
): Promise<{success: boolean; data?: ApiHitData; errors?: any[]}> => {
|
||||
// console.log(data);
|
||||
try {
|
||||
// Extract IP from request headers or connection info
|
||||
const forwarded = c.req.header("host");
|
||||
|
||||
//console.log(forwarded);
|
||||
console.log(forwarded);
|
||||
// Validate the data
|
||||
const validatedData = requestSchema.parse(data);
|
||||
const checkData = {
|
||||
ip: forwarded!,
|
||||
endpoint: data?.endpoint,
|
||||
lastBody: data?.lastBody,
|
||||
action: data?.action,
|
||||
stats: data?.stats,
|
||||
};
|
||||
const validatedData = requestSchema.parse(checkData);
|
||||
|
||||
// Proceed with the validated data
|
||||
// console.log("Validated Data:", validatedData);
|
||||
return {success: true, data: validatedData};
|
||||
} catch (error) {
|
||||
// Explicitly check if the error is an instance of ZodError
|
||||
|
||||
50
server/globalUtils/createSSCC.ts
Normal file
50
server/globalUtils/createSSCC.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {eq} from "drizzle-orm";
|
||||
import {db} from "../../database/dbclient.js";
|
||||
import {settings} from "../../database/schema/settings.js";
|
||||
import {query} from "../services/sqlServer/prodSqlServer.js";
|
||||
import {plantInfo} from "../services/sqlServer/querys/dataMart/plantInfo.js";
|
||||
import {createLog} from "../services/logger/logger.js";
|
||||
|
||||
export const createSSCC = async (runningNumber: number) => {
|
||||
// get the token
|
||||
const plantToken = await db.select().from(settings).where(eq(settings.name, "plantToken"));
|
||||
let global; // get from plant address in basis enter the entire string here.
|
||||
|
||||
try {
|
||||
global = await query(plantInfo.replaceAll("[token]", plantToken[0].value), "plantInfo");
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "globalUtils", `There was an error getting the GLN: Error: ${error}`);
|
||||
}
|
||||
|
||||
// create the sscc without the check diget and make sure we have it all correct
|
||||
|
||||
let step1SSCC = global[0].gln.toString().slice(0, 7).padStart(10, "0") + runningNumber.toString().padStart(9, "0");
|
||||
|
||||
let sum = 0;
|
||||
for (let i = 0; i < step1SSCC.length; i++) {
|
||||
let digit = parseInt(step1SSCC[i], 10);
|
||||
if (i % 2 === 0) {
|
||||
// Even index in 0-based index system means odd position in 1-based index system
|
||||
sum += digit * 3;
|
||||
} else {
|
||||
sum += digit;
|
||||
}
|
||||
}
|
||||
let checkDigit = (10 - (sum % 10)) % 10;
|
||||
|
||||
// make sure the check digit is never 10
|
||||
|
||||
// let checkDigit = 10 - ((oddSum * 3 + evenSum) % 10) === 10 ? 0 : (oddSum * 3 + evenSum) % 10;
|
||||
|
||||
// return the true sscc
|
||||
let sscc = step1SSCC + checkDigit;
|
||||
// console.log(step1SSCC);
|
||||
// console.log(checkDigit);
|
||||
return sscc.padStart(20, "0");
|
||||
};
|
||||
|
||||
// let rn = 518475;
|
||||
|
||||
// console.log(`Creating sscc`);
|
||||
// let sscc = await createSSCC(rn);
|
||||
// console.log(sscc);
|
||||
@@ -15,8 +15,19 @@ import tcpServer from "./services/tcpServer/tcpServer.js";
|
||||
import ocme from "./services/ocme/ocmeService.js";
|
||||
import sqlService from "./services/sqlServer/sqlService.js";
|
||||
import logistics from "./services/logistics/logisticsService.js";
|
||||
import {db} from "../database/dbclient.js";
|
||||
import {settings} from "../database/schema/settings.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
const allowedOrigins = ["http://localhost:3000", "http://localhost:4000", "http://localhost:5173"];
|
||||
// plant token
|
||||
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
|
||||
const serverPort = await db.select().from(settings).where(eq(settings.name, "serverPort"));
|
||||
const allowedOrigins = [
|
||||
"http://localhost:3000",
|
||||
"http://localhost:4000",
|
||||
"http://localhost:5173",
|
||||
`http://usmcd1vms006:4000`,
|
||||
];
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
// middle ware
|
||||
@@ -110,9 +121,10 @@ serve(
|
||||
{
|
||||
fetch: app.fetch,
|
||||
port: Number(process.env.VITE_SERVER_PORT),
|
||||
hostname: "0.0.0.0",
|
||||
},
|
||||
(info) => {
|
||||
createLog("info", "LST", "server", `Server is running on http://localhost:${info.port}`);
|
||||
createLog("info", "LST", "server", `Server is running on http://${info.address}:${info.port}`);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ app.route("auth/session", session);
|
||||
|
||||
// required to login
|
||||
/* User area just needs to be logged in to enter here */
|
||||
app.route("auth/profileUpdate", profile);
|
||||
app.route("auth/profileupdate", profile);
|
||||
|
||||
/* will need to increase to make sure the person coming here has the correct permissions */
|
||||
app.route("auth/getuseraccess", getAccess);
|
||||
|
||||
@@ -1 +1,46 @@
|
||||
export const registerUser = async () => {};
|
||||
import {eq} from "drizzle-orm";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {users} from "../../../../database/schema/users.js";
|
||||
import {createPassword} from "../utils/createPassword.js";
|
||||
import {setSysAdmin} from "./userRoles/setSysAdmin.js";
|
||||
|
||||
export const registerUser = async (username: string, password: string, email: string) => {
|
||||
const usercount = await db.select().from(users);
|
||||
|
||||
// make sure the user dose not already exist in the system
|
||||
const userCheck = await db.select().from(users).where(eq(users.username, username));
|
||||
|
||||
if (userCheck.length === 1) {
|
||||
return {
|
||||
success: false,
|
||||
message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
|
||||
};
|
||||
}
|
||||
|
||||
// make sure we only send over a username that is all lowercase
|
||||
username = username.toLowerCase();
|
||||
|
||||
// get the good kinda password
|
||||
password = await createPassword(password);
|
||||
|
||||
try {
|
||||
const user = await db
|
||||
.insert(users)
|
||||
.values({username, email, password})
|
||||
.returning({user: users.username, email: users.email});
|
||||
|
||||
if (usercount.length <= 1) {
|
||||
console.log(`${username} is the first user and will be set to system admin.`);
|
||||
const updateUser = await db.select().from(users).where(eq(users.username, username));
|
||||
setSysAdmin(updateUser, "systemAdmin");
|
||||
}
|
||||
|
||||
return {sucess: true, message: "User Registered", user};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {
|
||||
success: false,
|
||||
message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {users} from "../../../../database/schema/users.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {createPassword} from "../utils/createPassword.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
import {registerUser} from "../controllers/register.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
@@ -24,6 +21,7 @@ const UserSchema = z.object({
|
||||
type User = z.infer<typeof UserSchema>;
|
||||
|
||||
const responseSchema = z.object({
|
||||
success: z.boolean().optional().openapi({example: true}),
|
||||
message: z.string().optional().openapi({example: "User Created"}),
|
||||
});
|
||||
|
||||
@@ -79,32 +77,10 @@ app.openapi(
|
||||
);
|
||||
}
|
||||
|
||||
// make sure the user dose not already exist in the system
|
||||
const userCheck = await db.select().from(users).where(eq(users.username, username));
|
||||
|
||||
if (userCheck.length === 1) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
// make sure we only send over a username that is all lowercase
|
||||
username = username.toLowerCase();
|
||||
|
||||
// get the good kinda password
|
||||
password = await createPassword(password);
|
||||
|
||||
try {
|
||||
const user = await db
|
||||
.insert(users)
|
||||
.values({username, email, password})
|
||||
.returning({user: users.username, email: users.email});
|
||||
const register = await registerUser(username, password, email);
|
||||
|
||||
return c.json({message: "User Registered", user}, 200);
|
||||
return c.json({success: register.success, message: register.message, user: register?.user}, 200);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return c.json(
|
||||
|
||||
@@ -13,6 +13,7 @@ const newRoles = [
|
||||
{name: "supervisor"},
|
||||
{name: "manager"},
|
||||
{name: "admin"},
|
||||
{name: "tester"},
|
||||
{name: "systemAdmin"},
|
||||
];
|
||||
export const areRolesIn = async () => {
|
||||
|
||||
@@ -17,8 +17,8 @@ export default async function (log: Log) {
|
||||
// Insert log entry into the PostgreSQL database using Drizzle ORM
|
||||
await db.insert(logs).values({
|
||||
level: obj.level,
|
||||
username: obj?.username,
|
||||
service: obj?.service,
|
||||
username: obj?.username.toLowerCase(),
|
||||
service: obj?.service.toLowerCase(),
|
||||
message: obj.msg,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ export const consumeMaterial = async (data: Data, prod: any) => {
|
||||
if (barcode.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "The running number provided is not in stock please check if stock and try again.",
|
||||
message: "The running number you've is not in stock.",
|
||||
};
|
||||
//throw Error("The provided runningNr is not in stock");
|
||||
}
|
||||
@@ -49,6 +49,6 @@ export const consumeMaterial = async (data: Data, prod: any) => {
|
||||
//console.log(results);
|
||||
return {success: true, message: "Material was consumed", status: results.status};
|
||||
} catch (error: any) {
|
||||
return {success: false, status: error.response?.status, message: error.response?.data.errors[0].message};
|
||||
return {success: false, status: 200, message: error.response?.data.errors[0].message};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,11 +2,12 @@ import {db} from "../../../../database/dbclient.js";
|
||||
import {ocmeData} from "../../../../database/schema/ocme.js";
|
||||
import {differenceInMinutes} from "date-fns";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
export const getInfo = async () => {
|
||||
let ocmeInfo: any = [];
|
||||
try {
|
||||
ocmeInfo = await db.select().from(ocmeData);
|
||||
ocmeInfo = await db.select().from(ocmeData).where(eq(ocmeData.pickedUp, false));
|
||||
|
||||
// add in the time difference
|
||||
ocmeInfo = ocmeInfo.map((o: any) => {
|
||||
@@ -14,6 +15,7 @@ export const getInfo = async () => {
|
||||
const diff = differenceInMinutes(now, o.add_Date!);
|
||||
return {...o, waitingFor: diff};
|
||||
});
|
||||
createLog("info", "ocme", "ocme", `There are ${ocmeInfo.length} pallet(s) to be picked up.`);
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", "There was an error trying to retrive the ocmeInfo.");
|
||||
throw Error("There was an error trying to retrive the.");
|
||||
|
||||
42
server/services/ocme/controller/pickedup.ts
Normal file
42
server/services/ocme/controller/pickedup.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import {eq, sql} from "drizzle-orm";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {ocmeData} from "../../../../database/schema/ocme.js";
|
||||
import {createLog, logLevel} from "../../logger/logger.js";
|
||||
|
||||
export const pickedup = async (data: any) => {
|
||||
if (data.sscc && !data.runningNr) {
|
||||
data.runningNr = data.sscc.slice(10, -1);
|
||||
}
|
||||
|
||||
if (!data.sscc && !data.runningNr) {
|
||||
// data.runningNr = data.sscc.slice(10, -1);
|
||||
return {success: false, message: "Missing data please try again", data: []};
|
||||
}
|
||||
|
||||
if (data.all) {
|
||||
try {
|
||||
const updateRn = await db
|
||||
.update(ocmeData)
|
||||
.set({pickedUp: true, upd_date: sql`NOW()`})
|
||||
.returning({runningNr: ocmeData.runningNr});
|
||||
createLog("info", "ocme", "ocme", `Pending pallets were just cleared out.`);
|
||||
return {success: true, message: `Pending pallets were just cleared out.`, data: updateRn};
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", `Error clearing out the pallets.`);
|
||||
return {success: false, message: `Error clearing out the pallets.`, error};
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const updateRn = await db
|
||||
.update(ocmeData)
|
||||
.set({pickedUp: true, upd_date: sql`NOW()`})
|
||||
.where(eq(ocmeData.runningNr, data.runningNr))
|
||||
.returning({runningNr: ocmeData.runningNr});
|
||||
createLog("info", "ocme", "ocme", `${parseInt(data.runningNr)} was just pickedup`);
|
||||
return {success: true, message: `${parseInt(data.runningNr)} was just pickedup`, data: updateRn};
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", `${parseInt(data.runningNr)} was just pickedup`);
|
||||
return {success: false, message: `${parseInt(data.runningNr)} was not pickedup`, error};
|
||||
}
|
||||
};
|
||||
@@ -1,13 +1,43 @@
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {ocmeData} from "../../../../database/schema/ocme.js";
|
||||
import {createSSCC} from "../../../globalUtils/createSSCC.js";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import {query} from "../../sqlServer/prodSqlServer.js";
|
||||
import {labelData} from "../../sqlServer/querys/materialHelpers/labelInfo.js";
|
||||
|
||||
export const postLabelData = async (data: any) => {
|
||||
// if we have sscc we will do everything here and ignore the rn even it its sent over
|
||||
|
||||
if (data.sscc) {
|
||||
return {success: true, message: "sscc sent over", data: data};
|
||||
if (data.sscc && !data.runningNr) {
|
||||
data.runningNr = data.sscc.slice(10, -1);
|
||||
}
|
||||
|
||||
if (data.runningNr) {
|
||||
return {success: true, message: "runningNr sent over", data: data};
|
||||
} else {
|
||||
throw Error("Improper data was sent over");
|
||||
if (!data.sscc && !data.runningNr) {
|
||||
// data.runningNr = data.sscc.slice(10, -1);
|
||||
return {success: false, message: "Missing data please try again", data: []};
|
||||
}
|
||||
|
||||
let label;
|
||||
const filterQuery = labelData.replaceAll("[rn]", data.runningNr);
|
||||
|
||||
try {
|
||||
label = await query(filterQuery, "Label data");
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", "There was an error getting the labelData");
|
||||
}
|
||||
const newPost = {
|
||||
sscc: data.sscc ? data.sscc : await createSSCC(data.runningNr),
|
||||
runningNr: data.runningNr,
|
||||
completed: data.completed,
|
||||
lineNum: label[0].machineLocation,
|
||||
areaFrom: data.areaFrom,
|
||||
pickedUp: false,
|
||||
};
|
||||
|
||||
try {
|
||||
const enterNewData = await db.insert(ocmeData).values(newPost).returning({sscc: ocmeData.sscc});
|
||||
return {success: true, message: "Data was posted to ocme info", data: enterNewData};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {success: false, message: "Data was posted to ocme info", data: newPost};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,9 +3,13 @@ import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
// routes
|
||||
import getInfo from "./route/getInfo.js";
|
||||
import postRunningNr from "./route/postRunningNumber.js";
|
||||
import pickedup from "./route/pickedUp.js";
|
||||
import postsscc from "./route/postSSCC.js";
|
||||
import getShipments from "./route/getShipmentPallets.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const routes = [getInfo, postRunningNr] as const;
|
||||
const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments] as const;
|
||||
|
||||
// app.route("/server", modules);
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
@@ -69,6 +70,7 @@ app.openapi(
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
apiHit(c, {endpoint: "api/auth/register"});
|
||||
try {
|
||||
return c.json({success: true, message: "Ocme Info", data: await getInfo()}, 200);
|
||||
} catch (error) {
|
||||
|
||||
83
server/services/ocme/route/getShipmentPallets.ts
Normal file
83
server/services/ocme/route/getShipmentPallets.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const ShipmentID = z.object({
|
||||
shipmentID: z.string().optional().openapi({example: "14558"}),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/getshipmentpallets",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: ShipmentID},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/getshipmentpallets", lastBody: data});
|
||||
|
||||
const postPallet = {success: true, message: "Something", data: []};
|
||||
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting the shipment data.", data: error}, 400);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
89
server/services/ocme/route/pickedUp.ts
Normal file
89
server/services/ocme/route/pickedUp.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {pickedup} from "../controller/pickedup.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const PostRunningNr = z.object({
|
||||
sscc: z.string().optional().openapi({example: "00090103830005710997"}),
|
||||
runningNr: z.string().optional().openapi({example: "localhost"}),
|
||||
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}),
|
||||
completed: z.boolean().optional().openapi({example: true}),
|
||||
all: z.boolean().optional().openapi({example: false}),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Picks up a pallet in the system.",
|
||||
method: "patch",
|
||||
description:
|
||||
"removes the pallet(s) from showing as needed to be picked up, we clear everything related to the pallet number to reduce the risk of a mix, passing `all` will just clear everything that is pending.",
|
||||
path: "/pickedup",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: PostRunningNr},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
500: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/pickedup", lastBody: data});
|
||||
const postPallet = await pickedup(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -1,6 +1,7 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
@@ -31,7 +32,10 @@ app.openapi(
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
@@ -71,8 +75,9 @@ app.openapi(
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/postRunningNumber", lastBody: data});
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data}, 200);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
|
||||
86
server/services/ocme/route/postSSCC.ts
Normal file
86
server/services/ocme/route/postSSCC.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const PostRunningNr = z.object({
|
||||
sscc: z.string().optional().openapi({example: "00090103830005710997"}),
|
||||
runningNr: z.string().optional().openapi({example: "localhost"}),
|
||||
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}),
|
||||
completed: z.boolean().optional().openapi({example: true}),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/postsscc",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: PostRunningNr},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/postRunningNumber", lastBody: data});
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -8,13 +8,13 @@ import {modules} from "../../../../database/schema/modules.js";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
||||
const newModules = [
|
||||
{name: "production", active: false, roles: ["viewer", "systemAdmin"]},
|
||||
{name: "logistics", active: false, roles: ["viewer", "systemAdmin"]},
|
||||
{name: "quality", active: false, roles: ["viewer", "manager", "systemAdmin"]},
|
||||
{name: "forklift", active: false, roles: ["manager", "admin", "systemAdmin"]},
|
||||
{name: "eom", active: false, roles: ["manager", "admin", "systemAdmin"]},
|
||||
{name: "admin", active: false, roles: ["admin", "systemAdmin"]},
|
||||
{name: "ocp", active: false, roles: ["viewer", "admin", "systemAdmin"]},
|
||||
{name: "production", active: true, roles: ["viewer", "tester", "systemAdmin"]},
|
||||
{name: "logistics", active: false, roles: ["viewer", "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 () => {
|
||||
// get the roles
|
||||
|
||||
@@ -56,6 +56,12 @@ const newSettings = [
|
||||
description: "Dose the plant have 2 machines that go to 1?",
|
||||
moduleName: "ocp",
|
||||
},
|
||||
{
|
||||
name: "fifoCheck",
|
||||
value: "45",
|
||||
description: "How far back do we want to check for fifo default 45, putting 0 will ignore.",
|
||||
moduleName: "ocme",
|
||||
},
|
||||
];
|
||||
export const areSettingsIn = async () => {
|
||||
// get the roles
|
||||
@@ -69,12 +75,12 @@ export const areSettingsIn = async () => {
|
||||
.values(newSettings)
|
||||
.onConflictDoNothing() // this will only update the ones that are new :D
|
||||
.returning({name: settings.name});
|
||||
createLog("info", "lst", "server", "Roles were just added due to missing them on server startup");
|
||||
createLog("info", "lst", "server", "Settingss were just added due to missing them on server startup");
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "server", "There was an error adding new roles to the db");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "server", "There was an error getting or adding new roles");
|
||||
createLog("error", "lst", "server", "There was an error getting or adding new Settingss");
|
||||
}
|
||||
};
|
||||
|
||||
12
server/services/sqlServer/querys/dataMart/plantInfo.ts
Normal file
12
server/services/sqlServer/querys/dataMart/plantInfo.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export const plantInfo = `
|
||||
select werkkurzbez as plantToken,
|
||||
gln,
|
||||
IdAdressen as addressId,
|
||||
Bezeichnung as addressDecriptuion,
|
||||
Strasse as streetAddress,
|
||||
plz as zipcode,
|
||||
ort as cityState
|
||||
--,*
|
||||
from alplaprod_test1.dbo.T_Adressen where werkkurzbez = '[token]'
|
||||
|
||||
`;
|
||||
@@ -1,3 +1,20 @@
|
||||
export const labelData = `
|
||||
select Barcode as barcode from alplaprod_test1.dbo.V_LagerPositionenBarcodes (NOLOCK) where lfdnr = [rn]
|
||||
select x.Barcode as barcode,
|
||||
Produktionslos as lot,
|
||||
x.IdArtikelVarianten as article,
|
||||
x.ArtikelVariantenBez as description,
|
||||
m.Standort as machineLocation,
|
||||
m.Bezeichnung as machineDescription,
|
||||
e.IdEtikettenDrucker as printer,
|
||||
x.LfdNr as runningNr
|
||||
from alplaprod_test1.dbo.V_LagerPositionenBarcodes x (NOLOCK)
|
||||
left join
|
||||
alplaprod_test1.dbo.T_EtikettenGedruckt as e
|
||||
on x.Lfdnr = e.LfdNr
|
||||
|
||||
left join
|
||||
alplaprod_test1.dbo.T_Maschine as m on
|
||||
e.IdMaschine = m.IdMaschine
|
||||
|
||||
where x.lfdnr = [rn] and x.IdWarenlager not in(6)
|
||||
`;
|
||||
|
||||
16
server/services/sqlServer/querys/ocme/shipmentPallets.ts
Normal file
16
server/services/sqlServer/querys/ocme/shipmentPallets.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export const shipmentPallets = `
|
||||
select TOP([totalPallets]) IdLagerAbteilung as laneId,
|
||||
LagerAbteilungKurzBez as lane,
|
||||
Produktionslos as lotNum,
|
||||
lfdnr as runningNumber,
|
||||
IdAdresse as addressID,
|
||||
BewegungsDatumMax as lastMove, IdArtikelVarianten as article
|
||||
from AlplaPROD_test1.dbo.V_LagerPositionenBarcodes (nolock)
|
||||
where IdArtikelVarianten = [article]
|
||||
and LagerAbteilungKurzBez in ([lanes])
|
||||
and GesperrtAktivSum in (0)
|
||||
order by CASE
|
||||
WHEN BewegungsDatumMax <= DATEADD(DAY, -[fifo], GETDATE()) THEN 0
|
||||
ELSE 1
|
||||
END desc
|
||||
`;
|
||||
Reference in New Issue
Block a user