code ready, time for testing...
This commit is contained in:
@@ -8,4 +8,5 @@ const (
|
||||
UserDeleteAny Permission = "user.delete.any"
|
||||
CurrencyWrite Permission = "currency.write"
|
||||
ViewAllOrders Permission = "orders.view"
|
||||
ModifyAllOrders Permission = "orders.modify"
|
||||
)
|
||||
|
||||
@@ -61,8 +61,9 @@ func (h *OrdersHandler) ListOrders(c fiber.Ctx) error {
|
||||
}
|
||||
|
||||
var columnMappingListOrders map[string]string = map[string]string{
|
||||
"order_id": "b2b_customer_orders.id",
|
||||
"order_id": "b2b_customer_orders.order_id",
|
||||
"user_id": "b2b_customer_orders.user_id",
|
||||
"name": "b2b_customer_orders.name",
|
||||
"country_id": "b2b_customer_orders.country_id",
|
||||
"status": "b2b_customer_orders.status",
|
||||
}
|
||||
@@ -81,6 +82,7 @@ func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error {
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
|
||||
address_info := c.Query("address_info")
|
||||
country_id_attribute := c.Query("country_id")
|
||||
country_id, err := strconv.Atoi(country_id_attribute)
|
||||
if err != nil {
|
||||
@@ -88,9 +90,9 @@ func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error {
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
|
||||
address_info := c.Query("address_info")
|
||||
name := c.Query("name")
|
||||
|
||||
err = h.ordersService.PlaceNewOrder(userID, uint(cart_id), uint(country_id), address_info)
|
||||
err = h.ordersService.PlaceNewOrder(userID, uint(cart_id), name, uint(country_id), address_info)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package model
|
||||
|
||||
type CustomerOrder struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
UserID uint `gorm:"column:user_id;not null;index" json:"-"`
|
||||
OrderID uint `gorm:"column:order_id;primaryKey;autoIncrement" json:"order_id"`
|
||||
UserID uint `gorm:"column:user_id;not null;index" json:"user_id"`
|
||||
Name string `gorm:"column:name;not null" json:"name"`
|
||||
CountryID uint `gorm:"column:country_id;not null" json:"country_id"`
|
||||
AddressJSON *string `gorm:"column:address_json" json:"address_json,omitempty"`
|
||||
Status *string `gorm:"column:status;size:50" json:"status,omitempty"`
|
||||
Products []OrderProduct `gorm:"foreignKey:OrderID;references:ID" json:"products,omitempty"`
|
||||
AddressJSON string `gorm:"column:address_json;not null" json:"address_json"`
|
||||
Status string `gorm:"column:status;size:50;not null" json:"status"`
|
||||
Products []OrderProduct `gorm:"foreignKey:OrderID;references:ID" json:"products"`
|
||||
}
|
||||
|
||||
func (CustomerOrder) TableName() string {
|
||||
@@ -14,7 +15,6 @@ func (CustomerOrder) TableName() string {
|
||||
}
|
||||
|
||||
type OrderProduct struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"-"`
|
||||
OrderID uint `gorm:"column:order_id;not null;index" json:"-"`
|
||||
ProductID uint `gorm:"column:product_id;not null" json:"product_id"`
|
||||
ProductAttributeID *uint `gorm:"column:product_attribute_id" json:"product_attribute_id,omitempty"`
|
||||
|
||||
@@ -9,11 +9,11 @@ import (
|
||||
type UICartsRepo interface {
|
||||
CartsAmount(user_id uint) (uint, error)
|
||||
CreateNewCart(user_id uint) (model.CustomerCart, error)
|
||||
UserHasCart(user_id uint, cart_id uint) (uint, error)
|
||||
UserHasCart(user_id uint, cart_id uint) (bool, 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)
|
||||
CheckProductExists(product_id uint, product_attribute_id *uint) (uint, 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
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func (repo *CartsRepo) CreateNewCart(user_id uint) (model.CustomerCart, error) {
|
||||
return cart, err
|
||||
}
|
||||
|
||||
func (repo *CartsRepo) UserHasCart(user_id uint, cart_id uint) (uint, error) {
|
||||
func (repo *CartsRepo) UserHasCart(user_id uint, cart_id uint) (bool, error) {
|
||||
var amt uint
|
||||
|
||||
err := db.DB.
|
||||
@@ -59,7 +59,7 @@ func (repo *CartsRepo) UserHasCart(user_id uint, cart_id uint) (uint, error) {
|
||||
Scan(&amt).
|
||||
Error
|
||||
|
||||
return amt, err
|
||||
return amt >= 1, err
|
||||
}
|
||||
|
||||
func (repo *CartsRepo) UpdateCartName(user_id uint, cart_id uint, new_name string) error {
|
||||
@@ -96,7 +96,7 @@ func (repo *CartsRepo) RetrieveCart(user_id uint, cart_id uint) (*model.Customer
|
||||
return &cart, err
|
||||
}
|
||||
|
||||
func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id *uint) (uint, error) {
|
||||
func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id *uint) (bool, error) {
|
||||
var amt uint
|
||||
|
||||
if product_attribute_id == nil {
|
||||
@@ -106,7 +106,7 @@ func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id
|
||||
Where("id_product = ?", product_id).
|
||||
Scan(&amt).
|
||||
Error
|
||||
return amt, err
|
||||
return amt >= 1, err
|
||||
|
||||
} else {
|
||||
err := db.DB.
|
||||
@@ -116,7 +116,7 @@ func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id
|
||||
Where("ps.id_product = ? AND pas.id_product_attribute = ?", product_id, *product_attribute_id).
|
||||
Scan(&amt).
|
||||
Error
|
||||
return amt, err
|
||||
return amt >= 1, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,17 @@ package ordersRepo
|
||||
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 UIOrdersRepo interface {
|
||||
UserHasOrder(user_id uint, order_id uint) (bool, error)
|
||||
Find(user_id uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.CustomerOrder], error)
|
||||
PlaceNewOrder(user_id uint, cart_id uint, country_id uint, address_info string) error
|
||||
ChangeOrderAddress(user_id uint, order_id uint, country_id uint, address_info string) error
|
||||
ChangeOrderStatus(user_id uint, order_id uint, status string) error
|
||||
PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string) error
|
||||
ChangeOrderAddress(order_id uint, country_id uint, address_info string) error
|
||||
ChangeOrderStatus(order_id uint, status string) error
|
||||
}
|
||||
|
||||
type OrdersRepo struct{}
|
||||
@@ -20,6 +22,19 @@ func New() UIOrdersRepo {
|
||||
return &OrdersRepo{}
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) UserHasOrder(user_id uint, order_id uint) (bool, error) {
|
||||
var amt uint
|
||||
|
||||
err := db.DB.
|
||||
Table("b2b_customer_orders").
|
||||
Select("COUNT(*) AS amt").
|
||||
Where("user_id = ? AND order_id = ?", user_id, order_id).
|
||||
Scan(&amt).
|
||||
Error
|
||||
|
||||
return amt >= 1, err
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) Find(user_id uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.CustomerOrder], error) {
|
||||
var list []model.CustomerOrder
|
||||
var total int64
|
||||
@@ -54,15 +69,42 @@ func (repo *OrdersRepo) Find(user_id uint, p find.Paging, filt *filters.FiltersL
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) PlaceNewOrder(user_id uint, cart_id uint, country_id uint, address_info string) error {
|
||||
|
||||
return nil
|
||||
func (repo *OrdersRepo) PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string) error {
|
||||
order := model.CustomerOrder{
|
||||
UserID: cart.UserID,
|
||||
Name: name,
|
||||
CountryID: country_id,
|
||||
AddressJSON: address_info,
|
||||
Status: constdata.NEW_ORDER_STATUS,
|
||||
Products: make([]model.OrderProduct, 0, len(cart.Products)),
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) ChangeOrderAddress(user_id uint, order_id uint, country_id uint, address_info string) error {
|
||||
return nil
|
||||
for _, product := range cart.Products {
|
||||
order.Products = append(order.Products, model.OrderProduct{
|
||||
ProductID: product.ProductID,
|
||||
ProductAttributeID: product.ProductAttributeID,
|
||||
Amount: product.Amount,
|
||||
})
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) ChangeOrderStatus(user_id uint, order_id uint, status string) error {
|
||||
return nil
|
||||
return db.DB.Create(&order).Error
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) ChangeOrderAddress(order_id uint, country_id uint, address_info string) error {
|
||||
return db.DB.
|
||||
Table("b2b_customer_orders").
|
||||
Where("order_id = ?", order_id).
|
||||
Updates(map[string]interface{}{
|
||||
"country_id": country_id,
|
||||
"address_info": address_info,
|
||||
}).
|
||||
Error
|
||||
}
|
||||
|
||||
func (repo *OrdersRepo) ChangeOrderStatus(order_id uint, status string) error {
|
||||
return db.DB.
|
||||
Table("b2b_customer_orders").
|
||||
Where("order_id = ?", order_id).
|
||||
Update("status", status).
|
||||
Error
|
||||
}
|
||||
|
||||
@@ -37,17 +37,17 @@ func (s *OrderService) Find(user *model.Customer, p find.Paging, filt *filters.F
|
||||
return s.ordersRepo.Find(user.ID, p, filt)
|
||||
}
|
||||
|
||||
func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, country_id uint, address_info string) error {
|
||||
func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, name string, country_id uint, address_info string) error {
|
||||
_, err := s.addressesService.ValidateAddressJson(address_info, country_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
amt, err := s.cartsRepo.UserHasCart(user_id, cart_id)
|
||||
exists, err := s.cartsRepo.UserHasCart(user_id, cart_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if amt <= 0 {
|
||||
if !exists {
|
||||
return responseErrors.ErrUserHasNoSuchCart
|
||||
}
|
||||
|
||||
@@ -59,14 +59,45 @@ func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, country_id uint
|
||||
return responseErrors.ErrEmptyCart
|
||||
}
|
||||
|
||||
if name == "" && cart.Name != nil {
|
||||
name = *cart.Name
|
||||
}
|
||||
|
||||
// all checks passed
|
||||
return s.ordersRepo.PlaceNewOrder(user_id, cart_id, country_id, address_info)
|
||||
return s.ordersRepo.PlaceNewOrder(cart, name, country_id, address_info)
|
||||
}
|
||||
|
||||
func (s *OrderService) ChangeOrderAddress(user *model.Customer, order_id uint, country_id uint, address_info string) error {
|
||||
return nil
|
||||
_, err := s.addressesService.ValidateAddressJson(address_info, country_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !user.HasPermission(perms.ModifyAllOrders) {
|
||||
exists, err := s.ordersRepo.UserHasOrder(user.ID, order_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return responseErrors.ErrUserHasNoSuchOrder
|
||||
}
|
||||
}
|
||||
|
||||
return s.ordersRepo.ChangeOrderAddress(order_id, country_id, address_info)
|
||||
}
|
||||
|
||||
func (s *OrderService) ChangeOrderStatus(user *model.Customer, order_id uint, status string) error {
|
||||
return nil
|
||||
if !user.HasPermission(perms.ModifyAllOrders) {
|
||||
exists, err := s.ordersRepo.UserHasOrder(user.ID, order_id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return responseErrors.ErrUserHasNoSuchOrder
|
||||
}
|
||||
}
|
||||
|
||||
return s.ordersRepo.ChangeOrderStatus(order_id, status)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ const MAX_AMOUNT_OF_ADDRESSES_PER_USER = 10
|
||||
|
||||
const USER_LOCALE = "user"
|
||||
|
||||
// ORDERS
|
||||
const NEW_ORDER_STATUS = "PENDING"
|
||||
|
||||
// WEBDAV
|
||||
const NBYTES_IN_WEBDAV_TOKEN = 32
|
||||
const WEBDAV_HREF_ROOT = "http://localhost:3000/api/v1/webdav/storage"
|
||||
|
||||
@@ -65,7 +65,10 @@ var (
|
||||
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
||||
ErrUserHasNoSuchCart = errors.New("user does not have cart with given id")
|
||||
ErrProductOrItsVariationDoesNotExist = errors.New("product or its variation with given ids does not exist")
|
||||
|
||||
// Typed errors for orders handler
|
||||
ErrEmptyCart = errors.New("the cart is empty")
|
||||
ErrUserHasNoSuchOrder = errors.New("user does not have order with given id")
|
||||
|
||||
// Typed errors for storage
|
||||
ErrAccessDenied = errors.New("access denied!")
|
||||
@@ -196,8 +199,11 @@ func GetErrorCode(c fiber.Ctx, err error) string {
|
||||
return i18n.T_(c, "error.err_user_has_no_such_cart")
|
||||
case errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||
return i18n.T_(c, "error.err_product_or_its_variation_does_not_exist")
|
||||
|
||||
case errors.Is(err, ErrEmptyCart):
|
||||
return i18n.T_(c, "error.err_cart_is_empty")
|
||||
case errors.Is(err, ErrUserHasNoSuchOrder):
|
||||
return i18n.T_(c, "error.err_user_has_no_such_order")
|
||||
|
||||
case errors.Is(err, ErrAccessDenied):
|
||||
return i18n.T_(c, "error.err_access_denied")
|
||||
@@ -272,6 +278,7 @@ func GetErrorStatus(err error) int {
|
||||
errors.Is(err, ErrUserHasNoSuchCart),
|
||||
errors.Is(err, ErrProductOrItsVariationDoesNotExist),
|
||||
errors.Is(err, ErrEmptyCart),
|
||||
errors.Is(err, ErrUserHasNoSuchOrder),
|
||||
errors.Is(err, ErrAccessDenied),
|
||||
errors.Is(err, ErrFolderDoesNotExist),
|
||||
errors.Is(err, ErrFileDoesNotExist),
|
||||
|
||||
@@ -130,7 +130,7 @@ FOREIGN KEY (role_id) REFERENCES b2b_roles(id);
|
||||
|
||||
-- customer_carts
|
||||
CREATE TABLE IF NOT EXISTS b2b_customer_carts (
|
||||
cart_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
cart_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NULL,
|
||||
CONSTRAINT fk_customer_carts_customers FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
@@ -140,8 +140,8 @@ CREATE INDEX IF NOT EXISTS idx_customer_carts_user_id ON b2b_customer_carts (use
|
||||
|
||||
-- carts_products
|
||||
CREATE TABLE IF NOT EXISTS b2b_carts_products (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
cart_id INT UNSIGNED NOT NULL,
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
cart_id BIGINT UNSIGNED NOT NULL,
|
||||
product_id INT UNSIGNED NOT NULL,
|
||||
product_attribute_id INT NULL,
|
||||
amount INT UNSIGNED NOT NULL,
|
||||
@@ -153,11 +153,12 @@ CREATE INDEX IF NOT EXISTS idx_carts_products_cart_id ON b2b_carts_products (car
|
||||
|
||||
-- customer_orders
|
||||
CREATE TABLE IF NOT EXISTS b2b_customer_orders (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
order_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
country_id BIGINT UNSIGNED NOT NULL,
|
||||
address_json TEXT NULL,
|
||||
status VARCHAR(50) NULL,
|
||||
address_json TEXT NOT NULL,
|
||||
status VARCHAR(50) NOT NULL,
|
||||
CONSTRAINT fk_customer_orders_customers FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE NO ACTION ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_customer_orders_countries FOREIGN KEY (country_id) REFERENCES b2b_countries(id) ON DELETE NO ACTION ON UPDATE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||
@@ -167,7 +168,7 @@ CREATE INDEX idx_customer_orders_country_id ON b2b_customer_orders (country_id);
|
||||
|
||||
-- orders_products
|
||||
CREATE TABLE IF NOT EXISTS b2b_orders_products (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
order_id BIGINT UNSIGNED NOT NULL,
|
||||
product_id INT UNSIGNED NOT NULL,
|
||||
product_attribute_id INT NULL,
|
||||
|
||||
Reference in New Issue
Block a user