migration #51

Merged
cowch merged 166 commits from migration into main 2025-09-19 22:18:47 -05:00
11 changed files with 997 additions and 53 deletions
Showing only changes of commit 88f61c8eaa - Show all commits

View File

@@ -0,0 +1,3 @@
export default function MaterialCheck() {
return <div>MaterialCheck</div>;
}

View File

@@ -0,0 +1,211 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverTrigger } from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useSessionStore } from "@/lib/store/sessionStore";
import { useModuleStore } from "@/lib/store/useModuleStore";
import { cn } from "@/lib/utils";
import { PopoverContent } from "@radix-ui/react-popover";
import { Link, useRouter } from "@tanstack/react-router";
import { startOfMonth } from "date-fns";
import { format } from "date-fns-tz";
import { CalendarIcon } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import KFP from "../KFP";
export default function MaterialData() {
const { modules } = useModuleStore();
const { user } = useSessionStore();
const router = useRouter();
const [date, setDate] = useState<Date>();
if (!user) {
router.navigate({ to: "/" });
}
const eomMod = modules.filter((m) => m.name === "eom");
// the users current role for eom is?
const role: any =
user?.roles.filter((r) => r.module_id === eomMod[0].module_id) || "";
const tabs = [
{
key: "kfp",
label: "Key Figures",
roles: ["admin", "systemAdmin"],
content: <KFP />,
},
{
key: "fg",
label: "Finished Goods",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "mm",
label: "Main Material",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "mb",
label: "Master Batch",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "ab",
label: "Additive",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pp",
label: "Purchased Preforms",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pre",
label: "Preforms",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pkg",
label: "Packaging",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "ui",
label: "Undefined Items",
roles: ["admin"],
content: <DummyContent />,
},
];
return (
<div className="m-2 w-screen">
<div className="mb-2 flex flex-row">
<Popover>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-[280px] justify-start text-left font-normal",
!date && "text-muted-foreground"
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? (
format(date, "PPP")
) : (
<span>Pick a date</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
initialFocus
/>
</PopoverContent>
</Popover>
<div className="ml-2">
<Button
onClick={() =>
toast.success(
`Getting data for ${startOfMonth(date!)}-${date}`
)
}
>
<span className="text-sm">Update Data</span>
</Button>
</div>
</div>
<Tabs defaultValue="mm">
<TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return (
<TabsTrigger value={tab.key}>
{tab.label}
</TabsTrigger>
);
})}
</TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return (
<TabsContent value={tab.key}>
{tab.content}
</TabsContent>
);
})}
</Tabs>
</div>
);
}
function DummyContent() {
return (
<LstCard className="w-5/6">
<Table>
<TableHeader>
<TableRow>
<TableHead>Av</TableHead>
<TableHead>Description</TableHead>
<TableHead>Material Type</TableHead>
<TableHead>Waste</TableHead>
<TableHead>Loss / Gain $$</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array(10)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium m-2">
<Link
to="/article/$av"
params={{ av: `${i}` }}
>
{i}
</Link>
</TableCell>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
{/* <TableCell>
<Skeleton className="h-4" />
</TableCell> */}
</TableRow>
))}
</TableBody>
</Table>
</LstCard>
);
}

View File

