All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.2.0]

Added

  • Émission of transfer orders (CFONB 160). CFONB.Virement.encode/2 and encode!/2 generate an ordinary transfer order (code opération 02) as 03/06/08 records, 160 characters each. Bank coordinates are accepted as an IBAN (decomposed and key-checked) or as split RIB components — never both on the same struct (rejected as ambiguous).
  • Payment-safety validation in encode/2: mandatory names, account charset and length, émetteur-number length and type, amount and 08-total bounded to the 16-digit cents zone — every invalid input returns {:error, reason} instead of silently truncating, emitting blank zones, or raising.
  • CFONB.Encode — fixed-width field formatting helpers (numeric, alphanumeric, unsigned-cents amount, JJMMA date, character-set sanitization).
  • CFONB.Rib — shared RIB key computation and IBAN derivation, including from_iban/1 which verifies both the IBAN check digits and the RIB key.
  • FORMAT-VIREMENT.md documenting the CFONB 160 field layout.

Changed

Fixed (parser robustness)

  • Malformed numeric zones (date, scale, entry number, amount digits, and the 05 FEE/MMO zones) now return {:error, reason} — and are skippable with optimistic: true — instead of raising ArgumentError out of parse/2.
  • A physical line whose length is not a multiple of 120 no longer loses its trailing chunk silently: a non-blank tail surfaces as an invalid record (an all-blank tail is still treated as producer padding).
  • A FEE detail with a blank amount no longer reports a fee of 0.00; malformed FEE/MMO details are preserved verbatim under details.unknown.
  • CFONB.Rib.from_iban/1 validates the French BBAN structure (charset included), so a corrupted IBAN returns {:error, {:invalid_iban, _}} — including through CFONB.Virement.encode/2 — instead of raising.
  • CFONB.Statement.rib/1 / iban/1 raise a clear, documented ArgumentError when the parsed statement's bank/branch/account zones cannot form a RIB.

[0.1.0]

Added

  • Initial CFONB 120 account-statement parser: CFONB.parse/2, parse!/2, parse_operation/2, with 01/04/05/07 record decoding, qualifier-specific 05 details, RIB/IBAN derivation, raw-record access, and optimistic parsing. At feature parity with the reference Ruby gem.