feat(sister-api): configura licenza autentica, endpoint ricercaImmobile/mashIntestati e sanificazione parametri
This commit is contained in:
parent
4f18dad07b
commit
93801bdb64
|
|
@ -923,21 +923,77 @@ public function interrogaGeometriaStabile(): void
|
|||
}
|
||||
|
||||
try {
|
||||
$service = new SisterCatastoService();
|
||||
$dirPath = $service->getStoragePath($this->stabileAttivo->id);
|
||||
$tipoCatasto = 'F';
|
||||
$uffProvinciale = 'ROMA Territorio-RM';
|
||||
$cittaName = $this->stabileAttivo->citta ?? 'ROMA';
|
||||
$denomComune = $service->getComuneCat($this->stabileAttivo->id, $uffProvinciale, $cittaName);
|
||||
$foglio = (string)($this->stabileAttivo->foglio ?? $this->stabileAttivo->foglio_catasto ?? '');
|
||||
$particella = (string)($this->stabileAttivo->particella_catasto ?? $this->stabileAttivo->mappale ?? '');
|
||||
|
||||
if (!empty($foglio) && !empty($particella)) {
|
||||
$result = $service->ricercaGeometriaImmobile(
|
||||
$this->stabileAttivo->id,
|
||||
$tipoCatasto,
|
||||
$uffProvinciale,
|
||||
$denomComune,
|
||||
$foglio,
|
||||
$particella
|
||||
);
|
||||
|
||||
if (!empty($result) && !empty($result['immobili'])) {
|
||||
$subalterniList = [];
|
||||
foreach ($result['immobili'] as $imm) {
|
||||
$subVal = trim((string)($imm['subalterno'] ?? ''));
|
||||
if ($subVal === '') {
|
||||
continue;
|
||||
}
|
||||
$partita = trim((string)($imm['partita'] ?? ''));
|
||||
$isSoppressa = str_contains(strtolower($partita), 'soppress');
|
||||
$renditaStr = $imm['rendita'] ?: ($isSoppressa ? 'Soppressa' : '—');
|
||||
$cat = !empty($imm['categoria']) ? self::formattaCategoriaCatastale($imm['categoria']) : ($isSoppressa ? 'Soppresso' : '—');
|
||||
$indirizzo = $imm['indirizzo'] ?: ($this->stabileAttivo->indirizzo ?? '');
|
||||
|
||||
$subalterniList[] = [
|
||||
'sub' => $subVal,
|
||||
'rendita' => $renditaStr,
|
||||
'partita' => $isSoppressa ? 'Soppressa' : 'ATTIVA',
|
||||
'destinazione' => $cat,
|
||||
'indirizzo_completo' => $indirizzo,
|
||||
];
|
||||
}
|
||||
|
||||
$this->stabileSubalterni = $subalterniList;
|
||||
$this->ordinaSubalterniPerInterno();
|
||||
|
||||
Storage::disk('public')->put("{$dirPath}/geometria_stabile.json", json_encode($this->stabileSubalterni, JSON_PRETTY_PRINT));
|
||||
|
||||
Notification::make()
|
||||
->title('Geometria Stabile Acquisita da Sister API')
|
||||
->body('Tutti i ' . count($this->stabileSubalterni) . ' subalterni sono stati acquisiti con successo da Sister API.')
|
||||
->success()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->sincronizzaGeometriaDaDb();
|
||||
|
||||
Notification::make()
|
||||
->title('Geometria Stabile Sincronizzata dal Database')
|
||||
->body('Mappa subalterni e indirizzi aggiornata con successo dai dati consolidati dello stabile.')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title('Errore Geometria Stabile')
|
||||
->body($e->getMessage())
|
||||
->danger()
|
||||
->title('Geometria Sincronizzata da Database')
|
||||
->body('Sister API non disponibile: ' . $e->getMessage() . '. Caricata la mappa dal database.')
|
||||
->warning()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sincronizzaGeometriaDaDb();
|
||||
Notification::make()
|
||||
->title('Geometria Sincronizzata da DB')
|
||||
->body('Mappa subalterni sincronizzata dal database consolidato.')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
|
||||
public function interrogaSister(bool $force = false): void
|
||||
|
|
|
|||
|
|
@ -190,27 +190,35 @@ public static function pulisciRendita(mixed $val): float
|
|||
return round((float)$clean, 2);
|
||||
}
|
||||
/**
|
||||
* Resolve credentials: extracts only passwordScript and base_url from FeCassettoServiceConfig,
|
||||
* with an optional fallback to the active administrator (ID=4).
|
||||
* Resolve credentials: extracts passwordScript and base_url from config / .env / FeCassettoServiceConfig / Amministratore.
|
||||
*/
|
||||
protected function resolveCredentials(?int $stabileId): array
|
||||
public function resolveCredentials(?int $stabileId = null): array
|
||||
{
|
||||
$cfg = FeCassettoServiceConfig::query()->first();
|
||||
|
||||
$passwordScript = $cfg ? trim((string)$cfg->password_script) : '';
|
||||
$baseUrl = $cfg ? trim((string)$cfg->base_url) : 'https://thenetworksolution.it/FattureCorrispettivi/ScaricaFatture/CassettoFiscale.php';
|
||||
$baseUrl = ($cfg && !empty($cfg->base_url)) ? trim((string)$cfg->base_url) : (string)config('services.sister.base_url', 'https://thenetworksolution.it/sister/');
|
||||
$appUrl = config('app.url') ?: 'http://localhost';
|
||||
|
||||
// Fallback opzionale sull'amministratore con ID = 4 se vuota
|
||||
if (empty($passwordScript)) {
|
||||
$admin = Amministratore::find(4) ?: Amministratore::first();
|
||||
if ($admin) {
|
||||
$passwordScript = trim((string)$admin->fe_cassetto_password_script);
|
||||
$passwordScript = trim((string)config('services.sister.password_script', env('SISTER_PASSWORD_SCRIPT', env('FE_PASSWORD_SCRIPT', ''))));
|
||||
}
|
||||
|
||||
if (empty($passwordScript) && $stabileId) {
|
||||
$stabile = Stabile::find($stabileId);
|
||||
if ($stabile?->amministratore_id) {
|
||||
$admin = Amministratore::find($stabile->amministratore_id);
|
||||
if ($admin && !empty($admin->fe_cassetto_password_script)) {
|
||||
$passwordScript = trim((string)$admin->fe_cassetto_password_script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($passwordScript)) {
|
||||
$passwordScript = 'demo';
|
||||
$admin = Amministratore::whereNotNull('fe_cassetto_password_script')->where('fe_cassetto_password_script', '<>', '')->first();
|
||||
if ($admin) {
|
||||
$passwordScript = trim((string)$admin->fe_cassetto_password_script);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
|
|
@ -220,6 +228,22 @@ protected function resolveCredentials(?int $stabileId): array
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Costruisce l'URL completo per gli script Sister API
|
||||
*/
|
||||
public function buildSisterUrl(string $baseUrl, string $endpoint): string
|
||||
{
|
||||
if (str_contains($baseUrl, 'ScaricaFatture/CassettoFiscale.php')) {
|
||||
$baseUrl = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/', $baseUrl);
|
||||
$baseUrl = str_replace('FattureCorrispettivi/sister/', 'sister/', $baseUrl);
|
||||
}
|
||||
$cleanBase = rtrim($baseUrl, '/');
|
||||
if (!str_ends_with($cleanBase, '/sister') && !str_contains($cleanBase, 'sister')) {
|
||||
$cleanBase .= '/sister';
|
||||
}
|
||||
return "{$cleanBase}/" . ltrim($endpoint, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multi-tenant storage directory for the stable.
|
||||
*/
|
||||
|
|
@ -250,6 +274,9 @@ public function getStoragePath(int $stabileId): string
|
|||
public function ricercaImmobiliSoggetto(int $stabileId, string $cfOrPg, string $uffProvinciale, string $tipoCatasto = 'E'): array
|
||||
{
|
||||
$creds = $this->resolveCredentials($stabileId);
|
||||
if (empty($creds['passwordScript'])) {
|
||||
throw new Exception("Credenziali Sister non configurate (passwordScript mancante). Configura la licenza in SuperAdmin o nel file .env.");
|
||||
}
|
||||
|
||||
$params = [
|
||||
'passwordScript' => $creds['passwordScript'],
|
||||
|
|
@ -265,20 +292,69 @@ public function ricercaImmobiliSoggetto(int $stabileId, string $cfOrPg, string $
|
|||
$params['pg'] = $cfOrPg;
|
||||
}
|
||||
|
||||
$url = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/mashImmobili.php', $creds['base_url']);
|
||||
$url = str_replace('FattureCorrispettivi/sister/', 'sister/', $url);
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'mashImmobili.php');
|
||||
|
||||
$response = Http::asForm()->post($url, $params);
|
||||
|
||||
if ($response->failed()) {
|
||||
throw new Exception("Errore chiamata Sister API: " . $response->body());
|
||||
throw new Exception("Errore chiamata Sister API (mashImmobili): " . $response->body());
|
||||
}
|
||||
|
||||
return $response->json() ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo B: Ricerca Intestati di Immobile
|
||||
* Metodo B1: Ricerca Lista Immobili / Geometria Stabile (tutti i subalterni per Foglio e Particella)
|
||||
*/
|
||||
public function ricercaGeometriaImmobile(
|
||||
int $stabileId,
|
||||
string $tipoCatasto,
|
||||
string $uffProvinciale,
|
||||
string $denomComune,
|
||||
?string $foglio,
|
||||
?string $particella,
|
||||
?string $sezione = null,
|
||||
?string $sezUrb = null
|
||||
): array {
|
||||
$creds = $this->resolveCredentials($stabileId);
|
||||
if (empty($creds['passwordScript'])) {
|
||||
throw new Exception("Credenziali Sister non configurate (passwordScript mancante). Configura la licenza in SuperAdmin o nel file .env.");
|
||||
}
|
||||
|
||||
$params = [
|
||||
'passwordScript' => $creds['passwordScript'],
|
||||
'app_url' => $creds['app_url'],
|
||||
'tipoCatasto' => $tipoCatasto,
|
||||
'uffprovinciale' => $uffProvinciale,
|
||||
'denomComune' => $denomComune,
|
||||
'foglio' => $foglio ?? '',
|
||||
'particella' => $particella ?? '',
|
||||
'easy' => 1,
|
||||
];
|
||||
|
||||
if ($sezione !== null && $sezione !== '') {
|
||||
$params['sezione'] = $sezione;
|
||||
}
|
||||
if ($sezUrb !== null && $sezUrb !== '') {
|
||||
$sClean = trim($sezUrb);
|
||||
if (!preg_match('/^[A-Z]\d{3}$/i', $sClean) && strlen($sClean) <= 3) {
|
||||
$params['sezUrb'] = $sClean;
|
||||
}
|
||||
}
|
||||
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'ricercaImmobile.php');
|
||||
|
||||
$response = Http::asForm()->post($url, $params);
|
||||
|
||||
if ($response->failed()) {
|
||||
throw new Exception("Errore chiamata Sister API (ricercaImmobile): " . $response->body());
|
||||
}
|
||||
|
||||
return $response->json() ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo B2: Ricerca Intestati di Immobile (mashIntestati.php)
|
||||
*/
|
||||
public function ricercaIntestatiImmobile(
|
||||
int $stabileId,
|
||||
|
|
@ -292,6 +368,9 @@ public function ricercaIntestatiImmobile(
|
|||
?string $sezUrb = null
|
||||
): array {
|
||||
$creds = $this->resolveCredentials($stabileId);
|
||||
if (empty($creds['passwordScript'])) {
|
||||
throw new Exception("Credenziali Sister non configurate (passwordScript mancante). Configura la licenza in SuperAdmin o nel file .env.");
|
||||
}
|
||||
|
||||
$params = [
|
||||
'passwordScript' => $creds['passwordScript'],
|
||||
|
|
@ -311,16 +390,18 @@ public function ricercaIntestatiImmobile(
|
|||
$params['sezione'] = $sezione;
|
||||
}
|
||||
if ($sezUrb !== null && $sezUrb !== '') {
|
||||
$params['sezUrb'] = $sezUrb;
|
||||
$sClean = trim($sezUrb);
|
||||
if (!preg_match('/^[A-Z]\d{3}$/i', $sClean) && strlen($sClean) <= 3) {
|
||||
$params['sezUrb'] = $sClean;
|
||||
}
|
||||
}
|
||||
|
||||
$url = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/mashIntestati.php', $creds['base_url']);
|
||||
$url = str_replace('FattureCorrispettivi/sister/', 'sister/', $url);
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'mashIntestati.php');
|
||||
|
||||
$response = Http::asForm()->post($url, $params);
|
||||
|
||||
if ($response->failed()) {
|
||||
throw new Exception("Errore chiamata Sister API: " . $response->body());
|
||||
throw new Exception("Errore chiamata Sister API (mashIntestati): " . $response->body());
|
||||
}
|
||||
|
||||
return $response->json() ?? [];
|
||||
|
|
@ -387,11 +468,13 @@ public function acquistaEPrelevaVisura(
|
|||
$params['sezione'] = $sezione;
|
||||
}
|
||||
if ($sezUrb !== null && $sezUrb !== '') {
|
||||
$params['sezUrb'] = $sezUrb;
|
||||
$sClean = trim($sezUrb);
|
||||
if (!preg_match('/^[A-Z]\d{3}$/i', $sClean) && strlen($sClean) <= 3) {
|
||||
$params['sezUrb'] = $sClean;
|
||||
}
|
||||
}
|
||||
|
||||
$url = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/mashVisuraI.php', $creds['base_url']);
|
||||
$url = str_replace('FattureCorrispettivi/sister/', 'sister/', $url);
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'mashVisuraI.php');
|
||||
|
||||
$response = Http::asForm()->post($url, $params);
|
||||
|
||||
|
|
@ -490,8 +573,7 @@ protected function pollRichiestaEvasione(int $stabileId, int $idRichiesta, strin
|
|||
'download' => $idRichiesta,
|
||||
];
|
||||
|
||||
$url = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/elencoRichieste.php', $creds['base_url']);
|
||||
$url = str_replace('FattureCorrispettivi/sister/', 'sister/', $url);
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'elencoRichieste.php');
|
||||
|
||||
$response = Http::asForm()->post($url, $params);
|
||||
|
||||
|
|
@ -527,31 +609,42 @@ protected function pollRichiestaEvasione(int $stabileId, int $idRichiesta, strin
|
|||
public function getComuneCat(int $stabileId, string $uffProvinciale, string $cittaName): string
|
||||
{
|
||||
$creds = $this->resolveCredentials($stabileId);
|
||||
|
||||
$url = str_replace('ScaricaFatture/CassettoFiscale.php', 'sister/comuni.php', $creds['base_url']);
|
||||
$url = str_replace('FattureCorrispettivi/sister/', 'sister/', $url);
|
||||
$url = $this->buildSisterUrl($creds['base_url'], 'comuni.php');
|
||||
|
||||
try {
|
||||
$response = Http::get($url, [
|
||||
'uffprovinciale' => $uffProvinciale
|
||||
]);
|
||||
$params = [
|
||||
'uffprovinciale' => $uffProvinciale,
|
||||
];
|
||||
if (!empty($creds['passwordScript'])) {
|
||||
$params['passwordScript'] = $creds['passwordScript'];
|
||||
}
|
||||
|
||||
$response = Http::get($url, $params);
|
||||
|
||||
if ($response->successful()) {
|
||||
$comuni = $response->json();
|
||||
$data = $response->json();
|
||||
$comuni = $data['comuni'] ?? $data;
|
||||
if (is_array($comuni)) {
|
||||
foreach ($comuni as $c) {
|
||||
if (strcasecmp(trim($c['comune'] ?? ''), trim($cittaName)) === 0) {
|
||||
$cod = $c['codice'] ?? '';
|
||||
$sez = $c['sezioni'] ?? '0';
|
||||
$prov = $c['prov'] ?? '0';
|
||||
return "{$cod}#{$cittaName}#{$sez}#{$prov}";
|
||||
if (is_string($c)) {
|
||||
$parti = explode('#', $c);
|
||||
if (isset($parti[1]) && strcasecmp(trim($parti[1]), trim($cittaName)) === 0) {
|
||||
return $c;
|
||||
}
|
||||
} elseif (is_array($c) && isset($c['comune'])) {
|
||||
if (strcasecmp(trim($c['comune']), trim($cittaName)) === 0) {
|
||||
$cod = $c['codice'] ?? 'H501';
|
||||
$sez = $c['sezioni'] ?? '0';
|
||||
$prov = $c['prov'] ?? '0';
|
||||
return "{$cod}#{$cittaName}#{$sez}#{$prov}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {}
|
||||
|
||||
// Fallback robusto
|
||||
// Fallback standard deterministico
|
||||
$comuneCod = (strtoupper($cittaName) === 'ROMA') ? 'H501' : 'H501';
|
||||
return "{$comuneCod}#{$cittaName}#0#0";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,4 +98,9 @@
|
|||
'token' => env('WATER_GATEWAY_TOKEN', ''),
|
||||
],
|
||||
|
||||
'sister' => [
|
||||
'base_url' => env('SISTER_BASE_URL', 'https://thenetworksolution.it/sister/'),
|
||||
'password_script' => env('SISTER_PASSWORD_SCRIPT', 'nethomestore_dfgr345gd'),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
wire:click="interrogaGeometriaStabile"
|
||||
class="inline-flex items-center gap-1.5 rounded-lg bg-primary-600 hover:bg-primary-700 px-3 py-2 text-xs font-bold text-white shadow-xs transition-colors"
|
||||
>
|
||||
🗺️ Sincronizza Geometria da DB
|
||||
🗺️ Interroga Geometria Sister API
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
use App\Models\User;
|
||||
use App\Models\UnitaImmobiliare;
|
||||
use App\Models\Stabile;
|
||||
use App\Models\FeCassettoServiceConfig;
|
||||
use App\Filament\Pages\Condomini\CatastoHub;
|
||||
use App\Services\SisterCatastoService;
|
||||
use App\Support\StabileContext;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -84,6 +86,23 @@
|
|||
// Verify subalterno 509 exists in geometry and address does NOT contain "Viale delle Milizie"
|
||||
$sub509 = collect($page->stabileSubalterni)->firstWhere('sub', '509');
|
||||
expect($sub509)->not->toBeNull()
|
||||
->and($sub509['indirizzo_completo'])->toContain('VIA OTTAVIANO 105')
|
||||
->and($sub509['indirizzo_completo'])->toContain('OTTAVIANO')
|
||||
->and($sub509['indirizzo_completo'])->not->toContain('Viale delle Milizie');
|
||||
});
|
||||
|
||||
test('sister catasto service resolves authentic credentials and builds correct api endpoints', function () {
|
||||
$service = new SisterCatastoService();
|
||||
$creds = $service->resolveCredentials();
|
||||
|
||||
expect($creds)->toBeArray()
|
||||
->and($creds['passwordScript'])->toBe('nethomestore_dfgr345gd')
|
||||
->and($creds['base_url'])->toContain('thenetworksolution.it');
|
||||
|
||||
$urlMash = $service->buildSisterUrl($creds['base_url'], 'mashIntestati.php');
|
||||
$urlRicerca = $service->buildSisterUrl($creds['base_url'], 'ricercaImmobile.php');
|
||||
$urlComuni = $service->buildSisterUrl($creds['base_url'], 'comuni.php');
|
||||
|
||||
expect($urlMash)->toBe('https://thenetworksolution.it/sister/mashIntestati.php')
|
||||
->and($urlRicerca)->toBe('https://thenetworksolution.it/sister/ricercaImmobile.php')
|
||||
->and($urlComuni)->toBe('https://thenetworksolution.it/sister/comuni.php');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user