Compare commits

...

12 Commits

27 changed files with 2914 additions and 42 deletions

View File

@@ -0,0 +1 @@
ALTER TABLE "printerData" ADD COLUMN "processes" jsonb DEFAULT '[]'::jsonb;

File diff suppressed because it is too large Load Diff

View File

@@ -470,6 +470,13 @@
"when": 1749671243377, "when": 1749671243377,
"tag": "0066_nosy_dark_beast", "tag": "0066_nosy_dark_beast",
"breakpoints": true "breakpoints": true
},
{
"idx": 67,
"version": "7",
"when": 1749744049457,
"tag": "0067_shallow_trish_tilby",
"breakpoints": true
} }
] ]
} }

View File

@@ -7,6 +7,7 @@ import {
boolean, boolean,
uuid, uuid,
uniqueIndex, uniqueIndex,
jsonb,
} from "drizzle-orm/pg-core"; } from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod"; import { z } from "zod";
@@ -26,6 +27,7 @@ export const printerData = pgTable(
remark: text("remark"), remark: text("remark"),
printDelay: numeric("printDelay").default("90"), printDelay: numeric("printDelay").default("90"),
monitorState: boolean("monitorState").default(false), monitorState: boolean("monitorState").default(false),
processes: jsonb("processes").default([]),
add_Date: timestamp("add_Date").defaultNow(), add_Date: timestamp("add_Date").defaultNow(),
upd_date: timestamp("upd_date").defaultNow(), upd_date: timestamp("upd_date").defaultNow(),
}, },

View File

@@ -0,0 +1,214 @@
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 {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useSessionStore } from "@/lib/store/sessionStore";
import { getProdPerms } from "@/utils/querys/prodUser/getProdPerms";
import { useForm } from "@tanstack/react-form";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import { toast } from "sonner";
export default function ProdUserCard() {
const { token } = useSessionStore();
const { data, isError, isLoading } = useQuery(getProdPerms(token ?? ""));
const form = useForm({
defaultValues: {
username: "",
remark: "",
pcname: "",
role: "",
},
onSubmit: async ({ value }) => {
console.log(value);
if (value.role === "") {
toast.error(
"Role is missing please select a role and try again."
);
}
try {
const res = await axios.post("/api/produser/produser", value, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res.data);
if (!res.data.success) {
toast.error(res.data.data?.errors[0].message);
}
if (res.data.success) {
toast.success(res.data.message);
form.reset();
}
} catch (error) {
console.log(error);
}
},
});
if (isError)
return (
<>
<p>There was an error loading the prod Perms</p>
</>
);
if (isLoading)
return (
<>
<p>Loading.....</p>
</>
);
return (
<div className="m-4">
<LstCard>
<CardHeader>
<p>Alpla Prod user create/update</p>
</CardHeader>
<div className="m-2">
<p>
Please enter the windows username. <br /> To check the
user head here{" "}
<a
target="_blank"
href="https://alplaservicedesk.service-now.com/sp?id=sc_cat_item&sys_id=0c266831c32f41107cba16c4e40131c0&sysparm_category=564428bdc3eb41107cba16c4e40131f2"
>
<u>Active Directory</u>
</a>
</p>
</div>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
{/* Windows username */}
<form.Field
name="username"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 3
? undefined
: "Username must be longer than 3 letters",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor="username">Username</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
{/* Remark for the user */}
<form.Field
name="remark"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 3
? undefined
: "The remark should be longer than 3 letters",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor="remark">Remark</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
{/* Select the type of role we will be granting/updating */}
<form.Field
name="role"
//listeners={{onChange: ({value})=>{}}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor={field.name}>
Select role
</Label>
<Select
value={field.state.value}
onValueChange={field.handleChange}
>
<SelectTrigger className="w-[180px]">
<SelectValue
id={field.name}
placeholder="Select Role"
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Roles</SelectLabel>
{data.map((i: any) => {
return (
<SelectItem
key={i.prodPerm_id}
value={i.name}
>
{i.name}
</SelectItem>
);
})}
</SelectGroup>
</SelectContent>
</Select>
</div>
);
}}
/>
<div className="flex justify-end mr-3">
<Button onClick={form.handleSubmit}>Submit</Button>
</div>
</form>
</LstCard>
</div>
);
}

