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