Files
quality_app-v2/documentation/ASSIGN_TO_BOX_FORM_ANALYSIS.md
Quality App Developer b15cc93b9d 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
2026-01-30 10:50:06 +02:00

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">&times;</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()">&times;</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): flex layout
  • Display Method (Old): block layout
  • 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 (#007bff blue 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

  1. Quantity Field: New app adds quantity input (not just 1 unit)
  2. Flexbox Layout: Modal uses flex for better responsive design
  3. Better Spacing: More padding and margins for readability
  4. Font Sizes: Box input is 1.1em (easier for barcode scanners)
  5. Event Listeners: Consistent event listener pattern (not inline onclick)
  6. Modal Footer: Separate footer container for better organization
  7. Error Validation: Separate quantity validation check
  8. Button Labeling: Clear "Assign to Box" label (not just "Assign")

⚠️ Breaking Changes Between Apps

  1. Modal ID: Changed from box-assignment-modal to boxAssignmentModal

    • Any external code referencing old ID will break
  2. Input IDs: Changed from scan-box-input to boxNumber

    • Old app's direct references to element IDs will fail
  3. Button IDs: Changed from quick-box-create-btn to quickBoxLabel

    • Event listeners must be updated
  4. Display Method: Changed from display: 'block' to display: 'flex'

    • May affect CSS styling
  5. Button Handler: Changed from onclick="closeBoxModal()" to event listener

    • More scalable but different approach

📊 Form Input Summary

New App Form Fields

  • Inputs: 3 fields
    1. Box Number (text, required)
    2. Quantity (number, required, min=1, default=1)
    3. Hidden inputs: currentCpCode (JavaScript variable)

Old App Form Fields

  • Inputs: 1 field
    1. Box Number (text, required)
    2. Hidden inputs: currentCpCode (JavaScript variable)

Backend API Endpoint Comparison

NEW APP

  • Route: /quality/api/assign-cp-to-box (POST)
  • Handler: quality_bp.route in 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.route in 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

  1. Form Structure: The new app's form structure is well-organized and improved
  2. Quantity Support: Adding quantity field is a good enhancement
  3. Layout: Flexbox is better for responsive design
  4. Validation: More comprehensive validation is better
  5. ⚠️ API Route Names: Consider standardizing route naming across apps
  6. ⚠️ Element IDs: Document ID changes for future developers
  7. ⚠️ Migration: Any code expecting old IDs needs updating