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:
parent
02c7cb801f
commit
cd2c8488c2
@ -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`
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user