diff --git a/public/userarea/create_fixed_fields.php b/public/userarea/create_fixed_fields.php index 57eae375..bc4b7496 100644 --- a/public/userarea/create_fixed_fields.php +++ b/public/userarea/create_fixed_fields.php @@ -23,19 +23,17 @@ if ((int)$stmt->fetchColumn() > 0) { } /** - * FIXED FIELDS STANDARD (no UI selection) - * is_manual always 1 - * is_visible_import default 1 + * FIXED FIELDS STANDARD */ $fixedFields = [ - // fixed_field_key, data_type - ['ClienteResponsabile', 'INT'], - ['ClienteFornitore', 'INT'], - ['ClienteAnalisi', 'INT'], - ['MoltiplicatorePrezzo', 'INT'], - ['AnagraficaCertestObject', 'INT'], + ['ClienteResponsabile', 'INT'], + ['ClienteFornitore', 'INT'], + ['ClienteAnalisi', 'INT'], + ['ClienteFatturazione', 'INT'], // ← NUOVO + ['MoltiplicatorePrezzo', 'INT'], + ['AnagraficaCertestObject', 'INT'], ['AnagraficaCertestService', 'INT'], - ['ConsegnaRichiesta', 'DATE'], + ['ConsegnaRichiesta', 'DATE'], ]; @@ -43,12 +41,11 @@ try { $pdo->beginTransaction(); $ins = $pdo->prepare(" - INSERT INTO template_fixed_mapping - (template_id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import) - VALUES - (:template_id, :fixed_field_key, 1, :data_type, 1, NULL, 1) -"); - + INSERT INTO template_fixed_mapping + (template_id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import) + VALUES + (:template_id, :fixed_field_key, 1, :data_type, 1, NULL, 1) + "); foreach ($fixedFields as $f) { $ins->execute([ @@ -58,16 +55,15 @@ try { ]); } - $pdo->commit(); // Return rows (for client render) $stmt = $pdo->prepare(" - SELECT id, template_id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import - FROM template_fixed_mapping - WHERE template_id = ? - ORDER BY id ASC -"); + SELECT id, template_id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import + FROM template_fixed_mapping + WHERE template_id = ? + ORDER BY id ASC + "); $stmt->execute([$templateId]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); diff --git a/public/userarea/gridRenderer.js b/public/userarea/gridRenderer.js index e03185e8..8a169383 100644 --- a/public/userarea/gridRenderer.js +++ b/public/userarea/gridRenderer.js @@ -110,6 +110,9 @@ ids.add(String(val)); } } + if (row.fixedFields && row.fixedFields.ClienteFatturazione) { + ids.add(String(row.fixedFields.ClienteFatturazione)); + } }); // Batch resolve via single request per ID @@ -156,33 +159,50 @@ return textA.localeCompare(textB, "it", { sensitivity: "base" }); }); } - // Select2 AJAX config for client selects - const clientSelect2Config = { - placeholder: "Search client...", - allowClear: true, - width: "100%", - minimumInputLength: 0, - sorter: sortSelect2ResultsByStart, - dropdownCssClass: "select2-dropdown-smaller", - ajax: { - url: "search_clienti.php", - dataType: "json", - delay: 150, - data: function (params) { - return { q: params.term || "", limit: 20 }; - }, - processResults: function (data) { - const results = (data.results || []).map((item) => ({ - ...item, - text: formatClientLabel(item), - })); - - return { results: results }; - }, - cache: true, - }, + // Mappa: quale filtro Inattivo applicare per ogni campo cliente + const clientFieldTipoMap = { + ClienteFornitore: "attivo", + ClienteAnalisi: "attivo", + ClienteFatturazione: "inattivo", }; + // Select2 AJAX config factory for client selects (parametrizzata su "tipo") + function clientSelect2ConfigFor(tipo) { + return { + placeholder: "Search client...", + allowClear: true, + width: "100%", + minimumInputLength: 0, + sorter: sortSelect2ResultsByStart, + dropdownCssClass: "select2-dropdown-smaller", + ajax: { + url: "search_clienti.php", + dataType: "json", + delay: 150, + data: function (params) { + const d = { q: params.term || "", limit: 20 }; + if (tipo) d.tipo = tipo; + return d; + }, + processResults: function (data) { + const results = (data.results || []).map((item) => ({ + ...item, + text: formatClientLabel(item), + })); + + return { results: results }; + }, + cache: true, + }, + }; + } + + // Helper: inizializza Select2 su un elemento leggendo il tipo da data-client-tipo + function initClientSelect2(el) { + const tipo = el.dataset.clientTipo || ""; + $(el).select2(clientSelect2ConfigFor(tipo)); + } + async function loadClientData() { // No longer loads all clients — AJAX Select2 handles search // Just resolve names for pre-selected values @@ -215,6 +235,7 @@ getParams: (cid) => ({ id_cliente: cid }), }, ClienteFornitore: { source: "clients" }, + ClienteFatturazione: { source: "clients" }, ClienteAnalisi: { source: "clients" }, }; @@ -536,6 +557,7 @@ sel.className = "cell-input dropdown-select client-select searchable-client fornitore-select"; sel.dataset.currentValue = row.cliente_fornitore_id || ""; + sel.dataset.clientTipo = "attivo"; sel.innerHTML = buildClientOptionsHTML( row.cliente_fornitore_id, ); @@ -631,12 +653,13 @@ if (config && config.source === "clients") { const reqCls = col.isRequired ? " required-input" : ""; const req = col.isRequired ? " required" : ""; + const tipo = clientFieldTipoMap[col.key] || ""; let opts = ''; if (value) { const label = clientNameCache[value] || value; opts += ``; } - return ``; + return ``; } // Select — build from cache @@ -1070,7 +1093,7 @@ ``; } else if (col.type === "cliente_fornitore_id") { cell.innerHTML = - `` + + `` + ``; } else if (col.type === "fixed" && col.dataType === "DATE") { cell.innerHTML = @@ -1079,8 +1102,9 @@ } else if (col.type === "fixed") { const isApiField = !!fixedFieldApiConfig[col.key]; if (isApiField) { + const tipo = clientFieldTipoMap[col.key] || ""; cell.innerHTML = - `` + + `` + ``; } else { cell.innerHTML = @@ -1115,12 +1139,12 @@ const clientSel = document.getElementById("clientSelect"); if (clientSel) { clientSel.innerHTML = buildClientOptionsHTML(meta.defaultIdclient); - $(clientSel).select2(clientSelect2Config); + initClientSelect2(clientSel); } const fornitSel = document.getElementById("clienteFornitoreSelect"); if (fornitSel) { fornitSel.innerHTML = buildClientOptionsHTML(""); - $(fornitSel).select2(clientSelect2Config); + initClientSelect2(fornitSel); } // Fixed field selects in top row @@ -1130,7 +1154,7 @@ // Client-sourced → init as AJAX Select2 if (config && config.source === "clients") { - $(sel).select2(clientSelect2Config); + initClientSelect2(sel); return; } @@ -1583,7 +1607,7 @@ $(this) .find(".searchable-client:not(.select2-hidden-accessible)") .each(function () { - $(this).select2(clientSelect2Config); + initClientSelect2(this); }); $(this) .find(".searchable-dropdown:not(.select2-hidden-accessible)") diff --git a/public/userarea/imported.php b/public/userarea/imported.php index 3ba13d9c..247fb490 100644 --- a/public/userarea/imported.php +++ b/public/userarea/imported.php @@ -147,6 +147,7 @@ $desiredOrder = [ 'ClienteResponsabile', 'ClienteFornitore', 'ClienteAnalisi', + 'ClienteFatturazione', 'AnagraficaCertestObject', 'AnagraficaCertestService', 'MoltiplicatorePrezzo', @@ -181,6 +182,7 @@ $fixedAliasMap = [ 'ClienteResponsabile' => 'cliente_responsabile_id', 'ClienteFornitore' => 'cliente_fornitore_id', 'ClienteAnalisi' => 'clienteAnalisi', + 'ClienteFatturazione' => 'ClienteFatturazione', 'MoltiplicatorePrezzo' => 'moltiplicatore_prezzo_id', 'AnagraficaCertestObject' => 'anagrafica_certest_object_id', 'AnagraficaCertestService' => 'anagrafica_certest_service_id', @@ -285,6 +287,21 @@ $gridColumns[] = ['type' => 'idclient', 'key' => 'idclient', 'label' => 'Client' // 4. Cliente Fornitore $gridColumns[] = ['type' => 'cliente_fornitore_id', 'key' => 'cliente_fornitore_id', 'label' => $slugMapping['ClienteFornitore'] ?? 'ClienteFornitore', 'width' => 300]; +// 4b. Fatturazione Avanzata — subito dopo Cliente Fornitore +foreach ($fixedFields as $f) { + if ($f['fixed_field_key'] === 'ClienteFatturazione') { + $gridColumns[] = [ + 'type' => 'fixed', + 'key' => 'ClienteFatturazione', + 'label' => 'Fatturazione avanzata', + 'dataType' => $f['data_type'], + 'isRequired' => (bool)$f['is_required'], + 'width' => 180, + ]; + break; + } +} + // 5. Other custom fields in schema order foreach ($allMappings as $mapping) { if ( @@ -321,7 +338,18 @@ $gridColumns[] = ['type' => 'tracking', 'key' => 'tracking', 'label' => 'Trackin // 10. Fixed fields (with importreferencecode/filename/importdate after ConsegnaRichiesta) foreach ($fixedFields as $f) { $key = $f['fixed_field_key']; - $label = $slugMapping[$key] ?? $key; + + if ($key === 'ClienteFatturazione') continue; // già renderizzata al punto 4b + + // Cambia solo il titolo della colonna ClienteAnalisi + if ($key === 'ClienteAnalisi') { + $label = 'Buyer'; + } elseif ($key === 'ClienteFatturazione') { + $label = 'Fatturazione avanzata'; + } else { + $label = $slugMapping[$key] ?? $key; + } + $gridColumns[] = [ 'type' => 'fixed', 'key' => $key, @@ -330,6 +358,7 @@ foreach ($fixedFields as $f) { 'isRequired' => (bool)$f['is_required'], 'width' => 180, ]; + if ($key === 'ConsegnaRichiesta') { $gridColumns[] = ['type' => 'static', 'key' => 'importreferencecode', 'label' => $slugMapping['importreferencecode'] ?? 'Import Reference Code', 'width' => 150, 'editable' => false]; $gridColumns[] = ['type' => 'static', 'key' => 'filename_import', 'label' => $slugMapping['filename_import'] ?? 'File', 'width' => 150, 'editable' => false]; diff --git a/public/userarea/mapping_template_xls_scheme2.php b/public/userarea/mapping_template_xls_scheme2.php index e516f559..78c44167 100644 --- a/public/userarea/mapping_template_xls_scheme2.php +++ b/public/userarea/mapping_template_xls_scheme2.php @@ -627,6 +627,7 @@ $apiSampleJson = $template['api_sample_json'] ?? ''; 'ClienteResponsabile', 'ClienteFornitore', 'ClienteAnalisi', + 'ClienteFatturazione', 'MoltiplicatorePrezzo', 'AnagraficaCertestObject', 'AnagraficaCertestService' @@ -2183,11 +2184,11 @@ $apiSampleJson = $template['api_sample_json'] ?? ''; 'ClienteResponsabile', 'ClienteFornitore', 'ClienteAnalisi', + 'ClienteFatturazione', // ← AGGIUNGI QUESTA RIGA 'MoltiplicatorePrezzo', 'AnagraficaCertestObject', 'AnagraficaCertestService' ]; - tbody.innerHTML = rows.map(r => { const type = String(r.data_type || '').toUpperCase(); const dv = r.default_value ?? ''; @@ -2491,11 +2492,22 @@ $apiSampleJson = $template['api_sample_json'] ?? ''; })).filter(x => x.id != null && x.label); } - if (key === 'ClienteFornitore' || key === 'ClienteAnalisi') { + if (key === 'ClienteFornitore' || key === 'ClienteAnalisi' || key === 'ClienteFatturazione') { const j = await fetchJson('get_clienti.php'); const list = normalizeList(j, key); - return list.map(x => ({ + const isInattivo = (x) => { + const v = x.Inattivo; + return v === true || v === 1 || v === '1' || v === 'true'; + }; + + // Fornitore e Analisi: solo clienti ATTIVI (Inattivo = false) + // Fatturazione: solo clienti INATTIVI (Inattivo = true) + const filtered = (key === 'ClienteFatturazione') ? + list.filter(isInattivo) : + list.filter(x => !isInattivo(x)); + + return filtered.map(x => ({ id: x.IdCliente ?? x.Id ?? x.id, label: formatClientLabel(x) })).filter(x => x.id != null && x.label); diff --git a/public/userarea/schemi_base_response.json b/public/userarea/schemi_base_response.json index 4e39ea75..7a627e30 100644 --- a/public/userarea/schemi_base_response.json +++ b/public/userarea/schemi_base_response.json @@ -730,8 +730,8 @@ { "IdSchemaCustomFields": 177, "ConteggioClienti": 0, - "Nome": "Phoebe philo ACC", - "Descrizione": "(scarpe, borse, cinture, occhiali, gioielleria)\r\n" + "Nome": "Phoebe Philo ", + "Descrizione": "\r\n\r\n" }, { "IdSchemaCustomFields": 178, @@ -815,7 +815,7 @@ "IdSchemaCustomFields": 191, "ConteggioClienti": 0, "Nome": "KIABI", - "Descrizione": "Schema per il cliente Kiabi\r\n" + "Descrizione": "Schema per il cliente Kiabi\r\n\r\n" }, { "IdSchemaCustomFields": 192, @@ -900,6 +900,12 @@ "ConteggioClienti": 0, "Nome": "Chanel Flammability", "Descrizione": "Schema per Chanel Flammability\r\n" + }, + { + "IdSchemaCustomFields": 206, + "ConteggioClienti": 0, + "Nome": "COLDWATER CREEK", + "Descrizione": "\r\n" } ] } \ No newline at end of file diff --git a/public/userarea/search_clienti.php b/public/userarea/search_clienti.php index 5f008847..ff498cdd 100644 --- a/public/userarea/search_clienti.php +++ b/public/userarea/search_clienti.php @@ -19,6 +19,14 @@ $q = mb_strtolower(trim($_GET['q'] ?? '')); $limit = max(1, min(50, intval($_GET['limit'] ?? 20))); $id = isset($_GET['id']) ? intval($_GET['id']) : null; +$tipo = $_GET['tipo'] ?? ''; // 'attivo' | 'inattivo' | '' (nessun filtro) + +function isInattivo(array $c): bool +{ + $v = $c['Inattivo'] ?? false; + return $v === true || $v === 1 || $v === '1' || $v === 'true'; +} + function formatClientLabel(array $client): string { $name = trim($client['Nominativo'] ?? ''); @@ -49,7 +57,7 @@ try { $api = VisualLimsApiClient::getInstance(); $params = [ - '$select' => 'IdCliente,Nominativo,CodiceCliente', + '$select' => 'IdCliente,Nominativo,CodiceCliente,Inattivo', '$orderby' => 'Nominativo asc' ]; @@ -64,6 +72,14 @@ try { $clients = $data['value'] ?? []; + // Filtro tipo, applicato SOLO alla ricerca, non al lookup per id + $searchClients = $clients; + if ($tipo === 'attivo') { + $searchClients = array_values(array_filter($clients, fn($c) => !isInattivo($c))); + } elseif ($tipo === 'inattivo') { + $searchClients = array_values(array_filter($clients, fn($c) => isInattivo($c))); + } + // If requesting by specific ID, used for loading selected value if ($id !== null) { foreach ($clients as $c) { @@ -88,7 +104,7 @@ try { // Search by query $results = []; - foreach ($clients as $c) { + foreach ($searchClients as $c) { $name = trim($c['Nominativo'] ?? ''); $code = trim($c['CodiceCliente'] ?? '');