From 25ad592be39689c64df76812f9ee92d294fcb54d Mon Sep 17 00:00:00 2001 From: Daniel Goc Date: Mon, 23 Mar 2026 09:35:20 +0100 Subject: [PATCH] rename and move folders and files --- .../web/api/restricted/langsAndCountries.go | 52 ----------- .../web/api/restricted/listProducts.go | 9 +- .../web/api/restricted/localeSelector.go | 52 +++++++++++ .../web/api/restricted/meiliSearch.go | 30 ++++--- app/delivery/web/api/restricted/menu.go | 10 +-- .../web/api/restricted/productDescription.go | 29 +------ app/delivery/web/init.go | 8 +- app/model/productDescription.go | 8 ++ .../repos}/categoriesRepo/categoriesRepo.go | 7 +- .../langs.go => repos/langsRepo/langsRepo.go} | 0 .../listProductsRepo/listProductsRepo.go | 7 +- .../localeSelectorRepo/localeSelectorRepo.go | 14 +-- .../productDescriptionRepo.go | 21 ++--- .../langsAndCountriesService.go | 26 ------ app/service/langsService/service.go | 2 +- .../listProductsService.go | 6 +- .../localeSelectorService.go | 26 ++++++ app/service/meiliService/meiliService.go | 87 ++++++++++++++++++- app/service/menuService/menuService.go | 6 +- .../productDescriptionService.go | 16 ++-- app/utils/const_data/consts.go | 1 + 21 files changed, 243 insertions(+), 174 deletions(-) delete mode 100644 app/delivery/web/api/restricted/langsAndCountries.go create mode 100644 app/delivery/web/api/restricted/localeSelector.go rename {repository => app/repos}/categoriesRepo/categoriesRepo.go (77%) rename app/{langs/langs.go => repos/langsRepo/langsRepo.go} (100%) rename {repository => app/repos}/listProductsRepo/listProductsRepo.go (84%) rename repository/langsAndCountriesRepo/langsAndCountriesRepo.go => app/repos/localeSelectorRepo/localeSelectorRepo.go (66%) rename {repository => app/repos}/productDescriptionRepo/productDescriptionRepo.go (70%) delete mode 100644 app/service/langsAndCountriesService/langsAndCountriesService.go create mode 100644 app/service/localeSelectorService/localeSelectorService.go diff --git a/app/delivery/web/api/restricted/langsAndCountries.go b/app/delivery/web/api/restricted/langsAndCountries.go deleted file mode 100644 index dfd6aad..0000000 --- a/app/delivery/web/api/restricted/langsAndCountries.go +++ /dev/null @@ -1,52 +0,0 @@ -package restricted - -import ( - "git.ma-al.com/goc_daniel/b2b/app/service/langsAndCountriesService" - "git.ma-al.com/goc_daniel/b2b/app/utils/i18n" - "git.ma-al.com/goc_daniel/b2b/app/utils/nullable" - "git.ma-al.com/goc_daniel/b2b/app/utils/response" - "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" - "github.com/gofiber/fiber/v3" -) - -// LangsAndCountriesHandler for getting languages and countries data -type LangsAndCountriesHandler struct { - langsAndCountriesService *langsAndCountriesService.LangsAndCountriesService -} - -// NewLangsAndCountriesHandler creates a new LangsAndCountriesHandler instance -func NewLangsAndCountriesHandler() *LangsAndCountriesHandler { - langsAndCountriesService := langsAndCountriesService.New() - return &LangsAndCountriesHandler{ - langsAndCountriesService: langsAndCountriesService, - } -} - -func LangsAndCountriesHandlerRoutes(r fiber.Router) fiber.Router { - handler := NewLangsAndCountriesHandler() - - r.Get("/get-languages", handler.GetLanguages) - r.Get("/get-countries", handler.GetCountries) - - return r -} - -func (h *LangsAndCountriesHandler) GetLanguages(c fiber.Ctx) error { - languages, err := h.langsAndCountriesService.GetLanguages() - if err != nil { - return c.Status(responseErrors.GetErrorStatus(err)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - } - - return c.JSON(response.Make(&languages, 0, i18n.T_(c, response.Message_OK))) -} - -func (h *LangsAndCountriesHandler) GetCountries(c fiber.Ctx) error { - countries, err := h.langsAndCountriesService.GetCountriesAndCurrencies() - if err != nil { - return c.Status(responseErrors.GetErrorStatus(err)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - } - - return c.JSON(response.Make(&countries, 0, i18n.T_(c, response.Message_OK))) -} diff --git a/app/delivery/web/api/restricted/listProducts.go b/app/delivery/web/api/restricted/listProducts.go index 971a802..aeec22a 100644 --- a/app/delivery/web/api/restricted/listProducts.go +++ b/app/delivery/web/api/restricted/listProducts.go @@ -52,20 +52,13 @@ func (h *ListProductsHandler) GetListing(c fiber.Ctx) error { // "override_currency": c.Query("override_currency", ""), // } - id_shop_attribute := c.Query("shopID") - id_shop, err := strconv.Atoi(id_shop_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2")) if err != nil { return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - listing, err := h.listProductsService.GetListing(uint(id_shop), uint(id_lang), paging, filters) + listing, err := h.listProductsService.GetListing(uint(id_lang), paging, filters) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) diff --git a/app/delivery/web/api/restricted/localeSelector.go b/app/delivery/web/api/restricted/localeSelector.go new file mode 100644 index 0000000..8131501 --- /dev/null +++ b/app/delivery/web/api/restricted/localeSelector.go @@ -0,0 +1,52 @@ +package restricted + +import ( + "git.ma-al.com/goc_daniel/b2b/app/service/localeSelectorService" + "git.ma-al.com/goc_daniel/b2b/app/utils/i18n" + "git.ma-al.com/goc_daniel/b2b/app/utils/nullable" + "git.ma-al.com/goc_daniel/b2b/app/utils/response" + "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" + "github.com/gofiber/fiber/v3" +) + +// LocaleSelectorHandler for getting languages and countries data +type LocaleSelectorHandler struct { + localeSelectorService *localeSelectorService.LocaleSelectorService +} + +// NewLocaleSelectorHandler creates a new LocaleSelectorHandler instance +func NewLocaleSelectorHandler() *LocaleSelectorHandler { + localeSelectorService := localeSelectorService.New() + return &LocaleSelectorHandler{ + localeSelectorService: localeSelectorService, + } +} + +func LocaleSelectorHandlerRoutes(r fiber.Router) fiber.Router { + handler := NewLocaleSelectorHandler() + + r.Get("/get-languages", handler.GetLanguages) + r.Get("/get-countries", handler.GetCountries) + + return r +} + +func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error { + languages, err := h.localeSelectorService.GetLanguages() + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + return c.JSON(response.Make(&languages, 0, i18n.T_(c, response.Message_OK))) +} + +func (h *LocaleSelectorHandler) GetCountries(c fiber.Ctx) error { + countries, err := h.localeSelectorService.GetCountriesAndCurrencies() + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + return c.JSON(response.Make(&countries, 0, i18n.T_(c, response.Message_OK))) +} diff --git a/app/delivery/web/api/restricted/meiliSearch.go b/app/delivery/web/api/restricted/meiliSearch.go index d40a38e..b0b5aeb 100644 --- a/app/delivery/web/api/restricted/meiliSearch.go +++ b/app/delivery/web/api/restricted/meiliSearch.go @@ -26,26 +26,36 @@ func MeiliSearchHandlerRoutes(r fiber.Router) fiber.Router { handler := NewMeiliSearchHandler() r.Get("/test", handler.Test) + r.Get("/create-index", handler.CreateIndex) return r } -func (h *MeiliSearchHandler) Test(c fiber.Ctx) error { - - id_shop_attribute := c.Query("shopID") - id_shop, err := strconv.Atoi(id_shop_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - +func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error { id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2")) if err != nil { return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - test, err := h.meiliService.Test(uint(id_shop), uint(id_lang)) + err = h.meiliService.CreateIndex(uint(id_lang)) + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + nothing := "" + return c.JSON(response.Make(¬hing, 0, i18n.T_(c, response.Message_OK))) +} + +func (h *MeiliSearchHandler) Test(c fiber.Ctx) error { + id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2")) + if err != nil { + return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) + } + + test, err := h.meiliService.Test(uint(id_lang)) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) diff --git a/app/delivery/web/api/restricted/menu.go b/app/delivery/web/api/restricted/menu.go index 37c2596..d20cd45 100644 --- a/app/delivery/web/api/restricted/menu.go +++ b/app/delivery/web/api/restricted/menu.go @@ -31,21 +31,13 @@ func MenuHandlerRoutes(r fiber.Router) fiber.Router { } func (h *MenuHandler) GetMenu(c fiber.Ctx) error { - - id_shop_attribute := c.Query("shopID") - id_shop, err := strconv.Atoi(id_shop_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2")) if err != nil { return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - menu, err := h.menuService.GetMenu(uint(id_shop), uint(id_lang)) + menu, err := h.menuService.GetMenu(uint(id_lang)) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) diff --git a/app/delivery/web/api/restricted/productDescription.go b/app/delivery/web/api/restricted/productDescription.go index 4cca8a3..a107a21 100644 --- a/app/delivery/web/api/restricted/productDescription.go +++ b/app/delivery/web/api/restricted/productDescription.go @@ -54,13 +54,6 @@ func (h *ProductDescriptionHandler) GetProductDescription(c fiber.Ctx) error { JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - productShopID_attribute := c.Query("productShopID") - productShopID, err := strconv.Atoi(productShopID_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - productLangID_attribute := c.Query("productLangID") productLangID, err := strconv.Atoi(productLangID_attribute) if err != nil { @@ -68,7 +61,7 @@ func (h *ProductDescriptionHandler) GetProductDescription(c fiber.Ctx) error { JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - description, err := h.productDescriptionService.GetProductDescription(userID, uint(productID), uint(productShopID), uint(productLangID)) + description, err := h.productDescriptionService.GetProductDescription(userID, uint(productID), uint(productLangID)) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) @@ -77,7 +70,7 @@ func (h *ProductDescriptionHandler) GetProductDescription(c fiber.Ctx) error { return c.JSON(response.Make(description, 1, i18n.T_(c, response.Message_OK))) } -// SaveProductDescription saves the description for a given product ID, in given shop and language +// SaveProductDescription saves the description for a given product ID, in given language func (h *ProductDescriptionHandler) SaveProductDescription(c fiber.Ctx) error { userID, ok := c.Locals("userID").(uint) if !ok { @@ -92,13 +85,6 @@ func (h *ProductDescriptionHandler) SaveProductDescription(c fiber.Ctx) error { JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - productShopID_attribute := c.Query("productShopID") - productShopID, err := strconv.Atoi(productShopID_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - productLangID_attribute := c.Query("productLangID") productLangID, err := strconv.Atoi(productLangID_attribute) if err != nil { @@ -112,7 +98,7 @@ func (h *ProductDescriptionHandler) SaveProductDescription(c fiber.Ctx) error { JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody))) } - err = h.productDescriptionService.SaveProductDescription(userID, uint(productID), uint(productShopID), uint(productLangID), updates) + err = h.productDescriptionService.SaveProductDescription(userID, uint(productID), uint(productLangID), updates) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) @@ -136,13 +122,6 @@ func (h *ProductDescriptionHandler) TranslateProductDescription(c fiber.Ctx) err JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - productShopID_attribute := c.Query("productShopID") - productShopID, err := strconv.Atoi(productShopID_attribute) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). - JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) - } - productFromLangID_attribute := c.Query("productFromLangID") productFromLangID, err := strconv.Atoi(productFromLangID_attribute) if err != nil { @@ -163,7 +142,7 @@ func (h *ProductDescriptionHandler) TranslateProductDescription(c fiber.Ctx) err JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) } - description, err := h.productDescriptionService.TranslateProductDescription(userID, uint(productID), uint(productShopID), uint(productFromLangID), uint(productToLangID), aiModel) + description, err := h.productDescriptionService.TranslateProductDescription(userID, uint(productID), uint(productFromLangID), uint(productToLangID), aiModel) if err != nil { return c.Status(responseErrors.GetErrorStatus(err)). JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) diff --git a/app/delivery/web/init.go b/app/delivery/web/init.go index 30a372a..bc61539 100644 --- a/app/delivery/web/init.go +++ b/app/delivery/web/init.go @@ -97,10 +97,10 @@ func (s *Server) Setup() error { listProducts := s.restricted.Group("/list-products") restricted.ListProductsHandlerRoutes(listProducts) - // changing the JWT cookies routes (restricted) - // in reality it just handles changing user's country and language - langsAndCountries := s.restricted.Group("/langs-and-countries") - restricted.LangsAndCountriesHandlerRoutes(langsAndCountries) + // locale selector (restricted) + // this is basically for changing user's selected language and country + localeSelector := s.restricted.Group("/langs-and-countries") + restricted.LocaleSelectorHandlerRoutes(localeSelector) // menu (restricted) menu := s.restricted.Group("/menu") diff --git a/app/model/productDescription.go b/app/model/productDescription.go index 2411f59..e03bbc1 100644 --- a/app/model/productDescription.go +++ b/app/model/productDescription.go @@ -18,3 +18,11 @@ type ProductDescription struct { DeliveryOutStock string `gorm:"column:delivery_out_stock;type:varchar(255)" json:"delivery_out_stock" form:"delivery_out_stock"` Usage string `gorm:"column:usage;type:text" json:"usage" form:"usage"` } + +type MeiliSearchProduct struct { + ProductID uint + Name string + Description string + DescriptionShort string + Usage string +} diff --git a/repository/categoriesRepo/categoriesRepo.go b/app/repos/categoriesRepo/categoriesRepo.go similarity index 77% rename from repository/categoriesRepo/categoriesRepo.go rename to app/repos/categoriesRepo/categoriesRepo.go index 4303844..1713441 100644 --- a/repository/categoriesRepo/categoriesRepo.go +++ b/app/repos/categoriesRepo/categoriesRepo.go @@ -3,10 +3,11 @@ package categoriesRepo import ( "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 UICategoriesRepo interface { - GetAllCategories(id_shop uint, id_lang uint) ([]model.ScannedCategory, error) + GetAllCategories(id_lang uint) ([]model.ScannedCategory, error) } type CategoriesRepo struct{} @@ -15,7 +16,7 @@ func New() UICategoriesRepo { return &CategoriesRepo{} } -func (repo *CategoriesRepo) GetAllCategories(id_shop uint, id_lang uint) ([]model.ScannedCategory, error) { +func (repo *CategoriesRepo) GetAllCategories(id_lang uint) ([]model.ScannedCategory, error) { var allCategories []model.ScannedCategory err := db.DB.Raw(` @@ -34,7 +35,7 @@ func (repo *CategoriesRepo) GetAllCategories(id_shop uint, id_lang uint) ([]mode LEFT JOIN ps_category_shop ON ps_category_shop.id_category = ps_category.id_category AND ps_category_shop.id_shop = ?`, - id_shop, id_lang, id_shop). + constdata.SHOP_ID, id_lang, constdata.SHOP_ID). Scan(&allCategories).Error return allCategories, err diff --git a/app/langs/langs.go b/app/repos/langsRepo/langsRepo.go similarity index 100% rename from app/langs/langs.go rename to app/repos/langsRepo/langsRepo.go diff --git a/repository/listProductsRepo/listProductsRepo.go b/app/repos/listProductsRepo/listProductsRepo.go similarity index 84% rename from repository/listProductsRepo/listProductsRepo.go rename to app/repos/listProductsRepo/listProductsRepo.go index c57cd8f..db82261 100644 --- a/repository/listProductsRepo/listProductsRepo.go +++ b/app/repos/listProductsRepo/listProductsRepo.go @@ -3,12 +3,13 @@ package listProductsRepo import ( "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" "git.ma-al.com/goc_daniel/b2b/app/utils/query/filters" "git.ma-al.com/goc_daniel/b2b/app/utils/query/find" ) type UIListProductsRepo interface { - GetListing(id_shop uint, id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) + GetListing(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) } type ListProductsRepo struct{} @@ -17,7 +18,7 @@ func New() UIListProductsRepo { return &ListProductsRepo{} } -func (repo *ListProductsRepo) GetListing(id_shop uint, id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) { +func (repo *ListProductsRepo) GetListing(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) { var listing []model.ProductInList var total int64 @@ -60,7 +61,7 @@ func (repo *ListProductsRepo) GetListing(id_shop uint, id_lang uint, p find.Pagi ) any_image ON ps_product.id_product = any_image.id_product LIMIT ? OFFSET ?`, - id_shop, id_lang, id_shop, p.Limit(), p.Offset()). + constdata.SHOP_ID, id_lang, constdata.SHOP_ID, p.Limit(), p.Offset()). Scan(&listing).Error if err != nil { return find.Found[model.ProductInList]{}, err diff --git a/repository/langsAndCountriesRepo/langsAndCountriesRepo.go b/app/repos/localeSelectorRepo/localeSelectorRepo.go similarity index 66% rename from repository/langsAndCountriesRepo/langsAndCountriesRepo.go rename to app/repos/localeSelectorRepo/localeSelectorRepo.go index 22fbacc..f08a57b 100644 --- a/repository/langsAndCountriesRepo/langsAndCountriesRepo.go +++ b/app/repos/localeSelectorRepo/localeSelectorRepo.go @@ -1,22 +1,22 @@ -package langsAndCountriesRepo +package localeSelectorRepo import ( "git.ma-al.com/goc_daniel/b2b/app/db" "git.ma-al.com/goc_daniel/b2b/app/model" ) -type UILangsAndCountriesRepo interface { +type UILocaleSelectorRepo interface { GetLanguages() ([]model.Language, error) GetCountriesAndCurrencies() ([]model.Country, error) } -type LangsAndCountriesRepo struct{} +type LocaleSelectorRepo struct{} -func New() UILangsAndCountriesRepo { - return &LangsAndCountriesRepo{} +func New() UILocaleSelectorRepo { + return &LocaleSelectorRepo{} } -func (repo *LangsAndCountriesRepo) GetLanguages() ([]model.Language, error) { +func (repo *LocaleSelectorRepo) GetLanguages() ([]model.Language, error) { var languages []model.Language err := db.DB.Table("b2b_language").Scan(&languages).Error @@ -24,7 +24,7 @@ func (repo *LangsAndCountriesRepo) GetLanguages() ([]model.Language, error) { return languages, err } -func (repo *LangsAndCountriesRepo) GetCountriesAndCurrencies() ([]model.Country, error) { +func (repo *LocaleSelectorRepo) GetCountriesAndCurrencies() ([]model.Country, error) { var countries []model.Country err := db.DB.Table("b2b_countries"). diff --git a/repository/productDescriptionRepo/productDescriptionRepo.go b/app/repos/productDescriptionRepo/productDescriptionRepo.go similarity index 70% rename from repository/productDescriptionRepo/productDescriptionRepo.go rename to app/repos/productDescriptionRepo/productDescriptionRepo.go index 7c9e38f..ce4ad1b 100644 --- a/repository/productDescriptionRepo/productDescriptionRepo.go +++ b/app/repos/productDescriptionRepo/productDescriptionRepo.go @@ -5,12 +5,13 @@ import ( "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, productShopID uint, productLangID uint) (*model.ProductDescription, error) - CreateIfDoesNotExist(productID uint, productShopID uint, productLangID uint) error - UpdateFields(productID uint, productShopID uint, productLangID uint, updates map[string]string) error + GetProductDescription(productID uint, productLangID uint) (*model.ProductDescription, error) + CreateIfDoesNotExist(productID uint, productLangID uint) error + UpdateFields(productID uint, productLangID uint, updates map[string]string) error } type ProductDescriptionRepo struct{} @@ -20,12 +21,12 @@ func New() UIProductDescriptionRepo { } // We assume that any user has access to all product descriptions -func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productShopID uint, productLangID uint) (*model.ProductDescription, error) { +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, productShopID, productLangID). + 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) @@ -35,16 +36,16 @@ func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productSh } // If it doesn't exist, returns an error. -func (r *ProductDescriptionRepo) CreateIfDoesNotExist(productID uint, productShopID uint, productLangID uint) error { +func (r *ProductDescriptionRepo) CreateIfDoesNotExist(productID uint, productLangID uint) error { record := model.ProductDescription{ ProductID: productID, - ShopID: productShopID, + ShopID: constdata.SHOP_ID, LangID: productLangID, } err := db.DB. Table("ps_product_lang"). - Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, productShopID, productLangID). + 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) @@ -53,7 +54,7 @@ func (r *ProductDescriptionRepo) CreateIfDoesNotExist(productID uint, productSho return nil } -func (r *ProductDescriptionRepo) UpdateFields(productID uint, productShopID uint, productLangID uint, updates map[string]string) error { +func (r *ProductDescriptionRepo) UpdateFields(productID uint, productLangID uint, updates map[string]string) error { if len(updates) == 0 { return nil } @@ -64,7 +65,7 @@ func (r *ProductDescriptionRepo) UpdateFields(productID uint, productShopID uint err := db.DB. Table("ps_product_lang"). - Where("id_product = ? AND id_shop = ? AND id_lang = ?", productID, productShopID, productLangID). + 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) diff --git a/app/service/langsAndCountriesService/langsAndCountriesService.go b/app/service/langsAndCountriesService/langsAndCountriesService.go deleted file mode 100644 index 3c587b5..0000000 --- a/app/service/langsAndCountriesService/langsAndCountriesService.go +++ /dev/null @@ -1,26 +0,0 @@ -package langsAndCountriesService - -import ( - "git.ma-al.com/goc_daniel/b2b/app/model" - "git.ma-al.com/goc_daniel/b2b/repository/langsAndCountriesRepo" -) - -// LangsAndCountriesService literally sends back language and countries information. -type LangsAndCountriesService struct { - repo langsAndCountriesRepo.UILangsAndCountriesRepo -} - -// NewLangsAndCountriesService creates a new LangsAndCountries service -func New() *LangsAndCountriesService { - return &LangsAndCountriesService{ - repo: langsAndCountriesRepo.New(), - } -} - -func (s *LangsAndCountriesService) GetLanguages() ([]model.Language, error) { - return s.repo.GetLanguages() -} - -func (s *LangsAndCountriesService) GetCountriesAndCurrencies() ([]model.Country, error) { - return s.repo.GetCountriesAndCurrencies() -} diff --git a/app/service/langsService/service.go b/app/service/langsService/service.go index 14efec7..fac8f06 100644 --- a/app/service/langsService/service.go +++ b/app/service/langsService/service.go @@ -1,7 +1,7 @@ package langsService import ( - langs_repo "git.ma-al.com/goc_daniel/b2b/app/langs" + langs_repo "git.ma-al.com/goc_daniel/b2b/app/repos/langsRepo" "git.ma-al.com/goc_daniel/b2b/app/utils/i18n" "git.ma-al.com/goc_daniel/b2b/app/utils/nullable" "git.ma-al.com/goc_daniel/b2b/app/utils/response" diff --git a/app/service/listProductsService/listProductsService.go b/app/service/listProductsService/listProductsService.go index 8392731..93b5ddc 100644 --- a/app/service/listProductsService/listProductsService.go +++ b/app/service/listProductsService/listProductsService.go @@ -2,9 +2,9 @@ package listProductsService import ( "git.ma-al.com/goc_daniel/b2b/app/model" + "git.ma-al.com/goc_daniel/b2b/app/repos/listProductsRepo" "git.ma-al.com/goc_daniel/b2b/app/utils/query/filters" "git.ma-al.com/goc_daniel/b2b/app/utils/query/find" - "git.ma-al.com/goc_daniel/b2b/repository/listProductsRepo" ) type ListProductsService struct { @@ -17,7 +17,7 @@ func New() *ListProductsService { } } -func (s *ListProductsService) GetListing(id_shop uint, id_lang uint, p find.Paging, filters *filters.FiltersList) (find.Found[model.ProductInList], error) { +func (s *ListProductsService) GetListing(id_lang uint, p find.Paging, filters *filters.FiltersList) (find.Found[model.ProductInList], error) { var products find.Found[model.ProductInList] // currencyIso := c.Cookies("currency_iso", "") @@ -30,7 +30,7 @@ func (s *ListProductsService) GetListing(id_shop uint, id_lang uint, p find.Pagi // countryIso = overrides["override_country"] // } - products, err := s.listProductsRepo.GetListing(id_shop, id_lang, p, filters) + products, err := s.listProductsRepo.GetListing(id_lang, p, filters) if err != nil { return products, err } diff --git a/app/service/localeSelectorService/localeSelectorService.go b/app/service/localeSelectorService/localeSelectorService.go new file mode 100644 index 0000000..7f781dc --- /dev/null +++ b/app/service/localeSelectorService/localeSelectorService.go @@ -0,0 +1,26 @@ +package localeSelectorService + +import ( + "git.ma-al.com/goc_daniel/b2b/app/model" + "git.ma-al.com/goc_daniel/b2b/app/repos/localeSelectorRepo" +) + +// LocaleSelectorService literally sends back language and countries information. +type LocaleSelectorService struct { + repo localeSelectorRepo.UILocaleSelectorRepo +} + +// NewLocaleSelectorService creates a new LocaleSelector service +func New() *LocaleSelectorService { + return &LocaleSelectorService{ + repo: localeSelectorRepo.New(), + } +} + +func (s *LocaleSelectorService) GetLanguages() ([]model.Language, error) { + return s.repo.GetLanguages() +} + +func (s *LocaleSelectorService) GetCountriesAndCurrencies() ([]model.Country, error) { + return s.repo.GetCountriesAndCurrencies() +} diff --git a/app/service/meiliService/meiliService.go b/app/service/meiliService/meiliService.go index ab717ff..24cc106 100644 --- a/app/service/meiliService/meiliService.go +++ b/app/service/meiliService/meiliService.go @@ -1,10 +1,17 @@ package meiliService import ( + "encoding/xml" "fmt" + "io" "os" "strconv" + "strings" + "time" + "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" "github.com/meilisearch/meilisearch-go" ) @@ -26,9 +33,53 @@ func New() *MeiliService { } } +// ==================================== FOR SUPERADMIN ONLY ==================================== +func (s *MeiliService) CreateIndex(id_lang uint) error { + var products []model.ProductDescription + + err := db.DB. + Table("ps_product_lang"). + Where("id_shop = ? AND id_lang = ?", constdata.SHOP_ID, id_lang). + Scan(&products).Error + if err != nil { + return fmt.Errorf("database error: %w", err) + } + + var meiliProducts []model.MeiliSearchProduct + for i := 0; i < len(products); i++ { + var nextMeiliProduct model.MeiliSearchProduct + + nextMeiliProduct.ProductID = products[i].ProductID + nextMeiliProduct.Name = products[i].Name + nextMeiliProduct.Description = cleanHTML(products[i].Description) + nextMeiliProduct.DescriptionShort = cleanHTML(products[i].DescriptionShort) + nextMeiliProduct.Usage = cleanHTML(products[i].Usage) + + meiliProducts = append(meiliProducts, nextMeiliProduct) + } + + indexName := "meili_products_shop" + strconv.FormatInt(constdata.SHOP_ID, 10) + "_lang" + strconv.FormatInt(int64(id_lang), 10) + primaryKey := "product_id" + docOptions := &meilisearch.DocumentOptions{ + PrimaryKey: &primaryKey, + SkipCreation: false, + } + + task, err := s.meiliClient.Index(indexName).AddDocuments(meiliProducts, docOptions) + if err != nil { + return fmt.Errorf("meili AddDocuments error: %w", err) + } + + finishedTask, err := s.meiliClient.WaitForTask(task.TaskUID, 500*time.Millisecond) + fmt.Printf("Task status: %s\n", finishedTask.Status) + fmt.Printf("Task error: %s\n", finishedTask.Error) + + return err +} + // ==================================== FOR DEBUG ONLY ==================================== -func (s *MeiliService) Test(id_shop uint, id_lang uint) (meilisearch.SearchResponse, error) { - indexName := "products_lang" + strconv.FormatInt(int64(id_lang), 10) +func (s *MeiliService) Test(id_lang uint) (meilisearch.SearchResponse, error) { + indexName := "meili_products_shop" + strconv.FormatInt(constdata.SHOP_ID, 10) + "_lang" + strconv.FormatInt(int64(id_lang), 10) searchReq := &meilisearch.SearchRequest{ Limit: 3, @@ -70,3 +121,35 @@ func (s *MeiliService) HealthCheck() (*meilisearch.Health, error) { return health, nil } + +// remove all tags from HTML text +func cleanHTML(s string) string { + r := strings.NewReader(s) + d := xml.NewDecoder(r) + + text := "" + + // Configure the decoder for HTML; leave off strict and autoclose for XHTML + d.Strict = true + d.AutoClose = xml.HTMLAutoClose + d.Entity = xml.HTMLEntity + for { + token, err := d.Token() + if err == io.EOF { + break + } + + switch v := token.(type) { + case xml.StartElement: + text += "\n" + case xml.EndElement: + case xml.CharData: + text += string(v) + case xml.Comment: + case xml.ProcInst: + case xml.Directive: + } + } + + return text +} diff --git a/app/service/menuService/menuService.go b/app/service/menuService/menuService.go index 3186233..13a6a89 100644 --- a/app/service/menuService/menuService.go +++ b/app/service/menuService/menuService.go @@ -4,8 +4,8 @@ import ( "sort" "git.ma-al.com/goc_daniel/b2b/app/model" + "git.ma-al.com/goc_daniel/b2b/app/repos/categoriesRepo" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" - "git.ma-al.com/goc_daniel/b2b/repository/categoriesRepo" ) type MenuService struct { @@ -18,8 +18,8 @@ func New() *MenuService { } } -func (s *MenuService) GetMenu(id_shop uint, id_lang uint) (model.Category, error) { - all_categories, err := s.categoriesRepo.GetAllCategories(id_shop, id_lang) +func (s *MenuService) GetMenu(id_lang uint) (model.Category, error) { + all_categories, err := s.categoriesRepo.GetAllCategories(id_lang) if err != nil { return model.Category{}, err } diff --git a/app/service/productDescriptionService/productDescriptionService.go b/app/service/productDescriptionService/productDescriptionService.go index 4f4f136..df137ff 100644 --- a/app/service/productDescriptionService/productDescriptionService.go +++ b/app/service/productDescriptionService/productDescriptionService.go @@ -17,9 +17,9 @@ import ( "cloud.google.com/go/translate/apiv3/translatepb" "git.ma-al.com/goc_daniel/b2b/app/config" "git.ma-al.com/goc_daniel/b2b/app/model" + "git.ma-al.com/goc_daniel/b2b/app/repos/productDescriptionRepo" "git.ma-al.com/goc_daniel/b2b/app/service/langsService" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" - "git.ma-al.com/goc_daniel/b2b/repository/productDescriptionRepo" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/option" "github.com/openai/openai-go/v3/responses" @@ -82,12 +82,12 @@ func New() *ProductDescriptionService { } } -func (s *ProductDescriptionService) GetProductDescription(userID uint, productID uint, productShopID uint, productLangID uint) (*model.ProductDescription, error) { - return s.productDescriptionRepo.GetProductDescription(productID, productShopID, productLangID) +func (s *ProductDescriptionService) GetProductDescription(userID uint, productID uint, productLangID uint) (*model.ProductDescription, error) { + return s.productDescriptionRepo.GetProductDescription(productID, productLangID) } // Updates relevant fields with the "updates" map -func (s *ProductDescriptionService) SaveProductDescription(userID uint, productID uint, productShopID uint, productLangID uint, updates map[string]string) error { +func (s *ProductDescriptionService) SaveProductDescription(userID uint, productID uint, productLangID uint, updates map[string]string) error { // only some fields can be affected allowedFields := []string{"description", "description_short", "meta_description", "meta_title", "name", "available_now", "available_later", "usage"} for key := range updates { @@ -106,12 +106,12 @@ func (s *ProductDescriptionService) SaveProductDescription(userID uint, productI } } - err := s.productDescriptionRepo.CreateIfDoesNotExist(productID, productShopID, productLangID) + err := s.productDescriptionRepo.CreateIfDoesNotExist(productID, productLangID) if err != nil { return err } - return s.productDescriptionRepo.UpdateFields(productID, productShopID, productLangID, updates) + return s.productDescriptionRepo.UpdateFields(productID, productLangID, updates) } // TranslateProductDescription fetches the product description for productFromLangID, @@ -120,9 +120,9 @@ func (s *ProductDescriptionService) SaveProductDescription(userID uint, productI // // The Google Cloud project must have the Cloud Translation API enabled and the // service account must hold the "Cloud Translation API User" role. -func (s *ProductDescriptionService) TranslateProductDescription(userID uint, productID uint, productShopID uint, productFromLangID uint, productToLangID uint, aiModel string) (*model.ProductDescription, error) { +func (s *ProductDescriptionService) TranslateProductDescription(userID uint, productID uint, productFromLangID uint, productToLangID uint, aiModel string) (*model.ProductDescription, error) { - productDescription, err := s.productDescriptionRepo.GetProductDescription(productID, productShopID, productFromLangID) + productDescription, err := s.productDescriptionRepo.GetProductDescription(productID, productFromLangID) if err != nil { return nil, err } diff --git a/app/utils/const_data/consts.go b/app/utils/const_data/consts.go index a411036..8bdce27 100644 --- a/app/utils/const_data/consts.go +++ b/app/utils/const_data/consts.go @@ -2,3 +2,4 @@ package constdata // PASSWORD_VALIDATION_REGEX is used by the frontend (JavaScript supports lookaheads). const PASSWORD_VALIDATION_REGEX = `^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{10,}$` +const SHOP_ID = 1