186 lines
5.1 KiB
Go
186 lines
5.1 KiB
Go
package orderService
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
"git.ma-al.com/goc_daniel/b2b/app/repos/cartsRepo"
|
|
"git.ma-al.com/goc_daniel/b2b/app/repos/ordersRepo"
|
|
"git.ma-al.com/goc_daniel/b2b/app/repos/productsRepo"
|
|
"git.ma-al.com/goc_daniel/b2b/app/service/addressesService"
|
|
"git.ma-al.com/goc_daniel/b2b/app/service/emailService"
|
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
|
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
|
"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/app/utils/responseErrors"
|
|
)
|
|
|
|
type OrderService struct {
|
|
ordersRepo ordersRepo.UIOrdersRepo
|
|
cartsRepo cartsRepo.UICartsRepo
|
|
productsRepo productsRepo.UIProductsRepo
|
|
addressesService *addressesService.AddressesService
|
|
emailService *emailService.EmailService
|
|
}
|
|
|
|
func New() *OrderService {
|
|
return &OrderService{
|
|
ordersRepo: ordersRepo.New(),
|
|
cartsRepo: cartsRepo.New(),
|
|
productsRepo: productsRepo.New(),
|
|
addressesService: addressesService.New(),
|
|
emailService: emailService.NewEmailService(),
|
|
}
|
|
}
|
|
|
|
func (s *OrderService) Find(user *model.Customer, p find.Paging, filt *filters.FiltersList) (*find.Found[model.CustomerOrder], error) {
|
|
if !user.HasPermission(perms.OrdersViewAll) {
|
|
// append filter to view only this user's orders
|
|
idStr := strconv.FormatUint(uint64(user.ID), 10)
|
|
filt.Append(filters.Where("b2b_customer_orders.user_id = " + idStr))
|
|
}
|
|
|
|
list, err := s.ordersRepo.Find(user.ID, p, filt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i := 0; i < len(list.Items); i++ {
|
|
address_unparsed, err := s.addressesService.ValidateAddressJson(list.Items[i].AddressString, list.Items[i].CountryID)
|
|
if err != nil {
|
|
logger.Warn("failed to validate address",
|
|
"service", "orderService",
|
|
"order_id", list.Items[i].OrderID,
|
|
"error", err.Error(),
|
|
)
|
|
}
|
|
|
|
list.Items[i].AddressUnparsed = &address_unparsed
|
|
}
|
|
|
|
return list, nil
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
exists, err := s.cartsRepo.UserHasCart(user_id, cart_id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exists {
|
|
return responseErrors.ErrUserHasNoSuchCart
|
|
}
|
|
|
|
cart, err := s.cartsRepo.RetrieveCart(user_id, cart_id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(cart.Products) == 0 {
|
|
return responseErrors.ErrEmptyCart
|
|
}
|
|
|
|
if name == "" && cart.Name != nil {
|
|
name = *cart.Name
|
|
}
|
|
|
|
base_price, tax_incl, tax_excl, err := s.getOrderTotalPrice(user_id, cart_id, country_id)
|
|
|
|
// all checks passed
|
|
err = s.ordersRepo.PlaceNewOrder(cart, name, country_id, address_info, base_price, tax_incl, tax_excl)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// from this point onward we do not cancel this order.
|
|
|
|
// if no error is returned, remove the cart. This should be smooth
|
|
err = s.cartsRepo.RemoveCart(user_id, cart_id)
|
|
if err != nil {
|
|
logger.Warn("failed to remove cart after order placement",
|
|
"service", "orderService",
|
|
"user_id", user_id,
|
|
"cart_id", cart_id,
|
|
"error", err.Error(),
|
|
)
|
|
}
|
|
|
|
// send email to admin
|
|
go func(user_id uint) {
|
|
err := s.emailService.SendNewOrderPlacedNotification(user_id)
|
|
if err != nil {
|
|
logger.Warn("failed to send new order notification",
|
|
"service", "orderService",
|
|
"user_id", user_id,
|
|
"error", err.Error(),
|
|
)
|
|
}
|
|
}(user_id)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *OrderService) ChangeOrderAddress(user *model.Customer, order_id uint, country_id uint, address_info string) error {
|
|
_, err := s.addressesService.ValidateAddressJson(address_info, country_id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !user.HasPermission(perms.OrdersModifyAll) {
|
|
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)
|
|
}
|
|
|
|
// This is obiously just an initial version of this function
|
|
func (s *OrderService) ChangeOrderStatus(user *model.Customer, order_id uint, status string) error {
|
|
if !user.HasPermission(perms.OrdersModifyAll) {
|
|
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)
|
|
}
|
|
|
|
func (s *OrderService) getOrderTotalPrice(user_id uint, cart_id uint, country_id uint) (float64, float64, float64, error) {
|
|
cart, err := s.cartsRepo.RetrieveCart(user_id, cart_id)
|
|
if err != nil {
|
|
return 0.0, 0.0, 0.0, err
|
|
}
|
|
|
|
base_price := 0.0
|
|
tax_incl := 0.0
|
|
tax_excl := 0.0
|
|
|
|
for _, product := range cart.Products {
|
|
prices, err := s.productsRepo.GetPrice(product.ProductID, product.ProductAttributeID, constdata.SHOP_ID, user_id, country_id, product.Amount)
|
|
if err != nil {
|
|
return 0.0, 0.0, 0.0, err
|
|
}
|
|
|
|
base_price += prices.Base
|
|
tax_incl += prices.FinalTaxIncl
|
|
tax_excl += prices.FinalTaxExcl
|
|
}
|
|
|
|
return base_price, tax_incl, tax_excl, nil
|
|
}
|