Skip to main content

backbone_inventory/
lib.rs

1//! Inventory Module
2//!
3//! Generated by metaphor-schema. Enhanced with runtime implementations.
4//!
5//! This module provides:
6//! - Domain entities and repositories
7//! - Application services
8//! - HTTP and gRPC handlers
9//! - Route configuration
10//! - State machine enforcement
11//! - Validation rules runtime
12//! - RBAC middleware
13//! - Trigger execution system
14//! - Computed fields
15//! - Workflow orchestrator
16
17#![recursion_limit = "1024"]
18#![allow(unused_imports)]
19
20// Generated modules
21pub mod domain;
22pub mod infrastructure;
23pub mod application;
24pub mod presentation;
25pub mod seeders;
26pub mod exports;
27
28// Re-exports for convenience - Domain entities
29pub use domain::entity::*;
30
31// Re-exports - Infrastructure
32pub use infrastructure::persistence::*;
33
34// Re-exports - Application services
35pub use application::service::PickingBatchService;
36pub use application::service::DeliveryNoteService;
37pub use application::service::DeliveryNoteItemService;
38pub use application::service::InventoryCompanySettingService;
39pub use application::service::LandedCostService;
40pub use application::service::LandedCostLineService;
41pub use application::service::LandedCostAdjustmentLineService;
42pub use application::service::LocationService;
43pub use application::service::StockMoveService;
44pub use application::service::StockMoveLineService;
45pub use application::service::OperationTypeService;
46pub use application::service::TransferService;
47pub use application::service::RouteService;
48pub use application::service::RouteRuleService;
49pub use application::service::ReorderingRuleService;
50pub use application::service::PurchaseReceiptService;
51pub use application::service::PurchaseReceiptItemService;
52pub use application::service::QuantService;
53pub use application::service::ScrapService;
54pub use application::service::ScrapReasonTagService;
55pub use application::service::StockEntryService;
56pub use application::service::StockEntryItemService;
57pub use application::service::StockLedgerEntryService;
58pub use application::service::BinService;
59pub use application::service::StockReconciliationService;
60pub use application::service::StockReconciliationItemService;
61pub use application::service::PackageTypeService;
62pub use application::service::StorageCategoryService;
63pub use application::service::StorageCategoryCapacityService;
64pub use application::service::PutawayRuleService;
65pub use application::service::LotService;
66pub use application::service::PackageService;
67pub use application::service::WarehouseService;
68pub use application::service::StockItemService;
69
70use std::sync::Arc;
71use axum::Router;
72use sqlx::PgPool;
73
74/// Inventory module configuration
75///
76/// Use the builder pattern to configure and register this module:
77///
78/// ```text
79/// let inventory = InventoryModule::builder()
80///     .with_database(pool.clone())
81///     .build()?;
82///
83/// // Unguarded full CRUD (trusted/admin); compose a guarded router for production.
84/// let router = inventory.all_crud_routes();
85/// ```
86pub struct InventoryModule {
87    pub(crate) picking_batch_service: Arc<PickingBatchService>,
88    pub(crate) delivery_note_service: Arc<DeliveryNoteService>,
89    pub(crate) delivery_note_item_service: Arc<DeliveryNoteItemService>,
90    pub(crate) inventory_company_setting_service: Arc<InventoryCompanySettingService>,
91    pub(crate) landed_cost_service: Arc<LandedCostService>,
92    pub(crate) landed_cost_line_service: Arc<LandedCostLineService>,
93    pub(crate) landed_cost_adjustment_line_service: Arc<LandedCostAdjustmentLineService>,
94    pub(crate) location_service: Arc<LocationService>,
95    pub(crate) stock_move_service: Arc<StockMoveService>,
96    pub(crate) stock_move_line_service: Arc<StockMoveLineService>,
97    pub(crate) operation_type_service: Arc<OperationTypeService>,
98    pub(crate) transfer_service: Arc<TransferService>,
99    pub(crate) route_service: Arc<RouteService>,
100    pub(crate) route_rule_service: Arc<RouteRuleService>,
101    pub(crate) reordering_rule_service: Arc<ReorderingRuleService>,
102    pub(crate) purchase_receipt_service: Arc<PurchaseReceiptService>,
103    pub(crate) purchase_receipt_item_service: Arc<PurchaseReceiptItemService>,
104    pub(crate) quant_service: Arc<QuantService>,
105    pub(crate) scrap_service: Arc<ScrapService>,
106    pub(crate) scrap_reason_tag_service: Arc<ScrapReasonTagService>,
107    pub(crate) stock_entry_service: Arc<StockEntryService>,
108    pub(crate) stock_entry_item_service: Arc<StockEntryItemService>,
109    pub(crate) stock_ledger_entry_service: Arc<StockLedgerEntryService>,
110    pub(crate) bin_service: Arc<BinService>,
111    pub(crate) stock_reconciliation_service: Arc<StockReconciliationService>,
112    pub(crate) stock_reconciliation_item_service: Arc<StockReconciliationItemService>,
113    pub(crate) package_type_service: Arc<PackageTypeService>,
114    pub(crate) storage_category_service: Arc<StorageCategoryService>,
115    pub(crate) storage_category_capacity_service: Arc<StorageCategoryCapacityService>,
116    pub(crate) putaway_rule_service: Arc<PutawayRuleService>,
117    pub(crate) lot_service: Arc<LotService>,
118    pub(crate) package_service: Arc<PackageService>,
119    pub(crate) warehouse_service: Arc<WarehouseService>,
120    pub(crate) stock_item_service: Arc<StockItemService>,
121}
122
123impl InventoryModule {
124    /// Create a new module builder
125    pub fn builder() -> InventoryModuleBuilder {
126        InventoryModuleBuilder::new()
127    }
128
129    /// Mount ALL generated CRUD endpoints (12 per entity) with NO domain
130    /// validation — the fully **unguarded** surface. A well-formed request can
131    /// create invalid rows or soft-delete a referenced master out from under its
132    /// dependents. Prefer a guarded composition (read + validated writes) for any
133    /// real deployment; use this only in trusted/admin/seeding contexts.
134    pub fn all_crud_routes(&self) -> Router {
135        use presentation::http::{
136            create_picking_batch_read_routes,
137            create_delivery_note_read_routes,
138            create_delivery_note_item_read_routes,
139            create_inventory_company_setting_routes,
140            create_landed_cost_read_routes,
141            create_landed_cost_line_read_routes,
142            create_landed_cost_adjustment_line_read_routes,
143            create_location_routes,
144            create_stock_move_read_routes,
145            create_stock_move_line_read_routes,
146            create_operation_type_routes,
147            create_transfer_read_routes,
148            create_route_routes,
149            create_route_rule_routes,
150            create_reordering_rule_routes,
151            create_purchase_receipt_read_routes,
152            create_purchase_receipt_item_read_routes,
153            create_quant_read_routes,
154            create_scrap_read_routes,
155            create_scrap_reason_tag_routes,
156            create_stock_entry_read_routes,
157            create_stock_entry_item_read_routes,
158            create_stock_ledger_entry_read_routes,
159            create_bin_read_routes,
160            create_stock_reconciliation_read_routes,
161            create_stock_reconciliation_item_read_routes,
162            create_package_type_routes,
163            create_storage_category_routes,
164            create_storage_category_capacity_routes,
165            create_putaway_rule_routes,
166            create_lot_routes,
167            create_package_routes,
168            create_warehouse_routes,
169            create_stock_item_routes,
170        };
171
172        Router::new()
173            .merge(create_picking_batch_read_routes(self.picking_batch_service.clone()))
174            // DeliveryNote: hand_set lifecycle — the state field moves only through the
175            // module's validated verbs; generic writes cannot reach it, so only the
176            // read surface mounts here.
177            .merge(create_delivery_note_read_routes(self.delivery_note_service.clone()))
178            .merge(create_delivery_note_item_read_routes(self.delivery_note_item_service.clone()))
179            .merge(create_inventory_company_setting_routes(self.inventory_company_setting_service.clone()))
180            // LandedCost: hand_set lifecycle — the state field moves only through the
181            // module's validated verbs; generic writes cannot reach it, so only the
182            // read surface mounts here.
183            .merge(create_landed_cost_read_routes(self.landed_cost_service.clone()))
184            .merge(create_landed_cost_line_read_routes(self.landed_cost_line_service.clone()))
185            .merge(create_landed_cost_adjustment_line_read_routes(self.landed_cost_adjustment_line_service.clone()))
186            .merge(create_location_routes(self.location_service.clone()))
187            // StockMove: hand_set lifecycle — the state field moves only through the
188            // module's validated verbs; generic writes cannot reach it, so only the
189            // read surface mounts here.
190            .merge(create_stock_move_read_routes(self.stock_move_service.clone()))
191            .merge(create_stock_move_line_read_routes(self.stock_move_line_service.clone()))
192            .merge(create_operation_type_routes(self.operation_type_service.clone()))
193            .merge(create_transfer_read_routes(self.transfer_service.clone()))
194            .merge(create_route_routes(self.route_service.clone()))
195            .merge(create_route_rule_routes(self.route_rule_service.clone()))
196            .merge(create_reordering_rule_routes(self.reordering_rule_service.clone()))
197            // PurchaseReceipt: hand_set lifecycle — the state field moves only through the
198            // module's validated verbs; generic writes cannot reach it, so only the
199            // read surface mounts here.
200            .merge(create_purchase_receipt_read_routes(self.purchase_receipt_service.clone()))
201            .merge(create_purchase_receipt_item_read_routes(self.purchase_receipt_item_service.clone()))
202            .merge(create_quant_read_routes(self.quant_service.clone()))
203            .merge(create_scrap_read_routes(self.scrap_service.clone()))
204            .merge(create_scrap_reason_tag_routes(self.scrap_reason_tag_service.clone()))
205            // StockEntry: hand_set lifecycle — the state field moves only through the
206            // module's validated verbs; generic writes cannot reach it, so only the
207            // read surface mounts here.
208            .merge(create_stock_entry_read_routes(self.stock_entry_service.clone()))
209            .merge(create_stock_entry_item_read_routes(self.stock_entry_item_service.clone()))
210            // StockLedgerEntry: hand_set lifecycle — the state field moves only through the
211            // module's validated verbs; generic writes cannot reach it, so only the
212            // read surface mounts here.
213            .merge(create_stock_ledger_entry_read_routes(self.stock_ledger_entry_service.clone()))
214            .merge(create_bin_read_routes(self.bin_service.clone()))
215            // StockReconciliation: hand_set lifecycle — the state field moves only through the
216            // module's validated verbs; generic writes cannot reach it, so only the
217            // read surface mounts here.
218            .merge(create_stock_reconciliation_read_routes(self.stock_reconciliation_service.clone()))
219            .merge(create_stock_reconciliation_item_read_routes(self.stock_reconciliation_item_service.clone()))
220            .merge(create_package_type_routes(self.package_type_service.clone()))
221            .merge(create_storage_category_routes(self.storage_category_service.clone()))
222            .merge(create_storage_category_capacity_routes(self.storage_category_capacity_service.clone()))
223            .merge(create_putaway_rule_routes(self.putaway_rule_service.clone()))
224            .merge(create_lot_routes(self.lot_service.clone()))
225            .merge(create_package_routes(self.package_service.clone()))
226            .merge(create_warehouse_routes(self.warehouse_service.clone()))
227            .merge(create_stock_item_routes(self.stock_item_service.clone()))
228    }
229
230    /// Deprecated alias for [`Self::all_crud_routes`]. `routes()` reads like
231    /// "the routes" but mounts UNVALIDATED generic CRUD on every entity — a naive
232    /// mount exposes unguarded writes. Compose a guarded router (read + validated
233    /// writes) for production, or call `all_crud_routes()` to opt into the full
234    /// unguarded surface explicitly.
235    #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
236    pub fn routes(&self) -> Router {
237        self.all_crud_routes()
238    }
239
240    /// Read-only routes for every entity (GET endpoints only) — the safe base.
241    ///
242    /// Generic mutation can't reach here, so this surface cannot bypass a
243    /// validated write service's invariants. Use this as the production base and
244    /// merge validated write routes (or a write service's HTTP layer) onto it.
245    pub fn readonly_routes(&self) -> Router {
246        use presentation::http::{
247            create_picking_batch_read_routes,
248            create_delivery_note_read_routes,
249            create_delivery_note_item_read_routes,
250            create_inventory_company_setting_read_routes,
251            create_landed_cost_read_routes,
252            create_landed_cost_line_read_routes,
253            create_landed_cost_adjustment_line_read_routes,
254            create_location_read_routes,
255            create_stock_move_read_routes,
256            create_stock_move_line_read_routes,
257            create_operation_type_read_routes,
258            create_transfer_read_routes,
259            create_route_read_routes,
260            create_route_rule_read_routes,
261            create_reordering_rule_read_routes,
262            create_purchase_receipt_read_routes,
263            create_purchase_receipt_item_read_routes,
264            create_quant_read_routes,
265            create_scrap_read_routes,
266            create_scrap_reason_tag_read_routes,
267            create_stock_entry_read_routes,
268            create_stock_entry_item_read_routes,
269            create_stock_ledger_entry_read_routes,
270            create_bin_read_routes,
271            create_stock_reconciliation_read_routes,
272            create_stock_reconciliation_item_read_routes,
273            create_package_type_read_routes,
274            create_storage_category_read_routes,
275            create_storage_category_capacity_read_routes,
276            create_putaway_rule_read_routes,
277            create_lot_read_routes,
278            create_package_read_routes,
279            create_warehouse_read_routes,
280            create_stock_item_read_routes,
281        };
282
283        Router::new()
284            .merge(create_picking_batch_read_routes(self.picking_batch_service.clone()))
285            .merge(create_delivery_note_read_routes(self.delivery_note_service.clone()))
286            .merge(create_delivery_note_item_read_routes(self.delivery_note_item_service.clone()))
287            .merge(create_inventory_company_setting_read_routes(self.inventory_company_setting_service.clone()))
288            .merge(create_landed_cost_read_routes(self.landed_cost_service.clone()))
289            .merge(create_landed_cost_line_read_routes(self.landed_cost_line_service.clone()))
290            .merge(create_landed_cost_adjustment_line_read_routes(self.landed_cost_adjustment_line_service.clone()))
291            .merge(create_location_read_routes(self.location_service.clone()))
292            .merge(create_stock_move_read_routes(self.stock_move_service.clone()))
293            .merge(create_stock_move_line_read_routes(self.stock_move_line_service.clone()))
294            .merge(create_operation_type_read_routes(self.operation_type_service.clone()))
295            .merge(create_transfer_read_routes(self.transfer_service.clone()))
296            .merge(create_route_read_routes(self.route_service.clone()))
297            .merge(create_route_rule_read_routes(self.route_rule_service.clone()))
298            .merge(create_reordering_rule_read_routes(self.reordering_rule_service.clone()))
299            .merge(create_purchase_receipt_read_routes(self.purchase_receipt_service.clone()))
300            .merge(create_purchase_receipt_item_read_routes(self.purchase_receipt_item_service.clone()))
301            .merge(create_quant_read_routes(self.quant_service.clone()))
302            .merge(create_scrap_read_routes(self.scrap_service.clone()))
303            .merge(create_scrap_reason_tag_read_routes(self.scrap_reason_tag_service.clone()))
304            .merge(create_stock_entry_read_routes(self.stock_entry_service.clone()))
305            .merge(create_stock_entry_item_read_routes(self.stock_entry_item_service.clone()))
306            .merge(create_stock_ledger_entry_read_routes(self.stock_ledger_entry_service.clone()))
307            .merge(create_bin_read_routes(self.bin_service.clone()))
308            .merge(create_stock_reconciliation_read_routes(self.stock_reconciliation_service.clone()))
309            .merge(create_stock_reconciliation_item_read_routes(self.stock_reconciliation_item_service.clone()))
310            .merge(create_package_type_read_routes(self.package_type_service.clone()))
311            .merge(create_storage_category_read_routes(self.storage_category_service.clone()))
312            .merge(create_storage_category_capacity_read_routes(self.storage_category_capacity_service.clone()))
313            .merge(create_putaway_rule_read_routes(self.putaway_rule_service.clone()))
314            .merge(create_lot_read_routes(self.lot_service.clone()))
315            .merge(create_package_read_routes(self.package_service.clone()))
316            .merge(create_warehouse_read_routes(self.warehouse_service.clone()))
317            .merge(create_stock_item_read_routes(self.stock_item_service.clone()))
318    }
319
320}
321
322/// Builder for InventoryModule
323pub struct InventoryModuleBuilder {
324    db_pool: Option<PgPool>,
325}
326
327impl InventoryModuleBuilder {
328    /// Create a new builder
329    pub fn new() -> Self {
330        Self {
331            db_pool: None,
332        }
333    }
334
335    /// Set the database connection pool
336    pub fn with_database(mut self, pool: PgPool) -> Self {
337        self.db_pool = Some(pool);
338        self
339    }
340
341
342    /// Build the module with configured dependencies
343    pub fn build(self) -> anyhow::Result<InventoryModule> {
344        let db_pool = self.db_pool
345            .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
346
347        // PickingBatch service
348        let picking_batch_repository = Arc::new(PickingBatchRepository::new(db_pool.clone()));
349        let picking_batch_service = Arc::new(crate::application::service::build_picking_batch_service(picking_batch_repository.clone()));
350
351        // DeliveryNote service
352        let delivery_note_repository = Arc::new(DeliveryNoteRepository::new(db_pool.clone()));
353        let delivery_note_service = Arc::new(crate::application::service::build_delivery_note_service(delivery_note_repository.clone()));
354
355        // DeliveryNoteItem service
356        let delivery_note_item_repository = Arc::new(DeliveryNoteItemRepository::new(db_pool.clone()));
357        let delivery_note_item_service = Arc::new(crate::application::service::build_delivery_note_item_service(delivery_note_item_repository.clone()));
358
359        // InventoryCompanySetting service
360        let inventory_company_setting_repository = Arc::new(InventoryCompanySettingRepository::new(db_pool.clone()));
361        let inventory_company_setting_service = Arc::new(crate::application::service::build_inventory_company_setting_service(inventory_company_setting_repository.clone()));
362
363        // LandedCost service
364        let landed_cost_repository = Arc::new(LandedCostRepository::new(db_pool.clone()));
365        let landed_cost_service = Arc::new(crate::application::service::build_landed_cost_service(landed_cost_repository.clone()));
366
367        // LandedCostLine service
368        let landed_cost_line_repository = Arc::new(LandedCostLineRepository::new(db_pool.clone()));
369        let landed_cost_line_service = Arc::new(crate::application::service::build_landed_cost_line_service(landed_cost_line_repository.clone()));
370
371        // LandedCostAdjustmentLine service
372        let landed_cost_adjustment_line_repository = Arc::new(LandedCostAdjustmentLineRepository::new(db_pool.clone()));
373        let landed_cost_adjustment_line_service = Arc::new(crate::application::service::build_landed_cost_adjustment_line_service(landed_cost_adjustment_line_repository.clone()));
374
375        // Location service
376        let location_repository = Arc::new(LocationRepository::new(db_pool.clone()));
377        let location_service = Arc::new(crate::application::service::build_location_service(location_repository.clone()));
378
379        // StockMove service
380        let stock_move_repository = Arc::new(StockMoveRepository::new(db_pool.clone()));
381        let stock_move_service = Arc::new(crate::application::service::build_stock_move_service(stock_move_repository.clone()));
382
383        // StockMoveLine service
384        let stock_move_line_repository = Arc::new(StockMoveLineRepository::new(db_pool.clone()));
385        let stock_move_line_service = Arc::new(crate::application::service::build_stock_move_line_service(stock_move_line_repository.clone()));
386
387        // OperationType service
388        let operation_type_repository = Arc::new(OperationTypeRepository::new(db_pool.clone()));
389        let operation_type_service = Arc::new(crate::application::service::build_operation_type_service(operation_type_repository.clone()));
390
391        // Transfer service
392        let transfer_repository = Arc::new(TransferRepository::new(db_pool.clone()));
393        let transfer_service = Arc::new(crate::application::service::build_transfer_service(transfer_repository.clone()));
394
395        // Route service
396        let route_repository = Arc::new(RouteRepository::new(db_pool.clone()));
397        let route_service = Arc::new(crate::application::service::build_route_service(route_repository.clone()));
398
399        // RouteRule service
400        let route_rule_repository = Arc::new(RouteRuleRepository::new(db_pool.clone()));
401        let route_rule_service = Arc::new(crate::application::service::build_route_rule_service(route_rule_repository.clone()));
402
403        // ReorderingRule service
404        let reordering_rule_repository = Arc::new(ReorderingRuleRepository::new(db_pool.clone()));
405        let reordering_rule_service = Arc::new(crate::application::service::build_reordering_rule_service(reordering_rule_repository.clone()));
406
407        // PurchaseReceipt service
408        let purchase_receipt_repository = Arc::new(PurchaseReceiptRepository::new(db_pool.clone()));
409        let purchase_receipt_service = Arc::new(crate::application::service::build_purchase_receipt_service(purchase_receipt_repository.clone()));
410
411        // PurchaseReceiptItem service
412        let purchase_receipt_item_repository = Arc::new(PurchaseReceiptItemRepository::new(db_pool.clone()));
413        let purchase_receipt_item_service = Arc::new(crate::application::service::build_purchase_receipt_item_service(purchase_receipt_item_repository.clone()));
414
415        // Quant service
416        let quant_repository = Arc::new(QuantRepository::new(db_pool.clone()));
417        let quant_service = Arc::new(crate::application::service::build_quant_service(quant_repository.clone()));
418
419        // Scrap service
420        let scrap_repository = Arc::new(ScrapRepository::new(db_pool.clone()));
421        let scrap_service = Arc::new(crate::application::service::build_scrap_service(scrap_repository.clone()));
422
423        // ScrapReasonTag service
424        let scrap_reason_tag_repository = Arc::new(ScrapReasonTagRepository::new(db_pool.clone()));
425        let scrap_reason_tag_service = Arc::new(crate::application::service::build_scrap_reason_tag_service(scrap_reason_tag_repository.clone()));
426
427        // StockEntry service
428        let stock_entry_repository = Arc::new(StockEntryRepository::new(db_pool.clone()));
429        let stock_entry_service = Arc::new(crate::application::service::build_stock_entry_service(stock_entry_repository.clone()));
430
431        // StockEntryItem service
432        let stock_entry_item_repository = Arc::new(StockEntryItemRepository::new(db_pool.clone()));
433        let stock_entry_item_service = Arc::new(crate::application::service::build_stock_entry_item_service(stock_entry_item_repository.clone()));
434
435        // StockLedgerEntry service
436        let stock_ledger_entry_repository = Arc::new(StockLedgerEntryRepository::new(db_pool.clone()));
437        let stock_ledger_entry_service = Arc::new(crate::application::service::build_stock_ledger_entry_service(stock_ledger_entry_repository.clone()));
438
439        // Bin service
440        let bin_repository = Arc::new(BinRepository::new(db_pool.clone()));
441        let bin_service = Arc::new(crate::application::service::build_bin_service(bin_repository.clone()));
442
443        // StockReconciliation service
444        let stock_reconciliation_repository = Arc::new(StockReconciliationRepository::new(db_pool.clone()));
445        let stock_reconciliation_service = Arc::new(crate::application::service::build_stock_reconciliation_service(stock_reconciliation_repository.clone()));
446
447        // StockReconciliationItem service
448        let stock_reconciliation_item_repository = Arc::new(StockReconciliationItemRepository::new(db_pool.clone()));
449        let stock_reconciliation_item_service = Arc::new(crate::application::service::build_stock_reconciliation_item_service(stock_reconciliation_item_repository.clone()));
450
451        // PackageType service
452        let package_type_repository = Arc::new(PackageTypeRepository::new(db_pool.clone()));
453        let package_type_service = Arc::new(crate::application::service::build_package_type_service(package_type_repository.clone()));
454
455        // StorageCategory service
456        let storage_category_repository = Arc::new(StorageCategoryRepository::new(db_pool.clone()));
457        let storage_category_service = Arc::new(crate::application::service::build_storage_category_service(storage_category_repository.clone()));
458
459        // StorageCategoryCapacity service
460        let storage_category_capacity_repository = Arc::new(StorageCategoryCapacityRepository::new(db_pool.clone()));
461        let storage_category_capacity_service = Arc::new(crate::application::service::build_storage_category_capacity_service(storage_category_capacity_repository.clone()));
462
463        // PutawayRule service
464        let putaway_rule_repository = Arc::new(PutawayRuleRepository::new(db_pool.clone()));
465        let putaway_rule_service = Arc::new(crate::application::service::build_putaway_rule_service(putaway_rule_repository.clone()));
466
467        // Lot service
468        let lot_repository = Arc::new(LotRepository::new(db_pool.clone()));
469        let lot_service = Arc::new(crate::application::service::build_lot_service(lot_repository.clone()));
470
471        // Package service
472        let package_repository = Arc::new(PackageRepository::new(db_pool.clone()));
473        let package_service = Arc::new(crate::application::service::build_package_service(package_repository.clone()));
474
475        // Warehouse service
476        let warehouse_repository = Arc::new(WarehouseRepository::new(db_pool.clone()));
477        let warehouse_service = Arc::new(crate::application::service::build_warehouse_service(warehouse_repository.clone()));
478
479        // StockItem service
480        let stock_item_repository = Arc::new(StockItemRepository::new(db_pool.clone()));
481        let stock_item_service = Arc::new(crate::application::service::build_stock_item_service(stock_item_repository.clone()));
482
483
484        Ok(InventoryModule {
485            picking_batch_service,
486            delivery_note_service,
487            delivery_note_item_service,
488            inventory_company_setting_service,
489            landed_cost_service,
490            landed_cost_line_service,
491            landed_cost_adjustment_line_service,
492            location_service,
493            stock_move_service,
494            stock_move_line_service,
495            operation_type_service,
496            transfer_service,
497            route_service,
498            route_rule_service,
499            reordering_rule_service,
500            purchase_receipt_service,
501            purchase_receipt_item_service,
502            quant_service,
503            scrap_service,
504            scrap_reason_tag_service,
505            stock_entry_service,
506            stock_entry_item_service,
507            stock_ledger_entry_service,
508            bin_service,
509            stock_reconciliation_service,
510            stock_reconciliation_item_service,
511            package_type_service,
512            storage_category_service,
513            storage_category_capacity_service,
514            putaway_rule_service,
515            lot_service,
516            package_service,
517            warehouse_service,
518            stock_item_service,
519        })
520    }
521}
522
523impl Default for InventoryModuleBuilder {
524    fn default() -> Self {
525        Self::new()
526    }
527}
528
529// This directory's extension (hand-written; ADR-0031).
530include!("mod.ext.rs");