- 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
19 KiB
Assign to Box Form Analysis - New App vs Old App
Executive Summary
The "Assign to Box" modal form appears after scanning a product with defect code 000 (good quality) when "Scan to Boxes" is enabled. This document provides a detailed analysis of the form structure in both the new app and old app.
Status: The new app modal structure is implemented and functional ✅ Last Updated: January 29, 2026
Modal Form Structure Comparison
NEW APP (quality_app-v2)
File: app/templates/modules/quality/fg_scan.html
HTML Structure
<!-- Box Assignment Modal -->
<div id="boxAssignmentModal" class="box-modal" style="display: none;">
<div class="box-modal-content">
<div class="modal-header">
<h2>Assign to Box</h2>
<button type="button" class="modal-close" id="closeModal">×</button>
</div>
<div class="modal-body">
<!-- Display CP Code -->
<p style="margin-bottom: 20px; font-size: 0.95em; font-weight: 500;">
CP Code: <strong id="modal-cp-code" style="color: #007bff;">-</strong>
</p>
<!-- OPTION 1: Quick Box Creation -->
<div style="margin: 20px 0; padding: 15px; background: #f0f8ff; border: 1px solid #cce7ff; border-radius: 5px;">
<button type="button" id="quickBoxLabel" class="btn"
style="width: 100%; background: #28a745; color: white; padding: 10px; font-size: 1em; border: none; border-radius: 4px; cursor: pointer; font-weight: 600;">
📦 Quick Box Label Creation
</button>
<p style="font-size: 0.85em; color: #666; margin-top: 8px; text-align: center;">
Creates new box and prints label immediately
</p>
</div>
<!-- SEPARATOR -->
<div style="text-align: center; margin: 20px 0; color: #999; font-size: 0.9em; letter-spacing: 1px;">
━━━━━━━ OR ━━━━━━━
</div>
<!-- OPTION 2: Scan Existing Box -->
<div style="margin: 20px 0;">
<label for="boxNumber" style="font-weight: 600; display: block; margin-bottom: 8px; color: #333;">Scan Box Number:</label>
<input type="text" id="boxNumber" placeholder="Scan or enter box number"
style="width: 100%; padding: 8px; font-size: 1em; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; font-size: 1.1em;">
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">
Scan an existing box label or enter the box number manually
</p>
</div>
<!-- Quantity Input -->
<div style="margin: 20px 0;">
<label for="boxQty" style="font-weight: 600; display: block; margin-bottom: 8px; color: #333;">Quantity:</label>
<input type="number" id="boxQty" placeholder="Enter quantity" value="1" min="1"
style="width: 100%; padding: 8px; font-size: 1em; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">
How many units to assign to this box
</p>
</div>
</div>
<div class="modal-footer" style="padding: 15px 20px; border-top: 1px solid #eee; display: flex; justify-content: flex-end; gap: 10px;">
<button type="button" class="btn-secondary" id="cancelModal" style="padding: 8px 16px;">Skip</button>
<button type="button" class="btn-submit" id="assignToBox" style="padding: 8px 16px;">Assign to Box</button>
</div>
</div>
</div>
OLD APP (quality_app)
File: py_app/app/templates/fg_scan.html
HTML Structure
<!-- Box Assignment Popup Modal -->
<div id="box-assignment-modal" class="box-modal" style="display: none;">
<div class="box-modal-content">
<div class="box-modal-header">
<h3>Assign to Box</h3>
<span class="box-modal-close" onclick="closeBoxModal()">×</span>
</div>
<div class="box-modal-body">
<p>CP Code: <strong id="modal-cp-code"></strong></p>
<!-- Quick Box Creation -->
<div style="margin: 20px 0; padding: 15px; background: #f0f8ff; border-radius: 5px;">
<button type="button" id="quick-box-create-btn" class="btn" style="width: 100%; background: #28a745; color: white;">
📦 Quick Box Label Creation
</button>
<p style="font-size: 0.85em; color: #666; margin-top: 8px; text-align: center;">
Creates new box and prints label immediately
</p>
</div>
<div style="text-align: center; margin: 15px 0; color: #999;">— OR —</div>
<!-- Scan Existing Box -->
<div style="margin: 20px 0;">
<label style="font-weight: bold;">Scan Box Number:</label>
<input type="text" id="scan-box-input" placeholder="Scan or enter box number" style="width: 100%; padding: 8px; font-size: 1em; margin-top: 5px;">
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">
Scan an existing box label to assign this CP code to that box
</p>
</div>
<div class="box-modal-buttons" style="margin-top: 20px;">
<button type="button" class="btn" onclick="closeBoxModal()" style="background: #6c757d;">Skip</button>
<button type="button" id="assign-to-box-btn" class="btn" style="background: #007bff;">Assign to Box</button>
</div>
</div>
</div>
</div>
Form Fields Comparison
| Field | New App | Old App | Notes |
|---|---|---|---|
| Modal ID | boxAssignmentModal |
box-assignment-modal |
Different naming convention (camelCase vs kebab-case) |
| Header Class | modal-header |
box-modal-header |
Different class names |
| Body Class | modal-body |
box-modal-body |
Different class names |
| Footer Element | modal-footer div |
Part of box-modal-body |
New app has separate footer container |
| CP Code Display | modal-cp-code |
modal-cp-code |
✅ Same ID |
| Create Box Button | quickBoxLabel |
quick-box-create-btn |
Different button IDs |
| Box Number Input | boxNumber |
scan-box-input |
⚠️ Different input IDs |
| Quantity Input | boxQty |
Not present | New app adds quantity field |
| Skip Button | cancelModal |
Inline onclick="closeBoxModal()" |
New app uses event listener |
| Assign Button | assignToBox |
assign-to-box-btn |
Different button IDs |
| Modal Display Style | display: 'flex' |
display: 'block' |
New app uses flexbox |
Form Fields Details
1. Modal Display Element (boxAssignmentModal / box-assignment-modal)
- Type: Modal Container
- Visibility: Hidden by default (
display: none;) - Display Method (New):
flexlayout - Display Method (Old):
blocklayout - Z-Index: 10000 (ensures modal is above other content)
2. CP Code Display (modal-cp-code)
- Type: Read-only display element
- Purpose: Shows which CP code is being assigned
- Format: Bold, colored text (
#007bffblue in new app) - Population: JavaScript sets this when modal opens
3. Box Number Input (boxNumber / scan-box-input)
- Type: Text input
- Purpose: Accept existing box number via scan or manual entry
- Placeholder: "Scan or enter box number"
- Width: 100% (full modal width)
- Font Size (New): 1.1em (larger, easier for scanning)
- Font Size (Old): 1em
- Borders: Styled with #ddd border, rounded corners
4. Quantity Input (boxQty)
- Type: Number input
- Default Value: 1
- Min Value: 1
- Purpose: Specify how many units to assign to the box
- Status: ✅ New app feature (not in old app)
- Note: Allows quantity-based assignment instead of single-unit default
5. Quick Box Creation Button (quickBoxLabel / quick-box-create-btn)
- Type: Action button
- Color: Green (#28a745)
- Purpose: Create a new box, get box number, and print label immediately
- Width: 100% (full modal width)
- Behavior: Triggers box creation workflow
6. Skip Button (cancelModal / inline onclick)
- Type: Action button
- Color: Gray (#6c757d in old app, CSS class in new app)
- Purpose: Save scan without box assignment
- Behavior (New): Event listener triggers
closeBoxModal()function - Behavior (Old): Direct inline event handler
7. Assign Button (assignToBox / assign-to-box-btn)
- Type: Action button
- Color: Blue (#007bff)
- Purpose: Link CP code to selected box number
- Width: Fixed via padding in footer
- Behavior: Validates inputs, sends API request to link CP to box
Form Submission Flow
NEW APP
User scans product with defect code 000
↓
Form validation succeeds
↓
AJAX POST to /quality/fg_scan
↓
Scan saved to database
↓
Modal displays with:
- CP code filled in
- Box number input focused
- Ready for user input
↓
User selects action:
Option A: Click "📦 Quick Box Label Creation"
→ Creates new box
→ Prints label
→ Assigns CP to new box
Option B: Enter box number + quantity
→ Click "Assign to Box"
→ Validates inputs
→ POST to /quality/api/assign-cp-to-box
→ Links CP to existing box
→ Reloads page
Option C: Click "Skip"
→ Modal closes
→ Page reloads
→ Scan remains unassigned
OLD APP
Same workflow, but:
- No quantity field (always 1 unit)
- No separate footer container
- Quantity not configurable
- Otherwise identical behavior
JavaScript Event Handlers
NEW APP - Assign Button Handler
File: fg_scan.html
document.getElementById('assignToBox').addEventListener('click', async function() {
const boxNumber = document.getElementById('boxNumber').value.trim();
const boxQty = document.getElementById('boxQty').value.trim();
if (!boxNumber) {
showNotification('⚠️ Please enter a box number', 'warning');
return;
}
if (!boxQty || isNaN(boxQty) || parseInt(boxQty) < 1) {
showNotification('⚠️ Please enter a valid quantity', 'warning');
return;
}
try {
this.disabled = true;
this.textContent = '⏳ Assigning...';
// Submit box assignment
const response = await fetch('{{ url_for("quality.assign_cp_to_box") }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({
box_number: boxNumber,
cp_code: currentCpCode,
quantity: boxQty
})
});
if (!response.ok) {
throw new Error(`Server error: ${response.statusText}`);
}
const data = await response.json();
if (data.success) {
showNotification(
`✅ CP ${currentCpCode} assigned to box ${boxNumber}!`,
'success'
);
// Close modal
document.getElementById('boxAssignmentModal').style.display = 'none';
// Clear box inputs
document.getElementById('boxNumber').value = '';
document.getElementById('boxQty').value = '';
// Reload page to show updated scans table after a brief delay
setTimeout(() => {
location.reload();
}, 1000);
} else {
throw new Error(data.error || 'Unknown error');
}
} catch (error) {
console.error('Error:', error);
showNotification(`❌ Error: ${error.message}`, 'error');
} finally {
this.disabled = false;
this.textContent = 'Assign';
}
});
OLD APP - Assign Button Handler
File: py_app/app/templates/fg_scan.html
document.getElementById('assign-to-box-btn').addEventListener('click', async function() {
// Check if scan-to-boxes is enabled
if (!scanToBoxesEnabled) {
showNotification('⚠️ "Scan to Boxes" feature is disabled', 'warning');
closeBoxModal();
return;
}
const boxNumber = document.getElementById('scan-box-input').value.trim();
if (!boxNumber) {
showNotification('⚠️ Please scan or enter a box number', 'warning');
return;
}
try {
await assignCpToBox(boxNumber);
showNotification(`✅ CP ${currentCpCode} assigned to box ${boxNumber}`, 'success');
setTimeout(() => closeBoxModal(), 1000);
} catch (error) {
showNotification('❌ Error: ' + error.message, 'error');
}
});
Key Differences & Observations
✅ Improvements in New App
- Quantity Field: New app adds quantity input (not just 1 unit)
- Flexbox Layout: Modal uses flex for better responsive design
- Better Spacing: More padding and margins for readability
- Font Sizes: Box input is 1.1em (easier for barcode scanners)
- Event Listeners: Consistent event listener pattern (not inline onclick)
- Modal Footer: Separate footer container for better organization
- Error Validation: Separate quantity validation check
- Button Labeling: Clear "Assign to Box" label (not just "Assign")
⚠️ Breaking Changes Between Apps
-
Modal ID: Changed from
box-assignment-modaltoboxAssignmentModal- Any external code referencing old ID will break
-
Input IDs: Changed from
scan-box-inputtoboxNumber- Old app's direct references to element IDs will fail
-
Button IDs: Changed from
quick-box-create-btntoquickBoxLabel- Event listeners must be updated
-
Display Method: Changed from
display: 'block'todisplay: 'flex'- May affect CSS styling
-
Button Handler: Changed from
onclick="closeBoxModal()"to event listener- More scalable but different approach
📊 Form Input Summary
New App Form Fields
- Inputs: 3 fields
- Box Number (text, required)
- Quantity (number, required, min=1, default=1)
- Hidden inputs: currentCpCode (JavaScript variable)
Old App Form Fields
- Inputs: 1 field
- Box Number (text, required)
- Hidden inputs: currentCpCode (JavaScript variable)
Backend API Endpoint Comparison
NEW APP
- Route:
/quality/api/assign-cp-to-box(POST) - Handler:
quality_bp.routein app/modules/quality/routes.py - Parameters:
{ "box_number": "BOX-001", "cp_code": "CP-XXXXXXXXXX", "quantity": 1 }
OLD APP
- Route:
/warehouse/assign_cp_to_box(POST) - Handler:
warehouse_bp.routein py_app/app/routes.py - Parameters: Similar structure but route path differs
Validation Rules
NEW APP Validation
// Box Number Validation
if (!boxNumber) {
showNotification('⚠️ Please enter a box number', 'warning');
return;
}
// Quantity Validation
if (!boxQty || isNaN(boxQty) || parseInt(boxQty) < 1) {
showNotification('⚠️ Please enter a valid quantity', 'warning');
return;
}
OLD APP Validation
const boxNumber = document.getElementById('scan-box-input').value.trim();
if (!boxNumber) {
showNotification('⚠️ Please scan or enter a box number', 'warning');
return;
}
// No quantity validation (always 1)
CSS Classes Used
Modal Container
.box-modal {
position: fixed;
z-index: 10000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.5);
}
.box-modal-content {
background-color: #fefefe;
margin: 10% auto;
padding: 0;
border: 1px solid #888;
width: 500px;
max-width: 90%;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
Buttons
.btn-secondary {
/* Gray button for Skip */
}
.btn-submit {
/* Blue button for Assign to Box */
}
.modal-close {
/* X button in header */
}
Testing Checklist
- Modal appears when scanning product with defect code 000
- CP Code displays correctly in modal
- Box Number input accepts manual entry
- Box Number input accepts barcode scan
- Quantity field defaults to 1
- Quantity validation rejects non-numeric values
- Quantity validation rejects values < 1
- "Skip" button closes modal without assignment
- "Assign to Box" button validates inputs before submission
- "Assign to Box" button shows loading state ("⏳ Assigning...")
- Page reloads after successful assignment
- Error messages display for failed assignments
- "Quick Box Label Creation" button triggers box creation workflow
- Modal closes cleanly after assignment or skip
- "X" close button works and triggers reload
Summary Table
| Aspect | New App | Old App | Status |
|---|---|---|---|
| Modal ID | boxAssignmentModal |
box-assignment-modal |
🔄 Different |
| Box Input ID | boxNumber |
scan-box-input |
🔄 Different |
| Quantity Field | ✅ Present | ❌ Missing | ✅ Enhanced |
| Layout | Flexbox | Block | 🔄 Different |
| Footer Container | ✅ Separate | ❌ Inline | ✅ Better |
| Validation | Full | Partial | ✅ Better |
| Button IDs | camelCase | kebab-case | 🔄 Different |
| API Route | /quality/api/assign-cp-to-box |
/warehouse/assign_cp_to_box |
🔄 Different |
| Functionality | ✅ Full | ✅ Full | ✅ Both work |
Recommendations
- ✅ Form Structure: The new app's form structure is well-organized and improved
- ✅ Quantity Support: Adding quantity field is a good enhancement
- ✅ Layout: Flexbox is better for responsive design
- ✅ Validation: More comprehensive validation is better
- ⚠️ API Route Names: Consider standardizing route naming across apps
- ⚠️ Element IDs: Document ID changes for future developers
- ⚠️ Migration: Any code expecting old IDs needs updating