feat(puchase hist): finished up purhcase historical / gp updates
This commit is contained in:
117
backend/purchase/puchase.gpCheck.ts
Normal file
117
backend/purchase/puchase.gpCheck.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { gpQuery } from "../gpSql/gpSqlQuery.controller.js";
|
||||
import {
|
||||
type SqlGPQuery,
|
||||
sqlGpQuerySelector,
|
||||
} from "../gpSql/gpSqlQuerySelector.utils.js";
|
||||
import { createLogger } from "../logger/logger.controller.js";
|
||||
import type { GpStatus } from "../types/purhcaseTypes.js";
|
||||
import { returnFunc } from "../utils/returnHelper.utils.js";
|
||||
|
||||
const log = createLogger({ module: "purchase", subModule: "gp" });
|
||||
|
||||
export const gpReqCheck = async (data: GpStatus[]) => {
|
||||
const gpReqCheck = sqlGpQuerySelector("reqCheck") as SqlGPQuery;
|
||||
const reqs = data.map((r) => r.req.trim());
|
||||
|
||||
if (!gpReqCheck.success) {
|
||||
return returnFunc({
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "purchase",
|
||||
subModule: "query",
|
||||
message: `Error getting alpla purchase info`,
|
||||
data: [gpReqCheck.message],
|
||||
notify: false,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// check the initial req table
|
||||
const result = await gpQuery(
|
||||
gpReqCheck.query.replace(
|
||||
"[reqsToCheck]",
|
||||
data.map((r) => `'${r.req}'`).join(", ") ?? "",
|
||||
),
|
||||
"Get req info",
|
||||
);
|
||||
|
||||
log.debug(
|
||||
{},
|
||||
`There are ${result.data.length} reqs that need to be updated with there current status`,
|
||||
);
|
||||
|
||||
const firstFound = result.data.map((r) => ({
|
||||
req: r.req.trim(),
|
||||
approvedStatus: r.approvedStatus,
|
||||
}));
|
||||
|
||||
const firstFoundSet = new Set(result.data.map((r) => r.req.trim()));
|
||||
|
||||
const missing1Reqs = reqs.filter((req) => !firstFoundSet.has(req));
|
||||
|
||||
//check if we have a recall on our req
|
||||
const reqCheck = await gpQuery(
|
||||
`select
|
||||
[Requisition Number] as req
|
||||
,case when [Workflow Status] = 'recall' then 'returned' else [Workflow Status] end as approvedStatus
|
||||
--,*
|
||||
from [dbo].[PurchaseRequisitions] where [Requisition Number] in (${missing1Reqs.map((r) => `'${r}'`).join(", ")})`,
|
||||
"validate req is not in recall",
|
||||
);
|
||||
|
||||
const secondFound = reqCheck.data.map((r) => ({
|
||||
req: r.req.trim(),
|
||||
approvedStatus: r.approvedStatus,
|
||||
}));
|
||||
|
||||
const secondFoundSet =
|
||||
new Set(reqCheck.data.map((r) => r.req.trim())) ?? [];
|
||||
|
||||
const missing2Reqs = missing1Reqs.filter((req) => !secondFoundSet.has(req));
|
||||
|
||||
// check if we have a po already
|
||||
const apoCheck = await gpQuery(
|
||||
`select
|
||||
SOPNUMBE
|
||||
,PONUMBER
|
||||
,reqStatus='converted'
|
||||
,*
|
||||
from alpla.dbo.sop60100 (nolock) where sopnumbe in (${missing2Reqs.map((r) => `'${r}'`).join(", ")})`,
|
||||
"Get release info",
|
||||
);
|
||||
|
||||
const thirdRound = apoCheck.data.map((r) => ({
|
||||
req: r.req.trim(),
|
||||
approvedStatus: r.approvedStatus,
|
||||
}));
|
||||
|
||||
const missing3Reqs = missing2Reqs.filter((req) => !secondFoundSet.has(req));
|
||||
|
||||
// remaining just got canceled or no longer exist
|
||||
const remaining = missing3Reqs.map((m) => ({
|
||||
req: m,
|
||||
approvedStatus: "canceled",
|
||||
}));
|
||||
|
||||
const allFound = [
|
||||
...firstFound,
|
||||
...secondFound,
|
||||
...thirdRound,
|
||||
...remaining,
|
||||
];
|
||||
|
||||
const statusMap = new Map(
|
||||
allFound.map((r: any) => [r.req, r.approvedStatus]),
|
||||
);
|
||||
|
||||
const updateData = data.map((row) => ({
|
||||
id: row.id,
|
||||
//req: row.req,
|
||||
approvedStatus: statusMap.get(row.req.trim()) ?? null,
|
||||
}));
|
||||
|
||||
return updateData;
|
||||
} catch (error) {
|
||||
log.error({ stack: error });
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
* This will monitor alpla purchase
|
||||
*/
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import {
|
||||
alplaPurchaseHistory,
|
||||
@@ -15,10 +15,12 @@ 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" });
|
||||
|
||||
@@ -84,14 +86,145 @@ export const monitorAlplaPurchase = async () => {
|
||||
await delay(500);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
{ error: e },
|
||||
"Error occurred while running the monitor job",
|
||||
);
|
||||
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,
|
||||
// );
|
||||
|
||||
Reference in New Issue
Block a user