diff --git a/public/userarea/validate_export.php b/public/userarea/validate_export.php index aad2723..ecbd835 100644 --- a/public/userarea/validate_export.php +++ b/public/userarea/validate_export.php @@ -88,6 +88,58 @@ $validators[] = function (int $iddatadb, array $ctx): array { return []; }; +// 3. All LIMS-mandatory fields must be filled. +$validators[] = function (int $iddatadb, array $ctx): array { + $record = $ctx['record'] ?? null; + if (!$record) { + return []; + } + + $errors = []; + + // Fixed fields (stored as columns in datadb) + foreach (($ctx['requiredFixed'] ?? []) as $key => $label) { + $col = $ctx['fixedAliasMap'][$key] ?? null; + $val = $col !== null ? ($record[$col] ?? null) : null; + if ($val === null || $val === '' || (int) $val === 0) { + $errors[] = [ + 'field' => $key, + 'message' => $label . ' è obbligatorio.', + ]; + } + } + + // Custom fields (values stored in import_data_details, keyed by mapping_id) + foreach (($ctx['requiredCustom'] ?? []) as $cf) { + $val = $ctx['customValues'][(int) $cf['mapping_id']] ?? null; + if ($val === null || trim((string) $val) === '') { + $errors[] = [ + 'field' => 'field_label:' . $cf['field_label'], + 'message' => rtrim($cf['field_label'], ': ') . ' è obbligatorio.', + ]; + } + } + + return $errors; +}; + +// Logical fixed_field_key - real datadb column (mirrors imported.php $fixedAliasMap) +$fixedAliasMap = [ + 'ClienteResponsabile' => 'cliente_responsabile_id', + 'ClienteFornitore' => 'cliente_fornitore_id', + 'ClienteAnalisi' => 'clienteAnalisi', + 'MoltiplicatorePrezzo' => 'moltiplicatore_prezzo_id', + 'AnagraficaCertestObject' => 'anagrafica_certest_object_id', + 'AnagraficaCertestService' => 'anagrafica_certest_service_id', + 'ConsegnaRichiesta' => 'consegna_richiesta', +]; + +// Fixed keys NOT enforced by the generic mandatory check above: +// - ConsegnaRichiesta: handled by its dedicated validator (also checks the date) +// - ClienteFornitore / ClienteAnalisi: nullable placeholders, sent as null on +// export and accepted by LIMS. +$skipRequiredFixed = ['ConsegnaRichiesta', 'ClienteFornitore', 'ClienteAnalisi']; + // ── Main ──────────────────────────────────────────────────────────────────── try { @@ -104,9 +156,12 @@ try { $iddatadbList = array_column($rows, 'iddatadb'); $placeholders = implode(',', array_fill(0, count($iddatadbList), '?')); - // Records (datadb) for fixed field validation + // Records (datadb) — templateid + fixed-field columns for mandatory validation $stmt = $pdo->prepare(" - SELECT iddatadb, consegna_richiesta + SELECT iddatadb, templateid, consegna_richiesta, + cliente_responsabile_id, moltiplicatore_prezzo_id, + anagrafica_certest_object_id, anagrafica_certest_service_id, + cliente_fornitore_id, clienteAnalisi FROM datadb WHERE iddatadb IN ($placeholders) "); @@ -128,6 +183,62 @@ try { $partsInfo[(int)$r['iddatadb']][] = $r; } + // Mandatory-field config per template + $templateIds = array_values(array_unique(array_filter(array_map( + fn ($r) => (int)($r['templateid'] ?? 0), + $recordsInfo + )))); + + $requiredFixedByTemplate = []; // template_id => [ fixed_field_key => label ] + $requiredCustomByTemplate = []; // template_id => [ { mapping_id, field_label }, ... ] + + if (!empty($templateIds)) { + $tplPlaceholders = implode(',', array_fill(0, count($templateIds), '?')); + + // Required fixed fields (is_required synced from LIMS ObbligatorioWeb) + $stmt = $pdo->prepare(" + SELECT template_id, fixed_field_key + FROM template_fixed_mapping + WHERE template_id IN ($tplPlaceholders) AND is_required = 1 + "); + $stmt->execute($templateIds); + foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { + $key = $r['fixed_field_key']; + if (in_array($key, $skipRequiredFixed, true)) { + continue; + } + $requiredFixedByTemplate[(int)$r['template_id']][$key] = $key; + } + + // Required custom fields that are visible in the import grid + $stmt = $pdo->prepare(" + SELECT id AS mapping_id, template_id, field_label + FROM template_mapping + WHERE template_id IN ($tplPlaceholders) + AND is_required = 1 + AND is_visible_import = 1 + "); + $stmt->execute($templateIds); + foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { + $requiredCustomByTemplate[(int)$r['template_id']][] = [ + 'mapping_id' => (int)$r['mapping_id'], + 'field_label' => $r['field_label'], + ]; + } + } + + // Custom field values per record (import_data_details.id is the FK to datadb) + $stmt = $pdo->prepare(" + SELECT id AS iddatadb, mapping_id, field_value + FROM import_data_details + WHERE id IN ($placeholders) + "); + $stmt->execute($iddatadbList); + $customValuesByRecord = []; // iddatadb => [ mapping_id => field_value ] + foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { + $customValuesByRecord[(int)$r['iddatadb']][(int)$r['mapping_id']] = $r['field_value']; + } + // ── Run validators per row ────────────────────────────────────────────── $results = []; @@ -137,9 +248,15 @@ try { $index = $rowInfo['index']; // Build context for validators + $record = $recordsInfo[$iddatadb] ?? null; + $templateId = (int)($record['templateid'] ?? 0); $ctx = [ - 'record' => $recordsInfo[$iddatadb] ?? null, - 'parts' => $partsInfo[$iddatadb] ?? [], + 'record' => $record, + 'parts' => $partsInfo[$iddatadb] ?? [], + 'fixedAliasMap' => $fixedAliasMap, + 'requiredFixed' => $requiredFixedByTemplate[$templateId] ?? [], + 'requiredCustom' => $requiredCustomByTemplate[$templateId] ?? [], + 'customValues' => $customValuesByRecord[$iddatadb] ?? [], ]; $errors = [];