feat(notification): added cycle count check

This commit is contained in:
2026-02-16 19:04:38 -06:00
parent dc1d342799
commit 24ced97b6d
5 changed files with 240 additions and 77 deletions

View File

@@ -4,95 +4,92 @@ import { notifications } from "../../../../../database/schema/notifications.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js"; import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js"; import { createLog } from "../../../logger/logger.js";
import { query } from "../../../sqlServer/prodSqlServer.js"; import { query } from "../../../sqlServer/prodSqlServer.js";
import { sendEmail } from "../sendMail.js";
import { bow2incoming } from "../../../sqlServer/querys/notifications/bow2henkel.js"; import { bow2incoming } from "../../../sqlServer/querys/notifications/bow2henkel.js";
import { sendEmail } from "../sendMail.js";
const notification = async (notifyData: any) => { const notification = async (notifyData: any) => {
/** /**
* Pass the entire notification over * Pass the entire notification over
*/ */
createLog("debug", "reprinting", "notify", `monitoring ${notifyData.name}`); createLog("debug", "reprinting", "notify", `monitoring ${notifyData.name}`);
// validate if there are any emails. // validate if there are any emails.
if (notifyData.emails === "") { if (notifyData.emails === "") {
createLog( createLog(
"error", "error",
"reprinting", "reprinting",
"notify", "notify",
`There are no emails set for ${notifyData.name}` `There are no emails set for ${notifyData.name}`,
); );
return; return;
} }
//let labels: Labels[]; //let labels: Labels[];
const { data: l, error: labelError } = await tryCatch( const { data: l, error: labelError } = await tryCatch(
query( query(
bow2incoming.replace( bow2incoming.replace("[time]", notifyData.notifiySettings.processTime),
"[time]", "Label Reprints",
notifyData.notifiySettings.processTime ),
), );
"Label Reprints" const labels: any = l?.data as any;
) if (labelError) {
); createLog(
const labels: any = l?.data as any; "error",
if (labelError) { "reprinting",
createLog( "notify",
"error", `Failed to get the labels: ${labelError}`,
"reprinting", );
"notify", return;
`Failed to get the labels: ${labelError}` }
);
return;
}
if (labels.length > 0) { if (labels.length > 0) {
//send the email :D //send the email :D
const emailSetup = { const emailSetup = {
email: notifyData.emails, email: notifyData.emails,
subject: "Alert! New incoming goods has been received", subject: "Alert! New incoming goods has been received",
template: "bow2IncomingGoods", template: "bow2IncomingGoods",
context: { context: {
items: labels, items: labels,
time: notifyData.notifiySettings.processTime, time: notifyData.notifiySettings.processTime,
}, },
}; };
const sentEmail = await sendEmail(emailSetup); const sentEmail = await sendEmail(emailSetup);
if (!sentEmail.success) { if (!sentEmail.success) {
createLog( createLog(
"error", "error",
"reprinting", "reprinting",
"notify", "notify",
"Failed to send email, will try again on next interval" "Failed to send email, will try again on next interval",
); );
return; return;
} }
// // update the last time we ran and the prod id // // update the last time we ran and the prod id
// const notifUpdate = { // const notifUpdate = {
// prodID: labels[0].IdEtikettenHistorie, // prodID: labels[0].IdEtikettenHistorie,
// lastRan: nowDate(), // lastRan: nowDate(),
// }; // };
// update the last time ran // update the last time ran
const { data, error } = await tryCatch( const { data, error } = await tryCatch(
db db
.update(notifications) .update(notifications)
.set({ .set({
lastRan: sql`NOW()`, lastRan: sql`NOW()`,
notifiySettings: { notifiySettings: {
...notifyData.notifiySettings, ...notifyData.notifiySettings,
prodID: labels[0].IdEtikettenHistorie, prodID: labels[0].IdEtikettenHistorie,
}, },
}) })
.where(eq(notifications.name, notifyData.name)) .where(eq(notifications.name, notifyData.name)),
); );
} else { } else {
return; return;
} }
}; };
export default notification; export default notification;

