Compare commits

...

41 Commits

Author SHA1 Message Date
a3732c0208 fix(blocking notification): added throw error so i get an email when it errors 2025-04-21 21:06:23 -05:00
abc39634fb docs(macrotemplate): bump version so everyone gets the new sheety 2025-04-21 21:05:46 -05:00
dd7299ad76 refactor(serverdata): changed all server ports to 3000 2025-04-21 21:05:12 -05:00
2343f9387a refactor(ocme): moved the server port to the app vs ocme 2025-04-21 21:04:50 -05:00
9a6cec65cd refactor(inventory card): changed to 500 by default so we can scroll 2025-04-21 21:04:22 -05:00
92dc3855b9 fix(lst): removed console log on useraccess 2025-04-21 21:03:55 -05:00
6334efe093 test(time): more time testing 2025-04-21 21:03:38 -05:00
e9cb3e5db4 fix(manual print form): corrected typos and name 2025-04-21 21:03:13 -05:00
8422955d39 feat(dm): added import and exports plus first custom for dayton 2025-04-21 21:02:44 -05:00
06d2f1464b refactor(dm): repaced the orders in image with the new updated one 2025-04-21 21:01:57 -05:00
a1d526bd52 ci(release): bump build number to 287 2025-04-21 20:14:43 -05:00
6ef9626cb7 ci(release): bump build number to 286 2025-04-21 17:53:48 -05:00
55cc694a0e ci(release): bump build number to 285 2025-04-21 17:36:01 -05:00
3b8296dd54 ci(release): bump build number to 284 2025-04-21 16:29:23 -05:00
c39a12759f ci(release): bump build number to 283 2025-04-21 15:41:48 -05:00
7b0a1d08d2 ci(release): bump build number to 282 2025-04-21 08:03:02 -05:00
925776b634 ci(release): bump build number to 281 2025-04-21 08:01:08 -05:00
789ea31948 ci(release): bump build number to 280 2025-04-21 07:58:15 -05:00
f8ba05fbae ci(release): bump build number to 279 2025-04-21 07:56:20 -05:00
44f418cfbc ci(release): bump build number to 278 2025-04-21 07:53:18 -05:00
d65450d5ee fix(ocme): cycle counts on an empty stock row would crash corrected so this wont happen 2025-04-21 07:49:39 -05:00
8240e9c5d3 fix(log cleanup): corrected the level look at 2025-04-21 07:48:49 -05:00
bb6d1c3bff fix(time): changes the labeling time to be our db version 2025-04-21 07:48:21 -05:00
f44e5a87e7 refactor(v1 cleanup): added in removal of localstoage items from v1 2025-04-21 07:46:24 -05:00
b42b8a4c83 ci(release): bump build number to 277 2025-04-21 07:23:09 -05:00
c741274ffa ci(release): bump build number to 276 2025-04-21 07:19:22 -05:00
93693d3093 ci(release): bump build number to 275 2025-04-20 17:29:24 -05:00
fd49280313 ci(release): bump build number to 274 2025-04-20 17:25:51 -05:00
39e5929b46 ci(release): bump build number to 273 2025-04-20 17:23:27 -05:00
53520845a8 ci(release): bump build number to 272 2025-04-20 17:19:40 -05:00
4fe7eed8ef ci(release): bump build number to 271 2025-04-20 17:15:05 -05:00
c397e56407 ci(release): bump build number to 270 2025-04-20 17:13:48 -05:00
ea0610c86b ci(release): bump build number to 269 2025-04-20 17:00:07 -05:00
09fd408f6c ci(release): bump build number to 268 2025-04-20 16:54:57 -05:00
96c1e4d28a ci(release): bump build number to 267 2025-04-20 16:51:13 -05:00
0d4a5ca396 ci(release): bump build number to 266 2025-04-20 16:50:30 -05:00
9011b9cb64 ci(release): bump build number to 265 2025-04-20 16:44:30 -05:00
bc519bcfeb ci(release): bump build number to 264 2025-04-20 16:41:10 -05:00
f0a1a7ada2 ci(release): bump build number to 263 2025-04-20 16:37:50 -05:00
42dcd93d19 ci(release): bump build number to 262 2025-04-20 16:30:59 -05:00
fdd2024b84 ci(release): bump build number to 261 2025-04-20 16:28:53 -05:00
30 changed files with 615 additions and 149 deletions

