module Returnly class RefundPresenter class << self def present_refund(refunder) customer_return = refunder.customer_return refund = refunder.order.reload.refunds.last { refund_id: refund.try(:id).try(:to_s), user_id: refunder.order.user_id, line_items: customer_return.return_items.group_by { |ri| ri.inventory_unit.line_item.id }.map do |_, return_items| first_return_item = return_items.first { refund_line_item_id: first_return_item.id.to_s, order_line_item_id: first_return_item.inventory_unit.line_item.id.to_s, units: return_items.size, restock: first_return_item.resellable } end, transactions: refunder.reimbursement.refunds.map do |refund| { id: refund.transaction_id, amount: refund.amount.to_s, status: transaction_status(refund.payment), type: 'REFUND', gateway: refund.payment.payment_method.type.demodulize, is_online: true, is_test: !Rails.env.match?(/production/), payment_details: transaction_payment_details(refund.payment, refunder.gift_card_class.new(refund)), created_at: refund.created_at.iso8601(3), updated_at: refund.updated_at.iso8601(3) } end, created_at: refund.try(:created_at).try(:iso8601, 3), updated_at: refund.try(:updated_at).try(:iso8601, 3) } end def present_estimate(calculator) sub_total = Money.new 0 tax = Money.new 0 calculator.line_items_return_items.values.flatten.each do |return_item| sub_total += Money.from_amount return_item.inventory_unit.line_item.price tax += Money.from_amount calculator.line_item_tax(return_item.inventory_unit.line_item) end discount = Money.from_amount(calculator.discount) total_refund_amount = sub_total + tax - (discount * -1) # discount is negative, so we multiply it by -1 to make it positive for subtraction shipping_tax = calculator.shipping_tax { product_amount: sub_total.to_s, tax_amount: tax.to_s, discount_amount: (discount * -1).to_s, total_refund_amount: total_refund_amount.to_s, refundable_shipping_amount: Money.from_amount(calculator.order.shipment_total).to_s, refundable_shipping_tax_amount: Money.from_amount(shipping_tax).to_s, max_refundable_amount: Money.from_amount(calculator.order.total - calculator.order.refunds.reload.sum(&:amount)).to_s, transactions: transactions_for_estimate( calculator.order, calculator.gift_card, total_refund_amount.to_d + calculator.order.shipment_total + shipping_tax ) } end def present_refund_with_zero_amount(refunder) { refund_id: '1', line_items: refunder.line_items.map do |line_item| { refund_line_item_id: '1', order_line_item_id: line_item[:order_line_item_id].to_s, units: line_item[:units].to_i, restock: line_item[:restock].match?(/true/) } end, transactions: [], created_at: Time.zone.now.iso8601(3) } end private def transaction_status(payment) return 'SUCCESS' if payment.completed? return 'FAILURE' if payment.failed? || payment.invalid? 'PENDING' end def transaction_payment_details(payment, gift_card) details = {} details[:avs_result_code] = payment.avs_response if payment.avs_response.present? details[:cvv_result_code] = payment.cvv_response_code if payment.cvv_response_code.present? source = payment.source if source.respond_to?(:number) || source.respond_to?(:last_digits) details[:credit_card_number] = source.number || source.last_digits if source.number.present? || source.last_digits.present? details[:credit_card_company] = source.brand if source.brand.present? end details[:gift_card_id] = gift_card.id if gift_card.id.present? details[:gift_card_code] = gift_card.code if gift_card.code.present? details end def transactions_for_estimate(order, gift_card, payment_amount) ::RefundPayments.new(order, gift_card).perform!(payment_amount) end end end end