dodil/erp-brick-sales-order

DODIL ERP brick: sales order

src/brick_sales_order/domain/number_series.py

"""The counter behind order numbers: state, not a setting. A number is claimed once and never reused."""
from dataclasses import dataclass, field

from brick_sales_order.domain.errors import RuleBroken


@dataclass
class NumberSeries:
    series_id: str
    high_water_mark: int = 0
    events: list = field(default_factory=list, repr=False)

    def claim(self) -> int:
        """The next number. Saved at the version it was loaded at, so two claims racing cannot get the same one."""
        self.high_water_mark += 1
        return self.high_water_mark

    def raise_to(self, mark: int) -> None:
        """Move the mark UP (a migration continues the series after the numbers it carried); never down."""
        if mark < self.high_water_mark:
            raise RuleBroken(f"the series {self.series_id} is already at {self.high_water_mark}: a number is never reused")
        self.high_water_mark = mark