Class: FacturX::Validation::Rules

Inherits:
Object
  • Object
show all
Defined in:
lib/factur_x/validation/rules.rb

Overview

Business rules checked in Ruby so the invoicing domain gets fast, readable errors without shelling out to the official schematron. The rule identifiers refer to EN 16931; the schematron remains the authority and the test suite checks these rules agree with it.

Constant Summary collapse

CURRENCY_PATTERN =
/\A[A-Z]{3}\z/.freeze
COUNTRY_PATTERN =
/\A[A-Z]{2}\z/.freeze
IBAN_PATTERN =
/\A[A-Z]{2}[0-9]{2}[A-Z0-9]{10,30}\z/.freeze
SIRET_PATTERN =
/\A[0-9]{14}\z/.freeze
SIREN_PATTERN =
/\A[0-9]{9}\z/.freeze
VAT_NUMBER_PATTERN =
/\A[A-Z]{2}[A-Z0-9]{2,13}\z/.freeze
ROUNDING_TOLERANCE =
BigDecimal("0.01")
PROFILES =
%i[en16931 fr_ctc].freeze
MANDATORY_FRENCH_NOTES =

BR-FR-05: every invoice must carry these three statements.

{
  Codes::NoteSubject::PAYMENT_TERMS => "recovery costs",
  Codes::NoteSubject::PAYMENT_PENALTIES => "late payment penalties",
  Codes::NoteSubject::DISCOUNT_TERMS => "early payment discount"
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(invoice, profile: :fr_ctc) ⇒ Rules

Returns a new instance of Rules.

Raises:



34
35
36
37
38
39
40
# File 'lib/factur_x/validation/rules.rb', line 34

def initialize(invoice, profile: :fr_ctc)
  raise Error, "unknown profile #{profile.inspect}" unless PROFILES.include?(profile)

  @invoice = invoice
  @profile = profile
  @violations = []
end

Instance Method Details

#valid?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/factur_x/validation/rules.rb', line 54

def valid?
  violations.empty?
end

#validate!Object

Raises:



58
59
60
61
62
63
# File 'lib/factur_x/validation/rules.rb', line 58

def validate!
  found = violations
  raise ValidationError, found unless found.empty?

  invoice
end

#violationsObject



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/factur_x/validation/rules.rb', line 42

def violations
  @violations = []
  check_document
  check_parties
  check_lines
  check_tax_breakdowns
  check_payment
  check_totals
  check_french_requirements if french?
  @violations
end