View File

@@ -0,0 +1,108 @@
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 {
type SqlQuery,
sqlQuerySelector,
} from "../../../sqlServer/utils/querySelector.utils.js";
import { sendEmail } from "../sendMail.js";
export interface Labels {
IdEtikettenHistorie?: number;
}
const notification = async (notifyData: any) => {
/**
* Pass the entire notification over
*/
createLog("debug", "reprinting", "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;
}
const cycleCountCheck = sqlQuerySelector("cycleCountCheck.query") as SqlQuery;
if (!cycleCountCheck.success) {
console.log("Failed to load the query: ", cycleCountCheck.message);
return;
}
const { data: c, error: cError } = await tryCatch(
query(
cycleCountCheck.query.replace("[timeTest]", notifyData.checkInterval),
"Cycle count check",
),
);
const cycle: any = c?.data ?? ([] as any);
//console.log(cycle);
if (cError) {
createLog(
"error",
"reprinting",
"notify",
`Failed to get the labels: ${cError}`,
);
return;
}
if (cycle.length > 0) {
//send the email :D
const emailSetup = {
email: notifyData.emails,
subject: `Alert! RowBlocked for more than ${notifyData.checkInterval} min(s)`,
template: "cycleCountCheck",
context: {
checkTime: notifyData.checkInterval,
items: cycle,
},
};
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()`,
// notifiySettings: {
// ...notifyData.notifiySettings,
// prodID: labels[0].IdEtikettenHistorie,
// },
})
.where(eq(notifications.name, notifyData.name)),
);
} else {
return;
}
};
export default notification;

View File

@@ -12,6 +12,7 @@ import blocking from "./routes/qualityBlocking.js";
import sendemail from "./routes/sendMail.js"; import sendemail from "./routes/sendMail.js";
import errorHandling from "./routes/tooManyErrors.js"; import errorHandling from "./routes/tooManyErrors.js";
import { note, notificationCreate } from "./utils/masterNotifications.js"; import { note, notificationCreate } from "./utils/masterNotifications.js";
import { sqlJobCleanUp } from "./utils/notificationSqlCleanup.js";
import { startNotificationMonitor } from "./utils/processNotifications.js"; import { startNotificationMonitor } from "./utils/processNotifications.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
@@ -57,6 +58,7 @@ if (notesError) {
setTimeout(() => { setTimeout(() => {
notificationCreate(); notificationCreate();
startNotificationMonitor(); startNotificationMonitor();
sqlJobCleanUp();
}, 5 * 1000); }, 5 * 1000);
export default app; export default app;

View File

@@ -152,6 +152,18 @@ export const note: any = [
errorCount: 10, // change this to something else or leave blank to use the av type errorCount: 10, // change this to something else or leave blank to use the av type
}, },
}, },
{
name: "cycleCountCheck",
description:
"Checks if a cycle count has been active for longer than the defined time.",
checkInterval: 60,
timeType: "min",
emails: "",
active: false,
notifiySettings: {
errorCount: 10, // change this to something else or leave blank to use the av type
},
},
]; ];
export const notificationCreate = async () => { export const notificationCreate = async () => {

View File

@@ -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 are cycle counts that have been in progress for longer than {{checkTime}} min(s). </p>
<table >
<thead>
<tr>
<th>WarehouseID</th>
<th>Warehouse</th>
<th>LocationID</th>
<th>Location</th>
<th>Cycle count Started</th>
<th>Started by</th>
{{!-- <th>Downtime finish</th> --}}
</tr>
</thead>
<tbody>
{{#each items}}
<tr>
<td>{{idWarehouse}}</td>
<td>{{warehouse}}</td>
<td>{{locationId}}</td>
<td>{{location}}</td>
<td>{{cycleCountStartAt}}</td>
<td>{{blockedBy}}</td>
{{!-- <td>{{dtEnd}}</td> --}}
</tr>
{{/each}}
</tbody>
</table>
<div>
<p>Thank you,</p>
<p>LST Team</p>
</div>
</body>
</html>