268 lines
7.6 KiB
Go
268 lines
7.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"enaklo-pos-be/internal/common/mycontext"
|
|
"enaklo-pos-be/internal/constants"
|
|
"enaklo-pos-be/internal/entity"
|
|
"enaklo-pos-be/internal/repository/models"
|
|
"github.com/pkg/errors"
|
|
"gorm.io/gorm"
|
|
time2 "time"
|
|
)
|
|
|
|
type InProgressOrderRepository interface {
|
|
CreateOrUpdate(ctx mycontext.Context, order *entity.InProgressOrder) (*entity.InProgressOrder, error)
|
|
GetListByPartnerID(ctx mycontext.Context, partnerID int64, limit, offset int) ([]*entity.InProgressOrder, error)
|
|
}
|
|
|
|
type inprogressOrderRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewInProgressOrderRepository(db *gorm.DB) *inprogressOrderRepository {
|
|
return &inprogressOrderRepository{db: db}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) CreateOrUpdate(ctx mycontext.Context, order *entity.InProgressOrder) (*entity.InProgressOrder, error) {
|
|
isUpdate := order.ID != ""
|
|
|
|
tx := r.db.Begin()
|
|
if tx.Error != nil {
|
|
return nil, errors.Wrap(tx.Error, "failed to begin transaction")
|
|
}
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
orderDB := r.toInProgressOrderDBModel(order)
|
|
|
|
if isUpdate {
|
|
var existingOrder models.InProgressOrderDB
|
|
if err := tx.First(&existingOrder, order.ID).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "order not found for update")
|
|
}
|
|
|
|
if err := tx.Model(&orderDB).Updates(orderDB).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "failed to update order")
|
|
}
|
|
|
|
if err := tx.Where("in_progress_order_id = ?", order.ID).Delete(&models.InProgressOrderItemDB{}).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "failed to delete existing order items")
|
|
}
|
|
} else {
|
|
if err := tx.Create(&orderDB).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "failed to insert order")
|
|
}
|
|
|
|
order.ID = orderDB.ID
|
|
}
|
|
|
|
var itemIDs []int64
|
|
for i := range order.OrderItems {
|
|
itemIDs = append(itemIDs, order.OrderItems[i].ItemID)
|
|
}
|
|
|
|
var products []models.ProductDB
|
|
if len(itemIDs) > 0 {
|
|
if err := tx.Where("id IN ?", itemIDs).Find(&products).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "failed to fetch products")
|
|
}
|
|
}
|
|
|
|
productMap := make(map[int64]models.ProductDB)
|
|
for _, product := range products {
|
|
productMap[product.ID] = product
|
|
}
|
|
|
|
for i := range order.OrderItems {
|
|
item := &order.OrderItems[i]
|
|
|
|
itemDB := r.toOrderItemDBModel(item, orderDB.ID)
|
|
|
|
if err := tx.Create(&itemDB).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, errors.Wrap(err, "failed to insert order item")
|
|
}
|
|
|
|
item.ID = itemDB.ID
|
|
|
|
if product, exists := productMap[item.ItemID]; exists {
|
|
item.Product = r.toDomainProductModel(&product)
|
|
}
|
|
}
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
return nil, errors.Wrap(err, "failed to commit transaction")
|
|
}
|
|
|
|
return order, nil
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) GetListByPartnerID(ctx mycontext.Context, partnerID int64, limit, offset int) ([]*entity.InProgressOrder, error) {
|
|
var ordersDB []models.InProgressOrderDB
|
|
query := r.db.Where("partner_id = ?", partnerID).Order("created_at DESC")
|
|
|
|
if limit > 0 {
|
|
query = query.Limit(limit)
|
|
}
|
|
|
|
if offset > 0 {
|
|
query = query.Offset(offset)
|
|
}
|
|
|
|
if err := query.Preload("OrderItems.Product").Find(&ordersDB).Error; err != nil {
|
|
return nil, errors.Wrap(err, "failed to find orders by partner ID")
|
|
}
|
|
|
|
orders := make([]*entity.InProgressOrder, 0, len(ordersDB))
|
|
for _, orderDB := range ordersDB {
|
|
order := r.toDomainOrderModel(&orderDB)
|
|
order.OrderItems = make([]entity.InProgressOrderItem, 0, len(orderDB.OrderItems))
|
|
|
|
for _, itemDB := range orderDB.OrderItems {
|
|
item := r.toDomainOrderItemModel(&itemDB)
|
|
|
|
orderItem := entity.InProgressOrderItem{
|
|
ID: item.ID,
|
|
ItemID: item.ItemID,
|
|
Quantity: item.Quantity,
|
|
}
|
|
|
|
if itemDB.Product.ID > 0 {
|
|
productDomain := r.toDomainProductModel(&itemDB.Product)
|
|
orderItem.Product = productDomain
|
|
}
|
|
|
|
order.OrderItems = append(order.OrderItems, orderItem)
|
|
}
|
|
|
|
orders = append(orders, order)
|
|
}
|
|
|
|
return orders, nil
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toInProgressOrderDBModel(order *entity.InProgressOrder) models.InProgressOrderDB {
|
|
now := time2.Now()
|
|
return models.InProgressOrderDB{
|
|
ID: constants.GenerateUUID(),
|
|
PartnerID: order.PartnerID,
|
|
CustomerID: order.CustomerID,
|
|
CustomerName: order.CustomerName,
|
|
PaymentType: order.PaymentType,
|
|
CreatedBy: order.CreatedBy,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
TableNumber: order.TableNumber,
|
|
OrderType: order.OrderType,
|
|
}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toDomainOrderModel(dbModel *models.InProgressOrderDB) *entity.InProgressOrder {
|
|
return &entity.InProgressOrder{
|
|
ID: dbModel.ID,
|
|
PartnerID: dbModel.PartnerID,
|
|
CustomerID: dbModel.CustomerID,
|
|
CustomerName: dbModel.CustomerName,
|
|
PaymentType: dbModel.PaymentType,
|
|
CreatedBy: dbModel.CreatedBy,
|
|
OrderItems: []entity.InProgressOrderItem{},
|
|
TableNumber: dbModel.TableNumber,
|
|
OrderType: dbModel.OrderType,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
UpdatedAt: dbModel.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toOrderItemDBModel(item *entity.InProgressOrderItem, inprogressOrderID string) models.InProgressOrderItemDB {
|
|
return models.InProgressOrderItemDB{
|
|
ID: item.ID,
|
|
InProgressOrderIO: inprogressOrderID,
|
|
ItemID: item.ItemID,
|
|
Quantity: item.Quantity,
|
|
}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toDomainOrderItemModel(dbModel *models.InProgressOrderItemDB) *entity.OrderItem {
|
|
return &entity.OrderItem{
|
|
ID: dbModel.ID,
|
|
ItemID: dbModel.ItemID,
|
|
Quantity: dbModel.Quantity,
|
|
CreatedBy: dbModel.CreatedBy,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toOrderInquiryDBModel(inquiry *entity.OrderInquiry) models.OrderInquiryDB {
|
|
return models.OrderInquiryDB{
|
|
ID: inquiry.ID,
|
|
PartnerID: inquiry.PartnerID,
|
|
CustomerID: &inquiry.CustomerID,
|
|
Status: inquiry.Status,
|
|
Amount: inquiry.Amount,
|
|
Fee: inquiry.Fee,
|
|
Total: inquiry.Total,
|
|
PaymentType: inquiry.PaymentType,
|
|
Source: inquiry.Source,
|
|
CreatedBy: inquiry.CreatedBy,
|
|
CreatedAt: inquiry.CreatedAt,
|
|
UpdatedAt: inquiry.UpdatedAt,
|
|
ExpiresAt: inquiry.ExpiresAt,
|
|
CustomerName: inquiry.CustomerName,
|
|
CustomerPhoneNumber: inquiry.CustomerPhoneNumber,
|
|
CustomerEmail: inquiry.CustomerEmail,
|
|
PaymentProvider: inquiry.PaymentProvider,
|
|
OrderType: inquiry.OrderType,
|
|
TableNumber: inquiry.TableNumber,
|
|
}
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toDomainOrderInquiryModel(dbModel *models.OrderInquiryDB) *entity.OrderInquiry {
|
|
inquiry := &entity.OrderInquiry{
|
|
ID: dbModel.ID,
|
|
PartnerID: dbModel.PartnerID,
|
|
Status: dbModel.Status,
|
|
Amount: dbModel.Amount,
|
|
Fee: dbModel.Fee,
|
|
Total: dbModel.Total,
|
|
PaymentType: dbModel.PaymentType,
|
|
Source: dbModel.Source,
|
|
CreatedBy: dbModel.CreatedBy,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
ExpiresAt: dbModel.ExpiresAt,
|
|
OrderItems: []entity.OrderItem{},
|
|
}
|
|
|
|
if dbModel.CustomerID != nil {
|
|
inquiry.CustomerID = *dbModel.CustomerID
|
|
}
|
|
|
|
inquiry.UpdatedAt = dbModel.UpdatedAt
|
|
|
|
return inquiry
|
|
}
|
|
|
|
func (r *inprogressOrderRepository) toDomainProductModel(productDB *models.ProductDB) *entity.Product {
|
|
if productDB == nil {
|
|
return nil
|
|
}
|
|
|
|
return &entity.Product{
|
|
ID: productDB.ID,
|
|
Name: productDB.Name,
|
|
Description: productDB.Description,
|
|
Price: productDB.Price,
|
|
CreatedAt: productDB.CreatedAt,
|
|
UpdatedAt: productDB.UpdatedAt,
|
|
Type: productDB.Type,
|
|
Image: productDB.Image,
|
|
}
|
|
}
|