package repository import ( "context" "apskel-pos-be/internal/entities" "github.com/google/uuid" "gorm.io/gorm" ) type PaymentOrderItemRepository interface { Create(ctx context.Context, paymentOrderItem *entities.PaymentOrderItem) error GetByID(ctx context.Context, id uuid.UUID) (*entities.PaymentOrderItem, error) GetByPaymentID(ctx context.Context, paymentID uuid.UUID) ([]*entities.PaymentOrderItem, error) GetPaidQuantitiesByOrderID(ctx context.Context, orderID uuid.UUID) (map[uuid.UUID]int, error) Update(ctx context.Context, paymentOrderItem *entities.PaymentOrderItem) error Delete(ctx context.Context, id uuid.UUID) error } type PaymentOrderItemRepositoryImpl struct { db *gorm.DB } func NewPaymentOrderItemRepositoryImpl(db *gorm.DB) *PaymentOrderItemRepositoryImpl { return &PaymentOrderItemRepositoryImpl{ db: db, } } func (r *PaymentOrderItemRepositoryImpl) Create(ctx context.Context, paymentOrderItem *entities.PaymentOrderItem) error { return r.db.WithContext(ctx).Create(paymentOrderItem).Error } func (r *PaymentOrderItemRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.PaymentOrderItem, error) { var paymentOrderItem entities.PaymentOrderItem err := r.db.WithContext(ctx). Preload("Payment"). Preload("OrderItem"). First(&paymentOrderItem, "id = ?", id).Error if err != nil { return nil, err } return &paymentOrderItem, nil } func (r *PaymentOrderItemRepositoryImpl) GetByPaymentID(ctx context.Context, paymentID uuid.UUID) ([]*entities.PaymentOrderItem, error) { var paymentOrderItems []*entities.PaymentOrderItem err := r.db.WithContext(ctx). Preload("Payment"). Preload("OrderItem"). Where("payment_id = ?", paymentID). Find(&paymentOrderItems).Error return paymentOrderItems, err } func (r *PaymentOrderItemRepositoryImpl) Update(ctx context.Context, paymentOrderItem *entities.PaymentOrderItem) error { return r.db.WithContext(ctx).Save(paymentOrderItem).Error } func (r *PaymentOrderItemRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error { return r.db.WithContext(ctx).Delete(&entities.PaymentOrderItem{}, "id = ?", id).Error } // GetPaidQuantitiesByOrderID efficiently aggregates paid quantities for an order using SQL func (r *PaymentOrderItemRepositoryImpl) GetPaidQuantitiesByOrderID(ctx context.Context, orderID uuid.UUID) (map[uuid.UUID]int, error) { type Result struct { OrderItemID uuid.UUID `json:"order_item_id"` TotalQuantity int `json:"total_quantity"` } var results []Result // Efficient SQL query that aggregates quantities in the database err := r.db.WithContext(ctx). Table("payment_order_items poi"). Select("poi.order_item_id, SUM(poi.quantity) as total_quantity"). Joins("JOIN payments p ON poi.payment_id = p.id"). Where("p.order_id = ?", orderID). Group("poi.order_item_id"). Scan(&results).Error if err != nil { return nil, err } // Convert results to map paidQuantities := make(map[uuid.UUID]int) for _, result := range results { paidQuantities[result.OrderItemID] = result.TotalQuantity } return paidQuantities, nil }