package routes import ( "bssapp-backend/auth" "bssapp-backend/db" "database/sql" "encoding/json" "errors" "net/http" "strings" "time" "github.com/gorilla/mux" ) type ProductionUpdateLine struct { OrderLineID string `json:"OrderLineID"` ItemTypeCode int16 `json:"ItemTypeCode"` ItemCode string `json:"ItemCode"` ColorCode string `json:"ColorCode"` ItemDim1Code string `json:"ItemDim1Code"` ItemDim2Code string `json:"ItemDim2Code"` ItemDim3Code string `json:"ItemDim3Code"` LineDescription string `json:"LineDescription"` } type ProductionUpdateRequest struct { Lines []ProductionUpdateLine `json:"lines"` InsertMissing bool `json:"insertMissing"` } type MissingVariant struct { ItemTypeCode int16 `json:"ItemTypeCode"` ItemCode string `json:"ItemCode"` ColorCode string `json:"ColorCode"` ItemDim1Code string `json:"ItemDim1Code"` ItemDim2Code string `json:"ItemDim2Code"` ItemDim3Code string `json:"ItemDim3Code"` } // ====================================================== // 📌 OrderProductionUpdateRoute — U ürün satırlarını güncelle // ====================================================== func OrderProductionUpdateRoute(mssql *sql.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") id := mux.Vars(r)["id"] if id == "" { http.Error(w, "OrderHeaderID bulunamadı", http.StatusBadRequest) return } var req ProductionUpdateRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Geçersiz JSON", http.StatusBadRequest) return } if len(req.Lines) == 0 { http.Error(w, "Satır bulunamadı", http.StatusBadRequest) return } claims, _ := auth.GetClaimsFromContext(r.Context()) username := "" if claims != nil { username = claims.Username } if username == "" { username = "system" } tx, err := db.MssqlDB.Begin() if err != nil { http.Error(w, "İşlem başlatılamadı", http.StatusInternalServerError) return } defer tx.Rollback() // 1) Eksik varyantları kontrol et missingMap := make(map[string]MissingVariant) checkStmt, err := tx.Prepare(` SELECT TOP 1 1 FROM dbo.prItemVariant WHERE ItemTypeCode = @p1 AND ItemCode = @p2 AND ColorCode = @p3 AND ISNULL(ItemDim1Code,'') = ISNULL(@p4,'') AND ISNULL(ItemDim2Code,'') = ISNULL(@p5,'') AND ISNULL(ItemDim3Code,'') = ISNULL(@p6,'') `) if err != nil { http.Error(w, "Varyant kontrolü hazırlanamadı", http.StatusInternalServerError) return } defer checkStmt.Close() for _, ln := range req.Lines { if strings.TrimSpace(ln.ItemCode) == "" { http.Error(w, "Yeni model kodu boş", http.StatusBadRequest) return } row := checkStmt.QueryRow( ln.ItemTypeCode, ln.ItemCode, ln.ColorCode, ln.ItemDim1Code, ln.ItemDim2Code, ln.ItemDim3Code, ) var ok int if err := row.Scan(&ok); err != nil { if errors.Is(err, sql.ErrNoRows) { key := strings.Join([]string{ ln.ItemCode, ln.ColorCode, ln.ItemDim1Code, ln.ItemDim2Code, ln.ItemDim3Code, }, "|") missingMap[key] = MissingVariant{ ItemTypeCode: ln.ItemTypeCode, ItemCode: ln.ItemCode, ColorCode: ln.ColorCode, ItemDim1Code: ln.ItemDim1Code, ItemDim2Code: ln.ItemDim2Code, ItemDim3Code: ln.ItemDim3Code, } continue } http.Error(w, "Varyant kontrolü hatası", http.StatusInternalServerError) return } } if len(missingMap) > 0 && !req.InsertMissing { missing := make([]MissingVariant, 0, len(missingMap)) for _, v := range missingMap { missing = append(missing, v) } w.WriteHeader(http.StatusConflict) _ = json.NewEncoder(w).Encode(map[string]any{ "missing": missing, }) return } // 2) Eksikleri ekle (gerekirse) if len(missingMap) > 0 { // PLU üretimi (max + row_number) var basePlu int64 if err := tx.QueryRow(`SELECT ISNULL(MAX(PLU),0) FROM dbo.prItemVariant WITH (UPDLOCK, HOLDLOCK)`).Scan(&basePlu); err != nil { http.Error(w, "PLU alınamadı", http.StatusInternalServerError) return } now := time.Now() i := int64(0) for _, v := range missingMap { i++ if _, err := tx.Exec(` INSERT INTO dbo.prItemVariant ( ItemTypeCode, ItemCode, ColorCode, ItemDim1Code, ItemDim2Code, ItemDim3Code, PLU, CreatedUserName, CreatedDate, LastUpdatedUserName, LastUpdatedDate ) VALUES (@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9,@p8,@p9) `, v.ItemTypeCode, v.ItemCode, v.ColorCode, v.ItemDim1Code, v.ItemDim2Code, v.ItemDim3Code, basePlu+i, username, now, ); err != nil { http.Error(w, "Varyant insert hatası", http.StatusInternalServerError) return } } } // 3) trOrderLine güncelle updStmt, err := tx.Prepare(` UPDATE dbo.trOrderLine SET ItemCode = @p1, ColorCode = @p2, ItemDim2Code = @p3, LineDescription = @p4, LastUpdatedUserName = @p5, LastUpdatedDate = @p6 WHERE OrderHeaderID = @p7 AND OrderLineID = @p8 `) if err != nil { http.Error(w, "Update hazırlığı başarısız", http.StatusInternalServerError) return } defer updStmt.Close() now := time.Now() for _, ln := range req.Lines { if _, err := updStmt.Exec( ln.ItemCode, ln.ColorCode, ln.ItemDim2Code, ln.LineDescription, username, now, id, ln.OrderLineID, ); err != nil { http.Error(w, "Satır güncelleme hatası", http.StatusInternalServerError) return } } if err := tx.Commit(); err != nil { http.Error(w, "Commit hatası", http.StatusInternalServerError) return } _ = json.NewEncoder(w).Encode(map[string]any{ "status": "ok", "updated": len(req.Lines), }) }) }