From 142bab8c35771efce02d0e9fcd1f9077d97acb09 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 7 Aug 2020 13:13:43 +0100 Subject: [PATCH] Merge decorators with original spree files --- app/models/spree/credit_card.rb | 37 ++++++++- app/models/spree/credit_card_decorator.rb | 47 ----------- app/models/spree/gateway.rb | 9 ++- app/models/spree/gateway_decorator.rb | 9 --- app/models/spree/payment_method.rb | 84 +++++++++++++++++++- app/models/spree/payment_method_decorator.rb | 84 -------------------- 6 files changed, 126 insertions(+), 144 deletions(-) delete mode 100644 app/models/spree/credit_card_decorator.rb delete mode 100644 app/models/spree/gateway_decorator.rb delete mode 100644 app/models/spree/payment_method_decorator.rb diff --git a/app/models/spree/credit_card.rb b/app/models/spree/credit_card.rb index 21bc709ec1..46718b5ad8 100644 --- a/app/models/spree/credit_card.rb +++ b/app/models/spree/credit_card.rb @@ -1,16 +1,26 @@ module Spree class CreditCard < ActiveRecord::Base + # Should be able to remove once we reach Spree v2.2.0 + # https://github.com/spree/spree/commit/411010f3975c919ab298cb63962ee492455b415c + belongs_to :payment_method + belongs_to :user + has_many :payments, as: :source before_save :set_last_digits attr_accessor :number, :verification_value + # For holding customer preference in memory + attr_writer :save_requested_by_customer validates :month, :year, numericality: { only_integer: true } validates :number, presence: true, unless: :has_payment_profile?, on: :create validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create validate :expiry_not_in_the_past + after_create :ensure_single_default_card + after_save :ensure_single_default_card, if: :default_card_needs_updating? + scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') } # needed for some of the ActiveMerchant gateways (eg. SagePay) @@ -86,8 +96,9 @@ module Spree payment.credit_allowed > 0 end + # Allows us to use a gateway_payment_profile_id to store Stripe Tokens def has_payment_profile? - gateway_customer_profile_id.present? + gateway_customer_profile_id.present? || gateway_payment_profile_id.present? end def to_active_merchant @@ -101,6 +112,10 @@ module Spree ) end + def save_requested_by_customer? + !!@save_requested_by_customer + end + private def expiry_not_in_the_past @@ -111,5 +126,25 @@ module Spree end end end + + def reusable? + gateway_customer_profile_id.present? + end + + def default_missing? + !user.credit_cards.exists?(is_default: true) + end + + def default_card_needs_updating? + is_default_changed? || gateway_customer_profile_id_changed? + end + + def ensure_single_default_card + return unless user + return unless is_default? || (reusable? && default_missing?) + + user.credit_cards.update_all(['is_default=(id=?)', id]) + self.is_default = true + end end end diff --git a/app/models/spree/credit_card_decorator.rb b/app/models/spree/credit_card_decorator.rb deleted file mode 100644 index b8c78f01b7..0000000000 --- a/app/models/spree/credit_card_decorator.rb +++ /dev/null @@ -1,47 +0,0 @@ -Spree::CreditCard.class_eval do - # For holding customer preference in memory - attr_writer :save_requested_by_customer - - # Should be able to remove once we reach Spree v2.2.0 - # https://github.com/spree/spree/commit/411010f3975c919ab298cb63962ee492455b415c - belongs_to :payment_method - - belongs_to :user - - after_create :ensure_single_default_card - after_save :ensure_single_default_card, if: :default_card_needs_updating? - - # Allows us to use a gateway_payment_profile_id to store Stripe Tokens - # Should be able to remove once we reach Spree v2.2.0 - # Commit: https://github.com/spree/spree/commit/5a4d690ebc64b264bf12904a70187e7a8735ef3f - # See also: https://github.com/spree/spree_gateway/issues/111 - def has_payment_profile? # rubocop:disable Naming/PredicateName - gateway_customer_profile_id.present? || gateway_payment_profile_id.present? - end - - def save_requested_by_customer? - !!@save_requested_by_customer - end - - private - - def reusable? - gateway_customer_profile_id.present? - end - - def default_missing? - !user.credit_cards.exists?(is_default: true) - end - - def default_card_needs_updating? - is_default_changed? || gateway_customer_profile_id_changed? - end - - def ensure_single_default_card - return unless user - return unless is_default? || (reusable? && default_missing?) - - user.credit_cards.update_all(['is_default=(id=?)', id]) - self.is_default = true - end -end diff --git a/app/models/spree/gateway.rb b/app/models/spree/gateway.rb index 4e1cbaa368..165fffd91a 100644 --- a/app/models/spree/gateway.rb +++ b/app/models/spree/gateway.rb @@ -1,11 +1,16 @@ +require 'spree/concerns/payment_method_distributors' + module Spree class Gateway < PaymentMethod + include Spree::PaymentMethodDistributors + delegate_belongs_to :provider, :authorize, :purchase, :capture, :void, :credit validates :name, :type, presence: true - preference :server, :string, default: 'test' - preference :test_mode, :boolean, default: true + # Default to live + preference :server, :string, default: 'live' + preference :test_mode, :boolean, default: false def payment_source_class CreditCard diff --git a/app/models/spree/gateway_decorator.rb b/app/models/spree/gateway_decorator.rb deleted file mode 100644 index c62702a321..0000000000 --- a/app/models/spree/gateway_decorator.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spree/concerns/payment_method_distributors' - -Spree::Gateway.class_eval do - include Spree::PaymentMethodDistributors - - # Default to live - preference :server, :string, default: 'live' - preference :test_mode, :boolean, default: false -end diff --git a/app/models/spree/payment_method.rb b/app/models/spree/payment_method.rb index aba5a7ee9c..01a9be0ce5 100644 --- a/app/models/spree/payment_method.rb +++ b/app/models/spree/payment_method.rb @@ -1,12 +1,56 @@ +require 'spree/concerns/payment_method_distributors' + module Spree class PaymentMethod < ActiveRecord::Base + include Spree::Core::CalculatedAdjustments + include Spree::PaymentMethodDistributors + + acts_as_taggable acts_as_paranoid + DISPLAY = [:both, :front_end, :back_end] default_scope -> { where(deleted_at: nil) } - scope :production, -> { where(environment: 'production') } + has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37 validates :name, presence: true + validate :distributor_validation + + after_initialize :init + + scope :production, -> { where(environment: 'production') } + + # -- Scopes + scope :managed_by, lambda { |user| + if user.has_spree_role?('admin') + where(nil) + else + joins(:distributors). + where('distributors_payment_methods.distributor_id IN (?)', user.enterprises.select(&:id)). + select('DISTINCT spree_payment_methods.*') + end + } + + scope :for_distributors, ->(distributors) { + non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors }) + where(id: non_unique_matches.map(&:id)) + } + + scope :for_distributor, lambda { |distributor| + joins(:distributors). + where('enterprises.id = ?', distributor) + } + + scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) } + + scope :by_name, -> { order('spree_payment_methods.name ASC') } + + # Rewrite Spree's ruby-land class method as a scope + scope :available, lambda { |display_on = 'both'| + where(active: true). + where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, ''). + where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '') + } def self.providers Rails.application.config.spree.payment_methods @@ -58,5 +102,43 @@ module Spree def supports?(source) true end + + def init + unless reflections.key?(:calculator) + self.class.include Spree::Core::CalculatedAdjustments + end + + self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0) + end + + def has_distributor?(distributor) + distributors.include?(distributor) + end + + def self.clean_name + case name + when "Spree::PaymentMethod::Check" + "Cash/EFT/etc. (payments for which automatic validation is not required)" + when "Spree::Gateway::Migs" + "MasterCard Internet Gateway Service (MIGS)" + when "Spree::Gateway::Pin" + "Pin Payments" + when "Spree::Gateway::StripeConnect" + "Stripe" + when "Spree::Gateway::StripeSCA" + "Stripe SCA" + when "Spree::Gateway::PayPalExpress" + "PayPal Express" + else + i = name.rindex('::') + 2 + name[i..-1] + end + end + + private + + def distributor_validation + validates_with DistributorsValidator + end end end diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb deleted file mode 100644 index 4c2770daea..0000000000 --- a/app/models/spree/payment_method_decorator.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'spree/concerns/payment_method_distributors' - -Spree::PaymentMethod.class_eval do - include Spree::Core::CalculatedAdjustments - include Spree::PaymentMethodDistributors - - acts_as_taggable - - has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37 - - after_initialize :init - - validate :distributor_validation - - # -- Scopes - scope :managed_by, lambda { |user| - if user.has_spree_role?('admin') - where(nil) - else - joins(:distributors). - where('distributors_payment_methods.distributor_id IN (?)', user.enterprises.select(&:id)). - select('DISTINCT spree_payment_methods.*') - end - } - - scope :for_distributors, ->(distributors) { - non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors }) - where(id: non_unique_matches.map(&:id)) - } - - scope :for_distributor, lambda { |distributor| - joins(:distributors). - where('enterprises.id = ?', distributor) - } - - scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) } - - scope :by_name, -> { order('spree_payment_methods.name ASC') } - - # Rewrite Spree's ruby-land class method as a scope - scope :available, lambda { |display_on = 'both'| - where(active: true). - where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, ''). - where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '') - } - - def init - unless reflections.key?(:calculator) - self.class.include Spree::Core::CalculatedAdjustments - end - - self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0) - end - - def has_distributor?(distributor) - distributors.include?(distributor) - end - - def self.clean_name - case name - when "Spree::PaymentMethod::Check" - "Cash/EFT/etc. (payments for which automatic validation is not required)" - when "Spree::Gateway::Migs" - "MasterCard Internet Gateway Service (MIGS)" - when "Spree::Gateway::Pin" - "Pin Payments" - when "Spree::Gateway::StripeConnect" - "Stripe" - when "Spree::Gateway::StripeSCA" - "Stripe SCA" - when "Spree::Gateway::PayPalExpress" - "PayPal Express" - else - i = name.rindex('::') + 2 - name[i..-1] - end - end - - private - - def distributor_validation - validates_with DistributorsValidator - end -end