diff --git a/include/src/Components/Article.php b/include/src/Components/Article.php index 92b8c9ff5..ecff0c472 100644 --- a/include/src/Components/Article.php +++ b/include/src/Components/Article.php @@ -9,6 +9,7 @@ use UnexpectedValueException; abstract class Article extends Row { + public $movimenta_magazzino = true; protected $serialRowID = null; protected $abilita_movimentazione = true; protected $serialsList = null; @@ -28,7 +29,24 @@ abstract class Article extends Row return $model; } - abstract public function movimenta($qta); + public function movimenta($qta) + { + if (!$this->movimenta_magazzino) { + return; + } + + $movimenta = true; + + // Movimenta il magazzino solo se l'articolo non è già stato movimentato da un documento precedente + if ($this->hasOriginal()) { + $original = $this->getOriginal(); + $movimenta = !$original->movimenta_magazzino; + } + + if ($movimenta) { + $this->movimentaMagazzino($qta); + } + } abstract public function getDirection(); @@ -151,12 +169,16 @@ abstract class Article extends Row return parent::save($options); } + abstract protected function movimentaMagazzino($qta); + protected static function boot() { parent::boot(true); - static::addGlobalScope('articles', function (Builder $builder) { - $builder->whereNotNull('idarticolo')->where('idarticolo', '<>', 0); + $table = parent::getTableName(); + + static::addGlobalScope('articles', function (Builder $builder) use ($table) { + $builder->whereNotNull($table.'.idarticolo')->where($table.'.idarticolo', '<>', 0); }); } diff --git a/include/src/Components/Description.php b/include/src/Components/Description.php index 5d6c48673..db1599ae0 100644 --- a/include/src/Components/Description.php +++ b/include/src/Components/Description.php @@ -8,6 +8,8 @@ use Illuminate\Database\Eloquent\Builder; abstract class Description extends Model { + use MorphTrait; + protected $guarded = []; public static function build(Document $document, $bypass = false) @@ -36,9 +38,23 @@ abstract class Description extends Model $previous = $this->qta; $diff = $value - $previous; + if ($this->hasOriginal()) { + $original = $this->getOriginal(); + + if ($original->qta_rimanente < $diff) { + $diff = $original->qta_rimanente; + $value = $previous + $diff; + } + } + $this->attributes['qta'] = $value; - $this->evasione($diff); + if ($this->hasOriginal()) { + $original = $this->getOriginal(); + + $original->qta_evasa += $diff; + $original->save(); + } return $diff; } @@ -55,7 +71,7 @@ abstract class Description extends Model public function delete() { - $this->evasione(-$this->qta); + $this->qta = 0; return parent::delete(); } @@ -108,6 +124,9 @@ abstract class Description extends Model // Creazione del nuovo oggetto $model = new $object(); + $model->original_id = $this->id; + $model->original_type = $current; + // Azioni specifiche di inizalizzazione $model->customInitCopiaIn($this); @@ -131,10 +150,6 @@ abstract class Description extends Model $model->save(); - // Rimozione quantità evasa - $this->qta_evasa = $this->qta_evasa + abs($attributes['qta']); - $this->save(); - return $model; } @@ -162,10 +177,6 @@ abstract class Description extends Model return $this instanceof Article; } - protected function evasione($diff) - { - } - /** * Azione personalizzata per la copia dell'oggetto (inizializzazione della copia). * @@ -199,13 +210,15 @@ abstract class Description extends Model { parent::boot(); + $table = parent::getTableName(); + if (!$bypass) { - static::addGlobalScope('descriptions', function (Builder $builder) { - $builder->where('is_descrizione', '=', 1); + static::addGlobalScope('descriptions', function (Builder $builder) use ($table) { + $builder->where($table.'.is_descrizione', '=', 1); }); } else { - static::addGlobalScope('not_descriptions', function (Builder $builder) { - $builder->where('is_descrizione', '=', 0); + static::addGlobalScope('not_descriptions', function (Builder $builder) use ($table) { + $builder->where($table.'.is_descrizione', '=', 0); }); } } diff --git a/include/src/Components/Discount.php b/include/src/Components/Discount.php index c7c41357a..ce887d10d 100644 --- a/include/src/Components/Discount.php +++ b/include/src/Components/Discount.php @@ -48,8 +48,10 @@ abstract class Discount extends Row { parent::boot(true); - static::addGlobalScope('discounts', function (Builder $builder) { - $builder->where('is_sconto', '=', 1); + $table = parent::getTableName(); + + static::addGlobalScope('discounts', function (Builder $builder) use ($table) { + $builder->where($table.'.is_sconto', '=', 1); }); } } diff --git a/include/src/Components/MorphTrait.php b/include/src/Components/MorphTrait.php new file mode 100644 index 000000000..7d7df8a70 --- /dev/null +++ b/include/src/Components/MorphTrait.php @@ -0,0 +1,21 @@ +original_type) && !empty($this->original); + } + + public function original() + { + return $this->morphedByMany($this->original_type, 'original', $this->table, 'id'); + } + + public function getOriginal() + { + return $this->original()->first(); + } +} diff --git a/include/src/Components/Row.php b/include/src/Components/Row.php index c7ef9ec78..dadf170d5 100644 --- a/include/src/Components/Row.php +++ b/include/src/Components/Row.php @@ -173,13 +173,15 @@ abstract class Row extends Description { parent::boot(true); + $table = parent::getTableName(); + if (!$bypass) { - static::addGlobalScope('rows', function (Builder $builder) { - $builder->whereNull('idarticolo')->orWhere('idarticolo', '=', 0); + static::addGlobalScope('rows', function (Builder $builder) use ($table) { + $builder->whereNull($table.'.idarticolo')->orWhere($table.'.idarticolo', '=', 0); }); - static::addGlobalScope('not_discounts', function (Builder $builder) { - $builder->where('is_sconto', '=', 0); + static::addGlobalScope('not_discounts', function (Builder $builder) use ($table) { + $builder->where($table.'.is_sconto', '=', 0); }); } } diff --git a/include/src/Document.php b/include/src/Document.php index bc15c4cfe..4928eff2d 100644 --- a/include/src/Document.php +++ b/include/src/Document.php @@ -19,6 +19,29 @@ abstract class Document extends Model return $descrizioni->merge($righe)->merge($articoli)->merge($sconti)->sortBy('order'); } + /** + * Restituisce la collezione di righe e articoli con valori rilevanti per i conti, raggruppate sulla base dei documenti di provenienza. + * La chiave è la serializzazione del documento di origine, oppure null in caso non esista. + * + * @return iterable + */ + public function getRigheRaggruppate() + { + $righe = $this->getRighe(); + + $groups = $righe->groupBy(function ($item, $key) { + if (!$item->hasOriginal()) { + return null; + } + + $parent = $item->getOriginal()->parent; + + return serialize($parent); + }); + + return $groups; + } + abstract public function righe(); abstract public function articoli(); @@ -97,6 +120,16 @@ abstract class Document extends Model return $this->calcola('guadagno'); } + public function delete() + { + $righe = $this->getRighe(); + foreach ($righe as $riga) { + $riga->delete(); + } + + return parent::delete(); + } + /** * Calcola la somma degli attributi indicati come parametri. * Il metodo **non** deve essere adattato per ulteriori funzionalità: deve esclusivamente calcolare la somma richiesta in modo esplicito dagli argomenti. diff --git a/include/src/Model.php b/include/src/Model.php index 36869e2e0..c9d8c6ba8 100644 --- a/include/src/Model.php +++ b/include/src/Model.php @@ -7,7 +7,10 @@ use Illuminate\Database\Eloquent\Model as Original; abstract class Model extends Original { // Retrocompatibilità MySQL - const UPDATED_AT = null; + public function setUpdatedAtAttribute($value) + { + // to Disable updated_at + } /** * Crea una nuova istanza del modello. @@ -18,4 +21,9 @@ abstract class Model extends Original { return new static(); } + + public static function getTableName() + { + return with(new static())->getTable(); + } } diff --git a/modules/contratti/actions.php b/modules/contratti/actions.php index ebdf18946..c03a6185f 100644 --- a/modules/contratti/actions.php +++ b/modules/contratti/actions.php @@ -3,7 +3,9 @@ include_once __DIR__.'/../../core.php'; use Modules\Anagrafiche\Anagrafica; +use Modules\Articoli\Articolo as ArticoloOriginale; use Modules\Contratti\Components\Articolo; +use Modules\Contratti\Components\Descrizione; use Modules\Contratti\Components\Riga; use Modules\Contratti\Components\Sconto; use Modules\Contratti\Contratto; @@ -67,27 +69,27 @@ switch (post('op')) { } // Salvataggio costi attività unitari del contratto - foreach (post('costo_ore') as $idtipointervento => $valore) { - $rs = $dbo->fetchArray('SELECT * FROM co_contratti_tipiintervento WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($idtipointervento)); + foreach (post('costo_ore') as $id_tipo => $valore) { + $rs = $dbo->fetchArray('SELECT * FROM co_contratti_tipiintervento WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($id_tipo)); // Se non esiste il record lo inserisco... if (sizeof($rs) == 0) { // Se almeno un valore è diverso da 0 inserisco l'importo... - if (post('costo_ore')[$idtipointervento] != 0 || post('costo_km')[$idtipointervento] != 0 || post('costo_dirittochiamata')[$idtipointervento] != 0) { - $dbo->query('INSERT INTO co_contratti_tipiintervento(idcontratto, idtipointervento, costo_ore, costo_km, costo_dirittochiamata, costo_ore_tecnico, costo_km_tecnico, costo_dirittochiamata_tecnico) VALUES('.prepare($id_record).', '.prepare($idtipointervento).', '.prepare(post('costo_ore')[$idtipointervento]).', '.prepare(post('costo_km')[$idtipointervento]).', '.prepare(post('costo_dirittochiamata')[$idtipointervento]).', '.prepare(post('costo_ore_tecnico')[$idtipointervento]).', '.prepare(post('costo_km_tecnico')[$idtipointervento]).', '.prepare(post('costo_dirittochiamata_tecnico')[$idtipointervento]).')'); + if (post('costo_ore')[$id_tipo] != 0 || post('costo_km')[$id_tipo] != 0 || post('costo_dirittochiamata')[$id_tipo] != 0) { + $dbo->query('INSERT INTO co_contratti_tipiintervento(idcontratto, idtipointervento, costo_ore, costo_km, costo_dirittochiamata, costo_ore_tecnico, costo_km_tecnico, costo_dirittochiamata_tecnico) VALUES('.prepare($id_record).', '.prepare($id_tipo).', '.prepare(post('costo_ore')[$id_tipo]).', '.prepare(post('costo_km')[$id_tipo]).', '.prepare(post('costo_dirittochiamata')[$id_tipo]).', '.prepare(post('costo_ore_tecnico')[$id_tipo]).', '.prepare(post('costo_km_tecnico')[$id_tipo]).', '.prepare(post('costo_dirittochiamata_tecnico')[$id_tipo]).')'); } } // ...altrimenti... else { // Aggiorno il nuovo valore se è diverso da 0... - if (post('costo_ore')[$idtipointervento] != 0 || post('costo_km')[$idtipointervento] != 0 || post('costo_dirittochiamata')[$idtipointervento] != 0) { - $dbo->query('UPDATE co_contratti_tipiintervento SET costo_ore='.prepare(post('costo_ore')[$idtipointervento]).', costo_km='.prepare(post('costo_km')[$idtipointervento]).', costo_dirittochiamata='.prepare(post('costo_dirittochiamata')[$idtipointervento]).', costo_ore_tecnico='.prepare(post('costo_ore_tecnico')[$idtipointervento]).', costo_km_tecnico='.prepare(post('costo_km_tecnico')[$idtipointervento]).', costo_dirittochiamata_tecnico='.prepare(post('costo_dirittochiamata_tecnico')[$idtipointervento]).' WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($idtipointervento)); + if (post('costo_ore')[$id_tipo] != 0 || post('costo_km')[$id_tipo] != 0 || post('costo_dirittochiamata')[$id_tipo] != 0) { + $dbo->query('UPDATE co_contratti_tipiintervento SET costo_ore='.prepare(post('costo_ore')[$id_tipo]).', costo_km='.prepare(post('costo_km')[$id_tipo]).', costo_dirittochiamata='.prepare(post('costo_dirittochiamata')[$id_tipo]).', costo_ore_tecnico='.prepare(post('costo_ore_tecnico')[$id_tipo]).', costo_km_tecnico='.prepare(post('costo_km_tecnico')[$id_tipo]).', costo_dirittochiamata_tecnico='.prepare(post('costo_dirittochiamata_tecnico')[$id_tipo]).' WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($id_tipo)); } // ...altrimenti cancello l'eventuale riga else { - $dbo->query('DELETE FROM co_contratti_tipiintervento WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($idtipointervento)); + $dbo->query('DELETE FROM co_contratti_tipiintervento WHERE idcontratto='.prepare($id_record).' AND idtipointervento='.prepare($id_tipo)); } } } @@ -119,6 +121,42 @@ switch (post('op')) { break; + case 'manage_articolo': + if (post('idriga') != null) { + $articolo = Articolo::find(post('idriga')); + } else { + $originale = ArticoloOriginale::find(post('idarticolo')); + $articolo = Articolo::build($contratto, $originale); + } + + $qta = post('qta'); + + $articolo->descrizione = post('descrizione'); + $articolo->um = post('um') ?: null; + + $articolo->id_iva = post('idiva'); + + //$articolo->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0; + $articolo->prezzo_unitario_vendita = post('prezzo'); + $articolo->sconto_unitario = post('sconto'); + $articolo->tipo_sconto = post('tipo_sconto'); + + try { + $articolo->qta = $qta; + } catch (UnexpectedValueException $e) { + flash()->error(tr('Alcuni serial number sono già stati utilizzati!')); + } + + $articolo->save(); + + if (post('idriga') != null) { + flash()->info(tr('Articolo modificato!')); + } else { + flash()->info(tr('Articolo aggiunto!')); + } + + break; + case 'manage_sconto': if (post('idriga') != null) { $sconto = Sconto::find(post('idriga')); @@ -142,108 +180,69 @@ switch (post('op')) { break; - // Aggiungo una riga al contratto - case 'addriga': - $idiva = post('idiva'); - $idarticolo = post('idarticolo'); - $descrizione = post('descrizione'); + case 'manage_riga': + if (post('idriga') != null) { + $riga = Riga::find(post('idriga')); + } else { + $riga = Riga::build($contratto); + } $qta = post('qta'); - $prezzo = post('prezzo'); - // Calcolo dello sconto - $sconto_unitario = post('sconto'); - $tipo_sconto = post('tipo_sconto'); - $sconto = calcola_sconto([ - 'sconto' => $sconto_unitario, - 'prezzo' => $prezzo, - 'tipo' => $tipo_sconto, - 'qta' => $qta, - ]); + $riga->descrizione = post('descrizione'); + $riga->um = post('um') ?: null; - $subtot = $prezzo * $qta; + $riga->id_iva = post('idiva'); - $um = post('um'); + //$riga->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0; + $riga->prezzo_unitario_vendita = post('prezzo'); + $riga->sconto_unitario = post('sconto'); + $riga->tipo_sconto = post('tipo_sconto'); - // Lettura iva dell'articolo - $rs2 = $dbo->fetchArray('SELECT percentuale, descrizione, indetraibile FROM co_iva WHERE id='.prepare($idiva)); - $iva = ($prezzo * $qta - $sconto) / 100 * $rs2[0]['percentuale']; - $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; - $desc_iva = $rs2[0]['descrizione']; + $riga->qta = $qta; - $dbo->query('INSERT INTO co_righe_contratti(idcontratto, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, is_descrizione, `order`) VALUES ('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($um).', '.prepare($qta).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare(empty($qta)).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_contratti AS t WHERE idcontratto='.prepare($id_record).'))'); + $riga->save(); - // Messaggi informativi - if (!empty($idarticolo)) { - flash()->info(tr('Articolo aggiunto!')); - } elseif (!empty($qta)) { + if (post('idriga') != null) { + flash()->info(tr('Riga modificata!')); + } else { flash()->info(tr('Riga aggiunta!')); + } + + break; + + case 'manage_descrizione': + if (post('idriga') != null) { + $riga = Descrizione::find(post('idriga')); + } else { + $riga = Descrizione::build($contratto); + } + + $riga->descrizione = post('descrizione'); + + $riga->save(); + + if (post('idriga') != null) { + flash()->info(tr('Riga descrittiva modificata!')); } else { flash()->info(tr('Riga descrittiva aggiunta!')); } break; - case 'editriga': - $idriga = post('idriga'); - - $rs = $dbo->fetchArray("SELECT * FROM co_righe_contratti WHERE id='".$idriga."'"); - $is_descrizione = $rs[0]['is_descrizione']; - - $idarticolo = post('idarticolo'); - $descrizione = post('descrizione'); - - $qta = post('qta'); - $prezzo = post('prezzo'); - $subtot = $prezzo * $qta; - - // Calcolo dello sconto - $sconto_unitario = post('sconto'); - $tipo_sconto = post('tipo_sconto'); - $sconto = calcola_sconto([ - 'sconto' => $sconto_unitario, - 'prezzo' => $prezzo, - 'tipo' => $tipo_sconto, - 'qta' => $qta, - ]); - - $idiva = post('idiva'); - $um = post('um'); - - // Calcolo iva - $query = 'SELECT percentuale, descrizione, indetraibile FROM co_iva WHERE id='.prepare($idiva); - $rs = $dbo->fetchArray($query); - $iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale']; - $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; - $desc_iva = $rs[0]['descrizione']; - - // Modifica riga generica sul documento - if ($is_descrizione == 0) { - $query = 'UPDATE co_righe_contratti SET idarticolo='.prepare($idarticolo).', idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga); - } else { - $query = 'UPDATE co_righe_contratti SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga); - } - $dbo->query($query); - - flash()->info(tr('Riga modificata!')); - - break; - // Eliminazione riga - case 'delriga': - if (post('idriga') !== null) { - $idriga = post('idriga'); + case 'delete_riga': + $id_riga = post('idriga'); + if ($id_riga !== null) { + $riga = Descrizione::find($id_riga) ?: Riga::find($id_riga); + $riga = $riga ? $riga : Articolo::find($id_riga); + $riga = $riga ? $riga : Sconto::find($id_riga); - $query = 'DELETE FROM `co_righe_contratti` WHERE idcontratto='.prepare($id_record).' AND id='.prepare($idriga); + $riga->delete(); - if ($dbo->query($query)) { - flash()->info(tr('Riga eliminata!')); - } + flash()->info(tr('Riga eliminata!')); } - // Ricalcolo il budget - $dbo->query('UPDATE co_contratti SET budget=( SELECT SUM(subtotale) FROM co_righe_contratti GROUP BY idcontratto HAVING idcontratto=co_contratti.id ) WHERE id='.prepare($id_record)); - break; // Scollegamento intervento da contratto @@ -261,22 +260,22 @@ switch (post('op')) { } break; - case 'update_position': - $orders = explode(',', $_POST['order']); - $order = 0; + case 'update_position': + $orders = explode(',', $_POST['order']); + $order = 0; - foreach ($orders as $idriga) { - $dbo->query('UPDATE `co_righe_contratti` SET `order`='.prepare($order).' WHERE id='.prepare($idriga)); - ++$order; - } + foreach ($orders as $idriga) { + $dbo->query('UPDATE `co_righe_contratti` SET `order`='.prepare($order).' WHERE id='.prepare($idriga)); + ++$order; + } - break; + break; // eliminazione contratto case 'delete': - $dbo->query('DELETE FROM co_contratti WHERE id='.prepare($id_record)); $dbo->query('DELETE FROM co_promemoria WHERE idcontratto='.prepare($id_record)); - $dbo->query('DELETE FROM co_righe_contratti WHERE idcontratto='.prepare($id_record)); + + $contratto->delete(); flash()->info(tr('Contratto eliminato!')); diff --git a/modules/contratti/row-add.php b/modules/contratti/row-add.php index 23a59c0a1..8a38e0764 100644 --- a/modules/contratti/row-add.php +++ b/modules/contratti/row-add.php @@ -9,7 +9,7 @@ $documento = Contratto::find($id_record); // Impostazioni per la gestione $options = [ - 'op' => 'addriga', + 'op' => 'manage_riga', 'action' => 'add', 'dir' => $documento->direzione, 'idanagrafica' => $documento['idanagrafica'], @@ -35,6 +35,8 @@ $result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita'); $file = 'riga'; if (get('is_descrizione') !== null) { $file = 'descrizione'; + + $options['op'] = 'manage_descrizione'; } elseif (get('is_articolo') !== null) { $file = 'articolo'; @@ -45,6 +47,8 @@ if (get('is_descrizione') !== null) { $result['sconto_unitario'] = $listino['prc_guadagno']; $result['tipo_sconto'] = 'PRC'; } + + $options['op'] = 'manage_articolo'; } elseif (get('is_sconto') !== null) { $file = 'sconto'; diff --git a/modules/contratti/row-edit.php b/modules/contratti/row-edit.php index 109816768..cc04a3ec1 100644 --- a/modules/contratti/row-edit.php +++ b/modules/contratti/row-edit.php @@ -9,7 +9,7 @@ $documento = Contratto::find($id_record); // Impostazioni per la gestione $options = [ - 'op' => 'editriga', + 'op' => 'manage_riga', 'action' => 'edit', 'dir' => $documento->direzione, 'idanagrafica' => $documento['idanagrafica'], @@ -23,14 +23,16 @@ $riga = $documento->getRighe()->find($id_riga); $result = $riga->toArray(); $result['prezzo'] = $riga->prezzo_unitario_vendita; -// Importazione della gestione dedicata - // Importazione della gestione dedicata $file = 'riga'; if ($riga->isDescrizione()) { $file = 'descrizione'; + + $options['op'] = 'manage_descrizione'; } elseif ($riga->isArticolo()) { $file = 'articolo'; + + $options['op'] = 'manage_articolo'; } elseif ($riga->isSconto()) { $file = 'sconto'; diff --git a/modules/contratti/row-list.php b/modules/contratti/row-list.php index 629fe63e1..a1052797a 100644 --- a/modules/contratti/row-list.php +++ b/modules/contratti/row-list.php @@ -2,10 +2,8 @@ include_once __DIR__.'/../../core.php'; -/* -ARTICOLI + RIGHE GENERICHE -*/ -$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 FROM co_righe_contratti WHERE idcontratto='.prepare($id_record).' ORDER BY `order`'); +// Righe documento +$righe = $contratto->getRighe(); echo ' @@ -22,81 +20,71 @@ echo ' '; -foreach ($rs as $r) { +foreach ($righe as $riga) { + echo ' + '; + // Descrizione + $descrizione = nl2br($riga->descrizione); + if ($riga->isArticolo()) { + $descrizione = Modules::link('Articoli', $riga->idarticolo, $riga->articolo->codice.' - '.$descrizione); + } echo ' - - '; + + if ($riga->isDescrizione()) { + echo ' + + + + + '; } else { - echo nl2br($r['descrizione']); - } - - echo ' + // Q.tà + echo ' + '; - // Q.tà - echo ' - '; - // um - echo ' - '; + '; - // IVA - echo ' - '; - // Imponibile - echo ' - '; + } // Possibilità di rimuovere una riga solo se il preventivo non è stato pagato echo ' @@ -104,20 +92,14 @@ foreach ($rs as $r) { if ($record['stato'] != 'Pagato') { echo ' - + - - - - + + -
'; - - echo " - - - "; - echo ' +
+ +
'; } @@ -132,6 +114,22 @@ foreach ($rs as $r) {
'; } +echo ' +'; + +echo ' + '; + // Calcoli $imponibile = abs($contratto->imponibile); $sconto = $contratto->sconto; @@ -139,9 +137,6 @@ $totale_imponibile = abs($contratto->totale_imponibile); $iva = abs($contratto->iva); $totale = abs($contratto->totale); -echo ' - '; - // Totale totale imponibile echo ' @@ -149,7 +144,7 @@ echo ' '.tr('Imponibile', [], ['upper' => true]).':'; @@ -162,7 +157,7 @@ if (!empty($sconto)) { '.tr('Sconto/maggiorazione', [], ['upper' => true]).':'; @@ -187,7 +182,7 @@ echo ' '.tr('Iva', [], ['upper' => true]).':'; @@ -199,7 +194,7 @@ echo ' '.tr('Totale', [], ['upper' => true]).':'; diff --git a/modules/contratti/src/Components/Articolo.php b/modules/contratti/src/Components/Articolo.php index fe73e1d22..9e7a8be96 100644 --- a/modules/contratti/src/Components/Articolo.php +++ b/modules/contratti/src/Components/Articolo.php @@ -10,6 +10,8 @@ class Articolo extends Article { use RelationTrait; + public $movimenta_magazzino = false; + protected $table = 'co_righe_contratti'; /** @@ -27,7 +29,7 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { return; } diff --git a/modules/contratti/src/Components/RelationTrait.php b/modules/contratti/src/Components/RelationTrait.php index 0afa4ae3d..aeecfd9f9 100644 --- a/modules/contratti/src/Components/RelationTrait.php +++ b/modules/contratti/src/Components/RelationTrait.php @@ -20,4 +20,12 @@ trait RelationTrait { return $this->parent(); } + + public function delete() + { + $parent = $this->parent; + $parent->save(); + + return parent::delete(); + } } diff --git a/modules/contratti/src/Contratto.php b/modules/contratti/src/Contratto.php index c4d4ee842..f420647be 100644 --- a/modules/contratti/src/Contratto.php +++ b/modules/contratti/src/Contratto.php @@ -142,6 +142,18 @@ class Contratto extends Document return $this->hasMany(Intervento::class, 'id_contratto'); } + public function fixBudget() + { + $this->budget = $this->imponibile_scontato; + } + + public function save(array $options = []) + { + $this->fixBudget(); + + return parent::save($options); + } + // Metodi statici /** diff --git a/modules/ddt/src/Components/Articolo.php b/modules/ddt/src/Components/Articolo.php index 6f7a94c29..abb2fd4f9 100644 --- a/modules/ddt/src/Components/Articolo.php +++ b/modules/ddt/src/Components/Articolo.php @@ -28,7 +28,7 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { $ddt = $this->ddt; $tipo = $ddt->tipo; diff --git a/modules/fatture/row-list.php b/modules/fatture/row-list.php index 28055f195..f8369464d 100644 --- a/modules/fatture/row-list.php +++ b/modules/fatture/row-list.php @@ -2,9 +2,7 @@ include_once __DIR__.'/../../core.php'; -use Modules\Fatture\Components\Riga; - -// Righe fattura +// Righe documento $righe = $fattura->getRighe(); echo ' diff --git a/modules/fatture/src/Components/Articolo.php b/modules/fatture/src/Components/Articolo.php index 861294704..f8c1df202 100644 --- a/modules/fatture/src/Components/Articolo.php +++ b/modules/fatture/src/Components/Articolo.php @@ -28,7 +28,7 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { // Se il documento è generato da un ddt o intervento allora **non** movimento il magazzino if (!empty($this->idddt) || !empty($this->idintervento)) { diff --git a/modules/fatture/src/Fattura.php b/modules/fatture/src/Fattura.php index b41ce57a8..30ac7c510 100644 --- a/modules/fatture/src/Fattura.php +++ b/modules/fatture/src/Fattura.php @@ -367,7 +367,7 @@ class Fattura extends Document */ public static function registraScadenza(Fattura $fattura, $importo, $scadenza, $is_pagato, $type = 'fattura') { - //Calcolo la descrizione + // Individuazione della descrizione $descrizione = database()->fetchOne("SELECT CONCAT(co_tipidocumento.descrizione, CONCAT(' numero ', IF(numero_esterno!='', numero_esterno, numero))) AS descrizione FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='".$fattura->id."'")['descrizione']; database()->insert('co_scadenziario', [ diff --git a/modules/interventi/src/Components/Articolo.php b/modules/interventi/src/Components/Articolo.php index ea7e363cb..73663189f 100644 --- a/modules/interventi/src/Components/Articolo.php +++ b/modules/interventi/src/Components/Articolo.php @@ -34,7 +34,7 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { $articolo = $this->articolo; diff --git a/modules/ordini/src/Components/Articolo.php b/modules/ordini/src/Components/Articolo.php index 33825192f..246ada263 100644 --- a/modules/ordini/src/Components/Articolo.php +++ b/modules/ordini/src/Components/Articolo.php @@ -10,6 +10,8 @@ class Articolo extends Article { use RelationTrait; + public $movimenta_magazzino = false; + protected $table = 'or_righe_ordini'; protected $serialRowID = 'ordine'; @@ -28,9 +30,9 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { - return true; + return; } public function getDirection() diff --git a/modules/preventivi/actions.php b/modules/preventivi/actions.php index c1f24b33c..d9e2e141d 100644 --- a/modules/preventivi/actions.php +++ b/modules/preventivi/actions.php @@ -3,7 +3,10 @@ include_once __DIR__.'/../../core.php'; use Modules\Anagrafiche\Anagrafica; +use Modules\Articoli\Articolo as ArticoloOriginale; +use Modules\Interventi\TipoSessione; use Modules\Preventivi\Components\Articolo; +use Modules\Preventivi\Components\Descrizione; use Modules\Preventivi\Components\Riga; use Modules\Preventivi\Components\Sconto; use Modules\Preventivi\Preventivo; @@ -29,72 +32,35 @@ switch (post('op')) { case 'update': if (isset($id_record)) { - $idstato = post('idstato'); - $nome = post('nome'); - $idanagrafica = post('idanagrafica'); - $idsede = post('idsede'); - $idagente = post('idagente'); - $idreferente = post('idreferente'); - $idpagamento = post('idpagamento'); - $idporto = post('idporto'); - $tempi_consegna = post('tempi_consegna'); - $numero = post('numero'); + $preventivo->idstato = post('idstato'); + $preventivo->nome = post('nome'); + $preventivo->idanagrafica = post('idanagrafica'); + $preventivo->idsede = post('idsede'); + $preventivo->idagente = post('idagente'); + $preventivo->idreferente = post('idreferente'); + $preventivo->idpagamento = post('idpagamento'); + $preventivo->idporto = post('idporto'); + $preventivo->tempi_consegna = post('tempi_consegna'); + $preventivo->numero = post('numero'); + $preventivo->data_bozza = post('data_bozza'); + $preventivo->data_accettazione = post('data_accettazione'); + $preventivo->data_rifiuto = post('data_rifiuto'); + $preventivo->data_conclusione = post('data_conclusione'); + $preventivo->esclusioni = post('esclusioni'); + $preventivo->descrizione = post('descrizione'); + $preventivo->id_documento_fe = post('id_documento_fe'); + $preventivo->num_item = post('num_item'); + $preventivo->codice_cig = post('codice_cig'); + $preventivo->codice_cup = post('codice_cup'); + $preventivo->validita = post('validita'); + $preventivo->idtipointervento = post('idtipointervento'); + $preventivo->idiva = post('idiva'); - $tipo_sconto = post('tipo_sconto_generico'); - $sconto = post('sconto_generico'); + $preventivo->save(); - // $budget = post('budget'); - // $budget = str_replace( ",", ".", $budget ); - - $data_bozza = post('data_bozza'); - $data_accettazione = post('data_accettazione'); - $data_rifiuto = post('data_rifiuto'); - $data_conclusione = post('data_conclusione'); - $esclusioni = post('esclusioni'); - $descrizione = post('descrizione'); - $validita = post('validita'); - $idtipointervento = post('idtipointervento'); - - // $costo_diritto_chiamata = post('costo_diritto_chiamata'); - // $ore_lavoro = str_replace( ",", ".", post('ore_lavoro') ); - // $costo_orario = post('costo_orario'); - // $costo_km = post('costo_km'); - - $idiva = post('idiva'); - - $id_documento_fe = post('id_documento_fe'); - $num_item = post('num_item'); - $codice_cig = post('codice_cig'); - $codice_cup = post('codice_cup'); - - $query = 'UPDATE co_preventivi SET idstato='.prepare($idstato).','. - ' nome='.prepare($nome).','. - ' idanagrafica='.prepare($idanagrafica).','. - ' idsede='.prepare($idsede).','. - ' idagente='.prepare($idagente).','. - ' idreferente='.prepare($idreferente).','. - ' idpagamento='.prepare($idpagamento).','. - ' idporto='.prepare($idporto).','. - ' tempi_consegna='.prepare($tempi_consegna).','. - ' numero='.prepare($numero).','. - ' data_bozza='.prepare($data_bozza).','. - ' data_accettazione='.prepare($data_accettazione).','. - ' data_rifiuto='.prepare($data_rifiuto).','. - ' data_conclusione='.prepare($data_conclusione).','. - ' esclusioni='.prepare($esclusioni).','. - ' descrizione='.prepare($descrizione).','. - ' id_documento_fe='.prepare($id_documento_fe).','. - ' num_item='.prepare($num_item).','. - ' codice_cig='.prepare($codice_cig).','. - ' codice_cup='.prepare($codice_cup).','. - ' validita='.prepare($validita).','. - ' idtipointervento='.prepare($idtipointervento).','. - ' idiva='.prepare($idiva).' WHERE id='.prepare($id_record); - $dbo->query($query); - - // update_budget_preventivo( $id_record ); flash()->info(tr('Preventivo modificato correttamente!')); } + break; // Duplica preventivo @@ -143,25 +109,6 @@ switch (post('op')) { } break; - // Scollegamento articolo da ordine - case 'unlink_articolo': - if (post('idriga') !== null) { - $idriga = post('idriga'); - $idarticolo = post('idarticolo'); - - // Leggo la quantità di questo articolo nell'ordine - $query = 'SELECT qta, subtotale FROM co_righe_preventivi WHERE id='.prepare($idriga); - $rs = $dbo->fetchArray($query); - $qta = floatval($rs[0]['qta']); - $subtotale = $rs[0]['subtotale']; - - // Elimino la riga dal preventivo - $dbo->query('DELETE FROM co_righe_preventivi WHERE id='.prepare($idriga)); - - flash()->info(tr('Riga rimossa!')); - } - break; - // Scollegamento intervento da preventivo case 'unlink': if (isset($_GET['idpreventivo']) && isset($_GET['idintervento'])) { @@ -177,59 +124,46 @@ switch (post('op')) { } break; - // eliminazione preventivo + // Eliminazione preventivo case 'delete': - $rs_revisioni = $dbo->fetchArray('SELECT master_revision FROM co_preventivi WHERE id='.prepare($id_record)); - - //Cancello preventivo e revisioni - $dbo->query('DELETE FROM co_preventivi WHERE master_revision='.prepare($rs_revisioni[0]['master_revision'])); - - $dbo->update('in_interventi', [ - 'id_preventivo' => null, - ], ['id_preventivo' => $id_record]); + $preventivo->delete(); flash()->info(tr('Preventivo eliminato!')); break; - // Aggiungo una riga al preventivo - case 'addriga': - $idarticolo = post('idarticolo'); - $idiva = post('idiva'); - $descrizione = post('descrizione'); + case 'manage_articolo': + if (post('idriga') != null) { + $articolo = Articolo::find(post('idriga')); + } else { + $originale = ArticoloOriginale::find(post('idarticolo')); + $articolo = Articolo::build($preventivo, $originale); + } $qta = post('qta'); - $prezzo = post('prezzo'); - $prezzo_acquisto = post('prezzo_acquisto'); - // Calcolo dello sconto - $sconto_unitario = post('sconto'); - $tipo_sconto = post('tipo_sconto'); - $sconto = calcola_sconto([ - 'sconto' => $sconto_unitario, - 'prezzo' => $prezzo, - 'tipo' => $tipo_sconto, - 'qta' => $qta, - ]); + $articolo->descrizione = post('descrizione'); + $articolo->um = post('um') ?: null; - $subtot = $prezzo * $qta; + $articolo->id_iva = post('idiva'); - $um = post('um'); + //$articolo->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0; + $articolo->prezzo_unitario_vendita = post('prezzo'); + $articolo->sconto_unitario = post('sconto'); + $articolo->tipo_sconto = post('tipo_sconto'); - // Lettura iva dell'articolo - $rs2 = $dbo->fetchArray('SELECT descrizione, percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva)); - $iva = ($subtot - $sconto) / 100 * $rs2[0]['percentuale']; - $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; + try { + $articolo->qta = $qta; + } catch (UnexpectedValueException $e) { + flash()->error(tr('Alcuni serial number sono già stati utilizzati!')); + } - $dbo->query('INSERT INTO co_righe_preventivi(idpreventivo, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, prezzo_unitario_acquisto, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, is_descrizione, `order`) VALUES ('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($rs2[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo_acquisto).', '.prepare($subtot).', '.prepare($um).', '.prepare($qta).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare(empty($qta)).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_preventivi AS t WHERE idpreventivo='.prepare($id_record).'))'); + $articolo->save(); - // Messaggi informativi - if (!empty($idarticolo)) { - flash()->info(tr('Articolo aggiunto!')); - } elseif (!empty($qta)) { - flash()->info(tr('Riga aggiunta!')); + if (post('idriga') != null) { + flash()->info(tr('Articolo modificato!')); } else { - flash()->info(tr('Riga descrittiva aggiunta!')); + flash()->info(tr('Articolo aggiunto!')); } break; @@ -257,62 +191,72 @@ switch (post('op')) { break; - case 'editriga': - $idriga = post('idriga'); - $descrizione = post('descrizione'); - $idarticolo = post('idarticolo'); - //Info riga Preventivo - $rs = $dbo->fetchArray('SELECT * FROM co_righe_preventivi WHERE id='.prepare($idriga)); - $is_descrizione = $rs[0]['is_descrizione']; + case 'manage_riga': + if (post('idriga') != null) { + $riga = Riga::find(post('idriga')); + } else { + $riga = Riga::build($preventivo); + } $qta = post('qta'); - $prezzo = post('prezzo'); - $prezzo_acquisto = post('prezzo_acquisto'); - $subtot = $prezzo * $qta; - // Calcolo dello sconto - $sconto_unitario = post('sconto'); - $tipo_sconto = post('tipo_sconto'); - $sconto = calcola_sconto([ - 'sconto' => $sconto_unitario, - 'prezzo' => $prezzo, - 'tipo' => $tipo_sconto, - 'qta' => $qta, - ]); + $riga->descrizione = post('descrizione'); + $riga->um = post('um') ?: null; - $idiva = post('idiva'); - $um = post('um'); + $riga->id_iva = post('idiva'); - // Calcolo iva - $rs2 = $dbo->fetchArray('SELECT descrizione, percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva)); - $iva = ($subtot - $sconto) / 100 * $rs2[0]['percentuale']; - $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; - $desc_iva = $rs2[0]['descrizione']; + //$riga->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0; + $riga->prezzo_unitario_vendita = post('prezzo'); + $riga->sconto_unitario = post('sconto'); + $riga->tipo_sconto = post('tipo_sconto'); - if ($is_descrizione == 0) { - // Modifica riga generica sul documento - $query = 'UPDATE co_righe_preventivi SET idarticolo='.prepare($idarticolo).', idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', prezzo_unitario_acquisto='.prepare($prezzo_acquisto).',subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga); + $riga->qta = $qta; + + $riga->save(); + + if (post('idriga') != null) { + flash()->info(tr('Riga modificata!')); } else { - $query = 'UPDATE co_righe_preventivi SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga); + flash()->info(tr('Riga aggiunta!')); } - $dbo->query($query); - flash()->info('Riga modificata!'); break; - case 'update_position': - $orders = explode(',', $_POST['order']); - $order = 0; + case 'manage_descrizione': + if (post('idriga') != null) { + $riga = Descrizione::find(post('idriga')); + } else { + $riga = Descrizione::build($preventivo); + } - foreach ($orders as $idriga) { - $dbo->query('UPDATE `co_righe_preventivi` SET `order`='.prepare($order).' WHERE id='.prepare($idriga)); - ++$order; - } + $riga->descrizione = post('descrizione'); - break; + $riga->save(); + + if (post('idriga') != null) { + flash()->info(tr('Riga descrittiva modificata!')); + } else { + flash()->info(tr('Riga descrittiva aggiunta!')); + } + + break; + + // Eliminazione riga + case 'delete_riga': + $id_riga = post('idriga'); + if ($id_riga !== null) { + $riga = Descrizione::find($id_riga) ?: Riga::find($id_riga); + $riga = $riga ? $riga : Articolo::find($id_riga); + $riga = $riga ? $riga : Sconto::find($id_riga); + + $riga->delete(); + + flash()->info(tr('Riga eliminata!')); + } + + break; case 'add_revision': - //Copio il preventivo $rs_preventivo = $dbo->fetchArray("SELECT * FROM co_preventivi WHERE id='".$id_record."'"); diff --git a/modules/preventivi/modutil.php b/modules/preventivi/modutil.php index bc4710431..5090d1dce 100644 --- a/modules/preventivi/modutil.php +++ b/modules/preventivi/modutil.php @@ -4,27 +4,6 @@ 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 - * $idordine integer codice dell'ordine da cui scollegare l'articolo. - */ -function rimuovi_articolo_dapreventivo($idarticolo, $idpreventivo, $idriga) -{ - global $dir; - - $dbo = database(); - - // Leggo la quantità di questo articolo nell'ordine - $query = 'SELECT qta, subtotale FROM co_righe_preventivi WHERE id='.prepare($idriga); - $rs = $dbo->fetchArray($query); - $qta = floatval($rs[0]['qta']); - $subtotale = $rs[0]['subtotale']; - - // Elimino la riga dall'ordine - $dbo->query('DELETE FROM co_righe_preventivi WHERE id='.prepare($idriga)); -} - function get_imponibile_preventivo($idpreventivo) { $preventivo = Preventivo::find($idpreventivo); @@ -51,30 +30,3 @@ function get_stato_preventivo($idpreventivo) return 'Non evaso'; } } - -/** - * Aggiorna il budget del preventivo leggendo tutte le righe inserite. - * - * @deprecated 2.3 - */ -function update_budget_preventivo($idpreventivo) -{ - $dbo = database(); - - // Totale articoli - $rs = $dbo->fetchArray('SELECT SUM(subtotale) AS totale FROM co_righe_preventivi GROUP BY idpreventivo HAVING idpreventivo='.prepare($idpreventivo)); - $totale_articoli = $rs[0]['totale']; - - $rs = $dbo->fetchArray('SELECT SUM(sconto*qta) AS totale FROM co_righe_preventivi GROUP BY idpreventivo HAVING idpreventivo='.prepare($idpreventivo)); - $totale_sconto = $rs[0]['totale']; - - $rs = $dbo->fetchArray('SELECT SUM(iva) AS totale FROM co_righe_preventivi GROUP BY idpreventivo HAVING idpreventivo='.prepare($idpreventivo)); - $totale_iva = $rs[0]['totale']; - - // Totale costo ore, km e diritto di chiamata - // $rs = $dbo->fetchArray("SELECT SUM(costo_orario*ore_lavoro + costo_diritto_chiamata) AS totale FROM co_preventivi GROUP BY id HAVING id=\"".$idpreventivo."\""); - // $totale_lavoro = $rs[0]['totale']; - - // Aggiorno il budget su co_preventivi - $dbo->query('UPDATE co_preventivi SET budget='.prepare(($totale_articoli - $totale_sconto) + $totale_iva).' WHERE id='.prepare($idpreventivo)); -} diff --git a/modules/preventivi/row-add.php b/modules/preventivi/row-add.php index 0cb308c28..326bef1f9 100644 --- a/modules/preventivi/row-add.php +++ b/modules/preventivi/row-add.php @@ -9,7 +9,7 @@ $documento = Preventivo::find($id_record); // Impostazioni per la gestione $options = [ - 'op' => 'addriga', + 'op' => 'manage_riga', 'action' => 'add', 'dir' => $documento->direzione, 'idanagrafica' => $documento['idanagrafica'], @@ -35,6 +35,8 @@ $result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita'); $file = 'riga'; if (get('is_descrizione') !== null) { $file = 'descrizione'; + + $options['op'] = 'manage_descrizione'; } elseif (get('is_articolo') !== null) { $file = 'articolo'; @@ -45,6 +47,8 @@ if (get('is_descrizione') !== null) { $result['sconto_unitario'] = $listino['prc_guadagno']; $result['tipo_sconto'] = 'PRC'; } + + $options['op'] = 'manage_articolo'; } elseif (get('is_sconto') !== null) { $file = 'sconto'; diff --git a/modules/preventivi/row-edit.php b/modules/preventivi/row-edit.php index 71e789fda..e006bb1fe 100644 --- a/modules/preventivi/row-edit.php +++ b/modules/preventivi/row-edit.php @@ -9,7 +9,7 @@ $documento = Preventivo::find($id_record); // Impostazioni per la gestione $options = [ - 'op' => 'editriga', + 'op' => 'manage_riga', 'action' => 'edit', 'dir' => $documento->direzione, 'idanagrafica' => $documento['idanagrafica'], @@ -23,18 +23,19 @@ $riga = $documento->getRighe()->find($id_riga); $result = $riga->toArray(); $result['prezzo'] = $riga->prezzo_unitario_vendita; -// Importazione della gestione dedicata - // Importazione della gestione dedicata $file = 'riga'; if ($riga->isDescrizione()) { $file = 'descrizione'; + + $options['op'] = 'manage_descrizione'; } elseif ($riga->isArticolo()) { $file = 'articolo'; + + $options['op'] = 'manage_articolo'; } elseif ($riga->isSconto()) { $file = 'sconto'; $options['op'] = 'manage_sconto'; } - echo App::load($file.'.php', $result, $options); diff --git a/modules/preventivi/row-list.php b/modules/preventivi/row-list.php index 971b056e7..79d3fabb8 100644 --- a/modules/preventivi/row-list.php +++ b/modules/preventivi/row-list.php @@ -2,11 +2,8 @@ include_once __DIR__.'/../../core.php'; -/* -ARTICOLI + RIGHE GENERICHE -*/ -$q_art = '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 FROM co_righe_preventivi WHERE idpreventivo='.prepare($id_record).' ORDER BY `order`'; -$rs = $dbo->fetchArray($q_art); +// Righe documento +$righe = $preventivo->getRighe(); echo '
'; - if (!empty($r['idarticolo'])) { - echo Modules::link('Articoli', $r['idarticolo'], $r['codice'].' - '.$r['descrizione']); + + '.$descrizione.' + + '.Translator::numberToLocale($riga->qta_rimanente, 'qta').' / '.Translator::numberToLocale($riga->qta, 'qta').' '; - - if (empty($r['is_descrizione'])) { + // Unità di misura echo ' - '.Translator::numberToLocale($r['qta'] - $r['qta_evasa'], 'qta').' / '.Translator::numberToLocale($r['qta'], 'qta').''; - } - echo ' + + '.$riga->um.' '; - if (empty($r['is_descrizione'])) { + // Costo unitario echo ' - '.$r['um']; - } - echo ' - + '.moneyFormat($riga->prezzo_unitario_vendita); - // Costo unitario - echo ' - '; - if (empty($r['is_descrizione'])) { - echo ' - '.moneyFormat($r['subtotale'] / $r['qta']); - - if (abs($r['sconto_unitario']) > 0) { - $text = $r['sconto_unitario'] > 0 ? tr('sconto _TOT_ _TYPE_') : tr('maggiorazione _TOT_ _TYPE_'); + if (abs($riga->sconto_unitario) > 0) { + $text = $riga->sconto_unitario > 0 ? tr('sconto _TOT_ _TYPE_') : tr('maggiorazione _TOT_ _TYPE_'); echo '
'.replace($text, [ - '_TOT_' => Translator::numberToLocale(abs($r['sconto_unitario'])), - '_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : currency()), + '_TOT_' => Translator::numberToLocale(abs($riga->sconto_unitario)), + '_TYPE_' => ($riga->tipo_sconto == 'PRC' ? '%' : currency()), ]).''; } - } - echo' + + echo'
'; - if (empty($r['is_descrizione'])) { + // IVA echo ' - '.moneyFormat($r['iva'])."
- ".$r['desc_iva'].''; - } - echo ' +
+ '.moneyFormat($riga->iva).'
+ '.$riga->aliquota->descrizione.(($riga->aliquota->esente) ? ' ('.$riga->aliquota->codice_natura_fe.')' : null).'
'; - if (empty($r['is_descrizione'])) { + // Imponibile echo ' - '.moneyFormat($r['subtotale'] - $r['sconto']); - } - echo ' + + '.moneyFormat($riga->imponibile_scontato).'
- '.moneyFormat($imponibile, 2).' + '.moneyFormat($contratto->imponibile, 2).'
- '.moneyFormat($sconto, 2).' + '.moneyFormat($contratto->sconto, 2).'
- '.moneyFormat($iva, 2).' + '.moneyFormat($contratto->iva, 2).'
- '.moneyFormat($totale, 2).' + '.moneyFormat($contratto->totale, 2).'
@@ -15,7 +12,7 @@ echo ' - + @@ -23,79 +20,70 @@ echo ' '; -// se ho almeno un articolo caricato mostro la riga -foreach ($rs as $r) { +foreach ($righe as $riga) { echo ' - - '; - if (!empty($r['idarticolo'])) { - echo Modules::link('Articoli', $r['idarticolo'], $r['codice'].' - '.$r['descrizione']); + // Descrizione + $descrizione = nl2br($riga->descrizione); + if ($riga->isArticolo()) { + $descrizione = Modules::link('Articoli', $riga->idarticolo, $riga->articolo->codice.' - '.$descrizione); + } + echo ' + '; + + if ($riga->isDescrizione()) { + echo ' + + + + + '; } else { - echo nl2br($r['descrizione']); - } - - echo ' + // Q.tà + echo ' + '; - // q.tà - echo ' - '; - // um - echo ' - '; + '; - // iva - echo ' - '; - // Imponibile - echo ' - '; } // Possibilità di rimuovere una riga solo se il preventivo non è stato pagato @@ -103,19 +91,17 @@ foreach ($rs as $r) { '; +echo ' +'; + // Calcoli $imponibile = abs($preventivo->imponibile); $sconto = $preventivo->sconto; @@ -138,13 +137,16 @@ $totale_imponibile = abs($preventivo->totale_imponibile); $iva = abs($preventivo->iva); $totale = abs($preventivo->totale); -echo ' +// SCONTO +if (!empty($preventivo->sconto)) { + // Totale imponibile scontato + echo ' - '; @@ -156,13 +158,13 @@ if (!empty($sconto)) { - '; - // Totale imponibile + // Totale imponibile scontato echo ' - '; -// Totale preventivo +// Totale contratto echo ' - '; diff --git a/modules/preventivi/src/Components/Articolo.php b/modules/preventivi/src/Components/Articolo.php index 273c06cc1..b97ec0947 100644 --- a/modules/preventivi/src/Components/Articolo.php +++ b/modules/preventivi/src/Components/Articolo.php @@ -10,6 +10,8 @@ class Articolo extends Article { use RelationTrait; + public $movimenta_magazzino = false; + protected $table = 'co_righe_preventivi'; /** @@ -27,7 +29,7 @@ class Articolo extends Article return $model; } - public function movimenta($qta) + public function movimentaMagazzino($qta) { return; } diff --git a/modules/preventivi/src/Components/RelationTrait.php b/modules/preventivi/src/Components/RelationTrait.php index 64826346a..30de2c97b 100644 --- a/modules/preventivi/src/Components/RelationTrait.php +++ b/modules/preventivi/src/Components/RelationTrait.php @@ -20,4 +20,12 @@ trait RelationTrait { return $this->parent(); } + + public function delete() + { + $parent = $this->parent; + $parent->save(); + + return parent::delete(); + } } diff --git a/modules/preventivi/src/Preventivo.php b/modules/preventivi/src/Preventivo.php index b710095b6..8a75ca231 100644 --- a/modules/preventivi/src/Preventivo.php +++ b/modules/preventivi/src/Preventivo.php @@ -131,6 +131,30 @@ class Preventivo extends Document return $this->hasMany(Intervento::class, 'id_preventivo'); } + public function fixBudget() + { + $this->budget = $this->imponibile_scontato; + } + + public function save(array $options = []) + { + $this->fixBudget(); + + return parent::save($options); + } + + public function delete() + { + $this->interventi()->update(['id_preventivo' => null]); + $revision = $this->master_revision; + + $result = parent::delete(); + + self::where('master_revision', $revision)->delete(); + + return $result; + } + // Metodi statici /** diff --git a/update/2_4_9.sql b/update/2_4_9.sql index 0e8d93cf3..3c947fbc1 100644 --- a/update/2_4_9.sql +++ b/update/2_4_9.sql @@ -290,10 +290,10 @@ INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, ` INSERT INTO `in_statiintervento` (`idstatointervento`, `descrizione`, `colore`, `can_delete`, `completato`, `created_at`, `notifica`, `id_email`, `destinatari`) VALUES ('DAP', 'Da programmare', '#2deded', '1', '0', NULL, '0', NULL, NULL); -- Widget attività in programmazione -INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class`, `query`, `bgcolor`, `icon`, `print_link`, `more_link`, `more_link_type`, `php_include`, `text`, `enabled`, `order`, `help`) VALUES (NULL, 'Attività in programmazione', 'stats', '1', 'controller_top', 'col-md-12', 'SELECT COUNT(id) AS dato FROM in_interventi WHERE in_interventi.idstatointervento = (SELECT in_statiintervento.idstatointervento FROM in_statiintervento WHERE in_statiintervento.descrizione=\'Da programmare\') ORDER BY in_interventi.data_richiesta ASC', '#2deded', 'fa fa-hourglass-half', '', './modules/interventi/widgets/interventi_da_pianificare.php', 'popup', '', 'Attività in programmazione', '1', '8', NULL); +INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class`, `query`, `bgcolor`, `icon`, `print_link`, `more_link`, `more_link_type`, `php_include`, `text`, `enabled`, `order`, `help`) VALUES (NULL, 'Attività in programmazione', 'stats', '1', 'controller_top', 'col-md-12', 'SELECT COUNT(id) AS dato FROM in_interventi WHERE in_interventi.idstatointervento = (SELECT in_statiintervento.idstatointervento FROM in_statiintervento WHERE in_statiintervento.descrizione=\'Da programmare\') ORDER BY in_interventi.data_richiesta ASC', '#2deded', 'fa fa-hourglass-half', '', './modules/interventi/widgets/interventi_da_pianificare.php', 'popup', '', 'Attività in programmazione', '1', '8', NULL); -- Widget attività ancora da programmare -INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class`, `query`, `bgcolor`, `icon`, `print_link`, `more_link`, `more_link_type`, `php_include`, `text`, `enabled`, `order`, `help`) VALUES (NULL, 'Attività confermate', 'stats', '1', 'controller_top', 'col-md-12', 'SELECT COUNT(id) AS dato FROM in_interventi WHERE in_interventi.idstatointervento = (SELECT in_statiintervento.idstatointervento FROM in_statiintervento WHERE in_statiintervento.descrizione=\'In programmazione\') ORDER BY in_interventi.data_richiesta ASC', '#f2bd00', 'fa fa-hourglass-half', '', './modules/interventi/widgets/interventi_confermati.php', 'popup', '', 'Attività confermate', '1', '8', NULL); +INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class`, `query`, `bgcolor`, `icon`, `print_link`, `more_link`, `more_link_type`, `php_include`, `text`, `enabled`, `order`, `help`) VALUES (NULL, 'Attività confermate', 'stats', '1', 'controller_top', 'col-md-12', 'SELECT COUNT(id) AS dato FROM in_interventi WHERE in_interventi.idstatointervento = (SELECT in_statiintervento.idstatointervento FROM in_statiintervento WHERE in_statiintervento.descrizione=\'In programmazione\') ORDER BY in_interventi.data_richiesta ASC', '#f2bd00', 'fa fa-hourglass-half', '', './modules/interventi/widgets/interventi_confermati.php', 'popup', '', 'Attività confermate', '1', '8', NULL); -- Aggiunta ore rimanenti nel contratto per preavviso rinnovo ALTER TABLE `co_contratti` ADD `ore_preavviso_rinnovo` INT(11) NULL AFTER `giorni_preavviso_rinnovo`; @@ -309,8 +309,8 @@ INSERT INTO `zz_widgets` (`id`, `name`, `type`, `id_module`, `location`, `class` INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Contratti'), 'Rinnovabile', 'IF(`co_contratti`.`rinnovabile`=1, \'SI\', \'NO\')', '6', '1', '0', '1', '', '', '0', '0', '0'), (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Contratti'), 'Data conclusione', 'IF(data_conclusione=0, \'\', data_conclusione)', '7', '1', '0', '1', '', '', '0', '0', '0'); -- Aggiunta visualizzazione importo totale negli ordini -UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM ((`or_ordini` INNER JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`) INNER JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`) LEFT OUTER JOIN `or_righe_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine` WHERE 1=1 AND `dir` = \'entrata\' |date_period(`data`)| GROUP BY or_ordini.id HAVING 2=2 ORDER BY `data` DESC, CAST(`numero_esterno` AS UNSIGNED) DESC' WHERE `zz_modules`.`name` = 'Ordini cliente'; -UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM ((`or_ordini` INNER JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`) INNER JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`) LEFT OUTER JOIN `or_righe_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine` WHERE 1=1 AND `dir` = \'uscita\' |date_period(`data`)| GROUP BY or_ordini.id HAVING 2=2 ORDER BY `data` DESC, CAST(`numero_esterno` AS UNSIGNED) DESC' WHERE `zz_modules`.`name` = 'Ordini fornitore'; +UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM ((`or_ordini` INNER JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`) INNER JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`) LEFT OUTER JOIN `or_righe_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine` WHERE 1=1 AND `dir` = \'entrata\' |date_period(`data`)| GROUP BY or_ordini.id HAVING 2=2 ORDER BY `data` DESC, CAST(`numero_esterno` AS UNSIGNED) DESC' WHERE `zz_modules`.`name` = 'Ordini cliente'; +UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM ((`or_ordini` INNER JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`) INNER JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`) LEFT OUTER JOIN `or_righe_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine` WHERE 1=1 AND `dir` = \'uscita\' |date_period(`data`)| GROUP BY or_ordini.id HAVING 2=2 ORDER BY `data` DESC, CAST(`numero_esterno` AS UNSIGNED) DESC' WHERE `zz_modules`.`name` = 'Ordini fornitore'; INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Ordini cliente'), 'Totale', 'SUM(`subtotale` - `sconto`)', '5', '1', '0', '1', '', '', '1', '1', '0'); INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Ordini fornitore'), 'Totale', 'SUM(`subtotale` - `sconto`)', '5', '1', '0', '1', '', '', '1', '1', '0');
'.tr('Descrizione').' '.tr('Q.tà').' '.tr('U.m.').''.tr('Prezzo unitario').''.tr('Costo unitario').' '.tr('Iva').' '.tr('Imponibile').'
'; +
+ '.$descrizione.' + + '.Translator::numberToLocale($riga->qta_rimanente, 'qta').' / '.Translator::numberToLocale($riga->qta, 'qta').' '; - if (empty($r['is_descrizione'])) { + // Unità di misura echo ' - '.Translator::numberToLocale($r['qta'] - $r['qta_evasa'], 'qta').' / '.Translator::numberToLocale($r['qta'], 'qta').''; - } - echo ' + + '.$riga->um.' '; - if (empty($r['is_descrizione'])) { + // Costo unitario echo ' - '.$r['um']; - } - echo ' - + '.moneyFormat($riga->prezzo_unitario_vendita); - // prezzo di vendita unitario - echo ' - '; - if (empty($r['is_descrizione'])) { - echo ' - '.moneyFormat($r['subtotale'] / $r['qta']); - - if (abs($r['sconto_unitario']) > 0) { - $text = $r['sconto_unitario'] > 0 ? tr('sconto _TOT_ _TYPE_') : tr('maggiorazione _TOT_ _TYPE_'); + if (abs($riga->sconto_unitario) > 0) { + $text = $riga->sconto_unitario > 0 ? tr('sconto _TOT_ _TYPE_') : tr('maggiorazione _TOT_ _TYPE_'); echo '
'.replace($text, [ - '_TOT_' => Translator::numberToLocale(abs($r['sconto_unitario'])), - '_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : currency()), + '_TOT_' => Translator::numberToLocale(abs($riga->sconto_unitario)), + '_TYPE_' => ($riga->tipo_sconto == 'PRC' ? '%' : currency()), ]).''; } - } - echo ' + echo'
'; - if (empty($r['is_descrizione'])) { + // IVA echo ' - '.moneyFormat($r['iva']).' -
'.$r['desc_iva'].''; - } - echo' +
+ '.moneyFormat($riga->iva).'
+ '.$riga->aliquota->descrizione.(($riga->aliquota->esente) ? ' ('.$riga->aliquota->codice_natura_fe.')' : null).'
'; - if (empty($r['is_descrizione'])) { + // Imponibile echo ' - '.moneyFormat($r['subtotale'] - $r['sconto']); + + '.moneyFormat($riga->imponibile_scontato).' + '; if ($record['stato'] != 'Pagato') { - echo " -
- - - - + echo ' + + + + -
- - - +
+ +
- "; + '; } echo ' @@ -131,6 +117,19 @@ foreach ($rs as $r) { echo '
'.tr('Imponibile', [], ['upper' => true]).': - '.moneyFormat($imponibile, 2).' + + '.moneyFormat($preventivo->imponibile, 2).'
'.tr('Sconto/maggiorazione', [], ['upper' => true]).': - '.moneyFormat($sconto, 2).' + + '.moneyFormat($preventivo->sconto, 2).'
@@ -179,22 +181,22 @@ if (!empty($sconto)) { echo '
- '.tr('IVA', [], ['upper' => true]).': + '.tr('Iva', [], ['upper' => true]).': - '.moneyFormat($iva, 2).' + + '.moneyFormat($preventivo->iva, 2).'
'.tr('Totale', [], ['upper' => true]).': - '.moneyFormat($totale, 2).' + + '.moneyFormat($preventivo->totale, 2).'