fixed import fogli di lavoro and disegni tecnici

This commit is contained in:
2026-10-02 11:24:51 +02:00
parent 63674ea6be
commit c2212f7022
11 changed files with 802 additions and 87 deletions
+147 -21
View File
@@ -985,6 +985,22 @@ $isEdit = ($worksheet_id > 0);
margin-bottom: 16px;
font-size: 0.9rem;
}
tr.import-pending td {
background: #fff8db !important;
}
.pending-badge {
display: inline-flex;
align-items: center;
gap: 6px;
background: #fde68a;
color: #92400e;
border-radius: 999px;
padding: 3px 10px;
font-size: 0.75rem;
font-weight: 800;
}
</style>
</head>
@@ -1892,6 +1908,69 @@ $isEdit = ($worksheet_id > 0);
$(function() {
window.importStaged = null;
function renderPendingPackages(packages) {
$('#packageRowsBody tr.import-pending').remove();
$('#packageImportNote').remove();
const $tb = $('#packageRowsBody');
const nonAbbinati = [];
(packages || []).forEach(function(p) {
// righe solo per gli imballi ABBINATI (sicuri o proposti)
if (!p.package_code) {
nonAbbinati.push('“' + (p.raw || '') + '” (' + (p.source || '') + ')');
return;
}
const stato = p.needs_review ?
'<span class="pending-badge">❓ proposto — verifica</span>' :
'<span class="pending-badge">⏳ verrà aggiunto al salvataggio</span>';
const nome = p.matched_name || '—';
const $tr = $(
'<tr class="import-pending">' +
'<td>—</td>' +
'<td>' + (p.category || '—') + '</td>' +
'<td><div class="fw-bold">' + nome + '</div>' +
'<div class="text-muted small">dal file: ' + (p.raw || '') + ' (' + (p.source || '') + ')</div></td>' +
'<td>' + stato + '</td>' +
'</tr>'
);
$tb.prepend($tr);
});
// nota per gli imballi NON abbinati (niente righe vuote)
if (nonAbbinati.length) {
const $note = $(
'<div id="packageImportNote" class="import-hint" style="margin-bottom:10px;">' +
'⚠ Dal file non abbinati automaticamente: ' + nonAbbinati.join(', ') +
'. Aggiungili a mano qui sotto se servono.' +
'</div>'
);
$('#packageRowsBody').closest('.table-wrap').before($note);
}
}
function renderPendingMescole(mescole) {
// rimuove eventuali righe provvisorie precedenti
$('#tabellaMixRows tbody tr.import-pending').remove();
const $tb = $('#tabellaMixRows tbody');
(mescole || []).forEach(function(m) {
if (!m.idmescola) return; // le non riconosciute passano dal modal, non qui
const nome = m.matched_name || m.raw || '-';
const $tr = $(
'<tr class="import-pending">' +
'<td>—</td>' +
'<td><div class="fw-bold">' + nome + '</div>' +
'<div class="text-muted small">dal file: ' + (m.raw || '') + '</div></td>' +
'<td>' + (m.mix_weight_g_m ?? '-') + '</td>' +
'<td>' + (m.required_density ?? '-') + '</td>' +
'<td>' + (m.required_hardness_shore_a ?? '-') + '</td>' +
'<td>' + (m.lubrication_type ?? '-') + '</td>' +
'<td><span class="pending-badge">⏳ verrà aggiunta al salvataggio</span></td>' +
'</tr>'
);
$tb.prepend($tr);
});
}
function postForm(obj) {
return fetch('', {
method: 'POST',
@@ -1949,41 +2028,51 @@ $isEdit = ($worksheet_id > 0);
window.finalizeImportIfAny = async function(newId) {
const staged = window.importStaged;
if (!staged) return false;
const unresolved = [];
const unresolvedPkgs = [];
const matchedMescole = [];
const unmatchedMescole = [];
// imballi: salva solo quelli SICURI; i proposti li segnaliamo da confermare
for (const p of (staged.packages || [])) {
if (p.package_code) {
if (p.package_code && !p.needs_review) {
await postForm({
ajax: 1,
action: 'save_package_row',
worksheet_id: newId,
package_code: p.package_code
});
} else if (p.package_code && p.needs_review) {
unresolvedPkgs.push('Imballo “' + p.raw + '” (' + p.source + ') → proposto: ' + (p.matched_name || '') + ' — verifica e aggiungi a mano');
} else {
unresolved.push('Imballo “' + p.raw + '” (' + p.source + ')');
unresolvedPkgs.push('Imballo “' + p.raw + '” (' + p.source + ') → nessun abbinamento, aggiungi a mano');
}
}
// mescole: separa risolte / non risolte
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 + '”');
}
if (m.idmescola) matchedMescole.push(m);
else unmatchedMescole.push(m);
}
// salva automaticamente le mescole riconosciute
for (const m of matchedMescole) {
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: ''
});
}
window.importStaged = null;
// Allega il file Excel di origine al foglio appena creato
// allega il file Excel di origine al foglio appena creato
if (window.importFile) {
try {
const fd = new FormData();
@@ -1999,10 +2088,44 @@ $isEdit = ($worksheet_id > 0);
window.importFile = null;
}
// mescola NON riconosciuta -> apri il modal già precompilato (il foglio ora esiste)
if (unmatchedMescole.length) {
const m = unmatchedMescole[0]; // il modulo ha 1 mescola per foglio
$('#wsId').val(newId);
$('#mixWorksheetId').val(newId);
if (!window.location.search.includes('id=')) {
window.history.replaceState({}, '', 'manage-worksheet.php?id=' + newId);
}
const extra = unresolvedPkgs.length ? ('\n\nDa aggiungere a mano: ' + unresolvedPkgs.join(', ')) : '';
await Swal.fire({
icon: 'info',
title: 'Mescola da abbinare',
text: 'La mescola “' + m.raw + '” non è stata riconosciuta. Selezionala dal menu: peso, densità, durezza e lubrificazione sono già compilati.' + extra
});
// precompila i campi dopo che il modal (e select2) è pronto
$('#mixModal').one('shown.bs.modal', function() {
$('#mixModalTitle').text('Mescola dal file: ' + m.raw + ' — seleziona la corrispondenza');
$('#mixRowId').val(0);
$('#mixWorksheetId').val(newId);
$('#mix_weight_g_m').val(m.mix_weight_g_m ?? '');
$('#required_density').val(m.required_density ?? '');
$('#required_hardness_shore_a').val(m.required_hardness_shore_a ?? '');
$('#lubrication_type').val(m.lubrication_type ?? '');
$('#idmescola').val('').trigger('change');
});
const modal = new bootstrap.Modal(document.getElementById('mixModal'));
modal.show();
return true; // niente reload: ci pensa il salvataggio del modal (save_mix_row + reload)
}
// tutto risolto: messaggio + reload
let msg = 'Testata e righe importate salvate correttamente.';
if (unresolved.length) msg += '\n\nDa aggiungere a mano dopo il ricaricamento:\n• ' + unresolved.join('\n• ');
if (unresolvedPkgs.length) msg += '\n\nDa aggiungere a mano dopo il ricaricamento:\n• ' + unresolvedPkgs.join('\n• ');
await Swal.fire({
icon: unresolved.length ? 'warning' : 'success',
icon: unresolvedPkgs.length ? 'warning' : 'success',
title: 'Import completato',
text: msg
});
@@ -2031,6 +2154,7 @@ $isEdit = ($worksheet_id > 0);
const fd = new FormData();
fd.append('xlsx_file', file);
$('#packageImportNote').remove(); // azzera nota import precedente
Swal.fire({
title: 'Lettura Excel…',
allowOutsideClick: false,
@@ -2083,6 +2207,8 @@ $isEdit = ($worksheet_id > 0);
warnings: data.warnings || []
};
renderBanner(data);
renderPendingMescole(data.mescole || []);
renderPendingPackages(data.packages || []);
Swal.fire({
icon: 'success',