Class: Einvoicing::Invoice
- Inherits:
-
Data
- Object
- Data
- Einvoicing::Invoice
- Defined in:
- lib/einvoicing/invoice.rb
Overview
Core invoice model. All monetary values are in the invoice currency.
Constant Summary collapse
- RECOMPUTES_TAX_BREAKDOWN =
Changing any of these invalidates the memoised breakdown, so the copy has to recompute it — unless the caller supplies one of their own.
%i[lines allowances charges].freeze
Instance Attribute Summary collapse
-
#allowances ⇒ Object
readonly
Returns the value of attribute allowances.
-
#bic ⇒ Object
readonly
Returns the value of attribute bic.
-
#buyer ⇒ Object
readonly
Returns the value of attribute buyer.
-
#charges ⇒ Object
readonly
Returns the value of attribute charges.
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
-
#document_type ⇒ Object
readonly
Returns the value of attribute document_type.
-
#due_date ⇒ Object
readonly
Returns the value of attribute due_date.
-
#iban ⇒ Object
readonly
Returns the value of attribute iban.
-
#invoice_number ⇒ Object
readonly
Returns the value of attribute invoice_number.
-
#issue_date ⇒ Object
readonly
Returns the value of attribute issue_date.
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
-
#note ⇒ Object
readonly
Returns the value of attribute note.
-
#original_invoice_date ⇒ Object
readonly
Returns the value of attribute original_invoice_date.
-
#original_invoice_number ⇒ Object
readonly
Returns the value of attribute original_invoice_number.
-
#payment_means_code ⇒ Object
readonly
Returns the value of attribute payment_means_code.
-
#payment_reference ⇒ Object
readonly
Returns the value of attribute payment_reference.
-
#prepaid_amount ⇒ Object
readonly
Returns the value of attribute prepaid_amount.
-
#seller ⇒ Object
readonly
Returns the value of attribute seller.
-
#tax_breakdown ⇒ Object
readonly
Returns the value of attribute tax_breakdown.
-
#tax_currency ⇒ Object
readonly
Returns the value of attribute tax_currency.
-
#tax_exchange_rate ⇒ Object
readonly
Returns the value of attribute tax_exchange_rate.
Instance Method Summary collapse
-
#allowance_total ⇒ Object
Sum of document-level allowances (BT-107).
-
#charge_total ⇒ Object
Sum of document-level charges (BT-108).
-
#due_amount ⇒ Object
Amount due after deducting any retained/prepaid amount (BT-113).
-
#gross_total ⇒ Object
Grand total including VAT (BT-112) — BR-CO-15: net_total + tax_total.
-
#initialize(invoice_number:, issue_date:, seller:, buyer:, lines:, allowances: [], charges: [], due_date: nil, currency: "EUR", tax_currency: nil, tax_exchange_rate: nil, tax_breakdown: nil, payment_reference: nil, note: nil, payment_means_code: nil, iban: nil, bic: nil, document_type: :invoice, original_invoice_number: nil, original_invoice_date: nil, prepaid_amount: BigDecimal(0)) ⇒ Invoice
constructor
A new instance of Invoice.
-
#line_total ⇒ Object
Sum of all line net amounts, before document-level adjustments (BT-106).
-
#net_total ⇒ Object
Total amount without VAT (BT-109) — BR-CO-13: line_total − allowance_total + charge_total.
-
#tax_accounting_currency? ⇒ Boolean
BT-6 is set and differs from the invoice currency (BT-5), so BR-53 requires the total VAT to also be stated in the VAT accounting currency (BT-111).
-
#tax_total ⇒ Object
Total VAT across every category (BT-110).
-
#tax_total_in_tax_currency ⇒ Object
Total VAT in the VAT accounting currency (BT-111).
-
#with(**kwargs) ⇒ Object
Rebuilt through the constructor rather than by delegating to Data#with: only Ruby >= 3.3 routes #with through #initialize.
Constructor Details
#initialize(invoice_number:, issue_date:, seller:, buyer:, lines:, allowances: [], charges: [], due_date: nil, currency: "EUR", tax_currency: nil, tax_exchange_rate: nil, tax_breakdown: nil, payment_reference: nil, note: nil, payment_means_code: nil, iban: nil, bic: nil, document_type: :invoice, original_invoice_number: nil, original_invoice_date: nil, prepaid_amount: BigDecimal(0)) ⇒ Invoice
Returns a new instance of Invoice.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/einvoicing/invoice.rb', line 44 def initialize(invoice_number:, issue_date:, seller:, buyer:, lines:, allowances: [], charges: [], due_date: nil, currency: "EUR", tax_currency: nil, tax_exchange_rate: nil, tax_breakdown: nil, payment_reference: nil, note: nil, payment_means_code: nil, iban: nil, bic: nil, document_type: :invoice, original_invoice_number: nil, original_invoice_date: nil, prepaid_amount: BigDecimal(0)) allowances = allowances || [] charges = charges || [] computed_breakdown = tax_breakdown || compute_tax_breakdown(lines, allowances, charges) super( invoice_number: invoice_number, issue_date: issue_date, due_date: due_date, currency: currency, tax_currency: tax_currency, tax_exchange_rate: tax_exchange_rate.nil? ? nil : BigDecimal(tax_exchange_rate.to_s), seller: seller, buyer: buyer, lines: lines, allowances: allowances, charges: charges, tax_breakdown: computed_breakdown, payment_reference: payment_reference, note: note, payment_means_code: payment_means_code, iban: iban, bic: bic, document_type: document_type, original_invoice_number: original_invoice_number, original_invoice_date: original_invoice_date, prepaid_amount: prepaid_amount.nil? ? BigDecimal(0) : BigDecimal(prepaid_amount.to_s) ) end |
Instance Attribute Details
#allowances ⇒ Object (readonly)
Returns the value of attribute allowances
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def allowances @allowances end |
#bic ⇒ Object (readonly)
Returns the value of attribute bic
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def bic @bic end |
#buyer ⇒ Object (readonly)
Returns the value of attribute buyer
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def buyer @buyer end |
#charges ⇒ Object (readonly)
Returns the value of attribute charges
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def charges @charges end |
#currency ⇒ Object (readonly)
Returns the value of attribute currency
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def currency @currency end |
#document_type ⇒ Object (readonly)
Returns the value of attribute document_type
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def document_type @document_type end |
#due_date ⇒ Object (readonly)
Returns the value of attribute due_date
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def due_date @due_date end |
#iban ⇒ Object (readonly)
Returns the value of attribute iban
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def iban @iban end |
#invoice_number ⇒ Object (readonly)
Returns the value of attribute invoice_number
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def invoice_number @invoice_number end |
#issue_date ⇒ Object (readonly)
Returns the value of attribute issue_date
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def issue_date @issue_date end |
#lines ⇒ Object (readonly)
Returns the value of attribute lines
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def lines @lines end |
#note ⇒ Object (readonly)
Returns the value of attribute note
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def note @note end |
#original_invoice_date ⇒ Object (readonly)
Returns the value of attribute original_invoice_date
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def original_invoice_date @original_invoice_date end |
#original_invoice_number ⇒ Object (readonly)
Returns the value of attribute original_invoice_number
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def original_invoice_number @original_invoice_number end |
#payment_means_code ⇒ Object (readonly)
Returns the value of attribute payment_means_code
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def payment_means_code @payment_means_code end |
#payment_reference ⇒ Object (readonly)
Returns the value of attribute payment_reference
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def payment_reference @payment_reference end |
#prepaid_amount ⇒ Object (readonly)
Returns the value of attribute prepaid_amount
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def prepaid_amount @prepaid_amount end |
#seller ⇒ Object (readonly)
Returns the value of attribute seller
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def seller @seller end |
#tax_breakdown ⇒ Object (readonly)
Returns the value of attribute tax_breakdown
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def tax_breakdown @tax_breakdown end |
#tax_currency ⇒ Object (readonly)
Returns the value of attribute tax_currency
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def tax_currency @tax_currency end |
#tax_exchange_rate ⇒ Object (readonly)
Returns the value of attribute tax_exchange_rate
21 22 23 |
# File 'lib/einvoicing/invoice.rb', line 21 def tax_exchange_rate @tax_exchange_rate end |
Instance Method Details
#allowance_total ⇒ Object
Sum of document-level allowances (BT-107).
105 106 107 |
# File 'lib/einvoicing/invoice.rb', line 105 def allowance_total allowances.sum(BigDecimal("0"), &:amount).round(2, :half_up) end |
#charge_total ⇒ Object
Sum of document-level charges (BT-108).
110 111 112 |
# File 'lib/einvoicing/invoice.rb', line 110 def charge_total charges.sum(BigDecimal("0"), &:amount).round(2, :half_up) end |
#due_amount ⇒ Object
Amount due after deducting any retained/prepaid amount (BT-113). VAT remains due on the full gross_total — only the payable balance is reduced (EN 16931 BR-CO-16: DuePayableAmount = GrandTotal − TotalPrepaidAmount).
135 136 137 |
# File 'lib/einvoicing/invoice.rb', line 135 def due_amount gross_total - prepaid_amount end |
#gross_total ⇒ Object
Grand total including VAT (BT-112) — BR-CO-15: net_total + tax_total. Both operands are already rounded to 2 decimals from per-line amounts, so this introduces no double-rounding.
128 129 130 |
# File 'lib/einvoicing/invoice.rb', line 128 def gross_total (net_total + tax_total).round(2, :half_up) end |
#line_total ⇒ Object
Sum of all line net amounts, before document-level adjustments (BT-106).
100 101 102 |
# File 'lib/einvoicing/invoice.rb', line 100 def line_total lines.sum(BigDecimal("0"), &:net_amount).round(2, :half_up) end |
#net_total ⇒ Object
Total amount without VAT (BT-109) — BR-CO-13: line_total − allowance_total + charge_total.
116 117 118 |
# File 'lib/einvoicing/invoice.rb', line 116 def net_total (line_total - allowance_total + charge_total).round(2, :half_up) end |
#tax_accounting_currency? ⇒ Boolean
BT-6 is set and differs from the invoice currency (BT-5), so BR-53 requires the total VAT to also be stated in the VAT accounting currency (BT-111).
141 142 143 |
# File 'lib/einvoicing/invoice.rb', line 141 def tax_accounting_currency? !tax_currency.nil? && tax_currency != currency end |
#tax_total ⇒ Object
Total VAT across every category (BT-110).
121 122 123 |
# File 'lib/einvoicing/invoice.rb', line 121 def tax_total tax_breakdown.sum(BigDecimal("0"), &:tax_amount).round(2, :half_up) end |
#tax_total_in_tax_currency ⇒ Object
Total VAT in the VAT accounting currency (BT-111). Derived from
tax_exchange_rate when given; nil when there is nothing to convert.
147 148 149 150 151 152 |
# File 'lib/einvoicing/invoice.rb', line 147 def tax_total_in_tax_currency return nil unless tax_accounting_currency? return nil if tax_exchange_rate.nil? (tax_total * tax_exchange_rate).round(2, :half_up) end |
#with(**kwargs) ⇒ Object
Rebuilt through the constructor rather than by delegating to Data#with:
only Ruby >= 3.3 routes #with through #initialize. On 3.2 it copies the
members straight across, so tax_breakdown: nil would be written as-is
and every total computed from it would blow up on nil.
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/einvoicing/invoice.rb', line 88 def with(**kwargs) return self if kwargs.empty? attributes = to_h.merge(kwargs) if !kwargs.key?(:tax_breakdown) && kwargs.keys.intersect?(RECOMPUTES_TAX_BREAKDOWN) attributes[:tax_breakdown] = nil end self.class.new(**attributes) end |