fix(millesimi): align comproprietari matching across all stabili (OTTAVIANO B/1), load voc_spe voci di spesa, fix dropdown owner display and canonicalabile code folder paths (task-d095b0e23b)
This commit is contained in:
parent
836e59ea4e
commit
39dd7e515c
|
|
@ -1089,7 +1089,23 @@ protected function loadDettaglioTabella(): void
|
|||
|
||||
$dettagliByUnita = $tabella->dettagliMillesimali->keyBy('unita_immobiliare_id');
|
||||
|
||||
$periodOccupants = \Illuminate\Support\Facades\DB::table('unita_anagrafica_periodo')
|
||||
$rubricaOccupants = DB::table('rubrica_ruoli as rr')
|
||||
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
||||
->whereIn('rr.unita_immobiliare_id', $tutteUnita->pluck('id')->all())
|
||||
->where('rr.stabile_id', $this->stabileId)
|
||||
->where('rr.is_attivo', 1)
|
||||
->select([
|
||||
'rr.unita_immobiliare_id',
|
||||
'rr.ruolo_standard',
|
||||
'ru.nome_completo',
|
||||
'ru.ragione_sociale',
|
||||
'ru.cognome',
|
||||
'ru.nome',
|
||||
])
|
||||
->get()
|
||||
->groupBy('unita_immobiliare_id');
|
||||
|
||||
$periodOccupants = DB::table('unita_anagrafica_periodo')
|
||||
->join('anagrafiche', 'anagrafiche.id', '=', 'unita_anagrafica_periodo.anagrafica_id')
|
||||
->whereIn('unita_anagrafica_periodo.unita_immobiliare_id', $tutteUnita->pluck('id')->all())
|
||||
->select([
|
||||
|
|
@ -1113,27 +1129,58 @@ protected function loadDettaglioTabella(): void
|
|||
(int) $u->id
|
||||
);
|
||||
})
|
||||
->map(function ($u) use ($dettagliByUnita, $periodOccupants, $totale) {
|
||||
->map(function ($u) use ($dettagliByUnita, $rubricaOccupants, $periodOccupants, $totale) {
|
||||
$d = $dettagliByUnita->get($u->id);
|
||||
$millesimi = $d ? (float) ($d->millesimi ?? 0) : 0.0;
|
||||
$percentuale = $totale > 0 ? ($millesimi / $totale) * 100 : 0;
|
||||
|
||||
$occupants = $periodOccupants->get($u->id, collect());
|
||||
|
||||
$proprietarioList = $occupants->filter(fn($p) => strtoupper(trim((string)$p->ruolo_occupazione)) === 'C');
|
||||
$rOcc = $rubricaOccupants->get($u->id, collect());
|
||||
$proprietarioList = $rOcc->filter(fn($p) => in_array(strtolower(trim((string)$p->ruolo_standard)), ['condomino', 'proprietario', 'comproprietario', 'nudo_proprietario', 'usufruttuario'], true));
|
||||
$propNames = [];
|
||||
foreach ($proprietarioList as $p) {
|
||||
$propNames[] = trim($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome));
|
||||
$n = trim((string) ($p->nome_completo ?: ($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome))));
|
||||
if ($n !== '' && ! in_array($n, $propNames, true)) {
|
||||
$propNames[] = $n;
|
||||
}
|
||||
}
|
||||
|
||||
if ($propNames === []) {
|
||||
$occupants = $periodOccupants->get($u->id, collect());
|
||||
$pList = $occupants->filter(fn($p) => strtoupper(trim((string)$p->ruolo_occupazione)) === 'C');
|
||||
foreach ($pList as $p) {
|
||||
$n = trim($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome));
|
||||
if ($n !== '' && ! in_array($n, $propNames, true)) {
|
||||
$propNames[] = $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($propNames === [] && trim((string)$u->denominazione) !== '') {
|
||||
$propNames[] = trim((string)$u->denominazione);
|
||||
}
|
||||
|
||||
$proprietarioName = count($propNames) > 0 ? implode(' / ', $propNames) : '—';
|
||||
|
||||
$inquilinoList = $occupants->filter(fn($p) => strtoupper(trim((string)$p->ruolo_occupazione)) === 'I');
|
||||
$inquilinoList = $rOcc->filter(fn($p) => in_array(strtolower(trim((string)$p->ruolo_standard)), ['inquilino', 'locatario', 'conduttore'], true));
|
||||
$inqNames = [];
|
||||
foreach ($inquilinoList as $p) {
|
||||
$inqNames[] = trim($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome));
|
||||
$n = trim((string) ($p->nome_completo ?: ($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome))));
|
||||
if ($n !== '' && ! in_array($n, $inqNames, true)) {
|
||||
$inqNames[] = $n;
|
||||
}
|
||||
}
|
||||
if ($inqNames === []) {
|
||||
$occupants = $periodOccupants->get($u->id, collect());
|
||||
$iList = $occupants->filter(fn($p) => strtoupper(trim((string)$p->ruolo_occupazione)) === 'I');
|
||||
foreach ($iList as $p) {
|
||||
$n = trim($p->ragione_sociale ?: ($p->cognome . ' ' . $p->nome));
|
||||
if ($n !== '' && ! in_array($n, $inqNames, true)) {
|
||||
$inqNames[] = $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
$inquilinoName = count($inqNames) > 0 ? implode(' / ', $inqNames) : '—';
|
||||
|
||||
$inquilinoName = count($inqNames) > 0 ? implode(' / ', $inqNames) : '—';
|
||||
$ruolo = $d ? ($d->ruolo_legacy ?: 'C') : 'C';
|
||||
|
||||
return [
|
||||
|
|
@ -1196,9 +1243,97 @@ protected function loadVociSpesa(): void
|
|||
];
|
||||
})->all();
|
||||
|
||||
if (empty($this->vociSpesa)) {
|
||||
$this->vociSpesa = $this->loadVociSpesaFromLegacyMdb();
|
||||
}
|
||||
|
||||
$this->presetDirty = false;
|
||||
}
|
||||
|
||||
protected function loadVociSpesaFromLegacyMdb(): array
|
||||
{
|
||||
if (! $this->stabileId || ! $this->tabellaId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$codStabile = $this->codiceStabile;
|
||||
if (! $codStabile) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$tabellaCod = $this->tabellaInfo['codice'] ?? null;
|
||||
if (! $tabellaCod) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$gYear = sprintf('%04d', $this->annoGestione ?: 2026);
|
||||
$candidatePaths = [
|
||||
"/mnt/gescon-archives/gescon/{$codStabile}/{$gYear}/singolo_anno.mdb",
|
||||
"/mnt/gescon-archives/gescon/{$codStabile}/0914/singolo_anno.mdb",
|
||||
"/mnt/gescon-archives/gescon/{$codStabile}/0015/singolo_anno.mdb",
|
||||
"/mnt/gescon-archives/gescon/{$codStabile}/0004/singolo_anno.mdb",
|
||||
];
|
||||
|
||||
$mdbPath = null;
|
||||
foreach ($candidatePaths as $p) {
|
||||
if (file_exists($p) && is_readable($p)) {
|
||||
$mdbPath = $p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! $mdbPath) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$proc = new \Symfony\Component\Process\Process(['mdb-export', $mdbPath, 'voc_spe']);
|
||||
$proc->run();
|
||||
if (! $proc->isSuccessful()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$csvContent = $proc->getOutput();
|
||||
$stream = fopen('php://memory', 'r+');
|
||||
fwrite($stream, $csvContent);
|
||||
rewind($stream);
|
||||
|
||||
$header = fgetcsv($stream);
|
||||
if (! $header) {
|
||||
fclose($stream);
|
||||
return [];
|
||||
}
|
||||
|
||||
$res = [];
|
||||
while (($data = fgetcsv($stream)) !== false) {
|
||||
if (count($data) === count($header)) {
|
||||
$row = array_combine($header, $data);
|
||||
$tCod = trim((string) ($row['tabella'] ?? ''));
|
||||
if (strcasecmp($tCod, $tabellaCod) === 0 || strcasecmp($tCod, 'TAB.' . $tabellaCod) === 0) {
|
||||
$pInq = is_numeric($row['Perc_Inquilino'] ?? null) ? (float) $row['Perc_Inquilino'] : 0.0;
|
||||
$pProp = is_numeric($row['Perc_proprietario'] ?? null) && (float) $row['Perc_proprietario'] > 0 ? (float) $row['Perc_proprietario'] : (100.0 - $pInq);
|
||||
|
||||
$res[] = [
|
||||
'id' => null,
|
||||
'codice' => trim((string) ($row['cod'] ?? 'VOC')),
|
||||
'descrizione' => trim((string) ($row['descriz'] ?? 'Voce di spesa')),
|
||||
'categoria' => trim((string) ($row['v_ors'] ?? 'O')),
|
||||
'tipo_gestione' => trim((string) ($row['v_ors'] ?? 'O')),
|
||||
'percentuale_condomino' => $pProp,
|
||||
'percentuale_inquilino' => $pInq,
|
||||
'attiva' => true,
|
||||
'modifica' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($stream);
|
||||
return $res;
|
||||
} catch (\Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadPresetOptions(): void
|
||||
{
|
||||
$this->presetOptions = [];
|
||||
|
|
|
|||
|
|
@ -758,68 +758,61 @@ protected function refreshUnitaOptions(): void
|
|||
}
|
||||
|
||||
$currentNominativoByUnita = [];
|
||||
|
||||
if (DbSchema::hasTable('rubrica_ruoli') && DbSchema::hasTable('rubrica_universale')) {
|
||||
try {
|
||||
$rows = DB::table('rubrica_ruoli as rr')
|
||||
->join('rubrica_universale as ru', 'rr.rubrica_id', '=', 'ru.id')
|
||||
->whereIn('rr.unita_immobiliare_id', $unita->pluck('id'))
|
||||
->where('rr.stabile_id', $this->stabileId)
|
||||
->where('rr.is_attivo', 1)
|
||||
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), ['condomino', 'proprietario', 'comproprietario', 'nudo_proprietario', 'usufruttuario'])
|
||||
->select('rr.unita_immobiliare_id', 'ru.nome_completo', 'ru.cognome', 'ru.nome', 'ru.ragione_sociale')
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$unitId = (int) ($row->unita_immobiliare_id ?? 0);
|
||||
if ($unitId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim((string) ($row->nome_completo ?: ($row->ragione_sociale ?: ($row->cognome . ' ' . $row->nome))));
|
||||
if ($name !== '') {
|
||||
if (! isset($currentNominativoByUnita[$unitId])) {
|
||||
$currentNominativoByUnita[$unitId] = [];
|
||||
}
|
||||
if (! in_array($name, $currentNominativoByUnita[$unitId], true)) {
|
||||
$currentNominativoByUnita[$unitId][] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Ignore fallback error
|
||||
}
|
||||
}
|
||||
|
||||
if (DbSchema::hasTable('unita_immobiliare_nominativi')) {
|
||||
try {
|
||||
$today = now()->toDateString();
|
||||
$rows = DB::table('unita_immobiliare_nominativi')
|
||||
$rows = DB::table('unita_immobiliare_nominativi')
|
||||
->whereIn('unita_immobiliare_id', $unita->pluck('id'))
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('data_inizio')->orWhere('data_inizio', '<=', $today);
|
||||
})
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('data_fine')->orWhere('data_fine', '>=', $today);
|
||||
})
|
||||
->orderByRaw("CASE WHEN ruolo = 'C' THEN 0 ELSE 1 END")
|
||||
->orderByDesc('data_inizio')
|
||||
->whereIn('ruolo', ['C', 'P', 'CP'])
|
||||
->orderByDesc('id')
|
||||
->get(['unita_immobiliare_id', 'nominativo']);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$unitId = (int) ($row->unita_immobiliare_id ?? 0);
|
||||
if ($unitId <= 0 || isset($currentNominativoByUnita[$unitId])) {
|
||||
if ($unitId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim((string) ($row->nominativo ?? ''));
|
||||
if ($name !== '') {
|
||||
$currentNominativoByUnita[$unitId] = $name;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$currentNominativoByUnita = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (DbSchema::hasTable('persone_unita_relazioni') && DbSchema::hasTable('persone')) {
|
||||
try {
|
||||
$today = now()->toDateString();
|
||||
$rows = DB::table('persone_unita_relazioni as pur')
|
||||
->join('persone as p', 'pur.persona_id', '=', 'p.id')
|
||||
->whereIn('pur.unita_id', $unita->pluck('id'))
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('pur.data_inizio')->orWhere('pur.data_inizio', '<=', $today);
|
||||
})
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('pur.data_fine')->orWhere('pur.data_fine', '>=', $today);
|
||||
})
|
||||
->where('pur.attivo', 1)
|
||||
->orderByRaw("CASE WHEN pur.tipo_relazione = 'proprietario' THEN 0 ELSE 1 END")
|
||||
->orderByDesc('pur.data_inizio')
|
||||
->select('pur.unita_id', 'p.cognome', 'p.nome', 'p.ragione_sociale')
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$unitId = (int) ($row->unita_id ?? 0);
|
||||
if ($unitId <= 0 || isset($currentNominativoByUnita[$unitId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim((string) ($row->ragione_sociale ?? ''));
|
||||
if ($name === '') {
|
||||
$name = trim((string) ($row->cognome ?? '') . ' ' . (string) ($row->nome ?? ''));
|
||||
}
|
||||
if ($name !== '') {
|
||||
$currentNominativoByUnita[$unitId] = $name;
|
||||
if (! isset($currentNominativoByUnita[$unitId])) {
|
||||
$currentNominativoByUnita[$unitId] = [];
|
||||
}
|
||||
if (! in_array($name, $currentNominativoByUnita[$unitId], true)) {
|
||||
$currentNominativoByUnita[$unitId][] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
|
|
@ -827,42 +820,11 @@ protected function refreshUnitaOptions(): void
|
|||
}
|
||||
}
|
||||
|
||||
if (DbSchema::hasTable('rubrica_ruoli') && DbSchema::hasTable('rubrica_universale')) {
|
||||
try {
|
||||
$today = now()->toDateString();
|
||||
$rows = DB::table('rubrica_ruoli as rr')
|
||||
->join('rubrica_universale as ru', 'rr.rubrica_id', '=', 'ru.id')
|
||||
->whereIn('rr.unita_id', $unita->pluck('id'))
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('rr.data_inizio')->orWhere('rr.data_inizio', '<=', $today);
|
||||
})
|
||||
->where(function ($query) use ($today): void {
|
||||
$query->whereNull('rr.data_fine')->orWhere('rr.data_fine', '>=', $today);
|
||||
})
|
||||
->where('rr.attivo', 1)
|
||||
->orderByRaw("CASE WHEN rr.ruolo = 'proprietario' THEN 0 ELSE 1 END")
|
||||
->orderByDesc('rr.data_inizio')
|
||||
->select('rr.unita_id', 'ru.cognome', 'ru.nome', 'ru.ragione_sociale')
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$unitId = (int) ($row->unita_id ?? 0);
|
||||
if ($unitId <= 0 || isset($currentNominativoByUnita[$unitId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim((string) ($row->ragione_sociale ?? ''));
|
||||
if ($name === '') {
|
||||
$name = trim((string) ($row->cognome ?? '') . ' ' . (string) ($row->nome ?? ''));
|
||||
}
|
||||
if ($name !== '') {
|
||||
$currentNominativoByUnita[$unitId] = $name;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Ignore fallback error
|
||||
}
|
||||
$formattedNominativoByUnita = [];
|
||||
foreach ($currentNominativoByUnita as $uId => $namesArr) {
|
||||
$formattedNominativoByUnita[$uId] = is_array($namesArr) ? implode(' / ', $namesArr) : (string) $namesArr;
|
||||
}
|
||||
$currentNominativoByUnita = $formattedNominativoByUnita;
|
||||
|
||||
$sorted = $unita->sort(function (UnitaImmobiliare $a, UnitaImmobiliare $b): int {
|
||||
$pa = (int) ($a->palazzina_id ?? 0);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public function stabileCode(Stabile | string $stabile): string
|
|||
return $code;
|
||||
}
|
||||
|
||||
$code = trim((string) ($stabile->codice_univoco ?: $stabile->codice_stabile ?: ''));
|
||||
$code = trim((string) ($stabile->codice_stabile ?: $stabile->codice_univoco ?: ''));
|
||||
|
||||
if ($code === '') {
|
||||
throw new InvalidArgumentException('Stabile senza codice archivio canonico.');
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user