package repository import ( "enaklo-pos-be/internal/common/mycontext" "enaklo-pos-be/internal/entity" "enaklo-pos-be/internal/repository/models" "github.com/pkg/errors" "gorm.io/gorm" ) type ProductRepository interface { GetProductsByIDs(ctx mycontext.Context, ids []int64, partnerID int64) ([]*entity.Product, error) GetProductDetails(ctx mycontext.Context, productIDs []int64, partnerID int64) (*entity.ProductDetails, error) GetProductsByPartnerID(ctx mycontext.Context, req entity.ProductSearch) ([]*entity.Product, int64, error) } type productRepository struct { db *gorm.DB } func NewproductRepository(db *gorm.DB) *productRepository { return &productRepository{db: db} } func (r *productRepository) GetProductsByIDs(ctx mycontext.Context, ids []int64, partnerID int64) ([]*entity.Product, error) { if len(ids) == 0 { return []*entity.Product{}, nil } var productsDB []models.ProductDB if err := r.db.Where("id IN ? AND partner_id = ?", ids, partnerID).Find(&productsDB).Error; err != nil { return nil, errors.Wrap(err, "failed to find products") } products := make([]*entity.Product, 0, len(productsDB)) for i := range productsDB { product := r.toDomainProductModel(&productsDB[i]) products = append(products, product) } return products, nil } func (r *productRepository) GetProductDetails(ctx mycontext.Context, productIDs []int64, partnerID int64) (*entity.ProductDetails, error) { if len(productIDs) == 0 { return &entity.ProductDetails{ Products: make(map[int64]*entity.Product), }, nil } var productsDB []models.ProductDB if err := r.db.Where("id IN ? AND partner_id = ?", productIDs, partnerID).Find(&productsDB).Error; err != nil { return nil, errors.Wrap(err, "failed to find products") } productMap := make(map[int64]*entity.Product, len(productsDB)) for i := range productsDB { product := r.toDomainProductModel(&productsDB[i]) productMap[product.ID] = product } return &entity.ProductDetails{ Products: productMap, PartnerID: partnerID, }, nil } func (r *productRepository) toDomainProductModel(dbModel *models.ProductDB) *entity.Product { return &entity.Product{ ID: dbModel.ID, PartnerID: dbModel.PartnerID, Name: dbModel.Name, Description: dbModel.Description, Price: dbModel.Price, Type: dbModel.Type, Status: dbModel.Status, CreatedAt: dbModel.CreatedAt, UpdatedAt: dbModel.UpdatedAt, Image: dbModel.Image, } } func (r *productRepository) GetProductsByPartnerID(ctx mycontext.Context, req entity.ProductSearch) ([]*entity.Product, int64, error) { if req.PartnerID == 0 { return nil, 0, nil } query := r.db.Where("partner_id = ?", req.PartnerID) if req.Type != "" { query = query.Where("type = ?", req.Type) } if req.Name != "" { query = query.Where("name ILIKE ?", "%"+req.Name+"%") } var total int64 if err := query.Model(&models.ProductDB{}).Count(&total).Error; err != nil { return nil, 0, errors.Wrap(err, "failed to count products") } var productsDB []models.ProductDB if err := query.Find(&productsDB).Error; err != nil { return nil, 0, errors.Wrap(err, "failed to find products") } products := make([]*entity.Product, 0, len(productsDB)) for i := range productsDB { product := r.toDomainProductModel(&productsDB[i]) products = append(products, product) } return products, total, nil }