Supporto ai Preventivi tramite Eloquent

This commit is contained in:
Thomas Zilio 2019-01-01 11:39:20 +01:00
parent ad1a90da9a
commit 2799d5cab1
34 changed files with 570 additions and 404 deletions

View File

@ -7,6 +7,7 @@ return [
'modules/ddt' => 'Modules\DDT',
'modules/fatture' => 'Modules\Fatture',
'modules/ordini' => 'Modules\Ordini',
'modules/preventivi' => 'Modules\Preventivi',
'modules/interventi' => 'Modules\Interventi',
'plugins/exportFE' => 'Plugins\ExportFE',
'plugins/importFE' => 'Plugins\ImportFE',

View File

@ -207,17 +207,13 @@ switch (post('op')) {
$idpagamento = post('idpagamento');
$idconto = post('idconto');
$idordine = post('idordine');
$numero = get_new_numeroddt($data);
if ($dir == 'entrata') {
$numero_esterno = get_new_numerosecondarioddt($data);
} else {
$numero_esterno = '';
}
// Creazione DDT
$anagrafica = Anagrafica::find($idanagrafica);
$tipo = Tipo::where('dir', $dir)->first();
// Creazione nuovo ddt
$dbo->query('INSERT INTO dt_ddt( numero, numero_esterno, data, idanagrafica, idtipoddt, idstatoddt, idpagamento, idconto) VALUES('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($data).', '.prepare($idanagrafica).', (SELECT id FROM dt_tipiddt WHERE dir='.prepare($dir)."), (SELECT id FROM dt_statiddt WHERE descrizione='Bozza'), ".prepare($idpagamento).', '.prepare($idconto).')');
$id_record = $dbo->lastInsertedID();
$ddt = DDT::make($anagrafica, $tipo, $data);
$id_record = $ddt->id;
// Lettura di tutte le righe della tabella in arrivo
foreach (post('qta_da_evadere') as $idriga => $value) {

View File

@ -3,6 +3,8 @@
include_once __DIR__.'/../../core.php';
if (isset($id_record)) {
$ddt = Modules\DDT\DDT::with('tipo', 'stato')->find($id_record);
$record = $dbo->fetchOne('SELECT *, dt_ddt.note, dt_ddt.idpagamento, dt_ddt.id AS idddt, dt_statiddt.descrizione AS `stato`, dt_tipiddt.descrizione AS `descrizione_tipodoc`,
(SELECT completato FROM dt_statiddt WHERE dt_statiddt.id=dt_ddt.idstatoddt) AS flag_completato
FROM dt_ddt

View File

@ -2,49 +2,90 @@
include_once __DIR__.'/../../core.php';
use Modules\DDT\DDT;
/**
* Funzione per generare un nuovo numero per il ddt.
*
* @deprecated 2.4.5
*/
function get_new_numeroddt($data)
{
global $dir;
$dbo = database();
$query = "SELECT IFNULL(MAX(numero),'0') AS max_numeroddt FROM dt_ddt WHERE DATE_FORMAT( data, '%Y' ) = '".date('Y', strtotime($data))."' AND idtipoddt IN(SELECT id FROM dt_tipiddt WHERE dir='".$dir."') ORDER BY CAST(numero AS UNSIGNED) DESC LIMIT 0,1";
$rs = $dbo->fetchArray($query);
return intval($rs[0]['max_numeroddt']) + 1;
return DDT::getNextNumero($data, $dir);
}
/**
* Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni.
*
* @deprecated 2.4.5
*/
function get_new_numerosecondarioddt($data)
{
global $dir;
$dbo = database();
return DDT::getNextNumeroSecondario($data, $dir);
}
// Calcolo il numero secondario se stabilito dalle impostazioni e se documento di vendita
$formato_numero_secondario = setting('Formato numero secondario ddt');
/**
* Calcolo imponibile ddt (totale_righe - sconto).
*
* @deprecated 2.4.5
*/
function get_imponibile_ddt($id_ddt)
{
$ddt = DDT::find($id_ddt);
$query = "SELECT numero_esterno FROM dt_ddt WHERE DATE_FORMAT( data, '%Y' ) = '".date('Y', strtotime($data))."' AND idtipoddt IN(SELECT id FROM dt_tipiddt WHERE dir='".$dir."') ORDER BY CAST(numero_esterno AS UNSIGNED) DESC LIMIT 0,1";
return $ddt->imponibile;
}
$rs = $dbo->fetchArray($query);
$numero_secondario = $rs[0]['numero_esterno'];
/**
* Calcolo totale ddt (imponibile + iva).
*
* @deprecated 2.4.5
*/
function get_totale_ddt($id_ddt)
{
$ddt = DDT::find($id_ddt);
if ($numero_secondario == '') {
$numero_secondario = $formato_numero_secondario;
}
return $ddt->totale;
}
if ($formato_numero_secondario != '' && $dir == 'entrata') {
$numero_esterno = Util\Generator::generate($formato_numero_secondario, $numero_secondario);
} else {
$numero_esterno = '';
}
/**
* Calcolo netto a pagare ddt (totale - ritenute - bolli).
*
* @deprecated 2.4.5
*/
function get_netto_ddt($id_ddt)
{
$ddt = DDT::find($id_ddt);
return $numero_esterno;
return $ddt->netto;
}
/**
* Calcolo iva detraibile ddt.
*
* @deprecated 2.4.5
*/
function get_ivadetraibile_ddt($id_ddt)
{
$ddt = DDT::find($id_ddt);
return $ddt->iva_detraibile;
}
/**
* Calcolo iva indetraibile ddt.
*
* @deprecated 2.4.5
*/
function get_ivaindetraibile_ddt($id_ddt)
{
$ddt = DDT::find($id_ddt);
return $ddt->iva_indetraibile;
}
/**
@ -110,76 +151,6 @@ function rimuovi_articolo_daddt($idarticolo, $idddt, $idrigaddt)
return true;
}
/**
* Calcolo imponibile ddt (totale_righe - sconto).
*/
function get_imponibile_ddt($idddt)
{
$dbo = database();
$query = 'SELECT SUM(subtotale-sconto) AS imponibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='.prepare($idddt);
$rs = $dbo->fetchArray($query);
return $rs[0]['imponibile'];
}
/**
* Calcolo totale ddt (imponibile + iva).
*/
function get_totale_ddt($idddt)
{
$dbo = database();
// Sommo l'iva di ogni riga al totale
$query = 'SELECT SUM(iva) AS iva FROM dt_righe_ddt GROUP BY idddt HAVING idddt='.prepare($idddt);
$rs = $dbo->fetchArray($query);
// Aggiungo la rivalsa inps se c'è
$query2 = 'SELECT rivalsainps FROM dt_ddt WHERE id='.prepare($idddt);
$rs2 = $dbo->fetchArray($query2);
return get_imponibile_ddt($idddt) + $rs[0]['iva'] + $rs2[0]['rivalsainps'];
}
/**
* Calcolo netto a pagare ddt (totale - ritenute - bolli).
*/
function get_netto_ddt($idddt)
{
$dbo = database();
$query = 'SELECT ritenutaacconto,bollo FROM dt_ddt WHERE id='.prepare($idddt);
$rs = $dbo->fetchArray($query);
return get_totale_ddt($idddt) - $rs[0]['ritenutaacconto'] + $rs[0]['bollo'];
}
/**
* Calcolo iva detraibile ddt.
*/
function get_ivadetraibile_ddt($idddt)
{
$dbo = database();
$query = 'SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='.prepare($idddt);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_detraibile'];
}
/**
* Calcolo iva indetraibile ddt.
*/
function get_ivaindetraibile_ddt($idddt)
{
$dbo = database();
$query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='.prepare($idddt);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_indetraibile'];
}
/**
* Ricalcola i costi aggiuntivi in ddt (rivalsa inps, ritenuta d'acconto, marca da bollo)
* Deve essere eseguito ogni volta che si aggiunge o toglie una riga

View File

@ -20,15 +20,4 @@ trait RelationTrait
{
return $this->parent();
}
public function getNettoAttribute()
{
$result = parent::getNettoAttribute();
if ($this->parent->split_payment) {
$result = $result - $this->iva;
}
return $result;
}
}

View File

@ -41,7 +41,7 @@ class DDT extends Document
// Tipo di pagamento e banca predefinite dall'anagrafica
$id_pagamento = $database->fetchOne('SELECT id FROM co_pagamenti WHERE id = :id_pagamento', [
':id_pagamento' => $anagrafica['id_pagamento'.$conto],
':id_pagamento' => $anagrafica['idpagamento_'.$conto],
])['id'];
// Se il ddt è un ddt cliente e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni

View File

@ -8,7 +8,7 @@ class Stato extends Model
{
protected $table = 'dt_statiddt';
public function fatture()
public function ddt()
{
return $this->hasMany(DDT::class, 'idstatoddt');
}

View File

@ -8,7 +8,7 @@ class Tipo extends Model
{
protected $table = 'dt_tipiddt';
public function fatture()
public function ddt()
{
return $this->hasMany(DDT::class, 'idtipoddt');
}

View File

@ -4,6 +4,8 @@ use Modules\Fatture\Fattura;
/**
* Funzione per generare un nuovo numero per la fattura.
*
* @deprecated 2.4.5
*/
function get_new_numerofattura($data)
{
@ -15,6 +17,8 @@ function get_new_numerofattura($data)
/**
* Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni.
*
* @deprecated 2.4.5
*/
function get_new_numerosecondariofattura($data)
{
@ -24,6 +28,66 @@ function get_new_numerosecondariofattura($data)
return Fattura::getNextNumeroSecondario($data, $dir, $id_segment);
}
/**
* Calcolo imponibile fattura (totale_righe - sconto).
*
* @deprecated 2.4.5
*/
function get_imponibile_fattura($iddocumento)
{
$fattura = Fattura::find($iddocumento);
return $fattura->imponibile;
}
/**
* Calcolo totale fattura (imponibile + iva).
*
* @deprecated 2.4.5
*/
function get_totale_fattura($iddocumento)
{
$fattura = Fattura::find($iddocumento);
return $fattura->totale;
}
/**
* Calcolo netto a pagare fattura (totale - ritenute - bolli).
*
* @deprecated 2.4.5
*/
function get_netto_fattura($iddocumento)
{
$fattura = Fattura::find($iddocumento);
return $fattura->netto;
}
/**
* Calcolo iva detraibile fattura.
*
* @deprecated 2.4.5
*/
function get_ivadetraibile_fattura($iddocumento)
{
$fattura = Fattura::find($iddocumento);
return $fattura->iva_detraibile;
}
/**
* Calcolo iva indetraibile fattura.
*
* @deprecated 2.4.5
*/
function get_ivaindetraibile_fattura($iddocumento)
{
$fattura = Fattura::find($iddocumento);
return $fattura->iva_indetraibile;
}
/**
* Elimina una scadenza in base al codice documento.
*/
@ -435,105 +499,6 @@ function get_new_idmastrino($table = 'co_movimenti')
return intval($rs[0]['maxidmastrino']) + 1;
}
/**
* Calcolo imponibile fattura (totale_righe - sconto).
*/
function get_imponibile_fattura($iddocumento)
{
$dbo = database();
$query = 'SELECT SUM(co_righe_documenti.subtotale - co_righe_documenti.sconto) AS imponibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento);
$rs = $dbo->fetchArray($query);
return sum($rs[0]['imponibile'], null, 2);
}
/**
* Calcolo totale fattura (imponibile + iva).
*/
function get_totale_fattura($iddocumento)
{
$dbo = database();
// Sommo l'iva di ogni riga al totale
$query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento);
$rs = $dbo->fetchArray($query);
// Aggiungo la rivalsa inps se c'è
$query2 = 'SELECT rivalsainps FROM co_documenti WHERE id='.prepare($iddocumento);
$rs2 = $dbo->fetchArray($query2);
$iva_rivalsainps = 0;
$rsr = $dbo->fetchArray('SELECT idiva, rivalsainps FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento));
for ($r = 0; $r < sizeof($rsr); ++$r) {
$qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare($rsr[$r]['idiva']);
$rsi = $dbo->fetchArray($qi);
$iva_rivalsainps += $rsr[$r]['rivalsainps'] / 100 * $rsi[0]['percentuale'];
}
$iva = $rs[0]['iva'];
$totale_iva = sum($iva, $iva_rivalsainps);
$totale = sum([
get_imponibile_fattura($iddocumento),
$rs2[0]['rivalsainps'],
$totale_iva,
], null, 2);
return $totale;
}
/**
* Calcolo netto a pagare fattura (totale - ritenute - bolli).
*/
function get_netto_fattura($iddocumento)
{
$dbo = database();
$query = 'SELECT ritenutaacconto, bollo, split_payment FROM co_documenti WHERE id='.prepare($iddocumento);
$rs = $dbo->fetchArray($query);
$netto_a_pagare = sum([
get_totale_fattura($iddocumento),
$rs[0]['bollo'],
-$rs[0]['ritenutaacconto'],
], null, 2);
if ($rs[0]['split_payment']) {
$netto_a_pagare = sum($netto_a_pagare, -(get_ivadetraibile_fattura($iddocumento) + get_ivaindetraibile_fattura($iddocumento)), 2);
}
return $netto_a_pagare;
}
/**
* Calcolo iva detraibile fattura.
*/
function get_ivadetraibile_fattura($iddocumento)
{
$dbo = database();
$query = 'SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_detraibile'];
}
/**
* Calcolo iva indetraibile fattura.
*/
function get_ivaindetraibile_fattura($iddocumento)
{
$dbo = database();
$query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_indetraibile'];
}
/**
* 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

View File

@ -2,12 +2,11 @@
include_once __DIR__.'/../../core.php';
use Modules\Fatture\Articolo;
use Modules\Fatture\Descrizione;
use Modules\Fatture\Riga;
use Modules\Fatture\Components\Articolo;
use Modules\Fatture\Components\Descrizione;
use Modules\Fatture\Components\Riga;
// Righe fattura
//$rs = $dbo->fetchArray('SELECT *, round(sconto_unitario,'.setting('Cifre decimali per importi').') AS sconto_unitario, round(sconto,'.setting('Cifre decimali per importi').') AS sconto, round(subtotale,'.setting('Cifre decimali per importi').') AS subtotale, IFNULL((SELECT codice FROM mg_articoli WHERE id=idarticolo),"") AS codice, (SELECT descrizione FROM co_pianodeiconti3 WHERE co_pianodeiconti3.id=IF(co_righe_documenti.idconto = 0, (SELECT idconto FROM co_documenti WHERE iddocumento='.prepare($id_record).' LIMIT 1), co_righe_documenti.idconto)) AS descrizione_conto FROM `co_righe_documenti` WHERE iddocumento='.prepare($id_record).' ORDER BY `order`');
$righe = $fattura->getRighe();
echo '

View File

@ -53,7 +53,7 @@ class Fattura extends Document
// Tipo di pagamento e banca predefinite dall'anagrafica
$id_pagamento = $database->fetchOne('SELECT id FROM co_pagamenti WHERE id = :id_pagamento', [
':id_pagamento' => $anagrafica['id_pagamento'.$conto],
':id_pagamento' => $anagrafica['idpagamento_'.$conto],
])['id'];
$id_banca = $anagrafica['idbanca_'.$conto];

View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Interventi;
use Common\Model;
class Stato extends Model
{
protected $table = 'in_statiintervento';
public function interventi()
{
return $this->hasMany(Ordine::class, 'idstatointervento');
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Modules\Interventi;
use Common\Model;
class TipoSessione extends Model
{
protected $table = 'in_tipiintervento';
protected $primaryKey = 'idtipointervento';
}

View File

@ -3,6 +3,8 @@
include_once __DIR__.'/../../core.php';
if (isset($id_record)) {
$ordine = Modules\Ordini\Ordine::with('tipo', 'stato')->find($id_record);
// Aggiornamento stato di questo ordine (?)
if (!empty(get_stato_ordine($id_record)) && setting('Cambia automaticamente stato ordini fatturati')) {
$dbo->query('UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($id_record).'") WHERE id='.prepare($id_record));

View File

@ -2,120 +2,90 @@
include_once __DIR__.'/../../core.php';
use Modules\Ordini\Ordine;
/**
* Funzione per generare un nuovo numero per la fattura.
*
* @deprecated 2.4.5
*/
function get_new_numeroordine($data)
{
global $dir;
$dbo = database();
$query = "SELECT numero AS max_numeroordine FROM or_ordini WHERE DATE_FORMAT( data, '%Y' ) = ".prepare(date('Y', strtotime($data))).' AND idtipoordine IN(SELECT id FROM or_tipiordine WHERE dir='.prepare($dir).') ORDER BY CAST(numero AS UNSIGNED) DESC LIMIT 0,1';
$rs = $dbo->fetchArray($query);
$numero = $rs[0]['max_numeroordine'] + 1;
return $numero;
return Ordine::getNextNumero($data, $dir);
}
/**
* Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni.
*
* @deprecated 2.4.5
*/
function get_new_numerosecondarioordine($data)
{
global $dir;
$dbo = database();
// Calcolo il numero secondario se stabilito dalle impostazioni e se documento di vendita
$formato_numero_secondario = setting('Formato numero secondario ordine');
$formato_numero_secondario = str_replace('#', '%', $formato_numero_secondario);
$query = 'SELECT numero_esterno FROM or_ordini WHERE DATE_FORMAT( data, "%Y" ) = '.prepare(date('Y', strtotime($data))).' AND idtipoordine IN(SELECT id FROM or_tipiordine WHERE dir='.prepare($dir).') AND numero_esterno LIKE('.prepare(Util\Generator::complete($formato_numero_secondario)).') ORDER BY CAST(numero AS UNSIGNED) DESC LIMIT 0,1';
$rs = $dbo->fetchArray($query);
$numero_secondario = $rs[0]['numero_esterno'];
if ($numero_secondario == '') {
$numero_secondario = setting('Formato numero secondario ordine');
}
if ($formato_numero_secondario != '' && $dir == 'entrata') {
$numero_esterno = Util\Generator::generate(setting('Formato numero secondario ordine'), $numero_secondario);
} else {
$numero_esterno = '';
}
return $numero_esterno;
return Ordine::getNextNumeroSecondario($data, $dir);
}
/**
* Calcolo imponibile ordine (totale_righe - sconto).
*
* @deprecated 2.4.5
*/
function get_imponibile_ordine($idordine)
{
$dbo = database();
$ordine = Ordine::find($idordine);
$query = 'SELECT SUM(subtotale-sconto) AS imponibile FROM or_righe_ordini GROUP BY idordine HAVING idordine='.prepare($idordine);
$rs = $dbo->fetchArray($query);
return $rs[0]['imponibile'];
return $ordine->imponibile;
}
/**
* Calcolo totale ordine (imponibile + iva).
*
* @deprecated 2.4.5
*/
function get_totale_ordine($idordine)
{
$dbo = database();
$ordine = Ordine::find($idordine);
// Sommo l'iva di ogni riga al totale
$query = 'SELECT SUM(iva) AS iva FROM or_righe_ordini GROUP BY idordine HAVING idordine='.prepare($idordine);
$rs = $dbo->fetchArray($query);
// Aggiungo la rivalsa inps se c'è
$query2 = 'SELECT rivalsainps FROM or_ordini WHERE id='.prepare($idordine);
$rs2 = $dbo->fetchArray($query2);
return get_imponibile_ordine($idordine) + $rs[0]['iva'] + $rs2[0]['rivalsainps'];
return $ordine->totale;
}
/**
* Calcolo netto a pagare ordine (totale - iva).
* Calcolo netto a pagare ordine (totale - ritenute - bolli).
*
* @deprecated 2.4.5
*/
function get_netto_ordine($idordine)
{
$dbo = database();
$ordine = Ordine::find($idordine);
$query = 'SELECT ritenutaacconto,bollo FROM or_ordini WHERE id='.prepare($idordine);
$rs = $dbo->fetchArray($query);
return get_totale_ordine($idordine) - $rs[0]['ritenutaacconto'] + $rs[0]['bollo'];
return $ordine->netto;
}
/**
* Calcolo iva detraibile ordine.
*
* @deprecated 2.4.5
*/
function get_ivadetraibile_ordine($idordine)
{
$dbo = database();
$ordine = Ordine::find($idordine);
$query = 'SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM or_righe_ordini GROUP BY idordine HAVING idordine='.prepare($idordine);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_detraibile'];
return $ordine->iva_detraibile;
}
/**
* Calcolo iva indetraibile ordine.
*
* @deprecated 2.4.5
*/
function get_ivaindetraibile_ordine($idordine)
{
$dbo = database();
$ordine = Ordine::find($idordine);
$query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM or_righe_ordini GROUP BY idordine HAVING idordine='.prepare($idordine);
$rs = $dbo->fetchArray($query);
return $rs[0]['iva_indetraibile'];
return $ordine->iva_indetraibile;
}
/**

View File

@ -10,7 +10,7 @@ class Articolo extends Article
{
use RelationTrait;
protected $table = 'or_righe_ordine';
protected $table = 'or_righe_ordini';
/**
* Crea un nuovo articolo collegato ad una ordine.

View File

@ -9,7 +9,7 @@ class Descrizione extends Description
{
use RelationTrait;
protected $table = 'or_righe_ordine';
protected $table = 'or_righe_ordini';
/**
* Crea una nuova riga collegata ad una ordine.

View File

@ -20,15 +20,4 @@ trait RelationTrait
{
return $this->parent();
}
public function getNettoAttribute()
{
$result = parent::getNettoAttribute();
if ($this->parent->split_payment) {
$result = $result - $this->iva;
}
return $result;
}
}

View File

@ -9,7 +9,7 @@ class Riga extends Row
{
use RelationTrait;
protected $table = 'or_righe_ordine';
protected $table = 'or_righe_ordini';
/**
* Crea una nuova riga collegata ad una ordine.

View File

@ -9,7 +9,7 @@ class Sconto extends Discount
{
use RelationTrait;
protected $table = 'or_righe_ordine';
protected $table = 'or_righe_ordini';
/**
* Crea una nuovo sconto globale collegato alla ordine, oppure restituisce quello esistente.

View File

@ -41,7 +41,7 @@ class Ordine extends Document
// Tipo di pagamento e banca predefinite dall'anagrafica
$id_pagamento = $database->fetchOne('SELECT id FROM co_pagamenti WHERE id = :id_pagamento', [
':id_pagamento' => $anagrafica['id_pagamento'.$conto],
':id_pagamento' => $anagrafica['idpagamento_'.$conto],
])['id'];
// Se il ordine è un ordine cliente e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni
@ -85,7 +85,7 @@ class Ordine extends Document
// Aggiornamento sconto
aggiorna_sconto([
'parent' => 'or_ordini',
'row' => 'or_righe_ordine',
'row' => 'or_righe_ordini',
], [
'parent' => 'id',
'row' => 'idordine',

View File

@ -8,7 +8,7 @@ class Stato extends Model
{
protected $table = 'or_statiordine';
public function fatture()
public function ordini()
{
return $this->hasMany(Ordine::class, 'idstatoordine');
}

View File

@ -8,7 +8,7 @@ class Tipo extends Model
{
protected $table = 'or_tipiordine';
public function fatture()
public function ordini()
{
return $this->hasMany(Ordine::class, 'idtipoordine');
}

View File

@ -2,64 +2,25 @@
include_once __DIR__.'/../../core.php';
use Modules\Anagrafiche\Anagrafica;
use Modules\Articoli\Articolo as ArticoloOriginale;
use Modules\Preventivi\Components\Articolo;
use Modules\Preventivi\Components\Descrizione;
use Modules\Preventivi\Components\Riga;
use Modules\Preventivi\Preventivo;
use Modules\Interventi\TipoSessione as TipoIntervento;
switch (post('op')) {
case 'add':
$idanagrafica = post('idanagrafica');
$nome = post('nome');
$idtipointervento = post('idtipointervento');
$rs = $dbo->fetchArray('SELECT costo_orario, costo_diritto_chiamata FROM in_tipiintervento WHERE idtipointervento='.prepare($idtipointervento));
$costo_orario = $rs[0]['costo_orario'];
$costo_diritto_chiamata = $rs[0]['costo_diritto_chiamata'];
// Verifico se c'è già un agente o un metodo di pagamento collegato all'anagrafica cliente, così lo imposto già
$q = 'SELECT idagente, idpagamento_vendite AS idpagamento FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica);
$rs = $dbo->fetchArray($q);
$idagente = $rs[0]['idagente'];
$idpagamento = $rs[0]['idpagamento'];
$anagrafica = Anagrafica::find($idanagrafica);
$tipo = TipoIntervento::find($idtipointervento);
// Codice preventivo: calcolo il successivo in base al formato specificato
$numeropreventivo_template = setting('Formato codice preventivi');
$numeropreventivo_template = str_replace('#', '%', $numeropreventivo_template);
// Codice preventivo: calcolo il successivo in base al formato specificato
$rs = $dbo->fetchArray('SELECT numero FROM co_preventivi WHERE numero=(SELECT MAX(CAST(numero AS SIGNED)) FROM co_preventivi) AND numero LIKE('.prepare(Util\Generator::complete($numeropreventivo_template)).') ORDER BY numero DESC LIMIT 0,1');
$numero = Util\Generator::generate(setting('Formato codice preventivi'), $rs[0]['numero']);
if (!is_numeric($numero)) {
$rs = $dbo->fetchArray('SELECT numero FROM co_preventivi WHERE numero LIKE('.prepare(Util\Generator::complete($numeropreventivo_template)).') ORDER BY numero DESC LIMIT 0,1');
$numero = Util\Generator::generate(setting('Formato codice preventivi'), $rs[0]['numero']);
}
$idiva = setting('Iva predefinita');
$rs_iva = $dbo->fetchArray('SELECT descrizione, percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva));
// Se al preventivo non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni
if ($idpagamento == '') {
$idpagamento = setting('Tipo di pagamento predefinito');
}
$dbo->query('INSERT INTO co_preventivi(idanagrafica, nome, numero, idagente, idstato, idtipointervento, data_bozza, data_conclusione, idiva, idpagamento) VALUES ('.prepare($idanagrafica).', '.prepare($nome).', '.prepare($numero).', '.prepare($idagente).", (SELECT `id` FROM `co_statipreventivi` WHERE `descrizione`='Bozza'), ".prepare($idtipointervento).', NOW(), DATE_ADD(NOW(), INTERVAL +1 MONTH), '.prepare($idiva).', '.prepare($idpagamento).')');
$id_record = $dbo->lastInsertedID();
//Aggiungo master_revision e default_revision
$dbo->query('UPDATE co_preventivi SET master_revision='.prepare($id_record).', default_revision=1 WHERE id='.$id_record);
/*
// inserisco righe standard preventivo
// ore lavoro
$costo = $costo_orario;
$iva = $costo / 100 * $rs_iva[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs_iva[0]['indetraibile'];
$ore = $dbo->fetchArray("SELECT `id` FROM `mg_unitamisura` WHERE `valore`='ore'");
$dbo->query('INSERT INTO co_righe_preventivi(idpreventivo, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, `order`) VALUES ('.prepare($id_record).", '0', ".prepare($idiva).', '.prepare($rs_iva[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).", 'Ore lavoro', ".prepare($costo).', '.prepare('ore').", 1, 0, 0, 'UNT', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_preventivi AS t WHERE idpreventivo=".prepare($id_record).'))');
// diritto chiamata
$costo = $costo_diritto_chiamata;
$iva = $costo / 100 * $rs_iva[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs_iva[0]['indetraibile'];
$dbo->query('INSERT INTO co_righe_preventivi(idpreventivo, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, `order`) VALUES ('.prepare($id_record).", '0', ".prepare($idiva).', '.prepare($rs_iva[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).", 'Diritto chiamata', ".prepare($costo).", '', 1, 0, 0, 'UNT', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_preventivi AS t WHERE idpreventivo=".prepare($id_record).'))');
*/
$preventivo = Preventivo::make($anagrafica, $tipo, $nome);
$id_record = $preventivo->id;
flash()->info(tr('Aggiunto preventivo numero _NUM_!', [
'_NUM_' => $numero,

View File

@ -3,5 +3,7 @@
include_once __DIR__.'/../../core.php';
if (isset($id_record)) {
$preventivo = Modules\Preventivi\Preventivo::with('stato')->find($id_record);
$record = $dbo->fetchOne('SELECT *, (SELECT descrizione FROM co_statipreventivi WHERE id=idstato) AS stato FROM co_preventivi WHERE id='.prepare($id_record).Modules::getAdditionalsQuery($id_module));
}

View File

@ -2,6 +2,8 @@
include_once __DIR__.'/../../core.php';
use Modules\Preventivi\Preventivo;
/**
* Questa funzione rimuove un articolo dal ddt data e lo riporta in magazzino
* $idarticolo integer codice dell'articolo da scollegare dall'ordine
@ -99,12 +101,9 @@ function ricalcola_costiagg_preventivo($idpreventivo, $idrivalsainps = '', $idri
function get_imponibile_preventivo($idpreventivo)
{
$dbo = database();
$preventivo = Preventivo::find($idpreventivo);
$query = 'SELECT SUM(co_righe_preventivi.subtotale - co_righe_preventivi.sconto) AS imponibile FROM co_righe_preventivi GROUP BY idpreventivo HAVING idpreventivo='.prepare($idpreventivo);
$rs = $dbo->fetchArray($query);
return isset($rs[0]['imponibile']) ? $rs[0]['imponibile'] : 0;
return $preventivo->imponibile;
}
/**

View File

@ -15,11 +15,9 @@ echo '
<th>'.tr('Descrizione').'</th>
<th width="120">'.tr('Q.').'</th>
<th width="80">'.tr('U.m.').'</th>
<th width="150">'.tr('Prezzo acq. unitario').'</th>
<th width="160">'.tr('Prezzo vend. unitario').'</th>
<th width="160">'.tr('Prezzo unitario').'</th>
<th width="120">'.tr('Iva').'</th>
<th width="120">'.tr('Imponibile').'</th>
<th width="120">'.tr('Guadagno').'</th>
<th width="60"></th>
</tr>
</thead>
@ -60,15 +58,6 @@ foreach ($rs as $r) {
echo '
</td>';
// Prezzo di acquisto unitario
echo '
<td class="text-right">';
if (empty($r['is_descrizione'])) {
echo '
'.Translator::numberToLocale($r['prezzo_unitario_acquisto']).' &euro;';
}
// prezzo di vendita unitario
echo '
<td class="text-right">';
@ -107,22 +96,6 @@ foreach ($rs as $r) {
'.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;';
}
// Guadagno
$guadagno = $r['subtotale'] - ($r['prezzo_unitario_acquisto'] * $r['qta']) - ($r['sconto_unitario'] * $r['qta']);
if ($guadagno < 0) {
$guadagno_style = 'background-color: #FFC6C6; border: 3px solid red';
} else {
$guadagno_style = '';
}
echo '
<td class="text-right" style="'.$guadagno_style.'">';
if (empty($r['is_descrizione'])) {
echo '
'.Translator::numberToLocale($guadagno).' &euro;';
}
echo '
</td>';
// Possibilità di rimuovere una riga solo se il preventivo non è stato pagato
echo '
<td class="text-center">';
@ -181,7 +154,7 @@ echo '
if (abs($sconto) > 0) {
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('Imponibile', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -192,7 +165,7 @@ if (abs($sconto) > 0) {
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('Sconto', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -204,7 +177,7 @@ if (abs($sconto) > 0) {
// Totale imponibile
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('Imponibile scontato', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -216,7 +189,7 @@ if (abs($sconto) > 0) {
// Totale imponibile
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('Imponibile', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -229,7 +202,7 @@ if (abs($sconto) > 0) {
// Totale iva
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('IVA', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -241,7 +214,7 @@ echo '
// Totale preventivo
echo '
<tr>
<td colspan="7" class="text-right">
<td colspan="5" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
</td>
<td align="right">
@ -250,23 +223,6 @@ echo '
<td></td>
</tr>';
// GUADAGNO TOTALE
if ($totale_guadagno < 0) {
$guadagno_style = 'background-color: #FFC6C6; border: 3px solid red';
} else {
$guadagno_style = '';
}
echo '
<tr>
<td colspan="7" class="text-right">
<b>'.tr('Guadagno totale', [], ['upper' => true]).':</b>
</td>
<td align="right" style="'.$guadagno_style.'">
'.Translator::numberToLocale($totale_guadagno).' &euro;
</td>
<td></td>
</tr>';
echo '
</table>';
@ -286,7 +242,7 @@ $(document).ready(function(){
order += ","+$(this).data("id");
});
order = order.replace(/^,/, "");
$.post("'.$rootdir.'/actions.php", {
id: ui.item.data("id"),
id_module: '.$id_module.',

View File

@ -0,0 +1,58 @@
<?php
namespace Modules\Preventivi\Components;
use Common\Components\Article;
use Modules\Articoli\Articolo as Original;
use Modules\Preventivi\Preventivo;
class Articolo extends Article
{
use RelationTrait;
protected $table = 'co_righe_preventivi';
/**
* Crea un nuovo articolo collegato ad una preventivo.
*
* @param Preventivo $preventivo
* @param Original $articolo
*
* @return self
*/
public static function make(Preventivo $preventivo, Original $articolo)
{
$model = parent::make($preventivo, $articolo);
return $model;
}
public function movimenta($qta)
{
$preventivo = $this->preventivo;
$tipo = $preventivo->tipo;
$numero = $preventivo->numero_esterno ?: $preventivo->numero;
$data = $preventivo->data;
$carico = ($tipo->dir == 'entrata') ? tr('Ripristino articolo da _TYPE_ _NUM_') : tr('Carico magazzino da _TYPE_ numero _NUM_');
$scarico = ($tipo->dir == 'entrata') ? tr('Scarico magazzino per _TYPE_ numero _NUM_') : tr('Rimozione articolo da _TYPE_ _NUM_');
$qta = ($tipo->dir == 'uscita') ? -$qta : $qta;
$movimento = ($qta < 0) ? $carico : $scarico;
$movimento = replace($movimento, [
'_TYPE_' => $tipo->descrizione,
'_NUM_' => $numero,
]);
$this->articolo->movimenta(-$qta, $movimento, $data, false, [
'iddocumento' => $preventivo->id,
]);
}
public function getDirection()
{
return $this->preventivo->tipo->dir;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Modules\Preventivi\Components;
use Common\Components\Description;
use Modules\Preventivi\Preventivo;
class Descrizione extends Description
{
use RelationTrait;
protected $table = 'co_righe_preventivi';
/**
* Crea una nuova riga collegata ad una preventivo.
*
* @param Preventivo $preventivo
*
* @return self
*/
public static function make(Preventivo $preventivo)
{
$model = parent::make($preventivo);
return $model;
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Modules\Preventivi\Components;
use Modules\Preventivi\Preventivo;
trait RelationTrait
{
public function getParentID()
{
return 'idpreventivo';
}
public function parent()
{
return $this->belongsTo(Preventivo::class, $this->getParentID());
}
public function preventivo()
{
return $this->parent();
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Modules\Preventivi\Components;
use Common\Components\Row;
use Modules\Preventivi\Preventivo;
class Riga extends Row
{
use RelationTrait;
protected $table = 'co_righe_preventivi';
/**
* Crea una nuova riga collegata ad una preventivo.
*
* @param Preventivo $preventivo
*
* @return self
*/
public static function make(Preventivo $preventivo)
{
$model = parent::make($preventivo);
return $model;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Modules\Preventivi\Components;
use Common\Components\Discount;
use Modules\Preventivi\Preventivo;
class Sconto extends Discount
{
use RelationTrait;
protected $table = 'co_righe_preventivi';
/**
* Crea una nuovo sconto globale collegato alla preventivo, oppure restituisce quello esistente.
*
* @param Preventivo $preventivo
*
* @return self
*/
public static function make(Preventivo $preventivo)
{
$model = $preventivo->scontoGlobale;
if ($model == null) {
$model = parent::make();
$model->setPreventivo($preventivo);
}
return $model;
}
}

View File

@ -0,0 +1,154 @@
<?php
namespace Modules\Preventivi;
use Common\Document;
use Modules\Anagrafiche\Anagrafica;
use Modules\Interventi\TipoSessione as TipoIntervento;
use Traits\RecordTrait;
use Util\Generator;
use Carbon\Carbon;
class Preventivo extends Document
{
use RecordTrait;
protected $table = 'co_preventivi';
/**
* Crea un nuovo preventivo.
*
* @param Anagrafica $anagrafica
* @param TipoIntervento $tipo_intervento
* @param string $nome
*
* @return self
*/
public static function make(Anagrafica $anagrafica, TipoIntervento $tipo_intervento, $nome)
{
$model = parent::make();
$stato_documento = Stato::where('descrizione', 'Bozza')->first();
$id_anagrafica = $anagrafica->id;
$id_agente = $anagrafica->idagente;
$id_pagamento = $anagrafica->idpagamento_vendite;
$costo_orario = $tipo_intervento['costo_orario'];
$costo_diritto_chiamata = $tipo_intervento['costo_diritto_chiamata'];
$id_iva = setting('Iva predefinita');
if (empty($id_pagamento)) {
$id_pagamento = setting('Tipo di pagamento predefinito');
}
$model->anagrafica()->associate($anagrafica);
$model->stato()->associate($stato_documento);
$model->numero = static::getNextNumero();
// Salvataggio delle informazioni
$model->nome = $nome;
$model->data_bozza = Carbon::now();
$model->data_conclusione = Carbon::now()->addMonth();
if (!empty($id_agente)) {
$model->idagente = $id_agente;
}
if (!empty($id_iva)) {
$model->idiva = $id_iva;
}
if (!empty($id_pagamento)) {
$model->idpagamento = $id_pagamento;
}
$model->save();
// Gestione delle revisioni
$model->master_revision = $model->id;
$model->default_revision = 1;
$model->save();
return $model;
}
/**
* Restituisce il nome del modulo a cui l'oggetto è collegato.
*
* @return string
*/
public function getModuleAttribute()
{
return 'Preventivi';
}
public function updateSconto()
{
// Aggiornamento sconto
aggiorna_sconto([
'parent' => 'co_preventivi',
'row' => 'co_righe_preventivi',
], [
'parent' => 'id',
'row' => 'idpreventivo',
], $this->id);
}
public function anagrafica()
{
return $this->belongsTo(Anagrafica::class, 'idanagrafica');
}
public function stato()
{
return $this->belongsTo(Stato::class, 'idstato');
}
public function articoli()
{
return $this->hasMany(Components\Articolo::class, 'idpreventivo');
}
public function righe()
{
return $this->hasMany(Components\Riga::class, 'idpreventivo');
}
public function descrizioni()
{
return $this->hasMany(Components\Descrizione::class, 'idpreventivo');
}
public function scontoGlobale()
{
return $this->hasOne(Components\Sconto::class, 'idpreventivo');
}
// Metodi statici
/**
* Calcola il nuovo numero di preventivo.
*
* @return string
*/
public static function getNextNumero()
{
$database = database();
$maschera = setting('Formato codice preventivi');
$ultimo_preventivo = $database->fetchOne('SELECT numero FROM co_preventivi WHERE numero=(SELECT MAX(CAST(numero AS SIGNED)) FROM co_preventivi) AND numero LIKE('.prepare(Generator::complete($maschera)).') ORDER BY numero DESC');
$numero = Generator::generate($maschera, $ultimo_preventivo['numero']);
if (!is_numeric($numero)) {
$ultimo_preventivo = $database->fetchOne('SELECT numero FROM co_preventivi WHERE numero LIKE('.prepare(Generator::complete($maschera)).') ORDER BY numero DESC');
$numero = Generator::generate($maschera, $ultimo_preventivo['numero']);
}
return $numero;
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Preventivi;
use Common\Model;
class Stato extends Model
{
protected $table = 'co_statipreventivi';
public function preventivi()
{
return $this->hasMany(Preventivo::class, 'idstatopreventivo');
}
}