feat(migration): dm moved

This commit is contained in:
2025-10-26 11:47:12 -05:00
parent 6a84da4117
commit ac9670d553
19 changed files with 455 additions and 124 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -37,6 +37,7 @@ import { Route as OldOldocmeCyclecountIndexRouteImport } from './routes/_old/old
import { Route as OldOldlogisticsSiloAdjustmentsIndexRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/index'
import { Route as OldOldlogisticsMaterialHelperIndexRouteImport } from './routes/_old/old/(logistics)/materialHelper/index'
import { Route as OldOldlogisticsHelperCommandsIndexRouteImport } from './routes/_old/old/(logistics)/helperCommands/index'
import { Route as OldOldlogisticsDmIndexRouteImport } from './routes/_old/old/(logistics)/dm/index'
import { Route as OldOldlogisticsBarcodegenIndexRouteImport } from './routes/_old/old/(logistics)/barcodegen/index'
import { Route as OldOldlogisticsSiloAdjustmentsHistRouteImport } from './routes/_old/old/(logistics)/siloAdjustments/$hist'
import { Route as AppAdminLayoutAdminUsersUsersRouteImport } from './routes/_app/_adminLayout/admin/_users/users'
@@ -192,6 +193,11 @@ const OldOldlogisticsHelperCommandsIndexRoute =
path: '/helperCommands/',
getParentRoute: () => OldOldRouteRoute,
} as any)
const OldOldlogisticsDmIndexRoute = OldOldlogisticsDmIndexRouteImport.update({
id: '/(logistics)/dm/',
path: '/dm/',
getParentRoute: () => OldOldRouteRoute,
} as any)
const OldOldlogisticsBarcodegenIndexRoute =
OldOldlogisticsBarcodegenIndexRouteImport.update({
id: '/(logistics)/barcodegen/',
@@ -253,6 +259,7 @@ export interface FileRoutesByFullPath {
'/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute
'/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
'/old/barcodegen': typeof OldOldlogisticsBarcodegenIndexRoute
'/old/dm': typeof OldOldlogisticsDmIndexRoute
'/old/helperCommands': typeof OldOldlogisticsHelperCommandsIndexRoute
'/old/materialHelper': typeof OldOldlogisticsMaterialHelperIndexRoute
'/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
@@ -283,6 +290,7 @@ export interface FileRoutesByTo {
'/admin/users': typeof AppAdminLayoutAdminUsersUsersRoute
'/old/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
'/old/barcodegen': typeof OldOldlogisticsBarcodegenIndexRoute
'/old/dm': typeof OldOldlogisticsDmIndexRoute
'/old/helperCommands': typeof OldOldlogisticsHelperCommandsIndexRoute
'/old/materialHelper': typeof OldOldlogisticsMaterialHelperIndexRoute
'/old/siloAdjustments': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
@@ -319,6 +327,7 @@ export interface FileRoutesById {
'/_app/_adminLayout/admin/_users/users': typeof AppAdminLayoutAdminUsersUsersRoute
'/_old/old/(logistics)/siloAdjustments/$hist': typeof OldOldlogisticsSiloAdjustmentsHistRoute
'/_old/old/(logistics)/barcodegen/': typeof OldOldlogisticsBarcodegenIndexRoute
'/_old/old/(logistics)/dm/': typeof OldOldlogisticsDmIndexRoute
'/_old/old/(logistics)/helperCommands/': typeof OldOldlogisticsHelperCommandsIndexRoute
'/_old/old/(logistics)/materialHelper/': typeof OldOldlogisticsMaterialHelperIndexRoute
'/_old/old/(logistics)/siloAdjustments/': typeof OldOldlogisticsSiloAdjustmentsIndexRoute
@@ -352,6 +361,7 @@ export interface FileRouteTypes {
| '/admin/users'
| '/old/siloAdjustments/$hist'
| '/old/barcodegen'
| '/old/dm'
| '/old/helperCommands'
| '/old/materialHelper'
| '/old/siloAdjustments'
@@ -382,6 +392,7 @@ export interface FileRouteTypes {
| '/admin/users'
| '/old/siloAdjustments/$hist'
| '/old/barcodegen'
| '/old/dm'
| '/old/helperCommands'
| '/old/materialHelper'
| '/old/siloAdjustments'
@@ -417,6 +428,7 @@ export interface FileRouteTypes {
| '/_app/_adminLayout/admin/_users/users'
| '/_old/old/(logistics)/siloAdjustments/$hist'
| '/_old/old/(logistics)/barcodegen/'
| '/_old/old/(logistics)/dm/'
| '/_old/old/(logistics)/helperCommands/'
| '/_old/old/(logistics)/materialHelper/'
| '/_old/old/(logistics)/siloAdjustments/'
@@ -622,6 +634,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof OldOldlogisticsHelperCommandsIndexRouteImport
parentRoute: typeof OldOldRouteRoute
}
'/_old/old/(logistics)/dm/': {
id: '/_old/old/(logistics)/dm/'
path: '/dm'
fullPath: '/old/dm'
preLoaderRoute: typeof OldOldlogisticsDmIndexRouteImport
parentRoute: typeof OldOldRouteRoute
}
'/_old/old/(logistics)/barcodegen/': {
id: '/_old/old/(logistics)/barcodegen/'
path: '/barcodegen'
@@ -766,6 +785,7 @@ interface OldOldRouteRouteChildren {
OldOldRfidIndexRoute: typeof OldOldRfidIndexRoute
OldOldlogisticsSiloAdjustmentsHistRoute: typeof OldOldlogisticsSiloAdjustmentsHistRoute
OldOldlogisticsBarcodegenIndexRoute: typeof OldOldlogisticsBarcodegenIndexRoute
OldOldlogisticsDmIndexRoute: typeof OldOldlogisticsDmIndexRoute
OldOldlogisticsHelperCommandsIndexRoute: typeof OldOldlogisticsHelperCommandsIndexRoute
OldOldlogisticsMaterialHelperIndexRoute: typeof OldOldlogisticsMaterialHelperIndexRoute
OldOldlogisticsSiloAdjustmentsIndexRoute: typeof OldOldlogisticsSiloAdjustmentsIndexRoute
@@ -781,6 +801,7 @@ const OldOldRouteRouteChildren: OldOldRouteRouteChildren = {
OldOldlogisticsSiloAdjustmentsHistRoute:
OldOldlogisticsSiloAdjustmentsHistRoute,
OldOldlogisticsBarcodegenIndexRoute: OldOldlogisticsBarcodegenIndexRoute,
OldOldlogisticsDmIndexRoute: OldOldlogisticsDmIndexRoute,
OldOldlogisticsHelperCommandsIndexRoute:
OldOldlogisticsHelperCommandsIndexRoute,
OldOldlogisticsMaterialHelperIndexRoute:

View File

@@ -0,0 +1,33 @@
import { createFileRoute, redirect } from "@tanstack/react-router";
import { checkUserAccess } from "@/lib/authClient";
import DmPage from "../../-components/logistics/dm/dmPage";
export const Route = createFileRoute("/_old/old/(logistics)/dm/")({
component: RouteComponent,
beforeLoad: async () => {
const auth = await checkUserAccess({
allowedRoles: ["systemAdmin", "technician", "admin", "manager"],
moduleName: "siloAdjustments", // optional
});
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

@@ -1,73 +1,55 @@
import { useSettingStore } from "../../../-lib/store/useSettings";
import ForecastImport from "./ForecastImport";
import OrderImport from "./OrderImport";
import { useSettingStore } from "@/lib/store/useSettings";
export default function DMButtons() {
const { settings } = useSettingStore();
const testServers = ["test1", "test2", "test3"];
const plantToken = settings.filter((n) => n.name === "plantToken");
//console.log(plantToken);
return (
<div className="flex flex-row-reverse gap-1">
<OrderImport fileType={"macro"} name={"Macro Import"} />
{/* dev and testserver sees all */}
{testServers.includes(plantToken[0]?.value) && (
<div className="flex flex-row gap-2">
<OrderImport
fileType={"abbott"}
name={"Abbott truck list"}
/>
<OrderImport
fileType={"energizer"}
name={"Energizer Truck List"}
/>
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
<ForecastImport fileType={"pg"} name={"P&G"} />
<ForecastImport
fileType={"energizer"}
name={"Energizer Forecast"}
/>
</div>
)}
{plantToken[0]?.value === "usday1" && (
<div className="flex flex-row gap-2">
<OrderImport
fileType={"abbott"}
name={"Abbott truck list"}
/>
<OrderImport
fileType={"energizer"}
name={"Energizer Truck List"}
/>
<ForecastImport
fileType={"energizer"}
name={"Energizer Forecast"}
/>
</div>
)}
{plantToken[0]?.value === "usflo1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usstp1" && (
<div className="flex flex-row gap-2"></div>
)}
{plantToken[0]?.value === "usiow1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
{plantToken[0]?.value === "usiow2" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
{plantToken[0]?.value === "usksc1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
</div>
);
const { settings } = useSettingStore();
const testServers = ["test1", "test2", "test3"];
const plantToken = settings.filter((n) => n.name === "plantToken");
//console.log(plantToken);
return (
<div className="flex flex-row-reverse gap-1">
<OrderImport fileType={"macro"} name={"Macro Import"} />
{/* dev and testserver sees all */}
{testServers.includes(plantToken[0]?.value) && (
<div className="flex flex-row gap-2">
<OrderImport fileType={"abbott"} name={"Abbott truck list"} />
<OrderImport fileType={"energizer"} name={"Energizer Truck List"} />
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
<ForecastImport fileType={"pg"} name={"P&G"} />
<ForecastImport fileType={"energizer"} name={"Energizer Forecast"} />
</div>
)}
{plantToken[0]?.value === "usday1" && (
<div className="flex flex-row gap-2">
<OrderImport fileType={"abbott"} name={"Abbott truck list"} />
<OrderImport fileType={"energizer"} name={"Energizer Truck List"} />
<ForecastImport fileType={"energizer"} name={"Energizer Forecast"} />
</div>
)}
{plantToken[0]?.value === "usflo1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usstp1" && (
<div className="flex flex-row gap-2"></div>
)}
{plantToken[0]?.value === "usiow1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
{plantToken[0]?.value === "usiow2" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
{plantToken[0]?.value === "usksc1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
</div>
);
}

View File

@@ -0,0 +1,69 @@
import axios from "axios";
import { useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
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("postForecast", e.target.files[0]);
formData.append("fileType", props.fileType); // extra field
// console.log(formData);
toast.success("Import started.");
try {
const response = await axios.post(
"/lst/old/api/logistics/postforecastin",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
},
);
//console.log("Upload successful:", response.data);
toast.success(response?.data?.message);
fileInputRef.current.value = null;
setPosting(false);
// 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,64 @@
import axios from "axios";
import { useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
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
try {
const response = await axios.post(
"/lst/old/api/logistics/postbulkorders",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
},
);
//console.log("Upload successful:", response.data);
toast.success(response?.data?.message);
fileInputRef.current.value = null;
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,44 @@
import axios from "axios";
import { format } from "date-fns";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
export default function StandardForecastTemplate() {
const [template, setTemplate] = useState(false);
const getTemplate = async () => {
setTemplate(true);
try {
const res = await axios.get(
`/lst/old/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 axios from "axios";
import { format } from "date-fns";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
export default function StandardOrderTemplate() {
const [template, setTemplate] = useState(false);
const getTemplate = async () => {
setTemplate(true);
try {
const res = await axios.get(`/lst/old/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,133 @@
import { Separator } from "@/components/ui/separator";
import { LstCard } from "../../extendedUi/LstCard";
import ForecastImport from "./ForecastImport";
import OrderImport from "./OrderImport";
import StandardForecastTemplate from "./StandardForecastTemplate";
import StandardOrderTemplate from "./StandardOrderTemplate";
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>
<div className="flex flex-row gap-3 m-1">
<OrderImport fileType={"standard"} name={"Standard Order Import"} />
<StandardOrderTemplate />
</div>
<Separator />
</div>
<ul className="list-disc mr-2">
<li>
Download the standard template if you have not yet done so, Above
click Standard Order 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 entered, click Standard Order Import
</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="/lst/app/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>
<div className="flex flex-row gap-3 m-1">
<ForecastImport
fileType={"standard"}
name={"Standard Forecast Import"}
/>
<StandardForecastTemplate />
<Separator className="my-4" />
</div>
</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>
<li>
The customer MUST be set as default address in order for the
system to validate the av.
</li>
</ul>
</div>
<Separator className="my-4" />
<p className="text-center underline text-2xl">Example forecast</p>
<div className="flex justify-center">
<img
src="/lst/app/imgs/exampleforecast.png"
alt="orders in example"
className="w-[480px] h-[280px]"
/>
</div>
</LstCard>
</div>
);
}

View File

@@ -1,14 +0,0 @@
import BGPage from "@/components/logistics/barcodeGenerator/BGPage";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/barcodegen/")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<BGPage />
</div>
);
}

View File

@@ -1,28 +0,0 @@
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

@@ -1,14 +0,0 @@
import OpenOrders from "@/components/logistics/warehouse/openOrders";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/openOrders/")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div className="m-5 w-11/12 h-9/10">
<OpenOrders />
</div>
);
}