feat: Preserve quality check states and allow pre-lot checks for receipt operations by modifying quality.check and stock.move.line logic.
This commit is contained in:
parent
c5cd69b33a
commit
66c6c5af8e
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
|
||||||
|
# Odoo
|
||||||
|
*.pot
|
||||||
|
*.po
|
||||||
|
|
||||||
|
# Editor
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
156
README.md
Normal file → Executable file
156
README.md
Normal file → Executable file
@ -1,153 +1,17 @@
|
|||||||
# Quality Check Lot Preserve
|
# Quality Check Lot Preserve
|
||||||
|
|
||||||
## Overview
|
## 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.
|
## 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.
|
||||||
## Problem Statement
|
- **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.
|
||||||
|
|
||||||
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 ✓
|
|
||||||
|
|
||||||
## Technical Details
|
## 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
|
## Dependencies
|
||||||
|
- `quality_control`
|
||||||
#### stock.move.line
|
- `stock`
|
||||||
- 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
|
|
||||||
|
|||||||
0
__init__.py
Normal file → Executable file
0
__init__.py
Normal file → Executable file
0
__manifest__.py
Normal file → Executable file
0
__manifest__.py
Normal file → Executable file
Binary file not shown.
0
__pycache__/__manifest__.cpython-312.pyc
Normal file → Executable file
0
__pycache__/__manifest__.cpython-312.pyc
Normal file → Executable file
0
models/__init__.py
Normal file → Executable file
0
models/__init__.py
Normal file → Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
31
models/quality_check.py
Normal file → Executable file
31
models/quality_check.py
Normal file → Executable file
@ -195,3 +195,34 @@ class QualityCheck(models.Model):
|
|||||||
)
|
)
|
||||||
# Invalidate cache to ensure the updated values are reflected
|
# Invalidate cache to ensure the updated values are reflected
|
||||||
self.invalidate_recordset(['quality_state', 'user_id', 'control_date'])
|
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)
|
||||||
|
|||||||
0
models/stock_move_line.py
Normal file → Executable file
0
models/stock_move_line.py
Normal file → Executable file
0
tests/__init__.py
Normal file → Executable file
0
tests/__init__.py
Normal file → Executable file
0
tests/__pycache__/__init__.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/__init__.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_basic_functionality.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_basic_functionality.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_edge_cases.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_edge_cases.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_integration.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_integration.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_lot_propagation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_lot_propagation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_lot_update.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_lot_update.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_non_receipt_operation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_non_receipt_operation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_receipt_operation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_receipt_operation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_relationship_integrity.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_relationship_integrity.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_state_preservation.cpython-312.pyc
Normal file → Executable file
0
tests/__pycache__/test_property_state_preservation.cpython-312.pyc
Normal file → Executable file
0
tests/test_basic_functionality.py
Normal file → Executable file
0
tests/test_basic_functionality.py
Normal file → Executable file
0
tests/test_edge_cases.py
Normal file → Executable file
0
tests/test_edge_cases.py
Normal file → Executable file
0
tests/test_integration.py
Normal file → Executable file
0
tests/test_integration.py
Normal file → Executable file
0
tests/test_property_lot_propagation.py
Normal file → Executable file
0
tests/test_property_lot_propagation.py
Normal file → Executable file
0
tests/test_property_lot_update.py
Normal file → Executable file
0
tests/test_property_lot_update.py
Normal file → Executable file
0
tests/test_property_non_receipt_operation.py
Normal file → Executable file
0
tests/test_property_non_receipt_operation.py
Normal file → Executable file
0
tests/test_property_receipt_operation.py
Normal file → Executable file
0
tests/test_property_receipt_operation.py
Normal file → Executable file
0
tests/test_property_relationship_integrity.py
Normal file → Executable file
0
tests/test_property_relationship_integrity.py
Normal file → Executable file
0
tests/test_property_state_preservation.py
Normal file → Executable file
0
tests/test_property_state_preservation.py
Normal file → Executable file
Loading…
Reference in New Issue
Block a user