Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -709,6 +709,11 @@ func productSeriesApplyVariant(ctx context.Context, pg *sql.DB, v productSeriesA
|
||||
return 0, 0, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// Tag the DB session for audit attribution (scheduler vs http handler).
|
||||
// This affects only statements in this transaction.
|
||||
_, _ = tx.ExecContext(ctx, `SELECT set_config('application_name', current_setting('application_name') || '|series-auto', true)`)
|
||||
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
DELETE FROM zbggseri
|
||||
WHERE mmitem_id=$1
|
||||
|
||||
@@ -449,12 +449,30 @@ func PostProductSeriesMappingsSaveHandler(pg *sql.DB) http.HandlerFunc {
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// Tag the DB session for audit attribution (http handler vs scheduler).
|
||||
// This affects only statements in this transaction.
|
||||
_, _ = tx.ExecContext(ctx, `SELECT set_config('application_name', current_setting('application_name') || '|series-save', true)`)
|
||||
|
||||
// Safety defaults:
|
||||
// - Don't allow accidental clearing when UI sends empty series_ids.
|
||||
// - Don't allow saving fallback code=1 from UI unless explicitly enabled.
|
||||
allowClear := strings.TrimSpace(strings.ToLower(r.URL.Query().Get("clear"))) == "true"
|
||||
allowFallback := strings.TrimSpace(strings.ToLower(r.URL.Query().Get("allow_fallback"))) == "true"
|
||||
|
||||
log.Printf("[ProductSeriesMappingsSave] items=%d allow_clear=%t allow_fallback=%t remote=%s ua=%s",
|
||||
len(req.Items), allowClear, allowFallback, strings.TrimSpace(r.RemoteAddr), strings.TrimSpace(r.UserAgent()))
|
||||
|
||||
var fallbackSeriesID int64 = 0
|
||||
_ = tx.QueryRowContext(ctx, `SELECT id FROM dfgrp WHERE master='zbggseri' AND code='1'`).Scan(&fallbackSeriesID)
|
||||
|
||||
saved := 0
|
||||
skipped := 0
|
||||
for _, item := range req.Items {
|
||||
code := strings.TrimSpace(item.ProductCode)
|
||||
color := strings.TrimSpace(item.ColorCode)
|
||||
dim3Token := strings.TrimSpace(item.Dim3Code)
|
||||
if code == "" || color == "" {
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
mmitemID, err := resolveMmitemIDTx(ctx, tx, code)
|
||||
@@ -477,6 +495,39 @@ func PostProductSeriesMappingsSaveHandler(pg *sql.DB) http.HandlerFunc {
|
||||
dim3ID = sql.NullInt64{Int64: id, Valid: true}
|
||||
}
|
||||
|
||||
// Normalize/validate series ids.
|
||||
seen := map[int64]struct{}{}
|
||||
seriesIDs := make([]int64, 0, len(item.SeriesIDs))
|
||||
for _, seriesID := range item.SeriesIDs {
|
||||
if seriesID <= 0 {
|
||||
continue
|
||||
}
|
||||
if fallbackSeriesID > 0 && seriesID == fallbackSeriesID && !allowFallback {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[seriesID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[seriesID] = struct{}{}
|
||||
seriesIDs = append(seriesIDs, seriesID)
|
||||
}
|
||||
|
||||
// Prevent accidental destructive writes from UI.
|
||||
if len(seriesIDs) == 0 && !allowClear {
|
||||
log.Printf("[ProductSeriesMappingsSave] skip_empty_series_ids product=%s color=%s dim3=%s", code, color, dim3Token)
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
|
||||
{
|
||||
out := make([]string, 0, len(seriesIDs))
|
||||
for _, id := range seriesIDs {
|
||||
out = append(out, fmt.Sprintf("%d", id))
|
||||
}
|
||||
log.Printf("[ProductSeriesMappingsSave] write product=%s color=%s dim3=%s series_ids=%s",
|
||||
code, color, dim3Token, strings.Join(out, ","))
|
||||
}
|
||||
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
DELETE FROM zbggseri
|
||||
WHERE mmitem_id=$1
|
||||
@@ -486,15 +537,7 @@ WHERE mmitem_id=$1
|
||||
http.Error(w, "Seri eslesmesi temizlenemedi: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
seen := map[int64]struct{}{}
|
||||
for _, seriesID := range item.SeriesIDs {
|
||||
if seriesID <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[seriesID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[seriesID] = struct{}{}
|
||||
for _, seriesID := range seriesIDs {
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
INSERT INTO zbggseri (mmitem_id, dim1, seri_id, dim3)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
@@ -510,7 +553,7 @@ VALUES ($1, $2, $3, $4)
|
||||
http.Error(w, "Seri eslesmeleri kaydedilemedi: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
writeJSON(w, map[string]any{"saved": saved})
|
||||
writeJSON(w, map[string]any{"saved": saved, "skipped": skipped})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user