activity.models.invoice_reference

Module Contents

Classes

InvoiceReference

A reference pointing to an invoice. References are keys which are used

Schema

Defines the methods that need to be implemented by schemas. Schemas

FeriennetSchema

The default schema for customers without specific bank integrations.

ESRSchema

The default schema for ESR by Postfinance. In it's default form it is

RaiffeisenSchema

Customised ESR for Raiffeisen.

Attributes

KNOWN_SCHEMAS

INVALID_REFERENCE_CHARS_EX

REFERENCE_EX

activity.models.invoice_reference.KNOWN_SCHEMAS: dict[str, type[Schema]][source]
activity.models.invoice_reference.INVALID_REFERENCE_CHARS_EX[source]
activity.models.invoice_reference.REFERENCE_EX[source]
class activity.models.invoice_reference.InvoiceReference[source]

Bases: onegov.core.orm.Base, onegov.core.orm.mixins.TimestampMixin

A reference pointing to an invoice. References are keys which are used outside the application. Usually a code used on an invoice to enter through online-banking.

Each invoice may have multiple references pointing to it. Each refernce is however unique.

There are multiple schemas for references. Each schema generates its own set of references using a Python class and some optional settings given by the user (say a specific bank’s account number).

Each schema may only reference an invoice once.

Though each schema has its own set of references, the references-space is shared between all schemas. In other words, reference ‘foo’ of schema A would conflict with reference ‘foo’ of schema B.

This is because we do not know which schema was used when we encounter a reference.

In reality this should not be a problem as reference schemes provided by banks usually cover a very large space, so multiple schemas are expected to just generate random numbers until one is found that has not been used yet (which should almost always happen on the first try).

property readable: str[source]

Returns the human formatted variant of the reference.

__tablename__ = 'invoice_references'[source]
reference: Column[str][source]
invoice_id: Column[uuid.UUID][source]
invoice: relationship[Invoice][source]
schema: Column[str][source]
bucket: Column[str][source]
__table_args__ = ()[source]
validate_schema(field: str, value: str) str[source]
class activity.models.invoice_reference.Schema(**config: object)[source]

Defines the methods that need to be implemented by schemas. Schemas should generate numbers and be able to format them.

Schemas should never be deleted as we want to be able to display past schemas even if a certain schema is no longer in use.

If a new schema comes along that replaces an old one in an incompatible way, the new schema should get a new name and should be added alongside the old one.

property bucket: str[source]

Generates a unique identifer for the current schema and config.

name: ClassVar[str][source]
classmethod __init_subclass__(name: str, **kwargs: object) None[source]
classmethod render_bucket(schema_name: str, schema_config: dict[str, Any] | None = None) str[source]

Creates a new InvoiceReference for the given invoice.

The returned invoice should have a unique reference, so the chance of ending up with a conflict error later down the line are slim.

If the schema already has a linke to the invoice, we skip the creation.

By default we check our constraints before we write to the database. To be faster in performance critical situation we can however also chose to be ‘optimistic’ and forego those checks. Due to the random nature of schema references this should usually work.

The constraints are set on the database, so they will be enforced either way.

Additionally we can forego the session.flush if we want to.

abstract new() str[source]

Returns a new reference in the most compact way possible.

abstract format(reference: str) str[source]

Turns the reference into something human-readable.

class activity.models.invoice_reference.FeriennetSchema(**config: object)[source]

Bases: Schema

The default schema for customers without specific bank integrations.

The generated reference is entered as a note when conducting the online-banking transaction.

new() str[source]

Returns a new reference in the most compact way possible.

format(reference: str) str[source]

Turns the reference into something human-readable.

extract(text: str | None) str | None[source]

Takes a bunch of text and tries to extract the feriennet-v1 reference from it.

class activity.models.invoice_reference.ESRSchema(**config: object)[source]

Bases: Schema

The default schema for ESR by Postfinance. In it’s default form it is random and requires no configuration.

A ESR reference has 27 characters from 0-9. The first 26 characters can be chosen freely and the last character is the checksum.

Some banks require that references have certain prefixes/suffixes, but Postfinance who defined the ESR standard does not.

new() str[source]

Returns a new reference in the most compact way possible.

checksum(number: str) str[source]

Generates the modulo 10 checksum as required by Postfinance.

format(reference: str) str[source]

Takes an ESR reference and formats it in a human-readable way.

This is mandated as follows by Postfinance:

> Die Referenznummer ist rechtsbündig, in 5er-Blocks und einem > allfälligen Restblock zu platzieren. Vorlaufende Nullen können > unterdrückt werden.

class activity.models.invoice_reference.RaiffeisenSchema(**config: object)[source]

Bases: ESRSchema

Customised ESR for Raiffeisen.

esr_identification_number: str[source]
new() str[source]

Returns a new reference in the most compact way possible.