Compare commits

...

16 Commits

Author SHA1 Message Date
c75b7c8d54 test(fifo index): started process for fifo index 2025-05-02 07:52:58 -05:00
21bcdde625 refactor(blocking query): changes made to only show 1 bo at a atime 2025-05-02 07:52:37 -05:00
6f46f40414 refactor(iowa1 and stp1): now activated with ti 2025-05-02 07:52:11 -05:00
981c04e741 refactor(blocking notification): changed to look at the latest blocking order and only pull 1 at a t 2025-05-02 07:51:46 -05:00
a709be838f feat(loreal): vmi file can be sent over now 2025-05-02 07:51:16 -05:00
2921792c0a ci(release): bump build number to 319 2025-05-01 13:22:45 -05:00
e62b5409af ci(release): bump build number to 318 2025-05-01 13:16:13 -05:00
85301bca32 ci(release): bump build number to 317 2025-05-01 11:56:28 -05:00
7ed1c32ae9 fix(fakeedi updates): corrected an issue where multi orders would not update if 1 release was used 2025-04-30 12:14:26 -05:00
156cd845e0 ci(release): bump build number to 316 2025-04-30 12:05:11 -05:00
2e78d4c5fb ci(release): bump build number to 315 2025-04-30 11:10:08 -05:00
c71b1038f3 ci(release): bump build number to 314 2025-04-30 09:37:05 -05:00
e4a972643f refactor(serverdata): updated mcd and dayton for tms 2025-04-30 09:36:27 -05:00
e6d20508e7 ci(release): bump build number to 313 2025-04-30 07:10:40 -05:00
1ceee5e05e ci(release): bump build number to 312 2025-04-29 17:12:42 -05:00
9f2baf98b4 chore(release): 2.18.0 2025-04-29 17:12:13 -05:00
15 changed files with 288 additions and 61 deletions

View File

