mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
89 lines
2.9 KiB
Ruby
89 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Adapts checkout form data (params) so that the order can be directly saved to the database
|
|
module Checkout
|
|
class FormDataAdapter
|
|
attr_reader :params, :shipping_method_id
|
|
|
|
def initialize(params, order, current_user)
|
|
@params = params.dup
|
|
@order = order
|
|
@current_user = current_user
|
|
|
|
move_payment_source_to_payment_attributes!
|
|
|
|
fill_in_card_type
|
|
|
|
set_amount_in_payments_attributes
|
|
|
|
construct_saved_card_attributes if @params[:order][:existing_card_id]
|
|
|
|
@shipping_method_id = @params[:order].delete(:shipping_method_id)
|
|
end
|
|
|
|
private
|
|
|
|
# For payment step, filter order parameters to produce the expected
|
|
# nested attributes for a single payment and its source,
|
|
# discarding attributes for payment methods other than the one selected
|
|
def move_payment_source_to_payment_attributes!
|
|
return unless @params[:payment_source].present? &&
|
|
payment_source_params = delete_payment_source_params!
|
|
|
|
@params[:order][:payments_attributes].first[:source_attributes] = payment_source_params
|
|
end
|
|
|
|
# Ensures cc_type is always passed to the model by inferring the type when
|
|
# the frontend didn't provide it. This fixes Pin Payments specifically
|
|
# although it might be useful for future payment gateways.
|
|
#
|
|
# More details: app/assets/javascripts/darkswarm/services/checkout.js.coffee#L70-L98
|
|
def fill_in_card_type
|
|
return unless payment_source_attributes
|
|
|
|
return if payment_source_attributes.dig(:number).blank?
|
|
|
|
payment_source_attributes[:cc_type] ||= card_brand(payment_source_attributes[:number])
|
|
end
|
|
|
|
def payment_source_attributes
|
|
@payment_source_attributes ||=
|
|
params[:order][:payments_attributes]&.first&.dig(:source_attributes)
|
|
end
|
|
|
|
def card_brand(number)
|
|
ActiveMerchant::Billing::CreditCard.brand?(number)
|
|
end
|
|
|
|
def delete_payment_source_params!
|
|
@params.delete(:payment_source)[
|
|
@params[:order][:payments_attributes].first[:payment_method_id].underscore
|
|
]
|
|
end
|
|
|
|
def set_amount_in_payments_attributes
|
|
return unless @params[:order][:payments_attributes]
|
|
|
|
@params[:order][:payments_attributes].first[:amount] = @order.total
|
|
end
|
|
|
|
def construct_saved_card_attributes
|
|
existing_card_id = @params[:order].delete(:existing_card_id)
|
|
return if existing_card_id.blank?
|
|
|
|
add_to_payment_attributes(existing_card_id)
|
|
|
|
@params[:order][:payments_attributes].first.delete :source_attributes
|
|
end
|
|
|
|
def add_to_payment_attributes(existing_card_id)
|
|
credit_card = Spree::CreditCard.find(existing_card_id)
|
|
if credit_card.try(:user_id).blank? || credit_card.user_id != @current_user.try(:id)
|
|
raise Spree::Core::GatewayError, I18n.t(:invalid_credit_card)
|
|
end
|
|
|
|
@params[:order][:payments_attributes].first[:source] = credit_card
|
|
end
|
|
end
|
|
end
|