FG Scan form validation improvements with warehouse module updates
- Fixed 3 JavaScript syntax errors in fg_scan.html (lines 951, 840-950, 1175-1215) - Restored form field validation with proper null safety checks - Re-enabled auto-advance between form fields - Re-enabled CP code auto-complete with hyphen detection - Updated validation error messages with clear format specifications and examples - Added autocomplete='off' to all input fields - Removed auto-prefix correction feature - Updated warehouse routes and modules for box assignment workflow - Added/improved database initialization scripts - Updated requirements.txt dependencies Format specifications implemented: - Operator Code: OP + 2 digits (example: OP01, OP99) - CP Code: CP + 8 digits + hyphen + 4 digits (example: CP00000000-0001) - OC1/OC2 Codes: OC + 2 digits (example: OC01, OC99) - Defect Code: 3 digits only
This commit is contained in:
@@ -211,3 +211,227 @@ def delete_multiple_locations(location_ids):
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting multiple locations: {e}")
|
||||
return False, f"Error deleting locations: {str(e)}"
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Set Boxes Locations - Functions for assigning boxes to locations
|
||||
# ============================================================================
|
||||
|
||||
def search_box_by_number(box_number):
|
||||
"""Search for a box by its number
|
||||
|
||||
Returns:
|
||||
tuple: (success: bool, box_data: dict or None, status_code: int)
|
||||
"""
|
||||
try:
|
||||
if not box_number or not str(box_number).strip():
|
||||
return False, None, 400
|
||||
|
||||
conn = get_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
b.id,
|
||||
b.box_number,
|
||||
b.status,
|
||||
b.location_id,
|
||||
COALESCE(l.location_code, 'Not assigned') as location_code,
|
||||
b.created_at
|
||||
FROM boxes_crates b
|
||||
LEFT JOIN warehouse_locations l ON b.location_id = l.id
|
||||
WHERE b.box_number = %s
|
||||
""", (str(box_number).strip(),))
|
||||
|
||||
result = cursor.fetchone()
|
||||
cursor.close()
|
||||
|
||||
if not result:
|
||||
return False, None, 404
|
||||
|
||||
box_data = {
|
||||
'id': result[0],
|
||||
'box_number': result[1],
|
||||
'status': result[2],
|
||||
'location_id': result[3],
|
||||
'location_code': result[4],
|
||||
'created_at': str(result[5])
|
||||
}
|
||||
|
||||
return True, box_data, 200
|
||||
except Exception as e:
|
||||
logger.error(f"Error searching box: {e}")
|
||||
return False, None, 500
|
||||
|
||||
|
||||
def search_location_with_boxes(location_code):
|
||||
"""Search for a location and get all boxes assigned to it
|
||||
|
||||
Returns:
|
||||
tuple: (success: bool, data: dict, status_code: int)
|
||||
"""
|
||||
try:
|
||||
if not location_code or not str(location_code).strip():
|
||||
return False, {}, 400
|
||||
|
||||
conn = get_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Get location info
|
||||
cursor.execute("""
|
||||
SELECT id, location_code, size, description
|
||||
FROM warehouse_locations
|
||||
WHERE location_code = %s
|
||||
""", (str(location_code).strip(),))
|
||||
|
||||
location = cursor.fetchone()
|
||||
|
||||
if not location:
|
||||
cursor.close()
|
||||
return False, {'error': f'Location "{location_code}" not found'}, 404
|
||||
|
||||
location_id = location[0]
|
||||
|
||||
# Get all boxes in this location
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
id,
|
||||
box_number,
|
||||
status,
|
||||
created_at
|
||||
FROM boxes_crates
|
||||
WHERE location_id = %s
|
||||
ORDER BY id DESC
|
||||
""", (location_id,))
|
||||
|
||||
boxes = cursor.fetchall()
|
||||
cursor.close()
|
||||
|
||||
location_data = {
|
||||
'id': location[0],
|
||||
'location_code': location[1],
|
||||
'size': location[2],
|
||||
'description': location[3]
|
||||
}
|
||||
|
||||
boxes_list = []
|
||||
for box in boxes:
|
||||
boxes_list.append({
|
||||
'id': box[0],
|
||||
'box_number': box[1],
|
||||
'status': box[2],
|
||||
'created_at': str(box[3])
|
||||
})
|
||||
|
||||
return True, {'location': location_data, 'boxes': boxes_list}, 200
|
||||
except Exception as e:
|
||||
logger.error(f"Error searching location: {e}")
|
||||
return False, {'error': str(e)}, 500
|
||||
|
||||
|
||||
def assign_box_to_location(box_id, location_code):
|
||||
"""Assign a box to a warehouse location
|
||||
|
||||
Returns:
|
||||
tuple: (success: bool, message: str, status_code: int)
|
||||
"""
|
||||
try:
|
||||
if not box_id or not location_code:
|
||||
return False, 'Box ID and location code are required', 400
|
||||
|
||||
conn = get_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if location exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM warehouse_locations
|
||||
WHERE location_code = %s
|
||||
""", (location_code,))
|
||||
|
||||
location = cursor.fetchone()
|
||||
|
||||
if not location:
|
||||
cursor.close()
|
||||
return False, f'Location "{location_code}" not found', 404
|
||||
|
||||
location_id = location[0]
|
||||
|
||||
# Get box info
|
||||
cursor.execute("""
|
||||
SELECT box_number FROM boxes_crates WHERE id = %s
|
||||
""", (box_id,))
|
||||
|
||||
box = cursor.fetchone()
|
||||
|
||||
if not box:
|
||||
cursor.close()
|
||||
return False, 'Box not found', 404
|
||||
|
||||
# Update box location
|
||||
cursor.execute("""
|
||||
UPDATE boxes_crates
|
||||
SET location_id = %s, updated_at = NOW()
|
||||
WHERE id = %s
|
||||
""", (location_id, box_id))
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
|
||||
return True, f'Box "{box[0]}" assigned to location "{location_code}"', 200
|
||||
except Exception as e:
|
||||
logger.error(f"Error assigning box to location: {e}")
|
||||
return False, f'Error: {str(e)}', 500
|
||||
|
||||
|
||||
def move_box_to_new_location(box_id, new_location_code):
|
||||
"""Move a box from current location to a new location
|
||||
|
||||
Returns:
|
||||
tuple: (success: bool, message: str, status_code: int)
|
||||
"""
|
||||
try:
|
||||
if not box_id or not new_location_code:
|
||||
return False, 'Box ID and new location code are required', 400
|
||||
|
||||
conn = get_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if new location exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM warehouse_locations
|
||||
WHERE location_code = %s
|
||||
""", (new_location_code,))
|
||||
|
||||
location = cursor.fetchone()
|
||||
|
||||
if not location:
|
||||
cursor.close()
|
||||
return False, f'Location "{new_location_code}" not found', 404
|
||||
|
||||
new_location_id = location[0]
|
||||
|
||||
# Get box info
|
||||
cursor.execute("""
|
||||
SELECT box_number FROM boxes_crates WHERE id = %s
|
||||
""", (box_id,))
|
||||
|
||||
box = cursor.fetchone()
|
||||
|
||||
if not box:
|
||||
cursor.close()
|
||||
return False, 'Box not found', 404
|
||||
|
||||
# Update box location
|
||||
cursor.execute("""
|
||||
UPDATE boxes_crates
|
||||
SET location_id = %s, updated_at = NOW()
|
||||
WHERE id = %s
|
||||
""", (new_location_id, box_id))
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
|
||||
return True, f'Box "{box[0]}" moved to location "{new_location_code}"', 200
|
||||
except Exception as e:
|
||||
logger.error(f"Error moving box: {e}")
|
||||
return False, f'Error: {str(e)}', 500
|
||||
|
||||
Reference in New Issue
Block a user