cliente fornitore

This commit is contained in:
r.mubarakzyanov 2026-03-17 15:43:12 +03:00
parent 0e90db8219
commit 48387a9945
2 changed files with 114 additions and 22 deletions

View File

@ -174,9 +174,13 @@ $desiredOrder = [
// se ci sono altri campi fixed li mettiamo dopo
];
// ClienteFornitore is rendered as a standalone column (like idclient), skip it in fixed fields
$excludeFromFixed = ['ClienteFornitore'];
$fixedFields = [];
$tempMap = [];
foreach ($fixedFieldsRaw as $f) {
if (in_array($f['fixed_field_key'], $excludeFromFixed, true)) continue;
$tempMap[$f['fixed_field_key']] = $f;
}
@ -946,17 +950,24 @@ function fixedDefaultValue(array $f): string
$topColIndex = $mainFieldMapping ? 2 : 1; ?>
<div class="grid-cell grid-top-cell" style="flex: 0 0 300px;" data-index="<?= $mainFieldMapping ? 2 : 1 ?>">
<div class="grid-cell grid-top-cell" style="flex: 0 0 150px;" data-index="<?= $mainFieldMapping ? 2 : 1 ?>"></div>
<div class="grid-cell grid-top-cell" style="flex: 0 0 300px;" data-index="<?= $mainFieldMapping ? 3 : 2 ?>">
<select class="custom-field dropdown-select client-select searchable-client" data-column="idclient" id="clientSelect" name="idclient">
<option value="">Select a client...</option>
</select>
<button type="button" class="propagate-btn" data-column="idclient"><i class="fas fa-arrow-down"></i></button>
<span id="clientLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Recupero clienti in corso...</span>
</div>
<div class="grid-cell grid-top-cell" style="flex: 0 0 150px;" data-index="<?= $mainFieldMapping ? 3 : 2 ?>"></div>
<div class="grid-cell grid-top-cell" style="flex: 0 0 300px;" data-index="<?= $mainFieldMapping ? 4 : 3 ?>">
<select class="custom-field dropdown-select client-select searchable-client" data-column="cliente_fornitore_id" id="clienteFornitoreSelect" name="cliente_fornitore_id">
<option value="">Select a supplier...</option>
</select>
<button type="button" class="propagate-btn" data-column="cliente_fornitore_id"><i class="fas fa-arrow-down"></i></button>
</div>
<?php
$topColIndex = $mainFieldMapping ? 4 : 3;
$topColIndex = $mainFieldMapping ? 5 : 4;
$autoIndex = 0;
foreach ($allMappings as $mapping) {
@ -1118,12 +1129,14 @@ function fixedDefaultValue(array $f): string
<div class="resizer"></div>
</div>
<?php endif; ?>
<div class="grid-header" data-index="<?= $mainFieldMapping ? 2 : 1 ?>" style="flex: 0 0 300px; position: relative;">Client<div class="resizer"></div>
<div class="grid-header" data-index="<?= $mainFieldMapping ? 2 : 1 ?>" style="flex: 0 0 150px; position: relative;">Status<div class="resizer"></div>
</div>
<div class="grid-header" data-index="<?= $mainFieldMapping ? 3 : 2 ?>" style="flex: 0 0 150px; position: relative;">Status<div class="resizer"></div>
<div class="grid-header" data-index="<?= $mainFieldMapping ? 3 : 2 ?>" style="flex: 0 0 300px; position: relative;">Client<div class="resizer"></div>
</div>
<div class="grid-header" data-index="<?= $mainFieldMapping ? 4 : 3 ?>" style="flex: 0 0 300px; position: relative;">Cliente Fornitore<div class="resizer"></div>
</div>
<?php
$headerIndex = $mainFieldMapping ? 4 : 3;
$headerIndex = $mainFieldMapping ? 5 : 4;
foreach ($allMappings as $mapping) {
if (!$mapping['is_manual'] && $mapping['main_field'] != 1 && $mapping['is_visible_import'] == 1) {
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
@ -1211,12 +1224,7 @@ function fixedDefaultValue(array $f): string
<?php endif; ?>
</div>
<?php endif; ?>
<div class="grid-cell editable-cell" data-col="idclient" data-row="<?= $index ?>" data-index="<?= $mainFieldMapping ? 2 : 1 ?>" style="flex: 0 0 300px;">
<select name="rows[<?= $index ?>][idclient]" class="cell-input dropdown-select client-select searchable-client" data-current-value="<?= htmlspecialchars($row['idclient'] ?? $default_idclient) ?>">
<option value="">Select a client...</option>
</select>
</div>
<div class="grid-cell editable-cell" data-col="status" data-row="<?= $index ?>" data-index="<?= $mainFieldMapping ? 3 : 2 ?>" style="flex: 0 0 150px;">
<div class="grid-cell editable-cell" data-col="status" data-row="<?= $index ?>" data-index="<?= $mainFieldMapping ? 2 : 1 ?>" style="flex: 0 0 150px;">
<span class="status-badge status-<?= htmlspecialchars($row['status'] ?? 'i') ?>">
<?= htmlspecialchars($row['status'] === 'i' ? 'Imported' : ($row['status'] === 'P' ? 'In Progress' : 'To LIMS')) ?>
</span>
@ -1225,8 +1233,18 @@ function fixedDefaultValue(array $f): string
<?php endif; ?>
<input type="hidden" name="rows[<?= $index ?>][status]" value="<?= htmlspecialchars($row['status'] ?? 'i') ?>">
</div>
<div class="grid-cell editable-cell" data-col="idclient" data-row="<?= $index ?>" data-index="<?= $mainFieldMapping ? 3 : 2 ?>" style="flex: 0 0 300px;">
<select name="rows[<?= $index ?>][idclient]" class="cell-input dropdown-select client-select searchable-client" data-current-value="<?= htmlspecialchars($row['idclient'] ?? $default_idclient) ?>">
<option value="">Select a client...</option>
</select>
</div>
<div class="grid-cell editable-cell" data-col="cliente_fornitore_id" data-row="<?= $index ?>" data-index="<?= $mainFieldMapping ? 4 : 3 ?>" style="flex: 0 0 300px;">
<select name="rows[<?= $index ?>][cliente_fornitore_id]" class="cell-input dropdown-select client-select searchable-client fornitore-select" data-current-value="<?= htmlspecialchars($row['cliente_fornitore_id'] ?? '') ?>">
<option value="">Select a supplier...</option>
</select>
</div>
<?php
$cellIndex = $mainFieldMapping ? 4 : 3;
$cellIndex = $mainFieldMapping ? 5 : 4;
$rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']);
$autoIndex = 0;
foreach ($allMappings as $mapping) {
@ -1544,6 +1562,11 @@ function fixedDefaultValue(array $f): string
formData.append('idclient', idclientSelect.value);
}
const fornitoreSelect = row.querySelector(`select[name="rows[${rowIndex}][cliente_fornitore_id]"]`);
if (fornitoreSelect) {
formData.append('cliente_fornitore_id', fornitoreSelect.value);
}
// ---- FIXED FIELDS (NEW) ----
const fixedInputs = row.querySelectorAll(`input[name^="rows[${rowIndex}]["], select[name^="rows[${rowIndex}]["]`);
fixedInputs.forEach(inp => {
@ -1689,6 +1712,10 @@ function fixedDefaultValue(array $f): string
if (idclientSelect) {
formData.append('idclient', idclientSelect.value);
}
const fornitoreSelect = row.querySelector(`select[name="rows[${rowIndex}][cliente_fornitore_id]"]`);
if (fornitoreSelect) {
formData.append('cliente_fornitore_id', fornitoreSelect.value);
}
// ---- FIXED FIELDS ----
const fixedInputs = row.querySelectorAll(`input[name^="rows[${rowIndex}]["], select[name^="rows[${rowIndex}]["]`);
fixedInputs.forEach(inp => {
@ -1856,6 +1883,7 @@ function fixedDefaultValue(array $f): string
});
populateClientDropdowns();
populateFornitoreDropdowns();
clientLoadingStatus.textContent = "Clienti caricati.";
// ✅ force refresh of header dependent fixed fields
$('#clientSelect').trigger('change');
@ -1908,6 +1936,45 @@ function fixedDefaultValue(array $f): string
});
}
// Funzione per popolare i dropdown ClienteFornitore (header + rows)
function populateFornitoreDropdowns() {
// Header
const headerSelect = document.getElementById("clienteFornitoreSelect");
if (headerSelect) {
headerSelect.innerHTML = '<option value="">Select a supplier...</option>';
clientData.forEach(client => {
const nome = client.Nominativo || "Nome non disponibile";
const id = client.IdCliente || "ID non disponibile";
const codiceCliente = (client.CodiceCliente || '').toString().trim();
const suffix = (codiceCliente.split('_')[1] || '').trim();
const shortCode = suffix || (codiceCliente ? codiceCliente.charAt(0) : '--');
headerSelect.add(new Option(`${nome.trim()} - ${shortCode} (ID: ${id})`, id));
});
}
// Row dropdowns
const fornitoreDropdowns = document.querySelectorAll('select[name^="rows"][name$="[cliente_fornitore_id]"]');
fornitoreDropdowns.forEach(dropdown => {
const currentValue = dropdown.getAttribute('data-current-value') || '';
dropdown.innerHTML = '<option value="">Select a supplier...</option>';
clientData.forEach(client => {
const nome = client.Nominativo || "Nome non disponibile";
const id = client.IdCliente || "ID non disponibile";
const codiceCliente = (client.CodiceCliente || '').toString().trim();
const suffix = (codiceCliente.split('_')[1] || '').trim();
const shortCode = suffix || (codiceCliente ? codiceCliente.charAt(0) : '--');
const option = new Option(`${nome.trim()} - ${shortCode} (ID: ${id})`, id);
if (String(id) === String(currentValue)) {
option.selected = true;
}
dropdown.add(option);
});
if (currentValue) {
dropdown.value = currentValue;
}
});
}
// Carica i client all'avvio
loadClients();
@ -2381,6 +2448,13 @@ function fixedDefaultValue(array $f): string
});
gridCell.dispatchEvent(event);
}
if (e.target.matches('select[name^="rows"][name$="[cliente_fornitore_id]"]')) {
const gridCell = e.target.closest('.grid-cell');
const event = new Event('change', {
bubbles: true
});
gridCell.dispatchEvent(event);
}
});
});
</script>
@ -2397,11 +2471,10 @@ function fixedDefaultValue(array $f): string
// Ensure Select2 dropdowns trigger change events for unsaved changes tracking
$('.searchable-client').on('select2:select select2:clear', function(e) {
const gridCell = this.closest('.grid-cell');
const event = new Event('change', {
bubbles: true
});
gridCell.dispatchEvent(event);
// Trigger native change on the real <select> element so
// addEventListener('change') handlers can detect modifications.
const nativeEvent = new Event('change', { bubbles: true });
this.dispatchEvent(nativeEvent);
});
// Update propagate functionality for client dropdown
@ -2412,10 +2485,22 @@ function fixedDefaultValue(array $f): string
const clientSelect = row.querySelector('select[name$="[idclient]"]');
if (clientSelect) {
$(clientSelect).val(value).trigger('change.select2');
const event = new Event('change', {
bubbles: true
});
clientSelect.closest('.grid-cell').dispatchEvent(event);
const event = new Event('change', { bubbles: true });
clientSelect.dispatchEvent(event);
}
});
});
// Propagate ClienteFornitore
$('.propagate-btn[data-column="cliente_fornitore_id"]').on('click', function() {
const value = $('#clienteFornitoreSelect').val();
const rows = document.querySelectorAll('.grid-row');
rows.forEach(row => {
const fornitoreSelect = row.querySelector('select[name$="[cliente_fornitore_id]"]');
if (fornitoreSelect) {
$(fornitoreSelect).val(value).trigger('change.select2');
const event = new Event('change', { bubbles: true });
fornitoreSelect.dispatchEvent(event);
}
});
});

View File

@ -12,6 +12,7 @@ try {
$iddatadb = intval($_POST['iddatadb']);
$idclient = isset($_POST['idclient']) ? (is_numeric($_POST['idclient']) ? intval($_POST['idclient']) : null) : null;
$clienteFornitoreId = isset($_POST['cliente_fornitore_id']) ? (is_numeric($_POST['cliente_fornitore_id']) ? intval($_POST['cliente_fornitore_id']) : null) : null;
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
@ -137,6 +138,12 @@ try {
$params[] = $idclient;
}
// 5a2) cliente_fornitore_id (se presente)
if (isset($clienteFornitoreId)) {
$setParts[] = "cliente_fornitore_id = ?";
$params[] = $clienteFornitoreId;
}
// 5b) fixed fields dal POST
// QUI è il punto chiave: accettiamo SOLO colonne reali (realWhitelist),
// ma se dal JS arrivassero ancora key logiche, funzionerebbe uguale