View File

@@ -23,7 +23,6 @@
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
"@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.0.15",
"@tanstack/react-form": "^1.2.1",
"@tanstack/react-query": "^5.69.0",
@@ -2939,21 +2938,6 @@
"node": ">= 10"
}
},
"node_modules/@tailwindcss/typography": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
"integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
"license": "MIT",
"dependencies": {
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"postcss-selector-parser": "6.0.10"
},
"peerDependencies": {
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
}
},
"node_modules/@tailwindcss/vite": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.15.tgz",
@@ -4194,18 +4178,6 @@
"node": ">= 8"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -5746,12 +5718,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"license": "MIT"
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -5792,6 +5758,7 @@
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.once": {
@@ -6121,19 +6088,6 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7088,12 +7042,6 @@
"which-typed-array": "^1.1.2"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
"node_modules/victory-vendor": {
"version": "36.9.2",
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,80 @@
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import OrderImport from "./OrderImport";
import StandardOrderTemplate from "./StandardOrderTemplate";
import { Button } from "@/components/ui/button";
import StandardForecastTemplate from "./StandardForecastTemplate";
import ForecastImport from "./ForecastImport";
import { useSettingStore } from "@/lib/store/useSettings";
export default function DMButtons() {
const { settings } = useSettingStore();
const plantToken = settings.filter((n) => n.name === "plantToken");
console.log(plantToken);
return (
<div className="flex flex-row-reverse">
<div className="m-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>Standard DM</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>
Standard templates and imports
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>
<StandardOrderTemplate />
</DropdownMenuItem>
<DropdownMenuItem>
<OrderImport
fileType={"standard"}
name={"Standard Order Import"}
/>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<StandardForecastTemplate />
</DropdownMenuItem>
<DropdownMenuItem>
<ForecastImport
fileType={"standard"}
name={"Standard Forecast Import"}
/>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
{plantToken[0]?.value === "usday1" && (
<div className="m-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>Dayton Customs</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>
Custom import templates
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>
<OrderImport
fileType={"abbott"}
name={"Abbott truck list"}
/>
</DropdownMenuItem>
<DropdownMenuSeparator />
</DropdownMenuContent>
</DropdownMenu>
</div>
)}
</div>
);
}

View File

@@ -0,0 +1,66 @@
import { Button } from "@/components/ui/button";
import axios from "axios";
import { useRef, useState } from "react";
import { toast } from "sonner";
export default function ForecastImport(props: any) {
const fileInputRef: any = useRef(null);
const [posting, setPosting] = useState(false);
const token = localStorage.getItem("auth_token");
//const [fileType, setFileType] = useState("");
const importOrders = async (e: any) => {
const file = e.target.files[0];
if (!file) {
toast.error("Missing file please try again");
setPosting(false);
return;
}
// create the form data with the correct fileType
const formData = new FormData();
formData.append("postOrders", e.target.files[0]);
formData.append("fileType", props.fileType); // extra field
// console.log(formData);
try {
const response = await axios.post(
"/api/logistics/postforecastin",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
}
);
console.log("Upload successful:", response.data);
toast.success(
"File Uploaded, please validate processing in alplaprod 2.0"
);
setPosting(false);
} catch (error) {
console.log(error);
toast.error("Upload failed");
}
setPosting(false);
};
const handleButtonClick = () => {
setPosting(true);
fileInputRef.current.click();
};
return (
<div>
<Button onClick={handleButtonClick} disabled={posting}>
{props.name}
</Button>
<input
type="file"
accept=".xlsx, .xls, .xlsm"
ref={fileInputRef}
style={{ display: "none" }}
onChange={importOrders}
/>
</div>
);
}

View File

