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,
|
||||
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 () => {
|
||||
|
||||
@@ -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