feat: gestione sottoscorta per sede e aggiornamento quantità da plugin Giacenze
This commit is contained in:
parent
6623903b30
commit
72e1be49c7
|
@ -61,7 +61,6 @@ switch (post('op')) {
|
|||
$articolo->name = post('descrizione');
|
||||
}
|
||||
$articolo->barcode = post('barcode');
|
||||
$articolo->threshold_qta = post('threshold_qta');
|
||||
$articolo->coefficiente = post('coefficiente');
|
||||
$articolo->idiva_vendita = post('idiva_vendita');
|
||||
$articolo->prezzo_acquisto = post('prezzo_acquisto');
|
||||
|
@ -138,7 +137,6 @@ switch (post('op')) {
|
|||
$articolo->id_sottocategoria = post('subcategoria');
|
||||
$articolo->abilita_serial = post('abilita_serial');
|
||||
$articolo->ubicazione = post('ubicazione');
|
||||
$articolo->threshold_qta = post('threshold_qta');
|
||||
$articolo->coefficiente = post('coefficiente');
|
||||
$articolo->idiva_vendita = post('idiva_vendita');
|
||||
$articolo->prezzo_acquisto = post('prezzo_acquisto');
|
||||
|
@ -405,6 +403,57 @@ switch (post('op')) {
|
|||
]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'update_soglia_minima':
|
||||
$has_soglia_minima = $dbo->selectOne('mg_scorte_sedi', '*', ['id_articolo' => $id_record, 'id_sede' => post('id_sede')])['threshold_qta'];
|
||||
|
||||
if ($has_soglia_minima) {
|
||||
if (post('threshold_qta')) {
|
||||
$dbo->update('mg_scorte_sedi', [
|
||||
'threshold_qta' => post('threshold_qta'),
|
||||
],[
|
||||
'id_articolo' => $id_record,
|
||||
'id_sede' => post('id_sede'),
|
||||
]);
|
||||
} else {
|
||||
$dbo->delete('mg_scorte_sedi', [
|
||||
'id_articolo' => $id_record,
|
||||
'id_sede' => post('id_sede'),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$dbo->insert('mg_scorte_sedi', [
|
||||
'id_articolo' => $id_record,
|
||||
'id_sede' => post('id_sede'),
|
||||
'threshold_qta' => post('threshold_qta'),
|
||||
]);
|
||||
}
|
||||
|
||||
flash()->info(tr('Soglia minima aggiornata!'));
|
||||
|
||||
break;
|
||||
|
||||
case 'update_giacenza':
|
||||
$data = date('Y-m-d');
|
||||
|
||||
$qta = post('qta') ?: 0;
|
||||
$new_qta = post('new_qta') ?: 0;
|
||||
|
||||
$qta_movimento = $new_qta - $qta;
|
||||
if ($qta_movimento > 0) {
|
||||
$descrizione = tr('Carico manuale');
|
||||
} elseif ($qta_movimento < 0) {
|
||||
$descrizione = tr('Scarico manuale');
|
||||
}
|
||||
|
||||
// Registrazione del movimento con variazione della quantità
|
||||
$articolo->movimenta($qta_movimento, $descrizione, $data, 1, [
|
||||
'idsede' => post('id_sede')
|
||||
]);
|
||||
|
||||
flash()->info(tr('Giacenza aggiornata!'));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ $aliquota_predefinita = floatval(Aliquota::find($iva_predefinita)->percentuale);
|
|||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "decimals": "qta", "min-value": "undefined" ]}
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Abilita serial number'); ?>", "name": "abilita_serial_add", "help": "<?php echo tr('Abilita serial number in fase di aggiunta articolo in fattura o ddt'); ?>", "value": "<?php echo setting('Serial number abilitato di default'); ?>","placeholder": "<?php echo tr('Serial number'); ?>" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -128,12 +128,6 @@ $aliquota_predefinita = floatval(Aliquota::find($iva_predefinita)->percentuale);
|
|||
<input type="hidden" name="aliquota_predefinita" value="<?php echo $aliquota_predefinita; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "<?php echo tr('Abilita serial number'); ?>", "name": "abilita_serial_add", "help": "<?php echo tr('Abilita serial number in fase di aggiunta articolo in fattura o ddt'); ?>", "value": "<?php echo setting('Serial number abilitato di default'); ?>","placeholder": "<?php echo tr('Serial number'); ?>" ]}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -180,13 +180,9 @@ use Modules\Iva\Aliquota;
|
|||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-12">
|
||||
{[ "type": "number", "label": "<?php echo tr('Prezzo di acquisto'); ?>", "name": "prezzo_acquisto", "value": "$prezzo_acquisto$", "icon-after": "<?php echo currency(); ?>", "help": "<?php echo tr('Prezzo di acquisto previsto per i fornitori i cui dati non sono stati inseriti nel plugin Fornitori'); ?>." ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "value": "$threshold_qta$", "decimals": "qta", "min-value": "undefined" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
|
@ -246,7 +246,8 @@ echo '
|
|||
<thead>
|
||||
<tr>
|
||||
<th>'.tr('Sede').'</th>
|
||||
<th width="20%" class="text-center">'.tr('Q.tà').'</th>
|
||||
<th class="text-center" width="20%">'.tr('Soglia minima quantità').'</th>
|
||||
<th width="20%" class="text-center">'.tr('Giacenza').'</th>
|
||||
<th width="5%" class="text-center">#</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -254,10 +255,16 @@ echo '
|
|||
<tbody>';
|
||||
|
||||
foreach ($sedi as $sede) {
|
||||
$scorta = $dbo->selectOne('mg_scorte_sedi', '*', ['id_sede' => $sede['id'], 'id_articolo' => $id_record]);
|
||||
echo '
|
||||
<tr>
|
||||
<tr data-id="'.$sede['id'].'">
|
||||
<td>'.$sede['nomesede'].'</td>
|
||||
<td class="text-right">'.numberFormat($giacenze[$sede['id']][0], 'qta').' '.$articolo->um.'</td>
|
||||
<td>
|
||||
{[ "type": "number", "decimals": "qta", "name": "scorta_'.$sede['id'].'", "value": "'.$scorta['threshold_qta'].'", "onchange": "aggiornaSogliaMinima($(this).closest(\'tr\').data(\'id\'))" ]}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{[ "type": "number", "decimals": "qta", "name": "giacenza_'.$sede['id'].'", "value": "'.$giacenze[$sede['id']][0].'", "onchange": "aggiornaGiacenza($(this).closest(\'tr\').data(\'id\'),\''.$giacenze[$sede['id']][0].'\')" ]}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a class="btn btn-xs btn-info" title="Dettagli" onclick="getDettagli('.$sede['id'].');">
|
||||
<i class="fa fa-eye"></i>
|
||||
|
@ -282,4 +289,45 @@ function getDettagli(idsede) {
|
|||
openModal("'.tr('Dettagli').'", "'.$rootdir.'/modules/articoli/plugins/dettagli_giacenze.php?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&idsede=" + idsede );
|
||||
}
|
||||
|
||||
function aggiornaSogliaMinima(id_sede) {
|
||||
$.ajax({
|
||||
url: globals.rootdir + "/actions.php",
|
||||
type: "POST",
|
||||
data: {
|
||||
id_module: globals.id_module,
|
||||
id_record: globals.id_record,
|
||||
op: "update_soglia_minima",
|
||||
id_sede: id_sede,
|
||||
threshold_qta: $("#scorta_"+id_sede).val()
|
||||
},
|
||||
success: function(response) {
|
||||
renderMessages();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
renderMessages();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function aggiornaGiacenza(id_sede, giacenza) {
|
||||
content_was_modified = false;
|
||||
$.ajax({
|
||||
url: globals.rootdir + "/actions.php",
|
||||
type: "POST",
|
||||
data: {
|
||||
id_module: globals.id_module,
|
||||
id_record: globals.id_record,
|
||||
op: "update_giacenza",
|
||||
id_sede: id_sede,
|
||||
qta: giacenza,
|
||||
new_qta: $("#giacenza_"+id_sede).val()
|
||||
},
|
||||
success: function(response) {
|
||||
location.reload();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>';
|
||||
|
|
|
@ -19,28 +19,49 @@
|
|||
|
||||
include_once __DIR__.'/../../../core.php';
|
||||
|
||||
$rs = $dbo->fetchArray('SELECT `mg_articoli`.`id`, `mg_articoli_lang`.`title` as descrizione, `qta`, `threshold_qta`, `codice`, `um` AS unitamisura FROM `mg_articoli` LEFT JOIN `mg_articoli_lang` ON (`mg_articoli`.`id` = `mg_articoli_lang`.`id_record` AND `mg_articoli_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') WHERE `qta` < `threshold_qta` AND `attivo` = 1 AND `deleted_at` IS NULL ORDER BY `qta` ASC');
|
||||
use Modules\Anagrafiche\Anagrafica;
|
||||
use Modules\Anagrafiche\Sede;
|
||||
use Modules\Articoli\Articolo;
|
||||
|
||||
$rs = $dbo->fetchArray('SELECT `mg_articoli`.`id`, `mg_articoli_lang`.`title` as descrizione, `codice`, `um`, mg_scorte_sedi.threshold_qta, mg_scorte_sedi.id_sede FROM `mg_articoli` LEFT JOIN `mg_articoli_lang` ON (`mg_articoli`.`id` = `mg_articoli_lang`.`id_record` AND `mg_articoli_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') INNER JOIN `mg_scorte_sedi` ON `mg_articoli`.`id` = `mg_scorte_sedi`.`id_articolo` WHERE `attivo` = 1 AND `deleted_at` IS NULL ORDER BY `codice` ASC');
|
||||
$anagrafica_azienda = Anagrafica::find(setting('Azienda predefinita'));
|
||||
|
||||
if (!empty($rs)) {
|
||||
echo '
|
||||
<table class="table table-hover table-striped">
|
||||
<tr>
|
||||
<th width="80%">'.tr('Articolo').'</th>
|
||||
<th width="20%">'.tr('Q.tà').'</th>
|
||||
<th>'.tr('Articolo').'</th>
|
||||
<th width="25%">'.tr('Sede').'</th>
|
||||
<th class="text-center" width="14%">'.tr('Soglia minima').'</th>
|
||||
<th class="text-center" width="14%">'.tr('Q.tà').'</th>
|
||||
</tr>';
|
||||
|
||||
foreach ($rs as $r) {
|
||||
foreach ($rs as $r) {
|
||||
$articolo = Articolo::find($r['id']);
|
||||
$giacenze = $articolo->getGiacenze();
|
||||
if ($giacenze[$r['id_sede']][0] < $r['threshold_qta']) {
|
||||
if (!empty($r['id_sede'])) {
|
||||
$sede = Sede::find($r['id_sede'])->nomesede;
|
||||
} else {
|
||||
$sede = 'Sede Legale';
|
||||
}
|
||||
echo '
|
||||
<tr>
|
||||
<td>
|
||||
'.Modules::link('Articoli', $r['id'], $r['descrizione']).'
|
||||
<br><small>'.$r['codice'].'</small>
|
||||
</td>
|
||||
<td>
|
||||
'.Translator::numberToLocale($r['qta'], 'qta').' '.$r['unitamisura'].'
|
||||
</td>
|
||||
</tr>';
|
||||
<tr>
|
||||
<td>
|
||||
'.Modules::link('Articoli', $r['id'], $r['codice'].' - '.$r['descrizione']).'
|
||||
</td>
|
||||
<td>
|
||||
'.$sede.'
|
||||
</td>
|
||||
<td class="text-right">
|
||||
'.Translator::numberToLocale($r['threshold_qta'], 'qta').' '.$articolo->um.'
|
||||
</td>
|
||||
<td class="text-right">
|
||||
'.Translator::numberToLocale($giacenze[$r['id_sede']][0], 'qta').' '.$articolo->um.'
|
||||
</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '
|
||||
</table>';
|
||||
|
|
|
@ -116,3 +116,13 @@ INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`, `ord
|
|||
INSERT INTO `zz_settings_lang` (`id_record`, `id_lang`, `title`) VALUES
|
||||
(LAST_INSERT_ID(), 1, 'Metodo di importazione XML fatture di vendita'),
|
||||
(LAST_INSERT_ID(), 2, 'Metodo di importazione XML fatture di vendita');
|
||||
|
||||
-- Gestione sottoscorta per sede
|
||||
UPDATE `zz_widgets` SET `query` = 'SELECT COUNT(mg_articoli.id) AS dato, scorte_sedi.id_sede, IFNULL(movimenti.tot, 0), IFNULL(scorte_sedi.threshold_qta, 0)\nFROM `mg_articoli` LEFT JOIN ( SELECT sedi.id AS id_sede, mg_scorte_sedi.id_articolo, IFNULL(threshold_qta, 0) AS threshold_qta FROM ( SELECT \'0\' AS id UNION SELECT id FROM an_sedi ) sedi LEFT JOIN `mg_scorte_sedi` ON sedi.id = mg_scorte_sedi.id_sede GROUP BY sedi.id, mg_scorte_sedi.id_articolo, IFNULL(threshold_qta, 0) ) scorte_sedi ON ( scorte_sedi.id_articolo = mg_articoli.id OR scorte_sedi.id_articolo IS NULL ) LEFT JOIN( SELECT IFNULL(SUM(qta), 0) AS tot, idarticolo, idsede FROM mg_movimenti GROUP BY idarticolo, idsede ) movimenti ON movimenti.idsede = scorte_sedi.id_sede AND movimenti.idarticolo = mg_articoli.id\nWHERE `attivo` = 1 AND `deleted_at` IS NULL AND IFNULL(movimenti.tot,0)<IFNULL(scorte_sedi.threshold_qta,0)' WHERE `zz_widgets`.`name` = 'Articoli in esaurimento';
|
||||
|
||||
CREATE TABLE `mg_scorte_sedi` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`id_articolo` INT NOT NULL,
|
||||
`id_sede` INT NOT NULL,
|
||||
`threshold_qta` DECIMAL(15,6) NOT NULL,
|
||||
PRIMARY KEY (`id`));
|
Loading…
Reference in New Issue