Files
inventree-stock-tool/FIXES_APPLIED.md
grabowski ab0d1ae0db Initial commit: InvenTree Stock Tool v2
A comprehensive barcode scanning application for InvenTree inventory management.

Features:
- Multi-mode operation (Add/Update/Check/Locate stock)
- Smart duplicate prevention when adding stock
- Barcode scanning with automatic part code cleaning
- Real-time server connection monitoring
- Part information display with images
- Debug mode for troubleshooting

Fixes applied:
- Fixed encoding issues with non-ASCII characters in barcodes
- Fixed API response handling for list and dict formats
- Implemented duplicate prevention using PATCH to update existing stock
- Added comprehensive error handling and logging

Includes test suite for verification of all fixes.
2025-10-28 16:31:48 +07:00

197 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stock Tool GUI v2 - Fixes Applied
## Summary
Fixed three critical issues in `stock_tool_gui_v2.py`:
1. ✅ Encoding issue with barcode part numbers
2. ✅ API response handling causing "'list' object has no attribute 'get'" errors
3. ✅ Duplicate stock items being created when adding to existing location
---
## Issue 1: Encoding Problem with Part Numbers
### Problem
Raw scan data contained: `pm:STHW4-DU-HS24041¡­`
The non-ASCII characters (¡­) were being included in the parsed part number.
### Root Cause
The `parse_scan()` function was not cleaning/sanitizing the extracted part codes.
### Fix Applied
Added `clean_part_code()` helper function that:
- Filters out all non-ASCII characters
- Keeps only printable ASCII characters (codes 32-126)
- Removes encoding artifacts like `¡­`
### Location
File: `stock_tool_gui_v2.py`
Function: `parse_scan()` (lines 294-348)
### Result
- **Before**: `STHW4-DU-HS24041¡­`
- **After**: `STHW4-DU-HS24041`
---
## Issue 2: API Response Handling Error
### Problem
Error: `'list' object has no attribute 'get'`
- Stock not being added to InvenTree
- Stock levels not updating after adding items
### Root Cause
The InvenTree API POST response can return either:
- A dictionary: `{'pk': 123, 'quantity': 150, ...}`
- A list: `[{'pk': 123, 'quantity': 150, ...}]`
The code was assuming it would always be a dict and calling `.get()` directly on the response, which failed when the API returned a list.
### Locations with the Bug
1. `_add_stock()` function - line 806 (original)
2. `_update_stock()` function - line 865 (original)
3. Misplaced `get_stock_level()` function at top of file
### Fixes Applied
#### 1. Fixed `_add_stock()` function (lines 797-827)
**Before:**
```python
r.raise_for_status()
sid = r.json().get('pk', r.json().get('id')) # ❌ Fails if response is list
```
**After:**
```python
r.raise_for_status()
# Handle response - might be list or dict
response_data = r.json()
if isinstance(response_data, list):
stock_item = response_data[0] if response_data else {}
else:
stock_item = response_data
sid = stock_item.get('pk', stock_item.get('id')) # ✓ Works for both
```
#### 2. Fixed `_update_stock()` function (lines 858-875)
Applied the same fix for consistency.
#### 3. Moved `get_stock_level()` function (lines 256-270)
- Removed misplaced definition from top of file (before imports)
- Re-added in correct location after `find_stock_item()` function
---
## Issue 3: Duplicate Stock Items Created
### Problem
When scanning a part that already exists at a storage location, the tool was creating a duplicate stock item instead of adding to the existing quantity.
**Example:**
- Location C64_PSU has 150x STHW4-DU-HS24041
- Scan barcode to add 100 more
- **Bug**: Creates second stock item with 100 (now have two separate items)
- **Expected**: Updates existing item to 250
### Root Cause
The `_add_stock()` function was always creating a new stock item via POST without checking if one already existed at that location.
### Fix Applied (lines 791-845)
**Before:**
```python
def _add_stock(self, part_id: int, part_code: str, quantity: Optional[int]):
# Always creates new stock item - WRONG!
r = requests.post(f"{self.host}/api/stock/", ...)
```
**After:**
```python
def _add_stock(self, part_id: int, part_code: str, quantity: Optional[int]):
# Check if stock item already exists at this location
existing = find_stock_item(self.host, self.token, part_id, self.current_loc)
if existing:
# Stock exists - update the quantity by adding to it
sid = existing.get('pk', existing.get('id'))
new_stock = current_stock + quantity
r = requests.patch(f"{self.host}/api/stock/{sid}/",
json={'quantity': new_stock})
# Updates existing item ✓
else:
# No existing stock - create new stock item
r = requests.post(f"{self.host}/api/stock/", ...)
# Creates new item ✓
```
### Behavior Now
- **Same part + same location** = Updates existing stock item (no duplicate)
- **Same part + different location** = Creates new stock item (correct)
- **New part** = Creates new stock item (correct)
---
## Testing
### Test Files Created
1. `test_parse_fix.py` - Verifies encoding fix
2. `test_stock_level.py` - Verifies stock level retrieval
3. `test_add_stock.py` - Verifies API response handling
4. `test_duplicate_handling.py` - Verifies duplicate prevention logic
### Test Results
All tests pass ✓
---
## Expected Behavior Now
### When scanning barcode:
```
{pbn:PICK251017100019,on:WM2510170196,pc:C18548292,pm:STHW4-DU-HS24041¡­,qty:150,mc:,cc:1,pdi:180368458,hp:null,wc:JS}
```
The tool will:
1. ✅ Extract clean part number: `STHW4-DU-HS24041`
2. ✅ Extract quantity: `150`
3. ✅ Check if part already exists at current location
4. ✅ If exists: Add to existing stock (no duplicate created)
5. ✅ If new: Create new stock item
6. ✅ Display updated stock levels
7. ✅ Handle both dict and list API responses correctly
### Example Workflows
**Scenario 1: First time adding part to location**
- Scan: Part STHW4-DU-HS24041, Qty: 150
- Result: Creates new stock item
- Log: `✔ Created new stock item for 'STHW4-DU-HS24041' → StockItem #123`
- Log: `📊 Stock: 0 → 150 (+150)`
**Scenario 2: Adding more of same part to same location**
- Scan: Part STHW4-DU-HS24041, Qty: 100
- Result: Updates existing stock item #123
- Log: `✔ Added 100× to existing 'STHW4-DU-HS24041' (StockItem #123)`
- Log: `📊 Stock: 150 → 250 (+100)`
- **No duplicate created!** ✓
**Scenario 3: Adding same part to different location**
- Change location to C65_PSU
- Scan: Part STHW4-DU-HS24041, Qty: 75
- Result: Creates new stock item #124 at the new location
- Log: `✔ Created new stock item for 'STHW4-DU-HS24041' → StockItem #124`
- Log: `📊 Stock: 0 → 75 (+75)`
---
## Files Modified
- `stock_tool_gui_v2.py` - Main application file
## Files Created
- `test_parse_fix.py` - Test for encoding fix
- `test_stock_level.py` - Test for stock level retrieval
- `test_add_stock.py` - Test for API response handling
- `FIXES_APPLIED.md` - This document