Always require invoice VAT rate

Closes #1031
This commit is contained in:
Artur Beljajev 2019-03-07 17:42:21 +02:00
parent d85e57d800
commit 7723a30d1b
17 changed files with 240 additions and 200 deletions

View file

@ -28,16 +28,12 @@ class Invoice < ActiveRecord::Base
validates :due_date, :currency, :seller_name,
:seller_iban, :buyer_name, :items, presence: true
validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
allow_nil: true
before_create :set_invoice_number
before_create :apply_default_vat_rate, unless: :vat_rate?
before_create :calculate_total, unless: :total?
before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
attribute :vat_rate, ::Type::VATRate.new
attr_readonly :vat_rate
def set_invoice_number
last_no = Invoice.order(number: :desc).where('number IS NOT NULL').limit(1).pluck(:number).first
@ -85,7 +81,6 @@ class Invoice < ActiveRecord::Base
end
def vat_amount
return 0 unless vat_rate
subtotal * vat_rate / 100
end
@ -105,10 +100,6 @@ class Invoice < ActiveRecord::Base
private
def apply_default_vat_rate
self.vat_rate = buyer.effective_vat_rate
end
def apply_default_buyer_vat_no
self.buyer_vat_no = buyer.vat_no
end

View file

@ -0,0 +1,19 @@
class Invoice
class VatRateCalculator
attr_reader :registry
attr_reader :registrar
def initialize(registry: Registry.current, registrar:)
@registry = registry
@registrar = registrar
end
def calculate
if registrar.vat_liable_locally?(registry)
registry.vat_rate
else
registrar.vat_rate || 0
end
end
end
end

View file

@ -22,9 +22,9 @@ class Registrar < ActiveRecord::Base
validates :reference_no, format: Billing::ReferenceNo::REGEXP
validate :forbid_special_code
validates :vat_rate, presence: true, if: 'foreign_vat_payer? && vat_no.blank?'
validates :vat_rate, absence: true, if: :home_vat_payer?
validates :vat_rate, absence: true, if: 'foreign_vat_payer? && vat_no?'
validates :vat_rate, presence: true, if: 'vat_liable_in_foreign_country? && vat_no.blank?'
validates :vat_rate, absence: true, if: :vat_liable_locally?
validates :vat_rate, absence: true, if: 'vat_liable_in_foreign_country? && vat_no?'
validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
allow_nil: true
@ -52,7 +52,9 @@ class Registrar < ActiveRecord::Base
end
def issue_prepayment_invoice(amount, description = nil)
invoices.create(
vat_rate = ::Invoice::VatRateCalculator.new(registrar: self).calculate
invoices.create!(
issue_date: Time.zone.today,
due_date: (Time.zone.now + Setting.days_to_keep_invoices_active.days).to_date,
description: description,
@ -84,6 +86,7 @@ class Registrar < ActiveRecord::Base
buyer_url: website,
buyer_email: email,
reference_no: reference_no,
vat_rate: vat_rate,
items_attributes: [
{
description: 'prepayment',
@ -146,12 +149,16 @@ class Registrar < ActiveRecord::Base
end
end
def effective_vat_rate
if home_vat_payer?
Registry.instance.vat_rate
else
vat_rate
end
def vat_country=(country)
self.address_country_code = country.alpha2
end
def vat_country
country
end
def vat_liable_locally?(registry = Registry.current)
vat_country == registry.vat_country
end
def notify(action)
@ -169,11 +176,7 @@ class Registrar < ActiveRecord::Base
errors.add(:code, :forbidden) if code == 'CID'
end
def home_vat_payer?
country == Registry.instance.legal_address_country
def vat_liable_in_foreign_country?
!vat_liable_locally?
end
def foreign_vat_payer?
!home_vat_payer?
end
end
end

View file

@ -1,11 +1,13 @@
class Registry
include Singleton
include ActiveModel::Model
def vat_rate
Setting.registry_vat_prc.to_d * 100
end
attr_accessor :vat_rate
attr_accessor :vat_country
def legal_address_country
Country.new(Setting.registry_country_code)
def self.current
vat_rate = Setting.registry_vat_prc.to_d * 100
vat_country = Country.new(Setting.registry_country_code)
new(vat_rate: vat_rate, vat_country: vat_country)
end
end
end