2019-07-31 18:22:35 +02:00
< ? php
2024-12-02 11:17:31 +01:00
2020-09-07 15:04:06 +02:00
/*
* OpenSTAManager : il software gestionale open source per l ' assistenza tecnica e la fatturazione
2021-01-20 15:08:51 +01:00
* Copyright ( C ) DevCode s . r . l .
2020-09-07 15:04:06 +02:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2019-07-31 18:22:35 +02:00
namespace Modules\PrimaNota ;
2020-09-22 20:28:37 +02:00
use Common\SimpleModelTrait ;
use Illuminate\Database\Eloquent\Model ;
2019-07-31 18:22:35 +02:00
use Modules\Fatture\Fattura ;
2024-05-27 16:02:12 +02:00
use Modules\Fatture\Stato ;
2024-05-28 13:03:11 +02:00
use Modules\Scadenzario\Scadenza ;
2020-09-22 20:28:37 +02:00
/*
2020-08-07 11:05:08 +02:00
* Struttura ausiliaria dedicata alla raggruppamento e alla gestione di un insieme di Movimenti , unificati attraverso il numero di mastrino .
*
* Questa classe non è utilizzabile come normale modello Eloquent poichè non prevede operazioni di modifica a livello di database .
* La creazione di un record può essere utilizzata per la gestione di un insieme di Movimenti , mentre l ' eliminazione provoca la rimozione in cascata dei Movimenti associati al Mastrino .
*/
2020-09-22 20:28:37 +02:00
2019-08-01 10:08:34 +02:00
class Mastrino extends Model
2019-07-31 18:22:35 +02:00
{
2020-09-22 20:28:37 +02:00
use SimpleModelTrait ;
2019-07-31 18:22:35 +02:00
public $incrementing = false ;
protected $table = 'co_movimenti' ;
protected $primaryKey = 'idmastrino' ;
protected $hidden = [
'idmastrino' ,
'data_documento' ,
'iddocumento' ,
2020-11-02 17:00:36 +01:00
'id_anagrafica' ,
2019-07-31 18:22:35 +02:00
];
2024-03-19 18:18:11 +01:00
public static function build ( $descrizione = null , $data = null , $is_insoluto = false , $contabile = false , $id_anagrafica = null )
2019-07-31 18:22:35 +02:00
{
2020-09-22 20:28:37 +02:00
$model = new static ();
2019-07-31 18:22:35 +02:00
$model -> idmastrino = self :: getNextMastrino ();
$model -> data = $data ;
$model -> descrizione = $descrizione ;
$model -> is_insoluto = $is_insoluto ;
$model -> primanota = $contabile ;
2020-11-02 17:00:36 +01:00
$model -> id_anagrafica = $id_anagrafica ;
2020-11-06 10:46:42 +01:00
2019-07-31 18:22:35 +02:00
return $model ;
}
2020-08-05 17:58:54 +02:00
/**
* Rimuove tutti i movimenti collegati al mastrino .
*/
2019-07-31 18:22:35 +02:00
public function cleanup ()
{
$movimenti = $this -> movimenti ;
foreach ( $movimenti as $movimento ) {
$movimento -> delete ();
}
return $movimenti ;
}
public function save ( array $options = [])
{
2020-08-05 17:58:54 +02:00
return true ;
2019-07-31 18:22:35 +02:00
}
public function delete ()
{
2024-05-28 09:21:53 +02:00
// Per ogni movimento imposto il totale = 0
2019-07-31 18:22:35 +02:00
$movimenti = $this -> cleanup ();
2024-05-28 09:21:53 +02:00
foreach ( $movimenti as $movimento ) {
$movimento -> totale = 0 ;
$movimento -> save ();
}
2019-07-31 18:22:35 +02:00
$this -> aggiornaScadenzario ( $movimenti );
2020-08-05 17:58:54 +02:00
return parent :: delete ();
2019-07-31 18:22:35 +02:00
}
// Attributi
public function getIdAttribute ()
{
return $this -> idmastrino ;
}
public function getTotaleAttribute ()
{
$movimenti = $this -> movimenti -> where ( 'totale' , '>' , 0 );
$totale = $movimenti -> sum ( 'totale' );
return $totale ;
}
// Metodi generali
public function aggiornaScadenzario ( $movimenti = null )
{
2020-08-05 17:58:54 +02:00
// Aggiornamento dello scadenzario disponibile solo da Mastrino di PrimaNota
if ( empty ( $this -> primanota )) {
return ;
}
2019-07-31 18:22:35 +02:00
$movimenti = $movimenti ? : $this -> movimenti ;
2020-08-05 17:58:54 +02:00
// Aggiornamento delle scadenze per i singoli documenti
2024-05-27 16:02:12 +02:00
$documenti = $this -> getUniqueDocumenti ( $movimenti );
$scadenze = $this -> getScadenzePerDocumenti ( $movimenti , $documenti );
2024-05-29 09:25:33 +02:00
2019-07-31 18:22:35 +02:00
foreach ( $movimenti as $movimento ) {
2024-05-27 16:02:12 +02:00
$this -> correggiScadenza ( $movimento , $scadenze [ $movimento -> iddocumento ], $movimento -> iddocumento );
2019-07-31 18:22:35 +02:00
}
// Fix dello stato della Fattura
$database = database ();
2024-05-31 12:31:21 +02:00
if ( $documenti ) {
2024-06-25 09:40:41 +02:00
foreach ( $documenti as $id_documento ) {
if ( empty ( $id_documento )) {
continue ;
} else {
}
2024-05-31 12:31:21 +02:00
// Verifico se la fattura è stata pagata tutta, così imposto lo stato a "Pagato"
$totali = $database -> fetchOne ( 'SELECT SUM(pagato) AS tot_pagato, SUM(da_pagare) AS tot_da_pagare FROM co_scadenziario WHERE iddocumento=' . prepare ( $id_documento ));
$totale_pagato = abs ( floatval ( $totali [ 'tot_pagato' ]));
$totale_da_pagare = abs ( floatval ( $totali [ 'tot_da_pagare' ]));
// Aggiorno lo stato della fattura
if ( $totale_pagato == $totale_da_pagare ) {
$stato = 'Pagato' ;
} elseif ( $totale_pagato != $totale_da_pagare && $totale_pagato != 0 ) {
$stato = 'Parzialmente pagato' ;
} else {
$stato = 'Emessa' ;
}
$documento = Fattura :: find ( $id_documento );
2024-06-11 16:58:27 +02:00
$stato = Stato :: where ( 'name' , $stato ) -> first () -> id ;
2024-05-31 12:31:21 +02:00
$documento -> stato () -> associate ( $stato );
$documento -> save ();
2019-07-31 18:22:35 +02:00
}
}
}
2020-08-05 17:58:54 +02:00
// Relazioni Eloquent
public function fattura ()
{
return $this -> belongsTo ( Fattura :: class , 'iddocumento' );
}
public function movimenti ()
{
return $this -> hasMany ( Movimento :: class , 'idmastrino' );
}
// Metodi statici
public static function getNextMastrino ()
{
$ultimo = database () -> fetchOne ( 'SELECT MAX(idmastrino) AS max FROM co_movimenti' );
return intval ( $ultimo [ 'max' ]) + 1 ;
}
2021-02-26 16:38:08 +01:00
/**
* Funzione dedicata alla distribuzione del totale pagato del movimento nelle relative scadenze associate .
*/
2024-05-28 09:21:53 +02:00
protected function correggiScadenza ( Movimento $movimento , $scadenze = null , $id_documento = null )
2019-07-31 18:22:35 +02:00
{
2021-02-26 10:32:50 +01:00
$is_nota = false ;
2024-05-28 09:21:53 +02:00
$documento = Fattura :: find ( $id_documento );
2024-05-28 13:03:11 +02:00
$totale_da_distribuire = 0 ;
if ( ! empty ( $scadenze )) {
2024-05-27 16:02:12 +02:00
if ( empty ( $documento )) {
$dir = $movimento -> totale < 0 ? 'uscita' : 'entrata' ;
} else {
2024-05-28 09:21:53 +02:00
$dir = $documento -> direzione ;
2024-05-27 16:02:12 +02:00
}
2023-11-24 13:20:00 +01:00
2024-05-27 16:02:12 +02:00
foreach ( $scadenze as $scadenza ) {
2024-09-27 09:37:59 +02:00
$totale_da_distribuire = ( $movimento [ 'totale' ] != 0 ? Movimento :: where ( 'id_scadenza' , '=' , $scadenza )
2024-05-28 13:03:11 +02:00
-> where ( 'totale' , '>' , 0 )
-> sum ( 'totale' ) : 0 );
2024-05-27 16:02:12 +02:00
}
2021-02-26 16:38:08 +01:00
2024-05-28 13:03:11 +02:00
$totale_da_distribuire = abs ( $totale_da_distribuire );
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// Ciclo tra le rate dei pagamenti per inserire su `pagato` l'importo effettivamente pagato
// Nel caso il pagamento superi la rata, devo distribuirlo sulle rate successive
foreach ( $scadenze as $scadenza ) {
$scadenza = Scadenza :: find ( $scadenza );
2023-11-24 13:20:00 +01:00
2024-05-28 13:03:11 +02:00
if ( empty ( $scadenza )) {
continue ;
}
$scadenza_da_pagare = abs ( $scadenza -> da_pagare );
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// Nel caso in cui il totale da distribuire sia stato esaurito, imposta il pagato a zero
if ( $totale_da_distribuire <= 0 ) {
$pagato = 0 ;
}
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// Se il totale da distribuire è superiore al valore da pagare della scadenza, completa il pagamento
elseif ( $totale_da_distribuire >= $scadenza_da_pagare ) {
$pagato = $scadenza_da_pagare ;
$totale_da_distribuire -= $scadenza_da_pagare ;
}
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// In caso alternativo, assegno il rimanente da distribuire interamente alla scadenza
else {
$pagato = $totale_da_distribuire ;
$totale_da_distribuire = 0 ;
}
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// Inversione di segno per la direzione del movimento contabile
$pagato = ( $dir == 'uscita' ? - $pagato : $pagato );
$pagato = $is_nota ? - $pagato : $pagato ; // Inversione di segno per le note
2019-07-31 18:22:35 +02:00
2024-05-28 13:03:11 +02:00
// Salvataggio delle informazioni
$scadenza -> pagato = $pagato ;
$scadenza -> data_pagamento = $pagato ? $this -> data : null ;
$scadenza -> save ();
}
2019-07-31 18:22:35 +02:00
}
}
2024-05-29 09:25:33 +02:00
private function getUniqueDocumenti ( $movimenti )
{
$documentIds = [];
foreach ( $movimenti as $movimento ) {
if ( ! in_array ( $movimento -> iddocumento , $documentIds )) {
$documentIds [] = $movimento -> iddocumento ;
}
}
return $documentIds ;
}
private function getScadenzePerDocumenti ( $movimenti , $documenti )
{
$scadenze = [];
foreach ( $movimenti as $movimento ) {
if ( in_array ( $movimento -> iddocumento , $documenti )) {
if ( ! in_array ( $movimento -> id_scadenza , $scadenze [ $movimento -> iddocumento ] ? ? [])) {
$scadenze [ $movimento -> iddocumento ][] = $movimento -> id_scadenza ;
}
}
}
return $scadenze ;
}
2019-07-31 18:22:35 +02:00
}