pub struct ProcurementService { /* private fields */ }Implementations§
Source§impl ProcurementService
impl ProcurementService
pub fn new(db_pool: PgPool) -> Self
pub fn with_sink(db_pool: PgPool, sink: Arc<dyn InventoryEventSink>) -> Self
Sourcepub async fn create_route(&self, r: NewRoute) -> Result<Uuid, ProcurementError>
pub async fn create_route(&self, r: NewRoute) -> Result<Uuid, ProcurementError>
Create a route (an ordered rule collection).
The write rides its own transaction re-bound to the caller’s ambient org scope (ADR-0029) — the scope is task-local and a fresh pool transaction carries none of it; the composed decorator’s fill stamps the acting unit on the INSERT. Undecorated (module tests, jobs) the transaction stays plain.
Sourcepub async fn create_rule(
&self,
r: NewRouteRule,
) -> Result<Uuid, ProcurementError>
pub async fn create_rule( &self, r: NewRouteRule, ) -> Result<Uuid, ProcurementError>
Create a procurement rule after the R13-rule destination check (never route INTO a view location). The DB trigger is the backstop for raw writers; this check exists so a service caller gets the typed error instead of a constraint 500.
The pre-check read and the insert ride one transaction re-bound to the caller’s ambient org scope (ADR-0029); undecorated (module tests, jobs) the transaction stays plain.
Sourcepub async fn search_rule(
&self,
demand_location_id: Uuid,
route_ids: Option<Vec<Uuid>>,
) -> Result<Option<RuleRow>, ProcurementError>
pub async fn search_rule( &self, demand_location_id: Uuid, route_ids: Option<Vec<Uuid>>, ) -> Result<Option<RuleRow>, ProcurementError>
_search_rule: the highest-sequence active pull-capable rule covering the demand
location. Public — the confirm engine and later bridges select rules through the same
ordering the scheduler does.
Sourcepub async fn run_pull(
&self,
conn: &mut PgConnection,
rule: &RuleRow,
req: &ProcurementRequest,
) -> Result<Uuid, ProcurementError>
pub async fn run_pull( &self, conn: &mut PgConnection, rule: &RuleRow, req: &ProcurementRequest, ) -> Result<Uuid, ProcurementError>
_run_pull: mint the inbound DRAFT move a selected pull rule prescribes — FROM the
rule’s source (or the operation type’s default source when the rule names none) TO the
rule’s destination, at the requested quantity. The move enters the lifecycle as a draft;
the caller (scheduler or confirm engine) drives it through the pipeline.
Sourcepub async fn run_push(
&self,
conn: &mut PgConnection,
rule: &RuleRow,
upstream_move: &StockMove,
) -> Result<Uuid, ProcurementError>
pub async fn run_push( &self, conn: &mut PgConnection, rule: &RuleRow, upstream_move: &StockMove, ) -> Result<Uuid, ProcurementError>
_run_push: propagate a confirmed move FROM the rule’s source — mint the chained
downstream move (rule source → the upstream’s destination) and link it onto the
upstream’s move_dest_ids. Called by the move engine on _action_confirm for
transparent push rules; manual rules wait for a human.
Sourcepub async fn run_procurement(
&self,
conn: &mut PgConnection,
req: &ProcurementRequest,
) -> Result<Uuid, ProcurementError>
pub async fn run_procurement( &self, conn: &mut PgConnection, req: &ProcurementRequest, ) -> Result<Uuid, ProcurementError>
The procurement-group entry point: resolve the rule for a demand and mint the pull
move. This is the surface a sale-stock confirm engine calls per storable line and a
purchase bridge (_run_buy) attaches to — implemented here, consumed by later passes.
Sourcepub async fn create_orderpoint(
&self,
o: NewOrderpoint,
) -> Result<Uuid, ProcurementError>
pub async fn create_orderpoint( &self, o: NewOrderpoint, ) -> Result<Uuid, ProcurementError>
Create an orderpoint (min/max replenishment rule) — the service half of R6: a duplicate
(item, location) coverage is the typed orderpoint_exists error; the partial unique
index is the DB backstop a raw writer hits instead.
The duplicate-check read and the insert ride one transaction re-bound to the caller’s ambient org scope (ADR-0029); undecorated (module tests, jobs) it stays plain — the composed decorator owns isolation.
Sourcepub async fn compute_orderpoint(
&self,
conn: &mut PgConnection,
op: &OrderpointRow,
) -> Result<OrderpointComputes, ProcurementError>
pub async fn compute_orderpoint( &self, conn: &mut PgConnection, op: &OrderpointRow, ) -> Result<OrderpointComputes, ProcurementError>
The T11 computes for one orderpoint, from the forecast aggregation:
qty_forecast = on_hand + incoming − outgoing and
qty_to_order = max(qty_forecast, item_max_qty) − qty_forecast (floored at zero).
Lead days are the matched rule’s delay; the deadline is today + lead_days.
Sourcepub async fn recompute_orderpoint(
&self,
orderpoint_id: Uuid,
) -> Result<OrderpointComputes, ProcurementError>
pub async fn recompute_orderpoint( &self, orderpoint_id: Uuid, ) -> Result<OrderpointComputes, ProcurementError>
Recompute and persist one orderpoint’s stored computes (the read-model refresh a
replenishment view drives for manual trigger rules — humans order, the computes
recommend).
The orderpoint read rides the caller’s ambient org scope (ADR-0029): under the composed shape the decorator’s fence bounds it and the forecast/stamp writes ride the same bound transaction; undecorated (module tests, jobs) it is plain.
Sourcepub async fn reorder_one(
&self,
conn: &mut PgConnection,
op: &OrderpointRow,
) -> Result<Option<ReorderOutcome>, ProcurementError>
pub async fn reorder_one( &self, conn: &mut PgConnection, op: &OrderpointRow, ) -> Result<Option<ReorderOutcome>, ProcurementError>
The reorder rung (_run_orderpoints, §7 task 1) for ONE claimed orderpoint: refresh
the T11 computes, and when qty_forecast < item_min_qty, mint the replenishment move of
qty_to_order (a positive qty_to_order_manual overrides the computed figure) and
publish OrderpointTriggered. Returns the outcome when the rule fired.
Runs inside the caller’s transaction — the scheduler commits per batch and emits the event after that commit (an event never precedes its durable record).
Sourcepub fn emit_orderpoint_triggered(&self, o: &ReorderOutcome)
pub fn emit_orderpoint_triggered(&self, o: &ReorderOutcome)
Publish the reorder event (after the batch commit). Kept separate from
Self::reorder_one so the transaction boundary stays explicit.
Sourcepub async fn assign_one(
&self,
conn: &mut PgConnection,
pipeline: &dyn MovePipeline,
move_id: Uuid,
) -> Result<MoveState, MovePipelineError>
pub async fn assign_one( &self, conn: &mut PgConnection, pipeline: &dyn MovePipeline, move_id: Uuid, ) -> Result<MoveState, MovePipelineError>
_run_scheduler_assign for ONE claimed move: hand it to the move engine’s assign verb
on the caller’s connection. The sweep (claiming, ordering, accounting) lives in the
scheduler job; this is the per-move step so the engine contract is exercisable in
isolation.
Sourcepub async fn housekeep_quants(
&self,
conn: &mut PgConnection,
limit: i64,
) -> Result<u64, Error>
pub async fn housekeep_quants( &self, conn: &mut PgConnection, limit: i64, ) -> Result<u64, Error>
The quant vacuum tail (§7 task 3) — see the repository for the R21-shaped predicate. Returns the raw driver error: this is a pure delegation with no domain decision, and the scheduler (its only caller) reports infrastructure failures as-is.
pub fn sink(&self) -> Arc<dyn InventoryEventSink> ⓘ
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for ProcurementService
impl !UnwindSafe for ProcurementService
impl Freeze for ProcurementService
impl Send for ProcurementService
impl Sync for ProcurementService
impl Unpin for ProcurementService
impl UnsafeUnpin for ProcurementService
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more