From 6eea64f0ee08d4f1ff261e046cb3666a7bff6a57 Mon Sep 17 00:00:00 2001 From: MatteoPistorello Date: Tue, 15 Nov 2022 17:38:42 +0100 Subject: [PATCH] Aggiunto modulo Listini clienti e modifiche gestione prezzi --- composer.json | 3 +- include/common/articolo.php | 226 ++++++++++++++++-- include/common/riga.php | 26 +- modules/anagrafiche/actions.php | 5 +- modules/anagrafiche/edit.php | 19 +- modules/articoli/actions.php | 1 + modules/articoli/ajax/complete.php | 34 ++- modules/articoli/ajax/select.php | 10 +- modules/articoli/edit.php | 6 +- modules/articoli/src/Articolo.php | 21 ++ modules/contratti/row-add.php | 2 +- modules/ddt/row-add.php | 2 +- modules/fatture/row-add.php | 2 +- modules/interventi/row-add.php | 2 +- modules/listini_cliente/actions.php | 91 +++++++ modules/listini_cliente/add.php | 58 +++++ modules/listini_cliente/ajax/select.php | 35 +++ modules/listini_cliente/edit.php | 198 +++++++++++++++ modules/listini_cliente/init.php | 30 +++ .../modals/manage_articolo.php | 74 ++++++ modules/listini_cliente/src/Articolo.php | 86 +++++++ modules/listini_cliente/src/Listino.php | 50 ++++ modules/ordini/row-add.php | 2 +- modules/piano_sconto/init.php | 2 +- modules/piano_sconto/src/PianoSconto.php | 2 +- modules/preventivi/row-add.php | 2 +- modules/scadenzario/bulk.php | 98 ++++++++ plugins/piani_sconto_maggiorazione/edit.php | 2 +- plugins/pianificazione_interventi/row-add.php | 2 +- update/2_4_38.sql | 25 ++ update/tables.php | 2 + 31 files changed, 1055 insertions(+), 63 deletions(-) create mode 100644 modules/listini_cliente/actions.php create mode 100644 modules/listini_cliente/add.php create mode 100644 modules/listini_cliente/ajax/select.php create mode 100644 modules/listini_cliente/edit.php create mode 100644 modules/listini_cliente/init.php create mode 100644 modules/listini_cliente/modals/manage_articolo.php create mode 100644 modules/listini_cliente/src/Articolo.php create mode 100644 modules/listini_cliente/src/Listino.php create mode 100644 update/2_4_38.sql diff --git a/composer.json b/composer.json index d686ff4fb..104acd08e 100755 --- a/composer.json +++ b/composer.json @@ -86,6 +86,7 @@ "Modules\\Iva\\": ["modules/iva/custom/src/", "modules/iva/src/"], "Modules\\DDT\\": ["modules/ddt/custom/src/", "modules/ddt/src/"], "Modules\\Fatture\\": ["modules/fatture/custom/src/", "modules/fatture/src/"], + "Modules\\ListiniCliente\\": ["modules/listini_cliente/custom/src/", "modules/listini_cliente/src/"], "Modules\\Ordini\\": ["modules/ordini/custom/src/", "modules/ordini/src/"], "Modules\\Preventivi\\": ["modules/preventivi/custom/src/", "modules/preventivi/src/"], "Modules\\Contratti\\": ["modules/contratti/custom/src/", "modules/contratti/src/"], @@ -106,6 +107,7 @@ "Modules\\Importazione\\": ["modules/import/custom/src/", "modules/import/src/"], "Modules\\Impostazioni\\": ["modules/impostazioni/custom/src/", "modules/impostazioni/src/"], "Modules\\Partitario\\": ["modules/partitario/custom/src/", "modules/partitario/src/"], + "Modules\\StatoEmail\\": ["modules/stato_email/custom/src/", "modules/stato_email/src/"], "Plugins\\ExportFE\\": ["plugins/exportFE/custom/src/", "plugins/exportFE/src/"], "Plugins\\ImportFE\\": ["plugins/importFE/custom/src/", "plugins/importFE/src/"], "Plugins\\ReceiptFE\\": ["plugins/receiptFE/custom/src/", "plugins/receiptFE/src/"], @@ -116,7 +118,6 @@ "Plugins\\ListinoClienti\\": ["plugins/listino_clienti/custom/src/", "plugins/listino_clienti/src/"], "Plugins\\ListinoFornitori\\": ["plugins/listino_fornitori/custom/src/", "plugins/listino_fornitori/src/"], "Plugins\\ComponentiImpianti\\": ["plugins/componenti/custom/src/", "plugins/componenti/src/"], - "Modules\\StatoEmail\\": ["modules/stato_email/custom/src/", "modules/stato_email/src/"], "Plugins\\PresentazioniBancarie\\": ["plugins/presentazioni_bancarie/custom/src/", "plugins/presentazioni_bancarie/src/"] }, "files": [ diff --git a/include/common/articolo.php b/include/common/articolo.php index 1ebdbed78..bf281c765 100755 --- a/include/common/articolo.php +++ b/include/common/articolo.php @@ -19,6 +19,7 @@ $result['idarticolo'] = isset($result['idarticolo']) ? $result['idarticolo'] : null; $qta_minima = 0; +$id_listino = $dbo->selectOne('an_anagrafiche', 'id_listino', ['idanagrafica' => $options['idanagrafica']])['id_listino']; // Articolo if (empty($result['idarticolo'])) { @@ -60,6 +61,7 @@ if (empty($result['idarticolo'])) { ottieniDettagliArticolo("'.$articolo['id'].'").then(function (){ verificaPrezzoArticolo(); verificaScontoArticolo(); + verificaMinimoVendita(); }); }); '; @@ -124,7 +126,7 @@ $(document).ready(function () { } }); -$("#tipo_sconto").on("change", function() { +input("tipo_sconto").on("change", function() { verificaScontoArticolo(); }); @@ -207,6 +209,7 @@ $("#idsede").on("change", function() { $(document).on("change", "input[name^=qta], input[name^=prezzo_unitario], input[name^=sconto]", function() { verificaPrezzoArticolo(); verificaScontoArticolo(); + verificaMinimoVendita(); }); /** @@ -219,7 +222,7 @@ function getDettaglioPerQuantita(qta) { let dettaglio_predefinito = null; let dettaglio_selezionato = null; for (const dettaglio of data) { - if (dettaglio.minimo == null && dettaglio.massimo == null) { + if (dettaglio.minimo == null && dettaglio.massimo == null && dettaglio.prezzo_unitario != null) { dettaglio_predefinito = dettaglio; continue; } @@ -245,6 +248,78 @@ function getPrezzoPerQuantita(qta) { return dettaglio ? parseFloat(dettaglio.prezzo_unitario) : 0; } +/** +* Restituisce il prezzo del listino registrato per l\'articolo-anagrafica. +*/ +function getPrezzoListino() { + const data = globals.aggiunta_articolo.dettagli; + if (!data) return null; + + let dettaglio_listino = null; + for (const dettaglio of data) { + if (dettaglio.prezzo_unitario_listino != null) { + dettaglio_listino = dettaglio; + continue; + } + } + + return dettaglio_listino ? parseFloat(dettaglio_listino.prezzo_unitario_listino) : 0; +} + +/** +* Restituisce il prezzo della scheda articolo. +*/ +function getPrezzoScheda() { + const data = globals.aggiunta_articolo.dettagli; + if (!data) return null; + + let dettaglio_scheda = null; + for (const dettaglio of data) { + if (dettaglio.prezzo_scheda != null) { + dettaglio_scheda = dettaglio; + continue; + } + } + + return dettaglio_scheda ? parseFloat(dettaglio_scheda.prezzo_scheda) : 0; +} + +/** +* Restituisce l\'ultimo prezzo registrato dell\' articolo. +*/ +function getPrezzoUltimo() { + const data = globals.aggiunta_articolo.dettagli; + if (!data) return null; + + let dettaglio_ultimo = null; + for (const dettaglio of data) { + if (dettaglio.prezzo_ultimo != null) { + dettaglio_ultimo = dettaglio; + continue; + } + } + + return dettaglio_ultimo ? parseFloat(dettaglio_ultimo.prezzo_ultimo) : 0; +} + +/** +* Restituisce lo sconto registrato del listino registrato per l\'articolo-anagrafica. +*/ +function getScontoListino() { + const data = globals.aggiunta_articolo.dettagli; + if (!data) return null; + + let dettaglio_listino = null; + for (const dettaglio of data) { + if (dettaglio.sconto_percentuale_listino != null) { + dettaglio_listino = dettaglio; + continue; + } + } + + return dettaglio_listino ? parseFloat(dettaglio_listino.sconto_percentuale_listino) : 0; +} + /** * Restituisce lo sconto registrato per una specifica quantità dell\'articolo. */ @@ -269,56 +344,130 @@ function ottieniDettagliArticolo(id_articolo) { * Funzione per verificare se il prezzo unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione. */ function verificaPrezzoArticolo() { - let qta = $("#qta").val().toEnglish(); - let prezzo_previsto = getPrezzoPerQuantita(qta); - let prezzo_unitario_input = $("#prezzo_unitario"); let prezzo_unitario = prezzo_unitario_input.val().toEnglish(); - let div = prezzo_unitario_input.closest("div").parent().find("div[id*=errors]"); + let div = $(".prezzi"); - if (prezzo_previsto === prezzo_unitario || prezzo_previsto === 0 ) { - div.css("padding-top", "0"); - div.html(""); + div.css("padding-top", "0"); + div.html(""); - return; + let qta = $("#qta").val().toEnglish(); + let prezzo_anagrafica = getPrezzoPerQuantita(qta); + let prezzo_listino = getPrezzoListino(); + let prezzo_std = getPrezzoScheda(); + let prezzo_last = getPrezzoUltimo(); + + if (prezzo_anagrafica || prezzo_listino || prezzo_std || prezzo_last) { + div.html(``); + } + let table = $(".table-prezzi"); + + if (prezzo_anagrafica) { + table.append(``); + + let tr = $(".pr_anagrafica").parent(); + if (prezzo_unitario == prezzo_anagrafica.toFixed(2)) { + tr.append(``); + } else{ + tr.append(``); + } + table.append(``); } - div.css("padding-top", "5px"); - div.html(`'.tr('Prezzo').': ` + prezzo_previsto.toLocale() + " " + globals.currency + " " + `'.Plugins::link(($options['dir'] == 'uscita' ? 'Listino Fornitori' : 'Listino Clienti'), $options['idanagrafica'], null, null, '').'`); - - edit_listino = $("#listino").find("a"); - edit_listino.attr("href", edit_listino.attr("href").replace(/id_record=[0-9]*/, "id_record=" + $("#idarticolo").val())); + if (prezzo_listino) { + table.append(``); + + let tr = $(".pr_listino").parent(); + if (prezzo_unitario == prezzo_listino.toFixed(2)) { + tr.append(``); + } else{ + tr.append(``); + } + table.append(``); + } + + if (prezzo_std) { + table.append(``); + + let tr = $(".pr_std").parent(); + if (prezzo_unitario == prezzo_std.toFixed(2)) { + tr.append(``); + } else{ + tr.append(``); + } + } + + if (prezzo_last) { + table.append(``); + + let tr = $(".pr_last").parent(); + if (prezzo_unitario == prezzo_last.toFixed(2)) { + tr.append(``); + } else{ + tr.append(``); + } + } + + + if (prezzo_anagrafica || prezzo_listino || prezzo_std) { + table.append(`
'.($options['dir'] == 'uscita' ? tr('Prezzo listino') : tr('Netto cliente')).': '.Plugins::link(($options['dir'] == 'uscita' ? 'Listino Fornitori' : 'Netto Clienti'), $result['idarticolo'], tr('Visualizza'), null, '').'` + prezzo_anagrafica.toLocale() + ` ` + globals.currency + `
'.tr('Prezzo listino').': '.Modules::link('Listini Cliente', $id_listino, tr('Visualizza'), null, '').'` + prezzo_listino.toLocale() + ` ` + globals.currency + `
'.tr('Prezzo articolo').': '.Modules::link('Articoli', $result['idarticolo'], tr('Visualizza'), null, '').'` + prezzo_std.toLocale() + ` ` + globals.currency + `
'.tr('Ultimo prezzo').': '.Modules::link('Articoli', $result['idarticolo'], tr('Visualizza'), null, '').'` + prezzo_last.toLocale() + ` ` + globals.currency + `
`); + } } /** * Funzione per verificare se lo sconto unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione. */ function verificaScontoArticolo() { - let qta = $("#qta").val().toEnglish(); - let sconto_previsto = getScontoPerQuantita(qta); + let prezzo_unitario_input = $("#prezzo_unitario"); + let prezzo_unitario = prezzo_unitario_input.val().toEnglish(); + let prezzo_anagrafica = getPrezzoPerQuantita(qta); + let prezzo_listino = getPrezzoListino(); + let sconto_previsto = 0; + + + if (prezzo_unitario == prezzo_anagrafica.toFixed(2)) { + let qta = $("#qta").val().toEnglish(); + sconto_previsto = getScontoPerQuantita(qta); + } else if (prezzo_unitario == prezzo_listino.toFixed(2)) { + sconto_previsto = getScontoListino(); + } let sconto_input = $("#sconto"); let sconto = sconto_input.val().toEnglish(); - let div = sconto_input.parent().next(); - if (sconto_previsto === 0 || sconto_previsto === sconto || $("#tipo_sconto").val() === "UNT") { + let div = $(".sconto"); + if (sconto_previsto === 0 || sconto_previsto === sconto) { div.css("padding-top", "0"); div.html(""); return; } - div.css("padding-top", "5px"); - div.html(`'.tr('Sconto suggerito').': ` + sconto_previsto.toLocale() + `%`); + div.css("margin-top", "-13px"); + div.html(`'.tr('Sconto suggerito').': ` + sconto_previsto.toLocale() + `%`); } /** * Funzione per aggiornare il prezzo unitario sulla base dei valori automatici. */ -function aggiornaPrezzoArticolo() { - let qta = $("#qta").val().toEnglish(); - let prezzo_previsto = getPrezzoPerQuantita(qta); +function aggiornaPrezzoArticolo(aggiorna = "") { + let prezzo_previsto = 0; + if (aggiorna == "listino") { + prezzo_previsto = getPrezzoListino(); + } else if (aggiorna == "anagrafica") { + let qta = $("#qta").val().toEnglish(); + prezzo_previsto = getPrezzoPerQuantita(qta); + } else if (aggiorna == "std") { + prezzo_previsto = getPrezzoScheda(); + } else if (aggiorna == "last") { + prezzo_previsto = getPrezzoUltimo(); + } else { + let qta = $("#qta").val().toEnglish(); + prezzo1 = getPrezzoPerQuantita(qta); + prezzo2 = getPrezzoListino(); + prezzo_previsto = (!prezzo1 ? prezzo2 : (!prezzo2 ? prezzo1 : (prezzo1 > prezzo2 ? prezzo2 : prezzo1))); + } $("#prezzo_unitario").val(prezzo_previsto).trigger("change"); @@ -332,10 +481,22 @@ function aggiornaPrezzoArticolo() { * Funzione per aggiornare lo sconto unitario sulla base dei valori automatici. */ function aggiornaScontoArticolo() { - let qta = $("#qta").val().toEnglish(); - let sconto_previsto = getScontoPerQuantita(qta); + let prezzo_unitario_input = $("#prezzo_unitario"); + let prezzo_unitario = prezzo_unitario_input.val().toEnglish(); + let prezzo_anagrafica = getPrezzoPerQuantita(qta); + let prezzo_listino = getPrezzoListino(); + let sconto_previsto = 0; + + + if (prezzo_unitario == prezzo_anagrafica.toFixed(2)) { + let qta = $("#qta").val().toEnglish(); + sconto_previsto = getScontoPerQuantita(qta); + } else if (prezzo_unitario == prezzo_listino.toFixed(2)) { + sconto_previsto = getScontoListino(); + } $("#sconto").val(sconto_previsto).trigger("change"); + input("tipo_sconto").set("PRC").trigger("change"); // Aggiornamento automatico di guadagno e margine if (direzione === "entrata") { @@ -367,4 +528,17 @@ function aggiornaQtaMinima() { } } +function verificaMinimoVendita() { + let prezzo_unitario_input = $("#prezzo_unitario"); + let prezzo_unitario = prezzo_unitario_input.val().toEnglish(); + let minimo_vendita = parseFloat($("#idarticolo").selectData().minimo_vendita); + + let div = $(".minimo_vendita"); + div.css("margin-top", "-13px"); + if (prezzo_unitario < minimo_vendita) { + div.html(`

'.tr('Attenzione:
valore inferiore al prezzo minimo di vendita ').'` + minimo_vendita.toLocale() + ` ` + globals.currency + `

`); + } else { + div.html(""); + } +} '; diff --git a/include/common/riga.php b/include/common/riga.php index 654671809..f7def2244 100755 --- a/include/common/riga.php +++ b/include/common/riga.php @@ -180,14 +180,26 @@ echo ' if ($options['dir'] == 'entrata') { echo '
-
'; +
+
'; // Provvigione echo ' -
+
+
{[ "type": "number", "label": "'.tr('Provvigione unitaria').'", "name": "provvigione", "value": "'.($result['provvigione_percentuale'] ?: ($result['provvigione_unitaria'] ?: $result['provvigione_default'])).'", "icon-after": "choice|untprc|'.($result['tipo_provvigione'] ?: $result['tipo_provvigione_default']).'", "help": "'.tr('Provvigione destinata all\'agente.').'", "min-value": "0" ]}
+
+
+
'; +} else { + echo ' +
+
+
+
+
'; } // Data prevista evasione (per ordini) @@ -311,11 +323,21 @@ if (in_array($module['name'], ['Fatture di vendita', 'Fatture di acquisto'])) { function controlla_sconto() { let sconto = $("#sconto").val().toEnglish(); let div = $("#sconto").closest("div").next("div[id*=errors]"); + let div_margine = $(".margine"); + let div_prezzi = $(".prezzi"); + + div.css("margin-top", "-13px"); if (sconto > 0) { + div_margine.css("margin-top", "-20px"); + div_prezzi.css("margin-top", "-20px"); div.html(`'.tr('Sconto').'`); } else if (sconto < 0) { + div_margine.css("margin-top", "-20px"); + div_prezzi.css("margin-top", "-20px"); div.html(`'.tr('Maggiorazione').'`); } else { + div_margine.css("margin-top", "0px"); + div_prezzi.css("margin-top", "0px"); div.html(""); } } diff --git a/modules/anagrafiche/actions.php b/modules/anagrafiche/actions.php index 53b2bfc8e..3728f9120 100755 --- a/modules/anagrafiche/actions.php +++ b/modules/anagrafiche/actions.php @@ -74,8 +74,8 @@ switch (post('op')) { $anagrafica->diciturafissafattura = post('diciturafissafattura'); $anagrafica->idpagamento_acquisti = post('idpagamento_acquisti'); $anagrafica->idpagamento_vendite = post('idpagamento_vendite'); - $anagrafica->idlistino_acquisti = post('idlistino_acquisti'); - $anagrafica->idlistino_vendite = post('idlistino_vendite'); + $anagrafica->id_piano_sconto_acquisti = post('id_piano_sconto_acquisti'); + $anagrafica->id_piano_sconto_vendite = post('id_piano_sconto_vendite'); $anagrafica->idiva_acquisti = post('idiva_acquisti'); $anagrafica->idiva_vendite = post('idiva_vendite'); $anagrafica->idbanca_acquisti = post('idbanca_acquisti'); @@ -100,6 +100,7 @@ switch (post('op')) { $anagrafica->id_ritenuta_acconto_acquisti = post('id_ritenuta_acconto_acquisti'); $anagrafica->id_ritenuta_acconto_vendite = post('id_ritenuta_acconto_vendite'); $anagrafica->split_payment = post('split_payment'); + $anagrafica->id_listino = post('id_listino'); $anagrafica->tipologie = (array) post('idtipoanagrafica'); $anagrafica->codice_fiscale = strtoupper(post('codice_fiscale')); diff --git a/modules/anagrafiche/edit.php b/modules/anagrafiche/edit.php index 515f2acfb..4c5e3803a 100755 --- a/modules/anagrafiche/edit.php +++ b/modules/anagrafiche/edit.php @@ -519,7 +519,7 @@ if ($is_cliente or $is_fornitore or $is_tecnico) {
- {[ "type": "select", "label": "'.tr('Piano di sconto/magg. su articoli').'", "name": "idlistino_vendite", "values": "query=SELECT id, nome AS descrizione FROM mg_listini ORDER BY nome ASC", "value": "$idlistino_vendite$" ]} + {[ "type": "select", "label": "'.tr('Piano di sconto/magg. su articoli').'", "name": "id_piano_sconto_vendite", "values": "query=SELECT id, nome AS descrizione FROM mg_piani_sconto ORDER BY nome ASC", "value": "$id_piano_sconto_vendite$" ]}
@@ -535,6 +535,16 @@ if ($is_cliente or $is_fornitore or $is_tecnico) {
{[ "type": "select", "label": "'.tr('Agenti secondari').'", "multiple": "1", "name": "idagenti[]", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, IF(deleted_at IS NOT NULL, CONCAT(ragione_sociale, \' (Eliminato)\'), ragione_sociale ) AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE (descrizione=\'Agente\' AND deleted_at IS NULL AND an_anagrafiche.idanagrafica NOT IN (SELECT idagente FROM an_anagrafiche WHERE idanagrafica = '.prepare($record['idanagrafica']).')) OR (an_anagrafiche.idanagrafica IN (SELECT idagente FROM an_anagrafiche_agenti WHERE idanagrafica = '.prepare($record['idanagrafica']).') ) ORDER BY ragione_sociale", "value": "$idagenti$" ]}
+
+ +
+
+ {[ "type": "select", "label": "'.tr('Listino').'", "name": "id_listino", "ajax-source": "listini", "value": "$id_listino$" ]} +
+ +
+ {[ "type": "select", "label": "'.tr('Tipo attività predefinita').'", "name": "idtipointervento_default", "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione ASC", "value": "$idtipointervento_default$" ]} +
'; // Collegamento con il conto @@ -554,11 +564,6 @@ if ($is_cliente or $is_fornitore or $is_tecnico) { echo '
- - -
- {[ "type": "select", "label": "'.tr('Tipo attività predefinita').'", "name": "idtipointervento_default", "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione ASC", "value": "$idtipointervento_default$" ]} -
'; @@ -586,7 +591,7 @@ if ($is_cliente or $is_fornitore or $is_tecnico) {
- {[ "type": "select", "label": "'.tr('Piano di sconto/magg. su articoli').'", "name": "idlistino_acquisti", "values": "query=SELECT id, nome AS descrizione FROM mg_listini ORDER BY nome ASC", "value": "$idlistino_acquisti$" ]} + {[ "type": "select", "label": "'.tr('Piano di sconto/magg. su articoli').'", "name": "id_piano_sconto_acquisti", "values": "query=SELECT id, nome AS descrizione FROM mg_piani_sconto ORDER BY nome ASC", "value": "$id_piano_sconto_acquisti$" ]}
'; // Collegamento con il conto diff --git a/modules/articoli/actions.php b/modules/articoli/actions.php index 0fc7986ad..dc1660887 100755 --- a/modules/articoli/actions.php +++ b/modules/articoli/actions.php @@ -145,6 +145,7 @@ switch (post('op')) { $articolo->um_secondaria = post('um_secondaria'); $articolo->fattore_um_secondaria = post('fattore_um_secondaria'); $articolo->qta_multipla = post('qta_multipla'); + $articolo->setMinimoVendita(post('minimo_vendita'), post('idiva_vendita')); if (empty(post('coefficiente'))) { $articolo->setPrezzoVendita(post('prezzo_vendita'), post('idiva_vendita')); diff --git a/modules/articoli/ajax/complete.php b/modules/articoli/ajax/complete.php index c0632c0b2..51fcbdd7e 100755 --- a/modules/articoli/ajax/complete.php +++ b/modules/articoli/ajax/complete.php @@ -142,22 +142,32 @@ switch ($resource) { $query_anagrafica = replace($query, [ '|where|' => ' AND id_anagrafica = '.prepare($id_anagrafica), ]); - $results = $database->fetchArray($query_anagrafica); + $prezzi = $database->fetchArray($query_anagrafica); + + $query = 'SELECT sconto_percentuale AS sconto_percentuale_listino, + '.($prezzi_ivati ? 'prezzo_unitario_ivato' : 'prezzo_unitario').' AS prezzo_unitario_listino + FROM mg_listini + LEFT JOIN mg_listini_articoli ON mg_listini.id=mg_listini_articoli.id_listino + LEFT JOIN an_anagrafiche ON mg_listini.id=an_anagrafiche.id_listino + WHERE (mg_listini.is_sempre_visibile=1 OR (mg_listini.data_attivazione<=NOW() AND mg_listini_articoli.data_scadenza>=NOW())) AND id_articolo = '.prepare($id_articolo).' AND dir = '.prepare($direzione).' |where|'; + // Lettura dei prezzi relativi all'anagrafica + $query_anagrafica = replace($query, [ + '|where|' => ' AND idanagrafica = '.prepare($id_anagrafica), + ]); + $listino = $database->fetchArray($query_anagrafica); // Lettura dei prezzi registrati direttamente sull'articolo, per compatibilità con il formato standard - if (empty($results)) { - $result = $database->fetchOne('SELECT prezzo_acquisto, '.($prezzi_ivati ? 'prezzo_vendita_ivato' : 'prezzo_vendita').' AS prezzo_vendita FROM mg_articoli WHERE id = '.prepare($id_articolo)); - - $results = [ - [ - 'minimo' => null, - 'massimo' => null, - 'sconto_percentuale' => 0, - 'prezzo_unitario' => $direzione == 'uscita' ? $result['prezzo_acquisto'] : $result['prezzo_vendita'], - ], - ]; + if ($direzione == 'uscita') { + $prezzo_articolo = $database->fetchArray('SELECT prezzo_acquisto AS prezzo_scheda FROM mg_articoli WHERE id = '.prepare($id_articolo)); + } else { + $prezzo_articolo = $database->fetchArray('SELECT '.($prezzi_ivati ? 'prezzo_vendita_ivato' : 'prezzo_vendita').' AS prezzo_scheda FROM mg_articoli WHERE id = '.prepare($id_articolo)); } + // Ultimo prezzo al cliente + $ultimo_prezzo = $dbo->fetchArray('SELECT '.($prezzi_ivati ? '(prezzo_unitario_ivato-sconto_unitario_ivato)' : '(prezzo_unitario-sconto_unitario)').' AS prezzo_ultimo FROM co_righe_documenti LEFT JOIN co_documenti ON co_documenti.id=co_righe_documenti.iddocumento WHERE idarticolo='.prepare($id_articolo).' AND idanagrafica='.prepare($id_anagrafica).' AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='.prepare($direzione).') ORDER BY data DESC LIMIT 0,1'); + + $results = array_merge($prezzi, $listino, $prezzo_articolo, $ultimo_prezzo); + echo json_encode($results); break; diff --git a/modules/articoli/ajax/select.php b/modules/articoli/ajax/select.php index bd4e24b86..46c095a2b 100755 --- a/modules/articoli/ajax/select.php +++ b/modules/articoli/ajax/select.php @@ -35,14 +35,16 @@ switch ($resource) { $usare_iva_anagrafica = $superselect['dir'] == 'entrata' && !empty($superselect['idanagrafica']); $solo_non_varianti = $superselect['solo_non_varianti']; $idagente = $superselect['idagente']; + $id_listino = $superselect['id_listino']; $query = "SELECT DISTINCT mg_articoli.id, IF(`categoria`.`nome` IS NOT NULL, CONCAT(`categoria`.`nome`, IF(`sottocategoria`.`nome` IS NOT NULL, CONCAT(' (', `sottocategoria`.`nome`, ')'), '-')), '".tr('Nessuna categoria')."') AS optgroup, mg_articoli.barcode, - mg_articoli.".($prezzi_ivati ? 'prezzo_vendita_ivato' : 'prezzo_vendita').' AS prezzo_vendita, - mg_articoli.prezzo_vendita_ivato AS prezzo_vendita_ivato,'; + mg_articoli.".($prezzi_ivati ? 'prezzo_vendita_ivato' : 'prezzo_vendita')." AS prezzo_vendita, + mg_articoli.prezzo_vendita_ivato AS prezzo_vendita_ivato, + mg_articoli.".($prezzi_ivati ? 'minimo_vendita_ivato' : 'minimo_vendita')." AS minimo_vendita,"; // Informazioni relative al fornitore specificato dal documenti di acquisto if ($usare_dettaglio_fornitore) { @@ -159,6 +161,10 @@ switch ($resource) { $where[] = 'mg_articoli.id_combinazione IS NULL'; } + if ($id_listino) { + $where[] = 'mg_articoli.id NOT IN (SELECT id_articolo FROM mg_listini_articoli WHERE id_listino='.prepare($id_listino).')'; + } + if (!empty($search)) { $search_fields[] = 'mg_articoli.descrizione LIKE '.prepare('%'.$search.'%'); $search_fields[] = 'mg_articoli.codice LIKE '.prepare('%'.$search.'%'); diff --git a/modules/articoli/edit.php b/modules/articoli/edit.php index 719a8ef7c..228cb5046 100755 --- a/modules/articoli/edit.php +++ b/modules/articoli/edit.php @@ -266,9 +266,13 @@ echo '
-
+
{[ "type": "select", "label": "", "name": "idconto_vendita", "value": "$idconto_vendita$", "ajax-source": "conti-vendite" ]}
+ +
+ {[ "type": "number", "label": "", "name": "minimo_vendita", "value": "minimo_vendita_ivato : $articolo->minimo_vendita); ?>", "icon-after": "", "help": "" ]} +
diff --git a/modules/articoli/src/Articolo.php b/modules/articoli/src/Articolo.php index 9f5b7617a..25f63dad8 100755 --- a/modules/articoli/src/Articolo.php +++ b/modules/articoli/src/Articolo.php @@ -142,6 +142,27 @@ class Articolo extends Model } } + /** + * Imposta il prezzo di vendita sulla base dell'impstazione per l'utilizzo dei prezzi comprensivi di IVA. + * + * @param $prezzo_vendita + * @param $id_iva + */ + public function setMinimoVendita($prezzo_minimo, $id_iva) + { + // Calcolo prezzo minimo di vendita ivato e non ivato + $prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA'); + $id_iva = $id_iva ?: setting('Iva predefinita'); + $percentuale_aliquota = floatval(Aliquota::find($id_iva)->percentuale); + if ($prezzi_ivati) { + $this->minimo_vendita_ivato = $prezzo_minimo; + $this->minimo_vendita = $prezzo_minimo / (1 + $percentuale_aliquota / 100); + } else { + $this->minimo_vendita = $prezzo_minimo; + $this->minimo_vendita_ivato = $prezzo_minimo * (1 + $percentuale_aliquota / 100); + } + } + /** * Imposta il prezzo di acquisto e aggiorna il prezzo di vendita in base al coefficiente. * diff --git a/modules/contratti/row-add.php b/modules/contratti/row-add.php index 3524458dc..ae34893ac 100755 --- a/modules/contratti/row-add.php +++ b/modules/contratti/row-add.php @@ -72,7 +72,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/ddt/row-add.php b/modules/ddt/row-add.php index f4607f62f..6f1c8ed5f 100755 --- a/modules/ddt/row-add.php +++ b/modules/ddt/row-add.php @@ -75,7 +75,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/fatture/row-add.php b/modules/fatture/row-add.php index b27c32234..026f79fb7 100755 --- a/modules/fatture/row-add.php +++ b/modules/fatture/row-add.php @@ -101,7 +101,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/interventi/row-add.php b/modules/interventi/row-add.php index a262f7155..4436f627a 100755 --- a/modules/interventi/row-add.php +++ b/modules/interventi/row-add.php @@ -81,7 +81,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/listini_cliente/actions.php b/modules/listini_cliente/actions.php new file mode 100644 index 000000000..c9c016e7c --- /dev/null +++ b/modules/listini_cliente/actions.php @@ -0,0 +1,91 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +use Modules\Articoli\Articolo AS ArticoloOriginale; +use Modules\ListiniCliente\Articolo; +use Modules\ListiniCliente\Listino; + +switch (filter('op')) { + case 'update': + $listino->nome = post('nome'); + $listino->data_attivazione = post('data_attivazione') ?: null; + $listino->data_scadenza_predefinita = post('data_scadenza_predefinita') ?: null; + $listino->is_sempre_visibile = post('is_sempre_visibile'); + $listino->note = post('note'); + $listino->save(); + + flash()->info(tr('Listino modificato correttamente!')); + + break; + + case 'add': + $listino = Listino::build(post('nome')); + $listino->data_attivazione = post('data_attivazione') ?: null; + $listino->data_scadenza_predefinita = post('data_scadenza_predefinita') ?: null; + $listino->is_sempre_visibile = post('is_sempre_visibile'); + $listino->note = post('note'); + $listino->save(); + + $id_record = $listino->id; + + flash()->info(tr('Nuovo listino aggiunto!')); + + break; + + case 'manage_articolo': + if (empty(post('id'))) { + $articolo_originale = ArticoloOriginale::find(post('id_articolo')); + + $articolo_listino = Articolo::build($articolo_originale, $id_record); + $articolo_listino->data_scadenza = post('data_scadenza') ?: null; + $articolo_listino->setPrezzoUnitario(post('prezzo_unitario')); + $articolo_listino->sconto_percentuale = post('sconto_percentuale'); + $articolo_listino->save(); + } else { + $articolo_listino = Articolo::find(post('id')); + $articolo_listino->data_scadenza = post('data_scadenza') ?: null; + $articolo_listino->setPrezzoUnitario(post('prezzo_unitario')); + $articolo_listino->sconto_percentuale = post('sconto_percentuale'); + $articolo_listino->save(); + } + + flash()->info(tr('Nuovo articolo al listino aggiunto!')); + + break; + + case 'delete_articolo': + $articolo_listino = Articolo::find(post('id')); + $articolo_listino->delete(); + + flash()->info(tr('Articolo del listino eliminato correttamente!')); + + break; + + case 'delete': + if (isset($id_record)) { + $listino->delete(); + $dbo->query('UPDATE `an_anagrafiche` SET id_listino=0 WHERE id_listino='.prepare($id_record)); + $dbo->query('DELETE FROM `mg_listini_articoli` WHERE id_listino='.prepare($id_record)); + flash()->info(tr('Listino eliminato correttamente!')); + } + + break; +} diff --git a/modules/listini_cliente/add.php b/modules/listini_cliente/add.php new file mode 100644 index 000000000..17226bec8 --- /dev/null +++ b/modules/listini_cliente/add.php @@ -0,0 +1,58 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +echo ' +
+ + + +
+
+ {[ "type":"text", "label":"'.tr('Nome').'", "name":"nome", "required":"1" ]} +
+ +
+ {[ "type":"date", "label":"'.tr('Data attivazione').'", "name":"data_attivazione", "required":"1" ]} +
+ +
+ {[ "type":"date", "label":"'.tr('Data scadenza default').'", "name":"data_scadenza_predefinita" ]} +
+ +
+ {[ "type":"checkbox", "label":"'.tr('Sempre visibile').'", "name":"is_sempre_visibile", "help": "'.tr('Se attivo il valore sarà visibile sull\'articolo').'" ]} +
+
+ +
+
+ {[ "type":"textarea", "label":"'.tr('Note').'", "name":"note" ]} +
+
+ + + +
+
+ +
+
+
'; diff --git a/modules/listini_cliente/ajax/select.php b/modules/listini_cliente/ajax/select.php new file mode 100644 index 000000000..6eb931b57 --- /dev/null +++ b/modules/listini_cliente/ajax/select.php @@ -0,0 +1,35 @@ +. + */ + +include_once __DIR__.'/../../../core.php'; + +switch ($resource) { + case 'listini': + $query = 'SELECT id, nome AS descrizione FROM mg_listini |where| ORDER BY nome ASC'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + + break; +} diff --git a/modules/listini_cliente/edit.php b/modules/listini_cliente/edit.php new file mode 100644 index 000000000..7d891afd1 --- /dev/null +++ b/modules/listini_cliente/edit.php @@ -0,0 +1,198 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +echo ' +
+ + + +
+
+

'.tr('Listino').'

+
+ +
+
+
+ {[ "type":"text", "label":"'.tr('Nome').'", "name":"nome", "value":"$nome$", "required":"1" ]} +
+ +
+ {[ "type":"date", "label":"'.tr('Data attivazione').'", "name":"data_attivazione", "value":"$data_attivazione$", "required":"1" ]} +
+ +
+ {[ "type":"date", "label":"'.tr('Data scadenza default').'", "name":"data_scadenza_predefinita", "value":"$data_scadenza_predefinita$" ]} +
+ +
+ {[ "type":"checkbox", "label":"'.tr('Sempre visibile').'", "name":"is_sempre_visibile", "value":"$is_sempre_visibile$", "help": "'.tr('Se attivo il valore sarà visibile sull\'articolo').'" ]} +
+
+ +
+
+ {[ "type":"textarea", "label":"'.tr('Note').'", "name":"note", "value":"$note$" ]} +
+
+
+
+
+ {[ "type":"select", "label":"'.tr('Articolo').'", "ajax-source": "articoli", "select-options": {"permetti_movimento_a_zero": 1, "id_listino": '.$id_record.'} ]} +
+ +
+
+ +
+
+
+ +
+ + + + + + + + + + + '; + + foreach ($articoli as $articolo) { + echo ' + + + + + + + + + + + + + + + + + '; + } + + if (empty($articoli)) { + echo ' + + + '; + } + + echo ' +
'.tr('Codice').''.tr('Descrizione').''.tr('Data scadenza').''.tr('Minimo').''.tr('Prezzo di listino').''.tr('Prezzo ivato').''.tr('Sconto').'#
+ '.Modules::link('Articoli', $articolo['id_articolo'], $articolo['codice'], null, '').' + + '.$articolo['descrizione'].' + + '.dateFormat($articolo['data_scadenza']).' + + '.moneyFormat($articolo['minimo_vendita']).' + + '.moneyFormat($articolo['prezzo_unitario']).' + + '.moneyFormat($articolo['prezzo_unitario_ivato']).' + + '.numberFormat($articolo['sconto_percentuale']).' % + + + + + + + + +
+ '.tr('Nessun articolo presente').' +
+
+
+
+
+ + + '.tr('Elimina').' + + +'; \ No newline at end of file diff --git a/modules/listini_cliente/init.php b/modules/listini_cliente/init.php new file mode 100644 index 000000000..b6044104d --- /dev/null +++ b/modules/listini_cliente/init.php @@ -0,0 +1,30 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +use Modules\ListiniCliente\Listino; + +if (isset($id_record)) { + $listino = Listino::find($id_record); + $record = $dbo->fetchOne('SELECT * FROM `mg_listini` WHERE id='.prepare($id_record)); + + $prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA'); + $articoli = $dbo->fetchArray('SELECT mg_listini_articoli.*, mg_articoli.codice, mg_articoli.descrizione, mg_articoli.'.($prezzi_ivati ? 'minimo_vendita_ivato' : 'minimo_vendita').' AS minimo_vendita FROM mg_listini_articoli LEFT JOIN mg_articoli ON mg_listini_articoli.id_articolo=mg_articoli.id WHERE id_listino='.prepare($id_record)); +} diff --git a/modules/listini_cliente/modals/manage_articolo.php b/modules/listini_cliente/modals/manage_articolo.php new file mode 100644 index 000000000..54998e895 --- /dev/null +++ b/modules/listini_cliente/modals/manage_articolo.php @@ -0,0 +1,74 @@ +. + */ + +include_once __DIR__.'/../../../core.php'; +include_once __DIR__.'/../../../../core.php'; + +if (empty(get('id'))) { + $listino = $dbo->selectOne('mg_listini', '*', ['id' => get('id_record')]); + $data_scadenza = $listino['data_scadenza_predefinita']; + $id_articolo = get('id_articolo'); +} else { + $articolo = $dbo->selectOne('mg_listini_articoli', '*', ['id' => get('id')]); + $data_scadenza = $articolo['data_scadenza']; + $id_articolo = $articolo['id_articolo']; +} + +$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA'); +$prezzo_unitario = $prezzi_ivati ? $articolo['prezzo_unitario_ivato'] : $articolo['prezzo_unitario']; + +echo ' +
+ + + + + +
+
+ {[ "type":"select", "label":"'.tr('Articolo').'", "name":"id_articolo", "ajax-source": "articoli", "select-options": {"permetti_movimento_a_zero": 1}, "value": "'.$id_articolo.'", "disabled": "1" ]} +
+
+ +
+
+ {[ "type":"date", "label":"'.tr('Data scadenza').'", "name":"data_scadenza", "value":"'.$data_scadenza.'", "required": "1" ]} +
+ +
+ {[ "type":"number", "label":"'.tr('Prezzo unitario').'", "name":"prezzo_unitario", "icon-after": "'.currency().'", "value":"'.$prezzo_unitario.'" ]} +
+ +
+ {[ "type":"number", "label":"'.tr('Sconto percentuale').'", "name":"sconto_percentuale", "icon-after": "%", "value":"'.$articolo['sconto_percentuale'].'" ]} +
+
+ + +
+
+ +
+
+
'; + +echo ' +'; \ No newline at end of file diff --git a/modules/listini_cliente/src/Articolo.php b/modules/listini_cliente/src/Articolo.php new file mode 100644 index 000000000..a434b5757 --- /dev/null +++ b/modules/listini_cliente/src/Articolo.php @@ -0,0 +1,86 @@ +. + */ + +namespace Modules\ListiniCliente; + +use Common\SimpleModelTrait; +use Illuminate\Database\Eloquent\Model; +use Modules\Articoli\Articolo AS ArticoloOriginale; +use Modules\Iva\Aliquota; + +/* + * Classe per la gestione delle relazioni articolo-prezzo sulla base di un range di quantità e di una specifica anagrafica. + * + * @since 2.4.18 + */ +class Articolo extends Model +{ + use SimpleModelTrait; + + protected $table = 'mg_listini_articoli'; + + /** + * Crea una nuova relazione tra Articolo e Listino per la gestione dei prezzi. + * + * @return self + */ + public static function build(ArticoloOriginale $articolo, $id_listino, $direzione = 'entrata') + { + $model = new static(); + + $model->articolo()->associate($articolo); + $model->id_listino = $id_listino; + $model->dir = $direzione == 'uscita' ? 'uscita' : 'entrata'; + + $model->save(); + + return $model; + } + + /** + * Imposta il prezzo di vendita sulla base dell'impstazione per l'utilizzo dei prezzi comprensivi di IVA. + * + * @param $prezzo_unitario + */ + public function setPrezzoUnitario($prezzo_unitario) + { + $id_iva = $this->articolo->idiva_vendita; + + // Calcolo prezzo di vendita ivato e non ivato + $prezzi_ivati = ($this->dir == 'entrata' ? setting('Utilizza prezzi di vendita comprensivi di IVA') : 0); + $percentuale_aliquota = floatval(Aliquota::find($id_iva)->percentuale); + if ($prezzi_ivati) { + $this->prezzo_unitario_ivato = $prezzo_unitario; + $this->prezzo_unitario = $prezzo_unitario / (1 + $percentuale_aliquota / 100); + } else { + $this->prezzo_unitario = $prezzo_unitario; + $this->prezzo_unitario_ivato = $prezzo_unitario * (1 + $percentuale_aliquota / 100); + } + } + + public function articolo() + { + return $this->belongsTo(ArticoloOriginale::class, 'id_articolo'); + } + + public function listino() + { + return $this->belongsTo(Listino::class, 'id_listino'); + } +} diff --git a/modules/listini_cliente/src/Listino.php b/modules/listini_cliente/src/Listino.php new file mode 100644 index 000000000..d40b4779c --- /dev/null +++ b/modules/listini_cliente/src/Listino.php @@ -0,0 +1,50 @@ +. + */ + +namespace Modules\ListiniCliente; + +use Common\SimpleModelTrait; +use Illuminate\Database\Eloquent\Model; + +/* + * Classe per la gestione delle relazioni articolo-prezzo sulla base di un range di quantità e di una specifica anagrafica. + * + * @since 2.4.18 + */ +class Listino extends Model +{ + use SimpleModelTrait; + + protected $table = 'mg_listini'; + + /** + * Crea una nuova relazione tra Articolo e Anagrafica per la gestione dei prezzi. + * + * @return self + */ + public static function build($nome) + { + $model = new static(); + $model->nome = $nome; + + $model->save(); + + return $model; + } +} diff --git a/modules/ordini/row-add.php b/modules/ordini/row-add.php index f4acfea47..5d63a846c 100755 --- a/modules/ordini/row-add.php +++ b/modules/ordini/row-add.php @@ -73,7 +73,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/piano_sconto/init.php b/modules/piano_sconto/init.php index 96f1bbef5..1604e744c 100644 --- a/modules/piano_sconto/init.php +++ b/modules/piano_sconto/init.php @@ -22,7 +22,7 @@ include_once __DIR__.'/../../core.php'; use Modules\PianiSconto\PianoSconto; if (isset($id_record)) { - $record = $dbo->fetchOne('SELECT * FROM mg_listini WHERE id='.prepare($id_record)); + $record = $dbo->fetchOne('SELECT * FROM mg_piani_sconto WHERE id='.prepare($id_record)); $listino = PianoSconto::find($id_record); } diff --git a/modules/piano_sconto/src/PianoSconto.php b/modules/piano_sconto/src/PianoSconto.php index 8c9ff872c..2ae36d952 100644 --- a/modules/piano_sconto/src/PianoSconto.php +++ b/modules/piano_sconto/src/PianoSconto.php @@ -26,7 +26,7 @@ class PianoSconto extends Model { use SimpleModelTrait; - protected $table = 'mg_listini'; + protected $table = 'mg_piani_sconto'; public static function build($nome, $percentuale) { diff --git a/modules/preventivi/row-add.php b/modules/preventivi/row-add.php index 5ebbf5fc6..aa3407d03 100755 --- a/modules/preventivi/row-add.php +++ b/modules/preventivi/row-add.php @@ -72,7 +72,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/modules/scadenzario/bulk.php b/modules/scadenzario/bulk.php index bf54a57fb..a9529dd22 100755 --- a/modules/scadenzario/bulk.php +++ b/modules/scadenzario/bulk.php @@ -19,7 +19,10 @@ include_once __DIR__.'/../../core.php'; +use Models\OperationLog; use Modules\Anagrafiche\Anagrafica; +use Modules\Emails\Mail; +use Modules\Emails\Template; use Modules\Fatture\Fattura; use Modules\Scadenzario\Scadenza; @@ -66,6 +69,91 @@ switch (post('op')) { ])); } + break; + + case 'send-sollecito': + $list = []; + foreach ($id_records as $id) { + $scadenza = Scadenza::find($id); + $documento = $scadenza->documento; + + // Controllo se è una fattura di vendita + if ($documento->direzione == 'entrata'){ + $id_documento = $documento->id; + $id_anagrafica = $documento->idanagrafica; + + $fattura_allegata = $dbo->selectOne('zz_files', 'id', ['id_module' => $id_module, 'id_record' => $id, 'original' => 'Fattura di vendita.pdf'])['id']; + + // Allego stampa della fattura se non presente + if (empty($fattura_allegata)) { + $print_predefined = $dbo->selectOne('zz_prints', '*', ['predefined' => 1, 'id_module' => Modules::get('Fatture di vendita')['id']]); + + $print = Prints::render($print_predefined['id'], $id_documento, null, true); + $name = 'Fattura di vendita'; + $upload = Uploads::upload($print['pdf'], [ + 'name' => $name, + 'original_name' => $name.'.pdf', + 'category' => 'Generale', + 'id_module' => $id_module, + 'id_record' => $id, + ]); + + $fattura_allegata = $dbo->selectOne('zz_files', 'id', ['id_module' => $id_module, 'id_record' => $id, 'original' => 'Fattura di vendita.pdf'])['id']; + } + + // Selezione destinatari e invio mail + $template = Template::pool('Sollecito di pagamento'); + if (!empty($template)) { + $creata_mail = false; + $emails = []; + + // Aggiungo email anagrafica + if (!empty($documento->anagrafica->email)) { + $emails[] = $documento->anagrafica->email; + $mail = Mail::build(auth()->getUser(), $template, $id); + $mail->addReceiver($documento->anagrafica->email); + $creata_mail = true; + } + + // Aggiungo email referenti in base alla mansione impostata nel template + $mansioni = $dbo->select('em_mansioni_template', 'idmansione', ['id_template' => $template->id]); + foreach ($mansioni as $mansione) { + $referenti = $dbo->table('an_referenti')->where('idmansione', $mansione['idmansione'])->where('idanagrafica', $id_anagrafica)->where('email', '!=', '')->get(); + if (!$referenti->isEmpty() && $creata_mail == false) { + $mail = Mail::build(auth()->getUser(), $template, $id); + $creata_mail = true; + } + + foreach ($referenti as $referente) { + if (!in_array($referente->email, $emails)) { + $emails[] = $referente->email; + $mail->addReceiver($referente->email); + } + } + } + if ($creata_mail == true) { + if (!empty($fattura_allegata)) { + $mail->addUpload($fattura_allegata); + } + + $mail->save(); + OperationLog::setInfo('id_email', $mail->id); + OperationLog::setInfo('id_module', $id_module); + OperationLog::setInfo('id_record', $id_record); + OperationLog::build('send-email'); + + array_push($list, $documento->numero_esterno); + } + } + } + } + + if ($list){ + flash()->info(tr('Mail inviata per le Fatture _LIST_ !', [ + '_LIST_' => implode(',', $list), + ])); + } + break; } @@ -102,4 +190,14 @@ $operations['change-bank'] = [ ], ]; +$operations['send-sollecito'] = [ + 'text' => ' '.tr('Invia mail sollecito').'', + 'data' => [ + 'title' => tr('Inviare mail sollecito?'), + 'msg' => tr('Per ciascuna scadenza selezionata collegata ad una fattura di vendita, verrà inviata una mail con allegata la fattura di vendita corrispondente.
(Template utilizzato: Sollecito di pagamento)'), + 'button' => tr('Invia'), + 'class' => 'btn btn-lg btn-warning', + ], +]; + return $operations; diff --git a/plugins/piani_sconto_maggiorazione/edit.php b/plugins/piani_sconto_maggiorazione/edit.php index 231fcf8d5..bf80b3808 100644 --- a/plugins/piani_sconto_maggiorazione/edit.php +++ b/plugins/piani_sconto_maggiorazione/edit.php @@ -27,7 +27,7 @@ echo '
'; - $listini = $dbo->fetchArray('SELECT * FROM mg_listini ORDER BY id ASC'); + $listini = $dbo->fetchArray('SELECT * FROM mg_piani_sconto ORDER BY id ASC'); if (!empty($listini)) { echo ' diff --git a/plugins/pianificazione_interventi/row-add.php b/plugins/pianificazione_interventi/row-add.php index cf1eb3c75..b1b6a47c6 100755 --- a/plugins/pianificazione_interventi/row-add.php +++ b/plugins/pianificazione_interventi/row-add.php @@ -61,7 +61,7 @@ if (get('is_descrizione') !== null) { $file = 'articolo'; // Aggiunta sconto di default da listino per le vendite - $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_listini ON an_anagrafiche.idlistino_vendite=mg_listini.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); + $listino = $dbo->fetchOne('SELECT prc_guadagno FROM an_anagrafiche INNER JOIN mg_piani_sconto ON an_anagrafiche.id_piano_sconto_vendite=mg_piani_sconto.id WHERE idanagrafica='.prepare($documento['idanagrafica'])); if (!empty($listino['prc_guadagno'])) { $result['sconto_percentuale'] = $listino['prc_guadagno']; diff --git a/update/2_4_38.sql b/update/2_4_38.sql new file mode 100644 index 000000000..c3a8456ad --- /dev/null +++ b/update/2_4_38.sql @@ -0,0 +1,25 @@ +-- Aggiunto modulo Listini clienti +RENAME TABLE `mg_listini` TO `mg_piani_sconto`; +ALTER TABLE `an_anagrafiche` CHANGE `idlistino_acquisti` `id_piano_sconto_acquisti` INT(11) NULL DEFAULT NULL; +ALTER TABLE `an_anagrafiche` CHANGE `idlistino_vendite` `id_piano_sconto_vendite` INT(11) NULL DEFAULT NULL; +ALTER TABLE `an_anagrafiche` ADD `id_listino` INT NOT NULL AFTER `id_piano_sconto_acquisti`; + +CREATE TABLE `mg_listini` ( `id` INT NOT NULL AUTO_INCREMENT , `nome` VARCHAR(255) NOT NULL , `data_attivazione` DATE NULL , `data_scadenza_predefinita` DATE NULL , `is_sempre_visibile` BOOLEAN NOT NULL , `note` TEXT NOT NULL , `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `updated_at` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`)); + +CREATE TABLE `mg_listini_articoli` ( `id` INT NOT NULL AUTO_INCREMENT , `id_listino` INT NOT NULL, `id_articolo` INT NOT NULL , `data_scadenza` DATE NOT NULL , `prezzo_unitario` DECIMAL(15,6) NOT NULL , `prezzo_unitario_ivato` DECIMAL(15,6) NOT NULL , `sconto_percentuale` DECIMAL(15,6) NOT NULL , `dir` VARCHAR(20) NOT NULL , `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `updated_at` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`)); + +INSERT INTO `zz_modules` (`id`, `name`, `title`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`, `use_notes`, `use_checklists`) VALUES (NULL, 'Listini cliente', 'Listini cliente', 'listini_cliente', 'SELECT |select| FROM `mg_listini` WHERE 1=1 HAVING 2=2', '', 'fa fa-angle-right', '2.*', '2.*', '2', (SELECT `id` FROM `zz_modules` AS `t` WHERE `t`.`name`='Magazzino'), '1', '1', '0', '0'); + +INSERT INTO `zz_views` ( `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'id', 'id', 1, 1, 0, 0, '', '', 0, 0, 1), +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Nome', 'nome', 2, 1, 0, 0, '', '', 1, 0, 1); +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Data attivazione', 'data_attivazione', 3, 1, 0, 1, 0, '', '', 1, 0, 1), +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Articoli', '(SELECT COUNT(id) FROM mg_listini_articoli WHERE id_listino=mg_listini.id)', 4, 1, 0, 0, 0, '', '', 1, 0, 1), +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Anagrafiche', '(SELECT COUNT(idanagrafica) FROM an_anagrafiche WHERE id_listino=mg_listini.id)', 5, 1, 0, 0, 0, '', '', 1, 0, 1), +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Ultima modifica', '(SELECT username FROM zz_users WHERE id=(SELECT id_utente FROM zz_operations WHERE id_module=(SELECT id FROM zz_modules WHERE name=\'Listini cliente\') AND id_record=mg_listini.id ORDER BY id DESC LIMIT 0,1))', 6, 1, 0, 0, 0, '', '', 1, 0, 1), +((SELECT `id` FROM `zz_modules` WHERE name='Listini cliente'), 'Sempre visibile', 'IF(is_sempre_visibile=0,\'NO\',\'SÌ\')', 7, 1, 0, 0, 0, '', '', 1, 0, 1); + +UPDATE `zz_plugins` SET `title` = 'Netto clienti', `name` = 'Netto Clienti' WHERE `zz_plugins`.`name` = 'Listino Clienti'; + +ALTER TABLE `mg_articoli` ADD `minimo_vendita` DECIMAL(15,6) NOT NULL AFTER `prezzo_vendita_ivato`; +ALTER TABLE `mg_articoli` ADD `minimo_vendita_ivato` DECIMAL(15,6) NOT NULL AFTER `minimo_vendita`; \ No newline at end of file diff --git a/update/tables.php b/update/tables.php index 864b0a517..e445324a7 100755 --- a/update/tables.php +++ b/update/tables.php @@ -93,6 +93,8 @@ return [ 'mg_categorie', 'mg_causali_movimenti', 'mg_listini', + 'mg_listini_articoli', + 'mg_piani_sconto', 'mg_prezzi_articoli', 'mg_movimenti', 'mg_prodotti',