1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-17 11:54:22 +01:00

Compute the VAT per item in each invoices, instead of globally

This commit is contained in:
Sylvain 2019-09-18 17:14:59 +02:00
parent 02c7cb801f
commit cd2c8488c2
4 changed files with 34 additions and 14 deletions

View File

@ -1,6 +1,7 @@
# Changelog Fab Manager
- Ability to configure and export the accounting data to the ACD accounting software
- Compute the VAT per item in each invoices, instead of globally
- Fix a bug: invoices with total = 0, are marked as paid on site even if paid by card
- [TODO DEPLOY] `rake db:migrate`

View File

@ -21,6 +21,25 @@ class InvoiceItem < ActiveRecord::Base
footprint == compute_footprint
end
def amount_after_coupon
# deduct coupon discount
coupon_service = CouponService.new
coupon_service.ventilate(invoice.total, amount, invoice.coupon)
end
# return the item amount, coupon discount deducted, if any, and VAT excluded, if applicable
def net_amount
# deduct VAT
vat_service = VatHistoryService.new
vat_rate = vat_service.invoice_vat(invoice)
Rational(amount_after_coupon / (vat_rate / 100.00 + 1)).round.to_f
end
# return the VAT amount for this item
def vat
amount_after_coupon - net_amount
end
private
def compute_footprint

View File

@ -121,6 +121,8 @@ class PDF::Invoice < Prawn::Document
data = [[I18n.t('invoices.details'), I18n.t('invoices.amount')]]
total_calc = 0
total_ht = 0
total_vat = 0
# going through invoice_items
invoice.invoice_items.each do |item|
@ -184,6 +186,8 @@ class PDF::Invoice < Prawn::Document
data += [[details, number_to_currency(price)]]
total_calc += price
total_ht += item.net_amount
total_vat += item.vat
end
## subtract the coupon, if any
@ -210,15 +214,13 @@ class PDF::Invoice < Prawn::Document
# discount textual description
literal_discount = cp.percent_off
if cp.type == 'amount_off'
literal_discount = number_to_currency(cp.amount_off / 100.00)
end
literal_discount = number_to_currency(cp.amount_off / 100.00) if cp.type == 'amount_off'
# add a row for the coupon
data += [[_t('invoices.coupon_CODE_discount_of_DISCOUNT',
CODE: cp.code,
DISCOUNT: literal_discount,
TYPE: cp.type), number_to_currency(-discount)] ]
TYPE: cp.type), number_to_currency(-discount)]]
end
# total verification
@ -226,20 +228,18 @@ class PDF::Invoice < Prawn::Document
puts "ERROR: totals are NOT equals => expected: #{total}, computed: #{total_calc}" if total_calc != total
# TVA
if Setting.find_by(name: 'invoice_VAT-active').value == 'true'
vat_service = VatHistoryService.new
vat_rate = vat_service.invoice_vat(invoice)
if vat_rate != 0
data += [[I18n.t('invoices.total_including_all_taxes'), number_to_currency(total)]]
vat_service = VatHistoryService.new
vat_rate = vat_service.invoice_vat(invoice)
vat = total / (vat_rate / 100.00 + 1)
data += [[I18n.t('invoices.including_VAT_RATE', RATE: vat_rate), number_to_currency(total - vat)]]
data += [[I18n.t('invoices.including_total_excluding_taxes'), number_to_currency(vat)]]
data += [[I18n.t('invoices.including_VAT_RATE', RATE: vat_rate), number_to_currency(total_vat / 100.00)]]
data += [[I18n.t('invoices.including_total_excluding_taxes'), number_to_currency(total_ht / 100.00)]]
data += [[I18n.t('invoices.including_amount_payed_on_ordering'), number_to_currency(total)]]
# checking the round number
rounded = sprintf('%.2f', vat).to_f + sprintf('%.2f', total - vat).to_f
rounded = sprintf('%.2f', total_vat / 100.00).to_f + sprintf('%.2f', total_ht / 100.00).to_f
if rounded != sprintf('%.2f', total_calc).to_f
puts 'ERROR: rounding the numbers cause an invoice inconsistency. ' +
puts 'ERROR: rounding the numbers cause an invoice inconsistency. ' \
"Total expected: #{sprintf('%.2f', total_calc)}, total computed: #{rounded}"
end
else

View File

@ -7,7 +7,7 @@ class FootprintService
# @param item an instance of the provided class
# @param sort the items in database by the provided criterion, to find the previous one
def self.compute_footprint(klass, item, sort_on = 'id')
raise TypeError unless item.class.name == klass.name
raise TypeError unless item.is_a? klass
previous = klass.where("#{sort_on} < ?", item[sort_on])
.order("#{sort_on} DESC")