netgescon-day0/app/Services/FattureElettroniche/FeXsdCodesDiff.php

115 lines
3.9 KiB
PHP

<?php
namespace App\Services\FattureElettroniche;
use App\Models\FeXsdCode;
use App\Models\FeXsdCodeDomain;
use App\Models\FeXsdVersion;
class FeXsdCodesDiff
{
/**
* @return array{
* old_version_id:int|null,
* new_version_id:int,
* domains_added:int,
* domains_removed:int,
* domains_changed:int,
* codes_added:int,
* codes_removed:int,
* codes_changed:int,
* per_domain: array<int, array{type_name:string, added:int, removed:int, changed:int}>
* }
*/
public function diff(?FeXsdVersion $old, FeXsdVersion $new): array
{
$oldDomains = $old
? FeXsdCodeDomain::query()->where('version_id', $old->id)->get(['id', 'type_name'])->keyBy('type_name')
: collect();
$newDomains = FeXsdCodeDomain::query()->where('version_id', $new->id)->get(['id', 'type_name'])->keyBy('type_name');
$domainsAdded = 0;
$domainsRemoved = 0;
$domainsChanged = 0;
$codesAdded = 0;
$codesRemoved = 0;
$codesChanged = 0;
$perDomain = [];
$allDomainNames = $oldDomains->keys()->merge($newDomains->keys())->unique()->sort()->values();
foreach ($allDomainNames as $typeName) {
$oldDomain = $oldDomains->get($typeName);
$newDomain = $newDomains->get($typeName);
if (!$oldDomain && $newDomain) {
$domainsAdded++;
$count = FeXsdCode::query()->where('domain_id', $newDomain->id)->count();
$codesAdded += $count;
$perDomain[] = ['type_name' => $typeName, 'added' => $count, 'removed' => 0, 'changed' => 0];
continue;
}
if ($oldDomain && !$newDomain) {
$domainsRemoved++;
$count = FeXsdCode::query()->where('domain_id', $oldDomain->id)->count();
$codesRemoved += $count;
$perDomain[] = ['type_name' => $typeName, 'added' => 0, 'removed' => $count, 'changed' => 0];
continue;
}
if (!$oldDomain || !$newDomain) {
continue;
}
// Confronto per code + documentation.
$oldCodes = FeXsdCode::query()
->where('domain_id', $oldDomain->id)
->get(['code', 'documentation'])
->keyBy('code');
$newCodes = FeXsdCode::query()
->where('domain_id', $newDomain->id)
->get(['code', 'documentation'])
->keyBy('code');
$added = $newCodes->keys()->diff($oldCodes->keys())->count();
$removed = $oldCodes->keys()->diff($newCodes->keys())->count();
$changed = 0;
foreach ($newCodes as $code => $row) {
if (!$oldCodes->has($code)) {
continue;
}
$oldDoc = (string) ($oldCodes->get($code)?->documentation ?? '');
$newDoc = (string) ($row->documentation ?? '');
if (trim($oldDoc) !== trim($newDoc)) {
$changed++;
}
}
if ($added + $removed + $changed > 0) {
$domainsChanged++;
$codesAdded += $added;
$codesRemoved += $removed;
$codesChanged += $changed;
$perDomain[] = ['type_name' => $typeName, 'added' => $added, 'removed' => $removed, 'changed' => $changed];
}
}
return [
'old_version_id' => $old?->id,
'new_version_id' => $new->id,
'domains_added' => $domainsAdded,
'domains_removed' => $domainsRemoved,
'domains_changed' => $domainsChanged,
'codes_added' => $codesAdded,
'codes_removed' => $codesRemoved,
'codes_changed' => $codesChanged,
'per_domain' => $perDomain,
];
}
}