195 lines
8.1 KiB
PHP
195 lines
8.1 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Contabilita\Services;
|
|
|
|
use App\Models\GestioneContabile;
|
|
use App\Models\User;
|
|
use App\Modules\Contabilita\Models\Movimento;
|
|
use App\Modules\Contabilita\Models\Registrazione;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use RuntimeException;
|
|
|
|
class SituazioneInizialePrimaNotaService
|
|
{
|
|
/**
|
|
* Genera una registrazione di "bilancio di apertura" a partire dalle tabelle legacy importate.
|
|
*
|
|
* Logica volutamente minimale:
|
|
* - Debiti/Fondi: somma importo_euro da gescon_import.cre_deb_preced con c_d = 'D' (incluso=1)
|
|
* - Crediti: somma importo_euro da gescon_import.cre_deb_preced con c_d = 'C' (incluso=1)
|
|
* - Conguagli: somma cons_euro da gescon_import.dett_tab con cod_tab like 'CONG.%' (include negativi)
|
|
* - I conguagli vengono aggregati ai crediti verso condomini (se negativi riducono il credito complessivo)
|
|
* - Contropartita: conto speciale di apertura esercizio
|
|
*/
|
|
public function genera(
|
|
User $user,
|
|
int $stabileId,
|
|
GestioneContabile $gestione,
|
|
string $dataRegistrazione,
|
|
string $codStabileLegacy,
|
|
?string $legacyYear = null,
|
|
): Registrazione {
|
|
if (! Schema::hasColumn('contabilita_registrazioni', 'gestione_id')) {
|
|
throw new RuntimeException('Prima nota non supporta gestione_id. Eseguire le migrazioni.');
|
|
}
|
|
|
|
if (Schema::hasTable('contabilita_chiusure_gestione')) {
|
|
$chiusa = app(ChiusuraGestioneService::class)->isGestioneChiusa((int) $gestione->id);
|
|
if ($chiusa) {
|
|
throw new RuntimeException('Gestione chiusa: non è possibile generare nuove registrazioni.');
|
|
}
|
|
}
|
|
|
|
if (! Schema::connection('gescon_import')->hasTable('cre_deb_preced')) {
|
|
throw new RuntimeException('Tabella staging cre_deb_preced non presente. Importare prima dal MDB.');
|
|
}
|
|
|
|
if (! Schema::connection('gescon_import')->hasTable('dett_tab')) {
|
|
throw new RuntimeException('Tabella staging dett_tab non presente. Importare prima dal MDB.');
|
|
}
|
|
|
|
return DB::transaction(function () use ($user, $stabileId, $gestione, $dataRegistrazione, $codStabileLegacy, $legacyYear) {
|
|
$debiti = $this->sumCreDebPreced($codStabileLegacy, 'D', $legacyYear);
|
|
$crediti = $this->sumCreDebPreced($codStabileLegacy, 'C', $legacyYear);
|
|
$conguagli = $this->sumConguagli($codStabileLegacy, $legacyYear);
|
|
|
|
$creditiNetti = round($crediti + $conguagli, 2);
|
|
$debiti = round($debiti, 2);
|
|
|
|
$contoApertura = app(ChiusuraGestioneService::class)->resolveOrCreateConto(
|
|
(string) config('contabilita.conti_speciali.apertura_codice', ChiusuraGestioneService::CODICE_CONTO_APERTURA),
|
|
(string) config('contabilita.conti_speciali.apertura_descrizione', 'Conto apertura esercizio'),
|
|
(string) config('contabilita.conti_speciali.apertura_tipo', 'Patrimonio Netto'),
|
|
);
|
|
|
|
$contoCrediti = app(ChiusuraGestioneService::class)->resolveOrCreateConto(
|
|
(string) config('contabilita.conti_speciali.crediti_condomini_codice', '1100'),
|
|
(string) config('contabilita.conti_speciali.crediti_condomini_descrizione', 'Crediti verso condomini'),
|
|
(string) config('contabilita.conti_speciali.crediti_condomini_tipo', 'Attività'),
|
|
);
|
|
|
|
$contoDebiti = app(ChiusuraGestioneService::class)->resolveOrCreateConto(
|
|
(string) config('contabilita.conti_speciali.debiti_fornitori_codice', '2000'),
|
|
(string) config('contabilita.conti_speciali.debiti_fornitori_descrizione', 'Debiti verso fornitori'),
|
|
(string) config('contabilita.conti_speciali.debiti_fornitori_tipo', 'Passività'),
|
|
);
|
|
|
|
$regPayload = [
|
|
'stabile_id' => $stabileId,
|
|
'gestione_id' => Registrazione::resolveGestioneIdOrDefault((int) $gestione->id, $stabileId, $dataRegistrazione),
|
|
'data_registrazione' => $dataRegistrazione,
|
|
'descrizione' => 'Bilancio di apertura (situazione iniziale import)',
|
|
'created_by' => (int) $user->id,
|
|
'updated_by' => (int) $user->id,
|
|
];
|
|
|
|
if (Schema::hasColumn('contabilita_registrazioni', 'user_id')) {
|
|
$regPayload['user_id'] = (int) $user->id;
|
|
}
|
|
|
|
/** @var Registrazione $reg */
|
|
$reg = Registrazione::query()->create($regPayload);
|
|
|
|
$totDare = 0.0;
|
|
$totAvere = 0.0;
|
|
|
|
if (abs($creditiNetti) >= 0.005) {
|
|
if ($creditiNetti > 0) {
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoCrediti->id,
|
|
'tipo' => 'dare',
|
|
'importo' => $creditiNetti,
|
|
]);
|
|
$totDare += $creditiNetti;
|
|
} else {
|
|
$imp = abs($creditiNetti);
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoCrediti->id,
|
|
'tipo' => 'avere',
|
|
'importo' => $imp,
|
|
]);
|
|
$totAvere += $imp;
|
|
}
|
|
}
|
|
|
|
if (abs($debiti) >= 0.005) {
|
|
if ($debiti > 0) {
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoDebiti->id,
|
|
'tipo' => 'avere',
|
|
'importo' => $debiti,
|
|
]);
|
|
$totAvere += $debiti;
|
|
} else {
|
|
$imp = abs($debiti);
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoDebiti->id,
|
|
'tipo' => 'dare',
|
|
'importo' => $imp,
|
|
]);
|
|
$totDare += $imp;
|
|
}
|
|
}
|
|
|
|
$diff = round($totDare - $totAvere, 2);
|
|
if ($diff > 0) {
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoApertura->id,
|
|
'tipo' => 'avere',
|
|
'importo' => $diff,
|
|
]);
|
|
} elseif ($diff < 0) {
|
|
Movimento::query()->create([
|
|
'registrazione_id' => $reg->id,
|
|
'conto_id' => $contoApertura->id,
|
|
'tipo' => 'dare',
|
|
'importo' => abs($diff),
|
|
]);
|
|
}
|
|
|
|
$reg->assertBilanciata();
|
|
|
|
return $reg;
|
|
});
|
|
}
|
|
|
|
private function sumCreDebPreced(string $codStabileLegacy, string $cd, ?string $legacyYear): float
|
|
{
|
|
$q = DB::connection('gescon_import')->table('cre_deb_preced')
|
|
->where('cod_stabile', $codStabileLegacy)
|
|
->whereRaw('UPPER(c_d) = ?', [strtoupper($cd)]);
|
|
|
|
if (Schema::connection('gescon_import')->hasColumn('cre_deb_preced', 'incluso')) {
|
|
$q->where('incluso', 1);
|
|
}
|
|
|
|
if ($legacyYear !== null && $legacyYear !== '' && Schema::connection('gescon_import')->hasColumn('cre_deb_preced', 'legacy_year')) {
|
|
$q->where('legacy_year', $legacyYear);
|
|
}
|
|
|
|
return (float) ($q->sum('importo_euro') ?: 0);
|
|
}
|
|
|
|
private function sumConguagli(string $codStabileLegacy, ?string $legacyYear): float
|
|
{
|
|
$q = DB::connection('gescon_import')->table('dett_tab')
|
|
->where('cod_tab', 'like', 'CONG.%');
|
|
|
|
if (Schema::connection('gescon_import')->hasColumn('dett_tab', 'cod_stabile')) {
|
|
$q->where('cod_stabile', $codStabileLegacy);
|
|
}
|
|
|
|
if ($legacyYear !== null && $legacyYear !== '' && Schema::connection('gescon_import')->hasColumn('dett_tab', 'legacy_year')) {
|
|
$q->where('legacy_year', $legacyYear);
|
|
}
|
|
|
|
return (float) ($q->sum('cons_euro') ?: 0);
|
|
}
|
|
}
|