2018-08-08 19:32:20 +02:00
< ? php
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 />.
*/
2018-08-08 19:32:20 +02:00
namespace Modules\Fatture ;
2019-06-29 11:01:26 +02:00
use Auth ;
2019-09-13 11:29:45 +02:00
use Carbon\Carbon ;
2020-09-22 20:28:37 +02:00
use Common\Components\Component ;
2018-12-14 09:46:35 +01:00
use Common\Document ;
2020-02-24 12:21:47 +01:00
use Illuminate\Database\Eloquent\Builder ;
2020-09-08 10:38:27 +02:00
use Models\Upload ;
2018-08-29 18:06:51 +02:00
use Modules\Anagrafiche\Anagrafica ;
2020-09-09 16:55:45 +02:00
use Modules\Banche\Banca ;
2020-08-05 17:58:54 +02:00
use Modules\Fatture\Gestori\Bollo as GestoreBollo ;
use Modules\Fatture\Gestori\Movimenti as GestoreMovimenti ;
use Modules\Fatture\Gestori\Scadenze as GestoreScadenze ;
2019-03-08 16:59:55 +01:00
use Modules\Pagamenti\Pagamento ;
2019-07-31 18:22:35 +02:00
use Modules\PrimaNota\Movimento ;
2019-02-15 12:12:44 +01:00
use Modules\RitenuteContributi\RitenutaContributi ;
2019-07-31 18:22:35 +02:00
use Modules\Scadenzario\Scadenza ;
2019-09-13 11:29:45 +02:00
use Plugins\DichiarazioniIntento\Dichiarazione ;
2019-02-12 11:42:48 +01:00
use Plugins\ExportFE\FatturaElettronica ;
2018-12-29 12:03:22 +01:00
use Traits\RecordTrait ;
2020-03-03 10:33:32 +01:00
use Traits\ReferenceTrait ;
2021-06-28 11:33:51 +02:00
use Translator ;
2021-07-07 07:57:10 +02:00
use Util\Generator ;
2018-08-08 19:32:20 +02:00
2018-12-14 09:46:35 +01:00
class Fattura extends Document
2018-08-08 19:32:20 +02:00
{
2018-11-30 19:40:06 +01:00
use RecordTrait ;
2020-03-03 10:33:32 +01:00
use ReferenceTrait ;
2018-11-30 19:40:06 +01:00
2018-08-08 19:32:20 +02:00
protected $table = 'co_documenti' ;
2018-12-23 16:16:59 +01:00
protected $casts = [
'bollo' => 'float' ,
2020-07-08 08:45:55 +02:00
'peso' => 'float' ,
'volume' => 'float' ,
2021-02-26 18:45:52 +01:00
'sconto_finale' => 'float' ,
'sconto_finale_percentuale' => 'float' ,
2018-12-23 16:16:59 +01:00
];
2020-03-09 13:57:13 +01:00
protected $with = [
'tipo' ,
];
2020-03-14 14:32:47 +01:00
protected $dates = [
'data' ,
];
2020-08-05 17:58:54 +02:00
/** @var GestoreScadenze */
protected $gestoreScadenze ;
/** @var GestoreMovimenti */
protected $gestoreMovimenti ;
/** @var GestoreBollo */
2021-04-01 20:32:37 +02:00
protected $gestoreBollo ;
2020-08-05 17:58:54 +02:00
public function __construct ( array $attributes = [])
{
parent :: __construct ( $attributes );
// Inizializzazione gestori relativi
$this -> gestoreScadenze = new GestoreScadenze ( $this );
$this -> gestoreMovimenti = new GestoreMovimenti ( $this );
$this -> gestoreBollo = new GestoreBollo ( $this );
}
2018-08-08 19:32:20 +02:00
/**
* Crea una nuova fattura .
*
2020-02-11 11:43:59 +01:00
* @ param string $data
* @ param int $id_segment
2018-09-25 16:47:44 +02:00
*
* @ return self
2018-08-08 19:32:20 +02:00
*/
2020-04-22 18:17:25 +02:00
public static function build ( Anagrafica $anagrafica , Tipo $tipo_documento , $data , $id_segment , $numero_esterno = null )
2018-08-08 19:32:20 +02:00
{
2020-09-22 20:28:37 +02:00
$model = new static ();
2018-08-08 19:32:20 +02:00
2019-06-25 18:51:37 +02:00
$user = Auth :: user ();
2020-09-17 10:17:39 +02:00
$database = database ();
2019-06-25 18:51:37 +02:00
2020-09-17 10:17:39 +02:00
// Individuazione dello stato predefinito per il documento
2018-08-08 19:32:20 +02:00
$stato_documento = Stato :: where ( 'descrizione' , 'Bozza' ) -> first ();
$direzione = $tipo_documento -> dir ;
2020-09-17 10:17:39 +02:00
// Conto predefinito sulla base del flusso di denaro
2018-08-08 19:32:20 +02:00
if ( $direzione == 'entrata' ) {
$id_conto = setting ( 'Conto predefinito fatture di vendita' );
$conto = 'vendite' ;
} else {
$id_conto = setting ( 'Conto predefinito fatture di acquisto' );
$conto = 'acquisti' ;
}
2020-09-17 10:17:39 +02:00
// Informazioni di base
2018-09-28 09:30:46 +02:00
$model -> anagrafica () -> associate ( $anagrafica );
$model -> tipo () -> associate ( $tipo_documento );
$model -> stato () -> associate ( $stato_documento );
$model -> save ();
2018-08-08 19:32:20 +02:00
// Salvataggio delle informazioni
2018-09-25 16:47:44 +02:00
$model -> data = $data ;
2019-07-10 09:15:58 +02:00
$model -> data_registrazione = $data ;
$model -> data_competenza = $data ;
2018-09-25 16:47:44 +02:00
$model -> id_segment = $id_segment ;
2020-09-17 10:17:39 +02:00
$model -> idconto = $id_conto ;
2020-04-24 08:26:22 +02:00
if ( $numero_esterno ) {
2020-04-22 18:17:25 +02:00
$model -> numero_esterno = $numero_esterno ;
2020-04-24 08:26:22 +02:00
}
2018-09-28 09:30:46 +02:00
2020-09-17 10:17:39 +02:00
// Sede aziendale scelta tra le sedi disponibili per l'utente
2021-07-28 16:25:33 +02:00
$id_sede = $user -> id_sede_principale ;
2019-07-22 13:04:00 +02:00
if ( $direzione == 'entrata' ) {
2020-09-17 10:17:39 +02:00
$model -> idsede_destinazione = $id_sede ;
2019-06-04 20:45:40 +02:00
} else {
2020-09-17 10:17:39 +02:00
$model -> idsede_partenza = $id_sede ;
2019-05-29 19:17:57 +02:00
}
2020-09-17 10:17:39 +02:00
// Gestione della marca da bollo predefinita
2019-04-19 20:47:55 +02:00
$model -> addebita_bollo = setting ( 'Addebita marca da bollo al cliente' );
2020-09-17 10:17:39 +02:00
// Ritenuta contributi predefinita
2019-02-21 16:16:43 +01:00
$id_ritenuta_contributi = ( $tipo_documento -> dir == 'entrata' ) ? setting ( 'Ritenuta contributi' ) : null ;
$model -> id_ritenuta_contributi = $id_ritenuta_contributi ? : null ;
2019-02-15 12:12:44 +01:00
2020-09-17 10:17:39 +02:00
// Banca predefinita per l'anagrafica controparte
2020-09-24 16:41:43 +02:00
//$model->id_banca_controparte = ;
2020-09-17 10:17:39 +02:00
// Tipo di pagamento dall'anagrafica controparte
2019-09-13 11:29:45 +02:00
$id_pagamento = $database -> fetchOne ( 'SELECT id FROM co_pagamenti WHERE id = :id_pagamento' , [
2020-09-09 16:55:45 +02:00
':id_pagamento' => $anagrafica -> { 'idpagamento_' . $conto },
2019-09-13 11:29:45 +02:00
])[ 'id' ];
2020-09-17 10:17:39 +02:00
// Per Fatture di Vendita senza pagamento predefinito per il Cliente, si utilizza il pagamento predefinito dalle Impostazioni
2019-09-13 11:29:45 +02:00
if ( $direzione == 'entrata' && empty ( $id_pagamento )) {
$id_pagamento = setting ( 'Tipo di pagamento predefinito' );
}
2020-09-17 10:17:39 +02:00
// Salvataggio del pagamento
2018-09-25 16:47:44 +02:00
if ( ! empty ( $id_pagamento )) {
$model -> idpagamento = $id_pagamento ;
}
2020-09-17 10:17:39 +02:00
// Banca predefinita per l'azienda, con ricerca della banca impostata per il pagamento
2020-09-24 16:41:43 +02:00
$id_banca_azienda = $anagrafica -> { 'idbanca_' . $conto };
2020-09-17 10:17:39 +02:00
if ( empty ( $id_banca_azienda )) {
2020-09-24 16:41:43 +02:00
$azienda = Anagrafica :: find ( setting ( 'Azienda predefinita' ));
$id_banca_azienda = $database -> fetchOne ( 'SELECT id FROM co_banche WHERE id_pianodeiconti3 = (SELECT idconto_' . $conto . ' FROM co_pagamenti WHERE id = :id_pagamento) AND id_anagrafica = :id_anagrafica' , [
':id_pagamento' => $id_pagamento ,
':id_anagrafica' => $azienda -> id ,
])[ 'id' ];
if ( empty ( $id_banca_azienda )) {
$id_banca_azienda = $azienda -> { 'idbanca_' . $conto };
}
2018-09-25 16:47:44 +02:00
}
2021-02-18 18:48:44 +01:00
2020-12-18 12:21:23 +01:00
$model -> id_banca_azienda = $id_banca_azienda ;
2018-12-29 11:15:34 +01:00
2020-09-17 10:17:39 +02:00
// Gestione dello Split Payment sulla base dell'anagrafica Controparte
2019-09-13 11:29:45 +02:00
$split_payment = $anagrafica -> split_payment ;
2018-12-29 11:15:34 +01:00
if ( ! empty ( $split_payment )) {
$model -> split_payment = $split_payment ;
}
2020-09-17 10:17:39 +02:00
// Gestione della Dichiarazione d'Intento associata all'anargafica Controparte
2019-09-13 11:29:45 +02:00
$now = new Carbon ();
$dichiarazione = $anagrafica -> dichiarazioni ()
-> where ( 'massimale' , '>' , 'totale' )
-> where ( 'data_inizio' , '<' , $now )
-> where ( 'data_fine' , '>' , $now )
-> first ();
if ( ! empty ( $dichiarazione )) {
$model -> dichiarazione () -> associate ( $dichiarazione );
2020-09-17 10:17:39 +02:00
// Registrazione dell'operazione nelle note
2019-09-13 11:29:45 +02:00
$model -> note = tr ( " Operazione non imponibile come da vostra dichiarazione d'intento nr _PROT_ del _PROT_DATE_ emessa in data _RELEASE_DATE_, da noi registrata al nr _ID_ del _DATE_ " , [
2020-08-05 17:58:54 +02:00
'_PROT_' => $dichiarazione -> numero_protocollo ,
2021-06-28 11:33:51 +02:00
'_PROT_DATE_' => Translator :: dateToLocale ( $dichiarazione -> data_protocollo ),
'_RELEASE_DATE_' => Translator :: dateToLocale ( $dichiarazione -> data_emissione ),
2020-08-05 17:58:54 +02:00
'_ID_' => $dichiarazione -> id ,
2021-06-28 11:33:51 +02:00
'_DATE_' => Translator :: dateToLocale ( $dichiarazione -> data ),
2020-08-05 17:58:54 +02:00
]) . '.' ;
2019-09-13 11:29:45 +02:00
}
2018-08-08 19:32:20 +02:00
$model -> save ();
2019-06-04 20:45:40 +02:00
2018-08-08 19:32:20 +02:00
return $model ;
}
2019-09-13 11:29:45 +02:00
// Attributi Eloquent
2018-09-28 09:30:46 +02:00
/**
* Imposta il sezionale relativo alla fattura e calcola il relativo numero .
* ** Attenzione **: la data deve inserita prima !
*
2018-11-30 19:40:06 +01:00
* @ param int $value
2018-09-28 09:30:46 +02:00
*/
public function setIdSegmentAttribute ( $value )
{
$previous = $this -> id_segment ;
$this -> attributes [ 'id_segment' ] = $value ;
// Calcolo dei numeri fattura
if ( $value != $previous ) {
2018-10-25 16:57:39 +02:00
$direzione = $this -> tipo -> dir ;
2018-09-28 09:30:46 +02:00
$data = $this -> data ;
2018-12-07 12:10:55 +01:00
$this -> numero = static :: getNextNumero ( $data , $direzione , $value );
2019-08-29 17:25:41 +02:00
2020-03-06 17:28:00 +01:00
if ( $this -> stato -> descrizione == 'Bozza' ) {
$this -> numero_esterno = null ;
} elseif ( ! empty ( $previous )) {
2019-08-29 17:25:41 +02:00
$this -> numero_esterno = static :: getNextNumeroSecondario ( $data , $direzione , $value );
}
2018-09-28 09:30:46 +02:00
}
}
2018-08-08 19:32:20 +02:00
/**
2018-12-29 11:15:34 +01:00
* Restituisce il nome del modulo a cui l ' oggetto è collegato .
2018-08-08 19:32:20 +02:00
*
* @ return string
*/
2018-12-29 11:15:34 +01:00
public function getModuleAttribute ()
2018-08-08 19:32:20 +02:00
{
2019-03-29 12:46:17 +01:00
return $this -> direzione == 'entrata' ? 'Fatture di vendita' : 'Fatture di acquisto' ;
}
public function getDirezioneAttribute ()
{
return $this -> tipo -> dir ;
2018-08-08 19:32:20 +02:00
}
2020-07-08 08:45:55 +02:00
/**
* Restituisce il peso calcolato sulla base degli articoli del documento .
*
* @ return float
*/
public function getPesoCalcolatoAttribute ()
{
$righe = $this -> getRighe ();
$peso_lordo = $righe -> sum ( function ( $item ) {
return $item -> isArticolo () ? $item -> articolo -> peso_lordo * $item -> qta : 0 ;
});
return $peso_lordo ;
}
/**
* Restituisce il volume calcolato sulla base degli articoli del documento .
*
* @ return float
*/
public function getVolumeCalcolatoAttribute ()
{
$righe = $this -> getRighe ();
$volume = $righe -> sum ( function ( $item ) {
return $item -> isArticolo () ? $item -> articolo -> volume * $item -> qta : 0 ;
});
return $volume ;
}
2019-02-15 12:12:44 +01:00
// Calcoli
2018-08-08 19:32:20 +02:00
/**
2019-02-15 12:12:44 +01:00
* Calcola la rivalsa INPS totale della fattura .
2018-08-08 19:32:20 +02:00
*
2019-02-15 12:12:44 +01:00
* @ return float
2018-08-08 19:32:20 +02:00
*/
2019-02-15 12:12:44 +01:00
public function getRivalsaINPSAttribute ()
2018-08-08 19:32:20 +02:00
{
2019-02-15 12:12:44 +01:00
return $this -> calcola ( 'rivalsa_inps' );
2018-12-24 10:46:59 +01:00
}
/**
2019-02-15 12:12:44 +01:00
* Calcola l ' IVA totale della fattura .
2018-12-24 10:46:59 +01:00
*
2019-02-15 12:12:44 +01:00
* @ return float
2018-12-24 10:46:59 +01:00
*/
2019-02-15 12:12:44 +01:00
public function getIvaAttribute ()
2018-12-24 10:46:59 +01:00
{
2019-02-15 12:12:44 +01:00
return $this -> calcola ( 'iva' , 'iva_rivalsa_inps' );
2018-08-08 19:32:20 +02:00
}
2021-07-13 14:54:27 +02:00
/**
* Calcola l ' IVA INDETRAIBILE totale della fattura .
*
* @ return float
*/
public function getIvaIndetraibileAttribute ()
{
return $this -> calcola ( 'iva_indetraibile' );
}
2018-08-08 19:32:20 +02:00
/**
2019-02-15 12:12:44 +01:00
* Calcola l ' iva della rivalsa INPS totale della fattura .
2018-08-08 19:32:20 +02:00
*
2019-02-15 12:12:44 +01:00
* @ return float
2018-08-08 19:32:20 +02:00
*/
2019-02-15 12:12:44 +01:00
public function getIvaRivalsaINPSAttribute ()
2018-08-08 19:32:20 +02:00
{
2019-02-15 12:12:44 +01:00
return $this -> calcola ( 'iva_rivalsa_inps' );
2018-08-08 19:32:20 +02:00
}
2019-02-15 12:12:44 +01:00
/**
* Calcola la ritenuta d ' acconto totale della fattura .
*
* @ return float
*/
public function getRitenutaAccontoAttribute ()
2018-09-26 15:37:46 +02:00
{
2019-02-15 12:12:44 +01:00
return $this -> calcola ( 'ritenuta_acconto' );
2018-09-26 15:37:46 +02:00
}
2019-02-15 12:12:44 +01:00
public function getTotaleRitenutaContributiAttribute ()
{
return $this -> calcola ( 'ritenuta_contributi' );
}
2019-07-15 18:34:59 +02:00
/**
* Restituisce i dati aggiuntivi per la fattura elettronica dell ' elemento .
*
* @ return array
*/
public function getDatiAggiuntiviFEAttribute ()
{
$result = json_decode ( $this -> attributes [ 'dati_aggiuntivi_fe' ], true );
return ( array ) $result ;
}
/**
* Imposta i dati aggiuntivi per la fattura elettronica dell ' elemento .
*/
public function setDatiAggiuntiviFEAttribute ( $values )
{
$values = ( array ) $values ;
$dati = array_deep_clean ( $values );
$this -> attributes [ 'dati_aggiuntivi_fe' ] = json_encode ( $dati );
}
2019-02-15 12:12:44 +01:00
// Relazioni Eloquent
2018-08-09 10:14:26 +02:00
public function anagrafica ()
{
return $this -> belongsTo ( Anagrafica :: class , 'idanagrafica' );
}
2018-08-08 19:32:20 +02:00
public function tipo ()
{
return $this -> belongsTo ( Tipo :: class , 'idtipodocumento' );
}
2019-09-13 11:29:45 +02:00
public function stato ()
{
return $this -> belongsTo ( Stato :: class , 'idstatodocumento' );
}
2019-03-08 16:59:55 +01:00
public function pagamento ()
{
return $this -> belongsTo ( Pagamento :: class , 'idpagamento' );
}
2019-09-13 11:29:45 +02:00
public function dichiarazione ()
2018-08-08 19:32:20 +02:00
{
2019-09-13 11:29:45 +02:00
return $this -> belongsTo ( Dichiarazione :: class , 'id_dichiarazione_intento' );
2018-08-08 19:32:20 +02:00
}
2019-02-01 18:19:13 +01:00
public function statoFE ()
{
return $this -> belongsTo ( StatoFE :: class , 'codice_stato_fe' );
}
2018-09-25 16:47:44 +02:00
public function articoli ()
{
2018-12-25 11:32:19 +01:00
return $this -> hasMany ( Components\Articolo :: class , 'iddocumento' );
2018-09-25 16:47:44 +02:00
}
2018-08-08 19:32:20 +02:00
public function righe ()
{
2018-12-25 11:32:19 +01:00
return $this -> hasMany ( Components\Riga :: class , 'iddocumento' );
2018-08-08 19:32:20 +02:00
}
2018-09-25 11:55:52 +02:00
2019-04-04 17:12:32 +02:00
public function sconti ()
{
return $this -> hasMany ( Components\Sconto :: class , 'iddocumento' );
}
2018-09-26 15:37:46 +02:00
public function descrizioni ()
2018-09-25 11:55:52 +02:00
{
2018-12-25 11:32:19 +01:00
return $this -> hasMany ( Components\Descrizione :: class , 'iddocumento' );
2018-09-25 11:55:52 +02:00
}
2018-12-23 16:16:59 +01:00
2019-02-15 12:12:44 +01:00
public function ritenutaContributi ()
{
return $this -> belongsTo ( RitenutaContributi :: class , 'id_ritenuta_contributi' );
}
2019-04-19 20:47:55 +02:00
public function rigaBollo ()
{
return $this -> hasOne ( Components\Riga :: class , 'iddocumento' ) -> where ( 'id' , $this -> id_riga_bollo );
}
2019-07-31 18:22:35 +02:00
public function scadenze ()
{
2020-02-14 11:35:44 +01:00
return $this -> hasMany ( Scadenza :: class , 'iddocumento' ) -> orderBy ( 'scadenza' );
2019-07-31 18:22:35 +02:00
}
public function movimentiContabili ()
{
return $this -> hasMany ( Movimento :: class , 'iddocumento' ) -> where ( 'primanota' , 1 );
}
2019-02-15 12:12:44 +01:00
// Metodi generali
2020-09-22 20:28:37 +02:00
public function triggerComponent ( Component $trigger )
2019-09-13 11:29:45 +02:00
{
parent :: triggerComponent ( $trigger );
// Correzione del totale della dichiarazione d'intento
$dichiarazione = $this -> dichiarazione ;
if ( ! empty ( $dichiarazione )) {
$dichiarazione -> fixTotale ();
$dichiarazione -> save ();
}
}
/**
* Restituisce i contenuti della fattura elettronica relativa al documento .
*
* @ return false | string
*/
2019-02-12 11:42:48 +01:00
public function getXML ()
{
2019-03-15 12:16:20 +01:00
if ( empty ( $this -> progressivo_invio ) && $this -> module == 'Fatture di acquisto' ) {
2019-02-12 11:42:48 +01:00
$fe = new FatturaElettronica ( $this -> id );
return $fe -> toXML ();
}
2021-03-31 22:03:55 +02:00
$file = $this -> uploads () -> where ( 'name' , '=' , 'Fattura Elettronica' ) -> first ();
2019-02-12 11:42:48 +01:00
2021-03-08 11:20:04 +01:00
return $file -> getContent ();
2019-02-12 11:42:48 +01:00
}
2020-07-08 10:40:04 +02:00
/**
* Restituisce le ricevute della fattura elettronica relativa al documento .
*
* @ return iterable
*/
public function getRicevute ()
{
$nome = 'Ricevuta' ;
return $this -> uploads () -> filter ( function ( $item ) use ( $nome ) {
return false !== strstr ( $item -> name , $nome );
}) -> sortBy ( 'created_at' );
}
2019-02-12 11:42:48 +01:00
2020-09-08 10:38:27 +02:00
/**
* Restituisce la ricevuta principale , impostata attraverso il campo aggiuntivo id_ricevuta_principale .
*
* @ return Upload | null
*/
public function getRicevutaPrincipale ()
{
if ( empty ( $this -> id_ricevuta_principale )) {
return null ;
}
return $this -> getModule ()
-> uploads ( $this -> id )
-> where ( 'id' , $this -> id_ricevuta_principale )
-> first ();
}
2021-03-31 22:03:55 +02:00
/**
* Restituisce la fattura elettronica registrata come allegato .
*
* @ return Upload | null
*/
public function getFatturaElettronica ()
{
return $this -> uploads ()
-> where ( 'name' , '=' , 'Fattura Elettronica' )
-> first ();
}
2019-09-13 11:29:45 +02:00
/**
* Controlla se la fattura di acquisto è elettronica .
*
* @ return bool
*/
2019-02-12 11:42:48 +01:00
public function isFE ()
{
2021-03-31 22:03:55 +02:00
$file = $this -> getFatturaElettronica ();
2019-06-29 11:01:26 +02:00
return ! empty ( $this -> progressivo_invio ) and file_exists ( $file -> filepath );
2019-02-12 11:42:48 +01:00
}
2019-03-08 16:59:55 +01:00
/**
* Registra le scadenze della fattura .
*
* @ param bool $is_pagato
* @ param bool $ignora_fe
*/
public function registraScadenze ( $is_pagato = false , $ignora_fe = false )
{
2020-08-05 17:58:54 +02:00
$this -> gestoreScadenze -> registra ( $is_pagato , $ignora_fe );
2019-03-08 16:59:55 +01:00
}
/**
* Elimina le scadenze della fattura .
*/
public function rimuoviScadenze ()
{
2020-08-05 17:58:54 +02:00
$this -> gestoreScadenze -> rimuovi ();
2019-03-08 16:59:55 +01:00
}
2019-04-19 20:47:55 +02:00
/**
* Salva la fattura , impostando i campi dipendenti dai singoli parametri .
*
* @ return bool
*/
public function save ( array $options = [])
{
2021-04-23 13:02:03 +02:00
// Informazioni sul cambio dei valori
$stato_precedente = Stato :: find ( $this -> original [ 'idstatodocumento' ]);
$dichiarazione_precedente = Dichiarazione :: find ( $this -> original [ 'id_dichiarazione_intento' ]);
$is_fiscale = $this -> isFiscale ();
2021-04-22 09:57:17 +02:00
// Salvataggio effettivo
$result = parent :: save ( $options );
2019-04-19 20:47:55 +02:00
// Fix dei campi statici
2020-08-05 17:58:54 +02:00
$this -> id_riga_bollo = $this -> gestoreBollo -> manageRigaMarcaDaBollo ();
2019-04-19 20:47:55 +02:00
$this -> attributes [ 'ritenutaacconto' ] = $this -> ritenuta_acconto ;
$this -> attributes [ 'iva_rivalsainps' ] = $this -> iva_rivalsa_inps ;
$this -> attributes [ 'rivalsainps' ] = $this -> rivalsa_inps ;
$this -> attributes [ 'ritenutaacconto' ] = $this -> ritenuta_acconto ;
2020-02-13 02:30:29 +01:00
2020-08-05 17:58:54 +02:00
// Generazione numero fattura se non presente (Bozza -> Emessa)
2020-02-14 12:23:50 +01:00
if ((( $stato_precedente -> descrizione == 'Bozza' && $this -> stato [ 'descrizione' ] == 'Emessa' ) or ( ! $is_fiscale )) && empty ( $this -> numero_esterno )) {
2019-11-08 15:50:07 +01:00
$this -> numero_esterno = self :: getNextNumeroSecondario ( $this -> data , $this -> direzione , $this -> id_segment );
}
// Salvataggio effettivo
$result = parent :: save ( $options );
// Operazioni al cambiamento di stato
2020-08-05 17:58:54 +02:00
// Bozza o Annullato -> Stato diverso da Bozza o Annullato
2019-11-08 15:50:07 +01:00
if (
in_array ( $stato_precedente -> descrizione , [ 'Bozza' , 'Annullata' ])
&& ! in_array ( $this -> stato [ 'descrizione' ], [ 'Bozza' , 'Annullata' ])
) {
// Registrazione scadenze
$this -> registraScadenze ( $this -> stato [ 'descrizione' ] == 'Pagato' );
// Registrazione movimenti
2020-08-05 17:58:54 +02:00
$this -> gestoreMovimenti -> registra ();
} // Stato qualunque -> Bozza o Annullato
elseif ( in_array ( $this -> stato [ 'descrizione' ], [ 'Bozza' , 'Annullata' ])) {
// Rimozione delle scadenza
2019-11-08 15:50:07 +01:00
$this -> rimuoviScadenze ();
2020-08-05 17:58:54 +02:00
// Rimozione dei movimenti
$this -> gestoreMovimenti -> rimuovi ();
// Rimozione dei movimenti contabili (Prima nota)
$this -> movimentiContabili () -> delete ();
2019-11-08 15:50:07 +01:00
}
// Operazioni sulla dichiarazione d'intento
if ( ! empty ( $dichiarazione_precedente ) && $dichiarazione_precedente -> id != $this -> id_dichiarazione_intento ) {
// Correzione dichiarazione precedente
$dichiarazione_precedente -> fixTotale ();
$dichiarazione_precedente -> save ();
// Correzione nuova dichiarazione
$dichiarazione = Dichiarazione :: find ( $this -> id_dichiarazione_intento );
if ( ! empty ( $dichiarazione )) {
$dichiarazione -> fixTotale ();
$dichiarazione -> save ();
}
}
return $result ;
2019-04-19 20:47:55 +02:00
}
2019-07-23 15:39:00 +02:00
public function delete ()
{
$result = parent :: delete ();
2020-08-05 17:58:54 +02:00
// Rimozione delle scadenza
2019-07-23 15:39:00 +02:00
$this -> rimuoviScadenze ();
2020-08-05 17:58:54 +02:00
// Rimozione dei movimenti
$this -> gestoreMovimenti -> rimuovi ();
// Rimozione dei movimenti contabili (Prima nota)
$this -> movimentiContabili () -> delete ();
2019-07-23 15:39:00 +02:00
return $result ;
}
2021-03-01 14:46:13 +01:00
public function replicate ( array $except = null )
{
$new = parent :: replicate ( $except );
2021-04-08 17:10:58 +02:00
$now = Carbon :: now ();
2021-03-01 14:46:13 +01:00
// In fase di duplicazione di una fattura non deve essere calcolato il numero progressivo ma questo deve
// essere generato in fase di emissione della stessa.
$new -> numero_esterno = '' ;
2021-04-08 17:10:58 +02:00
$new -> numero = Fattura :: getNextNumero ( $now , $new -> direzione , $new -> id_segment );
2021-03-01 14:46:13 +01:00
// Rimozione informazioni di Fattura Elettronica
$new -> hook_send = false ;
$new -> codice_stato_fe = null ;
$new -> progressivo_invio = null ;
$new -> data_stato_fe = null ;
2021-04-08 17:10:58 +02:00
$new -> data = $now ;
$new -> data_registrazione = $now ;
$new -> data_competenza = $now ;
2021-03-01 14:46:13 +01:00
$new -> descrizione_ricevuta_fe = null ;
$new -> id_ricevuta_principale = null ;
// Spostamento dello stato
$stato = Stato :: where ( 'descrizione' , 'Bozza' ) -> first ();
$new -> stato () -> associate ( $stato );
return $new ;
}
2019-02-15 12:12:44 +01:00
/**
* Restituisce l ' elenco delle note di credito collegate .
*
* @ return iterable
*/
public function getNoteDiAccredito ()
{
return self :: where ( 'ref_documento' , $this -> id ) -> get ();
}
/**
* Restituisce l ' elenco delle note di credito collegate .
*
* @ return self
*/
public function getFatturaOriginale ()
{
return self :: find ( $this -> ref_documento );
}
/**
* Controlla se la fattura è una nota di credito .
*
* @ return bool
*/
2019-07-16 11:33:19 +02:00
public function isNota ()
2019-02-15 12:12:44 +01:00
{
return $this -> tipo -> reversed == 1 ;
}
2020-02-13 02:30:29 +01:00
/**
* Controlla se la fattura è fiscale .
*
* @ return bool
*/
public function isFiscale ()
{
$result = database () -> fetchOne ( 'SELECT is_fiscale FROM zz_segments WHERE id =' . prepare ( $this -> id_segment ))[ 'is_fiscale' ];
2020-02-14 12:23:50 +01:00
2020-02-13 02:30:29 +01:00
return $result ;
}
2020-02-24 12:21:47 +01:00
/**
2020-03-14 14:32:47 +01:00
* Scope per l ' inclusione delle sole fatture con valore contabile .
2020-02-24 12:21:47 +01:00
*
* @ param \Illuminate\Database\Eloquent\Builder $query
*
* @ return \Illuminate\Database\Eloquent\Builder
*/
public function scopeContabile ( $query )
{
return $query -> whereHas ( 'stato' , function ( Builder $query ) {
$query -> whereIn ( 'descrizione' , [ 'Emessa' , 'Parzialmente pagato' , 'Pagato' ]);
});
}
2019-05-04 00:32:28 +02:00
/**
* Restituisce i dati bancari in base al pagamento .
*
* @ return array
*/
public function getBanca ()
{
2021-04-19 17:35:42 +02:00
$pagamento = $this -> pagamento ;
2019-05-04 00:32:28 +02:00
2021-04-19 17:35:42 +02:00
if ( $pagamento -> isRiBa ()) {
2020-09-24 16:51:41 +02:00
$banca = Banca :: where ( 'id_anagrafica' , $this -> idanagrafica )
-> where ( 'predefined' , 1 )
-> first ();
2019-05-04 00:32:28 +02:00
} else {
2020-09-24 16:51:41 +02:00
$banca = Banca :: find ( $this -> id_banca_azienda );
2019-05-04 00:32:28 +02:00
}
2020-09-24 16:51:41 +02:00
return $banca ;
2019-05-04 00:32:28 +02:00
}
2019-07-31 18:22:35 +02:00
// Metodi statici
/**
* Calcola il nuovo numero di fattura .
*
* @ param string $data
* @ param string $direzione
* @ param int $id_segment
*
* @ return string
*/
public static function getNextNumero ( $data , $direzione , $id_segment )
{
if ( $direzione == 'entrata' ) {
return '' ;
}
// Recupero maschera per questo segmento
$maschera = Generator :: getMaschera ( $id_segment );
$ultimo = Generator :: getPreviousFrom ( $maschera , 'co_documenti' , 'numero' , [
'YEAR(data) = ' . prepare ( date ( 'Y' , strtotime ( $data ))),
'id_segment = ' . prepare ( $id_segment ),
]);
$numero = Generator :: generate ( $maschera , $ultimo , 1 , Generator :: dateToPattern ( $data ));
return $numero ;
}
2020-03-14 14:32:47 +01:00
/**
* Scope per l ' inclusione delle fatture di vendita .
*
* @ param \Illuminate\Database\Eloquent\Builder $query
*
* @ return \Illuminate\Database\Eloquent\Builder
*/
public function scopeVendita ( $query )
{
return $query -> whereHas ( 'tipo' , function ( Builder $query ) {
$query -> where ( 'dir' , 'entrata' );
});
}
/**
* Scope per l ' inclusione delle fatture di acquisto .
*
* @ param \Illuminate\Database\Eloquent\Builder $query
*
* @ return \Illuminate\Database\Eloquent\Builder
*/
public function scopeAcquisto ( $query )
{
return $query -> whereHas ( 'tipo' , function ( Builder $query ) {
$query -> where ( 'dir' , 'uscita' );
});
}
2019-07-31 18:22:35 +02:00
/**
* Calcola il nuovo numero secondario di fattura .
*
* @ param string $data
* @ param string $direzione
* @ param int $id_segment
*
* @ return string
*/
public static function getNextNumeroSecondario ( $data , $direzione , $id_segment )
{
if ( $direzione == 'uscita' ) {
return '' ;
}
// Recupero maschera per questo segmento
$maschera = Generator :: getMaschera ( $id_segment );
$ultimo = Generator :: getPreviousFrom ( $maschera , 'co_documenti' , 'numero_esterno' , [
'YEAR(data) = ' . prepare ( date ( 'Y' , strtotime ( $data ))),
'id_segment = ' . prepare ( $id_segment ),
2020-01-03 17:09:49 +01:00
], $data );
2019-07-31 18:22:35 +02:00
$numero = Generator :: generate ( $maschera , $ultimo , 1 , Generator :: dateToPattern ( $data ));
return $numero ;
}
2020-03-03 10:33:32 +01:00
// Opzioni di riferimento
public function getReferenceName ()
{
return $this -> tipo -> descrizione ;
}
public function getReferenceNumber ()
{
return $this -> numero_esterno ? : $this -> numero ;
}
public function getReferenceDate ()
{
return $this -> data ;
}
2020-10-15 17:00:43 +02:00
public function getReferenceRagioneSociale ()
{
return $this -> anagrafica -> ragione_sociale ;
}
2018-08-08 19:32:20 +02:00
}