Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5f7e8a4
Update Dockerfile
Idea-Junkie Feb 13, 2026
4770404
Merge branch 'inventree:master' into master
Idea-Junkie Feb 16, 2026
1b65627
Update Dockerfile
Idea-Junkie Feb 16, 2026
2d1a57e
Merge branch 'inventree:master' into master
Idea-Junkie Feb 17, 2026
ebd3b8b
Added More Info In Barcode API Scans
Idea-Junkie Feb 17, 2026
78cc917
Add NotFound to base Response
Idea-Junkie Feb 17, 2026
218a5dd
Added Simple Plugin Debug
Idea-Junkie Feb 17, 2026
facee25
Added finishing touches for API Error
Idea-Junkie Feb 18, 2026
462193d
clean up + comments
Idea-Junkie Feb 18, 2026
cd46859
Added No Supplier Plugin error
Idea-Junkie Feb 18, 2026
f616a1f
Merge branch 'master' into More-Barcode-Error-messages
matmair Feb 18, 2026
e03877e
fix style
matmair Feb 18, 2026
8ac9444
Formatting and fixing comments
Idea-Junkie Feb 18, 2026
af2270f
Merge branch 'More-Barcode-Error-messages' of https://github.com/Idea…
Idea-Junkie Feb 18, 2026
9f9006c
duplicate code fix
Idea-Junkie Feb 18, 2026
1dbdc0e
fixed some variable names
Idea-Junkie Feb 18, 2026
1876f8f
Small move of variables
Idea-Junkie Feb 19, 2026
1ae47a1
Updated To Nested Debug Dictionary
Idea-Junkie Feb 19, 2026
6064712
Added notes to documentation
Idea-Junkie Feb 19, 2026
051a814
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 19, 2026
e0658dc
Update docs/docs/app/barcode.md
Idea-Junkie Feb 19, 2026
438c4c4
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 19, 2026
96f4b92
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 22, 2026
cb9c89a
Updated JSON plugin debug name
Idea-Junkie Feb 22, 2026
fa3ccbd
Merge branch 'master' into More-Barcode-Error-messages
matmair Feb 23, 2026
b9eb645
fix style
matmair Feb 23, 2026
8b04510
DNE style fix
Idea-Junkie Feb 23, 2026
7aca9d3
Merge branch 'More-Barcode-Error-messages' of https://github.com/Idea…
Idea-Junkie Feb 23, 2026
ea32fa8
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 23, 2026
bcc0381
Style fix(again)
Idea-Junkie Feb 23, 2026
650ba9c
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 23, 2026
1f36f1e
Merge branch 'master' into More-Barcode-Error-messages
matmair Feb 23, 2026
5abadba
Merge branch 'master' into More-Barcode-Error-messages
SchrodingersGat Feb 24, 2026
c20be4a
Merge branch 'master' into More-Barcode-Error-messages
Idea-Junkie Feb 26, 2026
8ecb2bf
Merge branch 'master' into More-Barcode-Error-messages
matmair Mar 5, 2026
7b0ef13
Merge branch 'master' into More-Barcode-Error-messages
SchrodingersGat Mar 22, 2026
163b857
Merge branch 'master' into More-Barcode-Error-messages
matmair Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/docs/app/barcode.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ Transfer the currently selected stock location into another location. Scanning a

Receive incoming purchase order items into the selected location. Scanning a *new* barcode which is associated with an item in an incoming purchase order will receive the item into the selected location.

*Note: Both purchase order number and supplier SKU's are required to be found on the barcode for this function to find the associated line item. Missing one will lead to an error.*

#### Scan Items Into Location

