feat(notificaitons): fixed and corrections to get them working properly

This commit is contained in:
2025-04-04 17:12:48 -05:00
parent 99477bac19
commit a7818b4ca3
21 changed files with 888 additions and 633 deletions

View File

@@ -92,7 +92,7 @@ export default async function reprintLabelMonitor(notifyData: any) {
) {
//send the email :D
const emailSetup = {
emailTo: notifyData.emails,
email: notifyData.emails,
subject: `Alert! Downtime recorded greater than ${
notifyData.notifiySettings?.duration
}min ${

View File

@@ -65,7 +65,10 @@ export default async function reprintLabelMonitor(notifyData: any) {
`;
//update the time check
notifyQuery = notifyQuery.replaceAll("[timeCheck]", notifyData.checkTime);
notifyQuery = notifyQuery.replaceAll(
"[timeCheck]",
notifyData.checkInterval
);
notifyQuery = notifyQuery.replaceAll(
"[locations]",
notifyData.notifiySettings.locations
@@ -82,13 +85,13 @@ export default async function reprintLabelMonitor(notifyData: any) {
// update the count with the result
const emailSetup = {
emailTo: notifyData.emails,
email: notifyData.emails,
subject: `Alert! Pallets in production greater than ${notifyData.checkTime} ${notifyData.timeType}`,
template: "productionCheck",
context: {
items: prod,
count: prod.length,
checkTime: notifyData.checkTime,
checkTime: notifyData.checkInterval,
timeCheck: notifyData.timeType,
},
};

View File

@@ -1,5 +1,3 @@
// SELECT count(*) FROM V_EtikettenGedruckt where AnzahlGedruckterKopien > 2 and CONVERT(varchar(5), Add_Date,108) not like CONVERT(varchar(5), Upd_Date,108) and Upd_Date > DATEADD(SECOND, -30,getdate()) and VpkVorschriftBez not like '%$%'
import { eq, sql } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js";
import { notifications } from "../../../../../database/schema/notifications.js";
@@ -7,152 +5,121 @@ import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { sendEmail } from "../sendMail.js";
export interface Blocking {
HumanReadableId?: number;
subject?: string;
}
import { blockQuery } from "../../../sqlServer/querys/notifications/blocking.js";
export default async function qualityBlockingMonitor(notifyData: any) {
createLog("info", "notify", "notify", `monitoring ${notifyData.name}`);
createLog("info", "blcoking", "notify", `monitoring ${notifyData.name}`);
if (notifyData.emails === "") {
createLog(
"error",
"notify",
"blocking",
"notify",
`There are no emails set for ${notifyData.name}`
);
return;
return {
success: false,
message: `There are no emails set for ${notifyData.name}`,
};
}
let blockQuery = `
SELECT
'Alert! new blocking order: #' + cast(HumanReadableId as varchar) + ' - ' + ArticleVariantDescription as subject,
cast([HumanReadableId] as varchar) as blockingNumber,
[ArticleVariantDescription] as article,
cast([CustomerHumanReadableId] as varchar) + ' - ' + [CustomerDescription] as customer,
convert(varchar(10), [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].[BlockingDate], 101) + ' - ' + convert(varchar(5), [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].[BlockingDate], 108) as blockingDate,
cast(ArticleVariantHumanReadableId as varchar) + ' - ' + ArticleVariantDescription as av,
case when [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark = '' or [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark is NULL then 'Please reach out to quality for the reason this was placed on hold as a remark was not entered during the blocking processs' else [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark end as remark,
cast(FORMAT(TotalAmountOfPieces, '###,###') as varchar) + ' / ' + cast(LoadingUnit as varchar) as peicesAndLoadingUnits,
[test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].ProductionLotHumanReadableId as lotNumber,
cast(IdGlobalBlockingDefectsGroup as varchar) + ' - ' + BD.Description as mainDefectGroup,
cast(IdGlobalBlockingDefect as varchar) + ' - ' + MD.Description as mainDefect,
sent=0,
lot.MachineLocation as line,
HumanReadableId
FROM [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder] (nolock)
/*** Join 1.0 table to get correct id info to link ***/
join
[AlplaPROD_test1].[dbo].[T_BlockingOrders] (nolock) AS BO
on [HumanReadableId] = BO.[IdBlockingOrder]
/*** Get the main defect info ***/
Inner join
[AlplaPROD_test1].[dbo].[T_BlockingDefectsGroups] (nolock) as BD
ON BO.IdMainDefectGroup = BD.IdBlockingDefectsGroup
INNER join
[AlplaPROD_test1].[dbo].[T_BlockingDefects] as MD
ON BO.IdMainDefect = MD.IdBlockingDefect
/*** get lot info ***/
left join
(SELECT [MachineLocation]
,[MachineDescription]
,[ProductionLotHumanReadableId]
FROM [test1_AlplaPROD2.0_Reporting].[reporting_productionControlling].[ProducedLot]) as lot
on [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].ProductionLotHumanReadableId = lot.ProductionLotHumanReadableId
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])
`;
//add the blocking orders in.
blockQuery = blockQuery.replaceAll(
"[sentBlockingOrders]",
notifyData.sentBlocking[0].sentBlockingOrders
const { data: noti, error: notiError } = await tryCatch(
db
.select()
.from(notifications)
.where(eq(notifications.name, notifyData.name))
);
let blocking: any;
try {
blocking = await query(blockQuery, "Quality Blocking");
//console.log(labels.length);
// const now = Date.now()
//console.log(blocking);
// console.log(blocking[0].blockingNumber > data.prodID);
if (
blocking.length > 0 &&
blocking[0].HumanReadableId > notifyData.notifiySettings.prodID
) {
//send the email :D
const emailSetup = {
emailTo: notifyData.emails,
subject:
blocking.length > 0
? `Alert! New blocking orders.`
: blocking[0].subject,
template: "qualityBlocking",
context: {
items: blocking,
},
};
const sentEmail = await sendEmail(emailSetup);
if (!sentEmail.success) {
createLog(
"error",
"nofity",
"notify",
"Failed to send email, will try again on next interval"
);
return;
}
// add the new blocking order to this
const newBlockingOrders = blocking.map(
(b: any) => b.HumanReadableId
);
//console.log(newBlockingOrders);
//console.log(sentBlocking[0].sentBlockingOrders);
// Ensure no duplicates
const uniqueOrders = Array.from(
new Set([
...notifyData.sentBlocking[0].sentBlockingOrders,
...newBlockingOrders,
])
);
// Update sentBlockingOrders
notifyData.sentBlocking[0].sentBlockingOrders = uniqueOrders;
//console.log(notifUpdate);
const { data, error } = await tryCatch(
db
.update(notifications)
.set({
lastRan: sql`NOW()`,
notifiySettings: {
...notifyData.notifiySettings,
prodID: blocking[0].HumanReadableId,
sentBlockingOrders: uniqueOrders,
},
})
.where(eq(notifications.name, notifyData.name))
);
const notiData: any = noti;
const blockingOrders = notiData[0]?.notifiySettings.sentBlockingOrders.map(
(l: any) => {
return l.blockingOrder;
}
} catch (err) {
createLog(
"error",
"notify",
"notify",
`Error from running the blocking query: ${err}`
);
);
let blockingQuery = blockQuery.replaceAll(
"[sentBlockingOrders]",
blockingOrders
);
const { data: blocking, error: blockingError } = await tryCatch(
query(blockingQuery, "Quality Blocking")
);
if (blockingError) {
return {
success: false,
message: "Error getting blocking orders",
data: blockingError,
};
}
if (blocking.length > 0) {
const emailSetup = {
email: notifyData.emails,
subject:
blocking.length > 0
? `Alert! New blocking orders.`
: blocking[0].subject,
template: "qualityBlocking",
context: {
items: blocking,
},
};
const { data: sentEmail, error: sendEmailError } = await tryCatch(
sendEmail(emailSetup)
);
if (sendEmailError) {
createLog(
"error",
"blocking",
"notify",
"Failed to send email, will try again on next interval"
);
return {
success: false,
message:
"Failed to send email, will try again on next interval",
};
}
const newBlockingOrders = blocking.map((b: any) => {
return {
blockingOrder: b.HumanReadableId,
timeStamp: new Date(Date.now()),
};
});
const uniqueOrders = Array.from(
new Set([
...notifyData.notifiySettings.sentBlockingOrders,
...newBlockingOrders,
])
);
const { data, error } = await tryCatch(
db
.update(notifications)
.set({
lastRan: sql`NOW()`,
notifiySettings: {
...notifyData.notifiySettings,
prodID: blocking[0].HumanReadableId,
sentBlockingOrders: uniqueOrders,
},
})
.where(eq(notifications.name, notifyData.name))
);
if (error) {
return {
success: false,
message: "Error updating the blocking orders",
data: error,
};
}
}
return {
success: true,
message: "Blocking query ran successfully",
blocking,
};
}

View File

@@ -13,13 +13,13 @@ const notification = async (notifyData: any) => {
/**
* Pass the entire notification over
*/
createLog("info", "notify", "notify", `monitoring ${notifyData.name}`);
createLog("debug", "reprinting", "notify", `monitoring ${notifyData.name}`);
// validate if there are any emails.
if (notifyData.emails === "") {
createLog(
"error",
"notify",
"reprinting",
"notify",
`There are no emails set for ${notifyData.name}`
);
@@ -31,13 +31,14 @@ const notification = async (notifyData: any) => {
// set the time of getting the label
if (notifyData.timeType === "sec") {
timeCheck = `DATEADD(SECOND, -${notifyData.checkTime}, getdate()) `;
timeCheck = `DATEADD(SECOND, -${notifyData.checkInterval}, getdate()) `;
} else if (notifyData.timeType === "min") {
timeCheck = `DATEADD(MINUTE, -${notifyData.checkTime}, getdate()) `;
timeCheck = `DATEADD(MINUTE, -${notifyData.checkInterval}, getdate()) `;
}
let reprintQuery = `
SELECT
IdEtikettenHistorie,
IdArtikelvarianten as av,
ArtikelVariantenBez as alias,
LfdNr as runningNumber,
@@ -55,6 +56,7 @@ const notification = async (notifyData: any) => {
`;
//update the time check
reprintQuery = reprintQuery.replaceAll(
"DATEADD(SECOND, -30, getdate()) ",
timeCheck
@@ -66,10 +68,20 @@ const notification = async (notifyData: any) => {
query(reprintQuery, "Label Reprints")
);
if (labelError) {
createLog(
"error",
"reprinting",
"notify",
`Failed to get the labels: ${labelError}`
);
return;
}
if (labels.length > 0) {
//send the email :D
const emailSetup = {
emailTo: notifyData.emails,
email: notifyData.emails,
subject: "Alert! Label Reprinted",
template: "reprintLabels",
context: {
@@ -82,7 +94,7 @@ const notification = async (notifyData: any) => {
if (!sentEmail.success) {
createLog(
"error",
"notify",
"reprinting",
"notify",
"Failed to send email, will try again on next interval"
);
@@ -96,7 +108,6 @@ const notification = async (notifyData: any) => {
// };
// update the last time ran
const updateSettings = notifyData.notifiySettings;
const { data, error } = await tryCatch(
db
@@ -104,7 +115,7 @@ const notification = async (notifyData: any) => {
.set({
lastRan: sql`NOW()`,
notifiySettings: {
...updateSettings,
...notifyData.notifiySettings,
prodID: labels[0].IdEtikettenHistorie,
},
})

View File

@@ -64,7 +64,7 @@ export default async function reprintLabelMonitor(notifyData: any) {
//update the time check
noteQuery = noteQuery
.replaceAll("[timeCheck]", notifyData.checkTime)
.replaceAll("[timeCheck]", notifyData.checkInterval)
.replaceAll("[locations]", notifyData.notifiySettings.locations);
let stage: PPOO[];
@@ -78,13 +78,13 @@ export default async function reprintLabelMonitor(notifyData: any) {
// update the count with the result
const emailSetup = {
emailTo: notifyData.emails,
subject: `Alert! Pallets in staging greater than ${notifyData.checkTime} ${notifyData.timeType}`,
email: notifyData.emails,
subject: `Alert! Pallets in staging greater than ${notifyData.checkInterval} ${notifyData.timeType}`,
template: "stagingCheck",
context: {
items: stage,
count: stage.length,
checkTime: notifyData.checkTime,
checkTime: notifyData.checkInterval,
timeCheck: notifyData.timeType,
},
};

View File

@@ -0,0 +1,20 @@
export const dateCorrection = async (newDate: Date) => {
/**
* corrects the date format to be what ti is expecting
*/
const newDateFormat = new Date(newDate)
.toLocaleString("en-US", {
timeZone: "UTC",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hourCycle: "h23", // Ensures 24-hour format
})
.replace(",", "");
return newDateFormat;
};

View File

@@ -0,0 +1,23 @@
const requestUser = process.env.REQUESTUSER || "";
export const headerUpdate = async (data: any, plantToken: any) => {
// update the header
let webHeader = `
<request-id>[requestID]</request-id>
<data>
<WebImport>
<WebImportHeader>
<FileName>[requestID].XML</FileName>
<Type>SOTransportLoader</Type>
<UserName>[requestUser]</UserName>
</WebImportHeader>
`;
webHeader = webHeader
.replaceAll(
"[requestID]",
`${data[0].releaseNumber}-${plantToken[0].value}`
)
.replaceAll("[requestUser]", requestUser);
return webHeader;
};

View File

@@ -0,0 +1,54 @@
import { freightClass } from "../../../../../globalUtils/freightClass.js";
export const loadItems = async (data: any) => {
let itemGroups = "";
for (let i = 0; i < data.length; i++) {
let newItem = `
<ItemGroup id="" isShipUnit="false" isHandlingUnit="false" sequence="${
i + 1
}">
<ContainedBy id=""/>
<LineItem lineNumber="${i + 1}"/>
<Dimensions>
<Dimension type="Length" uom="IN">${(
data[i].pkgLengh / 25.4
).toFixed(2)}</Dimension>
<Dimension type="Width" uom="IN">${(
data[i].pkgWidth / 25.4
).toFixed(2)}</Dimension>
<Dimension type="Height" uom="IN">${Math.round(
data[i].pkgHeight / 25.4
).toFixed(2)}</Dimension>
</Dimensions>
<Description>${`av ${data[i].article} ${data[i].articleAlias}`}</Description>
<FreightClasses>
<FreightClass type="">${freightClass(
data[i].pkgWeight,
data[i].pkgLengh,
data[i].pkgWidth,
data[i].pkgHeight
)}</FreightClass>
</FreightClasses>
<Commodity/>
<NmfcCode/>
<HazardousMaterial>false</HazardousMaterial>
<HazMatDetail/>
<Weights>
<Weight type="actual" uom="KG">${
data[i].pkgWeight * data[i].Pallets
}</Weight>
</Weights>
<Quantities>
<Quantity type="actual" uom="pallet">${
data[i].Pallets
}</Quantity>
</Quantities>
</ItemGroup>
`;
itemGroups += newItem;
}
return itemGroups;
};

View File

@@ -0,0 +1,40 @@
import axios from "axios";
import querystring from "querystring";
import { createLog } from "../../../../logger/logger.js";
//tiCreds
const userid = process.env.USERID || "";
const password = process.env.PASSWORD || "";
export const postToTi = async (data: string) => {
const formBody = querystring.stringify({
userid,
password,
request: data,
});
axios
.post(
"https://t-insightws.mercurygate.net/MercuryGate/common/remoteService.jsp",
formBody,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
)
.then((response) => {
//console.log(response.data)
createLog("info", "ti", "notify", "Data was sent over to TI");
return {
success: true,
message: "Data was sent over to TI",
};
})
.catch((error) => {
createLog("error", "ti", "notify", error);
return {
success: false,
message: "Error sending data to TI",
data: error,
};
});
};

View File

@@ -0,0 +1,33 @@
import { createLog } from "../../../../logger/logger.js";
export const scacCheck = async (data: any) => {
createLog(
"info",
"ti",
"notify",
`Checking if ${data[0].addressAlias} has scac: ${
data[0].remark.split(",")[0] ? "there was one" : "no scac"
}`
);
const priceSheet = `
<PriceSheets>
<PriceSheet type="Carrier" isSelected="${
data[0].remark.split(",")[0] ? "true" : "false"
}">
<ContractId/>
${
data[0].remark.split(",")[0]
? `<SCAC>${data[0].remark
.split(",")[0]
.split(":")[1]
.toUpperCase()}</SCAC>`
: `<SCAC/>`
}
<Mode/>
</PriceSheet>
</PriceSheets>
`;
return priceSheet;
};

View File

@@ -0,0 +1,301 @@
import { eq, sql } from "drizzle-orm";
import { db } from "../../../../../../database/dbclient.js";
import { serverData } from "../../../../../../database/schema/serverData.js";
import { settings } from "../../../../../../database/schema/settings.js";
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
import { notifications } from "../../../../../../database/schema/notifications.js";
import { getHeaders } from "../../../../sqlServer/querys/notifications/ti/getHeaders.js";
import { query } from "../../../../sqlServer/prodSqlServer.js";
import { createLog } from "../../../../logger/logger.js";
import { getOrderToSend } from "../../../../sqlServer/querys/notifications/ti/getOrderToSend.js";
import { xmlPayloadTI } from "./tiXmlPayload.js";
import { headerUpdate } from "./headerUpdate.js";
import { loadItems } from "./loadItems.js";
import { dateCorrection } from "./dateCorrection.js";
import { scacCheck } from "./scacCodeCheck.js";
import { postToTi } from "./postToTI.js";
export const tiImport = async () => {
// get the plant token
let payload = xmlPayloadTI;
const { data: plantData, error: plantError } = await tryCatch(
db.select().from(settings)
);
if (plantError)
return {
success: false,
message: "Error Getting Plant Data.",
data: plantError,
};
const plantToken = plantData?.filter((n) => n.name === "plantToken");
const { data: plantInfo, error: plantEr } = await tryCatch(
db
.select()
.from(serverData)
.where(eq(serverData.plantToken, plantToken[0].value))
);
if (plantEr)
return {
success: false,
message: "Error Getting Plant Data.",
data: plantEr,
};
// parsing posting window
const plantI = plantInfo!;
// order notifications
const { data: notificationSet, error: notificationSettingsErr } =
await tryCatch(
db
.select()
.from(notifications)
.where(eq(notifications.name, "tiIntergration"))
);
if (notificationSettingsErr)
return {
success: false,
message: "Notification missing.",
data: notificationSettingsErr,
};
const notiSet: any = notificationSet;
const customerAccountNum = plantI[0].customerTiAcc as string; // tiIntergration
// get current releaes not in the already sent oders
const releaseString = notiSet[0].notifiySettings.releases
.map((num: any) => `'${num.releaseNumber}'`)
.join(", ");
let orders = getHeaders
.replaceAll("[from]", notiSet[0]?.notifiySettings.start)
.replaceAll("[to]", notiSet[0]?.notifiySettings.end)
.replaceAll("[exclude]", releaseString);
// get the headers pending
const { data: header, error: headerError } = await tryCatch(
query(orders, "Ti get open headers")
);
if (headerError) {
createLog(
"error",
"ti",
"notify",
`Error getting headers: ${headerError}`
);
return {
success: false,
message: "Error getting headers",
data: headerError,
};
}
if (header.length === 0) {
createLog(
"info",
"ti",
"notify",
"There are no pending orders to be sent over to ti."
);
return {
success: true,
message: "There are no pending orders to be sent over to ti.",
};
}
createLog(
"info",
"tiIntergration",
"notify",
`There are a total of ${header.length} to send over`
);
/**
* Update the query to get only the first header
*/
// update query to have the correct plant token
let orderToSend = getOrderToSend
.replaceAll("test1", plantToken[0].value)
.replaceAll("[releaseToProcess]", `'${header[0].releaseNumber}'`)
.replaceAll("[from]", notiSet[0].notifiySettings.start)
.replaceAll("[to]", notiSet[0].notifiySettings.end);
// get the headers pending
const { data: orderData, error: ordersError } = await tryCatch(
query(orderToSend, "Ti get open headers")
);
if (ordersError)
return {
success: false,
message: "Error getting getting orders",
data: ordersError,
};
// update the special instructions section
const otherSettings = plantI[0]?.otherSettings as {
specialInstructions: string;
active: boolean;
}[];
const specialInfo = otherSettings[0].specialInstructions.replaceAll(
"[header]",
orderData[0].Header
);
// add the full amount of pallets sending over
let fullPalToSend = orderData.reduce(
(acc: any, o: any) => acc + o.Pallets,
0
);
//console.log("payload", payload);
payload = payload
.replaceAll(
`[WebImportHeader]`,
await headerUpdate(orderData, plantToken)
)
.replaceAll(`[items]`, await loadItems(orderData))
.replaceAll(`[customerAccountNum]`, customerAccountNum)
.replaceAll("[fullTotalPal]", fullPalToSend)
// add in release info
.replaceAll(`[shipNumber]`, orderData[0].releaseNumber)
.replaceAll(`[loadNumber]`, orderData[0].releaseNumber);
// add in the multi release numbers
let multiRelease = ``;
if (orderData.length > 0) {
for (let i = 0; i < orderData.length; i++) {
const newRelease = `
<ReferenceNumber type="Release Number" isPrimary="false">${orderData[i].releaseNumber}</ReferenceNumber>`;
multiRelease += newRelease;
}
payload = payload.replaceAll("[multieReleaseNumber]", multiRelease);
} else {
payload = payload.replaceAll("[multieReleaseNumber]", "");
}
// add the correct date stuff
payload = payload
.replaceAll(
"[loadingDate]",
await dateCorrection(orderData[0].LoadingDate)
)
.replaceAll(
"[deliveryDate]",
await dateCorrection(orderData[0].DeliveryDate)
);
// shipping ours corrections
const formattedDate = orderData[0].LoadingDate.toLocaleDateString("en-US", {
month: "2-digit",
day: "2-digit",
year: "numeric",
});
const shippingHours = JSON.parse(plantI[0]?.shippingHours!);
payload = payload
.replaceAll(
"[shippingHoursEarly]",
`${formattedDate} ${shippingHours[0].early}`
)
.replaceAll(
"[shippingHoursLate]",
`${formattedDate} ${shippingHours[0].late}`
);
// special instructions
if (otherSettings[0].specialInstructions.length != 0) {
payload = payload.replaceAll("[specialInstructions]", specialInfo);
} else {
payload = payload.replaceAll("[specialInstructions]", "");
}
// shipper info
payload = payload
.replaceAll("[plantName]", `Alpla ${plantI[0]?.sName!}`)
.replaceAll("[plantStreetAddress]", plantI[0]?.streetAddress!)
.replaceAll("[plantCity]", plantI[0]?.cityState!.split(",")[0])
.replaceAll("[plantState]", plantI[0]?.cityState!.split(",")[1])
.replaceAll("[plantZipCode]", plantI[0]?.zipcode!)
.replaceAll("[contactNum]", plantI[0]?.contactPhone!)
.replaceAll("[contactEmail]", plantI[0]?.contactEmail!)
// customer info
.replaceAll("[customerName]", orderData[0].addressAlias)
.replaceAll("[customerStreetAddress]", orderData[0].streetAddress)
.replaceAll("[customerCity]", orderData[0].city.split(",")[0])
.replaceAll("[customerState]", orderData[0].city.split(",")[1])
.replaceAll("[customerZip]", orderData[0].zipCode)
.replaceAll("[customerPO]", orderData[0].Header)
.replaceAll(
"[glCoding]",
`52410-${
orderData[0].artileType.toLowerCase() === "preform" ||
orderData[0].artileType.toLowerCase() === "metalCage"
? 31
: plantI[0].greatPlainsPlantCode
}`
) // {"52410 - " + (artileType.toLowerCase() === "preform" || artileType.toLowerCase() === "metalCage" ? 31: plantInfo[0].greatPlainsPlantCode)}
.replaceAll(
"[pfc]",
`${
orderData[0].artileType.toLowerCase() === "preform" ||
orderData[0].artileType.toLowerCase() === "metalCage"
? 40
: orderData[0].costCenter
}`
)
.replaceAll("[priceSheet]", await scacCheck(orderData));
//send over to be processed
//console.log("payload", payload);
const { data: tiPost, error: tiError } = await tryCatch(postToTi(payload));
if (tiError) {
return {
success: false,
message: "Error posting to TI",
error: tiError,
};
}
/**
* Update the db so we dont try to pull the next one
*/
const uniqueOrders = Array.from(
new Set([
...notiSet[0].notifiySettings.releases,
{
releaseNumber: header[0].releaseNumber,
timeStamp: new Date(Date.now()),
},
])
);
const { data, error } = await tryCatch(
db
.update(notifications)
.set({
lastRan: sql`NOW()`,
notifiySettings: {
...notiSet[0].notifiySettings,
releases: uniqueOrders,
},
})
.where(eq(notifications.name, "tiIntergration"))
);
createLog("info", "ti", "notify", "done with this order");
return { message: "done with this order" };
};

View File

@@ -1,9 +1,6 @@
export let xmlPayloadTI = `
<service-request>
<service-id>ImportWeb</service-id>
<request-id>[requestID]</request-id>
<data>
<WebImport>
[WebImportHeader]
<WebImportFile>
<MercuryGate>
@@ -35,19 +32,18 @@ export let xmlPayloadTI = `
</Address>
</BillTo>
</Payment>
<PriceSheets>
<PriceSheet type="Carrier" isSelected="false"> // get this from the price sheet
<ContractId/>
<SCAC/>
<Mode/>
</PriceSheet>
</PriceSheets>
[priceSheet]
<!-- Comments here -->
<Comments>
<Comment type="SpecialInstructions">[specialInstructions]</Comment>
</Comments>
<Plan>
<Events count="2">
<Event type="Pickup" sequenceNum="1">
<Dates>
<Date type="earliest">[loadingDate]</Date>
<Date type="latest">[deliveryDate]</Date>
<Date type="earliest">[shippingHoursEarly]</Date>
<Date type="latest">[shippingHoursLate]</Date>
</Dates>
<Address type="" isResidential="" isPrimary="false">
<LocationCode/>
@@ -119,24 +115,20 @@ export let xmlPayloadTI = `
</ReferenceNumbers>
<Services/>
<EquipmentList/>
6
<Dimensions>
<Dimension type="RatingCount">[fullTotalPal]</Dimension>
</Dimensions>
<Dates>
<Pickup>
<Date type="earliest">[loadingDate]</Date>
<Date type="latest">[loadingDate]</Date>
<Date type="earliest">[shippingHoursEarly]</Date>
<Date type="latest">[shippingHoursLate]</Date>
</Pickup>
<Drop>
<Date type="earliest">[deliveryDate]</Date>
<Date type="latest">[deliveryDate]</Date>
</Drop>
</Dates>
<PriceSheets>
<PriceSheet type="Carrier" isSelected="false">
<ContractId/>
<SCAC/>
<Mode/>
</PriceSheet>
</PriceSheets>
[priceSheet]
<Shipper>
<Address type="" isResidential="" isPrimary="false">
<LocationCode/>
@@ -160,7 +152,7 @@ export let xmlPayloadTI = `
<Consignee>
<Address type="" isResidential="" isPrimary="false">
<LocationCode/>
<Name>[customer]</Name>
<Name>[customerName]</Name>
<AddrLine1>[customerStreetAddress]</AddrLine1>
<AddrLine2/>
<City>[customerCity]</City>
@@ -168,6 +160,17 @@ export let xmlPayloadTI = `
<PostalCode>[customerZip]</PostalCode>
<CountryCode>USA</CountryCode>
<Contacts />
<!-- Location contacts are optional -->
<Contacts>
<Contact type="">
<Name>Alpla</Name>
<ContactMethods>
<!-- Valid contactMethod types are phone, fax, and email -->
<ContactMethod sequenceNum="1" type="phone">[contactNum]</ContactMethod>
<ContactMethod sequenceNum="1" type="email">[contactEmail]</ContactMethod>
</ContactMethods>
</Contact>
</Contacts>
</Address>
</Consignee>

View File

@@ -1,413 +1,10 @@
import { xmlPayloadTI } from "./tiFullFlow/tiXmlPayload.js";
import axios from "axios";
import querystring from "querystring";
import { getOrderToSend } from "../../../sqlServer/querys/notifications/ti/getOrderToSend.js";
import { getHeaders } from "../../../sqlServer/querys/notifications/ti/getHeaders.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { db } from "../../../../../database/dbclient.js";
import { settings } from "../../../../../database/schema/settings.js";
import { serverData } from "../../../../../database/schema/serverData.js";
import { eq, sql } from "drizzle-orm";
import { notifications } from "../../../../../database/schema/notifications.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { createLog } from "../../../logger/logger.js";
import { freightClass } from "../../../../globalUtils/freightClass.js";
import { delay } from "../../../../globalUtils/delay.js";
const dateCorrection = (newDate: any) => {
return new Date(newDate)
.toLocaleString("en-US", {
timeZone: "UTC",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hourCycle: "h23", // Ensures 24-hour format
})
.replace(",", "");
};
const tiImport = async () => {
//await initializePool();
// get the plant token
const { data: plantData, error: plantError } = await tryCatch(
db.select().from(settings)
);
//await initializePool();
if (plantError) return;
const plantToken = plantData?.filter((n) => n.name === "plantToken");
const { data: plantInfo, error: plantEr } = await tryCatch(
db
.select()
.from(serverData)
.where(eq(serverData.plantToken, plantToken[0].value))
);
// parsing posting window
const plantI = plantInfo!;
//const postTime = JSON.parse(plantI[0]?.tiPostTime!);
// order notifications
const { data: notificationSet, error: notificationSettingsErr } =
await tryCatch(
db
.select()
.from(notifications)
.where(eq(notifications.name, "tiIntergration"))
);
if (notificationSettingsErr) return;
const notiSet: any = notificationSet;
//creds
const userid = "ALPLAWSTEST";
const password = "oe39U1LuLX9ZdY0XKobG";
// const requestID = `ALPLAPBTEST1`; // production will be alpla01-dateTime - this will be the time it was sent over.
const requestUser = "ALPLAWSTEST"; // if alplaprod_rs -- confirm we can use a user name vs the AlplapIMPORT // needs to stay the same as provied
const customerAccountNum = plantI[0].customerTiAcc as string; // ti
// it we dont get anything here we want to make sure we add it in
// get current releaes not in the already sent oders
let orders = getHeaders;
orders = orders
.replaceAll("test1", plantToken[0].value)
.replaceAll("[from]", notiSet?.notifiySettings.start)
.replaceAll("[to]", notiSet?.notifiySettings.end)
.replaceAll(
"[exclude]",
notiSet.notifiySettings.processed
.map((num: any) => `'${num}'`)
.join(", ")
);
//console.log(orders);
let headerPending = [];
try {
headerPending = await query(orders, "Ti get open headers");
} catch (error) {
console.log(error);
}
if (headerPending.length === 0) {
createLog(
"info",
"notification",
"notify",
"There are no pending orders to be sent over to ti."
);
return {
success: true,
code: 1,
message: "There are no pending orders to be sent over to ti.",
};
}
createLog(
"info",
"notification",
"notify",
`There are a total of ${headerPending.length} to send over`
);
// update query to have the correct plant token
let orderToSend = getOrderToSend;
orderToSend = orderToSend
.replaceAll("test1", plantToken[0].value)
.replaceAll("[releaseToProcess]", `'${headerPending[0].releaseNumber}'`)
.replaceAll("[from]", notiSet.notifiySettings.start)
.replaceAll("[to]", notiSet.notifiySettings.end);
// console.log(orderToSend);
let records = [];
try {
records = await query(orderToSend, "Ti send order");
} catch (error) {
console.log(error);
}
//console.log(headerPending.length);
// update the header
let webHeader = `
<request-id>[requestID]</request-id>
<data>
<WebImport>
<WebImportHeader>
<FileName>[requestID].XML</FileName>
<Type>SOTransportLoader</Type>
<UserName>[requestUser]</UserName>
</WebImportHeader>
`;
webHeader = webHeader.replaceAll(
"[requestID]",
`${records[0].releaseNumber}-${plantToken[0].value}`
);
webHeader = webHeader.replaceAll("[requestUser]", requestUser);
// update the special instructions section
const otherSettings = plantI[0]?.otherSettings as {
specialInstructions: string;
active: boolean;
}[];
const specialInfo = otherSettings[0].specialInstructions.replaceAll(
"[header]",
records[0].Header
);
// this part will link into the <ItemGroups></ItemGroups>
let itemGroups = "";
for (let i = 0; i < records.length; i++) {
let newItem = `
<ItemGroup id="" isShipUnit="false" isHandlingUnit="false" sequence="${
i + 1
}">
<ContainedBy id=""/>
<LineItem lineNumber="${i + 1}"/>
<Dimensions>
<Dimension type="Length" uom="IN">${(
records[i].pkgLengh / 25.4
).toFixed(2)}</Dimension>
<Dimension type="Width" uom="IN">${(
records[i].pkgWidth / 25.4
).toFixed(2)}</Dimension>
<Dimension type="Height" uom="IN">${Math.round(
records[i].pkgHeight / 25.4
).toFixed(2)}</Dimension>
</Dimensions>
<Description>${`av ${records[i].article} ${records[i].articleAlias}`}</Description>
<FreightClasses>
<FreightClass type="">${freightClass(
records[i].pkgWeight,
records[i].pkgLengh,
records[i].pkgWidth,
records[i].pkgHeight
)}</FreightClass>
</FreightClasses>
<Commodity/>
<NmfcCode/>
<HazardousMaterial>false</HazardousMaterial>
<HazMatDetail/>
<Weights>
<Weight type="actual" uom="KG">${
records[i].pkgWeight * records[i].Pallets
}</Weight>
</Weights>
<Quantities>
<Quantity type="actual" uom="pallet">${
records[i].Pallets
}</Quantity>
</Quantities>
</ItemGroup>
`;
itemGroups += newItem;
}
// add the full amount of pallets sending over
let fullPalToSend = records.reduce(
(acc: any, o: any) => acc + o.Pallets,
0
);
// rebuild the xml to be properly
let payload = xmlPayloadTI;
payload = payload
.replaceAll(`[WebImportHeader]`, webHeader)
.replaceAll(`[items]`, itemGroups)
.replaceAll(`[customerAccountNum]`, customerAccountNum)
.replaceAll("[fullTotalPal]", fullPalToSend);
// update the main release
//[loadNumber],[shipNumber]
payload = payload.replaceAll(`[shipNumber]`, records[0].releaseNumber);
payload = payload.replaceAll(`[loadNumber]`, records[0].releaseNumber);
// do the multie release if needed
// <ReferenceNumber type="Release Number" isPrimary="false">[multieReleaseNumber]</ReferenceNumber>
let multiRelease = ``;
if (records.length > 0) {
for (let i = 0; i < records.length; i++) {
const newRelease = `
<ReferenceNumber type="Release Number" isPrimary="false">${records[i].releaseNumber}</ReferenceNumber>`;
multiRelease += newRelease;
}
payload = payload.replaceAll("[multieReleaseNumber]", multiRelease);
} else {
payload = payload.replaceAll("[multieReleaseNumber]", "");
}
//update the delivery section
payload = payload.replaceAll(
"[loadingDate]",
dateCorrection(records[0].LoadingDate)
);
payload = payload.replaceAll(
"[deliveryDate]",
dateCorrection(records[0].DeliveryDate)
);
// shipping hours
//<Date type="earliest">[shippingHoursEarly]</Date>
//<Date type="latest">[shippingHoursLate]</Date>
// update teh shipping hours
const now = new Date();
const formattedDate = records[0].LoadingDate.toLocaleDateString("en-US", {
month: "2-digit",
day: "2-digit",
year: "numeric",
});
const shippingHours = JSON.parse(plantI[0]?.shippingHours!);
//console.log(shippingHours);
payload = payload
.replaceAll(
"[shippingHoursEarly]",
`${formattedDate} ${shippingHours[0].early}`
)
.replaceAll(
"[shippingHoursLate]",
`${formattedDate} ${shippingHours[0].late}`
);
payload = payload
.replaceAll("[plantName]", `Alpla ${plantI[0]?.sName!}`)
.replaceAll("[plantStreetAddress]", plantI[0]?.streetAddress!)
.replaceAll("[plantCity]", plantI[0]?.cityState!.split(",")[0])
.replaceAll("[plantState]", plantI[0]?.cityState!.split(",")[1])
.replaceAll("[plantZipCode]", plantI[0]?.zipcode!)
.replaceAll("[contactNum]", plantI[0]?.contactPhone!)
.replaceAll("[contactEmail]", plantI[0]?.contactEmail!)
// customer info
.replaceAll("[customerName]", records[0].addressAlias)
.replaceAll("[customerStreetAddress]", records[0].streetAddress)
.replaceAll("[customerCity]", records[0].city.split(",")[0])
.replaceAll("[customerState]", records[0].city.split(",")[1])
.replaceAll("[customerZip]", records[0].zipCode)
.replaceAll("[customerPO]", records[0].Header)
.replaceAll(
"[glCoding]",
`52410-${
records[0].artileType.toLowerCase() === "preform" ||
records[0].artileType.toLowerCase() === "metalCage"
? 31
: plantI[0].greatPlainsPlantCode
}`
) // {"52410 - " + (artileType.toLowerCase() === "preform" || artileType.toLowerCase() === "metalCage" ? 31: plantInfo[0].greatPlainsPlantCode)}
.replaceAll(
"[pfc]",
`${
records[0].artileType.toLowerCase() === "preform" ||
records[0].artileType.toLowerCase() === "metalCage"
? 40
: records[0].costCenter
}`
);
// special instructions
if (otherSettings[0].specialInstructions.length != 0) {
payload = payload.replaceAll("[specialInstructions]", specialInfo);
}
// update the carrier info if any is needed.
// check the address has a real carrier on it and change to true and put the sacs code in
const hasCarrier = true;
console.log(
`Checking if ${records[0].addressAlias} has scac: ${
records[0].remark.split(",")[0] ? "there was one" : "no scac"
}`
);
const priceSheet = `
<PriceSheets>
<PriceSheet type="Carrier" isSelected="${
records[0].remark.split(",")[0] ? "true" : "false"
}">
<ContractId/>
${
records[0].remark.split(",")[0]
? `<SCAC>${records[0].remark
.split(",")[0]
.split(":")[1]
.toUpperCase()}</SCAC>`
: `<SCAC/>`
}
<Mode/>
</PriceSheet>
</PriceSheets>
`;
payload = payload.replaceAll("[priceSheet]", priceSheet);
// console.log(payload);
//await closePool();
//put the xml into a form
const formBody = querystring.stringify({
userid,
password,
request: payload,
});
axios
.post(
"https://t-insightws.mercurygate.net/MercuryGate/common/remoteService.jsp",
formBody,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
)
.then((response) => {
//console.log(response.data)
console.log("Data was sent over to TI");
})
.catch((error) => console.error(error));
// console.log(payload);
// the order is done so we want to update the processed.
// add the new processed order to this
let notiSettingArray = notiSet.notifiySettings;
if (
!notiSettingArray[0].processed.includes(headerPending[0].releaseNumber)
) {
notiSettingArray[0].processed.push(headerPending[0].releaseNumber);
}
const { data, error } = await tryCatch(
db
.update(notifications)
.set({
lastRan: sql`NOW()`,
notifiySettings: {
...notiSettingArray,
prodID: 1,
},
})
.where(eq(notifications.name, "tiIntergration"))
);
createLog("info", "ti", "notify", "done with this order");
return { success: true, code: 0, message: "done with this order" };
};
import { createLog } from "../../../logger/logger.js";
import { tiImport } from "./tiFullFlow/tiImport.js";
// add a running check so we cant flag it twice
export let tiExportRunning = false;
export const runTiImport = async () => {
let finished = false;
let test: any;
@@ -420,14 +17,20 @@ export const runTiImport = async () => {
"info",
"ti",
"notify",
`Still more to process? ${test.code === 1 ? "No" : "Yes"}`
`Still more to process? ${test.success ? "No" : "Yes"}`
);
if (test.code === 1) {
if (test.success) {
finished = true;
}
if (!test.success) {
//errors are handled in the tiImport function
tiExportRunning = false;
}
await delay(1000 * 5);
} while (!finished);
tiExportRunning = false;
return { success: true, message: "Finished processing all data." };
};
export default tiImport;
export default runTiImport;

View File

@@ -9,10 +9,12 @@ import { createLog } from "../logger/logger.js";
import { note, notificationCreate } from "./utils/masterNotifications.js";
import { startNotificationMonitor } from "./utils/processNotifications.js";
import notifyStats from "./routes/getActiveNotifications.js";
import tiTrigger from "./routes/manualTiggerTi.js";
import blocking from "./routes/qualityBlocking.js";
const app = new OpenAPIHono();
const routes = [sendemail, notifyStats] as const;
const routes = [sendemail, notifyStats, tiTrigger, blocking] as const;
const appRoutes = routes.forEach((route) => {
app.route("/notify", route);
@@ -41,21 +43,9 @@ if (notesError) {
);
}
if (note.length != notes?.length) {
setTimeout(() => {
notificationCreate();
createLog("info", "notify", "notify", `New notifcations being added.`);
setTimeout(() => {
startNotificationMonitor();
}, 5 * 1000);
} else {
createLog(
"info",
"notify",
"notify",
`There are know new notifcations. no need to run the update. reminder all changes happen per server.`
);
setTimeout(() => {
startNotificationMonitor();
}, 5 * 1000);
}
startNotificationMonitor();
}, 5 * 1000);
export default app;

View File

@@ -1,22 +1,26 @@
// import {Router} from "express";
// import {tiExportRunning, runTiImport} from "../../notification/notification/tiFullFlow/tiImports.js";
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
// const router = Router();
import runTiImport from "../controller/notifications/tiIntergration.js";
// router.get("/tiTrigger", async (req, res): Promise<void> => {
// if (tiExportRunning) {
// res.status(200).json({
// success: false,
// message: "There is already a current sesion of the Export running please try again later.",
// });
// }
const app = new OpenAPIHono({ strict: false });
// // trigger the import
// runTiImport();
// res.status(200).json({
// success: true,
// message: "The Ti Export has been manually started and will continue to run in the background.",
// });
// });
// export default router;
app.openapi(
createRoute({
tags: ["notify"],
summary: "Manually trigger TI intergrations.",
method: "get",
path: "/tiTrigger",
//middleware: authMiddleware,
responses: responses(),
}),
async (c) => {
const tiImport = await runTiImport();
return c.json({
success: tiImport?.success,
message: tiImport?.message,
});
}
);
export default app;

View File

@@ -0,0 +1,50 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
import qualityBlockingMonitor from "../controller/notifications/qualityBlocking.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { notifications } from "../../../../database/schema/notifications.js";
import { db } from "../../../../database/dbclient.js";
import { eq } from "drizzle-orm";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["notify"],
summary: "Manually trigger TI intergrations.",
method: "get",
path: "/blockingTrigger",
//middleware: authMiddleware,
responses: responses(),
}),
async (c) => {
/**
* get the blocking notification stuff
*/
const { data, error } = await tryCatch(
db
.select()
.from(notifications)
.where(eq(notifications.name, "qualityBlocking"))
);
if (error) {
return c.json({
success: false,
message: "Error Getting Notification Settings.",
data: error,
});
}
const blocking = await qualityBlockingMonitor(data[0]);
return c.json({
success: blocking?.success,
message: blocking?.message,
});
}
);
export default app;

View File

@@ -31,7 +31,10 @@ export const note: any = [
timeType: "min",
emails: "",
active: false,
notifiySettings: { prodID: 1, sentBlockingOrders: [1] },
notifiySettings: {
prodID: 1,
sentBlockingOrders: [{ timeStamp: "0", blockingOrder: 1 }],
},
},
{
name: "productionCheck",
@@ -72,8 +75,8 @@ export const note: any = [
notifiySettings: {
prodID: 1,
start: 36,
end: 720,
releases: [1, 2, 3],
end: 36,
releases: [{ timeStamp: "0", releaseNumber: 1 }],
},
},
{
@@ -86,7 +89,7 @@ export const note: any = [
notifiySettings: {
prodID: 1,
start: 36,
end: 720,
end: 36,
releases: [1, 2, 3],
},
},
@@ -98,7 +101,14 @@ export const notificationCreate = async () => {
const notify = await db
.insert(notifications)
.values(note[i])
.onConflictDoNothing();
.onConflictDoUpdate({
target: notifications.name,
set: {
name: note[i].name,
description: note[i].description,
//notifiySettings: note[i].notifiySettings,
},
});
} catch (error) {
createLog(
"error",
@@ -110,4 +120,10 @@ export const notificationCreate = async () => {
);
}
}
createLog(
"info",
"lst",
"nofity",
"notifications were just added/updated due to server startup"
);
};

View File

@@ -43,23 +43,43 @@ export const startNotificationMonitor = async () => {
if (
!note.active ||
note.emails === "" ||
// note.emails === "" ||
runningNotifications[note.name]
) {
//console.log(`Skipping ${note.name} hes already scheduled`);
continue;
}
if (!runningNotifications[note.name] && note.active) {
createLog(
"info",
"notify",
"notify",
`${note.name} Is active and not already running.`
);
}
let time = `*/30 * * * *`; // default to be every 30 min
if (note.timeType === "min") {
console.log(`Creating the min mark here`);
time = `*/${note.checkInterval} * * * *`;
//console.log(`Creating the min mark here`);
const totalMinutes = note.checkInterval;
if (note.checkInterval > 60) {
const hours = Math.floor(totalMinutes / 60); // 1 hour
const minutes = totalMinutes % 60; // 45 minutes
time = `*/${minutes} */${hours} * * *`;
} else {
time = `*/${note.checkInterval} * * * *`;
}
}
if (note.timeType === "hour") {
console.log(`Creating the hour mark here`);
time = `* */${note.checkInterval} * * *`;
const totalHours = note.checkInterval;
if (note.checkInterval > 60) {
const days = Math.floor(totalHours / 24); // 1 hour
const hours = totalHours % 24; // 45 minutes
time = `* */${hours} */${days} * *`;
} else {
time = `* */${note.checkInterval} * * *`;
}
}
createJob(note.name, time, async () => {

View File

@@ -0,0 +1,45 @@
export const customerInvNoHold = `
select x.idartikelVarianten as av
,ArtikelVariantenAlias as Alias
--x.Lfdnr as RunningNumber,
--,round(sum(EinlagerungsMengeVPKSum),0) as Total_Pallets
--,sum(EinlagerungsMengeSum) as Total_PalletQTY
,round(sum(VerfuegbareMengeVPKSum),0) as Avalible_Pallets
,sum(VerfuegbareMengeSum) as Avaliable_PalletQTY
,sum(case when c.Description LIKE '%COA%' then GesperrteMengeVPKSum else 0 end) as COA_Pallets
,sum(case when c.Description LIKE '%COA%' then GesperrteMengeSum else 0 end) as COA_QTY
--,sum(case when c.Description NOT LIKE '%COA%' then GesperrteMengeVPKSum else 0 end) as Held_Pallets
--,sum(case when c.Description NOT LIKE '%COA%' then GesperrteMengeSum else 0 end) as Held_QTY
,IdProdPlanung as Lot
--,IdAdressen
--,x.AdressBez
--,*
from [AlplaPROD_test1].dbo.[V_LagerPositionenBarcodes] (nolock) x
left join
[AlplaPROD_test1].dbo.T_EtikettenGedruckt (nolock) on
x.Lfdnr = T_EtikettenGedruckt.Lfdnr AND T_EtikettenGedruckt.Lfdnr > 1
left join
(SELECT *
FROM [AlplaPROD_test1].[dbo].[T_BlockingDefects] (nolock) where Active = 1) as c
on x.IdMainDefect = c.IdBlockingDefect
/*
The data below will be controlled by the user in excell by default everything will be passed over
IdAdressen = 3
*/
where IdArtikelTyp = 1
and x.IdWarenlager not in (6, 1)
--and IdAdressen
group by x.IdArtikelVarianten
,ArtikelVariantenAlias
,IdProdPlanung
--,c.Description
,IdAdressen
,x.AdressBez
--, x.Lfdnr
order by x.IdArtikelVarianten
`;

View File

@@ -0,0 +1,27 @@
export const openOrders = `
Select LEFT(ArtikelVariantenAlias, charindex(' ', ArtikelVariantenAlias) - 1) customerItemNumber,
x.IdArtikelVarianten AS article,
ArtikelVariantenAlias AS articleDescription,
IdAuftragsAbruf as releaseNumber,
AuftragsNummer AS header,
AuftragsNummer as customerLineItemNo,
AbrufNummer AS customerReleaseNumber,
AbrufMengeVPK AS pallets,
AbrufMenge AS qty,
y.TradeUnits AS cartons,
IdAdresse AS customerID,
LieferAdressBez as DeliveryAddressDescription,
AbrufLadeDatum AS loadingDate,
AbrufLiefertermin AS deliveryDate
--,OrderStatus = 'loading'
--,*
FROM alplaprod_test1.dbo.V_TrackerAuftragsAbrufe (nolock) x
left join
[test1_AlplaPROD2.0_Read].[order].[Release] (nolock) y on
x.IdAuftragsAbruf = y.ReleaseNumber
--WHERE AbrufStatus = 1 AND AbrufLiefertermin < getdate() + 5 AND GelieferteMenge = 0
WHERE AbrufStatus = 1 AND AbrufLiefertermin between getDate() + -[sDay] and getdate() + [eDay] AND GelieferteMenge = 0
ORDER BY AbrufLiefertermin
`;

View File

@@ -0,0 +1,45 @@
export const blockQuery = `
SELECT
'Alert! new blocking order: #' + cast(HumanReadableId as varchar) + ' - ' + ArticleVariantDescription as subject,
cast([HumanReadableId] as varchar) as blockingNumber,
[ArticleVariantDescription] as article,
cast([CustomerHumanReadableId] as varchar) + ' - ' + [CustomerDescription] as customer,
convert(varchar(10), [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].[BlockingDate], 101) + ' - ' + convert(varchar(5), [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].[BlockingDate], 108) as blockingDate,
cast(ArticleVariantHumanReadableId as varchar) + ' - ' + ArticleVariantDescription as av,
case when [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark = '' or [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark is NULL then 'Please reach out to quality for the reason this was placed on hold as a remark was not entered during the blocking processs' else [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].Remark end as remark,
cast(FORMAT(TotalAmountOfPieces, '###,###') as varchar) + ' / ' + cast(LoadingUnit as varchar) as peicesAndLoadingUnits,
[test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].ProductionLotHumanReadableId as lotNumber,
cast(IdGlobalBlockingDefectsGroup as varchar) + ' - ' + BD.Description as mainDefectGroup,
cast(IdGlobalBlockingDefect as varchar) + ' - ' + MD.Description as mainDefect,
sent=0,
lot.MachineLocation as line,
HumanReadableId
FROM [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder] (nolock)
/*** Join 1.0 table to get correct id info to link ***/
join
[AlplaPROD_test1].[dbo].[T_BlockingOrders] (nolock) AS BO
on [HumanReadableId] = BO.[IdBlockingOrder]
/*** Get the main defect info ***/
Inner join
[AlplaPROD_test1].[dbo].[T_BlockingDefectsGroups] (nolock) as BD
ON BO.IdMainDefectGroup = BD.IdBlockingDefectsGroup
INNER join
[AlplaPROD_test1].[dbo].[T_BlockingDefects] as MD
ON BO.IdMainDefect = MD.IdBlockingDefect
/*** get lot info ***/
left join
(SELECT [MachineLocation]
,[MachineDescription]
,[ProductionLotHumanReadableId]
FROM [test1_AlplaPROD2.0_Reporting].[reporting_productionControlling].[ProducedLot]) as lot
on [test1_AlplaPROD2.0_Reporting].[reporting_blocking].[BlockingOrder].ProductionLotHumanReadableId = lot.ProductionLotHumanReadableId
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])
`;