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');
|
$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')
|
->join('anagrafiche', 'anagrafiche.id', '=', 'unita_anagrafica_periodo.anagrafica_id')
|
||||||
->whereIn('unita_anagrafica_periodo.unita_immobiliare_id', $tutteUnita->pluck('id')->all())
|
->whereIn('unita_anagrafica_periodo.unita_immobiliare_id', $tutteUnita->pluck('id')->all())
|
||||||
->select([
|
->select([
|
||||||
|
|
@ -1113,27 +1129,58 @@ protected function loadDettaglioTabella(): void
|
||||||
(int) $u->id
|
(int) $u->id
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
->map(function ($u) use ($dettagliByUnita, $periodOccupants, $totale) {
|
->map(function ($u) use ($dettagliByUnita, $rubricaOccupants, $periodOccupants, $totale) {
|
||||||
$d = $dettagliByUnita->get($u->id);
|
$d = $dettagliByUnita->get($u->id);
|
||||||
$millesimi = $d ? (float) ($d->millesimi ?? 0) : 0.0;
|
$millesimi = $d ? (float) ($d->millesimi ?? 0) : 0.0;
|
||||||
$percentuale = $totale > 0 ? ($millesimi / $totale) * 100 : 0;
|
$percentuale = $totale > 0 ? ($millesimi / $totale) * 100 : 0;
|
||||||
|
|
||||||
$occupants = $periodOccupants->get($u->id, collect());
|
$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));
|
||||||
$proprietarioList = $occupants->filter(fn($p) => strtoupper(trim((string)$p->ruolo_occupazione)) === 'C');
|
|
||||||
$propNames = [];
|
$propNames = [];
|
||||||
foreach ($proprietarioList as $p) {
|
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) : '—';
|
$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 = [];
|
$inqNames = [];
|
||||||
foreach ($inquilinoList as $p) {
|
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';
|
$ruolo = $d ? ($d->ruolo_legacy ?: 'C') : 'C';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
@ -1196,9 +1243,97 @@ protected function loadVociSpesa(): void
|
||||||
];
|
];
|
||||||
})->all();
|
})->all();
|
||||||
|
|
||||||
|
if (empty($this->vociSpesa)) {
|
||||||
|
$this->vociSpesa = $this->loadVociSpesaFromLegacyMdb();
|
||||||
|
}
|
||||||
|
|
||||||
$this->presetDirty = false;
|
$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
|
protected function loadPresetOptions(): void
|
||||||
{
|
{
|
||||||
$this->presetOptions = [];
|
$this->presetOptions = [];
|
||||||
|
|
|
||||||
|
|
@ -758,68 +758,61 @@ protected function refreshUnitaOptions(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentNominativoByUnita = [];
|
$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')) {
|
if (DbSchema::hasTable('unita_immobiliare_nominativi')) {
|
||||||
try {
|
try {
|
||||||
$today = now()->toDateString();
|
$rows = DB::table('unita_immobiliare_nominativi')
|
||||||
$rows = DB::table('unita_immobiliare_nominativi')
|
|
||||||
->whereIn('unita_immobiliare_id', $unita->pluck('id'))
|
->whereIn('unita_immobiliare_id', $unita->pluck('id'))
|
||||||
->where(function ($query) use ($today): void {
|
->whereIn('ruolo', ['C', 'P', 'CP'])
|
||||||
$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')
|
|
||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
->get(['unita_immobiliare_id', 'nominativo']);
|
->get(['unita_immobiliare_id', 'nominativo']);
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$unitId = (int) ($row->unita_immobiliare_id ?? 0);
|
$unitId = (int) ($row->unita_immobiliare_id ?? 0);
|
||||||
if ($unitId <= 0 || isset($currentNominativoByUnita[$unitId])) {
|
if ($unitId <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = trim((string) ($row->nominativo ?? ''));
|
$name = trim((string) ($row->nominativo ?? ''));
|
||||||
if ($name !== '') {
|
if ($name !== '') {
|
||||||
$currentNominativoByUnita[$unitId] = $name;
|
if (! isset($currentNominativoByUnita[$unitId])) {
|
||||||
}
|
$currentNominativoByUnita[$unitId] = [];
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
if (! in_array($name, $currentNominativoByUnita[$unitId], true)) {
|
||||||
$currentNominativoByUnita = [];
|
$currentNominativoByUnita[$unitId][] = $name;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
|
@ -827,42 +820,11 @@ protected function refreshUnitaOptions(): void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DbSchema::hasTable('rubrica_ruoli') && DbSchema::hasTable('rubrica_universale')) {
|
$formattedNominativoByUnita = [];
|
||||||
try {
|
foreach ($currentNominativoByUnita as $uId => $namesArr) {
|
||||||
$today = now()->toDateString();
|
$formattedNominativoByUnita[$uId] = is_array($namesArr) ? implode(' / ', $namesArr) : (string) $namesArr;
|
||||||
$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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$currentNominativoByUnita = $formattedNominativoByUnita;
|
||||||
|
|
||||||
$sorted = $unita->sort(function (UnitaImmobiliare $a, UnitaImmobiliare $b): int {
|
$sorted = $unita->sort(function (UnitaImmobiliare $a, UnitaImmobiliare $b): int {
|
||||||
$pa = (int) ($a->palazzina_id ?? 0);
|
$pa = (int) ($a->palazzina_id ?? 0);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public function stabileCode(Stabile | string $stabile): string
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
$code = trim((string) ($stabile->codice_univoco ?: $stabile->codice_stabile ?: ''));
|
$code = trim((string) ($stabile->codice_stabile ?: $stabile->codice_univoco ?: ''));
|
||||||
|
|
||||||
if ($code === '') {
|
if ($code === '') {
|
||||||
throw new InvalidArgumentException('Stabile senza codice archivio canonico.');
|
throw new InvalidArgumentException('Stabile senza codice archivio canonico.');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user