From 42a8d40b37f703380fa0f19fc55e2f01baecae42 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 28 Nov 2016 16:34:39 +0100 Subject: [PATCH] fix partial refund of invoices with cash coupons --- app/models/invoice.rb | 11 ++++++++--- app/pdfs/pdf/invoice.rb | 14 +++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/app/models/invoice.rb b/app/models/invoice.rb index bc0e9683f..3facee497 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -138,9 +138,14 @@ class Invoice < ActiveRecord::Base # override created_at to compute CA in stats avoir.created_at = avoir.avoir_date avoir.total = 0 + # refunds of invoices with cash coupons: we need to ventilate coupons on paid items + paid_items = 0 + refund_items = 0 invoice_items.each do |ii| - if attrs[:invoice_items_ids].include? ii.id - raise Exception if ii.invoice_item + paid_items += 1 unless ii.amount == 0 + if attrs[:invoice_items_ids].include? ii.id # list of items to refund (partial refunds) + raise Exception if ii.invoice_item # cannot refund an item that was already refunded + refund_items += 1 unless ii.amount == 0 avoir_ii = avoir.invoice_items.build(ii.dup.attributes) avoir_ii.created_at = avoir.avoir_date avoir_ii.invoice_item_id = ii.id @@ -153,7 +158,7 @@ class Invoice < ActiveRecord::Base if avoir.coupon.type == 'percent_off' discount = avoir.total * avoir.coupon.percent_off / 100.0 elsif avoir.coupon.type == 'amount_off' - discount = avoir.coupon.amount_off + discount = (avoir.coupon.amount_off / paid_items) * refund_items else raise InvalidCouponError end diff --git a/app/pdfs/pdf/invoice.rb b/app/pdfs/pdf/invoice.rb index b7720dcd1..6e02e15d2 100644 --- a/app/pdfs/pdf/invoice.rb +++ b/app/pdfs/pdf/invoice.rb @@ -141,14 +141,22 @@ module PDF total_calc += price end - # subtract the coupon, if any + ## subtract the coupon, if any unless invoice.coupon_id.nil? cp = invoice.coupon discount = 0 if cp.type == 'percent_off' discount = total_calc * cp.percent_off / 100.0 elsif cp.type == 'amount_off' - discount = cp.amount_off / 100.00 + # refunds of invoices with cash coupons: we need to ventilate coupons on paid items + if invoice.is_a?(Avoir) + paid_items = invoice.invoice.invoice_items.select{ |ii| ii.amount > 0 }.length + refund_items = invoice.invoice_items.select{ |ii| ii.amount > 0 }.length + + discount = ((invoice.coupon.amount_off / paid_items) * refund_items) / 100.0 + else + discount = cp.amount_off / 100.00 + end else raise InvalidCouponError end @@ -158,7 +166,7 @@ module PDF # discount textual description literal_discount = cp.percent_off if cp.type == 'amount_off' - literal_discount = number_to_currency(discount) + literal_discount = number_to_currency(cp.amount_off / 100.00) end # add a row for the coupon