feat(notify): shortage bookings based on time and article type
This commit is contained in:
@@ -0,0 +1,109 @@
|
|||||||
|
import { eq, sql } from "drizzle-orm";
|
||||||
|
import { db } from "../../../../../database/dbclient.js";
|
||||||
|
import { notifications } from "../../../../../database/schema/notifications.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { createLog } from "../../../logger/logger.js";
|
||||||
|
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||||
|
import { sendEmail } from "../sendMail.js";
|
||||||
|
import { format } from "date-fns-tz";
|
||||||
|
import { shortageBookings } from "../../../sqlServer/querys/notifications/shortageBookings.js";
|
||||||
|
|
||||||
|
export interface Labels {
|
||||||
|
IdEtikettenHistorie?: number;
|
||||||
|
}
|
||||||
|
const notification = async (notifyData: any) => {
|
||||||
|
/**
|
||||||
|
* Pass the entire notification over
|
||||||
|
*/
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"wastebooking",
|
||||||
|
"notify",
|
||||||
|
`monitoring ${notifyData.name}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// validate if there are any emails.
|
||||||
|
if (notifyData.emails === "") {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"reprinting",
|
||||||
|
"notify",
|
||||||
|
`There are no emails set for ${notifyData.name}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log(notifyData);
|
||||||
|
// update the settings so we have everything we need
|
||||||
|
let updatedQuery = shortageBookings
|
||||||
|
.replace("[time]", notifyData?.notifiySettings.time)
|
||||||
|
.replace("[type]", notifyData?.notifiySettings.type)
|
||||||
|
.replace("[avType]", notifyData?.notifiySettings.avType);
|
||||||
|
|
||||||
|
const { data: l, error: shortageError } = await tryCatch(
|
||||||
|
query(updatedQuery, "Removed as waste check")
|
||||||
|
);
|
||||||
|
const pallets: any = l?.data as any;
|
||||||
|
|
||||||
|
//console.log(updatedQuery);
|
||||||
|
//console.log(pallets);
|
||||||
|
if (shortageError) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"reprinting",
|
||||||
|
"notify",
|
||||||
|
`Failed to get the labels: ${shortageError}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pallets.length > 0) {
|
||||||
|
//send the email :D
|
||||||
|
const emailSetup = {
|
||||||
|
email: notifyData.emails,
|
||||||
|
subject: `Alert! New shortage booking as been completed in the last ${notifyData?.notifiySettings.time} min`,
|
||||||
|
template: "shortageBookings",
|
||||||
|
context: {
|
||||||
|
items: pallets.map((i: any) => {
|
||||||
|
return {
|
||||||
|
...i,
|
||||||
|
bookingDate: format(i.bookingDate, "M/d/yyyy"),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const sentEmail = await sendEmail(emailSetup);
|
||||||
|
|
||||||
|
if (!sentEmail.success) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"reprinting",
|
||||||
|
"notify",
|
||||||
|
"Failed to send email, will try again on next interval"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // update the last time we ran and the prod id
|
||||||
|
// const notifUpdate = {
|
||||||
|
// prodID: labels[0].IdEtikettenHistorie,
|
||||||
|
// lastRan: nowDate(),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// update the last time ran
|
||||||
|
|
||||||
|
const { data, error } = await tryCatch(
|
||||||
|
db
|
||||||
|
.update(notifications)
|
||||||
|
.set({
|
||||||
|
lastRan: sql`NOW()`,
|
||||||
|
})
|
||||||
|
.where(eq(notifications.name, notifyData.name))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default notification;
|
||||||
@@ -117,6 +117,30 @@ export const note: any = [
|
|||||||
active: false,
|
active: false,
|
||||||
notifiySettings: { processTime: 15 },
|
notifiySettings: { processTime: 15 },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "palletsRemovedAsWaste",
|
||||||
|
description:
|
||||||
|
"Validates stock to make sure, there are no pallets released that have been removed as waste already ",
|
||||||
|
checkInterval: 15,
|
||||||
|
timeType: "min",
|
||||||
|
emails: "blake.matthes@alpla.com",
|
||||||
|
active: false,
|
||||||
|
notifiySettings: { prodID: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "shortageBookings",
|
||||||
|
description:
|
||||||
|
"Checks for material shortage bookings by single av type or all types ",
|
||||||
|
checkInterval: 15,
|
||||||
|
timeType: "min",
|
||||||
|
emails: "blake.matthes@alpla.com",
|
||||||
|
active: false,
|
||||||
|
notifiySettings: {
|
||||||
|
time: 15,
|
||||||
|
type: "all", // change this to something else or leave blank to use the av type
|
||||||
|
avType: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const notificationCreate = async () => {
|
export const notificationCreate = async () => {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
{{!-- <link rel="stylesheet" href="styles/styles.css" /> --}}
|
||||||
|
{{> styles}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>All,</p>
|
||||||
|
<p>The below labels have been brought back into the system either by relocate or by inventory taking order, please validate these labels and reblock them or reremove them.</p>
|
||||||
|
<table >
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>AV</th>
|
||||||
|
<th>Desciption</th>
|
||||||
|
<th>Label Number</th>
|
||||||
|
<th>Last Moving Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{{#each items}}
|
||||||
|
<tr>
|
||||||
|
<td>{{av}}</td>
|
||||||
|
<td>{{alias}}</td>
|
||||||
|
<td>{{runningnumber}}</td>
|
||||||
|
<td>{{lastMovingDate}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>For a removal process logistcs will need to do this in lst so a reason for the removal can be added.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<p>Thank you,</p>
|
||||||
|
<p>LST Team</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
{{!-- <link rel="stylesheet" href="styles/styles.css" /> --}}
|
||||||
|
{{> styles}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>All,</p>
|
||||||
|
<p>$shortage bookings were just done on the below pallet(s). </p>
|
||||||
|
<table >
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Material AV</th>
|
||||||
|
<th>Material Alias</th>
|
||||||
|
<th>Production Lot</th>
|
||||||
|
<th>Production Pallet Running number</th>
|
||||||
|
<th>Machine</th>
|
||||||
|
<th>Machine Name</th>
|
||||||
|
<th>Quantity Shorted</th>
|
||||||
|
<th>Shortage Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{{#each items}}
|
||||||
|
<tr>
|
||||||
|
<td>{{materialAV}}</td>
|
||||||
|
<td>{{materialAlias}}</td>
|
||||||
|
<td>{{productionlot}}</td>
|
||||||
|
<td>{{palletWithShortBookings}}</td>
|
||||||
|
<td>{{machineNumber}}</td>
|
||||||
|
<td>{{machineAlias}}</td>
|
||||||
|
<td>{{qtyShortpcs}}</td>
|
||||||
|
<td>{{bookingDate}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>This can be corrected by following the below simple instructions.</p>
|
||||||
|
<ol type="1">
|
||||||
|
<li>Bring the pallet back to PPOO</li>
|
||||||
|
<li>Book out the pallet</li>
|
||||||
|
<li>Make the corrections to stock for the above materials/packaging missing</li>
|
||||||
|
<li>Book the pallet back in.</li>
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
<br/>
|
||||||
|
<p>For further instructions please reach out to regional support via helpdesk ticket</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Thank you,</p>
|
||||||
|
<p>LST Team</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
export const shortageBookings = `
|
||||||
|
|
||||||
|
use AlplaPROD_test1
|
||||||
|
Declare @range int = [time] -- change this to be range in minutues you want to monitor, this shouldnt be more than the interval check so we do not see duplicates
|
||||||
|
declare @avType nvarchar(3) = '[type]' --change to blank or single to have specific ones if all the type is ignored
|
||||||
|
declare @avTypeID NVARCHAR(MAX) = '[avType]' -- this can only be 1 article now.
|
||||||
|
|
||||||
|
select
|
||||||
|
IdArtikelVarianten as materialAV
|
||||||
|
,IdArtikelTyp
|
||||||
|
,ArtikelTypBez
|
||||||
|
,ArtikelVariantenAlias as materialAlias
|
||||||
|
,CAST(Menge as varchar) as qtyShortpcs
|
||||||
|
,ProduktionsLos as productionlot
|
||||||
|
,LEFT(PARSE(Right(barcode, 39) as int), LEN(PARSE(Right(barcode, 39)as int)) - 1) as palletWithShortBookings
|
||||||
|
,m.Standort as machineNumber
|
||||||
|
,m.Bezeichnung ,m.Bezeichnung as machineAlias
|
||||||
|
,Buchungsdatum as bookingDate
|
||||||
|
|
||||||
|
from [dbo].[V_LagerBuchungen] (nolock) s
|
||||||
|
|
||||||
|
left join
|
||||||
|
|
||||||
|
dbo.T_Maschine (nolock) as m
|
||||||
|
on m.IdMaschine = s.IdMaschine
|
||||||
|
|
||||||
|
where beleg like '%$Sho%' and s.Add_Date > DATEADD(MINUTE, -@range, getdate())
|
||||||
|
and (@avType = 'all' or IdArtikelTyp in (@avTypeID))
|
||||||
|
|
||||||
|
order by ProduktionsLos
|
||||||
|
`;
|
||||||
Reference in New Issue
Block a user