From 580a2e71d8879bac4834e0de2d83574b5be09ef0 Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Thu, 4 Oct 2018 17:25:42 +0200 Subject: [PATCH] Gestione seriali integrata nelle classi --- composer.json | 5 +- lib/functions.js | 6 - modules/fatture/actions.php | 159 ++++---------------- modules/fatture/edit.php | 17 ++- modules/fatture/row-add.php | 6 +- modules/fatture/row-edit.php | 6 +- modules/fatture/src/Articolo.php | 5 + modules/interventi/actions.php | 2 +- modules/interventi/src/Articolo.php | 5 + plugins/importPA/src/FatturaElettronica.php | 2 +- src/base/Article.php | 56 ++++++- src/base/Row.php | 2 +- 12 files changed, 117 insertions(+), 154 deletions(-) diff --git a/composer.json b/composer.json index f07e7e6c9..8740ee18e 100644 --- a/composer.json +++ b/composer.json @@ -69,6 +69,9 @@ "sort-packages": true, "optimize-autoloader": true, "apcu-autoloader": true, - "prefer-stable": true + "prefer-stable": true, + "platform": { + "php": "5.6.4" + } } } diff --git a/lib/functions.js b/lib/functions.js index 6dbae0fc8..633f4a586 100644 --- a/lib/functions.js +++ b/lib/functions.js @@ -432,21 +432,15 @@ function launch_modal(title, href, init_modal, id) { id = '#bs-popup'; } - if (init_modal == null) { init_modal = 1; } - $('html').addClass('modal-open'); - $(id).on('hidden.bs.modal', function () { - if ($('.modal-backdrop').length < 1) { - $('html').removeClass('modal-open'); $(this).html(''); $(this).data('modal', null); } - }); // Lettura contenuto div diff --git a/modules/fatture/actions.php b/modules/fatture/actions.php index 1f22c5e2e..27e84c484 100644 --- a/modules/fatture/actions.php +++ b/modules/fatture/actions.php @@ -477,15 +477,19 @@ switch (post('op')) { } break; - case 'add_articolo': + case 'manage_articolo': + if (post('idriga') != null) { + $articolo = Articolo::find(post('idriga')); + } else { + $originale = ArticoloOriginale::find(post('idarticolo')); + $articolo = Articolo::make($fattura, $originale); + } + $qta = post('qta'); if (!empty($record['is_reversed'])) { $qta = -$qta; } - $originale = ArticoloOriginale::find(post('idarticolo')); - $articolo = Articolo::make($fattura, $originale); - $articolo->descrizione = post('descrizione'); $um = post('um'); if (!empty($um)) { @@ -504,26 +508,36 @@ switch (post('op')) { } $articolo->costo_unitario = post('prezzo'); - $articolo->qta = $qta; $articolo->sconto_unitario = post('sconto'); $articolo->tipo_sconto = post('tipo_sconto'); - $articolo->save(); + try { + $articolo->qta = $qta; + } catch(UnexpectedValueException $e) { + flash()->error(tr('Alcuni serial number sono già stati utilizzati!')); + } - ricalcola_costiagg_fattura($id_record); + $articolo->save(); flash()->info(tr('Articolo aggiunto!')); + // Ricalcolo inps, ritenuta e bollo + ricalcola_costiagg_fattura($id_record); + break; - case 'add_riga': + case 'manage_riga': + if (post('idriga') != null) { + $riga = Riga::find(post('idriga')); + } else { + $riga = Riga::make($fattura); + } + $qta = post('qta'); if (!empty($record['is_reversed'])) { $qta = -$qta; } - $riga = Riga::make($fattura); - $riga->descrizione = post('descrizione'); $um = post('um'); if (!empty($um)) { @@ -548,14 +562,18 @@ switch (post('op')) { $riga->save(); - flash()->info(tr('Riga aggiunta!')); + if (post('idriga') != null) { + flash()->info(tr('Riga modificata!')); + } else { + flash()->info(tr('Riga aggiunta!')); + } // Ricalcolo inps, ritenuta e bollo ricalcola_costiagg_fattura($id_record); break; - case 'add_descrizione': + case 'manage_descrizione': $riga = Descrizione::make($fattura); $riga->descrizione = post('descrizione'); $riga->save(); @@ -564,112 +582,6 @@ switch (post('op')) { break; - case 'editriga': - if (post('idriga') !== null) { - // Selezione costi da intervento - $idriga = post('idriga'); - $descrizione = post('descrizione'); - $idiva = post('idiva'); - $idconto = post('idconto'); - $um = post('um'); - $calcolo_ritenutaacconto = post('calcolo_ritenuta_acconto'); - - $qta = post('qta'); - if (!empty($record['is_reversed'])) { - $qta = -$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, - ]); - - $subtot = $prezzo * $qta; - - // Lettura idarticolo dalla riga documento - $rs = $dbo->fetchArray('SELECT * FROM co_righe_documenti WHERE id='.prepare($idriga)); - $idarticolo = $rs[0]['idarticolo']; - $idddt = $rs[0]['idddt']; - $idordine = $rs[0]['idordine']; - $old_qta = $rs[0]['qta']; - $iddocumento = $rs[0]['iddocumento']; - $abilita_serial = $rs[0]['abilita_serial']; - $is_descrizione = $rs[0]['is_descrizione']; - - // Controllo per gestire i serial - if (!empty($idarticolo)) { - if (!controlla_seriali('id_riga_documento', $idriga, $old_qta, $qta, $dir)) { - flash()->error(tr('Alcuni serial number sono già stati utilizzati!')); - - return; - } - } - - // Se c'è un collegamento ad un ddt, aggiorno la quantità evasa - if (!empty($idddt)) { - $dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idddt='.prepare($idddt).' AND idiva='.prepare($rs[0]['idiva'])); - } - - // Se c'è un collegamento ad un ordine, aggiorno la quantità evasa - if (!empty($idddt)) { - $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idordine='.prepare($idordine).' AND idiva='.prepare($rs[0]['idiva'])); - } - - // Calcolo iva - $query = 'SELECT * 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']; - - // Calcolo rivalsa inps - $query = 'SELECT * FROM co_rivalsainps WHERE id='.prepare(post('id_rivalsa_inps')); - $rs = $dbo->fetchArray($query); - $rivalsainps = ($prezzo * $qta - $sconto) / 100 * $rs[0]['percentuale']; - - // Calcolo ritenuta d'acconto - $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(post('id_ritenuta_acconto')); - $rs = $dbo->fetchArray($query); - if ($calcolo_ritenutaacconto == 'Imponibile') { - $ritenutaacconto = (($prezzo * $qta) - $sconto) / 100 * $rs[0]['percentuale']; - } else { - $ritenutaacconto = (($prezzo * $qta) - $sconto + $rivalsainps) / 100 * $rs[0]['percentuale']; - } - - if ($is_descrizione == 0) { - // Modifica riga generica sul documento - $query = 'UPDATE co_righe_documenti SET idconto='.prepare($idconto).', 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).', idritenutaacconto='.prepare(post('id_ritenuta_acconto')).', ritenutaacconto='.prepare($ritenutaacconto).', idrivalsainps='.prepare(post('id_rivalsa_inps')).', rivalsainps='.prepare($rivalsainps).', calcolo_ritenutaacconto='.prepare(post(calcolo_ritenutaacconto)).', qta='.prepare($qta).' WHERE id='.prepare($idriga).' AND iddocumento='.prepare($iddocumento); - } else { - // Modifica riga descrizione sul documento - $query = 'UPDATE co_righe_documenti SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga).' AND iddocumento='.prepare($iddocumento); - } - if ($dbo->query($query)) { - // Modifica per gestire i serial - if (!empty($idarticolo)) { - $new_qta = $qta - $old_qta; - $new_qta = ($dir == 'entrata') ? -$new_qta : $new_qta; - add_movimento_magazzino($idarticolo, $new_qta, ['iddocumento' => $id_record]); - } - - flash()->info(tr('Riga modificata!')); - - // Ricalcolo inps, ritenuta e bollo - if ($dir == 'entrata') { - ricalcola_costiagg_fattura($id_record); - } else { - ricalcola_costiagg_fattura($id_record); - } - } - } - break; - // Creazione fattura da ddt case 'fattura_da_ddt': $totale_fattura = 0.00; @@ -1152,17 +1064,12 @@ switch (post('op')) { break; case 'add_serial': - $idriga = post('idriga'); - $idarticolo = post('idarticolo'); + $articolo = Articolo::find(post('idriga')); $serials = (array) post('serial'); - foreach ($serials as $key => $value) { - if (empty($value)) { - unset($serials[$key]); - } - } - $dbo->sync('mg_prodotti', ['id_riga_documento' => $idriga, 'dir' => $dir, 'id_articolo' => $idarticolo], ['serial' => $serials]); + $articolo->serials = $serials; + $articolo->save(); break; diff --git a/modules/fatture/edit.php b/modules/fatture/edit.php index 2f21cb891..9c1d5ae5a 100644 --- a/modules/fatture/edit.php +++ b/modules/fatture/edit.php @@ -442,7 +442,11 @@ if (!empty($note_accredito)) { $(".btn-sm[data-toggle=\"tooltip\"]").each(function() { - $(this).on("click", function(){ + $(this).on("click", function() { + if(!content_was_modified) { + return; + } + form = $("#edit-form"); btn = $(this); @@ -478,16 +482,13 @@ $(".btn-sm[data-toggle=\"tooltip\"]").each(function() { } else { swal({ type: "error", - text: "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente.').'", title: "'.tr('Errore').'", - onClose: hide_popup + text: "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente').'.", }); - function hide_popup(){ - $("#bs-popup").modal("hide"); - - form.parsley().validate(); - } + $("#bs-popup").one("show.bs.modal", function (e) { + return e.preventDefault(); + }); buttonRestore(btn, restore); } diff --git a/modules/fatture/row-add.php b/modules/fatture/row-add.php index 8022a658f..fa0b1d158 100644 --- a/modules/fatture/row-add.php +++ b/modules/fatture/row-add.php @@ -21,7 +21,7 @@ if (empty($idconto)) { // Impostazioni per la gestione $options = [ - 'op' => 'add_riga', + 'op' => 'manage_riga', 'action' => 'add', 'dir' => $dir, 'conti' => $conti, @@ -62,11 +62,11 @@ $file = 'riga'; if (get('is_descrizione') !== null) { $file = 'descrizione'; - $options['op'] = 'add_descrizione'; + $options['op'] = 'manage_descrizione'; } elseif (get('is_articolo') !== null) { $file = 'articolo'; - $options['op'] = 'add_articolo'; + $options['op'] = 'manage_articolo'; } echo App::load($file.'.php', $result, $options); diff --git a/modules/fatture/row-edit.php b/modules/fatture/row-edit.php index 9e6bf5585..c61186fa7 100644 --- a/modules/fatture/row-edit.php +++ b/modules/fatture/row-edit.php @@ -16,7 +16,7 @@ if ($module['name'] == 'Fatture di vendita') { // Impostazioni per la gestione $options = [ - 'op' => 'editriga', + 'op' => 'manage_riga', 'action' => 'edit', 'dir' => $dir, 'conti' => $conti, @@ -34,8 +34,12 @@ $result['prezzo'] = $rsr[0]['subtotale'] / $rsr[0]['qta']; $file = 'riga'; if (!empty($result['is_descrizione'])) { $file = 'descrizione'; + + $options['op'] = 'manage_articolo'; } elseif (!empty($result['idarticolo'])) { $file = 'articolo'; + + $options['op'] = 'manage_articolo'; } echo App::load($file.'.php', $result, $options); diff --git a/modules/fatture/src/Articolo.php b/modules/fatture/src/Articolo.php index c7f8815a0..25e74ada9 100644 --- a/modules/fatture/src/Articolo.php +++ b/modules/fatture/src/Articolo.php @@ -57,6 +57,11 @@ class Articolo extends Article ]); } + public function getDirection() + { + return $this->fattura()->first()->tipo()->first()->dir; + } + public function fattura() { return $this->belongsTo(Fattura::class, 'iddocumento'); diff --git a/modules/interventi/actions.php b/modules/interventi/actions.php index d5494165d..936b71dc8 100644 --- a/modules/interventi/actions.php +++ b/modules/interventi/actions.php @@ -545,7 +545,7 @@ switch (post('op')) { $serials = array_slice($serials, 0, $qta); } - $articolo->setSerials($serials); + $articolo->serials = $serials; } link_componente_to_articolo($id_record, $idimpianto, $idarticolo, $qta); diff --git a/modules/interventi/src/Articolo.php b/modules/interventi/src/Articolo.php index f129495b0..d64d8c3ac 100644 --- a/modules/interventi/src/Articolo.php +++ b/modules/interventi/src/Articolo.php @@ -77,6 +77,11 @@ class Articolo extends Article } } + public function getDirection() + { + return 'entrata'; + } + public function fixIvaIndetraibile() { } diff --git a/plugins/importPA/src/FatturaElettronica.php b/plugins/importPA/src/FatturaElettronica.php index 9a05e44af..6df3e16a8 100644 --- a/plugins/importPA/src/FatturaElettronica.php +++ b/plugins/importPA/src/FatturaElettronica.php @@ -141,7 +141,7 @@ class FatturaElettronica } $sede->save(); - return $anagrafica->id; + return $anagrafica; } public function getRighe() diff --git a/src/base/Article.php b/src/base/Article.php index 9a9ab7c36..ef8a17c91 100644 --- a/src/base/Article.php +++ b/src/base/Article.php @@ -4,6 +4,7 @@ namespace Base; use Modules\Articoli\Articolo as Original; use Illuminate\Database\Eloquent\Builder; +use UnexpectedValueException; abstract class Article extends Row { @@ -32,17 +33,18 @@ abstract class Article extends Row } abstract public function movimenta($qta); + abstract public function getDirection(); /** * Imposta i seriali collegati all'articolo del documento. * * @param array $serials */ - public function setSerials($serials) + public function setSerialsAttribute($serials) { database()->sync('mg_prodotti', [ 'id_riga_'.$this->serialRowID => $this->id, - 'dir' => 'entrata', + 'dir' => $this->getDirection(), 'id_articolo' => $this->idarticolo, ], [ 'serial' => array_clean($serials), @@ -61,9 +63,48 @@ abstract class Article extends Row } // Individuazione dei seriali - $list = database()->fetchArray('SELECT serial FROM mg_prodotti WHERE serial IS NOT NULL AND id_riga_'.$this->serialRowID.' = '.prepare($this->id)); + $results = database()->fetchArray('SELECT serial FROM mg_prodotti WHERE serial IS NOT NULL AND id_riga_'.$this->serialRowID.' = '.prepare($this->id)); - return array_column($list, 'serial'); + return array_column($results, 'serial'); + } + + protected function usedSerials() + { + if ($this->getDirection() == 'uscita') { + $results = database()->fetchArray("SELECT serial FROM mg_prodotti WHERE serial IN (SELECT DISTINCT serial FROM mg_prodotti WHERE dir = 'entrata') AND serial IS NOT NULL AND id_riga_".$this->serialRowID.' = '.prepare($this->id)); + + return array_column($results, 'serial'); + } + + return []; + } + + protected function cleanupSerials($new_qta) + { + // Se la nuova quantità è minore della precedente + if ($this->qta > $new_qta) { + $seriali_usati = $this->usedSerials(); + $count_seriali_usati = count($seriali_usati); + + // Controllo sulla possibilità di rimuovere i seriali (se non utilizzati da documenti di vendita) + if ($this->getDirection() == 'uscita' && $new_qta < $count_seriali_usati) { + return false; + } else { + // Controllo sul numero di seriali effettivi da rimuovere + $seriali = $this->serials; + + if ($new_qta < count($seriali)) { + $rimovibili = array_diff($seriali, $seriali_usati); + + // Rimozione dei seriali aggiuntivi + $serials = array_slice($rimovibili, 0, $new_qta - $count_seriali_usati); + + $this->serials = array_merge($seriali_usati, $serials); + } + } + } + + return true; } /** @@ -73,11 +114,14 @@ abstract class Article extends Row */ public function setQtaAttribute($value) { + if (!$this->cleanupSerials($value)) { + throw new UnexpectedValueException(); + } + $previous = $this->qta; + $diff = $value - $previous; parent::setQtaAttribute($value); - - $diff = $value - $previous; $this->movimenta($diff); $database = database(); diff --git a/src/base/Row.php b/src/base/Row.php index fcf656839..5aceddcdf 100644 --- a/src/base/Row.php +++ b/src/base/Row.php @@ -14,7 +14,7 @@ abstract class Row extends Description if (!$bypass) { static::addGlobalScope('rows', function (Builder $builder) { - $builder->whereNull('idarticolo')->where('idarticolo', '=', 0); + $builder->whereNull('idarticolo')->orWhere('idarticolo', '=', 0); }); } }