Compare commits
4 Commits
deb74fd971
...
b97424554c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b97424554c | ||
|
|
de72a1fb9e | ||
|
|
caeefa5d61 | ||
|
|
ea403934d3 |
2
app.py
2
app.py
@@ -28,7 +28,7 @@ app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)
|
||||
|
||||
|
||||
# 1. Define the version
|
||||
APP_VERSION = '0.18.0'
|
||||
APP_VERSION = '0.18.1'
|
||||
|
||||
# 2. Inject it into all templates automatically
|
||||
@app.context_processor
|
||||
|
||||
@@ -116,9 +116,9 @@ def execute_pipeline(actions, barcode, context):
|
||||
|
||||
placeholders = ', '.join(['?'] * len(cols))
|
||||
sql = f"INSERT INTO {context['table_name']} ({', '.join(cols)}) VALUES ({placeholders})"
|
||||
execute_db(sql, vals)
|
||||
new_id = execute_db(sql, vals)
|
||||
|
||||
return {'success': True, 'message': 'Saved Successfully', 'data': field_values}
|
||||
return {'success': True, 'message': 'Saved Successfully', 'detail_id': new_id, 'data': field_values}
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f"Database Error: {str(e)}", 'data': field_values}
|
||||
else:
|
||||
|
||||
@@ -109,6 +109,12 @@
|
||||
<i class="fa-solid fa-file-import"></i> Bulk Import Excel
|
||||
</button>
|
||||
</div>
|
||||
<div class="scans-grid scan-header-row" style="--field-count: {{ detail_fields|length }};">
|
||||
{% for field in detail_fields %}
|
||||
<div class="scan-row-cell scan-col-header">{{ field.field_label }}</div>
|
||||
{% endfor %}
|
||||
<div class="scan-row-cell scan-col-header">Status</div>
|
||||
</div>
|
||||
<div id="scansList" class="scans-grid" style="--field-count: {{ detail_fields|length }};">
|
||||
{% for scan in scans %}
|
||||
<div class="scan-row scan-row-{{ scan.duplicate_status }}"
|
||||
@@ -247,6 +253,7 @@ function processSmartScan(barcode, confirm = false) {
|
||||
|
||||
// --- 1. HANDLE DUPLICATE CONFIRMATION ---
|
||||
if (data.needs_confirmation) {
|
||||
playErrorBeep();
|
||||
isSmartScan = true;
|
||||
currentDupKeyValue = barcode;
|
||||
if (data.duplicate_status === 'dup_same_session') {
|
||||
@@ -296,23 +303,23 @@ function processSmartScan(barcode, confirm = false) {
|
||||
}
|
||||
|
||||
// --- 3. STANDARD SUCCESS/FAIL ---
|
||||
if(smartInput) {
|
||||
smartInput.value = '';
|
||||
smartInput.focus();
|
||||
}
|
||||
feedbackArea.style.display = 'block';
|
||||
|
||||
if (data.success) {
|
||||
feedbackArea.style.background = 'rgba(40, 167, 69, 0.2)';
|
||||
feedbackArea.style.border = '1px solid #28a745';
|
||||
feedbackText.style.color = '#28a745';
|
||||
feedbackText.textContent = data.message;
|
||||
if (data.message.includes('Saved')) setTimeout(() => location.reload(), 800);
|
||||
if (data.detail_id && data.data) {
|
||||
addScanToList(data.detail_id, data.data, data.data.duplicate_status);
|
||||
}
|
||||
feedbackArea.style.display = 'none';
|
||||
if(smartInput) {
|
||||
smartInput.value = '';
|
||||
smartInput.focus();
|
||||
}
|
||||
} else {
|
||||
playErrorBeep();
|
||||
feedbackArea.style.display = 'block';
|
||||
feedbackArea.style.background = 'rgba(220, 53, 69, 0.2)';
|
||||
feedbackArea.style.border = '1px solid #dc3545';
|
||||
feedbackText.style.color = '#dc3545';
|
||||
feedbackText.textContent = data.message;
|
||||
if(smartInput) smartInput.focus();
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
@@ -320,7 +327,7 @@ function processSmartScan(barcode, confirm = false) {
|
||||
console.error(err); // Log it, don't popup alert to annoy user
|
||||
});
|
||||
}
|
||||
// Function to handle the "Save" click from the Details Modal
|
||||
|
||||
// Function to handle the "Save" click from the Details Modal
|
||||
function saveSmartScanData() {
|
||||
// 1. Validate we have the original barcode
|
||||
@@ -357,8 +364,12 @@ function saveSmartScanData() {
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
document.getElementById('fieldsModal').style.display = 'none';
|
||||
// Optional: Small delay to let the user see it worked
|
||||
setTimeout(() => location.reload(), 300);
|
||||
if (data.detail_id && data.data) {
|
||||
addScanToList(data.detail_id, data.data, data.data.duplicate_status);
|
||||
}
|
||||
currentDupKeyValue = '';
|
||||
smartInput.value = '';
|
||||
smartInput.focus();
|
||||
} else if (data.needs_input) {
|
||||
alert("Error: Please fill in all required fields.");
|
||||
} else {
|
||||
@@ -372,6 +383,25 @@ function resetSmartScan() {
|
||||
document.getElementById('smartScanner').focus();
|
||||
document.getElementById('routerFeedback').style.display = 'none';
|
||||
}
|
||||
// --- ERROR BEEP ---
|
||||
function playErrorBeep() {
|
||||
try {
|
||||
const ctx = new (window.AudioContext || window.webkitAudioContext)();
|
||||
const oscillator = ctx.createOscillator();
|
||||
const gainNode = ctx.createGain();
|
||||
oscillator.connect(gainNode);
|
||||
gainNode.connect(ctx.destination);
|
||||
oscillator.type = 'square';
|
||||
oscillator.frequency.setValueAtTime(520, ctx.currentTime);
|
||||
gainNode.gain.setValueAtTime(0.3, ctx.currentTime);
|
||||
gainNode.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.4);
|
||||
oscillator.start(ctx.currentTime);
|
||||
oscillator.stop(ctx.currentTime + 0.4);
|
||||
} catch(e) {
|
||||
console.warn('Audio not available:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Standard variables
|
||||
let currentDupKeyValue = '';
|
||||
let currentDuplicateStatus = '';
|
||||
|
||||
@@ -1303,9 +1303,25 @@ body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scan-header-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--field-count), 1fr) auto;
|
||||
gap: var(--space-md);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
max-height: none;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.scan-col-header {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.scan-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr 1.5fr;
|
||||
grid-template-columns: repeat(var(--field-count), 1fr) 1fr;
|
||||
gap: var(--space-md);
|
||||
padding: var(--space-md);
|
||||
background: var(--color-bg);
|
||||
|
||||
Reference in New Issue
Block a user