Fix acqua views and expose millesimi ordering
This commit is contained in:
parent
91bf6713fd
commit
2639c0a0e3
|
|
@ -325,8 +325,8 @@ public function table(Table $table): Table
|
||||||
->color(function ($state, StabileServizioLettura $record): string {
|
->color(function ($state, StabileServizioLettura $record): string {
|
||||||
return match ((string) data_get($record->raw, 'consistency_check.status', '')) {
|
return match ((string) data_get($record->raw, 'consistency_check.status', '')) {
|
||||||
'warning' => 'warning',
|
'warning' => 'warning',
|
||||||
'danger' => 'danger',
|
'danger' => 'danger',
|
||||||
default => 'gray',
|
default => 'gray',
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
->wrap()
|
->wrap()
|
||||||
|
|
@ -600,15 +600,15 @@ public function table(Table $table): Table
|
||||||
TextInput::make('rilevatore_nome')->label('Nominativo rilevatore')->maxLength(191),
|
TextInput::make('rilevatore_nome')->label('Nominativo rilevatore')->maxLength(191),
|
||||||
Textarea::make('motivo')->label('Nota riassegnazione')->rows(3)->maxLength(1000),
|
Textarea::make('motivo')->label('Nota riassegnazione')->rows(3)->maxLength(1000),
|
||||||
])
|
])
|
||||||
->fillForm(fn(StabileServizioLettura $record): array => [
|
->fillForm(fn(StabileServizioLettura $record): array=> [
|
||||||
'unita_immobiliare_id' => $record->unita_immobiliare_id,
|
'unita_immobiliare_id' => $record->unita_immobiliare_id,
|
||||||
'rilevatore_tipo' => (string) ($record->rilevatore_tipo ?? ''),
|
'rilevatore_tipo' => (string) ($record->rilevatore_tipo ?? ''),
|
||||||
'rilevatore_nome' => (string) ($record->rilevatore_nome ?? ''),
|
'rilevatore_nome' => (string) ($record->rilevatore_nome ?? ''),
|
||||||
'motivo' => '',
|
'motivo' => '',
|
||||||
])
|
])
|
||||||
->action(function (StabileServizioLettura $record, array $data): void {
|
->action(function (StabileServizioLettura $record, array $data): void {
|
||||||
$raw = is_array($record->raw ?? null) ? $record->raw : [];
|
$raw = is_array($record->raw ?? null) ? $record->raw : [];
|
||||||
$reassignments = is_array($raw['reassignments'] ?? null) ? $raw['reassignments'] : [];
|
$reassignments = is_array($raw['reassignments'] ?? null) ? $raw['reassignments'] : [];
|
||||||
$reassignments[] = [
|
$reassignments[] = [
|
||||||
'from_unita_immobiliare_id' => (int) ($record->getOriginal('unita_immobiliare_id') ?? 0) ?: null,
|
'from_unita_immobiliare_id' => (int) ($record->getOriginal('unita_immobiliare_id') ?? 0) ?: null,
|
||||||
'to_unita_immobiliare_id' => (int) ($data['unita_immobiliare_id'] ?? 0) ?: null,
|
'to_unita_immobiliare_id' => (int) ($data['unita_immobiliare_id'] ?? 0) ?: null,
|
||||||
|
|
@ -618,7 +618,7 @@ public function table(Table $table): Table
|
||||||
'changed_by' => Auth::id(),
|
'changed_by' => Auth::id(),
|
||||||
'changed_at' => now()->toIso8601String(),
|
'changed_at' => now()->toIso8601String(),
|
||||||
];
|
];
|
||||||
$raw['reassignments'] = $reassignments;
|
$raw['reassignments'] = $reassignments;
|
||||||
$raw['reader_assignment'] = [
|
$raw['reader_assignment'] = [
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'name' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: null,
|
'name' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: null,
|
||||||
|
|
@ -626,12 +626,12 @@ public function table(Table $table): Table
|
||||||
];
|
];
|
||||||
|
|
||||||
$record->fill([
|
$record->fill([
|
||||||
'unita_immobiliare_id' => (int) ($data['unita_immobiliare_id'] ?? 0) ?: null,
|
'unita_immobiliare_id' => (int) ($data['unita_immobiliare_id'] ?? 0) ?: null,
|
||||||
'rilevatore_tipo' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: null,
|
'rilevatore_tipo' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: null,
|
||||||
'rilevatore_nome' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: null,
|
'rilevatore_nome' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: null,
|
||||||
'lettura_precedente_valore' => null,
|
'lettura_precedente_valore' => null,
|
||||||
'lettura_precedente_foto_path' => null,
|
'lettura_precedente_foto_path' => null,
|
||||||
'raw' => $raw,
|
'raw' => $raw,
|
||||||
]);
|
]);
|
||||||
$record->save();
|
$record->save();
|
||||||
$this->hydrateReadingWithPreviousData($record);
|
$this->hydrateReadingWithPreviousData($record);
|
||||||
|
|
@ -659,7 +659,7 @@ public function table(Table $table): Table
|
||||||
TextInput::make('rilevatore_nome')->label('Nominativo rilevatore')->maxLength(191),
|
TextInput::make('rilevatore_nome')->label('Nominativo rilevatore')->maxLength(191),
|
||||||
Textarea::make('motivo')->label('Motivo spostamento')->rows(3)->maxLength(1000),
|
Textarea::make('motivo')->label('Motivo spostamento')->rows(3)->maxLength(1000),
|
||||||
])
|
])
|
||||||
->fillForm(fn(StabileServizioLettura $record): array => [
|
->fillForm(fn(StabileServizioLettura $record): array=> [
|
||||||
'stabile_servizio_id' => $record->stabile_servizio_id,
|
'stabile_servizio_id' => $record->stabile_servizio_id,
|
||||||
'rilevatore_tipo' => (string) ($record->rilevatore_tipo ?? ''),
|
'rilevatore_tipo' => (string) ($record->rilevatore_tipo ?? ''),
|
||||||
'rilevatore_nome' => (string) ($record->rilevatore_nome ?? ''),
|
'rilevatore_nome' => (string) ($record->rilevatore_nome ?? ''),
|
||||||
|
|
@ -668,7 +668,7 @@ public function table(Table $table): Table
|
||||||
->visible(fn(StabileServizioLettura $record): bool => strtolower(trim((string) ($record->servizio?->tipo ?? ''))) === 'acqua')
|
->visible(fn(StabileServizioLettura $record): bool => strtolower(trim((string) ($record->servizio?->tipo ?? ''))) === 'acqua')
|
||||||
->action(function (StabileServizioLettura $record, array $data): void {
|
->action(function (StabileServizioLettura $record, array $data): void {
|
||||||
$targetServiceId = (int) ($data['stabile_servizio_id'] ?? 0);
|
$targetServiceId = (int) ($data['stabile_servizio_id'] ?? 0);
|
||||||
$targetService = StabileServizio::query()
|
$targetService = StabileServizio::query()
|
||||||
->where('id', $targetServiceId)
|
->where('id', $targetServiceId)
|
||||||
->where('stabile_id', (int) $record->stabile_id)
|
->where('stabile_id', (int) $record->stabile_id)
|
||||||
->where('tipo', 'acqua')
|
->where('tipo', 'acqua')
|
||||||
|
|
@ -679,20 +679,20 @@ public function table(Table $table): Table
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$raw = is_array($record->raw ?? null) ? $record->raw : [];
|
$raw = is_array($record->raw ?? null) ? $record->raw : [];
|
||||||
$movements = is_array($raw['common_meter_movements'] ?? null) ? $raw['common_meter_movements'] : [];
|
$movements = is_array($raw['common_meter_movements'] ?? null) ? $raw['common_meter_movements'] : [];
|
||||||
$movements[] = [
|
$movements[] = [
|
||||||
'from_stabile_servizio_id' => (int) ($record->getOriginal('stabile_servizio_id') ?? 0) ?: null,
|
'from_stabile_servizio_id' => (int) ($record->getOriginal('stabile_servizio_id') ?? 0) ?: null,
|
||||||
'to_stabile_servizio_id' => (int) $targetService->id,
|
'to_stabile_servizio_id' => (int) $targetService->id,
|
||||||
'from_unita_immobiliare_id'=> (int) ($record->getOriginal('unita_immobiliare_id') ?? 0) ?: null,
|
'from_unita_immobiliare_id' => (int) ($record->getOriginal('unita_immobiliare_id') ?? 0) ?: null,
|
||||||
'to_unita_immobiliare_id' => null,
|
'to_unita_immobiliare_id' => null,
|
||||||
'note' => trim((string) ($data['motivo'] ?? '')),
|
'note' => trim((string) ($data['motivo'] ?? '')),
|
||||||
'changed_by' => Auth::id(),
|
'changed_by' => Auth::id(),
|
||||||
'changed_at' => now()->toIso8601String(),
|
'changed_at' => now()->toIso8601String(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$raw['common_meter_movements'] = $movements;
|
$raw['common_meter_movements'] = $movements;
|
||||||
$raw['reader_assignment'] = [
|
$raw['reader_assignment'] = [
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'name' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: (trim((string) ($record->rilevatore_nome ?? '')) ?: null),
|
'name' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: (trim((string) ($record->rilevatore_nome ?? '')) ?: null),
|
||||||
'type' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: (trim((string) ($record->rilevatore_tipo ?? '')) ?: null),
|
'type' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: (trim((string) ($record->rilevatore_tipo ?? '')) ?: null),
|
||||||
|
|
@ -705,15 +705,15 @@ public function table(Table $table): Table
|
||||||
];
|
];
|
||||||
|
|
||||||
$record->fill([
|
$record->fill([
|
||||||
'stabile_servizio_id' => (int) $targetService->id,
|
'stabile_servizio_id' => (int) $targetService->id,
|
||||||
'unita_immobiliare_id' => null,
|
'unita_immobiliare_id' => null,
|
||||||
'fornitore_id' => $targetService->fornitore_id,
|
'fornitore_id' => $targetService->fornitore_id,
|
||||||
'rilevatore_tipo' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: $record->rilevatore_tipo,
|
'rilevatore_tipo' => trim((string) ($data['rilevatore_tipo'] ?? '')) ?: $record->rilevatore_tipo,
|
||||||
'rilevatore_nome' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: $record->rilevatore_nome,
|
'rilevatore_nome' => trim((string) ($data['rilevatore_nome'] ?? '')) ?: $record->rilevatore_nome,
|
||||||
'tipologia_lettura' => 'autolettura_contatore_generale',
|
'tipologia_lettura' => 'autolettura_contatore_generale',
|
||||||
'lettura_precedente_valore' => null,
|
'lettura_precedente_valore' => null,
|
||||||
'lettura_precedente_foto_path' => null,
|
'lettura_precedente_foto_path' => null,
|
||||||
'raw' => $raw,
|
'raw' => $raw,
|
||||||
]);
|
]);
|
||||||
$record->save();
|
$record->save();
|
||||||
$this->hydrateReadingWithPreviousData($record);
|
$this->hydrateReadingWithPreviousData($record);
|
||||||
|
|
@ -874,9 +874,9 @@ private function getServiziOptions(): array
|
||||||
->orderBy('nome')
|
->orderBy('nome')
|
||||||
->get(['id', 'tipo', 'nome', 'contatore_matricola', 'meta'])
|
->get(['id', 'tipo', 'nome', 'contatore_matricola', 'meta'])
|
||||||
->mapWithKeys(function (StabileServizio $s): array {
|
->mapWithKeys(function (StabileServizio $s): array {
|
||||||
$tipo = strtoupper(trim((string) ($s->tipo ?? '')));
|
$tipo = strtoupper(trim((string) ($s->tipo ?? '')));
|
||||||
$nome = trim((string) ($s->nome ?? ''));
|
$nome = trim((string) ($s->nome ?? ''));
|
||||||
$matr = trim((string) ($s->contatore_matricola ?? ''));
|
$matr = trim((string) ($s->contatore_matricola ?? ''));
|
||||||
$asset = trim((string) data_get($s->meta, 'common_asset_label', ''));
|
$asset = trim((string) data_get($s->meta, 'common_asset_label', ''));
|
||||||
|
|
||||||
$label = $nome !== '' ? $nome : ($tipo !== '' ? $tipo : ('Servizio #' . $s->id));
|
$label = $nome !== '' ? $nome : ($tipo !== '' ? $tipo : ('Servizio #' . $s->id));
|
||||||
|
|
@ -1084,11 +1084,11 @@ private function getCommonWaterServiceOptions(int $stabileId): array
|
||||||
->orderBy('contatore_matricola')
|
->orderBy('contatore_matricola')
|
||||||
->get(['id', 'nome', 'contatore_matricola', 'meta'])
|
->get(['id', 'nome', 'contatore_matricola', 'meta'])
|
||||||
->mapWithKeys(function (StabileServizio $service): array {
|
->mapWithKeys(function (StabileServizio $service): array {
|
||||||
$name = trim((string) ($service->nome ?? '')) ?: ('Servizio #' . (int) $service->id);
|
$name = trim((string) ($service->nome ?? '')) ?: ('Servizio #' . (int) $service->id);
|
||||||
$asset = trim((string) data_get($service->meta, 'common_asset_label', ''));
|
$asset = trim((string) data_get($service->meta, 'common_asset_label', ''));
|
||||||
$servedArea = trim((string) data_get($service->meta, 'served_area_label', ''));
|
$servedArea = trim((string) data_get($service->meta, 'served_area_label', ''));
|
||||||
$counterScope = trim((string) data_get($service->meta, 'counter_scope', ''));
|
$counterScope = trim((string) data_get($service->meta, 'counter_scope', ''));
|
||||||
$matricola = trim((string) ($service->contatore_matricola ?? ''));
|
$matricola = trim((string) ($service->contatore_matricola ?? ''));
|
||||||
|
|
||||||
$parts = array_filter([
|
$parts = array_filter([
|
||||||
$name,
|
$name,
|
||||||
|
|
|
||||||
|
|
@ -637,16 +637,16 @@ private function getServiceTypeOptions(): array
|
||||||
private function getCommonAssetScopeOptions(): array
|
private function getCommonAssetScopeOptions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'locale' => 'Locale',
|
'locale' => 'Locale',
|
||||||
'spazio' => 'Spazio comune',
|
'spazio' => 'Spazio comune',
|
||||||
'impianto' => 'Impianto',
|
'impianto' => 'Impianto',
|
||||||
'area_esterna' => 'Area esterna / giardino',
|
'area_esterna' => 'Area esterna / giardino',
|
||||||
'copertura' => 'Terrazzo / copertura',
|
'copertura' => 'Terrazzo / copertura',
|
||||||
'accesso' => 'Portone / accesso',
|
'accesso' => 'Portone / accesso',
|
||||||
'servizio' => 'Servizio comune',
|
'servizio' => 'Servizio comune',
|
||||||
'sicurezza' => 'Sicurezza / antincendio',
|
'sicurezza' => 'Sicurezza / antincendio',
|
||||||
'amministrativo'=> 'Privacy / assicurazione / studio',
|
'amministrativo' => 'Privacy / assicurazione / studio',
|
||||||
'altro' => 'Altro',
|
'altro' => 'Altro',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,12 +657,12 @@ private function getAllocationScopeOptions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'tutti_millesimi' => 'Tutti per millesimi',
|
'tutti_millesimi' => 'Tutti per millesimi',
|
||||||
'condomini_utilizzatori' => 'Condomini utilizzatori',
|
'condomini_utilizzatori' => 'Condomini utilizzatori',
|
||||||
'inquilini_utilizzatori' => 'Inquilini utilizzatori',
|
'inquilini_utilizzatori' => 'Inquilini utilizzatori',
|
||||||
'condomini_inquilini_utilizzatori'=> 'Condomini + inquilini utilizzatori',
|
'condomini_inquilini_utilizzatori' => 'Condomini + inquilini utilizzatori',
|
||||||
'rimborso_spese' => 'Rimborso spese uso bene comune',
|
'rimborso_spese' => 'Rimborso spese uso bene comune',
|
||||||
'gestione_studio' => 'Gestione studio / amministrazione',
|
'gestione_studio' => 'Gestione studio / amministrazione',
|
||||||
'altro' => 'Altro criterio',
|
'altro' => 'Altro criterio',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -672,11 +672,11 @@ private function getAllocationScopeOptions(): array
|
||||||
private function getFiscalScopeOptions(): array
|
private function getFiscalScopeOptions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'spesa_condominiale' => 'Spesa condominiale',
|
'spesa_condominiale' => 'Spesa condominiale',
|
||||||
'rimborso_non_fiscale' => 'Rimborso spese non fiscale',
|
'rimborso_non_fiscale' => 'Rimborso spese non fiscale',
|
||||||
'da_fatturare' => 'Da fatturare',
|
'da_fatturare' => 'Da fatturare',
|
||||||
'polizza_o_servizio' => 'Polizza / servizio',
|
'polizza_o_servizio' => 'Polizza / servizio',
|
||||||
'non_applicabile' => 'Non applicabile',
|
'non_applicabile' => 'Non applicabile',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,9 +177,9 @@ protected function getTableQuery(): Builder
|
||||||
return TabellaMillesimale::query()->whereRaw('1 = 0');
|
return TabellaMillesimale::query()->whereRaw('1 = 0');
|
||||||
}
|
}
|
||||||
|
|
||||||
$orderColumn = Schema::hasColumn('tabelle_millesimali', 'ordine_visualizzazione')
|
$orderColumn = Schema::hasColumn('tabelle_millesimali', 'nord')
|
||||||
? 'ordine_visualizzazione'
|
? 'nord'
|
||||||
: (Schema::hasColumn('tabelle_millesimali', 'nord') ? 'nord' : (Schema::hasColumn('tabelle_millesimali', 'ordinamento') ? 'ordinamento' : 'id'));
|
: (Schema::hasColumn('tabelle_millesimali', 'ordine_visualizzazione') ? 'ordine_visualizzazione' : (Schema::hasColumn('tabelle_millesimali', 'ordinamento') ? 'ordinamento' : 'id'));
|
||||||
|
|
||||||
return TabellaMillesimale::query()
|
return TabellaMillesimale::query()
|
||||||
->where('stabile_id', $activeStabileId)
|
->where('stabile_id', $activeStabileId)
|
||||||
|
|
@ -326,13 +326,13 @@ public function table(Table $table): Table
|
||||||
])
|
])
|
||||||
->columns([
|
->columns([
|
||||||
TextColumn::make(
|
TextColumn::make(
|
||||||
Schema::hasColumn('tabelle_millesimali', 'ordine_visualizzazione')
|
Schema::hasColumn('tabelle_millesimali', 'nord')
|
||||||
? 'ordine_visualizzazione'
|
? 'nord'
|
||||||
: 'ordinamento'
|
: (Schema::hasColumn('tabelle_millesimali', 'ordine_visualizzazione') ? 'ordine_visualizzazione' : 'ordinamento')
|
||||||
)
|
)
|
||||||
->label('Ord.')
|
->label('Nord')
|
||||||
->sortable()
|
->sortable()
|
||||||
->toggleable(isToggledHiddenByDefault: true),
|
->toggleable(),
|
||||||
|
|
||||||
TextColumn::make('codice_tabella')
|
TextColumn::make('codice_tabella')
|
||||||
->label('Codice')
|
->label('Codice')
|
||||||
|
|
@ -614,7 +614,7 @@ protected function loadTabelle(): void
|
||||||
->ordinato();
|
->ordinato();
|
||||||
|
|
||||||
$this->tabelle = $q
|
$this->tabelle = $q
|
||||||
->get(['id', 'codice_tabella', 'nome_tabella', 'denominazione', 'tipo_tabella', 'tipo_calcolo', 'totale_millesimi', 'ordinamento', 'meta_legacy'])
|
->get(['id', 'codice_tabella', 'nome_tabella', 'denominazione', 'tipo_tabella', 'tipo_calcolo', 'totale_millesimi', 'ordinamento', 'ordine_visualizzazione', 'nord', 'meta_legacy'])
|
||||||
->map(function (TabellaMillesimale $t) {
|
->map(function (TabellaMillesimale $t) {
|
||||||
$codice = $t->codice_tabella ?: ($t->nome_tabella ?: ('TAB ' . $t->id));
|
$codice = $t->codice_tabella ?: ($t->nome_tabella ?: ('TAB ' . $t->id));
|
||||||
$nome = $t->denominazione ?: ($t->nome_tabella_millesimale ?: ($t->nome_tabella ?: 'Tabella'));
|
$nome = $t->denominazione ?: ($t->nome_tabella_millesimale ?: ($t->nome_tabella ?: 'Tabella'));
|
||||||
|
|
@ -634,11 +634,12 @@ protected function loadTabelle(): void
|
||||||
'id' => (int) $t->id,
|
'id' => (int) $t->id,
|
||||||
'codice' => $codice,
|
'codice' => $codice,
|
||||||
'nome' => $nome,
|
'nome' => $nome,
|
||||||
|
'nord' => $this->resolveNordValue($t),
|
||||||
'tipo' => $tipoLabel,
|
'tipo' => $tipoLabel,
|
||||||
'calcolo' => $calcoloLabel,
|
'calcolo' => $calcoloLabel,
|
||||||
'is_consumo' => $isConsumo,
|
'is_consumo' => $isConsumo,
|
||||||
'totale' => is_numeric($t->totale_millesimi) ? (float) $t->totale_millesimi : null,
|
'totale' => is_numeric($t->totale_millesimi) ? (float) $t->totale_millesimi : null,
|
||||||
'ordinamento' => (int) ($t->ordinamento ?? 999999),
|
'ordinamento' => $this->resolveNordValue($t) ?? (int) ($t->ordine_visualizzazione ?? $t->ordinamento ?? 999999),
|
||||||
'is_bilanciata' => (bool) ($t->is_bilanciata ?? false),
|
'is_bilanciata' => (bool) ($t->is_bilanciata ?? false),
|
||||||
'preventivo' => is_numeric($prev) ? (float) $prev : null,
|
'preventivo' => is_numeric($prev) ? (float) $prev : null,
|
||||||
'consuntivo' => is_numeric($cons) ? (float) $cons : null,
|
'consuntivo' => is_numeric($cons) ? (float) $cons : null,
|
||||||
|
|
@ -646,6 +647,23 @@ protected function loadTabelle(): void
|
||||||
})
|
})
|
||||||
->values()
|
->values()
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
|
usort($this->tabelle, static function (array $left, array $right): int {
|
||||||
|
$leftNord = is_numeric($left['ordinamento'] ?? null) ? (int) $left['ordinamento'] : 999999;
|
||||||
|
$rightNord = is_numeric($right['ordinamento'] ?? null) ? (int) $right['ordinamento'] : 999999;
|
||||||
|
|
||||||
|
if ($leftNord !== $rightNord) {
|
||||||
|
return $leftNord <=> $rightNord;
|
||||||
|
}
|
||||||
|
|
||||||
|
$leftTipo = (string) ($left['tipo'] ?? '');
|
||||||
|
$rightTipo = (string) ($right['tipo'] ?? '');
|
||||||
|
if ($leftTipo !== $rightTipo) {
|
||||||
|
return strnatcasecmp($leftTipo, $rightTipo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strnatcasecmp((string) ($left['codice'] ?? ''), (string) ($right['codice'] ?? ''));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function pickTabellaId(?int $candidate): ?int
|
protected function pickTabellaId(?int $candidate): ?int
|
||||||
|
|
@ -1075,7 +1093,6 @@ private function formatCodiceUnita(?string $codice): ?string
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefix = is_string($this->codiceStabile) ? trim($this->codiceStabile) : '';
|
|
||||||
if ($prefix !== '') {
|
if ($prefix !== '') {
|
||||||
$pattern = '/^' . preg_quote($prefix, '/') . '[\s\-\/]+/';
|
$pattern = '/^' . preg_quote($prefix, '/') . '[\s\-\/]+/';
|
||||||
$codice = preg_replace($pattern, '', $codice) ?? $codice;
|
$codice = preg_replace($pattern, '', $codice) ?? $codice;
|
||||||
|
|
@ -1338,4 +1355,16 @@ private function isConsumoCalcolo(?string $calcolo): bool
|
||||||
$c = strtolower(trim((string) ($calcolo ?? '')));
|
$c = strtolower(trim((string) ($calcolo ?? '')));
|
||||||
return in_array($c, ['acqua', 'a', 'consumo', 'c', 'a_consumo'], true);
|
return in_array($c, ['acqua', 'a', 'consumo', 'c', 'a_consumo'], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function resolveNordValue(TabellaMillesimale $t): ?int
|
||||||
|
{
|
||||||
|
foreach (['nord', 'ordine_visualizzazione', 'ordinamento'] as $field) {
|
||||||
|
$value = $t->{$field} ?? null;
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public function getActiveStabileDestinationSummaryProperty(): string
|
||||||
}
|
}
|
||||||
|
|
||||||
$summary = $this->getActiveStabileLabelProperty();
|
$summary = $this->getActiveStabileLabelProperty();
|
||||||
$cf = $this->resolveStabileSoggettoCf($stabile);
|
$cf = $this->resolveStabileSoggettoCf($stabile);
|
||||||
|
|
||||||
if ($cf !== '') {
|
if ($cf !== '') {
|
||||||
$summary .= "\nCodice fiscale soggetto usato per lo scarico: {$cf}";
|
$summary .= "\nCodice fiscale soggetto usato per lo scarico: {$cf}";
|
||||||
|
|
@ -355,9 +355,9 @@ private function resolveStabileSoggettoCf(Stabile $stabile): string
|
||||||
|
|
||||||
private function isLikelyTechnicalFeShell(Stabile $stabile): bool
|
private function isLikelyTechnicalFeShell(Stabile $stabile): bool
|
||||||
{
|
{
|
||||||
$stabileCf = $this->resolveStabileSoggettoCf($stabile);
|
$stabileCf = $this->resolveStabileSoggettoCf($stabile);
|
||||||
$adminCf = strtoupper(trim((string) ($stabile->amministratore?->codice_fiscale_studio ?? '')));
|
$adminCf = strtoupper(trim((string) ($stabile->amministratore?->codice_fiscale_studio ?? '')));
|
||||||
$code = strtoupper(trim((string) ($stabile->codice_stabile ?? '')));
|
$code = strtoupper(trim((string) ($stabile->codice_stabile ?? '')));
|
||||||
$legacyCode = trim((string) ($stabile->cod_stabile ?? ''));
|
$legacyCode = trim((string) ($stabile->cod_stabile ?? ''));
|
||||||
|
|
||||||
return $stabileCf !== ''
|
return $stabileCf !== ''
|
||||||
|
|
|
||||||
|
|
@ -943,13 +943,13 @@ private function resolveUnitSearchNames(UnitaImmobiliare $unita): array
|
||||||
*/
|
*/
|
||||||
private function resolveRelevantHistoricNames(UnitaImmobiliare $unita): array
|
private function resolveRelevantHistoricNames(UnitaImmobiliare $unita): array
|
||||||
{
|
{
|
||||||
$today = now()->toDateString();
|
$today = now()->toDateString();
|
||||||
$historic = collect($unita->nominativiStorici ?? []);
|
$historic = collect($unita->nominativiStorici ?? []);
|
||||||
|
|
||||||
$current = $historic
|
$current = $historic
|
||||||
->filter(function ($item) use ($today): bool {
|
->filter(function ($item) use ($today): bool {
|
||||||
$start = trim((string) ($item->data_inizio ?? ''));
|
$start = trim((string) ($item->data_inizio ?? ''));
|
||||||
$end = trim((string) ($item->data_fine ?? ''));
|
$end = trim((string) ($item->data_fine ?? ''));
|
||||||
|
|
||||||
return ($start === '' || $start <= $today)
|
return ($start === '' || $start <= $today)
|
||||||
&& ($end === '' || $end >= $today);
|
&& ($end === '' || $end >= $today);
|
||||||
|
|
|
||||||
|
|
@ -920,10 +920,10 @@ private function buildReadingConsistencyCheck(int $servizioId, ?int $unitaId, fl
|
||||||
private function formatCounterScopeLabel(string $value): string
|
private function formatCounterScopeLabel(string $value): string
|
||||||
{
|
{
|
||||||
return match (strtolower(trim($value))) {
|
return match (strtolower(trim($value))) {
|
||||||
'generale' => 'generale',
|
'generale' => 'generale',
|
||||||
'particolare' => 'particolare',
|
'particolare' => 'particolare',
|
||||||
'assente' => 'senza contatore',
|
'assente' => 'senza contatore',
|
||||||
default => trim($value) !== '' ? trim($value) : 'n/d',
|
default => trim($value) !== '' ? trim($value) : 'n/d',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ private function resetLightUnitSelection(): void
|
||||||
{
|
{
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
||||||
$this->unitaId = null;
|
$this->unitaId = null;
|
||||||
$this->unitaSearch = '';
|
$this->unitaSearch = '';
|
||||||
$this->previousReading = null;
|
$this->previousReading = null;
|
||||||
$this->suggestedReaderName = null;
|
$this->suggestedReaderName = null;
|
||||||
|
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ public function panel(Panel $panel): Panel
|
||||||
->renderHook(PanelsRenderHook::HEAD_END, fn() => view('filament.components.legacy-admin-assets'))
|
->renderHook(PanelsRenderHook::HEAD_END, fn() => view('filament.components.legacy-admin-assets'))
|
||||||
->renderHook(PanelsRenderHook::TOPBAR_LOGO_AFTER, fn() => view('filament.components.topbar-context'))
|
->renderHook(PanelsRenderHook::TOPBAR_LOGO_AFTER, fn() => view('filament.components.topbar-context'))
|
||||||
->renderHook(PanelsRenderHook::USER_MENU_BEFORE, fn() => view('filament.components.topbar-icons'))
|
->renderHook(PanelsRenderHook::USER_MENU_BEFORE, fn() => view('filament.components.topbar-icons'))
|
||||||
->renderHook(PanelsRenderHook::FOOTER, fn() => view('filament.components.footer'))
|
|
||||||
->navigationItems([
|
->navigationItems([
|
||||||
NavigationItem::make('Rubrica Unica')
|
NavigationItem::make('Rubrica Unica')
|
||||||
->group('NetGescon')
|
->group('NetGescon')
|
||||||
|
|
@ -133,7 +132,7 @@ public function panel(Panel $panel): Panel
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveSupplierCatalogUrl(): string
|
protected function resolveSupplierCatalogUrl(): string
|
||||||
{
|
{
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Services\Consumi;
|
namespace App\Services\Consumi;
|
||||||
|
|
||||||
use App\Models\CategoriaTicket;
|
use App\Models\CategoriaTicket;
|
||||||
|
|
@ -33,7 +32,7 @@ public function ingest(
|
||||||
}
|
}
|
||||||
|
|
||||||
$storedPayload = [];
|
$storedPayload = [];
|
||||||
$storedRaw = is_string($fattura->consumo_raw ?? null) ? trim((string) $fattura->consumo_raw) : '';
|
$storedRaw = is_string($fattura->consumo_raw ?? null) ? trim((string) $fattura->consumo_raw) : '';
|
||||||
if ($storedRaw !== '') {
|
if ($storedRaw !== '') {
|
||||||
$decoded = json_decode($storedRaw, true);
|
$decoded = json_decode($storedRaw, true);
|
||||||
if (is_array($decoded) && (($decoded['type'] ?? null) === 'acqua')) {
|
if (is_array($decoded) && (($decoded['type'] ?? null) === 'acqua')) {
|
||||||
|
|
@ -51,13 +50,13 @@ public function ingest(
|
||||||
$parsed['consumi'] = $storedPayload['consumi'];
|
$parsed['consumi'] = $storedPayload['consumi'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$codici = is_array($parsed['codici'] ?? null) ? $parsed['codici'] : [];
|
$codici = is_array($parsed['codici'] ?? null) ? $parsed['codici'] : [];
|
||||||
$contatore = is_array($parsed['contatore'] ?? null) ? $parsed['contatore'] : [];
|
$contatore = is_array($parsed['contatore'] ?? null) ? $parsed['contatore'] : [];
|
||||||
$consumi = is_array($parsed['consumi'] ?? null) ? $parsed['consumi'] : [];
|
$consumi = is_array($parsed['consumi'] ?? null) ? $parsed['consumi'] : [];
|
||||||
|
|
||||||
$matricola = is_string($contatore['matricola'] ?? null) ? trim((string) $contatore['matricola']) : '';
|
$matricola = is_string($contatore['matricola'] ?? null) ? trim((string) $contatore['matricola']) : '';
|
||||||
$utenza = is_string($codici['utenza'] ?? null) ? trim((string) $codici['utenza']) : '';
|
$utenza = is_string($codici['utenza'] ?? null) ? trim((string) $codici['utenza']) : '';
|
||||||
$cliente = is_string($codici['cliente'] ?? null) ? trim((string) $codici['cliente']) : '';
|
$cliente = is_string($codici['cliente'] ?? null) ? trim((string) $codici['cliente']) : '';
|
||||||
$contratto = is_string($codici['contratto'] ?? null) ? trim((string) $codici['contratto']) : '';
|
$contratto = is_string($codici['contratto'] ?? null) ? trim((string) $codici['contratto']) : '';
|
||||||
|
|
||||||
$norm = static function (?string $value): string {
|
$norm = static function (?string $value): string {
|
||||||
|
|
@ -82,13 +81,13 @@ public function ingest(
|
||||||
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
||||||
'Parser acqua: dati non trovati',
|
'Parser acqua: dati non trovati',
|
||||||
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
||||||
. ($error !== '' ? ('Errore: ' . $error . "\n") : '')
|
. ($error !== '' ? ('Errore: ' . $error . "\n") : '')
|
||||||
. 'Nessun codice utenza/cliente/contratto, nessuna matricola contatore e nessun periodo consumo rilevato.',
|
. 'Nessun codice utenza/cliente/contratto, nessuna matricola contatore e nessun periodo consumo rilevato.',
|
||||||
) ? 1 : 0;
|
) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'status' => 'no-data',
|
'status' => 'no-data',
|
||||||
'tickets' => $tickets,
|
'tickets' => $tickets,
|
||||||
'message' => $error !== '' ? $error : 'Dati acqua non trovati nel PDF',
|
'message' => $error !== '' ? $error : 'Dati acqua non trovati nel PDF',
|
||||||
];
|
];
|
||||||
|
|
@ -107,22 +106,22 @@ public function ingest(
|
||||||
|
|
||||||
// Mismatch detection: se il servizio ha già un identificativo e il PDF ne porta un altro, apri ticket e non agganciare.
|
// Mismatch detection: se il servizio ha già un identificativo e il PDF ne porta un altro, apri ticket e non agganciare.
|
||||||
$mismatch = false;
|
$mismatch = false;
|
||||||
$why = [];
|
$why = [];
|
||||||
if (is_string($servizio->contatore_matricola) && $servizio->contatore_matricola !== '' && $matricola !== '' && $servizio->contatore_matricola !== $matricola) {
|
if (is_string($servizio->contatore_matricola) && $servizio->contatore_matricola !== '' && $matricola !== '' && $servizio->contatore_matricola !== $matricola) {
|
||||||
$mismatch = true;
|
$mismatch = true;
|
||||||
$why[] = 'matricola diversa (servizio ' . $servizio->contatore_matricola . ' vs PDF ' . $matricola . ')';
|
$why[] = 'matricola diversa (servizio ' . $servizio->contatore_matricola . ' vs PDF ' . $matricola . ')';
|
||||||
}
|
}
|
||||||
if (is_string($servizio->codice_utenza) && $servizio->codice_utenza !== '' && $utenza !== '' && $servizio->codice_utenza !== $utenza) {
|
if (is_string($servizio->codice_utenza) && $servizio->codice_utenza !== '' && $utenza !== '' && $servizio->codice_utenza !== $utenza) {
|
||||||
$mismatch = true;
|
$mismatch = true;
|
||||||
$why[] = 'utenza diversa (servizio ' . $servizio->codice_utenza . ' vs PDF ' . $utenza . ')';
|
$why[] = 'utenza diversa (servizio ' . $servizio->codice_utenza . ' vs PDF ' . $utenza . ')';
|
||||||
}
|
}
|
||||||
if (is_string($servizio->codice_cliente) && $servizio->codice_cliente !== '' && $cliente !== '' && $servizio->codice_cliente !== $cliente) {
|
if (is_string($servizio->codice_cliente) && $servizio->codice_cliente !== '' && $cliente !== '' && $servizio->codice_cliente !== $cliente) {
|
||||||
$mismatch = true;
|
$mismatch = true;
|
||||||
$why[] = 'cliente diverso (servizio ' . $servizio->codice_cliente . ' vs PDF ' . $cliente . ')';
|
$why[] = 'cliente diverso (servizio ' . $servizio->codice_cliente . ' vs PDF ' . $cliente . ')';
|
||||||
}
|
}
|
||||||
if (is_string($servizio->codice_contratto) && $servizio->codice_contratto !== '' && $contratto !== '' && $servizio->codice_contratto !== $contratto) {
|
if (is_string($servizio->codice_contratto) && $servizio->codice_contratto !== '' && $contratto !== '' && $servizio->codice_contratto !== $contratto) {
|
||||||
$mismatch = true;
|
$mismatch = true;
|
||||||
$why[] = 'contratto diverso (servizio ' . $servizio->codice_contratto . ' vs PDF ' . $contratto . ')';
|
$why[] = 'contratto diverso (servizio ' . $servizio->codice_contratto . ' vs PDF ' . $contratto . ')';
|
||||||
}
|
}
|
||||||
if ($mismatch && $createTicketOnMismatch) {
|
if ($mismatch && $createTicketOnMismatch) {
|
||||||
$tickets += $this->openTicket(
|
$tickets += $this->openTicket(
|
||||||
|
|
@ -147,20 +146,20 @@ public function ingest(
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$targetMatricola = $norm($matricola);
|
$targetMatricola = $norm($matricola);
|
||||||
$targetUtenza = $norm($utenza);
|
$targetUtenza = $norm($utenza);
|
||||||
$targetCliente = $norm($cliente);
|
$targetCliente = $norm($cliente);
|
||||||
$targetContratto = $norm($contratto);
|
$targetContratto = $norm($contratto);
|
||||||
|
|
||||||
$best = null;
|
$best = null;
|
||||||
$bestScore = 0;
|
$bestScore = 0;
|
||||||
$bestTie = 0;
|
$bestTie = 0;
|
||||||
|
|
||||||
foreach ($candidates as $cand) {
|
foreach ($candidates as $cand) {
|
||||||
$score = 0;
|
$score = 0;
|
||||||
|
|
||||||
$candMatricola = $norm(is_string($cand->contatore_matricola) ? $cand->contatore_matricola : null);
|
$candMatricola = $norm(is_string($cand->contatore_matricola) ? $cand->contatore_matricola : null);
|
||||||
$candUtenza = $norm(is_string($cand->codice_utenza) ? $cand->codice_utenza : null);
|
$candUtenza = $norm(is_string($cand->codice_utenza) ? $cand->codice_utenza : null);
|
||||||
$candCliente = $norm(is_string($cand->codice_cliente) ? $cand->codice_cliente : null);
|
$candCliente = $norm(is_string($cand->codice_cliente) ? $cand->codice_cliente : null);
|
||||||
$candContratto = $norm(is_string($cand->codice_contratto) ? $cand->codice_contratto : null);
|
$candContratto = $norm(is_string($cand->codice_contratto) ? $cand->codice_contratto : null);
|
||||||
|
|
||||||
if ($targetMatricola !== '' && $candMatricola !== '' && $targetMatricola === $candMatricola) {
|
if ($targetMatricola !== '' && $candMatricola !== '' && $targetMatricola === $candMatricola) {
|
||||||
|
|
@ -177,9 +176,9 @@ public function ingest(
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($score > $bestScore) {
|
if ($score > $bestScore) {
|
||||||
$best = $cand;
|
$best = $cand;
|
||||||
$bestScore = $score;
|
$bestScore = $score;
|
||||||
$bestTie = 0;
|
$bestTie = 0;
|
||||||
} elseif ($score > 0 && $score === $bestScore) {
|
} elseif ($score > 0 && $score === $bestScore) {
|
||||||
$bestTie++;
|
$bestTie++;
|
||||||
}
|
}
|
||||||
|
|
@ -193,8 +192,8 @@ public function ingest(
|
||||||
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
||||||
'Parser acqua: utenza ambigua',
|
'Parser acqua: utenza ambigua',
|
||||||
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
||||||
. 'Più utenze acqua compatibili con gli identificativi del PDF. ' .
|
. 'Più utenze acqua compatibili con gli identificativi del PDF. ' .
|
||||||
'Matricola=' . ($matricola !== '' ? $matricola : 'n/d') . ', Utenza=' . ($utenza !== '' ? $utenza : 'n/d') . ', Cliente=' . ($cliente !== '' ? $cliente : 'n/d') . ', Contratto=' . ($contratto !== '' ? $contratto : 'n/d'),
|
'Matricola=' . ($matricola !== '' ? $matricola : 'n/d') . ', Utenza=' . ($utenza !== '' ? $utenza : 'n/d') . ', Cliente=' . ($cliente !== '' ? $cliente : 'n/d') . ', Contratto=' . ($contratto !== '' ? $contratto : 'n/d'),
|
||||||
) ? 1 : 0;
|
) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,16 +215,16 @@ public function ingest(
|
||||||
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
(int) ($fattura->fornitore_id ?: 0) ?: null,
|
||||||
'Parser acqua: utenza non riconosciuta',
|
'Parser acqua: utenza non riconosciuta',
|
||||||
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
'FE #' . (int) $fattura->id . ' (' . ($fattura->sdi_file ?? 'n/d') . ")\n"
|
||||||
. 'Identificativi PDF non agganciati a nessuna utenza acqua esistente. ' .
|
. 'Identificativi PDF non agganciati a nessuna utenza acqua esistente. ' .
|
||||||
'Matricola=' . ($matricola !== '' ? $matricola : 'n/d') . ', Utenza=' . ($utenza !== '' ? $utenza : 'n/d') . ', Cliente=' . ($cliente !== '' ? $cliente : 'n/d') . ', Contratto=' . ($contratto !== '' ? $contratto : 'n/d'),
|
'Matricola=' . ($matricola !== '' ? $matricola : 'n/d') . ', Utenza=' . ($utenza !== '' ? $utenza : 'n/d') . ', Cliente=' . ($cliente !== '' ? $cliente : 'n/d') . ', Contratto=' . ($contratto !== '' ? $contratto : 'n/d'),
|
||||||
) ? 1 : 0;
|
) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$servizio = new StabileServizio([
|
$servizio = new StabileServizio([
|
||||||
'stabile_id' => $stabileId,
|
'stabile_id' => $stabileId,
|
||||||
'tipo' => 'acqua',
|
'tipo' => 'acqua',
|
||||||
'nome' => $name,
|
'nome' => $name,
|
||||||
'attivo' => true,
|
'attivo' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -263,36 +262,36 @@ public function ingest(
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($consumi as $c) {
|
foreach ($consumi as $c) {
|
||||||
$dal = is_string($c['dal'] ?? null) ? (string) $c['dal'] : null;
|
$dal = is_string($c['dal'] ?? null) ? (string) $c['dal'] : null;
|
||||||
$al = is_string($c['al'] ?? null) ? (string) $c['al'] : null;
|
$al = is_string($c['al'] ?? null) ? (string) $c['al'] : null;
|
||||||
$val = isset($c['valore']) && is_numeric($c['valore']) ? (float) $c['valore'] : null;
|
$val = isset($c['valore']) && is_numeric($c['valore']) ? (float) $c['valore'] : null;
|
||||||
$unita = is_string($c['unita'] ?? null) ? trim((string) $c['unita']) : '';
|
$unita = is_string($c['unita'] ?? null) ? trim((string) $c['unita']) : '';
|
||||||
$tipo = is_string($c['tipologia_lettura'] ?? null) ? trim((string) $c['tipologia_lettura']) : null;
|
$tipo = is_string($c['tipologia_lettura'] ?? null) ? trim((string) $c['tipologia_lettura']) : null;
|
||||||
|
|
||||||
$lettura = StabileServizioLettura::query()->firstOrNew([
|
$lettura = StabileServizioLettura::query()->firstOrNew([
|
||||||
'stabile_id' => $stabileId,
|
'stabile_id' => $stabileId,
|
||||||
'stabile_servizio_id' => (int) $servizio->id,
|
'stabile_servizio_id' => (int) $servizio->id,
|
||||||
'fattura_elettronica_id' => (int) $fattura->id,
|
'fattura_elettronica_id' => (int) $fattura->id,
|
||||||
'periodo_dal' => $dal,
|
'periodo_dal' => $dal,
|
||||||
'periodo_al' => $al,
|
'periodo_al' => $al,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$isNew = ! $lettura->exists;
|
$isNew = ! $lettura->exists;
|
||||||
|
|
||||||
$lettura->fill([
|
$lettura->fill([
|
||||||
'fornitore_id' => (int) ($fattura->fornitore_id ?: 0) ?: null,
|
'fornitore_id' => (int) ($fattura->fornitore_id ?: 0) ?: null,
|
||||||
'voce_spesa_id' => $voceSpesaId ?: ($servizio->voce_spesa_id ? (int) $servizio->voce_spesa_id : null),
|
'voce_spesa_id' => $voceSpesaId ?: ($servizio->voce_spesa_id ? (int) $servizio->voce_spesa_id : null),
|
||||||
'tipologia_lettura' => $tipo,
|
'tipologia_lettura' => $tipo,
|
||||||
'consumo_valore' => $val,
|
'consumo_valore' => $val,
|
||||||
'consumo_unita' => $unita !== '' ? $unita : 'mc',
|
'consumo_unita' => $unita !== '' ? $unita : 'mc',
|
||||||
'importo_totale' => $importo,
|
'importo_totale' => $importo,
|
||||||
'raw' => [
|
'raw' => [
|
||||||
'source' => 'pdf_ocr',
|
'source' => 'pdf_ocr',
|
||||||
'codici' => $parsed['codici'] ?? null,
|
'codici' => $parsed['codici'] ?? null,
|
||||||
'contatore' => $parsed['contatore'] ?? null,
|
'contatore' => $parsed['contatore'] ?? null,
|
||||||
'consumo' => $c,
|
'consumo' => $c,
|
||||||
],
|
],
|
||||||
'created_by' => $userId > 0 ? $userId : null,
|
'created_by' => $userId > 0 ? $userId : null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$lettura->save();
|
$lettura->save();
|
||||||
|
|
@ -305,11 +304,11 @@ public function ingest(
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'status' => 'ok',
|
'status' => 'ok',
|
||||||
'servizio_id' => (int) $servizio->id,
|
'servizio_id' => (int) $servizio->id,
|
||||||
'created_letture' => $created,
|
'created_letture' => $created,
|
||||||
'updated_letture' => $updated,
|
'updated_letture' => $updated,
|
||||||
'tickets' => $tickets,
|
'tickets' => $tickets,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,14 +345,14 @@ private function openTicket(int $stabileId, int $userId, ?int $fornitoreId, stri
|
||||||
}
|
}
|
||||||
|
|
||||||
Ticket::query()->create([
|
Ticket::query()->create([
|
||||||
'stabile_id' => $stabileId,
|
'stabile_id' => $stabileId,
|
||||||
'aperto_da_user_id' => $userId > 0 ? $userId : 1,
|
'aperto_da_user_id' => $userId > 0 ? $userId : 1,
|
||||||
'categoria_ticket_id' => (int) $cat->id,
|
'categoria_ticket_id' => (int) $cat->id,
|
||||||
'assegnato_a_fornitore_id' => $fornitoreId,
|
'assegnato_a_fornitore_id' => $fornitoreId,
|
||||||
'titolo' => $title,
|
'titolo' => $title,
|
||||||
'descrizione' => $body,
|
'descrizione' => $body,
|
||||||
'stato' => 'Aperto',
|
'stato' => 'Aperto',
|
||||||
'priorita' => 'Media',
|
'priorita' => 'Media',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,73 @@
|
||||||
|
# SESSION HANDOFF - 2026-04-13 / 2026-04-14
|
||||||
|
|
||||||
|
## Stato operativo reale alla chiusura sessione
|
||||||
|
|
||||||
|
- Repository: `/home/michele/netgescon/netgescon-day0`
|
||||||
|
- Focus stabile utente: `0021`, con attenzione anche allo shell tecnico FE `FE221005` (`stabili.id=29`)
|
||||||
|
- Obiettivo operativo chiuso in questa sessione:
|
||||||
|
- rendere esplicito e sicuro il CF soggetto nello scarico FE
|
||||||
|
- semplificare il flusso `ticket-acqua-light`
|
||||||
|
- rimuovere il footer Filament invasivo su mobile
|
||||||
|
- riallineare pagina `tabelle-millesimali` a `nord`, `tipo`, `calcolo`
|
||||||
|
- eliminare i blocchi Blade fragili nelle viste `ticket-acqua` e `ticket-acqua-generale`
|
||||||
|
|
||||||
|
## Verifiche fatte e confermate
|
||||||
|
|
||||||
|
- `php artisan view:clear && php artisan view:cache` eseguito con esito OK dopo gli ultimi fix.
|
||||||
|
- `php artisan route:list` carica `755` route.
|
||||||
|
- Il service FE usa il CF dello stabile, non il CF studio dell'amministratore:
|
||||||
|
- `stabili.id=25 / codice_stabile=0021 / CF=97487690584`
|
||||||
|
- `stabili.id=29 / codice_stabile=FE221005 / CF=10055221005`
|
||||||
|
- Il problema operativo dello scarico FE nasceva dal contesto dello stabile attivo in topbar/sessione, non dalla chiamata HTTP finale.
|
||||||
|
- Nella pagina FE è stato aggiunto un riepilogo esplicito del `Codice fiscale soggetto usato per lo scarico`.
|
||||||
|
- Le due Blade acqua sono state semplificate spostando il rendering metadati foto in partial condivisa, per evitare parse error residui in staging dovuti a blocchi Blade annidati.
|
||||||
|
|
||||||
|
## File toccati in questa fase
|
||||||
|
|
||||||
|
- `app/Providers/Filament/AdminFilamentPanelProvider.php`
|
||||||
|
- chain Filament riparata
|
||||||
|
- footer hook rimosso dal panel
|
||||||
|
- `app/Filament/Pages/Condomini/TabelleMillesimaliArchivio.php`
|
||||||
|
- preferenza a `tabelle_millesimali.nord` per ordinamento archivio
|
||||||
|
- `nord` portato nel payload usato dalla Blade
|
||||||
|
- lista tabelle ordinata per `nord`, poi `tipo`, poi codice
|
||||||
|
- `resources/views/filament/pages/condomini/tabelle-millesimali.blade.php`
|
||||||
|
- badge visivo `Ord. {nord}`
|
||||||
|
- `tipo` e `calcolo` mantenuti visibili nelle liste `prospetto` e `voci`
|
||||||
|
- `resources/views/filament/pages/supporto/ticket-acqua.blade.php`
|
||||||
|
- `resources/views/filament/pages/supporto/ticket-acqua-generale.blade.php`
|
||||||
|
- blocchi metadati foto sostituiti con partial condivisa
|
||||||
|
- `resources/views/filament/pages/supporto/partials/photo-metadata.blade.php`
|
||||||
|
- nuova partial minima in PHP/HTML, senza direttive Blade annidate
|
||||||
|
|
||||||
|
## Comandi rapidi per ripartenza domani
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/michele/netgescon/netgescon-day0
|
||||||
|
git status --short
|
||||||
|
php artisan view:clear
|
||||||
|
php artisan view:cache
|
||||||
|
php artisan route:list | tail -n 2
|
||||||
|
php artisan netgescon:qa-millesimi-spese --stabile=0021 --show-missing=20
|
||||||
|
tail -n 120 storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Punti ancora aperti da riprendere
|
||||||
|
|
||||||
|
1. QA millesimi/voci da rendere piu accurato per le gestioni straordinarie legate all'anno/esercizio.
|
||||||
|
2. Validazione staging reale dopo `git push` + update staging:
|
||||||
|
- `/admin-filament/condomini/tabelle-millesimali`
|
||||||
|
- `/admin-filament/supporto/ticket-acqua`
|
||||||
|
- `/admin-filament/supporto/ticket-acqua-generale`
|
||||||
|
3. Controllo del bug `fornitore Livewire root` ancora aperto nel tracker.
|
||||||
|
4. Diagnosi separata dei nominativi rumorosi per `0023`.
|
||||||
|
|
||||||
|
## Prompt consigliato per un altro agent
|
||||||
|
|
||||||
|
"Riparti da `docs/ai/SESSION_HANDOFF.md`. Prima verifica `git status`, poi esegui `php artisan view:clear && php artisan view:cache`. Controlla staging su `tabelle-millesimali`, `ticket-acqua` e `ticket-acqua-generale`. Se il deploy e allineato, passa al raffinamento del QA millesimi/voci per gestioni straordinarie con anno/esercizio, senza fare bonifiche contabili distruttive."
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# SESSION HANDOFF - 2026-04-08
|
# SESSION HANDOFF - 2026-04-08
|
||||||
|
|
||||||
## Contesto operativo attuale
|
## Contesto operativo attuale
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,13 @@ class="block rounded-xl border p-3 transition
|
||||||
>
|
>
|
||||||
<div class="flex items-start justify-between gap-3">
|
<div class="flex items-start justify-between gap-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-sm font-semibold {{ $selected ? 'text-primary-700' : 'text-gray-900' }}">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
{{ $t['codice'] }}
|
<div class="text-sm font-semibold {{ $selected ? 'text-primary-700' : 'text-gray-900' }}">
|
||||||
|
{{ $t['codice'] }}
|
||||||
|
</div>
|
||||||
|
@if(isset($t['nord']) && $t['nord'] !== null)
|
||||||
|
<span class="inline-flex items-center rounded-full bg-slate-100 px-2 py-0.5 text-[10px] font-semibold text-slate-700">Ord. {{ $t['nord'] }}</span>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-gray-600">{{ $t['nome'] }}</div>
|
<div class="text-xs text-gray-600">{{ $t['nome'] }}</div>
|
||||||
@if(!empty($t['tipo']) || !empty($t['calcolo']))
|
@if(!empty($t['tipo']) || !empty($t['calcolo']))
|
||||||
|
|
@ -241,8 +246,13 @@ class="block rounded-xl border p-3 transition
|
||||||
>
|
>
|
||||||
<div class="flex items-start justify-between gap-3">
|
<div class="flex items-start justify-between gap-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-sm font-semibold {{ $selected ? 'text-primary-700' : 'text-gray-900' }}">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
{{ $t['codice'] }}
|
<div class="text-sm font-semibold {{ $selected ? 'text-primary-700' : 'text-gray-900' }}">
|
||||||
|
{{ $t['codice'] }}
|
||||||
|
</div>
|
||||||
|
@if(isset($t['nord']) && $t['nord'] !== null)
|
||||||
|
<span class="inline-flex items-center rounded-full bg-slate-100 px-2 py-0.5 text-[10px] font-semibold text-slate-700">Ord. {{ $t['nord'] }}</span>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-gray-600">{{ $t['nome'] }}</div>
|
<div class="text-xs text-gray-600">{{ $t['nome'] }}</div>
|
||||||
@if(!empty($t['tipo']) || !empty($t['calcolo']))
|
@if(!empty($t['tipo']) || !empty($t['calcolo']))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
$badgeRows = is_array($badgeRows ?? null) ? $badgeRows : [];
|
||||||
|
$detailRows = is_array($detailRows ?? null) ? $detailRows : [];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($badgeRows !== []): ?>
|
||||||
|
<div class="mt-2 flex flex-wrap gap-1">
|
||||||
|
<?php foreach ($badgeRows as $badge): ?>
|
||||||
|
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-semibold <?= e((string) ($badge['class'] ?? '')) ?>"><?= e((string) ($badge['label'] ?? '')) ?></span>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($detailRows !== []): ?>
|
||||||
|
<div class="mt-2 rounded-lg border border-slate-200 bg-white p-2 text-[11px] text-slate-700">
|
||||||
|
<?php foreach ($detailRows as $detail): ?>
|
||||||
|
<div><span class="font-medium"><?= e((string) ($detail['label'] ?? '')) ?>:</span> <?= e((string) ($detail['value'] ?? '')) ?></div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
@ -63,7 +63,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@php($service = $this->selectedServiceSnapshot)
|
@php
|
||||||
|
$service = $this->selectedServiceSnapshot;
|
||||||
|
@endphp
|
||||||
@if($service)
|
@if($service)
|
||||||
<div class="rounded-2xl border border-emerald-200 bg-emerald-50 p-4 shadow-sm">
|
<div class="rounded-2xl border border-emerald-200 bg-emerald-50 p-4 shadow-sm">
|
||||||
<div class="text-sm font-semibold text-emerald-900">Riferimenti contratto selezionato</div>
|
<div class="text-sm font-semibold text-emerald-900">Riferimenti contratto selezionato</div>
|
||||||
|
|
@ -332,13 +334,7 @@
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
@if($detailRows !== [])
|
@include('filament.pages.supporto.partials.photo-metadata', ['badgeRows' => [], 'detailRows' => $detailRows])
|
||||||
<div class="mt-2 rounded-lg border border-slate-200 bg-white p-2 text-[11px] text-slate-700">
|
|
||||||
@foreach($detailRows as $detail)
|
|
||||||
<div><span class="font-medium">{{ $detail['label'] }}:</span> {{ $detail['value'] }}</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
<label class="mt-2 block">
|
<label class="mt-2 block">
|
||||||
<span class="mb-1 block text-[11px] font-medium">Nota foto</span>
|
<span class="mb-1 block text-[11px] font-medium">Nota foto</span>
|
||||||
<input type="text" wire:model.defer="generalWaterPhotoDescriptions.{{ $upload['index'] }}" class="w-full rounded-lg border-gray-300" placeholder="Es. display principale, targhetta matricola, quadro contatori" />
|
<input type="text" wire:model.defer="generalWaterPhotoDescriptions.{{ $upload['index'] }}" class="w-full rounded-lg border-gray-300" placeholder="Es. display principale, targhetta matricola, quadro contatori" />
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,9 @@
|
||||||
<div wire:loading wire:target="pendingWaterPhotos" class="mt-2 text-xs font-medium text-amber-700">Caricamento foto in corso: preparo la coda della lettura acqua.</div>
|
<div wire:loading wire:target="pendingWaterPhotos" class="mt-2 text-xs font-medium text-amber-700">Caricamento foto in corso: preparo la coda della lettura acqua.</div>
|
||||||
|
|
||||||
@if(count($this->selectedWaterUploads) > 0)
|
@if(count($this->selectedWaterUploads) > 0)
|
||||||
@php($focusUpload = $this->selectedWaterUploads[0] ?? null)
|
@php
|
||||||
|
$focusUpload = $this->selectedWaterUploads[0] ?? null;
|
||||||
|
@endphp
|
||||||
@if($focusUpload)
|
@if($focusUpload)
|
||||||
<div class="mt-4 rounded-2xl border border-sky-200 bg-sky-50 p-3">
|
<div class="mt-4 rounded-2xl border border-sky-200 bg-sky-50 p-3">
|
||||||
<div class="mb-2 text-xs font-semibold text-sky-900">Chicca lettura rapida</div>
|
<div class="mb-2 text-xs font-semibold text-sky-900">Chicca lettura rapida</div>
|
||||||
|
|
@ -318,22 +320,7 @@
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
@if($badgeRows !== [] || $detailRows !== [])
|
@include('filament.pages.supporto.partials.photo-metadata', ['badgeRows' => $badgeRows, 'detailRows' => $detailRows])
|
||||||
@if($badgeRows !== [])
|
|
||||||
<div class="mt-2 flex flex-wrap gap-1">
|
|
||||||
@foreach($badgeRows as $badge)
|
|
||||||
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-semibold {{ $badge['class'] }}">{{ $badge['label'] }}</span>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@if($detailRows !== [])
|
|
||||||
<div class="mt-2 rounded-lg border border-slate-200 bg-white p-2 text-[11px] text-slate-700">
|
|
||||||
@foreach($detailRows as $detail)
|
|
||||||
<div><span class="font-medium">{{ $detail['label'] }}:</span> {{ $detail['value'] }}</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
<label class="mt-2 block">
|
<label class="mt-2 block">
|
||||||
<span class="mb-1 block text-[11px] font-medium">Nota sotto la foto</span>
|
<span class="mb-1 block text-[11px] font-medium">Nota sotto la foto</span>
|
||||||
<input type="text" wire:model.defer="waterPhotoDescriptions.{{ $upload['index'] }}" class="w-full rounded-lg border-gray-300" placeholder="Es. contatore cucina, cifra poco leggibile" />
|
<input type="text" wire:model.defer="waterPhotoDescriptions.{{ $upload['index'] }}" class="w-full rounded-lg border-gray-300" placeholder="Es. contatore cucina, cifra poco leggibile" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user