Gestione seriali integrata nelle classi

This commit is contained in:
Thomas Zilio 2018-10-04 17:25:42 +02:00
parent f33d31a57e
commit 580a2e71d8
12 changed files with 117 additions and 154 deletions

View File

@ -69,6 +69,9 @@
"sort-packages": true, "sort-packages": true,
"optimize-autoloader": true, "optimize-autoloader": true,
"apcu-autoloader": true, "apcu-autoloader": true,
"prefer-stable": true "prefer-stable": true,
"platform": {
"php": "5.6.4"
}
} }
} }

View File

@ -432,21 +432,15 @@ function launch_modal(title, href, init_modal, id) {
id = '#bs-popup'; id = '#bs-popup';
} }
if (init_modal == null) { if (init_modal == null) {
init_modal = 1; init_modal = 1;
} }
$('html').addClass('modal-open');
$(id).on('hidden.bs.modal', function () { $(id).on('hidden.bs.modal', function () {
if ($('.modal-backdrop').length < 1) { if ($('.modal-backdrop').length < 1) {
$('html').removeClass('modal-open');
$(this).html(''); $(this).html('');
$(this).data('modal', null); $(this).data('modal', null);
} }
}); });
// Lettura contenuto div // Lettura contenuto div

View File

@ -477,15 +477,19 @@ switch (post('op')) {
} }
break; 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'); $qta = post('qta');
if (!empty($record['is_reversed'])) { if (!empty($record['is_reversed'])) {
$qta = -$qta; $qta = -$qta;
} }
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::make($fattura, $originale);
$articolo->descrizione = post('descrizione'); $articolo->descrizione = post('descrizione');
$um = post('um'); $um = post('um');
if (!empty($um)) { if (!empty($um)) {
@ -504,26 +508,36 @@ switch (post('op')) {
} }
$articolo->costo_unitario = post('prezzo'); $articolo->costo_unitario = post('prezzo');
$articolo->qta = $qta;
$articolo->sconto_unitario = post('sconto'); $articolo->sconto_unitario = post('sconto');
$articolo->tipo_sconto = post('tipo_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!')); flash()->info(tr('Articolo aggiunto!'));
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_fattura($id_record);
break; break;
case 'add_riga': case 'manage_riga':
if (post('idriga') != null) {
$riga = Riga::find(post('idriga'));
} else {
$riga = Riga::make($fattura);
}
$qta = post('qta'); $qta = post('qta');
if (!empty($record['is_reversed'])) { if (!empty($record['is_reversed'])) {
$qta = -$qta; $qta = -$qta;
} }
$riga = Riga::make($fattura);
$riga->descrizione = post('descrizione'); $riga->descrizione = post('descrizione');
$um = post('um'); $um = post('um');
if (!empty($um)) { if (!empty($um)) {
@ -548,14 +562,18 @@ switch (post('op')) {
$riga->save(); $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 // Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_fattura($id_record); ricalcola_costiagg_fattura($id_record);
break; break;
case 'add_descrizione': case 'manage_descrizione':
$riga = Descrizione::make($fattura); $riga = Descrizione::make($fattura);
$riga->descrizione = post('descrizione'); $riga->descrizione = post('descrizione');
$riga->save(); $riga->save();
@ -564,112 +582,6 @@ switch (post('op')) {
break; 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 // Creazione fattura da ddt
case 'fattura_da_ddt': case 'fattura_da_ddt':
$totale_fattura = 0.00; $totale_fattura = 0.00;
@ -1152,17 +1064,12 @@ switch (post('op')) {
break; break;
case 'add_serial': case 'add_serial':
$idriga = post('idriga'); $articolo = Articolo::find(post('idriga'));
$idarticolo = post('idarticolo');
$serials = (array) post('serial'); $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; break;

View File

@ -442,7 +442,11 @@ if (!empty($note_accredito)) {
$(".btn-sm[data-toggle=\"tooltip\"]").each(function() { $(".btn-sm[data-toggle=\"tooltip\"]").each(function() {
$(this).on("click", function(){ $(this).on("click", function() {
if(!content_was_modified) {
return;
}
form = $("#edit-form"); form = $("#edit-form");
btn = $(this); btn = $(this);
@ -478,16 +482,13 @@ $(".btn-sm[data-toggle=\"tooltip\"]").each(function() {
} else { } else {
swal({ swal({
type: "error", type: "error",
text: "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente.').'",
title: "'.tr('Errore').'", title: "'.tr('Errore').'",
onClose: hide_popup text: "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente').'.",
}); });
function hide_popup(){ $("#bs-popup").one("show.bs.modal", function (e) {
$("#bs-popup").modal("hide"); return e.preventDefault();
});
form.parsley().validate();
}
buttonRestore(btn, restore); buttonRestore(btn, restore);
} }

View File

@ -21,7 +21,7 @@ if (empty($idconto)) {
// Impostazioni per la gestione // Impostazioni per la gestione
$options = [ $options = [
'op' => 'add_riga', 'op' => 'manage_riga',
'action' => 'add', 'action' => 'add',
'dir' => $dir, 'dir' => $dir,
'conti' => $conti, 'conti' => $conti,
@ -62,11 +62,11 @@ $file = 'riga';
if (get('is_descrizione') !== null) { if (get('is_descrizione') !== null) {
$file = 'descrizione'; $file = 'descrizione';
$options['op'] = 'add_descrizione'; $options['op'] = 'manage_descrizione';
} elseif (get('is_articolo') !== null) { } elseif (get('is_articolo') !== null) {
$file = 'articolo'; $file = 'articolo';
$options['op'] = 'add_articolo'; $options['op'] = 'manage_articolo';
} }
echo App::load($file.'.php', $result, $options); echo App::load($file.'.php', $result, $options);

View File

@ -16,7 +16,7 @@ if ($module['name'] == 'Fatture di vendita') {
// Impostazioni per la gestione // Impostazioni per la gestione
$options = [ $options = [
'op' => 'editriga', 'op' => 'manage_riga',
'action' => 'edit', 'action' => 'edit',
'dir' => $dir, 'dir' => $dir,
'conti' => $conti, 'conti' => $conti,
@ -34,8 +34,12 @@ $result['prezzo'] = $rsr[0]['subtotale'] / $rsr[0]['qta'];
$file = 'riga'; $file = 'riga';
if (!empty($result['is_descrizione'])) { if (!empty($result['is_descrizione'])) {
$file = 'descrizione'; $file = 'descrizione';
$options['op'] = 'manage_articolo';
} elseif (!empty($result['idarticolo'])) { } elseif (!empty($result['idarticolo'])) {
$file = 'articolo'; $file = 'articolo';
$options['op'] = 'manage_articolo';
} }
echo App::load($file.'.php', $result, $options); echo App::load($file.'.php', $result, $options);

View File

@ -57,6 +57,11 @@ class Articolo extends Article
]); ]);
} }
public function getDirection()
{
return $this->fattura()->first()->tipo()->first()->dir;
}
public function fattura() public function fattura()
{ {
return $this->belongsTo(Fattura::class, 'iddocumento'); return $this->belongsTo(Fattura::class, 'iddocumento');

View File

@ -545,7 +545,7 @@ switch (post('op')) {
$serials = array_slice($serials, 0, $qta); $serials = array_slice($serials, 0, $qta);
} }
$articolo->setSerials($serials); $articolo->serials = $serials;
} }
link_componente_to_articolo($id_record, $idimpianto, $idarticolo, $qta); link_componente_to_articolo($id_record, $idimpianto, $idarticolo, $qta);

View File

@ -77,6 +77,11 @@ class Articolo extends Article
} }
} }
public function getDirection()
{
return 'entrata';
}
public function fixIvaIndetraibile() public function fixIvaIndetraibile()
{ {
} }

View File

@ -141,7 +141,7 @@ class FatturaElettronica
} }
$sede->save(); $sede->save();
return $anagrafica->id; return $anagrafica;
} }
public function getRighe() public function getRighe()

View File

@ -4,6 +4,7 @@ namespace Base;
use Modules\Articoli\Articolo as Original; use Modules\Articoli\Articolo as Original;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use UnexpectedValueException;
abstract class Article extends Row abstract class Article extends Row
{ {
@ -32,17 +33,18 @@ abstract class Article extends Row
} }
abstract public function movimenta($qta); abstract public function movimenta($qta);
abstract public function getDirection();
/** /**
* Imposta i seriali collegati all'articolo del documento. * Imposta i seriali collegati all'articolo del documento.
* *
* @param array $serials * @param array $serials
*/ */
public function setSerials($serials) public function setSerialsAttribute($serials)
{ {
database()->sync('mg_prodotti', [ database()->sync('mg_prodotti', [
'id_riga_'.$this->serialRowID => $this->id, 'id_riga_'.$this->serialRowID => $this->id,
'dir' => 'entrata', 'dir' => $this->getDirection(),
'id_articolo' => $this->idarticolo, 'id_articolo' => $this->idarticolo,
], [ ], [
'serial' => array_clean($serials), 'serial' => array_clean($serials),
@ -61,9 +63,48 @@ abstract class Article extends Row
} }
// Individuazione dei seriali // 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) public function setQtaAttribute($value)
{ {
if (!$this->cleanupSerials($value)) {
throw new UnexpectedValueException();
}
$previous = $this->qta; $previous = $this->qta;
$diff = $value - $previous;
parent::setQtaAttribute($value); parent::setQtaAttribute($value);
$diff = $value - $previous;
$this->movimenta($diff); $this->movimenta($diff);
$database = database(); $database = database();

View File

@ -14,7 +14,7 @@ abstract class Row extends Description
if (!$bypass) { if (!$bypass) {
static::addGlobalScope('rows', function (Builder $builder) { static::addGlobalScope('rows', function (Builder $builder) {
$builder->whereNull('idarticolo')->where('idarticolo', '=', 0); $builder->whereNull('idarticolo')->orWhere('idarticolo', '=', 0);
}); });
} }
} }