package repository import ( "context" "database/sql" "time" ) type PlanSummary struct { ID string `json:"id"` PlanCode string `json:"plan_code"` ProductName string `json:"product_name"` FabricCode string `json:"fabric_code"` Color string `json:"color"` ColorCode string `json:"color_code"` TargetQuantity float64 `json:"target_quantity"` CompletedQuantity float64 `json:"completed_quantity"` Status string `json:"status"` Remark *string `json:"remark,omitempty"` StartTime *time.Time `json:"start_time,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` FactoryID string `json:"factory_id"` } type PlanRepo struct { db *sql.DB } func NewPlanRepo(db *sql.DB) *PlanRepo { return &PlanRepo{db: db} } func (r *PlanRepo) ListByFactory(ctx context.Context, factoryCompanyID string) ([]PlanSummary, error) { query := ` SELECT pp.id, pp.plan_code, pp.product_name, pp.fabric_code, pp.color, pp.color_code, pp.target_quantity, pp.completed_quantity, pp.status, pp.remark, pp.start_time, pp.created_at, pp.updated_at, pf.factory_id FROM ilm_production_plan pp JOIN ilm_plan_factory pf ON pp.id = pf.plan_id WHERE pf.factory_id = ? AND pf.factory_type = 'textile' ORDER BY pp.created_at DESC` rows, err := r.db.QueryContext(ctx, query, factoryCompanyID) if err != nil { return nil, err } defer rows.Close() var plans []PlanSummary for rows.Next() { var p PlanSummary if err := rows.Scan( &p.ID, &p.PlanCode, &p.ProductName, &p.FabricCode, &p.Color, &p.ColorCode, &p.TargetQuantity, &p.CompletedQuantity, &p.Status, &p.Remark, &p.StartTime, &p.CreatedAt, &p.UpdatedAt, &p.FactoryID, ); err != nil { return nil, err } plans = append(plans, p) } return plans, rows.Err() } func (r *PlanRepo) GetByID(ctx context.Context, planID string) (*PlanSummary, error) { query := ` SELECT pp.id, pp.plan_code, pp.product_name, pp.fabric_code, pp.color, pp.color_code, pp.target_quantity, pp.completed_quantity, pp.status, pp.remark, pp.start_time, pp.created_at, pp.updated_at, COALESCE(pf.factory_id, '') FROM ilm_production_plan pp LEFT JOIN ilm_plan_factory pf ON pp.id = pf.plan_id AND pf.factory_type = 'textile' WHERE pp.id = ?` var p PlanSummary err := r.db.QueryRowContext(ctx, query, planID).Scan( &p.ID, &p.PlanCode, &p.ProductName, &p.FabricCode, &p.Color, &p.ColorCode, &p.TargetQuantity, &p.CompletedQuantity, &p.Status, &p.Remark, &p.StartTime, &p.CreatedAt, &p.UpdatedAt, &p.FactoryID, ) if err != nil { return nil, err } return &p, nil } func (r *PlanRepo) CountByFactory(ctx context.Context, factoryCompanyID string) (total, active, completed int, err error) { query := ` SELECT COUNT(*), COALESCE(SUM(CASE WHEN pp.status IN ('pending', 'in_progress') THEN 1 ELSE 0 END), 0), COALESCE(SUM(CASE WHEN pp.status = 'completed' THEN 1 ELSE 0 END), 0) FROM ilm_production_plan pp JOIN ilm_plan_factory pf ON pp.id = pf.plan_id WHERE pf.factory_id = ? AND pf.factory_type = 'textile'` err = r.db.QueryRowContext(ctx, query, factoryCompanyID).Scan(&total, &active, &completed) return }