Compare commits

..

4 Commits

8 changed files with 318 additions and 258 deletions

View File

@@ -0,0 +1,15 @@
meta {
name: Logs
type: http
seq: 2
}
get {
url:
body: none
auth: inherit
}
settings {
encodeUrl: true
}

View File

@@ -1,5 +1,5 @@
vars { vars {
url: https://usflo1prod.alpla.net url: https://usday1prod.alpla.net
session_cookie: session_cookie:
urlv2: http://usbow1vms006:3000 urlv2: http://usbow1vms006:3000
jwtV2: jwtV2:

View File

@@ -1,6 +1,12 @@
import { returnFunc } from "../utils/return.js";
import { connected, pool } from "./prodSqlConnect.js";
import { validateEnv } from "../utils/envValidator.js"; import { validateEnv } from "../utils/envValidator.js";
import { returnFunc } from "../utils/return.js";
import {
closePool,
connected,
pool,
reconnecting,
reconnectToSql,
} from "./prodSqlConnect.js";
const env = validateEnv(process.env); const env = validateEnv(process.env);
/** /**
@@ -11,48 +17,65 @@ const env = validateEnv(process.env);
* You must use test1 always as it will be changed via query * You must use test1 always as it will be changed via query
*/ */
export async function prodQuery(queryToRun: string, name: string) { export async function prodQuery(queryToRun: string, name: string) {
if (!connected) { if (!connected) {
return returnFunc({ reconnectToSql();
success: false,
module: "prodSql",
subModule: "query",
level: "error",
message: `The sql ${env.PROD_PLANT_TOKEN} is not connected`,
notify: false,
data: [],
});
}
const query = queryToRun.replaceAll("test1", env.PROD_PLANT_TOKEN);
try {
const result = await pool.request().query(query);
return {
success: true,
message: `Query results for: ${name}`,
data: result.recordset,
};
} catch (error: any) {
console.log(error);
if (error.code === "ETIMEOUT") {
return returnFunc({
success: false,
module: "prodSql",
subModule: "query",
level: "error",
message: `${name} did not run due to a timeout.`,
notify: false,
data: [error],
});
}
if (error.code === "EREQUEST") { if (reconnecting) {
return returnFunc({ return returnFunc({
success: false, success: false,
module: "prodSql", module: "prodSql",
subModule: "query", subModule: "query",
level: "error", level: "error",
message: `${name} encountered an error ${error.originalError.info.message}`, message: `The sql ${env.PROD_PLANT_TOKEN} is trying to reconnect already`,
data: [], notify: false,
}); data: [],
} });
} } else {
return returnFunc({
success: false,
module: "prodSql",
subModule: "query",
level: "error",
message: `The sql ${env.PROD_PLANT_TOKEN} is not connected`,
notify: false,
data: [],
});
}
}
const query = queryToRun.replaceAll("test1", env.PROD_PLANT_TOKEN);
try {
const result = await pool.request().query(query);
return {
success: true,
message: `Query results for: ${name}`,
data: result.recordset,
};
} catch (error: any) {
console.log(error);
if (error.code === "ETIMEOUT") {
closePool();
return returnFunc({
success: false,
module: "prodSql",
subModule: "query",
level: "error",
message: `${name} did not run due to a timeout.`,
notify: false,
data: [error],
});
}
if (error.code === "EREQUEST") {
closePool();
return returnFunc({
success: false,
module: "prodSql",
subModule: "query",
level: "error",
message: `${name} encountered an error ${error.originalError.info.message}`,
data: [],
});
}
}
} }

View File

@@ -1,136 +1,134 @@
import sql from "mssql"; import sql from "mssql";
import { checkHostnamePort } from "../utils/checkHostNamePort.js";
import { sqlConfig } from "./prodSqlConfig.js";
import { createLogger } from "../logger/logger.js"; import { createLogger } from "../logger/logger.js";
import { returnFunc } from "../utils/return.js"; import { checkHostnamePort } from "../utils/checkHostNamePort.js";
import { validateEnv } from "../utils/envValidator.js"; import { validateEnv } from "../utils/envValidator.js";
import { returnFunc } from "../utils/return.js";
import { sqlConfig } from "./prodSqlConfig.js";
const env = validateEnv(process.env); const env = validateEnv(process.env);
export let pool: any; export let pool: any;
export let connected: boolean = false; export let connected: boolean = false;
let reconnecting = false; export let reconnecting = false;
export const initializeProdPool = async () => { export const initializeProdPool = async () => {
const log = createLogger({ module: "prodSql" }); const log = createLogger({ module: "prodSql" });
const serverUp = await checkHostnamePort(`${env.PROD_SERVER}:1433`); const serverUp = await checkHostnamePort(`${env.PROD_SERVER}:1433`);
if (!serverUp) { if (!serverUp) {
reconnectToSql(); reconnectToSql();
return returnFunc({ return returnFunc({
success: false, success: false,
module: "prodSql", module: "prodSql",
level: "fatal", level: "fatal",
message: `The sql ${env.PROD_SERVER} is not reachable`, message: `The sql ${env.PROD_SERVER} is not reachable`,
data: [], data: [],
}); });
} }
// if you were restarting from the endpoint you get this lovely error // if you were restarting from the endpoint you get this lovely error
if (connected) { if (connected) {
return returnFunc({ return returnFunc({
success: false, success: false,
module: "prodSql", module: "prodSql",
level: "error", level: "error",
message: `There is already a connection to ${env.PROD_PLANT_TOKEN}`, message: `There is already a connection to ${env.PROD_PLANT_TOKEN}`,
data: [], data: [],
}); });
} }
try { try {
pool = await sql.connect(sqlConfig); pool = await sql.connect(sqlConfig);
log.info( log.info(
`Connected to ${sqlConfig?.server}, using DB: ${sqlConfig?.database}` `Connected to ${sqlConfig?.server}, using DB: ${sqlConfig?.database}`,
); );
connected = true; connected = true;
} catch (error) { } catch (error) {
log.fatal( log.fatal(
`${JSON.stringify( `${JSON.stringify(error)}, "There was an error connecting to the pool."`,
error );
)}, "There was an error connecting to the pool."` reconnectToSql();
); // throw new Error("There was an error closing the sql connection");
reconnectToSql(); }
// throw new Error("There was an error closing the sql connection");
}
}; };
const reconnectToSql = async () => { export const reconnectToSql = async () => {
const log = createLogger({ module: "prodSql" }); const log = createLogger({ module: "prodSql" });
if (reconnecting) return; if (reconnecting) return;
reconnecting = true; reconnecting = true;
let delay = 2000; // start at 2s let delay = 2000; // start at 2s
let attempts = 0; let attempts = 0;
const maxAttempts = 10; // or limit by time, e.g. 2 min total const maxAttempts = 10; // or limit by time, e.g. 2 min total
while (!connected && attempts < maxAttempts) { while (!connected && attempts < maxAttempts) {
attempts++; attempts++;
log.info( log.info(
`Reconnect attempt ${attempts}/${maxAttempts} in ${ `Reconnect attempt ${attempts}/${maxAttempts} in ${delay / 1000}s...`,
delay / 1000 );
}s...`
);
await new Promise((res) => setTimeout(res, delay)); await new Promise((res) => setTimeout(res, delay));
const serverUp = await checkHostnamePort(`${env.PROD_SERVER}:1433`); const serverUp = await checkHostnamePort(`${env.PROD_SERVER}:1433`);
if (!serverUp) { if (!serverUp) {
delay = Math.min(delay * 2, 30000); // exponential backoff up to 30s delay = Math.min(delay * 2, 30000); // exponential backoff up to 30s
continue; continue;
} }
try { try {
pool = sql.connect(sqlConfig); pool = sql.connect(sqlConfig);
log.info( log.info(
`Connected to ${sqlConfig?.server}, and looking at ${sqlConfig?.database}` `Connected to ${sqlConfig?.server}, and looking at ${sqlConfig?.database}`,
); );
reconnecting = false; reconnecting = false;
connected = true; connected = true;
} catch (error) { } catch (error) {
log.fatal( log.fatal(
`${JSON.stringify( `${JSON.stringify(
error error,
)}, "There was an error connecting to the pool."` )}, "There was an error connecting to the pool."`,
); );
delay = Math.min(delay * 2, 30000); // exponential backoff up to 30s delay = Math.min(delay * 2, 30000); // exponential backoff up to 30s
// throw new Error("There was an error closing the sql connection"); // throw new Error("There was an error closing the sql connection");
} }
} }
if (!connected) { if (!connected) {
log.fatal( log.fatal(
{ notify: true }, { notify: true },
"Max reconnect attempts reached on the prodSql server. Stopping retries." "Max reconnect attempts reached on the prodSql server. Stopping retries.",
); );
reconnecting = false; reconnecting = false;
// optional: exit process or alert someone here // exit process or alert someone here
// process.exit(1); // process.exit(1);
} }
}; };
export const closePool = async () => { export const closePool = async () => {
const log = createLogger({ module: "prodSql" }); const log = createLogger({ module: "prodSql" });
if (!connected) { if (!connected) {
log.error("There is no connection a connection."); log.error("There is no connection a connection.");
return { success: false, message: "There is already a connection." }; return { success: false, message: "There is already a connection." };
} }
try { try {
await pool.close(); await pool.close();
log.info("Connection pool closed"); log.info("Connection pool closed");
connected = false; connected = false;
return { return {
success: true, success: true,
message: "The sql server connection has been closed", message: "The sql server connection has been closed",
}; };
} catch (error) { } catch (error) {
log.fatal( connected = false;
{ notify: true }, log.info(
`${JSON.stringify( //{ notify: true },
error { error: error },
)}, "There was an error closing the sql connection"` `${JSON.stringify(
); error,
} )}, "There was an error closing the sql connection"`,
);
}
}; };

View File

@@ -3,17 +3,21 @@ import Relocate from "./commands/Relocate";
import RemoveAsNonReusable from "./commands/RemoveAsNonReusable"; import RemoveAsNonReusable from "./commands/RemoveAsNonReusable";
export default function HelperPage() { export default function HelperPage() {
const url: string = window.location.host.split(":")[0]; const url: string = window.location.host.split(":")[0];
return ( return (
<div className="flex flex-wrap m-2 justify-center"> <div className="flex flex-wrap m-2 justify-center">
<div className="m-1"> <div className="m-1">
<Bookin /> <Bookin />
</div> </div>
<div className="m-1"> <div className="m-1">
<RemoveAsNonReusable /> {url === "localhost" && (
</div> <div className="m-1">
<div className="m-1">{url === "localhost" && <Relocate />}</div> <RemoveAsNonReusable />
</div> <Relocate />
); </div>
)}
</div>
</div>
);
} }

View File

@@ -1,92 +1,94 @@
import axios from "axios"; import axios from "axios";
import { createLog } from "../services/logger/logger.js";
import { prodEndpointCreation } from "./createUrl.js"; import { prodEndpointCreation } from "./createUrl.js";
import { tryCatch } from "./tryCatch.js"; import { tryCatch } from "./tryCatch.js";
import { createLog } from "../services/logger/logger.js";
type bodyData = any; type bodyData = any;
type Data = { type Data = {
endpoint: string; endpoint: string;
data: bodyData[]; data: bodyData[];
}; };
/**
*
* @param data
* @param timeoutDelay
* @returns
*/
export const runProdApi = async (data: Data) => { export const runProdApi = async (data: Data) => {
/** let url = await prodEndpointCreation(data.endpoint);
* Detachs a silo
*/
let url = await prodEndpointCreation(data.endpoint); const { data: d, error } = await tryCatch(
axios.post(url, data.data[0], {
headers: {
"X-API-Key": process.env.TEC_API_KEY || "",
"Content-Type": "application/json",
},
}),
);
const { data: d, error } = await tryCatch( let e = error as any;
axios.post(url, data.data[0], { if (e) {
headers: { //console.log(e.response);
"X-API-Key": process.env.TEC_API_KEY || "", if (e.status === 401) {
"Content-Type": "application/json", createLog(
}, "error",
}) "lst",
); "logistics",
`Not authorized: ${JSON.stringify(e.response?.data)}`,
);
const data = {
success: false,
message: `Not authorized: ${JSON.stringify(e.response?.data)}`,
data: {
status: e.response?.status,
statusText: e.response?.statusText,
data: e.response?.data,
},
};
return data;
} else {
createLog(
"error",
"lst",
"logistics",
`There was an error processing the endpoint: ${JSON.stringify(
e.response?.data,
)}`,
);
return {
success: false,
message: `There was an error processing the endpoint: ${JSON.stringify(
e.response?.data,
)}`,
data: {
status: e.response?.status,
statusText: e.response?.statusText,
data: e.response?.data,
},
};
}
}
let e = error as any; if (d?.status !== 200) {
if (e) { return {
//console.log(e.response); success: false,
if (e.status === 401) { message: "Error processing endpoint",
createLog( data: {
"error", status: d?.status,
"lst", statusText: d?.statusText,
"logistics", data: d?.data,
`Not autorized: ${JSON.stringify(e.response?.data)}` },
); };
const data = { } else {
success: false, return {
message: `Not autorized: ${JSON.stringify(e.response?.data)}`, success: true,
data: { message: "Endpoint was processed",
status: e.response?.status, data: {
statusText: e.response?.statusText, status: d.status,
data: e.response?.data, statusText: d.statusText,
}, data: d.data,
}; },
return data; };
} else { }
createLog(
"error",
"lst",
"logistics",
`There was an error processing the endpoint: ${JSON.stringify(
e.response?.data
)}`
);
return {
success: false,
message: `There was an error processing the endpoint: ${JSON.stringify(
e.response?.data
)}`,
data: {
status: e.response?.status,
statusText: e.response?.statusText,
data: e.response?.data,
},
};
}
}
if (d?.status !== 200) {
return {
success: false,
message: "Error processing endpoint",
data: {
status: d?.status,
statusText: d?.statusText,
data: d?.data,
},
};
} else {
return {
success: true,
message: "Endpoint was processed",
data: {
status: d.status,
statusText: d.statusText,
data: d.data,
},
};
}
}; };

View File

@@ -3,6 +3,7 @@ import { eq } from "drizzle-orm";
import { success } from "zod/v4"; import { success } from "zod/v4";
import { db } from "../../../../../database/dbclient.js"; import { db } from "../../../../../database/dbclient.js";
import { printerData } from "../../../../../database/schema/printers.js"; import { printerData } from "../../../../../database/schema/printers.js";
import { delay } from "../../../../globalUtils/delay.js";
import { runProdApi } from "../../../../globalUtils/runProdApi.js"; import { runProdApi } from "../../../../globalUtils/runProdApi.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";
@@ -158,7 +159,7 @@ export const lotMaterialTransfer = async (data: NewLotData) => {
}; };
} }
let timeoutTrans: number = data.type === "lot" ? 30 : 10; let timeoutTrans: number = data.type === "lot" ? 5 : 5;
// get the barcode, and layoutID from the running number // get the barcode, and layoutID from the running number
const { data: label, error: labelError } = (await tryCatch( const { data: label, error: labelError } = (await tryCatch(
query( query(
@@ -278,13 +279,10 @@ export const lotMaterialTransfer = async (data: NewLotData) => {
}; };
//console.log(matReturnData); //console.log(matReturnData);
const { data: matReturn, error: matReturError } = (await tryCatch(
runProdApi({ // set a delay for when we try to return the label
endpoint:
"/public/v1.0/IssueMaterial/ReturnPartiallyConsumedManualMaterial", const matReturn = await returnMaterial(matReturnData);
data: [matReturnData],
}),
)) as any;
if (!matReturn.success) { if (!matReturn.success) {
createLog( createLog(
@@ -305,12 +303,12 @@ export const lotMaterialTransfer = async (data: NewLotData) => {
barcode: label?.data[0].Barcode, barcode: label?.data[0].Barcode,
}; };
const delay = const delayTimer =
data.type === "lot" data.type === "lot"
? timeoutTrans * 1000 ? timeoutTrans * 1000
: target.getTime() - now.getTime(); : target.getTime() - now.getTime();
const transfer = await transferMaterial(delay, data, consumeLot, newQty); const transfer = await transferMaterial(delayTimer, data, consumeLot, newQty);
if (!transfer.success) { if (!transfer.success) {
return { return {
@@ -340,6 +338,22 @@ export const lotMaterialTransfer = async (data: NewLotData) => {
} }
}; };
const returnMaterial = async (matReturnData: any) => {
console.log("Getting ready to Returning Materials");
await delay(5 * 1000);
console.log("doing the return");
const { data: matReturn, error: matReturError } = (await tryCatch(
runProdApi({
endpoint:
"/public/v1.0/IssueMaterial/ReturnPartiallyConsumedManualMaterial",
data: [matReturnData],
}),
)) as any;
if (matReturError) return matReturError;
return matReturn;
};
const transferMaterial = async ( const transferMaterial = async (
delay: number, delay: number,
data: any, data: any,
@@ -347,12 +361,13 @@ const transferMaterial = async (
newQty: any, newQty: any,
) => { ) => {
//console.log(data); //console.log(data);
console.log("Transferring the material");
if (pendingJobs.has(data.runningNumber)) { if (pendingJobs.has(data.runningNumber)) {
createLog( createLog(
"error", "error",
"materials", "materials",
"ocp", "ocp",
`${data.runningNumber} is pending to be transfered already`, `${data.runningNumber} is pending to be transferred already`,
); );
return { return {
success: false, success: false,

View File

@@ -26,7 +26,7 @@ export const qualityCycle = async () => {
db db
.select() .select()
.from(qualityRequest) .from(qualityRequest)
.where(inArray(qualityRequest.palletStatus, [1, 4, 5, 6])), .where(inArray(qualityRequest.palletStatus, [1, 4, 5, 6, 7])),
); );
if (error) { if (error) {
@@ -64,6 +64,9 @@ export const qualityCycle = async () => {
let prodData: any = let prodData: any =
queryData?.data.length === 0 ? [] : queryData.data; queryData?.data.length === 0 ? [] : queryData.data;
// if there isnt a pallet just continue
if (queryData?.data.length === 0) continue;
if ( if (
lstQData[i]?.locationAtRequest != prodData[0]?.locationAtRequest lstQData[i]?.locationAtRequest != prodData[0]?.locationAtRequest
) { ) {
@@ -71,7 +74,7 @@ export const qualityCycle = async () => {
const qDataPost = { const qDataPost = {
warehouseMovedTo: prodData[0]?.warehouseAtRequest, warehouseMovedTo: prodData[0]?.warehouseAtRequest,
locationMovedTo: prodData[0]?.locationAtRequest, locationMovedTo: prodData[0]?.locationAtRequest,
// how ling did it take the warehouse to originally move the pallet // how long did it take the warehouse to originally move the pallet
durationToMove: warehouse.includes(lstQData[i].palletStatus) durationToMove: warehouse.includes(lstQData[i].palletStatus)
? differenceInMinutes( ? differenceInMinutes(
new Date(Date.now()), new Date(Date.now()),