118 lines
4.4 KiB
Go
118 lines
4.4 KiB
Go
|
|
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
|
||
|
|
}
|