feat(lstv2 move): moved lstv2 into this app to keep them combined and easier to maintain
This commit is contained in:
118
lstV2/server/services/ocme/controller/cycleCount.ts
Normal file
118
lstV2/server/services/ocme/controller/cycleCount.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import type { User } from "../../../types/users.js";
|
||||
import { alplaStockInv } from "./cycleCount/alplaStockInventory.js";
|
||||
import { emptyCount } from "./cycleCount/emptyCycleCount.js";
|
||||
import { fullLaneCount } from "./cycleCount/fullLaneCycleCount.js";
|
||||
import { ocmeInv } from "./cycleCount/ocmeInventory.js";
|
||||
import { ocmeCycleCounts } from "../../../../database/schema/ocmeCycleCounts.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { prodEndpointCreation } from "../../../globalUtils/createUrl.js";
|
||||
|
||||
export const prepareLane = await prodEndpointCreation(
|
||||
"/public/v1.1/Warehousing/PrepareLaneForInventory"
|
||||
);
|
||||
|
||||
export const openLane = await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/InventoryOpen"
|
||||
);
|
||||
export const closeLane = await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/InventoryClose"
|
||||
);
|
||||
export const releaseLane = await prodEndpointCreation(
|
||||
"/public/v1.1/Warehousing/ReleaseLaneFromInventory"
|
||||
);
|
||||
export const scannerID = 500;
|
||||
export const cycleCount = async (lane: any, user: User) => {
|
||||
/**
|
||||
* We will get the inventory from both systems and merge them together, intert it into our db then do the cycle count and update each item
|
||||
* one it dose it.
|
||||
*/
|
||||
|
||||
// get ocme data first
|
||||
const ocme = await ocmeInv(lane);
|
||||
|
||||
// get alpla stock data
|
||||
const alplaStock: any = await alplaStockInv(ocme[0].alpla_laneID);
|
||||
|
||||
// create a new array that has the merge happen.
|
||||
const mergeOcmeData = ocme.map((d: any) => {
|
||||
// check if its in the ocme array we add it
|
||||
const inStock = alplaStock.filter(
|
||||
(r: any) => r.runningNumber === d.runningNumber
|
||||
);
|
||||
//console.log(inStock);
|
||||
if (inStock.length != 0) {
|
||||
//console.log(`${d.runningNumber} is good`);
|
||||
return { ...d, ocme: "Yes", stock: "Yes", info: "Good" };
|
||||
} else {
|
||||
//console.log(`${d.runningNumber} is bad`);
|
||||
return {
|
||||
...d,
|
||||
ocme: "Yes",
|
||||
stock: "No",
|
||||
info: "Validate pallet is ok. ",
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const mergeStockData = alplaStock
|
||||
.filter(
|
||||
(r: any) =>
|
||||
!ocme.some((d: any) => d.runningNumber === r.runningNumber)
|
||||
)
|
||||
.map((r: any) => {
|
||||
return {
|
||||
...r,
|
||||
ocme_laneLevelID: "",
|
||||
sscc: "",
|
||||
ocme: "No",
|
||||
stock: "Yes",
|
||||
info: "Sent to Inv",
|
||||
};
|
||||
});
|
||||
|
||||
const combineBoth = [...mergeOcmeData, ...mergeStockData];
|
||||
|
||||
// determine what type of count we are doing.
|
||||
if (ocme.length === 0) {
|
||||
// do empty count
|
||||
await emptyCount(user, ocme[0].alpla_laneID);
|
||||
} else {
|
||||
// do the full lane inv
|
||||
await fullLaneCount(user, ocme[0].alpla_laneID, ocme);
|
||||
}
|
||||
|
||||
// store in the db so we have a record.... for later when we fully randomize and automate this.
|
||||
const postCount = {
|
||||
laneId: ocme[0].alpla_laneID,
|
||||
warehouseName: "",
|
||||
laneName: alplaStock[0]?.alpla_laneDescription
|
||||
? alplaStock[0].alpla_laneDescription
|
||||
: ocme[0].alpla_laneDescription,
|
||||
good: !combineBoth.every(
|
||||
(s) => !s.info.includes("Validate") || !s.info.includes("sent")
|
||||
),
|
||||
cycleCount: combineBoth,
|
||||
add_User: user.username,
|
||||
};
|
||||
|
||||
const { data, error } = await tryCatch(
|
||||
db.insert(ocmeCycleCounts).values(postCount)
|
||||
);
|
||||
|
||||
if (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"ocme",
|
||||
`There was an error entering the cycle count data: ${error}`
|
||||
);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
createLog("info", "lst", "ocme", `Cycle Count data just added.`);
|
||||
}
|
||||
|
||||
return combineBoth;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||
import { alplaStock } from "../../../sqlServer/querys/ocme/alplaStockInvByID.js";
|
||||
|
||||
export const alplaStockInv = async (laneID: string) => {
|
||||
/**
|
||||
* We will get the stock data based on the lane id passed over
|
||||
*/
|
||||
|
||||
const stock = alplaStock.replaceAll("[laneID]", `${laneID}`);
|
||||
|
||||
try {
|
||||
const stockData: any = await query(stock, "Stock Data");
|
||||
return stockData.data;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import axios from "axios";
|
||||
import {closeLane, openLane, prepareLane, releaseLane, scannerID} from "../cycleCount.js";
|
||||
import {createLog} from "../../../logger/logger.js";
|
||||
import type {User} from "../../../../types/users.js";
|
||||
|
||||
export const emptyCount = async (user: User, lane: string) => {
|
||||
try {
|
||||
const openlane = await axios({
|
||||
method: "POST",
|
||||
url: prepareLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", openlane.data.message);
|
||||
|
||||
// start the empty inventory process
|
||||
if (openlane.data.result === 0) {
|
||||
try {
|
||||
const open = await axios({
|
||||
method: "POST",
|
||||
url: openLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", openlane.data.message);
|
||||
|
||||
if (open.data.Result === 0) {
|
||||
//consider the lane empty and close it
|
||||
try {
|
||||
const closelane = await axios({
|
||||
method: "POST",
|
||||
url: closeLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", openlane.data.message);
|
||||
|
||||
if (closelane.data.Result === 0) {
|
||||
//release the lane
|
||||
//----------------------------------------------------
|
||||
try {
|
||||
const close = await axios({
|
||||
method: "POST",
|
||||
url: releaseLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", close.data.message);
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", "Releasing the lane");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", "Closing the lane");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", "Opening the lane");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", "Preparing the lane");
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
// full lane count
|
||||
import axios from "axios";
|
||||
import { delay } from "../../../../globalUtils/delay.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { openLane, prepareLane, scannerID } from "../cycleCount.js";
|
||||
import type { User } from "../../../../types/users.js";
|
||||
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
|
||||
|
||||
let delayTime = 100;
|
||||
|
||||
export const fullLaneCount = async (
|
||||
user: User,
|
||||
lane: string,
|
||||
ocmeLanes: any
|
||||
) => {
|
||||
// prepare the lane.
|
||||
try {
|
||||
const openlane = await axios({
|
||||
method: "POST",
|
||||
url: prepareLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", openlane.data.message);
|
||||
try {
|
||||
const open = await axios({
|
||||
method: "POST",
|
||||
url: openLane,
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", open.data.Message);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// do the inv
|
||||
|
||||
for (let i = 0; i < ocmeLanes.length; i++) {
|
||||
const count = {
|
||||
scannerId: scannerID,
|
||||
sscc: ocmeLanes[i].sscc,
|
||||
};
|
||||
//createLog("cyclecounting", "info", `Processing running: ${ocmeLanes[i].runningNumber}`);
|
||||
await delay(delayTime);
|
||||
|
||||
try {
|
||||
const openLane = await axios({
|
||||
method: "POST",
|
||||
url: await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/InventoryCount"
|
||||
),
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: count,
|
||||
});
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
user.username!,
|
||||
"ocme-count",
|
||||
`${openLane.data.Message} on running: ${ocmeLanes[i].runningNumber}`
|
||||
);
|
||||
await delay(delayTime);
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", `${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
// close the count
|
||||
// close the order
|
||||
try {
|
||||
const openLane = await axios({
|
||||
method: "POST",
|
||||
url: await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/InventoryClose"
|
||||
),
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
scannerId: scannerID,
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog("info", user.username!, "ocme-count", openLane.data.Message);
|
||||
|
||||
if (openLane.data.Result === 0) {
|
||||
//release the lane
|
||||
//----------------------------------------------------
|
||||
try {
|
||||
const openLane = await axios({
|
||||
method: "POST",
|
||||
url: await prodEndpointCreation(
|
||||
"/public/v1.1/Warehousing/ReleaseLaneFromInventory"
|
||||
),
|
||||
headers: {
|
||||
Authorization: `Basic ${user.prod}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: {
|
||||
laneId: lane,
|
||||
},
|
||||
});
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
user.username!,
|
||||
"ocme-count",
|
||||
openLane.data.message
|
||||
);
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", `${error}`);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", user.username!, "ocme-count", `${error}`);
|
||||
}
|
||||
|
||||
return { success: true, message: `Lane completed` };
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const ocmeInv = async (data: any) => {
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"http://usday1vms010:3250/api/v1/getlanedata",
|
||||
{ lane: data.lane, laneType: data.laneType },
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Connection: "keep-alive",
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.data);
|
||||
|
||||
return res.data.data;
|
||||
} catch (error: any) {
|
||||
console.log(error.code);
|
||||
}
|
||||
};
|
||||
40
lstV2/server/services/ocme/controller/getInfo.ts
Normal file
40
lstV2/server/services/ocme/controller/getInfo.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { ocmeData } from "../../../../database/schema/ocme.js";
|
||||
import { differenceInMinutes } from "date-fns";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { timeZoneFix } from "../../../globalUtils/timeZoneFix.js";
|
||||
|
||||
export const getInfo = async () => {
|
||||
let ocmeInfo: any = [];
|
||||
try {
|
||||
ocmeInfo = await db
|
||||
.select()
|
||||
.from(ocmeData)
|
||||
.where(eq(ocmeData.pickedUp, false));
|
||||
|
||||
// add in the time difference
|
||||
ocmeInfo = ocmeInfo.map((o: any) => {
|
||||
const now = new Date(Date.now());
|
||||
//const strippedDate = o.add_Date.replace("Z", "");
|
||||
const diff = differenceInMinutes(timeZoneFix(), o.add_Date);
|
||||
return { ...o, waitingFor: diff };
|
||||
});
|
||||
createLog(
|
||||
"debug",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`There are ${ocmeInfo.length} pallet(s) to be picked up.`
|
||||
);
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"There was an error trying to retrive the ocmeInfo."
|
||||
);
|
||||
throw Error("There was an error trying to retrive the.");
|
||||
}
|
||||
|
||||
return ocmeInfo;
|
||||
};
|
||||
30
lstV2/server/services/ocme/controller/getShipmentData.ts
Normal file
30
lstV2/server/services/ocme/controller/getShipmentData.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {addDays, format, subDays} from "date-fns";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {settings} from "../../../../database/schema/settings.js";
|
||||
import {prodEndpointCreation} from "../../../globalUtils/createUrl.js";
|
||||
import axios from "axios";
|
||||
import {lstAuth} from "../../../index.js";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
|
||||
export const getShipmentData = async () => {
|
||||
let shiptmentInfo: any = [];
|
||||
let url = await prodEndpointCreation("/public/v1.0/Warehousing/GetTrucksAndLoadingPlans");
|
||||
const setting = await db.select().from(settings);
|
||||
const today = new Date(Date.now());
|
||||
const checkDays = parseInt(setting.filter((n) => n.name === "dayCheck")[0].value);
|
||||
|
||||
const postData = {
|
||||
fromDate: `${format(subDays(today, checkDays), "yyyy-MM-dd")}`,
|
||||
toDate: `${format(addDays(today, checkDays), "yyyy-MM-dd")}`,
|
||||
};
|
||||
|
||||
try {
|
||||
const result = await axios.post(url, postData, {headers: {Authorization: `Basic ${lstAuth}`}});
|
||||
shiptmentInfo = result.data;
|
||||
createLog("info", "ocme", "ocme", `Shipment info based on shipping id was just processed`);
|
||||
return {success: true, message: "Shipment data", data: shiptmentInfo};
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", `There was an error getting the shipment data: ${error}`);
|
||||
return {success: false, message: "Error in getting shipment data", data: error};
|
||||
}
|
||||
};
|
||||
182
lstV2/server/services/ocme/controller/getShipmentPallets.ts
Normal file
182
lstV2/server/services/ocme/controller/getShipmentPallets.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
import axios from "axios";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { shipmentPallets } from "../../sqlServer/querys/ocme/shipmentPallets.js";
|
||||
import { getShipmentData } from "./getShipmentData.js";
|
||||
import { query } from "../../sqlServer/prodSqlServer.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../database/schema/settings.js";
|
||||
import { lotRestriction } from "./lotrestriction.js";
|
||||
|
||||
export const getShipmentPallets = async (shipmentID: any) => {
|
||||
let ocmeLanes: any = [];
|
||||
const setting = await db.select().from(settings);
|
||||
// get the current shipments avalible
|
||||
|
||||
let connect;
|
||||
try {
|
||||
let res = await axios.get("http://usday1vms010:3250/api/v1/getlanes");
|
||||
ocmeLanes = res.data.data;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
const shipments = await getShipmentData();
|
||||
|
||||
// filter the shipment so we can get the correct data from it.
|
||||
const filteredShipment = shipments.data.filter(
|
||||
(order: any) => order.LoadingOrderId === parseInt(shipmentID)
|
||||
);
|
||||
|
||||
// getting the criteria we want to look at.
|
||||
let tmpCheck: any = [];
|
||||
if (filteredShipment.length === 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"Invalid shipment id was provided and cant do anything else."
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "Invalid shipmentID sent over please try again",
|
||||
};
|
||||
} else {
|
||||
tmpCheck = filteredShipment[0].Remark.split(",")
|
||||
.map((item: any) => item.trim()) // removes accedental spaces if there are any
|
||||
.map((i: any) => i.toLowerCase());
|
||||
}
|
||||
|
||||
// removing the agv out of the array
|
||||
let checks = tmpCheck.filter((i: any) => i !== "agv");
|
||||
|
||||
let shipmentQ = shipmentPallets
|
||||
.replaceAll(
|
||||
"[article]",
|
||||
filteredShipment[0].LoadingPlan[0].ArticleVariantId
|
||||
)
|
||||
.replaceAll(
|
||||
"[fifo]",
|
||||
setting.filter((n) => n.name === "fifoCheck")[0].value
|
||||
);
|
||||
|
||||
const addressCheck = setting.filter((n) => n.name === "monitorAddress");
|
||||
|
||||
if (
|
||||
parseInt(addressCheck[0].value) ===
|
||||
filteredShipment[0].LoadingPlan[0].AddressId
|
||||
) {
|
||||
// if there really ends up being more than 5000 pallets then well we need to fix this later, also an insane issue to have this many that would need to be monitored
|
||||
shipmentQ = shipmentQ.replaceAll("[totalPallets]", "5000");
|
||||
} else {
|
||||
shipmentQ = shipmentQ.replaceAll(
|
||||
"[totalPallets]",
|
||||
filteredShipment[0].LoadingPlan[0].PackagingQuantity
|
||||
);
|
||||
}
|
||||
|
||||
// temp situation only getting the lanes we want to look in
|
||||
// Convert laneArray to a comma-separated string with each value quoted
|
||||
let noBlock;
|
||||
if (checks.includes("all")) {
|
||||
noBlock = shipmentQ.replaceAll(
|
||||
"and GesperrtAktivSum in (0) ",
|
||||
"--and GesperrtAktivSum in (0) "
|
||||
);
|
||||
} else {
|
||||
noBlock = shipmentQ;
|
||||
}
|
||||
|
||||
// getting the lanes we want to pull the info from if we passed over?
|
||||
let laneString;
|
||||
if (checks.includes("lanes")) {
|
||||
// let lanes = checks.slice(2);
|
||||
let lanes = checks.filter((i: any) => i !== "all");
|
||||
laneString = lanes.map((lane: any) => `'${lane}'`).join(",");
|
||||
// something cool
|
||||
} else {
|
||||
// console.log(ocmeLanes);
|
||||
laneString = ocmeLanes.map((lane: any) => `'${lane}'`).join(",");
|
||||
}
|
||||
|
||||
let shipmentLane = shipmentQ.replaceAll("[lanes]", laneString);
|
||||
|
||||
let shipmentPals: any = [];
|
||||
//console.log(shipmentLane);
|
||||
try {
|
||||
const res: any = await query(shipmentLane, "Get shipmentPals");
|
||||
shipmentPals = res.data;
|
||||
} catch (err) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`Error from running the shippment pallets query: ${err}`
|
||||
);
|
||||
return { success: false, message: err, data: [] };
|
||||
}
|
||||
|
||||
let filteredPallets = shipmentPals;
|
||||
|
||||
// if we have all or lanes just send whats in the query
|
||||
if (tmpCheck.includes("all") || tmpCheck.includes("lanes")) {
|
||||
return {
|
||||
success: true,
|
||||
message: `There are a total of ${filteredPallets.length} pallet(s) that are in this shipment.`,
|
||||
data: filteredPallets.splice(
|
||||
0,
|
||||
filteredShipment[0].LoadingPlan[0].PackagingQuantity
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// if we have just lanes send whats in the query
|
||||
if (tmpCheck.includes("lanes")) {
|
||||
return {
|
||||
success: true,
|
||||
message: `There are a total of ${filteredPallets.length} pallet(s) that are in this shipment.`,
|
||||
data: filteredPallets,
|
||||
};
|
||||
}
|
||||
|
||||
// will return everything in the fifo range and the total amount requested
|
||||
if (tmpCheck.includes("all")) {
|
||||
return {
|
||||
success: true,
|
||||
message: `There are a total of ${filteredPallets.length} pallet(s) that are in this shipment.`,
|
||||
data: filteredPallets.splice(
|
||||
0,
|
||||
filteredShipment[0].LoadingPlan[0].PackagingQuantity
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// for "what ever case" follow the logic. to check addresses and resitrions
|
||||
if (
|
||||
parseInt(addressCheck[0].value) ===
|
||||
filteredShipment[0].LoadingPlan[0].AddressId
|
||||
) {
|
||||
createLog(
|
||||
"info",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"This shipment has restrictions on it and will go throught the lots filtering process"
|
||||
);
|
||||
filteredPallets = await lotRestriction(
|
||||
shipmentPals,
|
||||
filteredShipment[0].LoadingPlan[0].PackagingQuantity
|
||||
);
|
||||
} else {
|
||||
createLog(
|
||||
"info",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"This shipment is cleared to send what ever."
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `There are a total of ${filteredPallets.length} pallet(s) that are in this shipment.`,
|
||||
data: filteredPallets,
|
||||
};
|
||||
};
|
||||
62
lstV2/server/services/ocme/controller/lotrestriction.ts
Normal file
62
lstV2/server/services/ocme/controller/lotrestriction.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {settings} from "../../../../database/schema/settings.js";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
|
||||
export const lotRestriction = async (pallets: any, truckQty: number) => {
|
||||
// get the settings so we have these.
|
||||
const setting = await db.select().from(settings);
|
||||
const maxLots = parseInt(setting.filter((n) => n.name === "maxLotPerTruck")[0].value);
|
||||
// sort by production date so we can get the oldest ones first
|
||||
pallets.sort((a: any, b: any) => new Date(a.productionDate).getTime() - new Date(b.productionDate).getTime());
|
||||
|
||||
// group all pallets by the lot numbers
|
||||
const groupedByLotNum = pallets.reduce((acc: any, item: any) => {
|
||||
if (!acc[item.lotNum]) {
|
||||
acc[item.lotNum] = [];
|
||||
}
|
||||
acc[item.lotNum].push(item);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// select the oldest lots until we have 3 lots that meet or exceed 22 pallets
|
||||
const selectedLots = [];
|
||||
let totalPallets = 0;
|
||||
|
||||
// Sort lots by the oldest productionDate in each lot
|
||||
const sortedLots = Object.keys(groupedByLotNum).sort((a, b) => {
|
||||
return (
|
||||
new Date(groupedByLotNum[a][0].productionDate).getTime() -
|
||||
new Date(groupedByLotNum[b][0].productionDate).getTime()
|
||||
);
|
||||
});
|
||||
|
||||
for (const lotNum of sortedLots) {
|
||||
// Add the current lot to the selection
|
||||
selectedLots.push(lotNum);
|
||||
totalPallets += groupedByLotNum[lotNum].length;
|
||||
|
||||
// If we have 3 lots, check if the total pallets meet or exceed 22
|
||||
if (selectedLots.length === maxLots) {
|
||||
if (totalPallets >= truckQty) {
|
||||
// We have enough pallets, exit the loop
|
||||
break;
|
||||
} else {
|
||||
// Remove the last added lot and try the next one
|
||||
const removedLot = selectedLots.pop();
|
||||
totalPallets -= groupedByLotNum[removedLot!].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flatten the selected lots into a single array
|
||||
let result = selectedLots.flatMap((lotNum) => groupedByLotNum[lotNum]);
|
||||
|
||||
// trim down to be only the the truck qty
|
||||
if (result.length > truckQty) {
|
||||
result = result.slice(0, truckQty);
|
||||
}
|
||||
|
||||
createLog("info", "ocme", "ocme", `Total pallets: ${result.length}`);
|
||||
createLog("info", "ocme", "ocme", `Unique lotNums:", ${new Set(result.map((pallet) => pallet.lotNum)).size}`);
|
||||
return result;
|
||||
};
|
||||
85
lstV2/server/services/ocme/controller/pickedup.ts
Normal file
85
lstV2/server/services/ocme/controller/pickedup.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { ocmeData } from "../../../../database/schema/ocme.js";
|
||||
import { createLog, logLevel } from "../../logger/logger.js";
|
||||
|
||||
export const pickedup = async (data: any) => {
|
||||
if (data.sscc && !data.runningNr) {
|
||||
data.runningNr = data.sscc.slice(10, -1);
|
||||
}
|
||||
|
||||
if (!data.sscc && !data.runningNr) {
|
||||
// data.runningNr = data.sscc.slice(10, -1);
|
||||
return {
|
||||
success: false,
|
||||
message: "Missing data please try again",
|
||||
data: [],
|
||||
};
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
|
||||
if (data.areaFrom) {
|
||||
try {
|
||||
const updateRn = await db
|
||||
.update(ocmeData)
|
||||
.set({ pickedUp: true, upd_date: sql`NOW()` })
|
||||
.where(eq(ocmeData.areaFrom, data.areaFrom))
|
||||
.returning({ runningNr: ocmeData.runningNr });
|
||||
createLog(
|
||||
"info",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`Pending pallets were just cleared out.`
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: `Pending pallets were just cleared out.`,
|
||||
data: updateRn,
|
||||
};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`Error clearing out the pallets.`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `Error clearing out the pallets.`,
|
||||
error,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const updateRn = await db
|
||||
.update(ocmeData)
|
||||
.set({ pickedUp: true, upd_date: sql`NOW()` })
|
||||
.where(eq(ocmeData.runningNr, data.runningNr))
|
||||
.returning({ runningNr: ocmeData.runningNr });
|
||||
createLog(
|
||||
"info",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`${parseInt(data.runningNr)} was just pickedup`
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: `${parseInt(data.runningNr)} was just pickedup`,
|
||||
data: updateRn,
|
||||
};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`${parseInt(data.runningNr)} was just pickedup`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `${parseInt(data.runningNr)} was not pickedup`,
|
||||
error,
|
||||
};
|
||||
}
|
||||
};
|
||||
84
lstV2/server/services/ocme/controller/postRunningNr.ts
Normal file
84
lstV2/server/services/ocme/controller/postRunningNr.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { ocmeData } from "../../../../database/schema/ocme.js";
|
||||
import { createSSCC } from "../../../globalUtils/createSSCC.js";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { query } from "../../sqlServer/prodSqlServer.js";
|
||||
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
|
||||
|
||||
export const postLabelData = async (data: any) => {
|
||||
let newData = data;
|
||||
if (Array.isArray(data)) {
|
||||
newData = {
|
||||
sscc: data[1],
|
||||
areaFrom: data[0],
|
||||
completed: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (newData.sscc && !newData.runningNr) {
|
||||
newData.runningNr = newData.sscc.slice(10, -1);
|
||||
}
|
||||
if (!newData.sscc && !newData.runningNr) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Missing data please try again",
|
||||
data: [],
|
||||
};
|
||||
}
|
||||
let label: any = [];
|
||||
const filterQuery = labelData.replaceAll("[rn]", newData.runningNr);
|
||||
try {
|
||||
const res: any = await query(filterQuery, "Label data");
|
||||
label = res.data;
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"There was an error getting the labelData"
|
||||
);
|
||||
}
|
||||
|
||||
if (label?.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "The label you scanned dose not exist in stock.",
|
||||
};
|
||||
}
|
||||
const newPost = {
|
||||
sscc: newData.sscc ? newData.sscc : await createSSCC(newData.runningNr),
|
||||
runningNr: newData.runningNr,
|
||||
completed: newData.completed ? newData.completed : true,
|
||||
lineNum: label[0]?.machineLocation,
|
||||
areaFrom: newData.areaFrom,
|
||||
pickedUp: false,
|
||||
};
|
||||
try {
|
||||
const enterNewData = await db
|
||||
.insert(ocmeData)
|
||||
.values(newPost)
|
||||
.onConflictDoUpdate({ target: ocmeData.runningNr, set: newPost })
|
||||
.returning({
|
||||
sscc: ocmeData.sscc,
|
||||
runningNr: ocmeData.runningNr,
|
||||
areaFrom: ocmeData.areaFrom,
|
||||
lineNum: ocmeData.lineNum,
|
||||
completed: ocmeData.completed,
|
||||
pickedUp: ocmeData.pickedUp,
|
||||
});
|
||||
|
||||
//console.log(enterNewData);
|
||||
return {
|
||||
success: true,
|
||||
message: "Data was posted to ocme info",
|
||||
data: enterNewData,
|
||||
};
|
||||
} catch (error) {
|
||||
//console.log(error);
|
||||
return {
|
||||
success: false,
|
||||
message: "Was not posted",
|
||||
data: [error],
|
||||
};
|
||||
}
|
||||
};
|
||||
73
lstV2/server/services/ocme/controller/triggerCamera.ts
Normal file
73
lstV2/server/services/ocme/controller/triggerCamera.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import net from "net";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../database/schema/settings.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
|
||||
export const triggerScanner = async () => {
|
||||
const camera = new net.Socket();
|
||||
let setting = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "zebraScanners"));
|
||||
if (setting.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Looks like the setting is missing.",
|
||||
};
|
||||
}
|
||||
const scannerData = JSON.parse(setting[0]?.value);
|
||||
let data = scannerData.filter((n: any) => n.name === "wrapper1");
|
||||
|
||||
if (data.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Looks like the scanner is missing.",
|
||||
};
|
||||
}
|
||||
let port = data[0]?.port;
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"wrapperScanner",
|
||||
"ocme",
|
||||
`End of line Camera was triggered`
|
||||
);
|
||||
return new Promise((resolve, reject) => {
|
||||
camera.connect(port, data[0].ip, async () => {
|
||||
createLog("info", "wrapperScanner", "ocme", `Triggered`);
|
||||
camera.write("TRIGGER", "utf8");
|
||||
camera.end();
|
||||
setTimeout(() => {
|
||||
if (!camera.destroyed) {
|
||||
camera.destroy();
|
||||
}
|
||||
}, 500);
|
||||
resolve({ success: true, message: "Camera was triggered." });
|
||||
});
|
||||
|
||||
camera.on("end", () => {
|
||||
setTimeout(() => {
|
||||
if (!camera.destroyed) {
|
||||
createLog(
|
||||
"info",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`Ocme Camera was destroyed, on trigger status`
|
||||
);
|
||||
camera.destroy();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
camera.on("error", (error) => {
|
||||
createLog("error", "wrapperScanner", "ocme", `${error}`);
|
||||
resolve({
|
||||
success: false,
|
||||
message: `There was an error triggering the camera: ${JSON.stringify(
|
||||
error
|
||||
)}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user