244 lines
6.0 KiB
Go
244 lines
6.0 KiB
Go
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, handler, supplier) VALUES (?, ?, ?)`
|
|
result, err := tx.Exec(query, order.InboundDate, order.Handler, order.Supplier)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
orderID, err := result.LastInsertId()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
order.ID = orderID
|
|
|
|
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, inbound_date, handler, supplier, created_at, updated_at FROM inbound_orders WHERE id = ?`
|
|
err := database.DB.QueryRow(query, id).Scan(&order.ID, &order.InboundDate, &order.Handler, &order.Supplier, &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
|
|
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)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
order.Items = append(order.Items, item)
|
|
}
|
|
|
|
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, inbound_date, handler, supplier, 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.InboundDate, &order.Handler, &order.Supplier, &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 = ? WHERE id = ?`
|
|
_, err := tx.Exec(query, req.Handler, req.Supplier, 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
|
|
}
|