Barcode Issue Documentation¶
Overview¶
The Barcode Issue module (barcode.issue) provides a barcode-scanning interface for quickly issuing goods out of inventory. It's a transient wizard that simplifies outbound stock movements through barcode scanning, allowing warehouse staff to ship products for sales orders or returns without manually creating stock pickings.
Model Information¶
Model Name: barcode.issue
Display Name: Barcode Issue
Key Fields: None (transient model)
Features¶
- ❌ Audit logging disabled (transient model)
- ❌ Multi-company support (not enforced)
- ✅ Transient model (wizard - session data only)
- ✅ Container support (issue entire containers)
Purpose¶
- ✅ Fast barcode-based goods issuing
- ✅ Integration with sales orders
- ✅ Container-based picking (scan container, issue all contents)
- ✅ Lot/serial number tracking
- ✅ Automatic stock picking creation
- ✅ Real-time inventory updates
Key Fields Reference¶
Header Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
location_from_id |
Many2One | ❌ | Source location (internal only) |
location_to_id |
Many2One | ❌ | Destination location (non-internal) |
journal_id |
Many2One | ❌ | Stock journal for issuing |
related_id |
Reference | ❌ | Link to SO or PO (returns) |
container_from_id |
Many2One | ❌ | Source container to issue |
state |
Selection | ✅ | pending/done (default: done) |
Line Fields (barcode.issue.line)¶
| Field | Type | Required | Description |
|---|---|---|---|
wizard_id |
Many2One | ✅ | Parent wizard |
product_id |
Many2One | ✅ | Product being issued |
qty |
Decimal | ✅ | Quantity issued |
uom_id |
Many2One | ✅ | Unit of measurement |
qty2 |
Decimal | ❌ | Secondary quantity |
lot_id |
Many2One | ❌ | Lot/serial number |
container_from_id |
Many2One | ❌ | Source container |
container_to_id |
Many2One | ❌ | Destination container |
related_id |
Reference | ❌ | Related order line |
notes |
Text | ❌ | Additional notes |
API Methods¶
1. Create Barcode Issue Session¶
Method: create(vals, context)
Creates a new barcode issuing session.
Example:
# Create issuing session for sales order
wizard_id = get_model("barcode.issue").create({
"related_id": "sale.order,789",
"location_from_id": warehouse_loc_id,
"journal_id": shipping_journal_id,
"state": "done"
})
2. Fill Products¶
Method: fill_products(ids, context)
Auto-populates products from container or related order.
Behavior: - If container_from_id set: Issues entire container contents - If Sales Order linked: Adds remaining qty to deliver - If Purchase Order linked: Adds received qty (for supplier returns)
Example:
# Option 1: Issue entire container
wizard.write({"container_from_id": pallet_id})
wizard.fill_products() # Loads all products in container
# Option 2: Fill from sales order
wizard.write({"related_id": "sale.order,123"})
wizard.fill_products() # Loads products from SO
3. Validate and Create Picking¶
Method: validate(ids, context)
Creates goods issue picking from scanned items.
Returns:
{
"next": {
"name": "pick_out",
"mode": "page",
"active_id": pick_id
},
"flash": "Goods issue GI-2025-001 created successfully"
}
Example:
result = get_model("barcode.issue").validate([wizard_id])
# Creates stock.picking type="out"
# Opens the created picking
4. Clear Session¶
Method: clear(ids, context)
Clears wizard data for next issue.
Common Use Cases¶
Use Case 1: Ship Sales Order¶
# 1. Create session
wizard_id = get_model("barcode.issue").create({
"location_from_id": warehouse_id,
"journal_id": shipping_journal_id,
"related_id": "sale.order,456"
})
# 2. Auto-fill from SO
wizard = get_model("barcode.issue").browse(wizard_id)
wizard.fill_products()
# 3. Scan lot numbers for each product
for line in wizard.lines:
# Scan lot barcode
line.write({"lot_id": scanned_lot_id})
# 4. Validate and ship
wizard.validate()
Use Case 2: Issue Entire Container¶
# Quickly ship a pre-packed container/pallet
# 1. Create session
wizard_id = get_model("barcode.issue").create({
"location_from_id": warehouse_id,
"location_to_id": customer_loc_id,
"journal_id": shipping_journal_id
})
wizard = get_model("barcode.issue").browse(wizard_id)
# 2. Scan container barcode
wizard.write({"container_from_id": pallet_id})
# 3. Auto-fill all contents
wizard.fill_products()
# All products/lots in container now listed
# 4. Validate and ship entire container
wizard.validate()
Use Case 3: Supplier Return¶
# Return defective goods to supplier
wizard_id = get_model("barcode.issue").create({
"related_id": "purchase.order,789", # Original PO
"location_from_id": warehouse_id,
"journal_id": return_journal_id
})
wizard = get_model("barcode.issue").browse(wizard_id)
wizard.fill_products() # Loads received items
# Scan defective items to return
wizard.validate() # Creates goods issue back to supplier
Best Practices¶
1. Container-Based Picking¶
# Good: Use containers for efficiency
wizard.write({"container_from_id": pallet_id})
wizard.fill_products() # One scan, all products
# Slower: Manual item-by-item scanning
for product in order_products:
# scan each individually...
2. Link to Sales Orders¶
# Good: Traceability and accuracy
wizard.write({"related_id": "sale.order,123"})
wizard.fill_products()
# Avoid: Manual without SO link
# ... hard to track which order being shipped ...
Related Models¶
| Model | Relationship | Description |
|---|---|---|
barcode.issue.line |
One2Many | Issued product lines |
stock.picking |
Created | Generates goods issue |
stock.location |
Many2One | From/to locations |
sale.order |
Reference | Sales order being shipped |
stock.container |
Many2One | Source container |
stock.lot |
Many2One | Lot/serial numbers |
Troubleshooting¶
"Product list is empty"¶
Cause: No products scanned
Solution: Add lines or use fill_products()
"Customer location not found"¶
Cause: No type="customer" location
Solution: Create customer location
"Container is empty"¶
Cause: No stock in specified container
Solution: Verify container has inventory
Version History¶
Last Updated: October 2025
Model Version: barcode_issue.py
Framework: Netforce
This documentation is generated for developer onboarding and reference purposes.