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:
Quality App Developer
2026-01-30 10:50:06 +02:00
parent ac24e20fe1
commit b15cc93b9d
48 changed files with 16452 additions and 607 deletions

View File

@@ -308,6 +308,97 @@ def create_tables():
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'worker_manager_bindings'")
# Warehouse Locations table
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS warehouse_locations (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
location_code VARCHAR(12) NOT NULL UNIQUE,
size INT,
description VARCHAR(250),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'warehouse_locations'")
# Boxes Crates table (for quick box checkpoint)
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS boxes_crates (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
box_number VARCHAR(20) NOT NULL UNIQUE,
status ENUM('open', 'closed') DEFAULT 'open',
location_id BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
FOREIGN KEY (location_id) REFERENCES warehouse_locations(id) ON DELETE SET NULL,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_box_number (box_number),
INDEX idx_status (status),
INDEX idx_location_id (location_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'boxes_crates'")
# Box Contents table (CP-to-Box mapping)
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS box_contents (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
box_id BIGINT NOT NULL,
cp_code VARCHAR(50) NOT NULL,
quantity INT DEFAULT 1,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (box_id) REFERENCES boxes_crates(id) ON DELETE CASCADE,
INDEX idx_box_id (box_id),
INDEX idx_cp_code (cp_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'box_contents'")
# FG Scan Orders table
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS scanfg_orders (
id INT AUTO_INCREMENT PRIMARY KEY,
operator_code VARCHAR(50),
CP_full_code VARCHAR(50),
OC1_code VARCHAR(50),
OC2_code VARCHAR(50),
quality_code VARCHAR(10),
date DATE,
time TIME,
approved_quantity INT DEFAULT 0,
rejected_quantity INT DEFAULT 0,
box_id BIGINT,
location_id BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (box_id) REFERENCES boxes_crates(id) ON DELETE SET NULL,
FOREIGN KEY (location_id) REFERENCES warehouse_locations(id) ON DELETE SET NULL,
INDEX idx_cp_code (CP_full_code),
INDEX idx_operator (operator_code),
INDEX idx_date (date),
INDEX idx_box_id (box_id),
INDEX idx_location_id (location_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'scanfg_orders'")
# CP Location History table (audit trail)
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS cp_location_history (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cp_code VARCHAR(50) NOT NULL,
box_id BIGINT NOT NULL,
from_location_id BIGINT,
to_location_id BIGINT NOT NULL,
moved_by INT,
moved_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
reason VARCHAR(100),
FOREIGN KEY (box_id) REFERENCES boxes_crates(id) ON DELETE CASCADE,
FOREIGN KEY (from_location_id) REFERENCES warehouse_locations(id) ON DELETE SET NULL,
FOREIGN KEY (to_location_id) REFERENCES warehouse_locations(id) ON DELETE CASCADE,
FOREIGN KEY (moved_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_cp_code (cp_code),
INDEX idx_box_id (box_id),
INDEX idx_moved_at (moved_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'cp_location_history'")
conn.commit()
conn.close()
logger.info("✓ All tables created successfully")
@@ -394,6 +485,26 @@ def insert_default_data():
else:
logger.info(" ✓ Admin user already exists")
# Insert default warehouse locations
logger.info(" Creating default warehouse locations...")
warehouse_locations = [
('FG_INCOMING', 'Finished Goods Incoming', 'Initial receiving area for finished goods from production'),
('TRUCK_LOADING', 'Truck Loading Area', 'Loading and staging area for truck shipments'),
]
for location_code, location_name, description in warehouse_locations:
try:
cursor.execute(
"INSERT IGNORE INTO warehouse_locations (location_code, size, description) VALUES (%s, %s, %s)",
(location_code, 100, description)
)
logger.info(f" ✓ Warehouse location '{location_code}' created ({location_name})")
except pymysql.Error as e:
if "duplicate" in str(e).lower():
logger.info(f" ✓ Warehouse location '{location_code}' already exists")
else:
logger.warning(f" ⚠ Warehouse location '{location_code}': {e}")
# Insert default application settings
logger.info(" Creating default application settings...")
default_settings = [