From 92f677ae3ee9e45135d8ea53d0c5cbe77f25760e Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Tue, 31 Mar 2026 15:25:20 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/queries/order_write.go | 97 ++++++++++++++++++++++---------------- svc/routes/order_mail.go | 21 +++++++-- svc/routes/order_pdf.go | 31 ++++++++---- 3 files changed, 97 insertions(+), 52 deletions(-) diff --git a/svc/queries/order_write.go b/svc/queries/order_write.go index fbd7b53..0b1fb62 100644 --- a/svc/queries/order_write.go +++ b/svc/queries/order_write.go @@ -533,6 +533,50 @@ func loadVariantDim1SetTx(tx *sql.Tx, item, color, dim2 string) (map[string]stru return set, nil } +func loadVariantDim1SetDB(conn *sql.DB, item, color, dim2 string) (map[string]struct{}, error) { + rows, err := conn.Query(` + SELECT ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') AS ItemDim1Code + FROM BAGGI_V3.dbo.prItemVariant V WITH (NOLOCK) + WHERE ISNULL(LTRIM(RTRIM(V.ItemCode)),'') = @p1 + AND ( + ( + ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 + AND ( + ISNULL(LTRIM(RTRIM(@p3)),'') = '' + OR ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p3 + ) + ) + OR ( + ISNULL(LTRIM(RTRIM(@p3)),'') = '' + AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p2 + ) + ) + `, item, color, dim2) + if err != nil { + return nil, fmt.Errorf("variant set query hatası: %w", err) + } + defer rows.Close() + + set := make(map[string]struct{}) + for rows.Next() { + var raw string + if err := rows.Scan(&raw); err != nil { + return nil, fmt.Errorf("variant set scan hatası: %w", err) + } + norm := normalizeDim1Token(raw) + if norm != "" { + set[norm] = struct{}{} + } + if num := normalizeNumericToken(norm); num != "" { + set["#NUM:"+num] = struct{}{} + } + } + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("variant set rows hatası: %w", err) + } + return set, nil +} + // ======================================================= // AKSBIR DETECTION // ======================================================= @@ -641,43 +685,8 @@ func ValidateOrderVariants(db *sql.DB, lines []models.OrderDetail) ([]models.Inv return s } - stmt, err := db.Prepare(` - SELECT CASE WHEN EXISTS ( - SELECT 1 - FROM BAGGI_V3.dbo.prItemVariant V WITH (NOLOCK) - CROSS APPLY ( - SELECT UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')) AS Dim1Norm - ) X - WHERE ISNULL(LTRIM(RTRIM(V.ItemCode)),'') = @p1 - AND ( - ( - ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 - AND ( - ISNULL(LTRIM(RTRIM(@p4)),'') = '' - OR ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p4 - ) - ) - OR ( - ISNULL(LTRIM(RTRIM(@p4)),'') = '' - AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p2 - ) - ) - AND ( - X.Dim1Norm = @p3 - OR ( - ISNULL(LTRIM(RTRIM(@p5)),'') <> '' - AND X.Dim1Norm NOT LIKE '%[^0-9]%' - AND SUBSTRING(X.Dim1Norm, PATINDEX('%[^0]%', X.Dim1Norm + '0'), LEN(X.Dim1Norm)) = @p5 - ) - ) - ) THEN 1 ELSE 0 END - `) - if err != nil { - return nil, fmt.Errorf("validate prepare hatası: %w", err) - } - defer stmt.Close() - invalid := make([]models.InvalidVariant, 0) + cache := make(map[string]map[string]struct{}) for i, ln := range lines { qty := qtyValue(ln.Qty1) @@ -708,12 +717,20 @@ func ValidateOrderVariants(db *sql.DB, lines []models.OrderDetail) ([]models.Inv continue } - var exists int - if err := stmt.QueryRow(item, color, dim1Norm, dim2, dim1Numeric).Scan(&exists); err != nil { - return nil, fmt.Errorf("validate query hatası (i=%d): %w", i, err) + key := variantCacheKey(item, color, dim2) + set := cache[key] + if set == nil { + var err error + set, err = loadVariantDim1SetDB(db, item, color, dim2) + if err != nil { + return nil, fmt.Errorf("validate query hatası (i=%d): %w", i, err) + } + cache[key] = set } - if exists != 1 { + _, okNorm := set[dim1Norm] + _, okNum := set["#NUM:"+dim1Numeric] + if !(okNorm || (dim1Numeric != "" && okNum)) { invalid = append(invalid, models.InvalidVariant{ Index: i, ClientKey: safeNS(ln.ClientKey), diff --git a/svc/routes/order_mail.go b/svc/routes/order_mail.go index c7b6d61..5081f85 100644 --- a/svc/routes/order_mail.go +++ b/svc/routes/order_mail.go @@ -271,9 +271,24 @@ func buildOrderPDFBytesForMail(db *sql.DB, pgDB *sql.DB, orderID string) ([]byte return nil, nil, err } rows := normalizeOrderLinesForPdf(lines, sizeMatchData) - for _, rr := range rows { - if strings.TrimSpace(rr.Category) == "" { - return nil, nil, fmt.Errorf("product-size-match unmapped row: %s/%s/%s", rr.Model, rr.GroupMain, rr.GroupSub) + for i := range rows { + if strings.TrimSpace(rows[i].Category) != "" { + continue + } + bedenList := make([]string, 0, len(rows[i].SizeQty)) + for s := range rows[i].SizeQty { + bedenList = append(bedenList, s) + } + rows[i].Category = detectBedenGroupGo( + sizeMatchData, + bedenList, + rows[i].GroupMain, + rows[i].GroupSub, + rows[i].YetiskinGarson, + rows[i].YetiskinGarson, + ) + if strings.TrimSpace(rows[i].Category) == "" { + rows[i].Category = catTak } } diff --git a/svc/routes/order_pdf.go b/svc/routes/order_pdf.go index 3c5024a..fa29ed7 100644 --- a/svc/routes/order_pdf.go +++ b/svc/routes/order_pdf.go @@ -464,9 +464,6 @@ func detectBedenGroupGo( if ruleBased != "" { return ruleBased } - if matchData != nil && len(matchData.Rules) > 0 { - return "" - } ana = normalizeTextForMatchGo(ana) alt = normalizeTextForMatchGo(alt) @@ -1793,15 +1790,31 @@ func OrderPDFHandler(db *sql.DB, pgDB *sql.DB) http.Handler { } rows := normalizeOrderLinesForPdf(lines, sizeMatchData) unmapped := make([]string, 0) - for _, rr := range rows { - if strings.TrimSpace(rr.Category) == "" { - unmapped = append(unmapped, fmt.Sprintf("%s/%s/%s", rr.Model, rr.GroupMain, rr.GroupSub)) + for i := range rows { + if strings.TrimSpace(rows[i].Category) != "" { + continue + } + bedenList := make([]string, 0, len(rows[i].SizeQty)) + for s := range rows[i].SizeQty { + bedenList = append(bedenList, s) + } + rows[i].Category = detectBedenGroupGo( + sizeMatchData, + bedenList, + rows[i].GroupMain, + rows[i].GroupSub, + rows[i].YetiskinGarson, + rows[i].YetiskinGarson, + ) + if strings.TrimSpace(rows[i].Category) == "" { + rows[i].Category = catTak + } + if strings.TrimSpace(rows[i].Category) == "" { + unmapped = append(unmapped, fmt.Sprintf("%s/%s/%s", rows[i].Model, rows[i].GroupMain, rows[i].GroupSub)) } } if len(unmapped) > 0 { - log.Printf("❌ OrderPDF product-size-match unmapped orderID=%s rows=%v", orderID, unmapped) - http.Error(w, "product-size-match unmapped rows", http.StatusInternalServerError) - return + log.Printf("⚠️ OrderPDF unmapped rows fallback failed orderID=%s rows=%v", orderID, unmapped) } log.Printf("📄 OrderPDF normalized rows orderID=%s rowCount=%d", orderID, len(rows)) for i, rr := range rows {