@@ -1684,7 +1685,7 @@ $isEdit = ($worksheet_id > 0);
// Prepare modal for add
$('#mixModal').on('show.bs.modal', function() {
const wsId = parseInt(wsIdInput.val() || '0', 10);
- if (wsId <= 0) {
+ if (wsId <= 0 && !window.importStaged) {
Swal.fire({
icon: 'warning',
title: 'Salva prima la testata',
@@ -1693,12 +1694,12 @@ $isEdit = ($worksheet_id > 0);
return false;
}
- // Se stiamo modificando una riga esistente, non resettare il form
- if (parseInt($('#mixRowId').val() || '0', 10) > 0) {
+ // Se stiamo modificando una riga esistente o provvisoria, non resettare il form
+ if (parseInt($('#mixRowId').val() || '0', 10) > 0 || $('#mixStagedIdx').val() !== '') {
return;
}
- $('#mixModalTitle').text('Aggiungi Mescola');
+ $('#mixModalTitle').text(wsId > 0 ? 'Aggiungi Mescola' : 'Aggiungi Mescola (verrà salvata con la testata)');
$('#mixForm')[0].reset();
$('#mixRowId').val('0');
$('#mixWorksheetId').val(wsId);
@@ -1706,6 +1707,11 @@ $isEdit = ($worksheet_id > 0);
$('#lubrication_type').val('');
});
+ $('#mixModal').on('hidden.bs.modal', function() {
+ $('#mixStagedIdx').val('');
+ $('#mixRowId').val('0');
+ });
+
// Edit mix row
$(document).on('click', '.edit-mix', function() {
let row = $(this).attr('data-row');
@@ -1735,6 +1741,11 @@ $isEdit = ($worksheet_id > 0);
$('#mixForm').on('submit', function(e) {
e.preventDefault();
+ if (parseInt(wsIdInput.val() || '0', 10) <= 0 && window.importStaged) {
+ window.stageMixFromForm();
+ return;
+ }
+
const formData = new FormData(this);
formData.append('ajax', '1');
formData.append('action', 'save_mix_row');
@@ -1823,6 +1834,19 @@ $isEdit = ($worksheet_id > 0);
// Click: aggiungi imballo
btnAddPackage.on('click', function() {
const wsId = parseInt(wsIdInput.val() || '0', 10);
+ if (wsId <= 0 && window.importStaged) {
+ const code = $('#requested_package_code').val();
+ if (!code) {
+ Swal.fire({
+ icon: 'warning',
+ title: 'Seleziona un imballo',
+ timer: 1500
+ });
+ return;
+ }
+ window.stagePackage(code, $('#requested_package_code option:selected').text(), $('#packaging_category').val());
+ return;
+ }
if (wsId <= 0) {
Swal.fire({
icon: 'warning',
@@ -1922,40 +1946,53 @@ $isEdit = ($worksheet_id > 0);
$(function() {
window.importStaged = null;
+ function escH(v) {
+ return $('
').text(v == null ? '' : String(v)).html();
+ }
+
+ function stagedButtons() {
+ // con import in corso si può lavorare anche prima del salvataggio
+ if (window.importStaged) $('#btnAddMix, #btnAddPackage').prop('disabled', false);
+ }
+
function renderPendingPackages(packages) {
$('#packageRowsBody tr.import-pending').remove();
$('#packageImportNote').remove();
const $tb = $('#packageRowsBody');
const nonAbbinati = [];
+ const rows = [];
- (packages || []).forEach(function(p) {
- // righe solo per gli imballi ABBINATI (sicuri o proposti)
+ (packages || []).forEach(function(p, i) {
+ // righe solo per gli imballi ABBINATI (sicuri, proposti o aggiunti a mano)
if (!p.package_code) {
- nonAbbinati.push('“' + (p.raw || '') + '” (' + (p.source || '') + ')');
+ nonAbbinati.push('“' + escH(p.raw) + '” (' + escH(p.source) + ')');
return;
}
- const stato = p.needs_review ?
- '
❓ proposto — verifica ' :
- '
⏳ verrà aggiunto al salvataggio ';
- const nome = p.matched_name || '—';
- const $tr = $(
+ const stato = p.manual ?
+ '
➕ aggiunto, verrà salvato ' :
+ (p.needs_review ?
+ '
❓ proposto — verifica ' :
+ '
⏳ verrà salvato ');
+ const origine = p.manual ? 'aggiunto a mano' : ('dal file: ' + escH(p.raw) + ' (' + escH(p.source) + ')');
+ rows.push(
'
' +
'— ' +
- '' + (p.category || '—') + ' ' +
- '' + nome + '
' +
- 'dal file: ' + (p.raw || '') + ' (' + (p.source || '') + ')
' +
- '' + stato + ' ' +
+ '' + escH(p.category || '—') + ' ' +
+ '' + escH(p.matched_name || '—') + '
' +
+ '' + origine + '
' +
+ '' + stato +
+ ' 🗑️ ' +
' '
);
- $tb.prepend($tr);
});
+ $tb.prepend(rows.join(''));
// nota per gli imballi NON abbinati (niente righe vuote)
if (nonAbbinati.length) {
const $note = $(
'
' +
'⚠ Dal file non abbinati automaticamente: ' + nonAbbinati.join(', ') +
- '. Aggiungili a mano qui sotto se servono.' +
+ '. Se servono, sceglili qui sopra e premi “Aggiungi imballo”.' +
'
'
);
$('#packageRowsBody').closest('.table-wrap').before($note);
@@ -1963,29 +2000,137 @@ $isEdit = ($worksheet_id > 0);
}
function renderPendingMescole(mescole) {
- // rimuove eventuali righe provvisorie precedenti
+ // rimuove eventuali righe provvisorie precedenti e la riga "nessun dato" di DataTables
$('#tabellaMixRows tbody tr.import-pending').remove();
+ $('#tabellaMixRows tbody td.dataTables_empty').closest('tr').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 = $(
+ const rows = [];
+ (mescole || []).forEach(function(m, i) {
+ const nome = m.idmescola ?
+ escH(m.matched_name || m.raw || '-') :
+ '
⚠ da abbinare ';
+ const origine = m.manual ? 'aggiunta a mano' : ('dal file: ' + escH(m.raw));
+ const stato = m.idmescola ?
+ '
⏳ verrà salvata ' :
+ '
❓ scegli la mescola ';
+ rows.push(
'
' +
'— ' +
'' + nome + '
' +
- 'dal file: ' + (m.raw || '') + '
' +
- '' + (m.mix_weight_g_m ?? '-') + ' ' +
- '' + (m.support_weight_g_m ?? '-') + ' ' +
- '' + (m.required_density ?? '-') + ' ' +
- '' + (m.required_hardness_shore_a ?? '-') + ' ' +
- '' + (m.lubrication_type ?? '-') + ' ' +
- '⏳ verrà aggiunta al salvataggio ' +
+ '' + origine + '
' +
+ '' + escH(m.mix_weight_g_m ?? '-') + ' ' +
+ '' + escH(m.support_weight_g_m ?? '-') + ' ' +
+ '' + escH(m.required_density || '-') + ' ' +
+ '' + escH(m.required_hardness_shore_a || '-') + ' ' +
+ '' + escH(m.lubrication_type || '-') + ' ' +
+ '' + stato + ' ' +
+ '✏️ Modifica ' +
+ '🗑️ ' +
+ ' ' +
' '
);
- $tb.prepend($tr);
});
+ $tb.prepend(rows.join(''));
}
+ // ---- modifica della lista provvisoria (prima del salvataggio) ----
+ window.stagePackage = function(code, label, category) {
+ const st = window.importStaged;
+ if (!st) return;
+ if (st.packages.some(p => String(p.package_code) === String(code))) {
+ Swal.fire({
+ icon: 'warning',
+ title: 'Imballo già presente',
+ timer: 1500
+ });
+ return;
+ }
+ st.packages.push({
+ package_code: code,
+ matched_name: label,
+ category: category || '',
+ raw: '',
+ source: 'manuale',
+ needs_review: false,
+ manual: true
+ });
+ renderPendingPackages(st.packages);
+ $('#requested_package_code').val('');
+ };
+
+ $(document).on('click', '.staged-pkg-del', function() {
+ const st = window.importStaged;
+ if (!st) return;
+ st.packages.splice(parseInt($(this).data('i'), 10), 1);
+ renderPendingPackages(st.packages);
+ });
+
+ $(document).on('click', '.staged-mix-del', function() {
+ const st = window.importStaged;
+ if (!st) return;
+ st.mescole.splice(parseInt($(this).data('i'), 10), 1);
+ renderPendingMescole(st.mescole);
+ });
+
+ $(document).on('click', '.staged-mix-edit', function() {
+ const st = window.importStaged;
+ if (!st) return;
+ const i = parseInt($(this).data('i'), 10);
+ const m = st.mescole[i];
+ if (!m) return;
+
+ $('#mixForm')[0].reset();
+ $('#mixRowId').val('0');
+ $('#mixStagedIdx').val(i);
+ $('#mixModalTitle').text(m.idmescola ? 'Modifica mescola (non ancora salvata)' : 'Mescola dal file: ' + (m.raw || '') + ' — seleziona la corrispondenza');
+ $('#idmescola').prop('disabled', false).val(m.idmescola ? String(m.idmescola) : '').trigger('change');
+ $('#mix_weight_g_m').val(m.mix_weight_g_m ?? '');
+ $('#support_weight_g_m').val(m.support_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 ?? '');
+ $('#lubrication_notes').val(m.lubrication_notes ?? '');
+
+ bootstrap.Modal.getOrCreateInstance(document.getElementById('mixModal')).show();
+ });
+
+ // salvataggio del modal mescola quando il foglio non esiste ancora
+ window.stageMixFromForm = function() {
+ const st = window.importStaged;
+ if (!st) return;
+ const idm = $('#idmescola').val();
+ if (!idm) {
+ Swal.fire({
+ icon: 'warning',
+ title: 'Seleziona una mescola',
+ timer: 1500
+ });
+ return;
+ }
+ const idxTxt = $('#mixStagedIdx').val();
+ const old = idxTxt !== '' ? (st.mescole[parseInt(idxTxt, 10)] || {}) : {};
+ const m = Object.assign({}, old, {
+ idmescola: idm,
+ matched_name: $.trim($('#idmescola option:selected').text()),
+ needs_review: false,
+ mix_weight_g_m: $('#mix_weight_g_m').val(),
+ support_weight_g_m: $('#support_weight_g_m').val(),
+ required_density: $('#required_density').val(),
+ required_hardness_shore_a: $('#required_hardness_shore_a').val(),
+ lubrication_type: $('#lubrication_type').val(),
+ lubrication_notes: $('#lubrication_notes').val()
+ });
+ if (idxTxt !== '') {
+ st.mescole[parseInt(idxTxt, 10)] = m;
+ } else {
+ m.raw = '';
+ m.manual = true;
+ st.mescole.push(m);
+ }
+ renderPendingMescole(st.mescole);
+ bootstrap.Modal.getOrCreateInstance(document.getElementById('mixModal')).hide();
+ };
+
function postForm(obj) {
return fetch('', {
method: 'POST',
@@ -2027,7 +2172,7 @@ $isEdit = ($worksheet_id > 0);
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 = '
Import completato. Controlla i campi evidenziati in giallo, poi premi “Salva testata”.';
+ let html = '
Import completato. Controlla i campi evidenziati in giallo. Imballi e mescole in giallo si possono togliere (🗑️), correggere o aggiungere: al “Salva testata” viene salvato quello che vedi in tabella.';
if (bits.length) html += '
' + bits.map(b => '' + b + ' ').join('') + ' ';
if ((data.warnings || []).length) html += '
' + data.warnings.join(' ') + '
';
html += '
';
@@ -2048,17 +2193,15 @@ $isEdit = ($worksheet_id > 0);
const matchedMescole = [];
const unmatchedMescole = [];
- // imballi: salva solo quelli SICURI; i proposti li segnaliamo da confermare
+ // imballi: salva quelli rimasti in tabella (sicuri, proposti non tolti, aggiunti a mano)
for (const p of (staged.packages || [])) {
- if (p.package_code && !p.needs_review) {
+ if (p.package_code) {
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 {
unresolvedPkgs.push('Imballo “' + p.raw + '” (' + p.source + ') → nessun abbinamento, aggiungi a mano');
}
@@ -2082,7 +2225,7 @@ $isEdit = ($worksheet_id > 0);
required_density: m.required_density ?? '',
required_hardness_shore_a: m.required_hardness_shore_a ?? '',
lubrication_type: m.lubrication_type ?? '',
- lubrication_notes: ''
+ lubrication_notes: m.lubrication_notes ?? ''
});
}
@@ -2211,10 +2354,6 @@ $isEdit = ($worksheet_id > 0);
setVal('meters_per_package_tolerance', h.meters_per_package_tolerance);
setVal('meters_per_package_notes', h.meters_per_package_notes);
setVal('meters_per_box', h.meters_per_box);
- setVal('meters_per_package', h.meters_per_package);
- setVal('meters_per_package_tolerance', h.meters_per_package_tolerance);
- setVal('meters_per_package_notes', h.meters_per_package_notes);
- setVal('meters_per_box', h.meters_per_box);
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);
@@ -2234,6 +2373,7 @@ $isEdit = ($worksheet_id > 0);
renderBanner(data);
renderPendingMescole(data.mescole || []);
renderPendingPackages(data.packages || []);
+ stagedButtons();
Swal.fire({
icon: 'success',