Introduzione Totale reddito per i Movimenti
This commit is contained in:
parent
a1009c52a2
commit
8e4e6951cf
|
@ -91,6 +91,8 @@ function get_ivaindetraibile_fattura($iddocumento)
|
|||
|
||||
/**
|
||||
* Elimina una scadenza in base al codice documento.
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function elimina_scadenze($iddocumento)
|
||||
{
|
||||
|
@ -104,6 +106,8 @@ function elimina_scadenze($iddocumento)
|
|||
* $iddocumento string E' l'id del documento di cui ricalcolare lo scadenzario
|
||||
* $pagamento string Nome del tipo di pagamento. Se è vuoto lo leggo da co_pagamenti_documenti, perché significa che devo solo aggiornare gli importi.
|
||||
* $pagato boolean Indica se devo segnare l'importo come pagato.
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function aggiungi_scadenza($iddocumento, $pagamento = '', $pagato = false)
|
||||
{
|
||||
|
@ -118,6 +122,8 @@ function aggiungi_scadenza($iddocumento, $pagamento = '', $pagato = false)
|
|||
*
|
||||
* @param $iddocumento
|
||||
* @param int $prima_nota
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function elimina_movimenti($id_documento, $prima_nota = 0)
|
||||
{
|
||||
|
@ -134,6 +140,8 @@ function elimina_movimenti($id_documento, $prima_nota = 0)
|
|||
* $iddocumento string E' l'id del documento da collegare alla prima nota
|
||||
* $dir string Direzione dell'importo (entrata, uscita)
|
||||
* $primanota boolean Indica se il movimento è un movimento di prima nota o un movimento normale (di default movimento normale).
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function aggiungi_movimento($iddocumento, $dir, $primanota = 0)
|
||||
{
|
||||
|
@ -331,6 +339,8 @@ function aggiungi_movimento($iddocumento, $dir, $primanota = 0)
|
|||
|
||||
/**
|
||||
* Funzione per generare un nuovo codice per il mastrino.
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function get_new_idmastrino($table = 'co_movimenti')
|
||||
{
|
||||
|
@ -346,6 +356,8 @@ function get_new_idmastrino($table = 'co_movimenti')
|
|||
* Ricalcola i costi aggiuntivi in fattura (rivalsa inps, ritenuta d'acconto, marca da bollo)
|
||||
* Deve essere eseguito ogni volta che si aggiunge o toglie una riga
|
||||
* $iddocumento int ID della fattura.
|
||||
*
|
||||
* @deprecated 2.4.17
|
||||
*/
|
||||
function ricalcola_costiagg_fattura($iddocumento)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,9 @@ use Common\Components\Description;
|
|||
use Common\Document;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Modules\Anagrafiche\Anagrafica;
|
||||
use Modules\Fatture\Components\Riga;
|
||||
use Modules\Fatture\Gestori\Bollo as GestoreBollo;
|
||||
use Modules\Fatture\Gestori\Movimenti as GestoreMovimenti;
|
||||
use Modules\Fatture\Gestori\Scadenze as GestoreScadenze;
|
||||
use Modules\Pagamenti\Pagamento;
|
||||
use Modules\PrimaNota\Movimento;
|
||||
use Modules\RitenuteContributi\RitenutaContributi;
|
||||
|
@ -40,6 +42,23 @@ class Fattura extends Document
|
|||
'data',
|
||||
];
|
||||
|
||||
/** @var GestoreScadenze */
|
||||
protected $gestoreScadenze;
|
||||
/** @var GestoreMovimenti */
|
||||
protected $gestoreMovimenti;
|
||||
/** @var GestoreBollo */
|
||||
private $gestoreBollo;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea una nuova fattura.
|
||||
*
|
||||
|
@ -137,12 +156,12 @@ class Fattura extends Document
|
|||
$model->dichiarazione()->associate($dichiarazione);
|
||||
|
||||
$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_", [
|
||||
'_PROT_' => $dichiarazione->numero_protocollo,
|
||||
'_PROT_DATE_' => $dichiarazione->data_protocollo,
|
||||
'_RELEASE_DATE_' => $dichiarazione->data_emissione,
|
||||
'_ID_' => $dichiarazione->id,
|
||||
'_DATE_' => $dichiarazione->data,
|
||||
]).'.';
|
||||
'_PROT_' => $dichiarazione->numero_protocollo,
|
||||
'_PROT_DATE_' => $dichiarazione->data_protocollo,
|
||||
'_RELEASE_DATE_' => $dichiarazione->data_emissione,
|
||||
'_ID_' => $dichiarazione->id,
|
||||
'_DATE_' => $dichiarazione->data,
|
||||
]).'.';
|
||||
}
|
||||
|
||||
$model->save();
|
||||
|
@ -436,71 +455,6 @@ class Fattura extends Document
|
|||
return !empty($this->progressivo_invio) and file_exists($file->filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze della fattura elettronica collegata al documento.
|
||||
*
|
||||
* @param bool $is_pagato
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function registraScadenzeFE($is_pagato = false)
|
||||
{
|
||||
$xml = \Util\XML::read($this->getXML());
|
||||
|
||||
$pagamenti = $xml['FatturaElettronicaBody']['DatiPagamento']['DettaglioPagamento'];
|
||||
if (!empty($pagamenti)) {
|
||||
$rate = isset($pagamenti[0]) ? $pagamenti : [$pagamenti];
|
||||
|
||||
foreach ($rate as $rata) {
|
||||
$scadenza = $rata['DataScadenzaPagamento'] ?: $this->data;
|
||||
$importo = ($this->isNota()) ? $rata['ImportoPagamento'] : -$rata['ImportoPagamento'];
|
||||
|
||||
self::registraScadenza($this, $importo, $scadenza, $is_pagato);
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($pagamenti);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze tradizionali del gestionale.
|
||||
*
|
||||
* @param bool $is_pagato
|
||||
*/
|
||||
public function registraScadenzeTradizionali($is_pagato = false)
|
||||
{
|
||||
$rate = $this->pagamento->calcola($this->netto, $this->data);
|
||||
$direzione = $this->tipo->dir;
|
||||
|
||||
foreach ($rate as $rata) {
|
||||
$scadenza = $rata['scadenza'];
|
||||
$importo = $direzione == 'uscita' ? -$rata['importo'] : $rata['importo'];
|
||||
|
||||
self::registraScadenza($this, $importo, $scadenza, $is_pagato);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra una specifica scadenza nel database.
|
||||
*
|
||||
* @param float $importo
|
||||
* @param string $data_scadenza
|
||||
* @param bool $is_pagato
|
||||
* @param string $type
|
||||
*/
|
||||
public static function registraScadenza(Fattura $fattura, $importo, $data_scadenza, $is_pagato, $type = 'fattura')
|
||||
{
|
||||
$numero = $fattura->numero_esterno ?: $fattura->numero;
|
||||
$descrizione = $fattura->tipo->descrizione.' numero '.$numero;
|
||||
|
||||
$scadenza = Scadenza::build($descrizione, $importo, $data_scadenza, $type, $is_pagato);
|
||||
|
||||
$scadenza->documento()->associate($fattura);
|
||||
$scadenza->data_emissione = $fattura->data;
|
||||
|
||||
$scadenza->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze della fattura.
|
||||
*
|
||||
|
@ -509,29 +463,7 @@ class Fattura extends Document
|
|||
*/
|
||||
public function registraScadenze($is_pagato = false, $ignora_fe = false)
|
||||
{
|
||||
$this->rimuoviScadenze();
|
||||
|
||||
if (!$ignora_fe && $this->module == 'Fatture di acquisto' && $this->isFE()) {
|
||||
$scadenze_fe = $this->registraScadenzeFE($is_pagato);
|
||||
}
|
||||
|
||||
if (empty($scadenze_fe)) {
|
||||
$this->registraScadenzeTradizionali($is_pagato);
|
||||
}
|
||||
|
||||
$direzione = $this->tipo->dir;
|
||||
$ritenuta_acconto = $this->ritenuta_acconto;
|
||||
|
||||
// Se c'è una ritenuta d'acconto, la aggiungo allo scadenzario al 15 del mese dopo l'ultima scadenza di pagamento
|
||||
if ($direzione == 'uscita' && $ritenuta_acconto > 0) {
|
||||
$ultima_scadenza = $this->scadenze->last();
|
||||
$scadenza = $ultima_scadenza->scadenza->copy()->startOfMonth()->addMonth();
|
||||
$scadenza->setDate($scadenza->year, $scadenza->month, 15);
|
||||
|
||||
$importo = -$ritenuta_acconto;
|
||||
|
||||
self::registraScadenza($this, $importo, $scadenza, $is_pagato, 'ritenutaacconto');
|
||||
}
|
||||
$this->gestoreScadenze->registra($is_pagato, $ignora_fe);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -539,7 +471,7 @@ class Fattura extends Document
|
|||
*/
|
||||
public function rimuoviScadenze()
|
||||
{
|
||||
database()->delete('co_scadenziario', ['iddocumento' => $this->id]);
|
||||
$this->gestoreScadenze->rimuovi();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -550,7 +482,7 @@ class Fattura extends Document
|
|||
public function save(array $options = [])
|
||||
{
|
||||
// Fix dei campi statici
|
||||
$this->manageRigaMarcaDaBollo();
|
||||
$this->id_riga_bollo = $this->gestoreBollo->manageRigaMarcaDaBollo();
|
||||
|
||||
$this->attributes['ritenutaacconto'] = $this->ritenuta_acconto;
|
||||
$this->attributes['iva_rivalsainps'] = $this->iva_rivalsa_inps;
|
||||
|
@ -562,7 +494,7 @@ class Fattura extends Document
|
|||
$dichiarazione_precedente = Dichiarazione::find($this->original['id_dichiarazione_intento']);
|
||||
$is_fiscale = $this->isFiscale();
|
||||
|
||||
// Generazione numero fattura se non presente
|
||||
// Generazione numero fattura se non presente (Bozza -> Emessa)
|
||||
if ((($stato_precedente->descrizione == 'Bozza' && $this->stato['descrizione'] == 'Emessa') or (!$is_fiscale)) && empty($this->numero_esterno)) {
|
||||
$this->numero_esterno = self::getNextNumeroSecondario($this->data, $this->direzione, $this->id_segment);
|
||||
}
|
||||
|
@ -571,6 +503,7 @@ class Fattura extends Document
|
|||
$result = parent::save($options);
|
||||
|
||||
// Operazioni al cambiamento di stato
|
||||
// Bozza o Annullato -> Stato diverso da Bozza o Annullato
|
||||
if (
|
||||
in_array($stato_precedente->descrizione, ['Bozza', 'Annullata'])
|
||||
&& !in_array($this->stato['descrizione'], ['Bozza', 'Annullata'])
|
||||
|
@ -579,12 +512,17 @@ class Fattura extends Document
|
|||
$this->registraScadenze($this->stato['descrizione'] == 'Pagato');
|
||||
|
||||
// Registrazione movimenti
|
||||
aggiungi_movimento($this->id, $this->direzione);
|
||||
} elseif (in_array($this->stato['descrizione'], ['Bozza', 'Annullata'])) {
|
||||
$this->gestoreMovimenti->registra();
|
||||
} // Stato qualunque -> Bozza o Annullato
|
||||
elseif (in_array($this->stato['descrizione'], ['Bozza', 'Annullata'])) {
|
||||
// Rimozione delle scadenza
|
||||
$this->rimuoviScadenze();
|
||||
|
||||
elimina_movimenti($this->id, 1);
|
||||
elimina_movimenti($this->id);
|
||||
// Rimozione dei movimenti
|
||||
$this->gestoreMovimenti->rimuovi();
|
||||
|
||||
// Rimozione dei movimenti contabili (Prima nota)
|
||||
$this->movimentiContabili()->delete();
|
||||
}
|
||||
|
||||
// Operazioni sulla dichiarazione d'intento
|
||||
|
@ -608,8 +546,14 @@ class Fattura extends Document
|
|||
{
|
||||
$result = parent::delete();
|
||||
|
||||
// Rimozione delle scadenza
|
||||
$this->rimuoviScadenze();
|
||||
elimina_movimenti($this->id);
|
||||
|
||||
// Rimozione dei movimenti
|
||||
$this->gestoreMovimenti->rimuovi();
|
||||
|
||||
// Rimozione dei movimenti contabili (Prima nota)
|
||||
$this->movimentiContabili()->delete();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -688,74 +632,6 @@ class Fattura extends Document
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo per calcolare automaticamente il bollo da applicare al documento.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBollo()
|
||||
{
|
||||
if (isset($this->bollo)) {
|
||||
return $this->bollo;
|
||||
}
|
||||
|
||||
$righe_bollo = $this->getRighe()->filter(function ($item, $key) {
|
||||
return $item->aliquota != null && in_array($item->aliquota->codice_natura_fe, ['N1', 'N2', 'N3', 'N4']);
|
||||
});
|
||||
$importo_righe_bollo = $righe_bollo->sum('netto');
|
||||
|
||||
// Leggo la marca da bollo se c'è e se il netto a pagare supera la soglia
|
||||
$bollo = ($this->direzione == 'uscita') ? $this->bollo : setting('Importo marca da bollo');
|
||||
|
||||
$marca_da_bollo = 0;
|
||||
if (abs($bollo) > 0 && abs($importo_righe_bollo) > setting("Soglia minima per l'applicazione della marca da bollo")) {
|
||||
$marca_da_bollo = $bollo;
|
||||
}
|
||||
|
||||
// Se l'importo è negativo può essere una nota di credito, quindi cambio segno alla marca da bollo
|
||||
$marca_da_bollo = abs($marca_da_bollo);
|
||||
|
||||
return $marca_da_bollo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo per aggiornare ed eventualemente aggiungere la marca da bollo al documento.
|
||||
*/
|
||||
public function manageRigaMarcaDaBollo()
|
||||
{
|
||||
$riga = $this->rigaBollo;
|
||||
|
||||
$addebita_bollo = $this->addebita_bollo;
|
||||
$marca_da_bollo = $this->getBollo();
|
||||
|
||||
// Rimozione riga bollo se nullo
|
||||
if (empty($addebita_bollo) || empty($marca_da_bollo)) {
|
||||
if (!empty($riga)) {
|
||||
$this->id_riga_bollo = null;
|
||||
|
||||
$riga->delete();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Creazione riga bollo se non presente
|
||||
if (empty($riga)) {
|
||||
$riga = Components\Riga::build($this);
|
||||
$riga->save();
|
||||
|
||||
$this->id_riga_bollo = $riga->id;
|
||||
}
|
||||
|
||||
$riga->prezzo_unitario = $marca_da_bollo;
|
||||
$riga->qta = 1;
|
||||
$riga->descrizione = setting('Descrizione addebito bollo');
|
||||
$riga->id_iva = setting('Iva da applicare su marca da bollo');
|
||||
$riga->idconto = setting('Conto predefinito per la marca da bollo');
|
||||
|
||||
$riga->save();
|
||||
}
|
||||
|
||||
// Metodi statici
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Fatture\Gestori;
|
||||
|
||||
use Modules\Fatture\Components;
|
||||
use Modules\Fatture\Fattura;
|
||||
|
||||
class Bollo
|
||||
{
|
||||
private $fattura;
|
||||
|
||||
public function __construct(Fattura $fattura)
|
||||
{
|
||||
$this->fattura = $fattura;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo per calcolare automaticamente il bollo da applicare al documento.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBollo()
|
||||
{
|
||||
if (isset($this->fattura->bollo)) {
|
||||
return $this->fattura->bollo;
|
||||
}
|
||||
|
||||
$righe_bollo = $this->fattura->getRighe()->filter(function ($item, $key) {
|
||||
return $item->aliquota != null && in_array($item->aliquota->codice_natura_fe, ['N1', 'N2', 'N3', 'N4']);
|
||||
});
|
||||
$importo_righe_bollo = $righe_bollo->sum('netto');
|
||||
|
||||
// Leggo la marca da bollo se c'è e se il netto a pagare supera la soglia
|
||||
$bollo = ($this->fattura->direzione == 'uscita') ? $this->fattura->bollo : setting('Importo marca da bollo');
|
||||
|
||||
$marca_da_bollo = 0;
|
||||
if (abs($bollo) > 0 && abs($importo_righe_bollo) > setting("Soglia minima per l'applicazione della marca da bollo")) {
|
||||
$marca_da_bollo = $bollo;
|
||||
}
|
||||
|
||||
// Se l'importo è negativo può essere una nota di credito, quindi cambio segno alla marca da bollo
|
||||
$marca_da_bollo = abs($marca_da_bollo);
|
||||
|
||||
return $marca_da_bollo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metodo per aggiornare ed eventualmente aggiungere la marca da bollo al documento.
|
||||
*/
|
||||
public function manageRigaMarcaDaBollo()
|
||||
{
|
||||
$riga = $this->fattura->rigaBollo;
|
||||
|
||||
$addebita_bollo = $this->fattura->addebita_bollo;
|
||||
$marca_da_bollo = $this->getBollo();
|
||||
|
||||
// Rimozione riga bollo se nullo
|
||||
if (empty($addebita_bollo) || empty($marca_da_bollo)) {
|
||||
if (!empty($riga)) {
|
||||
$riga->delete();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Creazione riga bollo se non presente
|
||||
if (empty($riga)) {
|
||||
$riga = Components\Riga::build($this->fattura);
|
||||
$riga->save();
|
||||
}
|
||||
|
||||
$riga->prezzo_unitario = $marca_da_bollo;
|
||||
$riga->qta = 1;
|
||||
$riga->descrizione = setting('Descrizione addebito bollo');
|
||||
$riga->id_iva = setting('Iva da applicare su marca da bollo');
|
||||
$riga->idconto = setting('Conto predefinito per la marca da bollo');
|
||||
|
||||
$riga->save();
|
||||
|
||||
return $riga->id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Fatture\Gestori;
|
||||
|
||||
use Modules\Fatture\Fattura;
|
||||
use Modules\PrimaNota\Mastrino;
|
||||
use Modules\PrimaNota\Movimento;
|
||||
|
||||
class Movimenti
|
||||
{
|
||||
protected $fattura;
|
||||
protected $mastrino = null;
|
||||
|
||||
public function __construct(Fattura $fattura)
|
||||
{
|
||||
$this->fattura = $fattura;
|
||||
}
|
||||
|
||||
public function getMastrino()
|
||||
{
|
||||
if (!isset($this->mastrino)) {
|
||||
$this->mastrino = Mastrino::where('iddocumento', $this->fattura->id)
|
||||
->where('primanota', false)
|
||||
->first();
|
||||
}
|
||||
|
||||
return $this->mastrino;
|
||||
}
|
||||
|
||||
public function generateMastrino()
|
||||
{
|
||||
$descrizione = $this->fattura->getReference();
|
||||
$data = $this->fattura->data_competenza;
|
||||
|
||||
$mastrino = Mastrino::build($descrizione, $data, false, false);
|
||||
$mastrino->iddocumento = $this->fattura->id;
|
||||
|
||||
$this->mastrino = $mastrino;
|
||||
|
||||
return $this->mastrino;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra i movimenti relativi alla fattura.
|
||||
*/
|
||||
public function registra()
|
||||
{
|
||||
// Rimozione degli elementi pre-esistenti
|
||||
$this->rimuovi();
|
||||
|
||||
$movimenti = [];
|
||||
|
||||
// Informazioni generali sul documento
|
||||
$direzione = $this->fattura->direzione;
|
||||
$is_acquisto = $direzione == 'uscita';
|
||||
$split_payment = $this->fattura->split_payment;
|
||||
|
||||
// Totali utili per i movimenti
|
||||
$totale = $this->fattura->totale;
|
||||
$iva = $this->fattura->iva;
|
||||
$iva_indetraibile = $this->fattura->iva_indetraibile;
|
||||
$iva_detraibile = $iva - $iva_indetraibile;
|
||||
|
||||
/*
|
||||
* 1) Movimento relativo al conto dell'anagrafica del documento
|
||||
*
|
||||
* Totale (Split Payment disabilitato), oppure Totale - IVA detraibile (Split Payment abilitato) -> DARE per Vendita, AVERE per Acquisto
|
||||
*/
|
||||
$anagrafica = $this->fattura->anagrafica;
|
||||
|
||||
$id_conto = $is_acquisto ? $anagrafica->idconto_fornitore : $anagrafica->idconto_cliente;
|
||||
if (empty($id_conto)) {
|
||||
$id_conto = $is_acquisto ? setting('Conto per Riepilogativo fornitori') : setting('Conto per Riepilogativo clienti');
|
||||
}
|
||||
$id_conto_controparte = $id_conto; // Salvataggio del conto dell'anagrafica per usi successivi
|
||||
|
||||
$importo_anagrafica = $totale;
|
||||
if ($split_payment) {
|
||||
$importo_anagrafica = sum($importo_anagrafica, -$iva_detraibile, 2);
|
||||
}
|
||||
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'dare' => $importo_anagrafica,
|
||||
];
|
||||
|
||||
/*
|
||||
* 2) Movimento per ogni riga del documento
|
||||
* Imponibile -> AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
$righe = $this->fattura->getRighe();
|
||||
foreach ($righe as $riga) {
|
||||
// Retro-compatibilità per versioni <= 2.4
|
||||
$id_conto = $riga->id_conto ?: $this->fattura->idconto;
|
||||
|
||||
$imponibile = $riga->imponibile;
|
||||
if (!empty($imponibile)) {
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'avere' => $riga->imponibile,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 3) IVA detraibile sul relativo conto (Split Payment disabilitato)
|
||||
* IVA detraibile -> AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
if (!empty($iva_detraibile) && empty($split_payment)) {
|
||||
$id_conto = $is_acquisto ? setting('Conto per Iva su acquisti') : setting('Conto per Iva su vendite');
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'avere' => $iva_detraibile,
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* 4) IVA indetraibile sul relativo conto (Split Payment disabilitato)
|
||||
* IVA indetraibile -> AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
if (!empty($iva_indetraibile) && empty($split_payment)) {
|
||||
$id_conto = setting('Conto per Iva indetraibile');
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'avere' => $iva_indetraibile,
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* 5) Rivalsa INPS sul relativo conto
|
||||
* Rivalsa INPS (senza IVA) -> AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
$rivalsa_inps = $this->fattura->rivalsa_inps;
|
||||
if (!empty($rivalsa_inps)) {
|
||||
$id_conto = setting('Conto per Erario c/INPS');
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'avere' => $rivalsa_inps,
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* 6) Ritenuta d'acconto
|
||||
* Conto "Conto per Erario c/ritenute d'acconto": DARE per Vendita, AVERE per Acquisto
|
||||
* Conto della controparte: AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
$ritenuta_acconto = $this->fattura->ritenuta_acconto;
|
||||
if (!empty($ritenuta_acconto)) {
|
||||
$id_conto = setting("Conto per Erario c/ritenute d'acconto");
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'dare' => $ritenuta_acconto,
|
||||
];
|
||||
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto_controparte,
|
||||
'avere' => $ritenuta_acconto,
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* 7) Ritenuta contributi
|
||||
* Conto "Conto per Erario c/enasarco": DARE per Vendita, AVERE per Acquisto
|
||||
* Conto della controparte: AVERE per Vendita, DARE per Acquisto
|
||||
*/
|
||||
$ritenuta_contributi = $this->fattura->totale_ritenuta_contributi;
|
||||
if (!empty($ritenuta_contributi)) {
|
||||
$id_conto = setting('Conto per Erario c/enasarco');
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto,
|
||||
'dare' => $ritenuta_contributi,
|
||||
];
|
||||
|
||||
$movimenti[] = [
|
||||
'id_conto' => $id_conto_controparte,
|
||||
'avere' => $ritenuta_contributi,
|
||||
];
|
||||
}
|
||||
|
||||
// Inversione contabile per i documenti di acquisto
|
||||
if ($is_acquisto) {
|
||||
foreach ($movimenti as $movimento) {
|
||||
$temp = $movimento['avere'];
|
||||
$movimento['avere'] = $movimento['dare'];
|
||||
$movimento['dare'] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Registrazione dei singoli Movimenti nel relativo Mastrino
|
||||
$mastrino = $this->generateMastrino();
|
||||
foreach ($movimenti as $element) {
|
||||
$movimento = Movimento::build($mastrino, $element['id_conto']);
|
||||
$movimento->setTotale($element['avere'] ?: 0, $element['dare'] ?: 0);
|
||||
$movimento->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina i movimenti del mastrino relativo alla fattura.
|
||||
*/
|
||||
public function rimuovi()
|
||||
{
|
||||
$mastrino = $this->getMastrino();
|
||||
|
||||
if (!empty($mastrino)) {
|
||||
$mastrino->delete();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Fatture\Gestori;
|
||||
|
||||
use Modules\Fatture\Fattura;
|
||||
use Modules\Scadenzario\Scadenza;
|
||||
|
||||
class Scadenze
|
||||
{
|
||||
private $fattura;
|
||||
|
||||
public function __construct(Fattura $fattura)
|
||||
{
|
||||
$this->fattura = $fattura;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze della fattura.
|
||||
*
|
||||
* @param bool $is_pagato
|
||||
* @param bool $ignora_fe
|
||||
*/
|
||||
public function registra($is_pagato = false, $ignora_fe = false)
|
||||
{
|
||||
// Rimozione degli elementi pre-esistenti
|
||||
$this->rimuovi();
|
||||
|
||||
if (!$ignora_fe && $this->fattura->module == 'Fatture di acquisto' && $this->fattura->isFE()) {
|
||||
$scadenze_fe = $this->registraScadenzeFE($is_pagato);
|
||||
}
|
||||
|
||||
if (empty($scadenze_fe)) {
|
||||
$this->registraScadenzeTradizionali($is_pagato);
|
||||
}
|
||||
|
||||
$direzione = $this->fattura->tipo->dir;
|
||||
$ritenuta_acconto = $this->fattura->ritenuta_acconto;
|
||||
|
||||
// Se c'è una ritenuta d'acconto, la aggiungo allo scadenzario al 15 del mese dopo l'ultima scadenza di pagamento
|
||||
if ($direzione == 'uscita' && $ritenuta_acconto > 0) {
|
||||
$ultima_scadenza = $this->fattura->scadenze->last();
|
||||
$scadenza = $ultima_scadenza->scadenza->copy()->startOfMonth()->addMonth();
|
||||
$scadenza->setDate($scadenza->year, $scadenza->month, 15);
|
||||
|
||||
$importo = -$ritenuta_acconto;
|
||||
|
||||
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, 'ritenutaacconto');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina le scadenze della fattura.
|
||||
*/
|
||||
public function rimuovi()
|
||||
{
|
||||
database()->delete('co_scadenziario', ['iddocumento' => $this->fattura->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra una specifica scadenza nel database.
|
||||
*
|
||||
* @param float $importo
|
||||
* @param string $data_scadenza
|
||||
* @param bool $is_pagato
|
||||
* @param string $type
|
||||
*/
|
||||
protected function registraScadenza(Fattura $fattura, $importo, $data_scadenza, $is_pagato, $type = 'fattura')
|
||||
{
|
||||
$numero = $fattura->numero_esterno ?: $fattura->numero;
|
||||
$descrizione = $fattura->tipo->descrizione.' numero '.$numero;
|
||||
|
||||
$scadenza = Scadenza::build($descrizione, $importo, $data_scadenza, $type, $is_pagato);
|
||||
|
||||
$scadenza->documento()->associate($fattura);
|
||||
$scadenza->data_emissione = $fattura->data;
|
||||
|
||||
$scadenza->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze della fattura elettronica collegata al documento.
|
||||
*
|
||||
* @param bool $is_pagato
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function registraScadenzeFE($is_pagato = false)
|
||||
{
|
||||
$xml = \Util\XML::read($this->fattura->getXML());
|
||||
|
||||
$pagamenti = $xml['FatturaElettronicaBody']['DatiPagamento']['DettaglioPagamento'];
|
||||
if (!empty($pagamenti)) {
|
||||
$rate = isset($pagamenti[0]) ? $pagamenti : [$pagamenti];
|
||||
|
||||
foreach ($rate as $rata) {
|
||||
$scadenza = $rata['DataScadenzaPagamento'] ?: $this->fattura->data;
|
||||
$importo = ($this->fattura->isNota()) ? $rata['ImportoPagamento'] : -$rata['ImportoPagamento'];
|
||||
|
||||
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato);
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($pagamenti);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra le scadenze tradizionali del gestionale.
|
||||
*
|
||||
* @param bool $is_pagato
|
||||
*/
|
||||
protected function registraScadenzeTradizionali($is_pagato = false)
|
||||
{
|
||||
$rate = $this->fattura->pagamento->calcola($this->fattura->netto, $this->fattura->data);
|
||||
$direzione = $this->fattura->tipo->dir;
|
||||
|
||||
foreach ($rate as $rata) {
|
||||
$scadenza = $rata['scadenza'];
|
||||
$importo = $direzione == 'uscita' ? -$rata['importo'] : $rata['importo'];
|
||||
|
||||
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ if ($res) {
|
|||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "number", "label": "<?php echo tr('Indetraibile'); ?>", "name": "indetraibile", "value": "$indetraibile$", "icon-after": "<i class=\"fa fa-percent\"></i>", "readonly": "<?php echo $is_readonly; ?>", "extra": "<?php echo $attr; ?>", "max-value": "100" ]}
|
||||
{[ "type": "number", "label": "<?php echo tr('Indetraibile'); ?>", "name": "indetraibile", "value": "$indetraibile$", "icon-after": "<i class=\"fa fa-percent\"></i>", "readonly": "<?php echo $is_readonly; ?>", "extra": "<?php echo $attr; ?>", "max-value": "100" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ switch (post('op')) {
|
|||
} else {
|
||||
$duplicate_query = 'SELECT idpianodeiconti2, numero FROM co_pianodeiconti3 WHERE numero='.prepare($numero).' AND NOT id='.prepare($idconto).' AND idpianodeiconti2='.prepare($idpianodeiconti);
|
||||
|
||||
$update_query = 'UPDATE co_pianodeiconti3 SET numero='.prepare($numero).', descrizione='.prepare($descrizione).' WHERE id='.prepare($idconto);
|
||||
$update_query = 'UPDATE co_pianodeiconti3 SET numero='.prepare($numero).', descrizione='.prepare($descrizione).', percentuale_deducibile='.prepare(post('percentuale_deducibile')).' WHERE id='.prepare($idconto);
|
||||
}
|
||||
|
||||
// Controllo che non sia stato usato un numero non valido del conto
|
||||
|
|
|
@ -23,11 +23,16 @@ $info = $dbo->fetchOne($query);
|
|||
<input type="hidden" name="idconto" value="<?php echo $info['id']; ?>">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "text", "label": "<?php echo tr('Numero'); ?>", "name": "numero", "required": 1, "class": "text-center", "value": "<?php echo $info['numero']; ?>", "extra": "maxlength=\"6\"" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-6">
|
||||
{[ "type": "number", "label": "<?php echo tr('Percentuale deducibile'); ?>", "name": "percentuale_deducibile", "value": "<?php echo $info['percentuale_deducibile']; ?>", "disabled": <?php echo intval($lvl == 2); ?>, "icon-after": "<i class=\"fa fa-percent\"></i>", "max-value": "100", "min-value": "0" ]}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "required": 1, "value": <?php echo json_encode($info['descrizione']); ?> ]}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,3 +46,5 @@ $info = $dbo->fetchOne($query);
|
|||
<div class="clearfix"></div>
|
||||
</form>
|
||||
|
||||
<script>$(document).ready(init)</script>
|
||||
|
||||
|
|
|
@ -32,6 +32,11 @@ class Mastrino extends Model
|
|||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rimuove tutti i movimenti collegati al mastrino.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
$movimenti = $this->movimenti;
|
||||
|
@ -44,6 +49,7 @@ class Mastrino extends Model
|
|||
|
||||
public function save(array $options = [])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
|
@ -51,7 +57,7 @@ class Mastrino extends Model
|
|||
$movimenti = $this->cleanup();
|
||||
$this->aggiornaScadenzario($movimenti);
|
||||
|
||||
return parent::delete(); // TODO: Change the autogenerated stub
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
// Attributi
|
||||
|
@ -74,8 +80,13 @@ class Mastrino extends Model
|
|||
|
||||
public function aggiornaScadenzario($movimenti = null)
|
||||
{
|
||||
// Aggiornamento dello scadenzario disponibile solo da Mastrino di PrimaNota
|
||||
if (empty($this->primanota)) {
|
||||
return;
|
||||
}
|
||||
$movimenti = $movimenti ?: $this->movimenti;
|
||||
|
||||
// Aggiornamento delle scadenze per i singoli documenti
|
||||
$documenti = [];
|
||||
$scadenze = [];
|
||||
foreach ($movimenti as $movimento) {
|
||||
|
@ -123,7 +134,28 @@ class Mastrino extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function correggiScadenza(Movimento $movimento, Scadenza $scadenza = null, Fattura $documento = null)
|
||||
// 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;
|
||||
}
|
||||
|
||||
protected function correggiScadenza(Movimento $movimento, Scadenza $scadenza = null, Fattura $documento = null)
|
||||
{
|
||||
$documento = $documento ?: $scadenza->documento;
|
||||
if ($documento) {
|
||||
|
@ -184,25 +216,4 @@ class Mastrino extends Model
|
|||
$scadenza->save();
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,13 @@ class Movimento extends Model
|
|||
$model->primanota = $mastrino->primanota;
|
||||
$model->is_insoluto = $mastrino->is_insoluto;
|
||||
|
||||
$model->id_scadenza = $scadenza ? $scadenza->id : null;
|
||||
// Associazione al documento del mastrino
|
||||
if (!empty($mastrino->iddocumento)) {
|
||||
$model->iddocumento = $mastrino->iddocumento;
|
||||
}
|
||||
|
||||
// Associazione alla scadenza indicata
|
||||
$model->id_scadenza = $scadenza ? $scadenza->id : null;
|
||||
$documento = $scadenza ? $scadenza->documento : null;
|
||||
if (!empty($documento)) {
|
||||
$model->iddocumento = $documento->id;
|
||||
|
@ -52,6 +57,16 @@ class Movimento extends Model
|
|||
$this->totale = $totale;
|
||||
}
|
||||
|
||||
public function save(array $options = [])
|
||||
{
|
||||
// Aggiornamento automatico di totale_reddito
|
||||
$conto = database()->fetchOne('SELECT * FROM co_pianodeiconti3 WHERE id = '.prepare($this->id_conto));
|
||||
$percentuale = floatval($conto['percentuale_deducibile']);
|
||||
$this->totale_reddito = $this->totale * $percentuale / 100;
|
||||
|
||||
return parent::save($options);
|
||||
}
|
||||
|
||||
// Attributi
|
||||
|
||||
public function getIdContoAttribute()
|
||||
|
|
|
@ -227,3 +227,7 @@ UPDATE `my_impianto_componenti` SET `data_sostituzione` = NULL WHERE `data_sosti
|
|||
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`) VALUES
|
||||
(NULL, 'Mostra promemoria attività ai soli Tecnici assegnati', '1', 'boolean', '1', 'Attività', 14),
|
||||
(NULL, 'Espandi automaticamente la sezione "Dettagli aggiuntivi"', '0', 'boolean', '1', 'Attività', 15);
|
||||
|
||||
-- Modifica per introdurre il totale reddito per i Movimenti, sulla base del Conto relativo
|
||||
ALTER TABLE `co_movimenti` ADD `totale_reddito` decimal(12, 6) NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `co_pianodeiconti3` ADD `percentuale_deducibile` decimal(5,2) NOT NULL DEFAULT 0;
|
||||
|
|
Loading…
Reference in New Issue