module Solidus module Returnly class Refunds attr_accessor :calculator, :order, :line_items, :restock, :transactions, :customer_return def initialize(order:, line_items:, restock: true, transactions:) self.order = order self.line_items = line_items self.calculator = Calculator.new order, line_items self.restock = restock self.transactions = transactions self.customer_return = Spree::CustomerReturn.new customer_return_params end def proceed! customer_return.return_items = calculator.line_items_return_items.values.flatten customer_return.return_items.each do |return_item| return_item.amount = refund_amount_per_item - Money.from_amount(return_item.total - return_item.pre_tax_amount) return_item.resellable = restock end if customer_return.save! perform_reimbursement processed_customer_return(customer_return, reimbursement) end end def processed_customer_return(customer_return, reimbursement) { refund_id: customer_return.number, created_at: customer_return.created_at, updated_at: customer_return.updated_at, line_items: customer_return.return_items.group_by{ |ri| ri.inventory_unit.line_item.id }.map {|_, return_items| { refund_line_item_id: return_items.first.id, order_line_item_id: return_items.first.inventory_unit.line_item.id, refunded_amount_per_item: return_items.first.amount.to_f, total_refunded_per_line_item: return_items.sum(&:amount).to_f, quantity: return_items.size } }, transactions: [ id: reimbursement.id, amount: reimbursement.total ], restock: restock } end def perform_reimbursement reimbursement.save! reimbursement.perform! end def reimbursement @_reimbursement ||= Spree::Reimbursement.build_from_customer_return(customer_return) end def customer_return_params { stock_location_id: stock_location_id } end def stock_location_id order.shipments.last.stock_location.id end def refund_available_amount @available_amount ||= transactions.sum { |t| Money.from_amount(t[:amount].to_f) } end def refund_amount_per_item refund_available_amount / line_items.size end end end end