Skip to content

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...
# 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 ...

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.