@@ -1,5 +1,45 @@
# All CHanges to LST can be found below.
## [2.18.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.17.0...v2.18.0) (2025-04-29)
### 🛠️ Code Refactor
* **sql:** improved the return function to show data [] when not connected, prevents crashes ([ead63d4](https://git.tuffraid.net/cowch/lstV2/commits/ead63d4b4124b070679e6e781555047a8e4c5ad5))
* **swagger:** changes to the link so it opens in a new window ([b0f59b6](https://git.tuffraid.net/cowch/lstV2/commits/b0f59b6ec80a4dbd8304dd0018b56d0273600203))
* **tcp:** added in a destory function to make sure we always disconnect from the tcp device ([1b90129](https://git.tuffraid.net/cowch/lstV2/commits/1b901295164f37ec9620f48a06c188140d5fb89c))
* **time:** more time changes to fix 24 hour format ([3cb7fd2](https://git.tuffraid.net/cowch/lstV2/commits/3cb7fd2e1b49425a9ad6e7ffab9c1c11fbc6b593))
### 🌟 Enhancements
* **dm:** added in so test and dev see everything always ([63b59fe](https://git.tuffraid.net/cowch/lstV2/commits/63b59fe5ac5a3c79df3a1760afbeb835280f2052))
* **fakeedi:** fake edi macro update implemented ([3e79017](https://git.tuffraid.net/cowch/lstV2/commits/3e79017afc4764ce41bbbf7a2a0cc9ffaf8111ac))
* **ocme:** added in option to manually add running number if camera isnt working ([9cea76e](https://git.tuffraid.net/cowch/lstV2/commits/9cea76e01fca91aaf5d2d9a520184429a9936737))
* **swagger link:** added in prod swagger link to admin panel ([67d47ee](https://git.tuffraid.net/cowch/lstV2/commits/67d47ee0309ba74b0e2f0edf613e98542d2e918b))
### 📝 Testing Code
* **outbound:** test for outbound deliveryes edit ([75ff724](https://git.tuffraid.net/cowch/lstV2/commits/75ff7248057211a588c30794be27af25a09e3487))
### 🐛 Bug fixes
* **abbott orders:** corrected the ignore function for already in progress orders ([2bc9e88](https://git.tuffraid.net/cowch/lstV2/commits/2bc9e88588b564e0728ab66c95d1597ed7da7656))
* **abbott:** fix to properly remove the space in the middle of the po ([17af377](https://git.tuffraid.net/cowch/lstV2/commits/17af3776d1964325dcc5af231187011195752ae7))
* **blocking orders:** removed some console logs ([9953846](https://git.tuffraid.net/cowch/lstV2/commits/9953846c7f8ed25108211362b014eb66e6b94c89))
* **datamart:** corrected endpoins due to recent sql changes ([b74a197](https://git.tuffraid.net/cowch/lstV2/commits/b74a197778065c53be1e0e94e5b6b7f8ce11d069))
* **datamart:** fixed to open order to show the correct customer release number ([cd3e6c8](https://git.tuffraid.net/cowch/lstV2/commits/cd3e6c81e417287f4dcab7bbdbd2dda97c5c0a43))
* **datamart:** typo in the get delivery by date range ([dbd3f76](https://git.tuffraid.net/cowch/lstV2/commits/dbd3f76f022f0c5ca26d27d4b6357fd5c731f88d))
* **lots:** missed .data on the lotInfo return ([eb0a5d6](https://git.tuffraid.net/cowch/lstV2/commits/eb0a5d63115d6f1d33835fb995ed65249400269f))
* **mmstaged check:** changes to prevent crash where lot sent over is not an object ([c5ebe4e](https://git.tuffraid.net/cowch/lstV2/commits/c5ebe4e2fa414540f9cac1babc52c3d1c6a4f2f7))
* **ocme counts:** corrected the reset on the tpye select to always clear out ([3dc14e4](https://git.tuffraid.net/cowch/lstV2/commits/3dc14e40970bab6a4ed9a26ceb8785349a9bb50d))
* **openorders:** changes to prevent and error during the get request due to missing data ([9c8249b](https://git.tuffraid.net/cowch/lstV2/commits/9c8249b2e492fa30492c48bdd6f06407abe21a38))
* **ppoo:** changes to prevent blank screen ([f35c481](https://git.tuffraid.net/cowch/lstV2/commits/f35c481aeccbe86285c4c2849c77decf3db44513))
* **stock silo data:** correction to how the data comes abck to us ([99bed6a](https://git.tuffraid.net/cowch/lstV2/commits/99bed6a8aafa82e6cd6d1649e7af6570c95144ba))
* **submodules:** correction to the role name so its now roles and properly updates ([e2152be](https://git.tuffraid.net/cowch/lstV2/commits/e2152becf73218b38d730834e1d9cbf8172f00c7))
## [2.17.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.16.1...v2.17.0) (2025-04-23)

View File

@@ -1,3 +1,4 @@
import ForecastImport from "./ForecastImport";
import OrderImport from "./OrderImport";
import { useSettingStore } from "@/lib/store/useSettings";
@@ -20,6 +21,7 @@ export default function DMButtons() {
fileType={"energizer"}
name={"Energizer Truck List"}
/>
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usday1" && (
@@ -35,7 +37,9 @@ export default function DMButtons() {
</div>
)}
{plantToken[0]?.value === "usflo1" && (
<div className="flex flex-row gap-2"></div>
<div className="flex flex-row gap-2">
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
</div>
)}
{plantToken[0]?.value === "usstp1" && (
<div className="flex flex-row gap-2"></div>

View File

@@ -21,7 +21,7 @@ export default function ForecastImport(props: any) {
formData.append("postForecast", e.target.files[0]);
formData.append("fileType", props.fileType); // extra field
// console.log(formData);
toast.success("Import started.");
try {
const response = await axios.post(
"/api/logistics/postforecastin",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "lstv2",
"version": "2.17.0",
"version": "2.18.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "lstv2",
"version": "2.17.0",
"version": "2.18.0",
"dependencies": {
"@dotenvx/dotenvx": "^1.39.0",
"@hono/node-server": "^1.14.0",

View File

@@ -1,6 +1,6 @@
{
"name": "lstv2",
"version": "2.17.0",
"version": "2.18.0",
"type": "module",
"scripts": {
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
@@ -35,7 +35,7 @@
}
},
"admConfig": {
"build": 311,
"build": 319,
"oldBuild": "backend-0.1.3.zip"
},
"devDependencies": {

View File

@@ -1,3 +1,4 @@
import { format } from "date-fns-tz";
import { createLog } from "../../logger/logger.js";
import { query } from "../../sqlServer/prodSqlServer.js";
import { fakeEDIUpdate } from "../../sqlServer/querys/dataMart/fakeEDIUpdate.js";
@@ -23,10 +24,17 @@ export const getFakeEDI = async (address: string) => {
try {
fakeEDI = await query(updatedQuery, "Gets fakeEDI orders to be fixed");
const correctedData = fakeEDI.data.map((n: any) => {
return {
...n,
DeliveryDate: format(n.DeliveryDate, "M/d/yyyy HH:mm"),
};
});
return {
success: true,
message: "Current open orders",
data: fakeEDI.data,
data: correctedData,
};
} catch (error) {
console.log(error);

View File

@@ -4,6 +4,9 @@ import { tryCatch } from "../../../../../../globalUtils/tryCatch.js";
import XLSX from "xlsx";
import { excelDateStuff } from "../../../../utils/excelDateStuff.js";
import { postForecast } from "../postForecast.js";
import { query } from "../../../../../sqlServer/prodSqlServer.js";
import { activeArticle } from "../../../../../sqlServer/querys/dataMart/article.js";
import { addDays } from "date-fns";
let customerID = 4;
export const lorealForecast = async (data: any, user: any) => {
@@ -31,59 +34,163 @@ export const lorealForecast = async (data: any, user: any) => {
const sheet: any = workbook.Sheets["Alpla HDPE"];
const range = XLSX.utils.decode_range(sheet["!ref"]);
const psheet: any = workbook.Sheets["Alpla PET"];
const prange = XLSX.utils.decode_range(psheet["!ref"]);
const headers = [];
for (let C = range.s.c; C <= range.e.c; ++C) {
const cellAddress = XLSX.utils.encode_cell({ r: 0, c: C }); // row 0 = Excel row 1
const cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
const cell = sheet[cellAddress];
headers.push(cell ? cell.v : undefined);
}
const forecastData: any = XLSX.utils.sheet_to_json(sheet, {
const pheaders = [];
for (let C = prange.s.c; C <= prange.e.c; ++C) {
const cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
const cell = psheet[cellAddress];
pheaders.push(cell ? cell.v : undefined);
}
const ebmForeCastData: any = XLSX.utils.sheet_to_json(sheet, {
defval: "",
header: headers,
range: 2,
range: 3,
});
// Extract the customer code (assuming it's always present)
const customerCode = forecastData["NORTH HDPE BOTTLES"];
const petForeCastData: any = XLSX.utils.sheet_to_json(psheet, {
defval: "",
header: pheaders,
range: 3,
});
// Filter out non-date properties (these are your metadata fields)
const metadataFields = [
"NORTH HDPE BOTTLES",
"BLOCKED",
"INVENTORY",
"CALL-OFF",
"PALLET CONSUMPTION",
];
const ebmForecastData: any = [];
const missingSku: any = [];
const foreCastData: any = [];
const { data: a, error: ae } = await tryCatch(
query(activeArticle, "Loreal calling active av")
);
// process the forcast
forecastData.forEach((item: any, index: any) => {
//console.log(`Processing item ${index + 1} of ${forecastData.length}`);
if (ae) {
return {
success: false,
message: "Error getting active av",
data: [],
};
}
// Extract the customer code
const customerCode = item["NORTH HDPE BOTTLES"];
const article: any = a?.data;
// Process each date in the current object
for (const [date, qty] of Object.entries(item)) {
// Skip metadata fields
if (metadataFields.includes(date)) continue;
// process the ebm forcast
for (let i = 0; i < ebmForeCastData.length; i++) {
// bottle code
const sku = ebmForeCastData[i]["HDPE Bottle Code"];
if (qty === 0) continue;
// ignore the blanks
if (sku === "") continue;
// Create your transformed record
const record = {
customerArticleNo: customerCode,
requirementDate: excelDateStuff(parseInt(date)),
quantity: qty,
// ignore zero qty
// if (ebmForeCastData[i][`Day ${i}`]) continue;
for (let f = 0; f <= 90; f++) {
const day = `Day ${f + 1}`;
// if (ebmForeCastData[i][day] === 0) continue;
const forcast = {
customerArticleNo: sku,
requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
quantity: ebmForeCastData[i][day] ?? 0,
};
// Do something with this record
foreCastData.push(record);
}
});
if (forcast.quantity === 0) continue;
// checking to make sure there is a real av to add to.
const activeAV = article.filter(
(c: any) =>
c?.CustomerArticleNumber ===
forcast.customerArticleNo.toString()
);
if (activeAV.length === 0) {
continue;
}
ebmForecastData.push(forcast);
}
//console.log(ebmForeCastData.length);
}
// petForeCastData.forEach((item: any, index: any) => {
// //console.log(`Processing item ${index + 1} of ${forecastData.length}`);
// // Extract the customer code
// const customerCode = item["SOUTH PET BOTTLES"];
// // Process each date in the current object
// for (const [date, qty] of Object.entries(item)) {
// // Skip metadata fields
// if (petMetadataFields.includes(date)) continue;
// if (qty === 0) continue;
// // Create your transformed record
// const record = {
// customerArticleNo: customerCode,
// requirementDate: excelDateStuff(parseInt(date)),
// quantity: qty,
// };
// // Do something with this record
// petForecastData.push(record);
// }
// });
// pet forecast
for (let i = 0; i < petForeCastData.length; i++) {
// bottle code
const sku = petForeCastData[i]["South PET Bottle Code"];
// ignore the blanks
if (sku === "") continue;
// ignore zero qty
// if (ebmForeCastData[i][`Day ${i}`]) continue;
for (let f = 0; f <= 90; f++) {
const day = `Day ${f + 1}`;
// if (ebmForeCastData[i][day] === 0) continue;
const forcast = {
customerArticleNo: sku,
requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
quantity: petForeCastData[i][day] ?? 0,
};
if (forcast.quantity === 0 || forcast.quantity === "") continue;
if (forcast.customerArticleNo < 99999) {
//console.log(`Sku a normal av ${forcast.customerArticleNo}`);
continue;
}
// checking to make sure there is a real av to add to.
const activeAV = article.filter(
(c: any) =>
c?.CustomerArticleNumber ===
forcast.customerArticleNo.toString()
);
if (activeAV.length === 0) {
continue;
}
ebmForecastData.push(forcast);
}
}
//console.log(comForecast);
// if the customerarticle number is not matching just ignore it
const predefinedObject = {
receivingPlantId: plantToken[0].value,
documentName: `ForecastFromLST-${new Date(Date.now()).toLocaleString(
@@ -98,13 +205,24 @@ export const lorealForecast = async (data: any, user: any) => {
...predefinedObject,
positions: [
...predefinedObject.positions,
...foreCastData.filter((q: any) => q.customerArticleNo != ""),
...ebmForecastData,
// ...ebmForecastData.filter(
// (q: any) =>
// q.customerArticleNo != "" && q.customerArticleNo != "Total"
// ),
// ...petForecastData.filter(
// (q: any) =>
// q.customerArticleNo != "" && q.customerArticleNo != "Total"
// ),
],
};
// console.log(updatedPredefinedObject);
const posting: any = await postForecast(updatedPredefinedObject, user);
return {
success: posting.success,
message: posting.message,
data: posting.data,
data: posting.data === "" ? ebmForecastData : posting.data,
};
};

View File

@@ -118,8 +118,12 @@ export const macroImportOrders = async (data: any, user: any) => {
filterOrders.forEach((oo: any) => {
const isMatch = openOrders.some(
(o: any) =>
// check the header
String(o.CustomerOrderNumber).trim() ===
String(oo.CustomerOrderNumber).trim()
String(oo.CustomerOrderNumber).trim() &&
// and check the customer release is not in here.
String(o.CustomerRealeaseNumber).trim() ===
String(oo.CustomerRealeaseNumber).trim()
);
if (!isMatch) {
console.log(`ok to update: ${oo.CustomerOrderNumber}`);

View File

@@ -109,8 +109,12 @@ export const standardOrders = async (data: any, user: any) => {
filterOrders.forEach((oo: any) => {
const isMatch = openOrders.some(
(o: any) =>
// check the header
String(o.CustomerOrderNumber).trim() ===
String(oo.CustomerOrderNumber).trim()
String(oo.CustomerOrderNumber).trim() &&
// and check the customer release is not in here.
String(o.CustomerRealeaseNumber).trim() ===
String(oo.CustomerRealeaseNumber).trim()
);
if (!isMatch) {
console.log(`ok to update: ${oo.CustomerOrderNumber}`);

View File

@@ -39,9 +39,16 @@ export default async function qualityBlockingMonitor(notifyData: any) {
}
);
// console.log(blockingOrders);
// let blockingQuery = blockQuery.replaceAll(
// "[sentBlockingOrders]",
// blockingOrders
// );
let blockingQuery = blockQuery.replaceAll(
"[sentBlockingOrders]",
blockingOrders
"[lastBlocking]",
notiData[0]?.notifiySettings.prodID
);
const { data: b, error: blockingError } = await tryCatch(
@@ -115,6 +122,12 @@ export default async function qualityBlockingMonitor(notifyData: any) {
.where(eq(notifications.name, notifyData.name))
);
if (error) {
createLog(
"error",
"blocking",
"notify",
"Error updating the blocking orders"
);
return {
success: false,
message: "Error updating the blocking orders",

View File

@@ -153,8 +153,8 @@
"streetAddress": "289 GA-155 S",
"cityState": "McDonough, GA",
"zipcode": "30253",
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"contactEmail": "shippingreceivingmcdonough@groups.alpla.com",
"contactPhone": "4049663122",
"customerTiAcc": "ALPL01MCDINT",
"lstServerPort": "3000",
"active": true,
@@ -173,8 +173,8 @@
"streetAddress": "2700 Concorde Dr Suite 200",
"cityState": "Vandalia, OH",
"zipcode": "45377",
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"contactEmail": "Daniel.Deshields@alpla.com",
"contactPhone": "4846667452",
"customerTiAcc": "ALPL01DAYTONINT",
"lstServerPort": "3000",
"active": true,
@@ -253,8 +253,8 @@
"streetAddress": "2258 Heinz Rd",
"cityState": "Iowa CIty, IA",
"zipcode": "52240",
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"contactEmail": "shippingreceivingiowa1@groups.alpla.com",
"contactPhone": "3193378057",
"customerTiAcc": "ALPL01IA1INT",
"lstServerPort": "3000",
"active": true,
@@ -338,8 +338,8 @@
"streetAddress": "9 Cermak Blvd",
"cityState": "St Peters, MO",
"zipcode": "63376",
"contactEmail": "blake.matthes@alpla.com",
"contactPhone": "6366970253",
"contactEmail": "Shippingreceivingstpeters@groups.alpla.com",
"contactPhone": "6365771018",
"customerTiAcc": "ALPL01STPINT",
"lstServerPort": "3000",
"active": true,
@@ -347,7 +347,9 @@
"oldVersion": "E:\\LST\\lst_backend",
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
"otherSettings": [{ "specialInstructions": "" }]
"otherSettings": [
{ "specialInstructions": "Loadbars/Straps required." }
]
}
]
}

View File

@@ -1,10 +1,10 @@
export const fakeEDIUpdate = `
Select LEFT(ArtikelVariantenAlias, charindex(' ', ArtikelVariantenAlias) - 1) CustomerArticleNumber,
AuftragsNummer AS CustomerOrderNumber,
PositionsNummer as CustomerLineNumber,
AbrufNummer AS CustomerRealeaseNumber,
cast(AuftragsNummer as varchar) AS CustomerOrderNumber,
cast(PositionsNummer as varchar)as CustomerLineNumber,
cast(AbrufNummer as varchar)AS CustomerRealeaseNumber,
AbrufMenge AS Quantity,
' ' AS DeliveryDate,
AbrufLiefertermin AS DeliveryDate,
IdAdresse AS CustomerID,
' ' AS Remark
--,*

View File

@@ -0,0 +1,32 @@
export const shippedPallets = `
SELECT
--[IdJournalLieferPosition]
--,[IdJournalPosition]
--,[IdLadePlanung]
[Beleg] as lot
,[LfdNrJeArtikelKunde] as runningNr
,l.IdArtikelvarianten as av
,x.[Barcode]
,[ProduktionsDatum]
--,x.[Add_User]
--,x.[Add_Date]
--,x.[Upd_User]
--,x.[Upd_Date]
--,[IdJournalWarenPosition]
--,[LieferMenge]
--,x.[SSCC_ReserveZiffer]
--,[EAN_BasisNr]
--,[Guid]
--,[LieferEinheit]
--,x.[Bestrahlungsnummer]
FROM [AlplaPROD_test1].[dbo].[T_EAIJournalLieferPosition] x
--where Barcode = '1000000000000000000000000000000001144380'
left join
[AlplaPROD_test1].[dbo].[T_EtikettenGedruckt] l on
x.LfdNrJeArtikelKunde = l.LfdNr
where x.Add_Date between getDate()-2 and getDate()
`;

View File

@@ -1,6 +1,7 @@
export const orderState = `
SELECT top(10000)
CustomerOrderNumber
,r.CustomerReleaseNumber
, OrderState
, r.ReleaseState
, h.CreatedByEdi

View File

@@ -1,5 +1,5 @@
export const blockQuery = `
SELECT
SELECT TOP(1)
'Alert! new blocking order: #' + cast(HumanReadableId as varchar) + ' - ' + ArticleVariantDescription as subject,
cast([HumanReadableId] as varchar) as blockingNumber,
[ArticleVariantDescription] as article,
@@ -41,5 +41,6 @@ on [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Producti
where [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].[BlockingDate] between getdate() - 1 and getdate() + 1
and [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].BlockingTrigger = 1
and HumanReadableId NOT IN ([sentBlockingOrders])
--and HumanReadableId NOT IN ([sentBlockingOrders])
and HumanReadableId > [lastBlocking]
`;