From 4aebb36ff2e25d54fbb953e3f79de744231e4bd5 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Fri, 3 Jul 2026 06:01:23 +0300 Subject: [PATCH] product performance grouped kpi improvements --- svc/queries/product_performance.go | 176 +++++++++++++++---------- svc/queries/product_performance_sql.go | 84 ++++++------ 2 files changed, 151 insertions(+), 109 deletions(-) diff --git a/svc/queries/product_performance.go b/svc/queries/product_performance.go index 39d75db..9cb7ba9 100644 --- a/svc/queries/product_performance.go +++ b/svc/queries/product_performance.go @@ -61,9 +61,9 @@ func productPerformanceStockQuery() string { ), Raw AS ( SELECT - ProductCode = LTRIM(RTRIM(S.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(S.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(S.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(S.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(S.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(S.ItemDim2Code, '')))), MovementDate = CAST(S.DocumentDate AS date), ProcessCode = CASE WHEN LTRIM(RTRIM(ISNULL(S.ProcessCode, ''))) <> '' THEN LTRIM(RTRIM(S.ProcessCode)) @@ -79,15 +79,15 @@ Raw AS ( AND ( LEN(LTRIM(RTRIM(S.ItemCode))) = 13 AND ( - S.ItemCode LIKE 'S%' - OR S.ItemCode LIKE 'O%' - OR S.ItemCode LIKE 'N%' - OR S.ItemCode LIKE 'X%' - OR S.ItemCode LIKE 'I%' - OR S.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'A%' ) ) - AND (@p3 = '' OR S.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE @p3 + '%') AND S.DocumentDate < DATEADD(DAY, 1, @p2) GROUP BY S.ItemCode, @@ -187,9 +187,9 @@ Running AS ( ), CurrentStock AS ( SELECT - ProductCode = LTRIM(RTRIM(S.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(S.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(S.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(S.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(S.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(S.ItemDim2Code, '')))), InventoryQty1 = SUM(S.In_Qty1 - S.Out_Qty1) FROM trStock S WITH(NOLOCK) INNER JOIN ActiveWarehouses W @@ -198,58 +198,58 @@ CurrentStock AS ( AND ( LEN(LTRIM(RTRIM(S.ItemCode))) = 13 AND ( - S.ItemCode LIKE 'S%' - OR S.ItemCode LIKE 'O%' - OR S.ItemCode LIKE 'N%' - OR S.ItemCode LIKE 'X%' - OR S.ItemCode LIKE 'I%' - OR S.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'A%' ) ) - AND (@p3 = '' OR S.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE @p3 + '%') AND S.DocumentDate < DATEADD(DAY, 1, @p2) GROUP BY S.ItemCode, S.ColorCode, S.ItemDim2Code ), CurrentPick AS ( SELECT - ProductCode = LTRIM(RTRIM(P.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(P.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(P.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(P.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(P.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(P.ItemDim2Code, '')))), PickingQty1 = SUM(P.Qty1) FROM PickingStates P WITH(NOLOCK) INNER JOIN ActiveWarehouses W ON W.WarehouseCode = LTRIM(RTRIM(P.WarehouseCode)) WHERE P.ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(P.ItemCode))) = 13 - AND (@p3 = '' OR P.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(P.ItemCode))) LIKE @p3 + '%') GROUP BY P.ItemCode, P.ColorCode, P.ItemDim2Code ), CurrentReserve AS ( SELECT - ProductCode = LTRIM(RTRIM(R.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(R.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(R.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(R.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(R.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(R.ItemDim2Code, '')))), ReserveQty1 = SUM(R.Qty1) FROM ReserveStates R WITH(NOLOCK) INNER JOIN ActiveWarehouses W ON W.WarehouseCode = LTRIM(RTRIM(R.WarehouseCode)) WHERE R.ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(R.ItemCode))) = 13 - AND (@p3 = '' OR R.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(R.ItemCode))) LIKE @p3 + '%') GROUP BY R.ItemCode, R.ColorCode, R.ItemDim2Code ), CurrentDisp AS ( SELECT - ProductCode = LTRIM(RTRIM(D.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(D.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(D.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(D.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(D.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(D.ItemDim2Code, '')))), DispOrderQty1 = SUM(D.Qty1) FROM DispOrderStates D WITH(NOLOCK) INNER JOIN ActiveWarehouses W ON W.WarehouseCode = LTRIM(RTRIM(D.WarehouseCode)) WHERE D.ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(D.ItemCode))) = 13 - AND (@p3 = '' OR D.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(D.ItemCode))) LIKE @p3 + '%') GROUP BY D.ItemCode, D.ColorCode, D.ItemDim2Code ), CurrentAvailable AS ( @@ -678,6 +678,26 @@ func productPerformanceProductPrefix(raw string) string { } } +func normalizeProductPerformanceProductCode(raw string) string { + return strings.ToUpper(strings.TrimSpace(raw)) +} + +func normalizeProductPerformanceCode(raw string) string { + return strings.ToUpper(strings.TrimSpace(raw)) +} + +func normalizeProductPerformanceVariantCodes(productCode, colorCode, yakaKodu *string) { + if productCode != nil { + *productCode = normalizeProductPerformanceProductCode(*productCode) + } + if colorCode != nil { + *colorCode = normalizeProductPerformanceCode(*colorCode) + } + if yakaKodu != nil { + *yakaKodu = normalizeProductPerformanceCode(*yakaKodu) + } +} + func refreshProductPerformanceSales(ctx context.Context, tx *sql.Tx, startDate, endDate time.Time, productPrefix string) (int, error) { log.Printf("[ProductPerformanceRefresh] sales mssql query start start=%s end=%s prefix=%s", startDate.Format("2006-01-02"), endDate.Format("2006-01-02"), productPrefix) rows, err := db.MssqlDB.QueryContext(ctx, productPerformanceSalesSQL(), startDate, endDate, productPrefix) @@ -697,6 +717,7 @@ func refreshProductPerformanceSales(ctx context.Context, tx *sql.Tx, startDate, ); err != nil { return count, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) r.AskiliYan = cleanProductPerformanceOptionalAttr(r.AskiliYan) r.UrunIlkGrubu = cleanProductPerformanceFirstGroup(r.UrunIlkGrubu) if _, err := tx.ExecContext(ctx, ` @@ -761,6 +782,7 @@ func refreshProductPerformanceStock(ctx context.Context, tx *sql.Tx, startDate, ); err != nil { return count, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) if err := insertProductPerformanceStock(ctx, tx, r); err != nil { return count, err } @@ -828,6 +850,7 @@ func refreshProductPerformanceStockChunked(ctx context.Context, pg *sql.DB, star ); err != nil { return count, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) seen++ if resumeAfter > 0 && seen <= resumeAfter { if seen%50000 == 0 || seen == resumeAfter { @@ -894,6 +917,7 @@ func prepareProductPerformanceStockCopy(ctx context.Context, tx *sql.Tx) (*sql.S } func insertProductPerformanceStock(ctx context.Context, exec productPerformanceStockExec, r productPerformanceStockDaily) error { + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) _, err := exec.ExecContext(ctx, ` INSERT INTO mk_product_performance_stock_daily ( stock_date, product_code, color_code, yaka_kodu, stock_qty, in_qty, out_qty, @@ -936,6 +960,7 @@ func refreshProductPerformancePrices(ctx context.Context, tx *sql.Tx, productPre if err := rows.Scan(&code, &itemDescription, &kategori, &askiliYan, &urunIlkGrubu, &urunAnaGrubu, &urunAltGrubu, &cost, &usd, &tryPrice, &lastPricing); err != nil { return err } + code = normalizeProductPerformanceProductCode(code) askiliYan = cleanProductPerformanceOptionalAttr(askiliYan) urunIlkGrubu = cleanProductPerformanceFirstGroup(urunIlkGrubu) var lp any @@ -960,7 +985,7 @@ ON CONFLICT (product_code) DO UPDATE SET base_price_try=EXCLUDED.base_price_try, last_pricing_date=EXCLUDED.last_pricing_date, updated_at=now() -`, strings.TrimSpace(code), strings.TrimSpace(itemDescription), strings.TrimSpace(kategori), askiliYan, urunIlkGrubu, strings.TrimSpace(urunAnaGrubu), strings.TrimSpace(urunAltGrubu), cost, usd, tryPrice, lp); err != nil { +`, code, strings.TrimSpace(itemDescription), strings.TrimSpace(kategori), askiliYan, urunIlkGrubu, strings.TrimSpace(urunAnaGrubu), strings.TrimSpace(urunAltGrubu), cost, usd, tryPrice, lp); err != nil { return err } count++ @@ -1436,9 +1461,9 @@ WITH OpenOrderLines AS ( h.OrderHeaderID, h.OrderNumber, h.CurrAccCode, - ProductCode = LTRIM(RTRIM(l.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(l.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(l.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(l.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code, '')))), ItemDescription = dbo.HG_Temizlik(ISNULL(( SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) @@ -1575,12 +1600,12 @@ WITH OpenOrderLines AS ( AND ISNULL(l.Qty1, 0) > 0 AND LEN(LTRIM(RTRIM(l.ItemCode))) = 13 AND ( - l.ItemCode LIKE 'S%' - OR l.ItemCode LIKE 'O%' - OR l.ItemCode LIKE 'N%' - OR l.ItemCode LIKE 'X%' - OR l.ItemCode LIKE 'I%' - OR l.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'A%' ) ), Spread AS ( @@ -1644,6 +1669,7 @@ ORDER BY SUM(o.AmountUSD) DESC, SUM(o.Qty) DESC, o.ProductCode, o.ColorCode, o.Y ); err != nil { return nil, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) r.AskiliYan = cleanProductPerformanceOptionalAttr(r.AskiliYan) out = append(out, r) if !seenProducts[r.ProductCode] { @@ -1674,7 +1700,7 @@ ORDER BY SUM(o.AmountUSD) DESC, SUM(o.Qty) DESC, o.ProductCode, o.ColorCode, o.Y } for i := range out { row := &out[i] - price := priceByProduct[row.ProductCode] + price := priceByProduct[normalizeProductPerformanceProductCode(row.ProductCode)] attr := attrByKey[productPerformanceVariantKey(row.ProductCode, row.ColorCode, row.YakaKodu)] if strings.TrimSpace(row.ItemDescription) == "" { row.ItemDescription = attr.itemDescription @@ -1732,9 +1758,9 @@ WITH OpenOrderLines AS ( h.OrderHeaderID, h.CurrAccCode, CustomerName = ISNULL(cad.CurrAccDescription, ''), - ProductCode = LTRIM(RTRIM(l.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(l.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(l.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(l.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code, '')))), MarketKey = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdCurrAccAttributeDesc WITH(NOLOCK) @@ -1793,12 +1819,12 @@ WITH OpenOrderLines AS ( AND ISNULL(l.Qty1, 0) > 0 AND LEN(LTRIM(RTRIM(l.ItemCode))) = 13 AND ( - l.ItemCode LIKE 'S%' - OR l.ItemCode LIKE 'O%' - OR l.ItemCode LIKE 'N%' - OR l.ItemCode LIKE 'X%' - OR l.ItemCode LIKE 'I%' - OR l.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'A%' ) ) SELECT TOP (@p1) @@ -1845,6 +1871,7 @@ ORDER BY SUM(AmountUSD) DESC, SUM(Qty) DESC if err := rows.Scan(&d.productCode, &d.colorCode, &d.yakaKodu, &d.marketKey, &d.customerCode, &d.customerName, &d.orderQty, &d.orderUSD, &d.orderCount, &d.lineCount, &d.overdueQty); err != nil { return nil, err } + normalizeProductPerformanceVariantCodes(&d.productCode, &d.colorCode, &d.yakaKodu) details = append(details, d) if !seenProducts[d.productCode] { seenProducts[d.productCode] = true @@ -1901,7 +1928,7 @@ ORDER BY SUM(AmountUSD) DESC, SUM(Qty) DESC customerSets[groupKey] = map[string]bool{} stockVariantSets[groupKey] = map[string]bool{} } - price := priceByProduct[d.productCode] + price := priceByProduct[normalizeProductPerformanceProductCode(d.productCode)] variantKey := productPerformanceVariantKey(d.productCode, d.colorCode, d.yakaKodu) row.OrderQty += d.orderQty row.OrderUSD += d.orderUSD @@ -1972,9 +1999,9 @@ WITH OpenOrderLines AS ( h.OrderHeaderID, h.CurrAccCode, CustomerName = ISNULL(cad.CurrAccDescription, ''), - ProductCode = LTRIM(RTRIM(l.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(l.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(l.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(l.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code, '')))), ItemDescription = dbo.HG_Temizlik(ISNULL((SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) WHERE cdItemDesc.ItemTypeCode = l.ItemTypeCode AND cdItemDesc.ItemCode = l.ItemCode AND cdItemDesc.LangCode = 'TR'), SPACE(0))), MarketKey = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdCurrAccAttributeDesc WITH(NOLOCK) @@ -2006,7 +2033,7 @@ WITH OpenOrderLines AS ( AND l.ItemTypeCode = 1 AND ISNULL(l.Qty1, 0) > 0 AND LEN(LTRIM(RTRIM(l.ItemCode))) = 13 - AND (l.ItemCode LIKE 'S%' OR l.ItemCode LIKE 'O%' OR l.ItemCode LIKE 'N%' OR l.ItemCode LIKE 'X%' OR l.ItemCode LIKE 'I%' OR l.ItemCode LIKE 'A%') + AND (UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'S%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'O%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'N%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'X%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'I%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'A%') ) SELECT TOP (@p1) ProductCode, ColorCode, YakaKodu, MAX(ItemDescription), MarketKey, CurrAccCode, CustomerName, @@ -2030,6 +2057,7 @@ ORDER BY SUM(AmountUSD) DESC, SUM(Qty) DESC if err := rows.Scan(&r.ProductCode, &r.ColorCode, &r.YakaKodu, &r.ItemDescription, &r.MarketKey, &r.CustomerCode, &r.CustomerName, &r.OrderQty, &r.OrderUSD, &r.AvgOrderPriceUSD, &r.OrderCount, &r.LineCount, &r.OverdueQty); err != nil { return nil, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) out = append(out, r) if !seenProducts[r.ProductCode] { seenProducts[r.ProductCode] = true @@ -2058,7 +2086,7 @@ ORDER BY SUM(AmountUSD) DESC, SUM(Qty) DESC } for i := range out { row := &out[i] - price := priceByProduct[row.ProductCode] + price := priceByProduct[normalizeProductPerformanceProductCode(row.ProductCode)] attr := attrByKey[productPerformanceVariantKey(row.ProductCode, row.ColorCode, row.YakaKodu)] if strings.TrimSpace(row.ItemDescription) == "" { row.ItemDescription = attr.itemDescription @@ -2104,9 +2132,9 @@ WITH OpenOrderLines AS ( h.OrderNumber, OrderDate = CAST(h.OrderDate AS date), DueDate = CAST(ISNULL(l.DeliveryDate, h.AverageDueDate) AS date), - ProductCode = LTRIM(RTRIM(l.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(l.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(l.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(l.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code, '')))), ItemDescription = dbo.HG_Temizlik(ISNULL((SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) WHERE cdItemDesc.ItemTypeCode = l.ItemTypeCode AND cdItemDesc.ItemCode = l.ItemCode AND cdItemDesc.LangCode = 'TR'), SPACE(0))), Qty = ISNULL(l.Qty1, 0), AmountUSD = CASE @@ -2130,7 +2158,7 @@ WITH OpenOrderLines AS ( AND l.ItemTypeCode = 1 AND ISNULL(l.Qty1, 0) > 0 AND LEN(LTRIM(RTRIM(l.ItemCode))) = 13 - AND (l.ItemCode LIKE 'S%' OR l.ItemCode LIKE 'O%' OR l.ItemCode LIKE 'N%' OR l.ItemCode LIKE 'X%' OR l.ItemCode LIKE 'I%' OR l.ItemCode LIKE 'A%') + AND (UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'S%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'O%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'N%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'X%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'I%' OR UPPER(LTRIM(RTRIM(l.ItemCode))) LIKE 'A%') ) SELECT TOP (@p1) MarketKey, CurrAccCode, CustomerName, OrderNumber, CONVERT(varchar, OrderDate, 23), CONVERT(varchar, DueDate, 23), @@ -2155,6 +2183,7 @@ ORDER BY MarketKey, CustomerName, OrderDate DESC, OrderNumber, SUM(AmountUSD) DE if err := rows.Scan(&r.MarketKey, &r.CustomerCode, &r.CustomerName, &r.OrderNumber, &r.OrderDate, &r.DueDate, &r.ProductCode, &r.ColorCode, &r.YakaKodu, &r.ItemDescription, &r.OrderQty, &r.OrderUSD, &r.AvgOrderPriceUSD, &r.IsOverdue); err != nil { return nil, err } + normalizeProductPerformanceVariantCodes(&r.ProductCode, &r.ColorCode, &r.YakaKodu) out = append(out, r) if !seenProducts[r.ProductCode] { seenProducts[r.ProductCode] = true @@ -2179,7 +2208,7 @@ ORDER BY MarketKey, CustomerName, OrderDate DESC, OrderNumber, SUM(AmountUSD) DE } for i := range out { row := &out[i] - price := priceByProduct[row.ProductCode] + price := priceByProduct[normalizeProductPerformanceProductCode(row.ProductCode)] row.CostPriceUSD = price.cost row.BasePriceUSD = price.base row.StockQty = stockByKey[productPerformanceVariantKey(row.ProductCode, row.ColorCode, row.YakaKodu)] @@ -3947,7 +3976,7 @@ func productPerformanceWhere(f ProductPerformanceFilters) (string, []any) { idx := len(args) parts = append(parts, fmt.Sprintf(" AND (product_code ILIKE '%%' || $%d || '%%' OR item_description ILIKE '%%' || $%d || '%%')", idx, idx)) } - if v := strings.TrimSpace(f.ProductCode); v != "" { + if v := normalizeProductPerformanceProductCode(f.ProductCode); v != "" { add(" AND product_code = $%d", v) } if v := strings.TrimSpace(f.MarketKey); v != "" { @@ -4034,7 +4063,7 @@ type productPerformanceAttrInfo struct { } func productPerformanceVariantKey(productCode, colorCode, yakaKodu string) string { - return strings.TrimSpace(productCode) + "|" + strings.TrimSpace(colorCode) + "|" + strings.TrimSpace(yakaKodu) + return normalizeProductPerformanceProductCode(productCode) + "|" + strings.TrimSpace(colorCode) + "|" + strings.TrimSpace(yakaKodu) } func productPerformancePriceLookup(ctx context.Context, pg *sql.DB, productCodes []string) (map[string]productPerformancePriceInfo, error) { @@ -4042,11 +4071,24 @@ func productPerformancePriceLookup(ctx context.Context, pg *sql.DB, productCodes if len(productCodes) == 0 { return out, nil } + normalizedCodes := make([]string, 0, len(productCodes)) + seen := map[string]bool{} + for _, productCode := range productCodes { + code := normalizeProductPerformanceProductCode(productCode) + if code == "" || seen[code] { + continue + } + seen[code] = true + normalizedCodes = append(normalizedCodes, code) + } + if len(normalizedCodes) == 0 { + return out, nil + } rows, err := pg.QueryContext(ctx, ` SELECT product_code, COALESCE(cost_price_usd,0), COALESCE(base_price_usd,0) FROM mk_product_performance_price_dim WHERE product_code = ANY($1) -`, pq.Array(productCodes)) +`, pq.Array(normalizedCodes)) if err != nil { return nil, err } @@ -4057,7 +4099,7 @@ WHERE product_code = ANY($1) if err := rows.Scan(&productCode, &p.cost, &p.base); err != nil { return nil, err } - out[productCode] = p + out[normalizeProductPerformanceProductCode(productCode)] = p } return out, rows.Err() } diff --git a/svc/queries/product_performance_sql.go b/svc/queries/product_performance_sql.go index 29a90d9..27c3670 100644 --- a/svc/queries/product_performance_sql.go +++ b/svc/queries/product_performance_sql.go @@ -8,9 +8,9 @@ func productPerformanceSalesSQL() string { SalesDate = CAST(I.InvoiceDate AS date), I.InvoiceHeaderID, I.InvoiceNumber, - ProductCode = LTRIM(RTRIM(I.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(I.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(I.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(I.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(I.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(I.ItemDim2Code, '')))), ItemDescription = dbo.HG_Temizlik(ISNULL(( SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) @@ -165,15 +165,15 @@ func productPerformanceSalesSQL() string { AND ( LEN(LTRIM(RTRIM(I.ItemCode))) = 13 AND ( - I.ItemCode LIKE 'S%' - OR I.ItemCode LIKE 'O%' - OR I.ItemCode LIKE 'N%' - OR I.ItemCode LIKE 'X%' - OR I.ItemCode LIKE 'I%' - OR I.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE 'A%' ) ) - AND (@p3 = '' OR I.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE @p3 + '%') AND ( (I.CompanyCode = 1 AND I.ATAtt01 IN (1,2) AND I.ProcessCode IN ('WS','R')) OR (I.CompanyCode = 4 AND I.ProcessCode = 'R') @@ -234,9 +234,9 @@ func productPerformanceStockSQLUnused() string { ), Raw AS ( SELECT - ProductCode = LTRIM(RTRIM(S.ItemCode)), - ColorCode = LTRIM(RTRIM(ISNULL(S.ColorCode, ''))), - YakaKodu = LTRIM(RTRIM(ISNULL(S.ItemDim2Code, ''))), + ProductCode = UPPER(LTRIM(RTRIM(S.ItemCode))), + ColorCode = UPPER(LTRIM(RTRIM(ISNULL(S.ColorCode, '')))), + YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(S.ItemDim2Code, '')))), MovementDate = CAST(S.DocumentDate AS date), ProcessCode = CASE WHEN LTRIM(RTRIM(ISNULL(S.ProcessCode, ''))) <> '' THEN LTRIM(RTRIM(S.ProcessCode)) @@ -252,15 +252,15 @@ Raw AS ( AND ( LEN(LTRIM(RTRIM(S.ItemCode))) = 13 AND ( - S.ItemCode LIKE 'S%' - OR S.ItemCode LIKE 'O%' - OR S.ItemCode LIKE 'N%' - OR S.ItemCode LIKE 'X%' - OR S.ItemCode LIKE 'I%' - OR S.ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE 'A%' ) ) - AND (@p3 = '' OR S.ItemCode LIKE @p3 + '%') + AND (@p3 = '' OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE @p3 + '%') AND S.DocumentDate < DATEADD(DAY, 1, @p2) GROUP BY S.ItemCode, @@ -388,15 +388,15 @@ func productPerformancePriceSQL() string { AND ( LEN(LTRIM(RTRIM(ItemCode))) = 13 AND ( - ItemCode LIKE 'S%' - OR ItemCode LIKE 'O%' - OR ItemCode LIKE 'N%' - OR ItemCode LIKE 'X%' - OR ItemCode LIKE 'I%' - OR ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'A%' ) ) - AND (@p1 = '' OR ItemCode LIKE @p1 + '%') + AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') UNION SELECT DISTINCT ItemCode FROM trPriceListLine WITH(NOLOCK) @@ -404,15 +404,15 @@ func productPerformancePriceSQL() string { AND ( LEN(LTRIM(RTRIM(ItemCode))) = 13 AND ( - ItemCode LIKE 'S%' - OR ItemCode LIKE 'O%' - OR ItemCode LIKE 'N%' - OR ItemCode LIKE 'X%' - OR ItemCode LIKE 'I%' - OR ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'A%' ) ) - AND (@p1 = '' OR ItemCode LIKE @p1 + '%') + AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') UNION SELECT DISTINCT ItemCode FROM prItemBasePrice WITH(NOLOCK) @@ -420,15 +420,15 @@ func productPerformancePriceSQL() string { AND ( LEN(LTRIM(RTRIM(ItemCode))) = 13 AND ( - ItemCode LIKE 'S%' - OR ItemCode LIKE 'O%' - OR ItemCode LIKE 'N%' - OR ItemCode LIKE 'X%' - OR ItemCode LIKE 'I%' - OR ItemCode LIKE 'A%' + UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'S%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'O%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'N%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'X%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'I%' + OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE 'A%' ) ) - AND (@p1 = '' OR ItemCode LIKE @p1 + '%') + AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') ), LatestPrice AS ( SELECT @@ -475,7 +475,7 @@ Cost AS ( AND LTRIM(RTRIM(b.CurrencyCode)) = 'USD' ) SELECT - pc.ItemCode, + UPPER(LTRIM(RTRIM(pc.ItemCode))) AS ItemCode, ItemDescription = dbo.HG_Temizlik(ISNULL(( SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK)