carts #25
@@ -29,7 +29,9 @@ func CartsHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
|
|
||||||
r.Get("/add-new-cart", handler.AddNewCart)
|
r.Get("/add-new-cart", handler.AddNewCart)
|
||||||
r.Get("/change-cart-name", handler.ChangeCartName)
|
r.Get("/change-cart-name", handler.ChangeCartName)
|
||||||
|
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)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -75,6 +77,22 @@ func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
|||||||
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(nullable.GetNil(""), 0, i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
|
||||||
|
userID, ok := c.Locals("userID").(uint)
|
||||||
|
if !ok {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
carts_info, err := h.cartsService.RetrieveCartsInfo(userID)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(response.Make(&carts_info, 0, i18n.T_(c, response.Message_OK)))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(uint)
|
userID, ok := c.Locals("userID").(uint)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -97,3 +115,54 @@ 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)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
||||||
|
userID, ok := c.Locals("userID").(uint)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
amount_attribute := c.Query("amount")
|
||||||
|
amount, err := strconv.Atoi(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, uint(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)))
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type CustomerCart struct {
|
type CustomerCart struct {
|
||||||
CartID uint64 `gorm:"column:cart_id;primaryKey;autoIncrement" json:"cart_id"`
|
CartID uint `gorm:"column:cart_id;primaryKey;autoIncrement" json:"cart_id"`
|
||||||
UserID uint64 `gorm:"column:user_id;not null;index" json:"user_id"`
|
UserID uint `gorm:"column:user_id;not null;index" json:"-"`
|
||||||
Name *string `gorm:"column:name;size:255" json:"name,omitempty"`
|
Name *string `gorm:"column:name;size:255" json:"name,omitempty"`
|
||||||
Products []CartProduct `gorm:"foreignKey:CartID;references:CartID" json:"products,omitempty"`
|
Products []CartProduct `gorm:"foreignKey:CartID;references:CartID" json:"products,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -12,11 +12,11 @@ func (CustomerCart) TableName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CartProduct struct {
|
type CartProduct struct {
|
||||||
ID uint64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"-"`
|
||||||
CartID uint64 `gorm:"column:cart_id;not null;index" json:"cart_id"`
|
CartID uint `gorm:"column:cart_id;not null;index" json:"-"`
|
||||||
ProductID uint `gorm:"column:product_id;not null" json:"product_id"`
|
ProductID uint `gorm:"column:product_id;not null" json:"product_id"`
|
||||||
ProductAttributeID *uint64 `gorm:"column:product_attribute_id" json:"product_attribute_id,omitempty"`
|
ProductAttributeID *uint `gorm:"column:product_attribute_id" json:"product_attribute_id,omitempty"`
|
||||||
Amount int `gorm:"column:amount;not null" json:"amount"`
|
Amount uint `gorm:"column:amount;not null" json:"amount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (CartProduct) TableName() string {
|
func (CartProduct) TableName() string {
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ type UICartsRepo interface {
|
|||||||
CreateNewCart(user_id uint) (model.CustomerCart, error)
|
CreateNewCart(user_id uint) (model.CustomerCart, error)
|
||||||
UserHasCart(user_id uint, cart_id uint) (uint, error)
|
UserHasCart(user_id uint, cart_id uint) (uint, 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)
|
||||||
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) (uint, error)
|
||||||
|
AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type CartsRepo struct{}
|
type CartsRepo struct{}
|
||||||
@@ -38,7 +41,7 @@ func (repo *CartsRepo) CreateNewCart(user_id uint) (model.CustomerCart, error) {
|
|||||||
name = constdata.DEFAULT_NEW_CART_NAME
|
name = constdata.DEFAULT_NEW_CART_NAME
|
||||||
|
|
||||||
cart := model.CustomerCart{
|
cart := model.CustomerCart{
|
||||||
UserID: uint64(user_id),
|
UserID: user_id,
|
||||||
Name: &name,
|
Name: &name,
|
||||||
}
|
}
|
||||||
err := db.DB.Create(&cart).Error
|
err := db.DB.Create(&cart).Error
|
||||||
@@ -69,14 +72,62 @@ func (repo *CartsRepo) UpdateCartName(user_id uint, cart_id uint, new_name strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *CartsRepo) RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error) {
|
||||||
|
var carts []model.CustomerCart
|
||||||
|
|
||||||
|
err := db.DB.
|
||||||
|
Table("b2b_customer_carts").
|
||||||
|
Where("user_id = ?", user_id).
|
||||||
|
Scan(&carts).
|
||||||
|
Error
|
||||||
|
|
||||||
|
return carts, err
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *CartsRepo) RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error) {
|
func (repo *CartsRepo) RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error) {
|
||||||
var cart model.CustomerCart
|
var cart model.CustomerCart
|
||||||
|
|
||||||
err := db.DB.
|
err := db.DB.
|
||||||
Preload("b2b_carts_products").
|
Preload("Products").
|
||||||
Where("user_id = ? AND cart_id = ?", user_id, cart_id).
|
Where("user_id = ? AND cart_id = ?", user_id, cart_id).
|
||||||
First(&cart).
|
First(&cart).
|
||||||
Error
|
Error
|
||||||
|
|
||||||
return &cart, err
|
return &cart, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id *uint) (uint, error) {
|
||||||
|
var amt uint
|
||||||
|
|
||||||
|
if product_attribute_id == nil {
|
||||||
|
err := db.DB.
|
||||||
|
Table("ps_product_shop").
|
||||||
|
Select("COUNT(*) AS amt").
|
||||||
|
Where("id_product = ?", product_id).
|
||||||
|
Scan(&amt).
|
||||||
|
Error
|
||||||
|
return amt, err
|
||||||
|
|
||||||
|
} else {
|
||||||
|
err := db.DB.
|
||||||
|
Table("ps_product_shop AS ps").
|
||||||
|
Joins("INNER JOIN ps_product_attribute_shop AS pas ON pas.id_product = ps.id_product").
|
||||||
|
Select("COUNT(*) AS amt").
|
||||||
|
Where("ps.id_product = ? AND pas.id_product_attribute = ?", product_id, *product_attribute_id).
|
||||||
|
Scan(&amt).
|
||||||
|
Error
|
||||||
|
return amt, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *CartsRepo) AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error {
|
||||||
|
product := model.CartProduct{
|
||||||
|
CartID: cart_id,
|
||||||
|
ProductID: product_id,
|
||||||
|
ProductAttributeID: product_attribute_id,
|
||||||
|
Amount: amount,
|
||||||
|
}
|
||||||
|
err := db.DB.Create(&product).Error
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ func (s *CartsService) UpdateCartName(user_id uint, cart_id uint, new_name strin
|
|||||||
return s.repo.UpdateCartName(user_id, cart_id, new_name)
|
return s.repo.UpdateCartName(user_id, cart_id, new_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *CartsService) RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error) {
|
||||||
|
return s.repo.RetrieveCartsInfo(user_id)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *CartsService) RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error) {
|
func (s *CartsService) RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error) {
|
||||||
amt, err := s.repo.UserHasCart(user_id, cart_id)
|
amt, err := s.repo.UserHasCart(user_id, cart_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -57,3 +61,23 @@ 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 {
|
||||||
|
amt, err := s.repo.UserHasCart(user_id, cart_id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if amt != 1 {
|
||||||
|
return responseErrors.ErrUserHasNoSuchCart
|
||||||
|
}
|
||||||
|
|
||||||
|
amt, err = s.repo.CheckProductExists(product_id, product_attribute_id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if amt != 1 {
|
||||||
|
return responseErrors.ErrProductOrItsVariationDoesNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.AddProduct(user_id, cart_id, product_id, product_attribute_id, amount)
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ var (
|
|||||||
// Typed errors for carts handler
|
// Typed errors for carts handler
|
||||||
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")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents an error with HTTP status code
|
// Error represents an error with HTTP status code
|
||||||
@@ -148,7 +149,9 @@ func GetErrorCode(c fiber.Ctx, err error) string {
|
|||||||
case errors.Is(err, ErrMaxAmtOfCartsReached):
|
case errors.Is(err, ErrMaxAmtOfCartsReached):
|
||||||
return i18n.T_(c, "error.max_amt_of_carts_reached")
|
return i18n.T_(c, "error.max_amt_of_carts_reached")
|
||||||
case errors.Is(err, ErrUserHasNoSuchCart):
|
case errors.Is(err, ErrUserHasNoSuchCart):
|
||||||
return i18n.T_(c, "error.max_amt_of_carts_reached")
|
return i18n.T_(c, "error.user_has_no_such_cart")
|
||||||
|
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
|
return i18n.T_(c, "error.product_or_its_variation_does_not_exist")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return i18n.T_(c, "error.err_internal_server_error")
|
return i18n.T_(c, "error.err_internal_server_error")
|
||||||
@@ -187,7 +190,8 @@ func GetErrorStatus(err error) int {
|
|||||||
errors.Is(err, ErrBadPaging),
|
errors.Is(err, ErrBadPaging),
|
||||||
errors.Is(err, ErrNoRootFound),
|
errors.Is(err, ErrNoRootFound),
|
||||||
errors.Is(err, ErrMaxAmtOfCartsReached),
|
errors.Is(err, ErrMaxAmtOfCartsReached),
|
||||||
errors.Is(err, ErrUserHasNoSuchCart):
|
errors.Is(err, ErrUserHasNoSuchCart),
|
||||||
|
errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
return fiber.StatusBadRequest
|
return fiber.StatusBadRequest
|
||||||
case errors.Is(err, ErrEmailExists):
|
case errors.Is(err, ErrEmailExists):
|
||||||
return fiber.StatusConflict
|
return fiber.StatusConflict
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ CREATE TABLE IF NOT EXISTS b2b_carts_products (
|
|||||||
cart_id BIGINT UNSIGNED NOT NULL,
|
cart_id BIGINT UNSIGNED NOT NULL,
|
||||||
product_id INT UNSIGNED NOT NULL,
|
product_id INT UNSIGNED NOT NULL,
|
||||||
product_attribute_id BIGINT NULL,
|
product_attribute_id BIGINT NULL,
|
||||||
amount INT NOT NULL,
|
amount INT UNSIGNED NOT NULL,
|
||||||
CONSTRAINT fk_carts_products_customer_carts FOREIGN KEY (cart_id) REFERENCES b2b_customer_carts (cart_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
CONSTRAINT fk_carts_products_customer_carts FOREIGN KEY (cart_id) REFERENCES b2b_customer_carts (cart_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
CONSTRAINT fk_carts_products_product FOREIGN KEY (product_id) REFERENCES ps_product (id_product) ON DELETE CASCADE ON UPDATE CASCADE
|
CONSTRAINT fk_carts_products_product FOREIGN KEY (product_id) REFERENCES ps_product (id_product) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|||||||
Reference in New Issue
Block a user