Skip to content

refactor(inventory): extract inventory management logic to InventoryManager service#360

Merged
nikhilb2 merged 2 commits into
mainfrom
352-extract-inventory-management-logic-to-service-module
May 7, 2026
Merged

refactor(inventory): extract inventory management logic to InventoryManager service#360
nikhilb2 merged 2 commits into
mainfrom
352-extract-inventory-management-logic-to-service-module

Conversation

@nikhilb2
Copy link
Copy Markdown
Owner

@nikhilb2 nikhilb2 commented May 7, 2026

Summary

Closes #352

Extracts all inventory quantity operations from InvoiceProcessor into a dedicated InventoryManager service class.

Changes

New: backend/src/services/inventory_service.py

InventoryManager class with focused, independently-testable methods:

Method Responsibility
effect_for_voucher_type() Pure static helper — sales → negative, purchase → positive
update_quantity() Apply a signed delta, auto-create row, guard against negative stock, log all changes
check_availability() Pre-sales stock availability validation
reverse_invoice_inventory() Undo inventory on invoice cancellation
restore_invoice_inventory() Re-apply inventory on invoice restoration
apply_invoice_changes() Net-delta computation when editing an invoice (avoids full reverse-reapply)
apply_new_items() Apply inventory for a newly-created invoice

Refactored: backend/src/services/invoice_processor.py

  • InvoiceProcessor now holds self.inventory = InventoryManager(db)
  • reverse_inventory, restore_inventory, apply_inventory_delta_for_update delegate to InventoryManager
  • validate_items delegates availability check to InventoryManager.check_availability
  • apply_payload delegates new-item updates to InventoryManager.apply_new_items
  • Module-level change_inventory_quantity and inventory_effect_for_voucher_type kept as backward-compatible shims so existing callers and tests continue to work unchanged

New: backend/tests/services/test_inventory_service.py

21 unit tests covering all InventoryManager methods across happy paths, edge cases, and error scenarios.

Test Results

189 passed, 22 warnings in 2.99s

nikhilb2 added 2 commits May 7, 2026 21:43
- Add deterministic ORDER BY CASE in update_quantity and check_availability
  queries so a company-scoped row is always selected before a global
  (NULL company_id) row when both match the OR filter
- Import sqlalchemy.case in inventory_service.py
- Add 4 new tests:
  - test_prefers_company_row_over_global_row (update_quantity)
  - test_falls_back_to_global_row_when_only_global_exists (update_quantity)
  - test_uses_company_row_not_global_for_availability (check_availability)
  - test_falls_back_to_global_row_for_availability (check_availability)
@nikhilb2 nikhilb2 merged commit 6b39b15 into main May 7, 2026
1 check passed
@nikhilb2 nikhilb2 deleted the 352-extract-inventory-management-logic-to-service-module branch May 23, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract inventory management logic to service module

1 participant