diff --git a/svc/product_series_auto_scheduler.go b/svc/product_series_auto_scheduler.go index e888fce..20f5807 100644 --- a/svc/product_series_auto_scheduler.go +++ b/svc/product_series_auto_scheduler.go @@ -118,6 +118,38 @@ func productSeriesFallbackOverrideExisting() bool { return raw == "1" || raw == "true" || raw == "on" || raw == "yes" } +func productSeriesDebugMatch(v productSeriesAutoVariant) bool { + p := strings.TrimSpace(os.Getenv("PRODUCT_SERIES_DEBUG_PRODUCT")) + if p != "" && !strings.EqualFold(strings.TrimSpace(v.ProductCode), p) { + return false + } + c := strings.TrimSpace(os.Getenv("PRODUCT_SERIES_DEBUG_COLOR")) + if c != "" && !strings.EqualFold(strings.TrimSpace(v.ColorCode), c) { + return false + } + d := strings.TrimSpace(os.Getenv("PRODUCT_SERIES_DEBUG_DIM3")) + if d != "" && !strings.EqualFold(strings.TrimSpace(v.Dim3Code), d) { + return false + } + return p != "" || c != "" || d != "" +} + +func productSeriesFormatSizeQty(m map[string]float64) string { + if len(m) == 0 { + return "{}" + } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + parts := make([]string, 0, len(keys)) + for _, k := range keys { + parts = append(parts, fmt.Sprintf("%s=%.0f", k, m[k])) + } + return "{" + strings.Join(parts, ",") + "}" +} + func productSeriesFallbackCode() string { code := strings.TrimSpace(os.Getenv("PRODUCT_SERIES_FALLBACK_SERIES_CODE")) if code == "" { @@ -507,7 +539,42 @@ func productSeriesApplyVariant(ctx context.Context, pg *sql.DB, v productSeriesA } return 0, 1, nil } + if productSeriesDebugMatch(v) { + log.Printf("[ProductSeriesDebug] variant product=%s color=%s dim3=%s mmitem_id=%d dim1=%d dim3_id=%v group=%s total=%.0f sizes=%s", + strings.TrimSpace(v.ProductCode), + strings.TrimSpace(v.ColorCode), + strings.TrimSpace(v.Dim3Code), + mmitemID, + dim1ID, + func() any { + if dim3ID.Valid { + return dim3ID.Int64 + } + return nil + }(), + strings.TrimSpace(v.GroupKey), + math.Round(v.TotalQty), + productSeriesFormatSizeQty(v.SizeQty), + ) + } selected := productSeriesSelectRules(v, rules) + if productSeriesDebugMatch(v) { + if len(selected) == 0 { + log.Printf("[ProductSeriesDebug] selected=0 product=%s color=%s dim3=%s", strings.TrimSpace(v.ProductCode), strings.TrimSpace(v.ColorCode), strings.TrimSpace(v.Dim3Code)) + } else { + ids := make([]string, 0, len(selected)) + for _, r := range selected { + ids = append(ids, fmt.Sprintf("%d", r.SeriesID)) + } + log.Printf("[ProductSeriesDebug] selected=%d product=%s color=%s dim3=%s series_ids=%s", + len(selected), + strings.TrimSpace(v.ProductCode), + strings.TrimSpace(v.ColorCode), + strings.TrimSpace(v.Dim3Code), + strings.Join(ids, ","), + ) + } + } if len(selected) == 0 { fallbackID, fallbackCode, err := productSeriesResolveFallbackSeries(ctx, pg) if err != nil {