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, productid_lang uint) (*model.ProductDescription, error) CreateIfDoesNotExist(productID uint, productid_lang uint) error UpdateFields(productID uint, productid_lang 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, productid_lang 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, productid_lang). 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, productid_lang uint) error { record := model.ProductDescription{ ProductID: productID, ShopID: constdata.SHOP_ID, LangID: productid_lang, } err := db.DB. Table("ps_product_lang"). Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, constdata.SHOP_ID, productid_lang). FirstOrCreate(&record).Error if err != nil { return fmt.Errorf("database error: %w", err) } return nil } func (r *ProductDescriptionRepo) UpdateFields(productID uint, productid_lang 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, productid_lang). 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 query := db.Get().Debug().Raw(` WITH products_page AS ( SELECT ps.id_product, ps.price FROM ps_product_shop ps WHERE ps.id_shop = ? AND ps.active = 1 ), variation_attributes AS ( SELECT pas.id_product, pagl.public_name AS attribute_name, JSON_ARRAYAGG(DISTINCT pal.name) AS attribute_values FROM ps_product_attribute_shop pas JOIN ps_product_attribute_combination ppac ON ppac.id_product_attribute = pas.id_product_attribute JOIN ps_attribute_lang pal ON pal.id_attribute = ppac.id_attribute AND pal.id_lang = ? JOIN ps_attribute pa ON pa.id_attribute = ppac.id_attribute JOIN ps_attribute_group pag ON pag.id_attribute_group = pa.id_attribute_group JOIN ps_attribute_group_lang pagl ON pagl.id_attribute_group = pag.id_attribute_group AND pagl.id_lang = ? WHERE pas.id_shop = ? GROUP BY pas.id_product, pagl.public_name ), variations AS ( SELECT id_product, JSON_OBJECTAGG(attribute_name, attribute_values) AS attributes FROM variation_attributes GROUP BY id_product ), variation_attribute_filters AS ( SELECT pas.id_product, JSON_ARRAYAGG( DISTINCT CONCAT( LOWER(REPLACE(CAST(pagl.public_name AS CHAR) COLLATE utf8mb4_unicode_ci, ' ', '_')), ':', LOWER(REPLACE(CAST(pal.name AS CHAR) COLLATE utf8mb4_unicode_ci, ' ', '_')) ) ) AS attribute_filters FROM ps_product_attribute_shop pas JOIN ps_product_attribute_combination ppac ON ppac.id_product_attribute = pas.id_product_attribute JOIN ps_attribute_lang pal ON pal.id_attribute = ppac.id_attribute AND pal.id_lang = ? JOIN ps_attribute pa ON pa.id_attribute = ppac.id_attribute JOIN ps_attribute_group pag ON pag.id_attribute_group = pa.id_attribute_group JOIN ps_attribute_group_lang pagl ON pagl.id_attribute_group = pag.id_attribute_group AND pagl.id_lang = ? WHERE pas.id_shop = ? GROUP BY pas.id_product ), features AS ( SELECT pfp.id_product, JSON_OBJECTAGG(pfl.name, pfvl.value) AS features FROM ps_feature_product pfp JOIN ps_feature_lang pfl ON pfl.id_feature = pfp.id_feature AND pfl.id_lang = ? JOIN ps_feature_value_lang pfvl ON pfvl.id_feature_value = pfp.id_feature_value AND pfvl.id_lang = ? GROUP BY pfp.id_product ), images AS ( SELECT id_product, id_image FROM ps_image_shop WHERE id_shop = ? AND cover = 1 ), categories AS ( SELECT id_product, JSON_ARRAYAGG(id_category) AS category_ids FROM ps_category_product GROUP BY id_product ) SELECT pp.id_product, pl.name, TRIM(REGEXP_REPLACE(REGEXP_REPLACE(pl.description, '<[^>]*>', ' '), '[[:space:]]+', ' ')) AS description, TRIM(REGEXP_REPLACE(REGEXP_REPLACE(pl.description_short, '<[^>]*>', ' '), '[[:space:]]+', ' ')) AS description_short, TRIM(REGEXP_REPLACE(REGEXP_REPLACE(pl.usage, '<[^>]*>', ' '), '[[:space:]]+', ' ')) AS used_for, p.ean13, p.reference, pp.price, ps.id_category_default AS id_category, cl.name AS category_name, cl.link_rewrite, COALESCE(vary.attributes, JSON_OBJECT()) AS attributes, COALESCE(vaf.attribute_filters, JSON_ARRAY()) AS attribute_filters, COALESCE(feat.features, JSON_OBJECT()) AS features, img.id_image, cat.category_ids, (SELECT COUNT(*) FROM ps_product_attribute_shop pas2 WHERE pas2.id_product = pp.id_product AND pas2.id_shop = ?) AS variations FROM products_page pp JOIN ps_product_shop ps ON ps.id_product = pp.id_product JOIN ps_product_lang pl ON pl.id_product = ps.id_product AND pl.id_shop = ? AND pl.id_lang = ? JOIN ps_product p ON p.id_product = ps.id_product JOIN ps_category_lang cl ON cl.id_category = ps.id_category_default AND cl.id_shop = ? AND cl.id_lang = ? LEFT JOIN variations vary ON vary.id_product = ps.id_product LEFT JOIN variation_attribute_filters vaf ON vaf.id_product = ps.id_product LEFT JOIN features feat ON feat.id_product = ps.id_product LEFT JOIN images img ON img.id_product = ps.id_product LEFT JOIN categories cat ON cat.id_product = ps.id_product ORDER BY ps.id_product `, constdata.SHOP_ID, // products_page id_lang, id_lang, // variation_attributes pal.id_lang, pagl.id_lang constdata.SHOP_ID, // variation_attributes pas.id_shop id_lang, id_lang, // variation_attribute_filters pal.id_lang, pagl.id_lang constdata.SHOP_ID, // variation_attribute_filters pas.id_shop id_lang, id_lang, // features pfl.id_lang, pfvl.id_lang constdata.SHOP_ID, // images id_shop constdata.SHOP_ID, // variation count subquery constdata.SHOP_ID, // ps_product_lang pl.id_shop id_lang, // ps_product_lang pl.id_lang constdata.SHOP_ID, // ps_category_lang cl.id_shop id_lang, // ps_category_lang cl.id_lang ) if err := query.Scan(&products).Error; err != nil { return products, fmt.Errorf("database error: %w", err) } return products, nil }