@@ -0,0 +1,250 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardHeader } from "@/components/ui/card";
import { useAppForm } from "@/utils/formStuff";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export default function TransferToNextLot() {
const [gaylordFilled, setGaylordFilled] = useState([0]);
const form = useAppForm({
defaultValues: {
runnungNumber: "",
lotNumber: "",
originalAmount: "",
},
onSubmit: async ({ value }) => {
//console.log(transferData);
//toast.success("603468: qty: 361, was transfered to lot:24897");
try {
const res = await axios.post("/api/ocp/materiallottransfer", {
runnungNumber: Number(value.runnungNumber),
lotNumber: Number(value.lotNumber),
originalAmount: Number(value.originalAmount),
level: Number(
gaylordFilled.length === 1
? 0.25
: gaylordFilled.length === 2
? 0.5
: gaylordFilled.length === 3
? 0.75
: gaylordFilled.length === 4 && 0.95
),
});
if (res.data.success) {
toast.success(`${res.data.message}`);
form.reset();
}
//console.log(res.data);
if (!res.data.success) {
toast.error(res.data.message);
}
} catch (error) {
if (error) {
console.log(error);
//toast.error(error)
}
}
},
});
return (
<div>
<LstCard>
<CardHeader>
<p className="text-center text-lg">
Material Transfer to Next lot
</p>
</CardHeader>
<div>
<div className="flex flex-wrap m-2 gap-2">
<div className="flex gap-2">
<div>
<LstCard className="">
<div className="grid columns-1">
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(4)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([1, 2, 3, 4])
}
>
<p className="text-center">
Almost full
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(3)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([1, 2, 3])
}
>
<p className="text-center">
About 75% full
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(2)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([1, 2])
}
>
<p className="text-center">
Half full
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(1)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled(() => [1])
}
>
<p className="text-center">
Almost empty
</p>
</button>
</div>
<div className="flex justify-end pr-1">
<Button
onClick={() =>
setGaylordFilled([0])
}
>
Reset Gaylord
</Button>
</div>
</LstCard>
</div>
<div>
<div className="w-96">
<LstCard>
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<div className="mt-3 p-2">
<form.AppField
name="runnungNumber"
children={(field) => (
<field.InputField
label="Runnung Number"
inputType="number"
required={true}
/>
)}
/>
</div>
<div className="mt-3 p-2">
<form.AppField
name="lotNumber"
children={(field) => (
<field.InputField
label="Lot Number"
inputType="number"
required={true}
/>
)}
/>
<div className="mt-3 p-2">
<form.AppField
name="originalAmount"
children={(field) => (
<field.InputField
label="Orignal Quantity"
inputType="number"
required={true}
/>
)}
/>
</div>
</div>
<div className="flex justify-end p-2">
<form.AppForm>
<form.SubmitButton>
Transfer To Lot
</form.SubmitButton>
</form.AppForm>
</div>
</form>
</LstCard>
</div>
</div>
</div>
<div>
<LstCard className="p-2">
<CardHeader>
<p className="text-center text-lg">
Moving material to the next lot.
</p>
</CardHeader>
<div>
<ol>
<li>
1. Grab the gaylord running number
from the gaylord at the line/next to
the tschritter
</li>
<li>
2. Grab the next lot number you are
going to be running (or the one that
state no Main material prepared)
</li>
<li>
3. Enter the total gaylord weight
(this is how much the gaylord
weighed when it came in from the
supplier.)
</li>
<li>
4. *Click the level of the gaylord
(this is just an estimate to move to
the next lot.)
</li>
<li>
5. type in running number on the
gaylord.
</li>
<li>6. Type in the new lot number.</li>
<li>7. Press "Transfer To Lot"</li>
</ol>
<br></br>
<p>
* to reduce the time needed to get the
lot going we will use an estimate of how
full the gaylord is.
</p>
<p>
NOTE: This is not the return process,
this process will just get the gaylord
to the next lot.
</p>
</div>
</LstCard>
</div>
</div>
</div>
</LstCard>
</div>
);
}

View File

