diff --git a/app/models/spree/calculator/default_tax.rb b/app/models/spree/calculator/default_tax.rb index bfacafddef..87ea942067 100644 --- a/app/models/spree/calculator/default_tax.rb +++ b/app/models/spree/calculator/default_tax.rb @@ -1,4 +1,7 @@ +# frozen_string_literal: false + require_dependency 'spree/calculator' +require 'open_food_network/enterprise_fee_calculator' module Spree module Calculator @@ -19,19 +22,40 @@ module Spree private def rate - self.calculable + calculable end + # Enable calculation of tax for enterprise fees with tax rates where included_in_price = false def compute_order(order) matched_line_items = order.line_items.select do |line_item| - line_item.tax_category == rate.tax_category + line_item.product.tax_category == rate.tax_category end line_items_total = matched_line_items.sum(&:total) - if rate.included_in_price - deduced_total_by_rate(line_items_total, rate) - else - round_to_two_places(line_items_total * rate.amount) + + # Added this line + calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(order.distributor, order.order_cycle) + + # Added this block, finds relevant fees for each line_item, calculates the tax on them, and returns the total tax + per_item_fees_total = order.line_items.sum do |line_item| + calculator.per_item_enterprise_fee_applicators_for(line_item.variant) + .select { |applicator| + (!applicator.enterprise_fee.inherits_tax_category && applicator.enterprise_fee.tax_category == rate.tax_category) || + (applicator.enterprise_fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category) + } + .sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) } + end + + # Added this block, finds relevant fees for whole order, calculates the tax on them, and returns the total tax + per_order_fees_total = 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) } + + # round_to_two_places(line_items_total * rate.amount) # Removed this line + + # Added this block + [line_items_total, per_item_fees_total, per_order_fees_total].sum do |total| + round_to_two_places(total * rate.amount) end end diff --git a/app/models/spree/calculator/default_tax_decorator.rb b/app/models/spree/calculator/default_tax_decorator.rb deleted file mode 100644 index ccc73abb9f..0000000000 --- a/app/models/spree/calculator/default_tax_decorator.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'open_food_network/enterprise_fee_calculator' - -Spree::Calculator::DefaultTax.class_eval do - private - - # Override this method to enable calculation of tax for - # enterprise fees with tax rates where included_in_price = false - def compute_order(order) - matched_line_items = order.line_items.select do |line_item| - line_item.product.tax_category == rate.tax_category - end - - line_items_total = matched_line_items.sum(&:total) - - # Added this line - calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(order.distributor, order.order_cycle) - - # Added this block, finds relevant fees for each line_item, calculates the tax on them, and returns the total tax - per_item_fees_total = order.line_items.sum do |line_item| - calculator.per_item_enterprise_fee_applicators_for(line_item.variant) - .select { |applicator| - (!applicator.enterprise_fee.inherits_tax_category && applicator.enterprise_fee.tax_category == rate.tax_category) || - (applicator.enterprise_fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category) - } - .sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) } - end - - # Added this block, finds relevant fees for whole order, calculates the tax on them, and returns the total tax - per_order_fees_total = 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) } - - # round_to_two_places(line_items_total * rate.amount) # Removed this line - - # Added this block - [line_items_total, per_item_fees_total, per_order_fees_total].sum do |total| - round_to_two_places(total * rate.amount) - end - end -end diff --git a/app/models/spree/calculator/flat_percent_item_total.rb b/app/models/spree/calculator/flat_percent_item_total.rb index 8b897397e4..0d2dc7e0db 100644 --- a/app/models/spree/calculator/flat_percent_item_total.rb +++ b/app/models/spree/calculator/flat_percent_item_total.rb @@ -1,19 +1,24 @@ +# frozen_string_literal: false + require_dependency 'spree/calculator' +require 'spree/localized_number' module Spree module Calculator class FlatPercentItemTotal < 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) - return unless object.present? && object.respond_to?(:item_total) - - item_total = object.item_total - value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0 + item_total = line_items_for(object).map(&:amount).sum + value = item_total * BigDecimal(preferred_flat_percent.to_s) / 100.0 (value * 100).round.to_f / 100 end end diff --git a/app/models/spree/calculator/flat_percent_item_total_decorator.rb b/app/models/spree/calculator/flat_percent_item_total_decorator.rb deleted file mode 100644 index ae95f59ca2..0000000000 --- a/app/models/spree/calculator/flat_percent_item_total_decorator.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spree/localized_number' - -module Spree - Calculator::FlatPercentItemTotal.class_eval do - extend Spree::LocalizedNumber - - localize_number :preferred_flat_percent - - def compute(object) - item_total = line_items_for(object).map(&:amount).sum - value = item_total * BigDecimal(preferred_flat_percent.to_s) / 100.0 - (value * 100).round.to_f / 100 - end - end -end diff --git a/app/models/spree/calculator/flat_rate.rb b/app/models/spree/calculator/flat_rate.rb index 3cfb94dd4c..a2d6d9c55b 100644 --- a/app/models/spree/calculator/flat_rate.rb +++ b/app/models/spree/calculator/flat_rate.rb @@ -1,17 +1,24 @@ +# frozen_string_literal: false + require_dependency 'spree/calculator' +require 'spree/localized_number' module Spree module Calculator class FlatRate < Calculator + extend Spree::LocalizedNumber + preference :amount, :decimal, default: 0 preference :currency, :string, default: Spree::Config[:currency] + localize_number :preferred_amount + def self.description - Spree.t(:flat_rate_per_order) + I18n.t(:flat_rate_per_order) end - def compute(object=nil) - self.preferred_amount + def compute(_object = nil) + preferred_amount end end end diff --git a/app/models/spree/calculator/flat_rate_decorator.rb b/app/models/spree/calculator/flat_rate_decorator.rb deleted file mode 100644 index d7abe3cf1b..0000000000 --- a/app/models/spree/calculator/flat_rate_decorator.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'spree/localized_number' - -module Spree - Calculator::FlatRate.class_eval do - extend Spree::LocalizedNumber - - localize_number :preferred_amount - - def self.description - I18n.t(:flat_rate_per_order) - end - end -end diff --git a/app/models/spree/calculator/flexi_rate.rb b/app/models/spree/calculator/flexi_rate.rb index 9e8f16cc00..fe80c45883 100644 --- a/app/models/spree/calculator/flexi_rate.rb +++ b/app/models/spree/calculator/flexi_rate.rb @@ -1,30 +1,39 @@ +# frozen_string_literal: false + require_dependency 'spree/calculator' +require 'spree/localized_number' module Spree module Calculator class FlexiRate < 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 - Spree.t(:flexible_rate) + I18n.t(:flexible_rate) end - def self.available?(object) + def self.available?(_object) true end def compute(object) sum = 0 - max = self.preferred_max_items.to_i - items_count = object.line_items.map(&:quantity).sum - items_count.times do |i| - if i == 0 - sum += self.preferred_first_item.to_f - elsif ((max > 0) && (i <= (max - 1))) || (max == 0) - sum += self.preferred_additional_item.to_f + max = preferred_max_items.to_i + items_count = line_items_for(object).map(&:quantity).sum + # check max value to avoid divide by 0 errors + unless max == 0 + if items_count > max + sum += (max - 1) * preferred_additional_item.to_f + preferred_first_item.to_f + elsif items_count <= max + sum += (items_count - 1) * preferred_additional_item.to_f + preferred_first_item.to_f end end diff --git a/app/models/spree/calculator/flexi_rate_decorator.rb b/app/models/spree/calculator/flexi_rate_decorator.rb deleted file mode 100644 index de112f4f0b..0000000000 --- a/app/models/spree/calculator/flexi_rate_decorator.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'spree/localized_number' - -module Spree - Calculator::FlexiRate.class_eval do - extend Spree::LocalizedNumber - - localize_number :preferred_first_item, - :preferred_additional_item - - def self.description - I18n.t(:flexible_rate) - end - - def compute(object) - sum = 0 - max = preferred_max_items.to_i - items_count = line_items_for(object).map(&:quantity).sum - # check max value to avoid divide by 0 errors - unless max == 0 - if items_count > max - sum += (max - 1) * preferred_additional_item.to_f + preferred_first_item.to_f - elsif items_count <= max - sum += (items_count - 1) * preferred_additional_item.to_f + preferred_first_item.to_f - end - end - - sum - end - end -end diff --git a/app/models/spree/calculator/per_item.rb b/app/models/spree/calculator/per_item.rb index a2ce2f4348..10c7965c0d 100644 --- a/app/models/spree/calculator/per_item.rb +++ b/app/models/spree/calculator/per_item.rb @@ -1,25 +1,34 @@ +# frozen_string_literal: false + require_dependency 'spree/calculator' +require 'spree/localized_number' module Spree module Calculator class PerItem < Calculator + extend Spree::LocalizedNumber + preference :amount, :decimal, default: 0 preference :currency, :string, default: Spree::Config[:currency] + localize_number :preferred_amount + def self.description - Spree.t(:flat_rate_per_item) + I18n.t(:flat_rate_per_item) end - def compute(object=nil) + def compute(object = nil) return 0 if object.nil? - self.preferred_amount * object.line_items.reduce(0) do |sum, value| - if matching_products.blank? || matching_products.include?(value.product) - value_to_add = value.quantity - else - value_to_add = 0 - end + + 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 sum + value_to_add end + preferred_amount * number_of_line_items end # Returns all products that match this calculator, but only if the calculator diff --git a/app/models/spree/calculator/per_item_decorator.rb b/app/models/spree/calculator/per_item_decorator.rb deleted file mode 100644 index e385ad8bf8..0000000000 --- a/app/models/spree/calculator/per_item_decorator.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spree/localized_number' - -module Spree - Calculator::PerItem.class_eval do - extend Spree::LocalizedNumber - - localize_number :preferred_amount - - def self.description - I18n.t(:flat_rate_per_item) - end - - 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 - sum + value_to_add - end - preferred_amount * number_of_line_items - end - end -end diff --git a/app/models/spree/calculator/price_sack.rb b/app/models/spree/calculator/price_sack.rb index d3a05e0229..ac6bf0b653 100644 --- a/app/models/spree/calculator/price_sack.rb +++ b/app/models/spree/calculator/price_sack.rb @@ -1,32 +1,39 @@ +# 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 module Calculator class PriceSack < 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 + def self.description - Spree.t(:price_sack) + I18n.t(:price_sack) end - # as object we always get line items, as calculable we have Coupon, ShippingMethod def compute(object) - if object.is_a?(Array) - base = object.map { |o| o.respond_to?(:amount) ? o.amount : BigDecimal(o.to_s) }.sum - else - base = object.respond_to?(:amount) ? object.amount : BigDecimal(object.to_s) + min = preferred_minimal_amount.to_f + order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum + + if order_amount < min + cost = preferred_normal_amount.to_f + elsif order_amount >= min + cost = preferred_discount_amount.to_f end - if base < self.preferred_minimal_amount - self.preferred_normal_amount - else - self.preferred_discount_amount - end + cost end end end diff --git a/app/models/spree/calculator/price_sack_decorator.rb b/app/models/spree/calculator/price_sack_decorator.rb deleted file mode 100644 index 389649f916..0000000000 --- a/app/models/spree/calculator/price_sack_decorator.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spree/localized_number' - -module Spree - Calculator::PriceSack.class_eval do - extend Spree::LocalizedNumber - - localize_number :preferred_minimal_amount, - :preferred_normal_amount, - :preferred_discount_amount - - def self.description - I18n.t(:price_sack) - end - - def compute(object) - min = preferred_minimal_amount.to_f - order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum - - if order_amount < min - cost = preferred_normal_amount.to_f - elsif order_amount >= min - cost = preferred_discount_amount.to_f - end - - cost - end - end -end