ferrosoft.apps.emiflow.services.businesscentral package

Adapters for the Microsoft Dynamics 365 Business Central integration.

  • connector posts calculated emissions to the BC connector microservice.

  • rapidstart exports catalog and operation reference data as a gzipped RapidStart XML package that can be imported into a BC company.

Submodules

ferrosoft.apps.emiflow.services.businesscentral.connector module

HTTP client for the Business Central connector microservice.

Calculated transport emissions are POSTed to the BC connector, which relays them into a customer’s Business Central tenant. The JSON payload uses the BC field-name conventions (camelCase); units are flattened to {"value": ..., "unit": ...} shapes by _decimal().

class ferrosoft.apps.emiflow.services.businesscentral.connector.BcConnectorClient[source]

Bases: ABC

Abstract BC connector client. Production singleton is BcConnectorHTTPClient.

classmethod get_instance()[source]

Return the configured production client instance.

Return type:

BcConnectorClient

abstractmethod post_emission(emission, element_emissions, tenant=None)[source]

Forward a chain’s emission result and its per-element breakdown to BC.

class ferrosoft.apps.emiflow.services.businesscentral.connector.BcConnectorHTTPClient(config)[source]

Bases: BcConnectorClient

HTTP implementation of BcConnectorClient.

Uses a long-lived JWT (loaded from Django settings) as the bearer token; the connector identifies tenants by the Ferrosoft tenant UUID embedded in the payload.

class Config(base_url, jwt)[source]

Bases: object

Endpoint URL and bearer token for the connector.

base_url: str
classmethod from_django_settings()[source]

Build a config from BC_CONNECTOR_BASE_URL / BC_CONNECTOR_JWT settings.

jwt: str | None
classmethod get_instance()[source]

Instantiate the client with config loaded from Django settings.

post_emission(emission, element_emissions, tenant=None)[source]

POST one chain’s emissions (plus per-element breakdown) to the connector.

Raises:
exception ferrosoft.apps.emiflow.services.businesscentral.connector.ClientError[source]

Bases: Error

Configuration or request-time failure in the BC connector client.

exception ferrosoft.apps.emiflow.services.businesscentral.connector.Error[source]

Bases: RuntimeError

Base class for BC connector errors.

ferrosoft.apps.emiflow.services.businesscentral.rapidstart module

Export emiflow reference data as a Business Central RapidStart package.

RapidStart is BC’s bulk-import format: a gzipped XML document with one <TableNameList> per BC table, each holding the row data plus field metadata (TableID, PageID, ValidateField, ProcessingOrder, PrimaryKey). The ModelSerializerMeta metaclass registers each subclass with SerializerSwitch so RapidstartExporter can iterate the registered models in dependency order and assemble the complete DataList element.

Numbers in BC have a maximum length (20 chars), so primary keys are derived from the last seven characters of each Ferrosoft UUID via derive_bc_number().

class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.CatalogSerializer[source]

Bases: ModelSerializer

Serializer mapping EmissionsCatalog to the CatalogFER table.

model

alias of EmissionsCatalog

number_prefix: str = 'CAT'
page_id: int = 0
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060577
table_name: str = 'CatalogFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.ClassAttributes(attrs)[source]

Bases: object

Validator for class-attribute presence used by ModelSerializerMeta.

require_all(*required)[source]

Raise unless every named attribute is present in the wrapped dict.

Returns self so calls can be chained when more validators are added later.

Return type:

ClassAttributes

ferrosoft.apps.emiflow.services.businesscentral.rapidstart.Element(tag, text=None, children=None, attrib=None, **extra)[source]

Construct an ElementTree element in one expression.

Convenience wrapper that accepts text and children inline so RapidStart documents read close to the XML they produce.

Return type:

Element

class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.EmitterSerializer[source]

Bases: ModelSerializer

Serializer mapping Emitter to the EmitterFER table.

model

alias of Emitter

number_prefix: str = 'EMT'
page_id: int = 0
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060579
table_name: str = 'EmitterFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.EnergyCarrierSerializer[source]

Bases: ModelSerializer

Serializer mapping EnergyCarrier to the EnergyCarrierFER table.

model

alias of EnergyCarrier

number_prefix: str = 'ENR'
page_id: int = 0
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060578
table_name: str = 'EnergyCarrierFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.MeasurementUnitSerializer[source]