@@ -170,20 +170,15 @@ export const labelingProcess = async ({
};
}
// check mm is good
// check the material... mm,color (auto and manual combined), pkg
const mmStaged = await isMainMatStaged(filteredLot[0]);
if (!mmStaged) {
createLog(
"error",
"labeling",
"ocp",
`Main material is not prepaired for lot ${filteredLot[0].lot}`
);
if (!mmStaged.success) {
createLog("error", "labeling", "ocp", mmStaged.message);
return {
success: false,
message: `Main material is not prepaired for lot ${filteredLot[0].lot}`,
message: mmStaged.message,
};
}

View File

@@ -0,0 +1,206 @@
import { eq } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js";
import { printerData } from "../../../../../database/schema/printers.js";
import { runProdApi } from "../../../../globalUtils/runProdApi.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { labelInfo } from "../../../sqlServer/querys/warehouse/labelInfo.js";
type NewLotData = {
runnungNumber: number;
lotNumber: number;
originalAmount: number;
level: number;
};
/**
* Move manual material to a new lot.
*
* The data sent over should be
* Running number
* Lot number
* Orignal Quantity
* level of gaylord
*/
export const lotMaterialTransfer = async (data: NewLotData) => {
// get the barcode, and layoutID from the running number
const { data: label, error: labelError } = (await tryCatch(
query(
labelInfo.replace("[runningNr]", `${data.runnungNumber}`),
"Get label info"
)
)) as any;
if (labelError) {
createLog(
"error",
"materials",
"ocp",
"There was an error getting the label info"
);
return {
success: false,
message: "There was an error getting the label info",
data: labelError,
};
}
// if (
// label.data[0]?.stockStatus === "notOnStock" ||
// label.data.length === 0
// ) {
// createLog(
// "error",
// "materials",
// "ocp",
// `${data.runnungNumber}: dose not exist or no longer in stock.`
// );
// return {
// success: false,
// message: `${data.runnungNumber}: dose not exist or no longer in stock.`,
// data: [],
// };
// }
if (label.data[0]?.stockStatus === "onStock") {
createLog(
"error",
"materials",
"ocp",
`${data.runnungNumber}: currently in stock and not consumed to a lot.`
);
return {
success: false,
message: `${data.runnungNumber}: currently in stock and not consumed to a lot.`,
data: [],
};
}
// get the pdf24 printer id
const { data: printer, error: printerError } = (await tryCatch(
db.select().from(printerData).where(eq(printerData.name, "PDF24"))
)) as any;
if (printerError) {
createLog(
"error",
"materials",
"ocp",
"There was an error the printer info"
);
return {
success: false,
message: "There was an error the printer info",
data: printerError,
};
}
// calculate the remaining amount bascially it will be orignal number * level sent over
// level should be sent in a decimal .25 .5 .75 .95 the 95 will allow basically the what looks to be a full gaylord but we always want to consume something
const newQty = (data.originalAmount * data.level).toFixed(0);
// reprint the label and send it to pdf24
const reprintData = {
clientId: 999,
runningNo: label?.data[0].runnungNumber,
printerId: printer[0].humanReadableId,
layoutId: label?.data[0].labelLayout,
noOfCopies: 0,
quantity: newQty,
} as any;
const { data: reprint, error: reprintError } = (await tryCatch(
runProdApi({
endpoint: "/public/v1.0/ProductionLabelling/ReprintLabel",
data: [reprintData],
})
)) as any;
if (!reprint.success) {
createLog(
"error",
"materials",
"ocp",
`RN:${data.runnungNumber}, Error: ${reprint.data.data.message}`
);
return {
success: false,
message: `RN:${data.runnungNumber}, Error: ${reprint.data.data.message}`,
data: reprint,
};
}
// return the label back to fm1 lane id 10001
const matReturnData = {
barcode: label?.data[0].Barcode,
laneId: 10001,
};
const { data: matReturn, error: matReturError } = (await tryCatch(
runProdApi({
endpoint:
"/public/v1.0/IssueMaterial/ReturnPartiallyConsumedManualMaterial",
data: [matReturnData],
})
)) as any;
if (!matReturn.success) {
createLog(
"error",
"materials",
"ocp",
`RN:${data.runnungNumber}, Error ${matReturn.data.data.errors[0].message}`
);
return {
success: false,
message: `RN:${data.runnungNumber}, Error ${matReturn.data.data.errors[0].message}`,
data: matReturn,
};
}
// consume to the lot provided.
const consumeLot = {
productionLot: data.lotNumber,
barcode: label?.data[0].Barcode,
};
const { data: matConsume, error: matConsumeError } = (await tryCatch(
runProdApi({
endpoint:
"/public/v1.0/IssueMaterial/ConsumeNonPreparedManualMaterial",
data: [consumeLot],
})
)) as any;
if (!matConsume.success) {
createLog(
"error",
"materials",
"ocp",
`RN:${data.runnungNumber}, Error ${matConsume.data.data.errors[0].message}`
);
return {
success: false,
message: `RN:${data.runnungNumber}, Error ${matConsume.data.data.errors[0].message}`,
data: matConsume,
};
}
createLog(
"info",
"materials",
"ocp",
`RN:${data.runnungNumber}: qty: ${newQty}, was transfered to lot:${data.lotNumber}`
);
return {
success: true,
message: `RN:${data.runnungNumber}: qty: ${newQty}, was transfered to lot:${data.lotNumber}`,
data: [],
};
};
// setTimeout(async () => {
// lotMaterialTransfer({
// runnungNumber: 603468,
// lotNumber: 24897,
// originalAmount: 380,
// level: 0.95,
// });
// }, 5000);

View File

@@ -1,12 +1,14 @@
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { serverSettings } from "../../../server/controller/settings/getSettings.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { machineCheck } from "../../../sqlServer/querys/ocp/machineId.js";
import { mmQuery } from "../../../sqlServer/querys/ocp/mainMaterial.js";
export const isMainMatStaged = async (lot: any) => {
const set = serverSettings.length === 0 ? [] : serverSettings;
// make staged false by deefault and error logged if theres an issue
let isStaged = false;
let isStaged = { message: "Material is staged", success: true };
const { data, error } = (await tryCatch(
query(
@@ -26,7 +28,10 @@ export const isMainMatStaged = async (lot: any) => {
"ocp",
`The machine dose not require mm to print and book in.`
);
return true;
return {
message: "Machine dose not require material to be staged",
success: true,
};
}
// strangly the lot is not always sending over in slc so adding this in for now to see what line is cauing this issue
@@ -51,20 +56,101 @@ export const isMainMatStaged = async (lot: any) => {
const res: any = r.data;
// if (res[0].Staged >= 1) {
// isStaged = true;
// }
createLog("info", "mainMaterial", "ocp", `Maint material query ran.`);
const mainMateiral = res.filter((n: any) => n.IsMainMaterial);
if (mainMateiral[0]?.noMaterialShortage === "no") {
isStaged = {
message: `Main material: ${mainMateiral[0].MaterialHumanReadableId} - ${mainMateiral[0].MaterialDescription}: is not staged for ${lot.lot} `,
success: false,
};
}
// we need to filter the color stuff and then look for includes instead of a standard name. this way we can capture a everything and not a single type
// for manual consume color if active to check colors
const checkColorSetting = set.filter((n) => n.name === "checkColor");
if (checkColorSetting[0].value === "1") {
const autoConsumeColor = res.filter(
(n: any) => !n.IsMainMaterial && !n.isManual
);
if (
autoConsumeColor.some(
(n: any) => n.autoConsumeCheck === "autoConsumeNOK"
)
) {
const onlyNOK = autoConsumeColor.filter(
(n: any) => n.autoConsumeCheck === "autoConsumeNOK"
);
isStaged = {
message: `lot: ${lot.lot}, is missing: ${onlyNOK
.map(
(o: any) =>
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
)
.join(",\n ")} for autoconsume`,
success: false,
};
}
// // for manual consume color
const manualConsumeColor = res.filter(
(n: any) => !n.IsMainMaterial && n.isManual
);
if (
manualConsumeColor.some(
(n: any) => n.noMaterialShortage === "yes"
)
) {
isStaged = {
message: `lot: ${lot.lot}, is missing: ${manualConsumeColor
.map(
(o: any) =>
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
)
.join(",\n ")} for manual Material`,
success: false,
};
}
} else {
createLog(
"info",
"mainMaterial",
"ocp",
`MainMaterial results: ${JSON.stringify(res)}`
"Color check is not active."
);
if (res[0].Staged >= 1) {
isStaged = true;
}
// if (res[0].noShortage === "good") {
// isStaged = true;
// }
// // if we want to check the packaging
const checkPKGSetting = set.filter((n) => n.name === "checkPKG");
if (checkPKGSetting[0].value === "1") {
const packagingCheck = res.filter(
(n: any) => !n.IsMainMaterial && n.isManual
);
if (packagingCheck.some((n: any) => n.noPKGShortage === "noPkg")) {
isStaged = {
message: `lot: ${lot.lot}, is missing: ${packagingCheck
.map(
(o: any) =>
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
)
.join(",\n ")} for pkg`,
success: false,
};
}
} else {
createLog(
"info",
"mainMaterial",
"ocp",
"PKG check is not active."
);
}
} catch (err) {
createLog(
"error",

View File

@@ -24,6 +24,7 @@ import { deleteLabels } from "../../globalUtils/dbCleanUp/labelCleanUp.js";
import bookInLabel from "./routes/labeling/bookIn.js";
import labelRatio from "./routes/labeling/getLabelRatio.js";
import resetRatio from "./routes/labeling/resetLabelRatio.js";
import materialTransferLot from "./routes/materials/lotTransfer.js";
const app = new OpenAPIHono();
@@ -47,6 +48,8 @@ const routes = [
//dyco
dycoCon,
dycoClose,
// materials
materialTransferLot,
] as const;
const setting = await db.select().from(settings);
@@ -101,4 +104,5 @@ setInterval(() => {
setInterval(() => {
updatePrinters();
}, 1000 * 60 * 60 * 24);
export default app;

View File

@@ -0,0 +1,64 @@
// 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 { lotMaterialTransfer } from "../../controller/materials/lotTransfer.js";
const app = new OpenAPIHono({ strict: false });
const LotTransfer = z.object({
runnungNumber: z.number().openapi({ example: 1234 }),
lotNumber: z.number().openapi({ example: 1235 }),
originalAmount: z.number().openapi({ example: 457 }),
level: z.number().openapi({ examples: [0.24, 0.5, 0.75, 0.95] }),
});
app.openapi(
createRoute({
tags: ["ocp"],
summary: "Transfers a gaylord of material to provided lot",
method: "post",
path: "/materiallottransfer",
request: {
body: { content: { "application/json": { schema: LotTransfer } } },
},
responses: responses(),
}),
async (c) => {
//const hours = c.req.query("hours");
const { data: bodyData, error: bodyError } = await tryCatch(
c.req.json()
);
apiHit(c, { endpoint: "/materiallottransfer", lastBody: bodyData });
if (bodyError) {
return c.json({
success: false,
message: "You are missing data",
});
}
const { data: transferMaterial, error: transferError } = await tryCatch(
lotMaterialTransfer(bodyData)
);
if (transferError) {
console.log(transferError);
return c.json({
success: false,
message:
"There was an error transfering the material to the next lot.",
data: transferError,
});
}
return c.json({
success: transferMaterial.success,
message: transferMaterial.message,
data: transferMaterial.data,
});
}
);
export default app;

View File

@@ -245,6 +245,20 @@ const newSettings = [
roleToChange: "admin",
},
// temp settings can be deleted at a later date once that code is removed
{
name: "checkColor",
value: `0`,
description: "Checks autoconsume and manual consume color",
serviceBelowsTo: "admin",
roleToChange: "admin",
},
{
name: "checkPKG",
value: `0`,
description: "Checks checks if we have enough packaging or not",
serviceBelowsTo: "admin",
roleToChange: "admin",
},
{
name: "siloAdjMigrations",
value: `0`,

View File

@@ -1,22 +1,117 @@
// export const mmQuery = `
// SELECT lot.ProductionLotHumanReadableId,
// case when SourcingState in (1, 2) then 1
// when x.ProvidedAmount > 0 then 1
// when x.EffectiveConsumption > 0 then 1
// else 0 end as Staged,
// x.ProvidedAmount as Provided,
// x.EffectiveConsumption as consumption,
// x.TotalDemand as totalNeeded,
// /* remaining needed to complete the lot */
// x.TotalDemand - x.EffectiveConsumption as remainingNeeded,
// /* do we have enough staged or scanned to the lot? */
// case when (case when x.ProvidedAmount <> 0 then x.ProvidedAmount else x.EffectiveConsumption end) > x.TotalDemand then 'good' else 'bad' end as noShortage ,
// x.IsManualProcess as isManual,
// MaterialHumanReadableId
// FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[MaterialDemand] x (nolock)
// left join
// [test1_AlplaPROD2.0_Read].[issueMaterial].[ProductionLot] as lot on
// x.ProductionLotId = lot.Id
// where lot.ProductionLotHumanReadableId = [lotNumber]
// and IsMainMaterial = 1
// `;
export const mmQuery = `
SELECT lot.ProductionLotHumanReadableId,
case when SourcingState in (1, 2) then 1
when x.ProvidedAmount > 0 then 1
when x.EffectiveConsumption > 0 then 1
else 0 end as Staged,
x.ProvidedAmount as Provided,
x.EffectiveConsumption as consumption,
x.TotalDemand as totalNeeded,
use [test1_AlplaPROD2.0_Read]
/*
checks all needed material including pkg
we only want to monitor the manual materials and the mm materail to make sure they are good.
for auto consume materails this will be compared with another query.
*/
SELECT lot.ProductionLotHumanReadableId
,MaterialHumanReadableId
,MaterialDescription
--IsMainMaterial,
--case when SourcingState in (1, 2) then 1
--when x.ProvidedAmount > 0 then 1
--when x.EffectiveConsumption > 0 then 1
--else 0 end as Staged,
,x.ProvidedAmount as Provided
,x.EffectiveConsumption as consumption
,x.TotalDemand as totalDemand ,
case when cp.Pieces = 1 then (lot.TotalProducedLoadingUnits+1) * p.LoadingUnitPieces else
(a.Weight *(cp.Percentage / 100) * ((lot.TotalProducedLoadingUnits+1) * p.LoadingUnitPieces)) / 1000 end totalNeeded
,l.qty as invForAutoConsume
/* remaining needed to complete the lot */
x.TotalDemand - x.EffectiveConsumption as remainingNeeded,
--,x.TotalDemand - x.EffectiveConsumption as remainingNeeded
/* do we have enough staged or scanned to the lot? */
case when (case when x.ProvidedAmount <> 0 then x.ProvidedAmount else x.EffectiveConsumption end) > x.TotalDemand then 'good' else 'bad' end as noShortage ,
x.IsManualProcess as isManual,
MaterialHumanReadableId
FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[MaterialDemand] x (nolock)
,case when (case when x.ProvidedAmount <> 0
then x.ProvidedAmount else x.EffectiveConsumption end) >
case when cp.Pieces = 1 then (lot.TotalProducedLoadingUnits+1) * p.LoadingUnitPieces else
(a.Weight *(cp.Percentage / 100) * ((lot.TotalProducedLoadingUnits+1) * p.LoadingUnitPieces)) / 1000 end
then 'good'
else 'no' end as noMaterialShortage
-- pkg check
,case when pkg.QuantityPosition is null then null else
(case when l.qty > (lot.TotalProducedLoadingUnits+1) * pkg.QuantityPosition then 'pkgGood' else 'noPkg' end) end as noPKGShortage
,case when cp.Percentage is null then
case when l.qty > ((lot.TotalProducedLoadingUnits +1) * pkg.QuantityPosition) then 'autoConsumeOk' else 'autoConsumeNOK' end else
(case when l.qty > (a.Weight *(cp.Percentage / 100) * ((lot.TotalProducedLoadingUnits+1) * p.LoadingUnitPieces)) / 1000 and IsManualProcess = 0
then 'autoConsumeOk' else 'autoConsumeNOK' end) end as autoConsumeCheck
,x.IsManualProcess as isManual
,IsMainMaterial
,lot.TotalPlannedLoadingUnits
,lot.TotalProducedLoadingUnits
,lot.TotalPlannedLoadingUnits - lot.TotalProducedLoadingUnits as remainingPallets
,cp.Percentage
,case when cp.Pieces is not null then cp.Pieces else pkg.QuantityPosition end as peices
FROM [issueMaterial].[MaterialDemand] x (nolock)
left join
[test1_AlplaPROD2.0_Read].[issueMaterial].[ProductionLot] as lot on
x.ProductionLotId = lot.Id
[productionControlling].[ProducedLot] as lot on
lot.Id = x.ProductionLotId
/* av data */
left join
[masterData].[Article] as a on
a.id = lot.ArticleId
/* compound*/
left join
[masterData].[CompoundPosition] as cp on
cp.CompoundId = a.CompoundId
and cp.ArticleId = x.MaterialId
/* packagaing */
left join
[masterData].[PackagingInstructionPosition] as pkg on
pkg.PackagingInstructionId = lot.PackagingId
and pkg.ArticleId = x.MaterialId
-- get the pkg stuff so we have the total amount per pallet.
left join
[masterData].[PackagingInstruction] as p on
p.id = lot.PackagingId
/* current stock info for auto consumption*/
left join
(select
IdArtikelVarianten
,ArtikelVariantenBez
,sum(VerfuegbareMengeSum) as qty
from AlplaPROD_test1.dbo.V_LagerPositionenBarcodes as i (nolock)
left join
AlplaPROD_test1.dbo.V_LagerAbteilungen as l (nolock) on
l.IdLagerAbteilung = i.IdLagerAbteilung
where autoverbrauch = 1 and aktiv = 1
group by IdArtikelVarianten,ArtikelVariantenBez
) as l on
l.IdArtikelVarianten = MaterialHumanReadableId
where lot.ProductionLotHumanReadableId = [lotNumber]
and IsMainMaterial = 1
`;

View File

@@ -1,20 +1,36 @@
export const labelInfo = `
select top(500) e.Barcode,
e.IdArtikelvarianten as av,
e.lfdnr as rn,
IdEtikettenLayout as labelLayout,
AnzStkJePalette,
Sonstiges_9,AnzStkJeKarton
,case when EinlagerungsMengeSum IS NULL then 'notOnStock' else 'onStock' end as stockStatus
,EinlagerungsMengeSum
--,*
from [AlplaPROD_test1].dbo.[T_EtikettenGedruckt] e (nolock)
declare @runningNumber nvarchar(max) = [runningNr]
select e.Barcode,
e.RunningNumber as runnungNumber,
externalRunningNumber= null,
e.ArticleHumanReadableId as av,
e.LabelManagementHumanReadableId as labelLayout,
case when EinlagerungsMengeSum IS NULL then 'notOnStock' else 'onStock' end as stockStatus
from [test1_AlplaPROD2.0_Read].[labelling].[InternalLabel] (nolock) as e
left join
[AlplaPROD_test1].dbo.V_LagerPositionenBarcodes as l on
e.LfdNr = l.Lfdnr
alplaprod_test1.dbo.V_LagerPositionenBarcodes (nolock) as l on
e.RunningNumber = l.Lfdnr
where e.LfdNr in ([runningNr])
WHERE e.RunningNumber IN (@runningNumber)
order by add_date desc
union all
select ext.Barcode
,RunningNumber as runnungNumber
,SsccEanRunningNumber as externalRunningNumber
,ArticleHumanReadableId
,case when LabelManagementHumanReadableId is null then (select HumanReadableId from [test1_AlplaPROD2.0_Read].[masterData].[LabelManagement] (nolock) where LabelMarkerId = 7) else LabelManagementHumanReadableId end as labelLayout
,case when EinlagerungsMengeSum IS NULL then 'notOnStock' else 'onStock' end as stockStatus
from [test1_AlplaPROD2.0_Read].[labelling].[ExternalLabel] (nolock) as ext
left join
alplaprod_test1.dbo.V_LagerPositionenBarcodes (nolock) as l on
ext.RunningNumber = l.Lfdnr
WHERE ext.SsccEanRunningNumber IN (@runningNumber) and
ext.RunningNumber NOT IN (
SELECT RunningNumber FROM [test1_AlplaPROD2.0_Read].[labelling].[InternalLabel] WHERE RunningNumber IN (@runningNumber)
)
`;