mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-28 01:53:25 +00:00
Convert CalculatedAdjustments into a proper Concern and remove class_eval
This commit is contained in:
80
app/models/concerns/calculated_adjustments.rb
Normal file
80
app/models/concerns/calculated_adjustments.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "active_support/concern"
|
||||
|
||||
module CalculatedAdjustments
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_one :calculator, as: :calculable, class_name: "Spree::Calculator", dependent: :destroy
|
||||
accepts_nested_attributes_for :calculator
|
||||
validates :calculator, presence: true
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def calculators
|
||||
spree_calculators.__send__(model_name_without_spree_namespace)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_name_without_spree_namespace
|
||||
to_s.tableize.gsub('/', '_').sub('spree_', '')
|
||||
end
|
||||
|
||||
def spree_calculators
|
||||
Rails.application.config.spree.calculators
|
||||
end
|
||||
end
|
||||
|
||||
def calculator_type
|
||||
calculator.class.to_s if calculator
|
||||
end
|
||||
|
||||
def calculator_type=(calculator_type)
|
||||
klass = calculator_type.constantize if calculator_type
|
||||
self.calculator = klass.new if klass && !calculator.is_a?(klass)
|
||||
end
|
||||
|
||||
# Creates a new adjustment for the target object
|
||||
# (which is any class that has_many :adjustments) and sets amount based on the
|
||||
# calculator as applied to the given calculable (Order, LineItems[], Shipment, etc.)
|
||||
# By default the adjustment will not be considered mandatory
|
||||
def create_adjustment(label, adjustable, mandatory = false, state = "closed", tax_category = nil)
|
||||
amount = compute_amount(adjustable)
|
||||
return if amount.zero? && !mandatory
|
||||
|
||||
adjustment_attributes = {
|
||||
amount: amount,
|
||||
originator: self,
|
||||
order: order_object_for(adjustable),
|
||||
label: label,
|
||||
mandatory: mandatory,
|
||||
state: state,
|
||||
tax_category: tax_category
|
||||
}
|
||||
|
||||
if adjustable.respond_to?(:adjustments)
|
||||
adjustable.adjustments.create(adjustment_attributes)
|
||||
else
|
||||
adjustable.create_adjustment(adjustment_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
# Calculate the amount to be used when creating an adjustment
|
||||
# NOTE: May be overriden by classes where this module is included into.
|
||||
def compute_amount(calculable)
|
||||
calculator.compute(calculable)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_object_for(target)
|
||||
# Temporary method for adjustments transition.
|
||||
if target.is_a? Spree::Order
|
||||
target
|
||||
elsif target.respond_to?(:order)
|
||||
target.order
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class EnterpriseFee < ApplicationRecord
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include CalculatedAdjustments
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'concerns/payment_method_distributors'
|
||||
require 'spree/core/calculated_adjustments'
|
||||
|
||||
module Spree
|
||||
class PaymentMethod < ApplicationRecord
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include CalculatedAdjustments
|
||||
include PaymentMethodDistributors
|
||||
|
||||
acts_as_taggable
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
module Spree
|
||||
class ShippingMethod < ApplicationRecord
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include CalculatedAdjustments
|
||||
DISPLAY = [:both, :front_end, :back_end].freeze
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
@@ -15,7 +15,7 @@ end
|
||||
module Spree
|
||||
class TaxRate < ApplicationRecord
|
||||
acts_as_paranoid
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
include CalculatedAdjustments
|
||||
|
||||
belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates
|
||||
belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates
|
||||
|
||||
@@ -47,7 +47,6 @@ require 'spree/money'
|
||||
require 'spree/core/delegate_belongs_to'
|
||||
require 'spree/core/permalinks'
|
||||
require 'spree/core/token_resource'
|
||||
require 'spree/core/calculated_adjustments'
|
||||
require 'spree/core/product_duplicator'
|
||||
require 'spree/core/gateway_error'
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
module Core
|
||||
module CalculatedAdjustments
|
||||
def self.included(klass)
|
||||
klass.class_eval do
|
||||
has_one :calculator, class_name: "Spree::Calculator", as: :calculable, dependent: :destroy
|
||||
accepts_nested_attributes_for :calculator
|
||||
validates :calculator, presence: true
|
||||
|
||||
def self.calculators
|
||||
spree_calculators.__send__(model_name_without_spree_namespace)
|
||||
end
|
||||
|
||||
def calculator_type
|
||||
calculator.class.to_s if calculator
|
||||
end
|
||||
|
||||
def calculator_type=(calculator_type)
|
||||
klass = calculator_type.constantize if calculator_type
|
||||
self.calculator = klass.new if klass && !calculator.is_a?(klass)
|
||||
end
|
||||
|
||||
# Creates a new adjustment for the target object
|
||||
# (which is any class that has_many :adjustments) and sets amount based on the
|
||||
# calculator as applied to the given calculable (Order, LineItems[], Shipment, etc.)
|
||||
# By default the adjustment will not be considered mandatory
|
||||
def create_adjustment(label, adjustable, mandatory = false, state = "closed", tax_category = nil)
|
||||
amount = compute_amount(adjustable)
|
||||
return if amount.zero? && !mandatory
|
||||
|
||||
adjustment_attributes = {
|
||||
amount: amount,
|
||||
originator: self,
|
||||
order: order_object_for(adjustable),
|
||||
label: label,
|
||||
mandatory: mandatory,
|
||||
state: state,
|
||||
tax_category: tax_category
|
||||
}
|
||||
|
||||
if adjustable.respond_to?(:adjustments)
|
||||
adjustable.adjustments.create(adjustment_attributes)
|
||||
else
|
||||
adjustable.create_adjustment(adjustment_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
# Calculate the amount to be used when creating an adjustment
|
||||
# NOTE: May be overriden by classes where this module is included into.
|
||||
def compute_amount(calculable)
|
||||
calculator.compute(calculable)
|
||||
end
|
||||
|
||||
def self.model_name_without_spree_namespace
|
||||
to_s.tableize.gsub('/', '_').sub('spree_', '')
|
||||
end
|
||||
private_class_method :model_name_without_spree_namespace
|
||||
|
||||
def self.spree_calculators
|
||||
Rails.application.config.spree.calculators
|
||||
end
|
||||
private_class_method :spree_calculators
|
||||
|
||||
private
|
||||
|
||||
def order_object_for(target)
|
||||
# Temporary method for adjustments transition.
|
||||
if target.is_a? Spree::Order
|
||||
target
|
||||
elsif target.respond_to?(:order)
|
||||
target.order
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,7 @@ require 'spec_helper'
|
||||
# Its pretty difficult to test this module in isolation b/c it needs to work in conjunction
|
||||
# with an actual class that extends ActiveRecord::Base and has a corresponding table in the DB.
|
||||
# So we'll just test it using Order and ShippingMethod. These classes are including the module.
|
||||
describe Spree::Core::CalculatedAdjustments do
|
||||
describe CalculatedAdjustments do
|
||||
let(:calculator) { build(:calculator) }
|
||||
let(:tax_rate) { Spree::TaxRate.new(calculator: calculator) }
|
||||
|
||||
Reference in New Issue
Block a user