Compare commits
17 Commits
countries_
...
7bce04e05a
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bce04e05a | |||
| 9a90de3f11 | |||
|
|
754bf2fe01 | ||
|
|
2ca07f03ce | ||
| 6efb39edf7 | |||
| e9af4bf311 | |||
| cc570cc6a8 | |||
| 1bf706dcd0 | |||
| 84b4c70ffb | |||
| 66df535317 | |||
| e31ecda582 | |||
|
|
e0a86febc4 | ||
|
|
40154ec861 | ||
|
|
bb507036db | ||
| 8e063978a8 | |||
| 31a2744131 | |||
| f55d59a0fd |
@@ -29,10 +29,12 @@ func CartsHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
handler := NewCartsHandler()
|
handler := NewCartsHandler()
|
||||||
|
|
||||||
r.Get("/add-new-cart", handler.AddNewCart)
|
r.Get("/add-new-cart", handler.AddNewCart)
|
||||||
|
r.Delete("/remove-cart", handler.RemoveCart)
|
||||||
r.Get("/change-cart-name", handler.ChangeCartName)
|
r.Get("/change-cart-name", handler.ChangeCartName)
|
||||||
r.Get("/retrieve-carts-info", handler.RetrieveCartsInfo)
|
r.Get("/retrieve-carts-info", handler.RetrieveCartsInfo)
|
||||||
r.Get("/retrieve-cart", handler.RetrieveCart)
|
r.Get("/retrieve-cart", handler.RetrieveCart)
|
||||||
r.Get("/add-product-to-cart", handler.AddProduct)
|
r.Get("/add-product-to-cart", handler.AddProduct)
|
||||||
|
r.Delete("/remove-product-from-cart", handler.RemoveProduct)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -44,7 +46,8 @@ func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
|||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
}
|
}
|
||||||
|
|
||||||
new_cart, err := h.cartsService.CreateNewCart(userID)
|
name := c.Query("name")
|
||||||
|
new_cart, err := h.cartsService.CreateNewCart(userID, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
@@ -53,6 +56,29 @@ func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
|||||||
return c.JSON(response.Make(&new_cart, 0, i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(&new_cart, 0, i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *CartsHandler) RemoveCart(c fiber.Ctx) error {
|
||||||
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
|
if !ok {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
cart_id_attribute := c.Query("cart_id")
|
||||||
|
cart_id, err := strconv.Atoi(cart_id_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.cartsService.RemoveCart(userID, uint(cart_id))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
||||||
userID, ok := localeExtractor.GetUserID(c)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -117,6 +143,7 @@ func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
|||||||
return c.JSON(response.Make(cart, 0, i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(cart, 0, i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adds or sets given amount of products to the cart
|
||||||
func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
||||||
userID, ok := localeExtractor.GetUserID(c)
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -159,7 +186,59 @@ func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
|||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.cartsService.AddProduct(userID, uint(cart_id), uint(product_id), product_attribute_id, uint(amount))
|
set_amount_attribute := c.Query("set_amount")
|
||||||
|
set_amount, err := strconv.ParseBool(set_amount_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.cartsService.AddProduct(userID, uint(cart_id), uint(product_id), product_attribute_id, amount, set_amount)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes product from the cart.
|
||||||
|
func (h *CartsHandler) RemoveProduct(c fiber.Ctx) error {
|
||||||
|
userID, ok := localeExtractor.GetUserID(c)
|
||||||
|
if !ok {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
cart_id_attribute := c.Query("cart_id")
|
||||||
|
cart_id, err := strconv.Atoi(cart_id_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
product_id_attribute := c.Query("product_id")
|
||||||
|
product_id, err := strconv.Atoi(product_id_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
product_attribute_id_attribute := c.Query("product_attribute_id")
|
||||||
|
var product_attribute_id *uint
|
||||||
|
if product_attribute_id_attribute == "" {
|
||||||
|
product_attribute_id = nil
|
||||||
|
} else {
|
||||||
|
val, err := strconv.Atoi(product_attribute_id_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
uval := uint(val)
|
||||||
|
product_attribute_id = &uval
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.cartsService.RemoveProduct(userID, uint(cart_id), uint(product_id), product_attribute_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func CustomerHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
|
|
||||||
r.Get("", handler.customerData)
|
r.Get("", handler.customerData)
|
||||||
r.Get("/list", middleware.Require(perms.UserReadAny), handler.listCustomers)
|
r.Get("/list", middleware.Require(perms.UserReadAny), handler.listCustomers)
|
||||||
|
r.Patch("/no-vat", middleware.Require(perms.UserWriteAny), handler.setCustomerNoVatStatus)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,3 +101,28 @@ var columnMappingListUsers map[string]string = map[string]string{
|
|||||||
"first_name": "users.first_name",
|
"first_name": "users.first_name",
|
||||||
"last_name": "users.last_name",
|
"last_name": "users.last_name",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *customerHandler) setCustomerNoVatStatus(fc fiber.Ctx) error {
|
||||||
|
user, ok := localeExtractor.GetCustomer(fc)
|
||||||
|
if !ok || user == nil {
|
||||||
|
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrInvalidBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
var req struct {
|
||||||
|
CustomerID uint `json:"customer_id"`
|
||||||
|
IsNoVat bool `json:"is_no_vat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := fc.Bind().Body(&req); err != nil {
|
||||||
|
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrJSONBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrJSONBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.SetCustomerNoVatStatus(req.CustomerID, req.IsNoVat); err != nil {
|
||||||
|
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return fc.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(fc, response.Message_OK)))
|
||||||
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ var columnMappingListProducts map[string]string = map[string]string{
|
|||||||
"quantity": "bp.quantity",
|
"quantity": "bp.quantity",
|
||||||
"is_favorite": "bp.is_favorite",
|
"is_favorite": "bp.is_favorite",
|
||||||
"is_new": "bp.is_new",
|
"is_new": "bp.is_new",
|
||||||
|
"is_oem": "bp.is_oem",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error {
|
func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ type Customer struct {
|
|||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||||
|
IsNoVat bool `gorm:"default:false" json:"is_no_vat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Customer) HasPermission(permission perms.Permission) bool {
|
func (u *Customer) HasPermission(permission perms.Permission) bool {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ type ProductInList struct {
|
|||||||
PriceTaxExcl float64 `gorm:"column:price_tax_excl" json:"price_tax_excl"`
|
PriceTaxExcl float64 `gorm:"column:price_tax_excl" json:"price_tax_excl"`
|
||||||
PriceTaxIncl float64 `gorm:"column:price_tax_incl" json:"price_tax_incl"`
|
PriceTaxIncl float64 `gorm:"column:price_tax_incl" json:"price_tax_incl"`
|
||||||
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
|
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
|
||||||
IsNew uint `gorm:"column:is_new" json:"is_new"`
|
IsNew bool `gorm:"column:is_new" json:"is_new"`
|
||||||
|
IsOEM bool `gorm:"column:is_oem" json:"is_oem"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductFilters struct {
|
type ProductFilters struct {
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
package cartsRepo
|
package cartsRepo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/db"
|
"git.ma-al.com/goc_daniel/b2b/app/db"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UICartsRepo interface {
|
type UICartsRepo interface {
|
||||||
CartsAmount(user_id uint) (uint, error)
|
CartsAmount(user_id uint) (uint, error)
|
||||||
CreateNewCart(user_id uint) (model.CustomerCart, error)
|
CreateNewCart(user_id uint, name string) (model.CustomerCart, error)
|
||||||
RemoveCart(user_id uint, cart_id uint) error
|
RemoveCart(user_id uint, cart_id uint) error
|
||||||
UserHasCart(user_id uint, cart_id uint) (bool, error)
|
UserHasCart(user_id uint, cart_id uint) (bool, error)
|
||||||
UpdateCartName(user_id uint, cart_id uint, new_name string) error
|
UpdateCartName(user_id uint, cart_id uint, new_name string) error
|
||||||
RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error)
|
RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error)
|
||||||
RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error)
|
RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error)
|
||||||
CheckProductExists(product_id uint, product_attribute_id *uint) (bool, error)
|
CheckProductExists(product_id uint, product_attribute_id *uint) (bool, error)
|
||||||
AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error
|
AddProduct(cart_id uint, product_id uint, product_attribute_id *uint, amount uint, set_amount bool) error
|
||||||
|
RemoveProduct(cart_id uint, product_id uint, product_attribute_id *uint) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type CartsRepo struct{}
|
type CartsRepo struct{}
|
||||||
@@ -37,10 +42,7 @@ func (repo *CartsRepo) CartsAmount(user_id uint) (uint, error) {
|
|||||||
return amt, err
|
return amt, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *CartsRepo) CreateNewCart(user_id uint) (model.CustomerCart, error) {
|
func (repo *CartsRepo) CreateNewCart(user_id uint, name string) (model.CustomerCart, error) {
|
||||||
var name string
|
|
||||||
name = constdata.DEFAULT_NEW_CART_NAME
|
|
||||||
|
|
||||||
cart := model.CustomerCart{
|
cart := model.CustomerCart{
|
||||||
UserID: user_id,
|
UserID: user_id,
|
||||||
Name: &name,
|
Name: &name,
|
||||||
@@ -129,14 +131,61 @@ func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *CartsRepo) AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error {
|
func (repo *CartsRepo) AddProduct(cart_id uint, product_id uint, product_attribute_id *uint, amount uint, set_amount bool) error {
|
||||||
product := model.CartProduct{
|
var product model.CartProduct
|
||||||
CartID: cart_id,
|
|
||||||
ProductID: product_id,
|
|
||||||
ProductAttributeID: product_attribute_id,
|
|
||||||
Amount: amount,
|
|
||||||
}
|
|
||||||
err := db.DB.Create(&product).Error
|
|
||||||
|
|
||||||
return err
|
err := db.DB.
|
||||||
|
Where(&model.CartProduct{
|
||||||
|
CartID: cart_id,
|
||||||
|
ProductID: product_id,
|
||||||
|
ProductAttributeID: product_attribute_id,
|
||||||
|
}).
|
||||||
|
First(&product).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
if amount < 1 {
|
||||||
|
return responseErrors.ErrAmountMustBePositive
|
||||||
|
} else if amount > constdata.MAX_AMOUNT_OF_PRODUCT_IN_CART {
|
||||||
|
return responseErrors.ErrAmountMustBeReasonable
|
||||||
|
}
|
||||||
|
|
||||||
|
product = model.CartProduct{
|
||||||
|
CartID: cart_id,
|
||||||
|
ProductID: product_id,
|
||||||
|
ProductAttributeID: product_attribute_id,
|
||||||
|
Amount: amount,
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.DB.Create(&product).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some other DB error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product already exists in cart
|
||||||
|
if set_amount {
|
||||||
|
product.Amount = amount
|
||||||
|
} else {
|
||||||
|
product.Amount = product.Amount + amount
|
||||||
|
}
|
||||||
|
|
||||||
|
if product.Amount < 1 {
|
||||||
|
return responseErrors.ErrAmountMustBePositive
|
||||||
|
} else if product.Amount > constdata.MAX_AMOUNT_OF_PRODUCT_IN_CART {
|
||||||
|
return responseErrors.ErrAmountMustBeReasonable
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.DB.Save(&product).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *CartsRepo) RemoveProduct(cart_id uint, product_id uint, product_attribute_id *uint) error {
|
||||||
|
return db.DB.
|
||||||
|
Where(&model.CartProduct{
|
||||||
|
CartID: cart_id,
|
||||||
|
ProductID: product_id,
|
||||||
|
ProductAttributeID: product_attribute_id,
|
||||||
|
}).
|
||||||
|
Delete(&model.CartProduct{}).Error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type UICustomerRepo interface {
|
|||||||
Find(langId uint, p find.Paging, filt *filters.FiltersList, search string) (*find.Found[model.UserInList], error)
|
Find(langId uint, p find.Paging, filt *filters.FiltersList, search string) (*find.Found[model.UserInList], error)
|
||||||
Save(customer *model.Customer) error
|
Save(customer *model.Customer) error
|
||||||
Create(customer *model.Customer) error
|
Create(customer *model.Customer) error
|
||||||
|
SetCustomerNoVatStatus(customerID uint, isNoVat bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type CustomerRepo struct{}
|
type CustomerRepo struct{}
|
||||||
@@ -114,3 +115,7 @@ func (repo *CustomerRepo) Save(customer *model.Customer) error {
|
|||||||
func (repo *CustomerRepo) Create(customer *model.Customer) error {
|
func (repo *CustomerRepo) Create(customer *model.Customer) error {
|
||||||
return db.DB.Create(customer).Error
|
return db.DB.Create(customer).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *CustomerRepo) SetCustomerNoVatStatus(customerID uint, isNoVat bool) error {
|
||||||
|
return db.DB.Model(&model.Customer{}).Where("id = ?", customerID).Update("is_no_vat", isNoVat).Error
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,6 +122,19 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
|
|||||||
Group("product_id"),
|
Group("product_id"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "oems",
|
||||||
|
Subquery: exclause.Subquery{
|
||||||
|
DB: db.DB.
|
||||||
|
Table("b2b_oems").
|
||||||
|
Select(`
|
||||||
|
product_id AS product_id,
|
||||||
|
COUNT(*) > 0 AS is_customers_oem
|
||||||
|
`).
|
||||||
|
Where("user_id = ?", userID).
|
||||||
|
Group("product_id"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "new_product_days",
|
Name: "new_product_days",
|
||||||
Subquery: exclause.Subquery{
|
Subquery: exclause.Subquery{
|
||||||
@@ -150,6 +163,7 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
|
|||||||
pl.name AS name,
|
pl.name AS name,
|
||||||
ps.id_category_default AS category_id,
|
ps.id_category_default AS category_id,
|
||||||
p.reference AS reference,
|
p.reference AS reference,
|
||||||
|
p.is_oem AS is_oem,
|
||||||
sa.quantity AS quantity,
|
sa.quantity AS quantity,
|
||||||
COALESCE(f.is_favorite, 0) AS is_favorite,
|
COALESCE(f.is_favorite, 0) AS is_favorite,
|
||||||
CASE
|
CASE
|
||||||
@@ -166,7 +180,9 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
|
|||||||
Joins("LEFT JOIN favorites f ON f.product_id = ps.id_product").
|
Joins("LEFT JOIN favorites f ON f.product_id = ps.id_product").
|
||||||
Joins("LEFT JOIN ps_stock_available sa ON sa.id_product = ps.id_product AND sa.id_product_attribute = 0").
|
Joins("LEFT JOIN ps_stock_available sa ON sa.id_product = ps.id_product AND sa.id_product_attribute = 0").
|
||||||
Joins("LEFT JOIN new_product_days npd ON 1 = 1").
|
Joins("LEFT JOIN new_product_days npd ON 1 = 1").
|
||||||
|
Joins("LEFT JOIN oems ON oems.product_id = ps.id_product").
|
||||||
Where("ps.active = ?", 1).
|
Where("ps.active = ?", 1).
|
||||||
|
Where("(p.is_oem = 0 OR oems.is_customers_oem > 0)").
|
||||||
Group("ps.id_product"),
|
Group("ps.id_product"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -182,7 +198,8 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
|
|||||||
COALESCE(v.variants_number, 0) AS variants_number,
|
COALESCE(v.variants_number, 0) AS variants_number,
|
||||||
bp.quantity AS quantity,
|
bp.quantity AS quantity,
|
||||||
bp.is_favorite AS is_favorite,
|
bp.is_favorite AS is_favorite,
|
||||||
bp.is_new AS is_new
|
bp.is_new AS is_new,
|
||||||
|
bp.is_oem AS is_oem
|
||||||
`, config.Get().Image.ImagePrefix).
|
`, config.Get().Image.ImagePrefix).
|
||||||
Joins("JOIN ps_product_lang pl ON pl.id_product = bp.product_id AND pl.id_lang = ?", langID).
|
Joins("JOIN ps_product_lang pl ON pl.id_product = bp.product_id AND pl.id_lang = ?", langID).
|
||||||
Joins("JOIN ps_image_shop ims ON ims.id_product = bp.product_id AND ims.cover = 1").
|
Joins("JOIN ps_image_shop ims ON ims.id_product = bp.product_id AND ims.cover = 1").
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func New() *CartsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CartsService) CreateNewCart(user_id uint) (model.CustomerCart, error) {
|
func (s *CartsService) CreateNewCart(user_id uint, name string) (model.CustomerCart, error) {
|
||||||
var cart model.CustomerCart
|
var cart model.CustomerCart
|
||||||
|
|
||||||
customers_carts_amount, err := s.repo.CartsAmount(user_id)
|
customers_carts_amount, err := s.repo.CartsAmount(user_id)
|
||||||
@@ -28,8 +28,12 @@ func (s *CartsService) CreateNewCart(user_id uint) (model.CustomerCart, error) {
|
|||||||
return cart, responseErrors.ErrMaxAmtOfCartsReached
|
return cart, responseErrors.ErrMaxAmtOfCartsReached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name == "" {
|
||||||
|
name = constdata.DEFAULT_NEW_CART_NAME
|
||||||
|
}
|
||||||
|
|
||||||
// create new cart for customer
|
// create new cart for customer
|
||||||
cart, err = s.repo.CreateNewCart(user_id)
|
cart, err = s.repo.CreateNewCart(user_id, name)
|
||||||
|
|
||||||
return cart, nil
|
return cart, nil
|
||||||
}
|
}
|
||||||
@@ -74,7 +78,7 @@ func (s *CartsService) RetrieveCart(user_id uint, cart_id uint) (*model.Customer
|
|||||||
return s.repo.RetrieveCart(user_id, cart_id)
|
return s.repo.RetrieveCart(user_id, cart_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CartsService) AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error {
|
func (s *CartsService) AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount int, set_amount bool) error {
|
||||||
exists, err := s.repo.UserHasCart(user_id, cart_id)
|
exists, err := s.repo.UserHasCart(user_id, cart_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -91,5 +95,17 @@ func (s *CartsService) AddProduct(user_id uint, cart_id uint, product_id uint, p
|
|||||||
return responseErrors.ErrProductOrItsVariationDoesNotExist
|
return responseErrors.ErrProductOrItsVariationDoesNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.repo.AddProduct(user_id, cart_id, product_id, product_attribute_id, amount)
|
return s.repo.AddProduct(cart_id, product_id, product_attribute_id, uint(amount), set_amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CartsService) RemoveProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint) error {
|
||||||
|
exists, err := s.repo.UserHasCart(user_id, cart_id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return responseErrors.ErrUserHasNoSuchCart
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.RemoveProduct(cart_id, product_id, product_attribute_id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,3 +24,7 @@ func (s *CustomerService) GetById(id uint) (*model.Customer, error) {
|
|||||||
func (s *CustomerService) Find(langId uint, p find.Paging, filt *filters.FiltersList, search string) (*find.Found[model.UserInList], error) {
|
func (s *CustomerService) Find(langId uint, p find.Paging, filt *filters.FiltersList, search string) (*find.Found[model.UserInList], error) {
|
||||||
return s.repo.Find(langId, p, filt, search)
|
return s.repo.Find(langId, p, filt, search)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *CustomerService) SetCustomerNoVatStatus(customerID uint, isNoVat bool) error {
|
||||||
|
return s.repo.SetCustomerNoVatStatus(customerID, isNoVat)
|
||||||
|
}
|
||||||
|
|||||||
@@ -231,21 +231,54 @@ func (s *MenuService) GetTopMenu(languageId uint, roleId uint) ([]*model.B2BTopM
|
|||||||
|
|
||||||
func (s *MenuService) appendAdditional(all_categories *[]model.ScannedCategory, id_lang uint, iso_code string) {
|
func (s *MenuService) appendAdditional(all_categories *[]model.ScannedCategory, id_lang uint, iso_code string) {
|
||||||
for i := 0; i < len(*all_categories); i++ {
|
for i := 0; i < len(*all_categories); i++ {
|
||||||
(*all_categories)[i].Filter = "category_id_in=" + strconv.Itoa(int((*all_categories)[i].CategoryID))
|
(*all_categories)[i].Filter = "category_id_eq=" + strconv.Itoa(int((*all_categories)[i].CategoryID))
|
||||||
}
|
}
|
||||||
|
|
||||||
var additional model.ScannedCategory
|
// the new products category
|
||||||
additional.CategoryID = 10001
|
var new_products_category model.ScannedCategory
|
||||||
additional.Name = "New Products"
|
new_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 1
|
||||||
additional.Active = 1
|
new_products_category.Name = "New Products"
|
||||||
additional.Position = 10
|
new_products_category.Active = 1
|
||||||
additional.ParentID = 2
|
new_products_category.Position = 10
|
||||||
additional.IsRoot = 0
|
new_products_category.ParentID = 2
|
||||||
additional.LinkRewrite = i18n.T___(id_lang, "category.new_products")
|
new_products_category.IsRoot = 0
|
||||||
additional.IsoCode = iso_code
|
new_products_category.LinkRewrite = i18n.T___(id_lang, "category.new_products")
|
||||||
|
new_products_category.IsoCode = iso_code
|
||||||
|
|
||||||
additional.Visited = false
|
new_products_category.Visited = false
|
||||||
additional.Filter = "is_new_in=true"
|
new_products_category.Filter = "is_new_eq=true"
|
||||||
|
|
||||||
*all_categories = append(*all_categories, additional)
|
*all_categories = append(*all_categories, new_products_category)
|
||||||
|
|
||||||
|
// the oem products category
|
||||||
|
var oem_products_category model.ScannedCategory
|
||||||
|
oem_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 2
|
||||||
|
oem_products_category.Name = "OEM Products"
|
||||||
|
oem_products_category.Active = 1
|
||||||
|
oem_products_category.Position = 11
|
||||||
|
oem_products_category.ParentID = 2
|
||||||
|
oem_products_category.IsRoot = 0
|
||||||
|
oem_products_category.LinkRewrite = i18n.T___(id_lang, "category.oem_products")
|
||||||
|
oem_products_category.IsoCode = iso_code
|
||||||
|
|
||||||
|
oem_products_category.Visited = false
|
||||||
|
oem_products_category.Filter = "is_oem_eq=true"
|
||||||
|
|
||||||
|
*all_categories = append(*all_categories, oem_products_category)
|
||||||
|
|
||||||
|
// the favorite products category
|
||||||
|
var favorite_products_category model.ScannedCategory
|
||||||
|
favorite_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 3
|
||||||
|
favorite_products_category.Name = "Favourite Products" // British English version.
|
||||||
|
favorite_products_category.Active = 1
|
||||||
|
favorite_products_category.Position = 12
|
||||||
|
favorite_products_category.ParentID = 2
|
||||||
|
favorite_products_category.IsRoot = 0
|
||||||
|
favorite_products_category.LinkRewrite = i18n.T___(id_lang, "category.favorite_products")
|
||||||
|
favorite_products_category.IsoCode = iso_code
|
||||||
|
|
||||||
|
favorite_products_category.Visited = false
|
||||||
|
favorite_products_category.Filter = "is_favorite_eq=true"
|
||||||
|
|
||||||
|
*all_categories = append(*all_categories, favorite_products_category)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ const ADMIN_NOTIFICATION_LANGUAGE = 2
|
|||||||
|
|
||||||
// CATEGORY_TREE_ROOT_ID corresponds to id_category in ps_category which has is_root_category=1
|
// CATEGORY_TREE_ROOT_ID corresponds to id_category in ps_category which has is_root_category=1
|
||||||
const CATEGORY_TREE_ROOT_ID = 2
|
const CATEGORY_TREE_ROOT_ID = 2
|
||||||
|
const ADDITIONAL_CATEGORIES_INDEX = 10000
|
||||||
|
|
||||||
// since arrays can not be const
|
// since arrays can not be const
|
||||||
var CATEGORY_BLACKLIST = []uint{250}
|
var CATEGORY_BLACKLIST = []uint{250}
|
||||||
|
|
||||||
const MAX_AMOUNT_OF_CARTS_PER_USER = 10
|
const MAX_AMOUNT_OF_CARTS_PER_USER = 10
|
||||||
const DEFAULT_NEW_CART_NAME = "new cart"
|
const DEFAULT_NEW_CART_NAME = "new cart"
|
||||||
|
const MAX_AMOUNT_OF_PRODUCT_IN_CART = 1024
|
||||||
|
|
||||||
const MAX_AMOUNT_OF_ADDRESSES_PER_USER = 10
|
const MAX_AMOUNT_OF_ADDRESSES_PER_USER = 10
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ var (
|
|||||||
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
||||||
ErrUserHasNoSuchCart = errors.New("user does not have cart with given id")
|
ErrUserHasNoSuchCart = errors.New("user does not have cart with given id")
|
||||||
ErrProductOrItsVariationDoesNotExist = errors.New("product or its variation with given ids does not exist")
|
ErrProductOrItsVariationDoesNotExist = errors.New("product or its variation with given ids does not exist")
|
||||||
|
ErrAmountMustBePositive = errors.New("amount must be positive")
|
||||||
|
ErrAmountMustBeReasonable = errors.New("amount must be reasonable")
|
||||||
|
|
||||||
// Typed errors for orders handler
|
// Typed errors for orders handler
|
||||||
ErrEmptyCart = errors.New("the cart is empty")
|
ErrEmptyCart = errors.New("the cart is empty")
|
||||||
@@ -205,6 +207,10 @@ func GetErrorCode(c fiber.Ctx, err error) string {
|
|||||||
return i18n.T_(c, "error.err_user_has_no_such_cart")
|
return i18n.T_(c, "error.err_user_has_no_such_cart")
|
||||||
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
return i18n.T_(c, "error.err_product_or_its_variation_does_not_exist")
|
return i18n.T_(c, "error.err_product_or_its_variation_does_not_exist")
|
||||||
|
case errors.Is(err, ErrAmountMustBePositive):
|
||||||
|
return i18n.T_(c, "error.err_amount_must_be_positive")
|
||||||
|
case errors.Is(err, ErrAmountMustBeReasonable):
|
||||||
|
return i18n.T_(c, "error.err_amount_must_be_reasonable")
|
||||||
|
|
||||||
case errors.Is(err, ErrEmptyCart):
|
case errors.Is(err, ErrEmptyCart):
|
||||||
return i18n.T_(c, "error.err_cart_is_empty")
|
return i18n.T_(c, "error.err_cart_is_empty")
|
||||||
@@ -292,6 +298,8 @@ func GetErrorStatus(err error) int {
|
|||||||
errors.Is(err, ErrMaxAmtOfCartsReached),
|
errors.Is(err, ErrMaxAmtOfCartsReached),
|
||||||
errors.Is(err, ErrUserHasNoSuchCart),
|
errors.Is(err, ErrUserHasNoSuchCart),
|
||||||
errors.Is(err, ErrProductOrItsVariationDoesNotExist),
|
errors.Is(err, ErrProductOrItsVariationDoesNotExist),
|
||||||
|
errors.Is(err, ErrAmountMustBePositive),
|
||||||
|
errors.Is(err, ErrAmountMustBeReasonable),
|
||||||
errors.Is(err, ErrEmptyCart),
|
errors.Is(err, ErrEmptyCart),
|
||||||
errors.Is(err, ErrUserHasNoSuchOrder),
|
errors.Is(err, ErrUserHasNoSuchOrder),
|
||||||
errors.Is(err, ErrInvalidReductionType),
|
errors.Is(err, ErrInvalidReductionType),
|
||||||
|
|||||||
@@ -95,4 +95,6 @@ type Product struct {
|
|||||||
Category string `gorm:"column:category" json:"category"`
|
Category string `gorm:"column:category" json:"category"`
|
||||||
|
|
||||||
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
|
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
|
||||||
|
IsOEM bool `gorm:"column:is_oem" json:"is_oem"`
|
||||||
|
IsNew bool `gorm:"column:is_new" json:"is_new"`
|
||||||
}
|
}
|
||||||
|
|||||||
22
bruno/api_v1/customer/Set is_no_vat.yml
Normal file
22
bruno/api_v1/customer/Set is_no_vat.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
info:
|
||||||
|
name: Set is_no_vat
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
|
||||||
|
http:
|
||||||
|
method: PATCH
|
||||||
|
url: "{{bas_url}}/restricted/customer/no-vat"
|
||||||
|
body:
|
||||||
|
type: json
|
||||||
|
data: |-
|
||||||
|
{
|
||||||
|
"customer_id":1,
|
||||||
|
"is_no_vat": false
|
||||||
|
}
|
||||||
|
auth: inherit
|
||||||
|
|
||||||
|
settings:
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
followRedirects: true
|
||||||
|
maxRedirects: 5
|
||||||
@@ -5,7 +5,7 @@ info:
|
|||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: "{{bas_url}}/restricted/product/list?p=1&elems=30&reference=~NC100"
|
url: "{{bas_url}}/restricted/product/list?p=1&elems=30&reference=~NC100&is_new_eq=0&is_favorite_eq=false&is_oem_eq=FALSE"
|
||||||
params:
|
params:
|
||||||
- name: p
|
- name: p
|
||||||
value: "1"
|
value: "1"
|
||||||
@@ -27,11 +27,12 @@ http:
|
|||||||
- name: is_new_eq
|
- name: is_new_eq
|
||||||
value: "0"
|
value: "0"
|
||||||
type: query
|
type: query
|
||||||
disabled: true
|
|
||||||
- name: is_favorite_eq
|
- name: is_favorite_eq
|
||||||
value: "false"
|
value: "false"
|
||||||
type: query
|
type: query
|
||||||
disabled: true
|
- name: is_oem_eq
|
||||||
|
value: "FALSE"
|
||||||
|
type: query
|
||||||
body:
|
body:
|
||||||
type: json
|
type: json
|
||||||
data: ""
|
data: ""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: addresses
|
name: addresses
|
||||||
type: folder
|
type: folder
|
||||||
seq: 10
|
seq: 9
|
||||||
|
|
||||||
request:
|
request:
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ info:
|
|||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/carts/add-new-cart
|
url: http://localhost:3000/api/v1/restricted/carts/add-new-cart?name=carttt
|
||||||
|
params:
|
||||||
|
- name: name
|
||||||
|
value: carttt
|
||||||
|
type: query
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ info:
|
|||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&amount=1
|
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&amount=1&set_amount=false
|
||||||
params:
|
params:
|
||||||
- name: cart_id
|
- name: cart_id
|
||||||
value: "1"
|
value: "1"
|
||||||
@@ -16,6 +16,9 @@ http:
|
|||||||
- name: amount
|
- name: amount
|
||||||
value: "1"
|
value: "1"
|
||||||
type: query
|
type: query
|
||||||
|
- name: set_amount
|
||||||
|
value: "false"
|
||||||
|
type: query
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ info:
|
|||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&product_attribute_id=1115&amount=1
|
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&product_attribute_id=1115&amount=1&set_amount=true
|
||||||
params:
|
params:
|
||||||
- name: cart_id
|
- name: cart_id
|
||||||
value: "1"
|
value: "1"
|
||||||
@@ -19,6 +19,9 @@ http:
|
|||||||
- name: amount
|
- name: amount
|
||||||
value: "1"
|
value: "1"
|
||||||
type: query
|
type: query
|
||||||
|
- name: set_amount
|
||||||
|
value: "true"
|
||||||
|
type: query
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list
|
|
||||||
type: folder
|
|
||||||
seq: 3
|
|
||||||
|
|
||||||
request:
|
|
||||||
auth: inherit
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list-products
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/list/list-products?p=1&elems=10&target_user_id=2
|
|
||||||
params:
|
|
||||||
- name: p
|
|
||||||
value: "1"
|
|
||||||
type: query
|
|
||||||
- name: elems
|
|
||||||
value: "10"
|
|
||||||
type: query
|
|
||||||
- name: target_user_id
|
|
||||||
value: "2"
|
|
||||||
type: query
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
info:
|
|
||||||
name: list-users
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
|
|
||||||
http:
|
|
||||||
method: GET
|
|
||||||
url: http://localhost:3000/api/v1/restricted/list/list-users?p=1&elems=10
|
|
||||||
params:
|
|
||||||
- name: p
|
|
||||||
value: "1"
|
|
||||||
type: query
|
|
||||||
- name: elems
|
|
||||||
value: "10"
|
|
||||||
type: query
|
|
||||||
|
|
||||||
settings:
|
|
||||||
encodeUrl: true
|
|
||||||
timeout: 0
|
|
||||||
followRedirects: true
|
|
||||||
maxRedirects: 5
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: orders
|
name: orders
|
||||||
type: folder
|
type: folder
|
||||||
seq: 11
|
seq: 10
|
||||||
|
|
||||||
request:
|
request:
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: product-translation
|
name: product-translation
|
||||||
type: folder
|
type: folder
|
||||||
seq: 2
|
seq: 3
|
||||||
|
|
||||||
request:
|
request:
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: storage-old
|
name: storage-old
|
||||||
type: folder
|
type: folder
|
||||||
seq: 1
|
seq: 2
|
||||||
|
|
||||||
request:
|
request:
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
info:
|
info:
|
||||||
name: storage-restricted
|
name: storage-restricted
|
||||||
type: folder
|
type: folder
|
||||||
seq: 9
|
seq: 8
|
||||||
|
|
||||||
request:
|
request:
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ CREATE TABLE IF NOT EXISTS b2b_customers (
|
|||||||
country_id INT NULL DEFAULT 2,
|
country_id INT NULL DEFAULT 2,
|
||||||
created_at DATETIME(6) NULL,
|
created_at DATETIME(6) NULL,
|
||||||
updated_at DATETIME(6) NULL,
|
updated_at DATETIME(6) NULL,
|
||||||
deleted_at DATETIME(6) NULL
|
deleted_at DATETIME(6) NULL,
|
||||||
|
is_no_vat TINYINT(1) NULL DEFAULT 0
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_customers_email
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_customers_email
|
||||||
@@ -161,6 +162,16 @@ CREATE TABLE IF NOT EXISTS b2b_favorites (
|
|||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
|
-- oems
|
||||||
|
CREATE TABLE IF NOT EXISTS b2b_oems (
|
||||||
|
user_id BIGINT UNSIGNED NOT NULL,
|
||||||
|
product_id INT UNSIGNED NOT NULL,
|
||||||
|
PRIMARY KEY (user_id, product_id),
|
||||||
|
CONSTRAINT fk_oems_customer FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT fk_oems_product FOREIGN KEY (product_id) REFERENCES ps_product(id_product) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
-- refresh_tokens
|
-- refresh_tokens
|
||||||
CREATE TABLE IF NOT EXISTS b2b_refresh_tokens (
|
CREATE TABLE IF NOT EXISTS b2b_refresh_tokens (
|
||||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ INSERT INTO `b2b_route_roles` (`route_id`, `role_id`) VALUES
|
|||||||
(2, '1'),
|
(2, '1'),
|
||||||
(2, '2'),
|
(2, '2'),
|
||||||
(2, '3'),
|
(2, '3'),
|
||||||
|
(2, '4'),
|
||||||
(3, '1'),
|
(3, '1'),
|
||||||
(3, '2'),
|
(3, '2'),
|
||||||
(3, '3'),
|
(3, '3'),
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ READS SQL DATA
|
|||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
DECLARE v_tax_rate DECIMAL(10,4) DEFAULT 0;
|
DECLARE v_tax_rate DECIMAL(10,4) DEFAULT 0;
|
||||||
|
DECLARE v_tax_group INT;
|
||||||
|
|
||||||
DECLARE v_base_raw DECIMAL(20,6);
|
DECLARE v_base_raw DECIMAL(20,6);
|
||||||
DECLARE v_base DECIMAL(20,6);
|
DECLARE v_base DECIMAL(20,6);
|
||||||
@@ -29,45 +30,54 @@ BEGIN
|
|||||||
|
|
||||||
DECLARE v_has_specific INT DEFAULT 0;
|
DECLARE v_has_specific INT DEFAULT 0;
|
||||||
|
|
||||||
-- currency
|
|
||||||
DECLARE v_target_currency BIGINT;
|
DECLARE v_target_currency BIGINT;
|
||||||
DECLARE v_target_rate DECIMAL(13,6) DEFAULT 1;
|
DECLARE v_target_rate DECIMAL(13,6) DEFAULT 1;
|
||||||
DECLARE v_specific_rate DECIMAL(13,6) DEFAULT 1;
|
DECLARE v_specific_rate DECIMAL(13,6) DEFAULT 1;
|
||||||
|
|
||||||
|
DECLARE v_is_no_vat TINYINT DEFAULT 0;
|
||||||
|
|
||||||
SET p_id_product_attribute = NULLIF(p_id_product_attribute, 0);
|
SET p_id_product_attribute = NULLIF(p_id_product_attribute, 0);
|
||||||
|
|
||||||
|
-- ================= CUSTOMER VAT =================
|
||||||
|
SELECT COALESCE(c.is_no_vat, 0)
|
||||||
|
INTO v_is_no_vat
|
||||||
|
FROM b2b_customers c
|
||||||
|
WHERE c.id = p_id_customer
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- ================= TAX GROUP =================
|
||||||
|
SELECT ps.id_tax_rules_group
|
||||||
|
INTO v_tax_group
|
||||||
|
FROM ps_product_shop ps
|
||||||
|
WHERE ps.id_product = p_id_product
|
||||||
|
AND ps.id_shop = p_id_shop
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
-- ================= TAX =================
|
-- ================= TAX =================
|
||||||
SELECT COALESCE(t.rate, 0)
|
SELECT COALESCE(t.rate, 0)
|
||||||
INTO v_tax_rate
|
INTO v_tax_rate
|
||||||
FROM ps_tax_rule tr
|
FROM ps_tax_rule tr
|
||||||
JOIN ps_tax t ON t.id_tax = tr.id_tax
|
JOIN ps_tax t ON t.id_tax = tr.id_tax
|
||||||
LEFT JOIN b2b_countries c ON c.id = p_id_country
|
LEFT JOIN b2b_countries c ON c.id = p_id_country
|
||||||
WHERE tr.id_tax_rules_group = (
|
WHERE tr.id_tax_rules_group = v_tax_group
|
||||||
SELECT ps.id_tax_rules_group
|
AND tr.id_country = c.ps_id_country
|
||||||
FROM ps_product_shop ps
|
|
||||||
WHERE ps.id_product = p_id_product
|
|
||||||
AND ps.id_shop = p_id_shop
|
|
||||||
LIMIT 1
|
|
||||||
)
|
|
||||||
AND tr.id_country = c.ps_id_country
|
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
-- ================= TARGET CURRENCY =================
|
IF v_is_no_vat = 1 THEN
|
||||||
SELECT c.b2b_id_currency
|
SET v_tax_rate = 0;
|
||||||
INTO v_target_currency
|
END IF;
|
||||||
|
|
||||||
|
-- ================= CURRENCY =================
|
||||||
|
SELECT c.b2b_id_currency, r.conversion_rate
|
||||||
|
INTO v_target_currency, v_target_rate
|
||||||
FROM b2b_countries c
|
FROM b2b_countries c
|
||||||
|
LEFT JOIN b2b_currency_rates r
|
||||||
|
ON r.b2b_id_currency = c.b2b_id_currency
|
||||||
WHERE c.id = p_id_country
|
WHERE c.id = p_id_country
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
-- latest target rate
|
|
||||||
SELECT r.conversion_rate
|
|
||||||
INTO v_target_rate
|
|
||||||
FROM b2b_currency_rates r
|
|
||||||
WHERE r.b2b_id_currency = v_target_currency
|
|
||||||
ORDER BY r.created_at DESC
|
ORDER BY r.created_at DESC
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
-- ================= BASE PRICE (RAW) =================
|
-- ================= BASE PRICE =================
|
||||||
SELECT
|
SELECT
|
||||||
COALESCE(ps.price, p.price) + COALESCE(pas.price, 0)
|
COALESCE(ps.price, p.price) + COALESCE(pas.price, 0)
|
||||||
INTO v_base_raw
|
INTO v_base_raw
|
||||||
@@ -79,8 +89,8 @@ BEGIN
|
|||||||
AND pas.id_shop = p_id_shop
|
AND pas.id_shop = p_id_shop
|
||||||
WHERE p.id_product = p_id_product;
|
WHERE p.id_product = p_id_product;
|
||||||
|
|
||||||
-- convert base to target currency
|
|
||||||
SET v_base = v_base_raw * v_target_rate;
|
SET v_base = v_base_raw * v_target_rate;
|
||||||
|
SET v_excl = v_base;
|
||||||
|
|
||||||
-- ================= RULE SELECTION =================
|
-- ================= RULE SELECTION =================
|
||||||
SELECT
|
SELECT
|
||||||
@@ -99,71 +109,67 @@ BEGIN
|
|||||||
|
|
||||||
FROM b2b_specific_price bsp
|
FROM b2b_specific_price bsp
|
||||||
|
|
||||||
|
LEFT JOIN b2b_specific_price_product spp
|
||||||
|
ON spp.b2b_specific_price_id = bsp.id
|
||||||
|
AND spp.id_product = p_id_product
|
||||||
|
|
||||||
|
LEFT JOIN b2b_specific_price_product_attribute spa
|
||||||
|
ON spa.b2b_specific_price_id = bsp.id
|
||||||
|
AND spa.id_product_attribute = p_id_product_attribute
|
||||||
|
|
||||||
|
LEFT JOIN b2b_specific_price_customer spc
|
||||||
|
ON spc.b2b_specific_price_id = bsp.id
|
||||||
|
AND spc.b2b_id_customer = p_id_customer
|
||||||
|
|
||||||
|
LEFT JOIN b2b_specific_price_country spco
|
||||||
|
ON spco.b2b_specific_price_id = bsp.id
|
||||||
|
AND spco.b2b_id_country = p_id_country
|
||||||
|
|
||||||
|
LEFT JOIN b2b_specific_price_category spcat
|
||||||
|
ON spcat.b2b_specific_price_id = bsp.id
|
||||||
|
|
||||||
|
LEFT JOIN ps_category_product cp
|
||||||
|
ON cp.id_category = spcat.id_category
|
||||||
|
AND cp.id_product = p_id_product
|
||||||
|
|
||||||
WHERE bsp.is_active = 1
|
WHERE bsp.is_active = 1
|
||||||
AND bsp.from_quantity <= p_quantity
|
AND bsp.from_quantity <= p_quantity
|
||||||
|
|
||||||
-- intersection rules (unchanged)
|
AND (spp.id_product IS NOT NULL OR NOT EXISTS (
|
||||||
AND (
|
SELECT 1 FROM b2b_specific_price_product x WHERE x.b2b_specific_price_id = bsp.id
|
||||||
NOT EXISTS (SELECT 1 FROM b2b_specific_price_product x WHERE x.b2b_specific_price_id = bsp.id)
|
))
|
||||||
OR EXISTS (SELECT 1 FROM b2b_specific_price_product x WHERE x.b2b_specific_price_id = bsp.id AND x.id_product = p_id_product)
|
|
||||||
)
|
|
||||||
|
|
||||||
AND (
|
AND (spa.id_product_attribute IS NOT NULL OR NOT EXISTS (
|
||||||
NOT EXISTS (SELECT 1 FROM b2b_specific_price_product_attribute x WHERE x.b2b_specific_price_id = bsp.id)
|
SELECT 1 FROM b2b_specific_price_product_attribute x WHERE x.b2b_specific_price_id = bsp.id
|
||||||
OR EXISTS (SELECT 1 FROM b2b_specific_price_product_attribute x WHERE x.b2b_specific_price_id = bsp.id AND x.id_product_attribute = p_id_product_attribute)
|
))
|
||||||
)
|
|
||||||
|
|
||||||
AND (
|
AND (spc.b2b_id_customer IS NOT NULL OR NOT EXISTS (
|
||||||
NOT EXISTS (SELECT 1 FROM b2b_specific_price_category x WHERE x.b2b_specific_price_id = bsp.id)
|
SELECT 1 FROM b2b_specific_price_customer x WHERE x.b2b_specific_price_id = bsp.id
|
||||||
OR EXISTS (
|
))
|
||||||
SELECT 1 FROM b2b_specific_price_category x
|
|
||||||
JOIN ps_category_product cp ON cp.id_category = x.id_category
|
|
||||||
WHERE x.b2b_specific_price_id = bsp.id AND cp.id_product = p_id_product
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
AND (
|
AND (spco.b2b_id_country IS NOT NULL OR NOT EXISTS (
|
||||||
NOT EXISTS (SELECT 1 FROM b2b_specific_price_customer x WHERE x.b2b_specific_price_id = bsp.id)
|
SELECT 1 FROM b2b_specific_price_country x WHERE x.b2b_specific_price_id = bsp.id
|
||||||
OR EXISTS (SELECT 1 FROM b2b_specific_price_customer x WHERE x.b2b_specific_price_id = bsp.id AND x.b2b_id_customer = p_id_customer)
|
))
|
||||||
)
|
|
||||||
|
|
||||||
AND (
|
AND (cp.id_product IS NOT NULL OR NOT EXISTS (
|
||||||
NOT EXISTS (SELECT 1 FROM b2b_specific_price_country x WHERE x.b2b_specific_price_id = bsp.id)
|
SELECT 1 FROM b2b_specific_price_category x WHERE x.b2b_specific_price_id = bsp.id
|
||||||
OR EXISTS (SELECT 1 FROM b2b_specific_price_country x WHERE x.b2b_specific_price_id = bsp.id AND x.b2b_id_country = p_id_country)
|
))
|
||||||
)
|
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
-- customer wins
|
(spc.b2b_id_customer IS NOT NULL) DESC,
|
||||||
(EXISTS (SELECT 1 FROM b2b_specific_price_customer x WHERE x.b2b_specific_price_id = bsp.id AND x.b2b_id_customer = p_id_customer)) DESC,
|
(spa.id_product_attribute IS NOT NULL) DESC,
|
||||||
|
(spp.id_product IS NOT NULL) DESC,
|
||||||
-- attribute
|
(cp.id_product IS NOT NULL) DESC,
|
||||||
(EXISTS (SELECT 1 FROM b2b_specific_price_product_attribute x WHERE x.b2b_specific_price_id = bsp.id AND x.id_product_attribute = p_id_product_attribute)) DESC,
|
(spco.b2b_id_country IS NOT NULL) DESC,
|
||||||
|
|
||||||
-- product
|
|
||||||
(EXISTS (SELECT 1 FROM b2b_specific_price_product x WHERE x.b2b_specific_price_id = bsp.id AND x.id_product = p_id_product)) DESC,
|
|
||||||
|
|
||||||
-- category
|
|
||||||
(EXISTS (
|
|
||||||
SELECT 1 FROM b2b_specific_price_category x
|
|
||||||
JOIN ps_category_product cp ON cp.id_category = x.id_category
|
|
||||||
WHERE x.b2b_specific_price_id = bsp.id AND cp.id_product = p_id_product
|
|
||||||
)) DESC,
|
|
||||||
|
|
||||||
-- country
|
|
||||||
(EXISTS (SELECT 1 FROM b2b_specific_price_country x WHERE x.b2b_specific_price_id = bsp.id AND x.b2b_id_country = p_id_country)) DESC,
|
|
||||||
|
|
||||||
bsp.id DESC
|
bsp.id DESC
|
||||||
|
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
-- ================= APPLY =================
|
-- ================= APPLY =================
|
||||||
SET v_excl = v_base;
|
|
||||||
|
|
||||||
IF v_has_specific = 1 THEN
|
IF v_has_specific = 1 THEN
|
||||||
|
|
||||||
IF v_reduction_type = 'amount' THEN
|
IF v_reduction_type = 'amount' THEN
|
||||||
|
|
||||||
-- convert specific price currency if needed
|
|
||||||
IF v_specific_currency_id IS NOT NULL AND v_specific_currency_id != v_target_currency THEN
|
IF v_specific_currency_id IS NOT NULL AND v_specific_currency_id != v_target_currency THEN
|
||||||
|
|
||||||
SELECT r.conversion_rate
|
SELECT r.conversion_rate
|
||||||
@@ -173,7 +179,6 @@ BEGIN
|
|||||||
ORDER BY r.created_at DESC
|
ORDER BY r.created_at DESC
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
-- normalize → then convert to target
|
|
||||||
SET v_excl = (v_fixed_price / v_specific_rate) * v_target_rate;
|
SET v_excl = (v_fixed_price / v_specific_rate) * v_target_rate;
|
||||||
|
|
||||||
ELSE
|
ELSE
|
||||||
@@ -379,10 +384,19 @@ BEGIN
|
|||||||
m.name AS manufacturer,
|
m.name AS manufacturer,
|
||||||
cl.name AS category,
|
cl.name AS category,
|
||||||
|
|
||||||
|
p.is_oem,
|
||||||
EXISTS(
|
EXISTS(
|
||||||
SELECT 1 FROM b2b_favorites f
|
SELECT 1 FROM b2b_favorites f
|
||||||
WHERE f.user_id = p_id_customer AND f.product_id = p_id_product
|
WHERE f.user_id = p_id_customer AND f.product_id = p_id_product
|
||||||
) AS is_favorite
|
) AS is_favorite,
|
||||||
|
CASE
|
||||||
|
WHEN ps.date_add >= DATE_SUB(
|
||||||
|
NOW(),
|
||||||
|
INTERVAL COALESCE(CAST(ps_configuration.value AS SIGNED), 20) DAY
|
||||||
|
) AND ps.active = 1
|
||||||
|
THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END AS is_new
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -400,6 +414,8 @@ BEGIN
|
|||||||
AND cl.id_shop = p_id_shop
|
AND cl.id_shop = p_id_shop
|
||||||
LEFT JOIN ps_manufacturer m
|
LEFT JOIN ps_manufacturer m
|
||||||
ON m.id_manufacturer = p.id_manufacturer
|
ON m.id_manufacturer = p.id_manufacturer
|
||||||
|
LEFT JOIN ps_configuration
|
||||||
|
ON ps_configuration.name = PS_NB_DAYS_NEW_PRODUCT
|
||||||
|
|
||||||
WHERE p.id_product = p_id_product
|
WHERE p.id_product = p_id_product
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user