Skip to content

Operations

Operational workflows.

Entity Relationship Diagram

Operations ERD

Entities

iris.domain.operations.entities

Operations domain entities: PurchaseOrder, Requisition, RequestForQuote, Material, Supplier.

PurchaseOrder

Bases: NamedEntity

A purchase order issued to a supplier from a specific branch.

Represents the formal commitment to buy materials from a Supplier. The monetary breakdown (amount, tax, discount, total) mirrors the structure of SaleOrder; line items are modelled as PurchaseOrderItem instances.

PurchaseOrderItem

A single line item within a purchase order, referencing a material and its pricing.

Requisition

Bases: NamedEntity

An internal request for materials pending review and approval.

Initiates the procurement workflow. is_approved starts as False; approval is recorded via the RequisitionApproved domain event, which sets approved_by and approved_date in a new immutable instance.

RequisitionItem

A single material line within a requisition.

Links a Material and a requested quantity to a parent Requisition. sequence preserves the display order of items in the requisition form.

RequestForQuote

Bases: NamedEntity

A formal request for pricing sent to a supplier.

Issued after a Requisition is approved, targeting a specific Supplier. Triggers the RequestForQuoteIssued domain event. Line items are modelled as RequestForQuoteItem instances.

RequestForQuoteItem

A single material line within a request for quote.

Specifies the Material and quantity being priced. sequence preserves ordering across the items of the parent RequestForQuote.

Material

Bases: NamedEntity

A consumable material or reagent used in laboratory operations.

The materials catalog. material_type classifies the item (e.g. "reagent", "consumable"); sku and catalog_code map to external supplier references. is_active gates whether the material can appear in new RequisitionItem records.

Supplier

Bases: NamedEntity

An external supplier from which materials are purchased.

Stores all contact and fiscal information needed to raise a PurchaseOrder or RequestForQuote. Tax fields support local invoicing requirements; since records the start of the commercial relationship.

Objects

iris.domain.operations.objects

Operations domain value objects (currently empty).

Repositories

iris.domain.operations.repositories

Repository interfaces for the operations domain.

MaterialRepository

Bases: CrudRepository[Material]

CRUD repository for Material entities.

find_active abstractmethod

find_active()

Return all active materials in the catalog.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_active(self) -> Sequence[Material]:
    """Return all active materials in the catalog."""

find_by_type abstractmethod

find_by_type(material_type)

Return all materials of the given type.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_type(self, material_type: str) -> Sequence[Material]:
    """Return all materials of the given type."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

SupplierRepository

Bases: CrudRepository[Supplier]

CRUD repository for Supplier entities.

find_active abstractmethod

find_active()

Return all suppliers with an active relationship.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_active(self) -> Sequence[Supplier]:
    """Return all suppliers with an active relationship."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

RequisitionRepository

Bases: CrudRepository[Requisition]

CRUD repository for Requisition entities.

find_by_requester abstractmethod

find_by_requester(requester_id)

Return all requisitions submitted by the given requester.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_requester(self, requester_id: str) -> Sequence[Requisition]:
    """Return all requisitions submitted by the given requester."""

find_by_approved abstractmethod

find_by_approved(is_approved)

Return all requisitions filtered by approval status.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_approved(self, is_approved: bool) -> Sequence[Requisition]:
    """Return all requisitions filtered by approval status."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

RequestForQuoteRepository

Bases: CrudRepository[RequestForQuote]

CRUD repository for RequestForQuote entities.

find_by_supplier abstractmethod

find_by_supplier(supplier_id)

Return all RFQs sent to the given supplier.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_supplier(self, supplier_id: str) -> Sequence[RequestForQuote]:
    """Return all RFQs sent to the given supplier."""

find_by_date_range abstractmethod

find_by_date_range(start, end)

Return all RFQs with a request_date within [start, end].

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_date_range(self, start: dt.date, end: dt.date) -> Sequence[RequestForQuote]:
    """Return all RFQs with a request_date within [start, end]."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

PurchaseOrderRepository

Bases: CrudRepository[PurchaseOrder]

CRUD repository for PurchaseOrder entities.

find_by_supplier abstractmethod

find_by_supplier(supplier_id)

Return all purchase orders issued to the given supplier.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_supplier(self, supplier_id: str) -> Sequence[PurchaseOrder]:
    """Return all purchase orders issued to the given supplier."""

find_by_branch abstractmethod

find_by_branch(branch_id)

Return all purchase orders associated with the given branch.

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_branch(self, branch_id: str) -> Sequence[PurchaseOrder]:
    """Return all purchase orders associated with the given branch."""

find_by_date_range abstractmethod

find_by_date_range(start, end)

Return all purchase orders with a date within [start, end].

Source code in src/iris/domain/operations/repositories.py
@abstractmethod
def find_by_date_range(self, start: dt.date, end: dt.date) -> Sequence[PurchaseOrder]:
    """Return all purchase orders with a date within [start, end]."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

Events

iris.domain.operations.events

Domain events for the operations bounded context.

MaterialCreated

Emitted when a new material is added to the operations catalog.

MaterialDeactivated

Emitted when a material is deactivated and removed from active use.

SupplierRegistered

Emitted when a new supplier is registered in the system.

SupplierUpdated

Emitted when a supplier's information is updated.

RequisitionCreated

Emitted when a new material requisition is submitted.

RequisitionApproved

Emitted when a material requisition is approved.

RequestForQuoteIssued

Emitted when a request for quote is issued to a supplier.

PurchaseOrderCreated

Emitted when a new purchase order is created and sent to a supplier.

PurchaseOrderReceived

Emitted when materials from a purchase order are received at the laboratory.

Exceptions

iris.domain.operations.exceptions

Exceptions for the operations domain.

OperationsError

Bases: Exception

Base exception for the operations domain.

MaterialNotFoundError

Bases: OperationsError

Raised when a material cannot be found by the given identifier.

SupplierNotFoundError

Bases: OperationsError

Raised when a supplier cannot be found by the given identifier.

RequisitionNotFoundError

Bases: OperationsError

Raised when a requisition cannot be found by the given identifier.

RequisitionAlreadyApprovedError

Bases: OperationsError

Raised when attempting to approve a requisition that is already approved.

PurchaseOrderNotFoundError

Bases: OperationsError

Raised when a purchase order cannot be found by the given identifier.

RequestForQuoteNotFoundError

Bases: OperationsError

Raised when a request for quote cannot be found by the given identifier.