115 lines
3.9 KiB
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,
|
|
];
|
|
}
|
|
}
|