Bring calculators from spree_core

This commit is contained in:
Luis Ramos
2020-06-15 20:49:06 +01:00
parent 0f659d0f5e
commit c2898ba389
6 changed files with 198 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
require_dependency 'spree/calculator'
module Spree
class Calculator::DefaultTax < 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
self.calculable
end
def compute_order(order)
matched_line_items = order.line_items.select do |line_item|
line_item.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)
end
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.new(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

View File

@@ -0,0 +1,18 @@
require_dependency 'spree/calculator'
module Spree
class Calculator::FlatPercentItemTotal < Calculator
preference :flat_percent, :decimal, default: 0
def self.description
Spree.t(:flat_percent)
end
def compute(object)
return unless object.present? and object.respond_to?(:item_total)
item_total = object.item_total
value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
(value * 100).round.to_f / 100
end
end
end

View File

@@ -0,0 +1,16 @@
require_dependency 'spree/calculator'
module Spree
class Calculator::FlatRate < Calculator
preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]
def self.description
Spree.t(:flat_rate_per_order)
end
def compute(object=nil)
self.preferred_amount
end
end
end

View File

@@ -0,0 +1,33 @@
require_dependency 'spree/calculator'
module Spree
class Calculator::FlexiRate < Calculator
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]
def self.description
Spree.t(:flexible_rate)
end
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
end
end
sum
end
end
end

View File

@@ -0,0 +1,41 @@
require_dependency 'spree/calculator'
module Spree
class Calculator::PerItem < Calculator
preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]
def self.description
Spree.t(:flat_rate_per_item)
end
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
sum + value_to_add
end
end
# Returns all products that match this calculator, but only if the calculator
# is attached to a promotion. If attached to a ShippingMethod, nil is returned.
def matching_products
# Regression check for #1596
# Calculator::PerItem can be used in two cases.
# The first is in a typical promotion, providing a discount per item of a particular item
# The second is a ShippingMethod, where it applies to an entire order
#
# Shipping methods do not have promotions attached, but promotions do
# Therefore we must check for promotions
if self.calculable.respond_to?(:promotion)
self.calculable.promotion.rules.map do |rule|
rule.respond_to?(:products) ? rule.products : []
end.flatten
end
end
end
end

View File

@@ -0,0 +1,31 @@
require_dependency 'spree/calculator'
# For #to_d method on Ruby 1.8
require 'bigdecimal/util'
module Spree
class Calculator::PriceSack < Calculator
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]
def self.description
Spree.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)
end
if base < self.preferred_minimal_amount
self.preferred_normal_amount
else
self.preferred_discount_amount
end
end
end
end