csb43.aeb43
¶
Parsing and validation utilites for the Spanish standard norm 43 by the “Consejo Superior Bancario” (CSB) / “Asociación Española de Banca” (AEB) for storing bank account transactions.
[es] Herramientas para leer y validar datos almacenados siguiendo la norma 43 del Consejo Superior Bancario (CSB) / Asociación Española de Banca (CSB).
References¶
@techreport{n43_2012,
author = {Varios},
institution = {Confederación Española de Cajas de Ahorros},
month = 6,
number = {Serie normas y procedimientos bancarios nº 43},
publisher = {Asociación Española de Banca},
title = {{Información normalizada de cuenta corriente (SEPA)}},
year = {2012}
}
- class csb43.aeb43.Account(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, bank_code: String = String(field_id=<Field.BANK_CODE: 1>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), branch_code: String = String(field_id=<Field.BRANCH_CODE: 2>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), account_number: String = String(field_id=<Field.ACCOUNT_NUMBER: 3>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), initial_date: Date = Date(field_id=<Field.INITIAL_DATE: 4>, factory=<built-in method today of type object>), final_date: Date = Date(field_id=<Field.FINAL_DATE: 5>, factory=<built-in method today of type object>), initial_balance: Money = Money(value_id=<Field.INITIAL_BALANCE: 7>, mode_id=<Field.EXPENSE_OR_INCOME: 6>, default_mode=b'2', padding=b'0', non_negative=False, factory=<class 'decimal.Decimal'>), currency: Currency = Currency(field_id=<Field.CURRENCY_CODE: 8>, factory=<function euro_currency>), information_mode: InformationModeField = InformationModeField(field_id=<Field.INFORMATION_MODE: 9>, factory=<function InformationModeField.<lambda>>), short_name: String = String(field_id=<Field.SHORT_NAME: 10>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>), padding: String = String(field_id=<Field.PADDING: 11>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>), transactions: NestedCollection[Transaction] = None, summary: SummaryField[ClosingAccount] = None)¶
COD 11
Account record
[es] Registro de cabecera de cuenta
See [n43_2012] Appendix 1, section 1.1
Fields¶
- bank_codeString[4]
bank code / clave de la entidad
- branch_codeString[4]
branch code / clave de oficina
- account_numberString[10]
account number / número de cuenta
- initial_dateDate
initial date / fecha inicial
- final_dateDate
final date / fecha final
- initial_balanceMoney[12.2]
initial balance / importe saldo inicial
- currencyCurrency
currency / divisa
- information_modeInteger[1..3]
information mode / modalidad de información
- short_nameString[26]
short name / nombre abreviado
- paddingString[3]
padding / libre uso
- accepts_nested_codes(record: bytes) bool ¶
return True if the record accepts this nested record
- property account_control_key¶
get the account control key (CC)
- append(raw: bytes)¶
append a bytes record to the collection of dependent records
- describe(indent: str = '') str ¶
return a textual summary
- is_closed() bool ¶
return True if this account has a final summary
- to_dict(translated=True)¶
return fields as a dict of typed values
- validate_summary(summary: ClosingAccount)¶
validate summary record against the extant nested records
- class csb43.aeb43.Batch(context: Aeb43Context | None = None, accounts: NestedCollection[Account] | None = None, summary: SummaryField[EndOfFile] | None = None)¶
A batch of transactions grouped by accounts
Fields¶
- accountslist[Account]
accounts / cuentas
- summaryEndOfFile
summary record / registro de recuento
- accepts_nested_codes(record: bytes)¶
return True if the record accepts this nested record
- append(raw: bytes)¶
append a bytes record to the collection of dependent records
- describe(indent: str = '')¶
user friendly summary
- dump() bytes ¶
dump content to bytes
- is_closed()¶
return True if the container is closed
- to_dict(translated=True)¶
return content as a dictionary
- class csb43.aeb43.ClosingAccount(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, _validated: bool = False, bank_code: String = String(field_id=<Field.BANK_CODE: 1>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), branch_code: String = String(field_id=<Field.BRANCH_CODE: 2>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), account_number: String = String(field_id=<Field.ACCOUNT_NUMBER: 3>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), expense_entries: Integer = Integer(field_id=<Field.EXPENSE_ENTRIES: 4>, factory=<class 'int'>), expense: Money = Money(value_id=<Field.EXPENSE_AMOUNT: 5>, mode_id=None, default_mode=b'2', padding=b'0', non_negative=True, factory=<class 'decimal.Decimal'>), income_entries: Integer = Integer(field_id=<Field.INCOME_ENTRIES: 6>, factory=<class 'int'>), income: Money = Money(value_id=<Field.INCOME_AMOUNT: 7>, mode_id=None, default_mode=b'2', padding=b'0', non_negative=True, factory=<class 'decimal.Decimal'>), final_balance: Money = Money(value_id=<Field.FINAL_BALANCE: 9>, mode_id=<Field.FINAL_BALANCE_CODE: 8>, default_mode=b'2', padding=b'0', non_negative=False, factory=<class 'decimal.Decimal'>), currency: Currency = Currency(field_id=<Field.CURRENCY_CODE: 10>, factory=<function euro_currency>), padding: String = String(field_id=<Field.PADDING: 11>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>))¶
COD 33
Closing account record
[es] Registro de asiento de cuentas
See [n43_2012] Appendix 1, section 1.5
Fields¶
- bank_codeString[4]
bank code / clave de la entidad
- branch_codeString[4]
branch code / clave de oficina origen
- account_numberString[10]
account number / número de cuenta
- expense_entriesInteger
expense entries / número de apuntes en el Debe
- expenseMoney[12.2]
expense / total importes en el Debe
- income_entriesInteger
income entries / número de apuntes en el Haber
- incomeMoney[12.2]
income / total importes en el Haber
- paddingString[4]
padding / libre uso
- class csb43.aeb43.EndOfFile(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, _validated: bool = False, total_records: Integer = Integer(field_id=<Field.TOTAL_RECORDS: 1>, factory=<class 'int'>), padding: String = String(field_id=<Field.PADDING: 2>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>))¶
COD 88
End of file record
[es] Registro de fin de fichero
See [n43_2012] Appendix 1, section 1.6
Fields¶
- total_recordsInteger
total number of records / número total de registros
- paddingString[54]
padding / libre uso
- class csb43.aeb43.Exchange(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, original_currency: currency.Currency = Currency(field_id=<Field.CURRENCY: 1>, factory=<function euro_currency>), amount: money.Money = Money(value_id=<Field.AMOUNT: 2>, mode_id=None, default_mode=b'2', padding=b'0', non_negative=False, factory=<class 'decimal.Decimal'>), padding: string.String = String(field_id=<Field.PADDING: 3>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>))¶
COD 24-01
Exchange record
[es] Registro complementario de información de equivalencia de importe del apunte.
See [n43_2012] Appendix 1, section 1.4
Fields¶
- original_currencyCurrency
original currency / divisa origen del movimiento
- amountMoney[12.2]
transaction amount in the original currency / import en divisa origen
- paddingString[59]
unused space in record / libre
- class csb43.aeb43.Item(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, record_code: Integer = Integer(field_id=<Field.RECORD: 1>, factory=<function default_record_code>), item1: String = String(field_id=<Field.ITEM1: 2>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>), item2: String = String(field_id=<Field.ITEM2: 3>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>))¶
COD 23
Complementary item / [es] Registro complementario de concepto.
For SEPA normalization using item records, see:
csb43.aeb43.sepa_debit
csb43.aeb43.sepa_transfer
See [n43_2012] Appendix 1, section 1.3
Fields¶
- record_codeInteger[1..5]
sequence code for complementary item record / [es] código de registro
- item1String[38]
item #1 / [es] concepto 1
- item2String[38]
item #2 / [es] concepto 2
- class csb43.aeb43.SepaDebit(item1: NestedRecord[SepaDebitItem1], item2: NestedRecord[SepaDebitItem2], item3: NestedRecord[SepaDebitItem3], item4: NestedRecord[SepaDebitItem4], item5: NestedRecord[SepaDebitItem5], context: Aeb43Context | None = None)¶
SEPA direct debit
Set of five 80-bytes records
See [n43_2012] Appendix 4, section 2
- property creditor_id¶
creditor id [AT-02] / identificador del acreedor [AT-02]
- property creditor_name¶
creditor name [AT-03] / nombre del acreedor [AT-03]
- property creditor_reference¶
creditor reference [AT-10] / referencia del acreedor [AT-10]
- property debtor_name¶
debtor name [AT-14] / último deudor [AT-15]
- property mandate_reference¶
mandate reference [AT-01] / referencia única del mandato [AT-01]
- classmethod new(*records: bytes | bytearray, context: Aeb43Context | None = None) SepaDebit ¶
return an empty/default SEPA direct debit object
- property scheme_code¶
scheme code [AT-20] / código de esquema [AT-20]
- to_dict(translated: bool = True)¶
return dict with field values
- class csb43.aeb43.SepaTransfer(item1: NestedRecord[SepaTransferItem1], item2: NestedRecord[SepaTransferItem2], item3: NestedRecord[SepaDebitItem3], item4: NestedRecord[SepaDebitItem4], item5: NestedRecord[SepaTransferItem5], context: Aeb43Context | None = None)¶
SEPA transfer
Set of five 80-bytes records
See [n43_2012] Appendix 4, section 1
- property additional_info¶
additional info / campo de libre uso para información del beneficiario
- classmethod new(*records: bytes | bytearray, context: Aeb43Context | None = None) SepaTransfer ¶
return an empty/default SEPA transfer object
- property originator_code¶
originator code [AT-02] / código del ordenante [AT-02]
- property originator_name¶
originator name [AT-02] / nombre del ordenante [AT-02]
- property originator_reference¶
originator reference [AT-41] / referencia del ordenante [AT-41]
- property originator_reference_party¶
originator reference party [AT-08] & nombre de ‘por cuenta de’ [AT-08]
- to_dict(translated: bool = True)¶
return dict with field values
- class csb43.aeb43.Transaction(context: Aeb43Context | None = None, raw: dataclasses.InitVar[AnyBytes | None] = None, padding: String = String(field_id=<Field.PADDING: 1>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>), branch_code: String = BranchCode(field_id=<Field.BRANCH_CODE: 2>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), document_number: String = String(field_id=<Field.DOCUMENT_NUMBER: 9>, padding=b'0', trim=<Trim.BOTH_BLANK: 10>, align_left=False, mode=mappingproxy({}), factory=<class 'str'>), transaction_date: Date = Date(field_id=<Field.TRANSACTION_DATE: 3>, factory=<built-in method today of type object>), value_date: Date = Date(field_id=<Field.VALUE_DATE: 4>, factory=<built-in method today of type object>), shared_item: Integer = Integer(field_id=<Field.SHARED_ITEM: 5>, factory=<class 'int'>), own_item: Integer = Integer(field_id=<Field.OWN_ITEM: 6>, factory=<class 'int'>), amount: Money = Money(value_id=<Field.AMOUNT: 8>, mode_id=<Field.EXPENSE_OR_INCOME: 7>, default_mode=b'2', padding=b'0', non_negative=False, factory=<class 'decimal.Decimal'>), reference1: String = String(field_id=<Field.REFERENCE1: 10>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({<InformationMode.THIRD: 3>: {'padding': b'0', 'trim': <Trim.BOTH_BLANK: 10>, 'align_left': False}}), factory=<class 'str'>), reference2: String = String(field_id=<Field.REFERENCE2: 11>, padding=b' ', trim=<Trim.BOTH: 15>, align_left=True, mode=mappingproxy({}), factory=<class 'str'>), exchange: NestedRecord[Exchange] = None, optional_items: NestedCollection[Item] = None, sepa_transfer: SepaTransferField = None, sepa_debit: SepaDebitField = None)¶
COD 22
Main transaction record
[es] Registro principal de movimientos
See [n43_2012] Appendix 1, section 1.2
Fields¶
- paddingString[4]
padding / libre uso
- branch_codeString[4]
branch code / clave de oficina origen
- document_numberString[10]
document number / número de documento
- transaction_dateDate
date of transaction / fecha de operación
- value_dateDate
effective date / fecha de valor
- shared_itemInteger[0..99]
shared item / concepto común
- own_itemInteger[0..999]
own item / concepto propio
- amountMoney[12.2]
transaction amont / importe
- reference1String[12]
reference 1 / referencia 1
- reference2String[16]
reference 2 / referencia 2
- accepts_nested_codes(record: bytes) bool ¶
return True if the record accepts this nested record
- append(raw: bytes)¶
append a bytes record to the collection of dependent records
- iter_optional_items() Iterator[str] ¶
iterate optional items fields
- to_dict(translated=True)¶
return fields as a dict of typed values
- to_sepa() None ¶
convert complementary items to a SEPA debit/transfer object
- csb43.aeb43.get_current_context() Aeb43Context ¶
get the context for the current scope
- csb43.aeb43.read_batch(stream: IO[bytes], context: Aeb43Context | None = None) Batch ¶
read a batch of accounts from a binary stream
Context – [en] Contexto¶
Context object for reading AEB43 records
- class csb43.aeb43.record.context.Aeb43Context(strict: bool = False, silent: bool = False, encoding: str = 'latin1', sepa: bool = True, year_first: bool = True, cache_fields: bool = True, decimals: int = 2, information_mode: InformationMode = InformationMode.THIRD)¶
settings for encoded AEB43 records
Fields¶
- strictbool
raise exception when a validation fails if strict=True
- silentbool
if silent=True, validation warnings are not emitted
- encodingstr
string encoding use when transforming from binary files
- sepabool
when sepa=True, transactions trie to interpret optional items as SEPA transfer or direct debits
- cache_fieldsbool
cache values from setters/getters
- decimalint
number of decimal places used in money amounts
- information_modeInformationMode
information mode to use in nested records. Accounts will change this value.
- emit_validation_error(message: str) None ¶
raise ValidationException if strict or emits a ValidationWarning if not strict and not silent
- emit_validation_warning(message: str) None ¶
emit a warning
- error_message(message: str) str ¶
get a new error message in a batch context
- new_validation_error(message: str) ValidationException ¶
create a new validation error with message
Context line is added to the Exception
- scope(**kwargs)¶
create a scope for this context
- to_string(value) str ¶
convert value to string
- class csb43.aeb43.record.context.BatchContext(line: int | None = None)¶
line context
- scope()¶
create a scope for this context
- class csb43.aeb43.record.context.Contextual(*args, **kwargs)¶
protocol for any class that has a context property
- class csb43.aeb43.record.context.ContextualMixin¶
provides a method that always returns a context
- get_context() Aeb43Context ¶
get the context for the current scope
- class csb43.aeb43.record.context.InformationMode(value)¶
information mode
[es] modalidad de información
See [n43_2012] Appendix 1
- csb43.aeb43.record.context.check_compatible_encoding(encoding: str) bool ¶
returns True if ‘encoding’ is compatible with n43 records
- csb43.aeb43.record.context.get_batch_context() BatchContext ¶
get the context for the current scope
- csb43.aeb43.record.context.get_current_context() Aeb43Context ¶
get the context for the current scope