mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
(bug) test on invoice items was not idempotent
This commit is contained in:
parent
d9eee1aa3f
commit
46e042fd38
@ -13,15 +13,17 @@ class Invoice < PaymentDocument
|
||||
belongs_to :wallet_transaction
|
||||
belongs_to :coupon
|
||||
|
||||
has_one :avoir, class_name: 'Invoice', foreign_key: :invoice_id, dependent: :destroy
|
||||
has_one :payment_schedule_item
|
||||
has_one :payment_gateway_object, as: :item
|
||||
belongs_to :operator_profile, foreign_key: :operator_profile_id, class_name: 'InvoicingProfile'
|
||||
has_one :avoir, class_name: 'Invoice', dependent: :destroy, inverse_of: :avoir
|
||||
has_one :payment_schedule_item, dependent: :nullify
|
||||
has_one :payment_gateway_object, as: :item, dependent: :destroy
|
||||
belongs_to :operator_profile, class_name: 'InvoicingProfile'
|
||||
|
||||
delegate :user, to: :invoicing_profile
|
||||
|
||||
before_create :add_environment
|
||||
after_create :update_reference, :chain_record
|
||||
after_commit :generate_and_send_invoice, on: [:create], if: :persisted?
|
||||
after_update :log_changes
|
||||
after_commit :generate_and_send_invoice, on: [:create], if: :persisted?
|
||||
|
||||
validates_with ClosedPeriodValidator
|
||||
|
||||
@ -44,10 +46,6 @@ class Invoice < PaymentDocument
|
||||
"#{prefix}-#{id}_#{created_at.strftime('%d%m%Y')}.pdf"
|
||||
end
|
||||
|
||||
def user
|
||||
invoicing_profile.user
|
||||
end
|
||||
|
||||
def order_number
|
||||
PaymentDocumentService.generate_order_number(self)
|
||||
end
|
||||
@ -75,7 +73,7 @@ class Invoice < PaymentDocument
|
||||
invoice_items.each do |ii|
|
||||
paid_items += 1 unless ii.amount.zero?
|
||||
next unless 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
|
||||
raise StandardError if ii.invoice_item # cannot refund an item that was already refunded
|
||||
|
||||
refund_items += 1 unless ii.amount.zero?
|
||||
avoir_ii = avoir.invoice_items.build(ii.dup.attributes)
|
||||
@ -84,17 +82,7 @@ class Invoice < PaymentDocument
|
||||
avoir.total += avoir_ii.amount
|
||||
end
|
||||
# handle coupon
|
||||
unless avoir.coupon_id.nil?
|
||||
discount = avoir.total
|
||||
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 / paid_items) * refund_items
|
||||
else
|
||||
raise InvalidCouponError
|
||||
end
|
||||
avoir.total -= discount
|
||||
end
|
||||
avoir.total = CouponService.apply_on_refund(avoir.total, avoir.coupon, paid_items, refund_items)
|
||||
avoir
|
||||
end
|
||||
|
||||
@ -145,6 +133,10 @@ class Invoice < PaymentDocument
|
||||
invoice_items.where(main: true).first
|
||||
end
|
||||
|
||||
def other_items
|
||||
invoice_items.where(main: [nil, false])
|
||||
end
|
||||
|
||||
# get amount total paid
|
||||
def amount_paid
|
||||
total - (wallet_amount || 0)
|
||||
|
@ -4,7 +4,7 @@
|
||||
class PaymentScheduleItem < Footprintable
|
||||
belongs_to :payment_schedule
|
||||
belongs_to :invoice
|
||||
has_one :payment_gateway_object, as: :item
|
||||
has_one :payment_gateway_object, as: :item, dependent: :destroy
|
||||
|
||||
after_create :chain_record
|
||||
|
||||
|
@ -40,6 +40,21 @@ class CouponService
|
||||
price
|
||||
end
|
||||
|
||||
# Apply the provided coupon to the given amount, considering that this applies to a refund invoice (Avoir),
|
||||
# potentially partial
|
||||
def self.apply_on_refund(amount, coupon, paid_items = 1, refund_items = 1)
|
||||
return amount if coupon.nil?
|
||||
|
||||
case coupon.type
|
||||
when 'percent_off'
|
||||
amount - (Rational(amount * coupon.percent_off) / Rational(100.0)).to_f.ceil
|
||||
when 'amount_off'
|
||||
amount - (Rational(coupon.amount_off / paid_items) * Rational(refund_items)).to_f.ceil
|
||||
else
|
||||
raise InvalidCouponError
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Find the coupon associated with the given code and check it is valid for the given user
|
||||
# @param code {String} the literal code of the coupon
|
||||
|
@ -58,14 +58,14 @@ class Invoices::RoundTest < ActionDispatch::IntegrationTest
|
||||
### amount paid = 1295
|
||||
|
||||
invoice = Invoice.last
|
||||
assert_equal 121, invoice.invoice_items.first.amount
|
||||
assert_equal 1498, invoice.invoice_items.last.amount
|
||||
assert_equal 121, invoice.main_item.amount
|
||||
assert_equal 1498, invoice.other_items.last.amount
|
||||
assert_equal 1295, invoice.total
|
||||
|
||||
coupon_service = CouponService.new
|
||||
total_without_coupon = coupon_service.invoice_total_no_coupon(invoice)
|
||||
assert_equal 97, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.first.amount, invoice.coupon)
|
||||
assert_equal 1198, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.last.amount, invoice.coupon)
|
||||
assert_equal 97, coupon_service.ventilate(total_without_coupon, invoice.main_item.amount, invoice.coupon)
|
||||
assert_equal 1198, coupon_service.ventilate(total_without_coupon, invoice.other_items.last.amount, invoice.coupon)
|
||||
assert_equal 324, total_without_coupon - invoice.total
|
||||
|
||||
vat_service = VatHistoryService.new
|
||||
@ -121,14 +121,14 @@ class Invoices::RoundTest < ActionDispatch::IntegrationTest
|
||||
### amount paid = 2336
|
||||
|
||||
invoice = Invoice.last
|
||||
assert_equal 1423, invoice.invoice_items.first.amount
|
||||
assert_equal 1498, invoice.invoice_items.last.amount
|
||||
assert_equal 1423, invoice.main_item.amount
|
||||
assert_equal 1498, invoice.other_items.last.amount
|
||||
assert_equal 2336, invoice.total
|
||||
|
||||
coupon_service = CouponService.new
|
||||
total_without_coupon = coupon_service.invoice_total_no_coupon(invoice)
|
||||
assert_equal 1138, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.first.amount, invoice.coupon)
|
||||
assert_equal 1198, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.last.amount, invoice.coupon)
|
||||
assert_equal 1138, coupon_service.ventilate(total_without_coupon, invoice.main_item.amount, invoice.coupon)
|
||||
assert_equal 1198, coupon_service.ventilate(total_without_coupon, invoice.other_items.last.amount, invoice.coupon)
|
||||
assert_equal 585, total_without_coupon - invoice.total
|
||||
|
||||
vat_service = VatHistoryService.new
|
||||
@ -184,14 +184,14 @@ class Invoices::RoundTest < ActionDispatch::IntegrationTest
|
||||
### amount paid = 1319
|
||||
|
||||
invoice = Invoice.last
|
||||
assert_equal 121, invoice.invoice_items.first.amount
|
||||
assert_equal 1498, invoice.invoice_items.last.amount
|
||||
assert_equal 121, invoice.main_item.amount
|
||||
assert_equal 1498, invoice.other_items.last.amount
|
||||
assert_equal 1319, invoice.total
|
||||
|
||||
coupon_service = CouponService.new
|
||||
total_without_coupon = coupon_service.invoice_total_no_coupon(invoice)
|
||||
assert_equal 99, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.first.amount, invoice.coupon)
|
||||
assert_equal 1220, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.last.amount, invoice.coupon)
|
||||
assert_equal 99, coupon_service.ventilate(total_without_coupon, invoice.main_item.amount, invoice.coupon)
|
||||
assert_equal 1220, coupon_service.ventilate(total_without_coupon, invoice.other_items.last.amount, invoice.coupon)
|
||||
assert_equal 300, total_without_coupon - invoice.total
|
||||
|
||||
vat_service = VatHistoryService.new
|
||||
@ -247,14 +247,14 @@ class Invoices::RoundTest < ActionDispatch::IntegrationTest
|
||||
### amount paid = 2621
|
||||
|
||||
invoice = Invoice.last
|
||||
assert_equal 1423, invoice.invoice_items.first.amount
|
||||
assert_equal 1498, invoice.invoice_items.last.amount
|
||||
assert_equal 1423, invoice.main_item.amount
|
||||
assert_equal 1498, invoice.other_items.last.amount
|
||||
assert_equal 2621, invoice.total
|
||||
|
||||
coupon_service = CouponService.new
|
||||
total_without_coupon = coupon_service.invoice_total_no_coupon(invoice)
|
||||
assert_equal 1277, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.first.amount, invoice.coupon)
|
||||
assert_equal 1344, coupon_service.ventilate(total_without_coupon, invoice.invoice_items.last.amount, invoice.coupon)
|
||||
assert_equal 1277, coupon_service.ventilate(total_without_coupon, invoice.main_item.amount, invoice.coupon)
|
||||
assert_equal 1344, coupon_service.ventilate(total_without_coupon, invoice.other_items.last.amount, invoice.coupon)
|
||||
assert_equal 300, total_without_coupon - invoice.total
|
||||
|
||||
vat_service = VatHistoryService.new
|
||||
|
Loading…
x
Reference in New Issue
Block a user