@@ -0,0 +1,66 @@
import { Button } from "@/components/ui/button";
import axios from "axios";
import { useRef, useState } from "react";
import { toast } from "sonner";
export default function OrderImport(props: any) {
const fileInputRef: any = useRef(null);
const [posting, setPosting] = useState(false);
const token = localStorage.getItem("auth_token");
//const [fileType, setFileType] = useState("");
const importOrders = async (e: any) => {
const file = e.target.files[0];
if (!file) {
toast.error("Missing file please try again");
setPosting(false);
return;
}
// create the form data with the correct fileType
const formData = new FormData();
formData.append("postOrders", e.target.files[0]);
formData.append("fileType", props.fileType); // extra field
// console.log(formData);
try {
const response = await axios.post(
"/api/logistics/postbulkorders",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
}
);
console.log("Upload successful:", response.data);
toast.success(
"File Uploaded, please validate processing in alplaprod 2.0"
);
setPosting(false);
} catch (error) {
console.log(error);
toast.error("Upload failed");
}
setPosting(false);
};
const handleButtonClick = () => {
setPosting(true);
fileInputRef.current.click();
};
return (
<div>
<Button onClick={handleButtonClick} disabled={posting}>
{props.name}
</Button>
<input
type="file"
accept=".xlsx, .xls, .xlsm"
ref={fileInputRef}
style={{ display: "none" }}
onChange={importOrders}
/>
</div>
);
}

View File

@@ -0,0 +1,41 @@
import { Button } from "@/components/ui/button";
import axios from "axios";
import { format } from "date-fns";
import { useState } from "react";
import { toast } from "sonner";
export default function StandardForecastTemplate() {
const [template, setTemplate] = useState(false);
const getTemplate = async () => {
setTemplate(true);
try {
const res = await axios.get(`/api/logistics/bulkforcasttemplate`, {
responseType: "blob",
});
const blob = new Blob([res.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = `ForecastTemplate-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
document.body.appendChild(link);
link.click();
// Clean up
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
toast.success(`Forecast template`);
setTemplate(false);
} catch (error) {
setTemplate(false);
toast.error("There was an error getting the template");
}
};
return (
<Button onClick={getTemplate} disabled={template}>
Standard Forecast Template
</Button>
);
}

View File

@@ -0,0 +1,41 @@
import { Button } from "@/components/ui/button";
import axios from "axios";
import { format } from "date-fns";
import { useState } from "react";
import { toast } from "sonner";
export default function StandardOrderTemplate() {
const [template, setTemplate] = useState(false);
const getTemplate = async () => {
setTemplate(true);
try {
const res = await axios.get(`/api/logistics/bulkorderstemplate`, {
responseType: "blob",
});
const blob = new Blob([res.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = `BulkOrderTemplate-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
document.body.appendChild(link);
link.click();
// Clean up
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
toast.success(`Bulk Order template`);
setTemplate(false);
} catch (error) {
setTemplate(false);
toast.error("There was an error getting the tempalte");
}
};
return (
<Button onClick={getTemplate} disabled={template}>
Standard Order Template
</Button>
);
}

View File

@@ -0,0 +1,129 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Separator } from "@/components/ui/separator";
export default function DmPage() {
return (
<div className="flex flex-row gap-2">
<LstCard className="w-1/2">
<div className="w-96">
<h4 className="text-center underline text-2xl">
Simple instructions for creating/updating orders
</h4>
<Separator />
</div>
<ul className="list-disc mr-2">
<li>
Download the standard template if you have not yet done
so, top right click standard, then template.
</li>
<li>
Add in the orders like you see in the example below.
</li>
<li>
When updating orders you are required to have the
customerOrderNumber, customerLineNumber, and
customerReleaseNumber. Quatity and dates can change.
</li>
<li>
Once you have all the orders enters click the upload
button on the top right
</li>
</ul>
<Separator className="my-4" />
<div className="m-5">
<h4 className="text-center underline text-2xl">
Some notes to consider
</h4>
<ul className="list-disc mr-2">
<li>
No longer need to add in the invoice id, we take the
default one.
</li>
<li>
You can have as many customers you want in the file
and in any order.
</li>
<li>
Orders created Manually, can not be updated with
this process.
</li>
<li>
If you desire you can send up to 1000 orders at one
time... or more....
</li>
<li>
Customer mappings can be added, this means that you
can upload your customer file and it will parse
onces mapped, you need to request this.
</li>
<li>
Custom imports will be at the top right under
custom, here you will just upload the customer file
once mapped.
</li>
</ul>
</div>
<Separator className="my-4" />
<p className="text-center underline text-2xl">Example order</p>
<div className="flex justify-center">
<img
src="/imgs/ordersInExample.png"
alt="orders in example"
className="w-[680px] h-[280px]"
/>
</div>
</LstCard>
<LstCard className="w-1/2">
<div className="w-96">
<h4 className="text-center underline text-2xl">
Simple instructions for creating forecast
</h4>
<Separator className="my-4" />
</div>
<div className="m-5">
<ul className="list-disc mr-2">
<li>
Download the template if you have not yet done so.
</li>
<li>
Add in the forecast like you see in the example
below.
</li>
<li>
Once you have all the forecast enters click the
upload button on the top right
</li>
</ul>
</div>
<Separator className="my-4" />
<div className="m-5">
<h4 className="text-center underline text-2xl">
Some notes to consider.
</h4>
<ul className="list-disc mr-2">
<li>You can only use one customer at a time.</li>
<li>
If you desire you can send up to 1000 orders at one
time...
</li>
</ul>
</div>
<Separator className="my-4" />
<p className="text-center underline text-2xl">
Example forecast
</p>
<div className="flex justify-center">
<img
src="/imgs/exampleforecast.png"
alt="orders in example"
className="w-[480px] h-[280px]"
/>
</div>
</LstCard>
</div>
);
}

View File

@@ -2,7 +2,7 @@ import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
// DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
@@ -121,11 +121,11 @@ export default function ManualPrintForm() {
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>
<DialogTitle>Manual Print form</DialogTitle>
{/* <DialogDescription>
Make changes to your profile here. Click save when
you're done.
</DialogDescription>
</DialogDescription> */}
</DialogHeader>
<form onSubmit={handleSubmit(onSubmit)}>
<p>

View File

@@ -23,6 +23,13 @@ export const SessionProvider = ({
fetchUserRoles();
fetchSubModules();
}, []);
//temp
localStorage.removeItem("ally-supports-cache");
localStorage.removeItem("auth-storage");
localStorage.removeItem("nextauth.message");
localStorage.removeItem("prod");
localStorage.removeItem("card-storage");
return (
<QueryClientProvider client={queryClient}>
{children}

View File

@@ -5,12 +5,6 @@ import { useEffect } from "react";
const fetchSession = async () => {
const token = localStorage.getItem("auth_token");
//temp
localStorage.removeItem("ally-supports-cache");
localStorage.removeItem("auth-storage");
localStorage.removeItem("nextauth.message");
localStorage.removeItem("prod");
if (!token) {
throw new Error("No token found");
}

View File

@@ -43,7 +43,7 @@ export const useCardStore = create<CardStore>()(
cards: state.cards.filter((card) => card.name !== name),
})),
}),
{ name: "card-storage" }
{ name: "cards" }
)
)
);

