Files
b2b/app/repos/productDescriptionRepo/productDescriptionRepo.go

175 lines
6.3 KiB
Go

package productDescriptionRepo
import (
"fmt"
"git.ma-al.com/goc_daniel/b2b/app/db"
"git.ma-al.com/goc_daniel/b2b/app/model"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
)
type UIProductDescriptionRepo interface {
GetProductDescription(productID uint, productLangID uint) (*model.ProductDescription, error)
CreateIfDoesNotExist(productID uint, productLangID uint) error
UpdateFields(productID uint, productLangID uint, updates map[string]string) error
GetMeiliProducts(id_lang uint) ([]model.MeiliSearchProduct, error)
}
type ProductDescriptionRepo struct{}
func New() UIProductDescriptionRepo {
return &ProductDescriptionRepo{}
}
// We assume that any user has access to all product descriptions
func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productLangID uint) (*model.ProductDescription, error) {
var ProductDescription model.ProductDescription
err := db.DB.
Table("ps_product_lang").
Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, constdata.SHOP_ID, productLangID).
First(&ProductDescription).Error
if err != nil {
return nil, fmt.Errorf("database error: %w", err)
}
return &ProductDescription, nil
}
// If it doesn't exist, returns an error.
func (r *ProductDescriptionRepo) CreateIfDoesNotExist(productID uint, productLangID uint) error {
record := model.ProductDescription{
ProductID: productID,
ShopID: constdata.SHOP_ID,
LangID: productLangID,
}
err := db.DB.
Table("ps_product_lang").
Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, constdata.SHOP_ID, productLangID).
FirstOrCreate(&record).Error
if err != nil {
return fmt.Errorf("database error: %w", err)
}
return nil
}
func (r *ProductDescriptionRepo) UpdateFields(productID uint, productLangID uint, updates map[string]string) error {
if len(updates) == 0 {
return nil
}
updatesIface := make(map[string]interface{}, len(updates))
for k, v := range updates {
updatesIface[k] = v
}
err := db.DB.
Table("ps_product_lang").
Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, constdata.SHOP_ID, productLangID).
Updates(updatesIface).Error
if err != nil {
return fmt.Errorf("database error: %w", err)
}
return nil
}
// We assume that any user has access to all product descriptions
func (r *ProductDescriptionRepo) GetMeiliProducts(id_lang uint) ([]model.MeiliSearchProduct, error) {
var products []model.MeiliSearchProduct
err := db.DB.Debug().
// Select(`
// ps.id_product AS id_product,
// pl.name AS name,
// ps.price AS price,
// pl.description AS description,
// pl.description_short AS description_short,
// pl.usage AS used_for,
// p.ean13 AS ean13,
// p.reference AS reference,
// p.width AS width,
// p.height AS height,
// p.depth AS depth,
// p.weight AS weight,
// ps.id_category_default AS id_category,
// cl.name AS category_name,
// COUNT(DISTINCT pas.id_product_attribute) AS variations
// `).
// Table("ps_product_shop AS ps").
// Joins("LEFT JOIN ps_product_lang AS pl ON ps.id_product = pl.id_product AND pl.id_shop = ? AND pl.id_lang = ?", constdata.SHOP_ID, id_lang).
// Joins("LEFT JOIN ps_product AS p ON p.id_product = ps.id_product").
// Joins("LEFT JOIN ps_category_lang AS cl ON cl.id_category = ps.id_category_default AND cl.id_shop = ? AND cl.id_lang = ?", constdata.SHOP_ID, id_lang).
// Joins("LEFT JOIN ps_product_attribute_shop AS pas ON pas.id_product = ps.id_product AND pas.id_shop = ?", constdata.SHOP_ID).
// Where("ps.id_shop = ? AND ps.active = 1", constdata.SHOP_ID).
// Group("ps.id_product").
Select(`
ps.id_product AS id_product,
pl.name AS name,
pl.description AS description,
pl.description_short AS description_short,
pl.usage AS used_for,
p.ean13 AS ean13,
p.reference AS reference,
ps.id_category_default AS id_category,
cl.name AS category_name,
cl.link_rewrite as link_rewrite,
COUNT(DISTINCT pas.id_product_attribute) AS variations,
pis.id_image AS id_image,
GROUP_CONCAT(DISTINCT pcp.id_category) AS category_ids
`).
Table("ps_product_shop AS ps").
Joins("LEFT JOIN ps_product_lang AS pl ON ps.id_product = pl.id_product AND pl.id_shop = ? AND pl.id_lang = ?", constdata.SHOP_ID, id_lang).
Joins("LEFT JOIN ps_product AS p ON p.id_product = ps.id_product").
Joins("LEFT JOIN ps_category_lang AS cl ON cl.id_category = ps.id_category_default AND cl.id_shop = ? AND cl.id_lang = ?", constdata.SHOP_ID, id_lang).
Joins("LEFT JOIN ps_product_attribute_shop AS pas ON pas.id_product = ps.id_product AND pas.id_shop = ?", constdata.SHOP_ID).
Joins("JOIN ps_image_shop AS pis ON pis.id_product = ps.id_product AND pis.cover = 1").
Joins("JOIN ps_category_product AS pcp ON pcp.id_product = ps.id_product").
Where("ps.id_shop = ? AND ps.active = 1", constdata.SHOP_ID).
Group("pcp.id_product, ps.id_product").
Scan(&products).Error
if err != nil {
return products, fmt.Errorf("database error: %w", err)
}
// Get all category IDs for each product (including child categories)
for i := range products {
var categoryIDs []uint
// Find all parent categories and their children using nested set
err := db.DB.
Table("ps_category AS c").
Select("c.id_category").
Joins("JOIN ps_category_product AS cp ON cp.id_category = c.id_category").
Joins("JOIN ps_category AS parent ON c.nleft >= parent.nleft AND c.nright <= parent.nright AND parent.id_category = ?", products[i].CategoryID).
Where("cp.id_product = ?", products[i].ProductID).
Group("c.id_category").
Pluck("c.id_category", &categoryIDs).Error
if err != nil {
continue // Skip if error, use default category
}
if len(categoryIDs) > 0 {
products[i].CategoryIDs = categoryIDs
} else {
products[i].CategoryIDs = []uint{products[i].CategoryID}
}
// Get cover image for the product
var imageID int
err = db.DB.
Table("ps_image AS i").
Select("i.id_image").
Joins("LEFT JOIN ps_image_shop AS iss ON iss.id_image = i.id_image AND iss.id_shop = ?", constdata.SHOP_ID).
Where("i.id_product = ? AND (i.cover = 1 OR i.cover IS TRUE)", products[i].ProductID).
Order("i.position ASC").
Limit(1).
Pluck("i.id_image", &imageID).Error
if err == nil && imageID > 0 {
products[i].CoverImage = fmt.Sprintf("%d/%d.jpg", products[i].ProductID, imageID)
}
}
return products, nil
}