201 lines
7.5 KiB
PHP
Executable File
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');
|
|
}
|
|
}
|