feat: Major system improvements and production deployment
✨ New Features: - Added view_orders route with proper table display - Implemented CSV upload with preview workflow and date parsing - Added production WSGI server configuration with Gunicorn - Created comprehensive production management scripts 🔧 Bug Fixes: - Fixed upload_data route column mapping for actual CSV structure - Resolved print module database queries and template rendering - Fixed view orders navigation routing (was pointing to JSON API) - Corrected barcode display width constraints in print module - Added proper date format parsing for MySQL compatibility 🎨 UI/UX Improvements: - Updated view_orders template with theme-compliant styling - Hidden barcode text in print module preview for cleaner display - Enhanced CSV upload with two-step preview-then-save workflow - Improved error handling and debugging throughout upload process 🚀 Production Infrastructure: - Added Gunicorn WSGI server with proper configuration - Created systemd service for production deployment - Implemented production management scripts (start/stop/status) - Added comprehensive logging setup - Updated requirements.txt with production dependencies 📊 Database & Data: - Enhanced order_for_labels table compatibility - Fixed column mappings for real CSV data structure - Added proper date parsing and validation - Improved error handling with detailed debugging 🔧 Technical Debt: - Reorganized database setup documentation - Added proper error handling throughout upload workflow - Enhanced debugging capabilities for troubleshooting - Improved code organization and documentation
This commit is contained in:
@@ -23,6 +23,80 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const defectCodeInput = document.getElementById('defect_code');
|
||||
const form = document.getElementById('fg-scan-form');
|
||||
|
||||
// Restore saved operator code from localStorage (only Quality Operator Code)
|
||||
const savedOperatorCode = localStorage.getItem('fg_scan_operator_code');
|
||||
|
||||
if (savedOperatorCode) {
|
||||
operatorCodeInput.value = savedOperatorCode;
|
||||
}
|
||||
|
||||
// Check if we need to clear fields after a successful submission
|
||||
const shouldClearAfterSubmit = localStorage.getItem('fg_scan_clear_after_submit');
|
||||
if (shouldClearAfterSubmit === 'true') {
|
||||
// Clear the flag
|
||||
localStorage.removeItem('fg_scan_clear_after_submit');
|
||||
localStorage.removeItem('fg_scan_last_cp');
|
||||
localStorage.removeItem('fg_scan_last_defect');
|
||||
|
||||
// Clear CP code, OC1, OC2, and defect code for next scan
|
||||
cpCodeInput.value = '';
|
||||
oc1CodeInput.value = '';
|
||||
oc2CodeInput.value = '';
|
||||
defectCodeInput.value = '';
|
||||
|
||||
// Show success indicator
|
||||
setTimeout(function() {
|
||||
// Focus on CP code field for next scan
|
||||
cpCodeInput.focus();
|
||||
|
||||
// Add visual feedback
|
||||
const successIndicator = document.createElement('div');
|
||||
successIndicator.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
||||
font-weight: bold;
|
||||
`;
|
||||
successIndicator.textContent = '✅ Scan recorded! Ready for next scan';
|
||||
document.body.appendChild(successIndicator);
|
||||
|
||||
// Remove success indicator after 3 seconds
|
||||
setTimeout(function() {
|
||||
if (successIndicator.parentNode) {
|
||||
successIndicator.parentNode.removeChild(successIndicator);
|
||||
}
|
||||
}, 3000);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Focus on the first empty required field (only if not clearing after submit)
|
||||
if (shouldClearAfterSubmit !== 'true') {
|
||||
if (!operatorCodeInput.value) {
|
||||
operatorCodeInput.focus();
|
||||
} else if (!oc1CodeInput.value) {
|
||||
oc1CodeInput.focus();
|
||||
} else if (!oc2CodeInput.value) {
|
||||
oc2CodeInput.focus();
|
||||
} else if (!cpCodeInput.value) {
|
||||
cpCodeInput.focus();
|
||||
} else {
|
||||
defectCodeInput.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Save operator codes to localStorage when they change (only Quality Operator Code)
|
||||
operatorCodeInput.addEventListener('input', function() {
|
||||
if (this.value.startsWith('OP') && this.value.length >= 3) {
|
||||
localStorage.setItem('fg_scan_operator_code', this.value);
|
||||
}
|
||||
});
|
||||
|
||||
// Create error message element for operator code
|
||||
const operatorErrorMessage = document.createElement('div');
|
||||
operatorErrorMessage.className = 'error-message';
|
||||
@@ -338,6 +412,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
timeInput.value = `${hours}:${minutes}:${seconds}`;
|
||||
|
||||
// Save current CP code and defect code to localStorage for clearing after reload
|
||||
localStorage.setItem('fg_scan_clear_after_submit', 'true');
|
||||
localStorage.setItem('fg_scan_last_cp', cpCodeInput.value);
|
||||
localStorage.setItem('fg_scan_last_defect', defectCodeInput.value);
|
||||
|
||||
// Submit the form
|
||||
form.submit();
|
||||
}
|
||||
@@ -399,6 +478,27 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add functionality for clear saved codes button
|
||||
const clearSavedBtn = document.getElementById('clear-saved-btn');
|
||||
clearSavedBtn.addEventListener('click', function() {
|
||||
if (confirm('Clear saved Quality Operator code? You will need to re-enter it.')) {
|
||||
// Clear localStorage (only Quality Operator Code)
|
||||
localStorage.removeItem('fg_scan_operator_code');
|
||||
localStorage.removeItem('fg_scan_clear_after_submit');
|
||||
localStorage.removeItem('fg_scan_last_cp');
|
||||
localStorage.removeItem('fg_scan_last_defect');
|
||||
|
||||
// Clear Quality Operator Code field only
|
||||
operatorCodeInput.value = '';
|
||||
|
||||
// Focus on operator code field
|
||||
operatorCodeInput.focus();
|
||||
|
||||
// Show confirmation
|
||||
alert('✅ Saved Quality Operator code cleared! Please re-enter your operator code.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -430,6 +530,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<input type="text" id="time" name="time" value="{{ now().strftime('%H:%M:%S') }}" readonly>
|
||||
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
<button type="button" class="btn" id="clear-saved-btn" style="background-color: #ff6b6b; margin-left: 10px;">Clear Quality Operator</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user