Skip to content

Commit

Permalink
Merge pull request #5613 from luisramos0/calculators
Browse files Browse the repository at this point in the history
Move all Calculators from spree to OFN and out of the Spree namespace
  • Loading branch information
luisramos0 authored Jul 13, 2020
2 parents d536cc8 + 5e6739c commit 9c8318d
Show file tree
Hide file tree
Showing 49 changed files with 387 additions and 205 deletions.
1 change: 0 additions & 1 deletion .rubocop_manual_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ Layout/LineLength:
- app/models/concerns/variant_stock.rb
- app/models/content_configuration.rb
- app/models/customer.rb
- app/models/enterprise_fee.rb
- app/models/enterprise_group.rb
- app/models/enterprise_role.rb
- app/models/inventory_item.rb
Expand Down
93 changes: 93 additions & 0 deletions app/models/calculator/default_tax.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
require 'open_food_network/enterprise_fee_calculator'

module Calculator
class DefaultTax < Spree::Calculator
def self.description
Spree.t(:default_tax)
end

def compute(computable)
case computable
when Spree::Order
compute_order(computable)
when Spree::LineItem
compute_line_item(computable)
end
end

private

def rate
calculable
end

# Enable calculation of tax for enterprise fees with tax rates where included_in_price = false
def compute_order(order)
calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(order.distributor,
order.order_cycle)

[
line_items_total(order),
per_item_fees_total(order, calculator),
per_order_fees_total(order, calculator)
].sum do |total|
round_to_two_places(total * rate.amount)
end
end

def line_items_total(order)
matched_line_items = order.line_items.select do |line_item|
line_item.product.tax_category == rate.tax_category
end

matched_line_items.sum(&:total)
end

# Finds relevant fees for each line_item,
# calculates the tax on them, and returns the total tax
def per_item_fees_total(order, calculator)
order.line_items.sum do |line_item|
calculator.per_item_enterprise_fee_applicators_for(line_item.variant)
.select { |applicator| applicable_rate?(applicator, line_item) }
.sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) }
end
end

def applicable_rate?(applicator, line_item)
fee = applicator.enterprise_fee
(!fee.inherits_tax_category && fee.tax_category == rate.tax_category) ||
(fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category)
end

# Finds relevant fees for whole order,
# calculates the tax on them, and returns the total tax
def per_order_fees_total(order, calculator)
calculator.per_order_enterprise_fee_applicators_for(order)
.select { |applicator| applicator.enterprise_fee.tax_category == rate.tax_category }
.sum { |applicator| applicator.enterprise_fee.compute_amount(order) }
end

def compute_line_item(line_item)
if line_item.tax_category == rate.tax_category
if rate.included_in_price
deduced_total_by_rate(line_item.total, rate)
else
round_to_two_places(line_item.total * rate.amount)
end
else
0
end
end

def round_to_two_places(amount)
BigDecimal(amount.to_s).round(2, BigDecimal::ROUND_HALF_UP)
end

def deduced_total_by_rate(total, rate)
round_to_two_places(total - ( total / (1 + rate.amount) ) )
end
end
end
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
require 'spree/localized_number'

module Spree
Calculator::FlatPercentItemTotal.class_eval do
module Calculator
class FlatPercentItemTotal < Spree::Calculator
extend Spree::LocalizedNumber

preference :flat_percent, :decimal, default: 0

localize_number :preferred_flat_percent

def self.description
Spree.t(:flat_percent)
end

def compute(object)
item_total = line_items_for(object).map(&:amount).sum
value = item_total * BigDecimal(preferred_flat_percent.to_s) / 100.0
Expand Down
23 changes: 23 additions & 0 deletions app/models/calculator/flat_rate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
require 'spree/localized_number'

module Calculator
class FlatRate < Spree::Calculator
extend Spree::LocalizedNumber

preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]

localize_number :preferred_amount

def self.description
I18n.t(:flat_rate_per_order)
end

def compute(_object = nil)
preferred_amount
end
end
end
46 changes: 46 additions & 0 deletions app/models/calculator/flexi_rate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
require 'spree/localized_number'

module Calculator
class FlexiRate < Spree::Calculator
extend Spree::LocalizedNumber

preference :first_item, :decimal, default: 0.0
preference :additional_item, :decimal, default: 0.0
preference :max_items, :integer, default: 0
preference :currency, :string, default: Spree::Config[:currency]

localize_number :preferred_first_item,
:preferred_additional_item

def self.description
I18n.t(:flexible_rate)
end

def self.available?(_object)
true
end

def compute(object)
max = preferred_max_items.to_i
items_count = line_items_for(object).map(&:quantity).sum

# check max value to avoid divide by 0 errors
return 0 if max.zero?

if items_count > max
compute_for(max - 1)
elsif items_count <= max
compute_for(items_count - 1)
end
end

private

def compute_for(count)
count * preferred_additional_item.to_f + preferred_first_item.to_f
end
end
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
require 'spree/localized_number'

module Spree
Calculator::PerItem.class_eval do
module Calculator
class PerItem < Spree::Calculator
extend Spree::LocalizedNumber

preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]

localize_number :preferred_amount

def self.description
Expand All @@ -14,11 +20,7 @@ def compute(object = nil)
return 0 if object.nil?

number_of_line_items = line_items_for(object).reduce(0) do |sum, line_item|
value_to_add = if matching_products.blank? || matching_products.include?(line_item.product)
line_item.quantity
else
0
end
value_to_add = line_item.quantity
sum + value_to_add
end
preferred_amount * number_of_line_items
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
# frozen_string_literal: false

require_dependency 'spree/calculator'
# For #to_d method on Ruby 1.8
require 'bigdecimal/util'
require 'spree/localized_number'

module Spree
Calculator::PriceSack.class_eval do
module Calculator
class PriceSack < Spree::Calculator
extend Spree::LocalizedNumber

preference :minimal_amount, :decimal, default: 0
preference :normal_amount, :decimal, default: 0
preference :discount_amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]

localize_number :preferred_minimal_amount,
:preferred_normal_amount,
:preferred_discount_amount
Expand Down
4 changes: 3 additions & 1 deletion app/models/enterprise_fee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class EnterpriseFee < ActiveRecord::Base
has_many :exchanges, through: :exchange_fees

FEE_TYPES = %w(packing transport admin sales fundraising).freeze
PER_ORDER_CALCULATORS = ['Spree::Calculator::FlatRate', 'Spree::Calculator::FlexiRate', 'Spree::Calculator::PriceSack'].freeze
PER_ORDER_CALCULATORS = ['Calculator::FlatRate',
'Calculator::FlexiRate',
'Calculator::PriceSack'].freeze

validates :fee_type, inclusion: { in: FEE_TYPES }
validates :name, presence: true
Expand Down
40 changes: 0 additions & 40 deletions app/models/spree/calculator/default_tax_decorator.rb

This file was deleted.

13 changes: 0 additions & 13 deletions app/models/spree/calculator/flat_rate_decorator.rb

This file was deleted.

30 changes: 0 additions & 30 deletions app/models/spree/calculator/flexi_rate_decorator.rb

This file was deleted.

2 changes: 1 addition & 1 deletion app/models/spree/payment_method_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def init
self.class.include Spree::Core::CalculatedAdjustments
end

self.calculator ||= Spree::Calculator::FlatRate.new(preferred_amount: 0)
self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0)
end

def has_distributor?(distributor)
Expand Down
Loading

0 comments on commit 9c8318d

Please sign in to comment.