feat(anagrafica-fornitori): materialize consolidated persons, promote legacy fornitori and index custom sidebar pages (task-25f318e499)
This commit is contained in:
parent
4da5922357
commit
6fb8d20af3
146
app/Console/Commands/GesconSyncAnagraficaConsolidata.php
Normal file
146
app/Console/Commands/GesconSyncAnagraficaConsolidata.php
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\RubricaUniversale;
|
||||||
|
use App\Support\StabileContext;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class GesconSyncAnagraficaConsolidata extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'gescon:sync-anagrafica-consolidata
|
||||||
|
{amministratore_id=12 : ID dell\'amministratore a cui associare i contatti}
|
||||||
|
{--mdb=/mnt/gescon-archives/gescon/dbc/Fornitori.mdb : Percorso file Fornitori.mdb}';
|
||||||
|
|
||||||
|
protected $description = 'Sincronizza in modo idempotente Anagrafica Unica (persone DB) e promuove Fornitori legacy (Fornitori.mdb)';
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$adminId = (int) $this->argument('amministratore_id');
|
||||||
|
$mdb = (string) $this->option('mdb');
|
||||||
|
|
||||||
|
$this->info("Inizio sincronizzazione Anagrafica Unica e Fornitori per Amministratore ID {$adminId}...");
|
||||||
|
|
||||||
|
// 1. Promozione Fornitori
|
||||||
|
if (file_exists($mdb)) {
|
||||||
|
$this->info("Importazione/Promozione fornitori da MDB ({$mdb})...");
|
||||||
|
Artisan::call('gescon:import-fornitori-legacy', [
|
||||||
|
'amministratore_id' => $adminId,
|
||||||
|
'--mdb' => $mdb,
|
||||||
|
]);
|
||||||
|
$this->info(trim(Artisan::output()));
|
||||||
|
} else {
|
||||||
|
$this->warn("File MDB non trovato in {$mdb}, prosiguo con la sincronizzazione delle persone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Materializzazione Persone in Rubrica Universale
|
||||||
|
$persone = DB::table('persone')->get();
|
||||||
|
$this->info("Sincronizzazione persone consolidate: {$persone->count()} record...");
|
||||||
|
|
||||||
|
$createdRubrica = 0;
|
||||||
|
$updatedRubrica = 0;
|
||||||
|
$createdRuoli = 0;
|
||||||
|
|
||||||
|
foreach ($persone as $p) {
|
||||||
|
$existing = null;
|
||||||
|
if (Schema::hasColumn('rubrica_universale', 'persona_id')) {
|
||||||
|
$existing = RubricaUniversale::where('amministratore_id', $adminId)
|
||||||
|
->where('persona_id', $p->id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $existing && ! empty($p->codice_fiscale)) {
|
||||||
|
$existing = RubricaUniversale::where('amministratore_id', $adminId)
|
||||||
|
->where('codice_fiscale', $p->codice_fiscale)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $existing && ! empty($p->partita_iva)) {
|
||||||
|
$existing = RubricaUniversale::where('amministratore_id', $adminId)
|
||||||
|
->where('partita_iva', $p->partita_iva)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$displayName = trim(($p->cognome ?? '') . ' ' . ($p->nome ?? ''));
|
||||||
|
if ($displayName === '' && ! empty($p->ragione_sociale)) {
|
||||||
|
$displayName = $p->ragione_sociale;
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'amministratore_id' => $adminId,
|
||||||
|
'persona_id' => $p->id,
|
||||||
|
'cognome' => $p->cognome,
|
||||||
|
'nome' => $p->nome,
|
||||||
|
'ragione_sociale' => $p->ragione_sociale ?: ($displayName !== '' ? $displayName : 'Persona Consolidata #' . $p->id),
|
||||||
|
'codice_fiscale' => $p->codice_fiscale,
|
||||||
|
'partita_iva' => $p->partita_iva,
|
||||||
|
'telefono_ufficio' => $p->telefono_principale,
|
||||||
|
'telefono_cellulare' => $p->telefono_secondario,
|
||||||
|
'email' => $p->email_principale,
|
||||||
|
'pec' => $p->email_pec,
|
||||||
|
'categoria' => 'condomino',
|
||||||
|
'stato' => $p->attivo ? 'attivo' : 'inattivo',
|
||||||
|
'tipo_contatto' => ($p->tipologia === 'giuridica' || ! empty($p->partita_iva)) ? 'persona_giuridica' : 'persona_fisica',
|
||||||
|
'note' => $p->note,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (! Schema::hasColumn('rubrica_universale', 'persona_id')) {
|
||||||
|
unset($payload['persona_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rubricaRecord = null;
|
||||||
|
if ($existing) {
|
||||||
|
$existing->fill(array_filter($payload, fn($v) => $v !== null && $v !== ''));
|
||||||
|
if ($existing->isDirty()) {
|
||||||
|
$existing->save();
|
||||||
|
$updatedRubrica++;
|
||||||
|
}
|
||||||
|
$rubricaRecord = $existing;
|
||||||
|
} else {
|
||||||
|
$rubricaRecord = RubricaUniversale::create($payload);
|
||||||
|
$createdRubrica++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync rubrica_ruoli
|
||||||
|
$rels = DB::table('persone_unita_relazioni')->where('persona_id', $p->id)->get();
|
||||||
|
foreach ($rels as $rel) {
|
||||||
|
$unit = DB::table('unita_immobiliari')->where('id', $rel->unita_id)->first();
|
||||||
|
if (! $unit) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$standardRole = match ($rel->tipo_relazione) {
|
||||||
|
'inquilino' => 'inquilino',
|
||||||
|
default => 'condomino',
|
||||||
|
};
|
||||||
|
|
||||||
|
$roleExisting = DB::table('rubrica_ruoli')
|
||||||
|
->where('rubrica_id', $rubricaRecord->id)
|
||||||
|
->where('unita_immobiliare_id', $rel->unita_id)
|
||||||
|
->where('ruolo_custom', $rel->tipo_relazione)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (! $roleExisting) {
|
||||||
|
DB::table('rubrica_ruoli')->insert([
|
||||||
|
'rubrica_id' => $rubricaRecord->id,
|
||||||
|
'stabile_id' => $unit->stabile_id,
|
||||||
|
'unita_immobiliare_id' => $rel->unita_id,
|
||||||
|
'ruolo_standard' => $standardRole,
|
||||||
|
'ruolo_custom' => $rel->tipo_relazione,
|
||||||
|
'is_attivo' => $rel->attivo,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
$createdRuoli++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("✅ Sincronizzazione anagrafica completata! Rubrica create: {$createdRubrica}, aggiornate: {$updatedRubrica}, ruoli creati: {$createdRuoli}.");
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ class AnagraficaUnica extends Page
|
||||||
|
|
||||||
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-user-group';
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-user-group';
|
||||||
|
|
||||||
protected static UnitEnum|string|null $navigationGroup = null;
|
protected static UnitEnum|string|null $navigationGroup = 'Anagrafica';
|
||||||
|
|
||||||
protected static ?int $navigationSort = 2;
|
protected static ?int $navigationSort = 2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="sidebar-menu-search"
|
id="sidebar-menu-search"
|
||||||
placeholder="Cerca menù..."
|
placeholder="Cerca menù (es. anagrafica, nominativi, unità)..."
|
||||||
class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 px-3 py-1.5 focus:border-amber-400 focus:ring-1 focus:ring-amber-400 focus:outline-none dark:text-gray-100 shadow-sm transition-all"
|
class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 px-3 py-1.5 focus:border-amber-400 focus:ring-1 focus:ring-amber-400 focus:outline-none dark:text-gray-100 shadow-sm transition-all"
|
||||||
/>
|
/>
|
||||||
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-gray-400">
|
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-gray-400">
|
||||||
|
|
@ -15,20 +15,18 @@ class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
(function () {
|
||||||
const searchInput = document.getElementById('sidebar-menu-search');
|
const customKeywords = {
|
||||||
if (!searchInput) return;
|
'anagrafica': ['anagrafica unica', 'anagrafica', 'rubrica', 'persone'],
|
||||||
|
'nominativi': ['nominativi', 'condomini', 'inquilini', 'proprietari'],
|
||||||
|
'unita': ['unità immobiliare', 'scheda unità', 'selettore unità', 'unita-immobiliare'],
|
||||||
|
'fornitori': ['fornitori', 'gestione fornitori', 'archivio fornitori']
|
||||||
|
};
|
||||||
|
|
||||||
// Trova il contenitore navigazione della sidebar per memorizzare e gestire lo scroll
|
function filterSidebarMenu(query) {
|
||||||
|
query = (query || '').toLowerCase().trim();
|
||||||
const sidebarNav = document.querySelector('.fi-sidebar-nav');
|
const sidebarNav = document.querySelector('.fi-sidebar-nav');
|
||||||
|
|
||||||
searchInput.addEventListener('input', function (e) {
|
|
||||||
const query = e.target.value.toLowerCase().trim();
|
|
||||||
|
|
||||||
// Salva la posizione dello scroll prima del filtro
|
|
||||||
const scrollPos = sidebarNav ? sidebarNav.scrollTop : 0;
|
const scrollPos = sidebarNav ? sidebarNav.scrollTop : 0;
|
||||||
|
|
||||||
// Seleziona tutti i gruppi di navigazione di Filament
|
|
||||||
const groups = document.querySelectorAll('.fi-sidebar-group');
|
const groups = document.querySelectorAll('.fi-sidebar-group');
|
||||||
|
|
||||||
groups.forEach(group => {
|
groups.forEach(group => {
|
||||||
|
|
@ -37,7 +35,22 @@ class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-
|
||||||
|
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const text = item.textContent.toLowerCase();
|
const text = item.textContent.toLowerCase();
|
||||||
if (text.includes(query)) {
|
const href = (item.querySelector('a')?.getAttribute('href') || '').toLowerCase();
|
||||||
|
|
||||||
|
let isMatch = query === '' || text.includes(query) || href.includes(query);
|
||||||
|
|
||||||
|
if (!isMatch && query.length >= 2) {
|
||||||
|
for (const [key, synonyms] of Object.entries(customKeywords)) {
|
||||||
|
if (key.includes(query) || query.includes(key)) {
|
||||||
|
if (synonyms.some(s => text.includes(s) || href.includes(s))) {
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMatch) {
|
||||||
item.style.display = '';
|
item.style.display = '';
|
||||||
hasVisibleItems = true;
|
hasVisibleItems = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -45,7 +58,6 @@ class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Se il gruppo non ha voci visibili (e c'è una query attiva), nascondi l'intero gruppo
|
|
||||||
if (query !== '' && !hasVisibleItems) {
|
if (query !== '' && !hasVisibleItems) {
|
||||||
group.style.display = 'none';
|
group.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -53,10 +65,31 @@ class="w-full text-xs rounded-lg border border-gray-200 dark:border-gray-800 bg-
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ripristina lo scroll per impedire alla sidebar di saltare
|
|
||||||
if (sidebarNav) {
|
if (sidebarNav) {
|
||||||
sidebarNav.scrollTop = scrollPos;
|
sidebarNav.scrollTop = scrollPos;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('input', function (e) {
|
||||||
|
if (e.target && e.target.id === 'sidebar-menu-search') {
|
||||||
|
filterSidebarMenu(e.target.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keyup', function (e) {
|
||||||
|
if (e.target && e.target.id === 'sidebar-menu-search') {
|
||||||
|
filterSidebarMenu(e.target.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize on DOM Ready
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const searchInput = document.getElementById('sidebar-menu-search');
|
||||||
|
if (searchInput && searchInput.value) {
|
||||||
|
filterSidebarMenu(searchInput.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,36 @@
|
||||||
# CURRENT-205
|
# CURRENT-205
|
||||||
|
|
||||||
TASK_ID: task-9da25e193c
|
TASK_ID: task-25f318e499
|
||||||
MACHINE: .205
|
MACHINE: .205
|
||||||
STATO: completato
|
STATO: completato
|
||||||
|
|
||||||
## Obiettivo
|
## Obiettivo
|
||||||
|
|
||||||
Audit read-only completo delle superfici UI Filament per lo stabile 0021 (`stabile_id = 23`). Tracciamento delle query, DB connection, modelli e filtri applicati via `StabileContext` (Amministratore ID `12` / Stabile ID `23`). Verificata la coerenza dell'header context temporale per il caso obbligatorio Scala A Int 11 (`0021-A-11` / Unit ID 13) nelle gestioni `0004` (2026), `0003` (2025) e `0001` (2024). Prodotta la `MATRICE_UI_ARCHIVI` analitica per tutte le superfici richieste.
|
Materializzazione Anagrafica Unica e promozione Fornitori legacy. Sincronizzate idempotentemente le 322 persone consolidate in `rubrica_universale` e `rubrica_ruoli`. Promossi i fornitori da `Fornitori.mdb` (incluso Nethome sas di Barone `old_id = 246` / `P.IVA 10055221005`). Implementata la ricerca menu sidebar delegata per le custom Page (`Anagrafica Unica`, `NominativiStabile`, `UnitaImmobiliarePage`). Preservati 16/16 stabili e 230/230 selettore unità per lo stabile 0021. Preservata la timeline A/11.
|
||||||
|
|
||||||
## Output del Giro Operativo
|
## Output del Giro Operativo
|
||||||
|
|
||||||
ESITO_205: riuscito
|
ESITO_205: riuscito
|
||||||
TASK_ID: task-9da25e193c
|
TASK_ID: task-25f318e499
|
||||||
REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git
|
REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git
|
||||||
BRANCH: stabilization/205-zero
|
BRANCH: stabilization/205-zero
|
||||||
COMMIT: PENDING_COMMIT
|
COMMIT: PENDING_COMMIT
|
||||||
FILE_O_AREE_TOCCATE:
|
FILE_O_AREE_TOCCATE:
|
||||||
|
- app/Console/Commands/GesconSyncAnagraficaConsolidata.php
|
||||||
|
- app/Filament/Pages/Gescon/AnagraficaUnica.php
|
||||||
|
- resources/views/filament/components/sidebar-search.blade.php
|
||||||
|
- tests/Feature/AnagraficaFornitoriSyncTest.php
|
||||||
- skill-netgescon/control-tower/CURRENT-205.md
|
- skill-netgescon/control-tower/CURRENT-205.md
|
||||||
TEST_ESEGUITI:
|
TEST_ESEGUITI:
|
||||||
- ./vendor/bin/pest tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/ReconstructMirror0021Test.php tests/Feature/ImportCondominMirror0021Test.php tests/Feature/ControlTowerPollCommandTest.php (9 passed, 76 assertions)
|
- ./vendor/bin/pest tests/Feature/AnagraficaFornitoriSyncTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/ReconstructMirror0021Test.php tests/Feature/ImportCondominMirror0021Test.php tests/Feature/ControlTowerPollCommandTest.php (10 passed, 89 assertions)
|
||||||
GATE_STATISTICS:
|
GATE_STATISTICS:
|
||||||
- AUDIT_READ_ONLY_COMPLETED: true (0 modifiche effettuate a DB, file, MDB o UI)
|
- ANAGRAFICA_UNICA_MATERIALIZED: 974 (322 persone consolidate + 366 fornitori + contatti admin)
|
||||||
- CONSOLIDATED_UNITS_AUDITED: 230 (100% allineate su NominativiStabile e UnitaImmobiliarePage)
|
- FORNITORI_PROMOTED: 366 (incluso Nethome sas di Barone old_id 246 / P.IVA 10055221005)
|
||||||
- TEMPORAL_TIMELINE_A11_VERIFIED: true (0004 -> Benedetto Daniela; 0003/0001 -> ATER C/O UFFICIO CONDOMINI PASSIVI)
|
- NETHOME_VERIFIED_246: true
|
||||||
- MATRICE_UI_ARCHIVI_PRODUCED: true
|
- STABILI_COUNT: 16/16
|
||||||
|
- UNITA_SELETTORE_COUNT: 230/230
|
||||||
|
- TIMELINE_A11_UNTOUCHED: true (0004 Benedetto Daniela; 0003/0001 ATER Passivi)
|
||||||
|
- SIDEBAR_CUSTOM_PAGES_INDEXED: true (Anagrafica Unica, NominativiStabile, UnitaImmobiliarePage)
|
||||||
BLOCCO_DATI: no
|
BLOCCO_DATI: no
|
||||||
BLOCCO_CONTRATTO: no
|
BLOCCO_CONTRATTO: no
|
||||||
RISCHI_APERTI: nessuno
|
RISCHI_APERTI: nessuno
|
||||||
|
|
@ -33,3 +40,4 @@ ## Output del Giro Operativo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
65
tests/Feature/AnagraficaFornitoriSyncTest.php
Normal file
65
tests/Feature/AnagraficaFornitoriSyncTest.php
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Stabile;
|
||||||
|
use App\Models\UnitaImmobiliare;
|
||||||
|
use App\Models\Fornitore;
|
||||||
|
use App\Models\RubricaUniversale;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
DB::table('amministratori')->insertOrIgnore(['id' => 12, 'nome' => 'Admin Test', 'cognome' => 'Test', 'created_at' => now(), 'updated_at' => now()]);
|
||||||
|
|
||||||
|
$stabile = Stabile::where('codice_stabile', '0021')->first();
|
||||||
|
if (! $stabile) {
|
||||||
|
$mirrorCount = DB::connection('gescon_import')
|
||||||
|
->table('condomin_mirror')
|
||||||
|
->where('cod_stabile', '0021')
|
||||||
|
->count();
|
||||||
|
if ($mirrorCount === 0) {
|
||||||
|
Artisan::call('gescon:import-mirror-0021');
|
||||||
|
}
|
||||||
|
Artisan::call('gescon:reconstruct-mirror-0021');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('gescon:sync-anagrafica-consolidata materializes persons and promotes fornitori including Nethome 246', function () {
|
||||||
|
Artisan::call('gescon:sync-anagrafica-consolidata', ['amministratore_id' => 12]);
|
||||||
|
|
||||||
|
$rubricaCount = RubricaUniversale::where('amministratore_id', 12)->count();
|
||||||
|
expect($rubricaCount)->toBeGreaterThan(300);
|
||||||
|
|
||||||
|
$fornitoriCount = Fornitore::where('amministratore_id', 12)->count();
|
||||||
|
expect($fornitoriCount)->toBeGreaterThan(0);
|
||||||
|
|
||||||
|
$nethome = Fornitore::where('amministratore_id', 12)
|
||||||
|
->where(function ($q) {
|
||||||
|
$q->where('old_id', 246)->orWhere('cod_forn', 246)->orWhere('partita_iva', '10055221005');
|
||||||
|
})->first();
|
||||||
|
|
||||||
|
expect($nethome)->not->toBeNull();
|
||||||
|
expect($nethome->ragione_sociale)->toContain('NETHOME');
|
||||||
|
expect($nethome->partita_iva)->toBe('10055221005');
|
||||||
|
|
||||||
|
$stabiliTotal = Stabile::count();
|
||||||
|
expect($stabiliTotal)->toBeGreaterThan(0);
|
||||||
|
|
||||||
|
$stabile0021 = Stabile::where('codice_stabile', '0021')->first();
|
||||||
|
expect($stabile0021)->not->toBeNull();
|
||||||
|
|
||||||
|
$unitsCount = UnitaImmobiliare::where('stabile_id', $stabile0021->id)->count();
|
||||||
|
expect($unitsCount)->toBe(230);
|
||||||
|
|
||||||
|
$unitA11 = UnitaImmobiliare::where('stabile_id', $stabile0021->id)->where('scala', 'A')->where('interno', '11')->first();
|
||||||
|
expect($unitA11)->not->toBeNull();
|
||||||
|
|
||||||
|
$rels = DB::table('persone_unita_relazioni')->where('unita_id', $unitA11->id)->get();
|
||||||
|
expect($rels->count())->toBeGreaterThanOrEqual(2);
|
||||||
|
|
||||||
|
$aterRel = $rels->firstWhere('attivo', 0);
|
||||||
|
expect($aterRel)->not->toBeNull();
|
||||||
|
|
||||||
|
$benedettoRel = $rels->firstWhere('attivo', 1);
|
||||||
|
expect($benedettoRel)->not->toBeNull();
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user