Module: FactPulse::Helpers::AmountHelpers
- Defined in:
- lib/factpulse/helpers/client.rb
Overview
Helpers for creating simplified total amounts.
Class Method Summary collapse
- .amount(value) ⇒ Object
-
.beneficiary(name, **options) ⇒ Hash
Creates a beneficiary (factor) for factoring.
-
.compute_vat_intra(siren) ⇒ Object
Computes the French intra-community VAT number from a SIREN.
-
.electronic_address(identifier, scheme_id: '0009') ⇒ Object
Creates an electronic address.
-
.invoice_line(number, description, quantity, unit_price_excl_tax, line_total_excl_tax, vat_rate: '20.00', vat_category: 'S', unit: 'LUMP_SUM', **options) ⇒ Object
Creates an invoice line (aligned with InvoiceLine in models.py).
- .invoice_totals(excl_tax, vat, incl_tax, amount_due, discount_incl_tax: nil, discount_reason: nil, prepayment: nil) ⇒ Object
-
.postal_address(line1, postal_code, city, country: 'FR', line2: nil, line3: nil) ⇒ Object
Creates a postal address for the FactPulse API.
-
.recipient(name, siret, address_line1, postal_code, city, **options) ⇒ Object
Creates a recipient (customer) with auto-computed SIREN and addresses.
-
.supplier(name, siret, address_line1, postal_code, city, **options) ⇒ Object
Creates a supplier (issuer) with auto-computed SIREN, intra-EU VAT number and addresses.
-
.vat_line(rate_manual, base_amount_excl_tax, vat_amount, category: 'S') ⇒ Object
Creates a VAT line (aligned with VatLine in models.py).
Class Method Details
.amount(value) ⇒ Object
38 39 40 41 42 |
# File 'lib/factpulse/helpers/client.rb', line 38 def self.amount(value) return '0.00' if value.nil? return format('%.2f', value) if value.is_a?(Numeric) value.is_a?(String) ? value : '0.00' end |
.beneficiary(name, **options) ⇒ Hash
Creates a beneficiary (factor) for factoring.
The beneficiary (BG-10 / PayeeTradeParty) is used when payment must be made to a third party different from the supplier, typically a factor (factoring company).
For factored invoices, you also need to:
-
Use a factored document type (393, 396, 501, 502, 472, 473)
-
Add an ACC note with the subrogation mention
-
The beneficiary’s IBAN will be used for payment
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/factpulse/helpers/client.rb', line 151 def self.beneficiary(name, **) # Auto-compute SIREN from SIRET siret = [:siret] siren = [:siren] || (siret && siret.length == 14 ? siret[0, 9] : nil) result = { 'name' => name } result['siret'] = siret if siret result['siren'] = siren if siren result['iban'] = [:iban] if [:iban] result['bic'] = [:bic] if [:bic] result end |
.compute_vat_intra(siren) ⇒ Object
Computes the French intra-community VAT number from a SIREN.
95 96 97 98 99 |
# File 'lib/factpulse/helpers/client.rb', line 95 def self.compute_vat_intra(siren) return nil if siren.nil? || siren.length != 9 || !siren.match?(/^\d+$/) cle = (12 + 3 * (siren.to_i % 97)) % 97 format('FR%02d%s', cle, siren) end |
.electronic_address(identifier, scheme_id: '0009') ⇒ Object
Creates an electronic address. scheme_id: “0009”=SIREN, “0225”=SIRET
90 91 92 |
# File 'lib/factpulse/helpers/client.rb', line 90 def self.electronic_address(identifier, scheme_id: '0009') { 'identifier' => identifier, 'schemeId' => scheme_id } end |
.invoice_line(number, description, quantity, unit_price_excl_tax, line_total_excl_tax, vat_rate: '20.00', vat_category: 'S', unit: 'LUMP_SUM', **options) ⇒ Object
Creates an invoice line (aligned with InvoiceLine in models.py).
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/factpulse/helpers/client.rb', line 56 def self.invoice_line(number, description, quantity, unit_price_excl_tax, line_total_excl_tax, vat_rate: '20.00', vat_category: 'S', unit: 'LUMP_SUM', **) result = { 'number' => number, 'description' => description, 'quantity' => amount(quantity), 'unitPriceExclTax' => amount(unit_price_excl_tax), 'lineTotalExclTax' => amount(line_total_excl_tax), 'vatRateManual' => amount(vat_rate), 'vatCategory' => vat_category, 'unit' => unit } result['reference'] = [:reference] if [:reference] result['discountExclTax'] = amount([:discount_excl_tax]) if [:discount_excl_tax] result['discountReasonCode'] = [:discount_reason_code] if [:discount_reason_code] result['discountReason'] = [:discount_reason] if [:discount_reason] result['periodStartDate'] = [:period_start_date] if [:period_start_date] result['periodEndDate'] = [:period_end_date] if [:period_end_date] result end |
.invoice_totals(excl_tax, vat, incl_tax, amount_due, discount_incl_tax: nil, discount_reason: nil, prepayment: nil) ⇒ Object
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/factpulse/helpers/client.rb', line 44 def self.invoice_totals(excl_tax, vat, incl_tax, amount_due, discount_incl_tax: nil, discount_reason: nil, prepayment: nil) result = { 'totalExclTax' => amount(excl_tax), 'vatAmount' => amount(vat), 'totalInclTax' => amount(incl_tax), 'amountDue' => amount(amount_due) } result['globalDiscountInclTax'] = amount(discount_incl_tax) if discount_incl_tax result['globalDiscountReason'] = discount_reason if discount_reason result['prepayment'] = amount(prepayment) if prepayment result end |
.postal_address(line1, postal_code, city, country: 'FR', line2: nil, line3: nil) ⇒ Object
Creates a postal address for the FactPulse API.
82 83 84 85 86 87 |
# File 'lib/factpulse/helpers/client.rb', line 82 def self.postal_address(line1, postal_code, city, country: 'FR', line2: nil, line3: nil) result = { 'line1' => line1, 'postalCode' => postal_code, 'city' => city, 'countryCode' => country } result['line2'] = line2 if line2 result['line3'] = line3 if line3 result end |
.recipient(name, siret, address_line1, postal_code, city, **options) ⇒ Object
Creates a recipient (customer) with auto-computed SIREN and addresses.
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/factpulse/helpers/client.rb', line 119 def self.recipient(name, siret, address_line1, postal_code, city, **) siren = [:siren] || (siret.length == 14 ? siret[0, 9] : nil) result = { 'name' => name, 'siret' => siret, 'electronicAddress' => electronic_address(siret, scheme_id: '0225'), 'postalAddress' => postal_address(address_line1, postal_code, city, country: [:country] || 'FR', line2: [:address_line2]) } result['siren'] = siren if siren result['executingServiceCode'] = [:executing_service_code] if [:executing_service_code] result end |
.supplier(name, siret, address_line1, postal_code, city, **options) ⇒ Object
Creates a supplier (issuer) with auto-computed SIREN, intra-EU VAT number and addresses.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/factpulse/helpers/client.rb', line 102 def self.supplier(name, siret, address_line1, postal_code, city, **) siren = [:siren] || (siret.length == 14 ? siret[0, 9] : nil) vat_intra = [:vat_intra] || (siren ? compute_vat_intra(siren) : nil) result = { 'name' => name, 'supplierId' => [:supplier_id] || 0, 'siret' => siret, 'electronicAddress' => electronic_address(siret, scheme_id: '0225'), 'postalAddress' => postal_address(address_line1, postal_code, city, country: [:country] || 'FR', line2: [:address_line2]) } result['siren'] = siren if siren result['vatIntra'] = vat_intra if vat_intra result['iban'] = [:iban] if [:iban] result['supplierServiceId'] = [:service_code] if [:service_code] result['supplierBankCoordinatesCode'] = [:bank_coordinates_code] if [:bank_coordinates_code] result end |
.vat_line(rate_manual, base_amount_excl_tax, vat_amount, category: 'S') ⇒ Object
Creates a VAT line (aligned with VatLine in models.py).
74 75 76 77 78 79 |
# File 'lib/factpulse/helpers/client.rb', line 74 def self.vat_line(rate_manual, base_amount_excl_tax, vat_amount, category: 'S') { 'rateManual' => amount(rate_manual), 'baseAmountExclTax' => amount(base_amount_excl_tax), 'vatAmount' => amount(vat_amount), 'category' => category } end |