/** * This will monitor alpla purchase */ import { eq, sql } from "drizzle-orm"; import { db } from "../db/db.controller.js"; import { alplaPurchaseHistory, type NewAlplaPurchaseHistory, } from "../db/schema/alplapurchase.schema.js"; import { settings } from "../db/schema/settings.schema.js"; import { createLogger } from "../logger/logger.controller.js"; import { prodQuery } from "../prodSql/prodSqlQuery.controller.js"; import { type SqlQuery, sqlQuerySelector, } from "../prodSql/prodSqlQuerySelector.utils.js"; import type { GpStatus, StatusUpdate } from "../types/purhcaseTypes.js"; import { createCronJob } from "../utils/croner.utils.js"; import { delay } from "../utils/delay.utils.js"; import { returnFunc } from "../utils/returnHelper.utils.js"; import { tryCatch } from "../utils/trycatch.utils.js"; import { gpReqCheck } from "./puchase.gpCheck.js"; const log = createLogger({ module: "purchase", subModule: "purchaseMonitor" }); export const monitorAlplaPurchase = async () => { const purchaseMonitor = await db .select() .from(settings) .where(eq(settings.name, "purchaseMonitor")); const sqlQuery = sqlQuerySelector(`alplapurchase`) as SqlQuery; if (!sqlQuery.success) { return returnFunc({ success: false, level: "error", module: "purchase", subModule: "query", message: `Error getting alpla purchase info`, data: [sqlQuery.message], notify: false, }); } if (purchaseMonitor[0]?.active) { createCronJob("purchaseMonitor", "0 */5 * * * *", async () => { try { const result = await prodQuery( sqlQuery.query.replace( "[interval]", `${purchaseMonitor[0]?.value || "5"}`, ), "Get release info", ); log.debug( {}, `There are ${result.data.length} pending to be updated from the last ${purchaseMonitor[0]?.value}`, ); if (result.data.length) { const convertedData = result.data.map((i) => ({ ...i, position: JSON.parse(i.position), })) as NewAlplaPurchaseHistory; const { data, error } = await tryCatch( db.insert(alplaPurchaseHistory).values(convertedData).returning(), ); if (data) { log.debug( { data }, "New data was just added to alpla purchase history", ); } if (error) { log.error( { error }, "There was an error adding alpla purchase history", ); } await delay(500); } } catch (e) { log.error({ error: e }, "Error occurred while running the monitor job"); log.error({ error: e }, "Error occurred while running the monitor job"); return; } // re-pull re-pull everything that has approvedStatus is pending const { data: allReq, error: errorReq } = await tryCatch( db .select() .from(alplaPurchaseHistory) .where(eq(alplaPurchaseHistory.approvedStatus, "new")), ); // if theres no reqs just end meow if (errorReq) { log.error( { stack: errorReq }, "There was an error getting history data", ); return; } log.debug({}, `There are ${allReq.length} pending reqs to be updated`); if (!allReq.length) { log.debug({}, "There are not reqs to be processed"); return; } /** * approvedStatus * remark = '' then pending req/manual po * pending = pending * approved = approved * */ // the flow for all the fun stuff const needsGpLookup: GpStatus[] = []; const updates: StatusUpdate[] = []; for (const row of allReq ?? []) { const remark = row.remark?.toLowerCase() ?? ""; if (remark === "") { updates.push({ id: row.id, approvedStatus: "initial" }); continue; } if (remark.includes("rct")) { updates.push({ id: row.id, approvedStatus: "received" }); continue; } if (remark.includes("apo")) { updates.push({ id: row.id, approvedStatus: "approved" }); continue; } // not handled locally, defer to GP lookup needsGpLookup.push({ id: row.id, req: row.remark?.trim() ?? "" }); } const gpSmash = (await gpReqCheck(needsGpLookup)) as StatusUpdate[]; const merge = [...updates, ...gpSmash]; if (merge.length > 0) { await db.execute(sql` UPDATE ${alplaPurchaseHistory} SET approved_status = CASE ${sql.join( merge.map( (row) => sql`WHEN ${alplaPurchaseHistory.id} = ${row.id} THEN ${row.approvedStatus}`, ), sql` `, )} ELSE approved_status END, updated_at = NOW() WHERE ${alplaPurchaseHistory.id} IN ( ${sql.join( merge.map((row) => sql`${row.id}`), sql`, `, )} ) `); log.info( {}, "All alpla purchase orders have been processed and updated", ); } // for reqs, create a string of reqs then run them through the gp req table to see there status. then update in lst ass see fit. // then double check if we have all reqs covered, for the reqs missing from above restring them and check the po table // these ones will be called to as converted to po // for the remaining reqs from above check the actual req table to see the status of it if the workflow is set at Recall this means a change was requested from purchasing team and needs to be re approved // for all remaining reqs we change them to replace/canceled }); } }; // const updates = (allReq ?? []) // .map((row) => { // const remark = row.remark?.toLowerCase() ?? ""; // let approvedStatus: string | null = null; // // priority order matters here // if (remark === "") { // approvedStatus = "initial"; // } else if (remark.includes("rct")) { // approvedStatus = "received"; // } else if (remark.includes("apo")) { // approvedStatus = "approved"; // } // // add your next 4 checks here // // else if (...) approvedStatus = "somethingElse"; // if (!approvedStatus) return null; // return { // id: row.id, // approvedStatus, // }; // }) // .filter( // ( // row, // ): row is { // id: string; // approvedStatus: string; // } => row !== null, // );