View File

@@ -31,6 +31,7 @@ import { Route as ocmeCyclecountIndexImport } from './routes/(ocme)/cyclecount/i
import { Route as logisticsSiloAdjustmentsIndexImport } from './routes/(logistics)/siloAdjustments/index'
import { Route as logisticsOpenOrdersIndexImport } from './routes/(logistics)/openOrders/index'
import { Route as logisticsMaterialHelperIndexImport } from './routes/(logistics)/materialHelper/index'
import { Route as logisticsDmIndexImport } from './routes/(logistics)/dm/index'
import { Route as EomArticleAvImport } from './routes/_eom/article/$av'
import { Route as logisticsSiloAdjustmentsHistImport } from './routes/(logistics)/siloAdjustments/$hist'
import { Route as logisticsMaterialHelperSiloLinkIndexImport } from './routes/(logistics)/materialHelper/siloLink/index'
@@ -158,6 +159,12 @@ const logisticsMaterialHelperIndexRoute =
getParentRoute: () => rootRoute,
} as any)
const logisticsDmIndexRoute = logisticsDmIndexImport.update({
id: '/(logistics)/dm/',
path: '/dm/',
getParentRoute: () => rootRoute,
} as any)
const EomArticleAvRoute = EomArticleAvImport.update({
id: '/article/$av',
path: '/article/$av',
@@ -322,6 +329,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof EomArticleAvImport
parentRoute: typeof EomImport
}
'/(logistics)/dm/': {
id: '/(logistics)/dm/'
path: '/dm'
fullPath: '/dm'
preLoaderRoute: typeof logisticsDmIndexImport
parentRoute: typeof rootRoute
}
'/(logistics)/materialHelper/': {
id: '/(logistics)/materialHelper/'
path: '/materialHelper'
@@ -435,6 +449,7 @@ export interface FileRoutesByFullPath {
'/ocp': typeof OcpIndexRoute
'/siloAdjustments/$hist': typeof logisticsSiloAdjustmentsHistRoute
'/article/$av': typeof EomArticleAvRoute
'/dm': typeof logisticsDmIndexRoute
'/materialHelper': typeof logisticsMaterialHelperIndexRoute
'/openOrders': typeof logisticsOpenOrdersIndexRoute
'/siloAdjustments': typeof logisticsSiloAdjustmentsIndexRoute
@@ -461,6 +476,7 @@ export interface FileRoutesByTo {
'/ocp': typeof OcpIndexRoute
'/siloAdjustments/$hist': typeof logisticsSiloAdjustmentsHistRoute
'/article/$av': typeof EomArticleAvRoute
'/dm': typeof logisticsDmIndexRoute
'/materialHelper': typeof logisticsMaterialHelperIndexRoute
'/openOrders': typeof logisticsOpenOrdersIndexRoute
'/siloAdjustments': typeof logisticsSiloAdjustmentsIndexRoute
@@ -490,6 +506,7 @@ export interface FileRoutesById {
'/ocp/': typeof OcpIndexRoute
'/(logistics)/siloAdjustments/$hist': typeof logisticsSiloAdjustmentsHistRoute
'/_eom/article/$av': typeof EomArticleAvRoute
'/(logistics)/dm/': typeof logisticsDmIndexRoute
'/(logistics)/materialHelper/': typeof logisticsMaterialHelperIndexRoute
'/(logistics)/openOrders/': typeof logisticsOpenOrdersIndexRoute
'/(logistics)/siloAdjustments/': typeof logisticsSiloAdjustmentsIndexRoute
@@ -518,6 +535,7 @@ export interface FileRouteTypes {
| '/ocp'
| '/siloAdjustments/$hist'
| '/article/$av'
| '/dm'
| '/materialHelper'
| '/openOrders'
| '/siloAdjustments'
@@ -543,6 +561,7 @@ export interface FileRouteTypes {
| '/ocp'
| '/siloAdjustments/$hist'
| '/article/$av'
| '/dm'
| '/materialHelper'
| '/openOrders'
| '/siloAdjustments'
@@ -570,6 +589,7 @@ export interface FileRouteTypes {
| '/ocp/'
| '/(logistics)/siloAdjustments/$hist'
| '/_eom/article/$av'
| '/(logistics)/dm/'
| '/(logistics)/materialHelper/'
| '/(logistics)/openOrders/'
| '/(logistics)/siloAdjustments/'
@@ -590,6 +610,7 @@ export interface RootRouteChildren {
LoginRoute: typeof LoginRoute
OcpIndexRoute: typeof OcpIndexRoute
logisticsSiloAdjustmentsHistRoute: typeof logisticsSiloAdjustmentsHistRoute
logisticsDmIndexRoute: typeof logisticsDmIndexRoute
logisticsMaterialHelperIndexRoute: typeof logisticsMaterialHelperIndexRoute
logisticsOpenOrdersIndexRoute: typeof logisticsOpenOrdersIndexRoute
logisticsSiloAdjustmentsIndexRoute: typeof logisticsSiloAdjustmentsIndexRoute
@@ -609,6 +630,7 @@ const rootRouteChildren: RootRouteChildren = {
LoginRoute: LoginRoute,
OcpIndexRoute: OcpIndexRoute,
logisticsSiloAdjustmentsHistRoute: logisticsSiloAdjustmentsHistRoute,
logisticsDmIndexRoute: logisticsDmIndexRoute,
logisticsMaterialHelperIndexRoute: logisticsMaterialHelperIndexRoute,
logisticsOpenOrdersIndexRoute: logisticsOpenOrdersIndexRoute,
logisticsSiloAdjustmentsIndexRoute: logisticsSiloAdjustmentsIndexRoute,
@@ -640,6 +662,7 @@ export const routeTree = rootRoute
"/login",
"/ocp/",
"/(logistics)/siloAdjustments/$hist",
"/(logistics)/dm/",
"/(logistics)/materialHelper/",
"/(logistics)/openOrders/",
"/(logistics)/siloAdjustments/",
@@ -727,6 +750,9 @@ export const routeTree = rootRoute
"filePath": "_eom/article/$av.tsx",
"parent": "/_eom"
},
"/(logistics)/dm/": {
"filePath": "(logistics)/dm/index.tsx"
},
"/(logistics)/materialHelper/": {
"filePath": "(logistics)/materialHelper/index.tsx"
},

View File

@@ -0,0 +1,28 @@
import DmPage from "@/components/logistics/dm/dmPage";
import { createFileRoute, redirect } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/dm/")({
component: RouteComponent,
beforeLoad: async () => {
const auth = localStorage.getItem("auth_token");
if (!auth) {
throw redirect({
to: "/login",
search: {
// Use the current location to power a redirect after login
// (Do not use `router.state.resolvedLocation` as it can
// potentially lag behind the actual current location)
redirect: location.pathname + location.search,
},
});
}
},
});
function RouteComponent() {
return (
<div>
<DmPage />
</div>
);
}

View File

@@ -27,6 +27,7 @@ import { useSession } from "@/hooks/useSession";
import { useLogout } from "@/hooks/useLogout";
import ExportInventoryData from "@/components/logistics/warehouse/ExportInventoryData";
import { AddCards } from "@/components/dashboard/AddCards";
import DMButtons from "@/components/logistics/dm/DMButtons";
//import { AddCards } from "@/components/dashboard/AddCards";
// same as the layout
@@ -44,12 +45,19 @@ export const Route = createRootRoute({
<ThemeProvider>
<nav className="flex justify-end w-full shadow ">
<div className="m-2 flex flex-row">
{/* Inventory section */}
{location.pathname === "/" && (
<div className="m-auto pr-2 flex flex-row gap-2">
<ExportInventoryData />
<AddCards />
</div>
)}
{/* Demand mgt section this should also include plant token stuff */}
{location.pathname === "/dm" && (
<div className="m-auto pr-2 flex flex-row gap-2">
<DMButtons />
</div>
)}
<div className="m-1">
<ModeToggle />
</div>

View File

@@ -1,8 +1,12 @@
import { addHours, format } from "date-fns";
import { addHours } from "date-fns";
import { format } from "date-fns-tz";
export const fixTime = (date: any) => {
/**
* This fix is when it comes directly from lst
*/
if (!date) return;
// const strippedDate = date?.replace("Z", ""); // Remove Z
//const strippedDate = date?.replace("Z", ""); // Remove Z
//return format(strippedDate, "MM/dd/yyyy hh:mm a");
const rawDate = new Date(date).toISOString();
@@ -12,6 +16,6 @@ export const fixTime = (date: any) => {
return format(
addHours(rawDate, offsetHours).toISOString(),
"MM/dd/yyyy hh:mm a"
"MM/dd/yyyy hh:mm"
);
};

View File

@@ -39,7 +39,7 @@ export function InvTable<TData, TValue>({
const [sorting, setSorting] = useState<SortingState>([]);
const [pagination, setPagination] = useState({
pageIndex: 0, //initial page index
pageSize: 5, //default page size
pageSize: 500, //default page size
});
const table = useReactTable({
data,

View File

@@ -1,5 +1,6 @@
import { fixTime } from "@/utils/fixTime";
//import { fixTime } from "@/utils/fixTime";
import { ColumnDef } from "@tanstack/react-table";
import { format } from "date-fns-tz";
// This type is used to define the shape of our data.
// You can use a Zod schema here if you want.
@@ -33,9 +34,14 @@ export const labelolumns: ColumnDef<Adjustmnets>[] = [
header: "Label Date",
cell: ({ row }) => {
if (row.getValue("upd_date")) {
const correctDate = fixTime(row.getValue("upd_date"));
const correctDate: any = row.getValue("upd_date");
const strippedDate = correctDate.replace("Z", ""); // Remove Z
const formattedDate = format(
strippedDate,
"MM/dd/yyyy hh:mm a"
);
return (
<div className="text-left font-medium">{correctDate}</div>
<div className="text-left font-medium">{formattedDate}</div>
);
}
},

View File

@@ -35,7 +35,7 @@ export function hasPageAccess(
// get only the module in the user profile
//console.log(user);
const userRole = user?.roles.filter((role) => role.module_id === module_id);
console.log(userRole[0]?.role);
//console.log(userRole[0]?.role);
// if (role.includes(userRole[0]?.role)) {
// return true};

View File

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

View File

@@ -189,6 +189,7 @@ const port =
? process.env.VITE_SERVER_PORT
: process.env.PROD_PORT;
const ocmeport = process.env.OCME_PORT;
serve(
{
fetch: app.fetch,
@@ -205,4 +206,27 @@ serve(
}
);
/**
* Only for ocme until we get them switched over to the single port setup.
*/
const setting = await db.select().from(settings);
const isActive = setting.filter((n) => n.name === "ocmeService");
if (ocmeport && isActive[0]?.value === "1") {
serve(
{
fetch: app.fetch,
port: Number(ocmeport),
hostname: "0.0.0.0",
},
(info) => {
createLog(
"info",
"LST",
"server",
`Ocme section is listening on http://${info.address}:${info.port}`
);
}
);
}
export type AppRoutes = typeof appRoutes;

View File

@@ -105,7 +105,7 @@ app.openapi(
return c.json({
success: true,
message: "All Current Active Querys.",
sheetVersion: 2.5,
sheetVersion: 2.7,
data: current,
});
}

View File

@@ -1,7 +1,7 @@
import {and, eq, inArray, lte, ne, sql} from "drizzle-orm";
import {db} from "../../../../database/dbclient.js";
import {logs} from "../../../../database/schema/logs.js";
import {createLog} from "../logger.js";
import { and, eq, inArray, lte, ne, sql } from "drizzle-orm";
import { db } from "../../../../database/dbclient.js";
import { logs } from "../../../../database/schema/logs.js";
import { createLog } from "../logger.js";
export const logCleanup = async () => {
/**
@@ -12,15 +12,15 @@ export const logCleanup = async () => {
try {
// clear info logs older than 3 days
const delLogs = await db
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '3 days'`),
inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils"]),
eq(logs.level, "30")
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '3 days'`),
//inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils","notify", "logger", "serverupdater"]),
eq(logs.level, "info")
)
)
)
.returning({name: logs.message});
.returning({ name: logs.message });
createLog(
"info",
"lst",
@@ -28,21 +28,26 @@ export const logCleanup = async () => {
`${delLogs.length} Server logs were just deleted that were older than 3 days`
);
} catch (error) {
createLog("error", "lst", "logger", `There was an error deleteing server logs. ${error}`);
createLog(
"error",
"lst",
"logger",
`There was an error deleteing server logs. ${error}`
);
}
try {
// clear all remaining logs ne to info.
const delLogs = await db
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '7 days'`),
inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils"]),
ne(logs.level, "30")
.delete(logs)
.where(
and(
lte(logs.created_at, sql`NOW() - INTERVAL '7 days'`),
//inArray(logs.service, ["server", "tcp", "sqlProd", "globalutils", "notify", "logger", "serverupdater"]),
ne(logs.level, "info")
)
)
)
.returning({name: logs.message});
.returning({ name: logs.message });
createLog(
"info",
"lst",
@@ -50,6 +55,11 @@ export const logCleanup = async () => {
`${delLogs.length} Server logs were just deleted that were older than 7 days`
);
} catch (error) {
createLog("error", "lst", "logger", `There was an error deleteing server logs. ${error}`);
createLog(
"error",
"lst",
"logger",
`There was an error deleteing server logs. ${error}`
);
}
};

View File

@@ -28,6 +28,10 @@ export default async function qualityBlockingMonitor(notifyData: any) {
.where(eq(notifications.name, notifyData.name))
);
if (notiError) {
throw Error(`${JSON.stringify(notiError)}`);
}
const notiData: any = noti;
const blockingOrders = notiData[0]?.notifiySettings.sentBlockingOrders.map(
(l: any) => {

View File

@@ -81,7 +81,9 @@ export const cycleCount = async (lane: any, user: User) => {
const postCount = {
laneId: ocme[0].alpla_laneID,
warehouseName: "",
laneName: alplaStock[0].alpla_laneDescription,
laneName: alplaStock[0]?.alpla_laneDescription
? alplaStock[0].alpla_laneDescription
: ocme[0].alpla_laneDescription,
good: !combineBoth.every(
(s) => !s.info.includes("Validate") || !s.info.includes("sent")
),

View File

@@ -16,43 +16,24 @@ import manualTrigger from "./route/triggerCamera.js";
const app = new OpenAPIHono();
const port = process.env.OCME_PORT;
const routes = [
getInfo,
postRunningNr,
postsscc,
pickedup,
getShipments,
cycleCount,
manualTrigger,
getInfo,
postRunningNr,
postsscc,
pickedup,
getShipments,
cycleCount,
manualTrigger,
] as const;
const setting = await db.select().from(settings);
const isActive = setting.filter((n) => n.name === "ocmeService");
const appRoutes = routes.forEach((route) => {
app.route("/api/v1", route);
app.route("/api/v1", route);
});
app.all("/api/v1/*", (c) => {
return c.json({
success: false,
message: "you have encounted an ocme route that dose not exist.",
});
return c.json({
success: false,
message: "you have encounted an ocme route that dose not exist.",
});
});
if (port && isActive[0]?.value === "1") {
serve(
{
fetch: app.fetch,
port: Number(port),
hostname: "0.0.0.0",
},
(info) => {
createLog(
"info",
"LST",
"server",
`Ocme section is listening on http://${info.address}:${info.port}`
);
}
);
}
export default app;

View File

@@ -12,7 +12,7 @@
"contactEmail": "noreply@alpla.com",
"contactPhone": "770-914-1407",
"customerTiAcc": "ALPLA01INTGROUP",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -32,7 +32,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01BETHINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -52,7 +52,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01HOUSINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -72,7 +72,7 @@
"contactEmail": "ShippingReceivingBowlingGreen1@groups.alpla.com",
"contactPhone": "(270) 495-6647",
"customerTiAcc": "ALPL01BG1INT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -96,7 +96,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01IA2INT",
"lstServerPort": "4001",
"lstServerPort": "3001",
"active": true,
"serverLoc": "D:\\LST\\lstv2_2",
"oldVersion": "D:\\LST\\lst_backend_2",
@@ -116,7 +116,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01KCINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -136,7 +136,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01BG2INT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -156,7 +156,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01MCDINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -176,7 +176,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01DAYTONINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -196,7 +196,7 @@
"contactEmail": "ShippingReceivingSaltLake@groups.alpla.com",
"contactPhone": "801-673-2143",
"customerTiAcc": "ALPL01SLCINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -216,7 +216,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01LIMAINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -236,7 +236,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01FLORINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -256,7 +256,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01IA1INT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "D:\\LST\\lstv2",
"oldVersion": "D:\\LST\\lst_backend",
@@ -276,7 +276,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01JCINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -290,13 +290,13 @@
"plantToken": "usshe1",
"idAddress": "10.205.0.26",
"greatPlainsPlantCode": "21",
"streetAddress": "4000 Howe Dr",
"streetAddress": "3000 Howe Dr",
"cityState": "Sherman, TX",
"zipcode": "75092",
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01SHERMANINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -316,7 +316,7 @@
"contactEmail": "shippingreceivingwestbend@groups.alpla.com",
"contactPhone": "262-808-4211",
"customerTiAcc": "ALPL01WBINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
@@ -341,7 +341,7 @@
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01STPINT",
"lstServerPort": "4000",
"lstServerPort": "3000",
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",

View File

@@ -46,6 +46,7 @@ export const serversCheckPoint = async () => {
shippingHours: servers[i].shippingHours,
customerTiAcc: servers[i].customerTiAcc,
serverLoc: servers[i].serverLoc,
lstServerPort: servers[i].lstServerPort,
oldVersion: servers[i].oldVersion,
tiPostTime: servers[i].tiPostTime,
otherSettings: servers[i].otherSettings,

View File

@@ -19,10 +19,10 @@ const newSubModules = [
subSubModule: [],
},
{
name: "Bulk orders",
name: "Demand Management",
moduleName: "logistics",
description: "",
link: "#",
description: "Bulk order and Forecast imports",
link: "/dm",
icon: "Truck",
role: ["systemAdmin"],
active: false,