material_manage_system/internal/repository/inbound.go
2026-09-21 14:13:30 +08:00

250 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"database/sql"
"time"
"github.com/wmms/wmms/internal/model"
"github.com/wmms/wmms/pkg/database"
)
type InboundRepo struct{}
func NewInboundRepo() *InboundRepo {
return &InboundRepo{}
}
func (r *InboundRepo) Create(order *model.InboundOrder) error {
return r.CreateTx(nil, order)
}
func (r *InboundRepo) CreateTx(tx *sql.Tx, order *model.InboundOrder) error {
shouldCommit := false
if tx == nil {
var err error
tx, err = database.DB.Begin()
if err != nil {
return err
}
shouldCommit = true
}
if shouldCommit {
defer tx.Rollback()
}
query := `INSERT INTO inbound_orders (inbound_date, operator, handler, supplier, remark) VALUES (?, ?, ?, ?, ?)`
result, err := tx.Exec(query, order.InboundDate, order.Operator, order.Handler, order.Supplier, order.Remark)
if err != nil {
return err
}
orderID, err := result.LastInsertId()
if err != nil {
return err
}
order.ID = orderID
order.InboundNo = model.OrderNo("IN", orderID)
if _, err = tx.Exec(`UPDATE inbound_orders SET inbound_no = ? WHERE id = ?`, order.InboundNo, orderID); err != nil {
return err
}
for i := range order.Items {
item := &order.Items[i]
item.InboundOrderID = orderID
query := `INSERT INTO inbound_items (inbound_order_id, material_id, quantity) VALUES (?, ?, ?)`
result, err := tx.Exec(query, orderID, item.MaterialID, item.Quantity)
if err != nil {
return err
}
itemID, err := result.LastInsertId()
if err != nil {
return err
}
item.ID = itemID
}
if shouldCommit {
return tx.Commit()
}
return nil
}
func (r *InboundRepo) GetByID(id int64) (*model.InboundOrder, error) {
order := &model.InboundOrder{}
query := `SELECT id, COALESCE(inbound_no, CONCAT('IN-', LPAD(id, 8, '0'))), COALESCE(operator, ''), inbound_date, handler, supplier, COALESCE(remark, ''), created_at, updated_at FROM inbound_orders WHERE id = ?`
err := database.DB.QueryRow(query, id).Scan(&order.ID, &order.InboundNo, &order.Operator, &order.InboundDate, &order.Handler, &order.Supplier, &order.Remark, &order.CreatedAt, &order.UpdatedAt)
if err != nil {
return nil, err
}
itemsQuery := `SELECT ii.id, ii.inbound_order_id, ii.material_id, ii.quantity, m.material_code, m.name, m.status
FROM inbound_items ii
JOIN materials m ON ii.material_id = m.id
WHERE ii.inbound_order_id = ?`
rows, err := database.DB.Query(itemsQuery, id)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var item model.InboundItem
err := rows.Scan(&item.ID, &item.InboundOrderID, &item.MaterialID, &item.Quantity, &item.MaterialCode, &item.MaterialName, &item.MaterialStatus)
if err != nil {
return nil, err
}
order.Items = append(order.Items, item)
}
// 状态不落库:inbound_orders 没有 status 列,统一在这里给出。引入状态机时改为真实读写。
order.Status = "completed"
return order, nil
}
func (r *InboundRepo) List(search string, limit, offset int) ([]model.InboundOrder, int64, error) {
countQuery := `SELECT COUNT(*) FROM inbound_orders WHERE 1=1`
var countArgs []interface{}
if search != "" {
countQuery += ` AND (handler LIKE ? OR supplier LIKE ?)`
searchPattern := "%" + search + "%"
countArgs = append(countArgs, searchPattern, searchPattern)
}
var total int64
err := database.DB.QueryRow(countQuery, countArgs...).Scan(&total)
if err != nil {
return nil, 0, err
}
query := `SELECT id, COALESCE(inbound_no, CONCAT('IN-', LPAD(id, 8, '0'))), COALESCE(operator, ''), inbound_date, handler, supplier, COALESCE(remark, ''), created_at, updated_at FROM inbound_orders WHERE 1=1`
var args []interface{}
if search != "" {
query += ` AND (handler LIKE ? OR supplier LIKE ?)`
searchPattern := "%" + search + "%"
args = append(args, searchPattern, searchPattern)
}
query += ` ORDER BY id DESC LIMIT ? OFFSET ?`
args = append(args, limit, offset)
rows, err := database.DB.Query(query, args...)
if err != nil {
return nil, 0, err
}
defer rows.Close()
var orders []model.InboundOrder
for rows.Next() {
var order model.InboundOrder
err := rows.Scan(&order.ID, &order.InboundNo, &order.Operator, &order.InboundDate, &order.Handler, &order.Supplier, &order.Remark, &order.CreatedAt, &order.UpdatedAt)
if err != nil {
return nil, 0, err
}
// 同上:状态在查询层给出,列表里一并补上。
order.Status = "completed"
orders = append(orders, order)
}
return orders, total, nil
}
func (r *InboundRepo) GetByMaterialID(materialID int64) ([]model.InboundRecord, error) {
query := `SELECT ii.id, ii.inbound_order_id, io.handler, io.supplier, ii.quantity, ii.created_at
FROM inbound_items ii
JOIN inbound_orders io ON ii.inbound_order_id = io.id
WHERE ii.material_id = ?
ORDER BY ii.id DESC`
rows, err := database.DB.Query(query, materialID)
if err != nil {
return nil, err
}
defer rows.Close()
var records []model.InboundRecord
for rows.Next() {
var rec model.InboundRecord
err := rows.Scan(&rec.ID, &rec.InboundID, &rec.Handler, &rec.Supplier, &rec.Quantity, &rec.CreatedAt)
if err != nil {
return nil, err
}
records = append(records, rec)
}
return records, nil
}
func (r *InboundRepo) GetInboundDate(id int64) (time.Time, error) {
var inboundDate time.Time
query := `SELECT inbound_date FROM inbound_orders WHERE id = ?`
err := database.DB.QueryRow(query, id).Scan(&inboundDate)
return inboundDate, err
}
func (r *InboundRepo) Delete(id int64) error {
return r.DeleteTx(nil, id)
}
func (r *InboundRepo) DeleteTx(tx *sql.Tx, id int64) error {
if tx == nil {
var err error
tx, err = database.DB.Begin()
if err != nil {
return err
}
defer tx.Rollback()
_, err = tx.Exec(`DELETE FROM inbound_orders WHERE id = ?`, id)
if err != nil {
return err
}
return tx.Commit()
}
_, err := tx.Exec(`DELETE FROM inbound_orders WHERE id = ?`, id)
return err
}
func (r *InboundRepo) Update(id int64, req *model.UpdateInboundRequest) error {
return r.UpdateTx(nil, id, req)
}
func (r *InboundRepo) UpdateTx(tx *sql.Tx, id int64, req *model.UpdateInboundRequest) error {
shouldCommit := false
if tx == nil {
var err error
tx, err = database.DB.Begin()
if err != nil {
return err
}
shouldCommit = true
}
if shouldCommit {
defer tx.Rollback()
}
// Update order basic fields
query := `UPDATE inbound_orders SET handler = ?, supplier = ?, remark = ? WHERE id = ?`
_, err := tx.Exec(query, req.Handler, req.Supplier, req.Remark, id)
if err != nil {
return err
}
// Delete old items
_, err = tx.Exec(`DELETE FROM inbound_items WHERE inbound_order_id = ?`, id)
if err != nil {
return err
}
// Insert new items
for i := range req.Items {
item := &req.Items[i]
query := `INSERT INTO inbound_items (inbound_order_id, material_id, quantity) VALUES (?, ?, ?)`
_, err = tx.Exec(query, id, item.MaterialID, item.Quantity)
if err != nil {
return err
}
}
if shouldCommit {
return tx.Commit()
}
return nil
}