diff --git a/update/v2_4_10/Article.php b/update/v2_4_10/Article.php new file mode 100644 index 000000000..81f0702b4 --- /dev/null +++ b/update/v2_4_10/Article.php @@ -0,0 +1,215 @@ +articolo()->associate($articolo); + + $model->descrizione = $articolo->descrizione; + $model->abilita_serial = $articolo->abilita_serial; + $model->um = $articolo->um; + + return $model; + } + + abstract public function movimenta($qta); + + abstract public function getDirection(); + + /** + * Imposta i seriali collegati all'articolo. + * + * @param array $serials + */ + public function setSerialsAttribute($serials) + { + $serials = array_clean($serials); + + database()->sync('mg_prodotti', [ + 'id_riga_'.$this->serialRowID => $this->id, + 'dir' => $this->getDirection(), + 'id_articolo' => $this->idarticolo, + ], [ + 'serial' => $serials, + ]); + + $this->serialsList = $serials; + } + + /** + * Rimuove i seriali collegati all'articolo. + * + * @param array $serials + */ + public function removeSerials($serials) + { + database()->detach('mg_prodotti', [ + 'id_riga_'.$this->serialRowID => $this->id, + 'dir' => $this->getDirection(), + 'id_articolo' => $this->idarticolo, + ], [ + 'serial' => array_clean($serials), + ]); + + $this->serialsList = null; + } + + /** + * Restituisce l'elenco dei seriali collegati all'articolo del documento. + * + * @return array + */ + public function getSerialsAttribute() + { + if (empty($this->abilita_serial)) { + return []; + } + + if (!isset($this->serialsList)) { + // Individuazione dei seriali + $results = database()->fetchArray('SELECT serial FROM mg_prodotti WHERE serial IS NOT NULL AND id_riga_'.$this->serialRowID.' = '.prepare($this->id)); + + $this->serialsList = array_column($results, 'serial'); + } + + return $this->serialsList; + } + + /** + * Restituisce il numero di seriali mancanti per il completamento dell'articolo. + * + * @return float + */ + public function getMissingSerialsAttribute() + { + return $this->qta - count($this->serials); + } + + /** + * Modifica la quantità dell'articolo e movimenta automaticamente il magazzino. + * + * @param float $value + */ + public function setQtaAttribute($value) + { + if (!$this->cleanupSerials($value)) { + throw new UnexpectedValueException(); + } + + $diff = parent::setQtaAttribute($value); + + if ($this->abilita_movimentazione) { + $this->qta_movimentazione += $diff; + } + } + + public function articolo() + { + return $this->belongsTo(Original::class, 'idarticolo'); + } + + public function movimentazione($value = true) + { + $this->abilita_movimentazione = $value; + } + + /** + * Salva l'articolo, eventualmente movimentandone il magazzino. + * + * @param array $options + * + * @return bool + */ + public function save(array $options = []) + { + if (!empty($this->qta_movimentazione)) { + $this->movimenta($this->qta_movimentazione); + } + + return parent::save($options); + } + + protected static function boot() + { + parent::boot(true); + + static::addGlobalScope('articles', function (Builder $builder) { + $builder->whereNotNull('idarticolo')->where('idarticolo', '<>', 0); + }); + } + + 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; + } + + protected function customInitCopiaIn($original) + { + $this->articolo()->associate($original->articolo); + } + + protected function customBeforeDataCopiaIn($original) + { + $this->movimentazione(false); + + parent::customBeforeDataCopiaIn($original); + } + + protected function customAfterDataCopiaIn($original) + { + $this->movimentazione(true); + + parent::customAfterDataCopiaIn($original); + } +} diff --git a/update/v2_4_10/Components/Articolo.php b/update/v2_4_10/Components/Articolo.php new file mode 100644 index 000000000..5f3bed972 --- /dev/null +++ b/update/v2_4_10/Components/Articolo.php @@ -0,0 +1,64 @@ +idddt) || !empty($this->idintervento)) { + return; + } + + $fattura = $this->fattura; + $tipo = $fattura->tipo; + + $numero = $fattura->numero_esterno ?: $fattura->numero; + $data = $fattura->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' => $fattura->id, + ]); + } + + public function getDirection() + { + return $this->fattura->tipo->dir; + } +} diff --git a/update/v2_4_10/Components/Descrizione.php b/update/v2_4_10/Components/Descrizione.php new file mode 100644 index 000000000..5d4c78375 --- /dev/null +++ b/update/v2_4_10/Components/Descrizione.php @@ -0,0 +1,27 @@ +hasMany(Riga::class, 'iddocumento'); + return $this->hasMany(Components\Riga::class, 'iddocumento'); } public function sconti() @@ -262,7 +262,7 @@ class Fattura extends Document public function rigaBollo() { - return $this->hasOne(Riga::class, 'iddocumento')->where('id', $this->id_riga_bollo); + return $this->hasOne(Components\Riga::class, 'iddocumento')->where('id', $this->id_riga_bollo); } // Metodi generali @@ -566,7 +566,7 @@ class Fattura extends Document // Creazione riga bollo se non presente if (empty($riga)) { - $riga = Riga::build($this); + $riga = Components\Riga::build($this); $riga->save(); $this->id_riga_bollo = $riga->id;