diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2b0a61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python + +# Odoo +*.pot +*.po + +# Editor +.vscode/ +.idea/ +*.swp +*~ diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 5b6bffa..f4a3ef3 --- a/README.md +++ b/README.md @@ -1,153 +1,17 @@ # Quality Check Lot Preserve ## Overview +This module preserves the state of Quality Checks (`quality.check`) when lot numbers are assigned during receipt operations. It is designed to support workflows where quality checks are performed *before* or *during* the assignment of Lot/Serial numbers. -This module modifies the standard Odoo 18 quality check behavior for receipt operations to preserve quality check states when lot numbers are assigned after quality checks have been completed. - -## Problem Statement - -In standard Odoo, when a quality check is completed before a lot number is assigned, the quality check automatically resets to "Todo" state when the lot number is later assigned. This creates inefficiency in warehouse operations where: - -1. Quality checks are performed immediately upon receipt -2. Lot numbers are generated or assigned later in the process -3. Quality checks must be re-done unnecessarily - -## Solution - -This module provides the following functionality: - -### 1. State Preservation -- Quality check states (Pass, Fail, In Progress) are preserved when lot numbers are assigned -- Applies only to receipt operations (incoming shipments) -- Other operation types (manufacturing, internal transfers, delivery) continue with standard Odoo behavior - -### 2. Automatic Lot Number Synchronization -- Lot numbers assigned to stock move lines are automatically copied to related quality checks -- Lot number changes are synchronized in real-time -- Maintains traceability between inventory and quality records - -### 3. Selective Application -- Custom behavior applies only to receipt operations -- Standard Odoo workflows remain unchanged for other operation types -- Seamless integration with existing quality control processes - -## Installation - -1. Copy this module to your Odoo addons directory (e.g., `customaddons/quality_check_lot_preserve`) -2. Update the apps list in Odoo -3. Install the "Quality Check Lot Preserve" module - -## Dependencies - -- `stock` - Odoo Inventory Management -- `quality_control` - Odoo Quality Control (Enterprise module) - -**Note:** This module requires Odoo Enterprise edition as it depends on the `quality_control` module. - -## Usage - -### Typical Workflow - -1. **Receive Products**: Create a purchase order and validate the receipt -2. **Perform Quality Checks**: Complete quality checks immediately upon receipt (before lot assignment) -3. **Assign Lot Numbers**: Generate or manually assign lot numbers to the stock move lines -4. **Result**: Quality check states remain unchanged, and lot numbers are automatically copied to quality checks - -### Example Scenario - -**Before this module:** -- Receive 100 units of Product A -- Complete quality check → Status: "Pass" -- Assign lot number "LOT001" -- Quality check resets → Status: "Todo" ❌ -- Must re-do quality check - -**With this module:** -- Receive 100 units of Product A -- Complete quality check → Status: "Pass" -- Assign lot number "LOT001" -- Quality check remains → Status: "Pass" ✓ -- Lot number automatically copied to quality check ✓ +## Features +- **Preserve Check State**: Prevents Quality Checks from generating new checks or resetting their state (Pass/Fail) when a user assigns a Lot Number to a move line. +- **Allow Pre-Lot Checks**: Overrides default strict Odoo behavior to allow Quality Checks to be initiated and processed on Receipt operations even if the tracked product does not yet have a Lot/Serial Number assigned. ## Technical Details +- Overrides `quality.check` `_is_to_do()` to permit checks on receipts without lots. +- Overrides `stock.move.line` `_create_check()` to prevent duplicates. +- Uses custom state preservation logic during `write()` operations on quality checks and move lines. -### Extended Models - -#### stock.move.line -- Monitors `lot_id` and `lot_name` field changes -- Identifies related quality checks for receipt operations -- Triggers quality check lot number updates - -#### quality.check -- Prevents state resets during lot assignment for receipt operations -- Accepts lot number updates from stock move lines -- Maintains standard behavior for non-receipt operations - -### Operation Type Detection - -The module identifies receipt operations by checking: -- `picking_type_code == 'incoming'` -- Fallback to `picking_id.picking_type_id.code` - -### Data Flow - -``` -Stock Move Line (Lot Assigned) - ↓ -Detect Change (write method) - ↓ -Find Related Quality Checks - ↓ -Check Operation Type (Receipt?) - ↓ Yes -Copy Lot Number + Preserve State - ↓ -Update Quality Check -``` - -### Security and Access Rights - -This module extends existing Odoo models (`stock.move.line` and `quality.check`) without creating new models or data structures. Therefore: - -- **No new access rights are required** -- Access rights are inherited from the base modules (`stock` and `quality_control`) -- Users with existing quality control and inventory permissions can use this module -- The `security/ir.model.access.csv` file is present but empty (only contains the header row) - -The module respects all existing Odoo security rules and group permissions. - -## Configuration - -No additional configuration is required. The module works automatically once installed. - -## Compatibility - -- **Odoo Version**: 18.0 -- **Edition**: Enterprise (requires quality_control module) -- **Database**: PostgreSQL - -## Limitations - -- Only applies to receipt operations (incoming shipments) -- Requires the quality_control Enterprise module -- Does not modify historical quality check records - -## Support - -For issues, questions, or feature requests, please contact your Odoo implementation partner or system administrator. - -## License - -LGPL-3 - -## Author - -Your Company - -## Version History - -### 1.0.0 (Initial Release) -- State preservation for quality checks during lot assignment -- Automatic lot number synchronization -- Receipt operation filtering -- Full integration with standard Odoo quality control workflows +## Dependencies +- `quality_control` +- `stock` diff --git a/__init__.py b/__init__.py old mode 100644 new mode 100755 diff --git a/__manifest__.py b/__manifest__.py old mode 100644 new mode 100755 diff --git a/__pycache__/__init__.cpython-312.pyc b/__pycache__/__init__.cpython-312.pyc index 61d7d61..9a92657 100644 Binary files a/__pycache__/__init__.cpython-312.pyc and b/__pycache__/__init__.cpython-312.pyc differ diff --git a/__pycache__/__manifest__.cpython-312.pyc b/__pycache__/__manifest__.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/models/__init__.py b/models/__init__.py old mode 100644 new mode 100755 diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc index 160066d..c638e97 100644 Binary files a/models/__pycache__/__init__.cpython-312.pyc and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/quality_check.cpython-312.pyc b/models/__pycache__/quality_check.cpython-312.pyc index 07996a6..2fd6984 100644 Binary files a/models/__pycache__/quality_check.cpython-312.pyc and b/models/__pycache__/quality_check.cpython-312.pyc differ diff --git a/models/__pycache__/stock_move_line.cpython-312.pyc b/models/__pycache__/stock_move_line.cpython-312.pyc index 6d95667..b087a4c 100644 Binary files a/models/__pycache__/stock_move_line.cpython-312.pyc and b/models/__pycache__/stock_move_line.cpython-312.pyc differ diff --git a/models/quality_check.py b/models/quality_check.py old mode 100644 new mode 100755 index 2d4eafa..3c9d47c --- a/models/quality_check.py +++ b/models/quality_check.py @@ -195,3 +195,34 @@ class QualityCheck(models.Model): ) # Invalidate cache to ensure the updated values are reflected self.invalidate_recordset(['quality_state', 'user_id', 'control_date']) + + def _is_to_do(self, checkable_products, check_picked=False): + """ + Override to allow quality checks on receipt operations even if lot is not yet assigned. + """ + self.ensure_one() + + # If this is a receipt operation, we want to allow the check even if lot is missing + # because our module supports assigning the lot later or during the check + if self._is_receipt_operation(): + # Standard logic from quality_control.quality_check._is_to_do + # but skipping the lot requirement for tracked products on receipt + + if self.quality_state != 'none': + return False + + if self.measure_on != 'operation': + if self.product_id not in checkable_products: + return False + if self.move_line_id: + if not self.move_line_id._is_checkable(check_picked): + return False + + # This is the part we're effectively skipping for receipt operations: + # "Only process qc related to tracked product if its lot is set" + # We skip this check because we want to allow it. + + return True + + # For non-receipt operations, fall back to standard behavior + return super(QualityCheck, self)._is_to_do(checkable_products, check_picked) diff --git a/models/stock_move_line.py b/models/stock_move_line.py old mode 100644 new mode 100755 diff --git a/tests/__init__.py b/tests/__init__.py old mode 100644 new mode 100755 diff --git a/tests/__pycache__/__init__.cpython-312.pyc b/tests/__pycache__/__init__.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_basic_functionality.cpython-312.pyc b/tests/__pycache__/test_basic_functionality.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_edge_cases.cpython-312.pyc b/tests/__pycache__/test_edge_cases.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_integration.cpython-312.pyc b/tests/__pycache__/test_integration.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_lot_propagation.cpython-312.pyc b/tests/__pycache__/test_property_lot_propagation.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_lot_update.cpython-312.pyc b/tests/__pycache__/test_property_lot_update.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_non_receipt_operation.cpython-312.pyc b/tests/__pycache__/test_property_non_receipt_operation.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_receipt_operation.cpython-312.pyc b/tests/__pycache__/test_property_receipt_operation.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_relationship_integrity.cpython-312.pyc b/tests/__pycache__/test_property_relationship_integrity.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/__pycache__/test_property_state_preservation.cpython-312.pyc b/tests/__pycache__/test_property_state_preservation.cpython-312.pyc old mode 100644 new mode 100755 diff --git a/tests/test_basic_functionality.py b/tests/test_basic_functionality.py old mode 100644 new mode 100755 diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py old mode 100644 new mode 100755 diff --git a/tests/test_integration.py b/tests/test_integration.py old mode 100644 new mode 100755 diff --git a/tests/test_property_lot_propagation.py b/tests/test_property_lot_propagation.py old mode 100644 new mode 100755 diff --git a/tests/test_property_lot_update.py b/tests/test_property_lot_update.py old mode 100644 new mode 100755 diff --git a/tests/test_property_non_receipt_operation.py b/tests/test_property_non_receipt_operation.py old mode 100644 new mode 100755 diff --git a/tests/test_property_receipt_operation.py b/tests/test_property_receipt_operation.py old mode 100644 new mode 100755 diff --git a/tests/test_property_relationship_integrity.py b/tests/test_property_relationship_integrity.py old mode 100644 new mode 100755 diff --git a/tests/test_property_state_preservation.py b/tests/test_property_state_preservation.py old mode 100644 new mode 100755