Emiflow Package Overview¶
See the full API at ferrosoft.apps.emiflow package.
Modules¶
appsDjango application configuration for the emiflow app.
Wires up settings-menu entries (under the Emissions category) and hooks emiflow updater into ferrobase_update management command.
filterdjango-filterFilterSetdefinitions for emiflow list views.Each
FilterSethere backs a corresponding list view: it parses the request query string, validates it against the model fields declared inMeta, and produces a filtered queryset plus a bound form that templates render as the filter sidebar. Custommethodfilters support filtering by related-object primary key, by membership in a PostgreSQL array column, and byINclauses for multi-select widgets.metricsPrometheus metrics for emiflow tonnage tracking.
Exposes per-tenant tonnage usage and per-organisation tonnage limits so subscription overages can be alerted on and dashboarded.
tablesdjango-tables2table classes for emiflow list and detail views.Each table maps a model (or a flat record produced by an aggregation) to the columns shown in templates, with column types drawn from
ferrosoft.apps.ferrobase.tablesfor shared rendering behaviour (number formatting, action buttons, linkified cells). Tables ending inCRUDTableadd an actions column with edit/delete buttons whose delete URL each subclass resolves inget_delete_action_url.urlsURL configuration for the emiflow application.
Exposes the dashboard index, per-domain CRUD URL bundles imported from
ferrosoft.apps.emiflow.views, ad-hoc views for emission intensity, file import, reporting, treatment-operation allocation, and the settings pages, plus the DRF REST API mounted atapi/viaferrosoft.apps.emiflow.api.router.router. The app namespace isemiflow.widgetsCustom Django form widgets used by emiflow forms and tables.
Subpackages¶
emiflow.api¶
Detail page: ferrosoft.apps.emiflow.api package.
emiflow.catalog¶
Detail page: ferrosoft.apps.emiflow.catalog package.
conversionImport utilities for catalog files.
database
emiflow.dataimport¶
Detail page: ferrosoft.apps.emiflow.dataimport package.
emiflow.forms¶
Detail page: ferrosoft.apps.emiflow.forms package.
emiflow.management¶
Detail page: ferrosoft.apps.emiflow.management package.
emiflow.models¶
ORM models for the emiflow application.
The package is split into one module per bounded sub-domain:
booking— emission booking records and lifecycle categories (the immutable journal of calculated emissions).catalog— reference data for emission factors, energy carriers, emitters, and the catalogs they belong to.dataimport— staging tables for bulk transport import.intensity—EmissionIntensityshared by transport operations, treatment operations, and emitters.operation— transport operations (the activity definition reused across chain elements).reporting— report definitions and report templates.settings— per-tenant emiflow and Business Central settings.signals— post-save / post-delete hooks that keep cross-cutting state (allocation, intensity ownership) consistent.tegos— adapters for inbound data from the TEGOS waste-management ERP.transport— transport chains, their elements, and freight items.treatment— treatments, treatment operations, and their input/output lines.
Star-imports below flatten the public names into the package namespace
so callers can from ferrosoft.apps.emiflow.models import Treatment
without knowing which sub-module a model lives in.
Detail page: ferrosoft.apps.emiflow.models package.
bookingEmission booking records and lifecycle categories.
This module defines the immutable journal of calculated emissions:
EmissionBookingRecord— one row per(lifecycle category, emitting entity, material)triple. Fields are denormalised (material arrays, partner names) so reports can query a single table without joining live operational data.LifecycleCategory— user-defined categories plus the four predefined ones (treatment, incoming/outgoing transport, drop shipment) enumerated inPredefinedLCC.LCCValue— abstract base for manually entered per-category emission values that subclasses attach to transports or treatments.
The
EmissionBookingRecordQuerySetexposes the aggregations used by the reporting pipeline (totals by entity, by material, by lifecycle category) — all keyed off the denormalised columns so they remain valid even after the originating operation has changed.catalogReference catalog: emitters, energy carriers, and their emission factors.
A
EmissionsCatalogis a published bundle of emission data (e.g. the GLEC public extract) with copyright and licence information. Each catalog containsEmitter(vehicles or hub equipment),EnergyCarrier, andEmissionFactor. Models share the shape of the upstreamemiflow.jsonJSON schema so updates can be imported in bulk.dataimportStaging models for bulk transport-chain imports.
Rows here represent one input line that the
ferrosoft.apps.emiflow.dataimportservices then turn into realTransportChainrecords.SimpleImportLineandMultiLineImportLinediffer in whether one row maps to a whole transport chain or to one element of a multi-hop chain;MultiLineBookingRecordtracks which chains a given import job produced so it can post (or roll back) emissions atomically.intensityEmission intensity values shared across transport ops, treatment ops, and emitters.
An
EmissionIntensityis the calculated gCO2e per tkm (or gCO2e per t for treatments) figure with all of the input variables it was computed from. Theowner_type+owner_idpair forms a weak polymorphic reference so the same intensity row can belong to any of the three intensity-capable model classes; cleanup is handled by the post-delete signals inferrosoft.apps.emiflow.models.signals.operationTransport-operation model and its operation-type enum.
A
TransportOperationis the activity definition (emitter + energy carrier + activity type) that is reused across one or more transport-chain elements. It owns anEmissionIntensityonce calculated.reportingModels for emission reports and the templates that render them.
A
Reportcaptures the user’s selection (type, filter query string, proportional-emission method); aReportTemplatecaptures the visual chrome (logo, preamble, epilogue) reused across generated documents. Logos are inlined as base64 so the rendered HTML can be turned into PDF by WeasyPrint without external fetches.settingsPer-tenant emiflow configuration models.
Settingsis a singleton (created lazily on first read) that holds references to storage directories and the user-defined emissions catalog;TransportChainDefaultskeeps default transport-chain attributes per vehicle type;BusinessCentralSettingsholds OAuth credentials for the Dynamics 365 Business Central integration.signalsCross-model lifecycle hooks for emiflow.
Two concerns are wired up here:
Whenever a treatment-operation output line is inserted or removed, the parent operation’s allocation is recomputed (no-op under manual allocation).
Whenever an entity that owns an
EmissionIntensity(transport operation, treatment operation, or emitter) is deleted, the matching intensity row is removed. The intensity table uses a weak(owner_type, owner_id)reference rather than a real foreign key, so this cascade must be driven explicitly from signals.
The module is loaded via the wildcard import in
ferrosoft.apps.emiflow.models.__init__, which is what registers these receivers at app startup.tegosIn-memory value objects used by the TEGOS waste-management ERP adapter.
These types are not Django models — they carry data parsed out of TEGOS order documents while transport chains and freight items are being constructed. They live next to the persistent models because they share domain vocabulary (posting types, materials, weights).
transportTransport-chain domain models.
A
TransportChainis one consignment from consignor to consignee broken into orderedTransportChainElement(TCE) hops. Each TCE points at a reusableTransportOperation(the activity definition) and may carry geo-points for shortest-feasible or great- circle distance calculations. The chain’s freight is described byFreightItemrows (material + weight). Custom per-lifecycle emissions are attached viaTransportLCCValue.treatmentTreatment and treatment-operation domain models.
A
TreatmentOperationis the recipe: what materials go in, what comes out, which emitter and energy carrier are involved, and how emissions should be allocated to the outputs (by weight or manually). ATreatmentis a specific application of that recipe on a booking date, with its own input/output lines that can deviate from the operation defaults. Operations are certified before they can be referenced; certifying enforces that emission intensity is set and output allocations sum to 100 %.
emiflow.services¶
Service layer for the emiflow application.
This package holds the fat services / thin views business logic for emission calculation, reporting, integration, and supporting concerns:
builder— fluent builders that composeTransportChains and their related rows.businesscentral— adapters for the Microsoft Dynamics 365 Business Central connector.emissions— transport-chain emission calculator and booking service.geographic— strategy for resolving activity distance by distance type.pcf— product carbon footprint roll-up across all chains carrying a material.reporting— document generators that turn booking records into renderable reports.session— per-request storage of the current transport chain in the user session.tonnage— per-tenant / per-organisation tonnage queries used for subscription accounting.treatment— treatment emission calculator and booking service.update— periodic update hooks that seed predefined lifecycle categories per tenant.vehicle— heuristic that guesses aVehicleTypefrom freight weight.visitor— visitor implementations executed againstTransportChainwalks (debug printer, geocoding/routing).
Detail page: ferrosoft.apps.emiflow.services package.
builderFluent builders for assembling transport chains and related rows.
Each
ModelBuildersubclass wraps a Django model instance and exposes chainable setter methods so that complex transport chains can be constructed declaratively. Builders compose viaBuilderOfBuilders(a chain holds builders for its elements and freight items), and can eithersave()rows one-by-one or defer everything into aBulkCreatorfor one bulk upsert per model class.emissionsTransport-chain emission calculation and booking.
This module is the heart of the transport-side emiflow pipeline:
TransportChainCalculatorwalks a chain’s elements, looks up each operation’s emission intensity, and produces per-element and per-chain results (transport activity, distance, emissions for the operation and energy provision categories).EmissionIntensityCalculatorderives a new emission intensity from raw inputs (factor, fuel quantity, mass, distance), performing unit normalisation so callers can supply values in any supported unit.TransportBookingServiceposts a chain: it geocodes points, computes emissions, denormalises everything intoEmissionBookingRecordrows (one per chain + one perTransportLCCValue), and flips the chain status toPOSTED.
ISO 14083 terminology is used throughout: TCE = Transport Chain Element, transport activity = mass × distance (
tkm), intensity = emission / activity.geographicStrategy that resolves activity distance from a TCE’s distance type.
For actual distance the user-entered value is treated as authoritative. For great-circle (GCD) and shortest-feasible (SFD) distances the configured router computes the distance between origin and destination geo-points. Results are normalised to kilometres.
pcfProduct Carbon Footprint (PCF) calculation across all chains for a material.
The
ProductCarbonFootprintServiceaggregates transport emissions for everyTransportChainthat carries a givenMaterial, normalises units across chains, and reports the emission-per-tonne intensity inkgCO2e.reportingDocument generators that turn booking records into renderable reports.
Each
DocumentGeneratorsubclass binds aReport(and its filtered queryset of booking records) to a list ofDocumentOutputobjects. The basegenerate()renders each output’s template into HTML, andprepare_report_models()persists the rendered HTML as short-livedStoredFile-backed reports that can later be turned into PDF by the upstream reporting service.DocumentGeneratorRegistrymapsReportTypevalues to the matching generator class.sessionPer-user-session storage of the current transport chain.
When the user is mid-way through editing a transport chain across multiple views, the chain’s primary key is stashed in the Django session so subsequent views can resume without it being passed through every URL. All helpers degrade silently when the request has no session (e.g. during management commands or unit tests).
tonnageTonnage accounting for subscription billing.
Customers are billed on the cumulative weight of (non-simulation) emission bookings. This module exposes two query paths:
A direct database aggregate per tenant (
TonnageService.get_summary()) used at startup to seed the Prometheus counter and on demand for reconciliation. Expensive — it opens a connection to every active tenant database.A cheap VictoriaMetrics query (
TonnageServiceVictoria.get_org_stats()) that returns the rolling 4-week tonnage and configured limit per organisation from the metrics store.
treatmentEmission calculation and booking for treatments.
TreatmentEmissionCalculatormultiplies the treatment’s output mass by the operation’s emission intensity (for both operation and energy provision categories) to derive the total emission.TreatmentBookingServicethen splits that total across output lines using each line’sallocated_fractionand creates oneEmissionBookingRecordper output and per attachedTreatmentLCCValue.updateEmiflow hooks into the ferrobase update pipeline.
The ferrobase
ferrobase_updatemanagement command iterates over registered global and per-tenant updaters at deploy time. This module registers an updater that ensures the four predefinedLifecycleCategoryrows exist in every database — both the shared catalog database (global pass) and each tenant database (tenant pass).vehicleHeuristic mapping from freight weight to a likely
VehicleType.Used during bulk import when the source data does not specify the vehicle type explicitly. The thresholds are hard-coded approximations and will likely become tenant-configurable.
visitorVisitor implementations driven by
TransportChain.accept().Visitors here perform actions over an entire chain’s structure (elements, freight items, geo-points).
DebuggerVisitordumps every field to stdout for development;GeocodingRoutingVisitorpopulates missing coordinates and activity distances before emission calculation.
emiflow.views¶
Detail page: ferrosoft.apps.emiflow.views package.