package repository import ( "context" "database/sql" "fmt" "github.com/muyuqingfeng/iloom/washing-service/internal/model" ) type FinishedProductRepo struct { db *sql.DB } func NewFinishedProductRepo(db *sql.DB) *FinishedProductRepo { return &FinishedProductRepo{db: db} } func (r *FinishedProductRepo) List(ctx context.Context, companyID string) ([]model.FinishedProduct, error) { query := `SELECT id, company_id, product_name, fabric_code, color, color_code, weight, shrinkage_rate, washed_meters, stock_meters, stock_rolls, rolls, washing_cost, unit_cost, status, notes, product_id, washing_plan_id, warehouse_id, warehouse_location, created_by, created_at, updated_at FROM ilm_finished_product WHERE company_id = ? ORDER BY created_at DESC` rows, err := r.db.QueryContext(ctx, query, companyID) if err != nil { return nil, fmt.Errorf("list finished products: %w", err) } defer rows.Close() var products []model.FinishedProduct for rows.Next() { var fp model.FinishedProduct if err := rows.Scan( &fp.ID, &fp.CompanyID, &fp.ProductName, &fp.FabricCode, &fp.Color, &fp.ColorCode, &fp.Weight, &fp.ShrinkageRate, &fp.WashedMeters, &fp.StockMeters, &fp.StockRolls, &fp.Rolls, &fp.WashingCost, &fp.UnitCost, &fp.Status, &fp.Notes, &fp.ProductID, &fp.WashingPlanID, &fp.WarehouseID, &fp.WarehouseLocation, &fp.CreatedBy, &fp.CreatedAt, &fp.UpdatedAt, ); err != nil { return nil, fmt.Errorf("scan finished product: %w", err) } products = append(products, fp) } return products, nil } func (r *FinishedProductRepo) Create(ctx context.Context, tx *sql.Tx, fp *model.FinishedProduct) error { query := `INSERT INTO ilm_finished_product (id, company_id, product_name, fabric_code, color, color_code, weight, shrinkage_rate, washed_meters, stock_meters, stock_rolls, rolls, washing_cost, unit_cost, status, notes, product_id, washing_plan_id, warehouse_id, warehouse_location, created_by, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)` _, err := tx.ExecContext(ctx, query, fp.ID, fp.CompanyID, fp.ProductName, fp.FabricCode, fp.Color, fp.ColorCode, fp.Weight, fp.ShrinkageRate, fp.WashedMeters, fp.StockMeters, fp.StockRolls, fp.Rolls, fp.WashingCost, fp.UnitCost, fp.Status, fp.Notes, fp.ProductID, fp.WashingPlanID, fp.WarehouseID, fp.WarehouseLocation, fp.CreatedBy, fp.CreatedAt, fp.UpdatedAt, ) if err != nil { return fmt.Errorf("insert finished product: %w", err) } return nil } func (r *FinishedProductRepo) UpdateStock(ctx context.Context, tx *sql.Tx, id string, deltaMeters float64, deltaRolls int) error { query := `UPDATE ilm_finished_product SET stock_meters = stock_meters + ?, stock_rolls = stock_rolls + ?, updated_at = NOW() WHERE id = ?` _, err := tx.ExecContext(ctx, query, deltaMeters, deltaRolls, id) if err != nil { return fmt.Errorf("update finished product stock: %w", err) } return nil } func (r *FinishedProductRepo) CreateInventoryRecord(ctx context.Context, tx *sql.Tx, rec *model.FinishedProductInventoryRecord) error { query := `INSERT INTO ilm_finished_product_inventory (id, finished_product_id, company_id, record_type, rolls, meters, batch_no, notes, operator_id, warehouse_id, warehouse_location, washing_completion_id, related_order_id, related_order_type, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)` _, err := tx.ExecContext(ctx, query, rec.ID, rec.FinishedProductID, rec.CompanyID, rec.RecordType, rec.Rolls, rec.Meters, rec.BatchNo, rec.Notes, rec.OperatorID, rec.WarehouseID, rec.WarehouseLocation, rec.WashingCompletionID, rec.RelatedOrderID, rec.RelatedOrderType, rec.CreatedAt, ) if err != nil { return fmt.Errorf("insert inventory record: %w", err) } return nil } func (r *FinishedProductRepo) Count(ctx context.Context, companyID string) (int, error) { var count int err := r.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM ilm_finished_product WHERE company_id = ?`, companyID, ).Scan(&count) if err != nil { return 0, fmt.Errorf("count finished products: %w", err) } return count, nil } func (r *FinishedProductRepo) TotalStock(ctx context.Context, companyID string) (float64, error) { var total float64 err := r.db.QueryRowContext(ctx, `SELECT COALESCE(SUM(stock_meters), 0) FROM ilm_finished_product WHERE company_id = ?`, companyID, ).Scan(&total) if err != nil { return 0, fmt.Errorf("total stock: %w", err) } return total, nil }