diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index 97f648fa3..a77d06e67 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -40,7 +40,7 @@ class API::ProductsController < API::ApiController def destroy authorize @product - @product.destroy + ProductService.destroy(@product) head :no_content end diff --git a/app/exceptions/cannot_delete_product_error.rb b/app/exceptions/cannot_delete_product_error.rb new file mode 100644 index 000000000..f4e2eec80 --- /dev/null +++ b/app/exceptions/cannot_delete_product_error.rb @@ -0,0 +1,3 @@ +# Raised when delete a product if this product has used in order +class CannotDeleteProductError < StandardError +end diff --git a/app/services/checkout/payment_service.rb b/app/services/checkout/payment_service.rb index 470086f9b..138730b59 100644 --- a/app/services/checkout/payment_service.rb +++ b/app/services/checkout/payment_service.rb @@ -7,10 +7,10 @@ class Checkout::PaymentService include Payments::PaymentConcern def payment(order, operator, coupon_code, payment_id = '') - raise Cart::OutStockError unless Orders::OrderService.new.in_stock?(order, 'external') - raise Cart::InactiveProductError unless Orders::OrderService.new.all_products_is_active?(order) + raise Cart::OutStockError unless Orders::OrderService.new.in_stock?(order, 'external') + CouponService.new.validate(coupon_code, order.statistic_profile.user.id) amount = debit_amount(order) diff --git a/app/services/product_service.rb b/app/services/product_service.rb index 38db4eefb..c0b3c3a04 100644 --- a/app/services/product_service.rb +++ b/app/services/product_service.rb @@ -64,5 +64,20 @@ class ProductService update_stock(product, stock_movement_params) product end + + def destroy(product) + used_in_order = OrderItem.joins(:order).where.not('orders.state' => 'cart') + .exists?(orderable: product) + raise CannotDeleteProductError if used_in_order + + ActiveRecord::Base.transaction do + orders_with_product = Order.joins(:order_items).where(state: 'cart').where('order_items.orderable': product) + orders_with_product.each do |order| + ::Cart::RemoveItemService.new.call(order, product) + end + + product.destroy + end + end end end