Bases: ModelSerializer

Serializer mapping ferrobase MeasurementUnit to BC Unit of Measure.

get_queryset()[source]

Return the queryset whose rows should be exported.

model

alias of MeasurementUnit

page_id: int = 209
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 204
table_name: str = 'UnitofMeasure'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.ModelSerializer[source]

Bases: object

Base class for a serializer that emits one BC RapidStart table.

Subclasses declare model, table_id, table_name, and page_id as class attributes and implement serialize_fields() to return the per-record XML children. The first record gets full field metadata (ValidateField/ProcessingOrder/PrimaryKey); later records re-use it implicitly. Set primary_key to a list of field names when the table has a composite primary key.

get_all()[source]

Build the <TableNameList> element with one child per queryset row.

Return type:

Element

get_list_element()[source]

Return the empty <TableNameList> shell with table/page metadata.

get_queryset()[source]

Return the queryset whose rows should be exported.

model = None
number_prefix: str = None
page_id: int = None
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = None
table_name: str = None
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.ModelSerializerMeta(name, bases, attrs, **kwargs)[source]

Bases: type

Metaclass that auto-registers each ModelSerializer with the switch.

class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.RapidstartExporter[source]

Bases: object

Assemble and gzip the complete RapidStart DataList package.

Iterates models in dependency order (units → catalog → energy carriers → emitters → operations → operation lines) so that foreign-key targets always precede the rows that reference them in the resulting XML.

get_datalist(package_name, code)[source]

Build the top-level <DataList> element for the package.

Parameters:
  • package_name (str) – Human-readable package name shown in BC.

  • code (str) – RapidStart package code (typically alphanumeric).

Returns:

The fully populated <DataList> element with one table list per registered model.

Return type:

Element

static serialize(data_list)[source]

Serialise data_list to UTF-8 XML and return its gzipped bytes.

mtime=0 keeps the gzip output reproducible so two runs with the same data produce byte-identical packages.

Return type:

bytes

class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.SerializerSwitch[source]

Bases: object

Registry mapping Model classes to their ModelSerializer.

classmethod register(model, serializer)[source]

Register serializer as the serializer for model.

classmethod serialize(model)[source]

Run the registered serializer for model and return its element.

Raises RuntimeError when no serializer is registered.

Return type:

Element

class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.TransportOperationSerializer[source]

Bases: ModelSerializer

Serializer mapping TransportOperation to the TransportOperationFER table.

model

alias of TransportOperation

page_id: int = 0
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060580
table_name: str = 'TransportOperationFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.TreatmentOperationInputLineSerializer[source]

Bases: ModelSerializer

Serializer for TreatmentOperationInputLine rows (composite PK).

get_queryset()[source]

Sort by operation and material so the BC import is deterministic.

model

alias of TreatmentOperationInputLine

page_id: int = 0
primary_key = ['OperationNo', 'MaterialNo']
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060584
table_name: str = 'TreatmentOpInputLineFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.TreatmentOperationOutputLineSerializer[source]

Bases: ModelSerializer

Serializer for TreatmentOperationOutputLine rows (composite PK).

model

alias of TreatmentOperationOutputLine

page_id: int = 0
primary_key = ['OperationNo', 'MaterialNo']
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060583
table_name: str = 'TreatmentOpOutputLineFER'
class ferrosoft.apps.emiflow.services.businesscentral.rapidstart.TreatmentOperationSerializer[source]

Bases: ModelSerializer

Serializer mapping TreatmentOperation to TreatmentOperationFER.

Only certified operations are exported — open operations are still being authored and would mislead downstream BC bookings.

get_queryset()[source]

Limit the export to operations in the CERTIFIED status.

model

alias of TreatmentOperation

page_id: int = 0
serialize_fields(instance)[source]

Return the ordered field elements for a single instance.

Return type:

Iterable[Element]

table_id: int = 73060581
table_name: str = 'TreatmentOperationFER'
ferrosoft.apps.emiflow.services.businesscentral.rapidstart.derive_bc_number(default_prefix)[source]

Return a function that turns a UUID into a BC-friendly No. string.

The returned closure derives a string of the form "{prefix}{LAST_7_HEX_UPPER}"; prefix defaults to default_prefix but each call can override it (e.g. to reuse another model’s prefix when emitting a foreign-key reference).