From 755f6812d43f3b0124d5bda9b4d2e3bd946c071f Mon Sep 17 00:00:00 2001 From: "r.mubarakzyanov" Date: Fri, 20 Mar 2026 23:31:31 +0300 Subject: [PATCH] Campione custom fields (Tested Component + parts), per-part ConsegnaRichiesta with validation --- public/userarea/export_to_lims.php | 72 ++++++++++++++++++++++------- public/userarea/validate_export.php | 44 +++++++++++++++++- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/public/userarea/export_to_lims.php b/public/userarea/export_to_lims.php index ecf2aeb..db5dbbe 100644 --- a/public/userarea/export_to_lims.php +++ b/public/userarea/export_to_lims.php @@ -104,15 +104,31 @@ try { $clienteAnalisi = !empty($result['clienteAnalisi']) ? (int) $result['clienteAnalisi'] : null; $consegnaRichiesta = !empty($result['consegna_richiesta']) ? $result['consegna_richiesta'] : null; - // ๐Ÿ”น STEP 3: Fetch Parts (including idmatrice) + // ๐Ÿ”น STEP 3: Fetch Parts (including idmatrice and part id for custom fields) $stmt = $pdo->prepare(" - SELECT part_number, part_description, material, color, mix, idmatrice + SELECT id AS part_id, part_number, part_description, material, color, mix, idmatrice, dateexpiry FROM identification_parts WHERE iddatadb = :iddatadb "); $stmt->execute(['iddatadb' => $iddatadb]); $parts = $stmt->fetchAll(PDO::FETCH_ASSOC); + // ๐Ÿ”น STEP 3.1: Fetch custom field values per part from identification_parts_customfields + $partIds = array_column($parts, 'part_id'); + $partsCustomFields = []; // part_id => [ { field_id, value_id, value_text }, ... ] + if (!empty($partIds)) { + $placeholders = implode(',', array_fill(0, count($partIds), '?')); + $cfStmt = $pdo->prepare(" + SELECT part_id, field_id, value_id, value_text + FROM identification_parts_customfields + WHERE part_id IN ({$placeholders}) + "); + $cfStmt->execute($partIds); + foreach ($cfStmt->fetchAll(PDO::FETCH_ASSOC) as $cfRow) { + $partsCustomFields[(int)$cfRow['part_id']][] = $cfRow; + } + } + // ๐Ÿ”น STEP 4a: Auto-populate export_date / export_time fields $stmt = $pdo->prepare(" UPDATE import_data_details idd @@ -216,7 +232,7 @@ try { "SchemaCustomField" => $schemaId, // "Riferimento" => $part["part_description"] ?? "", "NoteWeb" => $part["part_description"] ?? "", - "ConsegnaRichiesta" => $consegnaRichiesta, + "ConsegnaRichiesta" => !empty($part["dateexpiry"]) ? $part["dateexpiry"] : $consegnaRichiesta, ]; // Costruisci curl-like per questo campione @@ -243,13 +259,39 @@ try { $logFileStep6 = $logDir . "commessa_{$commessaId}_campioni_step6_" . time() . ".txt"; $writeLog($logFileStep6, $logContentStep6, "STEP 6 - Campioni (commessa={$commessaId})"); - // ๐Ÿ”น STEP 6.0: PATCH each Campione to set "Tested Component" (CustomField 189) = part_description + // ๐Ÿ”น STEP 6.0: PATCH each Campione custom fields: + // - field 189 (Tested Component) = part_description + // - additional fields from identification_parts_customfields (field_id โ†’ value_id/value_text) $logContentStep63 = ""; foreach ($campioni as $index => $campione) { $campioneId = (int)($campione['IdCampione'] ?? 0); $partDescription = $parts[$index]['part_description'] ?? ''; + $partId = (int)($parts[$index]['part_id'] ?? 0); - if ($campioneId <= 0 || $partDescription === '') { + if ($campioneId <= 0) { + continue; + } + + // Build a map of overrides: IdCustomField => value + $overrides = []; + + // Override 1: Tested Component (field 189) = part_description + if ($partDescription !== '') { + $overrides[189] = $partDescription; + } + + // Override 2: values from identification_parts_customfields + $partCFs = $partsCustomFields[$partId] ?? []; + foreach ($partCFs as $pcf) { + $cfFieldId = (int)$pcf['field_id']; + $cfValue = $pcf['value_text'] ?? $pcf['value_id'] ?? null; + if ($cfFieldId > 0 && $cfValue !== null && $cfValue !== '') { + $overrides[$cfFieldId] = (string)$cfValue; + } + } + + // Skip if nothing to override + if (empty($overrides)) { continue; } @@ -258,25 +300,21 @@ try { $logContentStep63 .= "GET Campione({$campioneId}) CustomFields:\n" . json_encode($campioneWithFields['CampioniCustomFields'] ?? [], JSON_PRETTY_PRINT) . "\n\n"; + $logContentStep63 .= "Overrides for part {$partId}: " . json_encode($overrides) . "\n\n"; - // Find field 189 and build PATCH payload + // Build PATCH payload โ€” apply overrides where IdCustomField matches $campioniCustomFields = []; foreach ($campioneWithFields["CampioniCustomFields"] ?? [] as $cf) { $definitionId = (int)($cf["CustomField"]["IdCustomField"] ?? 0); $fieldInstanceId = (int)$cf["IdCampioniCustomFields"]; $currentValue = $cf["Valore"] ?? ''; - if ($definitionId === 189) { - $campioniCustomFields[] = [ - "IdCampioniCustomFields" => $fieldInstanceId, - "Valore" => $partDescription - ]; - } else { - $campioniCustomFields[] = [ - "IdCampioniCustomFields" => $fieldInstanceId, - "Valore" => $currentValue - ]; - } + $newValue = $overrides[$definitionId] ?? $currentValue; + + $campioniCustomFields[] = [ + "IdCampioniCustomFields" => $fieldInstanceId, + "Valore" => $newValue + ]; } if (!empty($campioniCustomFields)) { diff --git a/public/userarea/validate_export.php b/public/userarea/validate_export.php index b4176be..aad2723 100644 --- a/public/userarea/validate_export.php +++ b/public/userarea/validate_export.php @@ -59,6 +59,35 @@ $validators[] = function (int $iddatadb, array $ctx): array { return []; }; +// 2. ConsegnaRichiesta must be filled and >= today +$validators[] = function (int $iddatadb, array $ctx): array { + $record = $ctx['record'] ?? null; + if (!$record) { + return []; + } + + $consegna = $record['consegna_richiesta'] ?? null; + + if (empty($consegna)) { + return [[ + 'field' => 'ConsegnaRichiesta', + 'message' => 'ConsegnaRichiesta รจ obbligatorio.', + ]]; + } + + $consegnaDate = DateTime::createFromFormat('Y-m-d', $consegna) ?: DateTime::createFromFormat('Y-m-d H:i:s', $consegna); + $today = new DateTime('today'); + + if ($consegnaDate && $consegnaDate < $today) { + return [[ + 'field' => 'ConsegnaRichiesta', + 'message' => 'ConsegnaRichiesta deve essere uguale o superiore alla data odierna (' . $today->format('Y-m-d') . ').', + ]]; + } + + return []; +}; + // โ”€โ”€ Main โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ try { @@ -75,6 +104,18 @@ try { $iddatadbList = array_column($rows, 'iddatadb'); $placeholders = implode(',', array_fill(0, count($iddatadbList), '?')); + // Records (datadb) for fixed field validation + $stmt = $pdo->prepare(" + SELECT iddatadb, consegna_richiesta + FROM datadb + WHERE iddatadb IN ($placeholders) + "); + $stmt->execute($iddatadbList); + $recordsInfo = []; + foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { + $recordsInfo[(int)$r['iddatadb']] = $r; + } + // Parts (full rows, so validators can report which parts have issues) $stmt = $pdo->prepare(" SELECT iddatadb, part_number, part_description, idmatrice @@ -97,7 +138,8 @@ try { // Build context for validators $ctx = [ - 'parts' => $partsInfo[$iddatadb] ?? [], + 'record' => $recordsInfo[$iddatadb] ?? null, + 'parts' => $partsInfo[$iddatadb] ?? [], ]; $errors = [];