Pick Container Documentation¶
Overview¶
The Pick Container module (pick.container) provides a simple junction table that links stock pickings with containers. This model facilitates container tracking during picking operations, enabling efficient warehouse management and shipment preparation.
Model Information¶
Model Name: pick.container
Display Name: Pick Container
Key Fields: N/A
Features¶
- ❌ Audit logging enabled
- ❌ Multi-company support
- ❌ Complex business logic
- ✅ Simple junction/relationship table
Key Fields Reference¶
Relationship Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
picking_id |
Many2One | ❌ | Stock picking reference (stock.picking), deleted on cascade |
container_id |
Many2One | ❌ | Container reference (stock.container), deleted on cascade |
Understanding Cascade Deletion¶
Both fields use on_delete="cascade", which means:
- When a picking is deleted, all associated pick_container records are automatically deleted
- When a container is deleted, all associated pick_container records are automatically deleted
- This maintains referential integrity in the database
API Methods¶
1. Create Pick Container Association¶
Method: create(vals, context)
Links a container to a picking operation.
Parameters:
Returns: int - New record ID
Example:
# Associate container with picking
pc_id = get_model("pick.container").create({
"picking_id": picking_id,
"container_id": container_id
})
2. Bulk Create Container Associations¶
Method: create(vals, context) with multiple calls
Creates multiple container associations for a single picking.
Example:
# Associate multiple containers with one picking
container_ids = [101, 102, 103]
for cont_id in container_ids:
get_model("pick.container").create({
"picking_id": picking_id,
"container_id": cont_id
})
Search Functions¶
Search by Picking¶
# Find all containers associated with a picking
condition = [["picking_id", "=", picking_id]]
pc_records = get_model("pick.container").search(condition)
# Get container IDs
container_ids = [
get_model("pick.container").browse(pc_id).container_id.id
for pc_id in pc_records
]
Search by Container¶
# Find all pickings that used a specific container
condition = [["container_id", "=", container_id]]
pc_records = get_model("pick.container").search(condition)
# Get picking IDs
picking_ids = [
get_model("pick.container").browse(pc_id).picking_id.id
for pc_id in pc_records
]
Related Models¶
| Model | Relationship | Description |
|---|---|---|
stock.picking |
Many2One | Warehouse picking operations |
stock.container |
Many2One | Physical containers used in warehouse |
Common Use Cases¶
Use Case 1: Associate Container with Picking¶
# When preparing a shipment, link containers to picking
# 1. Create or get picking
pick_id = get_model("stock.picking").create({
"type": "out",
# ... other fields
})
# 2. Create or get container
cont_id = get_model("stock.container").create({
"number": "CONT-2025-001",
# ... other fields
})
# 3. Link container to picking
get_model("pick.container").create({
"picking_id": pick_id,
"container_id": cont_id
})
Use Case 2: Track Multiple Containers per Picking¶
# When a large order requires multiple containers
pick_id = 123
# Add multiple containers
containers = ["CONT-A", "CONT-B", "CONT-C"]
for cont_no in containers:
# Find or create container
res = get_model("stock.container").search([["number", "=", cont_no]])
if res:
cont_id = res[0]
else:
cont_id = get_model("stock.container").create({"number": cont_no})
# Link to picking
get_model("pick.container").create({
"picking_id": pick_id,
"container_id": cont_id
})
Use Case 3: Get All Containers for a Picking¶
# Retrieve all containers used in a picking
def get_picking_containers(picking_id):
"""Returns list of container objects for a picking"""
pc_ids = get_model("pick.container").search([
["picking_id", "=", picking_id]
])
containers = []
for pc_id in pc_ids:
pc = get_model("pick.container").browse(pc_id)
containers.append(pc.container_id)
return containers
# Usage
containers = get_picking_containers(123)
for cont in containers:
print(f"Container: {cont.number}")
Use Case 4: Get Picking History for a Container¶
# Track which pickings have used a specific container
def get_container_history(container_id):
"""Returns list of pickings that used this container"""
pc_ids = get_model("pick.container").search([
["container_id", "=", container_id]
])
pickings = []
for pc_id in pc_ids:
pc = get_model("pick.container").browse(pc_id)
pickings.append(pc.picking_id)
return pickings
# Usage
pickings = get_container_history(456)
for pick in pickings:
print(f"Picking: {pick.number}, Date: {pick.date}")
Best Practices¶
1. Check Existing Associations¶
# Good: Check before creating duplicate associations
existing = get_model("pick.container").search([
["picking_id", "=", picking_id],
["container_id", "=", container_id]
])
if not existing:
get_model("pick.container").create({
"picking_id": picking_id,
"container_id": container_id
})
# Bad: Create without checking
get_model("pick.container").create({ # ❌ May create duplicates
"picking_id": picking_id,
"container_id": container_id
})
2. Batch Operations¶
# Efficient: Batch create operations
container_ids = [101, 102, 103, 104]
# Create all associations at once
for cont_id in container_ids:
get_model("pick.container").create({
"picking_id": picking_id,
"container_id": cont_id
})
# Then fetch picking to refresh relationships
pick = get_model("stock.picking").browse(picking_id)
3. Clean Up Orphaned Records¶
# The cascade deletion handles this automatically, but be aware:
# When deleting a picking:
get_model("stock.picking").delete([picking_id])
# All pick.container records automatically deleted
# When deleting a container:
get_model("stock.container").delete([container_id])
# All pick.container records automatically deleted
Database Constraints¶
Cascade Deletion¶
-- Foreign key constraints with cascade
ALTER TABLE pick_container
ADD CONSTRAINT fk_picking
FOREIGN KEY (picking_id)
REFERENCES stock_picking(id)
ON DELETE CASCADE;
ALTER TABLE pick_container
ADD CONSTRAINT fk_container
FOREIGN KEY (container_id)
REFERENCES stock_container(id)
ON DELETE CASCADE;
This ensures referential integrity - orphaned records cannot exist.
Performance Tips¶
1. Index Queries¶
- Both
picking_idandcontainer_idare implicitly indexed as foreign keys - Queries on either field are efficient
2. Bulk Retrieval¶
# Efficient: Single query with browse_multi
pc_ids = get_model("pick.container").search([["picking_id", "=", picking_id]])
pc_records = get_model("pick.container").browse(pc_ids)
# Access all containers in one batch
containers = [pc.container_id for pc in pc_records]
3. Count Operations¶
# Fast: Count without retrieving full records
count = get_model("pick.container").search_count([
["picking_id", "=", picking_id]
])
print(f"Picking has {count} containers")
Integration Points¶
Internal Modules¶
- Stock Picking: Main warehouse operation module
- Stock Container: Container management system
Typical Workflow¶
Stock Picking Created
↓
Items Picked & Packed
↓
Containers Assigned ← pick.container links created here
↓
Shipment Prepared
↓
Picking Completed
Troubleshooting¶
"Foreign key violation"¶
Cause: Trying to create pick.container with non-existent picking_id or container_id
Solution: Verify both picking and container exist before creating association
"Duplicate records"¶
Cause: Creating multiple pick.container records with same picking_id and container_id
Solution: Check for existing associations before creating new ones (see Best Practices)
Testing Examples¶
Unit Test: Basic Association¶
def test_pick_container_association():
# Create picking
pick_id = get_model("stock.picking").create({
"type": "out"
})
# Create container
cont_id = get_model("stock.container").create({
"number": "TEST-CONT-001"
})
# Create association
pc_id = get_model("pick.container").create({
"picking_id": pick_id,
"container_id": cont_id
})
# Verify
pc = get_model("pick.container").browse(pc_id)
assert pc.picking_id.id == pick_id
assert pc.container_id.id == cont_id
Unit Test: Cascade Deletion¶
def test_cascade_deletion():
# Create picking and container association
pick_id = get_model("stock.picking").create({"type": "out"})
cont_id = get_model("stock.container").create({"number": "TEST"})
pc_id = get_model("pick.container").create({
"picking_id": pick_id,
"container_id": cont_id
})
# Delete picking
get_model("stock.picking").delete([pick_id])
# Verify pick.container also deleted
result = get_model("pick.container").search([["id", "=", pc_id]])
assert len(result) == 0, "pick.container should be cascade deleted"
Version History¶
Last Updated: 2025-10-27
Model Version: pick_container.py
Framework: Netforce
Additional Resources¶
- Stock Picking Documentation:
stock.picking - Stock Container Documentation:
stock.container
This documentation is generated for developer onboarding and reference purposes.