# Quick Box Creation & Label Printing - Code Snippets Reference ## Quick Reference - Key Code Files and Functions ### 1. Database Table Creation Code **File:** [app/warehouse.py](warehouse.py#L32-L62) **boxes_crates table:** ```python def ensure_boxes_crates_table(): try: conn = get_db_connection() cursor = conn.cursor() cursor.execute("SHOW TABLES LIKE 'boxes_crates'") result = cursor.fetchone() if not result: cursor.execute(''' CREATE TABLE IF NOT EXISTS boxes_crates ( id BIGINT AUTO_INCREMENT PRIMARY KEY, box_number VARCHAR(8) 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 VARCHAR(100), FOREIGN KEY (location_id) REFERENCES warehouse_locations(id) ON DELETE SET NULL ) ''') conn.commit() conn.close() except Exception as e: print(f"Error ensuring boxes_crates table: {e}") ``` **box_contents table:** ```python def ensure_box_contents_table(): """Ensure box_contents table exists for tracking CP codes in boxes""" try: conn = get_db_connection() cursor = conn.cursor() cursor.execute("SHOW TABLES LIKE 'box_contents'") result = cursor.fetchone() if not result: cursor.execute(''' CREATE TABLE IF NOT EXISTS box_contents ( id BIGINT AUTO_INCREMENT PRIMARY KEY, box_id BIGINT NOT NULL, cp_code VARCHAR(15) NOT NULL, scan_id BIGINT, scanned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, scanned_by VARCHAR(100), FOREIGN KEY (box_id) REFERENCES boxes_crates(id) ON DELETE CASCADE, INDEX idx_box_id (box_id), INDEX idx_cp_code (cp_code) ) ''') conn.commit() print("box_contents table created successfully") conn.close() except Exception as e: print(f"Error ensuring box_contents table: {e}") ``` --- ### 2. Frontend JavaScript Implementation **File:** [templates/fg_scan.html](templates/fg_scan.html#L10-L200) **Global Variables:** ```javascript // Global variables for scan-to-boxes feature let scanToBoxesEnabled = false; let currentCpCode = null; ``` **Main Submit Function:** ```javascript async function submitScanWithBoxAssignment() { const form = document.getElementById('fg-scan-form'); const formData = new FormData(form); console.log('=== submitScanWithBoxAssignment called ==='); try { const response = await fetch(window.location.href, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: formData }); console.log('Response status:', response.status); if (response.ok) { currentCpCode = formData.get('cp_code'); const defectCode = formData.get('defect_code') || '000'; console.log('CP Code:', currentCpCode); console.log('Defect Code:', defectCode); showNotification('✅ Scan recorded successfully!', 'success'); // Only show box modal if quality code is 000 if (defectCode === '000' || defectCode === '0') { console.log('Should show box modal'); showBoxModal(currentCpCode); } else { console.log('Defect code not 000, reloading page'); setTimeout(() => window.location.reload(), 1000); } // Clear form fields (except operator code) document.getElementById('cp_code').value = ''; document.getElementById('oc1_code').value = ''; document.getElementById('oc2_code').value = ''; document.getElementById('defect_code').value = ''; } else { console.error('Response not OK'); showNotification('❌ Scan submission failed', 'error'); } } catch (error) { console.error('Error in submitScanWithBoxAssignment:', error); showNotification('❌ Error: ' + error.message, 'error'); } } ``` **Show Modal Function:** ```javascript function showBoxModal(cpCode) { document.getElementById('modal-cp-code').textContent = cpCode; document.getElementById('box-assignment-modal').style.display = 'block'; document.getElementById('scan-box-input').value = ''; document.getElementById('scan-box-input').focus(); } ``` **Assign CP to Box Function:** ```javascript async function assignCpToBox(boxNumber) { const response = await fetch('/warehouse/assign_cp_to_box', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ box_number: boxNumber, cp_code: currentCpCode }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to assign CP to box'); } return await response.json(); } ``` **Notification Helper:** ```javascript function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: ${type === 'success' ? '#4CAF50' : type === 'error' ? '#f44336' : type === 'warning' ? '#ff9800' : '#2196F3'}; color: white; padding: 15px 20px; border-radius: 5px; z-index: 10001; box-shadow: 0 4px 10px rgba(0,0,0,0.3); font-weight: bold; `; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 4000); } ``` --- ### 3. Backend Routes **File:** [app/routes.py](routes.py#L1020-L1090) **FG Scan Route:** ```python @bp.route('/fg_scan', methods=['GET', 'POST']) @requires_quality_module def fg_scan(): # Ensure scanfg_orders table exists ensure_scanfg_orders_table() if request.method == 'POST': # Handle form submission operator_code = request.form.get('operator_code') cp_code = request.form.get('cp_code') oc1_code = request.form.get('oc1_code') oc2_code = request.form.get('oc2_code') defect_code = request.form.get('defect_code') date = request.form.get('date') time = request.form.get('time') try: # Connect to the database with db_connection_context() as conn: cursor = conn.cursor() # Always insert a new entry insert_query = """ INSERT INTO scanfg_orders (operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time) VALUES (%s, %s, %s, %s, %s, %s, %s) """ cursor.execute(insert_query, (operator_code, cp_code, oc1_code, oc2_code, defect_code, date, time)) conn.commit() # Get the quantities from the newly inserted row cp_base_code = cp_code[:10] cursor.execute(""" SELECT approved_quantity, rejected_quantity FROM scanfg_orders WHERE CP_full_code = %s """, (cp_code,)) result = cursor.fetchone() approved_count = result[0] if result else 0 rejected_count = result[1] if result else 0 # Flash appropriate message if int(defect_code) == 0: flash(f'✅ APPROVED scan recorded for {cp_code}. Total approved: {approved_count}') else: flash(f'❌ REJECTED scan recorded for {cp_code} (defect: {defect_code}). Total rejected: {rejected_count}') except mariadb.Error as e: print(f"Error saving finish goods scan data: {e}") flash(f"Error saving scan data: {e}") # Check if this is an AJAX request (for scan-to-boxes feature) if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or \ request.accept_mimetypes.best == 'application/json': # For AJAX requests, return JSON response without redirect return jsonify({'success': True, 'message': 'Scan recorded successfully'}) # For normal form submissions, redirect to prevent form resubmission return redirect(url_for('main.fg_scan')) # Fetch the latest scan data for display scan_data = [] try: with db_connection_context() as conn: cursor = conn.cursor() cursor.execute(""" SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity FROM scanfg_orders ORDER BY Id DESC LIMIT 15 """) raw_scan_data = cursor.fetchall() # Apply formatting to scan data scan_data = [[format_cell_data(cell) for cell in row] for row in raw_scan_data] except mariadb.Error as e: print(f"Error fetching finish goods scan data: {e}") flash(f"Error fetching scan data: {e}") return render_template('fg_scan.html', scan_data=scan_data) ``` --- ### 4. Box Management Functions **File:** [app/warehouse.py](warehouse.py#L155-L210) **Generate Box Number:** ```python def generate_box_number(): """Generate next box number with 8 digits (00000001, 00000002, etc.)""" conn = get_db_connection() cursor = conn.cursor() cursor.execute("SELECT MAX(CAST(box_number AS UNSIGNED)) FROM boxes_crates") result = cursor.fetchone() conn.close() if result and result[0]: next_number = int(result[0]) + 1 else: next_number = 1 return str(next_number).zfill(8) ``` **Add Box:** ```python def add_box(location_id=None, created_by=None): """Add a new box/crate""" conn = get_db_connection() cursor = conn.cursor() box_number = generate_box_number() try: cursor.execute( "INSERT INTO boxes_crates (box_number, status, location_id, created_by) VALUES (%s, %s, %s, %s)", (box_number, 'open', location_id if location_id else None, created_by) ) conn.commit() conn.close() return f"Box {box_number} created successfully" except Exception as e: conn.close() return f"Error creating box: {e}" ``` --- ### 5. CP to Box Assignment **File:** [app/warehouse.py](warehouse.py#L619-L658) **Assign CP to Box Handler:** ```python def assign_cp_to_box_handler(): """Handle assigning CP code to a box""" from flask import request, jsonify, session import json try: # Ensure box_contents table exists ensure_box_contents_table() data = json.loads(request.data) box_number = data.get('box_number') cp_code = data.get('cp_code') scanned_by = session.get('user', 'Unknown') if not box_number or not cp_code: return jsonify({'success': False, 'error': 'Missing box_number or cp_code'}), 400 conn = get_db_connection() cursor = conn.cursor() # Find the box by number cursor.execute("SELECT id FROM boxes_crates WHERE box_number = %s", (box_number,)) box = cursor.fetchone() if not box: conn.close() return jsonify({'success': False, 'error': f'Box {box_number} not found'}), 404 box_id = box[0] # Insert into box_contents cursor.execute(""" INSERT INTO box_contents (box_id, cp_code, scanned_by) VALUES (%s, %s, %s) """, (box_id, cp_code, scanned_by)) conn.commit() conn.close() return jsonify({ 'success': True, 'message': f'CP {cp_code} assigned to box {box_number}' }), 200 except Exception as e: import traceback print(f"Error in assign_cp_to_box_handler: {e}") print(traceback.format_exc()) return jsonify({'success': False, 'error': str(e)}), 500 ``` --- ### 6. Box Search and Management **File:** [app/warehouse.py](warehouse.py#L740-L830) **Search Box by Number:** ```python def search_box_by_number(box_number): """ Search for a box by box number and return its details including location Returns: tuple: (success: bool, data: dict, status_code: int) """ try: if not box_number: return False, {'message': 'Box number is required'}, 400 conn = get_db_connection() cursor = conn.cursor() # Search for the box and get its location info cursor.execute(""" SELECT b.id, b.box_number, b.status, b.location_id, w.location_code FROM boxes_crates b LEFT JOIN warehouse_locations w ON b.location_id = w.id WHERE b.box_number = %s """, (box_number,)) result = cursor.fetchone() conn.close() if result: return True, { 'box': { 'id': result[0], 'box_number': result[1], 'status': result[2], 'location_id': result[3], 'location_code': result[4] } }, 200 else: return False, {'message': f'Box "{box_number}" not found in the system'}, 404 except Exception as e: return False, {'message': f'Error searching for box: {str(e)}'}, 500 ``` **Assign Box to Location:** ```python def assign_box_to_location(box_id, location_code): """Assign a box to a warehouse location""" try: if not box_id or not location_code: return False, {'message': 'Box ID and location code are required'}, 400 conn = get_db_connection() cursor = conn.cursor() # Check if location exists cursor.execute("SELECT id FROM warehouse_locations WHERE location_code = %s", (location_code,)) location_result = cursor.fetchone() if not location_result: conn.close() return False, {'message': f'Location "{location_code}" not found in the system'}, 404 location_id = location_result[0] # Update box location cursor.execute(""" UPDATE boxes_crates SET location_id = %s, updated_at = NOW() WHERE id = %s """, (location_id, box_id)) conn.commit() conn.close() return True, {'message': f'Box successfully assigned to location "{location_code}"'}, 200 except Exception as e: return False, {'message': f'Error assigning box to location: {str(e)}'}, 500 ``` **Change Box Status:** ```python def change_box_status(box_id, new_status): """Change the status of a box (open/closed)""" try: if not box_id: return False, {'message': 'Box ID is required'}, 400 if new_status not in ['open', 'closed']: return False, {'message': 'Invalid status. Must be "open" or "closed"'}, 400 conn = get_db_connection() cursor = conn.cursor() # Get box number for response message cursor.execute("SELECT box_number FROM boxes_crates WHERE id = %s", (box_id,)) box_result = cursor.fetchone() if not box_result: conn.close() return False, {'message': 'Box not found'}, 404 box_number = box_result[0] # Update box status cursor.execute(""" UPDATE boxes_crates SET status = %s, updated_at = NOW() WHERE id = %s """, (new_status, box_id)) conn.commit() conn.close() return True, {'message': f'Box "{box_number}" status changed to "{new_status}"'}, 200 except Exception as e: return False, {'message': f'Error changing box status: {str(e)}'}, 500 ``` --- ### 7. API Routes **File:** [app/routes.py](routes.py#L5657-L5717) **Warehouse Box API Routes:** ```python @bp.route('/api/warehouse/box/search', methods=['POST']) @requires_warehouse_module def api_search_box(): """Search for a box by box number""" data = request.get_json() box_number = data.get('box_number', '').strip() success, response_data, status_code = search_box_by_number(box_number) return jsonify({ 'success': success, **response_data }), status_code @bp.route('/api/warehouse/box/assign-location', methods=['POST']) @requires_warehouse_module def api_assign_box_to_location(): """Assign a box to a warehouse location (only if box is closed)""" data = request.get_json() box_id = data.get('box_id') location_code = data.get('location_code', '').strip() # Additional check: verify box is closed before assigning if box_id: try: with db_connection_context() as conn: cursor = conn.cursor() cursor.execute("SELECT status FROM boxes_crates WHERE id = %s", (box_id,)) result = cursor.fetchone() if result and result[0] == 'open': return jsonify({ 'success': False, 'message': 'Cannot assign an open box to a location. Please close the box first.' }), 400 except Exception as e: pass # Continue to the main function success, response_data, status_code = assign_box_to_location(box_id, location_code) return jsonify({ 'success': success, **response_data }), status_code @bp.route('/api/warehouse/box/change-status', methods=['POST']) @requires_warehouse_module def api_change_box_status(): """Change the status of a box (open/closed)""" data = request.get_json() box_id = data.get('box_id') new_status = data.get('new_status', '').strip() success, response_data, status_code = change_box_status(box_id, new_status) return jsonify({ 'success': success, **response_data }), status_code ``` --- ## Summary of Key Code Locations | Feature | File | Lines | Function | |---------|------|-------|----------| | Create boxes_crates table | warehouse.py | 32-45 | `ensure_boxes_crates_table()` | | Create box_contents table | warehouse.py | 47-62 | `ensure_box_contents_table()` | | Generate box numbers | warehouse.py | 155-165 | `generate_box_number()` | | Add new box | warehouse.py | 167-183 | `add_box()` | | Assign CP to box | warehouse.py | 619-658 | `assign_cp_to_box_handler()` | | Search box | warehouse.py | 740-785 | `search_box_by_number()` | | Assign box to location | warehouse.py | 787-830 | `assign_box_to_location()` | | Change box status | warehouse.py | 906-965 | `change_box_status()` | | FG Scan route | routes.py | 1020-1090 | `fg_scan()` | | Warehouse API routes | routes.py | 5657-5717 | Multiple API endpoints | | Frontend JS | fg_scan.html | 10-200 | Multiple JS functions | All code snippets are from [/srv/quality_app/py_app/app/](../py_app/app/) directory.