From eccaf17332fb1c63b8d6bbea6f668c3bb42d44b7 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Tue, 14 Apr 2026 20:25:20 -0500 Subject: [PATCH] feat(datamart): migrations completed remaining is the deactivation that will be ran by anylitics --- README.md | 2 +- backend/datamart/datamart.controller.ts | 82 +++++++++++++++---- backend/datamart/datamartData.utlis.ts | 34 +++++++- ...ticles.sql => datamart.activeArticles.sql} | 0 .../queries/datamart.customerInventory.sql | 45 ++++++++++ ...e.sql => datamart.deliveryByDateRange.sql} | 0 .../queries/datamart.fakeEDIUpdate.sql | 29 +++++++ .../prodSql/queries/datamart.inventory.sql | 44 ++++++++++ .../prodSql/queries/datamart.openOrders.sql | 33 ++++++++ 9 files changed, 250 insertions(+), 19 deletions(-) rename backend/prodSql/queries/{activeArticles.sql => datamart.activeArticles.sql} (100%) create mode 100644 backend/prodSql/queries/datamart.customerInventory.sql rename backend/prodSql/queries/{deliveryByDateRange.sql => datamart.deliveryByDateRange.sql} (100%) create mode 100644 backend/prodSql/queries/datamart.fakeEDIUpdate.sql create mode 100644 backend/prodSql/queries/datamart.inventory.sql create mode 100644 backend/prodSql/queries/datamart.openOrders.sql diff --git a/README.md b/README.md index 31730db..79fe791 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Quick summary of current rewrite/migration goal. | User Profile | ~~Edit profile~~, upload avatar | 🟨 In Progress | | User Admin | Edit user, create user, remove user, alplaprod user integration | ⏳ Not Started | | Notifications | ~~Subscribe~~, ~~Create~~, ~~Update~~, ~~~~Remove~~, Manual Trigger | 🟨 In Progress | -| Datamart | Create, Update, Run, Deactivate | 🔧 In Progress | +| Datamart | ~~Create~~, ~~Update~~, ~~Run~~, Deactivate | 🟨 In Progress | | Frontend | Analytics and charts | ⏳ Not Started | | Docs | Instructions and trouble shooting | ⏳ Not Started | | One Click Print | Get printers, monitor printers, label process, material process, Special processes | ⏳ Not Started | diff --git a/backend/datamart/datamart.controller.ts b/backend/datamart/datamart.controller.ts index 8a204d2..da36462 100644 --- a/backend/datamart/datamart.controller.ts +++ b/backend/datamart/datamart.controller.ts @@ -13,6 +13,7 @@ * * when a criteria is password over we will handle it by counting how many were passed up to 3 then deal with each one respectively */ +import { createLogger } from "../logger/logger.controller.js"; import { prodQuery } from "../prodSql/prodSqlQuery.controller.js"; import { type SqlQuery, @@ -22,37 +23,34 @@ import { returnFunc } from "../utils/returnHelper.utils.js"; import { tryCatch } from "../utils/trycatch.utils.js"; import { datamartData } from "./datamartData.utlis.js"; -type Options = { - name: string; - value: string; -}; type Data = { name: string; - options: Options; + options: any; optionsRequired?: boolean; howManyOptionsRequired?: number; }; +const log = createLogger({ module: "datamart", submodule: "queryRun" }); export const runDatamartQuery = async (data: Data) => { // search the query db for the query by name - const sqlQuery = sqlQuerySelector(`${data.name}`) as SqlQuery; + const sqlQuery = sqlQuerySelector(`datamart.${data.name}`) as SqlQuery; const getDataMartInfo = datamartData.filter((x) => x.endpoint === data.name); // const optionsMissing = // !data.options || Object.keys(data.options).length === 0; - const optionCount = - Object.keys(data.options).length === - getDataMartInfo[0]?.howManyOptionsRequired; + const isValid = + Object.keys(data.options ?? {}).length >= + (getDataMartInfo[0]?.howManyOptionsRequired ?? 0); - if (getDataMartInfo[0]?.optionsRequired && !optionCount) { + if (getDataMartInfo[0]?.optionsRequired && !isValid) { return returnFunc({ success: false, level: "error", module: "datamart", subModule: "query", - message: `This query is required to have the ${getDataMartInfo[0]?.howManyOptionsRequired} options set in order use it.`, + message: `This query is required to have ${getDataMartInfo[0]?.howManyOptionsRequired} option(s) set in order use it, please add in your option(s) data and try again.`, data: [getDataMartInfo[0].options], notify: false, }); @@ -75,10 +73,64 @@ export const runDatamartQuery = async (data: Data) => { // split the criteria by "," then and then update the query if (data.options) { - Object.entries(data.options ?? {}).forEach(([key, value]) => { - const pattern = new RegExp(`\\[${key.trim()}\\]`, "g"); - datamartQuery = datamartQuery.replace(pattern, String(value).trim()); - }); + switch (data.name) { + case "activeArticles": + break; + case "deliveryByDateRange": + datamartQuery = datamartQuery + .replace("[startDate]", `${data.options.startDate}`) + .replace("[endDate]", `${data.options.endDate}`); + + break; + case "customerInventory": + datamartQuery = datamartQuery + .replace( + "--and IdAdressen", + `and IdAdressen in (${data.options.customer})`, + ) + .replace( + "--and x.IdWarenlager in (0)", + `${data.options.whseToInclude ? `and x.IdWarenlager in (${data.options.whseToInclude})` : `--and x.IdWarenlager in (0)`}`, + ); + break; + case "openOrders": + datamartQuery = datamartQuery + .replace("[startDay]", `${data.options.startDay}`) + .replace("[endDay]", `${data.options.endDay}`); + break; + case "inventory": + datamartQuery = datamartQuery + .replaceAll( + "--,l.RunningNumber", + `${data.options.includeRunningNumbers ? `,l.RunningNumber` : `--,l.RunningNumber`}`, + ) + .replaceAll( + "--,l.MachineLocation,l.MachineName,l.ProductionLotRunningNumber", + `${data.options.lots ? `,l.MachineLocation,l.MachineName,l.ProductionLotRunningNumber` : `--,l.MachineLocation,l.MachineName,l.ProductionLotRunningNumber`}`, + ) + .replaceAll( + "--,l.WarehouseDescription,l.LaneDescription", + `${data.options.locations ? `,l.WarehouseDescription,l.LaneDescription` : `--,l.WarehouseDescription,l.LaneDescription`}`, + ); + break; + case "fakeEDIUpdate": + datamartQuery = datamartQuery.replace( + "--AND h.CustomerHumanReadableId in (0)", + `${data.options.address ? `AND h.CustomerHumanReadableId in (${data.options.address})` : `--AND h.CustomerHumanReadableId in (0)`}`, + ); + + break; + default: + return returnFunc({ + success: false, + level: "error", + module: "datamart", + subModule: "query", + message: `${data.name} encountered an error as it might not exist in LST please contact support if this continues to happen`, + data: [sqlQuery.message], + notify: true, + }); + } } const { data: queryRun, error } = await tryCatch( diff --git a/backend/datamart/datamartData.utlis.ts b/backend/datamart/datamartData.utlis.ts index e149cf0..0e09009 100644 --- a/backend/datamart/datamartData.utlis.ts +++ b/backend/datamart/datamartData.utlis.ts @@ -10,15 +10,43 @@ export const datamartData = [ name: "Active articles", endpoint: "activeArticles", description: "returns all active articles for the server with custom data", - options: "", // set as a string and each item will be seperated by a , this way we can split it later in the excel file. + options: "", optionsRequired: false, }, { name: "Delivery by date range", endpoint: "deliveryByDateRange", - description: `Returns all Deliverys in selected date range IE: 1/1/${new Date(Date.now()).getFullYear()} to 1/31/${new Date(Date.now()).getFullYear()}`, - options: "startDate,endDate", // set as a string and each item will be seperated by a , this way we can split it later in the excel file. + description: `Returns all Deliveries in selected date range IE: 1/1/${new Date(Date.now()).getFullYear()} to 1/31/${new Date(Date.now()).getFullYear()}`, + options: "startDate,endDate", optionsRequired: true, howManyOptionsRequired: 2, }, + { + name: "Get Customer Inventory", + endpoint: "customerInventory", + description: `Returns specific customer inventory based on there address ID, IE: 8,12,145. \nWith option to include specific warehousesIds, IE 36,41,5. \nNOTES: *leaving warehouse blank will just pull everything for the customer, Inventory dose not include PPOO or INV`, + options: "customer,whseToInclude", + optionsRequired: true, + howManyOptionsRequired: 1, + }, + { + name: "Get open order", + endpoint: "openOrders", + description: `Returns open orders based on day count sent over, IE: startDay 15 days in the past endDay 5 days in the future, can be left empty for this default days`, + options: "startDay,endDay", + optionsRequired: true, + howManyOptionsRequired: 2, + }, + { + name: "Get inventory", + endpoint: "inventory", + description: `Returns all inventory, excludes inv location. adding an x in one of the options will enable it.`, + options: "includeRunningNumbers,locations,lots", + }, + { + name: "Fake EDI Update", + endpoint: "fakeEDIUpdate", + description: `Returns all open orders to correct and resubmit via lst demand mgt, leaving blank will get everything putting an address only returns the specified address. \nNOTE: only orders that were created via edi will populate here.`, + options: "address", + }, ]; diff --git a/backend/prodSql/queries/activeArticles.sql b/backend/prodSql/queries/datamart.activeArticles.sql similarity index 100% rename from backend/prodSql/queries/activeArticles.sql rename to backend/prodSql/queries/datamart.activeArticles.sql diff --git a/backend/prodSql/queries/datamart.customerInventory.sql b/backend/prodSql/queries/datamart.customerInventory.sql new file mode 100644 index 0000000..9f18902 --- /dev/null +++ b/backend/prodSql/queries/datamart.customerInventory.sql @@ -0,0 +1,45 @@ +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 +x.IdWarenlager not in (6, 1) +--and IdAdressen +--and x.IdWarenlager in (0) + + +group by x.IdArtikelVarianten +,ArtikelVariantenAlias +,IdProdPlanung +--,c.Description +,IdAdressen +,x.AdressBez +--, x.Lfdnr +order by x.IdArtikelVarianten \ No newline at end of file diff --git a/backend/prodSql/queries/deliveryByDateRange.sql b/backend/prodSql/queries/datamart.deliveryByDateRange.sql similarity index 100% rename from backend/prodSql/queries/deliveryByDateRange.sql rename to backend/prodSql/queries/datamart.deliveryByDateRange.sql diff --git a/backend/prodSql/queries/datamart.fakeEDIUpdate.sql b/backend/prodSql/queries/datamart.fakeEDIUpdate.sql new file mode 100644 index 0000000..81316fe --- /dev/null +++ b/backend/prodSql/queries/datamart.fakeEDIUpdate.sql @@ -0,0 +1,29 @@ +use [test1_AlplaPROD2.0_Read] + +select +customerartno as CustomerArticleNumber +,h.CustomerOrderNumber as CustomerOrderNumber +,l.CustomerLineItemNumber as CustomerLineNumber +,r.CustomerReleaseNumber as CustomerRealeaseNumber +,r.Quantity +,format(r.DeliveryDate, 'MM/dd/yyyy HH:mm') as DeliveryDate +,h.CustomerHumanReadableId as CustomerID +,r.Remark +--,* +from [order].[Release] as r (nolock) + +left join +[order].LineItem as l (nolock) on +l.id = r.LineItemId + +left join +[order].Header as h (nolock) on +h.id = l.HeaderId + +WHERE releaseState not in (1, 2, 3, 4) +AND h.CreatedByEdi = 1 +AND r.deliveryDate < getdate() + 1 +--AND h.CustomerHumanReadableId in (0) + + +order by r.deliveryDate \ No newline at end of file diff --git a/backend/prodSql/queries/datamart.inventory.sql b/backend/prodSql/queries/datamart.inventory.sql new file mode 100644 index 0000000..0570b3b --- /dev/null +++ b/backend/prodSql/queries/datamart.inventory.sql @@ -0,0 +1,44 @@ +select +ArticleHumanReadableId as av +,ArticleAlias as alias +,round(sum(QuantityLoadingUnits),0) total_pallets +,round(sum(Quantity),0) as total_palletQTY +,round(sum(case when State = 0 then QuantityLoadingUnits else 0 end),0) avalible_Pallets +,round(sum(case when State = 0 then Quantity else 0 end),0) available_QTY +,sum(case when b.HumanReadableId = 864 then QuantityLoadingUnits else 0 end) as coa_Pallets +,sum(case when b.HumanReadableId = 864 then Quantity else 0 end) as coa_QTY +,sum(case when b.HumanReadableId <> 864 then QuantityLoadingUnits else 0 end) as held_Pallets +,sum(case when b.HumanReadableId <> 864 then Quantity else 0 end) as held_QTY +--,l.RunningNumber +/** should be in line **/ +--,l.MachineLocation,l.MachineName,l.ProductionLotRunningNumber +/** should be in line **/ +--,l.WarehouseDescription,l.LaneDescription +,articleTypeName + +FROM [test1_AlplaPROD2.0_Read].[warehousing].[WarehouseUnit] as l +left join +( +SELECT [Id] + ,[HumanReadableId] + ,d.[Description] + ,[DefectGroupId] + ,[IsActive] + FROM [test1_AlplaPROD2.0_Read].[blocking].[BlockingDefect] as g + + left join + [AlplaPROD_test1].dbo.[T_BlockingDefects] as d (nolock) on + d.IdGlobalBlockingDefect = g.HumanReadableId +) as b on +b.id = l.MainDefectId +where LaneHumanReadableId not in (20000,21000) +group by ArticleHumanReadableId, +ArticleAlias, +ArticleTypeName +--,l.RunningNumber +/** should be in line **/ +--,l.MachineLocation,l.MachineName,l.ProductionLotRunningNumber +/** should be in line **/ +--,l.WarehouseDescription,l.LaneDescription + +order by ArticleHumanReadableId \ No newline at end of file diff --git a/backend/prodSql/queries/datamart.openOrders.sql b/backend/prodSql/queries/datamart.openOrders.sql new file mode 100644 index 0000000..961f3e5 --- /dev/null +++ b/backend/prodSql/queries/datamart.openOrders.sql @@ -0,0 +1,33 @@ +use [test1_AlplaPROD2.0_Read] + +select +customerartno +,r.ArticleHumanReadableId as article +,r.ArticleAlias as articleAlias +,ReleaseNumber +,h.CustomerOrderNumber as header +,l.CustomerLineItemNumber as lineItem +,r.CustomerReleaseNumber as releaseNumber +,r.LoadingUnits +,r.Quantity +,r.TradeUnits +,h.CustomerHumanReadableId +,r.DeliveryAddressDescription +,format(r.LoadingDate, 'MM/dd/yyyy HH:mm') as loadingDate +,format(r.DeliveryDate, 'MM/dd/yyyy HH:mm') as deliveryDate +,r.Remark +--,* +from [order].[Release] as r (nolock) + +left join +[order].LineItem as l (nolock) on +l.id = r.LineItemId + +left join +[order].Header as h (nolock) on +h.id = l.HeaderId + +WHERE releasestate not in (1, 2, 4) +AND r.deliverydate between getDate() + -[startDay] and getdate() + [endDay] + +order by r.deliverydate \ No newline at end of file