package storage import ( "fmt" "github.com/google/uuid" "gorm.io/gorm" "mengyastore-backend/internal/database" "mengyastore-backend/internal/models" ) type OrderStore struct { db *gorm.DB } func NewOrderStore(db *gorm.DB) (*OrderStore, error) { return &OrderStore{db: db}, nil } func orderRowToModel(row database.OrderRow) models.Order { return models.Order{ ID: row.ID, ProductID: row.ProductID, ProductName: row.ProductName, UserAccount: row.UserAccount, UserName: row.UserName, Quantity: row.Quantity, DeliveredCodes: row.DeliveredCodes, Status: row.Status, DeliveryMode: row.DeliveryMode, Note: row.Note, ContactPhone: row.ContactPhone, ContactEmail: row.ContactEmail, NotifyEmail: row.NotifyEmail, CreatedAt: row.CreatedAt, } } func (s *OrderStore) Create(order models.Order) (models.Order, error) { if order.ID == "" { order.ID = uuid.NewString() } if len(order.DeliveredCodes) == 0 { order.DeliveredCodes = []string{} } row := database.OrderRow{ ID: order.ID, ProductID: order.ProductID, ProductName: order.ProductName, UserAccount: order.UserAccount, UserName: order.UserName, Quantity: order.Quantity, DeliveredCodes: database.StringSlice(order.DeliveredCodes), Status: order.Status, DeliveryMode: order.DeliveryMode, Note: order.Note, ContactPhone: order.ContactPhone, ContactEmail: order.ContactEmail, NotifyEmail: order.NotifyEmail, } if err := s.db.Create(&row).Error; err != nil { return models.Order{}, err } order.CreatedAt = row.CreatedAt return order, nil } func (s *OrderStore) GetByID(id string) (models.Order, error) { var row database.OrderRow if err := s.db.First(&row, "id = ?", id).Error; err != nil { return models.Order{}, fmt.Errorf("order not found") } return orderRowToModel(row), nil } func (s *OrderStore) Confirm(id string) (models.Order, error) { var row database.OrderRow if err := s.db.First(&row, "id = ?", id).Error; err != nil { return models.Order{}, fmt.Errorf("order not found") } if err := s.db.Model(&row).Update("status", "completed").Error; err != nil { return models.Order{}, err } row.Status = "completed" return orderRowToModel(row), nil } func (s *OrderStore) ListByAccount(account string) ([]models.Order, error) { var rows []database.OrderRow if err := s.db.Where("user_account = ?", account).Order("created_at DESC").Find(&rows).Error; err != nil { return nil, err } orders := make([]models.Order, len(rows)) for i, r := range rows { orders[i] = orderRowToModel(r) } return orders, nil } func (s *OrderStore) ListAll() ([]models.Order, error) { var rows []database.OrderRow if err := s.db.Order("created_at DESC").Find(&rows).Error; err != nil { return nil, err } orders := make([]models.Order, len(rows)) for i, r := range rows { orders[i] = orderRowToModel(r) } return orders, nil } func (s *OrderStore) CountPurchasedByAccount(account, productID string) (int, error) { var total int64 err := s.db.Model(&database.OrderRow{}). Where("user_account = ? AND product_id = ? AND status = ?", account, productID, "completed"). Select("COALESCE(SUM(quantity), 0)").Scan(&total).Error return int(total), err } // Count returns the total number of orders. func (s *OrderStore) Count() (int, error) { var count int64 if err := s.db.Model(&database.OrderRow{}).Count(&count).Error; err != nil { return 0, err } return int(count), nil } // Delete removes a single order by ID. func (s *OrderStore) Delete(id string) error { return s.db.Delete(&database.OrderRow{}, "id = ?", id).Error } // UpdateCodes replaces the delivered codes for an order (used by auto-delivery to set codes after extracting). func (s *OrderStore) UpdateCodes(id string, codes []string) error { return s.db.Model(&database.OrderRow{}).Where("id = ?", id). Update("delivered_codes", database.StringSlice(codes)).Error }