717 lines
22 KiB
PHP
717 lines
22 KiB
PHP
<?php
|
|
|
|
function binding_normalize_value($value): string
|
|
{
|
|
$s = (string) $value;
|
|
$s = str_replace(
|
|
["\xC2\xA0", "\xE2\x80\xAF", "\xE2\x80\x87", "\xE2\x80\x89", "\xE2\x80\x8A", "\xEF\xBB\xBF"],
|
|
' ',
|
|
$s
|
|
);
|
|
$s = preg_replace('/\s+/u', ' ', $s);
|
|
|
|
return mb_strtolower(trim((string) $s));
|
|
}
|
|
|
|
function binding_is_list_field(array $mapping): bool
|
|
{
|
|
return strcasecmp(trim((string) ($mapping['data_type'] ?? '')), 'SceltaMultipla') === 0;
|
|
}
|
|
|
|
function binding_get_lims_values(int $fieldId): array
|
|
{
|
|
static $memo = [];
|
|
|
|
if ($fieldId <= 0) {
|
|
return [];
|
|
}
|
|
if (array_key_exists($fieldId, $memo)) {
|
|
return $memo[$fieldId];
|
|
}
|
|
|
|
$cacheDir = dirname(__DIR__) . '/cache';
|
|
$cacheFile = $cacheDir . '/customfield_' . $fieldId . '.json';
|
|
|
|
try {
|
|
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
|
|
$values = json_decode(file_get_contents($cacheFile), true);
|
|
} else {
|
|
require_once __DIR__ . '/VisualLimsApiClient.class.php';
|
|
$api = VisualLimsApiClient::getInstance();
|
|
$data = $api->get("CustomField($fieldId)?\$expand=CustomFieldsValues");
|
|
$values = $data['CustomFieldsValues'] ?? [];
|
|
if (!is_dir($cacheDir)) {
|
|
mkdir($cacheDir, 0777, true);
|
|
}
|
|
file_put_contents($cacheFile, json_encode($values));
|
|
}
|
|
} catch (Throwable $e) {
|
|
error_log("binding_get_lims_values failed for field $fieldId: " . $e->getMessage());
|
|
$values = [];
|
|
}
|
|
|
|
if (!is_array($values)) {
|
|
$values = [];
|
|
}
|
|
|
|
return $memo[$fieldId] = $values;
|
|
}
|
|
|
|
function binding_lims_value_index(int $fieldId): array
|
|
{
|
|
static $memo = [];
|
|
|
|
if (array_key_exists($fieldId, $memo)) {
|
|
return $memo[$fieldId];
|
|
}
|
|
|
|
$index = [];
|
|
foreach (binding_get_lims_values($fieldId) as $v) {
|
|
$id = (int) ($v['IdCustomFieldsValue'] ?? 0);
|
|
if ($id > 0) {
|
|
$index[$id] = (string) ($v['Valore'] ?? '');
|
|
}
|
|
}
|
|
|
|
return $memo[$fieldId] = $index;
|
|
}
|
|
|
|
function binding_has_lims_values(int $fieldId): bool
|
|
{
|
|
return binding_get_lims_values($fieldId) !== [];
|
|
}
|
|
|
|
function binding_is_lims_id(int $fieldId, $value): bool
|
|
{
|
|
$raw = trim((string) $value);
|
|
if ($raw === '' || !ctype_digit($raw)) {
|
|
return false;
|
|
}
|
|
|
|
$index = binding_lims_value_index($fieldId);
|
|
|
|
return $index === [] ? false : isset($index[(int) $raw]);
|
|
}
|
|
|
|
function binding_auto_match(int $fieldId, string $sourceValue): ?array
|
|
{
|
|
$needle = binding_normalize_value($sourceValue);
|
|
if ($needle === '') {
|
|
return null;
|
|
}
|
|
|
|
$matches = [];
|
|
foreach (binding_get_lims_values($fieldId) as $v) {
|
|
if (binding_normalize_value($v['Valore'] ?? '') === $needle) {
|
|
$matches[] = [
|
|
'id' => (int) ($v['IdCustomFieldsValue'] ?? 0),
|
|
'text' => (string) ($v['Valore'] ?? ''),
|
|
];
|
|
}
|
|
}
|
|
|
|
return count($matches) === 1 && $matches[0]['id'] > 0 ? $matches[0] : null;
|
|
}
|
|
|
|
function binding_lookup(PDO $pdo, int $mappingId, string $sourceValue, string $kind = 'custom'): ?array
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
"SELECT id, lims_value_id, lims_value, source_value
|
|
FROM lims_value_binding
|
|
WHERE binding_kind = ? AND mapping_id = ? AND source_key = ?
|
|
LIMIT 1"
|
|
);
|
|
$stmt->execute([$kind, $mappingId, binding_normalize_value($sourceValue)]);
|
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
return $row ?: null;
|
|
}
|
|
|
|
function binding_upsert(
|
|
PDO $pdo,
|
|
int $templateId,
|
|
int $mappingId,
|
|
int $fieldId,
|
|
string $sourceValue,
|
|
int $limsValueId,
|
|
string $limsValue,
|
|
?int $createdBy,
|
|
string $kind = 'custom'
|
|
): void {
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO lims_value_binding
|
|
(template_id, binding_kind, mapping_id, field_id, source_value, source_key, lims_value_id, lims_value, created_by)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE
|
|
lims_value_id = VALUES(lims_value_id),
|
|
lims_value = VALUES(lims_value),
|
|
field_id = VALUES(field_id),
|
|
template_id = VALUES(template_id)"
|
|
);
|
|
$stmt->execute([
|
|
$templateId,
|
|
$kind,
|
|
$mappingId,
|
|
$fieldId,
|
|
mb_substr(trim($sourceValue), 0, 500),
|
|
mb_substr(binding_normalize_value($sourceValue), 0, 500),
|
|
$limsValueId,
|
|
mb_substr($limsValue, 0, 500),
|
|
$createdBy,
|
|
]);
|
|
}
|
|
|
|
function binding_delete(PDO $pdo, int $mappingId, string $sourceValue, string $kind = 'custom'): int
|
|
{
|
|
$stmt = $pdo->prepare("DELETE FROM lims_value_binding WHERE binding_kind = ? AND mapping_id = ? AND source_key = ?");
|
|
$stmt->execute([$kind, $mappingId, binding_normalize_value($sourceValue)]);
|
|
|
|
return $stmt->rowCount();
|
|
}
|
|
|
|
function binding_delete_by_id(PDO $pdo, int $bindingId): int
|
|
{
|
|
$stmt = $pdo->prepare("DELETE FROM lims_value_binding WHERE id = ?");
|
|
$stmt->execute([$bindingId]);
|
|
|
|
return $stmt->rowCount();
|
|
}
|
|
|
|
function binding_suggest(PDO $pdo, int $fieldId, string $sourceValue, int $excludeMappingId): ?array
|
|
{
|
|
if ($fieldId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
"SELECT b.lims_value_id, b.lims_value, b.template_id, t.name AS template_name
|
|
FROM lims_value_binding b
|
|
LEFT JOIN excel_templates t ON t.id = b.template_id
|
|
WHERE b.binding_kind = 'custom' AND b.field_id = ? AND b.source_key = ? AND b.mapping_id <> ?
|
|
ORDER BY b.updated_at DESC
|
|
LIMIT 1"
|
|
);
|
|
$stmt->execute([$fieldId, binding_normalize_value($sourceValue), $excludeMappingId]);
|
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
return $row ?: null;
|
|
}
|
|
|
|
function binding_apply_to_details(PDO $pdo, int $mappingId, string $value, array $datadbIds): int
|
|
{
|
|
$datadbIds = array_values(array_filter(array_map('intval', $datadbIds)));
|
|
if (empty($datadbIds)) {
|
|
return 0;
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($datadbIds), '?'));
|
|
$stmt = $pdo->prepare(
|
|
"UPDATE import_data_details
|
|
SET field_value = ?
|
|
WHERE mapping_id = ? AND id IN ($placeholders)"
|
|
);
|
|
$stmt->execute(array_merge([$value, $mappingId], $datadbIds));
|
|
|
|
return $stmt->rowCount();
|
|
}
|
|
|
|
function binding_find_column_index(string $column, array $columns)
|
|
{
|
|
$needle = binding_normalize_value($column);
|
|
if ($needle === '') {
|
|
return false;
|
|
}
|
|
|
|
foreach ($columns as $i => $c) {
|
|
if (binding_normalize_value($c) === $needle) {
|
|
return $i;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function binding_fixed_alias_map(): array
|
|
{
|
|
return [
|
|
'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',
|
|
'ConsegnaRichiesta' => 'consegna_richiesta',
|
|
];
|
|
}
|
|
|
|
function binding_fixed_column(string $key): ?string
|
|
{
|
|
return binding_fixed_alias_map()[$key] ?? null;
|
|
}
|
|
|
|
function binding_fixed_is_list(string $key): bool
|
|
{
|
|
return in_array($key, [
|
|
'ClienteResponsabile',
|
|
'ClienteFornitore',
|
|
'ClienteAnalisi',
|
|
'ClienteFatturazione',
|
|
'MoltiplicatorePrezzo',
|
|
'AnagraficaCertestObject',
|
|
'AnagraficaCertestService',
|
|
], true);
|
|
}
|
|
|
|
function binding_fixed_is_date(string $key): bool
|
|
{
|
|
return $key === 'ConsegnaRichiesta';
|
|
}
|
|
|
|
function binding_fixed_auto_matchable(string $key): bool
|
|
{
|
|
return in_array($key, [
|
|
'MoltiplicatorePrezzo',
|
|
'AnagraficaCertestObject',
|
|
'AnagraficaCertestService',
|
|
], true);
|
|
}
|
|
|
|
function binding_fixed_label(string $key): string
|
|
{
|
|
$labels = [
|
|
'AnagraficaCertestObject' => 'Anagrafica Certest Object',
|
|
'AnagraficaCertestService' => 'Anagrafica Certest Service',
|
|
'MoltiplicatorePrezzo' => 'Moltiplicatore Prezzo',
|
|
'ClienteResponsabile' => 'Cliente Responsabile',
|
|
'ClienteFornitore' => 'Cliente Fornitore',
|
|
'ClienteAnalisi' => 'Buyer',
|
|
'ClienteFatturazione' => 'Cliente Fatturazione',
|
|
'ConsegnaRichiesta' => 'Consegna Richiesta',
|
|
];
|
|
|
|
return $labels[$key] ?? $key;
|
|
}
|
|
|
|
function binding_parse_date($value): ?string
|
|
{
|
|
$raw = trim((string) $value);
|
|
if ($raw === '') {
|
|
return null;
|
|
}
|
|
|
|
foreach (['Y-m-d', 'd/m/Y', 'd-m-Y', 'd.m.Y', 'Y/m/d', 'd/m/y', 'Y-m-d H:i:s'] as $format) {
|
|
$date = DateTime::createFromFormat($format, $raw);
|
|
if ($date && $date->format($format) === $raw) {
|
|
return $date->format('Y-m-d');
|
|
}
|
|
}
|
|
|
|
$ts = strtotime($raw);
|
|
|
|
return $ts ? date('Y-m-d', $ts) : null;
|
|
}
|
|
|
|
function binding_fixed_default(array $fixedMapping): string
|
|
{
|
|
$value = trim((string) ($fixedMapping['default_value'] ?? ''));
|
|
if ($value === '') {
|
|
return '';
|
|
}
|
|
|
|
$isDate = strcasecmp((string) ($fixedMapping['data_type'] ?? ''), 'DATE') === 0
|
|
|| binding_fixed_is_date((string) ($fixedMapping['fixed_field_key'] ?? ''));
|
|
|
|
if ($isDate && preg_match('/^today\s*(?:\+\s*(\d+))?$/i', $value, $m)) {
|
|
return date('Y-m-d', strtotime('+' . (int) ($m[1] ?? 0) . ' days'));
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
function binding_cached_get($api, string $cacheFile, string $endpoint, int $ttl = 3600): array
|
|
{
|
|
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $ttl)) {
|
|
$data = json_decode(file_get_contents($cacheFile), true);
|
|
if (is_array($data)) {
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
$data = $api->get($endpoint);
|
|
if (is_array($data)) {
|
|
$dir = dirname($cacheFile);
|
|
if (!is_dir($dir)) {
|
|
mkdir($dir, 0777, true);
|
|
}
|
|
file_put_contents($cacheFile, json_encode($data));
|
|
}
|
|
|
|
return is_array($data) ? $data : [];
|
|
}
|
|
|
|
function binding_template_idclient(PDO $pdo, int $templateId): int
|
|
{
|
|
$stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?");
|
|
$stmt->execute([$templateId]);
|
|
|
|
return (int) ($stmt->fetchColumn() ?: 0);
|
|
}
|
|
|
|
function binding_client_label(array $client): string
|
|
{
|
|
$name = trim((string) ($client['Nominativo'] ?? ''));
|
|
$code = trim((string) ($client['CodiceCliente'] ?? ''));
|
|
|
|
return $code !== '' ? ($name . ' - ' . $code) : $name;
|
|
}
|
|
|
|
function binding_get_fixed_values(PDO $pdo, string $fieldKey, int $templateId): array
|
|
{
|
|
static $memo = [];
|
|
$memoKey = $fieldKey . '|' . $templateId;
|
|
if (isset($memo[$memoKey])) {
|
|
return $memo[$memoKey];
|
|
}
|
|
|
|
$cacheDir = dirname(__DIR__) . '/cache';
|
|
$out = [];
|
|
|
|
try {
|
|
require_once __DIR__ . '/VisualLimsApiClient.class.php';
|
|
$api = VisualLimsApiClient::getInstance();
|
|
|
|
switch ($fieldKey) {
|
|
case 'MoltiplicatorePrezzo':
|
|
$data = binding_cached_get($api, "$cacheDir/moltiplicatori_prezzo.json", 'MoltiplicatorePrezzi');
|
|
foreach (($data['value'] ?? []) as $r) {
|
|
$out[] = ['id' => (int) ($r['IdMoltiplicatorePrezzo'] ?? 0), 'text' => (string) ($r['Descrizione'] ?? '')];
|
|
}
|
|
break;
|
|
|
|
case 'AnagraficaCertestObject':
|
|
case 'AnagraficaCertestService':
|
|
$file = $fieldKey === 'AnagraficaCertestObject'
|
|
? 'anagrafica_certest_object.json'
|
|
: 'anagrafica_certest_service.json';
|
|
$data = binding_cached_get($api, "$cacheDir/$file", $fieldKey);
|
|
foreach (($data['value'] ?? []) as $r) {
|
|
$code = trim((string) ($r['Codice'] ?? ''));
|
|
$name = (string) ($r['NomeAnagrafica'] ?? '');
|
|
$out[] = [
|
|
'id' => (int) ($r['IdAnagrafica'] ?? 0),
|
|
'text' => $name,
|
|
'aliases' => array_values(array_filter([$code, $code !== '' ? "$code - $name" : ''])),
|
|
];
|
|
}
|
|
break;
|
|
|
|
case 'ClienteResponsabile':
|
|
$idCliente = binding_template_idclient($pdo, $templateId);
|
|
if ($idCliente > 0) {
|
|
$data = binding_cached_get(
|
|
$api,
|
|
"$cacheDir/cliente_responsabili_$idCliente.json",
|
|
"Cliente($idCliente)?\$expand=Responsabili"
|
|
);
|
|
foreach (($data['Responsabili'] ?? []) as $r) {
|
|
$out[] = ['id' => (int) ($r['IdClienteResponsabile'] ?? 0), 'text' => (string) ($r['Nominativo'] ?? '')];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'ClienteFornitore':
|
|
case 'ClienteAnalisi':
|
|
case 'ClienteFatturazione':
|
|
$endpoint = 'Cliente?' . http_build_query([
|
|
'$select' => 'IdCliente,Nominativo,CodiceCliente',
|
|
'$orderby' => 'Nominativo asc',
|
|
]);
|
|
$data = binding_cached_get($api, "$cacheDir/clienti.json", $endpoint);
|
|
foreach (($data['value'] ?? []) as $r) {
|
|
$out[] = ['id' => (int) ($r['IdCliente'] ?? 0), 'text' => binding_client_label($r)];
|
|
}
|
|
break;
|
|
}
|
|
} catch (Throwable $e) {
|
|
error_log("binding_get_fixed_values($fieldKey) failed: " . $e->getMessage());
|
|
$out = [];
|
|
}
|
|
|
|
return $memo[$memoKey] = array_values(array_filter($out, fn($v) => $v['id'] > 0));
|
|
}
|
|
|
|
function binding_fixed_has_values(PDO $pdo, string $fieldKey, int $templateId): bool
|
|
{
|
|
return binding_get_fixed_values($pdo, $fieldKey, $templateId) !== [];
|
|
}
|
|
|
|
function binding_fixed_is_lims_id(PDO $pdo, string $fieldKey, int $templateId, $value): bool
|
|
{
|
|
$raw = trim((string) $value);
|
|
if ($raw === '' || !ctype_digit($raw)) {
|
|
return false;
|
|
}
|
|
|
|
foreach (binding_get_fixed_values($pdo, $fieldKey, $templateId) as $v) {
|
|
if ((int) $v['id'] === (int) $raw) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function binding_auto_match_fixed(array $values, string $sourceValue): ?array
|
|
{
|
|
$needle = binding_normalize_value($sourceValue);
|
|
if ($needle === '') {
|
|
return null;
|
|
}
|
|
|
|
$matches = [];
|
|
foreach ($values as $v) {
|
|
$candidates = array_merge([$v['text'] ?? ''], $v['aliases'] ?? []);
|
|
foreach ($candidates as $candidate) {
|
|
if (binding_normalize_value($candidate) === $needle) {
|
|
$matches[] = $v;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count($matches) === 1 ? $matches[0] : null;
|
|
}
|
|
|
|
function binding_suggest_fixed(PDO $pdo, string $fieldKey, string $sourceValue, int $excludeMappingId): ?array
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
"SELECT b.lims_value_id, b.lims_value, b.template_id, t.name AS template_name
|
|
FROM lims_value_binding b
|
|
JOIN template_fixed_mapping f ON f.id = b.mapping_id
|
|
LEFT JOIN excel_templates t ON t.id = b.template_id
|
|
WHERE b.binding_kind = 'fixed' AND f.fixed_field_key = ?
|
|
AND b.source_key = ? AND b.mapping_id <> ?
|
|
ORDER BY b.updated_at DESC
|
|
LIMIT 1"
|
|
);
|
|
$stmt->execute([$fieldKey, binding_normalize_value($sourceValue), $excludeMappingId]);
|
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
return $row ?: null;
|
|
}
|
|
|
|
function binding_apply_to_datadb(PDO $pdo, string $fieldKey, $value, array $datadbIds): int
|
|
{
|
|
$column = binding_fixed_column($fieldKey);
|
|
if ($column === null) {
|
|
throw new InvalidArgumentException("Campo fisso sconosciuto: $fieldKey");
|
|
}
|
|
|
|
$datadbIds = array_values(array_filter(array_map('intval', $datadbIds)));
|
|
if (empty($datadbIds)) {
|
|
return 0;
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($datadbIds), '?'));
|
|
$stmt = $pdo->prepare("UPDATE datadb SET `$column` = ? WHERE iddatadb IN ($placeholders)");
|
|
$stmt->execute(array_merge([$value === '' ? null : $value], $datadbIds));
|
|
|
|
return $stmt->rowCount();
|
|
}
|
|
|
|
function binding_write_fixed_columns(PDO $pdo, int $iddatadb, array $valuesByKey): int
|
|
{
|
|
$map = binding_fixed_alias_map();
|
|
$sets = [];
|
|
$params = [];
|
|
|
|
foreach ($valuesByKey as $key => $value) {
|
|
if (!isset($map[$key]) || $value === null || $value === '') {
|
|
continue;
|
|
}
|
|
$sets[] = "`{$map[$key]}` = ?";
|
|
$params[] = $value;
|
|
}
|
|
|
|
if (empty($sets)) {
|
|
return 0;
|
|
}
|
|
|
|
$params[] = $iddatadb;
|
|
$stmt = $pdo->prepare("UPDATE datadb SET " . implode(', ', $sets) . " WHERE iddatadb = ?");
|
|
$stmt->execute($params);
|
|
|
|
return $stmt->rowCount();
|
|
}
|
|
|
|
function binding_resolve_for_import(
|
|
PDO $pdo,
|
|
array $mapping,
|
|
int $templateId,
|
|
string $sourceValue,
|
|
int $iddatadb,
|
|
?int $userId,
|
|
array &$saved,
|
|
array &$auto,
|
|
array &$pending
|
|
): string {
|
|
$mappingId = (int) $mapping['id'];
|
|
$fieldId = (int) $mapping['field_id'];
|
|
$key = 'cf:' . $mappingId . '|' . binding_normalize_value($sourceValue);
|
|
|
|
$collect = function (array &$bucket, array $extra = []) use ($key, $mapping, $mappingId, $fieldId, $sourceValue, $iddatadb) {
|
|
if (!isset($bucket[$key])) {
|
|
$bucket[$key] = array_merge([
|
|
'kind' => 'custom',
|
|
'mapping_id' => $mappingId,
|
|
'field_id' => $fieldId,
|
|
'field_label' => $mapping['field_label'] ?? ('Mapping ' . $mappingId),
|
|
'source_value' => $sourceValue,
|
|
'datadb_ids' => [],
|
|
], $extra);
|
|
}
|
|
$bucket[$key]['datadb_ids'][] = $iddatadb;
|
|
};
|
|
|
|
if (!binding_has_lims_values($fieldId)) {
|
|
return $sourceValue;
|
|
}
|
|
|
|
if (binding_is_lims_id($fieldId, $sourceValue)) {
|
|
return $sourceValue;
|
|
}
|
|
|
|
if ($existing = binding_lookup($pdo, $mappingId, $sourceValue)) {
|
|
$collect($saved, [
|
|
'lims_value_id' => (int) $existing['lims_value_id'],
|
|
'lims_value' => (string) $existing['lims_value'],
|
|
]);
|
|
|
|
return (string) $existing['lims_value_id'];
|
|
}
|
|
|
|
if ($match = binding_auto_match($fieldId, $sourceValue)) {
|
|
binding_upsert($pdo, $templateId, $mappingId, $fieldId, $sourceValue, $match['id'], $match['text'], $userId);
|
|
$collect($auto, [
|
|
'lims_value_id' => $match['id'],
|
|
'lims_value' => $match['text'],
|
|
]);
|
|
|
|
return (string) $match['id'];
|
|
}
|
|
|
|
$collect($pending);
|
|
|
|
return $sourceValue;
|
|
}
|
|
|
|
function binding_resolve_fixed_for_import(
|
|
PDO $pdo,
|
|
array $fixedMapping,
|
|
int $templateId,
|
|
string $sourceValue,
|
|
int $iddatadb,
|
|
?int $userId,
|
|
array &$saved,
|
|
array &$auto,
|
|
array &$pending
|
|
): ?string {
|
|
$fieldKey = (string) $fixedMapping['fixed_field_key'];
|
|
$mappingId = (int) $fixedMapping['id'];
|
|
$key = 'fx:' . $mappingId . '|' . binding_normalize_value($sourceValue);
|
|
|
|
$collect = function (array &$bucket, array $extra = []) use ($key, $fieldKey, $mappingId, $sourceValue, $iddatadb) {
|
|
if (!isset($bucket[$key])) {
|
|
$bucket[$key] = array_merge([
|
|
'kind' => 'fixed',
|
|
'mapping_id' => $mappingId,
|
|
'fixed_field_key' => $fieldKey,
|
|
'field_id' => 0,
|
|
'field_label' => binding_fixed_label($fieldKey),
|
|
'source_value' => $sourceValue,
|
|
'datadb_ids' => [],
|
|
], $extra);
|
|
}
|
|
$bucket[$key]['datadb_ids'][] = $iddatadb;
|
|
};
|
|
|
|
if (binding_fixed_is_date($fieldKey)) {
|
|
return binding_parse_date($sourceValue);
|
|
}
|
|
|
|
if (!binding_fixed_is_list($fieldKey)) {
|
|
return $sourceValue;
|
|
}
|
|
|
|
if (!binding_fixed_has_values($pdo, $fieldKey, $templateId)) {
|
|
error_log("[BINDING] campo fisso $fieldKey: lista LIMS non disponibile, valore non scritto");
|
|
|
|
return null;
|
|
}
|
|
|
|
if (binding_fixed_is_lims_id($pdo, $fieldKey, $templateId, $sourceValue)) {
|
|
return (string) (int) $sourceValue;
|
|
}
|
|
|
|
if ($existing = binding_lookup($pdo, $mappingId, $sourceValue, 'fixed')) {
|
|
$collect($saved, [
|
|
'lims_value_id' => (int) $existing['lims_value_id'],
|
|
'lims_value' => (string) $existing['lims_value'],
|
|
]);
|
|
|
|
return (string) $existing['lims_value_id'];
|
|
}
|
|
|
|
if (binding_fixed_auto_matchable($fieldKey)) {
|
|
$match = binding_auto_match_fixed(binding_get_fixed_values($pdo, $fieldKey, $templateId), $sourceValue);
|
|
if ($match) {
|
|
binding_upsert($pdo, $templateId, $mappingId, 0, $sourceValue, (int) $match['id'], (string) $match['text'], $userId, 'fixed');
|
|
$collect($auto, [
|
|
'lims_value_id' => (int) $match['id'],
|
|
'lims_value' => (string) $match['text'],
|
|
]);
|
|
|
|
return (string) $match['id'];
|
|
}
|
|
}
|
|
|
|
$collect($pending);
|
|
|
|
return null;
|
|
}
|
|
|
|
function binding_merge_buckets(array $bucket, array $items): array
|
|
{
|
|
foreach ($items as $key => $item) {
|
|
if (!isset($bucket[$key])) {
|
|
$bucket[$key] = $item;
|
|
continue;
|
|
}
|
|
$bucket[$key]['datadb_ids'] = array_values(array_unique(array_merge(
|
|
$bucket[$key]['datadb_ids'] ?? [],
|
|
$item['datadb_ids'] ?? []
|
|
)));
|
|
}
|
|
|
|
return $bucket;
|
|
}
|
|
|
|
function binding_list_for_template(PDO $pdo, int $templateId): array
|
|
{
|
|
$stmt = $pdo->prepare(
|
|
"SELECT b.*,
|
|
COALESCE(m.field_label, f.fixed_field_key) AS field_label,
|
|
COALESCE(m.excel_column, f.excel_column) AS excel_column,
|
|
f.fixed_field_key
|
|
FROM lims_value_binding b
|
|
LEFT JOIN template_mapping m ON m.id = b.mapping_id AND b.binding_kind = 'custom'
|
|
LEFT JOIN template_fixed_mapping f ON f.id = b.mapping_id AND b.binding_kind = 'fixed'
|
|
WHERE b.template_id = ?
|
|
ORDER BY field_label ASC, b.source_value ASC"
|
|
);
|
|
$stmt->execute([$templateId]);
|
|
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|