package specificPriceRepo import ( "context" "errors" "time" "git.ma-al.com/goc_daniel/b2b/app/db" "git.ma-al.com/goc_daniel/b2b/app/model" "gorm.io/gorm" ) type UISpecificPriceRepo interface { Create(ctx context.Context, pr *model.SpecificPrice) error Update(ctx context.Context, pr *model.SpecificPrice) error Delete(ctx context.Context, id uint64) error GetByID(ctx context.Context, id uint64) (*model.SpecificPrice, error) List(ctx context.Context) ([]*model.SpecificPrice, error) SetActive(ctx context.Context, id uint64, active bool) error } type SpecificPriceRepo struct{} func New() UISpecificPriceRepo { return &SpecificPriceRepo{} } func (repo *SpecificPriceRepo) Create(ctx context.Context, pr *model.SpecificPrice) error { return db.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { now := time.Now() pr.CreatedAt = &now if err := tx.Create(pr).Error; err != nil { return err } return repo.insertRelations(tx, pr) }) } func (repo *SpecificPriceRepo) Update(ctx context.Context, pr *model.SpecificPrice) error { return db.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { now := time.Now() pr.UpdatedAt = &now if err := tx.Save(pr).Error; err != nil { return err } if err := repo.clearRelations(tx, pr.ID); err != nil { return err } return repo.insertRelations(tx, pr) }) } func (repo *SpecificPriceRepo) GetByID(ctx context.Context, id uint64) (*model.SpecificPrice, error) { var pr model.SpecificPrice err := db.DB.WithContext(ctx).Where("id = ?", id).First(&pr).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } if err := repo.loadRelations(ctx, &pr); err != nil { return nil, err } return &pr, nil } func (repo *SpecificPriceRepo) List(ctx context.Context) ([]*model.SpecificPrice, error) { var specificPrices []*model.SpecificPrice err := db.DB.WithContext(ctx).Find(&specificPrices).Error if err != nil { return nil, err } for i := range specificPrices { if err := repo.loadRelations(ctx, specificPrices[i]); err != nil { return nil, err } } return specificPrices, nil } func (repo *SpecificPriceRepo) SetActive(ctx context.Context, id uint64, active bool) error { return db.DB.WithContext(ctx).Model(&model.SpecificPrice{}).Where("id = ?", id).Update("is_active", active).Error } func (repo *SpecificPriceRepo) Delete(ctx context.Context, id uint64) error { return db.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Exec("DELETE FROM b2b_specific_price_product WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_category WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_product_attribute WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_country WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_customer WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Delete(&model.SpecificPrice{}, "id = ?", id).Error; err != nil { return err } return nil }) } func (repo *SpecificPriceRepo) insertRelations(tx *gorm.DB, pr *model.SpecificPrice) error { if len(pr.ProductIDs) > 0 { for _, productID := range pr.ProductIDs { if err := tx.Exec(` INSERT INTO b2b_specific_price_product (b2b_specific_price_id, id_product) VALUES (?, ?) `, pr.ID, productID).Error; err != nil { return err } } } if len(pr.CategoryIDs) > 0 { for _, categoryID := range pr.CategoryIDs { if err := tx.Exec(` INSERT INTO b2b_specific_price_category (b2b_specific_price_id, id_category) VALUES (?, ?) `, pr.ID, categoryID).Error; err != nil { return err } } } if len(pr.ProductAttributeIDs) > 0 { for _, attrID := range pr.ProductAttributeIDs { if err := tx.Exec(` INSERT INTO b2b_specific_price_product_attribute (b2b_specific_price_id, id_product_attribute) VALUES (?, ?) `, pr.ID, attrID).Error; err != nil { return err } } } if len(pr.CountryIDs) > 0 { for _, countryID := range pr.CountryIDs { if err := tx.Exec(` INSERT INTO b2b_specific_price_country (b2b_specific_price_id, b2b_id_country) VALUES (?, ?) `, pr.ID, countryID).Error; err != nil { return err } } } if len(pr.CustomerIDs) > 0 { for _, customerID := range pr.CustomerIDs { if err := tx.Exec(` INSERT INTO b2b_specific_price_customer (b2b_specific_price_id, b2b_id_customer) VALUES (?, ?) `, pr.ID, customerID).Error; err != nil { return err } } } return nil } func (repo *SpecificPriceRepo) clearRelations(tx *gorm.DB, id uint64) error { if err := tx.Exec("DELETE FROM b2b_specific_price_product WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_category WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_product_attribute WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_country WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } if err := tx.Exec("DELETE FROM b2b_specific_price_customer WHERE b2b_specific_price_id = ?", id).Error; err != nil { return err } return nil } func (repo *SpecificPriceRepo) loadRelations(ctx context.Context, pr *model.SpecificPrice) error { var err error var productIDs []struct { IDProduct uint64 `gorm:"column:id_product"` } if err = db.DB.WithContext(ctx).Table("b2b_specific_price_product").Where("b2b_specific_price_id = ?", pr.ID).Select("id_product").Scan(&productIDs).Error; err != nil { return err } for _, p := range productIDs { pr.ProductIDs = append(pr.ProductIDs, p.IDProduct) } var categoryIDs []struct { IDCategory uint64 `gorm:"column:id_category"` } if err = db.DB.WithContext(ctx).Table("b2b_specific_price_category").Where("b2b_specific_price_id = ?", pr.ID).Select("id_category").Scan(&categoryIDs).Error; err != nil { return err } for _, c := range categoryIDs { pr.CategoryIDs = append(pr.CategoryIDs, c.IDCategory) } var attrIDs []struct { IDAttr uint64 `gorm:"column:id_product_attribute"` } if err = db.DB.WithContext(ctx).Table("b2b_specific_price_product_attribute").Where("b2b_specific_price_id = ?", pr.ID).Select("id_product_attribute").Scan(&attrIDs).Error; err != nil { return err } for _, a := range attrIDs { pr.ProductAttributeIDs = append(pr.ProductAttributeIDs, a.IDAttr) } var countryIDs []struct { IDCountry uint64 `gorm:"column:b2b_id_country"` } if err = db.DB.WithContext(ctx).Table("b2b_specific_price_country").Where("b2b_specific_price_id = ?", pr.ID).Select("b2b_id_country").Scan(&countryIDs).Error; err != nil { return err } for _, c := range countryIDs { pr.CountryIDs = append(pr.CountryIDs, c.IDCountry) } var customerIDs []struct { IDCustomer uint64 `gorm:"column:b2b_id_customer"` } if err = db.DB.WithContext(ctx).Table("b2b_specific_price_customer").Where("b2b_specific_price_id = ?", pr.ID).Select("b2b_id_customer").Scan(&customerIDs).Error; err != nil { return err } for _, c := range customerIDs { pr.CustomerIDs = append(pr.CustomerIDs, c.IDCustomer) } return nil }