module Returnly class RefundCalculator attr_accessor :line_items, :order extend ::Returnly::RefundsConfiguration def self.process(order, line_items) refund_presenter_class.present_estimate new(order, line_items) end def initialize(order, line_items) self.line_items = line_items self.order = order end def discount Returnly::DiscountCalculator.new(order).calculate(line_items) end def line_item_tax(line_item) (line_item.adjustments.tax.sum(&:amount).to_d / line_item.quantity).round(2, :down) end def line_items_return_items(is_estimate) available_return_items(is_estimate).each_with_object({}) do |return_item, return_items| line_item_id = return_item.inventory_unit.line_item_id return_items[line_item_id] ||= [] return_items[line_item_id] << set_tax(return_item) return_items end end def shipping_tax order.all_adjustments.where(source_type: 'Spree::TaxRate', adjustable_type: 'Spree::Shipment').sum(&:amount).to_d.round(2, :down) end protected def available_return_items(is_estimate) return self.class.return_item_builder_class.new(order).build_for_estimate(line_items) if is_estimate self.class.return_item_builder_class.new(order).build_by_requested_line_items(line_items) end def set_tax(return_item) percent_of_tax = if return_item.amount <= 0 0 else return_item.amount / Spree::ReturnItem.refund_amount_calculator.new.compute(return_item) end additional_tax_total = percent_of_tax * return_item.inventory_unit.additional_tax_total included_tax_total = percent_of_tax * return_item.inventory_unit.included_tax_total return_item.additional_tax_total = additional_tax_total return_item.included_tax_total = included_tax_total return_item end end end