spb/air Public MIT
AIR — The Language of Accounting.
Python 100%
1# Projet : AIR — Accounting Intermediate Representation2# Auteur : Simon-Pierre Boucher3# Contact : contact@spboucher.ai4#5# Golden cases — FX conversion (IAS 21 transaction-date rate), realized FX6# gains/losses on settlement, settlements, equity and loan events.7# FX semantics per docs/research/fx-handling.md and accounting-standards.md.8# Rates in events are observed input data (e.g. Bank of Canada Valet), never9# constants of the engine.1011cases:12 - name: sale_usd_export13 description: "1000.00 USD export sale (zero-rated), booked at the 1.3500 transaction-date rate"14 air:15 events:16 - id: evt_sale_usd17 type: Sale18 date: 2026-07-0219 amount: {amount: "1000.00", currency: USD}20 tax: {jurisdiction: CA-QC, exempt: true}21 fx: {rate: "1.3500", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-07-02}22 expected_entries:23 - id: je_evt_sale_usd24 lines:25 - ["1100", debit, "1350.00", CAD]26 - ["4000", credit, "1350.00", CAD]2728 - name: purchase_eur_fx29 description: "500.00 EUR foreign purchase at 1.4800: booked at 740.00 CAD"30 air:31 events:32 - id: evt_purch_eur33 type: Purchase34 date: 2026-07-0335 amount: {amount: "500.00", currency: EUR}36 tax: {jurisdiction: CA-QC, exempt: true}37 fx: {rate: "1.4800", source: "bankofcanada.valet:FXEURCAD", rate_date: 2026-07-03}38 expected_entries:39 - id: je_evt_purch_eur40 lines:41 - ["5000", debit, "740.00", CAD]42 - ["2000", credit, "740.00", CAD]4344 - name: payment_received_cad45 description: "Customer settles the 1149.75 receivable, same currency: no FX"46 air:47 events:48 - id: evt_pay_in49 type: PaymentReceived50 date: 2026-07-3051 related_event: evt_sale_simple52 amount: {amount: "1149.75", currency: CAD}53 expected_entries:54 - id: je_evt_pay_in55 lines:56 - ["1000", debit, "1149.75", CAD]57 - ["1100", credit, "1149.75", CAD]5859 - name: payment_sent_cad60 description: "We settle the 459.90 payable, same currency: no FX"61 air:62 events:63 - id: evt_pay_out64 type: PaymentSent65 date: 2026-07-3166 related_event: evt_purch_supplies67 amount: {amount: "459.90", currency: CAD}68 expected_entries:69 - id: je_evt_pay_out70 lines:71 - ["2000", debit, "459.90", CAD]72 - ["1000", credit, "459.90", CAD]7374 - name: fx_gain_on_receipt75 description: "USD sale booked at 1.3000; collected at 1.3500 -> realized FX gain 50.00"76 air:77 events:78 - id: evt_sale_usd_g79 type: Sale80 date: 2026-06-0181 amount: {amount: "1000.00", currency: USD}82 tax: {jurisdiction: CA-QC, exempt: true}83 fx: {rate: "1.3000", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-06-01}84 - id: evt_pay_usd_g85 type: PaymentReceived86 date: 2026-06-3087 related_event: evt_sale_usd_g88 amount: {amount: "1000.00", currency: USD}89 fx: {rate: "1.3500", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-06-30}90 expected_entries:91 - id: je_evt_sale_usd_g92 lines:93 - ["1100", debit, "1300.00", CAD]94 - ["4000", credit, "1300.00", CAD]95 - id: je_evt_pay_usd_g96 lines:97 - ["1000", debit, "1350.00", CAD]98 - ["1100", credit, "1300.00", CAD]99 - ["4500", credit, "50.00", CAD]100101 - name: fx_loss_on_receipt102 description: "USD sale booked at 1.3500; collected at 1.3000 -> realized FX loss 50.00"103 air:104 events:105 - id: evt_sale_usd_l106 type: Sale107 date: 2026-06-05108 amount: {amount: "1000.00", currency: USD}109 tax: {jurisdiction: CA-QC, exempt: true}110 fx: {rate: "1.3500", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-06-05}111 - id: evt_pay_usd_l112 type: PaymentReceived113 date: 2026-07-05114 related_event: evt_sale_usd_l115 amount: {amount: "1000.00", currency: USD}116 fx: {rate: "1.3000", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-07-05}117 expected_entries:118 - id: je_evt_sale_usd_l119 lines:120 - ["1100", debit, "1350.00", CAD]121 - ["4000", credit, "1350.00", CAD]122 - id: je_evt_pay_usd_l123 lines:124 - ["1000", debit, "1300.00", CAD]125 - ["5500", debit, "50.00", CAD]126 - ["1100", credit, "1350.00", CAD]127128 - name: fx_loss_on_payment_sent129 description: "2000 USD purchase booked at 1.3000 (AP 2600.00); paid at 1.3400 (2680.00) -> FX loss 80.00"130 air:131 events:132 - id: evt_purch_usd133 type: Purchase134 date: 2026-06-10135 amount: {amount: "2000.00", currency: USD}136 tax: {jurisdiction: CA-QC, exempt: true}137 fx: {rate: "1.3000", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-06-10}138 - id: evt_pay_usd_out139 type: PaymentSent140 date: 2026-07-10141 related_event: evt_purch_usd142 amount: {amount: "2000.00", currency: USD}143 fx: {rate: "1.3400", source: "bankofcanada.valet:FXUSDCAD", rate_date: 2026-07-10}144 expected_entries:145 - id: je_evt_purch_usd146 lines:147 - ["5000", debit, "2600.00", CAD]148 - ["2000", credit, "2600.00", CAD]149 - id: je_evt_pay_usd_out150 lines:151 - ["2000", debit, "2600.00", CAD]152 - ["5500", debit, "80.00", CAD]153 - ["1000", credit, "2680.00", CAD]154155 - name: owner_contribution156 description: "Owner injects 10000.00: cash up, equity up"157 air:158 events:159 - id: evt_owner160 type: OwnerContribution161 date: 2026-01-01162 amount: {amount: "10000.00", currency: CAD}163 expected_entries:164 - id: je_evt_owner165 lines:166 - ["1000", debit, "10000.00", CAD]167 - ["3000", credit, "10000.00", CAD]168169 - name: loan_received170 description: "Bank loan 25000.00: cash up, liability up"171 air:172 events:173 - id: evt_loan174 type: LoanReceived175 date: 2026-01-02176 amount: {amount: "25000.00", currency: CAD}177 expected_entries:178 - id: je_evt_loan179 lines:180 - ["1000", debit, "25000.00", CAD]181 - ["2500", credit, "25000.00", CAD]182