/api/app/controllers/spree/api/orders_controller.rb

https://github.com/solidusio/solidus · Ruby · 190 lines · 160 code · 27 blank · 3 comment · 20 complexity · b6f01e5d217169c455338954cc56d210 MD5 · raw file

  1. # frozen_string_literal: true
  2. module Spree
  3. module Api
  4. class OrdersController < Spree::Api::BaseController
  5. class_attribute :admin_shipment_attributes
  6. self.admin_shipment_attributes = [:shipping_method, :stock_location, inventory_units: [:variant_id, :sku]]
  7. class_attribute :admin_order_attributes
  8. self.admin_order_attributes = [:import, :number, :completed_at, :locked_at, :channel, :user_id, :created_at]
  9. class_attribute :admin_payment_attributes
  10. self.admin_payment_attributes = [:payment_method, :amount, :state, source: {}]
  11. skip_before_action :authenticate_user, only: :apply_coupon_code
  12. before_action :find_order, except: [:create, :mine, :current, :index]
  13. around_action :lock_order, except: [:create, :mine, :current, :index, :show]
  14. # Dynamically defines our stores checkout steps to ensure we check authorization on each step.
  15. Spree::Order.checkout_steps.keys.each do |step|
  16. define_method step do
  17. authorize! :update, @order, params[:token]
  18. end
  19. end
  20. def cancel
  21. authorize! :update, @order, params[:token]
  22. @order.canceled_by(current_api_user)
  23. respond_with(@order, default_template: :show)
  24. end
  25. def create
  26. authorize! :create, Order
  27. if can?(:admin, Order)
  28. @order = Spree::Core::Importer::Order.import(determine_order_user, order_params)
  29. respond_with(@order, default_template: :show, status: 201)
  30. else
  31. @order = Spree::Order.create!(user: current_api_user, store: current_store)
  32. if @order.contents.update_cart order_params
  33. respond_with(@order, default_template: :show, status: 201)
  34. else
  35. invalid_resource!(@order)
  36. end
  37. end
  38. end
  39. def empty
  40. authorize! :update, @order, order_token
  41. @order.empty!
  42. render plain: nil, status: 204
  43. end
  44. def index
  45. authorize! :admin, Order
  46. orders_includes = [
  47. { user: :store_credits },
  48. :line_items,
  49. :valid_store_credit_payments
  50. ]
  51. @orders = paginate(
  52. Spree::Order
  53. .ransack(params[:q])
  54. .result
  55. .includes(orders_includes)
  56. )
  57. respond_with(@orders)
  58. end
  59. def show
  60. authorize! :show, @order, order_token
  61. respond_with(@order)
  62. end
  63. def update
  64. authorize! :update, @order, order_token
  65. if @order.contents.update_cart(order_params)
  66. user_id = params[:order][:user_id]
  67. if can?(:admin, @order) && user_id
  68. @order.associate_user!(Spree.user_class.find(user_id))
  69. end
  70. respond_with(@order, default_template: :show)
  71. else
  72. invalid_resource!(@order)
  73. end
  74. end
  75. def current
  76. if current_api_user && @order = current_api_user.last_incomplete_spree_order(store: current_store)
  77. respond_with(@order, default_template: :show, locals: { root_object: @order })
  78. else
  79. head :no_content
  80. end
  81. end
  82. def mine
  83. if current_api_user
  84. @orders = current_api_user.orders.by_store(current_store).reverse_chronological.ransack(params[:q]).result
  85. @orders = paginate(@orders)
  86. else
  87. render "spree/api/errors/unauthorized", status: :unauthorized
  88. end
  89. end
  90. def apply_coupon_code
  91. Spree::Deprecation.warn('This method is deprecated. Please use `Spree::Api::CouponCodesController#create` endpoint instead.')
  92. authorize! :update, @order, order_token
  93. @order.coupon_code = params[:coupon_code]
  94. @handler = PromotionHandler::Coupon.new(@order).apply
  95. if @handler.successful?
  96. render "spree/api/promotions/handler", status: 200
  97. else
  98. logger.error("apply_coupon_code_error=#{@handler.error.inspect}")
  99. render "spree/api/promotions/handler", status: 422
  100. end
  101. end
  102. private
  103. def order_params
  104. if params[:order]
  105. normalize_params
  106. params.require(:order).permit(permitted_order_attributes)
  107. else
  108. {}
  109. end
  110. end
  111. def normalize_params
  112. if params[:order][:payments]
  113. payments_params = params[:order].delete(:payments)
  114. params[:order][:payments_attributes] = payments_params.map do |payment_params|
  115. payment_params[:source_attributes] = payment_params.delete(:source) if payment_params[:source].present?
  116. payment_params
  117. end
  118. end
  119. params[:order][:shipments_attributes] = params[:order].delete(:shipments) if params[:order][:shipments]
  120. params[:order][:line_items_attributes] = params[:order].delete(:line_items) if params[:order][:line_items]
  121. params[:order][:ship_address_attributes] = params[:order].delete(:ship_address) if params[:order][:ship_address].present?
  122. params[:order][:bill_address_attributes] = params[:order].delete(:bill_address) if params[:order][:bill_address].present?
  123. end
  124. # @api public
  125. def determine_order_user
  126. if order_params[:user_id].present?
  127. Spree.user_class.find(order_params[:user_id])
  128. else
  129. current_api_user
  130. end
  131. end
  132. def permitted_order_attributes
  133. can?(:admin, Spree::Order) ? (super + admin_order_attributes) : super
  134. end
  135. def permitted_shipment_attributes
  136. if can?(:admin, Spree::Shipment)
  137. super + admin_shipment_attributes
  138. else
  139. super
  140. end
  141. end
  142. def permitted_payment_attributes
  143. if can?(:admin, Spree::Payment)
  144. super + admin_payment_attributes
  145. else
  146. super
  147. end
  148. end
  149. def find_order(_lock = false)
  150. @order = Spree::Order.
  151. includes(line_items: [:adjustments, { variant: :images }],
  152. payments: :payment_method,
  153. shipments: {
  154. shipping_rates: { shipping_method: :zones, taxes: :tax_rate }
  155. }).
  156. find_by!(number: params[:id])
  157. end
  158. def order_id
  159. super || params[:id]
  160. end
  161. end
  162. end
  163. end