142 lines
5.5 KiB
PHP
142 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Contabilita\Services;
|
|
|
|
use App\Models\User;
|
|
use App\Models\Fornitore;
|
|
use App\Modules\Contabilita\Models\Movimento;
|
|
use App\Modules\Contabilita\Models\MovimentoBanca;
|
|
use App\Modules\Contabilita\Models\PianoConti;
|
|
use App\Modules\Contabilita\Models\Registrazione;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use RuntimeException;
|
|
|
|
class PagamentoFornitorePrimaNotaService
|
|
{
|
|
/**
|
|
* @param array{gestione_id?:int, conto_finanziario_id?:int, descrizione?:string, data_registrazione?:string} $override
|
|
*/
|
|
public function generaPagamentoDaMovimento(User $user, MovimentoBanca $movimento, int $fornitoreId, array $override = []): Registrazione
|
|
{
|
|
if (! Schema::hasTable('contabilita_registrazioni') || ! Schema::hasTable('contabilita_movimenti')) {
|
|
throw new RuntimeException('Tabelle prima nota mancanti.');
|
|
}
|
|
|
|
if ($movimento->registrazione_id) {
|
|
$existing = Registrazione::query()->find((int) $movimento->registrazione_id);
|
|
if ($existing) {
|
|
return $existing;
|
|
}
|
|
}
|
|
|
|
$stabileId = (int) ($movimento->stabile_id ?? 0);
|
|
if ($stabileId <= 0) {
|
|
throw new RuntimeException('Movimento banca senza stabile_id.');
|
|
}
|
|
|
|
$gestioneId = (int) (($override['gestione_id'] ?? null) ?: ($movimento->gestione_id ?? 0));
|
|
if ($gestioneId <= 0) {
|
|
throw new RuntimeException('Seleziona una gestione per questo movimento banca.');
|
|
}
|
|
|
|
if (Schema::hasTable('contabilita_chiusure_gestione')) {
|
|
$chiusa = app(ChiusuraGestioneService::class)->isGestioneChiusa($gestioneId);
|
|
if ($chiusa) {
|
|
throw new RuntimeException('Gestione chiusa: non è possibile generare nuove registrazioni.');
|
|
}
|
|
}
|
|
|
|
$importo = (float) ($movimento->importo ?? 0);
|
|
if (abs($importo) < 0.005) {
|
|
throw new RuntimeException('Importo movimento banca non valido.');
|
|
}
|
|
|
|
// Pagamento fornitore: tipicamente uscita (importo < 0). Accettiamo comunque il valore assoluto.
|
|
$amount = round(abs($importo), 2);
|
|
|
|
$contoFinanziarioId = (int) (($override['conto_finanziario_id'] ?? null) ?: 0);
|
|
if ($contoFinanziarioId <= 0) {
|
|
throw new RuntimeException('Seleziona un conto finanziario (banca/cassa) per registrare il pagamento.');
|
|
}
|
|
|
|
$contoFinanziario = PianoConti::query()->find($contoFinanziarioId);
|
|
if (! $contoFinanziario) {
|
|
throw new RuntimeException('Conto finanziario non valido.');
|
|
}
|
|
|
|
$fornitore = Fornitore::query()->find($fornitoreId);
|
|
$fornitoreLabel = $fornitore && is_string($fornitore->ragione_sociale ?? null)
|
|
? trim((string) $fornitore->ragione_sociale)
|
|
: null;
|
|
$fornitoreCode = $fornitore && is_string($fornitore->codice_univoco ?? null)
|
|
? trim((string) $fornitore->codice_univoco)
|
|
: null;
|
|
|
|
$contoDebitoFornitore = app(ContiSoggettiService::class)->resolveContoDebitoFornitore(
|
|
$stabileId,
|
|
$fornitoreId,
|
|
$fornitoreLabel,
|
|
$fornitoreCode
|
|
);
|
|
|
|
$data = isset($override['data_registrazione']) && is_string($override['data_registrazione'])
|
|
? trim((string) $override['data_registrazione'])
|
|
: null;
|
|
$data = $data !== '' ? $data : null;
|
|
$data = $data ?: ($movimento->data ? $movimento->data->toDateString() : now()->toDateString());
|
|
|
|
$descr = isset($override['descrizione']) && is_string($override['descrizione'])
|
|
? trim((string) $override['descrizione'])
|
|
: '';
|
|
if ($descr === '') {
|
|
$base = is_string($movimento->descrizione) ? trim((string) $movimento->descrizione) : '';
|
|
$descr = $base !== '' ? $base : 'Pagamento fornitore';
|
|
}
|
|
|
|
return DB::transaction(function () use ($user, $movimento, $stabileId, $gestioneId, $data, $descr, $amount, $contoFinanziarioId, $contoDebitoFornitore) {
|
|
$regPayload = [
|
|
'stabile_id' => $stabileId,
|
|
'gestione_id' => (Schema::hasColumn('contabilita_registrazioni', 'gestione_id')
|
|
? Registrazione::resolveGestioneIdOrDefault($gestioneId, $stabileId, $data)
|
|
: null),
|
|
'data_registrazione' => $data,
|
|
'descrizione' => $descr,
|
|
'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);
|
|
|
|
// Dare: diminuisce il debito verso fornitore
|
|
Movimento::query()->create([
|
|
'registrazione_id' => (int) $reg->id,
|
|
'conto_id' => (int) $contoDebitoFornitore->id,
|
|
'tipo' => 'dare',
|
|
'importo' => $amount,
|
|
]);
|
|
|
|
// Avere: diminuisce la banca/cassa
|
|
Movimento::query()->create([
|
|
'registrazione_id' => (int) $reg->id,
|
|
'conto_id' => $contoFinanziarioId,
|
|
'tipo' => 'avere',
|
|
'importo' => $amount,
|
|
]);
|
|
|
|
$reg->assertBilanciata();
|
|
|
|
$movimento->registrazione_id = (int) $reg->id;
|
|
$movimento->gestione_id = $gestioneId;
|
|
$movimento->save();
|
|
|
|
return $reg;
|
|
});
|
|
}
|
|
}
|