From 1c9e7b163413e2cd12c10fec90b6684bd843d400 Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Fri, 4 Aug 2017 16:28:16 +0200 Subject: [PATCH] Commit iniziale (r1662) Migrazione da SourceForge, partendo dal commit 1662 della carrtella trunk/openstamanager. --- .editorconfig | 11 + .gitignore | 87 + .htaccess | 88 + CHANGELOG.md | 202 + README.md | 133 + VERSION | 1 + actions.php | 249 + add.php | 94 + ajax.php | 49 + ajax_autocomplete.php | 1196 ++++ ajax_dataload.php | 219 + ajax_select.php | 563 ++ api/index.php | 29 + assets/src/css/datatables.css | 221 + assets/src/css/print/print.css | 67 + assets/src/css/style.css | 561 ++ assets/src/css/themes/default.css | 214 + assets/src/img/ajax-loader.gif | Bin 0 -> 8238 bytes assets/src/img/help.png | Bin 0 -> 11709 bytes assets/src/img/logo.png | Bin 0 -> 8195 bytes assets/src/img/osm_loading.gif | Bin 0 -> 23501 bytes assets/src/img/progress.gif | Bin 0 -> 7970 bytes assets/src/js/custom.js | 41 + assets/src/js/i18n/datatables/it.json | 23 + backup/.htaccess | 1 + bug.php | 275 + call.php | 24 + composer.json | 57 + config.example.php | 22 + controller.php | 101 + core.php | 264 + couscous.yml | 47 + docs/.htaccess | 1 + docs/API.md | 110 + docs/Assets.md | 107 + docs/Contribuire.md | 10 + docs/File.md | 36 + docs/Framework.md | 67 + docs/Installazione.md | 150 + docs/Moduli.md | 271 + docs/Nucleo.md | 253 + docs/Plugin.md | 10 + docs/README.md | 51 + docs/Stampe.md | 37 + docs/Widget.md | 10 + editor.php | 212 + files/.htaccess | 5 + files/my_impianti/componente.ini | 20 + gulpfile.js | 300 + include/.htaccess | 1 + include/bottom.php | 54 + include/configuration.php | 450 ++ include/manager.php | 193 + include/top.php | 275 + include/update.php | 256 + index.php | 164 + info.php | 157 + lib/classes/API.php | 228 + lib/classes/Auth.php | 234 + lib/classes/CSRF.php | 309 + lib/classes/Database.php | 615 ++ lib/classes/Filter.php | 148 + lib/classes/HTMLBuilder/HTMLBuilder.php | 312 + .../HTMLBuilder/Handler/ChoicesHandler.php | 89 + .../HTMLBuilder/Handler/DateHandler.php | 77 + .../HTMLBuilder/Handler/DefaultHandler.php | 98 + .../HTMLBuilder/Handler/HandlerInterface.php | 12 + .../HTMLBuilder/Handler/MediaHandler.php | 41 + .../HTMLBuilder/Handler/SelectHandler.php | 202 + .../HTMLBuilder/Manager/CSRFManager.php | 23 + .../HTMLBuilder/Manager/FileManager.php | 128 + .../HTMLBuilder/Manager/ManagerInterface.php | 12 + .../HTMLBuilder/Wrapper/HTMLWrapper.php | 146 + .../HTMLBuilder/Wrapper/WrapperInterface.php | 14 + lib/classes/Intl/FileLoader.php | 52 + lib/classes/Intl/Formatter.php | 470 ++ lib/classes/Modules.php | 466 ++ lib/classes/Permissions.php | 89 + lib/classes/Plugins.php | 117 + lib/classes/Settings.php | 60 + lib/classes/Translator.php | 361 ++ lib/classes/Update.php | 306 + lib/classes/Util/Ini.php | 155 + lib/classes/Util/Singleton.php | 38 + lib/classes/Widgets.php | 173 + lib/deprecated.php | 1025 ++++ lib/functions.js | 1255 ++++ lib/functions.php | 842 +++ lib/init.js | 94 + lib/permissions_check.php | 61 + lib/user_check.php | 17 + lib/util.php | 416 ++ locale/.htaccess | 1 + locale/it/it.mo | Bin 0 -> 86288 bytes locale/it/it.po | 5462 +++++++++++++++++ log.php | 87 + logs/.htaccess | 1 + modules/aggiornamenti/actions.php | 127 + modules/aggiornamenti/api/retrieve.php | 64 + modules/aggiornamenti/edit.php | 292 + modules/aggiornamenti/upload_modules.php | 136 + modules/anagrafiche/actions.php | 239 + modules/anagrafiche/add.php | 33 + modules/anagrafiche/api/retrieve.php | 18 + modules/anagrafiche/bulk.php | 23 + modules/anagrafiche/edit.php | 351 ++ modules/anagrafiche/init.php | 9 + modules/anagrafiche/plugins/referenti.php | 153 + modules/anagrafiche/plugins/sedi.php | 264 + modules/anagrafiche/plugins/statistiche.php | 172 + modules/articoli/actions.php | 233 + modules/articoli/add.php | 55 + modules/articoli/edit.php | 269 + modules/articoli/init.php | 7 + modules/articoli/modutil.php | 95 + modules/articoli/plugins/articoli.lotti.php | 380 ++ .../articoli/plugins/articoli.movimenti.php | 69 + .../articoli/widgets/articoli.dashboard.php | 31 + modules/automezzi/actions.php | 162 + modules/automezzi/add.php | 25 + modules/automezzi/add_articolo.php | 38 + modules/automezzi/add_tecnico.php | 55 + modules/automezzi/edit.php | 96 + modules/automezzi/init.php | 7 + modules/automezzi/row-list-articoli.php | 62 + modules/automezzi/row-list-tecnici.php | 66 + modules/backup/actions.php | 30 + modules/backup/edit.php | 144 + modules/beni/actions.php | 40 + modules/beni/add.php | 21 + modules/beni/edit.php | 33 + modules/beni/init.php | 7 + modules/categorie/actions.php | 82 + modules/categorie/add.php | 83 + modules/categorie/edit.php | 82 + modules/categorie/init.php | 7 + modules/categorie/row-list.php | 20 + modules/causali/actions.php | 48 + modules/causali/add.php | 20 + modules/causali/edit.php | 32 + modules/causali/init.php | 7 + modules/contratti/actions.php | 253 + modules/contratti/add.php | 25 + modules/contratti/add_riga.php | 136 + modules/contratti/ajax.php | 36 + modules/contratti/edit.php | 333 + modules/contratti/init.php | 7 + modules/contratti/js/contratti_helper.js | 44 + modules/contratti/modutil.php | 188 + modules/contratti/plugins/addfattura.php | 55 + .../plugins/contratti.consuntivo.php | 343 ++ .../contratti.fatturaordiniservizio.php | 363 ++ .../contratti.ordiniservizio.interventi.php | 250 + .../plugins/contratti.ordiniservizio.php | 358 ++ .../contratti.pianificazioneinterventi.php | 152 + modules/contratti/row-list.php | 187 + ...tti.pianificazionedashboard.interventi.php | 116 + .../contratti.pianificazionedashboard.php | 110 + .../widgets/contratti.ratecontrattuali.php | 144 + .../widgets/contratti_scadenza.dashboard.php | 44 + modules/dashboard/ajaxreq.php | 136 + modules/dashboard/edit.php | 561 ++ modules/ddt/actions.php | 527 ++ modules/ddt/add.php | 48 + modules/ddt/add_articolo.php | 161 + modules/ddt/add_riga.php | 109 + modules/ddt/add_serial.php | 108 + modules/ddt/creafattura.php | 254 + modules/ddt/edit.php | 196 + modules/ddt/init.php | 7 + modules/ddt/modutil.php | 337 + modules/ddt/plugins/ddt.anagrafiche.php | 99 + modules/ddt/row-list.php | 380 ++ modules/fatture/actions.php | 1260 ++++ modules/fatture/add.php | 41 + modules/fatture/add_articolo.php | 165 + modules/fatture/add_contratto.php | 88 + modules/fatture/add_ddt.php | 42 + modules/fatture/add_ddt_righe.php | 224 + modules/fatture/add_intervento.php | 89 + modules/fatture/add_preventivo.php | 92 + modules/fatture/add_riga.php | 124 + modules/fatture/add_serial.php | 108 + modules/fatture/edit.php | 387 ++ modules/fatture/edit_riga.php | 120 + modules/fatture/init.php | 7 + modules/fatture/modutil.php | 744 +++ modules/fatture/row-list.php | 396 ++ modules/gestione_componenti/actions.php | 52 + modules/gestione_componenti/add.php | 40 + modules/gestione_componenti/edit.php | 68 + modules/gestione_componenti/init.php | 10 + modules/impostazioni/actions.php | 49 + modules/impostazioni/edit.php | 74 + modules/impostazioni/init.php | 7 + modules/interventi/actions.php | 622 ++ modules/interventi/add.php | 330 + modules/interventi/add_articolo.php | 207 + modules/interventi/add_firma.php | 113 + modules/interventi/add_righe.php | 119 + modules/interventi/add_serial.php | 47 + modules/interventi/ajax_articoli.php | 164 + modules/interventi/ajax_costi.php | 98 + modules/interventi/ajax_righe.php | 104 + modules/interventi/ajax_tecnici.php | 307 + modules/interventi/edit.php | 293 + modules/interventi/init.php | 9 + modules/interventi/js/interventi_helperjs.js | 31 + modules/interventi/modutil.php | 150 + .../plugins/my_impianti.interventi.php | 42 + modules/iva/actions.php | 53 + modules/iva/add.php | 31 + modules/iva/edit.php | 49 + modules/iva/init.php | 7 + modules/listini/actions.php | 33 + modules/listini/add.php | 26 + modules/listini/edit.php | 44 + modules/listini/init.php | 7 + modules/misure/actions.php | 52 + modules/misure/add.php | 21 + modules/misure/edit.php | 33 + modules/misure/init.php | 7 + modules/my_impianti/actions.php | 121 + modules/my_impianti/add.php | 33 + modules/my_impianti/edit.php | 109 + modules/my_impianti/init.php | 7 + modules/my_impianti/modutil.php | 15 + .../plugins/my_impianti.anagrafiche.php | 80 + .../plugins/my_impianti.componenti.php | 286 + .../plugins/my_impianti.interventi.php | 179 + modules/ordini/actions.php | 385 ++ modules/ordini/add.php | 40 + modules/ordini/add_articolo.php | 153 + modules/ordini/add_riga.php | 124 + modules/ordini/add_serial.php | 108 + modules/ordini/creaddt.php | 251 + modules/ordini/creafattura.php | 244 + modules/ordini/edit.php | 123 + modules/ordini/init.php | 7 + modules/ordini/modutil.php | 307 + modules/ordini/row-list.php | 352 ++ modules/pagamenti/actions.php | 89 + modules/pagamenti/add.php | 21 + modules/pagamenti/edit.php | 188 + modules/pagamenti/init.php | 7 + modules/partitario/actions.php | 65 + modules/partitario/add_conto.php | 30 + modules/partitario/edit.php | 256 + modules/partitario/edit_conto.php | 35 + modules/porti/actions.php | 53 + modules/porti/add.php | 21 + modules/porti/edit.php | 44 + modules/porti/init.php | 7 + modules/preventivi/actions.php | 301 + modules/preventivi/add.php | 32 + modules/preventivi/ajax.php | 10 + modules/preventivi/edit.php | 163 + modules/preventivi/edit_riga.php | 152 + modules/preventivi/init.php | 7 + modules/preventivi/modutil.php | 204 + .../plugins/preventivi.consuntivo.php | 331 + modules/preventivi/row-list.php | 226 + .../widgets/preventivi.dashboard.php | 36 + modules/primanota/actions.php | 301 + modules/primanota/add.php | 306 + modules/primanota/edit.php | 243 + modules/primanota/init.php | 7 + modules/ritenute/actions.php | 51 + modules/ritenute/add.php | 31 + modules/ritenute/edit.php | 43 + modules/ritenute/init.php | 7 + modules/scadenzario/actions.php | 29 + modules/scadenzario/controller_after.php | 35 + modules/scadenzario/edit.php | 179 + modules/scadenzario/init.php | 7 + modules/stati_intervento/actions.php | 41 + modules/stati_intervento/add.php | 39 + modules/stati_intervento/edit.php | 60 + modules/stati_intervento/init.php | 7 + modules/tecnici_tariffe/actions.php | 85 + modules/tecnici_tariffe/edit.php | 85 + modules/tecnici_tariffe/init.php | 15 + modules/tipi_anagrafiche/actions.php | 48 + modules/tipi_anagrafiche/add.php | 24 + modules/tipi_anagrafiche/edit.php | 54 + modules/tipi_anagrafiche/init.php | 7 + modules/tipi_intervento/actions.php | 54 + modules/tipi_intervento/add.php | 25 + modules/tipi_intervento/edit.php | 87 + modules/tipi_intervento/init.php | 7 + modules/utenti/actions.php | 160 + modules/utenti/add.php | 21 + modules/utenti/edit.php | 152 + modules/utenti/init.php | 7 + modules/utenti/modutil.php | 50 + modules/utenti/user.php | 83 + modules/viste/actions.php | 170 + modules/viste/edit.php | 495 ++ modules/viste/init.php | 7 + modules/voci_servizio/actions.php | 30 + modules/voci_servizio/add.php | 25 + modules/voci_servizio/edit.php | 28 + modules/voci_servizio/init.php | 7 + modules/zone/actions.php | 54 + modules/zone/add.php | 25 + modules/zone/edit.php | 30 + modules/zone/init.php | 7 + package.json | 199 + pdfgen.php | 98 + plugin_editor.php | 92 + plugins/sedi/actions.php | 61 + plugins/sedi/add.php | 70 + plugins/sedi/edit.php | 97 + plugins/sedi/init.php | 5 + templates/contratti/contratto.html | 18 + templates/contratti/contratto_body.html | 33 + templates/contratti/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/contratti/pdfgen.contratti.php | 192 + templates/contratti_cons/contratto.html | 18 + templates/contratti_cons/contratto_body.html | 40 + templates/contratti_cons/logo_azienda.jpg | Bin 0 -> 4348 bytes .../contratti_cons/pdfgen.contratti_cons.php | 335 + templates/ddt/ddt.html | 22 + templates/ddt/ddt_body.html | 58 + templates/ddt/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/ddt/pdfgen.ddt.php | 401 ++ templates/fatturato/fatturato.html | 59 + templates/fatturato/fatturato_body.html | 22 + templates/fatturato/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/fatturato/pdfgen.fatturato.php | 69 + templates/fatture/fattura.html | 22 + templates/fatture/fattura_body.html | 53 + templates/fatture/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/fatture/pdfgen.fatture.php | 466 ++ .../fatture_accompagnatorie/fattura.html | 22 + .../fatture_accompagnatorie/fattura_body.html | 61 + .../fatture_accompagnatorie/logo_azienda.jpg | Bin 0 -> 4348 bytes .../pdfgen.fatture_accompagnatorie.php | 540 ++ templates/interventi/actions.php | 610 ++ templates/interventi/init.php | 34 + templates/interventi/layout.html | 65 + templates/interventi/logo_azienda.jpg | Bin 0 -> 4348 bytes .../interventi_ordiniservizio/intervento.html | 12 + .../intervento_body.html | 48 + .../logo_azienda.jpg | Bin 0 -> 4348 bytes .../pdfgen.interventi_ordiniservizio.php | 207 + .../magazzino_inventario/logo_azienda.jpg | Bin 0 -> 4348 bytes .../magazzino_inventario.html | 59 + .../magazzino_inventario_body.html | 22 + .../pdfgen.magazzino_inventario.php | 73 + templates/ordini/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/ordini/ordine.html | 22 + templates/ordini/ordine_body.html | 41 + templates/ordini/pdfgen.ordini.php | 307 + .../partitario_mastrino/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/partitario_mastrino/partitario.html | 29 + .../partitario_mastrino/partitario_body.html | 36 + .../pdfgen.partitario_mastrino.php | 319 + templates/pdfgen_variables.php | 129 + templates/preventivi/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/preventivi/pdfgen.preventivi.php | 304 + templates/preventivi/preventivo.html | 18 + templates/preventivi/preventivo_body.html | 37 + templates/preventivi_cons/logo_azienda.jpg | Bin 0 -> 4348 bytes .../pdfgen.preventivi_cons.php | 383 ++ templates/preventivi_cons/preventivo.html | 18 + .../preventivi_cons/preventivo_body.html | 40 + templates/riepilogo_contratti/contratto.html | 17 + .../riepilogo_contratti/contratto_body.html | 37 + .../riepilogo_contratti/logo_azienda.jpg | Bin 0 -> 4348 bytes .../pdfgen.riepilogo_contratti.php | 148 + .../riepilogo_interventi/intervento.html | 17 + .../riepilogo_interventi/intervento_body.html | 40 + .../riepilogo_interventi/logo_azienda.jpg | Bin 0 -> 4348 bytes .../pdfgen.riepilogo_interventi.php | 419 ++ templates/scadenzario/logo_azienda.jpg | Bin 0 -> 4348 bytes templates/scadenzario/pdfgen.scadenzario.php | 68 + templates/scadenzario/scadenzario.html | 12 + templates/scadenzario/scadenzario_body.html | 13 + update/.htaccess | 1 + update/2_1.php | 25 + update/2_2.php | 113 + update/2_3.php | 223 + 383 files changed, 55144 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 VERSION create mode 100644 actions.php create mode 100644 add.php create mode 100644 ajax.php create mode 100644 ajax_autocomplete.php create mode 100644 ajax_dataload.php create mode 100644 ajax_select.php create mode 100644 api/index.php create mode 100644 assets/src/css/datatables.css create mode 100644 assets/src/css/print/print.css create mode 100644 assets/src/css/style.css create mode 100644 assets/src/css/themes/default.css create mode 100644 assets/src/img/ajax-loader.gif create mode 100644 assets/src/img/help.png create mode 100644 assets/src/img/logo.png create mode 100644 assets/src/img/osm_loading.gif create mode 100644 assets/src/img/progress.gif create mode 100644 assets/src/js/custom.js create mode 100644 assets/src/js/i18n/datatables/it.json create mode 100644 backup/.htaccess create mode 100644 bug.php create mode 100644 call.php create mode 100644 composer.json create mode 100644 config.example.php create mode 100644 controller.php create mode 100644 core.php create mode 100644 couscous.yml create mode 100644 docs/.htaccess create mode 100644 docs/API.md create mode 100644 docs/Assets.md create mode 100644 docs/Contribuire.md create mode 100644 docs/File.md create mode 100644 docs/Framework.md create mode 100644 docs/Installazione.md create mode 100644 docs/Moduli.md create mode 100644 docs/Nucleo.md create mode 100644 docs/Plugin.md create mode 100644 docs/README.md create mode 100644 docs/Stampe.md create mode 100644 docs/Widget.md create mode 100644 editor.php create mode 100644 files/.htaccess create mode 100644 files/my_impianti/componente.ini create mode 100644 gulpfile.js create mode 100644 include/.htaccess create mode 100644 include/bottom.php create mode 100644 include/configuration.php create mode 100644 include/manager.php create mode 100644 include/top.php create mode 100644 include/update.php create mode 100644 index.php create mode 100644 info.php create mode 100644 lib/classes/API.php create mode 100644 lib/classes/Auth.php create mode 100644 lib/classes/CSRF.php create mode 100644 lib/classes/Database.php create mode 100644 lib/classes/Filter.php create mode 100644 lib/classes/HTMLBuilder/HTMLBuilder.php create mode 100644 lib/classes/HTMLBuilder/Handler/ChoicesHandler.php create mode 100644 lib/classes/HTMLBuilder/Handler/DateHandler.php create mode 100644 lib/classes/HTMLBuilder/Handler/DefaultHandler.php create mode 100644 lib/classes/HTMLBuilder/Handler/HandlerInterface.php create mode 100644 lib/classes/HTMLBuilder/Handler/MediaHandler.php create mode 100644 lib/classes/HTMLBuilder/Handler/SelectHandler.php create mode 100644 lib/classes/HTMLBuilder/Manager/CSRFManager.php create mode 100644 lib/classes/HTMLBuilder/Manager/FileManager.php create mode 100644 lib/classes/HTMLBuilder/Manager/ManagerInterface.php create mode 100644 lib/classes/HTMLBuilder/Wrapper/HTMLWrapper.php create mode 100644 lib/classes/HTMLBuilder/Wrapper/WrapperInterface.php create mode 100644 lib/classes/Intl/FileLoader.php create mode 100644 lib/classes/Intl/Formatter.php create mode 100644 lib/classes/Modules.php create mode 100644 lib/classes/Permissions.php create mode 100644 lib/classes/Plugins.php create mode 100644 lib/classes/Settings.php create mode 100644 lib/classes/Translator.php create mode 100644 lib/classes/Update.php create mode 100644 lib/classes/Util/Ini.php create mode 100644 lib/classes/Util/Singleton.php create mode 100644 lib/classes/Widgets.php create mode 100644 lib/deprecated.php create mode 100644 lib/functions.js create mode 100644 lib/functions.php create mode 100644 lib/init.js create mode 100644 lib/permissions_check.php create mode 100644 lib/user_check.php create mode 100644 lib/util.php create mode 100644 locale/.htaccess create mode 100644 locale/it/it.mo create mode 100644 locale/it/it.po create mode 100644 log.php create mode 100644 logs/.htaccess create mode 100644 modules/aggiornamenti/actions.php create mode 100644 modules/aggiornamenti/api/retrieve.php create mode 100644 modules/aggiornamenti/edit.php create mode 100644 modules/aggiornamenti/upload_modules.php create mode 100644 modules/anagrafiche/actions.php create mode 100644 modules/anagrafiche/add.php create mode 100644 modules/anagrafiche/api/retrieve.php create mode 100644 modules/anagrafiche/bulk.php create mode 100644 modules/anagrafiche/edit.php create mode 100644 modules/anagrafiche/init.php create mode 100644 modules/anagrafiche/plugins/referenti.php create mode 100644 modules/anagrafiche/plugins/sedi.php create mode 100644 modules/anagrafiche/plugins/statistiche.php create mode 100644 modules/articoli/actions.php create mode 100644 modules/articoli/add.php create mode 100644 modules/articoli/edit.php create mode 100644 modules/articoli/init.php create mode 100644 modules/articoli/modutil.php create mode 100644 modules/articoli/plugins/articoli.lotti.php create mode 100644 modules/articoli/plugins/articoli.movimenti.php create mode 100644 modules/articoli/widgets/articoli.dashboard.php create mode 100644 modules/automezzi/actions.php create mode 100644 modules/automezzi/add.php create mode 100644 modules/automezzi/add_articolo.php create mode 100644 modules/automezzi/add_tecnico.php create mode 100644 modules/automezzi/edit.php create mode 100644 modules/automezzi/init.php create mode 100644 modules/automezzi/row-list-articoli.php create mode 100644 modules/automezzi/row-list-tecnici.php create mode 100644 modules/backup/actions.php create mode 100644 modules/backup/edit.php create mode 100644 modules/beni/actions.php create mode 100644 modules/beni/add.php create mode 100644 modules/beni/edit.php create mode 100644 modules/beni/init.php create mode 100644 modules/categorie/actions.php create mode 100644 modules/categorie/add.php create mode 100644 modules/categorie/edit.php create mode 100644 modules/categorie/init.php create mode 100644 modules/categorie/row-list.php create mode 100644 modules/causali/actions.php create mode 100644 modules/causali/add.php create mode 100644 modules/causali/edit.php create mode 100644 modules/causali/init.php create mode 100644 modules/contratti/actions.php create mode 100644 modules/contratti/add.php create mode 100644 modules/contratti/add_riga.php create mode 100644 modules/contratti/ajax.php create mode 100644 modules/contratti/edit.php create mode 100644 modules/contratti/init.php create mode 100644 modules/contratti/js/contratti_helper.js create mode 100644 modules/contratti/modutil.php create mode 100644 modules/contratti/plugins/addfattura.php create mode 100644 modules/contratti/plugins/contratti.consuntivo.php create mode 100644 modules/contratti/plugins/contratti.fatturaordiniservizio.php create mode 100644 modules/contratti/plugins/contratti.ordiniservizio.interventi.php create mode 100644 modules/contratti/plugins/contratti.ordiniservizio.php create mode 100644 modules/contratti/plugins/contratti.pianificazioneinterventi.php create mode 100644 modules/contratti/row-list.php create mode 100644 modules/contratti/widgets/contratti.pianificazionedashboard.interventi.php create mode 100644 modules/contratti/widgets/contratti.pianificazionedashboard.php create mode 100644 modules/contratti/widgets/contratti.ratecontrattuali.php create mode 100644 modules/contratti/widgets/contratti_scadenza.dashboard.php create mode 100644 modules/dashboard/ajaxreq.php create mode 100644 modules/dashboard/edit.php create mode 100644 modules/ddt/actions.php create mode 100644 modules/ddt/add.php create mode 100644 modules/ddt/add_articolo.php create mode 100644 modules/ddt/add_riga.php create mode 100644 modules/ddt/add_serial.php create mode 100644 modules/ddt/creafattura.php create mode 100644 modules/ddt/edit.php create mode 100644 modules/ddt/init.php create mode 100644 modules/ddt/modutil.php create mode 100644 modules/ddt/plugins/ddt.anagrafiche.php create mode 100644 modules/ddt/row-list.php create mode 100644 modules/fatture/actions.php create mode 100644 modules/fatture/add.php create mode 100644 modules/fatture/add_articolo.php create mode 100644 modules/fatture/add_contratto.php create mode 100644 modules/fatture/add_ddt.php create mode 100644 modules/fatture/add_ddt_righe.php create mode 100644 modules/fatture/add_intervento.php create mode 100644 modules/fatture/add_preventivo.php create mode 100644 modules/fatture/add_riga.php create mode 100644 modules/fatture/add_serial.php create mode 100644 modules/fatture/edit.php create mode 100644 modules/fatture/edit_riga.php create mode 100644 modules/fatture/init.php create mode 100644 modules/fatture/modutil.php create mode 100644 modules/fatture/row-list.php create mode 100644 modules/gestione_componenti/actions.php create mode 100644 modules/gestione_componenti/add.php create mode 100644 modules/gestione_componenti/edit.php create mode 100644 modules/gestione_componenti/init.php create mode 100644 modules/impostazioni/actions.php create mode 100644 modules/impostazioni/edit.php create mode 100644 modules/impostazioni/init.php create mode 100644 modules/interventi/actions.php create mode 100644 modules/interventi/add.php create mode 100644 modules/interventi/add_articolo.php create mode 100644 modules/interventi/add_firma.php create mode 100644 modules/interventi/add_righe.php create mode 100644 modules/interventi/add_serial.php create mode 100644 modules/interventi/ajax_articoli.php create mode 100644 modules/interventi/ajax_costi.php create mode 100644 modules/interventi/ajax_righe.php create mode 100644 modules/interventi/ajax_tecnici.php create mode 100644 modules/interventi/edit.php create mode 100644 modules/interventi/init.php create mode 100644 modules/interventi/js/interventi_helperjs.js create mode 100644 modules/interventi/modutil.php create mode 100644 modules/interventi/plugins/my_impianti.interventi.php create mode 100644 modules/iva/actions.php create mode 100644 modules/iva/add.php create mode 100644 modules/iva/edit.php create mode 100644 modules/iva/init.php create mode 100644 modules/listini/actions.php create mode 100644 modules/listini/add.php create mode 100644 modules/listini/edit.php create mode 100644 modules/listini/init.php create mode 100644 modules/misure/actions.php create mode 100644 modules/misure/add.php create mode 100644 modules/misure/edit.php create mode 100644 modules/misure/init.php create mode 100644 modules/my_impianti/actions.php create mode 100644 modules/my_impianti/add.php create mode 100644 modules/my_impianti/edit.php create mode 100644 modules/my_impianti/init.php create mode 100644 modules/my_impianti/modutil.php create mode 100644 modules/my_impianti/plugins/my_impianti.anagrafiche.php create mode 100644 modules/my_impianti/plugins/my_impianti.componenti.php create mode 100644 modules/my_impianti/plugins/my_impianti.interventi.php create mode 100644 modules/ordini/actions.php create mode 100644 modules/ordini/add.php create mode 100644 modules/ordini/add_articolo.php create mode 100644 modules/ordini/add_riga.php create mode 100644 modules/ordini/add_serial.php create mode 100644 modules/ordini/creaddt.php create mode 100644 modules/ordini/creafattura.php create mode 100644 modules/ordini/edit.php create mode 100644 modules/ordini/init.php create mode 100644 modules/ordini/modutil.php create mode 100644 modules/ordini/row-list.php create mode 100644 modules/pagamenti/actions.php create mode 100644 modules/pagamenti/add.php create mode 100644 modules/pagamenti/edit.php create mode 100644 modules/pagamenti/init.php create mode 100644 modules/partitario/actions.php create mode 100644 modules/partitario/add_conto.php create mode 100644 modules/partitario/edit.php create mode 100644 modules/partitario/edit_conto.php create mode 100644 modules/porti/actions.php create mode 100644 modules/porti/add.php create mode 100644 modules/porti/edit.php create mode 100644 modules/porti/init.php create mode 100644 modules/preventivi/actions.php create mode 100644 modules/preventivi/add.php create mode 100644 modules/preventivi/ajax.php create mode 100644 modules/preventivi/edit.php create mode 100644 modules/preventivi/edit_riga.php create mode 100644 modules/preventivi/init.php create mode 100644 modules/preventivi/modutil.php create mode 100644 modules/preventivi/plugins/preventivi.consuntivo.php create mode 100644 modules/preventivi/row-list.php create mode 100644 modules/preventivi/widgets/preventivi.dashboard.php create mode 100644 modules/primanota/actions.php create mode 100644 modules/primanota/add.php create mode 100644 modules/primanota/edit.php create mode 100644 modules/primanota/init.php create mode 100644 modules/ritenute/actions.php create mode 100644 modules/ritenute/add.php create mode 100644 modules/ritenute/edit.php create mode 100644 modules/ritenute/init.php create mode 100644 modules/scadenzario/actions.php create mode 100644 modules/scadenzario/controller_after.php create mode 100644 modules/scadenzario/edit.php create mode 100644 modules/scadenzario/init.php create mode 100644 modules/stati_intervento/actions.php create mode 100644 modules/stati_intervento/add.php create mode 100644 modules/stati_intervento/edit.php create mode 100644 modules/stati_intervento/init.php create mode 100644 modules/tecnici_tariffe/actions.php create mode 100644 modules/tecnici_tariffe/edit.php create mode 100644 modules/tecnici_tariffe/init.php create mode 100644 modules/tipi_anagrafiche/actions.php create mode 100644 modules/tipi_anagrafiche/add.php create mode 100644 modules/tipi_anagrafiche/edit.php create mode 100644 modules/tipi_anagrafiche/init.php create mode 100644 modules/tipi_intervento/actions.php create mode 100644 modules/tipi_intervento/add.php create mode 100644 modules/tipi_intervento/edit.php create mode 100644 modules/tipi_intervento/init.php create mode 100644 modules/utenti/actions.php create mode 100644 modules/utenti/add.php create mode 100644 modules/utenti/edit.php create mode 100644 modules/utenti/init.php create mode 100644 modules/utenti/modutil.php create mode 100644 modules/utenti/user.php create mode 100644 modules/viste/actions.php create mode 100644 modules/viste/edit.php create mode 100644 modules/viste/init.php create mode 100644 modules/voci_servizio/actions.php create mode 100644 modules/voci_servizio/add.php create mode 100644 modules/voci_servizio/edit.php create mode 100644 modules/voci_servizio/init.php create mode 100644 modules/zone/actions.php create mode 100644 modules/zone/add.php create mode 100644 modules/zone/edit.php create mode 100644 modules/zone/init.php create mode 100644 package.json create mode 100644 pdfgen.php create mode 100644 plugin_editor.php create mode 100644 plugins/sedi/actions.php create mode 100644 plugins/sedi/add.php create mode 100644 plugins/sedi/edit.php create mode 100644 plugins/sedi/init.php create mode 100644 templates/contratti/contratto.html create mode 100644 templates/contratti/contratto_body.html create mode 100644 templates/contratti/logo_azienda.jpg create mode 100644 templates/contratti/pdfgen.contratti.php create mode 100644 templates/contratti_cons/contratto.html create mode 100644 templates/contratti_cons/contratto_body.html create mode 100644 templates/contratti_cons/logo_azienda.jpg create mode 100644 templates/contratti_cons/pdfgen.contratti_cons.php create mode 100644 templates/ddt/ddt.html create mode 100644 templates/ddt/ddt_body.html create mode 100644 templates/ddt/logo_azienda.jpg create mode 100644 templates/ddt/pdfgen.ddt.php create mode 100644 templates/fatturato/fatturato.html create mode 100644 templates/fatturato/fatturato_body.html create mode 100644 templates/fatturato/logo_azienda.jpg create mode 100644 templates/fatturato/pdfgen.fatturato.php create mode 100644 templates/fatture/fattura.html create mode 100644 templates/fatture/fattura_body.html create mode 100644 templates/fatture/logo_azienda.jpg create mode 100644 templates/fatture/pdfgen.fatture.php create mode 100644 templates/fatture_accompagnatorie/fattura.html create mode 100644 templates/fatture_accompagnatorie/fattura_body.html create mode 100644 templates/fatture_accompagnatorie/logo_azienda.jpg create mode 100644 templates/fatture_accompagnatorie/pdfgen.fatture_accompagnatorie.php create mode 100644 templates/interventi/actions.php create mode 100644 templates/interventi/init.php create mode 100644 templates/interventi/layout.html create mode 100644 templates/interventi/logo_azienda.jpg create mode 100644 templates/interventi_ordiniservizio/intervento.html create mode 100644 templates/interventi_ordiniservizio/intervento_body.html create mode 100644 templates/interventi_ordiniservizio/logo_azienda.jpg create mode 100644 templates/interventi_ordiniservizio/pdfgen.interventi_ordiniservizio.php create mode 100644 templates/magazzino_inventario/logo_azienda.jpg create mode 100644 templates/magazzino_inventario/magazzino_inventario.html create mode 100644 templates/magazzino_inventario/magazzino_inventario_body.html create mode 100644 templates/magazzino_inventario/pdfgen.magazzino_inventario.php create mode 100644 templates/ordini/logo_azienda.jpg create mode 100644 templates/ordini/ordine.html create mode 100644 templates/ordini/ordine_body.html create mode 100644 templates/ordini/pdfgen.ordini.php create mode 100644 templates/partitario_mastrino/logo_azienda.jpg create mode 100644 templates/partitario_mastrino/partitario.html create mode 100644 templates/partitario_mastrino/partitario_body.html create mode 100644 templates/partitario_mastrino/pdfgen.partitario_mastrino.php create mode 100644 templates/pdfgen_variables.php create mode 100644 templates/preventivi/logo_azienda.jpg create mode 100644 templates/preventivi/pdfgen.preventivi.php create mode 100644 templates/preventivi/preventivo.html create mode 100644 templates/preventivi/preventivo_body.html create mode 100644 templates/preventivi_cons/logo_azienda.jpg create mode 100644 templates/preventivi_cons/pdfgen.preventivi_cons.php create mode 100644 templates/preventivi_cons/preventivo.html create mode 100644 templates/preventivi_cons/preventivo_body.html create mode 100644 templates/riepilogo_contratti/contratto.html create mode 100644 templates/riepilogo_contratti/contratto_body.html create mode 100644 templates/riepilogo_contratti/logo_azienda.jpg create mode 100644 templates/riepilogo_contratti/pdfgen.riepilogo_contratti.php create mode 100644 templates/riepilogo_interventi/intervento.html create mode 100644 templates/riepilogo_interventi/intervento_body.html create mode 100644 templates/riepilogo_interventi/logo_azienda.jpg create mode 100644 templates/riepilogo_interventi/pdfgen.riepilogo_interventi.php create mode 100644 templates/scadenzario/logo_azienda.jpg create mode 100644 templates/scadenzario/pdfgen.scadenzario.php create mode 100644 templates/scadenzario/scadenzario.html create mode 100644 templates/scadenzario/scadenzario_body.html create mode 100644 update/.htaccess create mode 100644 update/2_1.php create mode 100644 update/2_2.php create mode 100644 update/2_3.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..6bb235b83 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..2d5c859d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,87 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so +*.pyo +*.pyc + +# Packages # +############ +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +*~ +._* +.cache +.DS_Store +.DS_Store? +.idea +.project +.settings +.tmproj +*.esproj +*.sublime-project +*.sublime-workspace +nbproject +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +$RECYCLE.BIN +desktop.ini +Desktop.ini +.Spotlight-V100 +.Trashes +.fuse_hidden* +.directory +.Trash-* +.nfs* +*.cab +*.msi +*.msm +*.msp +*.lnk + +# Visual Studio Code # +###################### +.vscode/* + +# Npm and Yarn, Bower, Composer # +###################### +bower_components/ +node_modules/ +vendor/ + +# Project # +###################### +*.phar +*.lock +*.new +*.old +assets/dist +backup/* +!backup/.htaccess +files/* +!files/.htaccess +!files/my_impianti/ +files/my_impianti/* +!files/my_impianti/componente.ini +config.inc.php +REVISION diff --git a/.htaccess b/.htaccess new file mode 100644 index 000000000..6c0f5f354 --- /dev/null +++ b/.htaccess @@ -0,0 +1,88 @@ +# Remove autoindex +IndexIgnore * +## Options -Indexes + +# Try to set PHP settings +php_value upload_max_filesize 20M +php_value post_max_size 20M + +# Deny access to files starting with dot + + Order allow,deny + Deny from all + + +# Deny access to log, sql, htaccess ecc.. + + Order allow,deny + Deny from all + + +# Deny access to VERSION, REVISION and config file + + Order allow,deny + Deny from all + + +# Disable OSM indexing of php, html, htm, pdf files + + + Header set X-Robots-Tag: "noindex" + + + + + RewriteEngine On + + # Tell PHP that the mod_rewrite module is ENABLED. + SetEnv HTTP_MOD_REWRITE On + + # Deny access to protected folders + RewriteRule ^backup/?$ - [F,L] + RewriteRule ^docs/?$ - [F,L] + RewriteRule ^include/?$ - [F,L] + RewriteRule ^locale/?$ - [F,L] + RewriteRule ^logs/?$ - [F,L] + RewriteRule ^update/?$ - [F,L] + + # Deny access to svn, node_modules and vendor folders + RewriteRule ^.svn/?$ - [F,L] + RewriteRule ^node_modules/?$ - [F,L] + RewriteRule ^vendor/?$ - [F,L] + + # Prevent hacks + # proc/self/environ? no way! + RewriteCond %{QUERY_STRING} proc/self/environ [OR] + + # Block out any script trying to set a mosConfig value through the URL + RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR] + + # Block out any script trying to base64_encode crap to send via URL + RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR] + + # Block out any script that includes a '; +} + +echo ' + '; diff --git a/ajax.php b/ajax.php new file mode 100644 index 000000000..0ea57078a --- /dev/null +++ b/ajax.php @@ -0,0 +1,49 @@ + $val) { + // Se il valore esiste lo tolgo + if ($val == $value) { + $found = true; + + if ((int) $inversed == 1) { + unset($_SESSION[$array[0]][$array[1]][$idx]); + } + } + } + + if (!$found) { + array_push($_SESSION[$array[0]][$array[1]], $value); + } + + // print_r($_SESSION[$array[0]][$array[1]]); + + break; + + // Imposta un valore ad una sessione + case 'session_set': + $array = explode(',', get('session')); + $value = get('value'); + $clear = get('clear'); + + if ($clear == 1 || $value == '') { + unset($_SESSION[$array[0]][$array[1]]); + } else { + $_SESSION[$array[0]][$array[1]] = $value; + } + + break; +} diff --git a/ajax_autocomplete.php b/ajax_autocomplete.php new file mode 100644 index 000000000..fdf85608c --- /dev/null +++ b/ajax_autocomplete.php @@ -0,0 +1,1196 @@ +fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo htmlspecialchars_decode($rs[$i]['ragione_sociale'], ENT_QUOTES); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco città + elseif ($op == 'getcitta') { + $q = 'SELECT DISTINCT(citta) FROM an_anagrafiche WHERE 1=1 '.Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY citta'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo htmlspecialchars_decode($rs[$i]['citta'], ENT_QUOTES); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco province + elseif ($op == 'getprovince') { + $q = 'SELECT DISTINCT(provincia) FROM an_anagrafiche WHERE 1=1 '.Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY provincia'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['provincia']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco cap + elseif ($op == 'getcap') { + $q = 'SELECT DISTINCT(cap) FROM an_anagrafiche WHERE 1=1 '.Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY cap'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['cap']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco settori + elseif ($op == 'getsettori') { + $q = 'SELECT DISTINCT(settore) FROM an_anagrafiche WHERE 1=1 '.Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY settore'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['settore'], ENT_QUOTES); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco marche + elseif ($op == 'getmarche') { + $q = 'SELECT DISTINCT(marche) FROM an_anagrafiche WHERE 1=1 '.Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY marche'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['marche'], ENT_QUOTES); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco e-mail - uso la funzione nativa di php "trim" per rimuovere eventuali spazi dalle e-mail + elseif ($op == 'getemail') { + $idanagrafica = $get['idanagrafica']; + + if ($idanagrafica != '') { + $WHERE_IDANAGRAFICA = 'AND idanagrafica = '.$idanagrafica; + } + + // tutti i referenti per questo cliente + $q = 'SELECT DISTINCT(email),idanagrafica,nome FROM an_referenti WHERE 1=1 '.$WHERE_IDANAGRAFICA.' ORDER BY idanagrafica'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + if (trim($rs[$i]['email']) != '') { + echo html_entity_decode($rs[$i]['nome'].' <'.trim($rs[$i]['email']).'>'); + if (($i) < $n) { + echo '|'; + } + } + } + + // -- + + // tutti gli agenti + $q = "SELECT DISTINCT(email),ragione_sociale,an_anagrafiche.idanagrafica FROM an_anagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE idtipoanagrafica=(SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Agente') ORDER BY idanagrafica"; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + if (trim($rs[$i]['email']) != '') { + echo html_entity_decode($rs[$i]['nome'].' <'.trim($rs[$i]['email']).'>'); + if (($i) < $n) { + echo '|'; + } + } + } + + // -- + + // email azienda di questo cliente + $q = 'SELECT DISTINCT(email),ragione_sociale,idanagrafica FROM an_anagrafiche WHERE 1=1 '.$WHERE_IDANAGRAFICA.' ORDER BY idanagrafica'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + if (trim($rs[$i]['email']) != '') { + echo html_entity_decode($rs[$i]['ragione_sociale'].' <'.trim($rs[$i]['email']).'>'); + if (($i + 1) < $n) { + echo '|'; + } + } + } + } + + // Elenco sedi + elseif ($op == 'get_sedi') { + $idanagrafica = $get['idanagrafica']; + $q = "SELECT id, CONCAT_WS( ' - ', nomesede, citta ) AS descrizione FROM an_sedi WHERE idanagrafica='".$idanagrafica."' ".Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY id'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['id'].':'.$rs[$i]['descrizione']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco sedi con \n"; + echo "\n"; + + for ($i = 0; $i < $n; ++$i) { + echo '\n"; + } + } elseif ($op == 'get_default_value') { + $idanagrafica = $get['idanagrafica']; + $q = "SELECT idtipointervento_default FROM an_anagrafiche WHERE idanagrafica='".$idanagrafica."' ".Modules::getAdditionalsQuery('Anagrafiche').''; + $rs = $dbo->fetchArray($q); + + echo html_entity_decode($rs[0]['idtipointervento_default'], ENT_QUOTES); + } + + break; + + case 'Articoli': + // Elenco categorie + if ($op == 'getcategorie') { + $q = 'SELECT DISTINCT(categoria) FROM mg_articoli WHERE 1=1 '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY categoria'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['categoria']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco subcategorie + elseif ($op == 'getsubcategorie') { + $q = 'SELECT DISTINCT(subcategoria) FROM mg_articoli WHERE 1=1 '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY subcategoria'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['subcategoria']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco descrizione + elseif ($op == 'getdescrizione') { + $q = 'SELECT DISTINCT(descrizione) FROM mg_articoli WHERE 1=1 '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY descrizione'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['descrizione']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco codici + elseif ($op == 'getcodice') { + $q = 'SELECT DISTINCT(codice) FROM mg_articoli WHERE 1=1 '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY codice'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['codice']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + + // Elenco lotti in base all'articolo + elseif ($op == 'getlotti') { + $idarticolo = $get['idarticolo']; + $q = 'SELECT DISTINCT(lotto) FROM mg_prodotti WHERE idarticolo="'.$idarticolo.'" '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY lotto ASC'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + + echo "\n"; + + for ($i = 0; $i < $n; ++$i) { + $dir = 'entrata'; + + $qs = 'SELECT COUNT(serial) AS num_seriali FROM mg_prodotti WHERE idarticolo='.prepare($idarticolo).' AND lotto='.prepare($rs[$i]['lotto']).' '. + 'AND (serial NOT IN(SELECT serial FROM co_righe_documenti INNER JOIN co_documenti ON co_righe_documenti.iddocumento = co_documenti.id INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento = co_tipidocumento.id WHERE lotto='.prepare($rs[$i]['lotto']).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).') '. + 'AND serial NOT IN(SELECT serial FROM or_righe_ordini INNER JOIN or_ordini ON or_righe_ordini.idordine = or_ordini.id INNER JOIN or_tipiordine ON or_ordini.idtipoordine = or_tipiordine.id WHERE lotto='.prepare($rs[$i]['lotto']).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).') '. + 'AND serial NOT IN(SELECT serial FROM dt_righe_ddt INNER JOIN dt_ddt ON dt_righe_ddt.idddt = dt_ddt.id INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt = dt_tipiddt.id WHERE lotto='.prepare($rs[$i]['lotto']).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).') '. + 'AND serial NOT IN(SELECT serial FROM mg_articoli_interventi WHERE lotto='.prepare($rs[$i]['lotto']).' AND serial=mg_prodotti.serial) ) '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY serial ASC'; + + $rsn = $dbo->fetchArray($qs); + + echo '\n"; + + // echo '\n"; + } + } + + // Elenco lotti in base all'articolo e lotto + elseif ($op == 'getserial') { + $idarticolo = $get['idarticolo']; + $lotto = $get['lotto']; + + if (($get['serial_start'] != '') and ($get['serial_end'] != '')) { + $serial_start = $get['serial_start']; + $serial_end = $get['serial_end']; + $additional_where_serial = ' AND CAST(serial AS UNSIGNED) >= CAST('.prepare($$serial_start).' AS UNSIGNED) AND CAST(serial AS UNSIGNED) <= CAST('.prepare($serial_end).' AS UNSIGNED) '; + } elseif ($get['serial_start'] != '') { + $serial_start = $get['serial_start']; + $additional_where_serial = ' AND CAST(serial AS UNSIGNED) > CAST('.prepare($$serial_start).' AS UNSIGNED)'; + } elseif ($get['serial_end'] != '') { + $serial_end = $get['serial_end']; + $additional_where_serial = ' AND CAST(serial AS UNSIGNED) < CAST('.prepare($serial_end).' AS UNSIGNED)'; + } else { + $additional_where_serial = ''; + } + + if ($dir == 'entrata') { + $q = 'SELECT DISTINCT(serial) FROM mg_prodotti WHERE idarticolo='.prepare($idarticolo).' AND lotto='.prepare($lotto). + ' AND (serial NOT IN(SELECT serial FROM co_righe_documenti INNER JOIN co_documenti ON co_righe_documenti.iddocumento = co_documenti.id INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento = co_tipidocumento.id WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).')'. + ' AND serial NOT IN(SELECT serial FROM or_righe_ordini INNER JOIN or_ordini ON or_righe_ordini.idordine = or_ordini.id INNER JOIN or_tipiordine ON or_ordini.idtipoordine = or_tipiordine.id WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).') '. + ' AND serial NOT IN(SELECT serial FROM dt_righe_ddt INNER JOIN dt_ddt ON dt_righe_ddt.idddt = dt_ddt.id INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt = dt_tipiddt.id WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial AND dir = '.prepare($dir).') '. + 'AND serial NOT IN(SELECT serial FROM mg_articoli_interventi WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial) '.$additional_where_serial.' ) '. + Modules::getAdditionalsQuery('Magazzino').' ORDER BY serial ASC'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + } else { + $q = 'SELECT DISTINCT(serial) FROM mg_prodotti WHERE idarticolo='.prepare($idarticolo).' AND lotto='.prepare($lotto).' AND (serial NOT IN(SELECT serial FROM co_righe_documenti WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial ) AND serial NOT IN(SELECT serial FROM or_righe_ordini WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial) AND serial NOT IN(SELECT serial FROM dt_righe_ddt WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial) AND serial NOT IN(SELECT serial FROM mg_articoli_interventi WHERE lotto='.prepare($lotto).' AND serial=mg_prodotti.serial) '.$additional_where_serial.' ) '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY serial ASC'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + } + + if (($get['serial_start'] != '') or ($get['serial_end'] != '')) { + } elseif ($get['lotto'] == '') { + echo "\n"; + } else { + echo "\n"; + } + + for ($i = 0; $i < $n; ++$i) { + echo '\n"; + } + } + + // Elenco lotti in base all'articolo, lotto e serial + elseif ($op == 'getaltro') { + $idarticolo = $get['idarticolo']; + $lotto = $get['lotto']; + $serial = $get['serial']; + $q = 'SELECT DISTINCT(altro) FROM mg_prodotti WHERE idarticolo="'.$idarticolo.'" AND lotto="'.$lotto.'" AND serial="'.$serial.'" AND (altro NOT IN(SELECT altro FROM co_righe_documenti WHERE lotto="'.$lotto.'" AND serial="'.$serial.'" AND altro=mg_prodotti.altro) AND altro NOT IN(SELECT altro FROM or_righe_ordini WHERE lotto="'.$lotto.'" AND serial="'.$serial.'" AND altro=mg_prodotti.altro) AND altro NOT IN(SELECT altro FROM dt_righe_ddt WHERE lotto="'.$lotto.'" AND serial="'.$serial.'" AND altro=mg_prodotti.altro) AND altro NOT IN(SELECT altro FROM mg_articoli_interventi WHERE lotto="'.$lotto.'" AND serial="'.$serial.'" AND altro=mg_prodotti.altro)) '.Modules::getAdditionalsQuery('Magazzino').' ORDER BY altro ASC'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + + echo "\n"; + + for ($i = 0; $i < $n; ++$i) { + echo '\n"; + } + } + + // Legge gli ultimi prezzi di vendita di un determinato cliente e un determinato articolo e li visualizza per suggerire il prezzo di vendita + elseif ($op == 'getprezzi') { + $idarticolo = $get['idarticolo']; + $idanagrafica = $get['idanagrafica']; + $ids = ['""']; + + echo ''; + if (!empty($idarticolo)) { + // Ultime 5 vendite al cliente + $fatture = $dbo->fetchArray('SELECT iddocumento, (subtotale-sconto)/qta AS costo_unitario, (SELECT numero FROM co_documenti WHERE id=iddocumento) AS n_fattura, (SELECT numero_esterno FROM co_documenti WHERE id=iddocumento) AS n2_fattura, (SELECT data FROM co_documenti WHERE id=iddocumento) AS data_fattura FROM co_righe_documenti WHERE idarticolo="'.$idarticolo."\" AND iddocumento IN(SELECT id FROM co_documenti WHERE idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='entrata') AND idanagrafica=\"".$idanagrafica.'") LIMIT 0,5'); + + if (sizeof($fatture) > 0) { + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + for ($i = 0; $i < sizeof($fatture); ++$i) { + ($fatture[$i]['n2_fattura'] != '') ? $n_fattura = $fatture[$i]['n2_fattura'] : $n_fattura = $fatture[$i]['n_fattura']; + + $id_module = $modules_info['Fatture di vendita']['id']; + echo "\n"; + + echo "\n"; + echo "\n"; + array_push($ids, '"'.$fatture[$i]['iddocumento'].'"'); + } + echo "
DocumentoDataTotale
Fattura no ".$n_fattura."".Translator::dateToLocale($fatture[$i]['data_fattura'])."".Translator::numberToLocale($fatture[$i]['costo_unitario'])." €
\n"; + } else { + echo '
'._('Nessuna vendita di questo articolo al cliente selezionato')."...
\n"; + } + } + echo '
'; + } + + // Legge gli ultimi prezzi di vendita di un determinato articolo e li visualizza per suggerire il prezzo di vendita + elseif ($op == 'getprezzivendita') { + $idarticolo = $get['idarticolo']; + + echo ''; + // Ultime 5 vendite totali + $fatture = $dbo->fetchArray("SELECT DISTINCT iddocumento, (subtotale-sconto)/qta AS costo_unitario, (SELECT numero FROM co_documenti WHERE id=iddocumento) AS n_fattura, (SELECT numero_esterno FROM co_documenti WHERE id=iddocumento) AS n2_fattura, (SELECT data FROM co_documenti WHERE id=iddocumento) AS data_fattura FROM co_righe_documenti WHERE idarticolo='".$idarticolo."' AND iddocumento IN(SELECT id FROM co_documenti WHERE idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='entrata') ) ORDER BY data_fattura DESC, n_fattura DESC LIMIT 0,5"); + + if (sizeof($fatture) > 0) { + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + for ($i = 0; $i < sizeof($fatture); ++$i) { + ($fatture[$i]['n2_fattura'] != '') ? $n_fattura = $fatture[$i]['n2_fattura'] : $n_fattura = $fatture[$i]['n_fattura']; + + $id_module = $modules_info['Fatture di vendita']['id']; + echo "\n"; + + echo "\n"; + echo "\n"; + } + echo "
DocumentoDataTotale
Fattura no ".$n_fattura."".Translator::dateToLocale($fatture[$i]['data_fattura'])."".Translator::numberToLocale($fatture[$i]['costo_unitario'])." €
\n"; + } else { + echo '
'._('Questo articolo non è mai stato venduto')."...
\n"; + } + echo '
'; + echo '
'; + } + + // Legge gli ultimi prezzi di vendita di un determinato articolo e li visualizza per suggerire il prezzo di vendita + elseif ($op == 'getprezziacquisto') { + $idarticolo = $get['idarticolo']; + + echo ''; + // Ultime 5 vendite totali + $fatture = $dbo->fetchArray("SELECT DISTINCT iddocumento, (subtotale-sconto)/qta AS costo_unitario, (SELECT numero FROM co_documenti WHERE id=iddocumento) AS n_fattura, (SELECT numero_esterno FROM co_documenti WHERE id=iddocumento) AS n2_fattura, (SELECT data FROM co_documenti WHERE id=iddocumento) AS data_fattura FROM co_righe_documenti WHERE idarticolo='".$idarticolo."' AND iddocumento IN(SELECT id FROM co_documenti WHERE idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='uscita') ) ORDER BY data_fattura DESC, n_fattura DESC LIMIT 0,5"); + + if (sizeof($fatture) > 0) { + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + for ($i = 0; $i < sizeof($fatture); ++$i) { + ($fatture[$i]['n2_fattura'] != '') ? $n_fattura = $fatture[$i]['n2_fattura'] : $n_fattura = $fatture[$i]['n_fattura']; + + $id_module = $modules_info['Fatture di vendita']['id']; + echo "\n"; + + echo "\n"; + echo "\n"; + } + echo "
DocumentoDataTotale
Fattura no ".$n_fattura."".Translator::dateToLocale($fatture[$i]['data_fattura'])."".Translator::numberToLocale($fatture[$i]['costo_unitario'])." €
\n"; + } else { + echo '
'._('Questo articolo non è mai stato acquistato')."...
\n"; + } + echo '
'; + echo '
'; + } + break; + + case 'Interventi': + // Elenco nomi + if ($op == 'get_ragione_sociale') { + $ragione_sociale = $get['ragione_sociale']; + $q = "SELECT ragione_sociale FROM an_anagrafiche WHERE ragione_sociale LIKE '%$ragione_sociale%' ".Modules::getAdditionalsQuery('Anagrafiche').' ORDER BY ragione_sociale'; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo htmlspecialchars_decode($rs[$i]['ragione_sociale'], ENT_QUOTES); + if (($i + 1) < $n) { + echo '|'; + } + } + } + break; + + case 'Preventivi': + // Elenco nomi preventivi + if ($op == 'get_select_preventivi') { + $idanagrafica = $get['idanagrafica']; + $q = "SELECT co_preventivi.id AS idpreventivo, an_anagrafiche.idanagrafica, nome, idtipointervento FROM co_preventivi INNER JOIN an_anagrafiche ON co_preventivi.idanagrafica=an_anagrafiche.idanagrafica WHERE an_anagrafiche.idanagrafica='$idanagrafica' AND idstato NOT IN (SELECT `id` FROM co_statipreventivi WHERE descrizione='Bozza' OR descrizione='Rifiutato' OR descrizione='Pagato') ".Modules::getAdditionalsQuery('Preventivi'); + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['idpreventivo'].':'.$rs[$i]['nome'].':'.$rs[$i]['idtipointervento']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + break; + + case 'Contratti': + // Elenco nomi preventivi + if ($op == 'get_select_contratti') { + $idanagrafica = $get['idanagrafica']; + $q = "SELECT co_contratti.id AS idcontratto, an_anagrafiche.idanagrafica, nome FROM co_contratti INNER JOIN an_anagrafiche ON co_contratti.idanagrafica=an_anagrafiche.idanagrafica WHERE an_anagrafiche.idanagrafica='$idanagrafica' AND idstato NOT IN (SELECT `id` FROM co_staticontratti WHERE fatturabile = 1) ".Modules::getAdditionalsQuery('Contratti'); + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + for ($i = 0; $i < $n; ++$i) { + echo html_entity_decode($rs[$i]['idcontratto'].':'.$rs[$i]['nome']); + if (($i + 1) < $n) { + echo '|'; + } + } + } + break; + + case 'Fatture': + // Elenco fatture non pagate per anagrafica + if ($op == 'get_fatture') { + $idanagrafica = $get['idanagrafica']; + $q = "SELECT data, co_documenti.id AS iddocumento, co_tipidocumento.descrizione AS tipo_doc, dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.idanagrafica='$idanagrafica' AND (idstatodocumento=(SELECT `id` FROM co_statidocumento WHERE descrizione='Emessa') OR (SELECT da_pagare-pagato AS differenza FROM co_scadenziario WHERE NOT iddocumento=co_documenti.id=0) )"; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + if ($n > 0) { + echo "\n"; + } else { + echo _('Nessuna fattura trovata').'...'; + } + } + + // Elenco causali prima nota + elseif ($op == 'get_causali') { + $descrizione = $get['descrizione']; + $q = 'SELECT DISTINCT descrizione FROM co_movimenti WHERE descrizione LIKE "%'.$descrizione."%\" AND (iddocumento='' OR iddocumento IS NULL) AND primanota=1 ".Modules::getAdditionalsQuery('Prima nota'); + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + if ($n > 0) { + for ($i = 0; $i < $n; ++$i) { + echo $rs[$i]['descrizione']; + if (($i + 1) < $n) { + echo '|'; + } + } + } + } + break; + + case 'Ddt': + // Elenco ddt del fornitore scelto + if ($op == 'get_ddt') { + $idfornitore = $get['idfornitore']; + $q = "SELECT data, dt_ddt.id AS idddt, numero, dt_tipiddt.descrizione AS tipo_doc, dir FROM dt_ddt INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt=dt_tipiddt.id WHERE dt_ddt.idanagrafica='$idfornitore'"; + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + if ($n > 0) { + echo "\n"; + } else { + echo _('Nessun ddt trovato')."...\n"; + } + } + break; + + case 'MyImpianti': + // Elenco ddt del fornitore scelto + if ($op == 'get_impianti') { + $idanagrafica = $get['idanagrafica']; + $idsede = $get['idsede']; + + if ($idsede != '' && $idsede != '-1' && $idsede != 'undefined') { + $q = 'SELECT *, (SELECT nomesede FROM an_sedi WHERE id=my_impianti.idsede) AS nomesede FROM my_impianti WHERE idanagrafica="'.$idanagrafica.'" AND idsede="'.$idsede.'" ORDER BY idsede'; + } else { + $q = 'SELECT *, (SELECT nomesede FROM an_sedi WHERE id=my_impianti.idsede) AS nomesede FROM my_impianti WHERE idanagrafica="'.$idanagrafica.'" ORDER BY idsede'; + } + + $rs = $dbo->fetchArray($q); + $n = sizeof($rs); + + for ($i = 0; $i < $n; ++$i) { + echo $rs[$i]['id'].':'.$rs[$i]['matricola'].' - '.$rs[$i]['nome']."\n"; + + if (($i + 1) < $n) { + echo '|'; + } + } + } + break; +} + +/* + == Super search == + Ricerca di un termine su tutti i moduli. + Il risultato è in json +*/ +if ($op == 'supersearch') { + $term = $get['term']; + $term = str_replace('/', '\\/', $term); + $i = 0; + + if (strlen($term) < 2) { + echo 'null'; + exit; + } + + /* + Anagrafiche + */ + if (Modules::getPermission('Anagrafiche') != '-') { + $campi = ['codice', 'ragione_sociale', 'piva', 'codice_fiscale', 'indirizzo', 'indirizzo2', 'citta', 'cap', 'provincia', 'telefono', 'fax', 'cellulare', 'email', 'sitoweb', 'note', 'codicerea', 'settore', 'marche', 'cciaa', 'n_alboartigiani']; + $campi_text = ['Codice', 'Ragione sociale', 'Partita iva', 'Codice fiscale', 'Indirizzo', 'Indirizzo2', 'Città', 'C.A.P.', 'Provincia', 'Telefono', 'Fax', 'Cellulare', 'Email', 'Sito web', 'Note', 'Codice REA', 'Settore', 'Marche', 'CCIAA', 'Numero di iscrizione albo artigiani']; + + $rs = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name='Anagrafiche'"); + $id_module = $rs[0]['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%" AND deleted = 0'; + } + + $rs = $dbo->fetchArray('SELECT * FROM an_anagrafiche WHERE 1=0 '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['idanagrafica']; + $result[$r + $i]['title'] = $rs[$r]['ragione_sociale']; + $result[$r + $i]['category'] = 'Anagrafiche'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + } + + $i += $r; + } + } + + // Ricerca anagrafiche per ragione sociale per potere mostrare gli interventi, fatture, + // ordini, ecc della persona ricercata + $idanagrafiche = ['-1']; + $ragioni_sociali = ['-1']; + $rs = $dbo->fetchArray('SELECT idanagrafica, ragione_sociale FROM an_anagrafiche WHERE ragione_sociale LIKE "%'.$term.'%"'); + + for ($a = 0; $a < sizeof($rs); ++$a) { + $idanagrafiche[] = $rs[$a]['idanagrafica']; + $ragioni_sociali[$rs[$a]['idanagrafica']] = $rs[$a]['ragione_sociale']; + } + + /* + Referenti anagrafiche + */ + if (Modules::getPermission('Anagrafiche') != '-') { + $campi = ['nome', 'mansione', 'telefono', 'email']; + $campi_text = ['Nome', 'Mansione', 'Telefono', 'Email']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT * FROM an_referenti WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['idanagrafica'].'#tabs-2'; + $result[$r + $i]['title'] = $rs[$r]['nome']; + $result[$r + $i]['category'] = 'Referenti'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r + $i][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Interventi + */ + if (Modules::getPermission('Interventi') != '-') { + $campi = ['codice', '(SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=in_interventi.id)', 'data_richiesta', 'info_sede', 'richiesta', 'descrizione', 'informazioniaggiuntive']; + $campi_text = ['Codice intervento', 'Data intervento', 'Data richiesta intervento', 'Sede intervento', 'Richiesta', 'Descrizione', 'Informazioni aggiuntive']; + + $id_module = Modules::getModule('Interventi')['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $build_query .= Modules::getAdditionalsQuery('Interventi'); + + $rs = $dbo->fetchArray('SELECT *, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=in_interventi.id) AS data FROM in_interventi WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['id']; + $result[$r + $i]['title'] = 'Intervento '.$rs[$r]['codice'].' del '.Translator::dateToLocale($rs[$r]['data']); + $result[$r + $i]['category'] = 'Interventi'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Preventivi + */ + if (Modules::getPermission('Contabilita') != '-') { + $campi = ['numero', 'nome', 'descrizione']; + $campi_text = ['Codice preventivo', 'Nome', 'Descrizione']; + + $rs = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name='Preventivi'"); + $id_module = $rs[0]['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT *, co_preventivi.id AS idpreventivo FROM co_preventivi WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['idpreventivo']; + $result[$r + $i]['title'] = 'Preventivo '.$rs[$r]['numero'].(($rs[$r]['data_accettazione'] == '0000-00-00') ? ' del '.Translator::dateToLocale($rs[$r]['data_accettazione']) : ''); + $result[$r + $i]['category'] = 'Preventivi'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Fatture + */ + if (Modules::getPermission('Contabilita') != '-') { + $campi = ['numero', 'numero_esterno', 'data', 'note', 'note_aggiuntive', 'buono_ordine']; + $campi_text = ['Numero', 'Numero secondario', 'Data', 'Note', 'Note aggiuntive', 'Buono d\'ordine']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT *, co_documenti.id AS iddocumento FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + if ($rs[$r]['numero_esterno'] == '') { + $numero = $rs[$r]['numero']; + } else { + $numero = $rs[$r]['numero_esterno']; + } + + // Controllo se si tratta di una fattura di acquisto o di vendita e seleziono il modulo opportuno + if ($rs[$r]['dir'] == 'uscita') { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Fatture di acquisto'"); + $id_module = $rsm[0]['id']; + } else { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Fatture di vendita'"); + $id_module = $rsm[0]['id']; + } + + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['iddocumento']; + $result[$r + $i]['title'] = $rs[$r]['descrizione'].' no '.$numero.' del '.Translator::dateToLocale($rs[$r]['data']); + $result[$r + $i]['category'] = $rs[$r]['descrizione']; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Righe fatture + */ + if (Modules::getPermission('Contabilita') != '-') { + $campi = ['descrizione']; + $campi_text = ['Riga']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR co_righe_documenti.'.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT co_documenti.*, co_documenti.id AS iddocumento, co_tipidocumento.descrizione AS tipodoc, co_tipidocumento.dir, co_righe_documenti.descrizione FROM co_righe_documenti INNER JOIN (co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id) ON co_documenti.id=co_righe_documenti.iddocumento WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + if ($rs[$r]['numero_esterno'] == '') { + $numero = $rs[$r]['numero']; + } else { + $numero = $rs[$r]['numero_esterno']; + } + + // Controllo se si tratta di una fattura di acquisto o di vendita e seleziono il modulo opportuno + if ($rs[$r]['dir'] == 'uscita') { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Fatture di acquisto'"); + $id_module = $rsm[0]['id']; + } else { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Fatture di vendita'"); + $id_module = $rsm[0]['id']; + } + + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['iddocumento']; + $result[$r + $i]['title'] = $rs[$r]['tipodoc'].' no '.$numero.' del '.Translator::dateToLocale($rs[$r]['data']); + $result[$r + $i]['category'] = $rs[$r]['tipodoc']; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Articoli + */ + if (Modules::getPermission('Articoli') != '-') { + $campi = ['codice', 'descrizione', '(SELECT nome FROM mg_categorie WHERE mg_categorie.id = mg_articoli.id_categoria)', '(SELECT nome FROM mg_categorie WHERE mg_categorie.id = mg_articoli.id_sottocategoria)', 'note']; + $campi_text = ['Codice', 'Descrizione', 'Categoria', 'Subcategoria', 'Note']; + + $rs = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name='Articoli'"); + $id_module = $rs[0]['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT * FROM mg_articoli WHERE 1=0 '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['id']; + $result[$r + $i]['title'] = $rs[$r]['codice'].' - '.$rs[$r]['descrizione']; + $result[$r + $i]['category'] = 'Articoli'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + } + + $i += $r; + } + } + + /* + Automezzi + */ + if (Modules::getPermission('Automezzi') != '-') { + $campi = ['nome', 'descrizione', 'targa']; + $campi_text = ['Nome', 'Descrizione', 'Targa']; + + $rs = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name='Automezzi'"); + $id_module = $rs[0]['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT * FROM dt_automezzi WHERE 1=0 '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['id']; + $result[$r + $i]['title'] = $rs[$r]['nome']; + $result[$r + $i]['category'] = 'Automezzi'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + } + + $i += $r; + } + } + + /* + Ddt + */ + if (Modules::getPermission('Magazzino') != '-') { + $campi = ['numero', 'numero_esterno', 'data', 'note']; + $campi_text = ['Numero', 'Numero secondario', 'Data', 'Note']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT *, dt_ddt.id AS idddt FROM dt_ddt INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt=dt_tipiddt.id WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + if ($rs[$r]['numero_esterno'] == '') { + $numero = $rs[$r]['numero']; + } else { + $numero = $rs[$r]['numero_esterno']; + } + + // Controllo se si tratta di un tipo ddt di acquisto o di vendita e seleziono il modulo opportuno + if ($rs[$r]['dir'] == 'uscita') { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Ddt di acquisto'"); + $id_module = $rsm[0]['id']; + } else { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Ddt di vendita'"); + $id_module = $rsm[0]['id']; + } + + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['idddt']; + $result[$r + $i]['title'] = $rs[$r]['descrizione'].' no '.$numero.' del '.Translator::dateToLocale($rs[$r]['data']); + $result[$r + $i]['category'] = $rs[$r]['descrizione']; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + Righe ddt + */ + if (Modules::getPermission('Magazzino') != '-') { + $campi = ['descrizione']; + $campi_text = ['Riga']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR dt_righe_ddt.'.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $rs = $dbo->fetchArray('SELECT dt_ddt.*, dt_ddt.id AS idddt, dt_tipiddt.descrizione AS tipodoc, dt_tipiddt.dir, dt_righe_ddt.descrizione FROM dt_righe_ddt INNER JOIN (dt_ddt INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt=dt_tipiddt.id) ON dt_ddt.id=dt_righe_ddt.idddt WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + if ($rs[$r]['numero_esterno'] == '') { + $numero = $rs[$r]['numero']; + } else { + $numero = $rs[$r]['numero_esterno']; + } + + // Controllo se si tratta di un tipo ddt di acquisto o di vendita e seleziono il modulo opportuno + if ($rs[$r]['dir'] == 'uscita') { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Ddt di acquisto'"); + $id_module = $rsm[0]['id']; + } else { + $rsm = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name = 'Ddt di vendita'"); + $id_module = $rsm[0]['id']; + } + + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['idddt']; + // $result[$r+$i]['link'] = $rootdir."/modules/magazzino/ddt/ddt.php?idddt=".$rs[$r]['iddocumento']."&dir=".$rs[$r]['dir']; + $result[$r + $i]['title'] = $rs[$r]['tipodoc'].' no '.$numero.' del '.Translator::dateToLocale($rs[$r]['data']); + $result[$r + $i]['category'] = $rs[$r]['tipodoc']; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + /* + MyImpianti + */ + if (Modules::getPermission('MyImpianti') != '-') { + $campi = ['matricola', 'nome', 'descrizione', 'ubicazione', 'occupante', 'proprietario']; + $campi_text = ['Matricola', 'Nome', 'Descrizione', 'Ubicazione', 'Occupante', 'Proprietario']; + + $rs = $dbo->fetchArray("SELECT id FROM zz_modules WHERE name='MyImpianti'"); + $id_module = $rs[0]['id']; + + $build_query = ''; + + for ($c = 0; $c < sizeof($campi); ++$c) { + $build_query .= ' OR '.$campi[$c].' LIKE "%'.$term.'%"'; + } + + $build_query .= Modules::getAdditionalsQuery('MyImpianti'); + + $rs = $dbo->fetchArray('SELECT * FROM my_impianti WHERE idanagrafica IN('.implode(',', $idanagrafiche).') '.$build_query); + + if (sizeof($rs) > 0) { + // Loop record corrispondenti alla ricerca + for ($r = 0; $r < sizeof($rs); ++$r) { + $result[$r + $i]['link'] = $rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$rs[$r]['matricola']; + $result[$r + $i]['title'] = $rs[$r]['matricola'].' - '.$rs[$r]['nome']; + $result[$r + $i]['category'] = 'MyImpianti'; + $result[$r + $i]['labels'] = []; + + // Loop campi da evidenziare + for ($c = 0; $c < sizeof($campi); ++$c) { + if (preg_match('/'.$term.'/i', $rs[$r][$campi[$c]])) { + $text = $rs[$r][$campi[$c]]; + + // Evidenzio la parola cercata nei valori dei campi + preg_match('/'.$term.'/i', $rs[$r][$campi[$c]], $matches); + + for ($m = 0; $m < sizeof($matches); ++$m) { + $text = str_replace($matches[$m], "".$matches[$m].'', $text); + } + + $result[$r + $i]['labels'][] = $campi_text[$c].': '.$text.'
'; + } + } + + // Aggiunta nome anagrafica come ultimo campo + if (sizeof($ragioni_sociali) > 1) { + $result[$r + $i]['labels'][] = 'Anagrafica: '.$ragioni_sociali[$rs[$r]['idanagrafica']].'
'; + } + } + + $i += $r; + } + } + + // Contratti + // Ordini + + $result = (array) $result; + foreach ($result as $key => $value) { + $result[$key]['value'] = $key; + } + + echo json_encode($result); +} diff --git a/ajax_dataload.php b/ajax_dataload.php new file mode 100644 index 000000000..f2ab6feba --- /dev/null +++ b/ajax_dataload.php @@ -0,0 +1,219 @@ +fetchArray($query); + if (!empty($cont)) { + $results['recordsTotal'] = $cont[0]['tot']; + } + + // Filtri di ricerica + $search_filters = []; + for ($i = 0; $i < count($columns); ++$i) { + if (!empty($columns[$i]['search']['value'])) { + if (strpos($total['search_inside'][$i], '|search|') !== false) { + $pieces = explode(',', $columns[$i]['search']['value']); + foreach ($pieces as $piece) { + $piece = trim($piece); + $search_filters[] = str_replace('|search|', prepare('%'.$piece.'%'), $total['search_inside'][$i]); + } + } else { + $search_filters[] = '`'.$total['search_inside'][$i].'` LIKE '.prepare('%'.trim($columns[$i]['search']['value'].'%')); + } + } + } + + if (!empty($search_filters)) { + $module_query = str_replace('2=2', '2=2 AND ('.implode(' AND ', $search_filters).') ', $module_query); + } + + // Filtri derivanti dai permessi (eventuali) + $module_query = Modules::replaceAdditionals($id_module, $module_query); + + // Ordinamento dei risultati + if (isset($order['dir']) && isset($order['column'])) { + $pieces = explode('ORDER', $module_query); + + $cont = count($pieces); + if ($cont > 1) { + unset($pieces[$cont - 1]); + } + + $module_query = implode('ORDER', $pieces).' ORDER BY `'.$total['order_by'][$order['column']].'` '.$order['dir']; + } + + // Calcolo di eventuali somme + if (!empty($total['summable'])) { + $query = str_replace_once('SELECT', 'SELECT '.implode(', ', $total['summable']).' FROM(SELECT ', $module_query).') AS `z`'; + $sums = $dbo->fetchArray($query)[0]; + if (!empty($sums)) { + $r = []; + foreach ($sums as $key => $sum) { + if (strpos($key, 'sum_') !== false) { + $r[str_replace('sum_', '', $key)] = Translator::numberToLocale($sum); + } + } + $results['summable'] = $r; + } + } + + // Paginazione + if ($length > 0) { + $module_query .= ' LIMIT '.$start.', '.$length; + } + + // Query effettiva + $query = str_replace_once('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $module_query); + $rs = $dbo->fetchArray($query); + + // Conteggio dei record filtrati + $cont = $dbo->fetchArray('SELECT FOUND_ROWS()'); + if (!empty($cont)) { + $results['recordsFiltered'] = $cont[0]['FOUND_ROWS()']; + } + + // Creazione della tabella + $align = []; + foreach ($rs as $i => $r) { + if ($i == 0) { + foreach ($total['fields'] as $field) { + $value = trim($r[$field]); + + // Allineamento a destra se il valore della prima riga risulta numerica + if (Translator::getEnglishFormatter()->isNumber($value) || Translator::getEnglishFormatter()->isNumber($value)) { + $align[$field] = 'text-right'; + } + + // Allineamento al centro se il valore della prima riga risulta relativo a date o icone + elseif ((Translator::getEnglishFormatter()->isDate($value) || Translator::getEnglishFormatter()->isDate($value)) || preg_match('/^icon_(.+?)$/', $field)) { + $align[$field] = 'text-center'; + } + } + } + + $result = []; + $result[] = ''; + foreach ($total['fields'] as $pos => $field) { + $column = []; + + if (!empty($r['_bg_'])) { + $column['data-background'] = $r['_bg_']; + } + + // Allineamento + if (!empty($align[$field])) { + $column['class'] = $align[$field]; + } + + $value = trim($r[$field]); + + // Formattazione automatica + if (!empty($total['format'][$pos]) && !empty($value) && !empty(Translator::getEnglishFormatter())) { + if (Translator::getEnglishFormatter()->isNumber($value)) { + $value = Translator::numberToLocale($value); + } elseif (Translator::getEnglishFormatter()->isTimestamp($value)) { + $value = Translator::timestampToLocale($value); + } elseif (Translator::getEnglishFormatter()->isDate($value)) { + $value = Translator::dateToLocale($value); + } elseif (Translator::getEnglishFormatter()->isTime($value)) { + $value = Translator::timeToLocale($value); + } + } + + // Icona + if (preg_match('/^color_(.+?)$/', $field, $m)) { + $value = $r['color_title_'.$m[1]] ?: ''; + + $column['class'] = 'text-center small'; + $column['data-background'] = $r[$field]; + } + + // Icona di stampa + elseif ($field == '_print_') { + $print_url = $r['_print_']; + + preg_match_all('/\$(.+?)\$/', $print_url, $matches); + + for ($m = 0; $m < sizeof($matches[0]); ++$m) { + $print_url = str_replace($matches[0][$m], $r[$matches[1][$m]], $print_url); + } + + $value = ''; + } + + // Icona + elseif (preg_match('/^icon_(.+?)$/', trim($field), $m)) { + $value = ' '.$r['icon_title_'.$m[1]].''; + } + + // Colore del testo + if (!empty($column['data-background'])) { + $column['data-color'] = $column['data-color'] ?: color_inverse($column['data-background']); + } + + // Link della colonna + if ($field != '_print_') { + $id_record = $r['id']; + $hash = ''; + if (!empty($r['_link_record_'])) { + $id_module = $r['_link_module_']; + $id_record = $r['_link_record_']; + $hash = !empty($r['_link_hash_']) ? '#'.$r['_link_hash_'] : ''; + unset($id_plugin); + } + + $column['data-link'] = $rootdir.'/'.(empty($id_plugin) ? '' : 'plugin_').'editor.php?id_module='.$id_module.'&id_record='.$id_record.(empty($id_plugin) ? '' : '&id_plugin='.$id_plugin.'&id_parent='.$id_parent).$hash; + + if (!empty($id_plugin)) { + $column['data-type'] = 'dialog'; + } + } + + $attributes = []; + foreach ($column as $key => $val) { + $val = is_array($val) ? implode(' ', $val) : $val; + $attributes[] = $key.'="'.$val.'"'; + } + + $result[] = str_replace('|attr|', implode(' ', $attributes), '
'.$value.'
'); + } + + $results['data'][] = $result; + } +} + +echo json_encode($results); diff --git a/ajax_select.php b/ajax_select.php new file mode 100644 index 000000000..77ccedd0d --- /dev/null +++ b/ajax_select.php @@ -0,0 +1,563 @@ + 'id', + 'text' => 'descrizione', +]; + +if (!function_exists('completeResults')) { + function completeResults($query, $where, $filter = [], $search = [], $custom = []) + { + $dbo = Database::getConnection(); + + if (strpos($query, '|filter|') !== false) { + $query = str_replace('|filter|', !empty($filter) ? 'WHERE '.implode(' OR ', $filter) : '', $query); + } elseif (!empty($filter)) { + $where[] = '('.implode(' OR ', $filter).')'; + } + + if (!empty($search)) { + $where[] = '('.implode(' OR ', $search).')'; + } + + $query = str_replace('|where|', !empty($where) ? 'WHERE '.implode(' AND ', $where) : '', $query); + + $rs = $dbo->fetchArray($query); + + $results = []; + foreach ($rs as $r) { + $result = []; + foreach ($custom as $key => $value) { + $result[$key] = $r[$value]; + } + + $results[] = $result; + } + + return $results; + } +} + +switch ($op) { + case 'clienti': + if (Modules::getModule('Anagrafiche')['permessi'] != '-') { + $query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')'))) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale"; + + foreach ($elements as $element) { + $filter[] = 'an_anagrafiche.idanagrafica='.prepare($element); + } + + if (empty($filter)) { + $where[] = "descrizione='Cliente'"; + $where[] = 'deleted=0'; + } + + if (!empty($search)) { + $search_fields[] = 'ragione_sociale LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%'); + } + + $custom['idtipointervento'] = 'idtipointervento_default'; + } + + break; + + case 'fornitori': + if (Modules::getModule('Anagrafiche')['permessi'] != '-') { + $query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')'))) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale"; + + foreach ($elements as $element) { + $filter[] = 'an_anagrafiche.idanagrafica='.prepare($element); + } + + if (empty($filter)) { + $where[] = "descrizione='Fornitore'"; + $where[] = 'deleted=0'; + } + + if (!empty($search)) { + $search_fields[] = 'ragione_sociale LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%'); + } + + $custom['idtipointervento'] = 'idtipointervento_default'; + } + break; + + case 'agenti': + if (Modules::getModule('Anagrafiche')['permessi'] != '-') { + $query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')'))) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale"; + + foreach ($elements as $element) { + $filter[] = 'an_anagrafiche.idanagrafica='.prepare($element); + } + + if (empty($filter)) { + $where[] = "descrizione='Agente'"; + $where[] = 'deleted=0'; + } + + if (!empty($search)) { + $search_fields[] = 'ragione_sociale LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%'); + } + + $results = completeResults($query, $where, $filter, $search, $custom); + + // Evidenzia l'agente di default + if ($superselect['idanagrafica']) { + $rsa = $dbo->fetchArray('SELECT idagente FROM an_anagrafiche WHERE idanagrafica='.prepare($superselect['idanagrafica'])); + $idagente_default = $rsa[0]['idagente']; + } else { + $idagente_default = 0; + } + + $ids = array_column($results, $id); + $pos = array_search($idagente_default, $ids); + if ($pos !== false) { + $results[$pos]['_bgcolor_'] = '#ff0'; + } + } + break; + + case 'tecnici': + if (Modules::getModule('Anagrafiche')['permessi'] != '-') { + $query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')'))) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale"; + + foreach ($elements as $element) { + $filter[] = 'an_anagrafiche.idanagrafica='.prepare($element); + } + + if (empty($filter)) { + $where[] = "descrizione='Tecnico'"; + $where[] = 'deleted=0'; + } + + if (!empty($search)) { + $search_fields[] = 'ragione_sociale LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%'); + } + + // $custom['idtipointervento'] = 'idtipointervento_default'; + } + break; + + // Nota Bene: nel campo id viene specificato idtipoanagrafica-idanagrafica -> modulo Utenti e permessi, creazione nuovo utente + case 'anagrafiche': + if (Modules::getModule('Anagrafiche')['permessi'] != '-') { + $query = "SELECT CONCAT(an_tipianagrafiche.idtipoanagrafica, '-', an_anagrafiche.idanagrafica) AS id, CONCAT_WS('', ragione_sociale, ' (', citta, ' ', provincia, ')') AS descrizione idtipointervento_default 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| ORDER BY ragione_sociale"; + + foreach ($elements as $element) { + $filter[] = 'an_anagrafiche.idanagrafica='.prepare($element); + } + + if (empty($filter)) { + $where[] = 'deleted=0'; + } + + if (!empty($search)) { + $search_fields[] = 'ragione_sociale LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%'); + } + + // $custom['idtipointervento'] = 'idtipointervento_default'; + } + break; + + case 'sedi': + if (Modules::getModule('Anagrafiche')['permessi'] != '-' && isset($superselect['idanagrafica'])) { + $query = "SELECT * FROM (SELECT 0 AS id, 'Sede legale' AS descrizione UNION SELECT id, CONCAT_WS(' - ', nomesede, citta) FROM an_sedi |where|) AS tab |filter| ORDER BY id"; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = 'idanagrafica='.prepare($superselect['idanagrafica']); + + if (!empty($search)) { + $search_fields[] = 'nomesede LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'citta LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'referenti': + if (Modules::getModule('Anagrafiche')['permessi'] != '-' && isset($superselect['idanagrafica'])) { + $query = 'SELECT id, nome AS descrizione FROM an_referenti |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = 'idanagrafica='.prepare($superselect['idanagrafica']); + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'articoli': + $query = 'SELECT * FROM mg_articoli |where| ORDER BY id_categoria ASC, id_sottocategoria ASC'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = 'attivo=1'; + if (!empty($superselect['dir']) && $superselect['dir'] == 'entrata') { + $where[] = 'qta>0'; + } + + if (!empty($search)) { + $search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%'); + } + + $wh = ''; + if (!empty($search_fields)) { + $where[] = '('.implode(' OR ', $search_fields).')'; + } + if (count($where) != 0) { + $wh = 'WHERE '.implode(' AND ', $where); + } + $query = str_replace('|where|', $wh, $query); + + $prev = -1; + $rs = $dbo->fetchArray($query); + foreach ($rs as $r) { + if ($prev != $r['id_sottocategoria']) { + $prev = $r['id_sottocategoria']; + $results[] = ['text' => $dbo->fetchArray('SELECT `nome` FROM `mg_categorie` WHERE `id`='.prepare($r['id_categoria']))[0]['nome'], 'children' => []]; + } + + $results[count($results) - 1]['children'][] = [ + 'id' => $r['id'], + 'text' => $r['codice'].' - '.$r['descrizione'], + 'descrizione' => $r['descrizione'], + 'um' => $r['um'], + 'prezzo_acquisto' => Translator::numberToLocale($r['prezzo_acquisto']), + 'prezzo_vendita' => Translator::numberToLocale($r['prezzo_vendita']), + ]; + } + break; + + case 'conti': + if (Modules::getModule('Piano dei conti')['permessi'] != '-') { + $query = 'SELECT * FROM co_pianodeiconti2'; + + $rs = $dbo->fetchArray($query); + foreach ($rs as $r) { + $results[] = ['text' => $r['numero'].' '.$r['descrizione'], 'children' => []]; + + $subquery = 'SELECT * FROM co_pianodeiconti3 |where|'; + + $where = []; + $filter = []; + $search_fields = []; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + if (!empty($filter)) { + $where[] = '('.implode(' OR ', $filter).')'; + } + + $where[] = 'idpianodeiconti2='.prepare($r['id']); + + if (!empty($search)) { + $search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%'); + } + if (!empty($search_fields)) { + $where[] = '('.implode(' OR ', $search_fields).')'; + } + + $wh = ''; + if (count($where) != 0) { + $wh = 'WHERE '.implode(' AND ', $where); + } + $subquery = str_replace('|where|', $wh, $subquery); + + $rs2 = $dbo->fetchArray($subquery); + foreach ($rs2 as $r2) { + $results[count($results) - 1]['children'][] = ['id' => $r2['id'], 'text' => $r2['descrizione']]; + } + } + } + break; + + case 'conti-vendite': + if (Modules::getModule('Piano dei conti')['permessi'] != '-') { + $query = "SELECT co_pianodeiconti3.id, CONCAT_WS( ' ', co_pianodeiconti3.numero, co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti3.numero ASC"; + + foreach ($elements as $element) { + $filter[] = 'co_pianodeiconti3.id='.prepare($element); + } + + $where[] = "co_pianodeiconti1.descrizione='Economico'"; + $where[] = "co_pianodeiconti3.dir='entrata'"; + + if (!empty($search)) { + $search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'conti-acquisti': + if (Modules::getModule('Piano dei conti')['permessi'] != '-') { + $query = "SELECT co_pianodeiconti3.id, CONCAT_WS( ' ', co_pianodeiconti3.numero, co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti3.numero ASC"; + + foreach ($elements as $element) { + $filter[] = 'co_pianodeiconti3.id='.prepare($element); + } + + $where[] = "co_pianodeiconti1.descrizione='Economico'"; + $where[] = "co_pianodeiconti3.dir='uscita'"; + + if (!empty($search)) { + $search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'impianti': + if (Modules::getModule('MyImpianti')['permessi'] != '-' && isset($superselect['idanagrafica'])) { + $query = 'SELECT id, CONCAT(matricola, " - ", nome) AS descrizione FROM my_impianti |where| ORDER BY idsede'; + + foreach ($elements as $element) { + $filter[] = 'idsede='.prepare($element); + } + + $where[] = 'idanagrafica='.prepare($superselect['idanagrafica']); + $where[] = 'idsede='.prepare($superselect['idsede']); + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + $search_fields[] = 'matricola LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'componenti': + if (Modules::getModule('Gestione componenti')['permessi'] != '-' && isset($superselect['marticola'])) { + $query = 'SELECT id, nome AS descrizione, contenuto FROM my_impianto_componenti |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'idimpianto='.prepare($element); + } + + $temp = []; + $impianti = explode(',', $superselect['marticola']); + foreach ($impianti as $key => $idimpianto) { + $temp[] = 'idimpianto='.prepare($idimpianto); + } + $where[] = '('.implode(' OR ', $temp).')'; + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + + $custom['contenuto'] = 'contenuto'; + + $results = completeResults($query, $where, $filter, $search, $custom); + foreach ($results as $key => $value) { + $matricola = \Util\Ini::getValue($r['contenuto'], 'Matricola'); + + $results[$key]['text'] = (empty($matricola) ? '' : $matricola.' - ').$results[$key]['text']; + + unset($results[$key]['content']); + } + } + + break; + + case 'categorie': + if (Modules::getModule('Magazzino')['permessi'] != '-') { + $query = 'SELECT id, nome AS descrizione FROM mg_categorie |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = '`parent` IS NULL'; + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'sottocategorie': + if (Modules::getModule('Magazzino')['permessi'] != '-' && isset($superselect['id_categoria'])) { + $query = 'SELECT id, nome AS descrizione FROM mg_categorie |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = '`parent`='.prepare($superselect['id_categoria']); + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'preventivi': + if (Modules::getModule('Preventivi')['permessi'] != '-' && isset($superselect['idanagrafica'])) { + $query = 'SELECT co_preventivi.id AS id, an_anagrafiche.idanagrafica, CONCAT(numero, " ", nome) AS descrizione, co_preventivi.idtipointervento, (SELECT descrizione descrizione FROM in_tipiintervento WHERE in_tipiintervento.idtipointervento = co_preventivi.idtipointervento) AS idtipointervento_descrizione FROM co_preventivi INNER JOIN an_anagrafiche ON co_preventivi.idanagrafica=an_anagrafiche.idanagrafica |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = 'an_anagrafiche.idanagrafica='.prepare($superselect['idanagrafica']); + $where[] = "idstato NOT IN (SELECT `id` FROM co_statipreventivi WHERE descrizione='Bozza' OR descrizione='Rifiutato' OR descrizione='Pagato')"; + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + + $custom['idtipointervento'] = 'idtipointervento'; + $custom['idtipointervento_descrizione'] = 'idtipointervento_descrizione'; + } + break; + + case 'preventivi_aperti': + if (Modules::getModule('Preventivi')['permessi'] != '-') { + $query = 'SELECT co_preventivi.id AS id, CONCAT(numero, " ", nome, " (", ragione_sociale, ")") AS descrizione FROM co_preventivi INNER JOIN an_anagrafiche ON co_preventivi.idanagrafica=an_anagrafiche.idanagrafica |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'idpreventivo='.prepare($element); + } + $where[] = 'idstato IN (1)'; + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'contratti': + if (Modules::getModule('Contratti')['permessi'] != '-') { + $query = 'SELECT co_contratti.id AS id, CONCAT(numero, " ", nome) AS descrizione FROM co_contratti INNER JOIN an_anagrafiche ON co_contratti.idanagrafica=an_anagrafiche.idanagrafica |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + $where[] = 'an_anagrafiche.idanagrafica='.prepare($superselect['idanagrafica']); + $where[] = 'idstato IN (SELECT `id` FROM co_staticontratti WHERE pianificabile = 1)'; + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'tipiintervento': + if (Modules::getModule('Interventi')['permessi'] != '-') { + $query = 'SELECT idtipointervento AS id, descrizione FROM in_tipiintervento |where| ORDER BY idtipointervento'; + + foreach ($elements as $element) { + $filter[] = 'idtipointervento='.prepare($element); + } + if (!empty($search)) { + $search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'misure': + if (Modules::getModule('Magazzino')['permessi'] != '-') { + $query = 'SELECT valore AS id, valore AS descrizione FROM mg_unitamisura |where| ORDER BY valore'; + + foreach ($elements as $element) { + $filter[] = 'valore='.prepare($element).''; + } + if (!empty($search)) { + $search_fields[] = 'valore LIKE '.prepare('%'.$search.'%'); + } + } + break; + + case 'prodotti_lotti': + if (Modules::getModule('Magazzino')['permessi'] != '-') { + $query = 'SELECT DISTINCT lotto AS descrizione FROM mg_prodotti |where|'; + + $where[] = 'idarticolo='.prepare($superselect['idarticolo']); + + foreach ($elements as $element) { + $filter[] = 'lotto='.prepare($element).''; + } + + if (!empty($search)) { + $search_fields[] = 'lotto LIKE '.prepare('%'.$search.'%'); + } + + $custom['id'] = 'descrizione'; + } + break; + + case 'prodotti_serial': + if (Modules::getModule('Magazzino')['permessi'] != '-') { + $query = 'SELECT DISTINCT serial AS descrizione FROM mg_prodotti |where|'; + + $where[] = 'idarticolo='.prepare($superselect['idarticolo']); + $where[] = 'lotto='.prepare($superselect['lotto']); + + foreach ($elements as $element) { + $filter[] = 'serial='.prepare($element).''; + } + if (!empty($search)) { + $search_fields[] = 'serial LIKE '.prepare('%'.$search.'%'); + } + + $custom['id'] = 'descrizione'; + } + break; + + case 'prodotti_altro': + if (Modules::getModule('Magazzino')['permessi'] != '-') { + $query = 'SELECT DISTINCT altro AS descrizione FROM mg_prodotti |where|'; + + $where[] = 'idarticolo='.prepare($superselect['idarticolo']); + $where[] = 'lotto='.prepare($superselect['lotto']); + $where[] = 'serial='.prepare($superselect['serial']); + + foreach ($elements as $element) { + $filter[] = 'altro='.prepare($element).''; + } + if (!empty($search)) { + $search_fields[] = 'altro LIKE '.prepare('%'.$search.'%'); + } + + $custom['id'] = 'descrizione'; + } + break; +} + +if (!isset($results) && !empty($query)) { + $results = completeResults($query, $where, $filter, $search_fields, $custom); +} + +echo json_encode($results); diff --git a/api/index.php b/api/index.php new file mode 100644 index 000000000..da22121e5 --- /dev/null +++ b/api/index.php @@ -0,0 +1,29 @@ +retrieve($resource); + } else { + $result = API::response(API::getResources()['retrieve']); + } +} catch (InvalidArgumentException $e) { + $result = API::error('unauthorized'); +} catch (Exception $e) { + $result = API::error('serverError'); +} + +echo $result; diff --git a/assets/src/css/datatables.css b/assets/src/css/datatables.css new file mode 100644 index 000000000..cffe5e66a --- /dev/null +++ b/assets/src/css/datatables.css @@ -0,0 +1,221 @@ +/*! + * DataTables + Font Awesome integration + * License: MIT - http://datatables.net/license + */ + + +/* + * Sort styling + */ + +table.dataTable thead th { + position: relative; + background-image: none !important; + /* Remove the DataTables bootstrap integration styling */ +} + +table.dataTable thead th.sorting:after, +table.dataTable thead th.sorting_asc:after, +table.dataTable thead th.sorting_desc:after { + position: absolute; + top: 12px; + right: 8px; + display: block; + font-family: FontAwesome; +} + +table.dataTable thead th.sorting:after { + content: "\f0dc"; + color: #ddd; + font-size: 0.8em; + padding-top: 0.12em; +} + +table.dataTable thead th.sorting_asc:after { + content: "\f0de"; +} + +table.dataTable thead th.sorting_desc:after { + content: "\f0dd"; +} + +div.dataTables_scrollBody table.dataTable thead th.sorting:after, +div.dataTables_scrollBody table.dataTable thead th.sorting_asc:after, +div.dataTables_scrollBody table.dataTable thead th.sorting_desc:after { + content: ""; +} + + +/* In Bootstrap and Foundation the padding top is a little different from the DataTables stylesheet */ + +table.table thead th.sorting:after, +table.table thead th.sorting_asc:after, +table.table thead th.sorting_desc:after { + top: 8px; +} + + +/* + * DataTables style pagination controls + */ + +div.dataTables_paginate a.paginate_button.first, +div.dataTables_paginate a.paginate_button.previous { + position: relative; + padding-left: 24px; +} + +div.dataTables_paginate a.paginate_button.next, +div.dataTables_paginate a.paginate_button.last { + position: relative; + padding-right: 24px; +} + +div.dataTables_paginate a.first:before, +div.dataTables_paginate a.previous:before { + position: absolute; + top: 8px; + left: 10px; + display: block; + font-family: FontAwesome; +} + +div.dataTables_paginate a.next:after, +div.dataTables_paginate a.last:after { + position: absolute; + top: 8px; + right: 10px; + display: block; + font-family: FontAwesome; +} + +div.dataTables_paginate a.first:before { + content: "\f100"; +} + +div.dataTables_paginate a.previous:before { + content: "\f104"; +} + +div.dataTables_paginate a.next:after { + content: "\f105"; +} + +div.dataTables_paginate a.last:after { + content: "\f101"; +} + + +/* + * Bootstrap and foundation style pagination controls + */ + +div.dataTables_paginate li.first>a, +div.dataTables_paginate li.previous>a { + position: relative; + padding-left: 24px; +} + +div.dataTables_paginate li.next>a, +div.dataTables_paginate li.last>a { + position: relative; + padding-right: 24px; +} + +div.dataTables_paginate li.first a:before, +div.dataTables_paginate li.previous a:before { + position: absolute; + top: 6px; + left: 10px; + display: block; + font-family: FontAwesome; +} + +div.dataTables_paginate li.next a:after, +div.dataTables_paginate li.last a:after { + position: absolute; + top: 6px; + right: 10px; + display: block; + font-family: FontAwesome; +} + +div.dataTables_paginate li.first a:before { + content: "\f100"; +} + +div.dataTables_paginate li.previous a:before { + content: "\f104"; +} + +div.dataTables_paginate li.next a:after { + content: "\f105"; +} + +div.dataTables_paginate li.last a:after { + content: "\f101"; +} + + +/* In Foundation we don't want the padding like in bootstrap */ + +div.columns div.dataTables_paginate li.first a:before, +div.columns div.dataTables_paginate li.previous a:before, +div.columns div.dataTables_paginate li.next a:after, +div.columns div.dataTables_paginate li.last a:after { + top: 0; +} + + +/* Fix for Scroller plugin */ + +div.DTS { + display: block !important; +} + +div.DTS tbody th, +div.DTS tbody td { + white-space: nowrap; +} + +div.DTS div.DTS_Loading { + z-index: 1; +} + +div.DTS div.dataTables_scrollBody { + background: none; +} + +div.DTS div.dataTables_scrollBody table { + z-index: 2; +} + +div.DTS div.dataTables_paginate, +div.DTS div.dataTables_length { + display: none; +} + +/* Custom */ + +div.dataTables_wrapper { + min-height: 150px; +} + +.dataTables_filter input { + display: inline-block; + border-radius: 0px !important; + box-shadow: none; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857; + vertical-align: middle; + background-color: #FFF; + background-image: none; + border: 1px solid #CCC; + transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; +} + +.dataTables_info .select-info{ + display: none; +} diff --git a/assets/src/css/print/print.css b/assets/src/css/print/print.css new file mode 100644 index 000000000..06f4d4410 --- /dev/null +++ b/assets/src/css/print/print.css @@ -0,0 +1,67 @@ +input, +button, +.btn, +header, +.main-sidebar, +.main-footer, +#widget-controller_top, +#widget-controller_right, +.daterangepicker, +.datepicker, +#main-records_filter, +.extra-info, +.deleteicon, +.fa.deleteicon::after, +.fa.deleteicon::before, +.hide, +#back-to-top { + display: none; +} +td { + border: 1px solid #ccc; +} +th { + background: #333; + color: #fff; + text-align: left; + padding: 4px; +} +ul.nav { + float: left; +} +ul { + margin: 0; + padding: 0; +} +li.header i { + display: none; +} +li.header { + list-style: none; + margin: 10px 0; + padding: 0; +} +li.header > a { + font-size: 30px; + text-decoration: none; + font-weight: bold; + color: #333; + text-align: left; + float: left; +} +.table { + width: 100%; +} +.text-right { + text-align: right; +} +.pull-left { + float: left; + text-align: left; +} +#totali_colonne td { + background: #eee; +} +#totali_colonne td big { + font-size: 22px; +} diff --git a/assets/src/css/style.css b/assets/src/css/style.css new file mode 100644 index 000000000..17839b239 --- /dev/null +++ b/assets/src/css/style.css @@ -0,0 +1,561 @@ +*:focus { + outline: none; +} + +@font-face { + font-family: 'OpenSansRegular'; + src: url('../fonts/opensans-regular-webfont.eot'); + src: url('../fonts/opensans-regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/opensans-regular-webfont.woff') format('woff'), url('../fonts/opensans-regular-webfont.ttf') format('truetype'), url('../fonts/opensans-regular-webfont.svg#OpenSansRegular') format('svg'); + font-weight: normal; + font-style: normal; +} + +html, +body { + font-family: 'Open Sans', sans-serif; +} + +html { + height: 100%; +} + +textarea { + resize: vertical; +} + +a.disabled { + pointer-events: none; + cursor: default; + opacity: 0.6; +} + +.btn-calendar>.btn { + color: inherit !important; + background: transparent; + font-size: 20px; + margin-top: 2px; +} + +#progress { + width: 400px; + margin: auto; + position: relative; + display: none; +} + +#progress .progress-bar { + background-image: url(../img/progress.gif); +} + +#progress .progress-bar span { + position: absolute; + top: 2px; + left: 47%; + color: #a20; + font-weight: bold; +} + +#datetime { + font-size: 11px; + font-weight: normal; + color: #aaa; + margin: 8px 0 0 0; +} + +#right-menu { + padding: 10px; +} + +#right-menu .fa-info { + padding: 0px 5px +} + +.ui-menu { + position: fixed !important; +} + +.ui-autocomplete { + min-width: 160px; + padding: 10px; + margin: 2px; + list-style: none; + border-style: solid; + border-width: 1px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.ui-autocomplete-category { + font-size: 150%; +} + +.ui-autocomplete-scrollable { + max-height: 80vh; + width: 600px; + overflow-y: auto; + overflow-x: hidden; +} + +.ui-autocomplete a { + color: inherit; +} + +.square { + width: 24px; + height: 24px; + margin: auto; +} + +.content { + padding: 20px 15px; +} + +.navbar a:hover, +.logo:hover { + text-decoration: none +} + +.no-padding { + padding: 0 0px; +} + +.box-center { + width: 600px; + margin: 7% auto +} + +.box-center-large { + width: 850px; + margin: 7% auto +} + +.box-center .box-body, +.box-center-large .box-body { + padding: 20px; + border-top: 0 +} + +@media ( max-width:768px) { + .box-center, + .box-center-large { + width: 90%; + margin-top: 20px + } +} + +.li-widget a:hover { + text-decoration: none; +} + +.clickable { + cursor: pointer; +} + +#main_loading { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #555; + z-index: 9999; + text-align: center; + opacity: 0.9; + -moz-opacity: 0.9; + filter: alpha(opacity=90); +} + +#main_loading>div { + position: relative; + top: 50%; + color: #333; +} + +#main_loading>div>i { + font-size: 300px; + margin-top: -150px; + color: #e24e1e; +} + +#mini-loader { + position: fixed; + top: 0; + left: 0; + z-index: 9000; + width: 100%; + height: 100%; + background: rgba( 0, 0, 0, 0.15); +} + +#mini-loader>div { + position: absolute; + bottom: 50%; + left: 50%; + width: 100px; + height: 100px; + margin-top: -50px; + margin-left: -50px; + background: transparent url(../img/ajax-loader.gif) top left no-repeat; +} + +body .header .logo { + font-family: inherit; +} + +.btn-github { + color: #ffffff; + background-color: #444444; + border-color: rgba(0, 0, 0, 0.2); +} + +.btn-github:hover, +.btn-github:focus, +.btn-github:active, +.btn-github.active, +.open .dropdown-toggle.btn-github { + color: #ffffff; + background-color: #303030; + border-color: rgba(0, 0, 0, 0.2); +} + +.btn-github:active, +.btn-github.active, +.open .dropdown-toggle.btn-github { + background-image: none; +} + +.btn-github.disabled, +.btn-github[disabled], +fieldset[disabled] .btn-github, +.btn-github.disabled:hover, +.btn-github[disabled]:hover, +fieldset[disabled] .btn-github:hover, +.btn-github.disabled:focus, +.btn-github[disabled]:focus, +fieldset[disabled] .btn-github:focus, +.btn-github.disabled:active, +.btn-github[disabled]:active, +fieldset[disabled] .btn-github:active, +.btn-github.disabled.active, +.btn-github[disabled].active, +fieldset[disabled] .btn-github.active { + background-color: #444444; + border-color: rgba(0, 0, 0, 0.2); +} + +.btn-github .badge { + color: #444444; + background-color: #ffffff; +} + +span.form-control { + background: transparent; + border: none; +} + +.panel-heading.mini { + padding: 5px 8px; +} + +.dropdown.col-md-3>.dropdown-menu { + width: 91.5%; + left: 15px; + padding: 5px; +} + +.input-group-addon { + padding: 0px 12px; +} + +.colorpicker { + margin-top: 0px !important; +} + +@media ( max-width: 992px) { + .table-bordered>thead>tr>th, + .table-bordered>tbody>tr>th, + .table-bordered>tfoot>tr>th, + .table-bordered>thead>tr>td, + .table-bordered>tbody>tr>td, + .table-bordered>tfoot>tr>td { + word-break: break-all; + } +} + + +/* Aggiustamenti per i widget */ + +.widget li { + margin-left: 0 !important; + list-style-type: none; +} + +.widget { + padding: 0; + margin-bottom: 0; +} + +.widget.bordered { + border: 6px dashed #aaa; + margin: 10px; + min-height: 200px; + padding: 4px; +} + +.close { + padding-right: 5px; + position: relative; + z-index: 1; + opacity: 0.1; +} + + +/* Tooltip dark */ + +.ui-tooltip { + background: #222 !important; + color: white !important; + border: 0px; + font-size: 11px !important; +} + +.nav-tabs-custom>.nav-tabs.pull-right>li>a.back-btn { + font-size: 12px; + color: #3C8DBC; +} + +.nav-tabs-custom>.nav-tabs.pull-right>li>a.back-btn:hover { + cursor: pointer; + color: #72AFD2; +} + +@media ( max-width: 480px) { + #main_loading>div>i { + font-size: 160px; + margin-top: -80px; + } +} + +#back-to-top { + display: inline-block; + height: 60px; + width: 60px; + position: fixed; + bottom: 60px; + right: 10px; + z-index: 10; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.05); + /* image replacement properties */ + color: #fff; + overflow: hidden; + white-space: nowrap; + background: rgba(255, 78, 0, 0.8); + visibility: hidden; + opacity: 0; + -webkit-transition: opacity .3s 0s, visibility 0s .3s; + -moz-transition: opacity .3s 0s, visibility 0s .3s; + transition: opacity .3s 0s, visibility 0s .3s; +} + +#back-to-top>span { + position: absolute; + top: 50%; + left: 50%; + width: 30px; + height: 30px; + text-align: center; + margin-left: -15px; + margin-top: -15px; +} + +#back-to-top.cd-is-visible { + visibility: visible; + opacity: 0.8; + z-index: 900; +} + +#back-to-top.cd-is-visible:hover { + visibility: visible; + opacity: 1; + z-index: 900; +} + +#back-to-top.cd-fade-out { + opacity: 0.5; +} + +.input-searching { + background: #FFBF91; +} + +.deleteicon:hover { + color: black; +} + +.deleteicon { + color: gray; + width: 30px; + height: 30px; + position: absolute; + margin-left: -30px; + bottom: 7px; + right: 17px; + float: right; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.input-group-addon { + min-width: 40px; +} + +.info-box-icon i { + color: #fff; +} + +.progress-description, +.info-box-text { + white-space: normal; + overflow: auto; +} + +.colorpicker, +.colorpicker * { + z-index: 9999 +} + +.signature-pad { + width: 100%; + height: 100%; + font-size: 10px; + border: 1px solid #e8e8e8; + background-color: #fff; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset; + border-radius: 4px; +} + +.signature-pad:before, +.signature-pad:after { + content: ""; + width: 40%; + height: 10px; + left: 20px; + bottom: 10px; + background: transparent; + -webkit-transform: skew(-3deg) rotate(-3deg); + -moz-transform: skew(-3deg) rotate(-3deg); + -ms-transform: skew(-3deg) rotate(-3deg); + -o-transform: skew(-3deg) rotate(-3deg); + transform: skew(-3deg) rotate(-3deg); + box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4); +} + +.signature-pad:after { + left: auto; + right: 20px; + -webkit-transform: skew(3deg) rotate(3deg); + -moz-transform: skew(3deg) rotate(3deg); + -ms-transform: skew(3deg) rotate(3deg); + -o-transform: skew(3deg) rotate(3deg); + transform: skew(3deg) rotate(3deg); +} + +@media screen and (max-width: 1024px) { + .signature-pad { + top: 0; + left: 0; + right: 0; + bottom: 0; + width: auto; + height: auto; + min-width: 250px; + min-height: 140px; + margin: 5%; + } +} + +@media screen and (min-device-width: 768px) and (max-device-width: 1024px) { + .signature-pad { + margin: 10%; + } +} + +#canvas { + width: 100%; + height: 100%; + min-height: 202px; + border-radius: 4px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset; +} + +.sidebar-menu li>a>.pull-right-container { + position: absolute; + padding: 12px; + right: 10px; + top: 50%; + margin-top: -19px; +} + +.sidebar-form { + border-radius: 3px; + border-color: 1px; + margin: 10px 10px; +} + +.sidebar-form input[type="text"], +.sidebar-form .btn { + border: 1px; + height: 35px; + -webkit-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} + +.sidebar-form input[type="text"] { + border-top-left-radius: 2px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 2px; +} + +.sidebar-form .btn { + border-top-left-radius: 0; + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; + border-bottom-left-radius: 0; +} + +.swal2-buttonswrapper .btn { + margin: 5px; +} + + +/* Personalizzazione del plugin Select2 */ + +.select2-search, +.select2-search__field { + width: 100%!important +} + +.select2-results__option[aria-selected=true] { + display: none +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice { + margin: 2px 0 0 2px; +} + +.select2-container--bootstrap .select2-selection--single .select2-selection__rendered { + padding: 4px; +} + +.input-group-addon.no-padding { + border: 0px; +} + +.input-group-addon.no-padding>* { + border-radius: 0px; +} diff --git a/assets/src/css/themes/default.css b/assets/src/css/themes/default.css new file mode 100644 index 000000000..6b7e9ae00 --- /dev/null +++ b/assets/src/css/themes/default.css @@ -0,0 +1,214 @@ +.skin-default .wrapper, +.skin-default .main-sidebar, +.skin-default .left-side { + background: #333; +} + +.skin-default.login-page .wrapper { + background: #d2d6de; +} + +.skin-default .content-wrapper, +.skin-default .content { + background: #f6f6f6; +} + +.skin-default #supersearch { + color: #eee; +} + +.skin-default #supersearch:focus { + color: #222; +} + +.skin-default .inner { + color: #eee; +} + +.skin-default .nav-tabs-custom .nav-tabs li a { + color: #3c8dbc; +} + +.skin-default .nav-tabs-custom .nav-tabs li.active a { + color: inherit; +} + +.skin-default .nav-tabs-custom .nav-tabs.pull-right li a.back-btn { + color: #3C8DBC; +} + +.skin-default .nav-tabs-custom .nav-tabs.pull-right li a.back-btn:hover { + color: #72AFD2; +} + +.skin-default .main-header .navbar { + color: #eee; + background: #222; + border: none; +} + +.skin-default .main-header .navbar .nav li a +.skin-default .main-header .navbar .nav li a:hover, +.skin-default .main-header .navbar .nav li a:active, +.skin-default .main-header .navbar .nav li a:focus, +.skin-default .main-header .navbar .nav .open a, +.skin-default .main-header .navbar .nav .open a:hover, +.skin-default .main-header .navbar .nav .open a:focus, +.skin-default .main-header .navbar .nav .active a, +.skin-default .main-header .navbar .nav .actual a { + background: rgba(0, 0, 0, 0.2); + color: #f6f6f6; +} + +.skin-default .main-header .navbar .sidebar-toggle, +.skin-default .main-header .navbar .sidebar-toggle .icon-bar { + color: #f6f6f6; +} + +.skin-default .main-header .navbar .sidebar-toggle:hover { + color: #f6f6f6; + background: rgba(0, 0, 0, 0.2); +} + +.skin-default .main-header .navbar .sidebar-toggle { + color: #f6f6f6; +} + +.skin-default .main-header .navbar .sidebar-toggle:hover { + background: #222; +} + +@media (max-width: 767px) { + .skin-default .main-header .navbar .dropdown-menu li.divider { + background: rgba(255, 255, 255, 0.1); + } + .skin-default .main-header .navbar .dropdown-menu li a { + color: #f6f6f6; + } + .skin-default .main-header .navbar .dropdown-menu li a:hover { + background: #222; + } +} + +.skin-default .main-header .navbar .sidebar-toggle .icon-bar { + background: #f6f6f6; +} + +.skin-default .main-header .logo { + background: #222; + color: #f6f6f6; + border-bottom: 0 solid transparent; +} + +.skin-default .main-header .logo:hover { + background: #222; +} + +.skin-default .main-header li.user-header { + background: #222; +} + +.skin-default .main-header a { + text-decoration: none; +} + +.skin-default .content-header { + background: transparent; +} + +.skin-default .user-panel .info, +.skin-default .user-panel .info a { + color: #f6f6f6; +} + +.skin-default .sidebar-menu li.header { + color: #4b646f; + background: #222; +} + +.skin-default .sidebar-menu li a { + border-left: 3px solid transparent; +} + +.skin-default .sidebar-menu li:hover a, +.skin-default .sidebar-menu li.active a, +.skin-default .sidebar-menu li.actual a { + background: #222; + border-left-color: #222; +} + +.skin-default .sidebar-menu li:hover>a, +.skin-default .sidebar-menu li.actual>a { + color: #f6f6f6; +} + +.skin-default .sidebar-menu li .treeview-menu { + margin: 0 1px; + background: #222; +} + +.skin-default .sidebar a { + color: #f6f6f6; +} + +.skin-default .sidebar a:hover { + text-decoration: none; +} + +.skin-default .treeview-menu li a { + color: #f6f6f6; +} + +.skin-default .sidebar-form { + border-color: #222; +} + +.skin-default .sidebar-form input[type="text"], +.skin-default .sidebar-form .btn { + box-shadow: none; + background: #222; + border-color: transparent; +} + +.skin-default .sidebar-form input[type="text"] { + color: #666; +} + +.skin-default .sidebar-form input[type="text"]:focus, +.skin-default .sidebar-form input[type="text"]:focus+.input-group-btn .btn { + background: #f6f6f6; + color: #666; +} + +.skin-default .sidebar-form input[type="text"]:focus+.input-group-btn .btn { + border-left-color: #f6f6f6; +} + +.skin-default .sidebar-form .btn { + color: #999; +} + +.skin-default .main-sidebar li, +.skin-default .main-sidebar li a { + color: #ccc; +} + +.skin-default .panel-primary .panel-heading { + border-bottom: 2px solid #57a; +} + +.skin-default .ui-autocomplete { + background: #f6f6f6; + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.skin-default .parsley-errors-list{ + color: red; +} diff --git a/assets/src/img/ajax-loader.gif b/assets/src/img/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..cc70a7a8b3d426c30e76686fac70c0dcd4c70125 GIT binary patch literal 8238 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 literal 0 HcmV?d00001 diff --git a/assets/src/img/help.png b/assets/src/img/help.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4ce6eac18f3e466e8c09dc31d334d98ce47e61 GIT binary patch literal 11709 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 literal 0 HcmV?d00001 diff --git a/assets/src/img/osm_loading.gif b/assets/src/img/osm_loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..57f462b79a3d7049e8435c841977488848bccbca GIT binary patch literal 23501 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 GZ~qHVLrA>< literal 0 HcmV?d00001 diff --git a/assets/src/js/custom.js b/assets/src/js/custom.js new file mode 100644 index 000000000..6bc0634fd --- /dev/null +++ b/assets/src/js/custom.js @@ -0,0 +1,41 @@ +$(document).ready(function () { + var animationSpeed = 500; + $(document).off('click', '.sidebar li a') + .on('click', '.sidebar li a', function (e) { + //Get the clicked link and the next element + var $this = $(this); + var checkElement = $this.next(); + + //Check if the next element is a menu and is visible + if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) { + //Close the menu + checkElement.slideUp(animationSpeed, function () { + checkElement.removeClass('menu-open'); + }); + checkElement.parent("li").removeClass("active"); + } + //If the menu is not visible + else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) { + //Get the parent menu + var parent = $this.parents('ul').first(); + //Close all open menus within the parent + var ul = parent.find('ul:visible').slideUp(animationSpeed); + //Remove the menu-open class from the parent + ul.removeClass('menu-open'); + //Get the parent li + var parent_li = $this.parent("li"); + + //Open the target menu and add the menu-open class + checkElement.slideDown(animationSpeed, function () { + //Add the class active to the parent li + checkElement.addClass('menu-open'); + parent.find('li.active').removeClass('active'); + parent_li.addClass('active'); + }); + } + //if this isn't a link, prevent the page from being redirected + if (checkElement.is('.treeview-menu') && $(event.target).is('.pull-right-container')) { + e.preventDefault(); + } + }); +}); diff --git a/assets/src/js/i18n/datatables/it.json b/assets/src/js/i18n/datatables/it.json new file mode 100644 index 000000000..23cd07c2b --- /dev/null +++ b/assets/src/js/i18n/datatables/it.json @@ -0,0 +1,23 @@ +{ + "sEmptyTable": "Nessun dato presente nella tabella", + "sInfo": "Vista da _START_ a _END_ di _TOTAL_ elementi", + "sInfoEmpty": "Vista da 0 a 0 di 0 elementi", + "sInfoFiltered": "(filtrati da _MAX_ elementi totali)", + "sInfoPostFix": "", + "sInfoThousands": ".", + "sLengthMenu": "Visualizza _MENU_ elementi", + "sLoadingRecords": "Caricamento...", + "sProcessing": "Elaborazione...", + "sSearch": "Cerca:", + "sZeroRecords": "La ricerca non ha portato alcun risultato.", + "oPaginate": { + "sFirst": "Inizio", + "sPrevious": "Precedente", + "sNext": "Successivo", + "sLast": "Fine" + }, + "oAria": { + "sSortAscending": ": attiva per ordinare la colonna in ordine crescente", + "sSortDescending": ": attiva per ordinare la colonna in ordine decrescente" + } +} diff --git a/backup/.htaccess b/backup/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/backup/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/bug.php b/bug.php new file mode 100644 index 000000000..6ed761454 --- /dev/null +++ b/bug.php @@ -0,0 +1,275 @@ + 'email_host', + 'Username SMTP' => 'email_username', + 'Porta SMTP' => 'email_porta', + 'Sicurezza SMTP' => 'email_secure', + 'Password SMTP' => 'email_password', + ]; + $rs = $dbo->fetchArray("SELECT * FROM zz_settings WHERE sezione = 'Email'"); + foreach ($rs as $r) { + if (!empty($replace[$r['nome']])) { + $dati[$replace[$r['nome']]] = $r['valore']; + } + } + + // Preparazione email + $mail = new PHPMailer(); + + // Se non specificato l'host uso le impostazioni di invio mail di default del server + if (!empty($dati['email_host'])) { + $mail->IsSMTP(); + $mail->IsHTML(); + $mail->SMTPDebug = 2; + + $mail->Host = $dati['email_host']; + $mail->Port = $dati['email_porta']; + + // Controllo se è necessaria l'autenticazione per il server di posta + if (!empty($dati['email_username'])) { + $mail->SMTPAuth = true; + $mail->Username = $dati['email_username']; + $mail->Password = $dati['email_password']; + } + + if (in_array(strtolower($dati['email_secure']), ['ssl', 'tls'])) { + $mail->SMTPSecure = strtolower($dati['email_secure']); + } + } + + $mail->WordWrap = 50; + + // Mittente + $mail->From = $dati['email_from']; + $mail->FromName = $_SESSION['username']; + $mail->AddReplyTo($dati['email_from']); + + // Destinatario + $mail->AddAddress($dati['email_to']); + + // Copia + if (!empty($dati['email_cc'])) { + $mail->AddCC($dati['email_cc']); + } + + // Copia nascosta + if (!empty($dati['email_bcc'])) { + $mail->AddBCC($dati['email_bcc']); + } + + $mail->Subject = 'Segnalazione bug OSM '.$version.' ('.(!empty($revision) ? 'R'.$revision : _('In sviluppo')).')'; + $mail->AltBody = _('Questa email arriva dal modulo bug di segnalazione bug di OSM'); + $body = $dati['body'].'

'._('IP').': '.get_client_ip()."
\n"; + + // Se ho scelto di inoltrare i file di log, allego + if (!empty($post['log']) && file_exists($docroot.'/logs/error.log')) { + $mail->AddAttachment($docroot.'/logs/error.log'); + } + + // Se ho scelto di inoltrare copia del db + if (!empty($post['sql'])) { + $dump = "SET foreign_key_checks = 0;\n"; + $dump .= backup_tables(); + $dump .= "SET foreign_key_checks = 1;\n"; + + $backup_file = 'Backup OSM '.date('Y-m-d').' '.date('H_i_s').'.sql'; + + if (file_put_contents($docroot.'/'.$backup_file, $dump)) { + $mail->AddAttachment($docroot.'/'.$backup_file); + $_SESSION['infos'][] = _('Backup del database eseguito ed allegato correttamente!'); + } else { + $_SESSION['errors'][] = _('Errore durante la creazione del file di backup!'); + } + } + + // Se ho scelto di inoltrare le INFO del mio sistema + if (!empty($post['info'])) { + $body .= $_SERVER['HTTP_USER_AGENT'].' - '.getOS(); + } + + $mail->Body = $body; + + // Invio mail + if (!$mail->send()) { + $_SESSION['errors'][] = _("Errore durante l'invio della segnalazione").': '.$mail->ErrorInfo; + } else { + $_SESSION['infos'][] = _('Email inviata correttamente!'); + } + + $mail->SmtpClose(); + + if (!empty($post['sql'])) { + unlink($docroot.'/'.$backup_file); + } + + redirect($rootdir.'/bug.php'); + exit(); +} + +if (file_exists($docroot.'/include/custom/top.php')) { + include $docroot.'/include/custom/top.php'; +} else { + include $docroot.'/include/top.php'; +} + +$email_to = ''; +$email_from = ''; +$rs = $dbo->fetchArray("SELECT * FROM zz_settings WHERE sezione = 'Email'"); +foreach ($rs as $r) { + if (($r['nome'] == 'Server SMTP' || $r['nome'] == 'Indirizzo per le email in uscita' || $r['nome'] == 'Destinatario') && $r['valore'] == '') { + $alert = true; + } + + if ($r['nome'] == 'Destinatario') { + $email_to = $r['valore']; + } elseif ($r['nome'] == 'Indirizzo per le email in uscita') { + $email_from = $r['valore']; + } +} + +if (!empty($alert)) { + echo ' +
+ + '._('Attenzione!').' '._('Per utilizzare correttamente il modulo di segnalazione bug devi configurare alcuni parametri email nella scheda impostazioni').'. + '.Modules::link('Opzioni', $dbo->fetchArray("SELECT `idimpostazione` FROM `zz_settings` WHERE sezione='Email'")[0]['idimpostazione'], _('Correggi'), null, 'class="btn btn-warning pull-right"').' +
+
'; +} + +echo ' +
+
+

'._('Segnalazione bug').'

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
'._('Da').': + {[ "type": "email", "placeholder": "'._('Mittente').'", "name": "email_from", "value": "'.$email_from.'", "required": 1 ]} +
'._('A').': + {[ "type": "email", "placeholder": "'._('Destinatario').'", "name": "email_to", "value": "'.$email_to.'", "required": 1 ]} +
'._('Cc').': + {[ "type": "email", "placeholder": "'._('Copia a').'...", "name": "email_cc" ]} +
'._('Bcc').': + {[ "type": "email", "placeholder": "'._('Copia nascosta a').'...", "name": "email_bcc" ]} +
'._('Versione OSM').': + {[ "type": "span", "placeholder": "'._('Versione OSM').'", "value": "'.$version.' ('.(!empty($revision) ? 'R'.$revision : _('In sviluppo')).')" ]} +
+ +
+
+ {[ "type": "checkbox", "placeholder": "'._('Allega file di log').'", "name": "log", "value": "1" ]} +
+ +
+ {[ "type": "checkbox", "placeholder": "'._('Allega copia del database').'", "name": "sql", "value": "0" ]} +
+ +
+ {[ "type": "checkbox", "placeholder": "'._('Allega informazioni sul PC').'", "name": "info", "value": "1" ]} +
+
+ +
+
+ + {[ "type": "textarea", "label": "'._('Descrizione del bug').'", "name": "body" ]} + + +
+
+ +
+
+
+
+
+ + '; + +if (file_exists($docroot.'/include/custom/bottom.php')) { + include $docroot.'/include/custom/bottom.php'; +} else { + include $docroot.'/include/bottom.php'; +} diff --git a/call.php b/call.php new file mode 100644 index 000000000..418a0be1b --- /dev/null +++ b/call.php @@ -0,0 +1,24 @@ +query('UPDATE zz_semaphores SET updated_at = NOW() WHERE id_utente = '.prepare($_SESSION['idutente']).' AND posizione = '.prepare($posizione)); +$dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated_at, INTERVAL '.(get_var('Timeout notifica di presenza (minuti)') * 2).' SECOND) <= NOW()'); +$datas = $dbo->fetchArray('SELECT DISTINCT * FROM zz_semaphores INNER JOIN zz_users ON zz_semaphores.id_utente=zz_users.idutente WHERE id_utente != '.prepare($_SESSION['idutente']).' AND posizione = '.prepare($posizione)); + +$result = []; +if ($datas != null) { + foreach ($datas as $data) { + array_push($result, ['username' => $data['username']]); + } +} + +echo json_encode($result); diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..00853da82 --- /dev/null +++ b/composer.json @@ -0,0 +1,57 @@ +{ + "name": "openstamanager/openstamanager", + "description": "Gestionale open source per assistenza tecnica e fatturazione", + "version": "2.3.0", + "license": "GPL-3.0", + "keywords": [ + "open source", + "gestionale", + "assistenza tecnica", + "fatturazione" + ], + "homepage": "http://openstamanager.com/", + "authors": [{ + "name": "Fabio Lovato", + "email": "info@openstamanager.com" + }, { + "name": "Fabio Piovan", + "email": "info@openstamanager.com" + }, { + "name": "Luca Salvà", + "email": "info@openstamanager.com" + }], + "type": "project", + "require": { + "php": ">=5.4", + "ezyang/htmlpurifier": "^4.8", + "filp/whoops": "^2.1", + "intervention/image": "^2.3", + "ircmaxell/password-compat": "^1.0", + "maximebf/debugbar": "^1.13", + "monolog/monolog": "^1.22", + "paragonie/random_compat": "^2.0", + "phpmailer/phpmailer": "^5.2", + "spipu/html2pdf": "^4.6", + "symfony/translation": "^3.2" + }, + "autoload": { + "psr-4": { + "": "lib/classes/", + "Module\\": "modules/" + }, + "files": [ + "lib/functions.php", + "lib/util.php", + "lib/deprecated.php" + ] + }, + "scripts": { + "post-create-project-cmd": "yarn run release-OSM" + }, + "config": { + "sort-packages": true, + "optimize-autoloader": true, + "apcu-autoloader": true, + "prefer-stable": true + } +} diff --git a/config.example.php b/config.example.php new file mode 100644 index 000000000..cb9b11e18 --- /dev/null +++ b/config.example.php @@ -0,0 +1,22 @@ + +
+
+
'; + +include $docroot.'/include/manager.php'; + +echo ' +
'; + +// Inclusione contenuti varie tab dei plugin +foreach ($plugins as $plugin) { + echo ' +
'; + + $id_plugin = $plugin['id']; + + include $docroot.'/include/manager.php'; + + echo ' +
'; +} + +echo ' +
+ + '; + +/** + * Widget laterali. + */ +// Controllo se ho widget per il lato destro dello schermo, altrimenti non creo la colonna di destra +$result_widgets = $dbo->fetchArray('SELECT `id`, `location`, `class` FROM `zz_widgets` WHERE `id_module`='.prepare($id_module)." AND `location`='controller_right' AND `enabled`=1 ORDER BY `order` ASC"); +if (count($result_widgets) > 0) { + echo ' +
'; + echo Widgets::addModuleWidgets($id_module, 'controller_right'); + echo ' +
'; +} + +if (file_exists($docroot.'/include/custom/bottom.php')) { + include $docroot.'/include/custom/bottom.php'; +} else { + include $docroot.'/include/bottom.php'; +} diff --git a/core.php b/core.php new file mode 100644 index 000000000..0b68f2849 --- /dev/null +++ b/core.php @@ -0,0 +1,264 @@ +validate()){ + die(_('Constrollo CSRF fallito!')); +}*/ + +// Logger per la segnalazione degli errori +$logger = new Monolog\Logger(_('OpenSTAManager')); +$logger->pushProcessor(new Monolog\Processor\UidProcessor()); +$logger->pushProcessor(new Monolog\Processor\WebProcessor()); + +use Monolog\Handler\StreamHandler; +use Monolog\Handler\RotatingFileHandler; + +$handlers = []; +// File di log di base (logs/all.log) +$handlers[] = new StreamHandler(__DIR__.'/logs/error.log', Monolog\Logger::ERROR); +$handlers[] = new StreamHandler(__DIR__.'/logs/setup.log', Monolog\Logger::EMERGENCY); + +// Impostazioni di debug +if (!empty($debug)) { + if (empty($strict)) { + // Ignoramento degli avvertimenti e delle informazioni relative alla deprecazione di componenti + error_reporting(E_ALL & ~E_NOTICE & ~E_USER_DEPRECATED); + } + + // File di log ordinato in base alla data + $handlers[] = new RotatingFileHandler(__DIR__.'/logs/error.log', 0, Monolog\Logger::ERROR); + $handlers[] = new RotatingFileHandler(__DIR__.'/logs/setup.log', 0, Monolog\Logger::EMERGENCY); + + if (version_compare(PHP_VERSION, '5.5.9') >= 0) { + $prettyPageHandler = new Whoops\Handler\PrettyPageHandler(); + + // Imposta Whoops come gestore delle eccezioni di default + $whoops = new Whoops\Run(); + $whoops->pushHandler($prettyPageHandler); + + // Abilita la gestione degli errori nel caso la richiesta sia di tipo AJAX + if (\Whoops\Util\Misc::isAjaxRequest()) { + $whoops->pushHandler(new Whoops\Handler\JsonResponseHandler()); + } + + $whoops->register(); + } + + // Istanziamento della barra di debug + $debugbar = new DebugBar\StandardDebugBar(); + $debugbar->addCollector(new DebugBar\Bridge\MonologCollector($logger)); +} else { + // Disabilita la segnalazione degli errori + error_reporting(0); +} + +// Imposta il formato di salvataggio dei log +$monologFormatter = new Monolog\Formatter\LineFormatter('[%datetime%] %channel%.%level_name%: %message% %extra%'.PHP_EOL); +foreach ($handlers as $handler) { + $logger->pushHandler($handler->setFormatter($monologFormatter)); +} + +// Imposta Monolog come gestore degli errori (si sovrappone a Whoops) +Monolog\ErrorHandler::register($logger); + +// Istanziamento della gestione di date e numeri +$formatter = !empty($formatter) ? $formatter : []; +Translator::setLocaleFormatter($formatter); + +// Aggiunta del wrapper personalizzato per la generazione degli input +if (!empty($HTMLWrapper)) { + HTMLBuilder\HTMLBuilder::setWrapper($HTMLWrapper); +} + +// Aggiunta dei gestori personalizzati per la generazione degli input +foreach ((array) $HTMLHandlers as $key => $value) { + HTMLBuilder\HTMLBuilder::setHandler($key, $value); +} + +// Aggiunta dei gestori per componenti personalizzate +foreach ((array) $HTMLManagers as $key => $value) { + HTMLBuilder\HTMLBuilder::setManager($key, $value); +} + +// Registrazione globale del template per gli input HTML +register_shutdown_function('translateTemplate'); + +// Redirect al percorso HTTPS se impostato nella configurazione +if (!empty($redirectHTTPS) && !isHTTPS(true)) { + header('HTTP/1.1 301 Moved Permanently'); + header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + exit(); +} + +session_set_cookie_params(0, $rootdir); +session_start(); + +// Impostazione della sessione di base +$_SESSION['infos'] = isset($_SESSION['infos']) ? $_SESSION['infos'] : []; +$_SESSION['warnings'] = isset($_SESSION['warnings']) ? $_SESSION['warnings'] : []; +$_SESSION['errors'] = (array) $_SESSION['errors']; + +// Imposto il periodo di visualizzazione dei record dal 01-01-yyy al 31-12-yyyy +if (!empty($_GET['period_start'])) { + $_SESSION['period_start'] = $_GET['period_start']; + $_SESSION['period_end'] = $_GET['period_end']; +} elseif (!isset($_SESSION['period_start'])) { + $_SESSION['period_start'] = date('Y').'-01-01'; + $_SESSION['period_end'] = date('Y').'-12-31'; +} + +// Impostazione del tema grafico di default +$theme = !empty($theme) ? $theme : 'default'; + +// Istanziamento del gestore delle traduzioni del progetto +$lang = !empty($lang) ? $lang : 'it'; +$translator = new Translator($lang); +$translator->addLocalePath($docroot.'/locale'); +$translator->addLocalePath($docroot.'/modules/*/locale'); + +// Istanziamento del gestore degli utenti +if (!Update::isUpdateAvailable()) { + $auth = new Auth(); +} + +$version = Update::getVersion(); +$revision = Update::getRevision(); + +$assets = $rootdir.'/assets/dist'; +$css = $assets.'/css'; +$js = $assets.'/js'; +$img = $assets.'/img'; + +// CSS di base del progetto +$css_modules = []; + +$css_modules[] = $css.'/app.min.css'; +$css_modules[] = $css.'/style.min.css'; +$css_modules[] = $css.'/themes.min.css'; +$css_modules[] = [ + 'href' => $css.'/print.min.css', + 'media' => 'print', +]; + +// JS di base del progetto +$jscript_modules = []; + +$jscript_modules[] = $js.'/app.min.js'; +$jscript_modules[] = $js.'/custom.min.js'; +$jscript_modules[] = $js.'/i18n/parsleyjs/'.$lang.'.min.js'; +$jscript_modules[] = $js.'/i18n/select2/'.$lang.'.min.js'; +$jscript_modules[] = $js.'/i18n/moment/'.$lang.'.min.js'; +$jscript_modules[] = $js.'/i18n/fullcalendar/'.$lang.'.min.js'; + +if (Auth::check()) { + $jscript_modules[] = $rootdir.'/lib/functions.js'; + $jscript_modules[] = $rootdir.'/lib/init.js'; +} + +$dbo = Database::getConnection(); + +// Controllo sull'esistenza delle informazioni necessarie prima di effettuare la connessione al database +if ($dbo->isConnected() && $dbo->isInstalled() && (Auth::check() || API::isAPIRequest()) && !Update::isUpdateAvailable()) { + if (!empty($debugbar)) { + $debugbar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($dbo->getPDO())); + } + + $id_module = filter('id_module'); + $id_record = filter('id_record'); + $id_plugin = filter('id_plugin'); + $id_parent = filter('id_parent'); + + /* + * Creazione array con l'elenco dei moduli + * es. $modules['Anagrafiche']['nome_campo']; + */ + $rs = $dbo->fetchArray('SELECT * FROM `zz_modules` LEFT JOIN (SELECT `idmodule`, `permessi` FROM `zz_permissions` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `idutente`='.prepare($_SESSION['idutente']).')) AS `zz_permissions` ON `zz_modules`.`id`=`zz_permissions`.`idmodule` LEFT JOIN (SELECT `idmodule`, `clause` FROM `zz_group_module` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `idutente`='.prepare($_SESSION['idutente']).')) AS `zz_group_module` ON `zz_modules`.`id`=`zz_group_module`.`idmodule`'); + + $modules_info = []; + for ($i = 0; $i < count($rs); ++$i) { + foreach ($rs[$i] as $name => $value) { + if ($name == 'permessi' && (Auth::isAdmin() || $value == null)) { + if (Auth::isAdmin()) { + $value = 'rw'; + } else { + $value = '-'; + } + } + if ($name != 'idmodule' && $name != 'updated_at' && $name != 'created_at' && $name != 'clause') { + $modules_info[$rs[$i]['name']][$name] = $value; + } elseif ($name == 'clause') { + $additional_where[$rs[$i]['name']] = !empty($value) ? ' AND '.$value : $value; + } + } + + $modules_info[$rs[$i]['id']]['name'] = $rs[$i]['name']; + } + + $user = Auth::getUser(); + $user_idanagrafica = $user['idanagrafica']; + + if (!empty($id_module)) { + $module = Modules::getModule($id_module); + + $pageTitle = $module['title']; + + Permissions::addModule($id_module); + } + + if (!empty($skip_permissions)) { + Permissions::skip(); + } + + Permissions::check(); +} elseif (slashes($_SERVER['SCRIPT_FILENAME']) != slashes(DOCROOT.'/index.php')) { + redirect(ROOTDIR.'/index.php?op=logout'); + exit(); +} + +// Istanziamento di HTMLHelper +$html = new HTMLHelper(); + +// Variabili GET e POST +$post = Filter::getPOST(); +$get = Filter::getGET(); diff --git a/couscous.yml b/couscous.yml new file mode 100644 index 000000000..095dc8448 --- /dev/null +++ b/couscous.yml @@ -0,0 +1,47 @@ +template: + url: https://github.com/pnowy/CouscousNativeTemplate + +include: + - docs + +# Base URL of the published website (no "/" at the end!) +baseUrl: /osm/website + +title: OpenSTAManager +subTitle: Il gestionale open source per l'assistenza tecnica e la fatturazione +fontAwesomeIcon: fa fa-cog + +# The left menu bar +menu: + sections: + main: + name: Documentazione di base + items: + home: + text: Home page + relativeUrl: index.html + installazione: + text: Installazione + relativeUrl: installazione.html + framework: + text: Framework + relativeUrl: framework.html + assets: + text: Assets + relativeUrl: assets.html + moduli: + text: Moduli + relativeUrl: moduli.html + other: + name: Approfondimenti + items: + api: + text: API + relativeUrl: api.html + docs: + text: Documentazione completa + relativeUrl: docs/ + osm: + text: Sito ufficiale + absoluteUrl: http://www.openstamanager.com/ + diff --git a/docs/.htaccess b/docs/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/docs/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/docs/API.md b/docs/API.md new file mode 100644 index 000000000..4320cd940 --- /dev/null +++ b/docs/API.md @@ -0,0 +1,110 @@ +--- +currentMenu: api +--- + +# API + +> Con application programming interface (in acronimo API, in italiano interfaccia di programmazione di un'applicazione), in informatica, si indica ogni insieme di procedure disponibili al programmatore, di solito raggruppate a formare un set di strumenti specifici per l'espletamento di un determinato compito all'interno di un certo programma. +> +> \-- [Wikipedia](https://it.wikipedia.org/wiki/Application_programming_interface) + +L'API del progetto è attualmente ancora in sviluppo, e pertanto le funzioni disponibili potrebbero essere piuttosto ridotte. Di seguito sono elencate le basi per connettersi al sistema e ottenere i dati a cui si è interessati. + + + +- [Accesso](#accesso) +- [Output](#output) +- [Messaggi](#messaggi) +- [Formato dei componenti](#formato-dei-componenti) +- [Richieste di lettura](#richieste-di-lettura) + - [Interventi](#interventi) + - [Anagrafiche](#anagrafiche) + - [Richieste disabilitate](#richieste-disabilitate) + - [Modifiche](#modifiche) + - [Eliminazioni](#eliminazioni) + + + +## Accesso + +L'accesso all'API viene effettuato concatenendo la chiave dell'utenza all'URL del sito su cui è ospitato il progetto. + + http:///api/?token= + +La chiave di accesso è ottenibile eseguendo la seguente query all'interno del database del progetto: + +```sql +SELECT `token` FROM `zz_tokens` WHERE `id_utente` = +``` + +## Output + +L'API del progetto permette di ottenere le informazioni attraverso un array in formato JSON. +Per poter interpretare correttamente i dati, si devono ignorare gli indici numerici di primo livello (non rilevanti all'interno del formato) e sfruttare in particolare i seguenti campi generici: + +- `records`, rappresentante il numero totale dei record richiesti; +- `pages`, indicante il numero totale della pagine disponibili. + +Si ricorda che l'API prevede la restituzione di un insieme di dati limitato rispetto alla richiesta effettuatua: per ottenere l'intero insieme di informazioni è necessario eseguire molteplici richieste consecutive basate sul campo `page`. + +## Messaggi + +Ogni richiesta effettuata all'API viene accompagnata da un messaggio predefinito che permette di interpretare in modo più preciso la risposta. +In particolare, sono presenti i seguenti _status_: + +- `200: OK` - La richiesta è andata a buon fine. +- `400: Errore interno dell'API` - La richiesta effettuata risulta invalida per l'API. +- `401: Non autorizzato` - Accesso non autorizzato. +- `404: Non trovato` - La risorsa richiesta non risulta disponibile. +- `500: Errore del server` - Il gestionale non è in grado di completare la richiesta. + +## Formato dei componenti + +I seguenti componenti delle richieste devono seguire una rigida struttura: + +- `page` (intero). +- `upd` (yyyy-MM-dd hh:mm:ss). + +## Richieste di lettura + +### Interventi + +Tutto il contenuto della tabella in_interventi: + + http:///api/?token=&resource=in_interventi + +Singolo intervento (riga della tabella): + + http:///api/?token=&resource=in_interventi&filter[id]=[1] + +### Anagrafiche + +Tutto il contenuto della tabella an_anagrafiche: + + http:///api/?token=&resource=an_anagrafiche + +Singolo intervento (riga della tabella): + + http:///api/?token=&resource=an_anagrafiche&filter[idanagrafica]=[1] + +Ricerca per ragione sociale: + + http:///api/?token=&resource=an_anagrafiche&filter[ragione_sociale]=[%%] + +### Richieste disabilitate + +#### Modifiche + +Tutti i contenuti di tutte le tabelle: + + http:///api/?token=&resource=updates + +Tutti i contenuti di tutte le tabelle, aggiornati a partire da una data precisa: + + http:///api/?token=&resource=updates&upd=2016-01-31%2010:44:31 + +#### Eliminazioni + +Tutte le eliminazioni di tutte le tabelle: + + http:///api/?token=&resource=deleted diff --git a/docs/Assets.md b/docs/Assets.md new file mode 100644 index 000000000..b82de07e5 --- /dev/null +++ b/docs/Assets.md @@ -0,0 +1,107 @@ +--- +currentMenu: assets +--- + +# Assets + +> Web assets are things like CSS, JavaScript and image files that make the frontend of your site look and work great. +> +> \-- [Symfony](http://symfony.com/doc/current/best_practices/web-assets.html) + +Gli assets sono, all’interno dei moderni ambienti di sviluppo web, il cuore pulsante del software in relazione al layout e al livello di accessibilità; in particolare,il termine assets fa solitamente riferimento ai componenti di natura grafica di un software, quali immagini, fonts e icone, linguaggi di scripting client-side (JavaScript) e fogli di stile a cascata (_Cascading Style Sheets_). + +Il progetto utilizza [Yarn](https://yarnpkg.com/) per gestire l'installazione e l'aggiornamento degli assets e [Gulp](http://gulpjs.com/) per compilarli e associarli con le personalizzazioni. Viene inoltre richiesta la presenza di [Git](https://git-scm.com/) asll'interno del sistema operativo. + + + +- [Struttura](#struttura) +- [Personalizzazione](#personalizzazione) + - [Tema grafico](#tema-grafico) + - [Aggiornamento e installazione pacchetti](#aggiornamento-e-installazione-pacchetti) + - [Compilazione](#compilazione) +- [Assets predefiniti](#assets-predefiniti) + + + +## Struttura + +Yarn salva automaticamente gli assets da lui gestiti all'interno della cartella `node_modules`, non presente nella repository e nelle release del progetto per la sua natura estremamente variabile e facilmente riproducibile (tramite l'utilizzo dello strumento, come si vedrà in [Personalizzazione](#personalizzazione)). + +Gli assets personalizzati del progetto sono al contrario contenuti all'interno della cartella `assets/src`; parallelamente, gli assets utilizzati direttamente dal progetto sono infine contenuti all'interno della cartella `assets/dist`, generata in automatico tramite l'utilizzo di [Gulp](http://gulpjs.com/). + + +## Personalizzazione + +L'introduzione di una gestione automatizzata rende, di fatto, maggiromente semplificata la gestione delle dipendeze grafiche del progetto, portando però al tempo stesso alla necessità di utilizzare una specifica procedura per aggiornare e personalizzare gli assets. +Si ricorda che è altamente sconsigliato modificare i contenuti delle cartelle `node_modules` o `assets/dist` in modo manuale, poiché tali modifiche andrebbero perse a seguito di ogni aggiornamento. + + +### Tema grafico + +La personalizzazione dello stile del gestionale può essere effettuata a partire dal foglio di stile `assets/src/css/themes/default.css`, contentente le principali impoistazioni grafiche del progetto. +L'aggiunta di un nuovo tema richieda la creazione di un file indipendente nella stessa cartella, rinominando la classe CSS generica con il nome della skin inserita (da `.skin-default` a `.skin-nome`). + +Una volta eseguita la task automatica di compilazione, il nuovo file varrà aggiunto in `themes.min.css` di `assets/css`. + +Per modificare lo stile utilizzato dal gestionale, vedere la variabile `$theme` in `config.inc.php`. + +### Aggiornamento e installazione pacchetti + +Nel caso si rivelasse necessario installare o aggiornare i pacchetti predisposti dal gestionale, è necessario procedere all'esecuzione dei comdani caratteristici di Yarn e successivamente eseguire una compliazione degli assets. + +L'installazione di nuovi pacchetti viene eseguita attraverso il seguente comando: + +```bash +yarn add +``` + +L'aggiornamento degli assets gestiti è effettuabile tramite il seguente comando: + +```bash +yarn upgrade +``` + +Per ulteriori informazioni, consultare la [documentazione ufficiale di Yarn](https://yarnpkg.com/en/docs). + +### Compilazione + +Per compilare gli assets, sia quelli gestiti da Yarn che quelli personalizzati, è necessario eseguire il seguente comando: + +```bash +yarn run build-OSM +``` + +**Attenzione**: la compilazione è fondamentale a seguito di ogni modifica degli assets, poiché altrimenti i file utilizzati dal progetto non saranno aggiornati. + +## Assets predefiniti + +- admin-lte +- autosize +- bootstrap +- bootstrap-colorpicker +- bootstrap-daterangepicker +- bootstrap-switch +- ckeditor +- components-jqueryui +- datatables.net-bs +- datatables.net-scroller-bs +- eonasdan-bootstrap-datetimepicker +- font-awesome +- fullcalendar +- html5shiv +- inputmask +- jquery +- jquery-form +- jquery-slimscroll +- jquery-ui-touch-punch +- moment +- parsleyjs +- respond.js +- select2 +- select2-bootstrap-theme +- signature_pad +- smartwizard +- sweetalert2 +- tooltipster + +_I nomi sono indicati secondo la notazione tipica dei pacchetti NPM._ diff --git a/docs/Contribuire.md b/docs/Contribuire.md new file mode 100644 index 000000000..74f78a6ed --- /dev/null +++ b/docs/Contribuire.md @@ -0,0 +1,10 @@ +--- +currentMenu: contribuire +--- + +# Contribuire + + + + + diff --git a/docs/File.md b/docs/File.md new file mode 100644 index 000000000..9e3ec70fa --- /dev/null +++ b/docs/File.md @@ -0,0 +1,36 @@ +--- +currentMenu: file +--- + +# File + + + +- [MyImpianti](#myimpianti) + + + +## MyImpianti + +La cartella _files_ contiene file di vari tipologie, raggruppati in base al modulo di cui fanno parte: + +- Impostazione (`.ini`), utilizzate dai moduli abilitati in tal senso per ampliare l'offerta naturale degli stessi. +- File di cui viene effettuato l'upload all'interno dei vari moduli (riconosciuti dal gestionale tramite le funzioni interne al file `lib/modulebuilder.php`). + +I file \*.ini devono seguire il seguente standard. {} = facoltativo + +```ini +[Nome] +tipo = tag_HTML +valore ={ "Valore di default"} +{opzioni = "Opzione 1", "Opzione 2", "Opzione 3"} + +[Nome] +tipo = tag_HTML +valore ={ "Valore di default"} +{opzioni = "Opzione 1", "Opzione 2", "Opzione 3"} +``` + +Per tag_HTML si intendono tutti i tag HTML, con preferenza rivolata verso quelli di input (input, select, textarea, date, ...) sebbene il sistema accetti anche gli altri (span, p, ...). + +Attualmente questi file vengono utilizzati esclusivamente dal modulo **MyImpianti** per la gestione delle varie tipologie di _Componenti_. Il file `my_impianti/componente.ini` è un esempio di base di questa funzionalità, e un'ulteriore personalizzazione può essere trovata [nel forum](http://www.openstamanager.com/forum/viewtopic.php?f=5&t=93). diff --git a/docs/Framework.md b/docs/Framework.md new file mode 100644 index 000000000..87c3843d1 --- /dev/null +++ b/docs/Framework.md @@ -0,0 +1,67 @@ +--- +currentMenu: framework +--- + +# Framework + +> Un framework, termine della lingua inglese che può essere tradotto come intelaiatura o struttura, in informatica e specificatamente nello sviluppo software, è un'architettura logica di supporto (spesso un'implementazione logica di un particolare design pattern) su cui un software può essere progettato e realizzato, spesso facilitandone lo sviluppo da parte del programmatore. +> +> \-- [Wikipedia](https://it.wikipedia.org/wiki/Framework) + +Il progetto utilizza [Composer](https://getcomposer.org/) per gestire le librerie PHP in modo completamente gratuito e open source. Questo permette di completare l'installazione e l'aggiornamento dei diversi framework in modo facile ed intuitivo, senza doversi preoccupare in modo eccessivo delle dipendenze delle diverse librerie. + + + +- [Struttura](#struttura) +- [Personalizzazione](#personalizzazione) + - [Aggiornamento](#aggiornamento) + - [Installazione di nuovi pacchetti](#installazione-di-nuovi-pacchetti) +- [Framework predefiniti](#framework-predefiniti) + + + +## Struttura + +I framework vengono automaticamente scaricati da Composer all'interno della cartella _vendor_ nella root del progetto, dove vengono memorizzati secondo un percorso derivante dall'origine del pacchetto (per maggiori informazioni, consultare la [documentazione ufficiale di Composer](https://getcomposer.org/doc/)). + +La modifica dei contenuti di `vendor` è altamente sconsigliata, poichè qualunque aggiornamento potrebbe sovrascrivere ed annullare le modifiche effettuate. + +## Personalizzazione + +Nel caso si rivelasse necessario aggiornare i framework presenti o installare nuove librerie, è necessario avere disponibile una corretta e funzionante [installazione locale di Composer](https://getcomposer.org/download/). + +Una volta completata l'installazione di Composer è possibile, partendo dalla cartella del gestionale, iniziare l'aggiornamento e la personalizzazione tramite le seguenti operazioni. + +### Aggiornamento + +L'aggiornamento dei framework è effettuabile tramite il seguente comando: + +```bash +php composer.phar update +``` + +Per ulteriori informazioni, consultare la [documentazione ufficiale di Composer](https://getcomposer.org/doc/). + +### Installazione di nuovi pacchetti + +Per installare nuovi framework e/o librerie è utilizzabile il seguente comando: + +```bash +php composer.phar require +``` + +Per ulteriori informazioni, consultare la [documentazione ufficiale di Composer](https://getcomposer.org/doc/). + +## Framework predefiniti + +- ezyang/htmlpurifier +- filp/whoops +- intervention/image +- ircmaxell/password-compat +- maximebf/debugbar +- monolog/monolog +- phpmailer/phpmailer +- spipu/html2pdf +- symfony/translation + +_I nomi sono indicati secondo la notazione tipica dei progetti pubblici su Github._ diff --git a/docs/Installazione.md b/docs/Installazione.md new file mode 100644 index 000000000..ed1dbafbe --- /dev/null +++ b/docs/Installazione.md @@ -0,0 +1,150 @@ +--- +currentMenu: installazione +--- + +# Installazione + + + +- [Tabella dei contenuti](#tabella-dei-contenuti) +- [Requisiti](#requisiti) +- [Installazione](#installazione) + - [Versioni](#versioni) + - [SourceForge](#sourceforge) +- [Strumenti utili](#strumenti-utili) + - [Windows](#windows) + - [Linux](#linux) + - [MAC](#mac) +- [Problemi comuni](#problemi-comuni) + - [Schermata bianca iniziale](#schermata-bianca-iniziale) + - [Blocco dell'installazione allo 0%](#blocco-dellinstallazione-allo-0%25) + + + +## Requisiti + +Prima di iniziare l'installazione, è necessario procedere al download di una versione del progetto da [SourceForge](https://sourceforge.net/p/openstamanager/). Si consiglia inoltre di controllare che i prerequisiti del software, elencati di seguito, siano soddisfatti. + +L'installazione del gestionale richiede la presenza di un server web con abilitato il [DBMS (Database Management System)](https://it.wikipedia.org/wiki/Database_management_system) MySQL e il linguaggio di programmazione [PHP](http://php.net/). + +- PHP >= 5.4 (si consiglia come minimo la versione 5.6 per poter usufruire di tutte le funzionalità del progetto) +- MySQL >= 5.0 + +## Installazione + +Per procedere all'installazione è necessario seguire i seguenti punti: + +1. Creare una cartella (ad esempio `openstamanager`) nella root del sever web installato ed estrarvi il contenuto della release scaricata. Il percorso della cartella root del server varia in base al software in utilizzo: + + - LAMP (`/var/www/html`); + - XAMPP (`C:/xampp/htdocs` per Windows, `/opt/lampp/htdocs/` per Linux, `/Applications/XAMPP/htdocs/` per MAC); + - WAMP (`C:\wamp\www`); + - MAMP (`C:\MAMP\htdocs` per Windows, `/Applications/MAMP/htdocs` per MAC). + +2. Creare un database vuoto (tramite [PHPMyAdmin](http://localhost/phpmyadmin/) o riga di comando). +3. Accedere a dal vostro browser. +4. Inserire i dati per collegarsi al database e cliccare su **Installa** per completare l'installazione. + +**Attenzione**: è possibile che l'installazione richieda del tempo. Si consiglia pertanto di attendere almeno qualche minuto senza alcun cambiamento nella pagina di installazione (in particolare, della progress bar presente) prima di cercare una possibile soluzione nelle discussioni del forum o nella sezione dedicata. + +### Versioni + +Per mantenere un elevato grado di trasparenza riguardo al ciclo delle release, seguiamo le linee guida [Semantic Versioning (SemVer)](http://semver.org/) per definire le versioni del progetto. Per vedere tutte le versioni disponibili al download, visitare la [pagina relativa](https://sourceforge.net/projects/openstamanager/files/) su SourceForge. + +### SourceForge + +Nel caso si stia utilizzando la versione direttamente ottenuta dalla repository di SourceForge, è necessario eseguire i seguenti comandi da linea di comando per completare le dipendenze PHP (tramite [Composer](https://getcomposer.org/)) e gli asssets (tramite [Yarn](https://yarnpkg.com/)) del progetto. + +```bash +php composer.phar install +php composer.phar update +yarn global add gulp +yarn install +gulp +``` + +In alternativa alla sequenza di comandi precedente, è possibile utilizzare il seguente comando (richiede l'installazione di GIT e Yarn, oltre che l'inserimento dell'archivio `composer.phar` nella cartella principale del progetto): + +```bash +yarn run develop-OSM +``` + +Per ulteriori informazioni, visitare le sezioni [Assets](https://sourceforge.net/p/openstamanager/wiki/Assets/) e [Framework](https://sourceforge.net/p/openstamanager/wiki/Framework/) della documentazione. + +## Strumenti utili + +### Windows + +Per installare il server web si consiglia di scaricare [WAMP dal sito ufficiale](http://www.wampserver.com/en/#download-wrapper), seguendo l'installazione guidata senza particolari personalizzazioni. +Una volta terminata l’installazione è necessario creare una cartella per il gestionale in `C:\wamp\www\`, copiando al suo interno il contenuto della release scaricata. + +### Linux + +Per installare il web server è necessario installare i pacchetti `apache2`, `php5` e `mysql-server`. + +```bash +sudo apt-get install apache2 php5 mysql-server +``` + +Una volta completata l’installazione è necessario creare una cartella per il gestionale, copiandobi al suo interno il contenuto della release scaricata, nel web server di Apache2: + +- nella versione <= 2.3, la cartella si trova in `/var/www/`; +- nella versione >= 2.4, la cartella si trova in `/var/www/html/`; + +E' inoltre necessario assicurarsi di concedere i permessi di scrittura sulla cartella creata: + +```bash +sudo chmod 777 -R /var/www/ +``` + +Si consiglia l'installazione del pacchetto `phpmyadmin`, per poter gestire graficamente il database MySQL: + +```bash +sudo apt-get install phpmyadmin +``` + +### MAC + +La piattaforma Apple non è stata oggetto di molti test: pertanto si consiglia di individuare in prima persona un server web funzionante e con caratteristiche corrispondenti ai requisiti indicati. + +Il gestionale è stato testato con successo su Mac OS X con [MAMP](http://www.mamp.info/en/) e XAMPP. + +## Problemi comuni + +### Schermata bianca iniziale + +**Attenzione**: a partire dalla versione 2.3 questa problema non è più presente. + +Nel caso si verifichi il problema di schermata bianca iniziale è necessario controllare i valori delle variabili `$rootdir` e `$docroot` nelle prime righe di _core.php_. Una possibile soluzione, implementata dalla versione 2.3, potrebbe essere: + +```php +$docroot = __DIR__; +$rootdir = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/')); +if (strrpos($rootdir, '/'.basename($docroot).'/') !== false) { + $rootdir = substr($rootdir, 0, strrpos($rootdir, '/'.basename($docroot).'/')).'/'.basename($docroot); +} +$rootdir = str_replace('%2F', '/', rawurlencode($rootdir)); +``` + +Si ricorda comunque che: + +- `$docroot` deve corrispondere al percorso reale nel file system per raggiungere la cartella principale del gestionale. +- `$rootdir` deve corrispondere al percorso URL del browser per raggiungere il gestionale nel server web. + +### Blocco dell'installazione allo 0% + +**Attenzione**: a partire dalla versione 2.3 questa problema non è più presente. + +Nel caso l'installazione iniziale del database si blocchi allo 0% è probabilmente necessario effettuare una modifica nel file di impostazione del DBMS (`my.ini` nel caso di MySQL). + +```ini +#sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" +sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" +``` + +La riga preceduta da `#` è quella originale, mentre quella seguente è l'opzione che permette il corretto funzionamento dell'installazione. + +Discussioni originale: + +- [\[RISOLTO\] Tabelle Mancanti](http://www.openstamanager.com/forum/viewtopic.php?f=2&t=86981) +- [MySQL running in Strict Mode and giving me problems. How to fix this?](http://stackoverflow.com/questions/21667601/mysql-running-in-strict-mode-and-giving-me-problems-how-to-fix-this) diff --git a/docs/Moduli.md b/docs/Moduli.md new file mode 100644 index 000000000..791c8cf37 --- /dev/null +++ b/docs/Moduli.md @@ -0,0 +1,271 @@ +--- +currentMenu: moduli +--- + +# Moduli + +> Un modulo (software) è un componente software autonomo e ben identificato, e quindi facilmente riusabile. +> +> \-- [Wikipedia](https://it.wikipedia.org/wiki/Modulo#Informatica) + +All'interno del progetto, i moduli vengono genericamente definiti quali sistemi di gestione delle funzionalità del gestionale; proprio per questo, la loro struttura e composizione risulta spesso variabile e differenziata, presentando componenti uniche e talvolta complesse. +Ogni modulo è composto da diverse sezioni, generalmente suddivise in: + +- Nucleo; +- [Stampe](Stampe.md); +- [Widget](Widget.md); +- [Plugin](Plugin.md). + +Inoltre, OpenSTAManager presenta una struttura nativamente preposta alla personalizzazione delle proprie funzioni, che rende il progetto ancora più complicato da comprendere a prima vista. + +Segue un'analisi della struttura fisica e logica del nucleo dei moduli supportati dal gestionale; per ulteriori informazioni e approfondimenti, si consiglia di osservare l'effettiva composizione dei moduli implementati in modo ufficiale. + + + +- [Struttura](#struttura) + - [actions.php](#actionsphp) + - [add.php e edit.php](#addphp-e-editphp) + - [init.php](#initphp) + - [controller_after.php e controller_before.php](#controller_afterphp-e-controller_beforephp) + - [modutil.php](#modutilphp) +- [Database](#database) + - [zz_modules](#zz_modules) + - [zz_permissions e zz_group_module](#zz_permissions-e-zz_group_module) + - [zz_views e zz_group_view](#zz_views-e-zz_group_view) + - [zz_plugins e zz_widgets](#zz_plugins-e-zz_widgets) +- [Consigli per lo sviluppo](#consigli-per-lo-sviluppo) + - [Progettazione](#progettazione) + - [Sviluppo](#sviluppo) + - [Test](#test) +- [Installazione](#installazione) + - [Archivio ZIP](#archivio-zip) + - [update/VERSIONE.sql](#updateversionesql) + - [update/unistall.php (INCLUDE)](#updateunistallphp-include) + - [MODULE](#module) +- [Moduli di base](#moduli-di-base) + + + +## Struttura + +La sezione fondamentale di un qualsiasi modulo all'interno di OpenSTAManager risulta presenta all'interno della cartella `modules`, che contiene tutti i file su cui si basano tutti i moduli per funzionare correttamente. +In questo contensto, ogni modulo possiede una cartella univoca per gestire i propri contenuti in modo indipendente ma comunque sottoposto alla seguente struttura di base. + + . + └── modulo +    ├── actions.php +    ├── add.php +    ├── controller_after.php +    ├── controller_before.php +    ├── edit.php +    ├── init.php +    └── modutil.php + +Il gestionale supporta in modo nativo questa struttura, che può essere ampliata e personalizzata a necessità dagli sviluppatori: si consiglia pertanto di analizzare la struttuta dei moduli **Iva**, **Dashboard** e **Contratti** per esempi di diversa complessità e funzione. + +**Attenzione**: la presenza dei file sopra indicati non è strettamente necessaria per il funzionamento di un modulo (si veda **Movimenti**, presente esclusivamente a livello di database). + +### actions.php + +Il file `actions.php` gestisce tutte le operazioni supportate dal modulo. + +In generale, le diverse operazioni vengono gestite attraverso attraverso una logica programmativa basata su casi (solitamente, il parametro `op` permette di identificare quale azione viene richiesta); il funzionamento a livello di programmazione può essere comunque sottoposto a scelte personali. + +L'unico requisito effettivo risulta relativo alle operazioni di creazione dei nuovi record, per cui deve essere definito all'interno della variabile `$id_record` l'identificativo del nuovo elemento. +Per osservare questo sistema, si consiglia di analizzare il relativo file del modulo **Iva**. + +### add.php e edit.php + +Il file `add.php` contiene il template HTML dedicato all'inserimento di nuovi elementi per il modulo, mentre `edit.php` contiene il template HTML dedicato alla modifica degli stessi. + +In base alla configurazione del modulo nel database, il file `edit.php` può assumere il ruolo di gestore della sezione principale dell'interno modulo, permettendo così la personalizzazione dei contenuti come si può notare per i moduli **Dashboard** e **Gestione componenti**. + +**Attenzione**: il progetto individua in automatico la presenza di questo file e agisce di conseguenza per permettere o meno l'inserimento di nuovi valori. + +### init.php + +Il file `init.php` si occupa di individuare le informazioni principali utili all'identificazione e alla modifica dei singoli elementi del modulo. +In particolare, questi file sono solitamente composti da una query dedicata ad ottenere tutti i dati dell'elemento nella variabile `$records`, successivamente utilizzata dal gestore dei template per completare le informazioni degli input. + +### controller_after.php e controller_before.php + +Il file `controller_after.php` contiene le funzioni javaScript aggiuntive specifiche del modulo. + +### modutil.php + +Il file `modutil.php` viene utilizzato per definire le funzioni PHP specifiche per il modulo, e permettere in questo modo uan gestione semplificata delle operazioni più comuni. + +Si noti che un modulo non è necessariamente limitato all'utilizzo del proprio file `modutil.php`: come avviene per esempio in **Fatture** e **Interventi**, risulta possibile richiamare file di questa tipologia da altri moduli (in questo caso, da **Articoli** per la gestione delle movimentazioni di magazzino). + +## Database + +All'interno del database del progetto, le tabelle con il suffisso `zz` sono generalmente dedicate alla gestione delle funzioni di base del gestionale, finalizzate in particolare all'utilizzo dei moduli installati. + +La gestione dei moduli avviene in questo senso grazie alle seguenti tabelle: + +- `zz_modules`; +- `zz_permissions`; +- `zz_views`; +- `zz_plugins`; +- `zz_widgets`. + +### zz_modules + +La tabella `zz_modules` contiene tutte le informazioni dei diversi moduli installati nel gestionale in uso, con particolare riferimento a: + +- Nome (utilizzato a livello di programmazione) [`name`] +- Titolo (visibile e personalizzabile) [`title`] +- Percorso nel file system (partendo da `modules/`) [`directory`] +- Icona [`icon`] +- Posizione nella sidebar [`order`] +- Compatibilità [`compatibility`] +- Query di default [`options`] +- Query personalizzata [`options2`] + +Gli ultimi due attributi si rivelano di fondamentale importanza per garantire il corretto funzionamento del modulo, poiché descrivono il comportamento dello stesso per la generazione della schermata principale nativa di OpenSTAManager. +Sono permessi i seguenti valori: + +- custom [Modulo con schermata principale personalizzata e definita nel file `edit.php`] +- {VUOTO} [Menu non navigabile] +- menu [Menu non navigabile] +- Oggetto JSON + +```json + { "main_query": [ { "type": "table", "fields": "Nome, Descrizione", "query": "SELECT `id`, `nome` AS `Nome`, `descrizione` AS `Descrizione` FROM `tabella` HAVING 1=1 ORDER BY `nome`"} ]} +``` + +- Query SQL \[vedasi la tabella [zz_views](#zz_views-e-zz_group_view)] + +```sql + SELECT |select| FROM `tabella` HAVING 1=1 +``` + +### zz_permissions e zz_group_module + +La tabella `zz_permissions` contiene i permessi di accesso dei vari gruppi ai diversi moduli, mentre la tabella `zz_group_module` contiene le clausole DQL per permettere questo accesso. + +### zz_views e zz_group_view + +Le tabelle `zz_views` e `zz_group_view` vengono utilizzate dal gestionale per la visualizzazione delle informazioni secondo i permessi accordati, oltre che dal modulo **Viste** per la gestione dinamica delle query. + +### zz_plugins e zz_widgets + +La tabella `zz_plugins` contiene l'elenco di plugins relativi ai diversi moduli, mentre la tabella `zz_group_module` contiene l'elenco di widgets dei vari moduli. + +## Consigli per lo sviluppo + +### Progettazione + +Alla base dello sviluppo di ogni modulo vi è una fase di analisi indirizzata all'individuazione dettagliata delle funzionalità dello stesso e della struttura interna al database atta a sostenere queste funzioni. Siete dunque pregati di identificare chiaramente tutte le caratteristiche del Vostro nuovo modulo o delle Vostre modifiche prima di iniziare lo sviluppo vero e proprio (comunemente identificato con la scrittura del codice). + +> E' bene trascurare le fasi di analisi e di progetto e precipitarsi all'implementazione allo scopo di guadagnare il tempo necessario per rimediare agli errori commessi per aver trascurato la fase di analisi e di progetto. +> +> \-- Legge di Mayers + +### Sviluppo + +Lo sviluppo del codice deve seguire alcune direttive generali per la corretta interpretazione del codice all'interno del gestionale: ciò comporta una struttura di base fondata sui file precedentemente indicati nella sezione [Cartella `modules`](#Cartella_modules) ma ampliabile liberamente. + +### Test + +Prima di pubblicare un modulo si consiglia di effettuare svariati test in varie installazioni. Siete inoltre pregati di indicare i bug noti. + +> Se c’è una remota possibilità che qualcosa vada male, sicuramente ciò accadrà e produrrà il massimo danno. +> +> \-- Legge di Murphy + +## Installazione + +L'installazione di un modulo è completabile in modo automatico seguendo la seguente procedura: + +- Scaricare l'archivio `.zip` del modulo da installare; +- Accedere al proprio gestionale con un account abilita all'accesso del modulo **Aggiornamenti**; +- Selezionare l'archivio scaricato nella selezione file della sezione "Carica un nuovo modulo"; +- Cliccare il pulsante "Carica". + +Si ricorda che per effettuare l'installazione è necessaria la presenza dell'estensione `php_zip` (per ulteriori informazioni guardare [qui](http://php.net/manual/it/zip.installation.php)). + +**Attenzione**: la procedura può essere completata anche a livello manuale, ma si consiglia di evitare tale sistema a meno che non si conosca approfonditamente il funzionamento complessivo e specifico del database del progetto. + +### Archivio ZIP + +L'archivio scaricato deve contenere direttamente al proprio interno i contenuti del modulo da installare, organizzati secondo la seguente struttura: + + modulo.zip + ├── update + | ├── VERSIONE.sql + | └── unistall.php + ├── ... - File contententi il codice del modulo + └── MODULE + +#### update/VERSIONE.sql + +Il file `VERSIONE.sql` (dove VERSIONE sta per la versione del modulo con `_`[underscore] al posto di `.`[punto]) contiene le operazioni di installazione del modulo a livello del database, comprendenti la creazione delle tabelle di base del modulo e l'inserimento di ulteriori dati nelle altre tabelle. + +#### update/unistall.php (INCLUDE) + +Il file `unistall.php` contiene le operazioni di disinstallazione del modulo a livello del database, comprendenti l'eliminazione delle tabelle non più necessarie e dei dati inutilizzati. + +```php +query("DROP TABLE `tabella`"); + +?> +``` + +#### MODULE + +Il file `MODULE` è infine il diretto responsabile dell'installazione del modulo poiché definisce tutti i valori caratteristici dello stesso; in caso di sua assenza la cartella compressa viene considerata non corretta. + +```ini +module_name = Nome del modulo +module_version = Versione del modulo +module_dir = Cartella di installazione del modulo +module_options = Operazione da eseguire all'apertura del modulo +module_icon = Icona del modulo (Font-Awesome) +module_compatibility = Compatibilità del modulo +module_parent = "Genitore" del modulo +``` + +## Moduli di base + +Nella versione base del gestionale sono presenti, all'interno della cartella `modules`, i seguenti moduli. + + . + ├── aggiornamenti + ├── anagrafiche + ├── articoli + ├── automezzi + ├── backup + ├── beni + ├── categorie + ├── causali + ├── contratti + ├── dashboard + ├── ddt + ├── fatture + ├── gestione_componenti + ├── interventi + ├── impostazioni + ├── iva + ├── listini + ├── misure + ├── my_impianti + ├── ordini + ├── pagamenti + ├── partitario + ├── porti + ├── preventivi + ├── primanota + ├── scadenzario + ├── stati_intervento + ├── tecnici_tariffe + ├── tipi_anagrafiche + ├── tipi_intervento + ├── utenti + ├── viste + ├── voci_servizio + └── zone diff --git a/docs/Nucleo.md b/docs/Nucleo.md new file mode 100644 index 000000000..32aa8fe53 --- /dev/null +++ b/docs/Nucleo.md @@ -0,0 +1,253 @@ +--- +currentMenu: nucleo +--- + +# Nucleo + + + +- [Root](#root) + - [add.php](#addphp) + - [ajax_autocomplete.php](#ajax_autocompletephp) + - [ajax_dataload.php](#ajax_dataloadphp) + - [ajax_select.php](#ajax_selectphp) + - [bug.php](#bugphp) + - [core.php](#corephp) + - [config.inc.php](#configincphp) + - [controller.php](#controllerphp) + - [editor.php](#editorphp) + - [index.php](#indexphp) + - [info.php](#infophp) + - [log.php](#logphp) + - [composer.json, gulpfile.js, package.json](#composerjson-gulpfilejs-packagejson) +- [Cartella api](#cartella-api) +- [Cartella assets](#cartella-assets) +- [Cartella backup](#cartella-backup) +- [Cartella docs](#cartella-docs) +- [Cartella files](#cartella-files) +- [Cartella include](#cartella-include) + - [bottom.php (CUSTOMIZABLE)](#bottomphp-customizable) + - [top.php (CUSTOMIZABLE)](#topphp-customizable) +- [Cartella lib](#cartella-lib) + - [deprecated.php](#deprecatedphp) + - [functions.php](#functionsphp) + - [functionsjs.php (HTML)](#functionsjsphp-html) + - [init.js (HTML)](#initjs-html) + - [modulebuilder.php](#modulebuilderphp) + - [permissions_check.php](#permissions_checkphp) + - [user_check.php](#user_checkphp) + - [classes/Database.php](#classesdatabasephp) + - [classes/HTMLBuilder.php](#classeshtmlbuilderphp) +- [Cartella locale](#cartella-locale) +- [Cartella modules](#cartella-modules) +- [Cartella templates](#cartella-templates) +- [Cartella update](#cartella-update) + - [create_updates.sql](#create_updatessql) + - [update_VERSIONE.sql (OPEN)](#update_versionesql-open) + - [update_VERSIONE.php](#update_versionephp) +- [Cartella vendor](#cartella-vendor) + + + +Scaricando la versione SVN del progetto dovreste trovare una struttura di base molto simile a quella seguente. + + . + ├── api + ├── assets + ├── backup + ├── doc + ├── files + ├── include + ├── lib + ├── locale + ├── modules + ├── src + ├── templates + ├── update + └── vendor + +Analizzeremo ora in dettaglio la funzione delle diverse cartelle e dei relativi contenuti. +Si avverte che il gestionale è fortemente basato sulla correttezza contemporanea di molti file: siete pertanto pregati di astenervi da modifiche o, se queste dovessero rivelarsi necessarie, procedere alla creazione di un relativo file custom nella cartella del file. E' comunque consigliabile richiedere l'assistenza ufficiale. + +Per maggiori informazioni riguardanti il procedimento di personalizzazione, rivolgersi alla sezione [Personalizzazione]. + +## Root + +I contenuti della cartella _root_, indicata nella struttura precedente dal punto inziale, sono estremamente importante per il progetto, in quanto sono generalmente dedicati a garantire il funzionamento dell'intero gestionale. +Questa centralizzazione permette al software di essere estremamente scalabile e personalizzabile, soprattutto in relazione ai moduli. +Per maggiori informazioni riguardanti lo sviluppo di un modulo, consultare la sezione [Moduli]. + +### add.php + +Il file `add.php` è dedicato alla gestione dei form di creazione nuovi elementi all'interno dei vari moduli. +In particolare si occupa parallelamente della funzionalità di aggiunta al volo, visibile in azione nei modulo **Attività**, **Articoli** e in alcuni altri punti del software. + +### ajax_autocomplete.php + +Il file `ajax_dataload.php` gestisce il caricamento dinamico dei dati in varie sezioni del sito, relativamente alle operazioni di auto-completamento dei form. + +**Attenzione**: questo sistema è ormai quasi deprecato e, tranne in rari casi, completamente sostituito dall'utilizzo del file `ajax_select.php` e dal plugin [Select2](https://select2.github.io/). + +### ajax_dataload.php + +Il file `ajax_dataload.php` gestisce il caricamento dinamico dei dati nelle tabelle fornite nella vista generale dei moduli (`controller.php`), filtrando i risultati in base alle richieste dell'utente. + +### ajax_select.php + +Il file `ajax_select.php` gestisce il caricamento dinamico dei dati nei diversi select abilitati, garantendo l'accesso a tutti i record senza provocare rallentamenti (persino per numeri più elevati). + +### bug.php + +Il file `bug.php` si occupa della segnalazione dei bug, fornendo un sistema integrato di invio email dopo la configurazione di pochi parametri iniziali. +Le opzioni relative alle informazioni da allegare sono: + +- Allegare il file di log (fondamentale nel caso si stia effettuando una segnalazione) +- Allegare una copia del database +- Allegare le informazioni relative al PC utilizzato + +### core.php + +Il _core_, come si può discernere dal nome, è il nucleo dell'intero gestionale: si occupa delle operazioni di inizializzazione fondamentali, compresa l'inclusione del file di configurazione `config.inc.php` e la creazione dell'elenco degli assets da includere. +Si occupa inoltre del controllo dei permessi, tramite l'inclusione di `lib/permissions.php`, e dell'individuazione delle informazioni di base relative al modulo aperto. + +### config.inc.php + +Il file `config.inc.php` contiene tutte le informazioni per accedere correttamente al database e per determinare il tema utilizzato dal gestionale. + +**Attenzione**: questo file non è presente di default poiché obbligatoriamente da personalizzare tramite la procedura di installazione. + +### controller.php + +Il file `controller.php` si occupa di gestire l'accesso generico ai moduli, caricando le informazioni e i widget del modulo in oggetto. Permette inoltre la visualizzazione, in base ai permessi accordati all'utente, del pulsante di creazione nuovi elementi. + +### editor.php + +Il file `editor.php` si occupa di gestire l'accesso specifico ai dati di un singolo elemento di un modulo, caricando al tempo stesso l'insieme di plugin (e, in casi più rari, di widget) legati alla visualizzazione dell'elemento in oggetto. Permette inoltre, in base ai permessi accordati all'utente, la modifica dei dati inseriti e l'interazione con altri moduli. + +### index.php + +Il file `index.php` si occupa delle operazioni di autenticazione (login e logout), oltre che effettuare un controllo sulla disponibilità di aggiornamenti (tramite l'inclusione di `update/update_checker.php`) e a garantire il redirect iniziale al primo modulo su cui l'utente possiede i permessi di accesso. + +### info.php + +Il file `info.php` contiene la sezione informativa relativa al progetto, indicante la community, la modalità di supporto e le offerte a pagamento. + +### log.php + +Il file `log.php` permette di visualizzare le informazioni relative agli ultimi 100 accessi, comprendenti eventuali tentativi falliti ed errori. + +**Attenzione**: nel caso in cui l'utente sia un amministratore, le informazioni accessibili sono relative a _tutti_ i tentativi di accesso (al contrario, un utente normale può visualizzare esclusivamente i propri tentativi). + +### composer.json, gulpfile.js, package.json + +Per maggiori informazioni questi file, consultare le sezioni [Framework] e [Assets]. + +## Cartella api + +Per maggiori informazioni riguardanti la cartella `api` e i suoi contenuti, rivolgersi alla sezione [API]. + +## Cartella assets + +Per maggiori informazioni riguardanti la cartella `assets` e i suoi contenuti, rivolgersi alla sezione [Assets (CSS, JS e immagini)]. + +## Cartella backup + +La cartella _backup_ è quella di default utilizzata dall'operazione omonima del progetto. + +## Cartella docs + +La cartella `docs`, come si può intuire, contiene la documentazione di sviluppo del progetto. + +## Cartella files + +Per maggiori informazioni riguardanti la cartella `files` e i suoi contenuti, rivolgersi alla sezione [Moduli]. + +## Cartella include + +### bottom.php (CUSTOMIZABLE) + +Il file `bottom.php` si occupa delle operazioni di chiusura della pagina HTML, garantendo inoltre l'eliminazione dei log temporanei della sessione. + +### top.php (CUSTOMIZABLE) + +Il file `top.php` gestisce la creazione del layout di base del gestionale, comprendente la barra di navigazione e la sidebar. + +## Cartella lib + +La cartella `lib` contiene le librerie personalizzate e le funzioni utilizzate dall'intero gestionale nei diversi moduli. + +**Attenzione**: sono qui presenti solo i metodi generali e comunemente riutilizzati. Per maggiori informazioni riguardanti la locazione delle funzioni specifiche di un modulo, visitare la sezione [Moduli]. + +### deprecated.php + +Il file `deprecated.php` contiente l'insieme di funzioni deprecate nella versione corrente del gestionale, che verranno successivamente rimosse nella futura release. + +### functions.php + +Il file `functions.php` contiene tutte le funzioni comunemente utilizzate nel progetto. + +### functionsjs.php (HTML) + +Il file `functionsjs.php` contiene tutte le funzioni JavaScript comunemente utilizzate nel progetto. + +### init.js (HTML) + +Il file `init.js` contiene le funzioni JavaScript comunemente richiamate al caricamento di parti indipendenti del progetto. + +### modulebuilder.php + +Il file `modulebuilder.php` contiene le funzioni (e le sezioni HTML) atte all'upload di file e all'individuazione degli stessi, oltre che alla loro gestione, nei vari moduli. + +### permissions_check.php + +Il file `permissions_check.php` si occupa dei controlli relativi ai permessi di accesso di un utente ad un determinato modulo. + +**Attenzione**: questo file è ora sostituito dalla classe Permissions. + +### user_check.php + +Il file `user_check.php` si occupa di controllare se è stato effettuato l'accesso. + +**Attenzione**: questo file è ora sostituito dalla classe Permissions. + +### classes/Database.php + +La classe Database gestisce la connessione con il database, rendendo disponibile un insieme di funzioni utili ad elaborare i risulti delle diverse query. + +### classes/HTMLBuilder.php + +La classe HTMLBuilder contiene i metodi responsabili della creazione di contenuto HTML partendo dal template interno del progetto. + +Per maggiori informazioni le caratteristiche del template utilizzato dal gestionale, rivolgersi alla sezione [Template]. + +## Cartella locale + +La cartella `locale` contiene tutte le traduzioni del progetto, nei formati tipici di Gettext (`.po` e `.mo`). + +## Cartella modules + +Per maggiori informazioni riguardanti la cartella `modules` e i suoi contenuti, rivolgersi alla sezione [Moduli]. +Si ricorda che per tutti i contenuti del modulo è possibile creare una personalizzazione nella cartella `custom`. + +## Cartella templates + +La cartella `templates` contiene tutti i file relativi alla visualizzazione in PDF dei dati dei vari moduli. +Per maggiori informazioni riguardanti la cartella `templates` e i suoi contenuti, rivolgersi alla sezione [Stampe]. + +## Cartella update + +### create_updates.sql + +Il file `create_updates.sql` contiene la query SQL per la creazione della tabella di gestione degli aggiornamenti e delle installazioni del gestionale. + +### update_VERSIONE.sql (OPEN) + +I file `VERSIONE.sql` contengono l'insieme di query SQL necessarie per l'aggiornamento del gestionale alla versione _VERSIONE_. + +### update_VERSIONE.php + +I file `VERSIONE.php` contengono l'insieme di operazioni PHP (e, talvolta, SQL) necessarie per l'aggiornamento del gestionale alla versione _VERSIONE_. + +## Cartella vendor + +Per maggiori informazioni riguardanti la cartella `vendor` e i suoi contenuti, rivolgersi alla sezione [Framework]. diff --git a/docs/Plugin.md b/docs/Plugin.md new file mode 100644 index 000000000..c064a1594 --- /dev/null +++ b/docs/Plugin.md @@ -0,0 +1,10 @@ +--- +currentMenu: plugin +--- + +# Plugin + + + + + diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..841295727 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,51 @@ +--- +currentMenu: home +--- + +# OpenSTAManager - Documentazione + +Benvenuti nella wiki di OpenSTAManager! + +> Al giorno d'oggi, per le aziende coinvolte nel settore dell'assistenza tecnica la necessità di un software dedicato, flessibile, completo e funzionale in molteplici categorie di dispositivi risulta di fondamentale importanza per permettere un'efficiente gestione dell'attività lavorativa. +> Per rispondere a queste esigenze nasce il gestionale per il servizio di assistenza tecnica OpenSTAManager, che rende disponibile un supporto informatico per la gestione di questa tipologia di pratiche in un contesto talvolta povero di alternative. + +La documentazione del progetto presenta informazioni valide a partire dalla versione 2.3 dello stesso. +Si avverte pertanto che questa documentazione non è utilizzabile con efficacia per le versioni precedenti del progetto, con particolare riguardo verso le strutture relative ad assets e framework, oltre che alle procedure di sviluppo di moduli. + + + +- [Presentazione](#presentazione) +- [Storia](#storia) +- [Membri](#membri) + + + +## Presentazione + +Il gestionale OpenSTAManager è un software open-source e web based, sviluppato dall'azienda informatica DevCode di Este per gestire ed archiviare il servizio di assistenza tecnica e la relativa fatturazione. +Il nome del progetto deriva dalla parziale traduzione in inglese degli elementi principali che lo compongono: la natura open source e il suo obiettivo quale Gestore del Servizio Tecnico di Assistenza. + +Un software gestionale, identificato nell'insieme degli applicativi che automatizzano i processi di gestione all'interno delle aziende, appartiene solitamente a una specifica categoria del settore, specializzata negli ambiti di: + +- Gestione della contabilità; +- Gestione del magazzino; +- Gestione e ausilio della produzione; +- Gestione e previsione dei budget aziendali; +- Gestione ed analisi finanziaria. + +Secondo questa definizione, OpenSTAManager riesce a generalizzare al proprio interno le funzionalità caratteristiche della contabilità e della gestione del magazzino, presentando inoltre moduli piuttosto avanzati e destinati a complementare l'attività aziendale in relazione agli interventi di assistenza della realtà lavorativa in oggetto. + +Proprio grazie alla vasta gamma di funzionalità che lo caratterizzano, questo gestionale riesce a mantenere una posizione rilevante all'interno del mercato, garantita dalla natura open source del progetto e amplificata dall'ampio grado di personalizzazione che contraddistingue questo particolare software. + +## Storia + +OpenSTAManager viene inizialmente ideato da Nicoletta Marampon e sviluppato da **Fabio Lovato** al fine di gestire esclusivamente le anagrafiche e gli interventi aziendali per piccole realtà lavorative. + +La prima release (0.2RC2 dell'agosto 2008) viene successivamente ampliata con numerosi e innovativi componenti, quali il calendario delle attività, e ottimizzata in relazione al sistema di installazione e di aggiornamento; parallelamente, tra il 2011 e 2012, viene introdotto il sistema di gestione della contabilità e vengono migliorati numerosi moduli, soprattutto a livello grafico. +Fondamentale in questo senso risulta essere la collaborazione dei nuovi colleghi **Luca Salvà** e **Fabio Piovan**, che ha permesso il continuo adeguamento del progetto a un mondo informatico in continua evoluzione e a richieste sempre più complesse da parte dei clienti. + +L'insieme di cambiamenti introdotti nel periodo compreso tra giugno 2016 e giugno 2017 hanno infine portato alla generazione di un ramo di sviluppo parallelo (_branch_) per la versione 2.3, destinata a cambiare e migliorare in modo fondamentale numerose sezioni _front-end_ e _back-end_ del progetto. + +## Membri + +[[members]] diff --git a/docs/Stampe.md b/docs/Stampe.md new file mode 100644 index 000000000..c3999820b --- /dev/null +++ b/docs/Stampe.md @@ -0,0 +1,37 @@ +--- +currentMenu: stampe +--- + +# Stampe + + + +- [Struttura](#struttura) + - [pdfgen.php](#pdfgenphp) + - [pdfgen_variables.php (INCLUDE)](#pdfgen_variablesphp-include) + - [Struttura interna](#struttura-interna) + + + +### Struttura + +La cartella _templates_ contiene tutti i template per la creazione dei PDF, raggruppati in base al nome del modulo. QUesti vengono utilizzati da `pdfgen.php` e da `pdfgen_variables.php` per la generazione vera e propria del PDF tramite il framework [HTML2PDF](https://github.com/spipu/html2pdf). + +#### pdfgen.php + +Il file `pdfgen.php` si occupa della formattazione dei contenuti dei template per la visualizzazione vera e propria del PDF, inizializzando l'oggetto relativo ed eseguendone l'output. + +#### pdfgen_variables.php (INCLUDE) + +Il file `pdfgen_variables.php` si occupa della sostituzione delle variabili comuni a tutti i template, e viene richiamata dal file `pdfgen.MODULO.php` descritto di seguito. + +#### Struttura interna + +La cartella _templates_ contiene tutti i template per la creazione dei PDF relativi al modulo specifico, in una struttura interna simile alla seguente (modulo **Contratti** utilizzato come esempio). + + . + └── contratti +    ├── contratto_body.html (OPEN) - Struttura di base del PDF +    ├── contratto.html (OPEN) - Contenitore personalizzato della struttura del PDF +    ├── logo_azienda.jpg (HTML) - Logo dell'azienda specifico per il PDF +    └── pdfgen.contratti.php (INCLUDE) - Individuazione delle informazioni da visualizzare e generazione della loro struttura diff --git a/docs/Widget.md b/docs/Widget.md new file mode 100644 index 000000000..e17526a0f --- /dev/null +++ b/docs/Widget.md @@ -0,0 +1,10 @@ +--- +currentMenu: widget +--- + +# Widget + + + + + diff --git a/editor.php b/editor.php new file mode 100644 index 000000000..5fdb8c851 --- /dev/null +++ b/editor.php @@ -0,0 +1,212 @@ +query('DELETE FROM zz_semaphores WHERE id_utente='.prepare($_SESSION['idutente']).' AND posizione='.prepare($id_module.', '.$id_record)); + $dbo->query('INSERT INTO zz_semaphores (id_utente, posizione) VALUES ('.prepare($_SESSION['idutente']).', '.prepare($id_module.', '.$id_record).')'); + + echo ' +
+
+

'._('Attenzione!').'

+
+
+

'._('I seguenti utenti stanno visualizzando questa pagina').':

+
    +
+

'._('Prestare attenzione prima di effettuare modifiche, poichè queste potrebbero essere perse a causa di multipli salvataggi contemporanei').'.

+
+
'; +} + +if (empty($records)) { + echo ' +

'._('Record non trovato').'.

'; +} else { + /* + * Lettura eventuali plugins modulo da inserire come tab + */ + echo ' + '; +} + +$backto = filter('backto'); +// Scelta del redirect dopo un submit +if (!empty($backto)) { + $hash = filter('hash'); + if ($backto == 'record-edit') { + redirect(ROOTDIR.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.$hash); + exit(); + } elseif ($backto == 'record-list') { + redirect(ROOTDIR.'/controller.php?id_module='.$id_module.$hash); + exit(); + } +} + +echo ' +
+ '._('Indietro').''; + +/* +* Widget laterali +*/ +echo ' + +
'; +echo Widgets::addModuleWidgets($id_module, 'editor_right'); +echo ' +
'; + +?> + + REVISION'); + + del([ + './vendor/tecnickcom/tcpdf/fonts/*', + '!./vendor/tecnickcom/tcpdf/fonts/*helvetica*', + ]); + + var output = fs.createWriteStream('./release.zip'); + var archive = archiver('zip'); + + output.on('close', function() { + console.log('done!'); + }); + + archive.on('error', function(err) { + throw err; + }); + + archive.pipe(output); + + archive.glob('**/*', { + dot: true, + ignore: [ + '.svn/**', + 'node_modules/**', + 'backup/**', + 'files/**', + 'config.inc.php', + '*.lock', + '*.phar', + '**/*.log', + '**/*.zip', + '**/*.bak', + '**/~*', + ] + }); + + archive.file('backup/.htaccess'); + archive.file('files/.htaccess'); + archive.file('files/my_impianti/componente.ini'); + + archive.finalize(); +}); + +// Pulizia +gulp.task('clean', function () { + return del([config.production]); +}); + +// Operazioni di default per la generazione degli assets +gulp.task('bower', ['clean'], function () { + gulp.start('JS'); + gulp.start('CSS'); + gulp.start('images'); + gulp.start('fonts'); + gulp.start('other'); +}); + +// Operazioni particolari per la generazione degli assets +gulp.task('other', ['clean'], function () { + gulp.start('ckeditor'); + gulp.start('colorpicker'); + gulp.start('i18n'); + gulp.start('php-debugbar'); +}); + +gulp.task('default', ['clean', 'bower']); diff --git a/include/.htaccess b/include/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/include/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/include/bottom.php b/include/bottom.php new file mode 100644 index 000000000..1456d9e2c --- /dev/null +++ b/include/bottom.php @@ -0,0 +1,54 @@ + + + + +
+ + '._('OpenSTAManager').' +
+ + + + + + '; +} +echo ' + '; + +if (Auth::check()) { + if (!empty($_SESSION['keep_alive'])) { + echo ' + '; + } + + if (get_var('CSS Personalizzato') != '') { + echo ' + '; + } + + if (!empty($debugbarRenderer)) { + echo $debugbarRenderer->render(); + } +} + +echo ' + + +'; + +unset($_SESSION['infos']); +unset($_SESSION['errors']); +unset($_SESSION['warnings']); diff --git a/include/configuration.php b/include/configuration.php new file mode 100644 index 000000000..a5575d016 --- /dev/null +++ b/include/configuration.php @@ -0,0 +1,450 @@ +isConnected()) { + return; +} + +$pageTitle = _('Configurazione'); + +if (file_exists($docroot.'/include/custom/top.php')) { + include_once $docroot.'/include/custom/top.php'; +} else { + include_once $docroot.'/include/top.php'; +} + +// Controllo sull'esistenza di nuovi parametri di configurazione +if (post('db_host') !== null) { + $db_host = post('db_host'); + $db_name = post('db_name'); + $db_username = post('db_username'); + $db_password = post('db_password'); + $_SESSION['osm_password'] = post('osm_password'); + $_SESSION['osm_email'] = post('osm_email'); + + $valid_config = isset($db_host) && isset($db_name) && isset($db_username) && isset($db_password); + + // Generazione di una nuova connessione al database + $dbo = Database::getConnection(true); + + if ($dbo->isConnected()) { + // Impostazioni di configurazione strettamente necessarie al funzionamento del progetto + $backup_config = ' $db_host, + '|username|' => $db_username, + '|password|' => $db_password, + '|database|' => $db_name, + ]; + $new_config = str_replace(array_keys($values), $values, $new_config); + + // Controlla che la scrittura del file di configurazione sia andata a buon fine + $creation = file_put_contents('config.inc.php', $new_config); + if (!$creation) { + echo ' +
+
+

'._('Permessi di scrittura mancanti').'

+
+
+

'.str_replace('_FILE_', 'config.inc.php', _('Sembra che non ci siano i permessi di scrittura sul file _FILE_')).'

+
+
+ + + ; + +
+ '._('Torna indietro').' + +
+
+
+ +
+

'.str_replace('_FILE_', 'config.inc.php', _('Inserire il seguente testo nel file _FILE_')).'

+
'.htmlentities($new_config).'
+
+
+
+
'; + } + // Continua con l'esecuzione delle operazioni previste + else { + redirect(ROOTDIR.'/index.php'); + exit(); + } + } +} + +// Controlla che i parametri di configurazione permettano l'accesso al database +if ((file_exists('config.inc.php') || $valid_config) && !$dbo->isConnected()) { + echo ' +
+
+

'._('Impossibile connettersi al database').'

+
+
+

'._("Si è verificato un'errore durante la connessione al database").'.

+

'._('Controllare di aver inserito correttamente i dati di accesso, e che il database atto ad ospitare i dati del gestionale sia esistente').'.

+ '._('Riprova').' +
+
'; +} + +// Visualizzazione dell'interfaccia di impostazione iniziale, nel caso il file di configurazione sia mancante oppure i paramentri non siano sufficienti +if (empty($creation) && (!file_exists('config.inc.php') || !$valid_config)) { + if (file_exists('config.inc.php')) { + echo ' +
+
+

'._('Parametri non sufficienti!').'

+
+
+

'._("L'avvio del software è fallito a causa dell'assenza di alcuni paramentri nella configurazione di base").'.

+

'.str_replace('_CONFIG_', 'config.inc.php', _("Si prega di controllare che il file _CONFIG_ contenga tutti i dati inseriti durante la configurazione iniziale (con l'eccezione di password e indirizzo email amministrativi)")).'.

+

'._("Nel caso il problema persista, rivolgersi all'assistenza ufficiale").'.

+ '._('Riprova').' +
+
'; + } + + // Controlli per essere sicuro che l'utente abbia letto la licenza + echo ' + '; + + echo ' +
+
+ '._('OSM Logo').' +

'._('OpenSTAManager').'

+
+ +
'; + + // REQUISITI PER IL CORRETTO FUNZIONAMENTO + echo ' + + +
+ +
+

'._('Un benvenuto da OpenSTAManager!').'

+

'._("Prima di procedere alla configurazione e all'installazione del software, sono necessari alcuni accorgimenti per garantire il corretto funzionamento del gestionale").'.

+
'; + + // Estensioni di PHP + echo ' + +
+
+

'.str_replace('_FILE_', 'php.ini', _('Le seguenti estensioni PHP devono essere abilitate dal file di configurazione _FILE_')).':

+
'; + $extensions = [ + 'zip' => _("Necessario per l'utilizzo delle funzioni di aggiornamento automatico e backup, oltre che per eventuali moduli aggiuntivi"), + 'pdo_mysql' => _('Necessario per la connessione al database'), + 'openssl' => _('Utile per la generazione di chiavi complesse (non obbligatorio)'), + ]; + foreach ($extensions as $key => $value) { + $check = extension_loaded($key); + echo ' +
+

+ '.$key; + if ($check) { + echo ' + + + '; + } else { + echo ' + + + '; + } + echo ' +

+

'.$value.'

+
'; + } + echo ' +
+ +
+
'; + + // Impostazione di valore per PHP + echo ' + +
+

'.str_replace('_FILE_', 'php.ini', _('Le seguenti impostazioni PHP devono essere modificate nel file di configurazione _FILE_')).':

+
'; + $values = [ + 'display_errors' => true, + 'upload_max_filesize' => '>16M', + 'post_max_size' => '>16M', + ]; + foreach ($values as $key => $value) { + $ini = str_replace(['k', 'M'], ['000', '000000'], ini_get($key)); + $real = str_replace(['k', 'M'], ['000', '000000'], $value); + + if (starts_with($real, '>')) { + $check = $ini >= substr($real, 1); + } elseif (starts_with($real, '<')) { + $check = $ini <= substr($real, 1); + } else { + $check = ($real == $ini); + } + + if (is_bool($value)) { + $value = !empty($value) ? 'On' : 'Off'; + } else { + $value = str_replace(['>', '<'], '', $value); + } + + echo ' +
+

+ '.$key; + if ($check) { + echo ' + + + '; + } else { + echo ' + + + '; + } + echo ' +

+

'._('Valore consigliato').': '.$value.'

+
'; + } + echo ' +
+ +
+
+
'; + + // Percorsi necessari + echo ' + +
+
+

'._('Le seguenti cartelle devono risultare scrivibili da parte del gestionale').':

+
'; + $dirs = [ + 'backup' => _('Necessario per il salvataggio dei backup'), + 'files' => _('Necessario per il salvataggio di file inseriti dagli utenti'), + 'logs' => _('Necessario per la gestione dei file di log'), + ]; + foreach ($dirs as $key => $value) { + $check = is_writable($docroot.DIRECTORY_SEPARATOR.$key); + echo ' +
+

+ '.$key; + if ($check) { + echo ' + + + '; + } else { + echo ' + + + '; + } + echo ' +

+

'.$value.'

+
'; + } + echo ' +
+ +
+
+
+
'; + + // LICENZA + echo ' +
+

'.str_replace('_LICENSE_', 'GPL 3.0', _('OpenSTAManager è tutelato dalla licenza _LICENSE_!')).'

+ +
+
+ '._('Accetti la licenza GPLv3 di OpenSTAManager?').'* +
+ +
+ + +
+
+
+ +
+ [ '._('Versioni tradotte').' ]

+
'; + + $host = !empty($db_host) ? $db_host : ''; + $username = !empty($db_username) ? $db_username : ''; + $password = !empty($db_password) ? $db_password : ''; + $name = !empty($db_name) ? $db_name : ''; + $osm_password = !empty($_SESSION['osm_password']) ? $_SESSION['osm_password'] : ''; + $osm_email = !empty($_SESSION['osm_email']) ? $_SESSION['osm_email'] : ''; + + // PARAMETRI + echo ' +
+ '._('Aiuto').' + +

'._('Non hai ancora configurato OpenSTAManager').'.

+

'.str_replace('_CONFIG_', 'config.inc.php', _('Configura correttamente il software con i seguenti parametri (modificabili successivamente dal file _CONFIG_)')).'

'; + + // Form dei parametri + echo ' +
+
'; + + // db_host + echo ' +
+ {[ "type": "text", "label": "'._('Host del database').'", "name": "db_host", "placeholder": "'._("Indirizzo dell'host del database").'", "value": "'.$host.'", "help": "'._('Esempio').': localhost", "show-help": 1, "required": 1 ]} +
+
+ +
'; + + // db_username + echo ' +
+ {[ "type": "text", "label": "'._("Username dell'utente MySQL").'", "name": "db_username", "placeholder": "'._("Username dell'utente MySQL").'", "value": "'.$username.'", "help": "'._('Esempio').': root", "show-help": 1, "required": 1 ]} +
'; + + // db_password + echo ' +
+ {[ "type": "password", "label": "'._("Password dell'utente MySQL").'", "name": "db_password", "placeholder": "'._("Password dell'utente MySQL").'", "value": "'.$password.'", "help": "'._('Esempio').': mysql", "show-help": 1 ]} +
'; + + // db_name + echo ' +
+ {[ "type": "text", "label": "'._('Nome del database').'", "name": "db_name", "placeholder": "'._('Nome del database').'", "value": "'.$name.'", "help": "'._('Esempio').': openstamanager", "show-help": 1, "required": 1 ]} +
+
+ +
'; + + // Password utente admin + echo ' +
+ {[ "type": "password", "label": "'._("Password dell'amministratore").'", "name": "osm_password", "placeholder": "'._('Scegli la password di amministratore').'", "value": "'.$osm_password.'", "help": "'._('Valore di default').': admin", "show-help": 1 ]} +
'; + + // Email utente admin + echo ' +
+ {[ "type": "email", "label": "'._("Email dell'amministratore").'", "name": "osm_email", "placeholder": "'._("Digita l'indirizzo email dell'amministratore").'", "value": "'.$osm_email.'" ]} +
+
'; + + echo ' + '; + + echo ' + +
+
+ *'._('Campi obbligatori').' +
+
+ +
+
+ + +
+
+ +
+
+
'; +} + +if (file_exists($docroot.'/include/custom/bottom.php')) { + include_once $docroot.'/include/custom/bottom.php'; +} else { + include_once $docroot.'/include/bottom.php'; +} + +exit(); diff --git a/include/manager.php b/include/manager.php new file mode 100644 index 000000000..dcab65160 --- /dev/null +++ b/include/manager.php @@ -0,0 +1,193 @@ + + '.$info['name']; + + if (file_exists($docroot.'/plugins/'.$info['directory'].'/add.php')) { + echo ' + '; + } + + echo ' + '; + + $total = Plugins::getQuery($id_plugin); + + $directory = '/plugins/'.$info['directory']; +} else { + $info = Modules::getModule($id_module); + + $total = Modules::getQuery($id_module); + + $directory = '/modules/'.$info['directory']; +} + +$module_options = (!empty($info['options2'])) ? $info['options2'] : $info['options']; + +// Caricamento file aggiuntivo su elenco record +if (file_exists($docroot.$directory.'/custom/controller_before.php')) { + include $docroot.$directory.'/custom/controller_before.php'; +} elseif (file_exists($docroot.$directory.'/controller_before.php')) { + include $docroot.$directory.'/controller_before.php'; +} + +/* + * Datatables con record + */ +if (!empty($module_options) && $module_options != 'menu' && $module_options != 'custom') { + $table_id = 'main_'.rand(0, 99); + echo ' + + + + '; + + foreach ($total['fields'] as $key => $field) { + $attr_td = ''; + $name = trim($field); + + // Check per tipologie di campi particolari + if (preg_match('/^color_/', $field)) { + $attr_td .= " width='140'"; + $field = str_replace('color_', '', $field); + } + + // Data (larghezza fissa) + elseif (preg_match('/^Data/', $field)) { + $attr_td .= " width='100'"; + } + + // Icona di stampa + elseif (trim($field) == '_print_') { + $attr_td .= " width='30'"; + $field = str_replace('_print_', '', $field); + } elseif (preg_match('/^icon_/', $field)) { + $attr_td .= " width='30'"; + $name = str_replace('icon_', 'icon_title_', $name); + $field = str_replace('icon_', '', $field); + } + + echo ' + '.$field.''; + } + + echo ' + + + + + + + + '; + foreach ($total['fields'] as $key => $field) { + echo ' + '; + } + echo ' + + +
'; + + $bulk = null; + if (file_exists($docroot.$directory.'/custom/bulk.php')) { + $bulk = include $docroot.$directory.'/custom/bulk.php'; + } elseif (file_exists($docroot.$directory.'/bulk.php')) { + $bulk = include $docroot.$directory.'/bulk.php'; + } + $bulk = (array) $bulk; + + $tr = [ + 'delete' => _('Elimina selezione'), + ]; + + echo ' +
+
+
+ + +
+
+ + + +
+
+ + + +
+
+
'; +} + +/* + * Inclusione modulo personalizzato + */ +elseif ($module_options == 'custom') { + // Inclusione elementi fondamentali del modulo + include $docroot.'/actions.php'; + + // Lettura template modulo (verifico se ci sono template personalizzati, altrimenti uso quello base) + if (file_exists($docroot.$directory.'/custom/edit.php')) { + include $docroot.$directory.'/custom/edit.php'; + } elseif (file_exists($docroot.$directory.'/custom/edit.html')) { + include $docroot.$directory.'/custom/edit.html'; + } elseif (file_exists($docroot.$directory.'/edit.php')) { + include $docroot.$directory.'/edit.php'; + } elseif (file_exists($docroot.$directory.'/edit.html')) { + include $docroot.$directory.'/edit.html'; + } +} + +// Caricamento file aggiuntivo su elenco record +if (file_exists($docroot.$directory.'/custom/controller_after.php')) { + include $docroot.$directory.'/custom/controller_after.php'; +} elseif (file_exists($docroot.$directory.'/controller_after.php')) { + include $docroot.$directory.'/controller_after.php'; +} diff --git a/include/top.php b/include/top.php new file mode 100644 index 000000000..5ec71c3df --- /dev/null +++ b/include/top.php @@ -0,0 +1,275 @@ +getJavascriptRenderer(); + $debugbarRenderer->setIncludeVendors(false); + $debugbarRenderer->setBaseUrl($assets.'/php-debugbar'); +} + +echo ' + + + + + '.$pageTitle.' - '._('OpenSTAManager').' + + + + '; + +foreach ($css_modules as $style) { + $style = (is_array($style)) ? $style : ['href' => $style, 'media' => 'all']; + + echo ' +'; +} + +if (Auth::check()) { + echo ' + '; +} + +foreach ($jscript_modules as $js) { + echo ' + '; +} + +// Impostazioni di default per gli alert +echo ' + '; + +if (!empty($debugbarRenderer) && Auth::check()) { + echo $debugbarRenderer->renderHead(); +} + +echo ' + + + + +
'; + +if (Auth::check()) { + $calendar = ($_SESSION['period_start'] != date('Y').'-01-01' || $_SESSION['period_end'] != date('Y').'-12-31') ? 'red' : 'white'; + + echo ' + +
+
+ +
+
+ + + + +
+ + + +
+ + + + +
'; + } +} + +echo ' + + +
+
+ +
+
+'; + +echo ' + '; diff --git a/modules/ddt/creafattura.php b/modules/ddt/creafattura.php new file mode 100644 index 000000000..689c352ea --- /dev/null +++ b/modules/ddt/creafattura.php @@ -0,0 +1,254 @@ +fetchArray($q); +$numero = $rs[0]['numero']; +$idanagrafica = $rs[0]['idanagrafica']; +$idpagamento = $rs[0]['idpagamento']; +$idconto = $rs[0]['idconto']; + +/* +Form di inserimento riga documento +*/ + +echo ' +

'.str_replace('_NUM_', $numero, _('Ddt numero _NUM_')).'

'; + +//Selezione articoli del ddt da portare nella fattura, escludo quelli completamente evasi +$query = 'SELECT *, (qta - qta_evasa) AS qta_rimanente FROM dt_ddt INNER JOIN dt_righe_ddt ON dt_ddt.id=dt_righe_ddt.idddt WHERE dt_ddt.id='.prepare($idddt).' HAVING qta_rimanente > 0'; +$rs = $dbo->fetchArray($query); + +if (!empty($rs)) { + echo ' +

'._('Seleziona le righe che vuoi inserire nella fattura e la relativa quantità').'.



'; + + echo ' +'; +} else { + echo ' + '._('Non ci sono articoli da evadere in questo ddt').'...'; +} + +echo ' + '; + +?> + + diff --git a/modules/ddt/edit.php b/modules/ddt/edit.php new file mode 100644 index 000000000..5e3176f00 --- /dev/null +++ b/modules/ddt/edit.php @@ -0,0 +1,196 @@ + +
+ + + + + +
+
+

+
+ +
+
+ +
+
+ +
+ + {[ "type": "span", "label": "'. _('Numero ddt').'", "class": "text-center", "value": "$numero$" ]} +
'; +} +?> + +
+ {[ "type": "text", "label": "", "name": "numero_esterno", "class": "text-center", "value": "$numero_esterno$" ]} +
+ +
+ {[ "type": "date", "label": "", "maxlength": 10, "name": "data", "required": 1, "value": "$data$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idstatoddt", "required": 1, "values": "query=SELECT * FROM dt_statiddt", "value": "$idstatoddt$" ]} +
+
+ +
+
+ + {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "value": "$idanagrafica$", "ajax-source": "clienti" ]} + + {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "value": "$idanagrafica$", "ajax-source": "fornitori" ]} + +
+ +
+ {[ "type": "select", "label": "", "name": "idsede", "value": "$idsede$", "ajax-source": "sedi" ]} +
+
+ +
+ +
+
+ {[ "type": "select", "label": "", "name": "idaspettobeni", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_aspettobeni ORDER BY descrizione ASC", "value": "$idaspettobeni$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idcausalet", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_causalet ORDER BY descrizione ASC", "value": "$idcausalet$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idporto", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_porto ORDER BY descrizione ASC", "value": "$idporto$" ]} +
+ +
+ {[ "type": "text", "label": "o colli'); ?>", "name": "n_colli", "value": "$n_colli$" ]} +
+
+ +
+
+ {[ "type": "select", "label": "", "name": "idpagamento", "values": "query=SELECT id, descrizione FROM co_pagamenti GROUP BY descrizione ORDER BY descrizione ASC", "value": "$idpagamento$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idspedizione", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_spedizione ORDER BY descrizione ASC", "value": "$idspedizione$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idvettore", "values": "query=SELECT DISTINCT an_anagrafiche.idanagrafica AS id, an_anagrafiche.ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE an_tipianagrafiche_anagrafiche.idtipoanagrafica=(SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Vettore') ORDER BY descrizione ASC", "value": "$idvettore$" ]} +
+
+ +
+
+ {[ "type": "number", "label": "", "name": "sconto_generico", "value": "$sconto_globale$", "icon-after": "choice|untprc|$tipo_sconto_globale$" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "", "name": "note", "value": "$note$" ]} +
+
+ +
+ +
+
+ +
+ + + +
+
+

+
+ +
+
+ + + + + + + + +
+ +
+ + + + ... + + + + +
+ +
+
+ +
+
+ + + +
+
+
+
+ + + + + + diff --git a/modules/ddt/init.php b/modules/ddt/init.php new file mode 100644 index 000000000..3a6905fa9 --- /dev/null +++ b/modules/ddt/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT *, dt_ddt.note, dt_ddt.idpagamento, dt_ddt.id AS idddt, dt_statiddt.descrizione AS `stato`, dt_tipiddt.descrizione AS `descrizione_tipodoc` FROM ((dt_ddt LEFT OUTER JOIN dt_statiddt ON dt_ddt.idstatoddt=dt_statiddt.id) INNER JOIN an_anagrafiche ON dt_ddt.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt=dt_tipiddt.id WHERE dt_ddt.id='.prepare($id_record)); +} diff --git a/modules/ddt/modutil.php b/modules/ddt/modutil.php new file mode 100644 index 000000000..882c9ae20 --- /dev/null +++ b/modules/ddt/modutil.php @@ -0,0 +1,337 @@ +fetchArray($query); + + return intval($rs[0]['max_numeroddt']) + 1; +} + +/** + * Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni. + */ +function get_new_numerosecondarioddt($data) +{ + global $dbo; + global $dir; + + $query = "SELECT numero_esterno FROM dt_ddt WHERE DATE_FORMAT( data, '%Y' ) = '".date('Y', strtotime($data))."' AND idtipoddt IN(SELECT id FROM dt_tipiddt WHERE dir='".$dir."') ORDER BY CAST(numero_esterno AS UNSIGNED) DESC LIMIT 0,1"; + $rs = $dbo->fetchArray($query); + $numero_secondario = $rs[0]['numero_esterno']; + + // Calcolo il numero secondario se stabilito dalle impostazioni e se documento di vendita + $formato_numero_secondario = get_var('Formato numero secondario ddt'); + + if ($numero_secondario == '') { + $numero_secondario = $formato_numero_secondario; + } + + if ($formato_numero_secondario != '' && $dir == 'entrata') { + $numero_esterno = get_next_code($numero_secondario, 1, $formato_numero_secondario); + } else { + $numero_esterno = ''; + } + + return $numero_esterno; +} + +/** + * Questa funzione rimuove un articolo dal ddt data e lo riporta in magazzino + * $idarticolo integer codice dell'articolo da scollegare dal ddt + * $idddt integer codice del ddt da cui scollegare l'articolo. + */ +function rimuovi_articolo_daddt($idarticolo, $idddt, $idrigaddt) +{ + global $dbo; + global $dir; + + // Leggo la quantità di questo articolo in ddt + $query = 'SELECT idgruppo, qta, subtotale FROM dt_righe_ddt WHERE id='.prepare($idrigaddt); + $rs = $dbo->fetchArray($query); + $qta = floatval($rs[0]['qta']); + $subtotale = $rs[0]['subtotale']; + + $idgruppo = $rs[0]['idgruppo']; + + // Leggo l'idordine + $query = 'SELECT idordine FROM dt_righe_ddt WHERE id='.prepare($idrigaddt); + $rs = $dbo->fetchArray($query); + $idordine = $rs[0]['idordine']; + + if ($dir == 'uscita') { + $non_rimovibili = $dbo->fetchArray("SELECT COUNT(*) AS non_rimovibili FROM dt_righe_ddt WHERE serial IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idgruppo=".prepare($idgruppo).' AND idddt='.prepare($idddt))[0]['non_rimovibili']; + if ($non_rimovibili != 0) { + return false; + } + } + + // Ddt di vendita + if ($dir == 'entrata') { + add_movimento_magazzino($idarticolo, $qta, ['idddt' => $idddt]); + + // Se il ddt è stato generato da un ordine tolgo questa quantità dalla quantità evasa + if (!empty($idordine)) { + $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$qta.' WHERE idarticolo='.prepare($idarticolo).' AND idordine='.prepare($idordine)); + } + } + + // Ddt di acquisto + else { + add_movimento_magazzino($idarticolo, -$qta, ['idddt' => $idddt]); + + // Se il ddt è stato generato da un ordine tolgo questa quantità dalla quantità evasa + if (!empty($idordine)) { + $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$qta.' WHERE idarticolo='.prepare($idarticolo).' AND idordine='.prepare($idordine)); + } + } + + $dbo->query($query); + + // Elimino la riga dal ddt + $dbo->query('DELETE FROM `dt_righe_ddt` WHERE idgruppo='.prepare($idgruppo)); + + return true; +} + +/** + * Calcolo imponibile ddt (totale_righe - sconto). + */ +function get_imponibile_ddt($idddt) +{ + global $dbo; + + $query = "SELECT SUM(subtotale-sconto) AS imponibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='".$idddt."'"; + $rs = $dbo->fetchArray($query); + + return $rs[0]['imponibile']; +} + +/** + * Calcolo totale ddt (imponibile + iva). + */ +function get_totale_ddt($idddt) +{ + global $dbo; + + // Sommo l'iva di ogni riga al totale + $query = "SELECT SUM(iva) AS iva FROM dt_righe_ddt GROUP BY idddt HAVING idddt='".$idddt."'"; + $rs = $dbo->fetchArray($query); + + // Aggiungo la rivalsa inps se c'è + $query2 = "SELECT rivalsainps FROM dt_ddt WHERE id='".$idddt."'"; + $rs2 = $dbo->fetchArray($query2); + + return get_imponibile_ddt($idddt) + $rs[0]['iva'] + $rs2[0]['rivalsainps']; +} + +/** + * Calcolo netto a pagare ddt (totale - ritenute - bolli). + */ +function get_netto_ddt($idddt) +{ + global $dbo; + + $query = "SELECT ritenutaacconto,bollo FROM dt_ddt WHERE id='".$idddt."'"; + $rs = $dbo->fetchArray($query); + + return get_totale_ddt($idddt) - $rs[0]['ritenutaacconto'] + $rs[0]['bollo']; +} + +/** + * Calcolo iva detraibile ddt. + */ +function get_ivadetraibile_ddt($idddt) +{ + global $dbo; + + $query = "SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='".$idddt."'"; + $rs = $dbo->fetchArray($query); + + return $rs[0]['iva_detraibile']; +} + +/** + * Calcolo iva indetraibile ddt. + */ +function get_ivaindetraibile_ddt($idddt) +{ + global $dbo; + + $query = "SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM dt_righe_ddt GROUP BY idddt HAVING idddt='".$idddt."'"; + $rs = $dbo->fetchArray($query); + + return $rs[0]['iva_indetraibile']; +} + +/** + * Ricalcola i costi aggiuntivi in ddt (rivalsa inps, ritenuta d'acconto, marca da bollo) + * Deve essere eseguito ogni volta che si aggiunge o toglie una riga + * $idddt int ID del ddt + * $idrivalsainps int ID della rivalsa inps da applicare. Se omesso viene utilizzata quella impostata di default + * $idritenutaacconto int ID della ritenuta d'acconto da applicare. Se omesso viene utilizzata quella impostata di default + * $bolli float Costi aggiuntivi delle marche da bollo. Se omesso verrà usata la cifra predefinita. + */ +function ricalcola_costiagg_ddt($idddt, $idrivalsainps = '', $idritenutaacconto = '', $bolli = '') +{ + global $dbo; + global $dir; + + // Se ci sono righe nel ddt faccio i conteggi, altrimenti azzero gli sconti e le spese aggiuntive (inps, ritenuta, marche da bollo) + $query = "SELECT COUNT(id) AS righe FROM dt_righe_ddt WHERE idddt='$idddt'"; + $rs = $dbo->fetchArray($query); + if ($rs[0]['righe'] > 0) { + $totale_imponibile = get_imponibile_ddt($idddt); + $totale_ddt = get_totale_ddt($idddt); + + // Leggo gli id dei costi aggiuntivi + if ($dir == 'uscita') { + $query2 = "SELECT idrivalsainps, idritenutaacconto, bollo FROM dt_ddt WHERE id='$idddt'"; + $rs2 = $dbo->fetchArray($query2); + $idrivalsainps = $rs2[0]['idrivalsainps']; + $idritenutaacconto = $rs2[0]['idritenutaacconto']; + $bollo = $rs2[0]['bollo']; + } + + // Leggo la rivalsa inps se c'è (per i ddt di vendita lo leggo dalle impostazioni) + if ($dir == 'entrata') { + if (!empty($idrivalsainps)) { + $idrivalsainps = get_var('Percentuale rivalsa INPS'); + } + } + + $query = "SELECT percentuale FROM co_rivalsainps WHERE id='".$idrivalsainps."'"; + $rs = $dbo->fetchArray($query); + $rivalsainps = $totale_imponibile / 100 * $rs[0]['percentuale']; + + // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps + $qi = "SELECT percentuale FROM co_iva WHERE id='".get_var('Iva predefinita')."'"; + $rsi = $dbo->fetchArray($qi); + $iva_rivalsainps = $rivalsainps / 100 * $rsi[0]['percentuale']; + + // Aggiorno la rivalsa inps + $dbo->query("UPDATE dt_ddt SET rivalsainps='$rivalsainps', iva_rivalsainps='$iva_rivalsainps' WHERE id='$idddt'"); + + $totale_ddt = get_totale_ddt($idddt); + + // Leggo la ritenuta d'acconto se c'è (per i ddt di vendita lo leggo dalle impostazioni) + if (!empty($idritenutaacconto)) { + if ($dir == 'entrata') { + $idritenutaacconto = get_var("Percentuale ritenuta d'acconto"); + } + } + + $query = "SELECT percentuale FROM co_ritenutaacconto WHERE id='".$idritenutaacconto."'"; + $rs = $dbo->fetchArray($query); + $ritenutaacconto = $totale_ddt / 100 * $rs[0]['percentuale']; + $netto_a_pagare = $totale_ddt - $ritenutaacconto; + + // Leggo la marca da bollo se c'è e se il netto a pagare supera la soglia + $bolli = str_replace(',', '.', $bolli); + $bolli = floatval($bolli); + if ($dir == 'uscita') { + if ($bolli != 0.00) { + $bolli = str_replace(',', '.', $bolli); + if (abs($bolli) > 0 && abs($netto_a_pagare > get_var("Soglia minima per l'applicazione della marca da bollo"))) { + $marca_da_bollo = str_replace(',', '.', $bolli); + } else { + $marca_da_bollo = 0.00; + } + } + } else { + $bolli = str_replace(',', '.', get_var('Importo marca da bollo')); + if (abs($bolli) > 0 && abs($netto_a_pagare) > abs(get_var("Soglia minima per l'applicazione della marca da bollo"))) { + $marca_da_bollo = str_replace(',', '.', $bolli); + } else { + $marca_da_bollo = 0.00; + } + + // Se l'importo è negativo può essere una nota di accredito, quindi cambio segno alla marca da bollo + if ($netto_a_pagare < 0) { + $marca_da_bollo *= -1; + } + } + + $dbo->query("UPDATE dt_ddt SET ritenutaacconto='$ritenutaacconto', bollo='$marca_da_bollo' WHERE id='$idddt'"); + } else { + $dbo->query("UPDATE dt_ddt SET ritenutaacconto='0', bollo='0', rivalsainps='0', iva_rivalsainps='0' WHERE id='$idddt'"); + } +} + +/** + * Questa funzione aggiunge un articolo nel ddt + * $iddocumento integer id dell'ordine + * $idarticolo integer id dell'articolo da inserire nell'ordine + * $idiva integer id del codice iva associato all'articolo + * $qta float quantità dell'articolo nell'ordine + * $prezzo float prezzo totale degli articoli (prezzounitario*qtà). + */ +function add_articolo_inddt($idddt, $idarticolo, $descrizione, $idiva, $qta, $prezzo, $sconto = 0, $sconto_unitario = 0, $tipo_sconto = 'UNT', $lotto = '', $serial = '', $altro = '', $idgruppo = 0) +{ + global $dbo; + global $dir; + + // Lettura unità di misura dell'articolo + // $query = "SELECT valore FROM mg_unitamisura WHERE id=(SELECT idum FROM mg_articoli WHERE id='".$idarticolo."')"; + // $rs = $dbo->fetchArray($query); + // $um = $rs[0]['valore']; + + // Lettura unità di misura dell'articolo + if (empty($idum)) { + $query = 'SELECT um FROM mg_articoli WHERE id='.prepare($idarticolo); + $rs = $dbo->fetchArray($query); + $um = $rs[0]['valore']; + } else { + $um = $idum; + } + + // Lettura iva dell'articolo + $rs2 = $dbo->fetchArray('SELECT percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva)); + $iva = ($prezzo - $sconto) / 100 * $rs2[0]['percentuale']; + $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; + + if ($qta > 0) { + $rsart = $dbo->fetchArray('SELECT abilita_serial FROM mg_articoli WHERE id='.prepare($idarticolo)); + $qta_in = !empty($rsart[0]['abilita_serial']) ? $qta : 1; + + for ($i = 0; $i < $qta_in; ++$i) { + /* + $iva = $iva / $qta_in; + $qta = $qta / $qta_in; + $ubtotale = $subtotale / $qta_in; + $sconto = $sconto / $qta_in; + + $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; + */ + + $dbo->query('INSERT INTO dt_righe_ddt(idddt, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, qta, abilita_serial, serial, um, idgruppo, `order`) VALUES ('.prepare($idddt).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($qta).', '.prepare($rsart[0]['abilita_serial']).', '.prepare($serial).', '.prepare($um).', '.prepare($idgruppo).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM dt_righe_ddt AS t WHERE idddt='.prepare($idddt).'))'); + } + + $idriga = $dbo->lastInsertedID(); + + /* + Ddt cliente + */ + if ($dir == 'entrata') { + // Decremento la quantità dal magazzino centrale + add_movimento_magazzino($idarticolo, -$qta, ['idddt' => $idddt]); + } + /* + Ddt fornitore + */ + elseif ($dir == 'uscita') { + // Decremento la quantità dal magazzino centrale + add_movimento_magazzino($idarticolo, $qta, ['idddt' => $idddt]); + } + } + + return $idriga; +} diff --git a/modules/ddt/plugins/ddt.anagrafiche.php b/modules/ddt/plugins/ddt.anagrafiche.php new file mode 100644 index 000000000..2667350f4 --- /dev/null +++ b/modules/ddt/plugins/ddt.anagrafiche.php @@ -0,0 +1,99 @@ +fetchArray('SELECT *, dt_ddt.note, dt_ddt.idpagamento, dt_ddt.id AS idddt, dt_statiddt.descrizione AS `stato`, dt_tipiddt.descrizione AS `descrizione_tipodoc` FROM ((dt_ddt LEFT OUTER JOIN dt_statiddt ON dt_ddt.idstatoddt=dt_statiddt.id) INNER JOIN an_anagrafiche ON dt_ddt.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN dt_tipiddt ON dt_ddt.idtipoddt=dt_tipiddt.id LEFT OUTER JOIN dt_righe_ddt ON dt_ddt.id=dt_righe_ddt.idddt WHERE an_anagrafiche.idanagrafica='.prepare($id_record)); + +if (!empty($rsddt)) { + echo ' + + + + + + + + + + + + + + + + + + + + + + + '; + + foreach ($rsddt as $key => $r) { + echo ' + + + + + + + '; + } ?> + + + +
#'._('Numero').''._('Data').''._('Articolo').''._('Qtà').'
#'._('Numero').''._('Data').''._('Articolo').''._('Qtà').'
+ '.($key + 1).' + + '.Modules::link('Ddt di vendita', $rsddt[$i]['idddt'], $rsddt[$i]['numero_esterno']).' + + '.Translator::dateToLocale($rsddt[$i]['data']).' + + '.$rsddt[$i]['descrizione'].' + + '.Translator::numberToLocale($rsddt[$i]['qta']).' '.$rsddt[$i]['um'].' +
+ + + + + '._('Nessun ddt di vendita per questa anagrafica').'. +'; +} diff --git a/modules/ddt/row-list.php b/modules/ddt/row-list.php new file mode 100644 index 000000000..959d61471 --- /dev/null +++ b/modules/ddt/row-list.php @@ -0,0 +1,380 @@ + + + '._('Descrizione').' + '._('Q.tà').' + '._('U.m.').' + '._('Costo unitario').' + '._('Iva').' + '._('Imponibile').' + + + + '; + +/* + Articoli e righe generiche +*/ +$q_art = 'SELECT *, (SELECT codice FROM mg_articoli WHERE id=idarticolo) AS codice FROM `dt_righe_ddt` WHERE idddt='.prepare($id_record).' GROUP BY idgruppo ORDER BY `order`'; +$rs = $dbo->fetchArray($q_art); + +if (!empty($rs)) { + foreach ($rs as $r) { + if (!empty($r['idarticolo'])) { + $qserial = 'SELECT * FROM dt_righe_ddt WHERE idddt='.prepare($id_record).' AND idarticolo='.prepare($r['idarticolo']).' AND idgruppo='.prepare($r['idgruppo']); + $rsserial = $dbo->fetchArray($qserial); + + $mancanti = 0; + $serials = []; + + if (!empty($r['abilita_serial'])) { + foreach ($rsserial as $seriali) { + $seriali['serial'] = trim($seriali['serial']); + if (!empty($seriali['serial'])) { + $serials[] = $seriali['serial']; + } else { + ++$mancanti; + } + } + } + + if ($mancanti > 0) { + $extra = 'class="warning"'; + } + } + + echo ' + + '; + + if (!empty($r['idarticolo'])) { + echo ' + '.Modules::link('Articoli', $r['idarticolo'], $r['codice'].' - '.$r['descrizione']); + + if (!empty($r['abilita_serial'])) { + if (!empty($mancanti)) { + echo ' +
'.str_replace('_NUM_', $mancanti, _('_NUM_ serial mancanti')).''; + } + if (!empty($serials)) { + echo ' +
'._('SN').': '.implode(', ', $serials); + } + } else { + if ($r['lotto'] != '') { + echo '
Lotto: '.$r['lotto']; + } + if ($r['serial'] != '') { + echo '
SN: '.$r['serial']; + } + if ($r['altro'] != '') { + echo '
'.$r['altro']; + } + } + } else { + echo nl2br($r['descrizione']); + } + + // Aggiunta riferimento a ordine + if (!empty($r['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id='.prepare($r['idordine'])); + $numero = ($rso[0]['numero_esterno'] != '') ? $rso[0]['numero_esterno'] : $rso[0]['numero']; + echo '
Rif. ordine no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']); + } + echo ' + '; + + echo ' + '; + if (strpos($r['descrizione'], 'SCONTO') === false) { + echo ' + '.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).' +
('._('Q.tà iniziale').': '.Translator::numberToLocale($r['qta']).')'; + } else { + echo '1'; + } + echo ' + '; + + // Unità di misura + echo ' + + '.$r['um'].' + '; + + // Costo unitario + echo ' + + '.Translator::numberToLocale($r['subtotale'] / $r['qta']).' €'; + + if ($r['sconto_unitario'] > 0) { + echo ' +
- sconto '.Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €').''; + } + + echo ' + '; + + // Iva + echo ' + + '.Translator::numberToLocale($r['iva']).' € +
'.$r['desc_iva'].' + '; + + // Imponibile + echo ' + + '.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' € + '; + + // Possibilità di rimuovere una riga solo se il ddt non è evaso + echo ' + '; + if ($records[0]['stato'] != 'Evaso' && strpos($r['descrizione'], 'SCONTO') === false) { + echo " +
+ + + + "; + + if (!empty($r['idarticolo'])) { + echo " + + "; + } else { + echo " + + "; + } + + echo " + +
"; + + if (!empty($r['idarticolo']) && $r['abilita_serial']) { + echo " + "; + } + + echo " + + + + + + + +
+
"; + } + + if (strpos($r['descrizione'], 'SCONTO') === false) { + echo ' +
+ +
'; + } + + echo ' + + '; + } +} + +echo ' + '; + +// Calcoli +$imponibile = sum(array_column($rs, 'subtotale')); +$sconto = sum(array_column($rs, 'sconto')); +$iva = sum(array_column($rs, 'iva')); + +$imponibile_scontato = sum($imponibile, -$sconto); + +$totale_iva = sum($iva, $records[0]['iva_rivalsainps']); + +$totale = sum([ + $imponibile_scontato, + $records[0]['rivalsainps'], + $totale_iva, +]); + +$netto_a_pagare = sum([ + $totale, + $marca_da_bollo, + -$records[0]['ritenutaacconto'], +]); + +// IMPONIBILE +echo ' + + + '.strtoupper(_('Imponibile')).': + + + + '.Translator::numberToLocale($imponibile).' € + + + + '; + +if (abs($sconto) > 0) { + // SCONTO + echo ' + + + '.strtoupper(_('Sconto')).': + + + + '.Translator::numberToLocale($sconto).' € + + + + '; + + // IMPONIBILE SCONTATO +echo ' + + + '.strtoupper(_('Imponibile scontato')).': + + + + '.Translator::numberToLocale($imponibile_scontato).' € + + + + '; +} + +// RIVALSA INPS +if (abs($records[0]['rivalsainps']) > 0) { + echo ' + + + '.strtoupper(_('Rivalsa INPS')).': + + + + '.Translator::numberToLocale($records[0]['rivalsainps']).' € + + + + '; +} + +if (abs($totale_iva) > 0) { + echo ' + + + '.strtoupper(_('IVA')).': + + + + '.Translator::numberToLocale($totale_iva).' € + + + + '; +} + +// TOTALE +echo ' + + + '.strtoupper(_('Totale')).': + + + + '.Translator::numberToLocale($totale).' € + + + + '; + +// Mostra marca da bollo se c'è +if (abs($records[0]['bollo']) > 0) { + echo ' + + + '.strtoupper(_('Marca da bollo')).': + + + + '.Translator::numberToLocale($records[0]['bollo']).' € + + + + '; +} + +// RITENUTA D'ACCONTO +if (abs($records[0]['ritenutaacconto']) > 0) { + echo ' + + + '.strtoupper(_("Ritenuta d'acconto")).': + + + + '.Translator::numberToLocale($records[0]['ritenutaacconto']).' € + + + + '; +} + +// NETTO A PAGARE +if ($totale != $netto_a_pagare) { + echo ' + + + '.strtoupper(_('Netto a pagare')).': + + + + '.Translator::numberToLocale($netto_a_pagare).' € + + + + '; +} + +echo ' +'; + +echo ' +'; diff --git a/modules/fatture/actions.php b/modules/fatture/actions.php new file mode 100644 index 000000000..3d17647db --- /dev/null +++ b/modules/fatture/actions.php @@ -0,0 +1,1260 @@ +fetchArray($query); + $idpagamento = $rs[0]['id']; + + // Se la fattura è di vendita e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni + if ($dir == 'entrata' && $idpagamento == '') { + $idpagamento = get_var('Tipo di pagamento predefinito'); + } + + $query = 'INSERT INTO co_documenti (numero, numero_esterno, idanagrafica, idconto, idtipodocumento, idpagamento, data, idstatodocumento, idsede) VALUES ('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($idanagrafica).', '.prepare($idconto).', '.prepare($idtipodocumento).', '.prepare($idpagamento).', '.prepare($data).", (SELECT `id` FROM `co_statidocumento` WHERE `descrizione`='Bozza'), (SELECT idsede_fatturazione FROM an_anagrafiche WHERE idanagrafica=".prepare($idanagrafica).') )'; + $dbo->query($query); + + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = str_replace('_NUM_', $numero, _('Aggiunta fattura numero _NUM_!')); + + break; + + case 'update': + if (isset($post['id_record'])) { + $numero_esterno = post('numero_esterno'); + $data = $post['data']; + $idanagrafica = post('idanagrafica'); + $idagente = post('idagente'); + $note = post('note'); + $note_aggiuntive = post('note_aggiuntive'); + $idtipodocumento = post('idtipodocumento'); + $idstatodocumento = post('idstatodocumento'); + $idpagamento = post('idpagamento'); + $idcausalet = post('idcausalet'); + $idspedizione = post('idspedizione'); + $idporto = post('idporto'); + $idaspettobeni = post('idaspettobeni'); + $idvettore = post('idvettore'); + $n_colli = post('n_colli'); + $idsede = post('idsede'); + $idconto = post('idconto'); + $totale_imponibile = get_imponibile_fattura($id_record); + $totale_fattura = get_totale_fattura($id_record); + + $tipo_sconto = $post['tipo_sconto_generico']; + $sconto = $post['sconto_generico']; + + if ($dir == 'uscita') { + $idrivalsainps = post('idrivalsainps'); + $idritenutaacconto = post('idritenutaacconto'); + $bollo = post('bollo'); + } else { + $idrivalsainps = 0; + $idritenutaacconto = 0; + $bollo = 0; + } + + // Leggo la descrizione del pagamento + $query = 'SELECT descrizione FROM co_pagamenti WHERE id='.prepare($idpagamento); + $rs = $dbo->fetchArray($query); + $pagamento = $rs[0]['descrizione']; + + // Query di aggiornamento + $query = 'UPDATE co_documenti SET '. + ' data='.prepare($data).','. + ' idstatodocumento='.prepare($idstatodocumento).','. + ' idtipodocumento='.prepare($idtipodocumento).','. + ' idanagrafica='.prepare($idanagrafica).','. + ' idagente='.prepare($idagente).','. + ' idpagamento='.prepare($idpagamento).','. + ' idcausalet='.prepare($idcausalet).','. + ' idspedizione='.prepare($idspedizione).','. + ' idporto='.prepare($idporto).','. + ' idaspettobeni='.prepare($idaspettobeni).','. + ' idvettore='.prepare($idvettore).','. + ' n_colli='.prepare($n_colli).','. + ' idsede='.prepare($idsede).','. + ' numero_esterno='.prepare($numero_esterno).','. + ' tipo_sconto_globale='.prepare($tipo_sconto).','. + ' sconto_globale='.prepare($sconto).','. + ' note='.prepare($note).','. + ' note_aggiuntive='.prepare($note_aggiuntive).','. + ' idconto='.prepare($idconto).','. + ' idrivalsainps='.prepare($idrivalsainps).','. + ' idritenutaacconto='.prepare($idritenutaacconto).','. + ' bollo=0, rivalsainps=0, ritenutaacconto=0, iva_rivalsainps=0 '. + ' WHERE id='.prepare($id_record); + + $dbo->query($query); + $query = 'SELECT descrizione FROM co_statidocumento WHERE id='.prepare($idstatodocumento); + $rs = $dbo->fetchArray($query); + + $dbo->query("DELETE FROM co_righe_documenti WHERE descrizione LIKE '%SCONTO%' AND iddocumento=".prepare($id_record)); + + // Sconto unitario, quello percentuale viene gestito a fondo pagina + if ($tipo_sconto == 'UNT' && $sconto > 0) { + $subtotale = -$sconto; + + // Calcolo anche l'iva da scontare + $rsi = $dbo->fetchArray('SELECT descrizione, percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita'))); + $iva = $subtotale / 100 * $rsi[0]['percentuale']; + + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, descrizione, idiva, desc_iva, iva, subtotale, sconto, qta, idgruppo, `order`) VALUES( '.prepare($id_record).", 'SCONTO', ".prepare($idiva).', '.prepare($rsi[0]['descrizione']).', '.prepare($iva).', '.prepare($subtotale).', 0, 1, (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'); + } + + // Ricalcolo inps, ritenuta e bollo (se la fattura non è stata pagata) + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, $idrivalsainps, $idritenutaacconto, $bollo); + } + + // Elimino la scadenza e tutti i movimenti, poi se la fattura è emessa le ricalcolo + if ($rs[0]['descrizione'] == 'Bozza') { + elimina_scadenza($id_record); + elimina_movimento($id_record, 0); + elimina_movimento($id_record, 1); + } elseif ($rs[0]['descrizione'] == 'Emessa') { + elimina_scadenza($id_record); + elimina_movimento($id_record, 0); + } + + // Se la fattura è in stato "Emessa" posso inserirla in scadenziario e aprire il mastrino cliente + if ($rs[0]['descrizione'] == 'Emessa') { + aggiungi_scadenza($id_record, $pagamento); + aggiungi_movimento($id_record, $dir); + } + + $_SESSION['infos'][] = _('Fattura modificata correttamente!'); + } + + break; + + // eliminazione documento + case 'delete': + if ($dir == 'uscita') { + $non_rimovibili = $dbo->fetchArray("SELECT COUNT(*) AS non_rimovibili FROM co_righe_documenti WHERE serial IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND iddocumento=".prepare($id_record))[0]['non_rimovibili']; + if ($non_rimovibili != 0) { + $_SESSION['errors'][] = _('Alcuni serial number sono già stati utilizzati!'); + + return; + } + } + + // Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento" + $query = 'SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idpreventivo IS NOT NULL'; + $rs = $dbo->fetchArray($query); + + for ($i = 0; $i < sizeof($rs); ++$i) { + $dbo->query("UPDATE co_preventivi SET idstato=(SELECT id FROM co_statipreventivi WHERE descrizione='In lavorazione') WHERE id=".prepare($rs[$i]['idpreventivo'])); + } + + // Se ci sono degli interventi collegati li rimetto nello stato "Completato" + $query = 'SELECT idintervento FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idintervento IS NOT NULL'; + $rs = $dbo->fetchArray($query); + + for ($i = 0; $i < sizeof($rs); ++$i) { + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Completato') WHERE id=".prepare($rs[$i]['idintervento'])); + } + + // Se ci sono degli articoli collegati (ma non collegati a preventivi o interventi) li rimetto nel magazzino + $query = 'SELECT id, idarticolo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND NOT idarticolo=0 AND idpreventivo=0 AND idintervento IS NULL'; + $rs = $dbo->fetchArray($query); + + for ($i = 0; $i < sizeof($rs); ++$i) { + rimuovi_articolo_dafattura($rs[$i]['idarticolo'], $id_record, $rs[$i]['id']); + } + + $dbo->query('DELETE FROM co_documenti WHERE id='.prepare($id_record)); + $dbo->query('DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record)); + $dbo->query('DELETE FROM co_scadenziario WHERE iddocumento='.prepare($id_record)); + $dbo->query('DELETE FROM mg_movimenti WHERE iddocumento='.prepare($id_record)); + + // Azzeramento collegamento della rata contrattuale alla pianificazione + $dbo->query('UPDATE co_ordiniservizio_pianificazionefatture SET iddocumento=0 WHERE iddocumento='.prepare($id_record)); + + elimina_scadenza($id_record); + elimina_movimento($id_record); + + $_SESSION['infos'][] = _('Fattura eliminata!'); + + break; + + // Duplicazione fattura + case 'copy': + if ($id_record) { + // Calcolo prossimo numero fattura + $numero = get_new_numerofattura(date('Y-m-d')); + + if ($dir == 'entrata') { + $numero_esterno = get_new_numerosecondariofattura(date('Y-m-d')); + } else { + $numero_esterno = ''; + } + + // Lettura dati fattura attuale + $rs = $dbo->fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); + + // Duplicazione intestazione + $dbo->query('INSERT INTO co_documenti(numero, numero_esterno, data, idanagrafica, idcausalet, idspedizione, idporto, idaspettobeni, idvettore, n_colli, idsede, idtipodocumento, idstatodocumento, idpagamento, idconto, idrivalsainps, idritenutaacconto, rivalsainps, iva_rivalsainps, ritenutaacconto, bollo, note, note_aggiuntive, buono_ordine) VALUES('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($rs[0]['data']).', '.prepare($rs[0]['idanagrafica']).', '.prepare($rs[0]['idcausalet']).', '.prepare($rs[0]['idspedizione']).', '.prepare($rs[0]['idporto']).', '.prepare($rs[0]['idaspettobeni']).', '.prepare($rs[0]['idvettore']).', '.prepare($rs[0]['n_colli']).', '.prepare($rs[0]['idsede']).', '.prepare($rs[0]['idtipodocumento']).', (SELECT id FROM co_statidocumento WHERE descrizione=\'Bozza\'), '.prepare($rs[0]['idpagamento']).', '.prepare($rs[0]['idconto']).', '.prepare($rs[0]['idrivalsainps']).', '.prepare($rs[0]['idritenutaacconto']).', '.prepare($rs[0]['rivalsainps']).', '.prepare($rs[0]['iva_rivalsainps']).', '.prepare($rs[0]['ritenutaacconto']).', '.prepare($rs[0]['bollo']).', '.prepare($rs[0]['note']).', '.prepare($rs[0]['note_aggiuntive']).', '.prepare($rs[0]['buono_ordine']).')'); + $id_record = $dbo->lastInsertedID(); + + // Duplicazione righe + $rs = $dbo->fetchArray('SELECT * FROM co_righe_documenti WHERE iddocumento='.prepare($id_record)); + + for ($i = 0; $i < sizeof($rs); ++$i) { + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, idordine, idddt, idintervento, idarticolo, idpreventivo, idcontratto, idtecnico, idagente, idautomezzo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, um, qta, lotto, serial, altro, idgruppo, `order`) VALUES('.prepare($id_record).', 0, 0, 0, '.prepare($rs[$i]['idarticolo']).', '.prepare($rs[$i]['idpreventivo']).', '.prepare($rs[$i]['idcontratto']).', '.prepare($rs[$i]['idtecnico']).', '.prepare($rs[$i]['idagente']).', '.prepare($rs[$i]['idautomezzo']).', '.prepare($rs[$i]['idiva']).', '.prepare($rs[$i]['desc_iva']).', '.prepare($rs[$i]['iva']).', '.prepare($rs[$i]['iva_indetraibile']).', '.prepare($rs[$i]['descrizione']).', '.prepare($rs[$i]['subtotale']).', '.prepare($rs[$i]['sconto']).', '.prepare($rs[$i]['idritenutaacconto']).', '.prepare($rs[$i]['ritenutaacconto']).', '.prepare($rs[$i]['idrivalsainps']).', '.prepare($rs[$i]['rivalsainps']).', '.prepare($rs[$i]['um']).', '.prepare($rs[$i]['qta']).', '.prepare($rs[$i]['lotto']).', '.prepare($rs[$i]['serial']).', '.prepare($rs[$i]['altro']).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'); + + // Scarico/carico nuovamente l'articolo da magazzino + if (!empty($rs[$i]['idarticolo'])) { + add_articolo_infattura($id_record, $rs[$i]['idarticolo'], $rs[$i]['descrizione'], $rs[$i]['idiva'], $rs[$i]['qta'], $rs[$i]['subtotale'], 0, 0, 0); + } + } + + // Ricalcolo inps, ritenuta e bollo (se la fattura non è stata pagata) + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, $rs[0]['idrivalsainps'], $rs[0]['idritenutaacconto'], $rs[0]['bollo']); + } + + $_SESSION['infos'][] = _('Fattura duplicata correttamente!'); + + redirect($rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record); + } + + break; + + case 'reopen': + if (!empty($id_record)) { + if ($dbo->query("UPDATE co_documenti SET idstatodocumento=(SELECT id FROM co_statidocumento WHERE descrizione='Bozza') WHERE id=".prepare($id_record))) { + elimina_scadenza($id_record); + elimina_movimento($id_record, 1); + ricalcola_costiagg_fattura($id_record); + $_SESSION['infos'][] = _('Fattura riaperta!'); + } + } + + break; + + case 'addintervento': + if (!empty($id_record) && isset($post['idintervento'])) { + $idintervento = post('idintervento'); + $descrizione = post('descrizione'); + $idiva = post('idiva'); + $idconto = post('idconto'); + + $prezzo = $post['prezzo']; + $qta = 1; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // Leggo l'anagrafica del cliente + $rs = $dbo->fetchArray('SELECT idanagrafica, codice, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento='.prepare($idintervento).') AS data FROM `in_interventi` WHERE id='.prepare($idintervento)); + $idanagrafica = $rs[0]['idanagrafica']; + $data = $rs[0]['data']; + $codice = $rs[0]['codice']; + + if ($rs = $dbo->fetchArray('SELECT (SELECT SUM(km) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS km, (SELECT costo_orario FROM in_tipiintervento WHERE idtipointervento=in_interventi.idtipointervento) AS prezzo_ore_unitario, (SELECT costo_km FROM in_tipiintervento WHERE idtipointervento=in_interventi.idtipointervento) AS prezzo_km_unitario, (SELECT costo_diritto_chiamata FROM in_tipiintervento WHERE idtipointervento=in_interventi.idtipointervento) AS prezzo_diritto_chiamata, (SELECT SUM(TIME_TO_SEC(TIMEDIFF(orario_fine, orario_inizio))) FROM in_interventi_tecnici GROUP BY idintervento HAVING in_interventi_tecnici.idintervento=in_interventi.id) AS t1, (SELECT SUM(km) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS km, (SELECT SUM(prezzo_ore_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS tot_ore_consuntivo, (SELECT SUM(prezzo_km_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS tot_km_consuntivo, (SELECT COUNT(idtecnico) FROM in_interventi_tecnici WHERE idintervento=in_interventi.id) AS n_tecnici FROM `in_interventi` WHERE in_interventi.id='.prepare($idintervento).' AND in_interventi.id NOT IN (SELECT idintervento FROM co_righe_documenti WHERE idintervento IS NOT NULL AND NOT idintervento IS NULL)')) { + // Collego in fattura eventuali articoli collegati all'intervento + $rs2 = $dbo->fetchArray('SELECT mg_articoli_interventi.*, idarticolo FROM mg_articoli_interventi INNER JOIN mg_articoli ON mg_articoli_interventi.idarticolo=mg_articoli.id WHERE idintervento='.prepare($idintervento).' AND ( idintervento NOT IN(SELECT idintervento FROM co_righe_preventivi WHERE idpreventivo IN(SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) AND idintervento NOT IN(SELECT idintervento FROM co_righe_contratti WHERE idcontratto IN(SELECT idcontratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) )'); + for ($i = 0; $i < sizeof($rs2); ++$i) { + add_articolo_infattura($id_record, $rs2[$i]['idarticolo'], $rs2[$i]['descrizione'], $idiva, $rs2[$i]['qta'], $rs2[$i]['prezzo_vendita'] * $rs2[$i]['qta'], $rs2[$i]['sconto'], $rs2[$i]['sconto_unitario'], $rs2[$i]['tipo_sconto'], $idintervento, '', $rs2[$i]['serial']); + } + + // Subtot + $prezzo_ore_consuntivo = $rs[0]['tot_ore_consuntivo']; + $prezzo_km_consuntivo = $rs[0]['tot_km_consuntivo']; + $prezzo_ore_unitario = $rs[0]['prezzo_ore_unitario']; + $prezzo_km_unitario = $rs[0]['prezzo_km_unitario']; + $prezzo_diritto_chiamata = $rs[0]['prezzo_diritto_chiamata']; + $km = $rs[0]['km']; + + // Aggiunta km come "Trasferta" (se c'è) + if ($prezzo_km_consuntivo > 0) { + // Calcolo iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $desc_iva = $rs[0]['descrizione']; + + $subtot = $prezzo_km_consuntivo; + $iva = ($subtot) / 100 * $rs[0]['percentuale']; + $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; + + // Calcolo rivalsa inps + $query = 'SELECT * FROM co_rivalsainps WHERE id='.prepare(get_var('Percentuale rivalsa INPS')); + $rs = $dbo->fetchArray($query); + $rivalsainps = $subtot / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto")); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = ($subtot + $rivalsainps) / 100 * $rs[0]['percentuale']; + + $query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) VALUES('.prepare($id_record).', NULL, '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare('Trasferta intervento '.$codice.' del '.Translator::dateToLocale($data)).', '.prepare($subtot).", 'km' ".prepare($km).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + $dbo->query($query); + } + + // Aggiunta spese aggiuntive come righe generiche + $query = 'SELECT * FROM in_righe_interventi WHERE idintervento='.prepare($idintervento).' AND ( idintervento NOT IN(SELECT idintervento FROM co_righe_preventivi WHERE idpreventivo IN(SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) AND idintervento NOT IN(SELECT idintervento FROM co_righe_contratti WHERE idcontratto IN(SELECT idcontratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) )'; + $rsr = $dbo->fetchArray($query); + if (sizeof($rsr) > 0) { + for ($i = 0; $i < sizeof($rsr); ++$i) { + // Calcolo iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $desc_iva = $rs[0]['descrizione']; + + $subtot = $rsr[$i]['prezzo_vendita'] * $rsr[$i]['qta']; + $iva = ($subtot) / 100 * $rs[0]['percentuale']; + $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; + + // Calcolo rivalsa inps + $query = 'SELECT * FROM co_rivalsainps WHERE id='.prepare(get_var('Percentuale rivalsa INPS')); + $rs = $dbo->fetchArray($query); + $rivalsainps = ($subtot - $sconto) / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto")); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = ($subtot - $sconto + $rivalsainps) / 100 * $rs[0]['percentuale']; + + $query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) VALUES('.prepare($id_record).', NULL, '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($rsr[$i]['descrizione']).', '.prepare($subtot).", 0, 0, 'UNT', ".prepare($rsr[$i]['um']).', '.prepare($rsr[$i]['qta']).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + $dbo->query($query); + } + } + + $intervento = $dbo->fetchArray('SELECT (manodopera_scontato + viaggio_scontato - vw_activity_subtotal.sconto_globale) AS prezzo FROM in_interventi JOIN vw_activity_subtotal ON vw_activity_subtotal.id = in_interventi.id WHERE in_interventi.id = '.prepare($idintervento)); + + $prezzo = $intervento[0]['prezzo']; + + // Calcolo iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + + $subtot = $prezzo - $prezzo_km_consuntivo; + $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(get_var('Percentuale rivalsa INPS')); + $rs = $dbo->fetchArray($query); + $rivalsainps = $subtot / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto")); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = ($subtot + $rivalsainps) / 100 * $rs[0]['percentuale']; + + // Aggiunta riga intervento sul documento + $query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idintervento).', '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', ".prepare($qta).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + if ($dbo->query($query)) { + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + // Metto l'intervento in stato "Fatturato" + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Fatturato') WHERE id=".prepare($idintervento)); + + $_SESSION['infos'][] = str_replace('_NUM_', $idintervento, _('Intervento _NUM_ aggiunto!')); + } else { + $_SESSION['errors'][] = str_replace('_NUM_', $idintervento, _("Errore durante l'inserimento dell'intervento _NUM_ in fattura!")); + } + } + } + break; + + case 'addpreventivo': + if (!empty($id_record) && isset($post['idpreventivo'])) { + $idpreventivo = post('idpreventivo'); + $descrizione = post('descrizione'); + $idiva = post('idiva'); + $idconto = post('idconto'); + + $prezzo = $post['prezzo']; + $qta = 1; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $subtot = 0; + $aggiorna_budget = ($post['aggiorna_budget'] == 'on') ? 1 : 0; + + // Leggo l'anagrafica del cliente + $rs = $dbo->fetchArray('SELECT idanagrafica, numero FROM `co_preventivi` WHERE id='.prepare($idpreventivo)); + $idanagrafica = $rs[0]['idanagrafica']; + $numero = $rs[0]['numero']; + + // Calcolo iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $iva = $prezzo / 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(get_var('Percentuale rivalsa INPS')); + $rs = $dbo->fetchArray($query); + $rivalsainps = ($prezzo - $sconto) / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto")); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = ($prezzo - $sconto + $rivalsainps) / 100 * $rs[0]['percentuale']; + + if (!empty($post['import'])) { + // Replicazione delle righe del preventivo sul documento + $righe = $dbo->fetchArray('SELECT idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto FROM co_righe_preventivi WHERE idpreventivo='.prepare($idpreventivo)); + foreach ($righe as $key => $riga) { + $dbo->insert('co_righe_documenti', [ + 'iddocumento' => $id_record, + 'idpreventivo' => $idpreventivo, + 'idconto' => $idconto, + 'idarticolo' => $riga['idarticolo'], + 'idiva' => $riga['idiva'], + 'desc_iva' => $riga['desc_iva'], + 'iva' => $riga['iva'], + 'iva_indetraibile' => $riga['iva_indetraibile'], + 'descrizione' => str_replace('SCONTO', 'SCONTO PREVENTIVO', $riga['descrizione']), + 'subtotale' => $riga['subtotale'], + 'um' => $riga['um'], + 'qta' => $riga['qta'], + 'sconto' => $riga['sconto'], + 'sconto_unitario' => $riga['sconto_unitario'], + 'order' => '#(SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).')#', + 'idgruppo' => '#(SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).')#', + 'idritenutaacconto' => get_var("Percentuale ritenuta d'acconto"), + 'ritenutaacconto' => $ritenutaacconto, + 'idrivalsainps' => get_var('Percentuale rivalsa INPS'), + 'rivalsainps' => $rivalsainps, + ]); + + if (!empty($riga['idarticolo'])) { + add_movimento_magazzino($riga['idarticolo'], -$riga['qta'], ['iddocumento' => $id_record]); + } + } + } else { + // Aggiunta riga preventivo sul documento + $query = 'INSERT INTO co_righe_documenti(iddocumento, idpreventivo, idconto, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, `order`, idgruppo) VALUES('.prepare($id_record).', '.prepare($idpreventivo).', '.prepare($idconto).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + $dbo->query($query); + + // Aggiorno lo stato degli interventi collegati al preventivo se ce ne sono + $query2 = 'SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND NOT idpreventivo=0 AND idpreventivo IS NOT NULL'; + $rs2 = $dbo->fetchArray($query2); + for ($j = 0; $j < sizeof($rs2); ++$j) { + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Fatturato') WHERE id IN (SELECT idintervento FROM co_preventivi_interventi WHERE idpreventivo=".prepare($rs2[$j]['idpreventivo']).')'); + } + } + + $_SESSION['infos'][] = str_replace('_NUM_', $numero, _('Preventivo _NUM_ aggiunto!')); + + // Aggiorno il budget sul preventivo con l'importo inserito in fattura e imposto lo stato del preventivo "In attesa di pagamento" (se selezionato) + if ($aggiorna_budget) { + $dbo->query('UPDATE co_preventivi SET budget='.prepare($prezzo).' WHERE id='.prepare($idpreventivo)); + } + $dbo->query("UPDATE co_preventivi SET idstato=(SELECT id FROM co_statipreventivi WHERE descrizione='In attesa di pagamento') WHERE id=".prepare($idpreventivo)); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + } + + break; + + case 'addcontratto': + if (!empty($id_record) && isset($post['idcontratto'])) { + $idcontratto = post('idcontratto'); + $descrizione = post('descrizione'); + $idiva = post('idiva'); + $idconto = post('idconto'); + + $prezzo = $post['prezzo']; + $qta = 1; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $subtot = 0; + $aggiorna_budget = ($post['aggiorna_budget'] == 'on') ? 1 : 0; + + // Leggo l'anagrafica del cliente + $rs = $dbo->fetchArray('SELECT idanagrafica, numero FROM `co_contratti` WHERE id='.prepare($idcontratto)); + $idanagrafica = $rs[0]['idanagrafica']; + $numero = $rs[0]['numero']; + + // Calcolo iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $iva = $prezzo / 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(get_var('Percentuale rivalsa INPS')); + $rs = $dbo->fetchArray($query); + $rivalsainps = $prezzo / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto")); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = ($prezzo) / 100 * $rs[0]['percentuale']; + + // Aggiunta riga contratto sul documento + $query = 'INSERT INTO co_righe_documenti(iddocumento, idcontratto, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idcontratto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($idconto).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + if ($dbo->query($query)) { + $_SESSION['infos'][] = str_replace('_NUM_', $numero, _('Contratto _NUM_ aggiunto!')); + + // Aggiorno il budget sul contratto con l'importo inserito in fattura e imposto lo stato del contratto "In attesa di pagamento" (se selezionato) + if ($aggiorna_budget) { + $dbo->query('UPDATE co_contratti SET budget='.prepare($prezzo).' WHERE id='.prepare($idcontratto)); + } + + $dbo->query("UPDATE co_contratti SET idstato=(SELECT id FROM co_staticontratti WHERE descrizione='In attesa di pagamento') WHERE id=".prepare($idcontratto)); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + } + } + break; + + case 'addarticolo': + if (!empty($id_record) && isset($post['idarticolo'])) { + $idarticolo = post('idarticolo'); + $descrizione = post('descrizione'); + + $idiva = post('idiva'); + $idconto = post('idconto'); + $idum = post('um'); + + $qta = $post['qta']; + $prezzo = $post['prezzo']; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // Calcolo idgruppo per questo inserimento + $ridgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(idgruppo) + 1, 0) AS idgruppo FROM co_righe_documenti WHERE iddocumento = '.prepare($id_record)); + $idgruppo = $ridgruppo[0]['idgruppo']; + + add_articolo_infattura($id_record, $idarticolo, $descrizione, $idiva, $qta, $prezzo * $qta, $sconto, $sconto_unitario, $tipo_sconto, '0', $lotto, $serial, $altro, $idgruppo, $idconto, $idum); + + $_SESSION['infos'][] = _('Articolo aggiunto!'); + } + break; + + case 'addriga': + if (!empty($id_record)) { + // Selezione costi da intervento + $descrizione = post('descrizione'); + $idiva = post('idiva'); + $idconto = post('idconto'); + + $qta = $post['qta']; + $prezzo = $post['prezzo']; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $subtot = $prezzo * $qta; + + // 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('idrivalsainps')); + $rs = $dbo->fetchArray($query); + $rivalsainps = $prezzo * $qta / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(post('idritenutaacconto')); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = (($prezzo * $qta) + $rivalsainps) / 100 * $rs[0]['percentuale']; + + // Calcolo idgruppo per questo inserimento + $ridgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(idgruppo) + 1, 0) AS idgruppo FROM co_righe_documenti WHERE iddocumento = '.prepare($id_record)); + $idgruppo = $ridgruppo[0]['idgruppo']; + + // Aggiunta riga generica sul documento + $query = 'INSERT INTO co_righe_documenti(iddocumento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', '.prepare(post('idrivalsainps')).', '.prepare($rivalsainps).', '.prepare(post('idritenutaacconto')).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + + if ($dbo->query($query)) { + $_SESSION['infos'][] = _('Riga aggiunta!'); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record); + } + } + } + break; + + case 'editriga': + if (isset($post['idriga'])) { + // Selezione costi da intervento + $idriga = post('idriga'); + $descrizione = post('descrizione'); + $idiva = post('idiva'); + $idconto = post('idconto'); + $um = post('um'); + + $qta = $post['qta']; + $prezzo = $post['prezzo']; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $subtot = $prezzo * $qta; + + // Lettura idarticolo dalla riga documento + $rs = $dbo->fetchArray('SELECT idgruppo, iddocumento, idarticolo, qta, abilita_serial FROM co_righe_documenti WHERE id='.prepare($idriga)); + $idarticolo = $rs[0]['idarticolo']; + $old_qta = $rs[0]['qta']; + $idgruppo = $rs[0]['idgruppo']; + $iddocumento = $rs[0]['iddocumento']; + $abilita_serial = $rs[0]['abilita_serial']; + + // 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('idrivalsainps')); + $rs = $dbo->fetchArray($query); + $rivalsainps = $prezzo * $qta / 100 * $rs[0]['percentuale']; + + // Calcolo ritenuta d'acconto + $query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(post('idritenutaacconto')); + $rs = $dbo->fetchArray($query); + $ritenutaacconto = (($prezzo * $qta) + $rivalsainps) / 100 * $rs[0]['percentuale']; + + // 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('idritenutaacconto')).', ritenutaacconto='.prepare($ritenutaacconto).', idrivalsainps='.prepare(post('idrivalsainps')).', rivalsainps='.prepare($rivalsainps).' WHERE idgruppo='.prepare($idgruppo).' AND iddocumento='.prepare($iddocumento); + if ($dbo->query($query)) { + // Modifica della quantità + $dbo->query('UPDATE co_righe_documenti SET qta='.prepare($qta).' WHERE idgruppo='.prepare($idgruppo)); + + // Modifica per gestire i serial + if (!empty($idarticolo)) { + $new_qta = $qta - $old_qta; + $new_qta = ($old_qta < $qta) ? $new_qta : -$new_qta; + + if (!empty($abilita_serial)) { + if ($old_qta < $qta) { + for ($i = 0; $i < $new_qta; ++$i) { + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order`) SELECT iddocumento, idarticolo, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, idgruppo, `order` FROM co_righe_documenti WHERE id='.prepare($idriga)); + } + } else { + if ($dir == 'uscita') { + if ($new_qta > $dbo->fetchArray("SELECT COUNT(*) AS rimovibili FROM co_righe_documenti WHERE serial NOT IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idgruppo=".prepare($idgruppo).' AND iddocumento='.prepare($iddocumento))[0]['rimovibili']) { + $_SESSION['errors'][] = _('Alcuni serial number sono già stati utilizzati!'); + + return; + } else { + $deletes = $dbo->fetchArray('SELECT id FROM co_righe_documenti AS t WHERE idgruppo = '.prepare($idgruppo).' AND iddocumento='.prepare($iddocumento)." AND serial NOT IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') ORDER BY serial ASC LIMIT ".$new_qta); + } + } else { + $deletes = $dbo->fetchArray('SELECT id FROM co_righe_documenti AS t WHERE idgruppo = '.prepare($idgruppo).' AND iddocumento='.prepare($iddocumento).' ORDER BY serial ASC LIMIT '.$new_qta); + } + + foreach ((array) $deletes as $delete) { + $dbo->query('DELETE FROM co_righe_documenti WHERE id = '.prepare($delete['id'])); + } + } + } + + $new_qta = ($old_qta < $qta) ? $new_qta : -$new_qta; + + $new_qta = ($dir == 'entrata') ? -$new_qta : $new_qta; + add_movimento_magazzino($idarticolo, $new_qta, ['iddocumento' => $id_record]); + } + + $_SESSION['infos'][] = _('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; + $data = $post['data']; + $idanagrafica = $post['idanagrafica']; + $idarticolo = $post['idarticolo']; + $idpagamento = $post['idpagamento']; + $idconto = $post['idconto']; + $idddt = $post['idddt']; + $numero = get_new_numerofattura($data); + + if ($dir == 'entrata') { + $numero_esterno = get_new_numerosecondariofattura($data); + } else { + $numero_esterno = ''; + } + + $tipo_documento = ($dir == 'entrata') ? 'Fattura differita di vendita' : 'Fattura differita di acquisto'; + + // Creazione nuova fattura + $dbo->query('INSERT INTO co_documenti(numero, numero_esterno, data, idanagrafica, idtipodocumento, idstatodocumento, idpagamento, idconto) VALUES('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($data).', '.prepare($idanagrafica).', (SELECT id FROM co_tipidocumento WHERE descrizione='.prepare($tipo_documento)."), (SELECT id FROM co_statidocumento WHERE descrizione='Bozza'), ".prepare($idpagamento).', '.prepare($idconto).')'); + $id_record = $dbo->lastInsertedID(); + + // Lettura di tutte le righe della tabella in arrivo + for ($i = 0; $i < sizeof($post['qta_da_evadere']); ++$i) { + // Processo solo le righe da evadere + if ($post['evadere'][$i] == 'on') { + $idrigaddt = post('idrigaddt')[$i]; + $idarticolo = post('idarticolo')[$i]; + $descrizione = post('descrizione')[$i]; + $qta = $post['qta_da_evadere'][$i]; + $um = $post['um'][$i]; + $subtot = $post['subtot'][$i] * $qta; + $sconto = $post['sconto'][$i]; + $sconto = $sconto * $qta; + $idiva = post('idiva')[$i]; + + $qprc = 'SELECT tipo_sconto, sconto_unitario FROM dt_righe_ddt WHERE id='.$idrigaddt; + $rsprc = $dbo->fetchArray($qprc); + + $sconto_unitario = $rsprc[0]['sconto_unitario']; + $tipo_sconto = $rsprc[0]['tipo_sconto']; + + // Leggo la descrizione iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $perc_iva = $rs[0]['percentuale']; + $desc_iva = $rs[0]['descrizione']; + $iva = $subtot / 100 * $perc_iva; + + // Calcolo l'iva indetraibile + $q = 'SELECT indetraibile FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($q); + $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; + + // Lettura lotto, serial, altro dalla riga dell'ordine + $q = 'SELECT lotto, serial, altro, descrizione FROM dt_righe_ddt WHERE id='.prepare($idrigaddt); + $rs = $dbo->fetchArray($q); + + // Se sto aggiungendo un articolo uso la funzione per inserirlo e incrementare la giacenza + if (!empty($idarticolo)) { + $idiva_acquisto = $idiva; + $prezzo_acquisto = $subtot; + add_articolo_infattura($id_record, $idarticolo, $rs[0]['descrizione'], $idiva_acquisto, $qta, $prezzo_acquisto, $sconto, $sconto_unitario, $tipo_sconto, $rs[0]['lotto'], $rs[0]['serial'], $rs[0]['altro'], $rs[0]['idgruppo']); + } + + // Inserimento riga normale + elseif ($qta != 0) { + // Se la riga che sto inserendo è simile ad altre già inserite, aggiorno solo la quantità... + $query = 'SELECT id FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND descrizione='.prepare($descrizione).' AND (subtotale/qta)='.($subtot / $qta).' AND um='.prepare($um).' AND sconto='.prepare($sconto / $qta).' AND idiva='.prepare($idiva); + $rs = $dbo->fetchArray($query); + + if (sizeof($rs) > 0) { + $query = 'UPDATE co_righe_documenti SET qta=qta+'.$qta.' WHERE id='.prepare($rs[0]['id']); + } + + // ...altrimenti aggiungo una nuova riga + else { + $query = 'INSERT INTO co_righe_documenti(iddocumento, idarticolo, descrizione, idddt, idiva, desc_iva, iva, iva_indetraibile, subtotale, sconto, um, qta, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($descrizione).', '.prepare($idddt).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + } + + $dbo->query($query); + } + + // Scalo la quantità dal ddt + $dbo->query('UPDATE dt_righe_ddt SET qta_evasa = qta_evasa+'.$qta.' WHERE id='.prepare($idrigaddt)); + } + } + + ricalcola_costiagg_fattura($id_record); + + $_SESSION['infos'][] = _('Creata una nuova fattura!'); + + break; + + // Creazione fattura da ordine + case 'fattura_da_ordine': + $totale_fattura = 0.00; + $data = $post['data']; + $idanagrafica = $post['idanagrafica']; + $idarticolo = $post['idarticolo']; + $idpagamento = $post['idpagamento']; + $idconto = $post['idconto']; + $idordine = $post['idordine']; + $numero = get_new_numerofattura($data); + $numero_esterno = get_new_numerosecondariofattura($data); + + $tipo_documento = ($dir == 'entrata') ? 'Fattura immediata di vendita' : 'Fattura immediata di acquisto'; + + // Creazione nuova fattura + $dbo->query('INSERT INTO co_documenti(numero, numero_esterno, data, idanagrafica, idtipodocumento, idstatodocumento, idpagamento, idconto) VALUES('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($data).', '.prepare($idanagrafica).', (SELECT id FROM co_tipidocumento WHERE descrizione='.prepare($tipo_documento)."), (SELECT id FROM co_statidocumento WHERE descrizione='Bozza'), ".prepare($idpagamento).', '.prepare($idconto).')'); + $id_record = $dbo->lastInsertedID(); + + // Lettura di tutte le righe della tabella in arrivo + for ($i = 0; $i < sizeof($post['qta_da_evadere']); ++$i) { + // Processo solo le righe da evadere + if ($post['evadere'][$i] == 'on') { + $idrigaordine = post('idrigaordine')[$i]; + $idarticolo = post('idarticolo')[$i]; + $descrizione = post('descrizione')[$i]; + $qta = post('qta_da_evadere')[$i]; + $um = post('um')[$i]; + $subtot = save($post['subtot'][$i] * $qta); + $idiva = post('idiva')[$i]; + $iva = save($post['iva'][$i] * $qta); + $sconto = post('sconto')[$i]; + $sconto = $sconto * $qta; + + $qprc = 'SELECT tipo_sconto, sconto_unitario FROM or_righe_ordini WHERE id='.$idrigaordine; + $rsprc = $dbo->fetchArray($qprc); + + $sconto_unitario = $rsprc[0]['sconto_unitario']; + $tipo_sconto = $rsprc[0]['tipo_sconto']; + + // Calcolo l'iva indetraibile + $q = 'SELECT indetraibile FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($q); + $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; + + // Leggo la descrizione iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $desc_iva = $rs[0]['descrizione']; + + // Lettura lotto, serial, altro dalla riga dell'ordine + $q = 'SELECT lotto, serial, altro, descrizione FROM or_righe_ordini WHERE id='.prepare($idrigaordine); + $rs = $dbo->fetchArray($q); + + // Se sto aggiungendo un articolo uso la funzione per inserirlo e incrementare la giacenza + if (!empty($idarticolo)) { + $idiva_acquisto = $idiva; + $prezzo_acquisto = $subtot; + $idriga = add_articolo_infattura($id_record, $idarticolo, $rs[0]['descrizione'], $idiva_acquisto, $qta, $prezzo_acquisto, $sconto, $sconto_unitario, $tipo_sconto, '0', $rs[0]['lotto'], $rs[0]['serial'], $rs[0]['altro']); + + // Imposto la provenienza dell'ordine + $dbo->query('UPDATE co_righe_documenti SET idordine='.prepare($idordine).' WHERE id='.prepare($idriga)); + } + + // Inserimento riga normale + elseif ($qta != 0) { + // Se la riga che sto inserendo è simile ad altre già inserite, aggiorno solo la quantità... + $query = 'SELECT id FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND descrizione='.prepare($descrizione).' AND (subtotale/qta)='.($subtot / $qta).' AND um='.prepare($um).' AND sconto='.prepare($sconto / $qta).' AND idiva='.prepare($idiva); + $rs = $dbo->fetchArray($query); + + if (sizeof($rs) > 0) { + $dbo->query('UPDATE co_righe_documenti SET qta=qta+'.$qta.' WHERE id='.prepare($rs[0]['id'])); + $idriga = $rs[0]['id']; + } + + // ...altrimenti aggiungo una nuova riga + else { + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idordine, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, um, qta, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idordine).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'); + $idriga = $dbo->lastInsertedID(); + } + } + + // Scalo la quantità dall'ordine + $dbo->query('UPDATE or_righe_ordini SET qta_evasa = qta_evasa+'.$qta.' WHERE id='.prepare($idrigaordine)); + } + } + + ricalcola_costiagg_fattura($id_record); + $_SESSION['infos'][] = _('Creata una nuova fattura!'); + + break; + + // aggiungi righe da ddt + case 'add_ddt': + $idddt = $post['idddt']; + + $rs = $dbo->fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); + $idconto = $rs[0]['idconto']; + + // Lettura di tutte le righe della tabella in arrivo + for ($i = 0; $i < sizeof($post['qta_da_evadere']); ++$i) { + // Processo solo le righe da evadere + if ($post['evadere'][$i] == 'on') { + $idrigaddt = post('idrigaddt')[$i]; + $idarticolo = post('idarticolo')[$i]; + $descrizione = post('descrizione')[$i]; + + $qta = $post['qta_da_evadere'][$i]; + $um = post('um')[$i]; + + $subtot = $post['subtot'][$i] * $qta; + $sconto = $post['sconto'][$i]; + $sconto = $sconto * $qta; + + $qprc = 'SELECT tipo_sconto, sconto_unitario FROM dt_righe_ddt WHERE id='.prepare($idrigaddt); + $rsprc = $dbo->fetchArray($qprc); + + $sconto_unitario = $rsprc[0]['sconto_unitario']; + $tipo_sconto = $rsprc[0]['tipo_sconto']; + + $idiva = post('idiva')[$i]; + + // Calcolo l'iva indetraibile + $q = 'SELECT percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($q); + $iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale']; + $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; + + // Leggo la descrizione iva + $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); + $rs = $dbo->fetchArray($query); + $desc_iva = $rs[0]['descrizione']; + + // Lettura lotto, serial, altro dalla riga dell'ordine + $q = 'SELECT lotto, serial, altro, descrizione FROM dt_righe_ddt WHERE id='.prepare($idrigaddt); + $rs = $dbo->fetchArray($q); + + // Se sto aggiungendo un articolo uso la funzione per inserirlo e incrementare la giacenza + if (!empty($idarticolo)) { + $idiva_acquisto = $idiva; + $prezzo_acquisto = $subtot; + add_articolo_infattura($id_record, $idarticolo, $rs[0]['descrizione'], $idiva_acquisto, $qta, $prezzo_acquisto, 0, 0, 'UNT', 0, $rs[0]['lotto'], $rs[0]['serial'], $rs[0]['altro'], 0, $idconto); + } + + // Inserimento riga normale + elseif ($qta != 0) { + $query = 'INSERT INTO co_righe_documenti(iddocumento, idarticolo, descrizione, idconto, idddt, idiva, desc_iva, iva, iva_indetraibile, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($descrizione).', '.prepare($idconto).', '.prepare($idddt).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; + $dbo->query($query); + } + + // Scalo la quantità dal ddt + $dbo->query('UPDATE dt_righe_ddt SET qta_evasa = qta_evasa+'.$qta.' WHERE id='.prepare($idrigaddt)); + } + } + + ricalcola_costiagg_fattura($id_record); + + $_SESSION['infos'][] = _('Aggiunti nuovi articoli in fattura!'); + + break; + + // Scollegamento intervento da documento + case 'unlink_intervento': + if (!empty($id_record) && isset($post['idriga'])) { + $idriga = post('idriga'); + + // Lettura preventivi collegati + $query = 'SELECT idgruppo, iddocumento, idintervento FROM co_righe_documenti WHERE id='.prepare($idriga); + $rsp = $dbo->fetchArray($query); + $id_record = $rsp[0]['iddocumento']; + $idgruppo = $rsp[0]['idgruppo']; + $idintervento = $rsp[0]['idintervento']; + + $query = 'DELETE FROM `co_righe_documenti` WHERE iddocumento='.prepare($id_record).' AND idgruppo='.prepare($idgruppo); + + $dbo->query($query); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + // Lettura interventi collegati + $query = 'SELECT id, idintervento FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idintervento IS NOT NULL'; + $rs = $dbo->fetchArray($query); + + // Se ci sono degli interventi collegati li rimetto nello stato "Completato" + for ($i = 0; $i < sizeof($rs); ++$i) { + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Completato') WHERE id=".prepare($rs[$i]['idintervento'])); + + // Rimuovo dalla fattura gli articoli collegati all'intervento + $rs2 = $dbo->fetchArray('SELECT idarticolo FROM mg_articoli_interventi WHERE idintervento='.prepare($idintervento)); + for ($j = 0; $j < sizeof($rs2); ++$j) { + rimuovi_articolo_dafattura($rs[0]['idarticolo'], $id_record, $rs[0]['idrigadocumento']); + } + } + + $_SESSION['infos'][] = str_replace('_NUM_', $idintervento, _('Intervento _NUM_ rimosso!')); + } + break; + + // Scollegamento articolo da documento + case 'unlink_articolo': + if (!empty($id_record) && isset($post['idarticolo'])) { + $idriga = post('idriga'); + $idarticolo = post('idarticolo'); + + $res = rimuovi_articolo_dafattura($idarticolo, $id_record, $idriga); + + if (!$res) { + $_SESSION['errors'][] = _('Alcuni serial number sono già stati utilizzati!'); + + return; + } + + if ($dbo->query('DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga))) { + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Articolo rimosso!'); + } + } + break; + + // Scollegamento preventivo da documento + case 'unlink_preventivo': + if (isset($post['idriga'])) { + $idriga = post('idriga'); + + // Lettura preventivi collegati + $query = 'SELECT idgruppo, iddocumento, idpreventivo FROM co_righe_documenti WHERE id='.prepare($idriga); + $rsp = $dbo->fetchArray($query); + $id_record = $rsp[0]['iddocumento']; + $idgruppo = $rsp[0]['idgruppo']; + $idpreventivo = $rsp[0]['idpreventivo']; + + $query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idgruppo='.prepare($idgruppo); + + if ($dbo->query($query)) { + // Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento" + for ($i = 0; $i < sizeof($rsp); ++$i) { + $dbo->query("UPDATE co_preventivi SET idstato=(SELECT id FROM co_statipreventivi WHERE descrizione='In lavorazione') WHERE id=".prepare($rsp[$i]['idpreventivo'])); + + // Aggiorno anche lo stato degli interventi collegati ai preventivi + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Completato') WHERE id IN (SELECT idintervento FROM co_preventivi_interventi WHERE idpreventivo=".prepare($rsp[$i]['idpreventivo']).')'); + } + + /* + Rimuovo tutti gli articoli dalla fattura collegati agli interventi che sono collegati a questo preventivo + */ + $rs2 = $dbo->fetchArray('SELECT idintervento FROM co_preventivi_interventi WHERE idpreventivo='.prepare($idpreventivo)." AND NOT idpreventivo=''"); + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Leggo gli articoli usati in questo intervento + $rs3 = $dbo->fetchArray('SELECT idarticolo FROM mg_articoli_interventi WHERE idintervento='.prepare($rs2[$i]['idintervento'])); + for ($j = 0; $j < sizeof($rs3); ++$j) { + // Leggo l'id della riga in fattura di questo articolo + $rs4 = $dbo->fetchArray('SELECT id FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idarticolo='.prepare($rs3[$j]['idarticolo'])); + for ($x = 0; $x < sizeof($rs4); ++$x) { + rimuovi_articolo_dafattura($rs3[$j]['idarticolo'], $id_record, $rs4[$x]['id']); + } + } + } + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Preventivo rimosso!'); + } + } + break; + + // Scollegamento contratto da documento + case 'unlink_contratto': + if (isset($post['idriga'])) { + $idriga = post('idriga'); + + // Lettura contratti collegati + $query = 'SELECT iddocumento, idcontratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idcontratto IS NOT NULL AND NOT idcontratto=0'; + $rsp = $dbo->fetchArray($query); + $id_record = $rsp[0]['iddocumento']; + $idcontratto = $rsp[0]['idcontratto']; + + $query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idcontratto='.prepare($idcontratto); + + if ($dbo->query($query)) { + // Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento" + for ($i = 0; $i < sizeof($rsp); ++$i) { + $dbo->query("UPDATE co_contratti SET idstato=(SELECT id FROM co_staticontratti WHERE descrizione='In lavorazione') WHERE id=".prepare($rsp[$i]['idcontratto'])); + + // Aggiorno anche lo stato degli interventi collegati ai contratti + $dbo->query("UPDATE in_interventi SET idstatointervento=(SELECT idstatointervento FROM in_statiintervento WHERE descrizione='Completato') WHERE id IN (SELECT idintervento FROM co_righe_contratti WHERE idcontratto=".prepare($rsp[$i]['idcontratto']).')'); + } + + /* + Rimuovo tutti gli articoli dalla fattura collegati agli interventi che sono collegati a questo contratto + */ + $rs2 = $dbo->fetchArray('SELECT idintervento FROM co_righe_contratti WHERE idcontratto='.prepare($idcontratto)." AND NOT idcontratto=''"); + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Leggo gli articoli usati in questo intervento + $rs3 = $dbo->fetchArray('SELECT idarticolo FROM mg_articoli_interventi WHERE idintervento='.prepare($rs2[$i]['idintervento'])); + for ($j = 0; $j < sizeof($rs3); ++$j) { + // Leggo l'id della riga in fattura di questo articolo + $rs4 = $dbo->fetchArray('SELECT id FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idarticolo='.prepare($rs3[$j]['idarticolo'])); + for ($x = 0; $x < sizeof($rs4); ++$x) { + rimuovi_articolo_dafattura($rs3[$j]['idarticolo'], $id_record, $rs4[$x]['id']); + } + } + } + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Contratto rimosso!'); + } + } + break; + + // Scollegamento riga generica da documento + case 'unlink_riga': + if (isset($post['idriga'])) { + $idriga = post('idriga'); + + // Se la riga è stata creata da un ordine, devo riportare la quantità evasa nella tabella degli ordini + // al valore di prima, riaggiungendo la quantità che sto togliendo + $rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idordine, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga)); + + // Rimpiazzo la quantità negli ordini + $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$rs[0]['qta'].' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idordine='.prepare($rs[0]['idordine']).' AND idiva='.prepare($rs[0]['idiva'])); + + // Se la riga è stata creata da un ddt, devo riportare la quantità evasa nella tabella dei ddt + // al valore di prima, riaggiungendo la quantità che sto togliendo + $rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idddt, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga)); + + // Rimpiazzo la quantità nei ddt + $dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$rs[0]['qta'].' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idddt='.prepare($rs[0]['idddt']).' AND idiva='.prepare($rs[0]['idiva'])); + + $query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga); + + if ($dbo->query($query)) { + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_fattura($id_record); + } else { + ricalcola_costiagg_fattura($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Riga rimossa!'); + } + } + break; + + case 'add_serial': + $idgruppo = $post['idgruppo']; + $serial = $post['serial']; + + $q = 'SELECT * FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idgruppo='.prepare($idgruppo).' ORDER BY id'; + $rs = $dbo->fetchArray($q); + + foreach ($rs as $i => $r) { + $dbo->query('UPDATE co_righe_documenti SET serial='.prepare($serial[$i]).' WHERE id='.prepare($r['id'])); + } + + break; + + case 'update_position': + $start = filter('start'); + $end = filter('end'); + $id = filter('id'); + + if ($start > $end) { + $dbo->query('UPDATE `co_righe_documenti` SET `order`=`order` + 1 WHERE `order`>='.prepare($end).' AND `order`<'.prepare($start).' AND `iddocumento`='.prepare($id_record)); + $dbo->query('UPDATE `co_righe_documenti` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } elseif ($end != $start) { + $dbo->query('UPDATE `co_righe_documenti` SET `order`=`order` - 1 WHERE `order`>'.prepare($start).' AND `order`<='.prepare($end).' AND `iddocumento`='.prepare($id_record)); + $dbo->query('UPDATE `co_righe_documenti` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } + + break; +} + +if (post('op') !== null) { + $rs_sconto = $dbo->fetchArray('SELECT sconto_globale, tipo_sconto_globale FROM co_documenti WHERE id='.prepare($id_record)); + + // Aggiorno l'eventuale sconto gestendolo con le righe in fattura + if ($rs_sconto[0]['tipo_sconto_globale'] == 'PRC' && !empty($rs_sconto[0]['sconto_globale'])) { + // Se lo sconto c'è già lo elimino e lo ricalcolo + $dbo->query("DELETE FROM co_righe_documenti WHERE descrizione LIKE '%SCONTO %' AND iddocumento=".prepare($id_record)); + + $subtotale = get_imponibile_fattura($id_record); + $subtotale = -$subtotale / 100 * $rs_sconto[0]['sconto_globale']; + + // Calcolo anche l'iva da scontare + $rsi = $dbo->fetchArray('SELECT descrizione, percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita'))); + $iva = $subtotale / 100 * $rsi[0]['percentuale']; + + $descrizione = 'SCONTO '.Translator::numberToLocale($rs_sconto[0]['sconto_globale']).'%'; + + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, descrizione, idiva, desc_iva, iva, subtotale, sconto, qta, idgruppo, `order`) VALUES( '.prepare($id_record).', '.prepare($descrizione).', '.prepare($idiva).', '.prepare($rsi[0]['descrizione']).', '.prepare($iva).', '.prepare($subtotale).', 0, 1, (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'); + } +} diff --git a/modules/fatture/add.php b/modules/fatture/add.php new file mode 100644 index 000000000..4205fa4e7 --- /dev/null +++ b/modules/fatture/add.php @@ -0,0 +1,41 @@ + +
+ + + + +
+
+ {[ "type": "date", "label": "", "name": "data", "required": 1, "value": "-now-" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='' AND deleted=0 ORDER BY ragione_sociale", "value": "", "icon-after": "add||tipoanagrafica=" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idtipodocumento", "required": 1, "values": "query=SELECT id, descrizione FROM co_tipidocumento WHERE dir=''", "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/fatture/add_articolo.php b/modules/fatture/add_articolo.php new file mode 100644 index 000000000..de35f9efe --- /dev/null +++ b/modules/fatture/add_articolo.php @@ -0,0 +1,165 @@ +fetchArray($q); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$prc_guadagno = $record[0]['prc_guadagno']; + +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +// Seleziona articolo +// - per i documenti di vendita deve esserci almeno 1 unità +// - per i documenti di acquisto mostro tutti gli articoli +$_SESSION['superselect']['dir'] = $dir; + +/* + Form di inserimento riga documento +*/ +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + '; + +// Articolo +echo ' +
+
+ {[ "type": "select", "label": "'._('Articolo').'", "name": "idarticolo", "required": 1, "value": "'.$idarticolo.'", "ajax-source": "articoli" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +// Nelle fatture di acquisto leggo l'iva di acquisto dal fornitore +if ($dir == 'uscita') { + $rsf = $dbo->fetchArray('SELECT idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica)); + $idiva = $rsf[0]['idiva']; +} + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Quantità +echo ' +
+
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "1", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure" ]} +
'; + +// Costo unitario +echo ' +
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +// Informazioni aggiuntive +echo ' +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
'; + +echo ' + '; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/add_contratto.php b/modules/fatture/add_contratto.php new file mode 100644 index 000000000..f57889788 --- /dev/null +++ b/modules/fatture/add_contratto.php @@ -0,0 +1,88 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +/* + Form di inserimento riga documento +*/ +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + '; + +// Contratto +echo ' +
+
+ {[ "type": "select", "label": "'._('Contratto').'", "name": "idcontratto", "required": 1, "values": "query=SELECT id, CONCAT(\'Contratto numero \', numero, \' - \', nome) AS descrizione, budget, (SELECT SUM(subtotale) FROM co_righe2_contratti WHERE idcontratto=co_contratti.id) AS subtot, (SELECT SUM(sconto) FROM co_righe2_contratti WHERE idcontratto=co_contratti.id) AS sconto FROM co_contratti WHERE idanagrafica='.prepare($idanagrafica).' AND id NOT IN (SELECT idcontratto FROM co_righe_documenti WHERE NOT idcontratto=NULL) AND idstato IN( SELECT id FROM co_staticontratti WHERE fatturabile = 1 AND descrizione != \'Pagato\')", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.text); $(\'#prezzo\').val($data.subtot); $(\'#sconto\').val($data.sconto);\"" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Costo unitario +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/add_ddt.php b/modules/fatture/add_ddt.php new file mode 100644 index 000000000..85034e4b2 --- /dev/null +++ b/modules/fatture/add_ddt.php @@ -0,0 +1,42 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +// Preventivo +echo ' +
+
+ {[ "type": "select", "label": "'._('DDT').'", "name": "id_ddt", "required": 1, "values": "query=SELECT id, CONCAT(\'nr. \', if(numero_esterno != \'\', numero_esterno, numero), \' del \', DATE_FORMAT(data, \'%d-%m-%Y\')) AS descrizione, numero, numero_esterno, DATE_FORMAT(data, \'%d-%m-%Y\') AS data FROM dt_ddt WHERE idanagrafica='.prepare($idanagrafica).' AND idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione=\'Bozza\') AND idtipoddt=(SELECT id FROM dt_tipiddt WHERE dir='.prepare($dir).') ORDER BY data DESC, numero DESC" ]} +
+
'; + +echo ' +
+
+
'; + +echo ' + '; + +?> + + diff --git a/modules/fatture/add_ddt_righe.php b/modules/fatture/add_ddt_righe.php new file mode 100644 index 000000000..322e8d0fc --- /dev/null +++ b/modules/fatture/add_ddt_righe.php @@ -0,0 +1,224 @@ +fetchArray($q); + +$numero = $rs[0]['numero']; +$idanagrafica = $rs[0]['idanagrafica']; +$idpagamento = $rs[0]['idpagamento']; +$idconto = $rs[0]['idconto']; + +/* + Form di inserimento riga documento +*/ +echo ' +
+ + + + '; + +// Selezione righe ddt da portare nella fattura +$query = "SELECT *, IFNULL((SELECT codice FROM mg_articoli WHERE id=idarticolo),'') AS codice FROM dt_ddt INNER JOIN dt_righe_ddt ON dt_ddt.id=dt_righe_ddt.idddt WHERE dt_ddt.id=".prepare($idddt).' AND (qta - qta_evasa) > 0'; +$rs = $dbo->fetchArray($query); + +if (!empty($rs)) { + echo ' +

'._('Seleziona le righe che vuoi inserire nella fattura e la quantità').':

+ + + + + + + + + '; + + $totale = 0.00; + + foreach ($rs as $i => $r) { + // Descrizione + echo ' + + '; + + // Q.tà rimanente + echo ' + '; + + // Q.tà da evadere + echo ' + '; + + // Subtotale + $subtotale = $r['subtotale'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']); + $sconto = $r['sconto'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']); + $iva = $r['iva'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']); + + echo ' + '; + + // Checkbox - da evadere? + echo ' + + '; + + $totale += $subtotale - $sconto + $iva; + } + + // Totale + echo ' + + + + '; + echo ' +
'._('Descrizione').''._('Q.tà').''._('Q.tà da evadere').''._('Subtot.').''._('Da evadere').'
+ + + '; + + if ($r['codice'] != '') { + echo ' + '.$r['codice'].'
'; + } + + echo ' + '.nl2br($r['descrizione']).' + '; + + if ($r['lotto'] != '') { + echo ' +
Lotto: '.$r['lotto']; + } + if ($r['serial'] != '') { + echo ' +
SN: '.$r['serial']; + } + if ($r['altro'] != '') { + echo ' +
'.$r['altro']; + } + + echo ' +
+
+ + + '.Translator::numberToLocale(($r['qta'] - $r['qta_evasa'])).' + + {[ "type": "number", "name": "qta_da_evadere[]", "id": "qta_'.$i.'", "value": "'.($r['qta'] - $r['qta_evasa']).'", "decimals": "qta", "extra": "onkeyup=\"ricalcola_subtotale_riga('.$i.');\"" ]} + + + + + + + '.Translator::numberToLocale($subtotale - $sconto + $iva).' €
'.Translator::numberToLocale($subtotale - $sconto).' + '.Translator::numberToLocale($iva).' +
+ +
+ Totale: + + '.Translator::numberToLocale($totale).' € +
'; +} else { + echo ' +

'._('Non ci sono articoli da evadere in questo ddt').'...

'; +} + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; + +?> + + diff --git a/modules/fatture/add_intervento.php b/modules/fatture/add_intervento.php new file mode 100644 index 000000000..80db64775 --- /dev/null +++ b/modules/fatture/add_intervento.php @@ -0,0 +1,89 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +/* + Form di inserimento riga documento +*/ + +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + '; + +// Intervento +echo ' +
+
+ {[ "type": "select", "label": "'._('Intervento').'", "name": "idintervento", "required": 1, "values": "query=SELECT in_interventi.id, CONCAT(\'Intervento numero \', codice, \' del \', DATE_FORMAT(IFNULL((SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE in_interventi_tecnici.idintervento=in_interventi.id), data_richiesta), \'%d/%m/%Y\')) AS descrizione, (manodopera_scontato + viaggio_scontato + ricambi_scontato + altro_scontato - vw_activity_subtotal.sconto_globale) AS prezzo, IF(idclientefinale='.prepare($idanagrafica).', \'Interventi conto terzi\', \'Interventi diretti\') AS `optgroup`FROM in_interventi JOIN vw_activity_subtotal ON vw_activity_subtotal.id = in_interventi.id WHERE (idanagrafica='.prepare($idanagrafica).' OR idclientefinale='.prepare($idanagrafica).') AND NOT idstatointervento=\'DENY\' AND in_interventi.id NOT IN (SELECT idintervento FROM co_righe_documenti WHERE idintervento IS NOT NULL) AND NOT in_interventi.id IN (SELECT idintervento FROM co_preventivi_interventi WHERE idintervento IS NOT NULL) AND NOT in_interventi.id IN (SELECT idintervento FROM co_righe_contratti WHERE idintervento IS NOT NULL)", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.text); $(\'#prezzo\').val($data.prezzo); $(\'#sconto\').val($data.sconto);\"" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Costo unitario +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€", "disabled": 1 ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/add_preventivo.php b/modules/fatture/add_preventivo.php new file mode 100644 index 000000000..d7228c708 --- /dev/null +++ b/modules/fatture/add_preventivo.php @@ -0,0 +1,92 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +/* + Form di inserimento riga documento +*/ +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + '; + +// Preventivo +echo ' +
+
+ {[ "type": "select", "label": "'._('Preventivo').'", "name": "idpreventivo", "required": 1, "values": "query=SELECT id, CONCAT(\'Preventivo numero \', numero, \' - \', nome) AS descrizione, (SELECT SUM(subtotale) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) AS subtot, (SELECT SUM(sconto) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) AS sconto FROM co_preventivi WHERE idanagrafica='.prepare($idanagrafica).' AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione=\'Accettato\' OR descrizione=\'In lavorazione\' OR descrizione=\'In attesa di conferma\')", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.text); $(\'#prezzo\').val($data.subtot); $(\'#sconto\').val($data.sconto);\"" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Importa righe').'", "name": "import", "value": "1", "placeholder": "'._('Importa tutte le righe del preventivo').'" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Costo unitario +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/add_riga.php b/modules/fatture/add_riga.php new file mode 100644 index 000000000..8a6bb4f7d --- /dev/null +++ b/modules/fatture/add_riga.php @@ -0,0 +1,124 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idconto = $record[0]['idconto']; +$idanagrafica = $record[0]['idanagrafica']; + +/* + Form di inserimento riga documento +*/ +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + '; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d'acconto") != '') { + echo ' +
'; + + // Rivalsa INPS + if (get_var('Percentuale rivalsa INPS') != '') { + echo ' +
+ {[ "type": "select", "label": "'._('Rivalsa INPS').'", "name": "idrivalsainps", "required": 1, "value": "'.get_var('Percentuale rivalsa INPS').'", "values": "query=SELECT * FROM co_rivalsainps" ]} +
'; + } + + // Ritenuta d'acconto + if (get_var("Percentuale ritenuta d'acconto") != '') { + echo ' +
+ {[ "type": "select", "label": "'._("Ritenuta d'acconto").'", "name": "idritenutaacconto", "required": 1, "value": "'.get_var("Percentuale ritenuta d'acconto").'", "values": "query=SELECT * FROM co_ritenutaacconto" ]} +
'; + } + + echo ' +
'; +} + +// Nelle fatture di acquisto leggo l'iva di acquisto dal fornitore +if ($dir == 'uscita') { + $rsf = $dbo->fetchArray("SELECT idiva FROM an_anagrafiche WHERE idanagrafica=".prepare($idanagrafica)); + $idiva_predefinita = $rsf[0]['idiva']; +} + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Quantità +echo ' +
+
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "1", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure" ]} +
'; + +// Costo unitario +echo ' +
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/add_serial.php b/modules/fatture/add_serial.php new file mode 100644 index 000000000..201b76069 --- /dev/null +++ b/modules/fatture/add_serial.php @@ -0,0 +1,108 @@ +fetchArray($q2); + +echo ' +

'._('Articolo').': '.$rs2[0]['codice'].' - '.$rs2[0]['descrizione'].'

+ +
+ + + + '; + +$serials = []; +$array = array_column($rs2, 'serial'); +foreach ($array as $value) { + if (!empty($value)) { + $serials[] = $value; + } +} + +if ($dir == 'entrata') { + echo ' +
+
+ {[ "type": "select", "label": "'._('Serial').'", "name": "serial[]", "multiple": 1, "value": "'.implode(',', $serials).'", "values": "query=SELECT serial AS id, serial AS descrizione FROM vw_serials WHERE dir=\'uscita\' AND serial NOT IN (SELECT serial FROM vw_serials WHERE dir=\'entrata\' AND record != \'fat-'.$id_record.'\')", "extra": "data-maximum=\"'.count($rs2).'\"" ]} +
+
'; +} else { + echo ' +

'._('Inserisci i numeri seriali degli articoli aggiunti:').'

'; + + foreach ($array as $key => $serial) { + if ($key % 3 == 0) { + echo ' +
'; + } + + $res = $dbo->fetchArray("SELECT record FROM vw_serials WHERE dir='entrata' AND serial = ".prepare($serial)); + + echo ' +
+ {[ "type": "text", "name": "serial[]", "value": "'.$serial.'"'.(!empty($res) ? ', "readonly": 1' : '').' ]}'; + + if(!empty($res)){ + $pieces = explode('-', $res[0]['record']); + switch($pieces[0]){ + case 'int': + $modulo = 'Interventi'; + break; + + case 'ddt': + $modulo = 'Ddt di vendita'; + break; + + case 'fat': + $modulo = 'Fatture di vendita'; + break; + + case 'ord': + $modulo = 'Ordini cliente'; + break; + } + + echo ' + '.Modules::link($modulo, $pieces[1], _('Visualizza vendita').' ', null); + } + echo ' +
'; + + if (($key + 1) % 3 == 0) { + echo ' +
+
'; + } + } + if (($key + 1) % 3 != 0) { + echo ' + '; + } +} + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/edit.php b/modules/fatture/edit.php new file mode 100644 index 000000000..12a3dbbe3 --- /dev/null +++ b/modules/fatture/edit.php @@ -0,0 +1,387 @@ +fetchArray('SELECT co_tipidocumento.descrizione, dir FROM co_tipidocumento INNER JOIN co_documenti ON co_tipidocumento.id=co_documenti.idtipodocumento WHERE co_documenti.id='.prepare($id_record)); +$dir = $rs[0]['dir']; +$tipodoc = $rs[0]['descrizione']; + +?> +
+ + +
+ +
+ + + + + +
+
+

+
+ +
+
+ + + +
+
+ +
+ + {[ "type": "span", "label": "'._('Numero fattura').'", "name": "numero","class": "text-center", "value": "$numero$" ]} +
'; +} +?> +
+ {[ "type": "text", "label": "", "name": "numero_esterno", "class": "text-center", "value": "$numero_esterno$" ]} +
+ +
+ {[ "type": "date", "label": "", "maxlength": 10, "name": "data", "required": 1, "value": "$data$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idstatodocumento", "required": 1, "values": "query=SELECT * FROM co_statidocumento", "value": "$idstatodocumento$" ]} +
+ +
+ +
+
+ + {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "ajax-source": "clienti", "value": "$idanagrafica$" ]} + + {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "ajax-source": "fornitori", "value": "$idanagrafica$" ]} + +
+ +
+ {[ "type": "select", "label": "", "name": "idsede", "ajax-source": "sedi", "value": "$idsede$" ]} +
+ + +
+ {[ "type": "select", "label": "", "name": "idagente", "values": "query=SELECT an_anagrafiche_agenti.idagente AS id, ragione_sociale AS descrizione FROM an_anagrafiche_agenti INNER JOIN an_anagrafiche ON an_anagrafiche_agenti.idagente=an_anagrafiche.idanagrafica WHERE an_anagrafiche_agenti.idanagrafica='$idanagrafica$' ORDER BY ragione_sociale", "value": "$idagente$" ]} +
+ + + fetchArray('SELECT * FROM co_scadenziario WHERE iddocumento = '.prepare($id_record)); + echo ' +
+

'._('Scadenze').'

'; + foreach ($scadenze as $scadenza) { + echo ' +

'.Translator::dateToLocale($scadenza['scadenza']).' - '.Translator::numberToLocale($scadenza['da_pagare']).'€

'; + } + echo ' +
'; + } + ?> +
+
+ + +
+
+ {[ "type": "select", "label": "", "name": "idtipodocumento", "required": 1, "values": "query=SELECT id, descrizione FROM co_tipidocumento WHERE dir=''", "value": "$idtipodocumento$" ]} +
+ +
+ + {[ "type": "select", "label": "", "name": "idconto", "required": 1, "value": "$idconto$", "ajax-source": "" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idpagamento", "required": 1, "values": "query=SELECT id, descrizione FROM co_pagamenti GROUP BY descrizione ORDER BY descrizione ASC", "value": "$idpagamento$" ]} +
+ +
+ + + +
+
+ {[ "type": "select", "label": "", "name": "idaspettobeni", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_aspettobeni ORDER BY descrizione ASC", "value": "$idaspettobeni$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idcausalet", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_causalet ORDER BY descrizione ASC", "value": "$idcausalet$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idporto", "placeholder": "-", "values": "query=SELECT id, descrizione FROM dt_porto ORDER BY descrizione ASC", "value": "$idporto$" ]} +
+ +
+ {[ "type": "text", "label": "o colli'); ?>", "name": "n_colli", "value": "$n_colli$" ]} +
+
+ +
+
+ {[ "type": "number", "label": "", "name": "bollo", "value": "$bollo$" ]} +
+
+ + + +
+fetchNum($query2); + +$query3 = 'SELECT SUM(da_pagare-pagato) AS differenza, SUM(da_pagare) FROM co_scadenziario GROUP BY iddocumento HAVING iddocumento='.$id_record.''; +$rs3 = $dbo->fetchArray($query3); +$differenza = $rs3[0]['differenza']; +$da_pagare = $rs3[0]['da_pagare']; + +if (($n2 <= 0 && $records[0]['stato'] == 'Emessa') || $differenza != 0) { + ?> + Aggiungi prima nota...

+ + Riapri fattura... + +
+
+ +
+
+ {[ "type": "number", "label": "", "name": "sconto_generico", "value": "$sconto_globale$", "icon-after": "choice|untprc|$tipo_sconto_globale$" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "", "name": "note", "value": "$note$" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "", "name": "note_aggiuntive", "value": "$note_aggiuntive$" ]} +
+
+ + +
+ +
+
+ +
+ + + + +
+
+

Righe

+
+ +
+
+
+
+fetchArray($qi); + $ni = sizeof($rsi); + + //Se non trovo niente provo a vedere se ce ne sono per clienti terzi + if ($ni == 0) { + //Lettura interventi non rifiutati, non fatturati e non collegati a preventivi o contratti (clienti terzi) + $qi = 'SELECT id FROM in_interventi WHERE idclientefinale='.prepare($records[0]['idanagrafica'])." AND NOT idstatointervento='DENY' AND id NOT IN (SELECT idintervento FROM co_righe_documenti WHERE idintervento IS NOT NULL) AND id NOT IN (SELECT idintervento FROM co_preventivi_interventi WHERE idintervento IS NOT NULL) AND id NOT IN (SELECT idintervento FROM co_righe_contratti WHERE idintervento IS NOT NULL)"; + $rsi = $dbo->fetchArray($qi); + $ni = sizeof($rsi); + } + + //Lettura preventivi accettati, in attesa di conferma o in lavorazione + $qp = 'SELECT id FROM co_preventivi WHERE idanagrafica='.prepare($records[0]['idanagrafica'])." AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione='Accettato' OR descrizione='In lavorazione' OR descrizione='In attesa di conferma')"; + $rsp = $dbo->fetchArray($qp); + $np = sizeof($rsp); + + //Lettura contratti accettati, in attesa di conferma o in lavorazione + $qc = 'SELECT id FROM co_contratti WHERE idanagrafica='.prepare($records[0]['idanagrafica']).' AND id NOT IN (SELECT idcontratto FROM co_righe_documenti WHERE NOT idcontratto=NULL) AND idstato IN( SELECT id FROM co_staticontratti WHERE fatturabile = 1) AND NOT EXISTS (SELECT id FROM co_righe_documenti WHERE co_righe_documenti.idcontratto = co_contratti.id)'; + $rsc = $dbo->fetchArray($qc); + $nc = sizeof($rsc); + + //Lettura ddt + $qd = 'SELECT id FROM dt_ddt WHERE idanagrafica='.prepare($records[0]['idanagrafica']); + $rsd = $dbo->fetchArray($qd); + $nd = sizeof($rsd); + if ($ni > 0) { + ?> + Intervento + + Intervento + 0) { + ?> + Preventivo + + Preventivo + 0) { + ?> + Contratto + + Contratto + 0) { + echo ' + Ddt'; + } else { + echo ' + Ddt'; + } + } ?> + + Articolo + Riga generica + +
+ +
+ +fetchArray('SELECT piva, codice_fiscale, citta, indirizzo, cap, provincia FROM an_anagrafiche WHERE idanagrafica='.prepare($records[0]['idanagrafica'])); + $campi_mancanti = []; + + if ($rs2[0]['piva'] == '') { + if ($rs2[0]['codice_fiscale'] == '') { + array_push($campi_mancanti, 'codice fiscale'); + } + } + if ($rs2[0]['citta'] == '') { + array_push($campi_mancanti, 'citta'); + } + if ($rs2[0]['indirizzo'] == '') { + array_push($campi_mancanti, 'indirizzo'); + } + if ($rs2[0]['cap'] == '') { + array_push($campi_mancanti, 'C.A.P.'); + } + + if ($dir == 'entrata') { + if (sizeof($campi_mancanti) > 0) { + echo "
Prima di procedere alla stampa completa i seguenti campi dell'anagrafica:
".implode(', ', $campi_mancanti).'
+ '.Modules::link('Anagrafiche', $records[0]['idanagrafica'], _('Vai alla scheda anagrafica '), null).'
'; + } else { + if ($records[0]['descrizione_tipodoc'] == 'Fattura accompagnatoria di vendita') { + ?> + Stampa fattura + + Stampa fattura + +
+
+
+
+
+ +
+
+ +
+
+
+
+ +{( "name": "filelist_and_upload", "id_module": "", "id_record": "" )} + + + + + + diff --git a/modules/fatture/edit_riga.php b/modules/fatture/edit_riga.php new file mode 100644 index 000000000..07c955ead --- /dev/null +++ b/modules/fatture/edit_riga.php @@ -0,0 +1,120 @@ +fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); +$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero']; +$idanagrafica = $record[0]['idanagrafica']; + +$idriga = get('idriga'); + +// Info riga +$q = "SELECT * FROM co_righe_documenti WHERE iddocumento=".prepare($id_record)." AND id=".prepare($idriga); +$rsr = $dbo->fetchArray($q); +$sconto = $rsr[0]['sconto_unitario']; +$tipo_sconto = $rsr[0]['tipo_sconto']; +$idarticolo = $rsr[0]['idarticolo']; +$idconto = $rsr[0]['idconto']; + +echo ' +

'.str_replace('_NUM_', $numero, _('Documento numero _NUM_')).'

+ +
+ + + + '; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$rsr[0]['descrizione'].'" ]} +
+
'; + +if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') { + echo ' +
'; + + // Rivalsa INPS + if (get_var('Percentuale rivalsa INPS') != '' || $dir == 'uscita') { + echo ' +
+ {[ "type": "select", "label": "'._('Rivalsa INPS').'", "name": "idrivalsainps", "value": "'.$rsr[0]['idrivalsainps'].'", "values": "query=SELECT * FROM co_rivalsainps" ]} +
'; + } + + // Ritenuta d'acconto + if (get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') { + echo ' +
+ {[ "type": "select", "label": "'._("Ritenuta d'acconto").'", "name": "idritenutaacconto", "value": "'.$rsr[0]['idritenutaacconto'].'", "values": "query=SELECT * FROM co_ritenutaacconto" ]} +
'; + } + + echo ' +
'; +} + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$rsr[0]['idiva'].'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +echo ' +
+ {[ "type": "select", "label": "'._('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]} +
+
'; + +// Quantità +echo ' +
+
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "'.$rsr[0]['qta'].'", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure", "value": "'.$rsr[0]['um'].'" ]} +
'; + +// Costo unitario +echo ' +
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.($rsr[0]['subtotale']/$rsr[0]['qta']).'", "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/fatture/init.php b/modules/fatture/init.php new file mode 100644 index 000000000..cb1c85fbc --- /dev/null +++ b/modules/fatture/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT *, co_documenti.note, co_documenti.note_aggiuntive, co_documenti.idpagamento, co_documenti.id AS iddocumento, co_statidocumento.descrizione AS `stato`, co_tipidocumento.descrizione AS `descrizione_tipodoc`, (SELECT descrizione FROM co_ritenutaacconto WHERE id=idritenutaacconto) AS ritenutaacconto_desc, (SELECT descrizione FROM co_rivalsainps WHERE id=idrivalsainps) AS rivalsainps_desc FROM ((co_documenti LEFT OUTER JOIN co_statidocumento ON co_documenti.idstatodocumento=co_statidocumento.id) INNER JOIN an_anagrafiche ON co_documenti.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($id_record)); +} diff --git a/modules/fatture/modutil.php b/modules/fatture/modutil.php new file mode 100644 index 000000000..ef7f8e66d --- /dev/null +++ b/modules/fatture/modutil.php @@ -0,0 +1,744 @@ +fetchArray($query); + + $numero = $rs[0]['max_numerofattura'] + 1; + + return $numero; +} + +/** + * Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni. + */ +function get_new_numerosecondariofattura($data) +{ + global $dbo; + global $dir; + global $idtipodocumento; + + // DATE_FORMAT( data, '%Y' ) = '".date("Y", strtotime($data))."' + $query = "SELECT numero_esterno FROM co_documenti WHERE DATE_FORMAT( data, '%Y' ) = ".prepare(date('Y', strtotime($data))).' AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='.prepare($dir).') ORDER BY CAST(numero_esterno AS UNSIGNED) DESC LIMIT 0,1'; + $rs = $dbo->fetchArray($query); + $numero_secondario = $rs[0]['numero_esterno']; + + // Calcolo il numero secondario se stabilito dalle impostazioni e se documento di vendita + $formato_numero_secondario = get_var('Formato numero secondario fattura'); + + if ($numero_secondario == '') { + $numero_secondario = $formato_numero_secondario; + } + + if ($formato_numero_secondario != '' && $dir == 'entrata') { + $numero_esterno = get_next_code($numero_secondario, 1, $formato_numero_secondario); + } else { + $numero_esterno = ''; + } + + return $numero_esterno; +} + +/** + * Elimina una scadenza in base al codice documento. + */ +function elimina_scadenza($iddocumento) +{ + global $dbo; + + $query2 = 'DELETE FROM co_scadenziario WHERE iddocumento='.prepare($iddocumento); + $dbo->query($query2); +} + +/** + * Funzione per ricalcolare lo scadenziario di una determinata fattura + * $iddocumento string E' l'id del documento di cui ricalcolare lo scadenziario + * $pagamento string Nome del tipo di pagamento. Se è vuoto lo leggo da co_pagamenti_documenti, perché significa che devo solo aggiornare gli importi. + */ +function aggiungi_scadenza($iddocumento, $pagamento = '') +{ + global $dbo; + + $totale_da_pagare = 0.00; + $totale_fattura = get_totale_fattura($iddocumento); + $netto_fattura = get_netto_fattura($iddocumento); + $imponibile_fattura = get_imponibile_fattura($iddocumento); + $totale_iva = sum(abs($totale_fattura), -abs($imponibile_fattura)); + + // Lettura data di emissione fattura + $query3 = 'SELECT ritenutaacconto, data FROM co_documenti WHERE id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query3); + $data = $rs[0]['data']; + $ritenutaacconto = $rs[0]['ritenutaacconto']; + + // Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale + $query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); + $rs2 = $dbo->fetchArray($query2); + $dir = $rs2[0]['dir']; + + /* + Inserisco la nuova scadenza (anche più di una riga per pagamenti multipli + */ + // Se il pagamento non è specificato lo leggo dal documento + if ($pagamento == '') { + $query = 'SELECT descrizione FROM co_pagamenti WHERE id=(SELECT idpagamento FROM co_documenti WHERE id='.prepare($iddocumento).')'; + $rs = $dbo->fetchArray($query); + $pagamento = $rs[0]['descrizione']; + } + + $query4 = 'SELECT * FROM co_pagamenti WHERE descrizione='.prepare($pagamento); + $rs = $dbo->fetchArray($query4); + for ($i = 0; $i < sizeof($rs); ++$i) { + // X giorni esatti + if ($rs[$i]['giorno'] == 0) { + $scadenza = date('Y-m-d', strtotime($data.' +'.$rs[$i]['num_giorni'].' day')); + } + + // Ultimo del mese + elseif ($rs[$i]['giorno'] < 0) { + $scadenza = date('Y-m-t', strtotime($data.' +'.$rs[$i]['num_giorni'].' day')); + + // Ultimo del mese più X giorni + if ($rs[$i]['giorno'] != -1) { + $scadenza = date('Y-m-d', strtotime($scadenza.' +'.(-$rs[$i]['giorno'] - 1).' day')); + } + } + + // Giorno preciso del mese + else { + $scadenza = date('Y-m-'.$rs[$i]['giorno'], strtotime($data.' +'.$rs[$i]['num_giorni'].' day')); + } + + // All'ultimo ciclo imposto come cifra da pagare il totale della fattura meno gli importi già inseriti in scadenziario per evitare di inserire cifre arrotondate "male" + if ($i == (sizeof($rs) - 1)) { + $da_pagare = sum($netto_fattura, -$totale_da_pagare); + } + + // Totale da pagare (totale x percentuale di pagamento nei casi pagamenti multipli) + else { + $da_pagare = sum($netto_fattura / 100 * $rs[$i]['prc'], 0); + } + $totale_da_pagare = sum($da_pagare, $totale_da_pagare); + + if ($dir == 'uscita') { + $da_pagare = -$da_pagare; + } + + $dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare($scadenza).', '.prepare($da_pagare).", 0, 'fattura')"); + } + + // Se c'è una ritenuta d'acconto, la aggiungo allo scadenzario + if ($dir == 'uscita' && $ritenutaacconto > 0) { + $dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare(date('Y-m', strtotime($data.' +1 month')).'-15').', '.prepare(-$ritenutaacconto).", 0, 'ritenutaacconto')"); + } + + return true; +} + +/** + * Funzione per aggiornare lo stato dei pagamenti nello scadenziario + * $iddocumento int ID della fattura + * $totale_pagato float Totale importo pagato + * $data_pagamento datetime Data in cui avviene il pagamento (yyyy-mm-dd). + */ +function aggiorna_scadenziario($iddocumento, $totale_pagato, $data_pagamento) +{ + global $dbo; + + // Lettura righe scadenziario + $query = "SELECT * FROM co_scadenziario WHERE iddocumento='$iddocumento' AND ABS(pagato) < ABS(da_pagare) ORDER BY scadenza ASC"; + $rs = $dbo->fetchArray($query); + $netto_fattura = get_netto_fattura($iddocumento); + $rimanente = $netto_fattura; + $rimanente_da_pagare = abs($rs[0]['pagato']) + $totale_pagato; + + // Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale + $query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); + $rs2 = $dbo->fetchArray($query2); + $dir = $rs2[0]['dir']; + + // Ciclo tra le rate dei pagamenti per inserire su `pagato` l'importo effettivamente pagato. + // Nel caso il pagamento superi la rata, devo distribuirlo sulle rate successive + for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rimanente_da_pagare > 0) { + // ...riempio il pagato della rata con il totale della rata stessa se ho ricevuto un pagamento superiore alla rata stessa + if (abs($rimanente_da_pagare) >= abs($rs[$i]['da_pagare'])) { + $pagato = abs($rs[$i]['da_pagare']); + $rimanente_da_pagare -= abs($rs[$i]['da_pagare']); + } else { + // Se si inserisce una somma maggiore al dovuto, tengo valido il rimanente per saldare il tutto... + if (abs($rimanente_da_pagare) > abs($rs[$i]['da_pagare'])) { + $pagato = abs($rs[$i]['da_pagare']); + $rimanente_da_pagare -= abs($rs[$i]['da_pagare']); + } + + // ...altrimenti aggiungo l'importo pagato + else { + $pagato = abs($rimanente_da_pagare); + $rimanente_da_pagare -= abs($rs[$i]['da_pagare']) - abs($rs[$i]['pagato']); + } + } + + if ($dir == 'uscita') { + $rimanente_da_pagare = -$rimanente_da_pagare; + } + + if ($pagato > 0) { + if ($dir == 'uscita') { + $dbo->query('UPDATE co_scadenziario SET pagato='.prepare(-$pagato).', data_pagamento='.prepare($data_pagamento).' WHERE id='.prepare($rs[$i]['id'])); + } else { + $dbo->query('UPDATE co_scadenziario SET pagato='.prepare($pagato).', data_pagamento='.prepare($data_pagamento).' WHERE id='.prepare($rs[$i]['id'])); + } + } + } + } +} + +/** + * Elimina i movimenti collegati ad una fattura. + */ +function elimina_movimento($iddocumento, $anche_prima_nota = 0) +{ + global $dbo; + + $query2 = 'DELETE FROM co_movimenti WHERE iddocumento='.prepare($iddocumento).' AND primanota='.prepare($anche_prima_nota); + $dbo->query($query2); +} + +/** + * Funzione per aggiungere la fattura in prima nota + * $iddocumento string E' l'id del documento da collegare alla prima nota + * $dir string Direzione dell'importo (entrata, uscita) + * $primanota boolean Indica se il movimento è un movimento di prima nota o un movimento normale (di default movimento normale). + */ +function aggiungi_movimento($iddocumento, $dir, $primanota = 0) +{ + global $dbo; + + // Totale marca da bollo, inps, ritenuta, idagente + $query = 'SELECT data, bollo, ritenutaacconto, rivalsainps FROM co_documenti WHERE id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $totale_bolli = $rs[0]['bollo']; + $totale_ritenutaacconto = $rs[0]['ritenutaacconto']; + $totale_rivalsainps = $rs[0]['rivalsainps']; + $data_documento = $rs[0]['data']; + + $netto_fattura = get_netto_fattura($iddocumento); + $totale_fattura = get_totale_fattura($iddocumento); + $imponibile_fattura = get_imponibile_fattura($iddocumento); + + // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps + $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); + $rsi = $dbo->fetchArray($qi); + $iva_rivalsainps = $totale_rivalsainps / 100 * $rsi[0]['percentuale']; + + // Lettura iva indetraibile fattura + $query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $iva_indetraibile_fattura = $rs[0]['iva_indetraibile']; + + // Lettura iva delle righe in fattura + $query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $iva_fattura = $rs[0]['iva'] + $iva_rivalsainps - $iva_indetraibile_fattura; + + // Imposto i segni + e - in base se la fattura è di acquisto o vendita + if ($dir == 'uscita') { + $segno_mov1_cliente = -1; + $segno_mov2_ricavivendite = 1; + $segno_mov3_iva = 1; + + $segno_mov4_inps = 1; + $segno_mov5_ritenutaacconto = -1; + $segno_mov6_bollo = 1; + + // Lettura conto fornitore + $query = 'SELECT idconto_fornitore FROM an_anagrafiche INNER JOIN co_documenti ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_documenti.id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $idconto_controparte = $rs[0]['idconto_fornitore']; + + if ($idconto_controparte == '') { + $query = "SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo fornitori'"; + $rs = $dbo->fetchArray($query); + $idconto_controparte = $rs[0]['idconto_fornitore']; + } + } else { + $segno_mov1_cliente = 1; + $segno_mov2_ricavivendite = -1; + $segno_mov3_iva = -1; + + $segno_mov4_inps = -1; + $segno_mov5_ritenutaacconto = 1; + $segno_mov6_bollo = -1; + + // Lettura conto cliente + $query = 'SELECT idconto_cliente FROM an_anagrafiche INNER JOIN co_documenti ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_documenti.id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $idconto_controparte = $rs[0]['idconto_cliente']; + + if ($idconto_controparte == '') { + $query = "SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo clienti'"; + $rs = $dbo->fetchArray($query); + $idconto_controparte = $rs[0]['idconto_cliente']; + } + } + + // Lettura info fattura + $query = 'SELECT *, co_documenti.note, co_documenti.idpagamento, co_documenti.id AS iddocumento, co_statidocumento.descrizione AS `stato`, co_tipidocumento.descrizione AS `descrizione_tipodoc` FROM ((co_documenti LEFT OUTER JOIN co_statidocumento ON co_documenti.idstatodocumento=co_statidocumento.id) INNER JOIN an_anagrafiche ON co_documenti.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $n = sizeof($rs); + $data = $rs[0]['data']; + $idanagrafica = $rs[0]['idanagrafica']; + $ragione_sociale = $rs[0]['ragione_sociale']; + $stato = $rs[0]['stato']; + $idconto = $rs[0]['idconto']; + + // Scrivo il movimento solo se è stato selezionato un conto + if ($idconto != '') { + $idmastrino = get_new_idmastrino(); + + // Prendo il numero doc. esterno se c'è, altrimenti quello normale + if (!empty($rs[0]['numero_esterno'])) { + $numero = $rs[0]['numero_esterno']; + } else { + $numero = $rs[0]['numero']; + } + + $descrizione = $rs[0]['descrizione_tipodoc']." numero $numero"; + + /* + Il mastrino si apre con almeno 3 righe di solito (esempio fattura di vendita): + 1) dare imponibile+iva al conto cliente + 2) avere imponibile sul conto dei ricavi + 3) avere iva sul conto dell'iva a credito (ed eventuale iva indetraibile sul rispettivo conto) + + aggiuntivo: + 4) eventuale rivalsa inps + 5) eventuale ritenuta d'acconto + 6) eventuale marca da bollo + */ + // 1) Aggiungo la riga del conto cliente + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_controparte).', '.prepare(($totale_fattura + $totale_bolli) * $segno_mov1_cliente).', '.prepare($primanota).' )'; + $dbo->query($query2); + + // 2) Aggiungo il totale sul conto dei ricavi/spese scelto + // Lettura descrizione conto ricavi/spese per ogni riga del documento + $righe = $dbo->fetchArray('SELECT idconto, SUM(subtotale - sconto) AS imponibile FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento).' GROUP BY idconto'); + + foreach ($righe as $riga) { + // Retrocompatibilità + $idconto_riga = !empty($riga['idconto']) ? $riga['idconto'] : $idconto; + + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_riga).', '.prepare($riga['imponibile'] * $segno_mov2_ricavivendite).', '.prepare($primanota).')'; + $dbo->query($query2); + } + + // 3) Aggiungo il totale sul conto dell'iva + // Lettura id conto iva + if ($iva_fattura != 0) { + $descrizione_conto_iva = ($dir == 'entrata') ? 'Iva su vendite' : 'Iva su acquisti'; + $query = 'SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='.prepare($descrizione_conto_iva); + $rs = $dbo->fetchArray($query); + $idconto_iva = $rs[0]['id']; + $descrizione_conto_iva = $rs[0]['descrizione']; + + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_iva).', '.prepare($iva_fattura * $segno_mov3_iva).', '.prepare($primanota).')'; + $dbo->query($query2); + } + + // Lettura id conto iva indetraibile + if ($iva_indetraibile_fattura != 0) { + $descrizione_conto_iva2 = 'Iva indetraibile'; + $query = 'SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='.prepare($descrizione_conto_iva2); + $rs = $dbo->fetchArray($query); + $idconto_iva2 = $rs[0]['id']; + $descrizione_conto_iva2 = $rs[0]['descrizione']; + + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_iva2).', '.prepare($iva_indetraibile_fattura * $segno_mov3_iva).', '.prepare($primanota).')'; + $dbo->query($query2); + } + + // 4) Aggiungo la rivalsa INPS se c'è + // Lettura id conto inps + if ($totale_rivalsainps != 0) { + $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='Erario c/INPS'"; + $rs = $dbo->fetchArray($query); + $idconto_inps = $rs[0]['id']; + $descrizione_conto_inps = $rs[0]['descrizione']; + + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_inps).', '.prepare($totale_rivalsainps * $segno_mov4_inps).', '.prepare($primanota).')'; + $dbo->query($query2); + } + + // 5) Aggiungo la ritenuta d'acconto se c'è + // Lettura id conto ritenuta e la storno subito + if ($totale_ritenutaacconto != 0) { + $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione=\"Erario c/ritenute d'acconto\""; + $rs = $dbo->fetchArray($query); + $idconto_ritenutaacconto = $rs[0]['id']; + $descrizione_conto_ritenutaacconto = $rs[0]['descrizione']; + + // DARE nel conto ritenuta + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_ritenutaacconto).', '.prepare($totale_ritenutaacconto * $segno_mov5_ritenutaacconto).', '.prepare($primanota).')'; + $dbo->query($query2); + + // AVERE nel riepilogativo clienti + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_controparte).', '.prepare(($totale_ritenutaacconto * $segno_mov5_ritenutaacconto) * -1).', '.prepare($primanota).')'; + $dbo->query($query2); + } + + // 6) Aggiungo la marca da bollo se c'è + // Lettura id conto marca da bollo + if ($totale_bolli != 0) { + $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='Rimborso spese marche da bollo'"; + $rs = $dbo->fetchArray($query); + $idconto_bolli = $rs[0]['id']; + $descrizione_conto_bolli = $rs[0]['descrizione']; + + $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_bolli).', '.prepare($totale_bolli * $segno_mov6_bollo).', '.prepare($primanota).')'; + $dbo->query($query2); + } + } +} + +/** + * Funzione per generare un nuovo codice per il mastrino. + */ +function get_new_idmastrino() +{ + global $dbo; + + $query = 'SELECT MAX(idmastrino) AS maxidmastrino FROM co_movimenti'; + $rs = $dbo->fetchArray($query); + + return intval($rs[0]['maxidmastrino']) + 1; +} + +/** + * Calcolo imponibile fattura (totale_righe - sconto). + */ +function get_imponibile_fattura($iddocumento) +{ + global $dbo; + + $query = 'SELECT SUM(co_righe_documenti.subtotale - co_righe_documenti.sconto) AS imponibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + + return $rs[0]['imponibile']; +} + +/** + * Calcolo totale fattura (imponibile + iva). + */ +function get_totale_fattura($iddocumento) +{ + global $dbo; + + // Sommo l'iva di ogni riga al totale + $query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + + // Aggiungo la rivalsa inps se c'è + $query2 = 'SELECT rivalsainps FROM co_documenti WHERE id='.prepare($iddocumento); + $rs2 = $dbo->fetchArray($query2); + + // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps + $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); + $rsi = $dbo->fetchArray($qi); + $iva_rivalsainps = $rs2[0]['rivalsainps'] / 100 * $rsi[0]['percentuale']; + + return get_imponibile_fattura($iddocumento) + $rs[0]['iva'] + $iva_rivalsainps + $rs2[0]['rivalsainps']; +} + +/** + * Calcolo netto a pagare fattura (totale - ritenute - bolli). + */ +function get_netto_fattura($iddocumento) +{ + global $dbo; + + $query = 'SELECT ritenutaacconto, bollo FROM co_documenti WHERE id='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + + return get_totale_fattura($iddocumento) - $rs[0]['ritenutaacconto'] + $rs[0]['bollo']; +} + +/** + * Calcolo iva detraibile fattura. + */ +function get_ivadetraibile_fattura($iddocumento) +{ + global $dbo; + + $query = 'SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + + return $rs[0]['iva_detraibile']; +} + +/** + * Calcolo iva indetraibile fattura. + */ +function get_ivaindetraibile_fattura($iddocumento) +{ + global $dbo; + + $query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + + return $rs[0]['iva_indetraibile']; +} + +/** + * Ricalcola i costi aggiuntivi in fattura (rivalsa inps, ritenuta d'acconto, marca da bollo) + * Deve essere eseguito ogni volta che si aggiunge o toglie una riga + * $iddocumento int ID della fattura + * $idrivalsainps int ID della rivalsa inps da applicare. Se omesso viene utilizzata quella impostata di default + * $idritenutaacconto int ID della ritenuta d'acconto da applicare. Se omesso viene utilizzata quella impostata di default + * $bolli float Costi aggiuntivi delle marche da bollo. Se omesso verrà usata la cifra predefinita. + */ +function ricalcola_costiagg_fattura($iddocumento, $idrivalsainps = '', $idritenutaacconto = '', $bolli = '') +{ + global $dbo; + global $dir; + + // Se ci sono righe in fattura faccio i conteggi, altrimenti azzero gli sconti e le spese aggiuntive (inps, ritenuta, marche da bollo) + $query = 'SELECT COUNT(id) AS righe FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + if ($rs[0]['righe'] > 0) { + $totale_imponibile = get_imponibile_fattura($iddocumento); + $totale_fattura = get_totale_fattura($iddocumento); + + // Leggo gli id dei costi aggiuntivi + if ($dir == 'uscita') { + $query2 = 'SELECT bollo FROM co_documenti WHERE id='.prepare($iddocumento); + $rs2 = $dbo->fetchArray($query2); + $bollo = $rs2[0]['bollo']; + } + + $query = 'SELECT SUM(rivalsainps) AS rivalsainps, SUM(ritenutaacconto) AS ritenutaacconto FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); + $rs = $dbo->fetchArray($query); + $rivalsainps = $rs[0]['rivalsainps']; + $ritenutaacconto = $rs[0]['ritenutaacconto']; + + if ($dir == 'entrata') { + // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps + $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); + $rsi = $dbo->fetchArray($qi); + $iva_rivalsainps = $rivalsainps / 100 * $rsi[0]['percentuale']; + } else { + // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps + $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); + $rsi = $dbo->fetchArray($qi); + $iva_rivalsainps = $rivalsainps / 100 * $rsi[0]['percentuale']; + } + + // Leggo la ritenuta d'acconto se c'è + $totale_fattura = get_totale_fattura($iddocumento); + + $query = 'SELECT percentuale FROM co_ritenutaacconto WHERE id='.prepare($idritenutaacconto); + $rs = $dbo->fetchArray($query); + $netto_a_pagare = $totale_fattura - $ritenutaacconto; + + // Leggo la marca da bollo se c'è e se il netto a pagare supera la soglia + $bolli = str_replace(',', '.', $bolli); + $bolli = floatval($bolli); + if ($dir == 'uscita') { + if ($bolli != 0.00) { + $bolli = str_replace(',', '.', $bolli); + if (abs($bolli) > 0 && abs($netto_a_pagare > get_var("Soglia minima per l'applicazione della marca da bollo"))) { + $marca_da_bollo = str_replace(',', '.', $bolli); + } else { + $marca_da_bollo = 0.00; + } + } + } else { + $bolli = str_replace(',', '.', get_var('Importo marca da bollo')); + if (abs($bolli) > 0 && abs($netto_a_pagare) > abs(get_var("Soglia minima per l'applicazione della marca da bollo"))) { + $marca_da_bollo = str_replace(',', '.', $bolli); + } else { + $marca_da_bollo = 0.00; + } + + // Se l'importo è negativo può essere una nota di accredito, quindi cambio segno alla marca da bollo + if ($netto_a_pagare < 0) { + $marca_da_bollo *= -1; + } + } + + $dbo->query('UPDATE co_documenti SET ritenutaacconto='.prepare($ritenutaacconto).', rivalsainps='.prepare($rivalsainps).', iva_rivalsainps='.prepare($iva_rivalsainps).', bollo='.prepare($marca_da_bollo).' WHERE id='.prepare($iddocumento)); + } else { + $dbo->query("UPDATE co_documenti SET ritenutaacconto='0', bollo='0', rivalsainps='0', iva_rivalsainps='0' WHERE id=".prepare($iddocumento)); + } +} + +/** + * Questa funzione aggiunge un articolo in fattura. E' comoda quando si devono inserire + * degli interventi con articoli collegati o preventivi che hanno interventi con articoli collegati! + * $iddocumento integer id della fattura + * $idarticolo integer id dell'articolo da inserire in fattura + * $idiva integer id del codice iva associato all'articolo + * $qta float quantità dell'articolo in fattura + * $prezzo float prezzo totale dell'articolo (prezzounitario*qtà) + * $idintervento integer id dell'intervento da cui arriva l'articolo (per non creare casini quando si rimuoverà un articolo dalla fattura). + */ +function add_articolo_infattura($iddocumento, $idarticolo, $descrizione, $idiva, $qta, $prezzo, $sconto = 0, $sconto_unitario = 0, $tipo_sconto = 'UNT', $idintervento = 0, $lotto = '', $serial = '', $altro = '', $idgruppo = 0, $idconto = 0, $idum = 0) +{ + global $dbo; + global $dir; + + global $idddt; + if ($idddt == '') { + $idddt = 0; + } + + // Lettura unità di misura dell'articolo + if (empty($idum)) { + $query = 'SELECT um FROM mg_articoli WHERE id='.prepare($idarticolo); + $rs = $dbo->fetchArray($query); + $um = $rs[0]['valore']; + } else { + $um = $idum; + } + + if (empty($idgruppo)) { + $idgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(`idgruppo`) + 1, 0) AS idgruppo FROM co_righe_documenti AS t WHERE iddocumento='.prepare($iddocumento))[0]['idgruppo']; + } + + // Lettura iva dell'articolo + $rs2 = $dbo->fetchArray('SELECT * FROM co_iva WHERE id='.prepare($idiva)); + $iva = ($prezzo - $sconto) / 100 * $rs2[0]['percentuale']; + $desc_iva = $rs2[0]['descrizione']; + + if ($qta > 0) { + $rsart = $dbo->fetchArray('SELECT abilita_serial FROM mg_articoli WHERE id='.prepare($idarticolo)); + $qta_in = !empty($rsart[0]['abilita_serial']) ? $qta : 1; + + for ($i = 0; $i < $qta_in; ++$i) { + /* + $iva = $iva / $qta_in; + $qta = $qta / $qta_in; + $ubtotale = $subtotale / $qta_in; + $sconto = $sconto / $qta_in; + + $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; + */ + + $dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idintervento, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, qta, abilita_serial, serial, idconto, um, idgruppo, `order`) VALUES ('.prepare($iddocumento).', '.prepare($idarticolo).', '.(!empty($idintervento) ? prepare($idintervento) : 'NULL').', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($qta).', '.prepare($rsart[0]['abilita_serial']).', '.prepare($serial).', '.prepare($idconto).', '.prepare($um).', '.prepare($idgruppo).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($iddocumento).'))'); + } + + $idriga = $dbo->lastInsertedID(); + + /* + Fatture di vendita + */ + if ($dir == 'entrata') { + // Se il documento non è generato da un ddt o intervento allora movimento il magazzino + if (empty($idddt) && empty($idintervento)) { + add_movimento_magazzino($idarticolo, -$qta, ['iddocumento' => $iddocumento]); + } + } + /* + Fatture di acquisto + */ + elseif ($dir == 'uscita') { + // Se il documento non è generato da un ddt allora movimento il magazzino + if (empty($idddt)) { + add_movimento_magazzino($idarticolo, $qta, ['iddocumento' => $iddocumento]); + } + } + + // Inserisco il riferimento del ddt alla riga + $dbo->query('UPDATE co_righe_documenti SET idddt='.prepare($idddt).' WHERE id='.prepare($idriga)); + } + + return $idriga; +} + +/** + * Questa funzione rimuove un articolo dalla fattura data e lo riporta in magazzino nel primo lotto libero + * a partire dal lotto più vecchio + * $idarticolo integer codice dell'articolo da scollegare dalla fattura + * $iddocumento integer codice della fattura da cui scollegare l'articolo. + */ +function rimuovi_articolo_dafattura($idarticolo, $iddocumento, $idrigadocumento) +{ + global $dbo; + global $dir; + + // Leggo la quantità di questo articolo in fattura + $query = 'SELECT idgruppo, qta, idintervento, idpreventivo, idordine, idddt, subtotale, descrizione, lotto, serial, altro FROM co_righe_documenti WHERE id='.prepare($idrigadocumento); + $rs = $dbo->fetchArray($query); + $idintervento = $rs[0]['idintervento']; + $idpreventivo = $rs[0]['idpreventivo']; + $idddt = $rs[0]['idddt']; + $idordine = $rs[0]['idordine']; + $qta = $rs[0]['qta']; + $subtotale = $rs[0]['subtotale']; + + $idgruppo = $rs[0]['idgruppo']; + + $descrizione = $rs[0]['descrizione']; + + $lotto = $rs[0]['lotto']; + $serial = $rs[0]['serial']; + $altro = $rs[0]['altro']; + + if ($dir == 'uscita') { + $non_rimovibili = $dbo->fetchArray("SELECT COUNT(*) AS non_rimovibili FROM co_righe_documenti WHERE serial IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idgruppo=".prepare($idgruppo).' AND iddocumento='.prepare($iddocumento))[0]['non_rimovibili']; + if ($non_rimovibili != 0) { + return false; + } + } + + // Se l'articolo è stato aggiunto in fattura perché era collegato ad un intervento o + // preventivo o ddt o ordine non devo riportarlo in magazzino quando lo tolgo dalla fattura, perché + // se lo scollegassi poi anche dall'intervento aggiungerei in magazzino la quantità 2 volte!! + if ($qta > 0) { + if (empty($idintervento) && empty($idddt)) { + // Fatture di vendita + if ($dir == 'entrata') { + add_movimento_magazzino($idarticolo, $qta, ['iddocumento' => $iddocumento]); + } + + // Fatture di acquisto + else { + add_movimento_magazzino($idarticolo, -$qta, ['iddocumento' => $iddocumento]); + } + } + + // Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa + if (!empty($idddt)) { + $dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idddt='.prepare($idddt).' AND lotto='.prepare($rs[0]['lotto']).' AND serial='.prepare($rs[0]['serial']).' AND altro='.prepare($rs[0]['altro'])); + } + + // Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa + if (!empty($idordine)) { + $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idordine='.prepare($idordine)); + } + } + + if ($dir == 'uscita') { + // Elimino eventuali articoli caricati in mg_prodotti esclusivamente con la fattura di acquisto + $query = 'SELECT lotto, serial, altro, idarticolo FROM co_righe_documenti WHERE id='.prepare($idrigadocumento).' AND idddt = 0 AND idordine = 0'; + $rs = $dbo->fetchArray($query); + if (sizeof($rs) > 0) { + $dbo->query('DELETE FROM `mg_prodotti` WHERE lotto='.prepare($rs[0]['lotto']).' AND serial='.prepare($rs[0]['serial']).' AND altro='.prepare($rs[0]['altro']).' AND idarticolo='.prepare($rs[0]['idarticolo'])); + } + } + + // Elimino la riga dal documento + $dbo->query('DELETE FROM `co_righe_documenti` WHERE idgruppo='.prepare($idgruppo)); + + // Elimino i movimenti avvenuti nel magazzino per questo articolo lotto, serial, altro + $dbo->query('DELETE FROM `mg_movimenti` WHERE idarticolo = '.prepare($idarticolo).' AND iddocumento = '.prepare($iddocumento).' AND id = '.prepare($idrigadocumento)); + + return true; +} diff --git a/modules/fatture/row-list.php b/modules/fatture/row-list.php new file mode 100644 index 000000000..91aa74596 --- /dev/null +++ b/modules/fatture/row-list.php @@ -0,0 +1,396 @@ +fetchArray($q); + +echo ' + + + + + + + + + + + '; + +if (!empty($rs)) { + foreach ($rs as $r) { + $extra = ''; + + // Articoli + if (!empty($r['idarticolo'])) { + $modulo = Modules::getModule('Articoli')['id']; + $id = $r['idarticolo']; + + $r['descrizione'] = $r['codice'].' - '.$r['descrizione']; + + $delete = 'unlink_articolo'; + + $qserial = 'SELECT * FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idarticolo='.prepare($r['idarticolo']).' AND idgruppo='.prepare($r['idgruppo']); + $rsserial = $dbo->fetchArray($qserial); + + $mancanti = 0; + $serials = []; + + if (!empty($r['abilita_serial'])) { + foreach ($rsserial as $seriali) { + $seriali['serial'] = trim($seriali['serial']); + if (!empty($seriali['serial'])) { + $serials[] = $seriali['serial']; + } else { + ++$mancanti; + } + } + } + + if ($mancanti > 0) { + $extra = 'class="warning"'; + } + } + // Preventivi + elseif (!empty($r['idpreventivo'])) { + $modulo = Modules::getModule('Preventivi')['id']; + $id = $r['idpreventivo']; + + $delete = 'unlink_preventivo'; + } + // Contratti + elseif (!empty($r['idcontratto'])) { + $modulo = Modules::getModule('Contratti')['id']; + $id = $r['idcontratto']; + + $delete = 'unlink_contratto'; + } + // Intervento + elseif (!empty($r['idintervento'])) { + $modulo = Modules::getModule('Interventi')['id']; + $id = $r['idintervento']; + + $delete = 'unlink_intervento'; + } + // Righe generiche + else { + $modulo = 0; + $id = 0; + + $delete = 'unlink_riga'; + } + + echo ' + '; + + echo ' + '; + + echo ' + '; + + // Unità di misura + echo ' + '; + + // Costo unitario + echo ' + '; + + // Iva + echo ' + '; + + // Imponibile + echo ' + '; + + // Possibilità di rimuovere una riga solo se la fattura non è pagata + echo ' + + + '; + } +} + +echo ' + '; + +// Calcoli +$imponibile = sum(array_column($rs, 'subtotale')); +$sconto = sum(array_column($rs, 'sconto')); +$iva = sum(array_column($rs, 'iva')); + +$imponibile_scontato = sum($imponibile, -$sconto); + +$totale_iva = sum($iva, $records[0]['iva_rivalsainps']); + +$totale = sum([ + $imponibile_scontato, + $records[0]['rivalsainps'], + $totale_iva, +]); + +$netto_a_pagare = sum([ + $totale, + $marca_da_bollo, + -$records[0]['ritenutaacconto'], +]); + +// IMPONIBILE +echo ' + + + + + '; + +// SCONTO +if (abs($sconto) > 0) { + echo ' + + + + + '; + + // IMPONIBILE SCONTATO + echo ' + + + + + '; +} + +// RIVALSA INPS +if (abs($records[0]['rivalsainps']) > 0) { + echo ' + + + + + '; +} + +// IVA +if (abs($totale_iva) > 0) { + echo ' + + + + + '; +} + +// TOTALE +echo ' + + + + + '; + +// Mostra marca da bollo se c'è +if (abs($records[0]['bollo']) > 0) { + echo ' + + + + + '; +} + +// RITENUTA D'ACCONTO +if (abs($records[0]['ritenutaacconto']) > 0) { + echo ' + + + + + '; + + //$netto_a_pagare -= $records[0]['ritenutaacconto']; +} + +// NETTO A PAGARE +if ($totale != $netto_a_pagare) { + echo ' + + + + + '; +} + +echo ' +
'._('Descrizione').''._('Q.tà').''._('U.m.').''._('Costo unitario').''._('Iva').''._('Imponibile').'
+ '.Modules::link($modulo, $id, $r['descrizione']).' + '.$r['descrizione_conto'].''; + + if (!empty($r['abilita_serial'])) { + if (!empty($mancanti)) { + echo ' +
'.str_replace('_NUM_', $mancanti, _('_NUM_ serial mancanti')).''; + } + if (!empty($serials)) { + echo ' +
'._('SN').': '.implode(', ', $serials); + } + } else { + if ($r['lotto'] != '') { + echo ' +
'._('Lotto').': '.$r['lotto']; + } + if ($r['serial'] != '') { + echo ' +
'._('SN').': '.$r['serial']; + } + if ($r['altro'] != '') { + echo ' +
'.$r['altro']; + } + } + + // Aggiunta riferimento a ordine + if (!empty($r['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id='.prepare($r['idordine'])); + $numero = ($rso[0]['numero_esterno'] != '') ? $rso[0]['numero_esterno'] : $rso[0]['numero']; + echo ' +
'.str_replace(['_NUM_', '_DATE_'], [$numero, Translator::dateToLocale($rso[0]['data'])], _('Rif. ordine _NUM_ del _DATE_')); + } elseif (!empty($r['idddt'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM dt_ddt WHERE id='.prepare($r['idddt'])); + $numero = ($rso[0]['numero_esterno'] != '') ? $rso[0]['numero_esterno'] : $rso[0]['numero']; + echo ' +
'.str_replace(['_NUM_', '_DATE_'], [$numero, Translator::dateToLocale($rso[0]['data'])], _('Rif. ddt _NUM_ del _DATE_')); + } elseif (!empty($r['idpreventivo'])) { + $rso = $dbo->fetchArray('SELECT numero, data_bozza FROM co_preventivi WHERE id='.prepare($r['idpreventivo'])); + echo ' +
'.str_replace(['_NUM_', '_DATE_'], [$rso[0]['numero'], Translator::dateToLocale($rso[0]['data_bozza'])], _('Rif. preventivo _NUM_ del _DATE_')); + } + + echo ' +
+ '.Translator::numberToLocale($r['qta']).' + + '.$r['um'].' + + '.Translator::numberToLocale($r['subtotale'] / $r['qta']).' €'; + + if ($r['sconto_unitario'] > 0) { + echo ' +
- sconto '.Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €').''; + } + + echo ' +
+ '.Translator::numberToLocale($r['iva']).' € +
'.$r['desc_iva'].' +
+ '.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' € + '; + + if ($records[0]['stato'] != 'Pagato' && $records[0]['stato'] != 'Emessa' && strpos($r['descrizione'], 'SCONTO') === false) { + echo " +
+ + + "; + + if (!empty($r['idarticolo'])) { + echo " + "; + } + + echo " +
"; + + if (!empty($r['idarticolo']) && $r['abilita_serial'] && (empty($r['idddt']) || empty($r['idintervento']))) { + echo " + "; + } + + echo " + + +
+
"; + } + + if (strpos($r['descrizione'], 'SCONTO') === false) { + echo ' +
+ +
'; + } + + echo ' +
+ '.strtoupper(_('Imponibile')).': + + '.Translator::numberToLocale($imponibile).' € +
+ '.strtoupper(_('Sconto')).': + + '.Translator::numberToLocale($sconto).' € +
+ '.strtoupper(_('Imponibile scontato')).': + + '.Translator::numberToLocale($imponibile_scontato).' € +
+ '.strtoupper(_('Rivalsa INPS')).': + + '.Translator::numberToLocale($records[0]['rivalsainps']).' € +
+ '.strtoupper(_('Iva')).': + + '.Translator::numberToLocale($totale_iva).' € +
+ '.strtoupper(_('Totale')).': + + '.Translator::numberToLocale($totale).' € +
+ '.strtoupper(_('Marca da bollo')).': + + '.Translator::numberToLocale($records[0]['bollo']).' € +
+ '.strtoupper(_("Ritenuta d'acconto")).': + + '.Translator::numberToLocale($records[0]['ritenutaacconto']).' € +
+ '.strtoupper(_('Netto a pagare')).': + + '.Translator::numberToLocale($netto_a_pagare).' € +
'; + +echo ' +'; diff --git a/modules/gestione_componenti/actions.php b/modules/gestione_componenti/actions.php new file mode 100644 index 000000000..e97d0800e --- /dev/null +++ b/modules/gestione_componenti/actions.php @@ -0,0 +1,52 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "nomefile", "required": 1, "value": "" ]} +
+ + +
+ [Default] + {[ "type": "textarea", "label": "", "name": "contenuto", "required": 1, "class": "autosize", "value": "", "extra": "rows='10'" ]} +
+
+ + +
+
+ +
+
+
+ + diff --git a/modules/gestione_componenti/edit.php b/modules/gestione_componenti/edit.php new file mode 100644 index 000000000..ce4cd7855 --- /dev/null +++ b/modules/gestione_componenti/edit.php @@ -0,0 +1,68 @@ + + + + '._('Numero').' + '._('Nome del file').' + + + '; + + for ($c = 1; $c <= count($cmp); ++$c) { + echo ' + + '.$c.' + '.$cmp[$c-1][0].' + '; + } + echo ' + + '; +} else { + ?> +
+ + + + +
+
+

+
+ +
+ +
+ +
+
+ +
+
+ {[ "type": "text", "label": "", "name": "nomefile", "required": 1, "value": "$nomefile$", "readonly": 1 ]} +
+
+ + +
+
+ {[ "type": "textarea", "label": "", "name": "contenuto", "required": 1, "class": "autosize", "value": "$contenuto$" ]} +
+
+ +
+
+
+ + + + + + $value) { + $results = $dbo->fetchArray('SELECT * FROM `zz_settings` WHERE `idimpostazione`='.prepare($id).' AND editable = 1'); + $result = $results[0]; + + // integer + if ($result['tipo'] == 'integer') { + if (!preg_match('/^\d*$/', $value)) { + $_SESSION['errors'][] = str_replace('_NAME_', '"'.$result['nome'].'"', _('Il valore inserito del parametro _NAME_ deve essere un numero intero!')); + } + } + + // list + // verifico che il valore scelto sia nella lista enumerata nel db + elseif (preg_match("/list\[(.+?)\]/", $result['tipo'], $m)) { + $continue = false; + $m = explode(',', $m[1]); + for ($i = 0; $i < count($m); ++$i) { + if ($m[$i] == $value) { + $continue = true; + } + } + + if (!$continue) { + $_SESSION['errors'][] = str_replace('_NAME_', '"'.$result['nome'].'"', _('Il valore inserito del parametro _NAME_ deve essere un compreso tra i valori previsti!')); + } + } + + // Boolean (checkbox) + elseif ($result['tipo'] == 'boolean') { + $value = (empty($value) || $value == 'off') ? false : true; + } + + if (empty($_SESSION['errors'])) { + $dbo->query('UPDATE `zz_settings` SET `valore`='.prepare($value).' WHERE `idimpostazione`='.prepare($id)); + } + } + + if (count($_SESSION['errors']) <= 0) { + $_SESSION['infos'][] = _('Impostazioni aggiornate correttamente!'); + } + + break; +} diff --git a/modules/impostazioni/edit.php b/modules/impostazioni/edit.php new file mode 100644 index 000000000..abe47b671 --- /dev/null +++ b/modules/impostazioni/edit.php @@ -0,0 +1,74 @@ + + + + + +
+
+

'._('Valori della sezione').'

+
+ +
+
+ +
+

+ '; +foreach ($records as $record) { + // Scelta fra più valori + echo ' +
'; + if (preg_match("/list\[(.+?)\]/", $record['tipo'], $m)) { + $m = explode(',', $m[1]); + $list = ''; + for ($j = 0; $j < count($m); ++$j) { + if ($j != 0) { + $list .= ','; + } + $list .= '\\"'.$m[$j].'\\": \\"'.$m[$j].'\\"'; + } + echo ' + {[ "type": "select", "label": "'.$record['nome'].'", "name": "'.$record['idimpostazione'].'", "values": "list='.$list.'", "value": "'.$record['valore'].'" ]}'; + } + + // query + elseif (preg_match('/^query=(.+?)$/', $record['tipo'], $m)) { + echo ' + {[ "type": "select", "label": "'.$record['nome'].'", "name": "'.$record['idimpostazione'].'", "values": "'.$record['tipo'].'", "value": "'.$record['valore'].'" ]}'; + } + + // Boolean (checkbox) + elseif ($record['tipo'] == 'boolean') { + echo ' + {[ "type": "checkbox", "label": "'.$record['nome'].'", "name": "'.$record['idimpostazione'].'", "placeholder": "'._('Attivo').'", "value": "'.$record['valore'].'" ]}'; + } elseif ($record['tipo'] == 'textarea') { + echo ' + {[ "type": "textarea", "label": "'.$record['nome'].'", "name": "'.$record['idimpostazione'].'", "value": '.json_encode($record['valore']).' ]}'; + } + // Campo di testo normale + else { + $numerico = in_array($record['tipo'], ['integer', 'decimal']); + + $tipo = (preg_match('/password/i', $record['nome'], $m)) ? 'password' : $tipo; + $tipo = $numerico ? 'number' : 'text'; + + echo ' + {[ "type": "'.$tipo.'", "label": "'.$record['nome'].'", "name": "'.$record['idimpostazione'].'", "value": "'.$record['valore'].'"'.($numerico && $record['tipo'] == 'integer' ? ', "decimals": 0' : '').' ]}'; + } + echo ' +
'; +} +echo ' +

+
+ +
+
+
+ +'; diff --git a/modules/impostazioni/init.php b/modules/impostazioni/init.php new file mode 100644 index 000000000..f3fc40a59 --- /dev/null +++ b/modules/impostazioni/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM `zz_settings` WHERE `sezione`=(SELECT sezione FROM `zz_settings` WHERE `idimpostazione`='.prepare($id_record).") AND `editable`='1'"); +} diff --git a/modules/interventi/actions.php b/modules/interventi/actions.php new file mode 100644 index 000000000..4e6a36aa1 --- /dev/null +++ b/modules/interventi/actions.php @@ -0,0 +1,622 @@ +query('DELETE FROM co_preventivi_interventi WHERE idintervento='.prepare($id_record)); + if (!empty($idpreventivo)) { + $dbo->insert('co_preventivi_interventi', [ + 'idintervento' => $id_record, + 'idpreventivo' => $idpreventivo, + ]); + } + + /* + Collegamento intervento a contratto (se impostato). + Oltre al collegamento al contratto, l'intervento è collegato ad una riga di pianificazione, perciò è importante considerarla se è impostata + */ + $array = [ + 'idintervento' => $id_record, + 'idtipointervento' => $idtipointervento, + 'data_richiesta' => $data_richiesta, + 'richiesta' => $richiesta, + 'idsede' => $idsede ?: 0, + ]; + // Creazione nuova pianificazione se non era impostata + if (!empty($idcontratto) && empty($idcontratto_riga)) { + // Se questo intervento era collegato ad un altro contratto aggiorno le informazioni... + $rs = $dbo->fetchArray('SELECT id FROM co_righe_contratti WHERE idintervento='.prepare($id_record)); + if (empty($rs)) { + $dbo->insert('co_righe_contratti', array_merge(['idcontratto' => $idcontratto], $array)); + } + + // ...altrimenti se sto cambiando contratto aggiorno solo l'id del nuovo contratto + else { + $dbo->update('co_righe_contratti', ['idcontratto' => $idcontratto], ['idintervento' => $id_record]); + } + } + + // Pianificazione già impostata, aggiorno solo il codice intervento + elseif (!empty($idcontratto) && !empty($idcontratto_riga)) { + $dbo->update('co_righe_contratti', $array, ['idcontratto' => $idriga, 'id' => $idcontratto_riga]); + } + + // Se non è impostato nessun contratto o riga, tolgo il collegamento dell'intervento al contratto + elseif (empty($idcontratto)) { + $dbo->update('co_righe_contratti', ['idintervento' => null], ['idintervento' => $id_record]); + } + + // Aggiorna tutte le sessioni di lavoro + $lista = (array) post('id_'); + + // Limitazione delle azioni dei tecnici + if ($user['gruppo'] == 'Tecnici') { + $lista = get_var('Mostra i prezzi al tecnico') && !empty($user['idanagrafica']) ? [$user['idanagrafica']] : []; + } + + foreach ($lista as $idriga) { + // Lettura delle date di inizio e fine intervento (dd/mm/yyyy hh:mm - dd/mm/yyyy hh:mm) + $orario = post('orario')[$idriga]; + $v = explode(' - ', $orario); + + $orario_inizio = Translator::timestampToEnglish($v[0]); + $orario_fine = Translator::timestampToEnglish($v[1]); + + $km = post('km')[$idriga]; + $ore = post('ore')[$idriga]; + + // Lettura tariffe in base al tipo di intervento ed al tecnico + $idtipointervento_tecnico = $post['idtipointerventot'][$idriga]; + $rs = $dbo->fetchArray('SELECT * FROM in_interventi_tecnici WHERE idtecnico='.prepare($post['idtecnico'][$idriga]).' AND idintervento='.prepare($id_record)); + + if ($idtipointervento_tecnico != $rs[0]['idtipointervento']) { + $rs = $dbo->fetchArray('SELECT * FROM in_tariffe WHERE idtecnico='.prepare($post['idtecnico'][$idriga]).' AND idtipointervento='.prepare($idtipointervento_tecnico)); + + $prezzo_ore_unitario = $rs[0]['costo_ore']; + $prezzo_km_unitario = $rs[0]['costo_km']; + $prezzo_dirittochiamata = $rs[0]['costo_dirittochiamata']; + $prezzo_ore_unitario_tecnico = $rs[0]['costo_ore_tecnico']; + $prezzo_km_unitario_tecnico = $rs[0]['costo_km_tecnico']; + $prezzo_dirittochiamata_tecnico = $rs[0]['costo_dirittochiamata_tecnico']; + } else { + $prezzo_ore_unitario = $rs[0]['prezzo_ore_unitario']; + $prezzo_km_unitario = $rs[0]['prezzo_km_unitario']; + $prezzo_dirittochiamata = $rs[0]['prezzo_dirittochiamata']; + $prezzo_ore_unitario_tecnico = $rs[0]['prezzo_ore_unitario_tecnico']; + $prezzo_km_unitario_tecnico = $rs[0]['prezzo_km_unitario_tecnico']; + $prezzo_dirittochiamata_tecnico = $rs[0]['prezzo_dirittochiamata_tecnico']; + } + + // Totali + $prezzo_ore_consuntivo = $prezzo_ore_unitario * $ore + $prezzo_dirittochiamata; + $prezzo_km_consuntivo = $prezzo_km_unitario * $km; + + $prezzo_ore_consuntivo_tecnico = $prezzo_ore_unitario_tecnico * $ore + $prezzo_dirittochiamata_tecnico; + $prezzo_km_consuntivo_tecnico = $prezzo_km_unitario_tecnico * $km; + + // Sconti + $sconto_unitario = post('sconto')[$idriga]; + $tipo_sconto = post('tipo_sconto')[$idriga]; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo_ore_consuntivo * $sconto_unitario) / 100 : $sconto_unitario; + + $scontokm_unitario = post('scontokm')[$idriga]; + $tipo_scontokm = post('tipo_scontokm')[$idriga]; + $scontokm = ($tipo_scontokm == 'PRC') ? ($prezzo_km_consuntivo * $sconto_unitario) / 100 : $scontokm_unitario; + + $dbo->update('in_interventi_tecnici', [ + 'idintervento' => $id_record, + 'idtipointervento' => $idtipointervento_tecnico, + 'idtecnico' => post('idtecnico')[$idriga], + + 'orario_inizio' => $orario_inizio, + 'orario_fine' => $orario_fine, + 'ore' => $ore, + 'km' => $km, + + 'prezzo_ore_unitario' => $prezzo_ore_unitario, + 'prezzo_km_unitario' => $prezzo_km_unitari, + 'prezzo_dirittochiamata' => $prezzo_dirittochiamata, + 'prezzo_ore_unitario_tecnico' => $prezzo_ore_unitario_tecnico, + 'prezzo_km_unitario_tecnico' => $prezzo_km_unitario_tecnico, + 'prezzo_dirittochiamata_tecnico' => $prezzo_dirittochiamata_tecnico, + + 'prezzo_ore_consuntivo' => $prezzo_ore_consuntivo, + 'prezzo_km_consuntivo' => $prezzo_km_consuntivo, + 'prezzo_ore_consuntivo_tecnico' => $prezzo_ore_consuntivo_tecnico, + 'prezzo_km_consuntivo_tecnico' => $prezzo_km_consuntivo_tecnico, + + 'sconto' => $sconto, + 'sconto_unitario' => $sconto_unitario, + 'tipo_sconto' => $tipo_sconto, + + 'scontokm' => $scontokm, + 'scontokm_unitario' => $scontokm_unitario, + 'tipo_scontokm' => $tipo_scontokm, + ], ['id' => $idriga]); + } + + $tipo_sconto = $post['tipo_sconto_globale']; + $sconto = $post['sconto_globale']; + + // Salvataggio modifiche intervento + $dbo->update('in_interventi', [ + 'data_richiesta' => $data_richiesta, + 'richiesta' => $richiesta, + 'descrizione' => post('descrizione'), + 'informazioniaggiuntive' => post('informazioniaggiuntive'), + + 'idanagrafica' => post('idanagrafica'), + 'idclientefinale' => post('idclientefinale'), + 'idreferente' => post('idreferente'), + 'idtipointervento' => $idtipointervento, + + 'idstatointervento' => post('idstatointervento'), + 'idsede' => $idsede, + 'idautomezzo' => post('idautomezzo'), + + 'sconto_globale' => $sconto, + 'tipo_sconto_globale' => $tipo_sconto, + ], ['id' => $id_record]); + + $_SESSION['infos'][] = _('Informazioni salvate correttamente!'); + + break; + + case 'add': + $codice = post('codice'); + + // Controlli sul codice + $count = -1; + do { + $new_codice = ($count < 0) ? $codice : get_next_code($codice, 1, get_var('Formato codice intervento')); + $rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice='.prepare($new_codice)); + ++$count; + } while (!empty($rs) || empty($new_codice)); + + if ($count > 0) { + $_SESSION['warnings'][] = str_replace('_NUM_', "'".$codice."'", _('Numero intervento _NUM_ saltato perchè già esistente!')); + $_SESSION['warnings'][] = str_replace('_NUM_', "'".$new_codice."'", _('Nuovo numero intervento calcolato _NUM_')); + } + + $codice = $new_codice; + + // Informazioni di base + $idpreventivo = post('idpreventivo'); + $idcontratto = post('idcontratto'); + $idcontratto_riga = post('idcontratto_riga'); + $idtipointervento = post('idtipointervento'); + $idsede = post('idsede'); + $data_richiesta = post('data_richiesta'); + $richiesta = post('richiesta'); + + if (!empty($codice) && !empty($post['idanagrafica']) && !empty($post['idtipointervento'])) { + // Salvataggio modifiche intervento + $dbo->insert('in_interventi', [ + 'idanagrafica' => post('idanagrafica'), + 'idclientefinale' => post('idclientefinale') ?: 0, + 'idstatointervento' => post('idstatointervento'), + 'idtipointervento' => $idtipointervento, + 'idsede' => $idsede ?: 0, + 'idautomezzo' => $idautomezzo ?: 0, + + 'codice' => $codice, + 'data_richiesta' => $data_richiesta, + 'richiesta' => $richiesta, + ]); + + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = _('Aggiunto nuovo intervento!'); + } + + // Collego l'intervento al preventivo + if (!empty($idpreventivo)) { + $dbo->insert('co_preventivi_interventi', [ + 'idintervento' => $id_record, + 'idpreventivo' => $idpreventivo, + ]); + } + + // Collego l'intervento al contratto + if (!empty($idcontratto)) { + $array = [ + 'idintervento' => $id_record, + 'idtipointervento' => $idtipointervento, + 'data_richiesta' => $data_richiesta, + 'richiesta' => $richiesta, + 'idsede' => $idsede ?: 0, + ]; + + // Se è specificato che l'intervento fa parte di una pianificazione aggiorno il codice dell'intervento sulla riga della pianificazione + if (!empty($idcontratto_riga)) { + $dbo->update('co_righe_contratti', $array, ['idcontratto' => $idcontratto, 'id' => $idcontratto_riga]); + } + // Altrimenti inserisco una nuova pianificazione e collego l'intervento + else { + $dbo->insert('co_righe_contratti', array_merge(['idcontratto' => $idcontratto], $array)); + } + } + + if (!empty($post['idordineservizio'])) { + $dbo->query('UPDATE co_ordiniservizio SET idintervento='.prepare($id_record).' WHERE id='.prepare($post['idordineservizio'])); + } + + // Collegamenti tecnici/interventi + $idtecnici = post('idtecnico'); + $data = post('data'); + + foreach ($idtecnici as $idtecnico) { + add_tecnico($id_record, $idtecnico, $data.' '.post('orario_inizio'), $data.' '.post('orario_fine'), $idcontratto); + } + + // Collegamenti intervento/impianti + $impianti = (array) post('idimpianti'); + if (!empty($impianti)) { + foreach ($impianti as $impianto) { + $dbo->insert('my_impianti_interventi', [ + 'idintervento' => $id_record, + 'idimpianto' => $impianto, + ]); + } + + // Collegamenti intervento/componenti + $componenti = (array) post('componenti'); + foreach ($componenti as $componente) { + $dbo->insert('my_componenti_interventi', [ + 'id_intervento' => $id_record, + 'id_componente' => $componente, + ]); + } + } + + if (post('ref') == 'dashboard') { + $_SESSION['infos'] = []; + $_SESSION['warnings'] = []; + } + + break; + + // Eliminazione intervento + case 'delete': + // Elimino anche eventuali file caricati + $rs = $dbo->fetchArray('SELECT filename FROM zz_files WHERE id_module='.prepare($id_module).' AND id='.prepare($id_record)); + + for ($i = 0; $i < count($rs); ++$i) { + @unlink($docroot.'/files/interventi/'.$rs[$i]['filename']); + } + + $dbo->query('DELETE FROM zz_files WHERE id_module='.prepare($id_module).' AND id='.prepare($id_record)); + + /* + Riporto in magazzino gli articoli presenti nell'intervento in cancellazine + */ + // Leggo la quantità attuale nell'intervento + $q = 'SELECT qta, idautomezzo, idarticolo FROM mg_articoli_interventi WHERE idintervento='.prepare($id_record); + $rs = $dbo->fetchArray($q); + + for ($i = 0; $i < count($rs); ++$i) { + $qta = $rs[$i]['qta']; + $idautomezzo = $rs[$i]['idautomezzo']; + $idarticolo = $rs[$i]['idarticolo']; + + add_movimento_magazzino($idarticolo, $qta, ['idautomezzo' => $idautomezzo, 'idintervento' => $id_record]); + } + + // Eliminazione associazioni tra interventi e contratti + $query = 'UPDATE co_righe_contratti SET idintervento = NULL WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione dell'intervento + $query = 'DELETE FROM in_interventi WHERE id='.prepare($id_record).' '.Modules::getAdditionalsQuery($id_module); + $dbo->query($query); + + // Elimino i collegamenti degli articoli a questo intervento + $dbo->query('DELETE FROM mg_articoli_interventi WHERE idintervento='.prepare($id_record)); + + // Elimino il collegamento al componente + $dbo->query('DELETE FROM my_impianto_componenti WHERE idintervento='.prepare($id_record)); + + // Eliminazione associazione tecnici collegati all'intervento + $query = 'DELETE FROM in_interventi_tecnici WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione associazioni tra interventi e preventivi + $query = 'DELETE FROM co_preventivi_interventi WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione righe aggiuntive dell'intervento + $query = 'DELETE FROM in_righe_interventi WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione associazione interventi e articoli + $query = 'DELETE FROM mg_articoli_interventi WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione associazione interventi e my_impianti + $query = 'DELETE FROM my_impianti_interventi WHERE idintervento='.prepare($id_record); + $dbo->query($query); + + // Eliminazione movimenti riguardanti l'intervento cancellato + $dbo->query('DELETE FROM mg_movimenti WHERE idintervento='.prepare($id_record)); + + $_SESSION['infos'][] = str_replace('_NUM_', "'".$id_record."'", _('Intervento _NUM_ eliminato!')); + + break; + + /* + Gestione righe generiche + */ + case 'addriga': + $descrizione = post('descrizione'); + $qta = post('qta'); + $um = post('um'); + $prezzo_vendita = post('prezzo_vendita'); + $prezzo_acquisto = post('prezzo_acquisto'); + + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo_vendita * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $dbo->query('INSERT INTO in_righe_interventi(descrizione, qta, um, prezzo_vendita, prezzo_acquisto, sconto, sconto_unitario, tipo_sconto, idintervento) VALUES ('.prepare($descrizione).', '.prepare($qta).', '.prepare($um).', '.prepare($prezzo_vendita).', '.prepare($prezzo_acquisto).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($id_record).')'); + + break; + + case 'editriga': + $idriga = post('idriga'); + $descrizione = post('descrizione'); + $qta = post('qta'); + $um = post('um'); + $prezzo_vendita = post('prezzo_vendita'); + $prezzo_acquisto = post('prezzo_acquisto'); + + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo_vendita * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + $dbo->query('UPDATE in_righe_interventi SET '. + ' descrizione='.prepare($descrizione).','. + ' qta='.prepare($qta).','. + ' um='.prepare($um).','. + ' prezzo_vendita='.prepare($prezzo_vendita).','. + ' prezzo_acquisto='.prepare($prezzo_acquisto).','. + ' sconto='.prepare($sconto).','. + ' sconto_unitario='.prepare($sconto_unitario).','. + ' tipo_sconto='.prepare($tipo_sconto). + ' WHERE id='.prepare($idriga)); + + break; + + case 'delriga': + $idriga = post('idriga'); + $dbo->query('DELETE FROM in_righe_interventi WHERE id='.prepare($idriga).' '.Modules::getAdditionalsQuery($id_module)); + + break; + + /* + GESTIONE ARTICOLI + */ + + case 'editarticolo': + $idriga = post('idriga'); + $idarticolo = post('idarticolo'); + $idimpianto = post('idimpianto'); + $idautomezzo = post('idautomezzo'); + + $idarticolo_originale = post('idarticolo_originale'); + + // Leggo la quantità attuale nell'intervento + $q = 'SELECT qta, idautomezzo, idimpianto, serial FROM mg_articoli_interventi WHERE idarticolo='.prepare($idarticolo_originale).' AND idintervento='.prepare($id_record); + $rs = $dbo->fetchArray($q); + $qta = $rs[0]['qta']; + $idimpianto = $rs[0]['idimpianto']; + $idautomezzo = $rs[0]['idautomezzo']; + + $serials = array_column($rs, 'serial'); + + add_movimento_magazzino($idarticolo_originale, $qta, ['idautomezzo' => $idautomezzo, 'idintervento' => $id_record]); + + $rs = $dbo->fetchArray('SELECT idgruppo FROM mg_articoli_interventi WHERE id='.prepare($idriga)); + $idgruppo = $rs[0]['idgruppo']; + + // Elimino questo articolo dall'intervento + $dbo->query('DELETE FROM mg_articoli_interventi WHERE idgruppo='.prepare($idgruppo)); + + // Elimino il collegamento al componente + $dbo->query('DELETE FROM my_impianto_componenti WHERE idimpianto='.prepare($idimpianto).' AND idintervento='.prepare($id_record)); + + /* Ricollego l'articolo modificato all'intervento */ + /* ci può essere il caso in cui cambio idarticolo e anche qta */ + + case 'addarticolo': + $idarticolo = post('idarticolo'); + $idautomezzo = post('idautomezzo'); + $descrizione = post('descrizione'); + $idimpianto = post('idimpianto'); + $qta = post('qta'); + $um = post('um'); + $prezzo_vendita = post('prezzo_vendita'); + + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo_vendita * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // Decremento la quantità + add_movimento_magazzino($idarticolo, -$qta, ['idautomezzo' => $idautomezzo, 'idintervento' => $id_record]); + + // Aggiorno l'automezzo dell'intervento + $dbo->query('UPDATE in_interventi SET idautomezzo='.prepare($idautomezzo).' WHERE id='.prepare($id_record).' '.Modules::getAdditionalsQuery($id_module)); + + // Calcolo idgruppo per questo inserimento + $ridgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(idgruppo) + 1, 0) AS idgruppo FROM mg_articoli_interventi WHERE idintervento = '.prepare($id_record)); + $idgruppo = $ridgruppo[0]['idgruppo']; + + $rsart = $dbo->fetchArray('SELECT abilita_serial, prezzo_acquisto FROM mg_articoli WHERE id='.prepare($idarticolo)); + $qta_in = !empty($rsart[0]['abilita_serial']) ? $qta : 1; + $prezzo_acquisto = $rsart[0]['prezzo_acquisto']; + + for ($i = 0; $i < $qta_in; ++$i) { + // Aggiunto il collegamento fra l'articolo e l'intervento + $dbo->query('INSERT INTO mg_articoli_interventi(idarticolo, idintervento, idimpianto, idautomezzo, descrizione, prezzo_vendita, prezzo_acquisto, sconto, sconto_unitario, tipo_sconto, idiva_vendita, qta, um, abilita_serial, serial, idgruppo) VALUES ('.prepare($idarticolo).', '.prepare($id_record).', '.(empty($idimpianto) ? 'NULL' : prepare($idimpianto)).', '.prepare($idautomezzo).', '.prepare($descrizione).', '.prepare($prezzo_vendita).', '.prepare($prezzo_acquisto).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', (SELECT idiva_vendita FROM mg_articoli WHERE id='.prepare($idarticolo).'), '.prepare($qta).', '.prepare($um).', '.prepare($rsart[0]['abilita_serial']).', '.prepare(!empty($serials[$i]) ? $serials[$i] : '').', '.prepare($idgruppo).')'); + } + + link_componente_to_articolo($id_record, $idimpianto, $idarticolo, $qta); + + break; + + case 'unlink_articolo': + $idriga = post('idriga'); + $idarticolo = post('idarticolo'); + + // Riporto la merce nel magazzino + if (!empty($idriga) && !empty($id_record)) { + // Leggo la quantità attuale nell'intervento + $q = 'SELECT qta, idautomezzo, idarticolo, idimpianto FROM mg_articoli_interventi WHERE id='.prepare($idriga); + $rs = $dbo->fetchArray($q); + $qta = $rs[0]['qta']; + $idarticolo = $rs[0]['idarticolo']; + $idimpianto = $rs[0]['idimpianto']; + $idautomezzo = $rs[0]['idautomezzo']; + + add_movimento_magazzino($idarticolo, $qta, ['idautomezzo' => $idautomezzo, 'idintervento' => $id_record]); + + $idgruppo = $dbo->fetchArray('SELECT idgruppo FROM mg_articoli_interventi WHERE id='.prepare($idriga).' AND idintervento='.prepare($id_record))[0]['idgruppo']; + + // Elimino questo articolo dall'intervento + $dbo->query('DELETE FROM mg_articoli_interventi WHERE idgruppo='.prepare($idgruppo).' AND idintervento='.prepare($id_record)); + + // Elimino il collegamento al componente + $dbo->query('DELETE FROM my_impianto_componenti WHERE idimpianto='.prepare($idimpianto).' AND idintervento='.prepare($id_record)); + } + + break; + + case 'add_serial': + $idgruppo = $post['idgruppo']; + $serial = $post['serial']; + + $q = 'SELECT * FROM mg_articoli_interventi WHERE idintervento='.prepare($id_record).' AND idgruppo='.prepare($idgruppo).' ORDER BY id'; + $rs = $dbo->fetchArray($q); + + foreach ($rs as $i => $r) { + $dbo->query('UPDATE mg_articoli_interventi SET serial='.prepare($serial[$i]).' WHERE id='.prepare($r['id'])); + } + + break; + + case 'firma': + $directory_exists = (file_exists($docroot.'/files/interventi') || @mkdir($docroot.'/files/interventi')); + + if ($directory_exists) { + if (post('firma_base64') != '') { + // Salvataggio firma + $firma_file = 'firma_'.time().'.png'; + $firma_nome = post('firma_nome'); + + $data = explode(',', post('firma_base64')); + + $img = Intervention\Image\ImageManagerStatic::make(base64_decode($data[1])); + $img->resize(680, 202, function ($constraint) { + $constraint->aspectRatio(); + }); + + if (!$img->save($docroot.'/files/interventi/'.$firma_file)) { + $_SESSION['errors'][] = _('Impossibile creare il file!'); + } elseif ($dbo->query('UPDATE in_interventi SET firma_file='.prepare($firma_file).', firma_data=NOW(), firma_nome = '.prepare($firma_nome).', idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE completato = 1 LIMIT 0, 1) WHERE id='.prepare($id_record))) { + $_SESSION['infos'][] = _('Firma salvata correttamente!'); + $_SESSION['infos'][] = _('Attività completata!'); + } else { + $_SESSION['errors'][] = _('Errore durante il salvataggio della firma nel database!'); + } + } else { + $_SESSION['errors'][] = _('Errore durante il salvataggio della firma!')._('La firma risulta vuota').'...'; + } + } else { + $_SESSION['errors'][] = str_replace('_DIRECTORY_', '/files/interventi', _("Non è stato possibile creare la cartella _DIRECTORY_ per salvare l'immagine della firma!")); + } + + break; + + case 'sendemail': + $from_address = post('from_address'); + $from_name = post('from_name'); + + $destinatario = post('destinatario'); + $cc = get_var('Destinatario fisso in copia (campo CC)'); + + $oggetto = html_entity_decode(post('oggetto')); + $testo_email = post('body'); + $allegato = post('allegato'); + + $mail = new PHPMailer(); + + $mail->IsSMTP(); + $mail->Host = get_var('Server SMTP'); + + if (get_var('Username SMTP') != '') { + $mail->SMTPAuth = 1; + $mail->Username = get_var('Username SMTP'); + $mail->Password = get_var('Password SMTP'); + } + + if (get_var('Sicurezza SMTP') == 'SSL') { + $mail->SMTPSecure = 'ssl'; + } elseif (get_var('Sicurezza SMTP') == 'TLS') { + $mail->SMTPSecure = 'tls'; + } + + $mail->Port = get_var('Porta SMTP'); + + $mail->AddReplyTo($from_address, $from_name); + $mail->SetFrom($from_address, $from_name); + + $mail->WordWrap = 60; // a capo dopo 60 caratteri + $mail->IsHTML(true); // invio mail in formato HTML + $mail->AltBody = strip_tags($testo_email); + + $mail->AddAddress($destinatario, ''); + + // se ho impostato la conferma di lettura + if (post('confermalettura') == 'on') { + $mail->ConfirmReadingTo = $from_address; + } + + $mail->Subject = $oggetto; + $mail->AddCC($cc); + + $mail->MsgHTML($testo_email); + + if ($allegato != '') { + $mail->AddAttachment($allegato); + } + + if (!$mail->Send()) { + $_SESSION['errors'][] = _("Errore durante l'invio dell'email").': '.$mail->ErrorInfo; + } else { + $dbo->query('UPDATE in_interventi SET data_invio=NOW() WHERE id='.prepare($id_record)); + $_SESSION['infos'][] = _('Email inviata!'); + } + + break; +} diff --git a/modules/interventi/add.php b/modules/interventi/add.php new file mode 100644 index 000000000..34ecd84bb --- /dev/null +++ b/modules/interventi/add.php @@ -0,0 +1,330 @@ +fetchArray('SELECT idtipointervento_default FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica)); + $idtipointervento = $rs[0]['idtipointervento_default']; + $idstatointervento = 'WIP'; + $richiesta = filter('richiesta'); +} + +// Calcolo orario di inizio e fine di default +if (filter('orario_inizio') !== null && filter('orario_inizio') != '00:00:00') { + $orario_inizio = filter('orario_inizio'); + $orario_fine = filter('orario_fine'); +} else { + $orario_inizio = date('H').':00'; + $orario_fine = date('H', time() + 60 * 60).':00'; +} + +// Se sto pianificando un contratto, leggo tutti i dati del contratto per predisporre l'aggiunta intervento +$idcontratto = filter('idcontratto'); +$idordineservizio = filter('idordineservizio'); +$idcontratto_riga = filter('idcontratto_riga'); + +if (!empty($idcontratto) && !empty($idordineservizio)) { + $rs = $dbo->fetchArray('SELECT * FROM co_contratti WHERE id='.prepare($idcontratto)); + $idanagrafica = $rs[0]['idanagrafica']; + + // Info riga pianificata + $rs = $dbo->fetchArray('SELECT * FROM co_ordiniservizio WHERE idcontratto='.prepare($idcontratto).' AND id='.prepare($idordineservizio)); + $data = $rs[0]['data_scadenza']; + $idimpianto = $rs[0]['id']; + + // Seleziono "Ordine di servizio" come tipo intervento + $rs = $dbo->fetchArray("SELECT idtipointervento FROM in_tipiintervento WHERE descrizione='Ordine di servizio'"); + $idtipointervento = $rs[0]['idtipointervento']; + + // Spunto il tecnico di default assegnato all'impianto + $rs = $dbo->fetchArray('SELECT idtecnico FROM my_impianti WHERE id='.prepare($idimpianto)); + $idtecnico = $rs[0]['idtecnico'] ?: ''; +} + +// Se sto pianificando un contratto, leggo tutti i dati del contratto per predisporre l'aggiunta intervento +elseif (!empty($idcontratto) && !empty($idcontratto_riga)) { + $rs = $dbo->fetchArray('SELECT * FROM co_contratti WHERE id='.prepare($idcontratto)); + $idanagrafica = $rs[0]['idanagrafica']; + + // Info riga pianificata + $rs = $dbo->fetchArray('SELECT * FROM co_righe_contratti WHERE idcontratto='.prepare($idcontratto).' AND id='.prepare($idcontratto_riga)); + $idtipointervento = $rs[0]['idtipointervento']; + $data = (filter('data') !== null) ? filter('data') : $rs[0]['data_richiesta']; + $richiesta = $rs[0]['richiesta']; + $idsede = $rs[0]['idsede']; + + // Seleziono "In programmazione" come stato + $rs = $dbo->fetchArray("SELECT * FROM in_statiintervento WHERE descrizione='In programmazione'"); + $idstatointervento = $rs[0]['idstatointervento']; +} + +if (empty($data)) { + if (filter('data') !== null) { + $data = filter('data'); + } else { + $data = date(Translator::getLocaleFormatter()->getDatePattern()); + } +} + +$_SESSION['superselect']['idanagrafica'] = $idanagrafica; + +// Calcolo del nuovo codice +$idintervento_template = get_var('Formato codice intervento'); +$idintervento_template = str_replace('#', '%', $idintervento_template); + +// Calcolo codice intervento successivo +$rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice=(SELECT MAX(CAST(codice AS SIGNED)) FROM in_interventi) AND codice LIKE '.prepare($idintervento_template).' ORDER BY codice DESC LIMIT 0,1'); +$new_codice = get_next_code($rs[0]['codice'], 1, get_var('Formato codice intervento')); + +if (empty($new_codice)) { + $rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice LIKE '.prepare($idintervento_template).' ORDER BY codice DESC LIMIT 0,1'); + $new_codice = get_next_code($rs[0]['codice'], 1, get_var('Formato codice intervento')); +} + +?> + +
+ + + + + + +
+
+

+
+ +
+ + +
+
+ {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "value": "", "ajax-source": "clienti", "icon-after": "add||tipoanagrafica=Cliente", "data-heavy": 0 ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idsede", "value": "", "placheholder": "...", "ajax-source": "sedi" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idclientefinale", "value": "", "ajax-source": "clienti" ]} +
+
+ + +
+
+ {[ "type": "select", "label": "", "name": "idpreventivo", "value": "", "placeholder": "...", "ajax-source": "preventivi" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idcontratto", "value": "", "placeholder": "...", "ajax-source": "contratti" ]} +
+ +
+ {[ "type": "select", "label": "", "multiple": 1, "name": "idimpianti[]", "value": "", "placeholder": "...", "ajax-source": "impianti" ]} +
+
+ +
+
+ {[ "type": "select", "label": "", "multiple": 1, "name": "componenti[]", "value": "", "placeholder": "...", "ajax-source": "componenti" ]} +
+
+
+
+ + +
+
+

+
+ +
+ +
+
+ {[ "type": "text", "label": "", "name": "codice", "required": 1, "class": "text-center", "value": "" ]} +
+ +
+ {[ "type": "date", "label": "", "name": "data_richiesta", "required": 1, "value": "-now-" ]} +
+ +
+ {[ "type": "date", "label": "", "name": "data", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idzona", "values": "query=SELECT id, nome AS descrizione FROM an_zone ORDER BY nome", "value": "" ]} +
+
+ + +
+
+ {[ "type": "select", "label": "", "name": "idtipointervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento", "value": "", "ajax-source": "tipiintervento" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idstatointervento", "required": 1, "values": "query=SELECT idstatointervento AS id, descrizione, colore AS _bgcolor_ FROM in_statiintervento", "value": "" ]} +
+ +
+ {[ "type": "time", "label": "", "name": "orario_inizio", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "time", "label": "", "name": "orario_fine", "required": 1, "value": "" ]} +
+
+ + +
+
+ {[ "type": "select", "label": "", "multiple": "1", "name": "idtecnico[]", "required": 1, "ajax-source": "tecnici", "value": "" ]} +
+ +
+ {[ "type": "textarea", "label": "", "name": "richiesta", "required": 1, "value": "", "extra": "style='max-height:80px; ' " ]} +
+ + '; + } + + if (!empty($idordineservizio)) { + echo ''; + } + ?> +
+
+
+ + + +
+
+ +
+
+
+ + + + diff --git a/modules/interventi/add_articolo.php b/modules/interventi/add_articolo.php new file mode 100644 index 000000000..f18afaa09 --- /dev/null +++ b/modules/interventi/add_articolo.php @@ -0,0 +1,207 @@ +fetchArray('SELECT nome FROM zz_groups WHERE id IN(SELECT idgruppo FROM zz_users WHERE idutente='.prepare($_SESSION['idutente']).')'); +for ($i = 0; $i < count($rs); ++$i) { + $gruppi[$i] = $rs[$i]['nome']; +} + +$can_edit_prezzi = (in_array('Amministratori', $gruppi)) || (get_var('Mostra i prezzi al tecnico') == 1 && (in_array('Tecnici', $gruppi))); + +$idriga = get('idriga'); +$idautomezzo = (get('idautomezzo') == 'undefined') ? '' : get('idautomezzo'); + +if (empty($idriga)) { + $op = 'addarticolo'; + $button = ' '._('Aggiungi'); + + // valori default + $idarticolo = ''; + $descrizione = ''; + $qta = 1; + $um = ''; + + $prezzo_vendita = '0'; + + $sconto_unitario = 0; + + $idimpianto = 0; +} else { + $op = 'editarticolo'; + $button = ' '._('Modifica'); + + // carico record da modificare + $q = "SELECT *, (SELECT codice FROM mg_articoli WHERE id=mg_articoli_interventi.idarticolo) AS codice_articolo, (SELECT CONCAT(codice, ' - ', descrizione) FROM mg_articoli WHERE id=mg_articoli_interventi.idarticolo) AS descrizione_articolo FROM mg_articoli_interventi WHERE id=".prepare($idriga); + $rsr = $dbo->fetchArray($q); + + $idarticolo = $rsr[0]['idarticolo']; + $codice_articolo = $rsr[0]['codice_articolo']; + $descrizione = $rsr[0]['descrizione']; + $descrizione_articolo = $rsr[0]['descrizione_articolo']; // necessario per inizializzazione select2 idarticolo + $qta = $rsr[0]['qta']; + $um = $rsr[0]['um']; + + $prezzo_vendita = $rsr[0]['prezzo_vendita']; + + $sconto_unitario = $rsr[0]['sconto_unitario']; + $tipo_sconto = $rsr[0]['tipo_sconto']; + + $idautomezzo = $rsr[0]['idautomezzo']; + + $idimpianto = $rsr[0]['idimpianto']; +} + +// Lettura idanagrafica cliente e percentuale di sconto/rincaro in base al listino +$rs = $dbo->fetchArray('SELECT idanagrafica FROM in_interventi WHERE id='.prepare($id_record)); +$idanagrafica = $rs[0]['idanagrafica']; + +/* + Form di inserimento +*/ +echo ' +
+ + + '; + +if ($idarticolo != '') { + echo ' + '; +} + +// Articolo +echo ' +
+
+ {[ "type": "select", "label": "'._('Articolo').'", "name": "idarticolo", "required": 1, "value": "'.$idarticolo.'", "ajax-source": "articoli" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]} +
+
+
'; + +// Quantità +echo ' +
+
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "'.$qta.'", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "value": "'.$um.'", "ajax-source": "misure" ]} +
'; + +// Impianto +echo ' +
+ {[ "type": "select", "label": "'._('Impianto su cui installare').'", "name": "idimpianto", "value": "'.$idimpianto.'", "ajax-source": "impianti" ]} +
+
'; + +// Prezzo di vendita +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo_vendita", "required": 1, "value": "'.$prezzo_vendita.'", "icon-after": "€" ]} +
'; + +// Sconto +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc|'.$tipo_sconto.'", "value": "'.$sconto_unitario.'" ]} +
+
'; + +// Informazioni aggiuntive +echo ' +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
'; + +echo ' + '; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; + +?> + + diff --git a/modules/interventi/add_firma.php b/modules/interventi/add_firma.php new file mode 100644 index 000000000..e9ab50f44 --- /dev/null +++ b/modules/interventi/add_firma.php @@ -0,0 +1,113 @@ +fetchArray($query); + + if (empty($rs)) { + echo _('Intervento inesistente!'); + exit(); + } + + $idanagrafica = $rs[0]['idanagrafica']; + $idcliente = $rs[0]['idanagrafica']; + $data_intervento = $rs[0]['data_inizio']; + + // Gestione della stampa + $rapportino_nome = sanitizeFilename('Rapportino'.$rs[0]['codice'].'.pdf'); + $filename = $docroot.'/files/interventi/'.$rapportino_nome; + + $_GET['idintervento'] = $id_record; // Fix temporaneo per la stampa + $idintervento = $id_record; // Fix temporaneo per la stampa + $ptype = 'interventi'; + + require $docroot.'/pdfgen.php'; + + // HTML per la visualizzazione + echo ' + +
+ +
+ + alt : '.$rapportino_nome.' + '._('Plugin PDF mancante').' + +
'; +} + +?> +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "firma_nome", "required": 1 ]} +
+
+ +
+ + +
+ + +
+ + +
+ +
+
+ + diff --git a/modules/interventi/add_righe.php b/modules/interventi/add_righe.php new file mode 100644 index 000000000..2e989cb64 --- /dev/null +++ b/modules/interventi/add_righe.php @@ -0,0 +1,119 @@ +fetchArray('SELECT idanagrafica, (SELECT prc_guadagno FROM mg_listini WHERE id=(SELECT idlistino FROM an_anagrafiche WHERE idanagrafica=.in_interventi.idanagrafica)) AS prc_sconto FROM in_interventi WHERE id='.prepare($id_record)); +$idanagrafica = $rs[0]['idanagrafica']; +$prc_sconto = $rs[0]['prc_sconto']; + +if (empty($idriga)) { + $op = 'addriga'; + $button = ' '._('Aggiungi'); + + // valori default + $descrizione = ''; + $qta = 1; + $um = ''; + $prezzo_vendita = '0'; + $prezzo_acquisto = '0'; +} else { + $op = 'editriga'; + $button = ' '._('Modifica'); + + // carico record da modificare + $q = 'SELECT * FROM in_righe_interventi WHERE id='.prepare($idriga); + $rsr = $dbo->fetchArray($q); + + $descrizione = $rsr[0]['descrizione']; + $qta = $rsr[0]['qta']; + $um = $rsr[0]['um']; + $prezzo_vendita = $rsr[0]['prezzo_vendita']; + $prezzo_acquisto = $rsr[0]['prezzo_acquisto']; + + $sconto_unitario = $rsr[0]['sconto_unitario']; + $tipo_sconto = $rsr[0]['tipo_sconto']; +} + +/* + Form di inserimento +*/ +echo ' +
+ + '; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "id": "descrizione_riga", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]} +
+
+
'; + +// Quantità +echo ' +
+
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "'.$qta.'", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "value": "'.$um.'", "ajax-source": "misure" ]} +
+
'; + +// Prezzo di acquisto +echo ' +
+
+ {[ "type": "number", "label": "'._('Prezzo di acquisto (un.)').'", "name": "prezzo_acquisto", "required": 1, "value": "'.$prezzo_acquisto.'", "icon-after": "€" ]} +
'; + +// Prezzo di vendita +echo ' +
+ {[ "type": "number", "label": "'._('Prezzo di vendita (un.)').'", "name": "prezzo_vendita", "required": 1, "value": "'.$prezzo_vendita.'", "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc|'.$tipo_sconto.'", "value": "'.$sconto_unitario.'" ]} +
+
'; + +echo ' + +
+
'; + +?> + + + + diff --git a/modules/interventi/add_serial.php b/modules/interventi/add_serial.php new file mode 100644 index 000000000..e4fe90e0d --- /dev/null +++ b/modules/interventi/add_serial.php @@ -0,0 +1,47 @@ +fetchArray($q2); + +echo ' +

'._('Articolo').': '.$rs2[0]['codice'].' - '.$rs2[0]['descrizione'].'

+ +
+ + + + + '; + +$serials = []; +$array = array_column($rs2, 'serial'); +foreach ($array as $value) { + if (!empty($value)) { + $serials[] = $value; + } +} + + echo ' +
+
+ {[ "type": "select", "label": "'._('Serial').'", "name": "serial[]", "multiple": 1, "value": "'.implode(',', $serials).'", "values": "query=SELECT serial AS id, serial AS descrizione FROM vw_serials WHERE dir=\'uscita\' AND serial NOT IN (SELECT serial FROM vw_serials WHERE dir=\'entrata\' AND record != \'int-'.$id_record.'\')", "extra": "data-maximum=\"'.count($rs2).'\"" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/interventi/ajax_articoli.php b/modules/interventi/ajax_articoli.php new file mode 100644 index 000000000..a29209962 --- /dev/null +++ b/modules/interventi/ajax_articoli.php @@ -0,0 +1,164 @@ +fetchArray($query); + +if (!empty($rs)) { + echo ' + + + + '; + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + echo ' + '; + } + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + echo ' + + '; + } + + if ($rs[0]['stato'] != 'Fatturato' && $rs[0]['stato'] != 'Completato') { + echo ' + '; + } + echo ' + '; + + foreach ($rs as $r) { + $qserial = 'SELECT * FROM mg_articoli_interventi WHERE idintervento='.prepare($id_record).' AND idarticolo='.prepare($r['idarticolo']).' AND idgruppo='.prepare($r['idgruppo']); + $rsserial = $dbo->fetchArray($qserial); + + $mancanti = 0; + $serials = []; + + if (!empty($r['abilita_serial'])) { + foreach ($rsserial as $seriali) { + $seriali['serial'] = trim($seriali['serial']); + if (!empty($seriali['serial'])) { + $serials[] = $seriali['serial']; + } else { + ++$mancanti; + } + } + } + + if ($mancanti > 0) { + $extra = 'class="warning"'; + } + + echo ' + + '; + + // Quantità + echo ' + '; + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + echo ' + '; + } + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + // Prezzo unitario + echo ' + '; + + // Prezzo di vendita + echo ' + '; + } + + // Pulsante per riportare nel magazzino centrale. + // Visibile solo se l'intervento non è stato nè fatturato nè completato. + if ($rs[0]['stato'] != 'Fatturato' && $rs[0]['stato'] != 'Completato') { + echo ' + '; + } + echo ' + '; + } + + echo ' +
'._('Articolo').''._('Q.tà').''._('Prezzo di acquisto').''._('Prezzo di vendita').''._('Subtotale').'
+ + '.Modules::link('Articoli', $r['idarticolo'], $r['descrizione']); + + // Info extra (lotto, serial, altro) + if (!empty($r['abilita_serial'])) { + if (!empty($mancanti)) { + echo ' +
'.str_replace('_NUM_', $mancanti, _('_NUM_ serial mancanti')).''; + } + if (!empty($serials)) { + echo ' +
'._('SN').': '.implode(', ', $serials); + } + } else { + if ($r['lotto'] != '') { + echo ' +
'._('Lotto').': '.$r['lotto']; + } + if ($r['serial'] != '') { + echo ' +
'._('SN').': '.$r['serial']; + } + if ($r['altro'] != '') { + echo ' +
'.$r['altro']; + } + } + + echo ' +
+ '.Translator::numberToLocale($r['qta']).' '.$r['um'].' + + '.Translator::numberToLocale($r['prezzo_acquisto']).' € + + '.Translator::numberToLocale($r['prezzo_vendita']).' €'; + + if ($r['sconto_unitario'] > 0) { + echo ' +
+ - sconto '.Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €').' + '; + } + + echo ' +
+ '.Translator::numberToLocale(sum($r['prezzo_vendita'] * $r['qta'], -$r['sconto'])).' € + '; + + if ($r['abilita_serial']) { + echo ' + '; + } + + echo ' + + + + +
'; +} +?> + diff --git a/modules/interventi/ajax_costi.php b/modules/interventi/ajax_costi.php new file mode 100644 index 000000000..ac1ed560e --- /dev/null +++ b/modules/interventi/ajax_costi.php @@ -0,0 +1,98 @@ +fetchArray('SELECT idtipointervento, sconto_globale, tipo_sconto_globale FROM in_interventi WHERE id='.prepare($idintervento)); +$sconto = $rss[0]['sconto_globale']; +$tipo_sconto = $rss[0]['tipo_sconto_globale']; + +if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + $rsr = $dbo->fetchArray('SELECT * FROM vw_activity_subtotal WHERE id='.prepare($id_record)); + + $manodopera_costo = $rsr[0]['manodopera_costo']; + $manodopera_addebito = $rsr[0]['manodopera_addebito']; + $manodopera_scontato = $rsr[0]['manodopera_scontato']; + + $viaggio_costo = $rsr[0]['viaggio_costo']; + $viaggio_addebito = $rsr[0]['viaggio_addebito']; + $viaggio_scontato = $rsr[0]['viaggio_scontato']; + + $ricambi_costo = $rsr[0]['ricambi_costo']; + $ricambi_addebito = $rsr[0]['ricambi_addebito']; + $ricambi_scontato = $rsr[0]['ricambi_scontato']; + + $altro_costo = $rsr[0]['altro_costo']; + $altro_addebito = $rsr[0]['altro_addebito']; + $altro_scontato = $rsr[0]['altro_scontato']; + + $totale_costi = sum([$manodopera_costo, $viaggio_costo, $ricambi_costo, $altro_costo]); + $totale_addebito = sum([$manodopera_addebito, $viaggio_addebito, $ricambi_addebito, $altro_addebito]); + $totale_manodopera = sum([$manodopera_scontato, $viaggio_scontato, $ricambi_scontato, $altro_scontato]); + + $sconto_globale = $rsr[0]['sconto_globale']; + + $totale_manodopera = sum($totale_manodopera, -$sconto_globale); + + echo ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
'.strtoupper(_('Costo')).''.strtoupper(_('Addebito')).''.strtoupper(_('Tot. Scontato')).'
'.strtoupper(_('Totale manodopera')).''.Translator::numberToLocale($manodopera_costo).' €'.Translator::numberToLocale($manodopera_addebito).' €'.Translator::numberToLocale($manodopera_scontato).' €
'.strtoupper(_('Totale viaggio')).''.Translator::numberToLocale($viaggio_costo).' €'.Translator::numberToLocale($viaggio_addebito).' €'.Translator::numberToLocale($viaggio_scontato).' €
'.strtoupper(_('Totale articoli')).''.Translator::numberToLocale($ricambi_costo).' €'.Translator::numberToLocale($ricambi_addebito).' €'.Translator::numberToLocale($ricambi_scontato).' €
'.strtoupper(_('Totale altre spese')).''.Translator::numberToLocale($altro_costo).' €'.Translator::numberToLocale($altro_addebito).' €'.Translator::numberToLocale($altro_scontato).' €
'.strtoupper(_('Sconto totale')).'--'.Translator::numberToLocale(-$sconto_globale).' €
'.strtoupper(_('Totale')).''.Translator::numberToLocale($manodopera_costo + $viaggio_costo + $ricambi_costo + $altro_costo).' €'.Translator::numberToLocale($manodopera_addebito + $viaggio_addebito + $ricambi_addebito + $altro_addebito).' €'.Translator::numberToLocale($manodopera_scontato + $viaggio_scontato + $ricambi_scontato + $altro_scontato - $sconto_globale).' €
'; +} + +echo ' + + +
+
+ {[ "type": "number", "label": "'._('Sconto globale').'", "name": "sconto_globale", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]} +
+
'; diff --git a/modules/interventi/ajax_righe.php b/modules/interventi/ajax_righe.php new file mode 100644 index 000000000..ffa892206 --- /dev/null +++ b/modules/interventi/ajax_righe.php @@ -0,0 +1,104 @@ +fetchArray($query); + +if (count($rs2) > 0) { + echo ' + + + + + '; + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + echo ' + + '; + } + + if ($records[0]['stato'] != 'Fatturato' && $records[0]['stato'] != 'Completato') { + echo ' + '; + } + echo ' + '; + + foreach ($rs2 as $r) { + echo ' + + '; + + // Quantità + echo ' + '; + + //Costo unitario + echo ' + '; + + if (Auth::isAdmin() || $_SESSION['gruppo'] != 'Tecnici') { + // Prezzo unitario + $netto = $r['prezzo_vendita'] - $r['sconto_unitario']; + + echo ' + '; + + // Prezzo di vendita + echo ' + '; + } + + // Pulsante per riportare nel magazzino centrale. + // Visibile solo se l'intervento non è stato nè fatturato nè completato. + if ($records[0]['stato'] != 'Fatturato' && $records[0]['stato'] != 'Completato') { + echo ' + '; + } + echo ' + '; + } + + echo ' +
'._('Descrizione').''._('Q.tà').''._('Prezzo di acquisto').''._('Prezzo di vendita').''._('Subtotale').'
+ + '.nl2br($r['descrizione']).' + + '.Translator::numberToLocale($r['qta']).' '.$r['um'].' + + '.Translator::numberToLocale($r['prezzo_acquisto']).' € + + '.Translator::numberToLocale($r['prezzo_vendita']).' €'; + + if ($r['sconto_unitario'] > 0) { + echo ' +
+ - sconto '.Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €').' + '; + } + + echo ' +
+ '.Translator::numberToLocale(sum($r['prezzo_vendita'] * $r['qta'], -$r['sconto'])).' € + + + +
'; +} + +?> + + diff --git a/modules/interventi/ajax_tecnici.php b/modules/interventi/ajax_tecnici.php new file mode 100644 index 000000000..3447b208b --- /dev/null +++ b/modules/interventi/ajax_tecnici.php @@ -0,0 +1,307 @@ +fetchArray('SELECT idcontratto FROM co_righe_contratti WHERE idintervento='.prepare($id_record)); + $idcontratto = $rs[0]['idcontratto']; + + $ore = 1; + + $inizio = date('Y-m-d H:\0\0'); + $fine = date_modify(date_create(date('Y-m-d H:\0\0')), '+'.$ore.' hours')->format('Y-m-d H:\0\0'); + + add_tecnico($id_record, $idtecnico, $inizio, $fine, $idcontratto); + + break; + + // RIMOZIONE SESSIONE DI LAVORO + case 'del_sessione': + $dbo->query('DELETE FROM in_interventi_tecnici WHERE id='.prepare(get('id'))); + break; +} + +$show_costi = true; + +// Limitazione delle azioni dei tecnici +if ($user['gruppo'] == 'Tecnici') { + $show_costi = !empty($user_idanagrafica) && get_var('Mostra i prezzi al tecnico'); +} + +// RECUPERO IL TIPO DI INTERVENTO +$rss = $dbo->fetchArray('SELECT idtipointervento FROM in_interventi WHERE id='.prepare($id_record)); +$idtipointervento = $rs[0]['idtipointervento']; + +$query = 'SELECT * FROM an_anagrafiche JOIN in_interventi_tecnici ON in_interventi_tecnici.idtecnico = an_anagrafiche.idanagrafica WHERE deleted=0 AND idintervento='.prepare($id_record)." AND idanagrafica IN (SELECT idanagrafica FROM an_tipianagrafiche_anagrafiche WHERE idtipoanagrafica = (SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione = 'Tecnico')) ORDER BY ragione_sociale ASC, in_interventi_tecnici.orario_inizio ASC"; +$rs2 = $dbo->fetchArray($query); +$prev_tecnico = ''; + +if (!empty($rs2)) { + foreach ($rs2 as $key => $r) { + $idtecnico = $r['idanagrafica']; + + // Intestazione tecnico + if ($prev_tecnico != $r['ragione_sociale']) { + echo ' +
+ + + + + + + + + + '; + } + + $id = $r['id']; + + // Lettura costi unitari salvati al momento dell'intervento + $sconto_unitario = $r['sconto_unitario']; + $tipo_sconto = $r['tipo_sconto']; + + $scontokm_unitario = $r['scontokm_unitario']; + $tipo_scontokm = $r['tipo_scontokm']; + + $sconto = $r['sconto']; + $scontokm = $r['scontokm']; + + $costo_ore_unitario = $r['prezzo_ore_unitario']; + $costo_km_unitario = $r['prezzo_km_unitario']; + $costo_dirittochiamata = $r['prezzo_dirittochiamata']; + + $costo_ore_unitario_tecnico = $r['prezzo_ore_unitario_tecnico']; + $costo_km_unitario_tecnico = $r['prezzo_km_unitario_tecnico']; + $costo_dirittochiamata_tecnico = $r['prezzo_dirittochiamata_tecnico']; + + $costo_km_consuntivo_tecnico = $r['prezzo_km_consuntivo_tecnico']; + $costo_ore_consuntivo_tecnico = $r['prezzo_ore_consuntivo_tecnico']; + $costo_km_consuntivo = $r['prezzo_km_consuntivo']; + $costo_ore_consuntivo = $r['prezzo_ore_consuntivo']; + + $orario_inizio = '0000-00-00 00:00:00'; + $orario_fine = '0000-00-00 00:00:00'; + + $pausa_inizio = '0000-00-00 00:00:00'; + $pausa_fine = '0000-00-00 00:00:00'; + + if (!empty($r['orario_inizio'])) { + $orario_inizio = Translator::timestampToLocale($r['orario_inizio']); + } + + if (!empty($r['orario_fine'])) { + $orario_fine = Translator::timestampToLocale($r['orario_fine']); + } + + if (!empty($r['pausa_inizio'])) { + $pausa_inizio = Translator::timestampToLocale($r['pausa_inizio']); + } + + if (!empty($r['pausa_fine'])) { + $pausa_fine = Translator::timestampToLocale($r['pausa_fine']); + } + + $orario = $orario_inizio.' - '.$orario_fine; + $pausa = $pausa_inizio.' - '.$pausa_fine; + + $km = $r['km']; + $ore = $r['ore']; + + // Costi unitari + echo ' + + + + + + + + + '; + + echo ' + + '; + + // Orario + echo ' + '; + + // ORE + echo ' + '; + + // KM + echo ' + '; + + // Sconto ore + echo ' + '; + + // Sconto km + echo ' + '; + + // Pulsante aggiunta nuova sessione + echo ' + + '; + + // Intestazione tecnico + if (!isset($rs2[$key + 1]['ragione_sociale']) || $r['ragione_sociale'] != $rs2[$key + 1]['ragione_sociale']) { + echo ' +
'.$r['ragione_sociale'].''._('Orario').''._('Ore').''._('Km').''._('Sconto ore').''._('Sconto km').'
'; + + if ($rs[0]['stato'] != 'Fatturato') { + // Elenco tipologie di interventi + echo ' + {[ "type": "select", "name": "idtipointerventot['.$id.']", "value": "'.$r['idtipointervento'].'", "values": "query=SELECT idtipointervento AS id, descrizione, IFNULL((SELECT costo_ore FROM in_tariffe WHERE idtipointervento=in_tipiintervento.idtipointervento AND idtecnico='.prepare($r['idtecnico']).'), 0) AS costo_orario FROM in_tipiintervento ORDER BY descrizione" ]}'; + } + + echo ' + '; + if ($rs[0]['stato'] == 'Fatturato') { + echo ' + '.$ora_dal1.' + '; + } else { + echo ' + '; + } + echo ' + + {[ "type": "number", "name": "ore['.$id.']", "value": "'.$ore.'", "disabled": 1 ]} + +
+ + + + +
'._('Costo').':'.Translator::numberToLocale($costo_ore_consuntivo_tecnico)."".Translator::numberToLocale($costo_ore_unitario_tecnico).'x'.Translator::numberToLocale($ore).'
+'.Translator::numberToLocale($costo_dirittochiamata_tecnico).'
'._('Addebito').':'.Translator::numberToLocale($costo_ore_consuntivo).''.Translator::numberToLocale($costo_ore_unitario).'x'.Translator::numberToLocale($ore).'
+'.Translator::numberToLocale($costo_dirittochiamata).'
'._('Scontato').':'.Translator::numberToLocale($costo_ore_consuntivo - $sconto).'
+
+
+ {[ "type": "number", "name": "km['.$id.']", "value": "'.$km.'" ]} + +
+ + + + + + + + + + + + + +
'._('Costo').': + '.Translator::numberToLocale($costo_km_consuntivo_tecnico).' + + '.Translator::numberToLocale($costo_km_unitario_tecnico).'x'.Translator::numberToLocale($km).' +
+
'._('Addebito').': + '.Translator::numberToLocale($costo_km_consuntivo).' + + '.Translator::numberToLocale($costo_km_unitario).'x'.Translator::numberToLocale($km).' +
+
'._('Scontato').':'.Translator::numberToLocale($costo_km_consuntivo - $scontokm).'
+
+
'; + if ($user_idanagrafica == 0 || $show_costi) { + echo ' + {[ "type": "number", "name": "sconto['.$id.']", "value": "'.$sconto_unitario.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}'; + } else { + echo ' + + '; + } + + echo ' + '; + if ($user_idanagrafica == 0 || $show_costi) { + echo ' + {[ "type": "number", "name": "scontokm['.$id.']", "value": "'.$scontokm_unitario.'", "icon-after": "choice|untprc|'.$tipo_scontokm.'" ]}'; + } else { + echo ' + + '; + } + + echo ' + + + + + + +
+
'; + } + } +} else { + echo +'

'._('Nessun tecnico presente').'.

'; +} + +echo ' + +
+
+ {[ "type": "select", "label": "'._('Aggiungi tecnico').'", "name": "nuovotecnico", "ajax-source": "tecnici" ]} +
+ +
+
+ +
+
'; + +?> + + + + diff --git a/modules/interventi/edit.php b/modules/interventi/edit.php new file mode 100644 index 000000000..53f0db718 --- /dev/null +++ b/modules/interventi/edit.php @@ -0,0 +1,293 @@ + '.str_replace(['_TIMESTAMP_', '_PERSON_'], [''.date('d/m/Y \\a\\l\\l\\e H:i', strtotime($records[0]['firma_data'])).'', ''.$records[0]['firma_nome'].''], _('Firmato il _TIMESTAMP_ da _PERSON_')).''; +} + +?>
+ + + + + +
+
+

+
+ +
+ + +
+ + + + +
+
+
+ + +
+
+ + {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idanagrafica$", "ajax-source": "clienti" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idsede", "values": "query=SELECT 0 AS id, 'Sede legale' AS descrizione UNION SELECT id, CONCAT_WS( ' - ', nomesede, citta ) AS descrizione FROM an_sedi WHERE idanagrafica='$idanagrafica$'", "value": "$idsede$", "ajax-source": "sedi" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idclientefinale", "value": "$idclientefinale$", "ajax-source": "clienti" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idreferente", "value": "$idreferente$", "ajax-source": "referenti" ]} +
+
+ + + + +
+
+ + + {[ "type": "select", "label": "", "name": "idpreventivo", "value": "$idpreventivo$", "ajax-source": "preventivi" ]} +
+ +
+ fetchArray('SELECT id, idcontratto FROM co_righe_contratti WHERE idintervento='.prepare($id_record)); + if (count($rs) == 1) { + $idcontratto = $rs[0]['idcontratto']; + $idcontratto_riga = $rs[0]['id']; + } else { + $idcontratto = ''; + $idcontratto_riga = ''; + } + + if (($idcontratto != '')) { + echo ' + '.Modules::link('Contratti', $idcontratto, null, null, 'class="pull-right"'); + } + ?> + + {[ "type": "select", "label": "", "name": "idcontratto", "value": "", "ajax-source": "contratti" ]} + +
+
+
+
+ + + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+ {[ "type": "span", "label": "", "name": "codice", "value": "$codice$" ]} +
+ +
+ {[ "type": "date", "label": "", "name": "data_richiesta", "required": 1, "value": "$data_richiesta$" ]} +
+
+ + + +
+
+ {[ "type": "select", "label": "", "name": "idtipointervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento", "value": "$idtipointervento$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idstatointervento", "required": 1, "values": "query=SELECT idstatointervento AS id, descrizione, colore AS _bgcolor_ FROM in_statiintervento", "value": "$idstatointervento$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idautomezzo", "values": "query=SELECT id, CONCAT_WS( ')', CONCAT_WS( ' (', CONCAT_WS( ', ', nome, descrizione), targa ), '' ) AS descrizione FROM dt_automezzi", "value": "$idautomezzo$" ]} +
+
+ + + +
+
+ {[ "type": "textarea", "label": "", "name": "richiesta", "required": 1, "class": "autosize", "value": "$richiesta$", "extra": "rows='5'" ]} +
+ +
+ {[ "type": "textarea", "label": "", "name": "descrizione", "class": "autosize", "value": "$descrizione$", "extra": "rows='10'" ]} +
+ +
+ {[ "type": "textarea", "label": "", "name": "informazioniaggiuntive", "class": "autosize", "value": "$informazioniaggiuntive$", "extra": "rows='5'" ]} +
+
+
+
+ + +
+
+

+
+ +
+
+ + + +
+
+
+ +
+
+ +
+
+
+
+ + + +
+
+

+
+ +
+
+ +
+ + + + +
+
+ + +
+
+

+
+ +
+
+ +
+ + + + +
+
+ + +
+
+

+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+ +{( "name": "filelist_and_upload", "id_module": "", "id_record": "" )} + + +
+ '._('Questo intervento non è ancora stato firmato dal cliente').'.

'; + } else { + echo ' +
+
'.str_replace(['_TIMESTAMP_', '_PERSON_'], [''.date('d/m/Y \\a\\l\\l\\e H:i', strtotime($records[0]['firma_data'])).'', ''.$records[0]['firma_nome'].''], _('Firmato il _TIMESTAMP_ da _PERSON_')).'
'; + } + ?> +
+ + + + + + + + diff --git a/modules/interventi/init.php b/modules/interventi/init.php new file mode 100644 index 000000000..bd32a320f --- /dev/null +++ b/modules/interventi/init.php @@ -0,0 +1,9 @@ +fetchArray('SELECT *, (SELECT colore FROM in_statiintervento WHERE idstatointervento=in_interventi.idstatointervento) AS colore, (SELECT idpreventivo FROM co_preventivi_interventi WHERE idintervento=in_interventi.id LIMIT 0,1) AS idpreventivo FROM in_interventi WHERE id='.prepare($id_record).Modules::getAdditionalsQuery($id_module)); +} + +$jscript_modules[] = $rootdir.'/modules/interventi/js/interventi_helperjs.js'; diff --git a/modules/interventi/js/interventi_helperjs.js b/modules/interventi/js/interventi_helperjs.js new file mode 100644 index 000000000..d8f8d6aad --- /dev/null +++ b/modules/interventi/js/interventi_helperjs.js @@ -0,0 +1,31 @@ +/** + * Calcola la differenza in ore fra start ed end, e le scrive nel campo delle ore della riga specificata + */ +function calcola_ore(idriga, start, end) { + end = moment(end, globals.timestampFormat); + start = moment(start, globals.timestampFormat); + + totale_ore = end.diff(start, 'minutes') / 60; + totale_ore = totale_ore.toFixed(2); + + if (!isNaN(totale_ore)) { + $('#ore' + idriga).val(totale_ore); + } +} + +/* + Aggiunge una nuova riga per la sessione di lavoro in base al tecnico selezionato +*/ +function add_tecnici(idintervento, idtecnico) { + $('#tecnici').load(globals.rootdir + '/modules/interventi/ajax_tecnici.php?id_module=' + globals.id_module +'&id_record=' + idintervento + '&op=add_sessione&idtecnico=' + idtecnico); + + $('#costi').load(globals.rootdir + '/modules/interventi/ajax_costi.php?id_module=' + globals.id_module +'&id_record=' + idintervento); +} + +function elimina_sessione(idriga, idintervento, idzona) { + if (confirm('Eliminare sessione di lavoro?')) { + $('#tecnici').load(globals.rootdir + '/modules/interventi/ajax_tecnici.php?id_module=' + globals.id_module +'&id_record=' + idintervento + '&op=del_sessione&id=' + idriga); + + $('#costi').load(globals.rootdir + '/modules/interventi/ajax_costi.php?id_module=' + globals.id_module +'&id_record=' + idintervento); + } +} diff --git a/modules/interventi/modutil.php b/modules/interventi/modutil.php new file mode 100644 index 000000000..46a30f473 --- /dev/null +++ b/modules/interventi/modutil.php @@ -0,0 +1,150 @@ +fetchArray('SELECT idintervento, TIMESTAMPDIFF( MINUTE, orario_inizio, orario_fine ) / 60 AS tot_ore FROM in_interventi_tecnici WHERE idintervento = '.prepare($idintervento)); + + for ($i = 0; $i < count($rs); ++$i) { + $totale_ore = $totale_ore + $rs[$i]['tot_ore']; + } + + return $totale_ore; +} + +/** + * Funzione per collegare gli articoli, usati in un intervento, ai rispettivi impianti. + * + * @param [type] $idintervento + * @param [type] $idimpianto + * @param [type] $idarticolo + * @param [type] $qta + */ +function link_componente_to_articolo($idintervento, $idimpianto, $idarticolo, $qta) +{ + global $docroot; + $dbo = Database::getConnection(); + + if (!empty($idimpianto) && !empty($idintervento)) { + //Leggo la data dell'intervento + $rs = $dbo->fetchArray("SELECT DATE_FORMAT(MIN(orario_inizio),'%Y-%m-%d') AS data FROM in_interventi_tecnici WHERE idintervento=".prepare($idintervento)); + $data = $rs[0]['data']; + + $rs = $dbo->fetchArray('SELECT componente_filename, contenuto FROM mg_articoli WHERE id='.prepare($idarticolo)); + + //Se l'articolo aggiunto è collegato a un file .ini, aggiungo il componente all'impianto selezionato + if (count($rs) == 1 && $rs[0]['componente_filename'] != '') { + //Inserisco il componente tante volte quante la quantità degli articoli inseriti + for ($q = 0; $q < $qta; ++$q) { + $dbo->query('INSERT INTO my_impianto_componenti(idimpianto, idintervento, nome, data, filename, contenuto) VALUES ('.prepare($idimpianto).', '.prepare($idintervento).', '.prepare(\Util\Ini::getValue($rs[0]['componente_filename'], 'Nome')).', '.prepare($data).', '.prepare($rs[0]['componente_filename']).', '.prepare($rs[0]['contenuto']).')'); + } + } + } +} + +function add_tecnico($idintervento, $idtecnico, $inizio, $fine, $idcontratto) +{ + $dbo = Database::getConnection(); + + $rs = $dbo->fetchArray('SELECT idsede, idtipointervento FROM in_interventi WHERE id='.prepare($idintervento)); + $idtipointervento = $rs[0]['idtipointervento']; + $idsede = $rs[0]['idsede']; + + // Calcolo km in base a quelli impostati nell'anagrafica + // Nessuna sede + if ($idsede == '-1') { + $km = 0; + } + + // Sede legale + elseif (empty($idsede)) { + $rs2 = $dbo->fetchArray('SELECT km FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica)); + $km = $rs2[0]['km']; + } + + // Sede secondaria + else { + $rs2 = $dbo->fetchArray('SELECT km FROM an_sedi WHERE id='.prepare($idsede)); + $km = $rs2[0]['km']; + } + + $km = empty($km) ? 0 : $km; + + // Calcolo il totale delle ore lavorate + $diff = date_diff(date_create($inizio), date_create($fine)); + $ore = $diff->h + $diff->m / 60; + + // Leggo i costi unitari dalle tariffe se almeno un valore è stato impostato + $rsc = $dbo->fetchArray('SELECT * FROM in_tariffe WHERE idtecnico='.prepare($idtecnico).' AND idtipointervento='.prepare($idtipointervento)); + + if ($rsc[0]['costo_ore'] != 0 || $rsc[0]['costo_km'] != 0 || $rsc[0]['costo_dirittochiamata'] != 0 || $rsc[0]['costo_ore_tecnico'] != 0 || $rsc[0]['costo_km_tecnico'] != 0 || $rsc[0]['costo_dirittochiamata_tecnico'] != 0) { + $costo_ore = $rsc[0]['costo_ore']; + $costo_km = $rsc[0]['costo_km']; + $costo_dirittochiamata = $rsc[0]['costo_dirittochiamata']; + + $costo_ore_tecnico = $rsc[0]['costo_ore_tecnico']; + $costo_km_tecnico = $rsc[0]['costo_km_tecnico']; + $costo_dirittochiamata_tecnico = $rsc[0]['costo_dirittochiamata_tecnico']; + } + + // ...altrimenti se non c'è una tariffa per il tecnico leggo i costi globali + else { + $rsc = $dbo->fetchArray('SELECT * FROM in_tipiintervento WHERE idtipointervento='.prepare($idtipointervento)); + + $costo_ore = $rsc[0]['costo_orario']; + $costo_km = $rsc[0]['costo_km']; + $costo_dirittochiamata = $rsc[0]['costo_diritto_chiamata']; + + $costo_ore_tecnico = $rsc[0]['costo_orario_tecnico']; + $costo_km_tecnico = $rsc[0]['costo_km_tecnico']; + $costo_dirittochiamata_tecnico = $rsc[0]['costo_diritto_chiamata_tecnico']; + } + + // Leggo i costi unitari da contratto se l'intervento è legato ad un contratto e c'è almeno un record... + if (!empty($idcontratto)) { + $rsc = $dbo->fetchArray('SELECT * FROM co_contratti_tipiintervento WHERE idcontratto='.prepare($idcontratto).' AND idtipointervento='.prepare($idtipointervento)); + + if (count($rsc) == 1) { + $costo_ore = $rsc[0]['costo_ore']; + $costo_km = $rsc[0]['costo_km']; + $costo_dirittochiamata = $rsc[0]['costo_dirittochiamata']; + + $costo_ore_tecnico = $rsc[0]['costo_ore_tecnico']; + $costo_km_tecnico = $rsc[0]['costo_km_tecnico']; + $costo_dirittochiamata_tecnico = $rsc[0]['costo_dirittochiamata_tecnico']; + } + } + + // Inserisco le ore dei tecnici nella tabella "in_interventi_tecnici" + $dbo->insert('in_interventi_tecnici', [ + 'idintervento' => $idintervento, + 'idtipointervento' => $idtipointervento, + 'idtecnico' => $idtecnico, + 'km' => $km, + 'orario_inizio' => $inizio, + 'orario_fine' => $fine, + 'ore' => $ore, + 'prezzo_ore_unitario' => $costo_ore, + 'prezzo_km_unitario' => $costo_km, + + 'prezzo_ore_consuntivo' => $costo_ore * $ore + $costo_dirittochiamata, + 'prezzo_km_consuntivo' => 0, + 'prezzo_dirittochiamata' => $costo_dirittochiamata, + + 'prezzo_ore_unitario_tecnico' => $costo_ore_tecnico, + 'prezzo_km_unitario_tecnico' => $costo_km_tecnico, + + 'prezzo_ore_consuntivo_tecnico' => $costo_ore_tecnico * $ore + $costo_dirittochiamata_tecnico, + 'prezzo_km_consuntivo_tecnico' => 0, + 'prezzo_dirittochiamata_tecnico' => $costo_dirittochiamata_tecnico, + ]); +} diff --git a/modules/interventi/plugins/my_impianti.interventi.php b/modules/interventi/plugins/my_impianti.interventi.php new file mode 100644 index 000000000..55a052764 --- /dev/null +++ b/modules/interventi/plugins/my_impianti.interventi.php @@ -0,0 +1,42 @@ + +
+

'._('Interventi eseguiti su questo impianto').'

+
+
'; + +$results = $dbo->fetchArray('SELECT in_interventi.codice, descrizione, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=my_impianti_interventi.idintervento) AS data FROM my_impianti_interventi INNER JOIN in_interventi ON my_impianti_interventi.idintervento=in_interventi.id WHERE idimpianto='.prepare($id_record).' ORDER BY data DESC'); + +if (!empty($results)) { + echo ' + + + + + '; + + foreach ($results as $result) { + echo ' + + + + '; + } + + echo ' +
'._('Intervento').''._('Descrizione').'
+ '.Modules::link('Interventi', $result['codice'], str_replace(['_NUM_', '_DATE_'], [$result['idintervento'], Translator::dateToLocale($result['data'])], _('Intervento _NUM_ del _DATE_'))).' + '.nl2br($result['descrizione']).'
'; +} else { + echo ' +

'._('Nessun intervento su questo impianto').'...

'; +} + +echo ' +
+'; diff --git a/modules/iva/actions.php b/modules/iva/actions.php new file mode 100644 index 000000000..c3c0e5c48 --- /dev/null +++ b/modules/iva/actions.php @@ -0,0 +1,53 @@ +fetchNum('SELECT * FROM `co_iva` WHERE `descrizione`='.prepare($descrizione).' AND `id`!='.prepare($id_record)) == 0) { + $dbo->query('UPDATE `co_iva` SET `descrizione`='.prepare($descrizione).', `percentuale`='.prepare($percentuale).', `indetraibile`='.prepare($indetraibile).', `dicitura`='.prepare($dicitura).' WHERE `id`='.prepare($id_record)); + $_SESSION['infos'][] = _('Salvataggio completato!'); + } else { + $_SESSION['errors'][] = str_replace('_TYPE_', 'IVA', _("E' già presente una tipologia di _TYPE_ con la stessa descrizione!")); + } + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'add': + $descrizione = filter('descrizione'); + $percentuale = filter('percentuale'); + $indetraibile = filter('indetraibile'); + + if (isset($descrizione) && isset($percentuale) && isset($indetraibile)) { + if ($dbo->fetchNum('SELECT * FROM `co_iva` WHERE `descrizione`='.prepare($descrizione)) == 0) { + $dbo->query('INSERT INTO `co_iva` (`descrizione`, `percentuale`, `indetraibile`) VALUES ('.prepare($descrizione).', '.prepare($percentuale).', '.prepare($indetraibile).')'); + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = str_replace('_TYPE_', 'IVA', _('Aggiunta nuova tipologia di _TYPE_')); + } else { + $_SESSION['errors'][] = str_replace('_TYPE_', 'IVA', _("E' già presente una tipologia di _TYPE_ con la stessa descrizione!")); + } + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'delete': + if (isset($id_record)) { + $dbo->query('DELETE FROM `co_iva` WHERE `id`='.prepare($id_record)); + + $_SESSION['infos'][] = str_replace('_TYPE_', 'IVA', _('Tipologia di _TYPE_ eliminata con successo!')); + } + + break; +} diff --git a/modules/iva/add.php b/modules/iva/add.php new file mode 100644 index 000000000..56f299ec8 --- /dev/null +++ b/modules/iva/add.php @@ -0,0 +1,31 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "" ]} +
+
+ +
+
+ {[ "type": "number", "label": "", "name": "percentuale", "value": "", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "indetraibile", "value": "", "icon-after": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/iva/edit.php b/modules/iva/edit.php new file mode 100644 index 000000000..fb9806f2c --- /dev/null +++ b/modules/iva/edit.php @@ -0,0 +1,49 @@ +
+ + + +
+ +
+

+ + +
+
+

+
+ +
+
+
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "$descrizione$" ]} +
+
+ +
+
+ {[ "type": "number", "label": "", "name": "percentuale", "value": "$percentuale$", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "indetraibile", "value": "$indetraibile$", "icon-after": "" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "", "name": "dicitura", "value": "$dicitura$" ]} +
+
+
+
+ +
+ + + + diff --git a/modules/iva/init.php b/modules/iva/init.php new file mode 100644 index 000000000..2c257eb58 --- /dev/null +++ b/modules/iva/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM `co_iva` WHERE id='.prepare($id_record)); +} diff --git a/modules/listini/actions.php b/modules/listini/actions.php new file mode 100644 index 000000000..f7d726637 --- /dev/null +++ b/modules/listini/actions.php @@ -0,0 +1,33 @@ +query($query); + + $_SESSION['infos'][] = _('Informazioni salvate correttamente!'); + break; + + case 'add': + $nome = post('nome'); + $prc_guadagno = post('prc_guadagno'); + + if (isset($nome)) { + $dbo->query('INSERT INTO mg_listini( nome, prc_guadagno ) VALUES ('.prepare($nome).', '.prepare($prc_guadagno).')'); + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = _('Nuovo listino aggiunto!'); + } + break; + + case 'delete': + $dbo->query('DELETE FROM mg_listini WHERE id='.prepare($id_record)); + $_SESSION['infos'][] = _('Listino eliminato!'); + break; +} diff --git a/modules/listini/add.php b/modules/listini/add.php new file mode 100644 index 000000000..f43e5e339 --- /dev/null +++ b/modules/listini/add.php @@ -0,0 +1,26 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "prc_guadagno", "required": 1, "class": "text-right", "value": "0", "icon-after": "%" ]} +
+ +
+ + +
+
+ +
+
+
diff --git a/modules/listini/edit.php b/modules/listini/edit.php new file mode 100644 index 000000000..f94f5a0cd --- /dev/null +++ b/modules/listini/edit.php @@ -0,0 +1,44 @@ +
+ + + + +
+
+

+
+ +
+
+ +
+
+ + +
+
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "$nome$" ]} +
+
+ {[ "type": "text", "label": "", "name": "prc_guadagno", "required": 1, "class": "text-right", "value": "$prc_guadagno$", "icon-after": "%" ]} +
+ +
+
+
+ {[ "type": "textarea", "label": "", "name": "note", "value": "$note$" ]} +
+
+ + +
+
+ +
+ + + + diff --git a/modules/listini/init.php b/modules/listini/init.php new file mode 100644 index 000000000..de3b38c1e --- /dev/null +++ b/modules/listini/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM mg_listini WHERE id='.prepare($id_record)); +} diff --git a/modules/misure/actions.php b/modules/misure/actions.php new file mode 100644 index 000000000..208a4d36b --- /dev/null +++ b/modules/misure/actions.php @@ -0,0 +1,52 @@ +fetchNum('SELECT * FROM `mg_unitamisura` WHERE `valore`='.prepare($valore).' AND `id`!='.prepare($id_record)) == 0) { + $dbo->query('UPDATE `mg_unitamisura` SET `valore`='.prepare($valore).' WHERE `id`='.prepare($id_record)); + $_SESSION['infos'][] = _('Salvataggio completato!'); + } else { + $_SESSION['errors'][] = str_replace('_TYPE_', 'unità di misura', _("E' già presente una tipologia di _TYPE_ con lo stesso valore!")); + } + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'add': + $valore = filter('valore'); + + if (isset($valore)) { + if ($dbo->fetchNum('SELECT * FROM `mg_unitamisura` WHERE `valore`='.prepare($valore)) == 0) { + $dbo->query('INSERT INTO `mg_unitamisura` (`valore`) VALUES ('.prepare($valore).')'); + + $id_record = $dbo->lastInsertedID(); + + if (isAjaxRequest()) { + echo json_encode(['id' => $valore, 'text' => $valore]); + } + + $_SESSION['infos'][] = str_replace('_TYPE_', 'unità di misura', _('Aggiunta nuova tipologia di _TYPE_')); + } else { + $_SESSION['errors'][] = str_replace('_TYPE_', 'unità di misura', _("E' già presente una tipologia di _TYPE_ con lo stesso valore!")); + } + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'delete': + if (isset($id_record)) { + $dbo->query('DELETE FROM `mg_unitamisura` WHERE `id`='.prepare($id_record)); + $_SESSION['infos'][] = str_replace('_TYPE_', 'unità di misura', _('Tipologia di _TYPE_ eliminata con successo!')); + } + + break; +} diff --git a/modules/misure/add.php b/modules/misure/add.php new file mode 100644 index 000000000..652106816 --- /dev/null +++ b/modules/misure/add.php @@ -0,0 +1,21 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "valore", "required": 1, "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/misure/edit.php b/modules/misure/edit.php new file mode 100644 index 000000000..0bc02d075 --- /dev/null +++ b/modules/misure/edit.php @@ -0,0 +1,33 @@ +
+ + + +
+ +
+

+ + +
+
+

+
+ +
+
+
+ {[ "type": "text", "label": "", "name": "valore", "required": 1, "value": "$valore$" ]} +
+
+
+
+ +
+ + + + diff --git a/modules/misure/init.php b/modules/misure/init.php new file mode 100644 index 000000000..a8dc187b6 --- /dev/null +++ b/modules/misure/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM `mg_unitamisura` WHERE id='.prepare($id_record)); +} diff --git a/modules/my_impianti/actions.php b/modules/my_impianti/actions.php new file mode 100644 index 000000000..efa0a42ff --- /dev/null +++ b/modules/my_impianti/actions.php @@ -0,0 +1,121 @@ +query($query); + + $_SESSION['infos'][] = _('Informazioni salvate correttamente!'); + + // Upload file + if (!empty($_FILES) && !empty($_FILES['immagine']['name'])) { + $filename = $_FILES['immagine']['name']; + $tmp = $_FILES['immagine']['tmp_name']; + + $filename = unique_filename($filename, $upload_dir); + + if (move_uploaded_file($tmp, $upload_dir.'/'.$filename)) { + $dbo->query('UPDATE my_impianti SET immagine='.prepare($filename).' WHERE id='.prepare($id_record)); + } else { + $_SESSION['warnings'][] = str_replace('_DIR_', $upload_dir, _('Errore durante il caricamento del file in _DIR_!')); + } + } + + // Eliminazione file + if (post('delete_immagine') !== null) { + $filename = basename(post('immagine')); + unlink($upload_dir.'/'.$filename); + + $dbo->query("UPDATE my_impianti SET immagine='' WHERE id=".prepare($id_record)); + } + } + break; + + // Aggiungo impianto + case 'add': + $matricola = post('matricola'); + $idanagrafica = post('idanagrafica'); + $nome = post('nome'); + $idtecnico = post('idtecnico'); + + if (!empty($matricola)) { + $dbo->query('INSERT INTO my_impianti(matricola, idanagrafica, nome, data, idtecnico) VALUES ('.prepare($matricola).', '.prepare($idanagrafica).', '.prepare($nome).', NOW(), '.prepare($idtecnico).')'); + + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = _('Aggiunto nuovo impianto!'); + } + + break; + + // Carica i campi da compilare del componente + case 'load_componente': + include_once $docroot.'/modules/my_impianti/modutil.php'; + + $filename = post('filename'); + $idarticolo = post('idarticolo'); + + // Se è stato specificato un idarticolo, carico il file .ini dal campo `contenuto` di quell'idarticolo + $rs = $dbo->fetchArray('SELECT contenuto, componente_filename FROM mg_articoli WHERE id='.prepare($idarticolo)); + + // Se i campi da caricare sono del componente già salvato leggo dal campo `contenuto`... + if ($rs[0]['componente_filename'] == $filename) { + $contenuto = $rs[0]['contenuto']; + } + + // ...altrimenti carico dal file .ini + else if (file_exists($docroot.'/files/my_impianti/'.$filename)) { + $contenuto = file_get_contents($docroot.'/files/my_impianti/'.$filename); + } + + genera_form_componente($contenuto); + + break; + + // Rimuovo impianto e scollego tutti i suoi componenti + case 'delete': + $dbo->query('DELETE FROM my_impianti WHERE id='.prepare($id_record)); + + $_SESSION['infos'][] = _('Impianto e relativi componenti eliminati!'); + break; +} diff --git a/modules/my_impianti/add.php b/modules/my_impianti/add.php new file mode 100644 index 000000000..a893b70ba --- /dev/null +++ b/modules/my_impianti/add.php @@ -0,0 +1,33 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "matricola", "required": 1, "class": "text-center", "value": "" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "", "ajax-source": "clienti" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idtecnico", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='Tecnico' AND deleted=0 ORDER BY ragione_sociale", "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/my_impianti/edit.php b/modules/my_impianti/edit.php new file mode 100644 index 000000000..d404c6462 --- /dev/null +++ b/modules/my_impianti/edit.php @@ -0,0 +1,109 @@ +
+ + + + + +
+
+

+
+ +
+
+ +
+
+ +
+
+ + {[ "type": "image", "label": "", "name": "immagine", "class": "img-thumbnail", "value": "" ]} +
+ +
+
+
+ {[ "type": "text", "label": "", "name": "matricola", "required": 1, "class": "text-center", "value": "$matricola$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "$nome$" ]} +
+
+ +
+ {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idanagrafica$", "extra": "onchange=\"load_preventivi( this.value ); load_contratti( this.value ); $('#idsede').load( '/ajax_autocomplete.php?module=Anagrafiche&op=get_sedi_select&idanagrafica='+$('#idanagrafica option:selected').val() ); load_impianti( $('#idanagrafica option:selected').val(), $('#idsede option:selected').val() );\"", "ajax-source": "clienti" ]} +
+
+
+
+ +
+
+ {[ "type": "select", "label": "", "name": "idtecnico", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, 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='Tecnico' AND deleted=0 ORDER BY ragione_sociale ASC", "value": "$idtecnico$" ]} +
+ +
+ {[ "type": "date", "label": "", "name": "data", "value": "$data$" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idsede", "values": "query=SELECT 0 AS id, 'Sede legale' AS descrizione UNION SELECT id, CONCAT_WS( ' - ', nomesede, citta ) AS descrizione FROM an_sedi WHERE idanagrafica='$idanagrafica$'", "value": "$idsede$" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "", "name": "descrizione", "value": "$descrizione$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "", "name": "proprietario", "value": "$proprietario$" ]} +
+ +
+ +
+
+ {[ "type": "text", "label": "", "name": "ubicazione", "value": "$ubicazione$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "palazzo", "value": "$palazzo$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "scala", "value": "$scala$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "", "name": "piano", "value": "$piano$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "interno", "value": "$interno$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "occupante", "value": "$occupante$" ]} +
+
+ +
+
+
+ + + + diff --git a/modules/my_impianti/init.php b/modules/my_impianti/init.php new file mode 100644 index 000000000..74ae5f138 --- /dev/null +++ b/modules/my_impianti/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT *, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=my_impianti.idanagrafica) AS cliente FROM my_impianti WHERE id='.prepare($id_record).Modules::getAdditionalsQuery($id_module)); +} diff --git a/modules/my_impianti/modutil.php b/modules/my_impianti/modutil.php new file mode 100644 index 000000000..6c1be401b --- /dev/null +++ b/modules/my_impianti/modutil.php @@ -0,0 +1,15 @@ + $value) { + $fields[$key] = '
'.$value.'
'; + } + + echo $title.PHP_EOL.implode(PHP_EOL, $fields).PHP_EOL.''; +} diff --git a/modules/my_impianti/plugins/my_impianti.anagrafiche.php b/modules/my_impianti/plugins/my_impianti.anagrafiche.php new file mode 100644 index 000000000..a0733b5c0 --- /dev/null +++ b/modules/my_impianti/plugins/my_impianti.anagrafiche.php @@ -0,0 +1,80 @@ +query('DELETE FROM my_impianti WHERE idanagrafica='.prepare($id_record).' AND id='.prepare($matricola)); + + $_SESSION['infos'][] = _('Impianto rimosso!'); +} + +// IMPIANTI +echo ' +
+
+

'._('Impianti del cliente').'

+
+
'; + +// Verifico se l'anagrafica è un cliente +$rs = $dbo->fetchNum('SELECT idtipoanagrafica FROM an_tipianagrafiche_anagrafiche WHERE idanagrafica = '.prepare($id_record)." AND idtipoanagrafica = (SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Cliente')"); + +if (!empty($rs)) { + $rs = $dbo->fetchArray('SELECT * FROM my_impianti WHERE idanagrafica='.prepare($id_record)); + + if (!empty($rs)) { + foreach ($rs as $r) { + echo ' +
+ '; + + // MATRICOLA + echo ' + + + + '; + + // NOME + echo ' + + + + '; + + // DATA + echo ' + + + + '; + + // DESCRIZIONE + echo ' + + + + +
'._('Matricola').': + '.Modules::link('MyImpianti', $r['id'], ''.$r['matricola'].'').' + + + + +
'._('Nome').':'.$r['nome'].'
'._('Data').':'.Translator::dateToLocale($r['data']).'
'._('Descrizione').':'.$r['descrizione'].'
+
'; + } + } else { + echo ' +

'._('Questa anagrafica non ha impianti').'...

'; + } +} else { + echo ' +

'._("L'anagrafica corrente non è di tipo 'Cliente'").'.

'; +} + +echo ' +
+
'; diff --git a/modules/my_impianti/plugins/my_impianti.componenti.php b/modules/my_impianti/plugins/my_impianti.componenti.php new file mode 100644 index 000000000..4d3715ab1 --- /dev/null +++ b/modules/my_impianti/plugins/my_impianti.componenti.php @@ -0,0 +1,286 @@ +fetchArray($query); + $contenuto = $rs[0]['contenuto']; + + $contenuto = \Util\Ini::write($contenuto, $post); + + $query = 'UPDATE my_impianto_componenti SET data='.prepare($data).', contenuto='.prepare($contenuto).' WHERE idimpianto='.prepare($id_record).' AND id='.prepare($idcomponente); + $dbo->query($query); + + $_SESSION['infos'][] = _('Informazioni componente aggiornate correttamente!'); + + $_SESSION['idcomponente'] = $idcomponente; + break; + + case 'linkcomponente': + $filename = get('filename'); + + if (!empty($filename)) { + $contenuto = file_get_contents($docroot.'/files/my_impianti/'.$filename); + $nome = \Util\Ini::getValue(\Util\Ini::readFile($docroot.'/files/my_impianti/'.$filename), 'Nome'); + + $query = 'INSERT INTO my_impianto_componenti(filename, idimpianto, contenuto, nome, data) VALUES('.prepare($filename).', '.prepare($id_record).', '.prepare($contenuto).', '.prepare($nome).', NOW())'; + $dbo->query($query); + + $idcomponente = $dbo->lastInsertedID(); + $_SESSION['idcomponente'] = $idcomponente; + + $_SESSION['infos'][] = _("Aggiunto un nuovo componente all'impianto!"); + } + break; + + case 'sostituiscicomponente': + $filename = get('filename'); + $id = get('id'); + + $nome = \Util\Ini::getValue(\Util\Ini::readFile($docroot.'/files/my_impianti/'.$filename), 'Nome'); + $contenuto = file_get_contents($docroot.'/files/my_impianti/'.$filename); + + // Verifico che questo componente non sia già stato sostituito + $query = 'SELECT * FROM my_impianto_componenti WHERE idsostituto = '.prepare($id); + $rs = $dbo->fetchArray($query); + + if (empty($rs)) { + // Inserisco il nuovo componente in sostituzione + $query = 'INSERT INTO my_impianto_componenti(idsostituto, filename, idimpianto, contenuto, nome, data) VALUES('.prepare($id).', '.prepare($filename).', '.prepare($id_record).', '.prepare($contenuto).', '.prepare($nome).', NOW())'; + $dbo->query($query); + + $idcomponente = $dbo->lastInsertedID(); + $_SESSION['idcomponente'] = $idcomponente; + + // Aggiorno la data di sostituzione del componente precedente + $query = 'UPDATE my_impianto_componenti SET data_sostituzione = NOW() WHERE idimpianto = '.prepare($id_record).' AND id = '.prepare($id); + $dbo->query($query); + + $_SESSION['infos'][] = _('Aggiunto un nuovo componente in sostituzione al precedente!'); + } else { + $_SESSION['errors'][] = _('Questo componente è già stato sostituito!').' '.('Nessuna modifica applicata'); + } + break; + + case 'unlinkcomponente': + $idcomponente = filter('id'); + + $query = 'DELETE FROM my_impianto_componenti WHERE id='.prepare($idcomponente).' AND idimpianto='.prepare($id_record); + $dbo->query($query); + + $_SESSION['infos'][] = _("Rimosso componente dall'impianto!"); + break; +} + +// Componenti non ancora collegati +if ($id_list == '') { + $id_list = '0'; +} + +echo ' +
+
+

'._('Componenti installati').'

+
+
'; + +// Elenca i componenti disponibili +$cmp = \Util\Ini::getList($docroot.'/files/my_impianti/', $id_list); + +echo ' +
+
+ +
+ +
'; +echo " + "._('Aggiungi').''; +echo ' +
+
+ +
+
'; + +// Mostro tutti i componenti utilizzati elencando quelli attualmente installati per primi. +$q2 = 'SELECT *, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE in_interventi.id=my_impianto_componenti.idintervento) AS data_intervento FROM my_impianto_componenti WHERE idimpianto = '.prepare($id_record).' ORDER by nome ASC, data_intervento DESC, idsostituto DESC'; +$rs2 = $dbo->fetchArray($q2); +$n2 = count($rs2); + +if (!empty($rs2)) { + $prev_componente = ''; + + echo ' +
'; + + // Ciclo tra tutti i componenti + for ($j = 0; $j < $n2; ++$j) { + $contenuto = $rs2[$j]['contenuto']; + + $nome_componente = $rs2[$j]['nome']; + $filename = $rs2[$j]['filename']; + + if ($rs2[$j]['data_sostituzione'] == '0000-00-00 00:00:00') { + $statocomponente = str_replace('_DATE_', Translator::dateToLocale($rs2[$j]['data']), _('INSTALLATO in data _DATE_')); + } else { + $statocomponente = str_replace('_DATE_', Translator::dateToLocale($rs2[$j]['data_sostituzione']), _('SOSTITUITO in data _DATE_')); + } + + // Per più "versioni" dello stesso componente mostro un riga meno evidente + // per non confonderlo come componente in uso in questo momento + $same = ($prev_componente == $nome_componente); + echo ' +
+ '; + + if (get('id') == $rs2[$j]['id']) { + $in = 'in'; + } elseif ($_SESSION['idcomponente'] == $rs2[$j]['id']) { + unset($_SESSION['idcomponente']); + $in = 'in'; + } else { + $in = ''; + } + + echo ' +
+
'; + // FORM COMPONENTE + echo ' +
+ '; + + // Nome + echo ' +
+ {[ "type": "span", "label": "'._('Nome').':", "name": "nome", "value": "'.$rs2[$j]['nome'].'" ]} +
'; + + // Data + echo ' +
+ {[ "type": "date", "label": "'._('Data').':", "name": "data_componente", "id": "data_componente'.$j.'", "value": "'.$rs2[$j]['data'].'" ]} +
'; + + $fields = \Util\Ini::getFields($contenuto); + + array_shift($fields); + foreach ($fields as $field) { + echo ' +
+ '.$field.' +
'; + } + + $interventi = $dbo->fetchArray('SELECT *, (SELECT descrizione FROM in_tipiintervento WHERE idtipointervento=in_interventi.idtipointervento) AS tipo, (SELECT descrizione FROM in_statiintervento WHERE idstatointervento=in_interventi.idstatointervento) AS stato, (SELECT colore FROM in_statiintervento WHERE idstatointervento=in_interventi.idstatointervento) AS colore FROM in_interventi INNER JOIN my_componenti_interventi ON my_componenti_interventi.id_intervento=in_interventi.id WHERE id_componente='.prepare($rs2[$j]['id']).' ORDER BY id_intervento'); + if ($interventi != null) { + // Collegamento a intervento se c'è + echo ' +
+ '._('Interventi collegati').': + + + + + + + + '; + + foreach ($interventi as $intervento) { + echo ' + + + + + + + '; + } + + echo ' +
'._('Codice').''._('Tipo').''._('Stato').''._('Data richiesta').''._('Dettagli').'
'.$intervento['id_intervento'].''.$intervento['tipo'].''.$intervento['stato'].''.$intervento['data_richiesta'].''.Modules::link('Interventi', $intervento['id_intervento'], null, '-').'
+
'; + } else { + echo ' +
+
+
'._('Nessun intervento collegato a questo componente!').'
+
'; + } + + if (!empty($rs2[$j]['idintervento'])) { + echo ' + '.Modules::link('Interventi', $rs2[$j]['id'], str_replace(['_NUM_', '_DATE_'], [$rs2[$j]['codice'], Translator::dateToLocale($rs2[$j]['data_intervento'])], 'Intervento _NUM_ del _DATE_')).'
'; + } + + echo ' +
+
'; + + // Pulsante Salva/Elimina + echo ' +
+ + + + '._('Elimina').' + +
'; + + // Sostituisci componente con un altro dello stesso tipo, posso sostituire solo i componenti installati + echo ' +
'; + if ($rs2[$j]['data_sostituzione'] == '0000-00-00 00:00:00') { + echo " + "._('Sostituisci questo componente').'

'; + } else { + echo ' +

'._('Componente già sostituito').'

'; + } + + echo ' +
+ +
+
+
+
'; + $prev_componente = $nome_componente; + } + echo ' +
'; +} else { + echo ' +

'._('Nessun componente inserito').'.

'; +} + +echo ' +
+
'; diff --git a/modules/my_impianti/plugins/my_impianti.interventi.php b/modules/my_impianti/plugins/my_impianti.interventi.php new file mode 100644 index 000000000..591d5f581 --- /dev/null +++ b/modules/my_impianti/plugins/my_impianti.interventi.php @@ -0,0 +1,179 @@ +fetchArray('SELECT * FROM my_impianti_interventi WHERE idintervento='.prepare($id_record)); + $matricole_old = array_column($matricole_old, 'idimpianto'); + + // Individuazione delle matricole mancanti + foreach ($matricole_old as $matricola) { + if (!in_array($matricola, $matricole)) { + $dbo->query('DELETE FROM my_impianti_interventi WHERE idintervento='.prepare($id_record).' AND idimpianto = '.prepare($matricola)); + + $components = $dbo->fetchArray('SELECT * FROM my_impianto_componenti WHERE idimpianto = '.prepare($matricola)); + if (!empty($components)) { + foreach ($components as $component) { + $dbo->query('DELETE FROM my_componenti_interventi WHERE id_componente = '.prepare($component['id']).' AND id_intervento = '.prepare($id_record)); + } + } + } + } + + foreach ($matricole as $matricola) { + if (!in_array($matricola, $matricole_old)) { + $dbo->query('INSERT INTO my_impianti_interventi(idimpianto, idintervento) VALUES('.prepare($matricola).', '.prepare($id_record).')'); + } + } + + $_SESSION['infos'][] = _('Informazioni impianti salvate!'); +} elseif (filter('op') == 'link_componenti') { + $components = (array) $post['componenti']; + + $list = (!empty($post['list'])) ? explode(',', $post['list']) : []; + foreach ($list as $delete) { + if (!in_array($delete, $components)) { + $dbo->query('DELETE FROM my_componenti_interventi WHERE id_componente = '.prepare($delete).' AND id_intervento = '.prepare($id_record)); + } + } + + foreach ($components as $component) { + if (!in_array($component, $list)) { + $dbo->query('INSERT INTO my_componenti_interventi(id_componente, id_intervento) VALUES('.prepare($component).', '.prepare($id_record).')'); + } + } + + $_SESSION['infos'][] = _('Informazioni componenti salvate!'); +} + +// IMPIANTI +echo ' +
+
+

'._("Impianti dell'intervento").'

+
+
+

'._("Impianti su cui è stato effettuato l'intervento").'

'; + +$query = 'SELECT * FROM my_impianti_interventi INNER JOIN my_impianti ON my_impianti_interventi.idimpianto=my_impianti.id WHERE idintervento='.prepare($id_record); +$rs = $dbo->fetchArray($query); + +$impianti = array_column($rs, 'id'); + +echo ' +
'; + +foreach ($rs as $r) { + echo ' +
+ '; + + // MATRICOLA + echo ' + + + + '; + + // NOME + echo ' + + + + '; + + // DATA + echo ' + + + + '; + + // DESCRIZIONE + echo ' + + + + '; + + echo ' + + + + +
'._('Matricola').':'.$r['matricola'].'
'._('Nome').': + '.Modules::link('MyImpianti', $r['id'], $r['nome']).' +
'._('Data').':'.Translator::dateToLocale($r['data']).'
'._('Descrizione').':'.$r['descrizione'].'
'._("Componenti soggetti all'intervento").' +
+ + +

+ + + +
+
+
'; +} + +echo ' +
'; + +/* + Aggiunta impianti all'intervento +*/ +// Elenco impianti collegati all'intervento +$matricole = $dbo->fetchArray('SELECT idimpianto FROM my_impianti_interventi WHERE idintervento='.prepare($id_record)); +$matricole = !empty($matricole) ? array_column($matricole, 'idimpianto') : []; + +// Elenco sedi +$sedi = $dbo->fetchArray('SELECT id, nomesede, citta FROM an_sedi WHERE idanagrafica='.prepare($records[0]['idanagrafica'])." UNION SELECT 0, 'Sede legale', '' ORDER BY id"); + +echo ' +

'._('Impianti disponibili').'

+
+ +
+
+ {[ "type": "select", "name": "matricole[]", "multiple": 1, "value": "'.implode(',', $impianti).'", "values": "query=SELECT my_impianti.id, CONCAT(matricola, \' - \', nome) AS descrizione, CONCAT(nomesede, IF(citta IS NULL OR citta = \'\', \'\', CONCAT(\' (\', citta, \')\'))) AS optgroup FROM my_impianti JOIN (SELECT id, nomesede, citta FROM an_sedi UNION SELECT 0, \'Sede legale\', \'\') AS t ON t.id = my_impianti.idsede WHERE idanagrafica='.prepare($records[0]['idanagrafica']).' ORDER BY idsede ASC, matricola ASC" ]} +
+
+

+ + +
'; + +echo ' +
+
'; diff --git a/modules/ordini/actions.php b/modules/ordini/actions.php new file mode 100644 index 000000000..0a4d31d7e --- /dev/null +++ b/modules/ordini/actions.php @@ -0,0 +1,385 @@ +fetchArray('SELECT id FROM or_tipiordine WHERE dir='.prepare($dir)); + $idtipoordine = $rs[0]['id']; + + if (isset($post['idanagrafica'])) { + $numero = get_new_numeroordine($data); + if ($dir == 'entrata') { + $numero_esterno = get_new_numerosecondarioordine($data); + } else { + $numero_esterno = ''; + } + + $campo = ($dir == 'entrata') ? 'idpagamento_vendite' : 'idpagamento_acquisti'; + + // Tipo di pagamento predefinito dall'anagrafica + $query = 'SELECT id FROM co_pagamenti WHERE id=(SELECT '.$campo.' AS pagamento FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica).')'; + $rs = $dbo->fetchArray($query); + $idpagamento = $rs[0]['id']; + + // Se l'ordine è un ordine cliente e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni + if ($dir == 'entrata' && $idpagamento == '') { + $idpagamento = get_var('Tipo di pagamento predefinito'); + } + + $query = 'INSERT INTO or_ordini( numero, numero_esterno, idanagrafica, idtipoordine, idpagamento, data, idstatoordine ) VALUES ( '.prepare($numero).', '.prepare($numero_esterno).', '.prepare($idanagrafica).', '.prepare($idtipoordine).', '.prepare($idpagamento).', '.prepare($data).", (SELECT `id` FROM `or_statiordine` WHERE `descrizione`='Non evaso') )"; + $dbo->query($query); + + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = str_replace('_NUM_', $numero, _('Aggiunto ordine numero _NUM_!')); + } + break; + + case 'update': + if ($id_record != '') { + $numero_esterno = post('numero_esterno'); + $numero = post('numero'); + $data = $post['data']; + $idanagrafica = post('idanagrafica'); + $note = post('note'); + $idstatoordine = post('idstatoordine'); + $idpagamento = post('idpagamento'); + $idsede = post('idsede'); + $idconto = post('idconto'); + $idagente = post('idagente'); + $totale_imponibile = get_imponibile_ordine($id_record); + $totale_ordine = get_totale_ordine($id_record); + + $tipo_sconto = $post['tipo_sconto_generico']; + $sconto = $post['sconto_generico']; + + if ($dir == 'uscita') { + $idrivalsainps = post('idrivalsainps'); + $idritenutaacconto = post('idritenutaacconto'); + $bollo = post('bollo'); + } else { + $idrivalsainps = 0; + $idritenutaacconto = 0; + $bollo = 0; + } + + // Leggo la descrizione del pagamento + $query = 'SELECT descrizione FROM co_pagamenti WHERE id='.prepare($idpagamento); + $rs = $dbo->fetchArray($query); + $pagamento = $rs[0]['descrizione']; + + // Query di aggiornamento + $query = 'UPDATE or_ordini SET idanagrafica='.prepare($idanagrafica).','. + ' numero='.prepare($numero).','. + ' data='.prepare($data).','. + ' idagente='.prepare($idagente).','. + ' idstatoordine='.prepare($idstatoordine).','. + ' idpagamento='.prepare($idpagamento).','. + ' idsede='.prepare($idsede).','. + ' numero_esterno='.prepare($numero_esterno).','. + ' note='.prepare($note).','. + ' idconto='.prepare($idconto).','. + ' idrivalsainps='.prepare($idrivalsainps).','. + ' idritenutaacconto='.prepare($idritenutaacconto).','. + ' tipo_sconto_globale='.prepare($tipo_sconto).','. + ' sconto_globale='.prepare($sconto).','. + ' bollo=0, rivalsainps=0, ritenutaacconto=0 WHERE id='.prepare($id_record); + + if ($dbo->query($query)) { + $dbo->query("DELETE FROM or_righe_ordini WHERE descrizione LIKE '%SCONTO%' AND idordine=".prepare($id_record)); + + // Sconto unitario, quello percentuale viene gestito a fondo pagina + if ($tipo_sconto == 'UNT' && $sconto > 0) { + $subtotale = -$sconto; + + // Calcolo anche l'iva da scontare + $rsi = $dbo->fetchArray('SELECT descrizione, percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita'))); + $iva = $subtotale / 100 * $rsi[0]['percentuale']; + + $dbo->query('INSERT INTO or_righe_ordini(idordine, descrizione, idiva, desc_iva, iva, subtotale, sconto, qta, idgruppo, `order`) VALUES( '.prepare($id_record).", 'SCONTO', ".prepare($idiva).', '.prepare($rsi[0]['descrizione']).', '.prepare($iva).', '.prepare($subtotale).', 0, 1, (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'))'); + } + + $query = 'SELECT descrizione FROM or_statiordine WHERE id='.prepare($idstatoordine); + $rs = $dbo->fetchArray($query); + + // Ricalcolo inps, ritenuta e bollo (se l'ordine non è stato evaso) + if ($dir == 'entrata') { + if ($rs[0]['descrizione'] != 'Pagato') { + ricalcola_costiagg_ordine($id_record); + } + } else { + if ($rs[0]['descrizione'] != 'Pagato') { + ricalcola_costiagg_ordine($id_record, $idrivalsainps, $idritenutaacconto, $bollo); + } + } + + $_SESSION['infos'][] = _('Ordine modificato correttamente!'); + } + } + break; + + case 'addarticolo': + if ($id_record != '' && isset($post['idarticolo'])) { + $idarticolo = post('idarticolo'); + $idiva = post('idiva'); + $descrizione = post('descrizione'); + $qta = post('qta'); + $prezzo_vendita = post('prezzo'); + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // Calcolo idgruppo per questo inserimento + $ridgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(idgruppo) + 1, 0) AS idgruppo FROM or_righe_ordini WHERE idordine = '.prepare($id_record)); + $idgruppo = $ridgruppo[0]['idgruppo']; + + add_articolo_inordine($id_record, $idarticolo, $descrizione, $idiva, $qta, $prezzo_vendita * $qta, $sconto, $sconto_unitario, $tipo_sconto, '', '', '', $idgruppo); + + $_SESSION['infos'][] = _('Articolo aggiunto!'); + } + ricalcola_costiagg_ordine($id_record); + break; + + case 'addriga': + if ($id_record != '') { + // Selezione costi da intervento + $descrizione = post('descrizione'); + $prezzo = post('prezzo'); + $qta = post('qta'); + $idiva = post('idiva'); + $um = post('um'); + $subtot = $prezzo * $qta; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // Calcolo iva + $query = 'SELECT descrizione, percentuale, indetraibile 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']; + + $query = 'INSERT INTO or_righe_ordini(idordine, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idgruppo, `order`) VALUES('.prepare($id_record).', '.prepare($idiva).', '.prepare($rs[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'))'; + + if ($dbo->query($query)) { + $_SESSION['infos'][] = _('Riga aggiunta!'); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_ordine($id_record); + } else { + ricalcola_costiagg_ordine($id_record); + } + } + } + break; + + // Scollegamento articolo da ordine + case 'unlink_articolo': + $idarticolo = post('idarticolo'); + $idriga = post('idriga'); + + if ($id_record != '' && $idarticolo != '') { + rimuovi_articolo_daordine($idarticolo, $id_record, $idriga); + + // if( $dbo->query($query) ){ + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_ordine($id_record); + } else { + ricalcola_costiagg_ordine($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Articolo rimosso!'); + } + + break; + + // Scollegamento riga generica da ordine + case 'unlink_riga': + $idriga = post('idriga'); + + if ($id_record != '' && $idriga != '') { + $query = 'DELETE FROM or_righe_ordini WHERE idordine='.prepare($id_record).' AND id='.prepare($idriga); + + $dbo->query($query); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_ordine($id_record); + } else { + ricalcola_costiagg_ordine($id_record, 0, 0, 0); + } + + $_SESSION['infos'][] = _('Riga rimossa!'); + } + break; + + // Modifica riga + case 'editriga': + if (isset($post['idriga'])) { + $idriga = post('idriga'); + $descrizione = post('descrizione'); + $prezzo = post('prezzo'); + $qta = post('qta'); + $idiva = post('idiva'); + $um = post('um'); + $subtot = $prezzo * $qta; + + // Calcolo dello sconto + $sconto_unitario = $post['sconto']; + $tipo_sconto = $post['tipo_sconto']; + $sconto = ($tipo_sconto == 'PRC') ? ($prezzo * $sconto_unitario) / 100 : $sconto_unitario; + $sconto = $sconto * $qta; + + // 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']; + + // Lettura idarticolo dalla riga documento + $rs = $dbo->fetchArray('SELECT idgruppo, idordine, idarticolo, qta, abilita_serial FROM or_righe_ordini WHERE id='.prepare($idriga)); + $idarticolo = $rs[0]['idarticolo']; + $old_qta = $rs[0]['qta']; + $idgruppo = $rs[0]['idgruppo']; + $idordine = $rs[0]['idordine']; + $abilita_serial = $rs[0]['abilita_serial']; + + // Modifica riga generica sul documento + $query = 'UPDATE or_righe_ordini SET idiva='.prepare($idiva).', desc_iva='.prepare($rs[0]['descrizione']).', 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).' WHERE idgruppo='.prepare($idgruppo).' AND idordine='.prepare($idordine); + if ($dbo->query($query)) { + // Modifica della quantità + $dbo->query('UPDATE or_righe_ordini SET qta='.prepare($qta).' WHERE idgruppo='.prepare($idgruppo)); + + // Modifica per gestire i serial + if (!empty($idarticolo)) { + $new_qta = $qta - $old_qta; + $new_qta = ($old_qta < $qta) ? $new_qta : -$new_qta; + + if (!empty($abilita_serial)) { + if ($old_qta < $qta) { + for ($i = 0; $i < $new_qta; ++$i) { + $dbo->query('INSERT INTO or_righe_ordini(idordine, idarticolo, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idgruppo, `order`) SELECT idordine, idarticolo, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idgruppo, `order` FROM or_righe_ordini WHERE id='.prepare($idriga)); + } + } else { + if ($dir == 'uscita') { + if ($new_qta > $dbo->fetchArray("SELECT COUNT(*) AS rimovibili FROM or_righe_ordini WHERE serial NOT IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idgruppo=".prepare($idgruppo).' AND idordine='.prepare($idordine))[0]['rimovibili']) { + $_SESSION['errors'][] = _('Alcuni serial number sono già stati utilizzati!'); + + return; + } else { + $deletes = $dbo->fetchArray('SELECT id FROM or_righe_ordini AS t WHERE idgruppo = '.prepare($idgruppo).' AND idordine='.prepare($idordine)." AND serial NOT IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') ORDER BY serial ASC LIMIT ".$new_qta); + } + } else { + $deletes = $dbo->fetchArray('SELECT id FROM or_righe_ordini AS t WHERE idgruppo = '.prepare($idgruppo).' AND idordine='.prepare($idordine).' ORDER BY serial ASC LIMIT '.$new_qta); + } + + foreach ((array) $deletes as $delete) { + $dbo->query('DELETE FROM or_righe_ordini WHERE id = '.prepare($delete['id'])); + } + } + } + } + + $_SESSION['infos'][] = _('Riga modificata!'); + + // Ricalcolo inps, ritenuta e bollo + if ($dir == 'entrata') { + ricalcola_costiagg_ordine($id_record); + } else { + ricalcola_costiagg_ordine($id_record); + } + } + } + break; + + // eliminazione ordine + case 'delete': + if ($dir == 'uscita') { + $non_rimovibili = $dbo->fetchArray("SELECT COUNT(*) AS non_rimovibili FROM or_righe_ordini WHERE serial IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idordine=".prepare($id_record))[0]['non_rimovibili']; + if ($non_rimovibili != 0) { + $_SESSION['errors'][] = _('Alcuni serial number sono già stati utilizzati!'); + + return; + } + } + + $dbo->query('DELETE FROM or_ordini WHERE id='.prepare($id_record)); + $dbo->query('DELETE FROM or_righe_ordini WHERE idordine='.prepare($id_record)); + $_SESSION['infos'][] = _('Ordine eliminato!'); + + break; + + case 'add_serial': + $idgruppo = $post['idgruppo']; + $serial = $post['serial']; + + $q = 'SELECT * FROM or_righe_ordini WHERE idordine='.prepare($id_record).' AND idgruppo='.prepare($idgruppo).' ORDER BY id'; + $rs = $dbo->fetchArray($q); + + foreach ($rs as $i => $r) { + $dbo->query('UPDATE or_righe_ordini SET serial='.prepare($serial[$i]).' WHERE id='.prepare($r['id'])); + } + + break; + + case 'update_position': + $start = filter('start'); + $end = filter('end'); + $id = filter('id'); + + if ($start > $end) { + $dbo->query('UPDATE `or_righe_ordini` SET `order`=`order` + 1 WHERE `order`>='.prepare($end).' AND `order`<'.prepare($start).' AND `idordine`='.prepare($id_record)); + $dbo->query('UPDATE `or_righe_ordini` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } elseif ($end != $start) { + $dbo->query('UPDATE `or_righe_ordini` SET `order`=`order` - 1 WHERE `order`>'.prepare($start).' AND `order`<='.prepare($end).' AND `idordine`='.prepare($id_record)); + $dbo->query('UPDATE `or_righe_ordini` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } + + break; +} + +if (post('op') !== null) { + $rs_sconto = $dbo->fetchArray('SELECT sconto_globale, tipo_sconto_globale FROM or_ordini WHERE id='.prepare($id_record)); + + // Aggiorno l'eventuale sconto gestendolo con le righe in fattura + if ($rs_sconto[0]['tipo_sconto_globale'] == 'PRC' && !empty($rs_sconto[0]['sconto_globale'])) { + // Se lo sconto c'è già lo elimino e lo ricalcolo + $dbo->query("DELETE FROM or_righe_ordini WHERE descrizione LIKE '%SCONTO %' AND idordine=".prepare($id_record)); + + $subtotale = get_imponibile_ordine($id_record); + $subtotale = -$subtotale / 100 * $rs_sconto[0]['sconto_globale']; + + // Calcolo anche l'iva da scontare + $rsi = $dbo->fetchArray('SELECT descrizione, percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita'))); + $iva = $subtotale / 100 * $rsi[0]['percentuale']; + + $descrizione = 'SCONTO '.Translator::numberToLocale($rs_sconto[0]['sconto_globale']).'%'; + + $dbo->query('INSERT INTO or_righe_ordini(idordine, descrizione, idiva, desc_iva, iva, subtotale, sconto, qta, idgruppo, `order`) VALUES( '.prepare($id_record).', '.prepare($descrizione).', '.prepare($idiva).', '.prepare($rsi[0]['descrizione']).', '.prepare($iva).', '.prepare($subtotale).', 0, 1, (SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'), (SELECT IFNULL(MAX(`order`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'))'); + } +} diff --git a/modules/ordini/add.php b/modules/ordini/add.php new file mode 100644 index 000000000..e363df059 --- /dev/null +++ b/modules/ordini/add.php @@ -0,0 +1,40 @@ +
+ + + + +
+
+ {[ "type": "date", "label": "", "name": "data", "required": 1, "value": "-now-" ]} +
+ +
+ {[ "type": "select", "label": "", "name": "idanagrafica", "required": 1, "value": "", "value": "", "ajax-source": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/ordini/add_articolo.php b/modules/ordini/add_articolo.php new file mode 100644 index 000000000..3a4f89923 --- /dev/null +++ b/modules/ordini/add_articolo.php @@ -0,0 +1,153 @@ +fetchArray($q); +$numero = (!empty($rs[0]['numero_esterno'])) ? $rs[0]['numero_esterno'] : $rs[0]['numero']; +$idanagrafica = $rs[0]['idanagrafica']; +$prc_guadagno = $rs[0]['prc_guadagno']; + +// Seleziona articolo +// - per i documenti di vendita deve esserci almeno 1 unità +// - per i documenti di acquisto mostro tutti gli articoli +$_SESSION['superselect']['dir'] = $dir; + +echo ' +

'.str_replace('_NUM_', $numero, _('Ordine numero _NUM_')).'

+ +
+ + + '; + +// Articolo +echo ' +
+
+ {[ "type": "select", "label": "'._('Articolo').'", "name": "idarticolo", "required": 1, "value": "'.$idarticolo.'", "ajax-source": "articoli" ]} +
+
'; + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1 ]} +
+
'; + +// Nelle fatture di acquisto leggo l'iva di acquisto dal fornitore +if ($dir == 'uscita') { + $rsf = $dbo->fetchArray('SELECT idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica)); + $idiva_predefinita = $rsf[0]['idiva']; +} + +// Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica +$idiva = $idiva ?: get_var('Iva predefinita'); + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +// Quantità +echo ' +
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "1", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure" ]} +
+
'; + +// Costo unitario +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "icon-after": "choice|untprc" ]} +
+
'; + +// Informazioni aggiuntive +echo ' +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
'; + +echo ' + '; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/ordini/add_riga.php b/modules/ordini/add_riga.php new file mode 100644 index 000000000..34c5502c9 --- /dev/null +++ b/modules/ordini/add_riga.php @@ -0,0 +1,124 @@ +fetchArray($q); +$numero = (!empty($rs[0]['numero_esterno'])) ? $rs[0]['numero_esterno'] : $rs[0]['numero']; +$idanagrafica = $rs[0]['idanagrafica']; + +$idriga = $get['idriga']; + +if (empty($idriga)) { + $op = 'addriga'; + $button = _('Aggiungi'); + + // valori default + $descrizione = ''; + $qta = 1; + $um = ''; + $prezzo = 0; + $sconto = 0; + + // Nelle fatture di acquisto leggo l'iva di acquisto dal fornitore + if ($dir == 'uscita') { + $rsf = $dbo->fetchArray('SELECT idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($idanagrafica)); + $idiva = $rsf[0]['idiva']; + } + + // Leggo l'iva predefinita dall'articolo e se non c'è leggo quella predefinita generica + $idiva = $idiva ?: get_var('Iva predefinita'); +} else { + $op = 'editriga'; + $button = _('Modifica'); + + $rsr = $dbo->fetchArray('SELECT * FROM or_righe_ordini WHERE idordine='.prepare($id_record).' AND id='.prepare($idriga)); + + $descrizione = $rsr[0]['descrizione']; + $qta = $rsr[0]['qta']; + $um = $rsr[0]['um']; + $idiva = $rsr[0]['idiva']; + $prezzo = $rsr[0]['subtotale'] / $rsr[0]['qta']; + $sconto = $rsr[0]['sconto_unitario']; + $tipo_sconto = $rsr[0]['tipo_sconto']; +} + +/* + Form di inserimento riga documento +*/ +echo ' +

'.str_replace('_NUM_', $numero, _('Ordine numero _NUM_')).'

+ +
+ + + '; + +if (!empty($idriga)) { + echo ' + '; +} + +// Descrizione +echo ' +
+
+ {[ "type": "textarea", "label": "'._('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]} +
+
'; + +// Iva +echo ' +
+
+ {[ "type": "select", "label": "'._('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]} +
'; + +// Quantità +echo ' +
+ {[ "type": "number", "label": "'._('Q.tà').'", "name": "qta", "required": 1, "value": "'.$qta.'", "decimals": "qta" ]} +
'; + +// Unità di misura +echo ' +
+ {[ "type": "select", "label": "'._('Unità di misura').'", "icon-after": "add|'.Modules::getModule('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure", "value": "'.$um.'" ]} +
+
'; + +// Costo unitario +echo ' +
+
+ {[ "type": "number", "label": "'._('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "€", "value": "'.$prezzo.'" ]} +
'; + +// Sconto unitario +echo ' +
+ {[ "type": "number", "label": "'._('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]} +
+
'; + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/ordini/add_serial.php b/modules/ordini/add_serial.php new file mode 100644 index 000000000..b34367899 --- /dev/null +++ b/modules/ordini/add_serial.php @@ -0,0 +1,108 @@ +fetchArray($q2); + +echo ' +

'._('Articolo').': '.$rs2[0]['codice'].' - '.$rs2[0]['descrizione'].'

+ +
+ + + + '; + +$serials = []; +$array = array_column($rs2, 'serial'); +foreach ($array as $value) { + if (!empty($value)) { + $serials[] = $value; + } +} + +if ($dir == 'entrata') { + echo ' +
+
+ {[ "type": "select", "label": "'._('Serial').'", "name": "serial[]", "multiple": 1, "value": "'.implode(',', $serials).'", "values": "query=SELECT serial AS id, serial AS descrizione FROM vw_serials WHERE dir=\'uscita\' AND serial NOT IN (SELECT serial FROM vw_serials WHERE dir=\'entrata\' AND record != \'fat-'.$id_record.'\')", "extra": "data-maximum=\"'.count($rs2).'\"" ]} +
+
'; +} else { + echo ' +

'._('Inserisci i numeri seriali degli articoli aggiunti:').'

'; + + foreach ($array as $key => $serial) { + if ($key % 3 == 0) { + echo ' +
'; + } + + $res = $dbo->fetchArray("SELECT record FROM vw_serials WHERE dir='entrata' AND serial = ".prepare($serial)); + + echo ' +
+ {[ "type": "text", "name": "serial[]", "value": "'.$serial.'"'.(!empty($res) ? ', "readonly": 1' : '').' ]}'; + + if (!empty($res)) { + $pieces = explode('-', $res[0]['record']); + switch ($pieces[0]) { + case 'int': + $modulo = 'Interventi'; + break; + + case 'ddt': + $modulo = 'Ddt di vendita'; + break; + + case 'fat': + $modulo = 'Fatture di vendita'; + break; + + case 'ord': + $modulo = 'Ordini cliente'; + break; + } + + echo ' + '.Modules::link($modulo, $pieces[1], _('Visualizza vendita').' ', null); + } + echo ' +
'; + + if (($key + 1) % 3 == 0) { + echo ' +
+
'; + } + } + if (($key + 1) % 3 != 0) { + echo ' + '; + } +} + +echo ' + + +
+
+ +
+
+
'; + +echo ' + '; diff --git a/modules/ordini/creaddt.php b/modules/ordini/creaddt.php new file mode 100644 index 000000000..5db0f360a --- /dev/null +++ b/modules/ordini/creaddt.php @@ -0,0 +1,251 @@ +fetchArray("SELECT * FROM or_ordini WHERE id=".prepare($id_record)); +$numero = (!empty($rs[0]['numero_esterno'])) ? $rs[0]['numero_esterno'] : $rs[0]['numero']; +$idanagrafica = $rs[0]['idanagrafica']; +$idpagamento = $rs[0]['idpagamento']; +$idconto = $rs[0]['idconto']; + +/* + Form di inserimento riga documento +*/ + +echo "

Ordine numero $numero

"; +echo "Seleziona le righe che vuoi inserire nel ddt e la quantità:

"; + +echo ''; +} else { + $attr = ''; + $warning_text = ''; +} + +echo $warning_text; +?> + +
+ + + + + +
+ +
+
+ + +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "$descrizione$", "extra": "" ]} +
+ +
+
+ + + + + + +fetchArray('SELECT * FROM an_tipianagrafiche WHERE idtipoanagrafica='.prepare($id_record)); +} diff --git a/modules/tipi_intervento/actions.php b/modules/tipi_intervento/actions.php new file mode 100644 index 000000000..378b62b6f --- /dev/null +++ b/modules/tipi_intervento/actions.php @@ -0,0 +1,54 @@ +query($query); + $_SESSION['infos'][] = _('Informazioni tipo intervento salvate correttamente!'); + + break; + + case 'add': + $idtipointervento = post('idtipointervento'); + $descrizione = post('descrizione'); + + $query = 'INSERT INTO in_tipiintervento(idtipointervento, descrizione, costo_orario, costo_km) VALUES ('.prepare($idtipointervento).', '.prepare($descrizione).', 0.00, 0.00)'; + $dbo->query($query); + + $id_record = $idtipointervento; + + $_SESSION['infos'][] = _('Nuovo tipo di intervento aggiunto!'); + + break; + + case 'delete': + $query = 'DELETE FROM in_tipiintervento WHERE idtipointervento='.prepare($id_record); + $dbo->query($query); + + // Elimino anche le tariffe collegate ai vari tecnici + $query = 'DELETE FROM in_tariffe WHERE idtipointervento='.prepare($id_record); + $dbo->query($query); + + $_SESSION['infos'][] = _('Tipo di intervento eliminato!'); + break; +} diff --git a/modules/tipi_intervento/add.php b/modules/tipi_intervento/add.php new file mode 100644 index 000000000..a661f80c1 --- /dev/null +++ b/modules/tipi_intervento/add.php @@ -0,0 +1,25 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "idtipointervento", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/tipi_intervento/edit.php b/modules/tipi_intervento/edit.php new file mode 100644 index 000000000..a6b7916e5 --- /dev/null +++ b/modules/tipi_intervento/edit.php @@ -0,0 +1,87 @@ +
+ + + + + +
+ +
+
+ +
+
+ {[ "type": "span", "label": "", "name": "idtipointervento", "value": "$idtipointervento$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "$descrizione$" ]} +
+
+ +
+
+

+
+ +
+
+
+ {[ "type": "number", "label": "", "name": "costo_orario", "required": 1, "value": "$costo_orario$", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "costo_km", "required": 1, "value": "$costo_km$", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "costo_diritto_chiamata", "required": 1, "value": "$costo_diritto_chiamata$", "icon-after": "" ]} +
+
+
+
+ + +
+
+

+
+ +
+
+
+ {[ "type": "number", "label": "", "name": "costo_orario_tecnico", "required": 1, "value": "$costo_orario_tecnico$", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "costo_km_tecnico", "required_tecnico": 1, "value": "$costo_km_tecnico$", "icon-after": "" ]} +
+ +
+ {[ "type": "number", "label": "", "name": "costo_diritto_chiamata_tecnico", "required": 1, "value": "$costo_diritto_chiamata_tecnico$", "icon-after": "" ]} +
+
+
+
+
+ + + + + +fetchArray('SELECT COUNT(*) AS tot_interventi FROM in_interventi WHERE idtipointervento='.prepare($id_record)); + +$tot_interventi = $interventi[0]['tot_interventi']; +if ($tot_interventi > 0) { + echo ' +
+ '.str_replace('_NUM_', $tot_interventi, _('Ci sono _NUM_ interventi collegati')).'. + '._('Eliminando questo tipo di attività, vengono rimossi anche gli interventi collegati!').'. +
'; +} diff --git a/modules/tipi_intervento/init.php b/modules/tipi_intervento/init.php new file mode 100644 index 000000000..f11197299 --- /dev/null +++ b/modules/tipi_intervento/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM in_tipiintervento WHERE idtipointervento='.prepare($id_record)); +} diff --git a/modules/utenti/actions.php b/modules/utenti/actions.php new file mode 100644 index 000000000..8f5903a3d --- /dev/null +++ b/modules/utenti/actions.php @@ -0,0 +1,160 @@ +query('UPDATE zz_users SET enabled=1 WHERE idutente='.prepare($id_utente))) { + $_SESSION['infos'][] = _('Utente abilitato!'); + } + break; + + // Disabilita utente + case 'disable': + if ($dbo->query('UPDATE zz_users SET enabled=0 WHERE idutente='.prepare($id_utente))) { + $_SESSION['infos'][] = _('Utente disabilitato!'); + } + break; + + // Cambio di password e usernome dell'utente + case 'change_pwd': + $id_utente = filter('idutente'); + $min_length = filter('min_length'); + $min_length_username = filter('min_length_username'); + + $password = filter('password1'); + $password_rep = filter('password2'); + + // Verifico che la password sia di almeno x caratteri + if(strlen($password) < $min_length){ + $_SESSION['errors'][] = str_replace('_MIN_', $min_length, _('La password deve essere lunga almeno _MIN_ caratteri!')); + } + elseif($password != $password_rep){ + $_SESSION['errors'][] = _('Le password non coincidono'); + } + else{ + $dbo->query('UPDATE zz_users SET password='.prepare(Auth::hashPassword($password)).' WHERE idutente='.prepare($id_utente)); + + $_SESSION['infos'][] = _('Password aggiornata!'); + } + + $username = filter('username'); + + // Se ho modificato l'username, verifico che questo non sia già stato usato + $rs = $dbo->fetchArray('SELECT username FROM zz_users WHERE idutente='.prepare($id_utente)); + + if ($rs[0]['username'] != $username) { + $n = $dbo->fetchNum('SELECT idutente FROM zz_users WHERE username='.prepare($username)); + + if ($n == 0) { + $dbo->query('UPDATE zz_users SET username='.prepare($username).' WHERE idutente='.prepare($id_utente)); + + $_SESSION['infos'][] = _('Username aggiornato!'); + } else { + $_SESSION['errors'][] = _('Utente già esistente!'); + } + } + break; + + // Aggiunta di un nuovo utente + case 'adduser': + $username = filter('username'); + + $min_length = filter('min_length'); + $min_length_username = filter('min_length_username'); + + $password = filter('password1'); + $password_rep = filter('password2'); + + $idtipoanagrafica = ''; + $idanag = explode('-', filter('idanag')); + if (count($idanag) == 2) { + $idtipoanagrafica = $idanag[0]; + $idanagrafica = $idanag[1]; + } + + // Verifico che questo username non sia già stato usato + $n = $dbo->fetchNum('SELECT * FROM zz_users WHERE username='.prepare($username)); + + if ($n == 0) { + // Verifico che la password sia di almeno x caratteri + if(strlen($password) < $min_length){ + $_SESSION['errors'][] = str_replace('_MIN_', $min_length, _('La password deve essere lunga almeno _MIN_ caratteri!')); + } + elseif($password != $password_rep){ + $_SESSION['errors'][] = _('Le password non coincidono'); + } + else{ + if ($dbo->query('INSERT INTO zz_users(idgruppo, username, password, idanagrafica, idtipoanagrafica, enabled, email) VALUES('.prepare($id_record).', '.prepare($username).', '.prepare(Auth::hashPassword($password)).', '.prepare($idanagrafica).', '.prepare($idtipoanagrafica).", 1, '')")) { + $dbo->query('INSERT INTO `zz_tokens` (`id_utente`, `token`) VALUES ('.prepare($dbo->lastInsertedID()).', '.prepare(secure_random_string()).')'); + + $_SESSION['infos'][] = _('Utente aggiunto!'); + } + } + } else { + $_SESSION['errors'][] = _('Utente già esistente!'); + } + break; + + // Aggiunta nuovo gruppo + case 'add': + $nome = filter('nome'); + + // Verifico che questo username non sia già stato usato + if ($dbo->fetchNum('SELECT nome FROM zz_groups WHERE nome='.prepare($nome)) == 0) { + $dbo->query('INSERT INTO zz_groups( nome, editable ) VALUES('.prepare($nome).', 1)'); + $_SESSION['infos'][] = _('Gruppo aggiunto!'); + $id_record = $dbo->lastInsertedID(); + } else { + $_SESSION['errors'][] = _('Gruppo già esistente!'); + } + break; + + // Elimina utente + case 'delete': + if ($dbo->query('DELETE FROM zz_users WHERE idutente='.prepare($id_utente))) { + $_SESSION['infos'][] = _('Utente eliminato!'); + } + break; + + // Elimina gruppo + case 'deletegroup': + // Verifico se questo gruppo si può eliminare + $query = 'SELECT editable FROM zz_groups WHERE id='.prepare($id_record); + $rs = $dbo->fetchArray($query); + + if ($rs[0]['editable'] == 1) { + if ($dbo->query('DELETE FROM zz_groups WHERE id='.prepare($id_record))) { + $dbo->query('DELETE FROM zz_users WHERE idgruppo='.prepare($id_record)); + $dbo->query('DELETE FROM zz_permissions WHERE idgruppo='.prepare($id_record)); + $_SESSION['infos'][] = _('Gruppo eliminato!'); + } + } else { + $_SESSION['errors'][] = _('Questo gruppo non si può eliminare!'); + } + + break; + + // Aggiornamento dei permessi di accesso + case 'update_permission': + $permessi = filter('permesso'); + $idmodulo = filter('idmodulo'); + + // Verifico che ci sia il permesso per questo gruppo + $rs = $dbo->fetchArray('SELECT * FROM zz_permissions WHERE idgruppo='.prepare($id_record).' AND idmodule='.prepare($idmodulo)); + if (count($rs) == 0) { + $query = 'INSERT INTO zz_permissions(idgruppo, idmodule, permessi) VALUES('.prepare($id_record).', '.prepare($idmodulo).', '.prepare($permessi).')'; + } else { + $query = 'UPDATE zz_permissions SET permessi='.prepare($permessi).' WHERE id='.prepare($rs[0]['id']); + } + + $dbo->query($query); + + ob_end_clean(); + echo 'ok'; + + break; +} diff --git a/modules/utenti/add.php b/modules/utenti/add.php new file mode 100644 index 000000000..647804ccf --- /dev/null +++ b/modules/utenti/add.php @@ -0,0 +1,21 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/utenti/edit.php b/modules/utenti/edit.php new file mode 100644 index 000000000..cc1c769d4 --- /dev/null +++ b/modules/utenti/edit.php @@ -0,0 +1,152 @@ +fetchArray('SELECT * FROM zz_modules WHERE parent IS NULL ORDER BY `order` ASC'); + +$utenti = $dbo->fetchArray("SELECT *, (SELECT ragione_sociale FROM an_anagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE an_anagrafiche.idanagrafica=zz_users.idanagrafica AND an_tipianagrafiche_anagrafiche.idtipoanagrafica=zz_users.idtipoanagrafica) AS ragione_sociale, (SELECT descrizione FROM an_tipianagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche.idtipoanagrafica=an_tipianagrafiche_anagrafiche.idtipoanagrafica WHERE idanagrafica=zz_users.idanagrafica AND an_tipianagrafiche.idtipoanagrafica=zz_users.idtipoanagrafica) AS tipo FROM zz_users WHERE idgruppo=".prepare($record['id'])); + +echo ' +
+
+

'.str_replace('_GROUP_', $records[0]['nome'], _('Utenti _GROUP_')).'

+
+ +
'; +if (count($utenti) != 0) { + echo ' + + + + + + + '; + + for ($u = 0; $u < count($utenti); ++$u) { + echo ' + + '.$utenti[$u]['username'].''; + if ($utenti[$u]['idanagrafica'] != 0) { + echo ' + + '; + } else { + echo ' + + '; + } + /* + * Funzioni per gli utenti + */ + echo ' + + '; + } + + echo ' +
'._('Nome utente').''._('Ragione sociale').''._('Tipo di anagrafica').''._('Opzioni').'
'.Modules::link('Anagrafiche', $utenti[$u]['idanagrafica'], $utenti[$u]['ragione_sociale']).''.$utenti[$u]['tipo'].'--'; + // Disabilitazione utente, se diverso da idutente #1 (admin) + if ($utenti[$u]['idutente'] != '1') { + if ($utenti[$u]['enabled'] == 1) { + echo ' + '; + } else { + echo ' + '; + } + } else { + echo ' + '; + } + + // Cambio password e nome utente + echo ' + '; + + // Eliminazione utente, se diverso da idutente #1 (admin) + if ($utenti[$u]['idutente'] != '1') { + echo ' + '; + } else { + echo ' + '; + } + + echo ' +
'; +} else { + echo ' +

'._('Non ci sono utenti in questo gruppo').'...

'; +} +echo ' + '._('Aggiungi utente').' +
+
'; + +// Aggiunta nuovo utente +echo ' +
'; + +echo ' +
+
+

'._('Permessi').'

+
+ +
'; +if ($record['nome'] != 'Amministratori') { + echo ' + + + + + '; + for ($m = 0; $m < count($moduli); ++$m) { + $perms_values = ['-', 'r', 'rw']; + $perms_names = [_('Nessun permesso'), _('Sola lettura'), _('Lettura e scrittura')]; + echo menuSelection($moduli[$m], -1, $perms_values, $perms_names); + } + + echo ' +
'._('Modulo').''._('Permessi').'
'; +} else { + echo ' +

'._('Gli amministratori hanno accesso a qualsiasi modulo').'.

'; +} +echo ' +
+
'; + +// Eliminazione gruppo (se non è tra quelli di default) +if ($record['editable'] == 1) { + echo ' + '; +} + +echo ' +'; diff --git a/modules/utenti/init.php b/modules/utenti/init.php new file mode 100644 index 000000000..d2b3f9bca --- /dev/null +++ b/modules/utenti/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM `zz_groups` WHERE `id`='.prepare($id_record)); +} diff --git a/modules/utenti/modutil.php b/modules/utenti/modutil.php new file mode 100644 index 000000000..0c9e592f7 --- /dev/null +++ b/modules/utenti/modutil.php @@ -0,0 +1,50 @@ +fetchArray("SELECT * FROM zz_modules WHERE enabled='1' AND parent=".prepare($element['id'])." ORDER BY `order` ASC"); + + if ($submenus != null && count($submenus) != 0) { + $temp = ''; + foreach ($submenus as $submenu) { + $temp .= menuSelection($submenu, $depth, $perms_values, $perms_names); + } + } + $result .= ' + + '.str_repeat('     ', $depth).$name.' + + + + + '.$temp; + + return $result; +} diff --git a/modules/utenti/user.php b/modules/utenti/user.php new file mode 100644 index 000000000..9c73d8580 --- /dev/null +++ b/modules/utenti/user.php @@ -0,0 +1,83 @@ +fetchArray('SELECT username FROM zz_users WHERE idutente='.prepare($id_utente)); + $username = $rs[0]['username']; + $message = _('Modifica'); +} else { + $value = 'adduser'; + $username = ''; + $message = _('Aggiungi'); +} + +echo ' + + + +'; diff --git a/modules/viste/actions.php b/modules/viste/actions.php new file mode 100644 index 000000000..9ed387b4e --- /dev/null +++ b/modules/viste/actions.php @@ -0,0 +1,170 @@ +query('UPDATE `zz_modules` SET `title`='.prepare($post['title']).', `options2`='.prepare($post['options2']).' WHERE `id`='.prepare($id_record)); + } else { + $rs = false; + } + + if ($rs) { + $_SESSION['infos'][] = _('Salvataggio completato!'); + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'fields': + $rs = true; + + $dbo->query('DELETE FROM `zz_group_view` WHERE `id_vista` IN (SELECT `id` FROM `zz_views` WHERE `id_module`='.prepare($id_record).')'); + foreach ((array) $post['query'] as $c => $k) { + // Fix per la protezone contro XSS + $post['query'][$c] = htmlspecialchars_decode($post['query'][$c], ENT_QUOTES); + + if (check_query($post['query'][$c])) { + $array = [ + 'name' => $post['name'][$c], + 'query' => $post['query'][$c], + 'enabled' => $post['enabled'][$c], + 'search' => $post['search'][$c], + 'slow' => $post['slow'][$c], + 'format' => $post['format'][$c], + 'summable' => $post['sum'][$c], + 'search_inside' => $post['search_inside'][$c], + 'order_by' => $post['order_by'][$c], + ]; + + if (!empty($post['id'][$c]) && !empty($post['query'][$c])) { + $id = $post['id'][$c]; + + $dbo->update('zz_views', $array, ['id' => $id]); + } elseif (!empty($post['query'][$c])) { + $array['order'] = '#(SELECT IFNULL(MAX(`order`) + 1, 0) FROM zz_views AS t WHERE id_module='.prepare($id_record).')#'; + + $dbo->insert('zz_views', $array); + + $id = $dbo->lastInsertedID(); + } + + // Aggiunta dei permessi relativi + $gruppi = array_unique((array) $post['gruppi'][$c]); + foreach ($gruppi as $gruppo) { + $dbo->query('INSERT INTO `zz_group_view` (`id_gruppo`, `id_vista`) VALUES ('.prepare($gruppo).', '.prepare($id).')'); + } + } else { + $rs = false; + } + } + + if ($rs) { + $_SESSION['infos'][] = _('Salvataggio completato!'); + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'filters': + $rs = true; + + foreach ((array) $post['query'] as $c => $k) { + // Fix per la protezone contro XSS + $post['query'][$c] = htmlspecialchars_decode($post['query'][$c], ENT_QUOTES); + + if (check_query($post['query'][$c])) { + $array = [ + 'idgruppo' => $post['gruppo'][$c], + 'clause' => $post['query'][$c], + 'position' => !empty($post['position'][$c]) ? 'HVN' : 'WHR', + ]; + + if (!empty($post['id'][$c]) && !empty($post['query'][$c])) { + $id = $post['id'][$c]; + + $dbo->update('zz_group_module', $array, ['id' => $id]); + } elseif (!empty($post['query'][$c])) { + $dbo->insert('zz_group_module', $array); + + $id = $dbo->lastInsertedID(); + } + } else { + $rs = false; + } + } + + if ($rs) { + $_SESSION['infos'][] = _('Salvataggio completato!'); + } else { + $_SESSION['errors'][] = _('Ci sono stati alcuni errori durante il salvataggio!'); + } + + break; + + case 'change': + $id = filter('id'); + + $rs = $dbo->fetchArray('SELECT enabled FROM zz_group_module WHERE id='.prepare($id)); + + $array = ['enabled' => !empty($rs[0]['enabled']) ? 0 : 1]; + + $dbo->update('zz_group_module', $array, ['id' => $id]); + + $_SESSION['infos'][] = _('Salvataggio completato!'); + + break; + + case 'delete': + $id = filter('id'); + + $dbo->query('DELETE FROM `zz_views` WHERE `id`='.prepare($id)); + $dbo->query('DELETE FROM `zz_group_view` WHERE `id_vista`='.prepare($id)); + + $_SESSION['infos'][] = _('Eliminazione completata!'); + + break; + + case 'delete_filter': + $id = filter('id'); + + $dbo->query('DELETE FROM `zz_group_module` WHERE `id`='.prepare($id)); + + $_SESSION['infos'][] = _('Eliminazione completata!'); + + break; + + case 'update_position': + $start = filter('start') + 1; + $end = filter('end') + 1; + $id = filter('id'); + + if ($start > $end) { + $dbo->query('UPDATE `zz_views` SET `order`=`order` + 1 WHERE `order`>='.prepare($end).' AND `order`<'.prepare($start).' AND id_module='.prepare($id_record)); + $dbo->query('UPDATE `zz_views` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } elseif ($end != $start) { + $dbo->query('UPDATE `zz_views` SET `order`=`order` - 1 WHERE `order`>'.prepare($start).' AND `order`<='.prepare($end).' AND id_module='.prepare($id_record)); + $dbo->query('UPDATE `zz_views` SET `order`='.prepare($end).' WHERE id='.prepare($id)); + } + + break; +} diff --git a/modules/viste/edit.php b/modules/viste/edit.php new file mode 100644 index 000000000..a84b69265 --- /dev/null +++ b/modules/viste/edit.php @@ -0,0 +1,495 @@ + + + + +
+ +
+

+ + +
+
+

'._('Opzioni di visualizzazione').'

+
+ +
'; +$options = ($record['options2'] == '') ? $record['options'] : $record['options2']; +if ($options == 'menu') { + echo ' +

'._('Il modulo che stai analizzando è un semplice menu').'.

'; +} elseif ($options == 'custom') { + echo ' +

'._("Il modulo che stai analizzando possiede una struttura complessa, che prevede l'utilizzo di file personalizzati per la gestione delle viste").'.

'; +} + +echo ' +
+
+ {[ "type": "text", "label": "'._('Codice del modulo').'", "name": "name", "value": "'.$record['name'].'", "readonly": "1" ]} +
+ +
+ {[ "type": "text", "label": "'._('Nome del modulo').'", "name": "title", "value": "'.$record['title'].'", "help": "Il nome che identifica il modulo" ]} +
+
+ +
+
+ {[ "type": "textarea", "label": "'._('Query di default').'", "name": "options", "value": "'.str_replace(']}', '] }', $record['options']).'", "readonly": "1", "class": "autosize" ]} +
+ +
+ {[ "type": "textarea", "label": "'._('Query personalizzata').'", "name": "options2", "value": "'.str_replace(']}', '] }', $record['options2']).'", "class": "autosize", "help": "La query in sostituzione a quella di default: custom, menu oppure " ]} +
+
'; +if ($options != '' && $options != 'menu' && $options != 'custom') { + $module_query = $options; + $total = Modules::getQuery($id_record); + if (strpos($module_query, '|select|') === false) { + $module_query = json_decode($module_query, true); + $module_query = $module_query['main_query'][0]['query']; + } + $module_query = str_replace('|select|', $total['select'], $module_query); + $module_query = str_replace('|period_start|', $_SESSION['period_start'], $module_query); + $module_query = str_replace('|period_end|', $_SESSION['period_end'], $module_query); + + echo ' +
+
+

'._('Query risultante').':

+

'.$module_query.'

+
+
'; +} + +echo ' +
+
+'; + +if (!empty($options) && $options != 'custom') { + echo ' + +
+ + + +
+
+
+
+

'._('Campi disponibili').'

+
+ +
+
+
+ +
+
+
+ +
'; + + $key = 0; + $fields = $dbo->fetchArray('SELECT * FROM zz_views WHERE id_module='.prepare($record['id']).' ORDER BY `order` ASC'); + foreach ($fields as $key => $field) { + $editable = !($field['default'] && $enable_readonly); + + echo ' +
+ +
+
+ + +
+ {[ "type": "text", "label": "'._('Nome').'", "name": "name['.$key.']", "value": "'.$field['name'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Nome con cui il campo viene identificato e visualizzato nella tabella" ]} +
+ +
+ {[ "type": "text", "label": "'._('Query prevista').'", "name": "query['.$key.']", "value": "'.$field['query'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "required": "1", "help": "Nome effettivo del campo sulla tabella oppure subquery che permette di ottenere il valore del campo" ]} +
+
+ +
+
+ {[ "type": "select", "label": "'._('Gruppi con accesso').'", "name": "gruppi['.$key.'][]", "multiple": "1", "values": "query=SELECT id, nome AS descrizione FROM zz_groups ORDER BY id ASC", "value": "'; + $results = $dbo->fetchArray('SELECT GROUP_CONCAT(DISTINCT id_gruppo SEPARATOR \',\') AS gruppi FROM zz_group_view WHERE id_vista='.prepare($field['id'])); + + echo $results[0]['gruppi'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Gruppi di utenti in grado di visualizzare questo campo" ]} +
+ +
+ {[ "type": "select", "label": "'._('Visibilità').'", "name": "enabled['.$key.']", "values": "list=\"0\":\"'._('Nascosto (variabili di stato)').'\",\"1\": \"'._('Visibile nella sezione').'\"", "value": "'.$field['enabled'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Stato del campo: visibile nella tabella oppure nascosto" ]} +
+
+ +
+
+ {[ "type": "checkbox", "label": "'._('Ricercabile').'", "name": "search['.$key.']", "value": "'.$field['search'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Indica se il campo è ricercabile" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Ricerca lenta').'", "name": "slow['.$key.']", "value": "'.$field['slow'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Indica se la ricerca per questo campo è lenta (da utilizzare nel caso di evidenti rallentamenti, mostra solo un avviso all\'utente)" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Sommabile').'", "name": "sum['.$key.']", "value": "'.$field['summable'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Indica se il campo è da sommare" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Formattabile').'", "name": "format['.$key.']", "value": "'.$field['format'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "Indica se il campo è formattabile in modo automatico" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Ricerca tramite').'", "name": "search_inside['.$key.']", "value": "'.$field['search_inside'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "'._('Query personalizzata per la ricerca (consigliata per colori e icone)').'" ]} +
+ +
+ {[ "type": "text", "label": "'._('Ordina tramite').'", "name": "order_by['.$key.']", "value": "'.$field['order_by'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ', "help": "'._("Query personalizzata per l'ordinamento (date e numeri formattati tramite query)").'" ]} +
+
+
+
'; + } + echo ' +
+ +
+
+ + +
+
+ +
+
+
+ +
+
+
+

'._('Ordine di visualizzazione').'

+
+ +
'; + + foreach ($fields as $field) { + echo ' +

+ + '; + if ($field['enabled']) { + echo ''.$field['name'].''; + } else { + echo ''.$field['name'].''; + } + echo ' +

'; + } + + echo ' +
+
+
+'; + + echo ' +
+
+
+

'._('Nuovo campo').'

+
+
+
+ + +
+ {[ "type": "text", "label": "'._('Nome').'", "name": "name[-id-]" ]} +
+ +
+ {[ "type": "text", "label": "'._('Query prevista').'", "name": "query[-id-]" ]} +
+
+ +
+
+ {[ "type": "select", "label": "'._('Gruppi con accesso').'", "name": "gruppi[-id-][]", "multiple": "1", "values": "query=SELECT id, nome AS descrizione FROM zz_groups ORDER BY id ASC" ]} +
+ +
+ {[ "type": "select", "label": "'._('Visibilità').'", "name": "enabled[-id-]", "values": "list=\"0\":\"'._('Nascosto (variabili di stato)').'\",\"1\": \"'._('Visibile nella sezione').'\"" ]} +
+
+ +
+
+ {[ "type": "checkbox", "label": "'._('Ricercabile').'", "name": "search[-id-]" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Ricerca lenta').'", "name": "slow[-id-]" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Sommabile').'", "name": "sum[-id-]" ]} +
+ +
+ {[ "type": "checkbox", "label": "'._('Formattabile').'", "name": "format[-id-]" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Ricerca tramite').'", "name": "search_inside[-id-]" ]} +
+ +
+ {[ "type": "text", "label": "'._('Ordina tramite').'", "name": "order_by[-id-]" ]} +
+
+
+
+
'; + + echo ' +
+ + + +
+
+
+

'._('Filtri per gruppo di utenti').'

+
+ +
+
+
+ +
+
+
+ +
'; + + $num = 0; + $additionals = $dbo->fetchArray('SELECT * FROM zz_group_module WHERE idmodule='.prepare($record['id']).' ORDER BY `id` ASC'); + foreach ($additionals as $num => $additional) { + $editable = !($additional['default'] && $enable_readonly); + + echo ' +
+ +
+
+ + +
+ {[ "type": "textarea", "label": "'._('Query').'", "name": "query['.$num.']", "value": "'.$additional['clause'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ' ]} +
+ +
+ {[ "type": "select", "label": "'._('Gruppo').'", "name": "gruppo['.$num.']", "values": "query=SELECT id, nome AS descrizione FROM zz_groups ORDER BY id ASC", "value": "'.$additional['idgruppo'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ' ]} +
+ +
+ {[ "type": "select", "label": "'._('Posizione').'", "name": "position['.$num.']", "values": "list=\"0\":\"'._('WHERE').'\",\"1\": \"'._('HAVING').'\"", "value": "'.$additional['position'].'"'; + if (!$editable) { + echo ', "readonly": "1"'; + } + echo ' ]} +
+
+
+
'; + } + echo ' +
+ +
+
+ + +
+
+
+
+
+
'; + + echo ' +
+
+
+

'._('Nuovo filtro').'

+
+
+
+ + +
+ {[ "type": "textarea", "label": "'._('Query').'", "name": "query[-id-]" ]} +
+ +
+ {[ "type": "select", "label": "'._('Gruppo').'", "name": "gruppo[-id-]", "values": "query=SELECT id, nome AS descrizione FROM zz_groups ORDER BY id ASC" ]} +
+ +
+ {[ "type": "select", "label": "'._('Posizione').'", "name": "position[-id-]", "list=\"0\":\"'._('WHERE').'\",\"1\": \"'._('HAVING').'\"" ]} +
+
+
+'; + + echo ' +'; +} diff --git a/modules/viste/init.php b/modules/viste/init.php new file mode 100644 index 000000000..51647abf7 --- /dev/null +++ b/modules/viste/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM `zz_modules` WHERE id='.prepare($id_record)); +} diff --git a/modules/voci_servizio/actions.php b/modules/voci_servizio/actions.php new file mode 100644 index 000000000..b1f66c720 --- /dev/null +++ b/modules/voci_servizio/actions.php @@ -0,0 +1,30 @@ +query('UPDATE in_vociservizio SET descrizione='.prepare($descrizione).', categoria='.prepare($categoria).' WHERE id='.prepare($id_record)); + + $_SESSION['infos'][] = _('Informazioni salvate correttamente!'); + + break; + + case 'add': + $descrizione = post('descrizione'); + $categoria = post('categoria'); + + $dbo->query('INSERT INTO in_vociservizio(descrizione, categoria) VALUES ('.prepare($descrizione).', '.prepare($categoria).')'); + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = _('Nuova voce di servizio aggiunta!'); + + break; + + case 'delete': + $dbo->query('DELETE FROM in_vociservizio WHERE id='.prepare($id_record)); + break; +} diff --git a/modules/voci_servizio/add.php b/modules/voci_servizio/add.php new file mode 100644 index 000000000..853ba5bfa --- /dev/null +++ b/modules/voci_servizio/add.php @@ -0,0 +1,25 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "categoria", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/voci_servizio/edit.php b/modules/voci_servizio/edit.php new file mode 100644 index 000000000..0e2259bee --- /dev/null +++ b/modules/voci_servizio/edit.php @@ -0,0 +1,28 @@ +
+ + + + +
+ +
+
+ +
+
+ {[ "type": "text", "label": "", "name": "categoria", "required": 1, "value": "$categoria$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "$descrizione$" ]} +
+
+
+ + + + diff --git a/modules/voci_servizio/init.php b/modules/voci_servizio/init.php new file mode 100644 index 000000000..00afa3f79 --- /dev/null +++ b/modules/voci_servizio/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM in_vociservizio WHERE id='.prepare($id_record)); +} diff --git a/modules/zone/actions.php b/modules/zone/actions.php new file mode 100644 index 000000000..a8a118faa --- /dev/null +++ b/modules/zone/actions.php @@ -0,0 +1,54 @@ +fetchNum('SELECT id FROM an_zone WHERE (nome='.prepare($nome).' OR descrizione='.prepare($descrizione).') AND NOT id='.prepare($id_zona)); + + // Zona già esistente + if ($n > 0) { + $_SESSION['errors'][] = _('Zona già esistente!'); + } + // Zona non esistente + else { + $dbo->query('UPDATE an_zone SET nome='.prepare($nome).', descrizione='.prepare($descrizione).' WHERE id='.prepare($id_zona).' AND `default`=0'); + $_SESSION['infos'][] = _('Informazioni salvate correttamente!'); + } + + break; + + case 'add': + $nome = post('nome'); + $descrizione = post('descrizione'); + + // Verifico che il nome non sia duplicato + $n = $dbo->fetchNum('SELECT id FROM an_zone WHERE nome='.prepare($nome).' OR descrizione='.prepare($descrizione)); + + if ($n > 0) { + $_SESSION['errors'][] = _('Nome già esistente!'); + } else { + $query = 'INSERT INTO an_zone(`nome`, `descrizione`, `default`) VALUES ('.prepare($nome).', '.prepare($descrizione).', 0)'; + $dbo->query($query); + + $id_record = $dbo->lastInsertedID(); + + $_SESSION['infos'][] = _('Aggiunta una nuova zona!'); + } + break; + + case 'delete': + $dbo->query('DELETE FROM an_zone WHERE id='.prepare($id_record).' AND `default`=0'); + + // Reimposto a 0 tutti gli idzona su an_anagrafiche (scollego la zona da tutte le anagrafiche associate) + $dbo->query('UPDATE an_anagrafiche SET idzona = 0 WHERE idanagrafica='.prepare($id_record)); + + $_SESSION['infos'][] = _('Zona eliminata!'); + + break; +} diff --git a/modules/zone/add.php b/modules/zone/add.php new file mode 100644 index 000000000..0b2ee1a2f --- /dev/null +++ b/modules/zone/add.php @@ -0,0 +1,25 @@ +
+ + + +
+
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "" ]} +
+
+ + +
+
+ +
+
+
diff --git a/modules/zone/edit.php b/modules/zone/edit.php new file mode 100644 index 000000000..32baacdd8 --- /dev/null +++ b/modules/zone/edit.php @@ -0,0 +1,30 @@ + +
+ + + + + +
+ +
+
+ +
+
+ {[ "type": "text", "label": "", "name": "nome", "required": 1, "value": "$nome$" ]} +
+ +
+ {[ "type": "text", "label": "", "name": "descrizione", "required": 1, "value": "$descrizione$" ]} +
+
+
+ + + + diff --git a/modules/zone/init.php b/modules/zone/init.php new file mode 100644 index 000000000..1d102c29b --- /dev/null +++ b/modules/zone/init.php @@ -0,0 +1,7 @@ +fetchArray('SELECT * FROM an_zone WHERE id='.prepare($id_record)); +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..91c2328e0 --- /dev/null +++ b/package.json @@ -0,0 +1,199 @@ +{ + "name": "openstamanager", + "description": "Gestionale open source per assistenza tecnica e fatturazione", + "version": "2.3.0", + "license": "GPL-3.0", + "keywords": [ + "open source", + "gestionale", + "assistenza tecnica", + "fatturazione" + ], + "homepage": "http://openstamanager.com/", + "author": { + "name": "Fabio Lovato", + "email": "info@openstamanager.com" + }, + "contributors": [ + { + "name": "Fabio Piovan", + "email": "info@openstamanager.com" + }, + { + "name": "Luca Salvà", + "email": "info@openstamanager.com" + } + ], + "repository": { + "type": "svn", + "url": "svn://svn.code.sf.net/p/openstamanager/code/trunk" + }, + "main": "gulpfile.js", + "dependencies": { + "admin-lte": "^2.3.11", + "autosize": "^3.0.21", + "bootstrap": "^3.3.7", + "bootstrap-colorpicker": "^2.5.1", + "bootstrap-daterangepicker": "^2.1.25", + "bootstrap-switch": "^3.3.4", + "ckeditor": "^4.6.2", + "components-jqueryui": "^1.12.1", + "datatables.net-bs": "^1.10.15", + "datatables.net-buttons-bs": "^1.3.1", + "datatables.net-scroller-bs": "^1.4.2", + "datatables.net-select-bs": "^1.2.2", + "eonasdan-bootstrap-datetimepicker": "^4.17.47", + "font-awesome": "^4.7.0", + "fullcalendar": "^3.4.0", + "html5shiv": "^3.7.3", + "inputmask": "^3.3.6", + "jquery": "^3.2.1", + "jquery-form": "^4.2.1", + "jquery-slimscroll": "^1.3.8", + "jquery-ui-touch-punch": "^0.2.3", + "moment": "^2.18.1", + "parsleyjs": "^2.7.2", + "respond.js": "^1.4.2", + "select2": "^4.0.3", + "select2-bootstrap-theme": "^0.1.0-beta.10", + "signature_pad": "^2.1.1", + "smartwizard": "^4.2.2", + "sweetalert2": "^6.6.5", + "tooltipster": "^4.2.5" + }, + "devDependencies": { + "archiver": "^2.0.0", + "cwd": "^0.10.0", + "del": "^2.2.0", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", + "gulp-clean-css": "^2.3.2", + "gulp-concat": "^2.6.0", + "gulp-debug": "^3.1.0", + "gulp-flatten": "^0.2.0", + "gulp-if": "^2.0.2", + "gulp-json-minify": "^1.0.5", + "gulp-less": "^3.3.0", + "gulp-rename": "^1.2.2", + "gulp-sass": "^3.1.0", + "gulp-stylus": "^2.6.0", + "gulp-uglify": "^1.5.3", + "gulp-util": "^3.0.8", + "main-bower-files": "^2.13.1", + "shelljs": "^0.7.7" + }, + "scripts": { + "gulp": "gulp", + "release-OSM": "yarn run develop-OSM && gulp release", + "develop-OSM": "yarn install && yarn run install-OSM && yarn run assets-OSM", + "install-OSM": "php composer.phar install", + "assets-OSM": "yarn upgrade && yarn run build-OSM", + "build-OSM": "gulp", + "dump-OSM": "php composer.phar dump-autoload", + "doc-OSM": "php couscous.phar generate --target website && php phpDocumentor.phar -d . --ignore=\"vendor/*\" -t website/docs", + "windows-fix": "yarn global add windows-build-tools" + }, + "overrides": { + "almond": { + "ignore": true + }, + "ckeditor": { + "ignore": true + }, + "admin-lte": { + "main": [ + "dist/css/AdminLTE.css", + "dist/js/app.js" + ], + "dependencies": { + "jquery": ">=1.9.1" + } + }, + "bootstrap": { + "main": [ + "dist/js/bootstrap.min.js", + "dist/css/bootstrap.min.css", + "dist/fonts/*" + ], + "dependencies": { + "jquery": ">=1.9.1", + "admin-lte": "*" + } + }, + "datatables.net-bs": { + "main": [ + "js/dataTables.bootstrap.js", + "css/dataTables.bootstrap.css" + ] + }, + "datatables.net-buttons": { + "main": [ + "js/dataTables.buttons.js", + "js/buttons.colVis.js", + "js/buttons.flash.js", + "js/buttons.html5.js", + "js/buttons.print.js" + ] + }, + "datatables.net-buttons-bs": { + "main": [ + "js/buttons.bootstrap.js", + "css/buttons.bootstrap.css" + ] + }, + "datatables.net-scroller-bs": { + "main": "css/scroller.bootstrap.css" + }, + "datatables.net-select-bs": { + "main": "css/select.bootstrap.css" + }, + "font-awesome": { + "main": [ + "css/font-awesome.min.css", + "fonts/*" + ] + }, + "fullcalendar": { + "main": [ + "dist/fullcalendar.js", + "dist/fullcalendar.css" + ] + }, + "inputmask": { + "main": "dist/min/jquery.inputmask.bundle.min.js" + }, + "jquery-slimscroll": { + "main": "jquery.slimscroll.js" + }, + "parsleyjs": { + "main": [ + "dist/parsley.js", + "src/parsley.css" + ] + }, + "select2": { + "main": [ + "dist/js/select2.min.js", + "dist/css/select2.min.css" + ] + }, + "select2-bootstrap-theme": { + "main": "dist/select2-bootstrap.css" + }, + "smartwizard": { + "main": [ + "dist/css/smart_wizard.min.css", + "dist/css/smart_wizard_theme_arrows.min.css", + "dist/css/smart_wizard_theme_circles.min.css", + "dist/css/smart_wizard_theme_dots.min.css", + "dist/js/jquery.smartWizard.min.js" + ] + }, + "sweetalert2": { + "main": [ + "dist/sweetalert2.js", + "dist/sweetalert2.css" + ] + } + } +} diff --git a/pdfgen.php b/pdfgen.php new file mode 100644 index 000000000..8e4c72dcd --- /dev/null +++ b/pdfgen.php @@ -0,0 +1,98 @@ + $value) { + ${$key} = !empty(${$key}) ? ${$key} : $value; +} + +// Mostro o nascondo i costi dell'intervento... +$visualizza_costi = get_var('Visualizza i costi sulle stampe degli interventi'); + +// Nuovo sistema di generazione stampe +if (file_exists($docroot.'/templates/'.$ptype.'/init.php')) { + // Impostazione della stampa + if (file_exists($docroot.'/templates/'.$ptype.'/custom/layout.html')) { + $report = file_get_contents($docroot.'/templates/'.$ptype.'/custom/layout.html'); + } else { + $report = file_get_contents($docroot.'/templates/'.$ptype.'/layout.html'); + } + + // Individuazione delle variabili fondamentali per la sostituzione dei contenuti + if (file_exists($docroot.'/templates/'.$ptype.'/custom/init.php')) { + include $docroot.'/templates/'.$ptype.'/custom/init.php'; + } else { + include $docroot.'/templates/'.$ptype.'/init.php'; + } + + if (!empty($id_module)) { + Permissions::addModule($id_module); + } + Permissions::check(); + + // Operazioni di sostituzione + include $docroot.'/templates/pdfgen_variables.php'; + + // Azioni sui contenuti della stampa + if (file_exists($docroot.'/templates/'.$ptype.'/custom/actions.php')) { + include $docroot.'/templates/'.$ptype.'/custom/actions.php'; + } else { + include $docroot.'/templates/'.$ptype.'/actions.php'; + } +} else { + // Decido se usare la stampa personalizzata (se esiste) oppure quella standard + if (file_exists($ptype.'/custom/pdfgen.'.$ptype.'.php')) { + include $docroot.'/templates/'.$ptype.'/custom/pdfgen.'.$ptype.'.php'; + } else { + include $docroot.'/templates/'.$ptype.'/pdfgen.'.$ptype.'.php'; + } +} + +// Sostituzione di variabili generiche +$report = str_replace('$body$', $body, $report); +$report = str_replace('$footer$', $footer, $report); + +$report = str_replace('$font_size$', $font_size, $report); +$report = str_replace('$body_table_params$', $body_table_params, $report); + +$report = str_replace('$docroot$', $docroot, $report); +$report = str_replace('$rootdir$', $rootdir, $report); + +// Individuazione dellla configurazione +$directory = dirname($filename); +if (!empty($filename) && ((is_dir($directory) && !is_writable($directory)) || (!is_dir($directory) && !mkdir($directory)))) { + $error = str_replace('_DIRECTORY_', $directory, _('Non hai i permessi per creare directory e files in _DIRECTORY_')); + + $_SESSION['errors'][] = $error; + + echo ' +

'.$error.'

'; + + exit(); +} + +$mode = !empty($filename) ? 'F' : 'I'; + +$filename = !empty($filename) ? $filename : sanitizeFilename($report_name); +$title = basename($filename); + +// HTML +$html = (get_var('Formato report') == 'html'); + +try { + ob_end_clean(); + $html2pdf = new HTML2PDF($orientation, 'A4', 'it', true, 'UTF-8'); + + $html2pdf->writeHTML($report, $html); + $html2pdf->pdf->setTitle($title); + + $html2pdf->output($filename, $mode); +} catch (HTML2PDF_exception $e) { + echo $e; + exit(); +} diff --git a/plugin_editor.php b/plugin_editor.php new file mode 100644 index 000000000..63e5c3033 --- /dev/null +++ b/plugin_editor.php @@ -0,0 +1,92 @@ +'._('Record non trovato').'.

'; + } else { + // Lettura template modulo (verifico se ci sono template personalizzati, altrimenti uso quello base) + if (file_exists($docroot.'/plugins/'.$info['directory'].'/custom/edit.php')) { + include $docroot.'/plugins/'.$info['directory'].'/custom/edit.php'; + } elseif (file_exists($docroot.'/plugins/'.$info['directory'].'/custom/edit.html')) { + include $docroot.'/plugins/'.$info['directory'].'/custom/edit.html'; + } elseif (file_exists($docroot.'/plugins/'.$info['directory'].'/edit.php')) { + include $docroot.'/plugins/'.$info['directory'].'/edit.php'; + } elseif (file_exists($docroot.'/plugins/'.$info['directory'].'/edit.html')) { + include $docroot.'/plugins/'.$info['directory'].'/edit.html'; + } + } + + $backto = filter('backto'); + // Scelta del redirect dopo un submit + if (!empty($backto)) { + $hash = filter('hash'); + if ($backto == 'record-edit') { + redirect($rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_parent.$hash); + exit(); + } elseif ($backto == 'record-list') { + redirect($rootdir.'/controller.php?id_module='.$id_module.$hash); + exit(); + } + } + + $module = Modules::getModule($info['idmodule_to']); + + if ($module['permessi'] != 'rw') { + ?> + + +'; diff --git a/plugins/sedi/actions.php b/plugins/sedi/actions.php new file mode 100644 index 000000000..a45ef6377 --- /dev/null +++ b/plugins/sedi/actions.php @@ -0,0 +1,61 @@ + $id_parent, + 'nomesede' => $post['nomesede'], + 'indirizzo' => $post['indirizzo'], + 'indirizzo2' => $post['indirizzo2'], + 'citta' => $post['citta'], + 'cap' => $post['cap'], + 'km' => $post['km'], + 'cellulare' => $post['cellulare'], + 'telefono' => $post['telefono'], + 'email' => $post['email'], + 'idzona' => $post['idzona'], + ]; + + $dbo->insert('an_sedi', $array); + + $_SESSION['infos'][] = _('Aggiunta una nuova sede!'); + + break; + + case 'updatesede': + $array = [ + 'nomesede' => $post['nomesede'], + 'indirizzo' => $post['indirizzo'], + 'indirizzo2' => $post['indirizzo2'], + 'piva' => $post['piva'], + 'codice_fiscale' => $post['codice_fiscale'], + 'citta' => $post['citta'], + 'cap' => $post['cap'], + 'provincia' => $post['provincia'], + 'km' => $post['km'], + 'cellulare' => $post['cellulare'], + 'telefono' => $post['telefono'], + 'email' => $post['email'], + 'fax' => $post['fax'], + 'id_nazione' => !empty($post['id_nazione']) ? $post['id_nazione'] : null, + 'idzona' => $post['idzona'], + ]; + + $dbo->update('an_sedi', $array, ['id' => $post['id']]); + + $_SESSION['infos'][] = _('Salvataggio completato!'); + + break; + + case 'deletesede': + $idsede = filter('id'); + $dbo->query("DELETE FROM `an_sedi` WHERE `id`=".prepare($idsede)); + + $_SESSION['infos'][] = _('Sede eliminata!'); + + break; +} diff --git a/plugins/sedi/add.php b/plugins/sedi/add.php new file mode 100644 index 000000000..12c3f0756 --- /dev/null +++ b/plugins/sedi/add.php @@ -0,0 +1,70 @@ + + + + +
+
+ {[ "type": "text", "label": "'._('Nome sede').'", "name": "nomesede", "required": 1 ]} +
+ +
+ {[ "type": "text", "label": "'._('Indirizzo').'", "name": "indirizzo", "required": 1 ]} +
+ +
+ {[ "type": "text", "label": "'._('Secondo indirizzo').'", "name": "indirizzo2" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Città').'", "name": "citta" ]} +
+ +
+ {[ "type": "text", "label": "'._('C.A.P.').'", "name": "cap" ]} +
+ +
+ {[ "type": "text", "label": "'._('Provincia').'", "name": "provincia" ]} +
+ +
+ {[ "type": "text", "label": "'._('Km').'", "name": "km" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Cellulare').'", "name": "cellulare" ]} +
+ +
+ {[ "type": "text", "label": "'._('Telefono').'", "name": "telefono" ]} +
+ +
+ {[ "type": "text", "label": "'._('Indirizzo email').'", "name": "email" ]} +
+
+ +
+
+ {[ "type": "select", "label": "'._('Zona').'", "name": "idzona", "values": "query=SELECT `id`, CONCAT(`nome`, \' - \', `descrizione`) AS `descrizione` FROM `an_zone` ORDER BY `descrizione` ASC" ]} +
+
+ + +
+
+ +
+
+ + +'; diff --git a/plugins/sedi/edit.php b/plugins/sedi/edit.php new file mode 100644 index 000000000..1b557cbcf --- /dev/null +++ b/plugins/sedi/edit.php @@ -0,0 +1,97 @@ + + + + + +
+
+ {[ "type": "text", "label": "'._('Nome sede').'", "name": "nomesede", "required": 1, "value": "$nomesede$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Indirizzo').'", "name": "indirizzo", "required": 1, "value": "$indirizzo$" ]} +
+ +
+ {[ "type": "text", "label": "'._('Secondo indirizzo').'", "name": "indirizzo2", "value": "$indirizzo2$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('P.Iva').'", "name": "piva", "value": "$piva$" ]} +
+ +
+ {[ "type": "text", "label": "'._('Codice Fiscale').'", "name": "codice_fiscale", "value": "$codice_fiscale$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Città').'", "name": "citta", "value": "$citta$" ]} +
+ +
+ {[ "type": "text", "label": "'._('C.A.P.').'", "name": "cap", "value": "$cap$" ]} +
+ +
+ {[ "type": "text", "label": "'._('Provincia').'", "name": "provincia", "value": "$provincia$" ]} +
+ +
+ {[ "type": "number", "label": "'._('Km').'", "name": "km", "value": "$km$" ]} +
+
+ +
+
+ {[ "type": "select", "label": "'._('Nazione').'", "name": "id_nazione", "values": "query=SELECT `id`, `nome` AS `descrizione` FROM `an_nazioni` ORDER BY `descrizione` ASC", "value": "$id_nazione$" ]} +
+ +
+ {[ "type": "text", "label": "'._('Telefono').'", "name": "telefono", "value": "$telefono$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Fax').'", "name": "fax", "value": "$fax$" ]} +
+ +
+ {[ "type": "text", "label": "'._('Cellulare').'", "name": "cellulare", "value": "$cellulare$" ]} +
+
+ +
+
+ {[ "type": "text", "label": "'._('Indirizzo email').'", "name": "email", "value": "$email$" ]} +
+ +
+ {[ "type": "select", "label": "'._('Zona').'", "name": "idzona", "values": "query=SELECT `id`, CONCAT(`nome`, \' - \', `descrizione`) AS `descrizione` FROM `an_zone` ORDER BY `descrizione` ASC", "value": "$idzona$" ]} +
+
+ + +
+
+ + '._('Elimina').' + + + +
+
+ + +'; diff --git a/plugins/sedi/init.php b/plugins/sedi/init.php new file mode 100644 index 000000000..2d436142a --- /dev/null +++ b/plugins/sedi/init.php @@ -0,0 +1,5 @@ +fetchArray('SELECT * FROM an_sedi WHERE an_sedi.id='.prepare($id_record).' ORDER BY an_sedi.id DESC'); diff --git a/templates/contratti/contratto.html b/templates/contratti/contratto.html new file mode 100644 index 000000000..833e98b47 --- /dev/null +++ b/templates/contratti/contratto.html @@ -0,0 +1,18 @@ + + + + $body$ + diff --git a/templates/contratti/contratto_body.html b/templates/contratti/contratto_body.html new file mode 100644 index 000000000..eb9b0c92e --- /dev/null +++ b/templates/contratti/contratto_body.html @@ -0,0 +1,33 @@ + + + + + + + + +
+ Logo
+
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+
+
+ + + + + + +
+ Stampato con OpenSTAManager +
+
diff --git a/templates/contratti/logo_azienda.jpg b/templates/contratti/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); +$idcliente = $rscontrattii[0]['idanagrafica']; + +// carica report html +$report = file_get_contents($docroot.'/templates/contratti/contratto.html'); +$body = file_get_contents($docroot.'/templates/contratti/contratto_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$totrows = sizeof($rscontrattii); +$totale_km = 0; +$totale_ore = 0; +$totale = 0; +$contratti = []; +$ore = []; +$km = []; +$ntecnici = []; +$tecnici = []; +$costi_orari = []; +$costi_km = []; +$idinterventi = ['-1']; + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rscontrattii[0]['${1}'], $body); + +// Lettura nome referenti collegati all'anagrafica +$query = 'SELECT * FROM an_referenti WHERE id = "'.$rscontrattii[0]['idreferente'].'"'; +$rs = $dbo->fetchArray($query); +$nome_referente = $rs[0]['nome']; + +// Tabella intestazione +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; + +if ($nome_referente != '') { + $body .= "\n"; + $body .= "\n"; +} + +$body .= "
\n"; +$body .= " \n"; +$body .= "\n"; + +if ($c_cap != '') { + $c_cap = $c_cap.' '; +} + +if ($c_provincia != '') { + $c_provincia = ' ('.$c_provincia.')'; +} + +$body .= 'Spettabile
'.$c_ragionesociale.'
'.$c_indirizzo.'
'.$c_cap.$c_citta.$c_provincia.'
P.Iva: '.$c_piva."
\n"; +$body .= "
\n"; +$body .= ''.$f_citta.', '.Translator::dateToLocale($rscontrattii[0]['data_bozza'])."\n"; +$body .= "
\n"; +$body .= 'OGGETTO: CONTRATTO No '.$rscontrattii[0]['numero'].' DEL '.Translator::dateToLocale($rscontrattii[0]['data_bozza'])."\n"; +$body .= "
\n"; + $body .= 'C.A. '.$nome_referente."\n"; + $body .= "
\n"; + +/* + TABELLA COSTI +*/ +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +$rs = $dbo->fetchArray('SELECT * FROM co_righe2_contratti WHERE idcontratto="'.$idcontratto.'"'); +$totale = 0; + +for ($i = 0; $i < sizeof($rs); ++$i) { + // Descrizione + $body .= "\n"; + + // Q.tà + $body .= "\n"; + + // um + $body .= "\n"; + + // Costo unitario + $body .= "\n"; + + // Subtotale + $body .= "\n"; + $body .= "\n"; + + $totale += $rs[$i]['subtotale']; +} + +// Totale complessivo intervento +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; +$body .= "
DescrizioneQ.tàu.m.Costo unitarioImponibile
".nl2br($rs[$i]['descrizione'])."".Translator::numberToLocale($rs[$i]['qta'], 2)."".$rs[$i]['um']."".Translator::numberToLocale($rs[$i]['subtotale'] / $rs[$i]['qta'], 2)." €".Translator::numberToLocale($rs[$i]['subtotale'], 2)." €
\n"; +$body .= "QUOTAZIONE TOTALE:\n"; +$body .= "\n"; +$body .= ''.Translator::numberToLocale($totale, 2)." €\n"; +$body .= "


\n"; + +// CONDIZIONI GENERALI DI FORNITURA + +// Lettura pagamenti +if ($rscontrattii[0]['idpagamento'] != '') { + $query = 'SELECT * FROM co_pagamenti WHERE id = '.$rscontrattii[0]['idpagamento']; + $rs = $dbo->fetchArray($query); + $pagamento = $rs[0]['descrizione']; +} else { + $pagamento = 'N.D.'; +} + +$rscontrattii[0]['idpagamento']; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +// PAGAMENTI +$body .= "\n"; + +$body .= "\n"; + +// VALIDITA' OFFERTA +$body .= "\n"; + +$body .= "\n"; + +// VALIDITA' CONTRATTO +$body .= "\n"; + +$body .= "\n"; + +// ESCLUSIONI +$body .= "\n"; + +$body .= "\n"; + +$body .= "
\n"; +$body .= "CONDIZIONI GENERALI DI FORNITURA
\n"; +$body .= "
\n"; +$body .= "PAGAMENTI:\n"; +$body .= "\n"; +$body .= ''.$pagamento."\n"; +$body .= "
\n"; +$body .= "VALIDITÀ OFFERTA:\n"; +$body .= "\n"; +$body .= ''.$rscontrattii[0]['validita']." giorni\n"; +$body .= "
\n"; +$body .= "VALIDITÀ CONTRATTO:\n"; +$body .= "\n"; +$body .= 'dal '.Translator::dateToLocale($rscontrattii[0]['data_accettazione']).' al '.Translator::dateToLocale($rscontrattii[0]['data_conclusione'])."\n"; +$body .= "
\n"; +$body .= "ESCLUSIONI:\n"; +$body .= "\n"; +$body .= ''.$rscontrattii[0]['esclusioni']."\n"; +$body .= "
\n"; +$body .= "

\n"; + +$body .= "Il tutto S.E. & O.

\n"; +$body .= "In attesa di un Vostro Cortese riscontro scritto, l’occasione mi è gradita per porgere Cordiali Saluti.\n"; + +$report_name = 'contratto_'.$idcontratto.'.pdf'; diff --git a/templates/contratti_cons/contratto.html b/templates/contratti_cons/contratto.html new file mode 100644 index 000000000..e6af48f35 --- /dev/null +++ b/templates/contratti_cons/contratto.html @@ -0,0 +1,18 @@ + + + + $body$ + diff --git a/templates/contratti_cons/contratto_body.html b/templates/contratti_cons/contratto_body.html new file mode 100644 index 000000000..e7da98e41 --- /dev/null +++ b/templates/contratti_cons/contratto_body.html @@ -0,0 +1,40 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ +
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/contratti_cons/logo_azienda.jpg b/templates/contratti_cons/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); +$idcliente = $rscontratti[0]['idanagrafica']; + +$rs = $dbo->fetchArray("SELECT SUM(qta) AS totale_ore, SUM(subtotale) as totale_budget FROM `co_righe2_contratti` WHERE um='ore' AND idcontratto=\"".$idcontratto.'"'); +$contratto_tot_ore = $rs[0]['totale_ore']; +$contratto_tot_budget = $rs[0]['totale_budget']; + +// carica report html +$report = file_get_contents($docroot.'/templates/contratti_cons/contratto.html'); +$body = file_get_contents($docroot.'/templates/contratti_cons/contratto_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$totale = 0; +$contratti = []; +$ore = []; +$totale_ore_impiegate = 0; + +$costo_orario = []; +$costo_km = []; +$diritto_chiamata = []; + +$tot_ore_consuntivo = []; +$tot_km_consuntivo = []; +$tot_dirittochiamata = []; + +$km = []; +$ntecnici = []; +$tecnici = []; +$costi_orari = []; +$costi_km = []; +$idinterventi = ["''"]; + +// Ciclo tra le righe degli interventi da programmare +$rs_righe = $dbo->fetchArray('SELECT * FROM co_righe_contratti WHERE idcontratto="'.$idcontratto.'" ORDER BY data_richiesta ASC'); +$totrows = sizeof($rs_righe); + +for ($r = 0; $r < sizeof($rs_righe); ++$r) { + if (!empty($rs_righe[$r]['id'])) { + $totale_ore = 0; + $totale_km = 0; + $totale_diritto_chiamata = 0; + + $q = 'SELECT id, codice, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=in_interventi.id) AS data, (SELECT SUM(km) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS km, (SELECT SUM(prezzo_ore_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_ore_consuntivo`, (SELECT SUM(prezzo_km_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_km_consuntivo` FROM in_interventi WHERE id="'.$rs_righe[$r]['idintervento'].'"'; + $rscontrattii = $dbo->fetchArray($q); + + if (sizeof($rscontrattii) == 1) { + // Lettura numero tecnici collegati all'intervento + $query = 'SELECT an_anagrafiche.idanagrafica, prezzo_ore_consuntivo, prezzo_km_consuntivo, prezzo_ore_unitario, prezzo_km_unitario, prezzo_dirittochiamata, ragione_sociale, orario_inizio, orario_fine, in_interventi_tecnici.km FROM in_interventi_tecnici LEFT OUTER JOIN an_anagrafiche ON in_interventi_tecnici.idtecnico=an_anagrafiche.idanagrafica WHERE idintervento="'.$rscontrattii[0]['id'].'"'; + $rst = $dbo->fetchArray($query); + $n_tecnici = sizeof($rst); + $tecnici_full = ''; + + $t = 0; + + for ($j = 0; $j < $n_tecnici; ++$j) { + $t1 = datediff('n', $rst[$j]['orario_inizio'], $rst[$j]['orario_fine']); + + $orario = ''; + if (floatval($t1) > 0) { + $orario .= Translator::timestampToLocale($rst[$j]['orario_inizio']).' - '.Translator::timestampToLocale($rst[$j]['orario_fine']); + } + + $tecnici_full .= ''.$rst[$j]['ragione_sociale'].' ('.$orario.')
'.Translator::numberToLocale($t1 / 60, 2).'h x '.Translator::numberToLocale($rst[$j]['prezzo_ore_unitario'], 2).' €/h
'.Translator::numberToLocale($rst[$j]['km'], 2).'km x '.Translator::numberToLocale($rst[$j]['prezzo_km_unitario'], 2).' km/h
'.Translator::numberToLocale($rst[$j]['prezzo_dirittochiamata'], 2)."€ d.c.

\n"; + + // Conteggio ore totali + $t += $t1 / 60; + + $totale_ore += $rst[$j]['prezzo_ore_consuntivo']; + $totale_km += $rst[$j]['prezzo_km_consuntivo']; + $totale_diritto_chiamata += $rst[$j]['prezzo_dirittochiamata']; + } + + $totale_ore_impiegate += $t; + + $desc = str_replace("\n", '
', $rscontratti[$i]['descrizione']); + $line = 'Intervento '.$rscontrattii[0]['codice'].' del '.Translator::dateToLocale($rscontrattii[0]['data']).'
'.$desc; + + array_push($contratti, $line); + array_push($tot_ore_consuntivo, $totale_ore); + array_push($tot_km_consuntivo, $totale_km); + array_push($tot_dirittochiamata, $totale_diritto_chiamata); + + array_push($ntecnici, $n_tecnici); + array_push($tecnici, $tecnici_full); + array_push($idinterventi, "'".$rscontrattii[0]['codice']."'"); + } + } + + // Visualizzo i dati degli interventi programmati + else { + $line = 'Da programmare entro il '.Translator::dateToLocale($rs_righe[$r]['data_richiesta']); + + array_push($contratti, $line); + array_push($km, 0); + array_push($ore, 0); + + array_push($costo_orario, 0); + array_push($costo_km, 0); + array_push($diritto_chiamata, 0); + + array_push($tot_ore_consuntivo, 0); + array_push($tot_km_consuntivo, 0); + + array_push($ntecnici, 0); + array_push($tecnici, '-'); + } +} + +$body .= '> CONSUNTIVO CONTRATTO: '.$rscontratti[0]['nome']."\n"; +$body .= ''.str_replace("\n", '
', $rscontratti[0]['cdescrizione'])."

\n"; + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rscontratti[0]['${1}'], $body); + +if (sizeof($contratti) > 0) { + // Tabella con riepilogo interventi, km e ore + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + // Tabella con i dati + for ($j = 0; $j < sizeof($contratti); ++$j) { + // Intervento (+ tecnici) + $body .= "\n"; + + // Subtotale + $subtotale = $tot_ore_consuntivo[$j] + $km[$j] * $costo_km[$j] + $diritto_chiamata[$j]; + $body .= "\n"; + $totale += $subtotale; + $totale_consuntivo += $tot_ore_consuntivo[$j] + $tot_km_consuntivo[$j]; + } + + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + $body .= "
InterventiTecniciSubtotale
\n"; + $body .= ' '.$contratti[$j]."".$tecnici[$j]."\n"; + $body .= "\n"; + $body .= ' '.Translator::numberToLocale($subtotale, 2)."\n"; + $body .= "
\n"; + $body .= "Totale:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale, 2)." €\n"; + $body .= "
\n"; +} +$body .= "
\n"; + +// Conteggio articoli utilizzati +$query = "SELECT *, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=mg_articoli_interventi.idintervento) AS data_intervento, (SELECT percentuale FROM co_iva WHERE id=mg_articoli_interventi.idiva_vendita) AS prciva_vendita, (SELECT codice FROM mg_articoli WHERE id=idarticolo) AS codice_art, GROUP_CONCAT( CONCAT_WS(lotto, 'Lotto: ', ', '), CONCAT_WS(serial, 'SN: ', ', '), CONCAT_WS(altro, 'Altro: ', '') SEPARATOR '
') AS codice, SUM(qta) AS sumqta FROM `mg_articoli_interventi` GROUP BY idarticolo, idintervento, lotto HAVING idintervento IN(".implode(',', $idinterventi).") AND NOT idarticolo='0' ORDER BY idarticolo ASC"; +$rs2 = $dbo->fetchArray($query); + +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $totale_articoli = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['sumqta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_articoli += $netto * $qta; + } + + // Totale spesa articoli + $body .= "\n"; + + $body .= "\n"; + $body .= "
Materiale utilizzato per gli interventi
\n"; + $body .= "Articolo\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.nl2br($rs2[$i]['descrizione'])."\n"; + if ($rs2[$i]['codice'] != '' && $rs2[$i]['codice'] != 'Lotto: , SN: , Altro: ') { + $body .= '
'.$rs2[$i]['codice']."\n"; + } + + $body .= '
Intervento del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['sumqta']."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo_vendita']; + $netto = $netto + $netto / 100 * $rs2[$i]['prc_guadagno']; + $iva = $netto / 100 * $rs2[$i]['prciva_vendita']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= "".Translator::numberToLocale($netto * $qta, 2)."\n"; + $body .= "
\n"; + $body .= "TOTALE MATERIALE UTILIZZATO:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_articoli, 2)." €\n"; + $body .= "

\n"; +} + +// Conteggio spese aggiuntive +$query = 'SELECT *, (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE idintervento=in_righe_interventi.idintervento) AS data_intervento FROM in_righe_interventi WHERE idintervento IN('.implode(',', $idinterventi).') ORDER BY id ASC'; +$rs2 = $dbo->fetchArray($query); + +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $totale_spese = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['qta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_spese += $netto * $qta; + } + // Totale spese aggiuntive + $body .= "\n"; + + $body .= "\n"; + $body .= "
Spese aggiuntive
\n"; + $body .= "Descrizione\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['descrizione']."
\n"; + $body .= 'Intervento del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.Translator::numberToLocale($rs2[$i]['qta'], 2)."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto * $qta, 2)." €\n"; + $body .= "
\n"; + $body .= "ALTRE SPESE:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_spese, 2)." €\n"; + $body .= "

\n"; +} + +// Totale complessivo intervento +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$diff = Translator::numberToLocale($contratto_tot_budget - $totale_intervento_consuntivo, 2); +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "
\n"; +$body .= "TOTALE CONSUNTIVO:\n"; +$body .= "\n"; +$totale_intervento_consuntivo = Translator::numberToLocale($totale + $totale_articoli + $totale_spese, 2); +$body .= ''.$totale_intervento_consuntivo." €\n"; +$body .= "
\n"; +$body .= "BUDGET TOTALE (NO IVA):\n"; +$body .= "\n"; +$contratto_tot_budget = Translator::numberToLocale($contratto_tot_budget, 2); +$body .= ''.$contratto_tot_budget." €\n"; +$body .= "
\n"; +$body .= "RAPPORTO BUDGET/SPESA (NO IVA):\n"; +$body .= "\n"; +$body .= ''.$diff." €\n"; +$body .= "
\n"; +$body .= "ORE RESIDUE:\n"; +$body .= "\n"; +$diff2 = Translator::numberToLocale($contratto_tot_ore - $totale_ore_impiegate, 2); +$body .= "$diff2  (ore erogate: ".Translator::numberToLocale($totale_ore_impiegate, 2).' - ore in contratto: '.Translator::numberToLocale($contratto_tot_ore, 2).")\n"; +$body .= "
\n"; + +$report_name = 'contratto_'.$idcontratto.'_cons.pdf'; diff --git a/templates/ddt/ddt.html b/templates/ddt/ddt.html new file mode 100644 index 000000000..692366efb --- /dev/null +++ b/templates/ddt/ddt.html @@ -0,0 +1,22 @@ + + + + $body$ + diff --git a/templates/ddt/ddt_body.html b/templates/ddt/ddt_body.html new file mode 100644 index 000000000..7e1752444 --- /dev/null +++ b/templates/ddt/ddt_body.html @@ -0,0 +1,58 @@ + + + + + +
+ Logo + + $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +

+ + + + + + + + +
+ CLIENTE
+
+ $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ + $c_codicefiscale$ +
+
+ DESTINAZIONE
+
+ $c_destinazione$ +
+
+
+
+ + + + + |footer| + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/ddt/logo_azienda.jpg b/templates/ddt/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); +$numero_ddt = $rs[0]['numero']; +$idcliente = $rs[0]['idanagrafica']; +(!empty($rs[0]['numero_esterno'])) ? $numero = $rs[0]['numero_esterno'] : $numero = $rs[0]['numero']; + +// Lettura righe ddt +$q2 = "SELECT * FROM dt_righe_ddt WHERE idddt='$idddt'"; +$righe = $dbo->fetchArray($q2); + +// carica report html +$report = file_get_contents(__DIR__.'/ddt.html'); +$body = file_get_contents(__DIR__.'/ddt_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +// Leggo i dati della destinazione (se 0=sede legale, se!=altra sede da leggere da tabella an_sedi) +$destinazione = ''; +if ($rs[0]['idsede'] == 0) { + $queryd = "SELECT ragione_sociale, indirizzo, indirizzo2, cap, citta, provincia, piva, codice_fiscale FROM an_anagrafiche WHERE idanagrafica='".$idcliente."'"; + $rsd = $dbo->fetchArray($queryd); + + if ($rsd[0]['ragione_sociale'] != '') { + $destinazione .= $rsd[0]['ragione_sociale']."
\n"; + } + if ($rsd[0]['indirizzo'] != '') { + $destinazione .= $rsd[0]['indirizzo']."
\n"; + } + if ($rsd[0]['indirizzo2'] != '') { + $destinazione .= $rsd[0]['indirizzo2']."
\n"; + } + if ($rsd[0]['cap'] != '') { + $destinazione .= $rsd[0]['cap'].' '; + } + if ($rsd[0]['citta'] != '') { + $destinazione .= $rsd[0]['citta']; + } + if ($rsd[0]['provincia'] != '') { + $destinazione .= ' ('.$rsd[0]['provincia'].")
\n"; + } + if ($rsd[0]['piva'] != '') { + $destinazione .= 'P.IVA: '.$rsd[0]['piva']."
\n"; + } + if ($rsd[0]['codice_fiscale'] != '') { + $destinazione .= 'C.F.: '.$rsd[0]['codice_fiscale']."
\n"; + } +} else { + $queryd = "SELECT (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=an_sedi.idanagrafica) AS ragione_sociale, indirizzo, indirizzo2, cap, citta, provincia, piva, codice_fiscale FROM an_sedi WHERE idanagrafica='".$idcliente."' AND id='".$rs[0]['idsede']."'"; + $rsd = $dbo->fetchArray($queryd); + + if ($rsd[0]['ragione_sociale'] != '') { + $destinazione .= $rsd[0]['ragione_sociale']."
\n"; + } + if ($rsd[0]['indirizzo'] != '') { + $destinazione .= $rsd[0]['indirizzo']."
\n"; + } + if ($rsd[0]['indirizzo2'] != '') { + $destinazione .= $rsd[0]['indirizzo2']."
\n"; + } + if ($rsd[0]['cap'] != '') { + $destinazione .= $rsd[0]['cap'].' '; + } + if ($rsd[0]['citta'] != '') { + $destinazione .= $rsd[0]['citta']; + } + if ($rsd[0]['provincia'] != '') { + $destinazione .= ' ('.$rsd[0]['provincia'].")
\n"; + } + if ($rsd[0]['piva'] != '') { + $destinazione .= 'P.IVA: '.$rsd[0]['piva']."
\n"; + } + if ($rsd[0]['codice_fiscale'] != '') { + $destinazione .= 'C.F.: '.$rsd[0]['codice_fiscale']."
\n"; + } +} +$body = str_replace('$c_destinazione$', $destinazione, $body); + +// Dati generici ddt +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "
".$rs[0]['tipo_doc']."
no $numero
Data:
".Translator::dateToLocale($rs[0]['data'])."
Pagamento:
".$rs[0]['tipo_pagamento']."


\n"; + +// Intestazione tabella per righe +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +// Mostro le righe del ddt +$totale_ddt = 0.00; +$totale_imponibile = 0.00; +$totale_iva = 0.00; +$sconto = 0.00; + +/* + Articoli +*/ +$q_art = "SELECT *, GROUP_CONCAT( CONCAT_WS(lotto, 'Lotto: ', ', '), CONCAT_WS(serial, 'SN: ', ', '), CONCAT_WS(altro, 'Altro: ', '') SEPARATOR '
') AS codice, SUM(qta) AS sumqta FROM `dt_righe_ddt` GROUP BY idarticolo, idddt, lotto HAVING idddt='$idddt' AND NOT idarticolo='0' ORDER BY idarticolo ASC"; +$rs_art = $dbo->fetchArray($q_art); +$tot_art = sizeof($rs_art); +$imponibile_art = 0.0; +$iva_art = 0.0; + +if ($tot_art > 0) { + for ($i = 0; $i < $tot_art; ++$i) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_art += $rs_art[$i]['subtotale']; + $iva_art += $iva; + $sconto += $rs_art[$i]['sconto']; + } + $imponibile_ddt += $imponibile_art; + $totale_iva += $iva_art; + $totale_ddt += $imponibile_art; +} + +/* + Righe generiche +*/ +$q_gen = "SELECT * FROM `dt_righe_ddt` WHERE idddt='$idddt' AND idarticolo=0"; +$rs_gen = $dbo->fetchArray($q_gen); +$tot_gen = sizeof($rs_gen); +$imponibile_gen = 0.0; +$iva_gen = 0.0; + +if ($tot_gen > 0) { + for ($i = 0; $i < $tot_gen; ++$i) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_gen += $rs_gen[$i]['subtotale']; + $iva_gen += $iva; + $sconto += $rs_gen[$i]['sconto']; + } + $imponibile_ddt += $imponibile_gen; + $totale_iva += $iva_gen; + $totale_ddt += $imponibile_gen; +} + +// Totale imponibile +if ($show_costi) { + $body .= "\n"; + + $body .= "\n"; + + // Mostra sconto se c'è + if (abs($sconto) > 0) { + $body .= "\n"; + + // Sconto + $body .= "'; + $body .= "\n"; + + // Totale scontato + $body .= "\n"; + + // Sconto + $body .= "\n"; + } + + // Mostra INPS se c'è + if (abs($rs[0]['rivalsainps']) > 0) { + $body .= "\n"; + + // Rivalsa INPS + $body .= "\n"; + $totale_ddt += $rs[0]['rivalsainps']; + } + + // Mostra iva se c'è + $totale_iva += $rs[0]['iva_rivalsainps']; + if (abs($totale_iva) > 0) { + $body .= "\n"; + + // Iva + $body .= "\n"; + $totale_ddt += $totale_iva; + } + + /* + Totale ddt + */ + $body .= "\n"; + + $body .= "\n"; + $netto_a_pagare = $totale_ddt; + + // Mostra marca da bollo se c'è + if (abs($rs[0]['bollo']) > 0) { + $body .= "\n"; + + // Marca da bollo + $body .= "\n"; + $netto_a_pagare += $marca_da_bollo; + } + + // Mostra ritenuta d'acconto se c'è + if (abs($rs[0]['ritenutaacconto']) > 0) { + $body .= "\n"; + + // Ritenuta d'acconto + $body .= "\n"; + $netto_a_pagare -= $rs[0]['ritenutaacconto']; + } + + /* + Netto a pagare (se diverso dal totale) + */ + if ($totale_ddt != $netto_a_pagare) { + $body .= "\n"; + + $body .= "\n"; + } +} +$body .= "\n"; +$body .= "
DescrizioneQ.tàu.m.Costo unitarioIvaImponibile
\n"; + $body .= nl2br($rs_art[$i]['descrizione']); + if ($rs_art[$i]['codice'] != '') { + $body .= '
'.$rs_art[$i]['codice']."\n"; + } + + // Aggiunta riferimento a ordine + if (!empty($rs_art[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rs_art[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + + $body .= "
\n"; + $body .= Translator::numberToLocale($rs_art[$i]['sumqta'], 2)."\n"; + $body .= "\n"; + $body .= $rs_art[$i]['um']."\n"; + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'], 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + $iva = $rs_art[$i]['iva']; + if ($show_costi) { + $body .= Translator::numberToLocale($iva, 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'], 2)." €\n"; + + if ($rs_art[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rs_art[$i]['sconto'], 2)." €\n"; + } + } else { + $body .= '-'; + } + $body .= "
\n"; + $body .= nl2br($rs_gen[$i]['descrizione']); + + // Aggiunta riferimento a ordine + if (!empty($rs_gen[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rs_gen[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rs_gen[$i]['qta'], 2)."\n"; + $body .= "\n"; + $body .= $rs_gen[$i]['um']."\n"; + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_gen[$i]['subtotale'] / $rs_gen[$i]['qta'], 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + $iva = $rs_gen[$i]['iva']; + if ($show_costi) { + $body .= Translator::numberToLocale($iva, 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_gen[$i]['subtotale'], 2)." €\n"; + + if ($rs_gen[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rs_gen[$i]['sconto'], 2)." €\n"; + } + } else { + $body .= '-'; + } + $body .= "
\n"; + $body .= 'Totale imponibile:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($imponibile_ddt, 2)." €\n"; + $body .= "
\n"; + $body .= 'Sconto:'; + $body .= "\n"; + $body .= Translator::numberToLocale($sconto, 2).' €'; + $body .= '
\n"; + $body .= 'Totale scontato:'; + $body .= "\n"; + $totale_ddt -= $sconto; + $body .= Translator::numberToLocale($totale_ddt, 2).' €'; + $body .= "
\n"; + $body .= 'Rivalsa INPS:'; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['rivalsainps'], 2).' €'; + $body .= "
\n"; + $body .= 'Iva:'; + $body .= "\n"; + $body .= Translator::numberToLocale($totale_iva, 2)." €\n"; + $body .= "
\n"; + $body .= 'Totale ddt:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_ddt, 2)." €\n"; + $body .= "
\n"; + $body .= 'Marca da bollo:'; + $body .= "\n"; + $marca_da_bollo = str_replace(',', '.', $rs[0]['bollo']); + $body .= Translator::numberToLocale($marca_da_bollo, 2).' €'; + $body .= "
\n"; + $body .= "Ritenuta d'acconto:"; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['ritenutaacconto'], 2).' €'; + $body .= "
\n"; + $body .= 'Netto a pagare:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto_a_pagare, 2)." €\n"; + $body .= "
\n"; + +// Note +$body .= '

'.nl2br($rs[0]['note'])."

\n"; + +if ($rs[0]['vettore'] != '') { + $vettore = ' ('.$rs[0]['vettore'].')'; +} else { + $vettore = ''; +} + +// Dati footer ddt +$footer = "

\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "
Colli:
".$rs[0]['n_colli']." 
Aspetto beni:
".$rs[0]['aspettobeni']." 
Causale trasporto:
".$rs[0]['causalet']." 
Porto:
".$rs[0]['porto']." 
\n"; + +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "
Tipo di spedizione:
".$rs[0]['spedizione'].$vettore." 
Conducente:
______________________
Destinatario:
______________________
\n"; + +$body = str_replace('|footer|', $footer, $body); + +$report_name = 'ddt_'.$numero_ddt.'.pdf'; diff --git a/templates/fatturato/fatturato.html b/templates/fatturato/fatturato.html new file mode 100644 index 000000000..29fa3dd20 --- /dev/null +++ b/templates/fatturato/fatturato.html @@ -0,0 +1,59 @@ + + + + $body$ + diff --git a/templates/fatturato/fatturato_body.html b/templates/fatturato/fatturato_body.html new file mode 100644 index 000000000..89de682f2 --- /dev/null +++ b/templates/fatturato/fatturato_body.html @@ -0,0 +1,22 @@ + + + + +
+ Logo +
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/fatturato/logo_azienda.jpg b/templates/fatturato/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($query); +$totrows = sizeof($rs); + +if ($dir == 'entrata') { + $body .= '

FATTURATO MENSILE DAL '.Translator::dateToLocale($_SESSION['period_start']).' AL '.Translator::dateToLocale($_SESSION['period_end'])."

\n"; +} else { + $body .= '

ACQUISTI MENSILI DAL '.Translator::dateToLocale($_SESSION['period_start']).' AL '.Translator::dateToLocale($_SESSION['period_end'])."

\n"; +} + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +for ($r = 0; $r < sizeof($rs); ++$r) { + // Lettura totali + $rs2 = $dbo->fetchArray("SELECT SUM(subtotale-co_righe_documenti.sconto) AS imponibile, SUM(iva) AS iva, (SELECT SUM(bollo) FROM co_documenti WHERE DATE_FORMAT(data,'%m-%Y') = \"".$rs[$r]['periodo'].'" AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir="'.$dir."\")) AS bollo, SUM(co_righe_documenti.rivalsainps) AS rivalsainps, SUM(co_righe_documenti.ritenutaacconto) AS ritenutaacconto FROM co_righe_documenti INNER JOIN co_documenti ON co_righe_documenti.iddocumento=co_documenti.id WHERE DATE_FORMAT(data,'%m-%Y') = \"".$rs[$r]['periodo'].'" AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir="'.$dir.'")'); + + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $totale_imponibile += $rs2[0]['imponibile']; + $totale_iva += $rs2[0]['iva']; + $totale += $rs2[0]['imponibile'] + $rs2[0]['iva'] + $rs2[0]['rivalsainps'] + $rs2[0]['bollo'] + $rs2[0]['ritenutaacconto']; +} + +// Totali +$body .= "\n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= "\n"; + +$body .= "
MeseImponibileIvaTotale
".$mesi[intval(date('m', strtotime($rs[$r]['data'])))].' '.date('Y', strtotime($rs[$r]['data']))."".Translator::numberToLocale($rs2[0]['imponibile'], 2)." €".Translator::numberToLocale($rs2[0]['iva'], 2)." €".Translator::numberToLocale($rs2[0]['imponibile'] + $rs2[0]['iva'] + $rs2[0]['rivalsainps'] + $rs2[0]['bollo'] + $rs2[0]['ritenutaacconto'], 2)." €
TOTALE:".Translator::numberToLocale($totale_imponibile, 2)." €".Translator::numberToLocale($totale_iva, 2)." €".Translator::numberToLocale($totale, 2)." €
\n"; + +$report_name = 'inventario.pdf'; diff --git a/templates/fatture/fattura.html b/templates/fatture/fattura.html new file mode 100644 index 000000000..537e38684 --- /dev/null +++ b/templates/fatture/fattura.html @@ -0,0 +1,22 @@ + + + + $body$ + diff --git a/templates/fatture/fattura_body.html b/templates/fatture/fattura_body.html new file mode 100644 index 000000000..f2b86b34c --- /dev/null +++ b/templates/fatture/fattura_body.html @@ -0,0 +1,53 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ + +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ + $c_codicefiscale$ + $riferimentosede$ +
+
+
+ + + + + + + + + + + + +
+ + Ai sensi del D.Lgs. 196/2003 Vi informiamo che i Vs. dati saranno utilizzati esclusivamente per i fini connessi ai rapporti commerciali tra di noi in essere.
+ Contributo CONAI assolto ove dovuto - Vi preghiamo di controllare i Vs. dati anagrafici, la P. IVA e il Cod. Fiscale. Non ci riteniamo responsabili di eventuali errori.

+ +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/fatture/logo_azienda.jpg b/templates/fatture/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); + +if ($rs[0]['dir'] == 'entrata') { + $module_name = 'Fatture di vendita'; +} else { + $module_name = 'Fatture di acquisto'; +} + +$additional_where[$module_name] = str_replace('|idanagrafica|', "'".$user_idanagrafica."'", $additional_where[$module_name]); + +// Lettura info fattura +$q = 'SELECT *, (SELECT descrizione FROM co_tipidocumento WHERE id=idtipodocumento) AS tipo_doc, (SELECT descrizione FROM co_pagamenti WHERE id=idpagamento) AS tipo_pagamento, (SELECT dir FROM co_tipidocumento WHERE id=idtipodocumento) AS dir FROM co_documenti WHERE id="'.$iddocumento.'" '.$additional_where[$module_name]; +$rs = $dbo->fetchArray($q); +$numero_doc = $rs[0]['numero']; +$idcliente = $rs[0]['idanagrafica']; +(!empty($rs[0]['numero_esterno'])) ? $numero = $rs[0]['numero_esterno'] : $numero = $rs[0]['numero']; + +// Lettura righe documento +$q2 = "SELECT * FROM co_righe_documenti INNER JOIN co_documenti ON co_righe_documenti.iddocumento=co_documenti.id WHERE iddocumento='$iddocumento' ".$additional_where[$module_name]; +$righe = $dbo->fetchArray($q2); + +// carica report html +$report = file_get_contents($docroot.'/templates/fatture/fattura.html'); +$body = file_get_contents($docroot.'/templates/fatture/fattura_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +if (empty($rs[0]['idsede'])) { + $body = str_replace('$riferimentosede$', '', $body); +} else { + $q3 = "SELECT * FROM an_sedi WHERE id='".$rs[0]['idsede']."'"; + $sede = $dbo->fetchArray($q3); + + $riferimentosede = '
Rif. sede cliente:
'.$sede[0]['nomesede'].'
'.$sede[0]['indirizzo'].'
'.$sede[0]['cap'].' '.$sede[0]['citta'].' ('.$sede[0]['provincia'].')'; + + $body = str_replace('$riferimentosede$', $riferimentosede, $body); +} + +// Dati generici fattura +if ($rs[0]['buono_ordine'] != '') { + $width = '165'; +} else { + $width = '228'; +} + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +if ($rs[0]['buono_ordine']) { + $body .= "\n"; +} + +$body .= "\n"; +$body .= "
".$rs[0]['tipo_doc']."
no $numero
Data:
".Translator::dateToLocale($rs[0]['data'])."
Pagamento:
".$rs[0]['tipo_pagamento']."
Buono d'ordine:
".$rs[0]['buono_ordine']."


\n"; + +// Intestazione tabella per righe +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +// Mostro le righe del documento +$totale_documento = 0.00; +$totale_imponibile = 0.00; +$totale_iva = 0.00; +$sconto = 0.00; + +/* + Righe fattura +*/ +$qr = "SELECT * FROM `co_righe_documenti` WHERE iddocumento='$iddocumento' ORDER BY `order`"; +$rsr = $dbo->fetchArray($qr); +$tot = sizeof($rsr); +$imponibile_int = 0.00; +$iva_int = 0.00; + +if ($tot > 0) { + for ($i = 0; $i < $tot; ++$i) { + // Intervento + if (!empty($rsr[$i]['idintervento']) && empty($rsr[$i]['idarticolo'])) { + $body .= "\n"; + + $qta = $rsr[$i]['qta']; + ($qta == 0) ? $qta = '-' : $qta = Translator::numberToLocale($qta, 2); + $body .= "\n"; + + ($qta == 0) ? $um = '-' : $um = $rsr[$i]['um']; + $body .= "\n"; + + // costo unitario + $subtotale = $rsr[$i]['subtotale'] / $rsr[$i]['qta']; + ($subtotale == 0) ? $subtotale = '-' : $subtotale = Translator::numberToLocale($subtotale, 2).' €'; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $imponibile_int += $rsr[$i]['subtotale']; + $iva_int += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Preventivi + elseif ($rsr[$i]['idpreventivo'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_pre += $rsr[$i]['subtotale']; + $iva_pre += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Contratti + elseif ($rsr[$i]['idcontratto'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_con += $rsr[$i]['subtotale']; + $iva_con += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Articoli + elseif ($rsr[$i]['idarticolo'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // costo unitario + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $imponibile_art += $rsr[$i]['subtotale']; + $iva_art += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Righe generiche + else { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_gen += $rsr[$i]['subtotale']; + $iva_gen += $iva; + $sconto += $rsr[$i]['sconto']; + } + } + + $imponibile_documento += $imponibile_int; + $totale_iva += $iva_int; + $totale_documento += $imponibile_int; + + $imponibile_documento += $imponibile_pre; + $totale_iva += $iva_pre; + $totale_documento += $imponibile_pre; + + $imponibile_documento += $imponibile_con; + $totale_iva += $iva_con; + $totale_documento += $imponibile_con; + + $imponibile_documento += $imponibile_art; + $totale_iva += $iva_art; + $totale_documento += $imponibile_art; + + $imponibile_documento += $imponibile_gen; + $totale_iva += $iva_gen; + $totale_documento += $imponibile_gen; +} + +// Totale documento +$body .= "\n"; + +// Imponibile +$body .= "\n"; + +// Mostra sconto se c'è +if (abs($sconto) > 0) { + $body .= "\n"; + + // Sconto + $body .= "'; + + // Totale scontato + $body .= "\n"; + + // Sconto + $body .= "\n"; +} + +// Mostra INPS se c'è +if (abs($rs[0]['rivalsainps']) > 0) { + $body .= "\n"; + + // Rivalsa INPS + $body .= "\n"; + $totale_documento += $rs[0]['rivalsainps']; +} + +// Mostra iva se c'è +$totale_iva += $rs[0]['iva_rivalsainps']; +if (abs($totale_iva) > 0) { + $body .= "\n"; + + // Iva + $body .= "\n"; + $totale_documento += $totale_iva; +} + +/* + Totale documento +*/ +$body .= "\n"; + +$body .= "\n"; +$netto_a_pagare = $totale_documento; + +// Mostra marca da bollo se c'è +if (abs($rs[0]['bollo']) > 0) { + $body .= "\n"; + + // Marca da bollo + $body .= "\n"; + $netto_a_pagare += $marca_da_bollo; +} + +// Mostra ritenuta d'acconto se c'è +if (abs($rs[0]['ritenutaacconto']) > 0) { + $body .= "\n"; + + // Ritenuta d'acconto + $body .= "\n"; + $netto_a_pagare -= $rs[0]['ritenutaacconto']; +} + +/* + Netto a pagare (se diverso dal totale) +*/ +if ($totale_documento != $netto_a_pagare) { + $body .= "\n"; + + $body .= "\n"; +} +$body .= "\n"; +$body .= "
DescrizioneQ.tàu.m.Costo unitarioIvaImponibile
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= $qta; + $body .= "\n"; + $body .= $um; + $body .= "\n"; + $body .= $subtotale."\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= "1\n"; + $body .= "\n"; + $body .= '-'; + $body .= "\n"; + $body .= "-\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= "1\n"; + $body .= "\n"; + $body .= '-'; + $body .= "\n"; + $body .= "-\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + + // Immagine articolo + $f = pathinfo($rsr[$i]['immagine01']); + $img = $docroot.'/modules/magazzino/articoli/images/'.$f['filename'].'_thumb100.'.$f['extension']; + if (file_exists($img)) { + $body .= '\"\"\n"; + } + + $body .= nl2br($rsr[$i]['descrizione']); + + // Aggiunta riferimento a ordine + if (!empty($rsr[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rsr[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine '.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + + // Aggiunta riferimento a ddt + elseif (!empty($rsr[$i]['idddt'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM dt_ddt WHERE id="'.$rsr[$i]['idddt'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ddt '.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rsr[$i]['qta'], 2); + $body .= "\n"; + $body .= $rsr[$i]['um']; + $body .= "\n"; + $body .= Translator::numberToLocale($rsr[$i]['subtotale'] / $rsr[$i]['qta'], 2)." €\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione']); + + // Aggiunta riferimento a ordine + if (!empty($rsr[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rsr[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + + // Aggiunta riferimento a ddt + elseif (!empty($rsr[$i]['idddt'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM dt_ddt WHERE id="'.$rsr[$i]['idddt'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ddt no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rsr[$i]['qta'], 2)."\n"; + $body .= "\n"; + $body .= $rsr[$i]['um']."\n"; + $body .= "\n"; + $body .= Translator::numberToLocale($rsr[$i]['subtotale'] / $rsr[$i]['qta'], 2)." €\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; +$body .= 'Subtot.:'; +$body .= "\n"; +$totale_documento = $imponibile_documento; +$body .= Translator::numberToLocale($totale_documento, 2)." €\n"; +$body .= "
\n"; + $body .= 'Sconto:'; + $body .= "\n"; + $body .= Translator::numberToLocale($sconto, 2)." €\n"; + $body .= '
\n"; + $body .= 'Totale scontato:'; + $body .= "\n"; + $totale_documento -= $sconto; + $body .= Translator::numberToLocale($totale_documento, 2)." €\n"; + $body .= "
\n"; + $body .= 'Rivalsa INPS:'; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['rivalsainps'], 2)." €\n"; + $body .= "
\n"; + $body .= 'Iva:'; + $body .= "\n"; + $body .= Translator::numberToLocale($totale_iva, 2)." €\n"; + $body .= "
\n"; +$body .= 'Totale documento:'; +$body .= "\n"; +$body .= ''.Translator::numberToLocale($totale_documento, 2)." €\n"; +$body .= "
\n"; + $body .= 'Marca da bollo:'; + $body .= "\n"; + $marca_da_bollo = str_replace(',', '.', $rs[0]['bollo']); + $body .= Translator::numberToLocale($marca_da_bollo, 2).' €'; + $body .= "
\n"; + $body .= "Ritenuta d'acconto:"; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['ritenutaacconto'], 2).' €'; + $body .= "
\n"; + $body .= 'Netto a pagare:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto_a_pagare, 2)." €\n"; + $body .= "
\n"; + +$body .= '

'.nl2br($rs[0]['note'])."

\n"; + +$report_name = 'fattura_'.$numero_doc.'.pdf'; diff --git a/templates/fatture_accompagnatorie/fattura.html b/templates/fatture_accompagnatorie/fattura.html new file mode 100644 index 000000000..c32665b65 --- /dev/null +++ b/templates/fatture_accompagnatorie/fattura.html @@ -0,0 +1,22 @@ + + + + $body$ + diff --git a/templates/fatture_accompagnatorie/fattura_body.html b/templates/fatture_accompagnatorie/fattura_body.html new file mode 100644 index 000000000..d200eecf1 --- /dev/null +++ b/templates/fatture_accompagnatorie/fattura_body.html @@ -0,0 +1,61 @@ + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +

+ + + + + + + +
+ CLIENTE
+
+ $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ + $c_codicefiscale$ +
+
+ DESTINAZIONE
+
+ $c_destinazione$ +
+
+
+
+ + + + + |footer| + + + + + + +
+ Ai sensi del D.Lgs. 196/2003 Vi informiamo che i Vs. dati saranno utilizzati esclusivamente per i fini connessi ai rapporti commerciali tra di noi in essere.
+ Vi preghiamo di controllare i Vs. dati anagrafici, la P. IVA e il Cod. Fiscale. Non ci riteniamo responsabili di eventuali errori.

+ +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/fatture_accompagnatorie/logo_azienda.jpg b/templates/fatture_accompagnatorie/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); + +if ($rs[0]['dir'] == 'entrata') { + $module_name = 'Fatture di vendita'; +} else { + $module_name = 'Fatture di acquisto'; +} + +$additional_where[$module_name] = str_replace('|idanagrafica|', "'".$user_idanagrafica."'", $additional_where[$module_name]); + +// Lettura info fattura +$q = 'SELECT *, (SELECT descrizione FROM co_tipidocumento WHERE id=idtipodocumento) AS tipo_doc, (SELECT descrizione FROM co_pagamenti WHERE id=idpagamento) AS tipo_pagamento, (SELECT dir FROM co_tipidocumento WHERE id=idtipodocumento) AS dir FROM co_documenti WHERE id="'.$iddocumento.'" '.$additional_where[$module_name]; +$rs = $dbo->fetchArray($q); +$numero_doc = $rs[0]['numero']; +$idcliente = $rs[0]['idanagrafica']; +(!empty($rs[0]['numero_esterno'])) ? $numero = $rs[0]['numero_esterno'] : $numero = $rs[0]['numero']; + +// carica report html +$report = file_get_contents($docroot.'/templates/fatture_accompagnatorie/fattura.html'); +$body = file_get_contents($docroot.'/templates/fatture_accompagnatorie/fattura_body.html'); + +if (!($idcliente == $user_idanagrafica || Auth::isAdmin())) { + die('Non hai i permessi per questa stampa!'); +} + +include_once $docroot.'/templates/pdfgen_variables.php'; + +// Leggo i dati della destinazione (se 0=sede legale, se!=altra sede da leggere da tabella an_sedi) +$destinazione = ''; +if ($rs[0]['idsede'] == 0) { + $queryd = "SELECT ragione_sociale, indirizzo, indirizzo2, cap, citta, provincia, piva, codice_fiscale FROM an_anagrafiche WHERE idanagrafica='".$idcliente."'"; + $rsd = $dbo->fetchArray($queryd); + + if ($rsd[0]['ragione_sociale'] != '') { + $destinazione .= $rsd[0]['ragione_sociale']."
\n"; + } + if ($rsd[0]['indirizzo'] != '') { + $destinazione .= $rsd[0]['indirizzo']."
\n"; + } + if ($rsd[0]['indirizzo2'] != '') { + $destinazione .= $rsd[0]['indirizzo2']."
\n"; + } + if ($rsd[0]['cap'] != '') { + $destinazione .= $rsd[0]['cap'].' '; + } + if ($rsd[0]['citta'] != '') { + $destinazione .= $rsd[0]['citta']; + } + if ($rsd[0]['provincia'] != '') { + $destinazione .= ' ('.$rsd[0]['provincia'].")
\n"; + } + if ($rsd[0]['piva'] != '') { + $destinazione .= 'P.IVA: '.$rsd[0]['piva']."
\n"; + } + if ($rsd[0]['piva'] == '') { + $destinazione .= 'C.F.: '.$rsd[0]['codice_fiscale']."
\n"; + } +} else { + $queryd = "SELECT (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=an_sedi.idanagrafica) AS ragione_sociale, indirizzo, indirizzo2, cap, citta, provincia, piva, codice_fiscale FROM an_sedi WHERE idanagrafica='".$idcliente."' AND id='".$rs[0]['idsede']."'"; + $rsd = $dbo->fetchArray($queryd); + + if ($rsd[0]['ragione_sociale'] != '') { + $destinazione .= $rsd[0]['ragione_sociale']."
\n"; + } + if ($rsd[0]['indirizzo'] != '') { + $destinazione .= $rsd[0]['indirizzo']."
\n"; + } + if ($rsd[0]['indirizzo2'] != '') { + $destinazione .= $rsd[0]['indirizzo2']."
\n"; + } + if ($rsd[0]['cap'] != '') { + $destinazione .= $rsd[0]['cap'].' '; + } + if ($rsd[0]['citta'] != '') { + $destinazione .= $rsd[0]['citta']; + } + if ($rsd[0]['provincia'] != '') { + $destinazione .= ' ('.$rsd[0]['provincia'].")
\n"; + } + if ($rsd[0]['piva'] != '') { + $destinazione .= 'P.IVA: '.$rsd[0]['piva']."
\n"; + } + if ($rsd[0]['codice_fiscale'] != '') { + $destinazione .= 'C.F.: '.$rsd[0]['codice_fiscale']."
\n"; + } +} +$body = str_replace('$c_destinazione$', $destinazione, $body); + +// Dati generici fattura +if ($rs[0]['buono_ordine'] != '') { + $width = '165'; +} else { + $width = '228'; +} + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +if ($rs[0]['buono_ordine']) { + $body .= "\n"; +} + +$body .= "\n"; +$body .= "
".$rs[0]['tipo_doc']."
no $numero
Data:
".Translator::dateToLocale($rs[0]['data'])."
Pagamento:
".$rs[0]['tipo_pagamento']."
Buono d'ordine:
".$rs[0]['buono_ordine']."


\n"; + +// Intestazione tabella per righe +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +// Mostro le righe del documento +$totale_documento = 0.00; +$totale_imponibile = 0.00; +$totale_iva = 0.00; +$sconto = 0.00; + +/* + Righe fattura +*/ +$qr = "SELECT * FROM `co_righe_documenti` WHERE iddocumento='$iddocumento'"; +$rsr = $dbo->fetchArray($qr); +$tot = sizeof($rsr); +$imponibile_int = 0.00; +$iva_int = 0.00; + +if ($tot > 0) { + for ($i = 0; $i < $tot; ++$i) { + // Intervento + if (!empty($rsr[$i]['idintervento']) && empty($rsr[$i]['idarticolo'])) { + $body .= "\n"; + + $qta = $rsr[$i]['qta']; + ($qta == 0) ? $qta = '-' : $qta = Translator::numberToLocale($qta, 2); + $body .= "\n"; + + ($qta == 0) ? $um = '-' : $um = $rsr[$i]['um']; + $body .= "\n"; + + // costo unitario + $subtotale = $rsr[$i]['subtotale'] / $rsr[$i]['qta']; + ($subtotale == 0) ? $subtotale = '-' : $subtotale = Translator::numberToLocale($subtotale, 2).' €'; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $imponibile_int += $rsr[$i]['subtotale']; + $iva_int += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Preventivi + elseif ($rsr[$i]['idpreventivo'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_pre += $rsr[$i]['subtotale']; + $iva_pre += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Contratti + elseif ($rsr[$i]['idcontratto'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_con += $rsr[$i]['subtotale']; + $iva_con += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Articoli + elseif ($rsr[$i]['idarticolo'] != 0) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // costo unitario + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $imponibile_art += $rsr[$i]['subtotale']; + $iva_art += $iva; + $sconto += $rsr[$i]['sconto']; + } + + // Righe generiche + else { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_gen += $rsr[$i]['subtotale']; + $iva_gen += $iva; + $sconto += $rsr[$i]['sconto']; + } + } + + $imponibile_documento += $imponibile_int; + $totale_iva += $iva_int; + $totale_documento += $imponibile_int; + + $imponibile_documento += $imponibile_pre; + $totale_iva += $iva_pre; + $totale_documento += $imponibile_pre; + + $imponibile_documento += $imponibile_con; + $totale_iva += $iva_con; + $totale_documento += $imponibile_con; + + $imponibile_documento += $imponibile_art; + $totale_iva += $iva_art; + $totale_documento += $imponibile_art; + + $imponibile_documento += $imponibile_gen; + $totale_iva += $iva_gen; + $totale_documento += $imponibile_gen; +} + +// Totale documento +$body .= "\n"; + +// Imponibile +$body .= "\n"; + +// Mostra sconto se c'è +if (abs($sconto) > 0) { + $body .= "\n"; + + // Sconto + $body .= "'; + + // Totale scontato + $body .= "\n"; + + // Sconto + $body .= "\n"; +} + +// Mostra INPS se c'è +if (abs($rs[0]['rivalsainps']) > 0) { + $body .= "\n"; + + // Rivalsa INPS + $body .= "\n"; + $totale_documento += $rs[0]['rivalsainps']; +} + +// Mostra iva se c'è +$totale_iva += $rs[0]['iva_rivalsainps']; +if (abs($totale_iva) > 0) { + $body .= "\n"; + + // Iva + $body .= "\n"; + $totale_documento += $totale_iva; +} + +/* + Totale documento +*/ +$body .= "\n"; + +$body .= "\n"; +$netto_a_pagare = $totale_documento; + +// Mostra marca da bollo se c'è +if (abs($rs[0]['bollo']) > 0) { + $body .= "\n"; + + // Marca da bollo + $body .= "\n"; + $netto_a_pagare += $marca_da_bollo; +} + +// Mostra ritenuta d'acconto se c'è +if (abs($rs[0]['ritenutaacconto']) > 0) { + $body .= "\n"; + + // Ritenuta d'acconto + $body .= "\n"; + $netto_a_pagare -= $rs[0]['ritenutaacconto']; +} + +/* + Netto a pagare (se diverso dal totale) +*/ +if ($totale_documento != $netto_a_pagare) { + $body .= "\n"; + + $body .= "\n"; +} +$body .= "\n"; +$body .= "
DescrizioneQ.tàu.m.Costo unitarioIvaImponibile
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= $qta; + $body .= "\n"; + $body .= $um; + $body .= "\n"; + $body .= $subtotale."\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= "1\n"; + $body .= "\n"; + $body .= '-'; + $body .= "\n"; + $body .= "-\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione'])."\n"; + $body .= "\n"; + $body .= "1\n"; + $body .= "\n"; + $body .= '-'; + $body .= "\n"; + $body .= "-\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + + // Immagine articolo + $f = pathinfo($rsr[$i]['immagine01']); + $img = $docroot.'/modules/magazzino/articoli/images/'.$f['filename'].'_thumb100.'.$f['extension']; + if (file_exists($img)) { + $body .= '\"\"\n"; + } + + $body .= nl2br($rsr[$i]['descrizione']); + + // Aggiunta riferimento a ordine + if (!empty($rsr[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rsr[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine '.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + + // Aggiunta riferimento a ddt + elseif (!empty($rsr[$i]['idddt'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM dt_ddt WHERE id="'.$rsr[$i]['idddt'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ddt '.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rsr[$i]['qta'], 2); + $body .= "\n"; + $body .= $rsr[$i]['um']; + $body .= "\n"; + $body .= Translator::numberToLocale($rsr[$i]['subtotale'] / $rsr[$i]['sumqta'], 2)." €\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; + $body .= nl2br($rsr[$i]['descrizione']); + + // Aggiunta riferimento a ordine + if (!empty($rsr[$i]['idordine'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM or_ordini WHERE id="'.$rsr[$i]['idordine'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ordine no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + + // Aggiunta riferimento a ddt + elseif (!empty($rsr[$i]['idddt'])) { + $rso = $dbo->fetchArray('SELECT numero, numero_esterno, data FROM dt_ddt WHERE id="'.$rsr[$i]['idddt'].'"'); + ($rso[0]['numero_esterno'] != '') ? $numero = $rso[0]['numero_esterno'] : $numero = $rso[0]['numero']; + $body .= '
Rif. ddt no'.$numero.' del '.Translator::dateToLocale($rso[0]['data']).''; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rsr[$i]['qta'], 2)."\n"; + $body .= "\n"; + $body .= $rsr[$i]['um']."\n"; + $body .= "\n"; + $body .= Translator::numberToLocale($rsr[$i]['subtotale'] / $rsr[$i]['qta'], 2)." €\n"; + $body .= "\n"; + $iva = $rsr[$i]['iva']; + $body .= '
'.Translator::numberToLocale($iva, 2)." €
".$rsr[$i]['desc_iva']."\n"; + $body .= "
\n"; + $subtot = $rsr[$i]['subtotale']; + $body .= Translator::numberToLocale($subtot, 2)." €\n"; + if ($rsr[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rsr[$i]['sconto'], 2)." €\n"; + } + $body .= "
\n"; +$body .= 'Subtot.:'; +$body .= "\n"; +$totale_documento = $imponibile_documento; +$body .= Translator::numberToLocale($totale_documento, 2)." €\n"; +$body .= "
\n"; + $body .= 'Sconto:'; + $body .= "\n"; + $body .= Translator::numberToLocale($sconto, 2)." €\n"; + $body .= '
\n"; + $body .= 'Totale scontato:'; + $body .= "\n"; + $totale_documento -= $sconto; + $body .= Translator::numberToLocale($totale_documento, 2)." €\n"; + $body .= "
\n"; + $body .= 'Rivalsa INPS:'; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['rivalsainps'], 2)." €\n"; + $body .= "
\n"; + $body .= 'Iva:'; + $body .= "\n"; + $body .= Translator::numberToLocale($totale_iva, 2)." €\n"; + $body .= "
\n"; +$body .= 'Totale documento:'; +$body .= "\n"; +$body .= ''.Translator::numberToLocale($totale_documento, 2)." €\n"; +$body .= "
\n"; + $body .= 'Marca da bollo:'; + $body .= "\n"; + $marca_da_bollo = str_replace(',', '.', $rs[0]['bollo']); + $body .= Translator::numberToLocale($marca_da_bollo, 2).' €'; + $body .= "
\n"; + $body .= "Ritenuta d'acconto:"; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['ritenutaacconto'], 2).' €'; + $body .= "
\n"; + $body .= 'Netto a pagare:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto_a_pagare, 2)." €\n"; + $body .= "
\n"; + +$body .= '

'.nl2br($rs[0]['note'])."

\n"; + +if ($rs[0]['vettore'] != '') { + $vettore = ' ('.$rs[0]['vettore'].')'; +} else { + $vettore = ''; +} + +// Dati footer ddt +$footer = "

\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "
Colli:
".$rs[0]['n_colli']." 
Aspetto beni:
".$rs[0]['aspettobeni']." 
Causale trasporto:
".$rs[0]['causalet']." 
Porto:
".$rs[0]['porto']." 
\n"; + +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "\n"; +$footer .= "
Tipo di spedizione:
".$rs[0]['spedizione'].$vettore." 
Conducente:
______________________
Destinatario:
______________________
\n"; + +$body = str_replace('|footer|', $footer, $body); + +$report_name = 'fattura_'.$numero_doc.'.pdf'; diff --git a/templates/interventi/actions.php b/templates/interventi/actions.php new file mode 100644 index 000000000..2433d2885 --- /dev/null +++ b/templates/interventi/actions.php @@ -0,0 +1,610 @@ + + + + + + '._('Cliente').': '.$c_codiceanagrafica.' '.$c_ragionesociale.'
+ '._('Indirizzo').': '.$c_indirizzo.'-'.$c_cap.' '.$c_citta.' ('.strtoupper($c_provincia).')
+ + + '._('Referente').': '.$referente.''; + if ($c_telefono != '') { + $body .= ' +
'._('Telefono azienda').': '.$c_telefono.''; + } + if ($c_email != '') { + $body .= ' +
'._('Email').': '.$c_email.''; + } + $body .= ' + + '; + +// Richiesta +$body .= ' + + '._('Richiesta').': + + + '.nl2br($records[0]['richiesta']).' + '; + +// Descrizione +if ($records[0]['descrizione_intervento'] != '') { + $body .= ' + + '._('Descrizione').': + + + '.nl2br($records[0]['descrizione_intervento']).' + '; +} +$body .= ' +'; + +$totale = []; + +// MATERIALE UTILIZZATO + +// Conteggio articoli utilizzati +$rs2 = $dbo->fetchArray('SELECT *, (SELECT codice FROM mg_articoli WHERE id=idarticolo) AS codice_art, SUM(qta) AS sumqta FROM `mg_articoli_interventi` GROUP BY idgruppo HAVING idintervento='.prepare($idintervento)." AND NOT idarticolo='0' ORDER BY idarticolo ASC"); +if (!empty($rs2)) { + $body .= ' + + + + + + + + + + + + + + + + + + + + '; + + $totale_articoli = []; + + foreach ($rs2 as $r) { + $body .= ' + '; + + // Codice + $body .= ' + '; + + // Descrizione + $body .= ' + '; + + // Quantità + $body .= ' + '; + + // Prezzo unitario + $body .= ' + '; + + // Sconto unitario + if ($r['sconto_unitario'] > 0) { + $sconto = Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €'); + } else { + $sconto = '-'; + } + + $body .= ' + '; + + // Netto + $netto = ($r['prezzo_vendita'] - $r['sconto']) * $r['sumqta']; + + $body .= ' + + '; + + // Totale + $totale_articoli[] = $netto; + } + + $totale_articoli = sum($totale_articoli); + $totale[] = $totale_articoli; + + // Totale spesa articoli + if ($visualizza_costi) { + $body .= ' + + + + + '; + } + + $body .= ' +
+ '.strtoupper(_('Materiale utilizzato')).' +
+ '._('Codice').' + + '._('Descrizione').' + + '._('Q.tà').' + + '._('Prezzo listino').' + + '._('Sconto').' + + '._('Subtot. netto').' +
+ '.$r['codice_art'].' + + '.$r['descrizione'].' + + '.Translator::numberToLocale($r['sumqta'], 2).' '.$r['um'].' + + '.($visualizza_costi ? Translator::numberToLocale($r['prezzo_vendita'], 2).' €' : '-').' + + '.($visualizza_costi ? $sconto : '-').' + + '.($visualizza_costi ? Translator::numberToLocale($netto, 2) : '-').' +
+ '.strtoupper(_('Totale materiale utilizzato')).': + + '.Translator::numberToLocale($totale_articoli, 2).' € +
'; +} + +// FINE MATERIALE UTILIZZATO + +// Conteggio SPESE AGGIUNTIVE +$rs2 = $dbo->fetchArray('SELECT * FROM in_righe_interventi WHERE idintervento='.prepare($idintervento).' ORDER BY id ASC'); +if (!empty($rs2)) { + $body .= ' + + + + + + + + + + + + + + + + + + + + '; + + $totale_righe = []; + + foreach ($rs2 as $r) { + // Articolo + $body .= ' + + + + '; + + // Quantità + $body .= ' + '; + + // Prezzo unitario + + $body .= ' + '; + + // Sconto unitario + if ($r['sconto_unitario'] > 0) { + $sconto = Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €'); + } else { + $sconto = '-'; + } + + $body .= ' + '; + + // Prezzo totale + $netto = ($r['prezzo_vendita'] - $r['sconto']) * $r['qta']; + + $body .= ' + + '; + + // Subtot + $totale_righe[] = $netto; + } + + $totale_righe = sum($totale_righe); + $totale[] = $totale_righe; + + if ($visualizza_costi) { + // Totale spese aggiuntive + $body .= ' + + + + + '; + } + + $body .= ' +
+ '.strtoupper(_('Spese aggiuntive')).' +
+ + + '._('Descrizione').' + + '._('Q.tà').' + + '._('Prezzo listino').' + + '._('Sconto').' + + '._('Subtot. netto').' +
+ '.nl2br($r['descrizione']).' + + '.Translator::numberToLocale($r['qta'], 2).' + + '.($visualizza_costi ? Translator::numberToLocale($r['prezzo_vendita'], 2).' €' : '-').' + + '.($visualizza_costi ? $sconto : '-').' + + '.($visualizza_costi ? Translator::numberToLocale($netto, 2) : '-').' +
+ '.strtoupper(_('Totale spese aggiuntive')).': + + '.Translator::numberToLocale($totale_righe, 2).' € +
'; +} + +// FINE SPESE AGGIUNTIVE + +// ORE TECNICI + FIRMA +$body .= ' + + + + + + '; + +// INTESTAZIONE ELENCO TECNICI +$body .= ' + + + + + + + + + + + '; + +// Sessioni di lavoro dei tecnici +$rst = $dbo->fetchArray('SELECT an_anagrafiche.*, in_interventi_tecnici.* FROM in_interventi_tecnici JOIN an_anagrafiche ON in_interventi_tecnici.idtecnico=an_anagrafiche.idanagrafica WHERE in_interventi_tecnici.idintervento='.prepare($idintervento).' ORDER BY in_interventi_tecnici.orario_inizio'); + +$totale_ore = 0; +$totale_costo_ore = 0; +$totale_costo_km = 0; +$totale_sconto = 0; +$totale_sconto_km = 0; +$totale_manodopera = 0; +$totale_viaggio = 0; + +foreach ($rst as $r) { + $body .= ' + '; + + // nome tecnico + $body .= ' + '; + + // data + $body .= ' + '; + + // ora inizio + $body .= ' + '; + + // ora fine + $body .= ' + '; + + // Sconto + $body .= ' + + '; + + $totale_ore += $r['ore']; + $totale_km += $r['km']; + + $totale_costo_ore = sum($totale_costo_ore, $r['prezzo_ore_consuntivo']); + $totale_sconto = sum($totale_sconto, $r['sconto']); + + $totale_costo_km = sum($totale_costo_km, $r['prezzo_km_consuntivo']); + $totale_sconto_km = sum($totale_sconto_km, $r['scontokm']); +} + +$totale_manodopera = sum($totale_costo_ore, -$totale_sconto); +$totale_viaggio = sum($totale_costo_km, -$totale_sconto_km); + +$totale_intervento = sum($totale_manodopera, $totale_viaggio); + +$totale[] = $totale_intervento; + +$body .= ' +
+ '.strtoupper(_('Ore tecnici')).' +
+ '._('Tecnico').' + + '._('Data').' + + '._('Dalle').' + + '._('Alle').' + + '._('Sconto').' +
+ '.$r['ragione_sociale'].' + + '.Translator::dateToLocale($r['orario_inizio'], '-').' + + '.Translator::timeToLocale($r['orario_inizio'], '-').' + + '.Translator::timeToLocale($r['orario_fine'], '-').' + + '.($r['sconto_unitario'] > 0 ? Translator::numberToLocale($r['sconto_unitario']).($r['tipo_sconto'] == 'PRC' ? '%' : ' €') : '-').' +
'; + +// ore lavorate +$body .= ' + + + + + + + + + + + + + + '; + +// Ore lavoro +$body .= ' + + + + + + '; + +if ($visualizza_costi) { + $body .= ' + + + '; +} else { + $body .= ' + + '; +} + +$body .= ' + '; + +// Ore di viaggio +if ($totale_km > 0) { + $body .= ' + + + + + + '; + + if ($visualizza_costi) { + $body .= ' + + + '; + } else { + $body .= ' + + '; + } + $body .= ' + '; +} + +// Subtotale manodopera + viaggio +if ($visualizza_costi) { + $body .= ' + + + + + '; +} + +$body .= ' +
+ '._('Descrizione').' + + '._('Q.tà').' + + '._('Prezzo listino').' + + '._('Subtot. netto').' +
+ '._('Ore tecnici').' + + '.Translator::numberToLocale($totale_ore, 2).' ore + + '.Translator::numberToLocale($totale_costo_ore, 2).' € + + '.Translator::numberToLocale($totale_manodopera, 2).' € + --
+ '._('Km / viaggio').' + + '.Translator::numberToLocale($totale_km, 2).' km + + '.Translator::numberToLocale($totale_costo_km, 2).' € + + '.Translator::numberToLocale($totale_viaggio, 2).' € + --
+ '.strtoupper(_('Totale intervento')).': + + '.Translator::numberToLocale($totale_intervento, 2).' € +
'; + +$totale = sum($totale); + +// TOTALE COSTI FINALI +if ($visualizza_costi) { + $body .= ' +
+ + + + '; + + // Totale imponibile + $body .= ' + + + + + '; + + // Eventuale sconto incondizionato + if ($records[0]['sconto_globale'] > 0) { + $prc = ($records[0]['tipo_sconto'] == 'PRC'); + $records[0]['sconto_globale'] = $prc ? $totale * $records[0]['sconto_globale'] / 100 : $records[0]['sconto_globale']; + + $sconto = Translator::numberToLocale($records[0]['sconto_globale'], ($prc ? 0 : 2)).($prc ? '%' : '€'); + + $totale = sum($totale, -$records[0]['sconto_globale']); + + $body .= ' + + + + + '; + + // Imponibile scontato + $body .= ' + + + + + '; + } + + // Leggo iva da applicare + $q1 = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); + $rs1 = $dbo->fetchArray($q1); + $percentuale_iva = $rs1[0]['percentuale']; + + $iva = ($totale / 100 * $percentuale_iva); + + // IVA + // Totale intervento + $body .= ' + + + + + '; + + $totale = sum($totale, $iva); + + // TOTALE INTERVENTO + $body .= ' + + + + +
+ '.strtoupper(_('Imponibile')).': + + '.Translator::numberToLocale($totale, 2).' € +
+ '.strtoupper(_('Sconto incondizionato')).': + + -'.Translator::numberToLocale($sconto, 2).' € +
+ '.strtoupper(_('Imponibile scontato')).': + + '.Translator::numberToLocale($totale, 2).' € +
+ '.strtoupper(_('Iva')).' ('.Translator::numberToLocale($percentuale_iva, 0).'%): + + '.Translator::numberToLocale($iva, 2).' € +
+ '.strtoupper(_('Totale intervento')).': + + '.Translator::numberToLocale($totale, 2).' € +
+
'; +} + +// timbro e firma +if ($records[0]['firma_file'] != '') { + $firma = ''; +} else { + $firma = ''; +} + +$body .= ' +
+ + + + + + + +
+ '._('Si dichiara che i lavori sono stati eseguiti ed i materiali installati').'.
+ '._('I dati del ricevente verrano trattati in base al D.lgs n. 196/2003').'. +
+ '.$firma.'
+ ('._('Timbro e firma leggibile').'.) +
'; + +$report_name = 'intervento_'.$idintervento.'.pdf'; diff --git a/templates/interventi/init.php b/templates/interventi/init.php new file mode 100644 index 000000000..011a6bcf3 --- /dev/null +++ b/templates/interventi/init.php @@ -0,0 +1,34 @@ +fetchArray($query); + +$id_anagrafica = $records[0]['idanagrafica']; +$id_cliente = $records[0]['idanagrafica']; +$id_sede = $records[0]['idsede']; + +// Leggo il nome del referente se selezionato da menu a tendina +if (!empty($records[0]['idreferente'])) { + $rs2 = $dbo->fetchArray('SELECT * FROM an_referenti WHERE id='.prepare($records[0]['idreferente'])); + $referente = $rs2[0]['nome']; +} else { + $referente = $records[0]['referente'].' '.$records[0]['telefono_referente']; +} + +// Sostituzioni specifiche +// Imposta numerointervento-data-numerocommessa su intestazione +$report = str_replace('$intervento_numero$', $records[0]['codice'], $report); +$report = str_replace('$intervento_data$', Translator::dateToLocale($records[0]['data_richiesta']), $report); + +if ($records[0]['numero_preventivo']) { + $report = str_replace('$commessa_numero$', $records[0]['codice'], $report); +} else { + $report = str_replace('$commessa_numero$', ' ', $report); +} diff --git a/templates/interventi/layout.html b/templates/interventi/layout.html new file mode 100644 index 000000000..d2f361cbd --- /dev/null +++ b/templates/interventi/layout.html @@ -0,0 +1,65 @@ + + + + $body$ + + + + + + + + + +
+ Logo + + $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+
diff --git a/templates/interventi/logo_azienda.jpg b/templates/interventi/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBv + + + + + $body$ + diff --git a/templates/interventi_ordiniservizio/intervento_body.html b/templates/interventi_ordiniservizio/intervento_body.html new file mode 100644 index 000000000..17de27b03 --- /dev/null +++ b/templates/interventi_ordiniservizio/intervento_body.html @@ -0,0 +1,48 @@ + + + + + + + + + + +
+ CONTROLLO EFFETTUATO DA:
+
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+
+ + + + + + + + + +
+ Firma Tecnico


+
+ ___________________________________


+
+ Firma Cliente


+
+ ___________________________________


+
+ Firma Amministratore + + ___________________________________ +
+
+
diff --git a/templates/interventi_ordiniservizio/logo_azienda.jpg b/templates/interventi_ordiniservizio/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($query); +$idcliente = $rs[0]['idanagrafica']; +$data_intervento = $rs[0]['data_intervento']; + +$copia_centrale = $rs[0]['copia_centrale']; +$copia_cliente = $rs[0]['copia_cliente']; +$copia_amministratore = $rs[0]['copia_amministratore']; +$funzionamento_in_sicurezza = $rs[0]['funzionamento_in_sicurezza']; + +// carica report html +$report = file_get_contents($docroot.'/templates/interventi_ordiniservizio/intervento.html'); +$body = file_get_contents($docroot.'/templates/interventi_ordiniservizio/intervento_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +/* + Dati intervento +*/ +$body .= "\n"; + +// Titolo +$body .= "\n"; + +// Titolo "ordine di servizio" e tecnico +$body .= "\n"; +$body .= '\n"; +$body .= '\n"; +$body .= "\n"; + +$body .= "
Programmazione della manutenzione periodica
ORDINE DI SERVIZIO No '.$rs[0]['id']."TECNICO: '.$rs[0]['tecnico']."
\n\n\n"; + +/* + Dati intestazione doppia +*/ +// Info contratto +$rs2 = $dbo->fetchArray('SELECT * FROM co_contratti WHERE id="'.$rs[0]['idcontratto'].'"'); +$body .= "\n"; + +// Informazioni a sinistra +$body .= "\n"; +$body .= "\n"; + +/* + Info cliente +*/ +$body .= "\n"; +$body .= "
\n"; +$body .= ' Contratto no '.$rs2[0]['numero'].":
\n"; +$body .= ' durata dal '.Translator::dateToLocale($rs2[0]['data_accettazione']).' al '.Translator::dateToLocale($rs2[0]['data_conclusione'])."
\n"; +$body .= ' Tipologia: '.$rs2[0]['nome']."

\n"; + +// Info impianto +$rs3 = $dbo->fetchArray('SELECT * FROM my_impianti WHERE id="'.$rs[0]['id'].'"'); +$body .= " Impianto:
\n"; +$body .= ' Matricola: '.$rs3[0]['matricola']."
\n"; +$body .= ' Tipologia: '.$rs3[0]['nome']."
\n"; +$body .= ' Data di installazione: '.Translator::dateToLocale($rs3[0]['data'])."
\n"; +$body .= ' Ubicazione: '.$rs3[0]['ubicazione']."
\n"; +$body .= ' Scala: '.$rs3[0]['scala']."
\n"; +$body .= ' Piano: '.$rs3[0]['piano']."

\n"; + +$body .= " Lavori da eseguire nel periodo:
\n"; +$body .= ' dal 01/'.date('m/Y', strtotime($rs[0]['data_scadenza'])).' al '.date('t/m/Y', strtotime($rs[0]['data_scadenza']))."

\n"; +$body .= "
\n"; + +// Sede impianto +$ripeti = true; +$rs2 = $dbo->fetchArray('SELECT * FROM an_sedi WHERE id=(SELECT idsede FROM my_impianti WHERE id="'.$rs[0]['id'].'")'); + +if ($rs2[0]['indirizzo'] != '') { + $body .= " Indirizzo impianto:
\n"; + $body .= ' '.$rs2[0]['nomesede']."
\n"; + $body .= ' '.$rs2[0]['indirizzo']."
\n"; + $body .= ' '.$rs2[0]['cap'].' '.$rs2[0]['citta'].' '.$rs2[0]['provincia']."

\n"; + $ripeti = false; +} + +$rs2 = $dbo->fetchArray('SELECT * FROM an_anagrafiche WHERE idanagrafica=(SELECT idanagrafica FROM in_interventi WHERE id="'.$idintervento.'")'); + +if ($ripeti) { + $body .= " Indirizzo impianto:
\n"; + $body .= ' '.$rs2[0]['indirizzo']."
\n"; + $body .= ' '.$rs2[0]['cap'].' '.$rs2[0]['citta'].' '.$rs2[0]['provincia']."
\n"; + $body .= ' Telefono: '.$rs2[0]['telefono']."
\n"; + $body .= ' Email: '.$rs2[0]['email']."

\n"; + + $body .= " Cliente:
\n"; + $body .= ' '.$rs2[0]['indirizzo']."
\n"; + $body .= ' '.$rs2[0]['cap'].' '.$rs2[0]['citta'].' '.$rs2[0]['provincia']."
\n"; + $body .= ' Telefono: '.$rs2[0]['telefono']."
\n"; + $body .= ' Email: '.$rs2[0]['email']."
\n"; +} else { + $body .= " Cliente
\n"; + $body .= ' '.$rs2[0]['ragione_sociale']."
\n"; + $body .= ' '.$rs2[0]['indirizzo']."
\n"; + $body .= ' '.$rs2[0]['cap'].' '.$rs2[0]['citta'].' '.$rs2[0]['provincia']."
\n"; + $body .= ' Telefono: '.$rs2[0]['telefono']."
\n"; + $body .= ' Email: '.$rs2[0]['email']."
\n"; +} + +$body .= "

\n\n\n"; + +/* + Elenco voci di servizio +*/ +$rs = $dbo->fetchArray('SELECT * FROM co_ordiniservizio_vociservizio WHERE idordineservizio=(SELECT id FROM co_ordiniservizio WHERE idintervento="'.$idintervento.'" LIMIT 0,1) ORDER BY categoria ASC'); + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$prev_cat = ''; + +for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['eseguito'] == '1') { + $eseguito_si = "x"; + $eseguito_no = ''; + } elseif ($rs[$i]['eseguito'] == '-1') { + $eseguito_si = ''; + $eseguito_no = "x"; + } else { + $eseguito_si = ''; + $eseguito_no = ''; + } + + if ($prev_cat != $rs[$i]['categoria']) { + $body .= "\n"; + } + + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $prev_cat = $rs[$i]['categoria']; +} + +$body .= "
VERIFICHEESEGUITONON ESEGUITONOTE
".$rs[$i]['categoria']."
".$rs[$i]['voce']."  ".$eseguito_si."  ".$eseguito_no."  ".$rs[$i]['note']." 

\n\n\n"; + +/* + Spunte e note +*/ +$body .= "\n"; + +// Copia centrale +if ($copia_centrale == '1') { + $copia_centrale = 'SÌ'; +} else { + $copia_centrale = 'NO'; +} +$body .= "\n"; + +// Copia cliente +if ($copia_cliente == '1') { + $copia_cliente = 'SÌ'; +} else { + $copia_cliente = 'NO'; +} +$body .= "\n"; + +// Copia amministratore +if ($copia_amministratore == '1') { + $copia_amministratore = 'SÌ'; +} else { + $copia_amministratore = 'NO'; +} +$body .= "\n"; + +// Funzionamento in sicurezza +if ($funzionamento_in_sicurezza == '1') { + $funzionamento_in_sicurezza = 'SÌ'; +} else { + $funzionamento_in_sicurezza = 'NO'; +} +$body .= "\n"; + +$body .= "
\n"; +$body .= " Consegnata copia in centrale: $copia_centrale"; +$body .= "\n"; +$body .= " al cliente: $copia_cliente"; +$body .= "\n"; +$body .= " all'amministratore: $copia_amministratore"; +$body .= "
\n"; +$body .= '
In data '.Translator::dateToLocale($data_intervento)." l'impianto può funzionare in sicurezza: $funzionamento_in_sicurezza"; +$body .= "
\n\n\n"; + +$report_name = 'ordine_servizio_intervento_'.$idintervento.'.pdf'; diff --git a/templates/magazzino_inventario/logo_azienda.jpg b/templates/magazzino_inventario/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBv + + + + + $body$ + diff --git a/templates/magazzino_inventario/magazzino_inventario_body.html b/templates/magazzino_inventario/magazzino_inventario_body.html new file mode 100644 index 000000000..29fdcdfc2 --- /dev/null +++ b/templates/magazzino_inventario/magazzino_inventario_body.html @@ -0,0 +1,22 @@ + + + + +
+ Logo +
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/magazzino_inventario/pdfgen.magazzino_inventario.php b/templates/magazzino_inventario/pdfgen.magazzino_inventario.php new file mode 100644 index 000000000..5f3ca406a --- /dev/null +++ b/templates/magazzino_inventario/pdfgen.magazzino_inventario.php @@ -0,0 +1,73 @@ +form('search_codice'); +$search_descrizione = $html->form('search_descrizione'); +$search_categoria = $html->form('search_categoria').' '.$html->form('search_subcategoria'); +$search_tipo = $html->form('search_tipo'); + +if ($search_tipo == '') { + $search_tipo = 'solo prodotti attivi'; +} + +if ($search_tipo == 'solo prodotti attivi') { + $add_where = ' AND attivo=1'; +} elseif ($search_tipo == 'solo prodotti non attivi') { + $add_where = ' AND attivo=0'; +} else { + $add_where = ''; +} + +include_once $docroot.'/templates/pdfgen_variables.php'; + +// Ciclo tra gli articoli selezionati +// LEFT OUTER JOIN mg_unitamisura ON mg_unitamisura.id=mg_articoli.idum +// mg_unitamisura.valore AS um +// LEFT OUTER JOIN mg_categorie ON (mg_categorie.id=mg_articoli.id_categoria AND mg_categorie.parent = 0) OR (mg_categorie.id=mg_articoli.id_sottocategoria AND mg_categorie.parent = 1) +$rs = $dbo->fetchArray("SELECT *, mg_articoli.id AS id_articolo, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 0 AND mg_categorie.id = mg_articoli.id_categoria) AS categoria, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 1 AND mg_categorie.id = mg_articoli.id_sottocategoria) AS subcategoria FROM mg_articoli WHERE ( replace(codice,'.','') LIKE \"%$search_codice%\" OR codice LIKE \"%$search_codice%\" ) AND replace(descrizione,'.','') LIKE \"%$search_descrizione%\" ".$add_where." AND qta > 0 HAVING CONCAT_WS( ' ', categoria, subcategoria ) LIKE \"%".$search_categoria.'%" ORDER BY codice ASC'); +$totrows = sizeof($rs); + +$body .= '

INVENTARIO AL '.date('d/m/Y')."

\n"; + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +for ($r = 0; $r < sizeof($rs); ++$r) { + $body .= "\n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + $body .= "\n"; + + $totale_qta += $rs[$r]['qta']; + $totale_acquisto += ($rs[$r]['prezzo_acquisto'] * $rs[$r]['qta']); +} + +// Totali +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "
CodiceDescrizionePrezzo di venditaQ.tàPrezzo di acquistoValore totale
".$rs[$r]['codice']."".$rs[$r]['descrizione']."".Translator::numberToLocale($rs[$r]['prezzo_vendita'], 2)." €".$rs[$r]['um'].' '.Translator::numberToLocale($rs[$r]['qta'], 2)."".Translator::numberToLocale($rs[$r]['prezzo_acquisto'], 2)." €".Translator::numberToLocale(($rs[$r]['prezzo_acquisto'] * $rs[$r]['qta']), 2)." €
TOTALE:".Translator::numberToLocale($totale_qta, 2)."".Translator::numberToLocale($totale_acquisto, 2)." €
\n"; + +$report_name = 'inventario.pdf'; diff --git a/templates/ordini/logo_azienda.jpg b/templates/ordini/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBv + + + + + $body$ + diff --git a/templates/ordini/ordine_body.html b/templates/ordini/ordine_body.html new file mode 100644 index 000000000..faf9eff21 --- /dev/null +++ b/templates/ordini/ordine_body.html @@ -0,0 +1,41 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ +
+
+
+ + + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/ordini/pdfgen.ordini.php b/templates/ordini/pdfgen.ordini.php new file mode 100644 index 000000000..8a6ca7ca2 --- /dev/null +++ b/templates/ordini/pdfgen.ordini.php @@ -0,0 +1,307 @@ +fetchArray($q); +$numero_ord = $rs[0]['numero']; +$idcliente = $rs[0]['idanagrafica']; +(!empty($rs[0]['numero_esterno'])) ? $numero = $rs[0]['numero_esterno'] : $numero = $rs[0]['numero']; + +// Lettura righe ordine +$q2 = "SELECT * FROM or_righe_ordini WHERE idordine='".$idordine."'"; +$righe = $dbo->fetchArray($q2); + +// carica report html +$report = file_get_contents($docroot.'/templates/ordini/ordine.html'); +$body = file_get_contents($docroot.'/templates/ordini/ordine_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +// Dati generici fattura +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "
".$rs[0]['tipo_doc']."
no $numero
Data:
".Translator::dateToLocale($rs[0]['data'])."
Pagamento:
".$rs[0]['tipo_pagamento']."


\n"; + +// Intestazione tabella per righe +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +// Mostro le righe del ordine +$totale_ordine = 0.00; +$totale_imponibile = 0.00; +$totale_iva = 0.00; +$sconto = 0.00; + +/* + Articoli +*/ +$q_art = "SELECT *, GROUP_CONCAT( CONCAT_WS(lotto, 'Lotto: ', ', '), CONCAT_WS(serial, 'SN: ', ', '), CONCAT_WS(altro, 'Altro: ', '') SEPARATOR '
') AS codice, SUM(qta) AS sumqta FROM `or_righe_ordini` GROUP BY idarticolo, idordine, lotto HAVING idordine='$idordine' AND NOT idarticolo='0' ORDER BY idarticolo ASC"; +$rs_art = $dbo->fetchArray($q_art); +$tot_art = sizeof($rs_art); +$imponibile_art = 0.0; +$iva_art = 0.0; + +if ($tot_art > 0) { + $prec_art = ''; + $riga_art = ''; + + for ($i = 0; $i < $tot_art; ++$i) { + if ($rs_art[$i]['idarticolo'] != $prec_art) { + $q_art = 0; + } + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_art += $rs_art[$i]['subtotale']; + $iva_art += $iva; + $sconto += $rs_art[$i]['sconto']; + } + $imponibile_ordine += $imponibile_art; + $totale_iva += $iva_art; + $totale_ordine += $imponibile_art; +} + +/* + Righe generiche +*/ +$q_gen = "SELECT * FROM `or_righe_ordini` WHERE idordine='$idordine' AND idarticolo=0"; +$rs_gen = $dbo->fetchArray($q_gen); +$tot_gen = sizeof($rs_gen); +$imponibile_gen = 0.0; +$iva_gen = 0.0; + +if ($tot_gen > 0) { + for ($i = 0; $i < $tot_gen; ++$i) { + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Iva + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_gen += $rs_gen[$i]['subtotale']; + $iva_gen += $iva; + $sconto += $rs_gen[$i]['sconto']; + } + $imponibile_ordine += $imponibile_gen; + $totale_iva += $iva_gen; + $totale_ordine += $imponibile_gen; +} + +// Totale imponibile +if ($show_costi) { + $body .= "\n"; + + $body .= "\n"; + + // Mostra sconto se c'è + if (abs($sconto) > 0) { + $body .= "\n"; + + // Sconto + $body .= "'; + $body .= "\n"; + + // Totale scontato + $body .= "\n"; + + // Sconto + $body .= "\n"; + } + + // Mostra INPS se c'è + if (abs($rs[0]['rivalsainps']) > 0) { + $body .= "\n"; + + // Rivalsa INPS + $body .= "\n"; + $totale_ordine += $rs[0]['rivalsainps']; + } + + // Mostra iva se c'è + $totale_iva += $rs[0]['iva_rivalsainps']; + if (abs($totale_iva) > 0) { + $body .= "\n"; + + // Iva + $body .= "\n"; + $totale_ordine += $totale_iva; + } + + /* + Totale ordine + */ + $body .= "\n"; + + $body .= "\n"; + $netto_a_pagare = $totale_ordine; + + // Mostra marca da bollo se c'è + if (abs($rs[0]['bollo']) > 0) { + $body .= "\n"; + + // Marca da bollo + $body .= "\n"; + $netto_a_pagare += $marca_da_bollo; + } + + // Mostra ritenuta d'acconto se c'è + if (abs($rs[0]['ritenutaacconto']) > 0) { + $body .= "\n"; + + // Ritenuta d'acconto + $body .= "\n"; + $netto_a_pagare -= $rs[0]['ritenutaacconto']; + } + + /* + Netto a pagare (se diverso dal totale) + */ + if ($totale_ordine != $netto_a_pagare) { + $body .= "\n"; + + $body .= "\n"; + } +} + +$body .= "\n"; +$body .= "
DescrizioneQ.tàu.m.Costo unitarioIvaImponibile
\n"; + $body .= nl2br($rs_art[$i]['descrizione']); + if ($rs_art[$i]['codice'] != '') { + $body .= '
'.$rs_art[$i]['codice']."\n"; + } + $body .= "
\n"; + $body .= Translator::numberToLocale($rs_art[$i]['sumqta'], 2)."\n"; + $body .= "\n"; + $body .= $rs_art[$i]['um']."\n"; + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'] / $rs_art[$i]['sumqta'], 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + $iva = $rs_art[$i]['iva']; + if ($show_costi) { + $body .= Translator::numberToLocale($iva, 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'], 2)." €\n"; + + if ($rs_art[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rs_art[$i]['sconto'], 2)." €\n"; + } + } else { + $body .= '-'; + } + $body .= "
\n"; + $body .= nl2br($rs_gen[$i]['descrizione']); + $body .= "\n"; + $body .= Translator::numberToLocale($rs_gen[$i]['qta'], 2)."\n"; + $body .= "\n"; + $body .= $rs_gen[$i]['um']."\n"; + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_gen[$i]['subtotale'] / $rs_gen[$i]['qta'], 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + $iva = $rs_gen[$i]['iva']; + if ($show_costi) { + $body .= Translator::numberToLocale($iva, 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_gen[$i]['subtotale'], 2)." €\n"; + + if ($rs_gen[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rs_gen[$i]['sconto'], 2)." €\n"; + } + } else { + $body .= '-'; + } + $body .= "
\n"; + $body .= 'Totale imponibile:'; + $body .= "\n"; + $body .= Translator::numberToLocale($imponibile_ordine, 2).' €'; + $body .= "
\n"; + $body .= 'Sconto:'; + $body .= "\n"; + $body .= Translator::numberToLocale($sconto, 2).' €'; + $body .= '
\n"; + $body .= 'Totale scontato:'; + $body .= "\n"; + $totale_ordine = $imponibile_ordine - $sconto; + $body .= Translator::numberToLocale($totale_ordine, 2).' €'; + $body .= "
\n"; + $body .= 'Rivalsa INPS:'; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['rivalsainps'], 2).' €'; + $body .= "
\n"; + $body .= 'Iva:'; + $body .= "\n"; + $body .= Translator::numberToLocale($totale_iva, 2)." €\n"; + $body .= "
\n"; + $body .= 'Totale ordine:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_ordine, 2)." €\n"; + $body .= "
\n"; + $body .= 'Marca da bollo:'; + $body .= "\n"; + $marca_da_bollo = str_replace(',', '.', $rs[0]['bollo']); + $body .= Translator::numberToLocale($marca_da_bollo, 2).' €'; + $body .= "
\n"; + $body .= "Ritenuta d'acconto:"; + $body .= "\n"; + $body .= Translator::numberToLocale($rs[0]['ritenutaacconto'], 2).' €'; + $body .= "
\n"; + $body .= 'Netto a pagare:'; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto_a_pagare, 2)." €\n"; + $body .= "
\n"; + +$body .= '

'.nl2br($rs[0]['note'])."

\n"; + +$report_name = 'Ordine_'.$numero_ord.'.pdf'; diff --git a/templates/partitario_mastrino/logo_azienda.jpg b/templates/partitario_mastrino/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBv +body{ font-size:12px; } +th{ background:#eee; } + +th.padded, +td.padded{ + padding: 4px; + vertical-align: top; +} + +.text-right{ text-align:right; } +.text-center{ text-align:center; } + +.br{ + border-right: 1px solid #999; +} + +.bb{ + border-bottom: 1px solid #999; +} + +.bt{ + border-top: 1px solid #999; +} + + + + $body$ + diff --git a/templates/partitario_mastrino/partitario_body.html b/templates/partitario_mastrino/partitario_body.html new file mode 100644 index 000000000..0061d053e --- /dev/null +++ b/templates/partitario_mastrino/partitario_body.html @@ -0,0 +1,36 @@ + + + + + +
+ + + + +
+ STAMPA MASTRINO (|period_start| - |period_end|)
+ |percorso| +
+ |info_fornitore| +
+
+ + + +
DATADESCRIZIONEDAREAVERE
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/partitario_mastrino/pdfgen.partitario_mastrino.php b/templates/partitario_mastrino/pdfgen.partitario_mastrino.php new file mode 100644 index 000000000..ecd746da7 --- /dev/null +++ b/templates/partitario_mastrino/pdfgen.partitario_mastrino.php @@ -0,0 +1,319 @@ +form('idconto'); +$module_name = 'Piano dei conti'; + +// carica report html +$report = file_get_contents($docroot.'/templates/partitario_mastrino/partitario.html'); +$body = file_get_contents($docroot.'/templates/partitario_mastrino/partitario_body.html'); +include_once $docroot.'/templates/pdfgen_variables.php'; + +// Calcolo il percorso piano dei conti +if ($html->form('lev') == '3') { + $rs = $dbo->fetchArray("SELECT idpianodeiconti2, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti3 WHERE id=\"".$idconto.'"'); + $percorso = $rs[0]['descrizione']; + $idpianodeiconti2 = $rs[0]['idpianodeiconti2']; + + $rs = $dbo->fetchArray("SELECT idpianodeiconti1, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti2 WHERE id=\"".$idpianodeiconti2.'"'); + $percorso = $rs[0]['descrizione'].'
    '.$percorso; + $idpianodeiconti1 = $rs[0]['idpianodeiconti1']; + + $rs = $dbo->fetchArray("SELECT CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti1 WHERE id=\"".$idpianodeiconti1.'"'); + + ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; + $percorso = $descrizione.'
  '.$percorso; +} elseif ($html->form('lev') == '2') { + $rs = $dbo->fetchArray("SELECT idpianodeiconti1, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti2 WHERE id=\"".$idconto.'"'); + $percorso = $rs[0]['descrizione'].'
    '.$percorso; + $idpianodeiconti1 = $rs[0]['idpianodeiconti1']; + + $rs = $dbo->fetchArray("SELECT CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti1 WHERE id=\"".$idpianodeiconti1.'"'); + + ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; + $percorso = $descrizione.'
  '.$percorso; +} elseif ($html->form('lev') == '1') { + $rs = $dbo->fetchArray("SELECT CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti1 WHERE id=\"".$idconto.'"'); + + ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; + $percorso = $descrizione.'
 
 '; +} + +$body = str_replace('|percorso|', $percorso, $body); +$body = str_replace('|info_fornitore|', $f_ragionesociale.'
'.$f_indirizzo.'
'.$f_citta, $body); +$body = str_replace('|period_start|', Translator::dateToLocale($_SESSION['period_start']), $body); +$body = str_replace('|period_end|', Translator::dateToLocale($_SESSION['period_end']), $body); + +// Stampa da livello 3 +if ($html->form('lev') == '3') { + $body .= " + + \n"; + + // Inizializzo saldo finale + $saldo_finale = 0; + + // Calcolo saldo iniziale + $rs = $dbo->fetchArray('SELECT SUM(totale) AS totale FROM co_movimenti WHERE idconto="'.$idconto.'" AND data < "'.$_SESSION['period_start'].'"'); + $saldo_iniziale = $rs[0]['totale']; + $saldo_finale = $saldo_iniziale; + + if ($saldo_iniziale < 0) { + $dare = ''; + $avere = abs($saldo_iniziale); + } else { + $dare = abs($saldo_iniziale); + $avere = ''; + } + + $body .= " \n"; + + $rs = $dbo->fetchArray('SELECT * FROM co_movimenti WHERE idconto="'.$idconto.'" AND data >= "'.$_SESSION['period_start'].'" AND data <= "'.$_SESSION['period_end'].'" ORDER BY data ASC'); + + for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['totale'] >= 0) { + $dare = Translator::numberToLocale(abs($rs[$i]['totale']), 2); + $avere = ''; + } else { + $dare = ''; + $avere = Translator::numberToLocale(abs($rs[$i]['totale']), 2); + } + + $body .= " \n"; + + $saldo_finale += $rs[$i]['totale']; + } + + if ($saldo_finale < 0) { + $dare = ''; + $avere = abs($saldo_finale); + } else { + $dare = abs($saldo_finale); + $avere = ''; + } + + // Mostro il saldo finale + $body .= " \n"; + + $body .= " +
SALDO INIZIALE".Translator::numberToLocale(abs($dare), 2)."".Translator::numberToLocale(abs($avere), 2)."
".Translator::dateToLocale($rs[$i]['data'])."".$rs[$i]['descrizione']."".$dare."".$avere."
SALDO FINALE".Translator::numberToLocale(abs($dare), 2)."".Translator::numberToLocale(abs($avere), 2)."
\n"; +} + +// Stampa da livello 2 +elseif ($html->form('lev') == '2') { + $body .= " + + \n"; + + // Ciclo fra i sotto-conti di livello 2 + $rs3 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti3 WHERE idpianodeiconti2="'.$idconto.'"'); + + for ($z = 0; $z < sizeof($rs3); ++$z) { + // Inizializzo saldo finale + $saldo_finale = 0; + + // Calcolo saldo iniziale + $rs = $dbo->fetchArray('SELECT SUM(totale) AS totale FROM co_movimenti WHERE idconto="'.$rs3[$z]['id'].'" AND data < "'.$_SESSION['period_start'].'"'); + $saldo_iniziale = $rs[0]['totale']; + $saldo_finale = $saldo_iniziale; + + if ($saldo_iniziale < 0) { + $dare = ''; + $avere = abs($saldo_iniziale); + } else { + $dare = abs($saldo_iniziale); + $avere = ''; + } + + $rs = $dbo->fetchArray('SELECT * FROM co_movimenti WHERE idconto="'.$rs3[$z]['id'].'" AND data >= "'.$_SESSION['period_start'].'" AND data <= "'.$_SESSION['period_end'].'" ORDER BY data ASC'); + + for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['totale'] >= 0) { + $dare += abs($rs[$i]['totale']); + } else { + $avere += abs($rs[$i]['totale']); + } + } + + $totale = $dare - $avere; + + if ($totale >= 0) { + $dare = Translator::numberToLocale(abs($totale), 2); + $avere = ''; + } else { + $dare = ''; + $avere = Translator::numberToLocale(abs($totale), 2); + } + + // Mostro il saldo finale del conto di livello 3 + $body .= " \n"; + } + + $body .= " +
".$rs3[$z]['numero'].' '.$rs3[$z]['descrizione']."".$dare."".$avere."
\n"; +} + +// Stampa completa bilancio +elseif ($html->form('lev') == '1') { + $ricavi = 0; + $costi = 0; + $totale_attivita = 0; + $totale_passivita = 0; + + $body .= " + + \n"; + + // Ciclo fra il conto principale scelto (Economico o Patrimoniale) + $rs1 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti1 WHERE id="'.$idconto.'" ORDER BY numero DESC'); + + for ($x = 0; $x < sizeof($rs1); ++$x) { + // Ciclo fra i sotto-conti di livello 1 + $rs2 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti2 WHERE idpianodeiconti1="'.$rs1[$x]['id'].'"'); + + for ($y = 0; $y < sizeof($rs2); ++$y) { + $body .= " \n"; + + // Ciclo fra i sotto-conti di livello 2 + $rs3 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti3 WHERE idpianodeiconti2="'.$rs2[$y]['id'].'"'); + + for ($z = 0; $z < sizeof($rs3); ++$z) { + $dare = 0; + $avere = 0; + + $rs = $dbo->fetchArray('SELECT * FROM co_movimenti WHERE idconto="'.$rs3[$z]['id'].'" AND data >= "'.$_SESSION['period_start'].'" AND data <= "'.$_SESSION['period_end'].'" ORDER BY data ASC'); + + for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['totale'] >= 0) { + $dare += abs($rs[$i]['totale']); + } else { + $avere += abs($rs[$i]['totale']); + } + } + + $totale = $dare - $avere; + + if ($totale >= 0) { + $dare = abs($totale); + $avere = 0; + $totale_attivita += $dare; + $costi += abs($dare); + } else { + $dare = 0; + $avere = abs($totale); + $totale_passivita += $avere; + $ricavi += abs($avere); + } + + // Mostro il saldo finale del conto di livello 3 + $body .= " \n"; + } + } + } + + // Stampa "Costi/Ricavi" se conto economico + if ($rs1[0]['descrizione'] == 'Economico') { + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + } + + // Stampa "Attività/Passività" se stato patrimoniale + else { + $costi = 0; + $ricavi = 0; + + // Ciclo fra il conto economico per calcolare l'utile o la perdita + $rs1 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti1 WHERE NOT id="'.$idconto.'" ORDER BY numero DESC'); + + for ($x = 0; $x < sizeof($rs1); ++$x) { + // Ciclo fra i sotto-conti di livello 1 + $rs2 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti2 WHERE idpianodeiconti1="'.$rs1[$x]['id'].'"'); + + for ($y = 0; $y < sizeof($rs2); ++$y) { + // Ciclo fra i sotto-conti di livello 2 + $rs3 = $dbo->fetchArray('SELECT id, numero, descrizione FROM co_pianodeiconti3 WHERE idpianodeiconti2="'.$rs2[$y]['id'].'"'); + + for ($z = 0; $z < sizeof($rs3); ++$z) { + // Inizializzo saldo finale + $saldo_finale = 0; + + // Calcolo saldo iniziale + $rs = $dbo->fetchArray('SELECT SUM(totale) AS totale FROM co_movimenti WHERE idconto="'.$rs2[$y]['id'].'" AND data < "'.$_SESSION['period_start'].'"'); + $dare = 0; + $avere = 0; + + $rs = $dbo->fetchArray('SELECT * FROM co_movimenti WHERE idconto="'.$rs3[$z]['id'].'" AND data >= "'.$_SESSION['period_start'].'" AND data <= "'.$_SESSION['period_end'].'" ORDER BY data ASC'); + + for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['totale'] >= 0) { + $dare += abs($rs[$i]['totale']); + } else { + $avere += abs($rs[$i]['totale']); + } + } + + $totale = $dare - $avere; + + if ($totale >= 0) { + $costi += abs($totale); + } else { + $ricavi += abs($totale); + } + } + } + } + + $body .= " \n"; + $body .= "
".$rs2[$y]['numero'].' '.$rs2[$y]['descrizione']."
".$rs3[$z]['numero'].' '.$rs3[$z]['descrizione']."".Translator::numberToLocale(abs($dare), 2)."".Translator::numberToLocale(abs($avere), 2)."
RICAVI".Translator::numberToLocale($ricavi, 2)."
COSTI".Translator::numberToLocale($costi, 2)."
UTILE".Translator::numberToLocale($ricavi - $costi, 2)."
\n"; + + // Tabella di riepilogo finale + $totale_attivita = abs($totale_attivita); + $totale_passivita = abs($totale_passivita); + $utile_perdita = abs($ricavi) - abs($costi); + + if ($utile_perdita < 0) { + $pareggio1 = $totale_attivita + abs($utile_perdita); + $pareggio2 = abs($totale_passivita); + } else { + $pareggio1 = $totale_attivita; + $pareggio2 = abs($totale_passivita) + abs($utile_perdita); + } + + $body .= " + + \n"; + + // Attività + $body .= " \n"; + + // Passività + $body .= " \n"; + + if ($utile_perdita < 0) { + // Perdita d'esercizio + $body .= " \n"; + + // Utile + $body .= " \n"; + } else { + // Perdita d'esercizio + $body .= " \n"; + + // Utile + $body .= " \n"; + } + + // PAREGGIO 1 + $body .= " \n"; + + // PAREGGIO 2 + $body .= " \n"; + } + + $body .= " +
TOTALE ATTIVITÀ".Translator::numberToLocale($totale_attivita, 2)."PASSIVITÀ".Translator::numberToLocale($totale_passivita, 2)."
PERDITA D'ESERCIZIO".Translator::numberToLocale(abs($utile_perdita), 2)."  
  UTILE".Translator::numberToLocale(abs($utile_perdita), 2)."
TOTALE A PAREGGIO".Translator::numberToLocale($pareggio1, 2)."TOTALE A PAREGGIO".Translator::numberToLocale($pareggio2, 2)."
\n"; +} + +$report_name = 'mastrino.pdf'; diff --git a/templates/pdfgen_variables.php b/templates/pdfgen_variables.php new file mode 100644 index 000000000..e86a4c3f7 --- /dev/null +++ b/templates/pdfgen_variables.php @@ -0,0 +1,129 @@ +fetchArray($queryc); + +// Lettura dati aziendali +$rsf = $dbo->fetchArray("SELECT * FROM an_anagrafiche WHERE idanagrafica = (SELECT valore FROM zz_settings WHERE nome='Azienda predefinita')"); +$id_azienda = $rsd[0]['id']; + +$replace = [ + 'c_' => $rsc[0], + 'f_' => $rsf[0], +]; + +$rename = [ + 'capitale_sociale' => 'capsoc', + 'ragione_sociale' => 'ragionesociale', + 'codice' => 'codiceanagrafica', +]; + +$keys = []; + +foreach ($replace as $prefix => $values) { + $values = (array) $values; + if ($prefix == 'c_') { + $keys = array_keys($values); + } + + if (empty($values)) { + // Azienda predefinita non impostata + if ($prefix == 'f_') { + $values = []; + foreach ($keys as $key) { + $values[$key] = ''; + } + } else { + die(_('Accesso negato')); + } + } + + foreach ($rename as $key => $value) { + $values[$value] = $values[$key]; + unset($values[$key]); + } + + foreach ($values as $key => $value) { + ${$prefix.$key} = $value; + } + + $values['codice'] = !empty($values['codice']) ? $values['codice'].',' : ''; + $values['ragionesociale'] = !empty($values['ragionesociale']) ? $values['ragionesociale'].',' : ''; + $values['provincia'] = !empty($values['provincia']) ? '('.$values['provincia'].')' : ''; + + $citta = ''; + + if ($values['cap'] != '') { + $citta .= $values['cap']; + } + if ($values['citta'] != '') { + $citta .= ' '.$values['citta']; + } + if ($values['provincia'] != '') { + $citta .= ' '.$values['provincia']; + } + $citta .= '
'; + + $values['citta'] = $citta; + + if ($values['piva'] != $values['codicefiscale']) { + $values['piva'] = !empty($values['piva']) ? 'P.Iva: '.$values['piva'] : ''; + $values['codicefiscale'] = !empty($values['codicefiscale']) ? 'C.F.: '.$values['codicefiscale'] : ''; + } else { + $values['piva'] = !empty($values['piva']) ? 'P.Iva/C.F.: '.$values['piva'] : ''; + $values['codicefiscale'] = ''; + } + + $values['capsoc'] = !empty($values['capsoc']) ? 'Cap.Soc.: '.$values['capsoc'] : ''; + $values['sitoweb'] = !empty($values['sitoweb']) ? 'Web: '.$values['sitoweb'] : ''; + $values['telefono'] = !empty($values['telefono']) ? 'Tel: '.$values['telefono'] : ''; + $values['fax'] = !empty($values['fax']) ? 'Fax: '.$values['fax'] : ''; + $values['cellulare'] = !empty($values['cellulare']) ? 'Cell: '.$values['cellulare'] : ''; + $values['email'] = !empty($values['email']) ? 'Email: '.$values['email'] : ''; + $values['codiceiban'] = !empty($values['codiceiban']) ? 'Cap.Soc.: '.$values['codiceiban'] : ''; + + if ($key == 'c_') { + $keys = array_unique(array_merge($keys, array_keys($values))); + } + + foreach ($values as $key => $value) { + $values['$'.$prefix.$key.'$'] = empty($value) ? $value : $value.'
'; + unset($values[$key]); + } + + // Sostituisce alle variabili del template i valori + $body = str_replace(array_keys($values), array_values($values), $body); + $report = str_replace(array_keys($values), array_values($values), $report); +} + +// Aggiunta del footer standard +if (strpos($body, '') === false && strpos($report, '') === false) { + $report .= ' + + + + + + + + +
+ '._('Stampato con OpenSTAManager').' + + '.str_replace(['_PAGE_', '_TOTAL_'], ['[[page_cu]]', '[[page_nb]]'], _('Pagina _PAGE_ di _TOTAL_')).' +
+
'; +} diff --git a/templates/preventivi/logo_azienda.jpg b/templates/preventivi/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F z*G;^Z@LK|Fdd3NSqUGAu@eQMK`F=e#>6TaaO#e|%2%O*{5IK4;5-IuU>Lmw%n1eGe z%kaEY&OC3FH(wd=;LrMJAE+TtEo3Y_yX%0aw~cepyOT7pqflUlRQW{=UZKZKpJiTc z;PdnRc!njkTUU3nfrYRx4*+b+PuY?WyrV7Dt-ixF;CGoHNdF}8aM0-oHUP>Fr-oV* z4uBv~5SWhc&y#=vP&yEplS>J%OwWN3HRl$QSJ6gN-A&QgtFDHC-HhfI>5_Z0A&2cUPd#RbIXo){l zn=;x&Y~0`+X;Q07sDd6Yemk3q5rX?}W>YTvIA!fzGH;tgW;Ss~QFJ=U;FO$aJ7z_p zgQu~Rzg%uiuUZ%jDnFk+GMmKOEp~efQkUuzoN6;TlFYY6&z$zcXLj#7^RCp|D))+j zdQhNV16(lvz;-(KybE6+)HD%!w%yGSvz$>QmgPBUwsdFS!%Aq|P2JT_t%VTV7;S7v zcUq}=IOC~B!{x3*{9QGhN)SEPcAicual?{m(CVHDYc%GXfMx>C{E;_et z_NbMda#3kWxu6>Co3Bx#%`jO`+jfsxu0`#m8_|jfJinJkCG4V78IFe`3}Xbe7{xjd zAqyTw{XH}PF?T1es5$=3us^d9caT)nzkn8qPV3)DfWJ$q)3Oyr4~2kPp^yVJU@CzF zicnNaD?}>j_`^A|qUKy8V)Dw`x)#nZkx?W+eEsaRwe>&pmtG6Z?&RB~f0s|Dj^q}X zB%^HWT-49XW8+RB{(VGKZ2^Z{Cr7rWuS@LMzpZ&&{L#n1$v?I6X$^7Sv0p(dL^Di@ z#(Hi6_LCE^|5kB6ck*p;`;bwnT~dGhjTEm9rR|#+SFoR(lH1F_ng@PSx&6wTw;o?% zDvjB$EFq8`2!_2B%RqTmpcFIC+x70bti#b?Smu<|D4BD&8QulWq;fV{*=r0Y=L$~3 zO>_83y9|1@=}oXrt85Pwis$VfgWm+DR7@TKL91_%@g$XO=Yl*f6pL0 zpZZ#W(w?i#8v&=cVdy(K-Di^Om)oK6lu# z)$_U4?&;AEA=Q$IEw}4^iTSI;EG2tC9p5qhQt)Z6ongIn$!c_fxHB%C%MY!6HEKKD zYq020`NcGO%ysGY@Y&wjcHwUecK$BuRfGnO;=pyQ$Hf=t=a$|PuRXBREbIChyw1Gk zaK1)>=q>A-bw?B; zD?~}MMk!@59Y^tak`Y?7a*mc>%?D9<@BL0_+F+sn!{0NrV@FAUv=%T30;YpfEBud= z2XP=3*0Aev9p}P&bHB7_^4gKJB7e3PEu`Ori4**;6X@|{y^l-@SJE%%{1v2U+#m^^ z+~u**mP1tF3psjm?WI9p(s-*9NBJ^RJl*a=XKvcSTs$Svho#G-TcVUTu7cxh3c;Sj zd!->)yiZ?^&qp!!RVYo_@5Q3}8JM5NSwAhO*ymviceURO*|Sbk*wfVe=*I9@?zYcK zhVb7NvJNOv-Bl-C5{oW9j+q}a_B>`%xyNSa1~ZXho_Kq%b0|wndg(pkGmnJf=eAE_ z4C{;cMQV+DrMW9nH#IN7<2A3Xyr|n2w-2ntMzv;X#htx%*lgg1XBTUt7CkH+&4e zED5SO6a7AJ)QsFl*P(+SXp6n&nsBi;)Zbtp9G4TYg8Wbw+z9jGm1TZx^QQAm&lS`J z0cl2B!^&BieiBdAEj)49;q498I2Yw#Jp?gwhA;i9^$?CFCf!o`&ORR}>H?M;kLFOg z;TD|Iil>D>BpUlKDB1Gkt_~bRTf{X6yQbt0KbFi5e%Pb8aS?yBi^4ugYOb13^J7cc z6q+l-qB5Gp3wjIS!i|PZg^Xqy1Gpn^gwgKSCBeqHDyhW2+Nc*9jN$Z5ku=_gaMQSv zWZt`WQiLxYI(;Ki!!_-YmzDD&8vT(lM6TAo13!1=H&QsceLm<5WN(lW6*r$J&kbqOKiVz3{3Z~xK4+iz_k6cs0KGSg~ z!Tll&&C^8W>$SgEKKzD?zPBxzz$Ps+_g`7klb}fp)dsJLzFn7hRat%q_JN<(9TJah zRx4+8KV;4SjmYtEWL3YK=qzV@+NrdVzv}uPLf^g?jG5XxdRfL33azsbz4R?Cb2mJn zYQeGHkiV&P=KUC4LVO1PFd*(uECRJH!ajMv=Z>4Q+}1E##q?=HjFWH7M@U1{&qX?P z(a_>6=GT%2>+=fYF{SUyS^EaioUKLlIN8mDinT*d9cRMJ;uf;H3}(tc#T{E+tkv?; zoo+mRZ%BL_>eyHsQLad4Aorp1ro8>SMp@+8jI$Mb2}@&NLo9l5vhYZQ&Sat^DnCBq`N>E0}m5LWFB)v9XJ~`z0=~zZdB#%n=>WA5? zlWXbIU#Jn?+S&Ab5~67~9sq|;{7T}ZvmKvyziFwkwX_hSjvVauON@4!xUMaZdX%b6 z$jgY$`pR8iF(7CI+iVX@XonN^ZNi*4ZSTd)>(vkA*eDg8L%pmq7z(%YQp?71hc{R$ z96bd&>1m1Yu{Sd|XVw`(rVf$p8(cM`3$AH= zleCvk6vZs`v3qZt3E=Y!r|E<|ofuFIxftxiCWBIMLa7 zXJ|6-i5@S8R7QU?=SJg9TEmna@PuKZ3A@CSdP{k zHTpLVG7|Fk0oEHYj$&C#7I%-k91AxaTSY^55{f<0cf`mi9X{*>(H8FO!+AcBqWH)2 pzkP8z7RFBvfetchArray($q); +$idcliente = $rspreventivii[0]['idanagrafica']; + +// carica report html +$report = file_get_contents($docroot.'/templates/preventivi/preventivo.html'); +$body = file_get_contents($docroot.'/templates/preventivi/preventivo_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$totrows = sizeof($rspreventivii); +$totale_km = 0; +$totale_ore = 0; +$totale = 0; +$preventivi = []; +$ore = []; +$km = []; +$ntecnici = []; +$tecnici = []; +$costi_orari = []; +$costi_km = []; +$idinterventi = ['-1']; + +if ($totrows > 0) { + for ($i = 0; $i < $totrows; ++$i) { + // Lettura numero tecnici collegati all'intervento + $query = 'SELECT an_anagrafiche.idanagrafica, ragione_sociale FROM in_interventi_tecnici LEFT OUTER JOIN an_anagrafiche ON in_interventi_tecnici.idtecnico=an_anagrafiche.idanagrafica WHERE idintervento="'.$rspreventivii[$i]['idintervento'].'"'; + $rs = $dbo->fetchArray($query); + $n_tecnici = sizeof($rs); + $tecnici_full = ''; + for ($j = 0; $j < $n_tecnici; ++$j) { + $tecnici_full .= '- '.$rs[$j]['ragione_sociale']."
\n"; + } + + // Conteggio ore totali + $t = datediff('n', $rspreventivii[$i]['ora_dal'], $rspreventivii[$i]['ora_al']); + $ore_pausa = Translator::numberToLocale($rspreventivii[$i]['ore_pausa'], 2); + $t = round($t / 60 - $rspreventivii[$i]['ore_pausa'], 1); + + if ($rspreventivii[$i]['data'] != '') { + $line = 'Intervento del '.Translator::dateToLocale($rspreventivii[$i]['data']).":
".str_replace("\n", '
', $rspreventivii[$i]['descrizione'])."

\n"; + array_push($preventivi, $line); + } + array_push($km, floatval($rspreventivii[$i]['km'])); + array_push($ore, $t); + array_push($ntecnici, $n_tecnici); + array_push($tecnici, $tecnici_full); + if ($rspreventivii[$i]['prezzo_ore'] > 0) { + array_push($ore, $rspreventivii[$i]['prezzo_ore_scontato'] / $rspreventivii[$i]['prezzo_ore']); + } else { + array_push($ore, 0); + } + array_push($costi_orari, floatval($rspreventivii[$i]['costo_orario'])); + array_push($costi_km, floatval($rspreventivii[$i]['costo_km'])); + if ($rspreventivii[$i]['prezzo_ore_unitario'] > 0) { + $totale_ore += $rspreventivii[$i]['prezzo_ore_scontato'] / $rspreventivii[$i]['prezzo_ore_unitario']; + } + + $totale_km += floatval($rspreventivii[$i]['km']); + } +} + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rspreventivii[0]['${1}'], $body); + +// Lettura nome referenti collegati all'anagrafica +$query = 'SELECT * FROM an_referenti WHERE id = '.$rspreventivii[0]['idreferente']; +$rs = $dbo->fetchArray($query); +$nome_referente = $rs[0]['nome']; + +// Tabella intestazione +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +if ($nome_referente != '') { + $body .= "\n"; + $body .= "\n"; +} + +$body .= "\n"; +$body .= "\n"; + +$body .= "
\n"; + +$body .= ''.$f_citta.', '.$rspreventivii[0]['data']."

\n"; +$body .= 'PREVENTIVO No '.$rspreventivii[0]['numero'].' DEL '.$rspreventivii[0]['data']."\n"; + +$body .= "
\n"; + +if ($c_cap != '') { + $c_cap = $c_cap.' '; +} +if ($c_provincia != '') { + $c_provincia = ' ('.$c_provincia.')'; +} + +$body .= 'Spettabile
'.$c_ragionesociale.'
'.$c_indirizzo.'
'.$c_cap.$c_citta.$c_provincia.'
P.Iva: '.$c_piva."
\n"; +$body .= "
\n"; + $body .= 'C.A. '.$nome_referente."\n"; + $body .= "
\n"; +$body .= ''.str_replace("\n", '
', $rspreventivii[0]['cdescrizione'])."


\n"; +$body .= "
\n"; + +/* + TABELLA COSTI +*/ +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +$cifredecimali = get_var('Cifre decimali per importi'); + +// ARTICOLI +$q_art = "SELECT *, IFNULL((SELECT codice FROM mg_articoli WHERE id=idarticolo),'') AS codice, (SELECT descrizione FROM co_iva WHERE id=idiva) AS desc_iva FROM `co_righe_preventivi` WHERE idpreventivo='$idpreventivo' ORDER BY id ASC"; +$rs_art = $dbo->fetchArray($q_art); +$tot_art = sizeof($rs_art); + +$imponibile_articoli = 0.0; +$totale_iva = 0.0; +$totale_sconto = 0.0; + +for ($i = 0; $i < $tot_art; ++$i) { + // descrizione + $body .= "\n"; + + // q.tà + $body .= "\n"; + + // Costo unitario + $body .= "\n"; + + $body .= "\n"; + + // Imponibile + $body .= "\n"; + + $imponibile_articoli += $rs_art[$i]['subtotale']; + $totale_iva += $iva; +} + +// SCONTO +if (abs($totale_sconto) > 0) { + $body .= "\n"; + $body .= "\n"; +} + +// Totale iva +$body .= "\n"; +$body .= "\n"; + +// Totale iva +$body .= "\n"; +$body .= "\n"; + +// Totale complessivo intervento +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= "
DescrizioneQ.tàCosto U.IvaImponibile
\n"; + + if ($rs_art[$i]['codice'] != '') { + $body .= $rs_art[$i]['codice'].' - '; + } + $body .= nl2br($rs_art[$i]['descrizione']); + + $body .= "\n"; + $qta = $rs_art[$i]['qta']; + $body .= Translator::numberToLocale($rs_art[$i]['qta'], 2)."\n"; + if ($rs_art[$i]['um'] != '') { + $body .= "
\n".$rs_art[$i]['um']."\n"; + } + $body .= "
\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'] / $rs_art[$i]['qta'], 2)." €\n"; + if ($rs_art[$i]['sconto'] > 0) { + $body .= "
\n- sconto ".Translator::numberToLocale($rs_art[$i]['sconto'], 2)." €\n"; + } + } else { + $body .= '-'; + } + $totale_sconto += ($rs_art[$i]['sconto'] * $qta); + $body .= "
\n"; + $iva = $rs_art[$i]['iva']; + $body .= Translator::numberToLocale($iva, 2)." €
".$rs_art[$i]['desc_iva']."\n"; + $body .= "
\n"; + if ($show_costi) { + $body .= Translator::numberToLocale($rs_art[$i]['subtotale'] - ($qta * $rs_art[$i]['sconto']), 2)." €\n"; + } else { + $body .= '-'; + } + $body .= "
\n"; + $body .= " SCONTO:\n"; + $body .= "\n"; + $body .= ' - '.Translator::numberToLocale($totale_sconto, 2)." €\n"; + $body .= "
\n"; +$body .= " TOTALE IMPONIBILE:\n"; +$body .= "\n"; +$body .= ' '.Translator::numberToLocale(($imponibile_articoli - $totale_sconto), 2)." €\n"; +$body .= "
\n"; +$body .= " TOTALE IVA:\n"; +$body .= "\n"; +$body .= ''.Translator::numberToLocale($totale_iva, 2)." €\n"; +$body .= "
\n"; +$body .= "QUOTAZIONE TOTALE: \n"; +$body .= "\n"; +$body .= ''.Translator::numberToLocale(($imponibile_articoli - $totale_sconto) + $totale_iva, 2)." €\n"; +$body .= "


\n"; + +// CONDIZIONI GENERALI DI FORNITURA + +// Lettura pagamenti +$query = 'SELECT * FROM co_pagamenti WHERE id = '.$rspreventivii[0]['idpagamento']; +$rs = $dbo->fetchArray($query); +$pagamento = $rs[0]['descrizione']; + +// Lettura resa +$query = 'SELECT * FROM dt_porto WHERE id = '.$rspreventivii[0]['idporto']; +$rs = $dbo->fetchArray($query); +$resa_materiale = $rs[0]['descrizione']; + +$rspreventivii[0]['idpagamento']; + +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +// PAGAMENTI +$body .= "\n"; + +$body .= "\n"; + +// RESA MATERIALI +$body .= "\n"; + +$body .= "\n"; + +// VALIDITA' OFFERTA +$body .= "\n"; + +$body .= "\n"; + +// TEMPI CONSEGNA +$body .= "\n"; + +$body .= "\n"; + +// ESCLUSIONI +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; +$body .= " \n"; +$body .= "\n"; + +$body .= "
\n"; +$body .= "CONDIZIONI GENERALI DI FORNITURA\n"; +$body .= "
\n"; +$body .= "PAGAMENTI:\n"; +$body .= "\n"; +$body .= ''.$pagamento."\n"; +$body .= "
\n"; +$body .= "RESA MATERIALI:\n"; +$body .= "\n"; +$body .= ''.$resa_materiale."\n"; +$body .= "
\n"; +$body .= "VALIDITÀ OFFERTA:\n"; +$body .= "\n"; +$body .= ''.$rspreventivii[0]['validita']." giorni\n"; +$body .= "
\n"; +$body .= "TEMPI CONSEGNA:\n"; +$body .= "\n"; +$body .= ''.$rspreventivii[0]['tempi_consegna']." giorni\n"; +$body .= "
\n"; +$body .= "ESCLUSIONI:\n"; +$body .= "\n"; +$body .= ''.nl2br($rspreventivii[0]['esclusioni'])."\n"; +$body .= "
\n"; +$body .= "
In attesa di un Vostro Cortese riscontro, colgo l’occasione per porgere Cordiali Saluti.\n"; +$body .= "
\n"; + +$report_name = 'preventivo_'.$idpreventivo.'.pdf'; diff --git a/templates/preventivi/preventivo.html b/templates/preventivi/preventivo.html new file mode 100644 index 000000000..833e98b47 --- /dev/null +++ b/templates/preventivi/preventivo.html @@ -0,0 +1,18 @@ + + + + $body$ + diff --git a/templates/preventivi/preventivo_body.html b/templates/preventivi/preventivo_body.html new file mode 100644 index 000000000..f7850ce29 --- /dev/null +++ b/templates/preventivi/preventivo_body.html @@ -0,0 +1,37 @@ + + + + + + + + +
+ Logo + + $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ +
+ + + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/preventivi_cons/logo_azienda.jpg b/templates/preventivi_cons/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($q); +$idcliente = $rspreventivii[0]['idanagrafica']; +$budget = Translator::numberToLocale($rspreventivii[0]['budget'], 2); + +// carica report html +$report = file_get_contents($docroot.'/templates/preventivi_cons/preventivo.html'); +$body = file_get_contents($docroot.'/templates/preventivi_cons/preventivo_body.html'); + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$totrows = sizeof($rspreventivii); +$totale_km = 0; +$totale_ore = 0; +$totale = 0; +$preventivi = []; +$ore = []; +$km = []; +$dc = []; +$ntecnici = []; +$tecnici = []; +$costi_orari = []; +$costi_km = []; +$idinterventi = []; + +if ($totrows > 0) { + for ($i = 0; $i < $totrows; ++$i) { + if (!empty($rspreventivii[$i]['codice'])) { + // Lettura numero tecnici collegati all'intervento + $query = 'SELECT an_anagrafiche.idanagrafica, ragione_sociale, in_interventi_tecnici.ore, in_interventi_tecnici.km, prezzo_dirittochiamata FROM in_interventi_tecnici LEFT OUTER JOIN an_anagrafiche ON in_interventi_tecnici.idtecnico=an_anagrafiche.idanagrafica WHERE idintervento="'.$rspreventivii[$i]['id'].'"'; + $rst = $dbo->fetchArray($query); + $n_tecnici = sizeof($rst); + $tecnici_full = []; + $dc_tecnici = 0; + $t = 0; + + for ($j = 0; $j < $n_tecnici; ++$j) { + $t1 = $rst[$j]['ore']; + + array_push($tecnici_full, $rst[$j]['ragione_sociale']); + + // Conteggio ore totali + $t += $rst[$j]['ore']; + + $dc_tecnici += $rst[$j]['prezzo_dirittochiamata']; + } + + $desc = str_replace("\n", '
  ', ''.$rspreventivii[$i]['descrizione'].''); + $line = 'Attività '.$rspreventivii[$i]['codice'].' del '.Translator::dateToLocale($rspreventivii[$i]['data'])."
\n  ".$desc; + + array_push($preventivi, $line); + array_push($km, $rspreventivii[$i]['km']); + array_push($ore, $t); + array_push($dc, $dc_tecnici); + array_push($ntecnici, $n_tecnici); + array_push($tecnici, implode(', ', array_unique($tecnici_full))); + $totale_ore += $t; + $totale_km += floatval($rspreventivii[$i]['km']); + $totale_diritto_chiamata += $dc_tecnici; + } + } +} + +$body .= 'PREVENTIVO: '.$rspreventivii[0]['nome']."

\n"; +$body .= ''.str_replace("\n", '
', $rspreventivii[0]['cdescrizione'])."

\n"; + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rspreventivii[0]['${1}'], $body); + +if (sizeof($preventivi) > 0) { + // Tabella con riepilogo interventi, km e ore + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + // Tabella con i dati + for ($j = 0; $j < sizeof($preventivi); ++$j) { + $body .= "\n"; + + // Km + $body .= "\n"; + + // Costo unitario km + $body .= "\n"; + + // Ore + $body .= "\n"; + + // Costo unitario ore + $body .= "\n"; + + // Diritto chiamata + $body .= "\n"; + + // Subtotale + $subtotale = $rspreventivii[$j]['src_costo_km'] * $km[$j] + $rspreventivii[$j]['src_costo_orario'] * $ore[$j] + $rspreventivii[$j]['src_diritto_chiamata']; + $body .= "\n"; + + $totale += $subtotale; + $totale_consuntivo += $rspreventivii[$j]['tot_ore_consuntivo'] + $rspreventivii[$j]['tot_km_consuntivo']; + + array_push($idinterventi, "'".$rspreventivii[$j]['id']."'"); + } + + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + // Riga dello sconto + // $sconto = $totale_consuntivo - $totale; + // $sconto = 0; + if ($sconto != 0) { + /* + $body .= "\n\n"; + */ + + $body .= "\n"; + } + // Fine riga dello sconto + + $totale_intervento_consuntivo += $totale_consuntivo; + $totale_intervento_consuntivo = $totale; + $body .= "\n"; + $body .= "
AttivitàKmCosto al kmOreCosto orarioDiritto ch.Subtotale
\n"; + $body .= $preventivi[$j]."
\n"; + $body .= 'Tecnici:
'.$tecnici[$j]."
\n"; + $body .= "
\n"; + $body .= Translator::numberToLocale($km[$j], 2); + $body .= "\n"; + $body .= Translator::numberToLocale($rspreventivii[$j]['src_costo_km'], 2); + + $body .= "\n"; + $body .= Translator::numberToLocale($ore[$j], 2); + $body .= "\n"; + $body .= Translator::numberToLocale($rspreventivii[$j]['src_costo_orario'], 2); + $body .= "\n"; + $body .= Translator::numberToLocale($dc[$j], 2); + $body .= "\n"; + $body .= Translator::numberToLocale($subtotale, 2); + + // Sconto ore + km + if ($rspreventivii[$j]['tot_sconto_ore'] + $rspreventivii[$j]['tot_sconto_km'] > 0) { + $body .= "
".Translator::numberToLocale(-($rspreventivii[$j]['tot_sconto_ore'] + $rspreventivii[$j]['tot_sconto_km']), 2).''; + } + + $body .= "
\n"; + $body .= "Totale:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_km, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_ore, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_diritto_chiamata, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale, 2)." €\n"; + $body .= "
\n"; + $body .= "Arrotondamenti:\n"; + + $body .= "\n"; + $body .= "".Translator::numberToLocale( $sconto, 2)." €\n"; + $body .= "
\n"; + $body .= "Totale:\n"; + + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_consuntivo, 2)." €\n"; + $body .= "
\n"; +} +$body .= "
\n"; + +// Conteggio articoli utilizzati +$query = "SELECT *, (SELECT orario_inizio FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento = mg_articoli_interventi.idintervento) AS data_intervento, (SELECT percentuale FROM co_iva WHERE id=mg_articoli_interventi.idiva_vendita) AS prciva_vendita, (SELECT codice FROM mg_articoli WHERE id=idarticolo) AS codice_art, GROUP_CONCAT( CONCAT_WS(lotto, 'Lotto: ', ', '), CONCAT_WS(serial, 'SN: ', ', '), CONCAT_WS(altro, 'Altro: ', '') SEPARATOR '
') AS codice, SUM(qta) AS sumqta FROM `mg_articoli_interventi` GROUP BY idarticolo, idintervento, lotto HAVING ".(!empty($idinterventi) ? 'idintervento IN('.implode(',', $idinterventi).') AND ' : '')." NOT idarticolo='0' ORDER BY idarticolo ASC"; +$rs2 = $dbo->fetchArray($query); + +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $totale_articoli = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['sumqta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_articoli += $netto * $qta; + } + + // Totale spesa articoli + $body .= "\n"; + + $body .= "\n"; + $body .= "
Materiale utilizzato per gli interventi
\n"; + $body .= "Articolo\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.nl2br($rs2[$i]['descrizione'])."\n"; + if ($rs2[$i]['codice'] != '' && $rs2[$i]['codice'] != 'Lotto: , SN: , Altro: ') { + $body .= '
'.$rs2[$i]['codice']."\n"; + } + + $body .= '
Intervento del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['sumqta']."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo_vendita']; + $netto = $netto + $netto / 100 * $rs2[$i]['prc_guadagno']; + $iva = $netto / 100 * $rs2[$i]['prciva_vendita']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= "".Translator::numberToLocale($netto * $qta, 2)."\n"; + $body .= "
\n"; + $body .= "TOTALE MATERIALE UTILIZZATO:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_articoli, 2)." €\n"; + $body .= "

\n"; +} + +// Conteggio spese aggiuntive +$query = 'SELECT *, (SELECT orario_inizio FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento = in_righe_interventi.idintervento) AS data_intervento FROM in_righe_interventi '.(!empty($idinterventi) ? 'WHERE idintervento IN('.implode(',', $idinterventi).')' : '').' ORDER BY id ASC'; +$rs2 = $dbo->fetchArray($query); + +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $totale_spese = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['qta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_spese += $netto * $qta; + } + // Totale spese aggiuntive + $body .= "\n"; + + $body .= "\n"; + $body .= "
Spese aggiuntive
\n"; + $body .= "Descrizione\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['descrizione']."
\n"; + $body .= 'Intervento del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.Translator::numberToLocale($rs2[$i]['qta'], 2)."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto * $qta, 2)." €\n"; + $body .= "
\n"; + $body .= "ALTRE SPESE:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_spese, 2)." €\n"; + $body .= "

\n"; +} + +// Totale complessivo intervento +$body .= "\n"; + +$body .= "\n"; + +// IMPONIBILE +$body .= "\n"; + +$body .= "\n"; + +// IVA +$q = "SELECT * FROM co_iva INNER JOIN zz_settings WHERE co_iva.id = zz_settings.valore AND zz_settings.nome = 'Iva predefinita' "; +$rs = $dbo->fetchArray($q); +$percentuale_iva = $rs[0]['percentuale']; + +$body .= "\n"; + +$body .= "\n"; + +// TOTALE (IMPONIBILE + IVA) +$body .= "\n"; + +$body .= "\n"; + +// BUDGET +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$diff = Translator::numberToLocale($budget - $totale, 2); +$body .= "\n"; + +$body .= "
\n"; +$body .= "IMPONIBILE:\n"; +$body .= "\n"; +$totale = Translator::numberToLocale($totale_intervento_consuntivo + $totale_articoli + $totale_spese, 2); +$body .= ''.Translator::numberToLocale($totale_intervento_consuntivo + $totale_articoli + $totale_spese, 2)." €\n"; +$body .= "
\n"; +$body .= 'IVA ('.number_format($percentuale_iva, 0)."%):\n"; +$body .= "\n"; +$body .= ''.Translator::numberToLocale(($totale_intervento_consuntivo + $totale_articoli + $totale_spese) / 100 * $percentuale_iva, 2)." €\n"; +$body .= "
\n"; +$body .= "TOTALE CONSUNTIVO:\n"; +$body .= "\n"; +$totale_ivato = Translator::numberToLocale(($totale_intervento_consuntivo + $totale_articoli + $totale_spese) + ($totale_intervento_consuntivo + $totale_articoli + $totale_spese) / 100 * $percentuale_iva, 2); +$body .= ''.$totale_ivato." €\n"; +$body .= "
\n"; +$body .= "BUDGET (NO IVA):\n"; +$body .= "\n"; +$body .= ''.$budget." €\n"; +$body .= "
\n"; +$body .= "RAPPORTO BUDGET/SPESA (NO IVA):\n"; +$body .= "\n"; +$body .= ''.$diff." €\n"; +$body .= "
\n"; + +$report_name = 'preventivo_'.$idpreventivo.'_cons.pdf'; diff --git a/templates/preventivi_cons/preventivo.html b/templates/preventivi_cons/preventivo.html new file mode 100644 index 000000000..e6af48f35 --- /dev/null +++ b/templates/preventivi_cons/preventivo.html @@ -0,0 +1,18 @@ + + + + $body$ + diff --git a/templates/preventivi_cons/preventivo_body.html b/templates/preventivi_cons/preventivo_body.html new file mode 100644 index 000000000..bd2c951db --- /dev/null +++ b/templates/preventivi_cons/preventivo_body.html @@ -0,0 +1,40 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ +
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/riepilogo_contratti/contratto.html b/templates/riepilogo_contratti/contratto.html new file mode 100644 index 000000000..8caf2af02 --- /dev/null +++ b/templates/riepilogo_contratti/contratto.html @@ -0,0 +1,17 @@ + + + + $body$ + diff --git a/templates/riepilogo_contratti/contratto_body.html b/templates/riepilogo_contratti/contratto_body.html new file mode 100644 index 000000000..cb87b0504 --- /dev/null +++ b/templates/riepilogo_contratti/contratto_body.html @@ -0,0 +1,37 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ +
+
+
+ + + + + + +
+ Stampato con OpenSTAManager +
+
diff --git a/templates/riepilogo_contratti/logo_azienda.jpg b/templates/riepilogo_contratti/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvfetchArray($query); + +// Se il cliente è uno solo carico la sua intestazione, altrimenti la lascio in bianco +$idcliente = $rsi[0]['idanagrafica']; +$singolo_cliente = true; +for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['idanagrafica'] != $idcliente) { + $singolo_cliente = false; + } +} + +if (!$singolo_cliente) { + $idcliente = ''; +} + +// carica report html +$report = file_get_contents($docroot.'/templates/riepilogo_contratti/contratto.html'); +$body = file_get_contents($docroot.'/templates/riepilogo_contratti/contratto_body.html'); + +if (!$singolo_cliente) { + $body = str_replace('Spett.le', '', $body); +} + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$body .= 'RIEPILOGO CONTRATTI DAL '.$search_datastart.' al '.$search_dataend."

\n"; + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rs[0]['${1}'], $body); + +// Tabella con riepilogo contratti +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; + +// Tabella con i dati +for ($i = 0; $i < sizeof($rs); ++$i) { + $data_accettazione = Translator::dateToLocale($rs[$i]['data_accettazione']); + $data_conclusione = Translator::dateToLocale($rs[$i]['data_conclusione']); + + if ($data_accettazione == '01/01/1970') { + $data_accettazione = ''; + } + + if ($data_conclusione == '01/01/1970') { + $data_conclusione = ''; + } + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $totale += $rs[$i]['budget_totale']; +} + +// Totale +$body .= "\n"; + +$body .= "\n"; + +$body .= "\n"; +$body .= "
\n"; +$body .= " Numero\n"; +$body .= "\n"; +$body .= " Ragione sociale\n"; +$body .= "\n"; +$body .= " Nome\n"; +$body .= "\n"; +$body .= " Stato\n"; +$body .= "\n"; +$body .= " Data inizio\n"; +$body .= "\n"; +$body .= " Data conclusione\n"; +$body .= "\n"; +$body .= " Budget\n"; +$body .= "
\n"; + $body .= ' '.$rs[$i]['numero']."\n"; + $body .= "\n"; + $body .= ' '.str_replace(' ', ' ', $rs[$i]['ragione_sociale'])."\n"; + $body .= "\n"; + $body .= ' '.str_replace(' ', ' ', $rs[$i]['nome'])."\n"; + $body .= "\n"; + $body .= ' '.str_replace(' ', ' ', $rs[$i]['stato'])."\n"; + $body .= "\n"; + $body .= ' '.$data_accettazione."\n"; + $body .= "\n"; + $body .= ' '.$data_conclusione."\n"; + $body .= "\n"; + $body .= ' '.str_replace(' ', ' ', Translator::numberToLocale($rs[$i]['budget_totale'], 2).' €')."\n"; + $body .= "
\n"; +$body .= " TOTALE:\n"; +$body .= "\n"; +$body .= ' '.str_replace(' ', ' ', Translator::numberToLocale($totale, 2).' €')."\n"; +$body .= "
\n"; + +$orientation = 'L'; +$report_name = 'Riepilogo_contratti.pdf'; diff --git a/templates/riepilogo_interventi/intervento.html b/templates/riepilogo_interventi/intervento.html new file mode 100644 index 000000000..388dc7ed5 --- /dev/null +++ b/templates/riepilogo_interventi/intervento.html @@ -0,0 +1,17 @@ + + + + $body$ + diff --git a/templates/riepilogo_interventi/intervento_body.html b/templates/riepilogo_interventi/intervento_body.html new file mode 100644 index 000000000..d0c367982 --- /dev/null +++ b/templates/riepilogo_interventi/intervento_body.html @@ -0,0 +1,40 @@ + + + + + + + + +
+ Logo
+ $f_ragionesociale$ + $f_indirizzo$ + $f_citta$ + $f_piva$ + $f_codicefiscale$ + $f_capsoc$ + $f_telefono$ + $f_sitoweb$ + $f_email$ +
+ Spett.le $c_ragionesociale$ + $c_indirizzo$ + $c_citta$ + $c_piva$ +
+
+
+ + + + + + + +
+ Stampato con OpenSTAManager + + Pagina [[page_cu]] di [[page_nb]] +
+
diff --git a/templates/riepilogo_interventi/logo_azienda.jpg b/templates/riepilogo_interventi/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvform('id_module'); + +$fields = []; +$select = '*'; +$datas = $dbo->fetchArray('SELECT * FROM zz_views WHERE id_module='.$id_module.' AND id IN (SELECT id_vista FROM zz_group_view WHERE id_gruppo=(SELECT idgruppo FROM zz_users WHERE idutente='.$_SESSION['idutente'].')) ORDER BY `order` ASC'); +if ($datas != null) { + $select = ''; + foreach ($datas as $data) { + $select .= $data['query']." AS '".$data['name']."',"; + if ($data['enabled']) { + array_push($fields, trim($data['name'])); + } + } + $select = substr($select, 0, strlen($select) - 1); +} + +$module = $dbo->fetchArray('SELECT * FROM zz_modules WHERE id="'.$id_module.'"')[0]; +$module_query = ($module['options2'] != '') ? $module['options2'] : $module['options']; + +$module_query = str_replace('|select|', $select, $module_query); +$module_query = str_replace('|period_start|', $_SESSION['period_start'], $module_query); +$module_query = str_replace('|period_end|', $_SESSION['period_end'], $module_query); +$module_dir = $module['directory']; + +$search_filters = []; + +if (is_array($_SESSION['module_'.$id_module])) { + foreach ($_SESSION['module_'.$id_module] as $field_name => $field_value) { + if ($field_value != '') { + $field_name = str_replace('search_', '', $field_name); + $field_name = str_replace('__', ' ', $field_name); + array_push($search_filters, '`'.$field_name.'` LIKE "%'.$field_value.'%"'); + } + } +} + +if (sizeof($search_filters) > 0) { + $module_query = str_replace('1=1', '1=1 AND ('.implode(' AND ', $search_filters).') ', $module_query); +} + +// Aggiungo eventuali filtri dei permessi +if ($additional_where[$rs[0]['name']] != '') { + $module_query = str_replace('1=1', '1=1 '.$additional_where[$rs[0]['name']], $module_query); +} + +$rsi = $dbo->fetchArray($module_query); + +// Se il cliente è uno solo carico la sua intestazione, altrimenti la lascio in bianco +$idcliente = $rsi[0]['idanagrafica']; +$singolo_cliente = true; +for ($i = 0; $i < sizeof($rsi) && $singolo_cliente; ++$i) { + if ($rsi[$i]['idanagrafica'] != $idcliente) { + $singolo_cliente = false; + } +} + +if (!$singolo_cliente) { + $idcliente = ''; +} + +// carica report html +$report = file_get_contents($docroot.'/templates/riepilogo_interventi/intervento.html'); +$body = file_get_contents($docroot.'/templates/riepilogo_interventi/intervento_body.html'); + +if (!$singolo_cliente) { + $body = str_replace('Spett.le', '', $body); +} + +include_once $docroot.'/templates/pdfgen_variables.php'; + +$totrows = sizeof($rsi); +$totale_km = 0.00; +$totale_ore = 0.00; +$totale = 0.00; +$totale_calcolato = 0.00; +$info_intervento = []; +$ore = []; +$km = []; +$ntecnici = []; +$tecnici = []; +$costi_orari = []; +$costi_km = []; +$diritto_chiamata = []; + +$costo_ore_cons = []; +$costo_km_cons = []; +$diritto_chiamata_cons = []; + +$idinterventi = ['0']; + +if ($totrows > 0) { + for ($i = 0; $i < $totrows; ++$i) { + // Lettura dati dei tecnici dell'intervento corrente + $query = 'SELECT *, ( ( TIME_TO_SEC(orario_fine)-TIME_TO_SEC(orario_inizio) ) ) AS t, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico FROM in_interventi_tecnici WHERE idintervento="'.$rsi[$i]['id'].'"'; + $rs = $dbo->fetchArray($query); + $n_tecnici = sizeof($rs); + + $riga_tecnici = "\n"; + $t = 0; + + for ($j = 0; $j < $n_tecnici; ++$j) { + $riga_tecnici .= "\n"; + $riga_tecnici .= "\n"; + + // Conteggio ore totali + $t += round($rs[$j]['t'] / 60 / 60, 2); + + array_push($costi_orari, floatval($rs[$j]['prezzo_ore_unitario'])); + array_push($costi_km, floatval($rs[$j]['prezzo_km_unitario'])); + array_push($diritto_chiamata, floatval($rs[$j]['prezzo_dirittochiamata'])); + + array_push($costo_ore_cons, floatval($rs[$j]['prezzo_ore_consuntivo'])); + array_push($costo_km_cons, floatval($rs[$j]['prezzo_km_consuntivo'])); + array_push($diritto_chiamata_cons, floatval($rs[$j]['prezzo_dirittochiamata_consuntivo'])); + array_push($km, floatval($rs[$j]['km'])); + $totale_km += floatval($rs[$j]['km']); + } + + $riga_tecnici .= "
\n".$rs[$j]['nome_tecnico']."\n\n".Translator::dateToLocale($rs[$j]['orario_inizio']).' - '.Translator::timeToLocale($rs[$j]['orario_inizio']).'-'.Translator::timeToLocale($rs[$j]['orario_fine'])."\n"; + $riga_tecnici .= "
\n"; + + $line = 'Intervento '.$rsi[$i]['id'].' del '.$rsi[$i]['Data inizio'].":
".nl2br($rsi[$i]['richiesta'])."

\n"; + + // Se l'elenco non è di un singolo cliente stampo anche la sua ragione sociale + if (!$singolo_cliente) { + $line .= '
Cliente: '.$rsi[$i]['Ragione sociale']."\n"; + } + + array_push($info_intervento, $line); + + array_push($ntecnici, $n_tecnici); + array_push($tecnici, $riga_tecnici); + array_push($ore, $t); + $totale_ore += floatval($t); + $totale_dirittochiamata += floatval($rs[$i]['prezzo_dirittochiamata']); + array_push($idinterventi, "'".$rsi[$i]['id']."'"); + } +} + +$body .= 'RIEPILOGO INTERVENTI DAL '.Translator::dateToLocale($_SESSION['period_start']).' al '.Translator::dateToLocale($_SESSION['period_end'])."

\n"; + +// Sostituisco i valori tra | | con il valore del campo del db +$body .= preg_replace('/|(.+?)|/', $rsi[0]['${1}'], $body); + +if (sizeof($info_intervento) > 0) { + // Tabella con riepilogo interventi, km e ore + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + // Tabella con i dati + for ($i = 0; $i < sizeof($info_intervento); ++$i) { + $subtotale_consuntivo = floatval($costo_ore_cons[$i] + $costo_km_cons[$i] + $diritto_chiamata_cons[$i]); + $totale_consuntivo += $subtotale_consuntivo; + + $subtotale_calcolato = $costi_orari[$i] * $ore[$i] + $costi_km[$i] * $km[$i] + $diritto_chiamata[$i]; + $totale_calcolato += $subtotale_calcolato; + + $body .= "\n"; + + // Totale km + $body .= '\n"; + + // Costo km + $body .= '\n"; + + // Totale ore + $body .= '\n"; + + // Costo ore + $body .= '\n"; + + // Diritto chiamata + $body .= '\n"; + + // Subtot + $body .= '\n"; + } + + $body .= "\n"; + + // Totale costo km + $body .= "\n"; + $body .= "\n"; + + // Totale costo ore + $body .= "\n"; + $body .= "\n"; + + // Totale diritto chiamata + $body .= "\n"; + + $body .= "\n"; + + // Riga dello sconto + $sconto = $totale_calcolato - $totale_consuntivo; + if ($sconto != 0) { + /* + $body .= "\n\n"; + */ + + $body .= "\n"; + } + + $totale_intervento_scontato = $totale_calcolato - $sconto; + $body .= "\n"; + $body .= "
\n"; + $body .= "Interventi\n"; + $body .= "\n"; + $body .= "km\n"; + $body .= "\n"; + $body .= "Costo unitario al km\n"; + $body .= "\n"; + $body .= "Ore\n"; + $body .= "\n"; + $body .= "Costo unitario all’ora\n"; + $body .= "\n"; + $body .= "Diritto chiamata\n"; + $body .= "\n"; + $body .= "Subtotale\n"; + $body .= "
\n"; + $body .= '
'.$info_intervento[$i].'
Tecnici:

'.$tecnici[$i]."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($km[$i], 2)."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($costi_km[$i], 2)."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($ore[$i], 2)."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($costi_orari[$i], 2)."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($diritto_chiamata[$i], 2)."
\n"; + $body .= "
'; + $body .= '
'.Translator::numberToLocale($subtotale_calcolato, 2)."
\n"; + $body .= "
\n"; + $body .= "Totale:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_km, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_ore, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_dirittochiamata, 2)."\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_calcolato, 2)." €\n"; + $body .= "
\n"; + $body .= "Arrotondamenti:\n"; + $body .= "\n"; + $body .= "".Translator::numberToLocale( -$sconto, 2)." €\n"; + $body .= "
\n"; + $body .= "Totale scontato:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_calcolato - $sconto, 2)." €\n"; + $body .= "

\n"; +} + +// Conteggio articoli utilizzati +$query = "SELECT *, (SELECT percentuale FROM co_iva WHERE id=(SELECT idiva_vendita FROM mg_articoli WHERE id=idarticolo)) AS prciva_vendita, (SELECT orario_inizio FROM in_interventi_tecnici WHERE idintervento=mg_articoli_interventi.idintervento GROUP BY idintervento HAVING idintervento=mg_articoli_interventi.idintervento) AS data_intervento, (SELECT prc_guadagno FROM mg_listini WHERE id=(SELECT idlistino FROM an_anagrafiche WHERE idanagrafica=(SELECT idanagrafica FROM in_interventi WHERE id=mg_articoli_interventi.idintervento) ) ) AS prc_guadagno, (SELECT codice FROM mg_articoli WHERE id=idarticolo) AS codice_art, GROUP_CONCAT( CONCAT_WS(lotto, 'Lotto: ', ', '), CONCAT_WS(serial, 'SN: ', ', '), CONCAT_WS(altro, 'Altro: ', '') SEPARATOR '
') AS codice, SUM(qta) AS sumqta FROM `mg_articoli_interventi` GROUP BY idarticolo, idintervento, lotto HAVING idintervento IN(".implode(',', $idinterventi).") AND NOT idarticolo='0' ORDER BY idarticolo ASC"; +$rs2 = $dbo->fetchArray($query); +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $totale_articoli = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['sumqta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_articoli += $netto * $qta; + } + + // Totale spesa articoli + $body .= "\n"; + + $body .= "\n"; + $body .= "
Materiale utilizzato per gli interventi
\n"; + $body .= "Articolo\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.nl2br($rs2[$i]['descrizione'])."\n"; + if ($rs2[$i]['codice'] != '' && $rs2[$i]['codice'] != 'Lotto: , SN: , Altro: ') { + $body .= '
'.$rs2[$i]['codice']."\n"; + } + + $body .= '
Intervento '.$rs2[$i]['idintervento'].' del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['sumqta']."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo_vendita']; + $netto = $netto + $netto / 100 * $rs2[$i]['prc_guadagno']; + $iva = $netto / 100 * $rs2[$i]['prciva_vendita']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto * $qta, 2)."\n"; + $body .= "
\n"; + $body .= "TOTALE MATERIALE UTILIZZATO:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_articoli, 2)." €\n"; + $body .= "

\n"; +} + +// Conteggio spese aggiuntive +$query = 'SELECT *, (SELECT orario_inizio FROM in_interventi_tecnici WHERE idintervento=in_righe_interventi.idintervento GROUP BY idintervento HAVING idintervento=in_righe_interventi.idintervento ORDER BY orario_inizio) AS data_intervento FROM in_righe_interventi WHERE idintervento IN('.implode(',', $idinterventi).') ORDER BY id ASC'; +$rs2 = $dbo->fetchArray($query); + +if (sizeof($rs2) > 0) { + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + + $body .= "\n"; + $body .= "\n"; + + $totale_spese = 0.00; + + for ($i = 0; $i < sizeof($rs2); ++$i) { + // Articolo + $body .= "\n"; + + // Quantità + $qta = $rs2[$i]['qta']; + $body .= "\n"; + + // Prezzo unitario + $body .= "\n"; + + // Prezzo di vendita + $body .= "\n"; + $totale_spese += $netto * $qta; + } + + // Totale spese aggiuntive + $body .= "\n"; + + $body .= "\n"; + $body .= "
Spese aggiuntive
\n"; + $body .= "Descrizione\n"; + $body .= "\n"; + $body .= "Q.tà\n"; + $body .= "\n"; + $body .= "Prezzo unitario\n"; + $body .= "\n"; + $body .= "Subtot\n"; + $body .= "
\n"; + $body .= ''.$rs2[$i]['descrizione']."
\n"; + $body .= 'Intervento '.$rs2[$i]['idintervento'].' del '.Translator::dateToLocale($rs2[$i]['data_intervento'])."\n"; + $body .= "
\n"; + $body .= ''.Translator::numberToLocale($rs2[$i]['qta'], 2)."\n"; + $body .= "\n"; + $netto = $rs2[$i]['prezzo']; + $body .= ''.Translator::numberToLocale($netto, 2)." €\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($netto * $qta, 2)." €\n"; + $body .= "
\n"; + $body .= "ALTRE SPESE:\n"; + $body .= "\n"; + $body .= ''.Translator::numberToLocale($totale_spese, 2)." €\n"; + $body .= "

\n"; +} + +// Totale complessivo intervento +$body .= "

\n"; +$body .= 'TOTALE INTERVENTI: '.Translator::numberToLocale($totale_intervento_scontato + $totale_articoli + $totale_spese, 2)." €\n"; +$body .= "

\n"; + +$report_name = 'Riepilogo_interventi.pdf'; diff --git a/templates/scadenzario/logo_azienda.jpg b/templates/scadenzario/logo_azienda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fd3914522510a5f6af55ca002d656131577943f GIT binary patch literal 4348 zcmcIG2UJtpwl@VrCxoJO0wL0+iU>%N7AX=0X-XSViqaGWl->m-1e5`!S7|~75d=X3 zN^z7RHAo$0C`u6!6#_qDW_+&y)_d>IU-Qnn>)hSXzWeNb_t_uYp8?>f4KM}(2m}J0 zs1w+q08Rn)P&#@#C_OzLJq$+AzyxPvVq|3EVq<54AL2TE_z)Kl51*j8Fdx5|01uCd zjEETeh@_MxuduAVtc1L{gro$`2nYs)F)=W4GBI&V@bU0T{N=IV32-m~J|H;=hyws~ zfFK;8{VsqX009uHw;YHsSymH+?*e`4T3wM!=3P%0DwPvc>F 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 pzkP8z7RFBvform('type') == 'clienti') { + $titolo = 'Scadenzario clienti'; + $add_where = "AND an_tipianagrafiche.descrizione='Cliente'"; +} elseif ($html->form('type') == 'fornitori') { + $titolo = 'Scadenzario fornitori'; + $add_where = "AND an_tipianagrafiche.descrizione='Fornitore'"; +} else { + $titolo = 'Scadenzario'; + $add_where = ''; +} + +$body .= '

'.$titolo.' dal '.Translator::dateToLocale($_SESSION['period_start']).' al '.Translator::dateToLocale($_SESSION['period_end'])."

\n"; +$body .= "\n"; +$body .= "\n"; + +$body .= "\n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; +$body .= "\n"; + +$body .= "\n"; + +$rs = $dbo->fetchArray("SELECT co_scadenziario.id AS id, ragione_sociale AS `Anagrafica`, co_pagamenti.descrizione AS `Tipo di pagamento`, CONCAT( co_tipidocumento.descrizione, CONCAT( ' numero ', IF(numero_esterno<>'', numero_esterno, numero) ) ) AS `Documento`, DATE_FORMAT(data_emissione, '%d/%m/%Y') AS `Data emissione`, DATE_FORMAT(scadenza, '%d/%m/%Y') AS `Data scadenza`, da_pagare AS `Importo`, pagato AS `Pagato`, IF(scadenza= '".$_SESSION['period_start']."' AND scadenza <= '".$_SESSION['period_end']."' ORDER BY scadenza ASC"); + +for ($i = 0; $i < sizeof($rs); ++$i) { + $body .= ' '; + $body .= ' \n"; + $body .= ' \n"; + $body .= ' \n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + $body .= " \n"; + + $totale_da_pagare += $rs[$i]['Importo']; + $totale_pagato += $rs[$i]['Pagato']; +} + +$body .= " \n"; +$body .= " \n"; +$body .= " \n"; + +$body .= "\n"; +$body .= "
DocumentoAnagraficaTipo di pagamentoData scadenzaImportoGià pagato
'.$rs[$i]['Documento'].'
'.$rs[$i]['Data emissione']."
'.$rs[$i]['Anagrafica']."'.$rs[$i]['Tipo di pagamento']."".$rs[$i]['Data scadenza']."".Translator::numberToLocale($rs[$i]['Importo'], 2)."".Translator::numberToLocale($rs[$i]['Pagato'], 2)."
TOTALE:".Translator::numberToLocale($totale_da_pagare, 2)."".Translator::numberToLocale($totale_pagato, 2)."
\n"; + +$orientation = 'L'; +$report_name = 'Scadenzario_Totale.pdf'; diff --git a/templates/scadenzario/scadenzario.html b/templates/scadenzario/scadenzario.html new file mode 100644 index 000000000..0f1c46135 --- /dev/null +++ b/templates/scadenzario/scadenzario.html @@ -0,0 +1,12 @@ + + + + $body$ + diff --git a/templates/scadenzario/scadenzario_body.html b/templates/scadenzario/scadenzario_body.html new file mode 100644 index 000000000..bac476409 --- /dev/null +++ b/templates/scadenzario/scadenzario_body.html @@ -0,0 +1,13 @@ + + + + + + + + + +
+ Stampato con OpenSTAManager +
+
diff --git a/update/.htaccess b/update/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/update/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/update/2_1.php b/update/2_1.php new file mode 100644 index 000000000..5d331af37 --- /dev/null +++ b/update/2_1.php @@ -0,0 +1,25 @@ +fetchArray('SELECT id FROM co_documenti'); + +for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rivalsainps != '') { + $dbo->query('UPDATE co_righe_documenti SET idrivalsainps="'.get_var('Percentuale rivalsa INPS').'", rivalsainps=( (subtotale-sconto) /100 * 4 ) WHERE iddocumento="'.$rs[$i]['id'].'"'); + } else { + $dbo->query('UPDATE co_righe_documenti SET idrivalsainps="0", rivalsainps=0 WHERE iddocumento="'.$rs[$i]['id'].'"'); + } + + if ($ritenuta != '') { + $dbo->query('UPDATE co_righe_documenti SET idritenutaacconto="'.get_var("Percentuale ritenuta d'acconto").'", ritenutaacconto=( (subtotale+rivalsainps-sconto) /100 * 20 ) WHERE iddocumento="'.$rs[$i]['id'].'"'); + } else { + $dbo->query('UPDATE co_righe_documenti SET idritenutaacconto="0", ritenutaacconto=0 WHERE iddocumento="'.$rs[$i]['id'].'"'); + } +} diff --git a/update/2_2.php b/update/2_2.php new file mode 100644 index 000000000..e87f15f41 --- /dev/null +++ b/update/2_2.php @@ -0,0 +1,113 @@ +fetchArray('SELECT idanagrafica, ragione_sociale, (SELECT GROUP_CONCAT(an_tipianagrafiche.descrizione) FROM an_tipianagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche.idtipoanagrafica=an_tipianagrafiche_anagrafiche.idtipoanagrafica WHERE idanagrafica=an_anagrafiche.idanagrafica) AS idtipianagrafica FROM an_anagrafiche WHERE idconto_cliente=0 OR idconto_fornitore=0'); + +for ($i = 0; $i < sizeof($rs); ++$i) { + if (in_array('Cliente', explode(',', $rs[$i]['idtipianagrafica']))) { + //Calcolo il codice conto più alto + $rs2 = $dbo->fetchArray("SELECT MAX( CAST(numero AS UNSIGNED) ) AS max_numero, idpianodeiconti2 FROM co_pianodeiconti3 WHERE numero=CAST(numero AS UNSIGNED) AND idpianodeiconti2=(SELECT id FROM co_pianodeiconti2 WHERE descrizione='Crediti clienti e crediti diversi')"); + $numero = str_pad($rs2[0]['max_numero'] + 1, 6, '0', STR_PAD_LEFT); + $idpianodeiconti2 = $rs2[0]['idpianodeiconti2']; + + //Creo il nuovo conto + $dbo->query('INSERT INTO co_pianodeiconti3( numero, descrizione, idpianodeiconti2, can_delete, can_edit ) VALUES( "'.$numero.'", "'.$rs[$i]['ragione_sociale'].'", "'.$idpianodeiconti2.'", 1, 1 )'); + $idconto = $dbo->lastInsertedID(); + + //Collego questo conto al cliente + $dbo->query('UPDATE an_anagrafiche SET idconto_cliente="'.$idconto.'" WHERE idanagrafica="'.$rs[$i]['idanagrafica'].'"'); + } + + if (in_array('Fornitore', explode(',', $rs[$i]['idtipianagrafica']))) { + //Calcolo il codice conto più alto + $rs2 = $dbo->fetchArray("SELECT MAX( CAST(numero AS UNSIGNED) ) AS max_numero, idpianodeiconti2 FROM co_pianodeiconti3 WHERE numero=CAST(numero AS UNSIGNED) AND idpianodeiconti2=(SELECT id FROM co_pianodeiconti2 WHERE descrizione='Debiti fornitori e debiti diversi')"); + $numero = str_pad($rs2[0]['max_numero'] + 1, 6, '0', STR_PAD_LEFT); + $idpianodeiconti2 = $rs2[0]['idpianodeiconti2']; + + //Creo il nuovo conto + $dbo->query('INSERT INTO co_pianodeiconti3( numero, descrizione, idpianodeiconti2, can_delete, can_edit ) VALUES( "'.$numero.'", "'.$rs[$i]['ragione_sociale'].'", "'.$idpianodeiconti2.'", 1, 1 )'); + $idconto = $dbo->lastInsertedID(); + + //Collego questo conto al cliente + $dbo->query('UPDATE an_anagrafiche SET idconto_fornitore="'.$idconto.'" WHERE idanagrafica="'.$rs[$i]['idanagrafica'].'"'); + } +} + +//Sposto tutti i movimenti delle fatture dal riepilogativo (clienti o fornitori) al relativo conto di ogni anagrafica +$rs = $dbo->fetchArray('SELECT co_movimenti.id, co_documenti.idanagrafica, dir FROM (co_movimenti INNER JOIN co_documenti ON co_movimenti.iddocumento=co_documenti.id) INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento WHERE NOT iddocumento=0'); + +for ($i = 0; $i < sizeof($rs); ++$i) { + if ($rs[$i]['dir'] == 'entrata') { + $query = 'UPDATE co_movimenti SET idconto=(SELECT idconto_cliente FROM an_anagrafiche WHERE idanagrafica="'.$rs[$i]['idanagrafica'].'") WHERE id="'.$rs[$i]['id']."\" AND idconto=(SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo clienti')"; + } else { + $query = 'UPDATE co_movimenti SET idconto=(SELECT idconto_fornitore FROM an_anagrafiche WHERE idanagrafica="'.$rs[$i]['idanagrafica'].'") WHERE id="'.$rs[$i]['id']."\" AND idconto=(SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo fornitori')"; + } + + $dbo->query($query); +} + +//Aggiungo il flag "Attiva aggiornamenti" se manca (nella migrazione della 2.0 non c'è) +$rs = $dbo->fetchArray("SELECT idimpostazione FROM zz_impostazioni WHERE nome='Attiva aggiornamenti'"); + +if (sizeof($rs) == 0) { + $dbo->query("INSERT INTO `zz_impostazioni` (`nome`, `valore`, `tipo`, `editable`, `sezione`) VALUES ( 'Attiva aggiornamenti', '1', 'boolean', '0', 'Generali')"); +} + +//Spostamento ore di lavoro e diritto di chiamata dei preventivi nella tabella +$idiva = get_var('Iva predefinita'); + +$rs = $dbo->fetchArray('SELECT percentuale, indetraibile FROM co_iva WHERE id="'.$idiva.'"'); +$percentuale = $rs[0]['percentuale']; +$indetraibile = $rs[0]['indetraibile']; + +$rs = $dbo->fetchArray('SELECT * FROM co_preventivi WHERE ore_lavoro > 0 OR costo_diritto_chiamata > 0'); + +for ($i = 0; $i < sizeof($rs); ++$i) { + //Ore lavoro + if ($rs[$i]['ore_lavoro'] > 0) { + $imponibile = $rs[$i]['costo_orario'] * $rs[$i]['ore_lavoro']; + + $iva = $imponibile / 100 * $percentuale; + $iva_indetraibile = $imponibile / 100 * $indetraibile; + + $dbo->query('INSERT INTO co_righe_preventivi( idpreventivo, idiva, iva, iva_indetraibile, descrizione, subtotale, sconto, um, qta ) VALUES( "'.$rs[$i]['id'].'", "'.$idiva.'", "'.$iva.'", "'.$iva_indetraibile.'", "Ore lavoro", "'.$imponibile.'", "0.00", "ore", "'.$rs[$i]['ore_lavoro'].'" )'); + } + + //Ore diritto chiamata + if ($rs[$i]['costo_diritto_chiamata'] > 0) { + $imponibile = $rs[$i]['costo_diritto_chiamata']; + + $iva = $imponibile / 100 * $percentuale; + $iva_indetraibile = $imponibile / 100 * $indetraibile; + + $dbo->query('INSERT INTO co_righe_preventivi( idpreventivo, idiva, iva, iva_indetraibile, descrizione, subtotale, sconto, um, qta ) VALUES( "'.$rs[$i]['id'].'", "'.$idiva.'", "'.$iva.'", "'.$iva_indetraibile.'", "Diritto chiamata", "'.$imponibile.'", "0.00", "", "'.$rs[$i]['costo_diritto_chiamata'].'" )'); + } +} + +//Eliminazione vecchi file +@unlink($docroot.'/share/themes/default/css/font-awesome.css'); +@deltree($docroot.'/modules/preventivi/js/'); + +/* + Spostamento agente di riferimento su nuova tabella an_anagrafiche_agenti +*/ +$rs = $dbo->fetchArray('SELECT idanagrafica, idagente FROM an_anagrafiche WHERE NOT idagente=0'); + +for ($i = 0; $i < sizeof($rs); ++$i) { + $dbo->query('INSERT INTO an_anagrafiche_agenti( idanagrafica, idagente ) VALUES( "'.$rs[$i]['idanagrafica'].'", "'.$rs[$i]['idagente'].'" )'); +} + +/** + * 2016-11-09 (r1509) + * Creo le associazioni fra i tipi di intervento e i contratti. + */ +$rsc = $dbo->fetchArray('SELECT id FROM co_contratti'); + +for ($c = 0; $c < sizeof($rsc); ++$c) { + $rsi = $dbo->fetchArray('SELECT * FROM in_tipiintervento WHERE (costo_orario!=0 OR costo_km!=0 OR costo_diritto_chiamata!=0)'); + + for ($i = 0; $i < sizeof($rsi); ++$i) { + $dbo->query('INSERT INTO co_contratti_tipiintervento( idcontratto, idtipointervento, costo_ore, costo_km, costo_dirittochiamata, costo_ore_tecnico, costo_km_tecnico, costo_dirittochiamata_tecnico ) VALUES( "'.$rsc[$c]['id'].'", "'.$rsi[$i]['idtipointervento'].'", "'.$rsi[$i]['costo_orario'].'", "'.$rsi[$i]['costo_km'].'", "'.$rsi[$i]['costo_diritto_chiamata'].'", "'.$rsi[$i]['costo_orario_tecnico'].'", "'.$rsi[$i]['costo_km_tecnico'].'", "'.$rsi[$i]['costo_diritto_chiamata_tecnico'].'" )'); + } +} diff --git a/update/2_3.php b/update/2_3.php new file mode 100644 index 000000000..92bc2dd4c --- /dev/null +++ b/update/2_3.php @@ -0,0 +1,223 @@ += 0; +foreach ($tables as $table) { + if ($latest_ver) { + $database->query('ALTER TABLE `'.$table.'` ADD (`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); + } else { + $database->query('ALTER TABLE `'.$table."` ADD (`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)"); + $database->query('CREATE TRIGGER '.$table.'_creation BEFORE INSERT ON '.$table.' FOR EACH ROW SET NEW.created_at = CURRENT_TIMESTAMP'); + } +} + +/* +* Inserimento valori di default +*/ + +// Permessi di default delle viste +$gruppi = $database->fetchArray('SELECT `id` FROM `zz_groups`'); +$results = $database->fetchArray('SELECT `id` FROM `zz_views` WHERE `id` NOT IN (SELECT `id_vista` FROM `zz_group_view`)'); + +$array = []; +foreach ($results as $result) { + foreach ($gruppi as $gruppo) { + $array[] = [ + 'id_gruppo' => $gruppo['id'], + 'id_vista' => $result['id'], + ]; + } +} +if (!empty($array)) { + $database->insert('zz_group_view', $array); +} + +// Generazione delle chiavi di default per gli utenti +$utenti = $database->fetchArray('SELECT `idutente` FROM `zz_users`'); + +$array = []; +foreach ($utenti as $utente) { + $array[] = [ + 'id_utente' => $utente['idutente'], + 'token' => secure_random_string(), + ]; +} +if (!empty($array)) { + $database->insert('zz_tokens', $array); +} + +/* +* Fix +*/ + +// Fix per i contenuti ini inseriti all'interno del database +$database->query("UPDATE mg_articoli SET contenuto = REPLACE(REPLACE(REPLACE(contenuto, '"', '\"'), '\n', ".prepare(PHP_EOL)."), '`', '\"')"); +$database->query("UPDATE my_impianto_componenti SET contenuto = REPLACE(REPLACE(REPLACE(contenuto, '"', '\"'), '\n', ".prepare(PHP_EOL)."), '`', '\"')"); + +// Fix dei timestamp delle tabelle zz_logs e zz_files +$database->query('UPDATE `zz_logs` SET `created_at` = `timestamp`, `updated_at` = `timestamp`'); +$database->query('ALTER TABLE `zz_logs` DROP `timestamp`'); + +$database->query('UPDATE `zz_files` SET `created_at` = `data`, `updated_at` = `data`'); +$database->query('ALTER TABLE `zz_files` DROP `data`'); + +/* +* Rimozione file e cartelle deprecati +*/ + +// Cartelle deprecate +$dirs = [ + 'lib/jscripts', + 'lib/html2pdf', + 'widgets', + 'share', +]; + +foreach ($dirs as $dir) { + $dir = realpath($docroot.'/'.$dir); + if (is_dir($dir)) { + deltree($dir); + } +} + +// File deprecati +$files = [ + 'lib/class.phpmailer.php', + 'lib/class.pop3.php', + 'lib/class.smtp.php', + 'lib/PHPMailerAutoload.php', + 'lib/dbo.class.php', + 'lib/html-helpers.class.php', + 'lib/photo.class.php', + 'lib/widgets.class.php', + 'templates/pdfgen.php', + 'update/install_2.0.sql', + 'update/update_2.1.sql', + 'update/update_2.1.php', + 'update/update_2.2.sql', + 'update/update_2.2.php', + 'update/update_checker.php', + 'permissions.php', + 'settings.php', + 'addgroup.php', + 'adduser.php', + 'change_pwd.php', + 'README', +]; + +foreach ($files as $file) { + $file = realpath($docroot.'/'.$file); + if (file_exists($file)) { + unlink($file); + } +} + +// File .html dei moduli di default +// Per un problema sulla lunghezza massima del path su glob è necessario dividere le cartelle dei moduli di default da pulire +$dirs = [ + 'aggiornamenti,anagrafiche,articoli,automezzi,backup', + 'beni,categorie,causali,contratti,dashboard', + 'ddt,fatture,gestione_componenti,interventi,iva', + 'listini,misure,my_impianti,opzioni,ordini,pagamenti', + 'partitario,porti,preventivi,primanota,scadenzario', + 'stati_intervento,tecnici_tariffe,tipi_anagrafiche,tipi_intervento', + 'utenti,viste,voci_servizio,zone', +]; + +foreach ($dirs as $dir) { + $files = glob($docroot.'/modules/{'.$dir.'}/*.html', GLOB_BRACE); + foreach ($files as $file) { + unlink($file); + } +}