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; }); } }