module Workarea module Pricing class TaxApplier include TaxApplication def initialize(shipping, adjustments_to_tax) @shipping = shipping @adjustments_to_tax = adjustments_to_tax @adjustments_by_parent = adjustments_to_tax.grouped_by_parent end def shipping_total @shipping_total ||= @shipping.price_adjustments.adjusting('shipping').sum end def apply @adjustments_to_tax.each { |a| assign_item_tax(a) } assign_shipping_tax if @shipping.shipping_service.present? end private def assign_item_tax(adjustment) taxable_amount = taxable_amount_for(adjustment) return if taxable_amount.zero? rate = Tax.find_rate( adjustment.data['tax_code'], taxable_amount, @shipping.address ) tax_amounts = calculate_tax_amounts(taxable_amount, rate) return if tax_amounts.values.sum.zero? @shipping.adjust_pricing( price: 'tax', calculator: self.class.name, description: 'Item Tax', amount: tax_amounts.values.sum, data: tax_amounts.merge( 'adjustment' => adjustment.id, 'order_item_id' => adjustment._parent.id, 'tax_code' => adjustment.data['tax_code'] ) ) end def taxable_amount_for(adjustment) order_item = adjustment._parent partial_shipping_quantity = @shipping.quantities[order_item.id.to_s].to_i return 0 if @shipping.partial? && partial_shipping_quantity.zero? total = @adjustments_by_parent[order_item].taxable_share_for(adjustment) total *= partial_shipping_quantity / order_item.quantity.to_f if @shipping.partial? total end def assign_shipping_tax return unless shipping_total.positive? tax_rate = Tax.find_rate( @shipping.shipping_service.tax_code, shipping_total, @shipping.address ) return unless tax_rate.charge_on_shipping? amounts = calculate_tax_amounts(shipping_total, tax_rate) if amounts.values.sum.positive? @shipping.adjust_pricing( price: 'tax', calculator: self.class.name, description: 'Shipping Tax', amount: amounts.values.sum, data: amounts.merge( 'shipping_service_tax' => true, 'tax_code' => tax_rate.category.code ) ) end end end end end