diff options
-rw-r--r-- | app/controllers/api/orders_controller.rb | 14 | ||||
-rw-r--r-- | app/models/order.rb | 8 | ||||
-rw-r--r-- | app/models/payment.rb | 2 | ||||
-rw-r--r-- | app/models/user_account.rb | 1 | ||||
-rw-r--r-- | app/serializers/order_serializer.rb | 2 | ||||
-rw-r--r-- | app/services/payment/cart_to_order_service.rb | 21 | ||||
-rw-r--r-- | app/services/payment/payment_service.rb | 42 | ||||
-rw-r--r-- | app/services/payment_services/cart_to_order_service.rb | 33 | ||||
-rw-r--r-- | app/services/payment_services/payment_service.rb | 48 | ||||
-rw-r--r-- | config/routes.rb | 1 |
10 files changed, 104 insertions, 68 deletions
diff --git a/app/controllers/api/orders_controller.rb b/app/controllers/api/orders_controller.rb index 7a26d11..a57bf68 100644 --- a/app/controllers/api/orders_controller.rb +++ b/app/controllers/api/orders_controller.rb @@ -9,8 +9,16 @@ module Api render json: serialized_collection.serializable_hash, status: :ok end + def show + @order = current_user_account.orders.find_by(id: params[:id]) + + render status: :not_found and return if @order.nil? + + render json: serialized_object.serializable_hash, status: :ok + end + def create - @service = PaymentService.new(@order, permitted_params[:card_id]) + @service = PaymentServices::PaymentService.new(permitted_params[:card_id], current_user_account) @order = @service.call if @order @@ -29,5 +37,9 @@ module Api def serialized_object @serialized_object ||= OrderSerializer.new(@order) end + + def permitted_params + params.permit(:card_id) + end end end diff --git a/app/models/order.rb b/app/models/order.rb index 213bde9..519de09 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -4,8 +4,12 @@ # public_id: string class Order < ApplicationRecord belongs_to :user_account - has_one :payment - has_many :product_orders + has_one :payment, dependent: :destroy + has_many :product_orders, dependent: :destroy has_many :products, through: :product_orders accepts_nested_attributes_for :product_orders + + def to_param + public_id + end end diff --git a/app/models/payment.rb b/app/models/payment.rb index 4839de8..8be9c7f 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -8,7 +8,7 @@ class Payment < ApplicationRecord validate :card_belongs_to_user def card_belongs_to_user - return unless order.user_account.cards.find_by(id: card.id).nil? + return if Order.find_by(id: order_id)&.user_account&.cards&.exists?(card_id) errors.add(:card_id, "doesn't belong to user") end diff --git a/app/models/user_account.rb b/app/models/user_account.rb index 3e05056..6740f32 100644 --- a/app/models/user_account.rb +++ b/app/models/user_account.rb @@ -13,6 +13,7 @@ class UserAccount < ApplicationRecord has_many :addresses, through: :user_account_addresses has_many :cards, dependent: :destroy has_many :product_reviews + has_many :orders validates :email, presence: true validates :email, uniqueness: true diff --git a/app/serializers/order_serializer.rb b/app/serializers/order_serializer.rb index e6883bf..617918e 100644 --- a/app/serializers/order_serializer.rb +++ b/app/serializers/order_serializer.rb @@ -5,7 +5,7 @@ class OrderSerializer < BaseSerializer attributes :public_id, :created_at attribute :products do |object| ProductSerializer.new( - Product.joins(:product_order).select('products.*', 'product_orders.quantity AS quantity') + Product.joins(:product_orders).select('products.*', 'product_orders.quantity AS quantity') .includes(picture_attachment: :blob).where('product_orders.order_id = ?', object.id) ).serializable_hash end diff --git a/app/services/payment/cart_to_order_service.rb b/app/services/payment/cart_to_order_service.rb deleted file mode 100644 index 8dff43e..0000000 --- a/app/services/payment/cart_to_order_service.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Payment - # CartToOrderService - class CartToOrderService - def initialize(user_account) - @user_account = user_account - @cart = @user_account.cart - end - - def call - order = Order.create(user_account_id: @user_account.id) - - @cart.product_carts.pluck(:product_id, :quantity).each do |data| - ProductOrder.create(order_id: order.id, product_id: data[0], quantity: data[1]) - end - - order - end - end -end diff --git a/app/services/payment/payment_service.rb b/app/services/payment/payment_service.rb deleted file mode 100644 index 9f44f87..0000000 --- a/app/services/payment/payment_service.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -module Payment - # PaymentService - class PaymentService - attr_reader :error_messages - - def initialize(params, user_account) - @user_account = user_account - @params = params - @order = Order.new(params.except(:card_id)) - @card_id = params[:card_id] - @order = CartToOrderService.new(@user_account).call - end - - def call - payment = Payment.new(order_id: @order.id, card_id: @card_id, total:) - - @error_messages = { errors: @payment.errors.as_json } and return unless payment.save - - @order.update(payment_id: payment.id) - user_account.cart.product_carts.destroy_all - @order - end - - private - - def total - total = 0 - - @order.product_orders.joins(:product).select( - 'product_orders.*, products.bulk_price AS bulk_price, products.unitary_price AS unitary_price' - ).each do |product_order| - total += if product_order.quantity < 5 - unitary_price * product_order.quantity - else - bulk_price * product_order.quantity - end - end - end - end -end diff --git a/app/services/payment_services/cart_to_order_service.rb b/app/services/payment_services/cart_to_order_service.rb new file mode 100644 index 0000000..3985f90 --- /dev/null +++ b/app/services/payment_services/cart_to_order_service.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module PaymentServices + # CartToOrderService + class CartToOrderService + attr_reader :error_messages + + def initialize(user_account) + @user_account = user_account + @cart = @user_account.cart + end + + def call + @error_messages = { errors: 'Cart is empty' } and return if @cart.product_carts.empty? + + order = Order.create(user_account_id: @user_account.id, public_id: generate_public_id) + + @cart.product_carts.pluck(:product_id, :quantity).each do |data| + ProductOrder.create(order_id: order.id, product_id: data[0], quantity: data[1]) + end + + order + end + + private + + def generate_public_id + public_id = SecureRandom.hex(12) + public_id = SecureRandom.hex(12) while Order.exists?(public_id:) + public_id + end + end +end diff --git a/app/services/payment_services/payment_service.rb b/app/services/payment_services/payment_service.rb new file mode 100644 index 0000000..82267d5 --- /dev/null +++ b/app/services/payment_services/payment_service.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module PaymentServices + # PaymentService + class PaymentService + attr_reader :error_messages + + def initialize(card_id, user_account) + @user_account = user_account + @card_id = card_id + @service = CartToOrderService.new(@user_account) + @order = @service.call + end + + def call + @error_messages = @service.error_messages and return if @order.nil? + + @payment = Payment.new(order_id: @order.id, card_id: @card_id, total:) + + unless @payment.save + @error_messages = @payment.errors.as_json + @order.destroy + return + end + + @order.update(payment_id: @payment.id) + @user_account.cart.product_carts.destroy_all + @order + end + + private + + def total + total = 0 + + @order.product_orders.joins(:product).select( + 'product_orders.*, products.bulk_price AS bulk_price, products.unitary_price AS unitary_price' + ).each do |product_order| + total += if product_order.quantity < 5 + product_order.unitary_price * product_order.quantity + else + product_order.bulk_price * product_order.quantity + end + end + total + end + end +end diff --git a/config/routes.rb b/config/routes.rb index af97ac4..bc38e3f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,6 +21,7 @@ Rails.application.routes.draw do put '/account/cards/:id', to: 'cards#update' delete '/account/cards/:id', to: 'cards#destroy' put '/account', to: 'user_accounts#update' + resources :orders, only: %i[index show create] resources :companies, only: %i[index show create update] resources :products, only: %i[index show create update destroy] resources :products do |