#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
pub use use_ach as ach;
pub use use_amount as amount;
pub use use_bai2 as bai2;
pub use use_bank_account as bank_account;
pub use use_bic as bic;
pub use use_currency as currency;
pub use use_iban as iban;
pub use use_invoice as invoice;
pub use use_ledger as ledger;
pub use use_money as money;
pub use use_payment as payment;
pub use use_receipt as receipt;
pub use use_reconciliation as reconciliation;
pub use use_routing_number as routing_number;
pub use use_transaction as transaction;
pub mod prelude {
pub use crate::ach::{
AchAccountType, AchAddendaIndicator, AchCompanyId, AchEntry, AchEntryDirection, AchError,
AchIndividualId, AchStandardEntryClass, AchTraceNumber, AchTransactionCode,
};
pub use crate::amount::{Amount, AmountError};
pub use crate::bai2::{
AccountIdentifierRecord, Bai2Error, FileHeaderRecord, FileTrailerRecord, FundsTypeCode,
NormalizedTransaction, RawRecord, RecordCode, TransactionDetailRecord, TransactionTypeCode,
};
pub use crate::bank_account::{
AccountHolderName, AccountNumber, AccountType, BankAccount, MaskedAccountNumber,
};
pub use crate::bic::{Bic, BicError};
pub use crate::currency::{AUD, CAD, CurrencyCode, CurrencyCodeError, EUR, GBP, JPY, USD};
pub use crate::iban::{Iban, IbanError};
pub use crate::invoice::{
BalanceDue, DueDate, Invoice, InvoiceLine, InvoiceNumber, InvoiceStatus, Subtotal, Total,
};
pub use crate::ledger::{Balance, DebitCredit, JournalEntry, LedgerEntry, Posting};
pub use crate::money::{CurrencyMismatch, Money, MoneyError};
pub use crate::payment::{
Payment, PaymentDirection, PaymentMethod, PaymentReference, PaymentStatus,
};
pub use crate::receipt::{
AppliedAmount, Receipt, ReceiptNumber, ReceiptStatus, ReceivedAt, UnappliedAmount,
};
pub use crate::reconciliation::{
ExceptionReason, MatchConfidence, MatchScore, MatchStatus, ReconciliationCandidate,
ReconciliationResult,
};
pub use crate::routing_number::{RoutingNumber, RoutingNumberError};
pub use crate::transaction::{
EffectiveDate, PostedDate, Transaction, TransactionDate, TransactionDirection,
TransactionId, TransactionStatus,
};
}
#[cfg(test)]
mod tests {
use super::{ach, amount, bai2, bic, currency, iban, money, reconciliation, routing_number};
#[test]
fn facade_exposes_composable_finance_primitives() -> Result<(), Box<dyn std::error::Error>> {
let usd = currency::CurrencyCode::new("USD")?;
let cents = amount::Amount::from_minor_units(12_345, 2)?;
let invoice_total = money::Money::new(cents, usd);
let routing = routing_number::RoutingNumber::new("021000021")?;
assert_eq!(routing.as_str(), "021000021");
let iban = iban::Iban::new("GB82 WEST 1234 5698 7654 32")?;
let bic = bic::Bic::new("DEUTDEFF500")?;
let ach_entry = ach::AchEntry::new(
ach::AchStandardEntryClass::Ppd,
ach::AchTransactionCode::CheckingCredit,
ach::AchTraceNumber::new("123456780000001")?,
ach::AchCompanyId::new("1234567890")?,
ach::AchIndividualId::new("EMPLOYEE001")?,
);
let records =
bai2::parse_logical_records("16,475,12345,Z,bank-ref,customer-ref,invoice payment/\n")?;
let detail = bai2::TransactionDetailRecord::try_from(&records[0])?;
let normalized = bai2::NormalizedTransaction::from_detail(&detail)?;
let candidate = reconciliation::ReconciliationCandidate::new(
"bank-ref",
"invoice-1001",
amount::Amount::zero(2)?,
reconciliation::MatchScore::exact(),
)?;
assert_eq!(invoice_total.currency().as_str(), "USD");
assert_eq!(iban.country_code(), "GB");
assert_eq!(bic.country_code(), "DE");
assert_eq!(
ach_entry.transaction_code().direction(),
ach::AchEntryDirection::Credit
);
assert_eq!(normalized.amount().minor_units(), 12_345);
assert_eq!(candidate.score(), reconciliation::MatchScore::exact());
Ok(())
}
}