the *Scan Items Into Location* action allows you to scan items into the selected location. Scanning a valid barcode associated with a stock item (already in the database) will result in that item being transferred to the selected location.
Expand Down Expand Up @@ -105,6 +107,8 @@ From the [Purchase Order detail page](./po.md#purchase-order-detail) page, the f

Receive incoming purchase order items against the selected purchase order. Scanning a *new* barcode which is associated with an item in an incoming purchase order will receive the item into stock.

*Note: supplier SKU's are required to be found on the barcode for this function to find the associated line item.*

### Sales Order Actions

The following barcode actions are available for [Sales Orders](./so.md):
Expand Down
72 changes: 69 additions & 3 deletions src/backend/InvenTree/plugin/base/barcodes/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,23 @@ def handle_barcode(self, barcode: str, request, **kwargs):
# Now, look just for "supplier-barcode" plugins
plugins = registry.with_mixin(PluginMixinEnum.SUPPLIER_BARCODE)

plugin_slug = None

plugin_response = None

plugin_error = None

no_supplier_plugin_error = []

supplier_purchase_order = None

plugin_supplier = None

supplier_part = None

for current_plugin in plugins:
try:
# Will either Output Debugresponse if No_Match is True or return the regular response if No_Match is False
result = current_plugin.scan_receive_item(
barcode,
request.user,
Expand All @@ -546,12 +559,58 @@ def handle_barcode(self, barcode: str, request, **kwargs):
line_item=line_item,
auto_allocate=auto_allocate,
)

except Exception:
log_error('BarcodePOReceive.handle_barcode', plugin=current_plugin.slug)
continue

if result is None:
continue
no_match = result.get('no_match', True)

# No_Match Determines if it found a exact match for all the required fields from scan_recieve_item
if no_match is True:
supplier_found = False

try:
plugin_slug = current_plugin.slug
supplier_purchase_order = result.get('PO')
plugin_supplier = result.get('supplier')
supplier_part = result.get('supplier_part')
except KeyError as e:
log_error(
f'BarcodePOReceive.handle_barcode debugresponse: KeyError {e}'
)
continue

# Supplier does not have associated Supplier ID
if plugin_supplier is None:
no_supplier_plugin_error.append(plugin_slug)
continue

# No Purchase Order or Supplier Part Found
if supplier_purchase_order is None and supplier_part is None:
continue

# Purchase Order exists and is found but Supplier part does not exist
if supplier_purchase_order != None and supplier_part is None:
# Supplier was Found
supplier_found = True
plugin_error = _('Purchase order Found\rNo supplier Part Match')

# Supplier Part is Found but Purchase Order does not exist
elif supplier_purchase_order is None and supplier_part != None:
# Supplier was Found
supplier_found = True
plugin_error = _('Supplier Part Found\rNo Purchase Order Match')

# Supplier for PO or Supplier part in barcode was found
if supplier_found is True:
# Adds info on for what was found in the barcode
response['supplier_matches'] = {
'purchase_order': supplier_purchase_order,
'no_match': no_match,
'supplier': plugin_supplier,
'supplier_part': supplier_part,
}

if 'error' in result:
logger.info(
Expand All @@ -569,13 +628,20 @@ def handle_barcode(self, barcode: str, request, **kwargs):

response['plugin'] = plugin.name if plugin else None

if plugin_response:
# If there is a plugin response, and there is a match (no_match = false), combine the dictionaries
if plugin_response and plugin_response.get('no_match') is False:
response = {**response, **plugin_response}
elif no_supplier_plugin_error:
response['no_supplier_plugin_error'] = no_supplier_plugin_error

# A plugin has not been found!
if plugin is None:
response['error'] = _('No plugin match for supplier barcode')

# A plugin was found, with a Error
elif plugin_error:
response['error'] = plugin_error

self.log_scan(request, response, 'success' in response)

if 'error' in response:
Expand Down
43 changes: 31 additions & 12 deletions src/backend/InvenTree/plugin/base/barcodes/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def scan_receive_item(
location=None,
auto_allocate: bool = True,
**kwargs,
) -> dict | None:
) -> dict:
"""Attempt to receive an item against a PurchaseOrder via barcode scanning.

Arguments:
Expand All @@ -344,32 +344,50 @@ def scan_receive_item(
# Extract supplier information
supplier = supplier or self.get_supplier(cache=True)

if not supplier:
"""Construct Debug Response
This is returned if a perfect match is not found with the info provided from the barcode

Response Info:
'supplier': get supplier ID
'PO': Represented for "Purchase Order", find PO number to supplier
'supplier_part': find supplier part info to supplier
'no_match': Boolean, did we find a perfect match with info given? False is Yes, True is No
"""
debug_response = {}

if supplier is None:
# No supplier information available
return None
debug_response['supplier'] = None
else:
debug_response['supplier'] = supplier.name

# Extract purchase order information
purchase_order = purchase_order or self.get_purchase_order()

if not purchase_order or purchase_order.supplier != supplier:
if purchase_order is None or purchase_order.supplier != supplier:
# Purchase order does not match supplier
return None
debug_response['PO'] = None
else:
debug_response['PO'] = purchase_order.reference

supplier_part = self.get_supplier_part()

if not supplier_part:
if supplier_part is None:
# No supplier part information available
return None
debug_response['supplier_part'] = None
else:
debug_response['supplier_part'] = supplier_part.part

# Attempt to find matching line item
if not line_item:
if not line_item and purchase_order != None:
line_items = purchase_order.lines.filter(part=supplier_part)
if line_items.count() == 1:
line_item = line_items.first()

if not line_item:
# No line item information available
return None
# If Purchase Order or Supplier Part does not exist, throw debug response
if debug_response['PO'] is None or debug_response['supplier_part'] is None:
debug_response['no_match'] = True
return debug_response

if line_item.part != supplier_part:
return {'error': _('Supplier part does not match line item')}
Expand Down Expand Up @@ -406,7 +424,8 @@ def scan_receive_item(
'supplier_part': supplier_part.pk,
'purchase_order': purchase_order.pk,
'location': location.pk if location else None,
}
},
'no_match': False,
}

if action_required:
Expand Down
Loading