Class: Einvoicing::Tax
- Inherits:
-
Object
- Object
- Einvoicing::Tax
- Defined in:
- lib/einvoicing/tax.rb
Overview
VAT breakdown entry (BG-23) for a single rate/category pair.
Constant Summary collapse
- CATEGORY_CODES =
EN 16931 BT-118 — the UNCL5305 subset the standard allows.
{ standard: "S", # Standard rate zero_rated: "Z", # Zero rated goods exempt: "E", # Exempt from VAT reverse_charge: "AE", # VAT reverse charge intra_community: "K", # Intra-Community supply export: "G", # Export outside the EU not_subject: "O" # Services outside scope of tax }.freeze
- EXEMPTION_REQUIRED_CODES =
BR-E-10, BR-AE-10, BR-IC-10, BR-G-10, BR-O-10: these categories must carry a VAT exemption reason (BT-120) or reason code (BT-121). BR-Z-10 and the standard category must NOT carry one.
%w[E AE K G O].freeze
- ZERO_VAT_CODES =
Categories that net out to 0 % VAT whatever rate the caller passed in.
%w[Z E AE K G O].freeze
- DEFAULT_EXEMPTIONS =
Defaults from the EN 16931 VATEX code list. "E" is deliberately absent: the reason depends on which exemption is invoked, so the caller supplies it (e.g. VATEX_FR_FRANCHISE for the French art. 293 B franchise).
{ "AE" => [ "VATEX-EU-AE", "Reverse charge" ], "K" => [ "VATEX-EU-IC", "Intra-Community supply" ], "G" => [ "VATEX-EU-G", "Export outside the EU" ], "O" => [ "VATEX-EU-O", "Not subject to VAT" ] }.freeze
- VATEX_FR_FRANCHISE =
France, art. 293 B du CGI — franchise en base de TVA.
"VATEX-FR-FRANCHISE"
Class Method Summary collapse
-
.category_code_for(rate:, category: nil) ⇒ Object
Shared lookup used by Tax, LineItem and AllowanceCharge.
-
.effective_rate(rate:, category: nil) ⇒ Object
The rate actually billed once the category is taken into account: an exempt / reverse-charge / out-of-scope category charges 0 % whatever rate was passed in.
Instance Method Summary collapse
- #category_code ⇒ Object
-
#exemption_required? ⇒ Boolean
True when EN 16931 requires BT-120 or BT-121 on this breakdown line.
-
#initialize(rate:, taxable_amount:, tax_amount:, category: nil, exemption_reason: nil, exemption_reason_code: nil) ⇒ Tax
constructor
A new instance of Tax.
- #rate_percent ⇒ Object
Constructor Details
#initialize(rate:, taxable_amount:, tax_amount:, category: nil, exemption_reason: nil, exemption_reason_code: nil) ⇒ Tax
Returns a new instance of Tax.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/einvoicing/tax.rb', line 67 def initialize(rate:, taxable_amount:, tax_amount:, category: nil, exemption_reason: nil, exemption_reason_code: nil) raise ArgumentError, Einvoicing::I18n.t("tax.invalid_rate", rate: rate) if rate.to_f.negative? code = Tax.category_code_for(rate: rate, category: category) default_code, default_reason = DEFAULT_EXEMPTIONS.fetch(code, [ nil, nil ]) super( rate: rate, taxable_amount: taxable_amount, tax_amount: tax_amount, category: category, exemption_reason: exemption_reason || default_reason, exemption_reason_code: exemption_reason_code || default_code ) end |
Class Method Details
.category_code_for(rate:, category: nil) ⇒ Object
Shared lookup used by Tax, LineItem and AllowanceCharge.
43 44 45 46 47 48 49 |
# File 'lib/einvoicing/tax.rb', line 43 def self.category_code_for(rate:, category: nil) return rate.to_f.zero? ? "Z" : "S" if category.nil? CATEGORY_CODES.fetch(category) do raise ArgumentError, Einvoicing::I18n.t("tax.unknown_category", category: category.inspect) end end |
.effective_rate(rate:, category: nil) ⇒ Object
The rate actually billed once the category is taken into account: an exempt / reverse-charge / out-of-scope category charges 0 % whatever rate was passed in.
54 55 56 57 58 |
# File 'lib/einvoicing/tax.rb', line 54 def self.effective_rate(rate:, category: nil) return BigDecimal("0") if ZERO_VAT_CODES.include?(category_code_for(rate: rate, category: category)) BigDecimal(rate.to_s) end |
Instance Method Details
#category_code ⇒ Object
84 85 86 |
# File 'lib/einvoicing/tax.rb', line 84 def category_code Tax.category_code_for(rate: rate, category: category) end |
#exemption_required? ⇒ Boolean
True when EN 16931 requires BT-120 or BT-121 on this breakdown line.
89 90 91 |
# File 'lib/einvoicing/tax.rb', line 89 def exemption_required? EXEMPTION_REQUIRED_CODES.include?(category_code) end |
#rate_percent ⇒ Object
93 94 95 |
# File 'lib/einvoicing/tax.rb', line 93 def rate_percent (Tax.effective_rate(rate: rate, category: category) * 100).round(2) end |