netgescon-day0/app/Modules/Contabilita/Models/Movimento.php

201 lines
7.5 KiB
PHP
Executable File

<?php
namespace App\Modules\Contabilita\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class Movimento extends Model
{
protected $table = 'contabilita_movimenti';
public $timestamps = false; // No created_at/updated_at for this table
protected $fillable = [
'registrazione_id',
'conto_id',
'voce_spesa_id',
'importo',
'tipo',
'entry_id',
'chart_account_id',
'master_code',
'account_code',
'subaccount_code',
'debit_amount',
'credit_amount',
'movement_description',
'metadata',
'sequence',
];
protected static function booted(): void
{
static::creating(function (Movimento $movimento): void {
if (Schema::hasColumn('contabilita_movimenti', 'entry_id') && empty($movimento->entry_id)) {
$movimento->entry_id = $movimento->registrazione_id;
}
if (Schema::hasColumn('contabilita_movimenti', 'chart_account_id') && empty($movimento->chart_account_id)) {
$chartId = self::resolveLegacyChartAccountId($movimento);
if ($chartId > 0) {
$movimento->chart_account_id = $chartId;
}
}
$code = null;
if (
Schema::hasColumn('contabilita_movimenti', 'master_code')
|| Schema::hasColumn('contabilita_movimenti', 'account_code')
|| Schema::hasColumn('contabilita_movimenti', 'subaccount_code')
) {
$conto = PianoConti::query()->find($movimento->conto_id);
$code = trim((string) ($conto?->codice ?? ''));
if ($code === '') {
$code = (string) $movimento->conto_id;
}
$normalized = preg_replace('/[^A-Za-z0-9]/', '', strtoupper($code)) ?: (string) $movimento->conto_id;
$masterCode = str_pad(substr($normalized, 0, 3), 3, '0', STR_PAD_LEFT);
$accountCode = str_pad(substr($normalized, 0, 8), 8, '0', STR_PAD_LEFT);
$subAccountCode = str_pad(substr($normalized, -5), 5, '0', STR_PAD_LEFT);
if (Schema::hasColumn('contabilita_movimenti', 'master_code') && empty($movimento->master_code)) {
$movimento->master_code = $masterCode;
}
if (Schema::hasColumn('contabilita_movimenti', 'account_code') && empty($movimento->account_code)) {
$movimento->account_code = $accountCode;
}
if (Schema::hasColumn('contabilita_movimenti', 'subaccount_code') && empty($movimento->subaccount_code)) {
$movimento->subaccount_code = $subAccountCode;
}
}
if (Schema::hasColumn('contabilita_movimenti', 'debit_amount') && empty($movimento->debit_amount)) {
$movimento->debit_amount = $movimento->tipo === 'dare' ? (float) $movimento->importo : 0.0;
}
if (Schema::hasColumn('contabilita_movimenti', 'credit_amount') && empty($movimento->credit_amount)) {
$movimento->credit_amount = $movimento->tipo === 'avere' ? (float) $movimento->importo : 0.0;
}
if (Schema::hasColumn('contabilita_movimenti', 'sequence') && empty($movimento->sequence)) {
$movimento->sequence = 1;
}
});
}
private static function resolveLegacyChartAccountId(Movimento $movimento): int
{
if (! Schema::hasTable('piano_conti')) {
return 0;
}
$conto = PianoConti::query()->find($movimento->conto_id);
if (! $conto) {
return 0;
}
$code = trim((string) ($conto->codice ?? ''));
if ($code === '') {
$code = (string) $movimento->conto_id;
}
$normalized = preg_replace('/[^A-Za-z0-9]/', '', strtoupper($code)) ?: (string) $movimento->conto_id;
$masterCode = str_pad(substr($normalized, 0, 3), 3, '0', STR_PAD_LEFT);
$accountCode = str_pad(substr($normalized, 0, 8), 8, '0', STR_PAD_LEFT);
$subAccountCode = str_pad(substr($normalized, -5), 5, '0', STR_PAD_LEFT);
$mastro = str_pad(substr($masterCode, 0, 4), 4, '0', STR_PAD_LEFT);
$contoCode = str_pad(substr($accountCode, 0, 8), 8, '0', STR_PAD_LEFT);
$sotto = str_pad(substr($subAccountCode, -5), 5, '0', STR_PAD_LEFT);
$quarto = '00000';
$query = DB::table('piano_conti')
->where('mastro', $mastro)
->where('conto', $contoCode)
->where('sottoconto', $sotto)
->where('quarto_livello', $quarto);
if (Schema::hasColumn('piano_conti', 'stabile_id')) {
$stabileId = null;
if (! empty($movimento->registrazione_id)) {
$reg = Registrazione::query()->find($movimento->registrazione_id);
$stabileId = $reg?->stabile_id;
}
if ($stabileId) {
$query->where(function ($q) use ($stabileId) {
$q->whereNull('stabile_id')->orWhere('stabile_id', $stabileId);
});
}
}
$existingId = $query->value('id');
if (is_numeric($existingId)) {
return (int) $existingId;
}
$descr = trim((string) ($conto->descrizione ?? $conto->description ?? ''));
if ($descr === '') {
$descr = 'Conto ' . $mastro . '.' . $contoCode . '.' . $sotto;
}
$tipo = strtoupper(trim((string) ($conto->tipo ?? '')));
$tipoEnum = match ($tipo) {
'ATTIVITÀ', 'ATTIVITA', 'ATTIVO' => 'ATTIVO',
'PASSIVITÀ', 'PASSIVITA', 'PASSIVO' => 'PASSIVO',
'RICAVO' => 'RICAVO',
'PATRIMONIO NETTO', 'PATRIMONIO' => 'PATRIMONIO',
default => 'COSTO',
};
$tipologia = match ($tipoEnum) {
'RICAVO' => 'RIC',
'ATTIVO' => 'ATT',
'PASSIVO' => 'PAS',
'PATRIMONIO' => 'PAT',
default => 'SPE',
};
$insert = [
'mastro' => $mastro,
'conto' => $contoCode,
'sottoconto' => $sotto,
'quarto_livello' => $quarto,
'denominazione' => $descr,
'tipo' => $tipoEnum,
'tipologia' => $tipologia,
'attivo' => 1,
'created_at' => now(),
'updated_at' => now(),
];
if (Schema::hasColumn('piano_conti', 'stabile_id')) {
$stabileId = null;
if (! empty($movimento->registrazione_id)) {
$reg = Registrazione::query()->find($movimento->registrazione_id);
$stabileId = $reg?->stabile_id;
}
$insert['stabile_id'] = $stabileId ?: null;
}
try {
$id = DB::table('piano_conti')->insertGetId($insert);
return is_numeric($id) ? (int) $id : 0;
} catch (\Throwable) {
return 0;
}
}
public function registrazione()
{
return $this->belongsTo(Registrazione::class, 'registrazione_id');
}
public function conto()
{
return $this->belongsTo(PianoConti::class, 'conto_id');
}
public function voceSpesa()
{
return $this->belongsTo(\App\Models\VoceSpesa::class, 'voce_spesa_id');
}
}