View File

@@ -0,0 +1,133 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useForm } from "@tanstack/react-form";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export default function Relocate() {
const [bookingIn, setBookingIn] = useState(false);
const form = useForm({
defaultValues: { runningNr: " ", lane: "" },
onSubmit: async ({ value }) => {
// Do something with form data
setBookingIn(true);
try {
const res = await axios.post("/api/ocp/bookin", {
runningNr: parseInt(value.runningNr),
});
if (res.data.success) {
toast.success(res.data.message);
form.reset();
setBookingIn(false);
} else {
console.log(res.data.data.errors);
toast.error(res.data.data.errors[0]?.message);
form.reset();
setBookingIn(false);
}
} catch (error) {
console.log(error);
toast.error(
"There was an error booking in pallet please validate you entered the correct info and try again."
);
setBookingIn(false);
}
},
});
return (
<LstCard>
<CardHeader>
<p>Relocate a pallet to another lane</p>
</CardHeader>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<CardContent>
<form.Field
name="runningNr"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 2
? undefined
: "Please enter a valid running number",
}}
children={(field) => {
return (
<div className="">
<Label htmlFor="runningNr" className="mb-2">
Runnning Number
</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
<form.Field
name="lane"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 2
? undefined
: "Please enter a valid running number",
}}
children={(field) => {
return (
<div className="">
<Label htmlFor="runningNr" className="mb-2">
Enter lane
</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
<div className="flex mt-2 justify-end">
<Button
onClick={form.handleSubmit}
disabled={bookingIn}
>
Relocate
</Button>
</div>
</CardContent>
</form>
</LstCard>
);
}

View File

@@ -1,7 +1,9 @@
import Bookin from "./commands/Bookin"; import Bookin from "./commands/Bookin";
import Relocate from "./commands/Relocate";
import RemoveAsNonReusable from "./commands/RemoveAsNonReusable"; import RemoveAsNonReusable from "./commands/RemoveAsNonReusable";
export default function HelperPage() { export default function HelperPage() {
const url: string = window.location.host.split(":")[0];
return ( return (
<div className="flex flex-wrap m-2 justify-center"> <div className="flex flex-wrap m-2 justify-center">
<div className="m-1"> <div className="m-1">
@@ -11,6 +13,7 @@ export default function HelperPage() {
<div className="m-1"> <div className="m-1">
<RemoveAsNonReusable /> <RemoveAsNonReusable />
</div> </div>
<div className="m-1">{url === "localhost" && <Relocate />}</div>
</div> </div>
); );
} }

View File

@@ -0,0 +1,149 @@
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 { useSessionStore } from "@/lib/store/sessionStore";
import axios from "axios";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
export default function PreformReturn() {
const {
register: register1,
handleSubmit: handleSubmit1,
reset,
} = useForm();
const [submitting, setSubmitting] = useState(false);
const { token } = useSessionStore();
const handleConsume = async (data: any) => {
setSubmitting(true);
try {
const result = await axios.post(`/api/logistics/consume`, data, {
headers: { Authorization: `Bearer ${token}` },
});
if (result.data.success) {
toast.success(result.data.message);
setSubmitting(false);
reset();
}
if (!result.data.success) {
//console.log(result.data);
setSubmitting(false);
toast.error(result.data.message);
}
} catch (error: any) {
//console.log(error);
setSubmitting(false);
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">Preform Return.</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 the new wight of the gaylord of
preforms
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Select the printer you would like to
print to
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Select the staging location to be
returned to.
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<Button
className="m-2"
color="primary"
type="submit"
disabled={submitting}
>
Preform return
</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
preform cage you would like to return
</li>
<li>
2. Enter the new weight of the gaylord
</li>
<li>
3. Select the printer you would like to
print to
</li>
</ol>
<p className="text-pretty w-96">
*As soon as you press preform return it will
print a new label and return to the staging
location.
</p>
</div>
</LstCard>
</div>
</div>
</LstCard>
</div>
);
}

View File

@@ -26,6 +26,7 @@ import { Route as AdminUsersImport } from './routes/_admin/users'
import { Route as AdminSubModulesImport } from './routes/_admin/subModules' import { Route as AdminSubModulesImport } from './routes/_admin/subModules'
import { Route as AdminSettingsImport } from './routes/_admin/settings' import { Route as AdminSettingsImport } from './routes/_admin/settings'
import { Route as AdminServersImport } from './routes/_admin/servers' import { Route as AdminServersImport } from './routes/_admin/servers'
import { Route as AdminProdUsersImport } from './routes/_admin/prodUsers'
import { Route as AdminNotificationMGTImport } from './routes/_admin/notificationMGT' import { Route as AdminNotificationMGTImport } from './routes/_admin/notificationMGT'
import { Route as AdminModulesImport } from './routes/_admin/modules' import { Route as AdminModulesImport } from './routes/_admin/modules'
import { Route as userPasswordChangeImport } from './routes/(user)/passwordChange' import { Route as userPasswordChangeImport } from './routes/(user)/passwordChange'
@@ -131,6 +132,12 @@ const AdminServersRoute = AdminServersImport.update({
getParentRoute: () => AdminRoute, getParentRoute: () => AdminRoute,
} as any) } as any)
const AdminProdUsersRoute = AdminProdUsersImport.update({
id: '/prodUsers',
path: '/prodUsers',
getParentRoute: () => AdminRoute,
} as any)
const AdminNotificationMGTRoute = AdminNotificationMGTImport.update({ const AdminNotificationMGTRoute = AdminNotificationMGTImport.update({
id: '/notificationMGT', id: '/notificationMGT',
path: '/notificationMGT', path: '/notificationMGT',
@@ -309,6 +316,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AdminNotificationMGTImport preLoaderRoute: typeof AdminNotificationMGTImport
parentRoute: typeof AdminImport parentRoute: typeof AdminImport
} }
'/_admin/prodUsers': {
id: '/_admin/prodUsers'
path: '/prodUsers'
fullPath: '/prodUsers'
preLoaderRoute: typeof AdminProdUsersImport
parentRoute: typeof AdminImport
}
'/_admin/servers': { '/_admin/servers': {
id: '/_admin/servers' id: '/_admin/servers'
path: '/servers' path: '/servers'
@@ -450,6 +464,7 @@ declare module '@tanstack/react-router' {
interface AdminRouteChildren { interface AdminRouteChildren {
AdminModulesRoute: typeof AdminModulesRoute AdminModulesRoute: typeof AdminModulesRoute
AdminNotificationMGTRoute: typeof AdminNotificationMGTRoute AdminNotificationMGTRoute: typeof AdminNotificationMGTRoute
AdminProdUsersRoute: typeof AdminProdUsersRoute
AdminServersRoute: typeof AdminServersRoute AdminServersRoute: typeof AdminServersRoute
AdminSettingsRoute: typeof AdminSettingsRoute AdminSettingsRoute: typeof AdminSettingsRoute
AdminSubModulesRoute: typeof AdminSubModulesRoute AdminSubModulesRoute: typeof AdminSubModulesRoute
@@ -459,6 +474,7 @@ interface AdminRouteChildren {
const AdminRouteChildren: AdminRouteChildren = { const AdminRouteChildren: AdminRouteChildren = {
AdminModulesRoute: AdminModulesRoute, AdminModulesRoute: AdminModulesRoute,
AdminNotificationMGTRoute: AdminNotificationMGTRoute, AdminNotificationMGTRoute: AdminNotificationMGTRoute,
AdminProdUsersRoute: AdminProdUsersRoute,
AdminServersRoute: AdminServersRoute, AdminServersRoute: AdminServersRoute,
AdminSettingsRoute: AdminSettingsRoute, AdminSettingsRoute: AdminSettingsRoute,
AdminSubModulesRoute: AdminSubModulesRoute, AdminSubModulesRoute: AdminSubModulesRoute,
@@ -499,6 +515,7 @@ export interface FileRoutesByFullPath {
'/passwordChange': typeof userPasswordChangeRoute '/passwordChange': typeof userPasswordChangeRoute
'/modules': typeof AdminModulesRoute '/modules': typeof AdminModulesRoute
'/notificationMGT': typeof AdminNotificationMGTRoute '/notificationMGT': typeof AdminNotificationMGTRoute
'/prodUsers': typeof AdminProdUsersRoute
'/servers': typeof AdminServersRoute '/servers': typeof AdminServersRoute
'/settings': typeof AdminSettingsRoute '/settings': typeof AdminSettingsRoute
'/subModules': typeof AdminSubModulesRoute '/subModules': typeof AdminSubModulesRoute
@@ -530,6 +547,7 @@ export interface FileRoutesByTo {
'/passwordChange': typeof userPasswordChangeRoute '/passwordChange': typeof userPasswordChangeRoute
'/modules': typeof AdminModulesRoute '/modules': typeof AdminModulesRoute
'/notificationMGT': typeof AdminNotificationMGTRoute '/notificationMGT': typeof AdminNotificationMGTRoute
'/prodUsers': typeof AdminProdUsersRoute
'/servers': typeof AdminServersRoute '/servers': typeof AdminServersRoute
'/settings': typeof AdminSettingsRoute '/settings': typeof AdminSettingsRoute
'/subModules': typeof AdminSubModulesRoute '/subModules': typeof AdminSubModulesRoute
@@ -564,6 +582,7 @@ export interface FileRoutesById {
'/(user)/passwordChange': typeof userPasswordChangeRoute '/(user)/passwordChange': typeof userPasswordChangeRoute
'/_admin/modules': typeof AdminModulesRoute '/_admin/modules': typeof AdminModulesRoute
'/_admin/notificationMGT': typeof AdminNotificationMGTRoute '/_admin/notificationMGT': typeof AdminNotificationMGTRoute
'/_admin/prodUsers': typeof AdminProdUsersRoute
'/_admin/servers': typeof AdminServersRoute '/_admin/servers': typeof AdminServersRoute
'/_admin/settings': typeof AdminSettingsRoute '/_admin/settings': typeof AdminSettingsRoute
'/_admin/subModules': typeof AdminSubModulesRoute '/_admin/subModules': typeof AdminSubModulesRoute
@@ -597,6 +616,7 @@ export interface FileRouteTypes {
| '/passwordChange' | '/passwordChange'
| '/modules' | '/modules'
| '/notificationMGT' | '/notificationMGT'
| '/prodUsers'
| '/servers' | '/servers'
| '/settings' | '/settings'
| '/subModules' | '/subModules'
@@ -627,6 +647,7 @@ export interface FileRouteTypes {
| '/passwordChange' | '/passwordChange'
| '/modules' | '/modules'
| '/notificationMGT' | '/notificationMGT'
| '/prodUsers'
| '/servers' | '/servers'
| '/settings' | '/settings'
| '/subModules' | '/subModules'
@@ -659,6 +680,7 @@ export interface FileRouteTypes {
| '/(user)/passwordChange' | '/(user)/passwordChange'
| '/_admin/modules' | '/_admin/modules'
| '/_admin/notificationMGT' | '/_admin/notificationMGT'
| '/_admin/prodUsers'
| '/_admin/servers' | '/_admin/servers'
| '/_admin/settings' | '/_admin/settings'
| '/_admin/subModules' | '/_admin/subModules'
@@ -773,6 +795,7 @@ export const routeTree = rootRoute
"children": [ "children": [
"/_admin/modules", "/_admin/modules",
"/_admin/notificationMGT", "/_admin/notificationMGT",
"/_admin/prodUsers",
"/_admin/servers", "/_admin/servers",
"/_admin/settings", "/_admin/settings",
"/_admin/subModules", "/_admin/subModules",
@@ -815,6 +838,10 @@ export const routeTree = rootRoute
"filePath": "_admin/notificationMGT.tsx", "filePath": "_admin/notificationMGT.tsx",
"parent": "/_admin" "parent": "/_admin"
}, },
"/_admin/prodUsers": {
"filePath": "_admin/prodUsers.tsx",
"parent": "/_admin"
},
"/_admin/servers": { "/_admin/servers": {
"filePath": "_admin/servers.tsx", "filePath": "_admin/servers.tsx",
"parent": "/_admin" "parent": "/_admin"

View File

@@ -1,7 +1,10 @@
import ConsumeMaterial from "@/components/logistics/materialHelper/consumption/ConsumeMaterial"; import ConsumeMaterial from "@/components/logistics/materialHelper/consumption/ConsumeMaterial";
import {createFileRoute} from "@tanstack/react-router"; import PreformReturn from "@/components/logistics/materialHelper/consumption/PreformReturn";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/materialHelper/consumption/")({ export const Route = createFileRoute(
"/(logistics)/materialHelper/consumption/"
)({
component: RouteComponent, component: RouteComponent,
head: () => ({ head: () => ({
meta: [ meta: [
@@ -17,9 +20,11 @@ export const Route = createFileRoute("/(logistics)/materialHelper/consumption/")
}); });
function RouteComponent() { function RouteComponent() {
const url: string = window.location.host.split(":")[0];
return ( return (
<div> <div>
<ConsumeMaterial /> <ConsumeMaterial />
{url === "localhost" && <PreformReturn />}
</div> </div>
); );
} }

View File

@@ -1,5 +1,5 @@
import MaterialHelperPage from "@/components/logistics/materialHelper/materialHelperPage"; import MaterialHelperPage from "@/components/logistics/materialHelper/materialHelperPage";
import {createFileRoute} from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/materialHelper/")({ export const Route = createFileRoute("/(logistics)/materialHelper/")({
component: RouteComponent, component: RouteComponent,

View File

@@ -0,0 +1,14 @@
import ProdUserCard from "@/components/admin/prodUser/ProdUserCard";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/_admin/prodUsers")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<ProdUserCard />
</div>
);
}

View File

@@ -0,0 +1,25 @@
import { queryOptions } from "@tanstack/react-query";
import axios from "axios";
export function getProdPerms(token: string) {
return queryOptions({
queryKey: ["prodPerms"],
queryFn: () => fetch(token),
enabled: !!token,
staleTime: 1000,
refetchOnWindowFocus: true,
});
}
const fetch = async (token: string) => {
const { data } = await axios.get("/api/produser/prodrole", {
headers: { Authorization: `Bearer ${token}` },
});
// if we are not localhost ignore the devDir setting.
// const url: string = window.location.host.split(":")[0];
// let settingsData = data.data;
// if (url != "localhost") {
// settingsData.filter((n: any) => n.name === "devDir");
// }
return data.data;
};

View File

@@ -1,23 +1,25 @@
import {queryOptions} from "@tanstack/react-query"; import { queryOptions } from "@tanstack/react-query";
import axios from "axios"; import axios from "axios";
export function getSettings(token: string) { export function getSettings(token: string) {
return queryOptions({ return queryOptions({
queryKey: ["settings"], queryKey: ["settings"],
queryFn: () => fetchSettings(token), queryFn: () => fetch(token),
enabled: !!token, enabled: !!token,
staleTime: 1000, staleTime: 1000,
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
}); });
} }
const fetchSettings = async (token: string) => { const fetch = async (token: string) => {
const {data} = await axios.get("/api/server/settings", {headers: {Authorization: `Bearer ${token}`}}); const { data } = await axios.get("/api/server/settings", {
headers: { Authorization: `Bearer ${token}` },
});
// if we are not localhost ignore the devDir setting. // if we are not localhost ignore the devDir setting.
const url: string = window.location.host.split(":")[0]; // const url: string = window.location.host.split(":")[0];
let settingsData = data.data; // let settingsData = data.data;
if (url != "localhost") { // if (url != "localhost") {
settingsData.filter((n: any) => n.name === "devDir"); // settingsData.filter((n: any) => n.name === "devDir");
} // }
return settingsData; return data.data;
}; };

View File

@@ -35,7 +35,7 @@
} }
}, },
"admConfig": { "admConfig": {
"build": 399, "build": 406,
"oldBuild": "backend-0.1.3.zip" "oldBuild": "backend-0.1.3.zip"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -72,7 +72,7 @@ export const removeAsNonReusable = async (data: any) => {
if (stage === 0) { if (stage === 0) {
stage = 1; stage = 1;
scanner.write( scanner.write(
`${STX}${scannerID[0].value}${label.data[0].Barcode}${ETX}` `${STX}${scannerID[0].value}@${label.data[0].Barcode}${ETX}`
); );
} else if (stage === 1) { } else if (stage === 1) {
scanner.end(); scanner.end();

View File

@@ -44,6 +44,7 @@ export const updatePrinters = async () => {
ipAddress: prodPrinterInfo[i].ipAddress, ipAddress: prodPrinterInfo[i].ipAddress,
port: prodPrinterInfo[i].port, port: prodPrinterInfo[i].port,
remark: prodPrinterInfo[i].remark, remark: prodPrinterInfo[i].remark,
processes: prodPrinterInfo[i].processes,
}; };
const { data, error } = await tryCatch( const { data, error } = await tryCatch(
db db
@@ -57,6 +58,7 @@ export const updatePrinters = async () => {
ipAddress: prodPrinterInfo[i].ipAddress, ipAddress: prodPrinterInfo[i].ipAddress,
port: prodPrinterInfo[i].port, port: prodPrinterInfo[i].port,
remark: prodPrinterInfo[i].remark, remark: prodPrinterInfo[i].remark,
processes: prodPrinterInfo[i].processes,
upd_date: sql`NOW()`, upd_date: sql`NOW()`,
//printDelay: "90", // need to remove in a couple weeks //printDelay: "90", // need to remove in a couple weeks
}, },

View File

@@ -49,6 +49,6 @@ export const palletSendTag = async (tagData: any) => {
Date.now() - tagTime <= 5000 && Date.now() - tagTime <= 5000 &&
!tagData.value !tagData.value
) { ) {
await pickedup({ runningNr: 1234, all: true }); await pickedup({ runningNr: 1234, all: true, areaFrom: "wrapper1" });
} }
}; };

View File

@@ -0,0 +1,23 @@
import { db } from "../../../../database/dbclient.js";
import { prodPermissions } from "../../../../database/schema/prodPermissions.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
export const getProdRoles = async () => {
const { data, error } = (await tryCatch(
db.select().from(prodPermissions)
)) as any;
if (error) {
return {
success: false,
message: "Error getting prod permissions",
data: error,
};
}
return {
success: true,
message: "Current prod permissions",
data: data,
};
};

View File

@@ -28,7 +28,7 @@ export const prodUser = async (data: any) => {
if (pe) { if (pe) {
console.log(pe); console.log(pe);
return { return {
succes: false, success: false,
message: "There was an error getting the base prod permissions", message: "There was an error getting the base prod permissions",
data: pe, data: pe,
}; };
@@ -39,7 +39,7 @@ export const prodUser = async (data: any) => {
if (permRoleCheck.length === 0) { if (permRoleCheck.length === 0) {
return { return {
succes: false, success: false,
message: `Role: ${data.role}, dose note exist please check the role you have selected and try again.`, message: `Role: ${data.role}, dose note exist please check the role you have selected and try again.`,
data: [], data: [],
}; };
@@ -55,6 +55,8 @@ export const prodUser = async (data: any) => {
console.log(userError); console.log(userError);
} }
//console.log(permRoleCheck);
if (usercheck?.data.length === 0) { if (usercheck?.data.length === 0) {
// create the user // create the user
const newUser: any = { const newUser: any = {
@@ -69,9 +71,7 @@ export const prodUser = async (data: any) => {
const { data: newU, error: newE } = (await tryCatch( const { data: newU, error: newE } = (await tryCatch(
axios.post(newurl, newUser, { axios.post(newurl, newUser, {
headers: { headers: {
Authorization: `Basic ${btoa( "X-API-Key": process.env.TEC_API_KEY || "",
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}) })
@@ -80,42 +80,40 @@ export const prodUser = async (data: any) => {
if (newE) { if (newE) {
console.log(newE); console.log(newE);
return { return {
succes: false, success: false,
message: `${data.username} encountered an error creating..`, message: `${data.username} encountered an error creating..`,
data: newE.response.data, data: newE.response.data,
}; };
} }
return { return {
succes: true, success: true,
message: `${data.username} was just created or updated.`, message: `${data.username} was just created or updated.`,
data: [], data: [],
}; };
} else { } else {
// revoke and readd // revoke and readd
const revokePerms: any = { const revokePerms: any = {
roles: roles: JSON.parse(
JSON.parse(usercheck.data[0].roles.replaceAll("\\", "\\\\")) || usercheck.data[0].roles.replaceAll("\\", "\\\\")
[], ) || ["Manufacturing\\IssueMaterial\\MaterialHandler"],
rolesLegacy: JSON.parse(usercheck.data[0].legacyRoles) || [], rolesLegacy: JSON.parse(usercheck.data[0].legacyRoles) || [3],
}; };
const { data: newU, error: newE } = (await tryCatch( const { data: newU, error: newE } = (await tryCatch(
axios.patch(revoke, revokePerms, { axios.patch(revoke, revokePerms, {
headers: { headers: {
Authorization: `Basic ${btoa( "X-API-Key": process.env.TEC_API_KEY || "",
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}) })
)) as any; )) as any;
if (newE) { if (newE) {
console.log(newE.response.data); console.log("Revoke failed with: ", newE.response.data);
return { return {
succes: false, success: false,
message: `${data.username} encountered an error updating..`, message: `${data.username} encountered an error updating..`,
data: newE.response.data, data: newE.response.data,
}; };
@@ -130,9 +128,7 @@ export const prodUser = async (data: any) => {
const { data: grant, error: grante } = (await tryCatch( const { data: grant, error: grante } = (await tryCatch(
axios.patch(grantUrl, grantRole, { axios.patch(grantUrl, grantRole, {
headers: { headers: {
Authorization: `Basic ${btoa( "X-API-Key": process.env.TEC_API_KEY || "",
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}) })
@@ -141,7 +137,7 @@ export const prodUser = async (data: any) => {
if (grante) { if (grante) {
console.log(newE.response.data); console.log(newE.response.data);
return { return {
succes: false, success: false,
message: `${data.username} encountered an error updating..`, message: `${data.username} encountered an error updating..`,
data: newE.response.data, data: newE.response.data,
}; };
@@ -149,8 +145,59 @@ export const prodUser = async (data: any) => {
} }
return { return {
succes: true, success: true,
message: `${data.username} was just created or updated.`, message: `${data.username} was just created or updated.`,
data: [], data: [],
}; };
}; };
const deleteUser = async (data: any, permRoleCheck: any) => {
const remove = await prodEndpointCreation(
`/public/v1.0/Administration/User/${data.username}`
);
const newurl = await prodEndpointCreation(
`/public/v1.0/Administration/User`
);
const { data: removal, error: grante } = (await tryCatch(
axios.delete(remove, {
headers: {
"X-API-Key": process.env.TEC_API_KEY || "",
"Content-Type": "application/json",
},
})
)) as any;
const newUser: any = {
userId: data.username,
remark: data.remark,
languageCode: "en",
active: true,
roles: permRoleCheck[0].roles,
rolesLegacy: permRoleCheck[0].rolesLegacy,
};
const { data: newU, error: newE } = (await tryCatch(
axios.post(newurl, newUser, {
headers: {
"X-API-Key": process.env.TEC_API_KEY || "",
"Content-Type": "application/json",
},
})
)) as any;
if (newE) {
console.log(newE);
return {
success: false,
message: `${data.username} encountered an error creating..`,
data: newE.response.data,
};
}
return {
success: true,
message: `${data.username} was just created.`,
data: [],
};
};

View File

@@ -1,10 +1,11 @@
import { OpenAPIHono } from "@hono/zod-openapi"; import { OpenAPIHono } from "@hono/zod-openapi";
import produser from "./routes/produser.js"; import produser from "./routes/produser.js";
import createProdRole from "./routes/addProdRole.js"; import createProdRole from "./routes/addProdRole.js";
import getRoles from "./routes/getProdRoles.js";
import { prodRoles } from "./utils/prodRoles.js"; import { prodRoles } from "./utils/prodRoles.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
const routes = [produser, createProdRole] as const; const routes = [produser, createProdRole, getRoles] as const;
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/produser", route); app.route("/produser", route);

View File

@@ -34,7 +34,7 @@ app.openapi(
} }
return c.json({ return c.json({
success: data.succes, success: data.success,
message: data.message, message: data.message,
data: data.data, data: data.data,
}); });

View File

@@ -0,0 +1,36 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { apiHit } from "../../../globalUtils/apiHits.js";
import { prodUser } from "../controller/produser.js";
import { getProdRoles } from "../controller/getprodRoles.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["admin"],
summary: "Returns the current prod roles",
method: "get",
path: "/prodrole",
responses: responses(),
}),
async (c) => {
const { data, error } = await tryCatch(getProdRoles());
apiHit(c, { endpoint: "/prodrole" });
if (error) {
return c.json({
success: false,
message: "Error getting new role.",
});
}
return c.json({
success: data.success,
message: data.message,
data: data.data,
});
}
);
export default app;

View File

@@ -36,7 +36,7 @@ app.openapi(
} }
return c.json({ return c.json({
success: data.succes, success: data.success,
message: data.message, message: data.message,
data: data.data, data: data.data,
}); });

View File

@@ -56,7 +56,7 @@ const newProdRoles: any = [
"DemandManagement\\Forecast\\ProcessAdmin", "DemandManagement\\Forecast\\ProcessAdmin",
"Manufacturing\\ProductionLabelling\\ProcessAdmin", "Manufacturing\\ProductionLabelling\\ProcessAdmin",
], ],
rolesLegacy: [4, 55, 145, 95, 45, 105, 65, 15, 125], rolesLegacy: [3, 55, 145, 95, 45, 105, 65, 15, 125],
}, },
// regional // regional
]; ];

View File

@@ -236,6 +236,14 @@ const newSettings = [
serviceBelowsTo: "logistics", serviceBelowsTo: "logistics",
roleToChange: "admin", roleToChange: "admin",
}, },
{
name: "stagingReturnLocations",
value: `30125,31523`,
description:
"What are the staging location IDs we will use to select from. seperated by commas",
serviceBelowsTo: "logistics",
roleToChange: "admin",
},
// temp settings can be deleted at a later date once that code is removed // temp settings can be deleted at a later date once that code is removed
{ {
name: "siloAdjMigrations", name: "siloAdjMigrations",

View File

@@ -172,6 +172,13 @@ const newSubModules = [
newWindow: false, newWindow: false,
isActive: true, isActive: true,
}, },
{
name: "Prod Perms",
link: "/produsers",
icon: "Users",
newWindow: false,
isActive: true,
},
{ {
name: "UCD", name: "UCD",
link: "https://ucd.alpla.net:8443/", link: "https://ucd.alpla.net:8443/",