Introduzione Totale reddito per i Movimenti

This commit is contained in:
Thomas Zilio 2020-08-05 17:58:54 +02:00
parent a1009c52a2
commit 8e4e6951cf
11 changed files with 538 additions and 199 deletions

View File

@ -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)
{

View File

@ -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
/**

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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()

View File

@ -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;