import fogli di lavoro
This commit is contained in:
@@ -963,6 +963,28 @@ $isEdit = ($worksheet_id > 0);
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.import-review {
|
||||
background: #fff8db !important;
|
||||
border-color: #f59e0b !important;
|
||||
}
|
||||
|
||||
.import-hint {
|
||||
font-size: 0.78rem;
|
||||
color: #92400e;
|
||||
margin-top: 4px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.import-banner {
|
||||
background: #ecfeff;
|
||||
border: 1px solid #a5f3fc;
|
||||
color: #155e75;
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -983,6 +1005,13 @@ $isEdit = ($worksheet_id > 0);
|
||||
</div>
|
||||
|
||||
<div class="top-actions">
|
||||
<input type="file" id="xlsxImportInput" accept=".xlsx" style="display:none">
|
||||
<button type="button" class="btn btn-history" id="btnImportXlsx">📥 Importa da Excel</button>
|
||||
<?php if ($worksheet && !empty($worksheet['source_xlsx_path'])): ?>
|
||||
<a class="btn btn-history" href="download_worksheet_file.php?id=<?= (int)$worksheet_id ?>" target="_blank">
|
||||
📎 Excel di origine
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<button class="btn btn-history" onclick="location.href='worksheets.php'">↩️ Storico fogli</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1594,6 +1623,12 @@ $isEdit = ($worksheet_id > 0);
|
||||
window.history.replaceState({}, '', newUrl);
|
||||
}
|
||||
|
||||
// Import da Excel in corso: salva righe e ricarica
|
||||
if (window.importStaged) {
|
||||
window.finalizeImportIfAny(data.id);
|
||||
return;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Testata salvata',
|
||||
@@ -1853,6 +1888,220 @@ $isEdit = ($worksheet_id > 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$(function() {
|
||||
window.importStaged = null;
|
||||
|
||||
function postForm(obj) {
|
||||
return fetch('', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: new URLSearchParams(obj)
|
||||
}).then(r => r.json()).catch(() => ({
|
||||
success: false
|
||||
}));
|
||||
}
|
||||
|
||||
function setVal(name, val) {
|
||||
if (val === null || val === undefined) return;
|
||||
const $el = $('[name="' + name + '"]');
|
||||
if ($el.length) $el.val(val);
|
||||
}
|
||||
|
||||
function markReview(name, info) {
|
||||
const $el = $('#' + name);
|
||||
if (!$el.length) return;
|
||||
info = info || {};
|
||||
$el.addClass('import-review');
|
||||
$el.val(info.value ? info.value : ''); // pre-seleziona il suggerimento se c'è
|
||||
const $wrap = $el.closest('[class*="col-"]');
|
||||
let $tip = $wrap.find('.import-hint');
|
||||
if (!$tip.length) {
|
||||
$tip = $('<div class="import-hint"></div>');
|
||||
$el.after($tip);
|
||||
}
|
||||
$tip.text(info.value ?
|
||||
'Suggerito dal file: ' + (info.label || info.value) + ' — verifica' :
|
||||
'Dal file: ' + (info.raw || '') + ' — scegli il valore');
|
||||
}
|
||||
|
||||
function renderBanner(data) {
|
||||
const bits = [];
|
||||
(data.mescole || []).forEach(m =>
|
||||
bits.push('Mescola “' + m.raw + '” ' + (m.idmescola ? '✓' : '⚠ da abbinare a mano')));
|
||||
(data.packages || []).forEach(p =>
|
||||
bits.push('Imballo “' + p.raw + '” (' + p.source + ') ' + (p.package_code ? '✓' : '⚠ da aggiungere a mano')));
|
||||
let html = '<div class="import-banner"><strong>Import completato.</strong> Controlla i campi evidenziati in giallo, poi premi “Salva testata”.';
|
||||
if (bits.length) html += '<ul style="margin:8px 0 0 18px;">' + bits.map(b => '<li>' + b + '</li>').join('') + '</ul>';
|
||||
if ((data.warnings || []).length) html += '<div style="color:#b45309;margin-top:6px;">' + data.warnings.join('<br>') + '</div>';
|
||||
html += '</div>';
|
||||
let $b = $('#importBanner');
|
||||
if (!$b.length) {
|
||||
$b = $('<div id="importBanner"></div>');
|
||||
$('#worksheetHeaderForm').prepend($b);
|
||||
}
|
||||
$b.html(html);
|
||||
}
|
||||
|
||||
// Salvataggio righe dopo la testata (chiamato dal handler esistente)
|
||||
window.finalizeImportIfAny = async function(newId) {
|
||||
const staged = window.importStaged;
|
||||
if (!staged) return false;
|
||||
const unresolved = [];
|
||||
|
||||
for (const p of (staged.packages || [])) {
|
||||
if (p.package_code) {
|
||||
await postForm({
|
||||
ajax: 1,
|
||||
action: 'save_package_row',
|
||||
worksheet_id: newId,
|
||||
package_code: p.package_code
|
||||
});
|
||||
} else {
|
||||
unresolved.push('Imballo “' + p.raw + '” (' + p.source + ')');
|
||||
}
|
||||
}
|
||||
for (const m of (staged.mescole || [])) {
|
||||
if (m.idmescola) {
|
||||
await postForm({
|
||||
ajax: 1,
|
||||
action: 'save_mix_row',
|
||||
worksheet_id: newId,
|
||||
idmescola: m.idmescola,
|
||||
mix_weight_g_m: m.mix_weight_g_m ?? '',
|
||||
required_density: m.required_density ?? '',
|
||||
required_hardness_shore_a: m.required_hardness_shore_a ?? '',
|
||||
lubrication_type: m.lubrication_type ?? '',
|
||||
lubrication_notes: ''
|
||||
});
|
||||
} else {
|
||||
unresolved.push('Mescola “' + m.raw + '”');
|
||||
}
|
||||
}
|
||||
|
||||
window.importStaged = null;
|
||||
|
||||
// Allega il file Excel di origine al foglio appena creato
|
||||
if (window.importFile) {
|
||||
try {
|
||||
const fd = new FormData();
|
||||
fd.append('worksheet_id', newId);
|
||||
fd.append('xlsx_file', window.importFile);
|
||||
await fetch('attach_worksheet_file.php', {
|
||||
method: 'POST',
|
||||
body: fd
|
||||
});
|
||||
} catch (e) {
|
||||
/* se l'allegato fallisce non blocchiamo il flusso */
|
||||
}
|
||||
window.importFile = null;
|
||||
}
|
||||
|
||||
let msg = 'Testata e righe importate salvate correttamente.';
|
||||
if (unresolved.length) msg += '\n\nDa aggiungere a mano dopo il ricaricamento:\n• ' + unresolved.join('\n• ');
|
||||
await Swal.fire({
|
||||
icon: unresolved.length ? 'warning' : 'success',
|
||||
title: 'Import completato',
|
||||
text: msg
|
||||
});
|
||||
window.location.href = 'manage-worksheet.php?id=' + newId;
|
||||
return true;
|
||||
};
|
||||
|
||||
$('#btnImportXlsx').on('click', function() {
|
||||
const wsId = parseInt($('#wsId').val() || '0', 10);
|
||||
if (wsId > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
title: 'Import solo su foglio nuovo',
|
||||
text: 'Apri “Nuovo Foglio di Lavoro” per importare un Excel.'
|
||||
});
|
||||
return;
|
||||
}
|
||||
$('#xlsxImportInput').val('').click();
|
||||
});
|
||||
|
||||
$('#xlsxImportInput').on('change', function() {
|
||||
const file = this.files && this.files[0];
|
||||
if (!file) return;
|
||||
window.importFile = file; // conserva il file per allegarlo dopo il salvataggio
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append('xlsx_file', file);
|
||||
|
||||
Swal.fire({
|
||||
title: 'Lettura Excel…',
|
||||
allowOutsideClick: false,
|
||||
didOpen: () => Swal.showLoading()
|
||||
});
|
||||
|
||||
fetch('import_worksheet_xlsx.php', {
|
||||
method: 'POST',
|
||||
body: fd
|
||||
})
|
||||
.then(async r => {
|
||||
const t = await r.text();
|
||||
try {
|
||||
return JSON.parse(t);
|
||||
} catch (e) {
|
||||
throw new Error('Risposta non valida dal parser:\n' + t.slice(0, 300));
|
||||
}
|
||||
})
|
||||
.then(data => {
|
||||
Swal.close();
|
||||
if (!data.success) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Errore import',
|
||||
text: data.message || 'Errore sconosciuto'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const h = data.header || {};
|
||||
setVal('worksheet_date', h.worksheet_date);
|
||||
setVal('customer_name', h.customer_name);
|
||||
setVal('profile_type_code', h.profile_type_code);
|
||||
setVal('marking', h.marking);
|
||||
setVal('prod_control_measure_settings', h.prod_control_measure_settings);
|
||||
setVal('packages_or_pieces_per_box', h.packages_or_pieces_per_box);
|
||||
setVal('boxes_or_packages_per_pallet', h.boxes_or_packages_per_pallet);
|
||||
setVal('speed_expected_kg_h', h.speed_expected_kg_h);
|
||||
setVal('speed_expected_m_h', h.speed_expected_m_h);
|
||||
setVal('notes', h.notes);
|
||||
|
||||
const lk = data.header_lookups || {};
|
||||
Object.keys(lk).forEach(name => {
|
||||
if (lk[name] && lk[name].needs_review) markReview(name, lk[name]);
|
||||
});
|
||||
|
||||
window.importStaged = {
|
||||
mescole: data.mescole || [],
|
||||
packages: data.packages || [],
|
||||
warnings: data.warnings || []
|
||||
};
|
||||
renderBanner(data);
|
||||
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Excel letto',
|
||||
text: 'Controlla i campi evidenziati, poi premi “Salva testata”.',
|
||||
timer: 1800
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
Swal.close();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Errore',
|
||||
text: err.message
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user