feat: 🏗️ Introduzione Laravel 8

This commit is contained in:
Maicol Battistini 2021-07-30 18:38:43 +02:00
parent 82cfeaee32
commit e95a36991d
No known key found for this signature in database
GPG Key ID: 4FDB0F87CDB1D34A
1095 changed files with 2217 additions and 175431 deletions

View File

@ -1,11 +1,18 @@
# 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
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

51
.env.example Normal file
View File

@ -0,0 +1,51 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

191
.gitattributes vendored
View File

@ -1,191 +0,0 @@
## GITATTRIBUTES FOR WEB PROJECTS
#
# These settings are for any web project.
#
# Details per file setting:
# text These files should be normalized (i.e. convert CRLF to LF).
# binary These files are binary and should be left untouched.
#
# Note that binary is a macro for -text -diff.
######################################################################
## AUTO-DETECT
## Handle line endings automatically for files detected as
## text and leave all files detected as binary untouched.
## This will handle all files NOT defined below.
* text=auto
## SOURCE CODE
*.bat text eol=crlf
*.coffee text
*.css text
*.htm text
*.html text
*.inc text
*.ini text
*.js text
*.json text
*.jsx text
*.less text
*.od text
*.onlydata text
*.php text
*.pl text
*.py text
*.rb text
*.sass text
*.scm text
*.scss text
*.sh text eol=lf
*.sql text
*.styl text
*.tag text
*.ts text
*.tsx text
*.xml text
*.xhtml text
## DOCKER
*.dockerignore text
Dockerfile text
## DOCUMENTATION
*.markdown text
*.md text
*.mdwn text
*.mdown text
*.mkd text
*.mkdn text
*.mdtxt text
*.mdtext text
*.txt text
AUTHORS text
CHANGELOG text
CHANGES text
CONTRIBUTING text
COPYING text
copyright text
*COPYRIGHT* text
INSTALL text
license text
LICENSE text
NEWS text
readme text
*README* text
TODO text
## TEMPLATES
*.dot text
*.ejs text
*.haml text
*.handlebars text
*.hbs text
*.hbt text
*.jade text
*.latte text
*.mustache text
*.njk text
*.phtml text
*.tmpl text
*.tpl text
*.twig text
## LINTERS
.csslintrc text
.eslintrc text
.htmlhintrc text
.jscsrc text
.jshintrc text
.jshintignore text
.stylelintrc text
## CONFIGS
*.bowerrc text
*.cnf text
*.conf text
*.config text
.browserslistrc text
.editorconfig text
.gitattributes text
.gitconfig text
.htaccess text
*.npmignore text
*.yaml text
*.yml text
browserslist text
Makefile text
makefile text
## HEROKU
Procfile text
.slugignore text
## GRAPHICS
*.ai binary
*.bmp binary
*.eps binary
*.gif binary
*.ico binary
*.jng binary
*.jp2 binary
*.jpg binary
*.jpeg binary
*.jpx binary
*.jxr binary
*.pdf binary
*.png binary
*.psb binary
*.psd binary
*.svg text
*.svgz binary
*.tif binary
*.tiff binary
*.wbmp binary
*.webp binary
## AUDIO
*.kar binary
*.m4a binary
*.mid binary
*.midi binary
*.mp3 binary
*.ogg binary
*.ra binary
## VIDEO
*.3gpp binary
*.3gp binary
*.as binary
*.asf binary
*.asx binary
*.fla binary
*.flv binary
*.m4v binary
*.mng binary
*.mov binary
*.mp4 binary
*.mpeg binary
*.mpg binary
*.ogv binary
*.swc binary
*.swf binary
*.webm binary
## ARCHIVES
*.7z binary
*.gz binary
*.jar binary
*.rar binary
*.tar binary
*.zip binary
## FONTS
*.ttf binary
*.eot binary
*.otf binary
*.woff binary
*.woff2 binary
## EXECUTABLES
*.exe binary
*.pyc binary

View File

@ -1,96 +0,0 @@
---
currentMenu: contribuire
---
# Contribuire
Sei interessato a contribuire allo sviluppo di OpenSTAManger? Ottimo, sei il benvenuto!
Siamo entusiasti di ogni nuova contribuzione che otteniamo dalla nostra community.
Ci sono molti modi per contribuire: segnalare bug, richiedere miglioramenti, scrivere tutorial, migliorare la documentazione, ...
Non serve essere degli esperti programmatori per aiutarci! :smile_cat:
Leggi le seguenti sezioni per scoprire come ti consigliamo di procedere.
Se ti serve un aiuto, crea una issue su GitHub.
## Linee guida
Per migliorare il sistema con cui sviluppiamo il codice, abbiamo deciso di adottare alcune linee guida per facilitare la collaborazione tra più persone.
### Standard del codice
Per lo standard ufficiale riguardante i nomi e le strutture da utilizzare, visita la sezione [Standard](STANDARD.md).
### Codice di condotta
Per il momento non abbiamo adottato un vero e proprio codice di condotta, ma ti chiediamo di essere il più civile possibile nel comunicare con gli altri per questo progetto.
### Stile del codice
Utilizziamo principalmente due strumenti per mantenere consistente nel tempo lo stile del codice:
- [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer)
- [EditorConfig](https://editorconfig.org)
PHP CS Fixer viene utilizzato per formattare automaticamente il codice PHP e aumentare la sua comprensibilità.
La configurazione può essere trovata nel file [.php_cs](https://github.com/devcode-it/openstamanager/blob/master/.php_cs).
EditorConfig viene sfruttato per mantenere la consistenza nella formattazione di base dei diversi altri file utilizzati nel progetto.
La configurazione può essere trovata nel file [.editorconfig](https://github.com/devcode-it/openstamanager/blob/master/.editorconfig).
Maggiori informazioni sui plugin che permettono di integrare questi strumenti sono disponibili nei relativi siti.
## Prima contribuzione
Sei insicuro su cosa potresti lavorare per contribuire al progetto?
Prova a dare un'occhiata alle issue sotto la label [nuovi contributori](https://github.com/devcode-it/openstamanager/labels/nuovi%20contributori), dove sono indicate le migliorie più semplici da applicare.
## Problemi di sicurezza
Se trovi un problema di sicurezza, NON aprire una issue. Inviaci un'email all'indirizzo `info at openstamanager dot com`.
Per capire se hai individuato un problema di sicurezza, prova a farti queste domande:
* Posso accedere a qualcosa a cui non dovrei avere accesso?
* Posso disabilitare qualcosa per altre persone?
Se la risposta a una di queste domande è positiva, allora probabilmente hai individuato un problema di sicurezza.
Considera però che anche in caso negativo potrebbe trattarsi di un problema di questo tipo, quindi se sei insicuro contattaci comunque via email.
## Segnalare un bug
Se hai individuato un bug e desideri segnalarlo, apri una nuova issue provando a mantenerti sulla base del [file di template su GitHub](https://github.com/devcode-it/openstamanager/blob/master/.github/ISSUE_TEMPLATE.md).
Se vuoi suggerire una miglioramento di qualche tipo oppure una nuova funzionalità, sentiti libero di aprire una issue apposita dove spieghi dettagliatamente la modifica che vorresti, la sua utilità e il suo funzionamento generale
## Pull Request
Se sei in grado di risolvere uno dei bug segnalati oppure vuoi completare una nuova funzionalità, apri una nuova Pull Request provando a mantenerti sulla base del [file di template su GitHub](https://github.com/devcode-it/openstamanager/blob/master/.github/PULL_REQUEST_TEMPLATE.md).
## Community
Siamo presenti su [Facebook](https://www.facebook.com/openstamanager), e il nostro forum ufficiale è disponibile all'indirizzo <http://www.openstamanager.com/forum/>.
Cerchiamo di essere disponibili quanto possibile, ma non sempre riusciamo a rispondere tempestivamente.
## Testing
Il progetto presenta, a partire dalla versione 2.4.2, un insieme di test per facilitare il controllo sul corretto funzionamento del gestionale.
E' innanzitutto necessario configurare correttamente l'ambiente locale per l'esecuzione dei test:
- Impostare l'URL del web server locale nel file `codeception.yml` per Codeception
```yml
modules:
config:
WebDriver:
url: http://localhost/openstamanager
```
- Scaricare (ChromeDriver)[https://sites.google.com/a/chromium.org/chromedriver/getting-started], rendendolo eseguibile da riga di comando (su Windows, aggiungerlo al PATH)
E' quindi possibile eseguire i tests avviando dapprima il server ChromeDriver e poi Codeception in shell differenti:
```bash
chromedriver --url-base=/wd/hub
php codecept.phar run --steps
```

View File

@ -1,38 +0,0 @@
## Comportamento richiesto
Descrivi il comportamento che ti aspetti dal progetto.
## Comportamento attuale
Qual è il comportamento attuale, e come ti aspetti che venga migliorato?
## Possibile soluzione
[Non obbligatorio] Hai suggerimenti su come risolvere il bug o individuarne le cause?
## Passi per riprodurre il comportamento
[Per i bug] Descrivi dettagliatamente i singoli passi per riprodurre il malfunzionamento.
1.
2.
3.
Eventuale codice rilevante:
```php
Se serve, aggiungi qui il codice che vuoi farci testare
```
Eventuali log relativi (cartella **logs/**):
```
Se presenti, aggiungi qui i log relativi al malfunzionamento
```
## Contesto
Inserisci le informazioni riguardanti il tuo ambiente di esecuzione. Può essere utile per individuare problemi riproducibili solo con condizioni specifiche.
* Modulo:
* Versione del progetto:
* Versione PHP:
* Tipo di server:

View File

@ -1,22 +0,0 @@
## Descrizione
Includi un sommario dei cambiamenti introdotti, con il relativo contesto.
Elenca anche le eventuali dipendenze aggiuntive richieste per questa modifica.
Risolve: #(issue)
## Tipologia
Rimuovi le opzioni non rilevanti.
- [ ] Bug fix (cambiamenti minori che risolvono una issue)
- [ ] Nuova funzionalità (cambiamenti minori che aggiungono una nuova funzionalità)
- [ ] Cambiamento maggiore (fix o funzionalità che richiede una revisione prima di essere pubblicata)
- [ ] Questo cambiamenti richiede un aggiornamento della documentazione
# Checklist
- [ ] Il codice segue le linee guida del progetto
- [ ] Ho commentato il codice, in particolare nelle parti più complesse
- [ ] Ho aggiornato di conseguenza la documentazione (se presente)
- [ ] Il codice non genera warnings

28
.github/STANDARD.md vendored
View File

@ -1,28 +0,0 @@
# Standard del codice
Lo standard prevede l'utilizzo di nomi in italiano per la maggior parte dei contenuti, esclusi i sistemi di gestione interna del gestionale (tabelle `zz_*` e codici particolarmente rilevanti).
I nomi delle variabili devono seguire uno standard comune, che prevede la sostituzione degli spazi con `_` (*underscore*) e la rimozione delle lettere accentate a favore di quelle semplici.
Le variabili devono possedere nomi completi e chiari.
Esempio:
- Partita IVA -> `partita_iva` nel database, `$partita_iva` in PHP
## Database
Gli identificatori devono iniziare per `id_*` e i flag per `is_*`.
E' fondamentale ricordarsi di impostare correttamente le **FOREIGN KEYS** delle relative tabelle.
Ci sono inoltre alcuni campi utilizzati in modo riccorrente all'interno del gestionale:
- `default boolean NOT NULL DEFAULT 0` per i valori di default, non cancellabili e con modificabilità limitata
- `predefined boolean NOT NULL DEFAULT 0` per i valori predefiniti in selezioni o gruppi
- `visible boolean NOT NULL DEFAULT 1` per nascondere gli elementi
- `deleted_at timestamp NULL DEFAULT NULL,` per segnare un elemento come eliminato
Per tabelle non presenti all'interno della lista ufficiale di OpenSTAManager (file **update/tables.php**), è necessario inoltre provvedere all'aggiunta dei seguenti campi:
- `updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`
- `created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP`
## Note
Malgrado una buona parte del codice ufficiale non segua completamente queste buone pratiche, è consigliato l'implementazione di queste linee guida per nuove funzioni e strutture mentre il sistema di base viene lentamente standardizzato.

View File

@ -1,129 +0,0 @@
name: OpenSTAManager CI
on:
workflow_dispatch
jobs:
tests:
runs-on: ubuntu-18.04
strategy:
matrix:
python-version: [3.9]
php-version: ['7.4']
steps:
- uses: actions/checkout@v2
# - name: Set up PHP ${{ matrix.php-version }}
# uses: shivammathur/setup-php@v2
# with:
# php-version: ${{ matrix.php-version }}
# extensions: zip, mbstring, pdo_mysql, mysql, dom, xsl, openssl, intl, curl, soap, gd
- name: Setup PHP
run: |
sudo apt install libapache2-mod-php7.4
sudo sed -i 's,^post_max_size =.*$,post_max_size = 32M,' /etc/php/7.4/apache2/php.ini
sudo sed -i 's,^upload_max_filesize =.*$,upload_max_filesize = 32M,' /etc/php/7.4/apache2/php.ini
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install SeleniumBase
uses: actions/checkout@v2
with:
repository: seleniumbase/SeleniumBase
path: selenium-base
- name: Configure SeleniumBase
run: |
cd selenium-base
python setup.py install
- name: Install Chrome and Firefox
run: |
sudo apt install google-chrome-stable
sudo apt-get install firefox
- name: Check the console scripts interface
run: |
seleniumbase
sbase
- name: Install chromedriver and geckodriver (Firefox Webdriver)
run: |
seleniumbase install chromedriver
seleniumbase install geckodriver
- name: Make sure pytest is working
run: |
echo "def test_1(): pass" > nothing.py
pytest nothing.py
- name: Make sure nosetests is working
run: |
echo "def test_2(): pass" > nothing2.py
nosetests nothing2.py
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install Composer dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Use NPM and Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install NPM and compile assets
run: |
yarn install
npm run build-OSM
- name: Copy OSM to www root
run: |
sudo cp -R /home/runner/work/openstamanager/openstamanager /var/www/html/
sudo chmod -R 0777 /var/www/html/openstamanager
sudo rm /var/www/html/openstamanager/.htaccess
- name: Check out test repository
uses: actions/checkout@v2
with:
repository: devcode-it/openstamanager-tests
path: python-tests
- name: Install Python dependencies
run: |
cd python-tests/
python -m pip install --upgrade pip
python -m pip install pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Restart apache
run: sudo service apache2 restart
- name: Restart MySQL
run: sudo service mysql restart
- name: Init test configuration
run: |
curl http://localhost/openstamanager/
sudo cat /var/log/apache2/access.log
cd python-tests/
echo -ne "{\n \"login\": {\n \"password\": \"adminadmin\",\n \"username\": \"admin\"\n },\n \"database\": {\n \"host\": \"localhost\",\n \"user\": \"root\",\n \"pass\": \"root\",\n \"name\": \"osm\"\n },\n \"server\": \"http://localhost/openstamanager/\",\n \"browser\": \"firefox\",\n \"headless\": true\n}" > config.json
pytest Init.py
- name: Execute tests
run: |
cd python-tests/
pytest tests

249
.gitignore vendored
View File

@ -1,100 +1,163 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyo
*.pyc
/.vscode
# Packages #
############
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Created by https://www.toptal.com/developers/gitignore/api/phpstorm,laravel,composer,yarn
# Edit at https://www.toptal.com/developers/gitignore?templates=phpstorm,laravel,composer,yarn
# Logs and databases #
######################
*.log
*.sqlite
### Composer ###
composer.phar
/vendor/
# Mixed #
######################
*~
._*
.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
.vscode/*
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
# Npm, Bower, Composer #
######################
bower_components/
### Laravel ###
node_modules/
vendor/
*.phar
*.lock
package-lock.json
npm-debug.log
yarn-error.log
# Project #
######################
*.new
*.old
*.txt
assets/dist/
backup/*
!backup/.htaccess
custom/
files/*
!files/.htaccess
!files/impianti/
files/impianti/*
!files/impianti/componente.ini
!files/temp/
files/temp/*
tmp/
config.inc.php
database.sql
VERSION
REVISION
.php_cs.cache
manifest.json
checksum.json
database.json
# Laravel 4 specific
bootstrap/compiled.php
app/storage/
# Laravel 5 & Lumen specific
public/storage
public/hot
# Laravel 5 & Lumen specific with changed public path
public_html/storage
public_html/hot
storage/*.key
.env
.env.backup
Homestead.yaml
Homestead.json
/.vagrant
.phpunit.result.cache
docker-compose.override.yml
### PhpStorm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### PhpStorm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
### yarn ###
# https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
# if you are NOT using Zero-installs, then:
# comment the following lines
!.yarn/cache
# and uncomment the following lines
# .pnp.*
# End of https://www.toptal.com/developers/gitignore/api/phpstorm,laravel,composer,yarn
/tests/_log/*
/tests/_temp/*
codeception.yml
!.gitkeep

13
.styleci.yml Normal file
View File

@ -0,0 +1,13 @@
php:
preset: laravel
disabled:
- no_unused_imports
finder:
not-name:
- index.php
- server.php
js:
finder:
not-name:
- webpack.mix.js
css: true

View File

@ -1,429 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
use Models\Note;
use Models\OperationLog;
use Models\Upload;
use Modules\Checklists\Check;
use Modules\Checklists\Checklist;
use Modules\Emails\Template;
use Notifications\EmailNotification;
if (empty($structure) || empty($structure['enabled'])) {
exit(tr('Accesso negato'));
}
$upload_dir = base_dir().'/'.Uploads::getDirectory($id_module, $id_plugin);
$database->beginTransaction();
// Upload allegati e rimozione
if (filter('op') == 'aggiungi-allegato' || filter('op') == 'rimuovi-allegato') {
// Controllo sui permessi di scrittura per il modulo
if (Modules::getPermission($id_module) != 'rw') {
flash()->error(tr('Non hai permessi di scrittura per il modulo _MODULE_', [
'_MODULE_' => '"'.Modules::get($id_module)['name'].'"',
]));
}
// Controllo sui permessi di scrittura per il file system
elseif (!directory($upload_dir)) {
flash()->error(tr('Non hai i permessi di scrittura nella cartella _DIR_!', [
'_DIR_' => '"files"',
]));
}
// Gestione delle operazioni
else {
// UPLOAD
if (filter('op') == 'aggiungi-allegato' && !empty($_FILES) && !empty($_FILES['file']['name'])) {
$upload = Uploads::upload($_FILES['file'], [
'name' => filter('nome_allegato'),
'category' => filter('categoria'),
'id_module' => $id_module,
'id_plugin' => $id_plugin,
'id_record' => $id_record,
]);
// Creazione file fisico
if (!empty($upload)) {
flash()->info(tr('File caricato correttamente!'));
} else {
flash()->error(tr('Errore durante il caricamento del file!'));
}
}
// DELETE
elseif (filter('op') == 'rimuovi-allegato' && filter('filename') !== null) {
$name = Uploads::delete(filter('filename'), [
'id_module' => $id_module,
'id_plugin' => $id_plugin,
'id_record' => $id_record,
]);
if (!empty($name)) {
flash()->info(tr('File _FILE_ eliminato!', [
'_FILE_' => '"'.$name.'"',
]));
} else {
flash()->error(tr("Errore durante l'eliminazione del file!"));
}
}
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.((!empty($options['id_plugin'])) ? '#tab_'.$options['id_plugin'] : ''));
}
}
// Download allegati
elseif (filter('op') == 'download-allegato') {
$rs = $dbo->fetchArray('SELECT * FROM zz_files WHERE id_module='.prepare($id_module).' AND id='.prepare(filter('id')).' AND filename='.prepare(filter('filename')));
download($upload_dir.'/'.$rs[0]['filename'], $rs[0]['original']);
} elseif (filter('op') == 'visualizza-modifica-allegato') {
include_once base_dir().'/include/modifica_allegato.php';
}
// Modifica dati di un allegato
elseif (filter('op') == 'modifica-allegato') {
$id_allegato = filter('id_allegato');
$allegato = Upload::find($id_allegato);
$allegato->name = post('nome_allegato');
$allegato->category = post('categoria_allegato');
$allegato->save();
}
// Modifica nome della categoria degli allegati
elseif (filter('op') == 'modifica-categoria-allegato') {
$category = post('category');
$name = post('name');
$uploads = $structure->uploads($id_record)->where('category', $category);
foreach ($uploads as $upload) {
$upload->category = $name;
$upload->save();
}
}
// Validazione dati
elseif (filter('op') == 'validate') {
// Lettura informazioni di base
$init = $structure->filepath('init.php');
if (!empty($init)) {
include_once $init;
}
// Validazione del campo
$validation = $structure->filepath('validation.php');
if (!empty($validation)) {
include_once $validation;
}
echo json_encode($response);
return;
}
// Aggiunta nota interna
elseif (filter('op') == 'aggiungi-nota') {
$contenuto = post('contenuto');
$data_notifica = post('data_notifica') ?: null;
$nota = Note::build($user, $structure, $id_record, $contenuto, $data_notifica);
flash()->info(tr('Nota interna aggiunta correttamente!'));
}
// Rimozione data di notifica dalla nota interna
elseif (filter('op') == 'rimuovi-notifica-nota') {
$id_nota = post('id_nota');
$nota = Note::find($id_nota);
$nota->notification_date = null;
$nota->save();
flash()->info(tr('Data di notifica rimossa dalla nota interna!'));
}
// Rimozione nota interna
elseif (filter('op') == 'rimuovi-nota') {
$id_nota = post('id_nota');
$nota = Note::find($id_nota);
$nota->delete();
flash()->info(tr('Nota interna aggiunta correttamente!'));
}
// Clonazione di una checklist
elseif (filter('op') == 'copia-checklist') {
$content = post('content');
$checklist_id = post('checklist');
$users = post('assigned_users');
$users = array_clean($users);
$group_id = post('group_id');
$checklist = Checklist::find($checklist_id);
$checklist->copia($user, $id_record, $users, $group_id);
}
// Aggiunta check alla checklist
elseif (filter('op') == 'aggiungi-check') {
$content = post('content');
$parent_id = post('parent') ?: null;
$users = post('assigned_users');
$users = array_clean($users);
$group_id = post('group_id');
$check = Check::build($user, $structure, $id_record, $content, $parent_id);
$check->setAccess($users, $group_id);
}
// Rimozione di un check della checklist
elseif (filter('op') == 'rimuovi-check') {
$check_id = post('check_id');
$check = Check::find($check_id);
if (!empty($check) && $check->user->id == $user->id) {
$check->delete();
} else {
flash()->error(tr('Impossibile eliminare il check!'));
}
}
// Gestione check per le checklist
elseif (filter('op') == 'toggle-check') {
$check_id = post('check_id');
$check = Check::find($check_id);
if (!empty($check) && $check->assignedUsers->pluck('id')->search($user->id) !== false) {
$check->toggleCheck($user);
} else {
flash()->error(tr('Impossibile cambiare lo stato del check!'));
}
}
// Gestione ordine per le checklist
elseif (filter('op') == 'ordina-checks') {
$ids = explode(',', $_POST['order']);
$order = 0;
foreach ($ids as $id) {
$dbo->query('UPDATE `zz_checks` SET `order` = '.prepare($order).' WHERE id = '.prepare($id));
++$order;
}
}
// Inizializzazione email
elseif (post('op') == 'send-email') {
$template = Template::find(post('template'));
$mail = \Modules\Emails\Mail::build($user, $template, $id_record);
// Rimozione allegati predefiniti
$mail->resetPrints();
// Destinatari
$receivers = array_clean(post('destinatari'));
$types = post('tipo_destinatari');
foreach ($receivers as $key => $receiver) {
$mail->addReceiver($receiver, $types[$key]);
}
// Contenuti
$mail->subject = post('subject');
$mail->content = post('body');
// Conferma di lettura
$mail->read_notify = post('read_notify');
// Stampe da allegare
$prints = post('prints');
foreach ($prints as $print) {
$mail->addPrint($print);
}
// Allegati originali
$files = post('uploads');
foreach ($files as $file) {
$mail->addUpload($file);
}
// Salvataggio email nella coda di invio
$mail->save();
// Invio mail istantaneo
$email = EmailNotification::build($mail);
$email_success = $email->send();
if ($email_success) {
OperationLog::setInfo('id_email', $mail->id);
flash()->info(tr('Email inviata correttamente!'));
} else {
$mail->delete();
flash()->error(tr('Errore durante l\'invio email! Verifica i parametri dell\'account SMTP utilizzato.'));
}
} elseif (filter('op') == 'aggiorna_colonne') {
include_once base_dir().'/include/colonne.php';
} elseif (filter('op') == 'toggle_colonna') {
$visible = filter('visible');
$id_riga = filter('id_vista');
$dbo->query('UPDATE `zz_views` SET `visible` = '.prepare($visible).' WHERE id = '.prepare($id_riga));
} elseif (filter('op') == 'ordina_colonne') {
$order = explode(',', post('order', true));
foreach ($order as $i => $id_riga) {
$dbo->query('UPDATE `zz_views` SET `order` = '.prepare($i).' WHERE id='.prepare($id_riga));
}
} elseif (filter('op') == 'visualizza_righe_riferimenti') {
include_once base_dir().'/include/riferimenti/riferimenti.php';
} elseif (filter('op') == 'visualizza_righe_documento') {
include_once base_dir().'/include/riferimenti/righe_documento.php';
} elseif (filter('op') == 'salva_riferimento_riga') {
$database->insert('co_riferimenti_righe', [
'source_type' => filter('source_type'),
'source_id' => filter('source_id'),
'target_type' => filter('target_type'),
'target_id' => filter('target_id'),
]);
} elseif (filter('op') == 'rimuovi_riferimento_riga') {
$database->delete('co_riferimenti_righe', [
'id' => filter('idriferimento'),
]);
}
// Inclusione di eventuale plugin personalizzato
if (!empty($structure['script'])) {
$path = $structure->getEditFile();
if (!empty($path)) {
include $path;
}
$database->commitTransaction();
return;
}
// Lettura risultato query del modulo
$init = $structure->filepath('init.php');
if (!empty($init)) {
include_once $init;
}
// Retrocompatibilità
if (!isset($record) && isset($records[0])) {
$record = $records[0];
} elseif (!isset($records[0]) && isset($record)) {
$records = [$record];
} elseif (!isset($record)) {
$record = [];
$records = [$record];
}
// Registrazione del record
HTMLBuilder\HTMLBuilder::setRecord($record);
if ($structure->permission == 'rw') {
// Esecuzione delle operazioni di gruppo
$id_records = post('id_records');
$id_records = is_array($id_records) ? $id_records : explode(';', $id_records);
$id_records = array_clean($id_records);
$id_records = array_unique($id_records);
$bulk = $structure->filepath('bulk.php');
$bulk = empty($bulk) ? [] : include $bulk;
$bulk = empty($bulk) ? [] : $bulk;
if (in_array(post('op'), array_keys($bulk))) {
redirect(base_path().'/controller.php?id_module='.$id_module, 'js');
} else {
// Esecuzione delle operazioni del modulo
($include_file = $structure->filepath('actions.php')) ? include $include_file : null;
// Operazioni generiche per i campi personalizzati
if (post('op') != null) {
$custom_where = !empty($id_plugin) ? '`id_plugin` = '.prepare($id_plugin) : '`id_module` = '.prepare($id_module);
$query = 'SELECT `id`, `html_name` AS `name` FROM `zz_fields` WHERE '.$custom_where;
$customs = $dbo->fetchArray($query);
if (!string_starts_with(post('op'), 'delete')) {
$values = [];
foreach ($customs as $custom) {
if (post($custom['name']) !== null) {
$values[$custom['id']] = post($custom['name']);
}
}
// Inserimento iniziale
if (string_starts_with(post('op'), 'add')) {
// Informazioni di log
Filter::set('get', 'id_record', $id_record);
foreach ($values as $key => $value) {
$dbo->insert('zz_field_record', [
'id_record' => $id_record,
'id_field' => $key,
'value' => $value,
]);
}
}
// Aggiornamento
elseif (string_starts_with(post('op'), 'update')) {
$query = 'SELECT `zz_field_record`.`id_field` FROM `zz_field_record` JOIN `zz_fields` ON `zz_fields`.`id` = `zz_field_record`.`id_field` WHERE id_record = '.prepare($id_record).' AND '.$custom_where;
$customs_present = $dbo->fetchArray($query);
$customs_present = array_column($customs_present, 'id_field');
foreach ($values as $key => $value) {
if (in_array($key, $customs_present)) {
$dbo->update('zz_field_record', [
'value' => $value,
], [
'id_record' => $id_record,
'id_field' => $key,
]);
} else {
$dbo->insert('zz_field_record', [
'id_record' => $id_record,
'id_field' => $key,
'value' => $value,
]);
}
}
}
}
// Eliminazione
elseif (!empty($customs)) {
$dbo->query('DELETE FROM `zz_field_record` WHERE `id_record` = '.prepare($id_record).' AND `id_field` IN ('.implode(',', array_column($customs, 'id')).')');
}
}
}
}
$database->commitTransaction();

105
add.php
View File

@ -1,105 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
// Inclusione elementi fondamentali del modulo
include base_dir().'/actions.php';
// Controllo dei permessi
if (empty($id_plugin)) {
Permissions::check('rw');
}
// Caricamento template
echo '
<div id="form_'.$id_module.'-'.$id_plugin.'">
';
include !empty(get('edit')) ? $structure->getEditFile() : $structure->getAddFile();
echo '
</div>';
// Campi personalizzati
echo '
<div class="hide" id="custom_fields_top-add">
<input type="hidden" name="id_module" value="'.$id_module.'">
<input type="hidden" name="id_plugin" value="'.$id_plugin.'">
{( "name": "custom_fields", "id_module": "'.$id_module.'", "id_plugin": "'.$id_plugin.'", "position": "top", "place": "add" )}
</div>
<div class="hide" id="custom_fields_bottom-add">
{( "name": "custom_fields", "id_module": "'.$id_module.'", "id_plugin": "'.$id_plugin.'", "position": "bottom", "place": "add" )}
</div>
<script>
$(document).ready(function(){
let form = $("#custom_fields_top-add").parent().find("form").first();
// Ultima sezione/campo del form
let last = form.find(".panel").last();
if (!last.length) {
last = form.find(".box").last();
}
if (!last.length) {
last = form.find(".row").eq(-2);
}
// Campi a inizio form
aggiungiContenuto(form, "#custom_fields_top-add", {}, true);
// Campi a fine form
aggiungiContenuto(last, "#custom_fields_bottom-add", {});
});
</script>';
if (isAjaxRequest()) {
echo '
<script>
$(document).ready(function(){
$("#form_'.$id_module.'-'.$id_plugin.'").find("form").submit(function () {
let $form = $(this);
salvaForm(this, {
id_module: "'.$id_module.'",
id_plugin: "'.$id_plugin.'",
}).then(function(response) {
// Selezione automatica nuovo valore per il select
let select = "#'.get('select').'";
if ($(select).val() !== undefined) {
$(select).selectSetNew(response.id, response.text, response.data);
$(select).change();
}
$form.closest("div[id^=bs-popup").modal("hide");
})
return false;
})
});
</script>';
}
echo '
<script>$(document).ready(init)</script>';

171
ajax.php
View File

@ -1,171 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
use Models\Hook;
switch (filter('op')) {
// Imposta un valore ad un array di $_SESSION
// esempio: push di un valore in $_SESSION['dashboard']['idtecnici']
// iversed: specifica se rimuovere dall'array il valore trovato e applicare quindi una deselezione (valori 0 o 1, default 1)
case 'session_set_array':
$array = explode(',', get('session'));
$value = "'".get('value')."'";
$inversed = get('inversed');
$found = false;
// Ricerca valore nell'array
foreach ($_SESSION[$array[0]][$array[1]] as $idx => $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;
case 'list_attachments':
echo '{( "name": "filelist_and_upload", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "id_plugin": "'.$id_plugin.'" )}';
break;
case 'checklists':
include base_dir().'/plugins/checks.php';
break;
case 'active_users':
$posizione = get('id_module');
if (isset($id_record)) {
$posizione .= ', '.get('id_record');
}
$user = Auth::user();
$interval = setting('Timeout notifica di presenza (minuti)') * 60 * 2;
$dbo->query('UPDATE zz_semaphores SET updated = NOW() WHERE id_utente = :user_id AND posizione = :position', [
':user_id' => $user['id'],
':position' => $posizione,
]);
// Rimozione record scaduti
$dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated, INTERVAL :interval SECOND) <= NOW()', [
':interval' => $interval,
]);
$datas = $dbo->fetchArray('SELECT DISTINCT username FROM zz_semaphores INNER JOIN zz_users ON zz_semaphores.id_utente=zz_users.id WHERE zz_semaphores.id_utente != :user_id AND posizione = :position', [
':user_id' => $user['id'],
':position' => $posizione,
]);
echo json_encode($datas);
break;
case 'hooks':
$hooks = Hook::all();
$results = [];
foreach ($hooks as $hook) {
if ($hook->permission != '-') {
$results[] = [
'id' => $hook->id,
'name' => $hook->name,
];
}
}
echo json_encode($results);
break;
case 'hook-lock':
$hook_id = filter('id');
$hook = Hook::find($hook_id);
$token = $hook->lock();
echo json_encode($token);
break;
case 'hook-execute':
$hook_id = filter('id');
$token = filter('token');
$hook = Hook::find($hook_id);
$response = $hook->execute($token);
echo json_encode($response);
break;
case 'hook-response':
$hook_id = filter('id');
$hook = Hook::find($hook_id);
$response = $hook->response();
echo json_encode($response);
break;
case 'flash':
$response = flash()->getMessages();
echo json_encode($response);
break;
case 'summable-results':
$ids = post('ids') ?: [];
$results = Util\Query::getSums($structure, [
'id' => $ids,
]);
echo json_encode($results);
break;
}

View File

@ -1,33 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
if (!isset($resource)) {
$module = get('module');
$op = get('op');
$result = AJAX::complete($op);
echo $result;
}
// Casi particolari
else {
}

View File

@ -1,204 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
use Util\Query;
// Informazioni fondamentali
$columns = (array) filter('columns');
$order = filter('order') ? filter('order')[0] : [];
$draw_numer = intval(filter('draw'));
if (!empty(filter('order'))) {
$order['column'] = $order['column'] - 1;
}
array_shift($columns);
$total = Util\Query::readQuery($structure);
// Ricerca
$search = [];
for ($i = 0; $i < count($columns); ++$i) {
if (!empty($columns[$i]['search']['value']) || $columns[$i]['search']['value'] == '0') {
$search[$total['fields'][$i]] = $columns[$i]['search']['value'];
}
}
$limit = [
'start' => filter('start'),
'length' => filter('length'),
];
// Predisposizione della risposta
$results = [
'data' => [],
'recordsTotal' => 0,
'recordsFiltered' => 0,
'summable' => [],
'draw' => $draw_numer,
];
$query = Query::getQuery($structure);
if (!empty($query)) {
// CONTEGGIO TOTALE
$results['recordsTotal'] = $dbo->fetchNum($query);
// RISULTATI VISIBILI
$query = Query::getQuery($structure, $search, $order, $limit);
// Filtri derivanti dai permessi (eventuali)
if (empty($id_plugin)) {
$query = Modules::replaceAdditionals($id_module, $query);
}
// Conteggio dei record filtrati
$data = Query::executeAndCount($query);
$rows = $data['results'];
$results['recordsFiltered'] = $data['count'];
// SOMME
$results['summable'] = Util\Query::getSums($structure, $search);
// Allineamento delle righe
$align = [];
$row = isset($rows[0]) ? $rows[0] : [];
foreach ($row as $field => $value) {
$value = trim($value);
// Allineamento a destra se il valore della prima riga risulta numerica
if (is_numeric($value) && formatter()->isStandardNumber($value)) {
$align[$field] = 'text-right';
}
// Allineamento al centro se il valore della prima riga risulta relativo a date o icone
elseif (formatter()->isStandardDate($value) || preg_match('/^icon_(.+?)$/', $field)) {
$align[$field] = 'text-center';
}
}
// Creazione della tabella
foreach ($rows as $i => $r) {
// Evitare risultati con ID a null
// Codice non applicabile in ogni caso: sulla base dei permessi, ID può non essere impostato
/*
if (empty($r['id'])) {
continue;
}*/
$result = [
'id' => $r['id'],
'<span class="hide" data-id="'.$r['id'].'"></span>', // Colonna ID
];
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)) {
if (formatter()->isStandardTimestamp($value)) {
$value = Translator::timestampToLocale($value);
} elseif (formatter()->isStandardDate($value)) {
$value = Translator::dateToLocale($value);
} elseif (formatter()->isStandardTime($value)) {
$value = Translator::timeToLocale($value);
} elseif (formatter()->isStandardNumber($value)) {
$value = Translator::numberToLocale($value);
}
}
// Icona
if (preg_match('/^color_(.+?)$/', $field, $m)) {
$value = isset($r['color_title_'.$m[1]]) ? $r['color_title_'.$m[1]] : '';
$column['class'] = 'text-center small';
$column['data-background'] = $r[$field];
}
// Icona di stampa
elseif ($field == '_print_') {
$print = $r['_print_'];
$print_url = Prints::getHref($print, $r['id']);
$value = '<a href="'.$print_url.'" target="_blank"><i class="fa fa-2x fa-print"></i></a>';
}
// Icona
elseif (preg_match('/^icon_(.+?)$/', trim($field), $m)) {
$value = '<span class=\'label text-black\' style=\'font-weight:normal;\' ><i class="'.$r[$field].'" title="'.$r['icon_title_'.$m[1]].'" ></i> <span>'.$r['icon_title_'.$m[1]].'</span></span>';
}
// Colore del testo
if (!empty($column['data-background'])) {
$column['data-color'] = isset($column['data-color']) ? $column['data-color'] : color_inverse(trim($column['data-background']));
}
// Link della colonna
if ($field != '_print_') {
$id_record = $r['id'];
$hash = '';
$id_module = !empty($r['_link_module_']) ? $r['_link_module_'] : $id_module;
if (!empty($r['_link_record_'])) {
$id_record = $r['_link_record_'];
$hash = !empty($r['_link_hash_']) ? '#'.$r['_link_hash_'] : '';
unset($id_plugin);
}
// Link per i moduli
if (empty($id_plugin)) {
$column['data-link'] = base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.$hash;
}
// Link per i plugin
else {
$column['data-link'] = base_path().'/add.php?id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'&id_parent='.$id_parent.'&edit=1'.$hash;
$column['data-type'] = 'dialog';
}
}
$attributes = [];
foreach ($column as $key => $val) {
$val = is_array($val) ? implode(' ', $val) : $val;
$attributes[] = $key.'="'.$val.'"';
}
// Replace base_link() per le query
$value = str_replace('base_link()', base_path(), $value);
$result[] = str_replace('|attr|', implode(' ', $attributes), '<div |attr|>'.$value.'</div>');
}
$results['data'][] = $result;
}
}
$json = json_encode($results);
echo $json;

View File

@ -1,39 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
if (!isset($term)) {
/*
== Super search ==
Ricerca di un termine su tutti i moduli.
Il risultato è in json
*/
$term = get('term');
$term = str_replace('/', '\\/', $term);
$results = AJAX::search($term);
echo json_encode($results);
}
// Casi particolari
else {
}

View File

@ -1,46 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
if (!isset($resource)) {
$op = empty($op) ? filter('op') : $op;
$search = filter('search');
$page = filter('page') ?: 0;
$length = filter('length') ?: 100;
// Opzioni di selezione sugli elementi
$options = filter('options') ?: [];
$options_compatibility = session_get('superselect', []);
$options = array_merge($options_compatibility, $options);
// Preselezione su $elements dichiarato da file precedente
if (!isset($elements)) {
$elements = [];
}
$elements = (!is_array($elements)) ? explode(',', $elements) : $elements;
$results = AJAX::select($op, $elements, $search, $page, $length, $options);
echo json_encode($results);
}
// Casi particolari
else {
}

View File

@ -1,69 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use API\Response;
function serverError()
{
$error = error_get_last();
if ($error['type'] == E_ERROR) {
ob_end_clean();
echo Response::error('serverError');
}
}
// Gestione degli errori
set_error_handler('serverError');
register_shutdown_function('serverError');
include_once __DIR__.'/../core.php';
// Disabilita la sessione per l'API
session_write_close();
// Permesso di accesso all'API da ogni dispositivo
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');
try {
$response = Response::manage();
} catch (Exception $e) {
// Log dell'errore
$logger = logger();
$logger->addRecord(\Monolog\Logger::ERROR, $e);
$response = Response::error('serverError');
}
// Richiesta OPTIONS (controllo da parte del dispositivo)
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
$response = Response::error('ok');
}
json_decode($response);
// Impostazioni di Content-Type e Charset Header
if (json_last_error() == JSON_ERROR_NONE) {
header('Content-Type: application/json; charset=UTF-8');
} else {
header('Content-Type: text/plain; charset=UTF-8');
}
// Stampa dei risultati
echo $response;

53
artisan Normal file
View File

@ -0,0 +1,53 @@
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any of our classes manually. It's great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);

View File

@ -1,239 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*!
* 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 td {
white-space: normal;
}
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;
}

View File

@ -1,105 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;
}
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;
}
.li-widget, .nav-tabs, .dataTables_info, tfoot, #th_selector, td.select-checkbox, th.search.sorting {
display: none !important;
}
a[href]:after {
content: none !important;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,224 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
.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 > span {
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,
.skin-default .main-header .navbar .nav .menu-open 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,
.skin-default .sidebar-menu li.menu-open 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 .nav-button {
background-color: #333;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -1,99 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Aggiunta dell'ingranaggio all'unload della pagina
$(window).on("beforeunload", function () {
$("#main_loading").show();
});
// Rimozione dell'ingranaggio al caricamento completo della pagina
$(window).on("load", function () {
$("#main_loading").fadeOut();
});
// Fix multi-modal
$(document).on('hidden.bs.modal', '.modal', function () {
$(this).remove();
$('.modal:visible').length && $(document.body).addClass('modal-open');
});
$(document).ready(function () {
// Standard per i popup
toastr.options = {
"closeButton": true,
"debug": false,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-top-right",
//"preventDuplicates": true,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "12000",
"extendedTimeOut": "8000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
};
// Imposta lo standard per la conversione dei numeri
if (numeral.locales['current_locale'] === undefined) {
numeral.register('locale', 'current_locale', {
delimiters: {
thousands: globals.thousands,
decimal: globals.decimals,
},
abbreviations: {
thousand: 'k',
million: 'm',
billion: 'b',
trillion: 't'
},
currency: {
symbol: '€'
}
});
}
numeral.locale('current_locale');
numeral.defaultFormat('0,0.' + ('0').repeat(globals.cifre_decimali));
// Richiamo alla generazione di Datatables
start_datatables();
// Calendario principale
start_complete_calendar("#daterange", function (start, end) {
// Esegue il submit del periodo selezionato e ricarica la pagina
$.get(globals.rootdir + '/core.php?period_start=' + start.format('YYYY-MM-DD') + '&period_end=' + end.format('YYYY-MM-DD'), function (data) {
location.reload();
});
});
// Messaggi automatici di eliminazione
$(document).on('click', '.ask', function () {
message(this);
});
// Forza l'evento "blur" nei campi di testo per formattare i numeri con
// jquery inputmask prima del submit
setTimeout(function () {
$('form').on('submit', function () {
$('input').trigger('blur');
});
}, 1000);
});

View File

@ -1,144 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
// Pulsanti di Datatables
$(".btn-csv").off("click").on("click", function (e) {
var table = $(document).find("#" + $(this).closest("[data-target]").data("target")).DataTable();
table.buttons(0).trigger();
});
$(".btn-excel").off("click").on("click", function (e) {
var table = $(document).find("#" + $(this).closest("[data-target]").data("target")).DataTable();
table.buttons(3).trigger();
});
$(".btn-pdf").off("click").on("click", function (e) {
var table = $(document).find("#" + $(this).closest("[data-target]").data("target")).DataTable();
table.buttons(4).trigger();
});
$(".btn-copy").off("click").on("click", function (e) {
var table = $(document).find("#" + $(this).closest("[data-target]").data("target")).DataTable();
table.buttons(1).trigger();
});
$(".btn-print").off("click").on("click", function (e) {
var table = $(document).find("#" + $(this).closest("[data-target]").data("target")).DataTable();
table.buttons(2).trigger();
});
$(".btn-select-all").click(function () {
var table_selector = "#" + $(this).closest("[data-target]").data("target");
var wrapper = getTable(table_selector);
var table = wrapper.datatable;
// Visualizzazione del caricamento
$("#main_loading").show();
// Parametri della richiesta
var params = table.ajax.params();
params.length = -1;
$.ajax({
url: table.ajax.url(),
data: params,
type: 'GET',
dataType: "json",
success: function (response) {
var row_ids = response.data.map(function (a) {
return a.id;
});
// Chiamata di selezione completa
wrapper.addSelectedRows(row_ids);
table.clear().draw();
$("#main_loading").hide();
}
})
});
$(".btn-select-none").click(function () {
var table_selector = "#" + $(this).closest("[data-target]").data("target");
var wrapper = getTable(table_selector);
var table = wrapper.datatable;
// Chiamata di deselezione completa
var row_ids = wrapper.getSelectedRows();
wrapper.removeSelectedRows(row_ids);
table.clear().draw();
});
$(document).on("click", ".select-checkbox", function () {
var row = $(this).parent();
var row_id = row.attr("id");
var table_selector = $(this).closest(".dataTable");
var wrapper = getTable(table_selector);
if (row.hasClass("selected")) {
//table.datatable.rows("#" + row_id).select();
wrapper.addSelectedRows(row_id);
} else {
//table.datatable.rows("#" + row_id).deselect();
wrapper.removeSelectedRows(row_id);
}
});
$(".bulk-action").click(function () {
var table = $(document).find("#" + $(this).parent().parent().parent().parent().data("target"));
if (table.data('selected')) {
$(this).attr("data-id_records", table.data('selected'));
$(this).data("id_records", table.data('selected'));
if ($(this).data("type") === "modal") {
var data = JSON.parse(JSON.stringify($(this).data()));
var href = data.url;
delete data.url;
delete data.title;
delete data.op;
delete data.backto;
delete data.blank;
var values = [];
for (var name in data) {
values.push(name + '=' + data[name]);
}
var link = href + (href.indexOf('?') !== -1 ? '&' : '?') + values.join('&');
launch_modal($(this).data("title"), link);
} else {
message(this);
}
$(this).attr("data-id_records", "");
$(this).data("id_records", "");
} else {
swal(globals.translations.waiting, globals.translations.waitingMessage, "error");
}
});
});

View File

@ -1,68 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
// Tabs
$('.nav-tabs').tabs();
// Entra nel tab indicato al caricamento della pagina
var hash = location.hash ? location.hash : getUrlVars().hash;
if (hash && hash != '#tab_0') {
$('ul.nav-tabs a[href="' + hash + '"]').tab('show').trigger('shown.bs.tab');
} else {
removeHash();
}
$(window).bind('beforeunload', function () {
if (location.hash == '#tab_0') {
removeHash();
}
});
// Nel caso la navigazione sia da mobile, disabilito il ritorno al punto precedente
if (!globals.is_mobile) {
// Salvo lo scroll per riportare qui l'utente al reload
$(window).on('scroll', function () {
if (sessionStorage != undefined) {
sessionStorage.setItem('scrollTop_' + globals.id_module + '_' + globals.id_record, $(document).scrollTop());
}
});
// Riporto l'utente allo scroll precedente
if (sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record] != undefined) {
setTimeout(function () {
scrollToOffset(sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record]);
}, 1);
}
}
$('.nav-tabs a').click(function (e) {
$(this).tab('show');
let scroll = $('body').scrollTop() || $('html').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scroll);
});
// Fix per la visualizzazione di Datatables all'interno dei tab Bootstrap
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$($.fn.dataTable.tables(true)).DataTable().columns.adjust();
$($.fn.dataTable.tables(true)).DataTable().scroller.measure();
});
});

View File

@ -1,108 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
// Fix per il menu principale
$('.sidebar-menu').tree({
followLink: true,
});
$('.sidebar-menu > li.treeview i.fa-angle-left').click(function (e) {
e.preventDefault();
$(this).find('ul').stop().slideDown();
});
$('.sidebar-menu > li.treeview i.fa-angle-down').click(function (e) {
e.preventDefault();
$(this).find('ul').stop().slideUp();
});
const elenco_menu = $('.treeview-menu > li.active');
for (i = 0; i < elenco_menu.length; i++) {
const elemento = $(elenco_menu[i]);
elemento.parent().show().parent().addClass('active');
elemento.parent().parent().find('i.fa-angle-left').removeClass('fa-angle-left').addClass('fa-angle-down');
}
// Menu ordinabile
if (!globals.is_mobile) {
sortable(".sidebar-menu", {
axis: "y",
cursor: "move",
dropOnEmpty: true,
scroll: true,
})[0].addEventListener("sortupdate", function (e) {
let order = $(".sidebar-menu > .treeview[data-id]").toArray().map(a => $(a).data("id"))
$.post(globals.rootdir + "/actions.php", {
id_module: globals.order_manager_id,
op: "sort_modules",
order: order.join(","),
});
});
}
// Mostra/nasconde sidebar del menu principale
$(".sidebar-toggle").on("click", function () {
if ($("body").hasClass("sidebar-collapse")) {
session_set("settings,sidebar-collapse", 0, 1, 0);
} else {
session_set("settings,sidebar-collapse", 1, 0, 0);
}
setTimeout(function () {
window.dispatchEvent(new Event('resize'));
}, 350);
});
// Barra plugin laterale
const pluginToggle = $(".control-sidebar-toggle");
const largeScreen = screen.width > 1200;
// Gestione click sul pulsante per il toggle
pluginToggle.on("click", function () {
$("aside.content-wrapper, .main-footer").toggleClass("with-control-sidebar");
toggleControlSidebar();
});
// Gestione click sulla sidebar per evitare chiusura
$(".control-sidebar").on("click", function (e) {
if (largeScreen && e.target.tagName === 'A' && $(".main-footer").hasClass("with-control-sidebar")) {
toggleControlSidebar();
}
});
// Barra plugin laterale disabilitata per schermi piccoli
if (largeScreen && !globals.collapse_plugin_sidebar) {
pluginToggle.click();
}
});
/**
* Funzione dedicata alla gestione del toggle della sidebar.
*/
function toggleControlSidebar() {
const sidebar = $(".control-sidebar");
sidebar.toggleClass("control-sidebar-open");
if (sidebar.hasClass("control-sidebar-open")) {
sidebar.show();
}
}

View File

@ -1,65 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
// Pulsante per il ritorno a inizio pagina
var slideToTop = $("<div />");
slideToTop.html('<i class="fa fa-chevron-up"></i>');
slideToTop.css({
position: 'fixed',
bottom: '20px',
right: '25px',
width: '40px',
height: '40px',
color: '#eee',
'font-size': '',
'line-height': '40px',
'text-align': 'center',
'background-color': 'rgba(255, 78, 0)',
'box-shadow': '0 0 10px rgba(0, 0, 0, 0.05)',
cursor: 'pointer',
'z-index': '99999',
opacity: '.7',
'display': 'none'
});
slideToTop.on('mouseenter', function () {
$(this).css('opacity', '1');
});
slideToTop.on('mouseout', function () {
$(this).css('opacity', '.7');
});
$('.wrapper').append(slideToTop);
$(window).scroll(function () {
if ($(window).scrollTop() >= 150) {
if (!$(slideToTop).is(':visible')) {
$(slideToTop).fadeIn(500);
}
} else {
$(slideToTop).fadeOut(500);
}
});
$(slideToTop).click(function () {
$("html, body").animate({
scrollTop: 0
}, 500);
});
});

View File

@ -1,91 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
const searchInput = $('#supersearch');
const searchButton = searchInput.parent().find('i');
const searches = [];
autocomplete({
minLength: 1,
input: searchInput[0],
emptyMsg: globals.translations.noResults,
debounceWaitMs: 500,
fetch: function(text, update) {
text = text.toLowerCase();
// Registrazione ricerca
searches.push(text);
searchButton
.removeClass('fa-search')
.addClass('fa-spinner fa-spin');
$.ajax({
url: globals.rootdir + '/ajax_search.php',
dataType: "JSON",
data: {
term: text,
},
success: function (data) {
// Fix per gestione risultati null
data = data ? data : [];
// Trasformazione risultati in formato leggibile
const results = data.map(function (result) {
return {
label: result.label ? result.label : '<h4>' + result.title + '</h4>' + result.labels
.join('').split('<br/>,').join('<br/>'),
group: result.category,
link: result.link,
value: result.title
}
});
// Rimozione ricerca in corso
searches.pop();
if (searches.length === 0) {
searchButton
.removeClass('fa-spinner fa-spin')
.addClass('fa-search');
}
update(results);
},
error: function (){
searchButton
.removeClass('fa-spinner fa-spin')
.addClass('fa-exclamation-triangle');
}
});
},
preventSubmit: true,
disableAutoSelect: true,
onSelect: function(item) {
window.location.href = item.link;
},
customize: function(input, inputRect, container, maxHeight) {
container.style.width = '600px';
},
render: function(item, currentValue){
const itemElement = document.createElement("div");
itemElement.innerHTML = item.label;
// <a href='" + item.link + "' title='Clicca per aprire'><b>" + item.value + "</b><br/>" + item.label + "</a>
return itemElement;
}
});
});

View File

@ -1,52 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
const widgets = sortable("#widget-top, #widget-right", {
forcePlaceholderSize: true,
items: 'li',
cursor: 'move',
dropOnEmpty: true,
acceptFrom: '.widget',
scroll: true,
});
for (const sorting of widgets) {
sorting.addEventListener("sortupdate", function (e) {
// Rimuovo l'evidenziazione dell'area widget
$('.widget').removeClass('bordered');
// Salvo la lista su cui ho eseguito il drop
const location = $(e.detail.destination.container).attr('id').replace('widget-', '');
let order = $(".widget li[data-id]").toArray().map(a => $(a).data("id"))
$.post(globals.rootdir + "/actions.php", {
id_module: globals.order_manager_id,
id_module_widget: globals.id_module,
op: 'sort_widgets',
location: location,
order: order.join(','),
});
});
sorting.addEventListener("sortstart", function (e) {
// Evidenzio le aree dei widget
$('.widget').addClass('bordered');
});
}
});

View File

@ -1,308 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Disabling autoDiscover, otherwise Dropzone will try to attach twice.
Dropzone.autoDiscover = false;
/**
* Restituisce filename ed estensione di un file indicato.
* @param path
* @returns [string, string]
*/
function getFilenameAndExtension(path) {
let filename_extension = path.replace(/^.*[\\\/]/, '');
let filename = filename_extension.substring(0, filename_extension.lastIndexOf('.'));
let ext = filename_extension.split('.').pop();
return [filename, ext];
}
/**
* Inizializza la gestione degli allegati.
* @param gestione
*/
function initGestioneAllegati(gestione) {
const dropzone_id = '#' + gestione.attr('id') + ' .dropzone';
const maxFilesize = gestione.data('max_filesize');
if ($(dropzone_id).length === 0) {
return;
}
let params = new URLSearchParams({
op: "aggiungi-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
}).toString();
let dragdrop = new Dropzone(dropzone_id, {
dictDefaultMessage: globals.translations.allegati.messaggio + ".<br>(" + globals.translations.allegati.maxFilesize.replace('_SIZE_', maxFilesize) + ")",
paramName: "file",
maxFilesize: maxFilesize, // MB
uploadMultiple: false,
parallelUploads: 2,
addRemoveLinks: false,
autoProcessQueue: true,
autoQueue: true,
url: globals.rootdir + "/actions.php?" + params,
init: function (file, xhr, formData) {
this.on("success", function (file) {
dragdrop.removeFile(file);
});
this.on("complete", function (file) {
// Ricarico solo quando ho finito
if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
ricaricaAllegati(gestione);
}
});
}
});
}
/**
* Funzione per l'apertura della schermata di modifica per una categoria di allegati.
* @param gestione
* @param pulsanteModifica
*/
function modificaCategoriaAllegati(gestione, pulsanteModifica) {
const categoria = $(pulsanteModifica).parent().parent();
console.log(categoria)
const nome = categoria.find(".box-title");
nome.addClass('hidden');
$(pulsanteModifica).addClass('hidden');
const pulsanteSalva = categoria.find(".category-save");
const pulsanteAnnulla = categoria.find(".category-cancel");
const inputNome = categoria.find(".category-name");
pulsanteSalva.removeClass("hidden");
pulsanteAnnulla.removeClass("hidden");
inputNome.removeClass("hidden");
}
/**
* Funzione per salvare le modifiche effettuate su una categoria di allegati.
* @param gestione
* @param pulsanteSalva
*/
function salvaCategoriaAllegati(gestione, pulsanteSalva) {
const categoria = $(pulsanteSalva).parent().parent();
const nome = categoria.find(".box-title");
const inputNome = categoria.find(".category-name");
mostraCaricamentoAllegati(gestione);
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "POST",
data: {
op: "modifica-categoria-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
category: nome.text(),
name: inputNome.val(),
},
success: function (data) {
ricaricaAllegati(gestione);
},
error: function (gestione) {
ricaricaAllegati(gestione);
}
});
}
/**
* Funzione per caricare un nuovo allegato.
* @param gestione
*/
function aggiungiAllegato(gestione) {
const id = "#" + gestione.attr('id');
const form = $(id + " #upload-form");
form.ajaxSubmit({
url: globals.rootdir + "/actions.php",
data: data,
type: "post",
uploadProgress: function (event, position, total, percentComplete) {
$(id + " #upload").prop("disabled", true).html(percentComplete + "%").removeClass("btn-success").addClass("btn-info");
},
success: function (data) {
ricaricaAllegati(gestione);
},
error: function (data) {
alert(globals.translations.allegati.errore + ": " + data);
}
});
}
/**
* Funzione per mostrare il loader di caricamento per gli allegati.
* @param gestione
*/
function mostraCaricamentoAllegati(gestione) {
const id = "#" + gestione.attr('id');
localLoading($(id + " .panel-body"), true);
}
/**
* Funzione dedicata al caricamento dinamico degli allegati.
* @param gestione
*/
function ricaricaAllegati(gestione) {
const id = "#" + gestione.attr('id');
let params = new URLSearchParams({
op: "list_attachments",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
}).toString();
$(id).load(globals.rootdir + "/ajax.php?" + params, function () {
localLoading($(id + " .panel-body"), false);
const nuovoAllegato = $(id + " table tr").eq(-1).attr("id");
if (nuovoAllegato !== undefined) {
$("#" + nuovoAllegato).effect("highlight", {}, 1500);
}
});
}
/**
* Funzione per l'apertura della pagina di gestione dei dati dell'allegato.
* @param button
*/
function modificaAllegato(button) {
const gestione = $(button).closest(".gestione-allegati");
const allegato = $(button).closest("tr").data();
let params = new URLSearchParams({
op: "visualizza-modifica-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id_allegato: allegato.id,
}).toString();
openModal(globals.translations.allegati.modifica, globals.rootdir + "/actions.php?" + params);
}
/**
* Funzione per gestire il download di un allegato.
* @param button
*/
function saggiungiAllegato(button) {
const gestione = $(button).closest(".gestione-allegati");
const allegato = $(button).closest("tr").data();
let params = new URLSearchParams({
op: "download-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id: allegato.id,
filename: allegato.filename,
}).toString();
window.open(globals.rootdir + "/actions.php?" + params, "_blank")
}
/**
* Funzione per l'apertura dell'anteprima di visualizzazione allegato.
* @param button
*/
function visualizzaAllegato(button) {
const allegato = $(button).closest("tr").data();
let params = new URLSearchParams({
file_id: allegato.id,
}).toString();
openModal(allegato.nome + ' <small style="color:white"><i>(' + allegato.filename + ')</i></small>', globals.rootdir + "/view.php?" + params);
}
/**
* Funzione per la gestione della rimozione di un allegato specifico.
*
* @param button
*/
function rimuoviAllegato(button) {
const gestione = $(button).closest(".gestione-allegati");
const allegato = $(button).closest("tr").data();
swal({
title: globals.translations.allegati.elimina,
type: "warning",
showCancelButton: true,
confirmButtonText: globals.translations.allegati.procedi,
}).then(function () {
mostraCaricamentoAllegati(gestione);
// Parametri della richiesta AJAX
let params = new URLSearchParams({
op: "rimuovi-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id_allegato: allegato.id,
filename: allegato.filename,
}).toString();
// Richiesta AJAX
$.ajax(globals.rootdir + "/actions.php?" + params)
.then(function () {
ricaricaAllegati(gestione);
});
}).catch(swal.noop);
}
function impostaCategorieAllegatiDisponibili(gestione, categorie) {
// Disabilitazione per rimozione input in aggiunta
return;
const id = "#" + gestione.attr('id');
const input = $("#modifica-allegato #categoria_allegato")[0];
autocomplete({
minLength: 0,
input: input,
emptyMsg: globals.translations.noResults,
fetch: function (text, update) {
text = text.toLowerCase();
const suggestions = categorie.filter(n => n.toLowerCase().startsWith(text));
// Trasformazione risultati in formato leggibile
const results = suggestions.map(function (result) {
return {
label: result,
value: result
}
});
update(results);
},
onSelect: function (item) {
input.value = item.label;
},
});
}

View File

@ -1,521 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function start_local_datatables() {
$('.datatables').each(function () {
if (!$.fn.DataTable.isDataTable($(this))) {
$(this).DataTable({
language: globals.translations.datatables,
retrieve: true,
ordering: true,
searching: true,
paging: false,
order: [],
lengthChange: false,
scrollY: "70vh",
});
}
});
}
// Datatable
function start_datatables() {
start_local_datatables();
$('.main-records').each(function () {
const $this = $(this);
// Controlla che la tabella non sia già inizializzata
if (!$.fn.DataTable.isDataTable('#' + $this.attr('id'))) {
const id_module = $this.data('idmodule');
const id_plugin = $this.data('idplugin');
const id_parent = $this.data('idparent');
// Parametri di ricerca da url o sessione
const search = getTableSearch();
const column_search = [];
$this.find("th").each(function () {
const id = $(this).attr('id').replace("th_", "");
const single_value = search["search_" + id] ? search["search_" + id] : "";
column_search.push({
"sSearch": single_value,
});
});
$this.on('preInit.dt', function (ev, settings) {
$('#mini-loader').show();
});
const table = $this.DataTable({
language: globals.translations.datatables,
autoWidth: true,
dom: "ti",
serverSide: true,
deferRender: true,
ordering: true,
searching: true,
aaSorting: [],
aoSearchCols: column_search,
scrollY: "60vh",
scrollX: '100%',
retrieve: true,
stateSave: true,
rowId: 'id',
stateSaveCallback: function (settings, data) {
sessionStorage.setItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent, JSON.stringify(data));
},
stateLoadCallback: function (settings) {
return JSON.parse(sessionStorage.getItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent));
},
columnDefs: [{
searchable: false,
orderable: false,
width: '1%',
className: 'select-checkbox',
targets: 0
}],
select: {
style: 'multi',
selector: 'td:first-child'
},
buttons: getDatatablesButtons($this),
scroller: {
loadingIndicator: true,
displayBuffer: globals.dataload_page_buffer,
},
ajax: {
url: "ajax_dataload.php?id_module=" + id_module + "&id_plugin=" + id_plugin + "&id_parent=" + id_parent,
type: 'GET',
dataSrc: "data",
},
initComplete: initComplete,
drawCallback: drawCallback,
footerCallback: footerCallback,
});
table.on('processing.dt', function (e, settings, processing) {
if (processing) {
$('#mini-loader').show();
} else {
$('#mini-loader').hide();
}
})
}
});
}
/**
* Funzione per evitare il sorting al click della colonna.
* Utilizzata per evitare il sorting nelle ricerche.
* @param {*} e
*/
function stopTableSorting(e) {
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}
/**
* Funzione per resettare il campo di ricerca in una specifica colonna.
* @param {string} type
*/
function resetTableSearch(type) {
if (type == null) $('[id^=th_] input').val('').trigger('keyup');
else $('[id^=th_' + type + '] input').val('').trigger('keyup');
}
/**
* Sostituisce i caratteri speciali per la ricerca attraverso le tabelle Datatables.
*
* @param {string} field
* @return string
*/
function searchFieldName(field) {
return field.replace(' ', '-').replace('.', '');
}
/**
* Salva nella sessione la ricerca per le tabelle Datatables.
*
* @param {int} module_id
* @param {string} field
* @param {string} value
*/
function setTableSearch(module_id, field, value) {
session_set('module_' + module_id + ',' + 'search_' + searchFieldName(field), value, 0);
}
/**
* Restituisce i valori di ricerca impostati nell'URL della pagina.
* @returns {{}}
*/
function getTableSearch() {
// Parametri di ricerca da url o sessione
const search = getUrlVars();
globals.search.forEach(function (value, index, array) {
if (search[array[index]] === undefined) {
search[array[index]] = array[value];
}
});
return search;
}
/**
* Restituisce i pulsanti da generare per la tabella Datatables.
* @returns
*/
function getDatatablesButtons(table) {
return [
// Pulsante di esportazione CSV
{
extend: 'csv',
footer: true,
fieldSeparator: ";",
exportOptions: {
modifier: {
selected: true
},
format: {
body: function (data, row, column, node) {
data = $('<p>' + data + '</p>').text();
data_edit = data.replace('.', ''); // Rimozione punto delle migliaia
return data_edit.match(/^[0-9,]+$/) ? data_edit : data;
}
}
}
},
// Pulsante di esportazione tramite copia
{
extend: 'copy',
footer: true,
exportOptions: {
modifier: {
selected: true
}
}
},
// Pulsante di esportazione via stampa della tabella
{
extend: 'print',
autoPrint: true,
footer: false, // Non funzionante in Firefox, e saltuarmente in Chrome
customize: function (win, config, datatable) {
const footer = datatable.table().footer().children[0];
const body = $(win.document.body);
body.find('table')
.addClass('compact')
.css('font-size', 'inherit')
.append(footer.cloneNode(true));
body.find('td:first-child, th:first-child')
.addClass('hide');
},
exportOptions: {
modifier: {
selected: true
}
}
},
// Pulsante di esportazione in formato Excel
{
extend: 'excel',
footer: true,
exportOptions: {
modifier: {
selected: true
},
format: {
body: function (data, row, column, node) {
data = $('<p>' + data + '</p>').text();
data_edit = data.replace('.', ''); // Fix specifico per i numeri italiani
data_edit = data_edit.replace(',', '.');
return data_edit.match(/^[0-9\.]+$/) ? data_edit : data;
}
}
}
},
// Pulsante di esportazione in formato PDF
{
extend: 'pdf',
footer: true,
exportOptions: {
modifier: {
selected: true
}
}
},
];
}
function initComplete(settings) {
const api = this.api();
const $this = $(this);
const search = getTableSearch();
api.columns('.search').every(function () {
const column = this;
// Valore predefinito della ricerca
let tempo;
const header = $(column.header());
const name = header.attr('id').replace('th_', '');
const value = search['search_' + name] ? search['search_' + name] : '';
$('<br><input type="text" style="width:100%" class="form-control' + (value ? ' input-searching' : '') + '" placeholder="' + globals.translations.filter + '..." value="' + value.replace(/"/g, '&quot;') + '"><i class="deleteicon fa fa-times fa-2x' + (value ? '' : ' hide') + '"></i>')
.appendTo(column.header())
.on('keyup', function (e) {
clearInterval(tempo);
// Fix del pulsante di pulizia ricerca e del messaggio sulla ricerca lenta
if (e.which != 9) {
if (!$(this).val()) {
if ($(this).parent().data("slow") != undefined) $("#slow").remove();
$(this).removeClass('input-searching');
$(this).next('.deleteicon').addClass('hide');
} else {
if ($(this).parent().data("slow") != undefined && $("#slow").length == 0) {
$("#" + $this.attr('id') + "_info").parent().append('<span class="text-danger" id="slow"><i class="fa fa-refresh fa-spin"></i> ' + globals.translations.long + '</span>');
}
$(this).addClass('input-searching');
$(this).next('.deleteicon').removeClass('hide');
}
}
function start_search(module_id, field, search_value) {
setTableSearch(module_id, field, search_value);
column.search(search_value).draw();
}
// Impostazione delle sessioni per le ricerche del modulo e del campo specificati
const module_id = $this.data('idmodule'); //+ "-" + $this.data('idplugin');
const field = $(this).parent().attr('id').replace('th_', '');
const value = $(this).val();
if (e.keyCode == 13 || $(this).val() == '') {
start_search(module_id, field, value);
} else {
const tempo_attesa_ricerche = (globals.tempo_attesa_ricerche * 1000);
tempo = window.setTimeout(start_search, tempo_attesa_ricerche, module_id, field, value);
}
});
});
// Disabilito l'ordinamento alla pressione del tasto invio sull'<input>
$("thead input, .search").on('keypress', function (e) {
stopTableSorting(e);
});
// Disabilito l'ordinamento al click sull'<input>
$("thead input, .deleteicon").click(function (e) {
stopTableSorting(e);
});
$('.deleteicon').on("click", function (e) {
resetTableSearch($(this).parent().attr("id").replace("th_", ""));
});
}
function drawCallback(settings) {
const table = getTable(settings.nTable);
const datatable = table.datatable;
$(".dataTables_sizing .deleteicon").addClass('hide');
$("[data-background]").each(function () {
$(this).parent().css("background", $(this).data("background"));
});
$("[data-color]").each(function () {
$(this).parent().css("color", $(this).data("color"));
});
$("[data-link]").each(function () {
const $link = $(this);
$(this).parent().not('.bound').addClass('bound').click(function (event) {
if ($link.data('type') === 'dialog') {
launch_modal(globals.translations.details, $link.data('link'));
} else {
openLink(event, $link.data('link'))
}
});
$(this).parent().addClass("clickable");
});
// Reimposto il flag sulle righe ricaricate selezionate in precedenza
const selected = table.getSelectedRows();
datatable.rows().every(function (rowIdx) {
if (selected.includes(this.id())) {
datatable.row(':eq(' + rowIdx + ')', {
page: 'current'
}).select();
}
});
}
function footerCallback(row, data, start, end, display) {
let i = -1;
const json = this.api().ajax.json();
this.api().columns().every(function () {
if (json.summable[i] !== undefined) {
$(this.footer()).addClass("text-right")
.attr("id", "summable")
.html(json.summable[i]);
}
i++;
});
}
/**
* Restituisce un oggetto che permette di gestire le tabelle DataTables.
*
* @param selector
*/
function getTable(selector) {
const table = $(selector);
const selected = new Map();
const selected_ids = table.data('selected') ? table.data('selected').split(';') : [];
selected_ids.forEach(function (item, index) {
selected.set(item, true);
});
return {
table: table,
id_module: table.data('idmodule'),
id_plugin: table.data('idplugin'),
initDatatable: function () {
if (table.hasClass('datatables')) {
start_local_datatables();
} else {
start_datatables();
}
},
datatable: table.DataTable(),
// Funzioni per i contenitori relativi alla tabella
getSelectControllerContainer: function () {
return $('.row[data-target="' + table.attr('id') + '"]').find('.select-controller-container');
},
getExportContainer: function () {
return $('.row[data-target="' + table.attr('id') + '"]').find('.export-container');
},
getActionsContainer: function () {
return $('.row[data-target="' + table.attr('id') + '"]').find('.actions-container');
},
// Gestione delle righe selezionate
selected: selected,
getSelectedRows: function () {
return Array.from(selected.keys());
},
saveSelectedRows: function () {
const selected_rows = this.getSelectedRows();
table.data('selected', selected_rows.join(';'));
// Abilitazione dinamica di azioni di gruppo e esportazione
const bulk_container = this.getActionsContainer();
const export_buttons = this.getExportContainer().find('.table-btn');
if (selected_rows.length > 0) {
bulk_container.removeClass('disabled').attr('disabled', false);
export_buttons.removeClass('disabled').attr('disabled', false);
} else {
bulk_container.addClass('disabled').attr('disabled', true);
export_buttons.addClass('disabled').attr('disabled', true);
}
// Aggiornamento contatore delle selezioni
this.getSelectControllerContainer()
.find('.selected-count').html(selected_rows.length);
// Aggiornamento del footer nel caso sia richiesto
if (globals.restrict_summables_to_selected) {
this.updateFooterForSelectedRows();
}
},
addSelectedRows: function (row_ids) {
row_ids = Array.isArray(row_ids) ? row_ids : [row_ids];
row_ids.forEach(function (item, index) {
selected.set(item.toString(), true);
});
this.saveSelectedRows();
},
removeSelectedRows: function (row_ids) {
row_ids = Array.isArray(row_ids) ? row_ids : [row_ids];
row_ids.forEach(function (item, index) {
selected.delete(item.toString());
});
this.saveSelectedRows();
},
clearSelectedRows: function () {
selected.clear();
this.saveSelectedRows();
},
/**
* Nuovi valori dei campi summable
* @returns
*/
getSelectedRowsFooter: function () {
let ids = this.getSelectedRows();
return $.ajax({
url: globals.rootdir + "/ajax.php",
type: "POST",
dataType: "json",
data: {
id_module: this.id_module,
id_plugin: this.id_plugin,
op: "summable-results",
ids: ids,
}
});
},
/**
* Aggiornamento dei campi summable
*/
updateFooterForSelectedRows: function () {
let datatable = this.datatable;
this.getSelectedRowsFooter().then(function (response) {
for (let [column, value] of Object.entries(response)) {
let index = parseInt(column) + 1;
let sel = datatable.column(index).footer();
$(sel).addClass("text-right")
.attr("id", "summable")
.html(value);
}
});
},
};
}

View File

@ -1,151 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function getCalendarIcons() {
return {
time: 'fa fa-clock-o',
date: 'fa fa-calendar',
up: 'fa fa-chevron-up',
down: 'fa fa-chevron-down',
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-street-view',
clear: 'fa fa-trash',
close: 'fa fa-times'
};
}
function initDateInput(input) {
let date_format = dateFormatMoment(globals.date_format);
let calendar_icons = getCalendarIcons();
let $input = $(input);
$(input).datetimepicker({
format: date_format,
locale: globals.locale,
icons: calendar_icons,
useCurrent: false,
minDate: moment($input.attr('min-date')).isValid() ? $input.attr('min-date') : false,
maxDate: moment($input.attr('max-date')).isValid() ? $input.attr('max-date') : false,
});
return true;
}
function initTimestampInput(input) {
let $input = $(input);
let timestamp_format = dateFormatMoment(globals.timestamp_format);
let calendar_icons = getCalendarIcons();
$input.datetimepicker({
format: timestamp_format,
locale: globals.locale,
icons: calendar_icons,
collapse: false,
sideBySide: true,
useCurrent: false,
stepping: 5,
widgetPositioning: {
horizontal: 'left',
vertical: 'auto'
},
minDate: moment($input.attr('min-date')).isValid() ? $input.attr('min-date') : false,
maxDate: moment($input.attr('max-date')).isValid() ? $input.attr('max-date') : false,
});
// fix per timestamp-picker non visibile con la classe table-responsive
$input.on("dp.show", function (e) {
$('#tecnici > div').removeClass('table-responsive');
});
$input.on("dp.hide", function (e) {
$('#tecnici > div').addClass('table-responsive');
});
return true;
}
function initTimeInput(input) {
let $input = $(input);
let time_format = dateFormatMoment(globals.time_format);
let calendar_icons = getCalendarIcons();
$input.datetimepicker({
format: time_format,
locale: globals.locale,
icons: calendar_icons,
useCurrent: false,
stepping: 5,
minDate: moment($input.attr('min-date')).isValid() ? $input.attr('min-date') : false,
maxDate: moment($input.attr('max-date')).isValid() ? $input.attr('max-date') : false,
});
return true;
}
/**
* @deprecated
*/
function start_datepickers() {
$('.timestamp-picker').each(function () {
input(this);
});
$('.datepicker').each(function () {
input(this);
});
$('.timepicker').each(function () {
input(this);
});
}
function start_complete_calendar(id, callback) {
var ranges = {};
ranges[globals.translations.today] = [moment(), moment()];
ranges[globals.translations.firstThreemester] = [moment("01", "MM"), moment("03", "MM").endOf('month')];
ranges[globals.translations.secondThreemester] = [moment("04", "MM"), moment("06", "MM").endOf('month')];
ranges[globals.translations.thirdThreemester] = [moment("07", "MM"), moment("09", "MM").endOf('month')];
ranges[globals.translations.fourthThreemester] = [moment("10", "MM"), moment("12", "MM").endOf('month')];
ranges[globals.translations.firstSemester] = [moment("01", "MM"), moment("06", "MM").endOf('month')];
ranges[globals.translations.secondSemester] = [moment("06", "MM"), moment("12", "MM").endOf('month')];
ranges[globals.translations.thisMonth] = [moment().startOf('month'), moment().endOf('month')];
ranges[globals.translations.lastMonth] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
ranges[globals.translations.thisYear] = [moment().startOf('year'), moment().endOf('year')];
ranges[globals.translations.lastYear] = [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')];
var format = dateFormatMoment(globals.date_format);
$(id).daterangepicker({
locale: {
format: format,
customRangeLabel: globals.translations.custom,
applyLabel: globals.translations.apply,
cancelLabel: globals.translations.cancel,
fromLabel: globals.translations.from,
toLabel: globals.translations.to,
},
ranges: ranges,
startDate: globals.start_date_formatted,
endDate: globals.end_date_formatted,
applyClass: 'btn btn-success btn-sm',
cancelClass: 'btn btn-danger btn-sm',
linkedCalendars: false
},
callback
);
}

View File

@ -1,249 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* @deprecated
* @param form
* @param data
* @param callback
* @param errorCallback
* @returns {*|jQuery}
*/
function submitAjax(form, data, callback, errorCallback) {
let valid = $(form).parsley().validate();
if (!valid) {
return valid;
}
if (!data) data = {};
// Lettura dei contenuti degli input
data = {...getInputsData(form), ...data};
$("#main_loading").show();
content_was_modified = false;
// Fix per gli id di default
data.id_module = data.id_module ? data.id_module : globals.id_module;
data.id_record = data.id_record ? data.id_record : globals.id_record;
data.id_plugin = data.id_plugin ? data.id_plugin : globals.id_plugin;
data.ajax = 1;
prepareForm(form);
// Invio dei dati
$(form).ajaxSubmit({
url: globals.rootdir + "/actions.php",
data: data,
type: "post",
success: function (data) {
let response = data.trim();
// Tentativo di conversione da JSON
try {
response = JSON.parse(response);
} catch (e) {
}
callback(response);
$("#main_loading").fadeOut();
renderMessages();
},
error: function (data) {
$("#main_loading").fadeOut();
toastr["error"](data);
if (errorCallback) errorCallback(data);
}
});
return valid;
}
/**
*
* @param form
*/
function prepareForm(form) {
$(form).find('input:disabled, select:disabled').prop('disabled', false);
let hash = window.location.hash;
if (hash) {
var input = $('<input/>', {
type: 'hidden',
name: 'hash',
value: hash,
});
$(form).append(input);
}
}
/**
* Funzione per la gestione delle animazioni di caricamento sui pulsanti cliccati e appositamente predisposti,
*
* @param button
* @returns {[*, *]}
*/
function buttonLoading(button) {
let $this = $(button);
let result = [
$this.html(),
$this.attr("class")
];
$this.html('<i class="fa fa-spinner fa-pulse fa-fw"></i> Attendere...');
$this.addClass("btn-warning");
$this.prop("disabled", true);
return result;
}
/**
* Funzione per ripristinare un pulsante con animazioni allo stato precedente.
*
* @param button
* @param loadingResult
*/
function buttonRestore(button, loadingResult) {
let $this = $(button);
$this.html(loadingResult[0]);
$this.attr("class", "");
$this.addClass(loadingResult[1]);
$this.prop("disabled", false);
}
/**
* Funzione per salvare i contenuti di un form via AJAX, utilizzando una struttura più recente fondata sull'utilizzo di Promise.
*
* @param button
* @param form
* @param data
* @returns {Promise<unknown>}
*/
function salvaForm(form, data = {}, button = null) {
return new Promise(function (resolve, reject) {
// Caricamento visibile nel pulsante
let restore = buttonLoading(button);
// Messaggio in caso di eventuali errori
let valid = $(form).parsley().validate();
if (!valid) {
swal({
type: "error",
title: globals.translations.ajax.missing.title,
text: globals.translations.ajax.missing.text,
});
buttonRestore(button, restore);
reject();
return;
}
// Gestione grafica di salvataggio
$("#main_loading").show();
content_was_modified = false;
// Lettura dei contenuti degli input
data = {...getInputsData(form), ...data};
data.ajax = 1;
// Fix per gli id di default
data.id_module = data.id_module ? data.id_module : globals.id_module;
data.id_record = data.id_record ? data.id_record : globals.id_record;
data.id_plugin = data.id_plugin ? data.id_plugin : globals.id_plugin;
// Invio dei dati
$.ajax({
url: globals.rootdir + "/actions.php",
data: data,
type: "POST",
success: function (data) {
let response = data.trim();
// Tentativo di conversione da JSON
try {
response = JSON.parse(response);
} catch (e) {
}
// Gestione grafica del successo
$("#main_loading").fadeOut();
renderMessages();
buttonRestore(button, restore);
resolve(response);
},
error: function (data) {
toastr["error"](data);
// Gestione grafica dell'errore
$("#main_loading").fadeOut();
swal({
type: "error",
title: globals.translations.ajax.error.title,
text: globals.translations.ajax.error.text,
});
buttonRestore(button, restore);
reject(data);
}
});
});
}
/**
* Funzione per recuperare come oggetto i contenuti degli input interni a un tag HTML.
*
* @param {HTMLElement|string|jQuery} form
* @returns {{}}
*/
function getInputsData(form) {
let place = $(form);
let data = {};
// Gestione input previsti con sistema JS integrato
let inputs = place.find('.openstamanager-input');
for (const x of inputs) {
const i = input(x);
const name = i.getElement().attr('name');
const value = i.get();
data[name] = value === undefined || value === null ? undefined : value;
}
// Gestione input HTML standard
let standardInputs = place.find(':input').not('.openstamanager-input').serializeArray();
for (const x of standardInputs) {
data[x.name] = x.value;
}
// Gestione hash dell'URL
let hash = window.location.hash;
if (hash) {
data['hash'] = hash;
}
return data;
}

View File

@ -1,608 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Modal gestito da versioni precedenti.
* @param title
* @param href
* @param init_modal
*/
function launch_modal(title, href, init_modal) {
openModal(title, href);
}
/**
* Modal.
* @param title
* @param href
*/
function openModal(title, href) {
// Fix - Select2 does not function properly when I use it inside a Bootstrap modal.
$.fn.modal.Constructor.prototype.enforceFocus = function () {
};
// Generazione dinamica modal
do {
id = '#bs-popup-' + Math.floor(Math.random() * 100);
} while ($(id).length !== 0);
if ($(id).length === 0) {
$('#modals').append('<div class="modal fade" id="' + id.replace("#", "") + '" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="true"></div>');
}
$(id).on('hidden.bs.modal', function () {
if ($('.modal-backdrop').length < 1) {
$(this).html('');
$(this).data('modal', null);
}
});
// Promise per la gestione degli eventi
const d = $.Deferred();
$(id).one('shown.bs.modal', d.resolve);
const content = '<div class="modal-dialog modal-lg">\
<div class="modal-content">\
<div class="modal-header bg-light-blue">\
<button type="button" class="close" data-dismiss="modal">\
<span aria-hidden="true">&times;</span><span class="sr-only">' + globals.translations.close + '</span>\
</button>\
<h4 class="modal-title">\
<i class="fa fa-pencil"></i> ' + title + '\
</h4>\
</div>\
<div class="modal-body">|data|</div>\
</div>\
</div>';
// Lettura contenuto div
if (href.substr(0, 1) === '#') {
const data = $(href).html();
$(id).html(content.replace("|data|", data));
$(id).modal('show');
} else {
$.get(href, function (data, response) {
if (response === 'success') {
$(id).html(content.replace("|data|", data));
$(id).modal('show');
}
});
}
return d.promise();
}
/**
*
* @param event
* @param link
*/
function openLink(event, link) {
if (event.ctrlKey) {
window.open(link);
} else {
location.href = link;
}
}
/**
* Funzione per far scrollare la pagina fino a un offset
* @param offset
*/
function scrollToOffset(offset) {
$('html,body').animate({
scrollTop: offset
}, 'slow');
}
/**
* Ritorna un array associativo con i parametri passati via GET
*/
function getUrlVars() {
let params = {};
let query = window.location.search.substring(1);
let parameterArray = query.split('&');
if (parameterArray && parameterArray.length) {
parameterArray.map(param => {
let keyValuePair = param.split('=')
let key = keyValuePair[0];
params[key] = keyValuePair[1] ? decodeURIComponent(keyValuePair[1]) : null;
})
}
return params;
}
/**
* Data e ora (orologio)
*/
function clock() {
$('#datetime').html(moment().formatPHP(globals.timestamp_format));
setTimeout('clock()', 1000);
}
/**
* Funzione per impostare un valore ad un array in $_SESSION
*/
function session_set_array(session_array, value, inversed) {
if (inversed == undefined) {
inversed = 1;
}
return $.get(globals.rootdir + "/ajax.php?op=session_set_array&session=" + session_array + "&value=" + value + "&inversed=" + inversed);
}
/**
* Funzione per impostare un valore ad una sessione
*/
function session_set(session_array, value, clear, reload) {
if (clear === undefined) {
clear = 1;
}
if (reload === undefined) {
reload = 0;
}
return $.get(globals.rootdir + "/ajax.php?op=session_set&session=" + session_array + "&value=" + value + "&clear=" + clear, function (data, status) {
if (reload === 1) {
location.reload();
}
});
}
function session_keep_alive() {
$.get(globals.rootdir + '/core.php');
}
function setContrast(backgroundcolor) {
var rgb = [];
var bg = String(backgroundcolor);
// ex. backgroundcolor = #ffc400
rgb[0] = bg.substr(1, 2);
rgb[1] = bg.substr(2, 2);
rgb[2] = bg.substr(5, 2);
var R1 = parseInt(rgb[0], 16);
var G1 = parseInt(rgb[1], 16);
var B1 = parseInt(rgb[2], 16);
var R2 = 255;
var G2 = 255;
var B2 = 255;
var L1 = 0.2126 * Math.pow(R1 / 255, 2.2) + 0.7152 * Math.pow(G1 / 255, 2.2) + 0.0722 * Math.pow(B1 / 255, 2.2);
var L2 = 0.2126 * Math.pow(R2 / 255, 2.2) + 0.7152 * Math.pow(G2 / 255, 2.2) + 0.0722 * Math.pow(B2 / 255, 2.2);
if (L1 > L2) {
var lum = (L1 + 0.05) / (L2 + 0.05);
} else {
var lum = (L2 + 0.05) / (L1 + 0.05);
}
if (lum >= 9) {
return "#ffffff";
} else {
return "#000000";
}
}
function message(element) {
data = $.extend({}, $(element).data());
var title = globals.translations.deleteTitle;
if (data["title"] != undefined) title = data["title"];
var msg = globals.translations.deleteMessage;
if (data["msg"] != undefined) msg = data["msg"];
var button = globals.translations.delete;
if (data["button"] != undefined) button = data["button"];
var btn_class = "btn btn-lg btn-danger";
if (data["class"] != undefined) btn_class = data["class"];
swal({
title: title,
html: '<div id="swal-form" data-parsley-validate>' + msg + '</div>',
type: "warning",
showCancelButton: true,
confirmButtonText: button,
confirmButtonClass: btn_class,
onOpen: function () {
restart_inputs();
},
preConfirm: function () {
$form = $('#swal-form');
$form.find(':input').each(function () {
data[$(this).attr('name')] = $(this).val();
});
if ($form.parsley().validate()) {
return new Promise(function (resolve) {
resolve();
});
} else {
$('.swal2-buttonswrapper button').each(function () {
$(this).prop('disabled', false);
});
}
}
}).then(
function () {
if (data["op"] == undefined) data["op"] = "delete";
var href = window.location.href.split("#")[0];
if (data["href"] != undefined) {
href = data["href"];
delete data.href;
}
var hash = window.location.href.split("#")[1];
if (hash) {
data["hash"] = hash;
}
method = "post";
if (data["method"] != undefined) {
if (data["method"] == "post" || data["method"] == "get") {
method = data["method"];
}
delete data.method;
}
blank = data.blank != undefined && data.blank;
delete data.blank;
if (data.callback) {
$.ajax({
type: method,
crossDomain: true,
url: href,
data: data,
beforeSend: function (response) {
var before = window[data.before];
if (typeof before === 'function') {
before(response);
}
},
success: function (response) {
var callback = window[data.callback];
if (typeof callback === 'function') {
callback(response);
}
},
error: function (xhr, ajaxOptions, error) {
swal({
title: globals.translations.errorTitle,
html: globals.translations.errorMessage,
type: "error",
})
},
});
} else {
redirect(href, data, method, blank);
}
},
function (dismiss) {
}
);
}
function redirect(href, data, method, blank) {
method = method ? method : "get";
blank = blank ? blank : false;
if (method == "post") {
var text = '<form action="' + href + window.location.hash + '" method="post"' + (blank ? ' target="_blank"' : '') + '>';
for (var name in data) {
text += '<input type="hidden" name="' + name + '" value="' + data[name] + '"/>';
}
text += '</form>';
var form = $(text);
$('body').append(form);
form.submit();
} else {
var values = [];
for (var name in data) {
values.push(name + '=' + data[name]);
}
var link = href + (href.indexOf('?') !== -1 ? '&' : '?') + values.join('&') + window.location.hash;
if (!blank) {
location.href = link;
} else {
window.open(link);
}
}
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
/**
* Visualizzazione dei messaggi attivi tramite toastr.
*/
function renderMessages() {
$.ajax({
url: globals.rootdir + '/ajax.php',
type: 'get',
dataType: 'JSON',
data: {
op: 'flash',
},
success: function (messages) {
let info = messages.info ? messages.info : [];
info.forEach(function (element) {
if (element) toastr["success"](element);
});
let warning = messages.warning ? messages.warning : [];
warning.forEach(function (element) {
if (element) toastr["warning"](element);
});
let error = messages.error ? messages.error : [];
error.forEach(function (element) {
if (element) toastr["error"](element);
});
}
});
}
/**
* Rimuove l'hash dall'URL corrente.
*/
function removeHash() {
history.replaceState(null, null, ' ');
}
/**
*
* @param str
* @param find
* @param replace
* @returns {*}
*/
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, "g"), replace);
}
/**
* @deprecated
*/
function cleanup_inputs() {
$('.bound').removeClass("bound");
$('.superselect, .superselectajax').each(function () {
let $this = $(this);
if ($this.data('select2')) {
input(this).destroy();
}
});
}
/**
* @deprecated
*/
function restart_inputs() {
// Generazione degli input
$('.openstamanager-input').each(function () {
input(this);
});
}
/**
* Messaggio di avviso salvataggio a comparsa sulla destra solo nella versione a desktop intero
*/
function alertPush() {
if ($(window).width() > 1023) {
let i = 0;
$('.alert-success.push').each(function () {
i++;
tops = 60 * i + 95;
$(this).css({
'position': 'fixed',
'z-index': 3000,
'right': '10px',
'top': -100,
}).delay(1000).animate({
'top': tops,
}).delay(3000).animate({
'top': -100,
});
});
}
// Nascondo la notifica se passo sopra col mouse
$('.alert-success.push').on('mouseover', function () {
$(this).stop().animate({
'top': -100,
'opacity': 0
});
});
}
/**
* Funzione per l'apertura del messaggi di rimozione elemento standard.
*
* @param button
* @param title
* @param message
* @returns {*}
*/
function confirmDelete(button, title, message) {
return swal({
title: title ? title : globals.translations.deleteTitle,
html: message ? message : globals.translations.deleteMessage,
type: "warning",
showCancelButton: true,
confirmButtonText: globals.translations.delete,
confirmButtonClass: "btn btn-lg btn-danger",
})
}
/**
* Nasconde una specifica colonna di una tabella indicata.
*
* @param table
* @param column
*/
function hideTableColumn(table, column) {
column = "" + column; // Cast a stringa
// Verifica sulle colonne nascoste in precedenza
let hiddenColumns = table.getAttribute("hidden-columns");
hiddenColumns = hiddenColumns ? hiddenColumns.split(",") : [];
if (hiddenColumns.includes(column)) {
return;
}
// Salvataggio delle colonne nascoste
hiddenColumns.push(column);
table.setAttribute("hidden-columns", hiddenColumns.join(","));
let rows = table.rows;
for (let row of rows) {
let currentColumn = 1;
for (let i = 0; i < row.cells.length; i++) {
let cell = row.cells[i];
// Individuazione del colspan
let colspan = parseInt(cell.getAttribute("colspan"));
let hiddenColspan = cell.getAttribute("colspan-hidden");
hiddenColspan = parseInt(hiddenColspan ? hiddenColspan : 0);
let totalColspan = colspan + hiddenColspan;
// Gestione dell'operazione nel caso di cella multipla
if (totalColspan && totalColspan > 1) {
if (column >= currentColumn && column <= currentColumn + totalColspan - 1) {
cell.setAttribute("colspan", colspan - 1);
cell.setAttribute("colspan-hidden", hiddenColspan + 1);
// Cella nascosta nel caso colspan sia nullo
if (colspan - 1 === 0) {
cell.classList.add("hidden");
}
}
currentColumn += totalColspan;
}
// Gestione di una cella normale
else {
if (column === "" + currentColumn) {
cell.classList.add("hidden");
}
currentColumn++;
}
}
}
}
/**
* Funzione per aggiungere in un *endpoint* il contenuto di uno specifico *template*, effettuando delle sostituzioni di base e inizializzando i campi aggiunti.
*
* @param {string|jQuery|HTMLElement} endpoint_selector
* @param {string|jQuery|HTMLElement} template_selector
* @param {object} replaces
* @param {boolean} prepend
* @returns {*|jQuery|HTMLElement}
*/
function aggiungiContenuto(endpoint_selector, template_selector, replaces = {}, prepend = false) {
let template = $(template_selector);
let endpoint = $(endpoint_selector);
// Distruzione degli input interni
template.find('.openstamanager-input').each(function () {
input(this).destroy();
});
// Contenuto da sostituire
let content = template.html();
for ([key, value] of Object.entries(replaces)) {
content = replaceAll(content, key, value);
}
// Aggiunta del contenuto
let element = $(content);
if (prepend) {
endpoint.prepend(element);
} else {
endpoint.append(element);
}
// Rigenerazione degli input interni
element.find('.openstamanager-input').each(function () {
input(this).trigger("change");
});
return element;
}
/**
* Funzione per forzare l'apertura di uno specifico tab senza un relativo cambiamento di URL.
*
* @param {HTMLElement} link
*/
function apriTab(link) {
let element = $(link).closest("li");
let parent = element.closest(".nav-tabs-custom");
parent.find("ul > li").removeClass("active");
element.addClass("active");
let tab = $(link).data("tab");
parent.find(".tab-pane").removeClass("active");
parent.find(".tab-pane#" + tab).addClass("active");
}

View File

@ -1,230 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
*
*/
function startHooks() {
$.ajax({
url: globals.rootdir + "/ajax.php",
type: "get",
data: {
op: "hooks",
},
success: function (data) {
hooks = JSON.parse(data);
$("#hooks-header").text(globals.translations.hooksExecuting);
$("#hooks-number").text(hooks.length);
if (hooks.length == 0) {
$("#hooks-loading").hide();
$("#hooks-number").text(0);
$("#hooks-header").text(globals.translations.hookNone);
}
hooks.forEach(function (item, index) {
renderHook(item, {
show: true,
message: globals.translations.hookExecuting.replace('_NAME_', item.name)
});
startHook(item, true);
});
},
});
}
/**
* Richiama l'hook per l'esecuzione.
*
* @param hook
*/
function startHook(hook, init) {
$.ajax({
url: globals.rootdir + "/ajax.php",
type: "get",
data: {
op: "hook-lock",
id: hook.id,
},
success: function (data) {
var token = JSON.parse(data);
if (init) {
hookCount("#hooks-counter");
updateHook(hook);
}
if (token) {
executeHook(hook, token);
} else {
var timeout = 10;
setTimeout(function () {
startHook(hook);
}, timeout * 1000);
}
},
});
}
/**
* Richiama l'hook per l'esecuzione.
*
* @param hook
* @param token
*/
function executeHook(hook, token) {
$.ajax({
url: globals.rootdir + "/ajax.php",
type: "get",
data: {
op: "hook-execute",
id: hook.id,
token: token,
},
success: function (data) {
var result = JSON.parse(data);
updateHook(hook);
var timeout;
if (result.execute) {
startHook(hook);
} else {
timeout = 30;
setTimeout(function () {
startHook(hook);
}, timeout * 1000);
}
},
});
}
/**
* Aggiorna le informazioni dell'hook.
*
* @param hook
* @param init
*/
function updateHook(hook) {
$.ajax({
url: globals.rootdir + "/ajax.php",
type: "get",
data: {
op: "hook-response",
id: hook.id,
},
success: function (data) {
var result = JSON.parse(data);
renderHook(hook, result);
// Rimozione eventuale della rotella di caricamento
var counter = $("#hooks-counter").text();
var number = $("#hooks > li").length;
if (number == 0) {
$("#hooks-notified").html('<i class="fa fa-check" aria-hidden="true"></i>');
$("#hooks-label").removeClass();
$("#hooks-label").addClass('label').addClass('label-success');
} else {
$("#hooks-notified").text(number);
$("#hooks-label").removeClass();
$("#hooks-label").addClass('label').addClass('label-danger');
}
if (counter == $("#hooks-number").text()) {
$("#hooks-loading").hide();
var hookMessage;
if (number > 1) {
hookMessage = globals.translations.hookMultiple.replace('_NUM_', number);
} else if (number == 1) {
hookMessage = globals.translations.hookSingle;
} else {
hookMessage = globals.translations.hookNone;
}
$("#hooks-header").text(hookMessage);
}
},
});
}
/**
* Aggiunta dell'hook al numero totale.
*/
function hookCount(id, value) {
value = value ? value : 1;
var element = $(id);
var number = parseInt(element.text());
number = isNaN(number) ? 0 : number;
number += value;
element.text(number);
return number;
}
/**
* Genera l'HTML per la visualizzazione degli hook.
*
* @param element_id
* @param result
*/
function renderHook(hook, result) {
if (result.length == 0) return;
var element_id = "hook-" + hook.id;
// Inizializzazione
var element = $("#" + element_id);
if (element.length == 0) {
$("#hooks").append('<li class="hook-element" id="' + element_id + '"></li>');
element = $("#" + element_id);
}
// Rimozione
if (!result.show) {
element.remove();
return;
}
// Contenuto
var content = '<a href="' + (result.link ? result.link : "#") + '"><i class="' + result.icon + '"></i><span class="small"> ' + result.message + '</span>';
if (result.progress) {
var current = result.progress.current;
var total = result.progress.total;
var percentage = current / total * 100;
percentage = isNaN(percentage) ? 100 : percentage;
percentage = Math.round(percentage * 100) / 100;
content += '<div class="progress" style="margin-bottom: 0px;"><div class="progress-bar" role="progressbar" aria-valuenow="' + percentage + '" aria-valuemin="0" aria-valuemax="100" style="width:' + percentage + '%">' + percentage + '% (' + current + '/' + total + ')</div></div>';
}
content += '</a>';
element.html(content);
}

View File

@ -1,71 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function init() {
// Inizializzazzione dei box AdminLTE
$('.box').boxWidget();
// Modal di default
$('[data-href]').not('.ask, .bound').click(function () {
launch_modal($(this).data('title'), $(this).data('href'), 1);
});
$('[data-href]').not('.ask, .bound').addClass('bound clickable');
// Tooltip
$('.tip').not('.tooltipstered').each(function () {
$this = $(this);
$this.tooltipster({
animation: 'grow',
contentAsHTML: true,
hideOnClick: true,
onlyOne: true,
maxWidth: 350,
touchDevices: true,
trigger: 'hover',
position: $this.data('position') ? $this.data('position') : 'top',
});
});
if ($('form').length) {
$('form').not('.no-check').parsley();
}
// Aggiunta nell'URL del nome tab su cui tornare dopo il submit
// Blocco del pulsante di submit dopo il primo submit
$('form').on("submit", function (e) {
if ($(this).parsley().validate() && (e.result == undefined || e.result)) {
$(this).submit(function () {
return false;
});
$(this).find('[type=submit]').prop("disabled", true).addClass("disabled");
prepareForm(this);
return true;
}
return false;
});
window.Parsley.on('field:success', function () {
this.$element.removeClass('parsley-success');
});
restart_inputs();
}

View File

@ -1,411 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Funzione semplificata per accedere ad uno specifico input.
* Accetta un oggetto jQuery, oppure un elemento JS HTMLElement, oppure il nome dell'input di interesse.
*
* Attenzione: in caso di molteplici input individuati, viene restituito l'ultimo individuato.
*
* @param {string|jQuery|HTMLElement} name
* @returns {Input|*}
*/
function input(name) {
let element;
// Selezione tramite jQuery
if (name instanceof jQuery) {
element = name.last();
}
// Selezione tramite JS diretto
else if (isElement(name)) {
element = $(name);
}
// Selezione per nome
else {
element = $("[name='" + name + "']").last();
// Fix per select multipli
if (element.length === 0) {
element = $("[name='" + name + "[]']").last();
}
}
if (!element.data("input-controller")) {
return new Input(element);
} else {
const controller = element.data("input-controller");
if (!element.data("input-init")) {
controller.init();
}
return controller;
}
}
/**
*
* @constructor
* @param {jQuery} element
*/
function Input(element) {
this.element = element;
this.element.data("input-controller", this);
this.element.data("required", this.element.attr("required"));
this.init();
}
/**
* Effettua le operazioni di inizializzazione sull'input in base alla relativa tipologia.
*/
Input.prototype.init = function () {
let initCompleted = false;
let htmlElement = this.element[0];
// Operazioni di inizializzazione per input specifici
// Inizializzazione per date
if (this.element.hasClass('timestamp-picker')) {
initCompleted = initTimestampInput(htmlElement);
} else if (this.element.hasClass('datepicker')) {
initCompleted = initDateInput(htmlElement);
} else if (this.element.hasClass('timepicker')) {
initCompleted = initTimeInput(htmlElement);
}
// Inizializzazione per campi numerici
else if (this.element.hasClass('number-input')) {
initCompleted = initNumberInput(htmlElement);
}
// Inizializzazione per textarea
else if (this.element.hasClass('editor-input')) {
initCompleted = initEditorInput(htmlElement);
}
// Inizializzazione per textarea
else if (this.element.hasClass('autosize') || this.element.attr('maxlength')) {
if (this.element.hasClass('autosize'))
initCompleted = initTextareaInput(htmlElement);
if (htmlElement.hasAttribute('charcounter'))
initCompleted = initCharCounter(htmlElement);
}
// Inizializzazione per select
else if (this.element.hasClass('select-input')) {
initCompleted = initSelectInput(htmlElement);
}
// Inizializzazione alternativa per maschere
else {
initCompleted = initMaskInput(htmlElement);
}
this.element.data("input-init", !!initCompleted);
}
/**
* Restituisce l'elemento jQuery che rappresenta l'input.
*
* @returns {jQuery}
*/
Input.prototype.getElement = function () {
return this.element;
}
/**
* Gestisce l'abilitazione e la disibilitazione dell'input sulla base del valore indicato.
*
* @param {boolean} value
* @returns {Input}
*/
Input.prototype.setDisabled = function (value) {
if (value) {
return this.disable();
} else {
return this.enable();
}
}
/**
* Disabilita l'input all'utilizzo grafico.
*
* @returns {Input}
*/
Input.prototype.disable = function () {
this.element.addClass("disabled")
.attr("disabled", true)
.attr("readonly", false)
.attr("required", false);
let group = this.element.closest(".form-group");
// Disabilitazione eventuali pulsanti relativi
group.find("button")
.addClass("disabled");
// Disabilitazione per checkbox
group.find(".btn-group label")
.addClass("disabled");
group.find("input[type=checkbox]")
.attr("disabled", true)
.attr("readonly", false)
.addClass("disabled");
// Gestione dell'editor
if (this.element.hasClass("editor-input")) {
const name = this.element.attr("id");
CKEDITOR.instances[name].setReadOnly(true);
}
return this;
}
/**
* Abilita l'input all'utilizzo grafico.
*
* @returns {Input}
*/
Input.prototype.enable = function () {
this.element.removeClass("disabled")
.attr("disabled", false)
.attr("readonly", false)
.attr("required", this.element.data("required"));
let group = this.element.closest(".form-group");
// Abilitazione eventuali pulsanti relativi
group.find("button")
.removeClass("disabled");
// Abilitazione per checkbox
group.find(".btn-group label")
.removeClass("disabled");
group.find("input[type=checkbox]")
.attr("disabled", false)
.attr("readonly", false)
.removeClass("disabled");
// Gestione dell'editor
if (this.element.hasClass("editor-input")) {
const name = this.element.attr("id");
CKEDITOR.instances[name].setReadOnly(false);
}
return this;
}
/**
* Controlla se l'input è disabilitato.
*
* @returns {boolean}
*/
Input.prototype.isDisabled = function () {
return this.element.hasClass("disabled")
}
/**
* Restituisce un oggetto cotentente le caratteristiche dell'input.
*
* @returns {{value: (string|number)}|jQuery|any}
*/
Input.prototype.getData = function () {
if (this.element.is('select')) {
return this.element.selectData();
}
return {
value: this.get()
};
}
/**
* Restituisce il valore corrente dell'input.
*
* @returns {string|number}
*/
Input.prototype.get = function () {
let value = this.element.val();
// Gestione dei valori per select
if (this.element.hasClass("select-input")) {
value = value ? value : null;
}
// Gestione dei valori per l'editor
if (this.element.hasClass("editor-input")) {
const name = this.element.attr("id");
value = typeof CKEDITOR !== 'undefined' ? CKEDITOR.instances[name].getData() : value;
}
// Conversione del valore per le checkbox
let group = this.element.closest(".form-group");
if (group.find("input[type=checkbox]").length) {
return parseInt(value) ? 1 : 0;
}
// Gestione dei valori numerici
if (this.element.hasClass("number-input")) {
const autonumeric = this.element.data("autonumeric");
if (autonumeric) {
return parseFloat(autonumeric.rawValue);
}
// In attesa dell'inizializzazione per autonumeric, il valore registrato è interpretabile
else {
return parseFloat(value);
}
}
return value;
}
/**
* Imposta il valore per l'input.
*
* @param value
* @returns {Input}
*/
Input.prototype.set = function (value) {
// Gestione dei valori per l'editor
if (this.element.hasClass("editor-input") && typeof CKEDITOR !== 'undefined') {
const name = this.element.attr("id");
CKEDITOR.instances[name].setData(value);
} else {
this.element.val(value).trigger("change");
}
return this;
}
/**
* Imposta l'input per essere obbligatorio o meno.
* @param {bool} value
* @returns {Input}
*/
Input.prototype.setRequired = function (value) {
this.element.attr("required", value)
.data("required", value);
return this;
}
// Eventi permessi
/**
* Gestisce gli eventi di tipologia "change".
*
* @param callable
* @returns {Input}
*/
Input.prototype.change = function (callable) {
this.on("change", callable)
return this;
}
/**
* Gestisce l'ascolto a uno specifico evento sulla base dell'oggetto jQuery.
*
* @param {string} event
* @param callable
*
* @returns {Input}
*/
Input.prototype.on = function (event, callable) {
this.element.on(event, callable);
return this;
}
/**
* Gestisce la rimozione degli ascoltatori attivi per uno specifico evento sulla base dell'oggetto jQuery.
*
* @param {string} event
*
* @returns {Input}
*/
Input.prototype.off = function (event) {
this.element.off(event);
return this;
}
/**
* Effettua il trigger di uno specifico evento sull'input.
* @param {string} event
* @param callable
* @returns {Input}
*/
Input.prototype.trigger = function (event, callable) {
this.element.trigger(event, callable);
return this;
}
/**
* Distrugge il gestore attuale per l'input e ne disabilita le funzionalità previste.
*/
Input.prototype.destroy = function () {
if (this.element.data('select2')) {
this.element.select2().select2("destroy")
}
// Gestione della distruzione per l'editor
if (this.element.hasClass("editor-input")) {
const name = this.element.attr("id");
CKEDITOR.instances[name].destroy();
}
this.element.data("input-controller", null);
this.element.data("input-init", false);
}
/**
* Returns true if it is a DOM node.
*
* @param o
* @returns boolean
*
* @source https://stackoverflow.com/a/384380
*/
function isNode(o) {
return (
typeof Node === "object" ? o instanceof Node :
o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"
);
}
/**
* Returns true if it is a DOM element.
*
* @param o
* @returns boolean
*
* @source https://stackoverflow.com/a/384380
*/
function isElement(o) {
return (
typeof HTMLElement === "object" ? o instanceof HTMLElement : // DOM2
o && typeof o === "object" && o.nodeType === 1 && typeof o.nodeName === "string"
);
}

View File

@ -1,71 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Funzione per l'inizializzazione delle maschere sui campi impostati.
* @param input
*/
function initMaskInput(input) {
let $input = $(input);
if ($input.hasClass('email-mask')) {
$input.inputmask('Regex', {
regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$",
});
} else if ($input.hasClass('rea-mask')) {
$input.inputmask({
mask: "AA-999999{1,15}",
casing: "upper",
});
} else if ($input.hasClass('provincia-mask')) {
$input.inputmask({
mask: "AA",
casing: "upper",
});
} else if ($input.hasClass('alphanumeric-mask')) {
$input.inputmask('Regex', {
regex: "[A-Za-z0-9#_|\/\\-.]*",
});
} else if ($input.hasClass('math-mask')) {
$input.inputmask('Regex', {
regex: "[0-9,.+\-]*",
});
}
return true;
}
/**
* Inputmask.
*
* @param element
*/
function start_inputmask(element) {
if (element === undefined) {
element = '';
} else {
element = element + ' ';
}
let masks = ['math-mask', 'alphanumeric-mask', 'provincia-mask', 'rea-mask', 'email-mask'];
let selector = element + '.' + masks.join(', ' + element + '.')
$(selector).each(function () {
input(this);
});
}

View File

@ -1,70 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Funzione per gestire il loader locale per uno specifico DIV.
*
* @param div Identificatore JS dell'elemento
* @param show
*/
function localLoading(div, show) {
let container = $(div);
// Ricerca del loader esistente
let loader = container.find(".panel-loading");
// Aggiunta del loader in caso di assenza
if (!loader.length) {
let html = `<div class="text-center hidden local-loader">
<div class="local-loader-content">
<i class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
<span class="sr-only">
` + globals.translations.loading + `
</span>
</div>
</div>`;
container.prepend(html);
loader = container.find(".local-loader");
}
// Visualizzazione del loader
if (show) {
loader.removeClass("hidden");
container.addClass("div-loading");
}
// Rimozione del loader
else {
loader.addClass("hidden");
container.removeClass("div-loading");
}
}
/**
* Funzione per gestire la visualizzazione del loader generale del gestionale.
* @param show
*/
function mainLoader(show) {
let loader = $("#main_loading");
if (show) {
loader.show();
} else {
loader.fadeOut();
}
}

View File

@ -1,93 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function dateFormatMoment(format) {
/*
* PHP => moment.js
* Will take a php date format and convert it into a JS format for moment
* http://www.php.net/manual/en/function.date.php
* http://momentjs.com/docs/#/displaying/format/
*/
var formatMap = {
d: 'DD',
D: 'ddd',
j: 'D',
l: 'dddd',
N: 'E',
S: function () {
return '[' + moment().format('Do').replace(/\d*/g, '') + ']';
},
w: 'd',
z: function () {
return moment().format('DDD') - 1;
},
W: 'W',
F: 'MMMM',
m: 'MM',
M: 'MMM',
n: 'M',
t: function () {
return moment().daysInMonth();
},
L: function () {
return moment().isLeapYear() ? 1 : 0;
},
o: 'GGGG',
Y: 'YYYY',
y: 'YY',
a: 'a',
A: 'A',
B: function () {
var thisUTC = moment().clone().utc(),
// Shamelessly stolen from http://javascript.about.com/library/blswatch.htm
swatch = ((thisUTC.hours() + 1) % 24) + (thisUTC.minutes() / 60) + (thisUTC.seconds() / 3600);
return Math.floor(swatch * 1000 / 24);
},
g: 'h',
G: 'H',
h: 'hh',
H: 'HH',
i: 'mm',
s: 'ss',
u: '[u]', // not sure if moment has this
e: '[e]', // moment does not have this
I: function () {
return moment().isDST() ? 1 : 0;
},
O: 'ZZ',
P: 'Z',
T: '[T]', // deprecated in moment
Z: function () {
return parseInt(moment().format('ZZ'), 10) * 36;
},
c: 'YYYY-MM-DD[T]HH:mm:ssZ',
r: 'ddd, DD MMM YYYY HH:mm:ss ZZ',
U: 'X'
};
var formatEx = /[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]/g;
return format.replace(formatEx, function (phpStr) {
return typeof formatMap[phpStr] === 'function' ? formatMap[phpStr].call(that) : formatMap[phpStr];
})
}
(function (m) {
moment.fn.formatPHP = function (format) {
return this.format(dateFormatMoment(format));
};
}(moment));

View File

@ -1,67 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Funzione per inizializzare i campi di input numerici per la gestione integrata del formato impostato per il gestionale.
*
* @deprecated
*/
function initNumbers() {
$('.number-input').each(function () {
input(this);
});
}
/**
* Funzione per l'inizializzazione dei campi numerici.
* @param input
*/
function initNumberInput(input) {
let $input = $(input);
if (AutoNumeric.isManagedByAutoNumeric(input)) {
return true;
}
let min = $input.attr('min-value') && $input.attr('min-value') !== "undefined" ? $input.attr('min-value') : null;
let max = $input.attr('max-value') && $input.attr('max-value') !== "undefined" ? $input.attr('max-value') : null;
let decimals = $input.attr('decimals') ? $input.attr('decimals') : globals.cifre_decimali;
let autonumeric = new AutoNumeric(input, {
caretPositionOnFocus: "decimalLeft",
allowDecimalPadding: true,
currencySymbolPlacement: "s",
negativePositiveSignPlacement: "p",
decimalCharacter: globals.decimals,
decimalCharacterAlternative: ".",
digitGroupSeparator: globals.thousands,
emptyInputBehavior: min ? min : "zero",
overrideMinMaxLimits: "ignore",
modifyValueOnWheel: false,
outputFormat: "string",
unformatOnSubmit: true,
watchExternalChanges: true,
minimumValue: min ? min : "-10000000000000",
maximumValue: max ? max : "10000000000000",
decimalPlaces: decimals,
});
$input.data("autonumeric", autonumeric);
return true;
}

View File

@ -1,25 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
String.prototype.toEnglish = function () {
return numeral(this.toString()).value();
};
Number.prototype.toLocale = function () {
return numeral(this).format();
};

View File

@ -1,344 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Select.
*
* @deprecated
*/
function start_superselect() {
$('.superselect, .superselectajax').each(function () {
input(this);
});
}
/**
* Gestisce le operazioni di rendering per una singola opzione del select.
*
* @param data
* @param container
* @returns {*}
*/
function optionRendering(data, container) {
// Aggiunta degli attributi impostati staticamente
selectOptionAttributes(data);
// Impostazione del colore dell'opzione
let bg;
if (data._bgcolor_) {
bg = data._bgcolor_;
} else if ($(data.element).attr("_bgcolor_")) {
bg = $(data.element).attr("_bgcolor_");
} else if ($(data.element).data("_bgcolor_")) {
bg = $(data.element).data("_bgcolor_");
}
if (bg && !$("head").find('#' + data._resultId + '_style').length) {
$(container).css("background-color", bg);
$(container).css("color", setContrast(bg));
}
return data.text;
}
/**
* Gestisce le operazioni di rendering per le opzioni selezionate del select.
*
* @param data
* @returns {*}
*/
function selectionRendering(data) {
// Aggiunta degli attributi impostati staticamente
selectOptionAttributes(data);
return data.text;
}
/**
* Gestisce le operazioni per l'impostazione dinamica degli attributi per una singola opzione del select.
*
* @param data
* @returns {void}
*/
function selectOptionAttributes(data) {
// Aggiunta degli attributi impostati staticamente
let attributes = $(data.element).data("select-attributes");
if (attributes) {
for ([key, value] of Object.entries(attributes)) {
data[key] = value;
}
}
}
/**
* Reimposta i contenuti di un <select> creato con select2.
*/
jQuery.fn.selectClear = function () {
this.val([]).trigger("change");
return this;
};
/**
* Resetta i contenuti di un <select> creato con select2.
*/
jQuery.fn.selectReset = function (placeholder) {
this.selectClear();
this.empty();
if (placeholder !== undefined) {
this.next().find('.select2-selection__placeholder').text(placeholder);
this.next().find('input.select2-search__field').attr('placeholder', placeholder);
}
return this;
};
/**
* Aggiorna un <select> creato con select2 impostando un valore di default.
* Da utilizzare per l'impostazione dei select basati su richieste AJAX.
*/
jQuery.fn.selectSetNew = function (value, label, data) {
// Fix selezione per valori multipli
let values = this.val();
if (this.prop("multiple")) {
values.push(value);
} else {
this.selectReset();
values = value;
}
this.selectAdd([{
'value': value,
'text': label,
'data': data,
}]);
this.selectSet(values);
return this;
};
/**
* Aggiorna un <select> creato con select2 impostando un valore di default.
* Da utilizzare per l'impostazione dei select statici.
*/
jQuery.fn.selectSet = function (value) {
this.val(value).trigger("change");
return this;
};
/**
* Aggiorna un <select> creato con select2 impostando un valore di default
*/
jQuery.fn.selectAdd = function (values) {
let $this = this;
values.forEach(function (item) {
if (item.data) {
item['data-select-attributes'] = JSON.stringify(item.data);
// Retrocompatibilità per l'uso del attributo data su selectData
Object.keys(item.data).forEach(function (element) {
item['data-' + element] = item.data[element];
});
}
delete item.data;
const option = $('<option/>', item);
$this.append(option);
});
return this;
};
/**
* Restituisce l'oggetto contenente gli attributi di una <option> generata da select2.
*/
jQuery.fn.selectData = function () {
let selectData = this.select2('data');
if (this.prop('multiple')) {
return selectData;
} else if (selectData.length !== 0 && selectData[0].id) {
return selectData[0];
}
return undefined;
};
/**
* Imposta il valore di un'opzione di un <select> creato con select2.
*/
jQuery.fn.setSelectOption = function (name, value) {
this.data('select-options')[name] = value;
return this;
};
/**
* Restituisce il valore impostato per un'opzione di un <select> creato con select2.
*/
jQuery.fn.getSelectOption = function (name) {
return this.data('select-options')[name];
};
/**
* Imposta il valore di un opzioni per tutti i select attivi della pagina.
*
* @param name
* @param value
*/
function updateSelectOption(name, value) {
$(".superselectajax").each(function () {
$(this).setSelectOption(name, value);
})
}
/**
* Funzione per l'inizializzazione automatica del select.
*
* @param input
*/
function initSelectInput(input) {
let $input = $(input);
if ($input.hasClass('superselect')) {
initStaticSelectInput(input);
} else {
initDynamicSelectInput(input);
}
return $input.data('select2');
}
/**
* Funzione per l'inizializzazione del select statico.
*
* @param input
*/
function initStaticSelectInput(input) {
let $input = $(input);
$input.select2({
theme: "bootstrap",
language: "it",
width: '100%',
maximumSelectionLength: $input.data('maximum') ? $input.data('maximum') : -1,
minimumResultsForSearch: $input.hasClass('no-search') ? -1 : 0,
allowClear: !$input.hasClass('no-search'),
escapeMarkup: function (text) {
return text;
},
templateResult: optionRendering,
templateSelection: selectionRendering,
});
}
/**
* Funzione per l'inizializzazione del select dinamico.
*
* @param input
*/
function initDynamicSelectInput(input) {
let $input = $(input);
$input.select2({
theme: "bootstrap",
language: "it",
maximumSelectionLength: $input.data('maximum') ? $input.data('maximum') : -1,
minimumInputLength: $input.data('heavy') ? 3 : 0,
allowClear: true,
escapeMarkup: function (text) {
return text;
},
templateResult: optionRendering,
templateSelection: selectionRendering,
ajax: {
url: globals.rootdir + "/ajax_select.php?op=" + $input.data('source'),
dataType: 'json',
delay: 250,
data: function (params) {
return {
search: params.term,
page: params.page || 0,
length: params.length || 100,
options: this.data('select-options'), // Dati aggiuntivi
};
},
processResults: function (data, params) {
params.page = params.page || 0;
params.length = params.length || 100;
let results = data.results;
// Interpretazione forzata per campi optgroup
if (results && results[0] && results[0]['optgroup']) {
let groups = results.reduce(function (r, a) {
r[a.optgroup] = r[a.optgroup] || [];
r[a.optgroup].push(a);
return r;
}, {});
let results_groups = [];
for ([key, results] of Object.entries(groups)) {
results_groups.push({
text: key,
children: groups[key],
});
}
results = results_groups;
}
return {
results: results,
pagination: {
more: (params.page + 1) * params.length < data.recordsFiltered,
}
};
},
cache: false
},
width: '100%'
});
// Rimozione delle option presenti nell'HTML per permettere l'aggiornamento dei dati via AJAX
// Rimozione per select multipli
if ($input.prop("multiple")) {
$input.on('select2:unselecting', function (e) {
let data = e.params ? e.params.data : null;
if (data) {
let option = $input.find('option[value="' + data.id + '"]');
option.remove();
}
});
}
// Rimozione per select singoli
else {
$input.on('select2:selecting', function (e) {
let data = $input.selectData();
if (data) {
let option = $input.find('option[value="' + data.id + '"]');
option.remove();
}
});
}
}

View File

@ -1,120 +0,0 @@
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Funzione per l'inizializzazione dei campi textarea.
* @param input
*/
function initTextareaInput(input) {
autosize($(input));
return true;
}
function initCharCounter(input) {
let $input = $(input);
if (input.hasAttribute('maxlength')) {
$input.maxlength({
warningClass: "help-block",
limitReachedClass: "help-block text-danger",
preText: '',
separator: ' / ',
postText: '',
showMaxLength: true,
placement: 'bottom-right-inside',
utf8: true,
appendToParent: true,
alwaysShow: false,
threshold: 150
});
} else {
$input.attr('maxlength', '65535');
$input.maxlength({
warningClass: "help-block",
limitReachedClass: "help-block text-danger",
showMaxLength: false,
placement: 'bottom-right-inside',
utf8: true,
appendToParent: true,
alwaysShow: true
});
}
return true;
}
function waitCKEditor(input) {
setTimeout(function () {
initEditorInput(input);
}, 100);
}
/**
* Funzione per l'inizializzazione dei campi editor.
* @param input
*/
function initEditorInput(input) {
if (window.CKEDITOR && CKEDITOR.status === "loaded") {
initCKEditor(input);
} else {
waitCKEditor(input);
}
return true;
}
function initCKEditor(input) {
let $input = $(input);
let name = input.getAttribute("id");
// Controllo su istanza già esistente
let instance = CKEDITOR.instances[name];
if (instance) {
instance.destroy();
}
// Avvio di CKEditor
CKEDITOR.replace(name, {
toolbar: (input.hasAttribute('use_full_ckeditor')) ? globals.ckeditorToolbar_Full : globals.ckeditorToolbar,
language: globals.locale,
scayt_autoStartup: true,
scayt_sLang: globals.full_locale,
disableNativeSpellChecker: false,
fullPage: (input.hasAttribute('use_full_ckeditor')) ? true : false,
allowedContent: (input.hasAttribute('use_full_ckeditor')) ? true : false,
extraPlugins: 'scayt',
skin: 'moono-lisa',
});
// Gestione di eventi noti
CKEDITOR.instances[name].on("key", function (event) {
$input.trigger("keydown", event.data);
$input.trigger("keyup", event.data);
});
CKEDITOR.instances[name].on("change", function (event) {
$input.trigger("change", event);
});
CKEDITOR.instances[name].on("focus", function (event) {
$input.trigger("focus", event);
});
}

View File

@ -1 +0,0 @@
Deny from all

55
bootstrap/app.php Normal file
View File

@ -0,0 +1,55 @@
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

2
bootstrap/cache/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

203
bug.php
View File

@ -1,203 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Modules\Emails\Account;
use Notifications\EmailNotification;
include_once __DIR__.'/core.php';
$account = Account::where('predefined', true)->first();
$bug_email = 'info@openstamanager.com';
$user = Auth::user();
if (filter('op') == 'send') {
// Preparazione email
$mail = new EmailNotification();
// Destinatario
$mail->AddAddress($bug_email);
// Oggetto
$mail->Subject = 'Segnalazione bug OSM '.$version;
// Aggiunta dei file di log (facoltativo)
if (!empty(post('log')) && file_exists(base_dir().'/logs/error.log')) {
$mail->AddAttachment(base_dir().'/logs/error.log');
}
// Aggiunta della copia del database (facoltativo)
if (!empty(post('sql'))) {
$backup_file = base_dir().'/Backup OSM '.date('Y-m-d').' '.date('H_i_s').'.sql';
Backup::database($backup_file);
$mail->AddAttachment($backup_file);
flash()->info(tr('Backup del database eseguito ed allegato correttamente!'));
}
// Aggiunta delle informazioni di base sull'installazione
$infos = [
'Utente' => $user['username'],
'IP' => get_client_ip(),
'Versione OSM' => $version.' ('.(!empty($revision) ? $revision : 'In sviluppo').')',
'PHP' => phpversion(),
];
// Aggiunta delle informazioni sul sistema (facoltativo)
if (!empty(post('info'))) {
$infos['Sistema'] = $_SERVER['HTTP_USER_AGENT'].' - '.getOS();
}
// Completamento del body
$body = post('body').'<hr>';
foreach ($infos as $key => $value) {
$body .= '<p>'.$key.': '.$value.'</p>';
}
$mail->Body = $body;
$mail->AltBody = 'Questa email arriva dal modulo bug di segnalazione bug di OSM';
// Invio mail
if (!$mail->send()) {
flash()->error(tr("Errore durante l'invio della segnalazione").': '.$mail->ErrorInfo);
} else {
flash()->info(tr('Email inviata correttamente!'));
}
// Rimozione del dump del database
if (!empty(post('sql'))) {
delete($backup_file);
}
redirect(base_path().'/bug.php');
exit();
}
$pageTitle = tr('Bug');
include_once App::filepath('include|custom|', 'top.php');
if (empty($account['from_address']) || empty($account['server'])) {
echo '
<div class="alert alert-warning">
<i class="fa fa-warning"></i>
<b>'.tr('Attenzione!').'</b> '.tr('Per utilizzare correttamente il modulo di segnalazione bug devi configurare alcuni parametri riguardanti le impostazione delle email').'.
'.Modules::link('Account email', $account['id'], tr('Correggi account'), null, 'class="btn btn-warning pull-right"').'
<div class="clearfix"></div>
</div>';
}
echo '
<div class="box">
<div class="box-header">
<h3 class="box-title"><i class="fa fa-bug"></i> '.tr('Segnalazione bug').'</h3>
</div>
<div class="box-body">
<form method="post" action="">
<input type="hidden" name="op" value="send">
<table class="table table-bordered table-condensed table-striped table-hover">
<tr>
<th width="150" class="text-right">'.tr('Da').':</th>
<td>'.$account['from_address'].'</td>
</tr>
<!-- A -->
<tr>
<th class="text-right">'.tr('A').':</th>
<td>'.$bug_email.'</td>
</tr>
<!-- Versione -->
<tr>
<th class="text-right">'.tr('Versione OSM').':</th>
<td>'.$version.' ('.(!empty($revision) ? $revision : tr('In sviluppo')).')</td>
</tr>
</table>
<div class="row">
<div class="col-md-4">
{[ "type": "checkbox", "placeholder": "'.tr('Allega file di log').'", "name": "log", "value": "1" ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "placeholder": "'.tr('Allega copia del database').'", "name": "sql" ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "placeholder": "'.tr('Allega informazioni sul PC').'", "name": "info", "value": "1" ]}
</div>
</div>
<div class="clearfix"></div>
<br>
{[ "type": "ckeditor", "label": "'.tr('Descrizione del bug').'", "name": "body" ]}
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary" id="send" disabled>
<i class="fa fa-envelope"></i> '.tr('Invia segnalazione').'
</button>
</div>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function() {
init();
var html = "<p>'.tr('Se hai riscontrato un bug ricordati di specificare').':</p>" +
"<ul>" +
"<li>'.tr('Modulo esatto (o pagina relativa) in cui questi si è verificato').';</li>" +
"<li>'.tr('Dopo quali specifiche operazioni hai notato il malfunzionamento').'.</li>" +
"</ul>" +
"<p>'.tr('Assicurati inoltre di controllare che il checkbox relativo ai file di log sia contrassegnato, oppure riporta qui l\'errore visualizzato').'.</p>" +
"<p>'.tr('Ti ringraziamo per il tuo contributo').',<br>" +
"'.tr('Lo staff di OSM').'</p>";
var firstFocus = true;
let editor = input("body");
editor.set(html);
editor.on("change", function() {
setTimeout(function() {
$("#send").prop("disabled", editor.get() === "");
}, 10);
});
editor.on("focus", function() {
if (firstFocus) {
editor.set("");
firstFocus = false;
}
});
});
</script>
<script type="text/javascript" charset="utf-8" src="'.App::getPaths()['js'].'/ckeditor/ckeditor.js'.'"></script>';
include_once App::filepath('include|custom|', 'bottom.php');

View File

@ -1,130 +0,0 @@
{
"name": "devcode-it/openstamanager",
"description": "Gestionale open-source per assistenza tecnica e fatturazione elettronica",
"license": "GPL-3.0",
"keywords": [
"gestionale",
"assistenza tecnica",
"fatturazione elettronica",
"open-source"
],
"homepage": "https://www.openstamanager.com/",
"authors": [{
"name": "DevCode s.r.l.",
"email": "info@openstamanager.com"
}],
"type": "project",
"require": {
"php": ">=5.6.4",
"ext-curl": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-intl": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-pdo": "*",
"ext-simplexml": "*",
"ext-xsl": "*",
"ext-zip": "*",
"aluguest/ical-easy-reader": "^1.5",
"danielstjules/stringy": "^3.1",
"davidepastore/codice-fiscale": "^0.6.0",
"dragonmantank/cron-expression": "^1.0",
"ezyang/htmlpurifier": "^4.8",
"filp/whoops": "^2.1",
"guzzlehttp/guzzle": "^6.3",
"ifsnop/mysqldump-php": "^2.3",
"illuminate/database": "~5.4.0",
"intervention/image": "^2.3",
"league/csv": "^8.2",
"league/oauth2-client": "^2.6",
"league/oauth2-google": "^3.0",
"maximebf/debugbar": "^1.15",
"monolog/monolog": "^1.22",
"mpdf/mpdf": "^v8.0.7",
"mpociot/vat-calculator": "^2.3",
"owasp/csrf-protector-php": "^1.0",
"phpmailer/phpmailer": "^6.0",
"respect/validation": "^1.1",
"servo/fluidxml": "^1.21",
"slim/flash": "^0.4.0",
"spipu/html2pdf": "^5.0",
"symfony/filesystem": "^3.3",
"symfony/finder": "^3.3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-php70": "^1.8",
"symfony/translation": "^3.3",
"symfony/var-dumper": "^3.3",
"thenetworg/oauth2-azure": "^2.0",
"willdurand/geocoder": "^3.3"
},
"require-dev": {
"codeception/codeception": "^3.0",
"friendsofphp/php-cs-fixer": "^2.10"
},
"autoload": {
"psr-4": {
"": "src/",
"Update\\": "update/",
"Modules\\Aggiornamenti\\": ["modules/aggiornamenti/custom/src/", "modules/aggiornamenti/src/"],
"Modules\\Anagrafiche\\": ["modules/anagrafiche/custom/src/", "modules/anagrafiche/src/"],
"Modules\\Backups\\": ["modules/backups/custom/src/", "modules/backups/src/"],
"Modules\\Emails\\": ["modules/emails/custom/src/", "modules/emails/src/"],
"Modules\\Articoli\\": ["modules/articoli/custom/src/", "modules/articoli/src/"],
"Modules\\Checklists\\": ["modules/checklists/custom/src/", "modules/checklists/src/"],
"Modules\\Ritenute\\": ["modules/ritenute/custom/src/", "modules/ritenute/src/"],
"Modules\\RitenuteContributi\\": ["modules/ritenute_contributi/custom/src/", "modules/ritenute_contributi/src/"],
"Modules\\Rivalse\\": ["modules/rivalse/custom/src/", "modules/rivalse/src/"],
"Modules\\Newsletter\\": ["modules/newsletter/custom/src/", "modules/newsletter/src/"],
"Modules\\Iva\\": ["modules/iva/custom/src/", "modules/iva/src/"],
"Modules\\DDT\\": ["modules/ddt/custom/src/", "modules/ddt/src/"],
"Modules\\Fatture\\": ["modules/fatture/custom/src/", "modules/fatture/src/"],
"Modules\\Ordini\\": ["modules/ordini/custom/src/", "modules/ordini/src/"],
"Modules\\Preventivi\\": ["modules/preventivi/custom/src/", "modules/preventivi/src/"],
"Modules\\Contratti\\": ["modules/contratti/custom/src/", "modules/contratti/src/"],
"Modules\\Interventi\\": ["modules/interventi/custom/src/", "modules/interventi/src/"],
"Modules\\Pagamenti\\": ["modules/pagamenti/custom/src/", "modules/pagamenti/src/"],
"Modules\\Statistiche\\": ["modules/statistiche/custom/src/", "modules/statistiche/src/"],
"Modules\\Scadenzario\\": ["modules/scadenzario/custom/src/", "modules/scadenzario/src/"],
"Modules\\PrimaNota\\": ["modules/primanota/custom/src/", "modules/primanota/src/"],
"Modules\\Utenti\\": ["modules/utenti/custom/src/", "modules/utenti/src/"],
"Modules\\StatoServizi\\": ["modules/stato_servizi/custom/src/", "modules/stato_servizi/src/"],
"Modules\\StatiIntervento\\": ["modules/stati_intervento/custom/src/", "modules/stati_intervento/src/"],
"Modules\\StatiPreventivo\\": ["modules/stati_preventivo/custom/src/", "modules/stati_preventivo/src/"],
"Modules\\StatiContratto\\": ["modules/stati_contratto/custom/src/", "modules/stati_contratto/src/"],
"Modules\\TipiIntervento\\": ["modules/tipi_intervento/custom/src/", "modules/tipi_intervento/src/"],
"Modules\\CategorieDocumentali\\": ["modules/categorie_documenti/custom/src/", "modules/categorie_documenti/src/"],
"Modules\\PianiSconto\\": ["modules/piano_sconto/custom/src/", "modules/piano_sconto/src/"],
"Modules\\Impianti\\": ["modules/impianti/custom/src/", "modules/impianti/src/"],
"Modules\\Importazione\\": ["modules/import/custom/src/", "modules/import/src/"],
"Modules\\Impostazioni\\": ["modules/impostazioni/custom/src/", "modules/impostazioni/src/"],
"Plugins\\ExportFE\\": ["plugins/exportFE/custom/src/", "plugins/exportFE/src/"],
"Plugins\\ImportFE\\": ["plugins/importFE/custom/src/", "plugins/importFE/src/"],
"Plugins\\ReceiptFE\\": ["plugins/receiptFE/custom/src/", "plugins/receiptFE/src/"],
"Plugins\\DichiarazioniIntento\\": ["plugins/dichiarazioni_intento/custom/src/", "plugins/dichiarazioni_intento/src/"],
"Plugins\\PianificazioneInterventi\\": ["plugins/pianificazione_interventi/custom/src/", "plugins/pianificazione_interventi/src/"],
"Plugins\\PianificazioneFatturazione\\": ["plugins/pianificazione_fatturazione/custom/src/", "plugins/pianificazione_fatturazione/src/"],
"Plugins\\StatisticheArticoli\\": ["plugins/statistiche_articoli/custom/src/", "plugins/statistiche_articoli/src/"],
"Plugins\\ListinoClienti\\": ["plugins/listino_clienti/custom/src/", "plugins/listino_clienti/src/"],
"Plugins\\ListinoFornitori\\": ["plugins/listino_fornitori/custom/src/", "plugins/listino_fornitori/src/"]
},
"files": [
"lib/functions.php",
"lib/common.php",
"lib/helpers.php",
"lib/util.php",
"lib/deprecated.php"
]
},
"config": {
"sort-packages": true,
"optimize-autoloader": false,
"apcu-autoloader": true,
"prefer-stable": true,
"platform": {
"php": "5.6.4"
}
}
}

View File

@ -1,63 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Impostazioni di base per l'accesso al database
$db_host = '|host|';
$db_username = '|username|';
$db_password = '|password|';
$db_name = '|database|';
//$port = '|port|';
// Percorso della cartella di backup
$backup_dir = __DIR__.'/backup/';
// Tema selezionato per il front-end
$theme = 'default';
// Impostazioni di sicurezza
$redirectHTTPS = false; // Redirect automatico delle richieste da HTTP a HTTPS
$disableCSRF = true; // Protezione contro CSRF
// Impostazioni di debug
$debug = false;
// Personalizzazione dei gestori dei tag personalizzati
$HTMLWrapper = null;
$HTMLHandlers = [];
$HTMLManagers = [];
// Lingua del progetto (per la traduzione e la conversione numerica)
$lang = '|lang|';
// Personalizzazione della formattazione di timestamp, date e orari
$formatter = [
'timestamp' => '|timestamp|',
'date' => '|date|',
'time' => '|time|',
'number' => [
'decimals' => '|decimals|',
'thousands' => '|thousands|',
],
];
// Ulteriori file CSS e JS da includere
$assets = [
'css' => [],
'print' => [],
'js' => [],
];

234
config/app.php Normal file
View File

@ -0,0 +1,234 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
*/
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'Date' => Illuminate\Support\Facades\Date::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Http' => Illuminate\Support\Facades\Http::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'RateLimiter' => Illuminate\Support\Facades\RateLimiter::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
// 'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
];

117
config/auth.php Normal file
View File

@ -0,0 +1,117 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];

64
config/broadcasting.php Normal file
View File

@ -0,0 +1,64 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "ably", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

110
config/cache.php Normal file
View File

@ -0,0 +1,110 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
| Supported drivers: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb", "octane", "null"
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
'serialize' => false,
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
'lock_connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'lock_connection' => 'default',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
'octane' => [
'driver' => 'octane',
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
];

34
config/cors.php Normal file
View File

@ -0,0 +1,34 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];

View File

@ -1,38 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Configuration file for CSRF Protector.
*/
return [
'logDirectory' => base_dir().'/logs',
'failedAuthAction' => [
'GET' => 0,
'POST' => 0,
],
'jsUrl' => base_path().'/assets/dist/js/csrf/csrfprotector.js',
'tokenLength' => 10,
'cookieConfig' => [
'path' => base_path(),
'secure' => isHTTPS(true),
],
'verifyGetFor' => [],
'CSRFP_TOKEN' => '',
'disabledJavascriptMessage' => '',
];

147
config/database.php Normal file
View File

@ -0,0 +1,147 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
];

73
config/filesystems.php Normal file
View File

@ -0,0 +1,73 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
],
],
/*
|--------------------------------------------------------------------------
| Symbolic Links
|--------------------------------------------------------------------------
|
| Here you may configure the symbolic links that will be created when the
| `storage:link` Artisan command is executed. The array keys should be
| the locations of the links and the values should be their targets.
|
*/
'links' => [
public_path('storage') => storage_path('app/public'),
],
];

52
config/hashing.php Normal file
View File

@ -0,0 +1,52 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon", "argon2id"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];

105
config/logging.php Normal file
View File

@ -0,0 +1,105 @@
<?php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => env('LOG_LEVEL', 'critical'),
],
'papertrail' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => env('LOG_LEVEL', 'debug'),
],
'errorlog' => [
'driver' => 'errorlog',
'level' => env('LOG_LEVEL', 'debug'),
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
'emergency' => [
'path' => storage_path('logs/laravel.log'),
],
],
];

110
config/mail.php Normal file
View File

@ -0,0 +1,110 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Mailer
|--------------------------------------------------------------------------
|
| This option controls the default mailer that is used to send any email
| messages sent by your application. Alternative mailers may be setup
| and used as needed; however, this mailer will be used by default.
|
*/
'default' => env('MAIL_MAILER', 'smtp'),
/*
|--------------------------------------------------------------------------
| Mailer Configurations
|--------------------------------------------------------------------------
|
| Here you may configure all of the mailers used by your application plus
| their respective settings. Several examples have been configured for
| you and you are free to add your own as your application requires.
|
| Laravel supports a variety of mail "transport" drivers to be used while
| sending an e-mail. You will specify which one you are using for your
| mailers below. You are free to add additional mailers as required.
|
| Supported: "smtp", "sendmail", "mailgun", "ses",
| "postmark", "log", "array"
|
*/
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'auth_mode' => null,
],
'ses' => [
'transport' => 'ses',
],
'mailgun' => [
'transport' => 'mailgun',
],
'postmark' => [
'transport' => 'postmark',
],
'sendmail' => [
'transport' => 'sendmail',
'path' => '/usr/sbin/sendmail -bs',
],
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
],
'array' => [
'transport' => 'array',
],
],
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];

View File

@ -1,64 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
return [
'modules/banche' => 'Modules\Banche',
];
/*
'modules/aggiornamenti' => 'Modules\Aggiornamenti',
'modules/anagrafiche' => 'Modules\Anagrafiche',
'modules/backups' => 'Modules\Backups',
'modules/emails' => 'Modules\Emails',
'modules/articoli' => 'Modules\Articoli',
'modules/checklists' => 'Modules\Checklists',
'modules/ritenute' => 'Modules\Ritenute',
'modules/ritenute_contributi' => 'Modules\RitenuteContributi',
'modules/rivalse' => 'Modules\Rivalse',
'modules/newsletter' => 'Modules\Newsletter',
'modules/iva' => 'Modules\Iva',
'modules/ddt' => 'Modules\DDT',
'modules/fatture' => 'Modules\Fatture',
'modules/ordini' => 'Modules\Ordini',
'modules/preventivi' => 'Modules\Preventivi',
'modules/contratti' => 'Modules\Contratti',
'modules/interventi' => 'Modules\Interventi',
'modules/pagamenti' => 'Modules\Pagamenti',
'modules/statistiche' => 'Modules\Statistiche',
'modules/scadenzario' => 'Modules\Scadenzario',
'modules/primanota' => 'Modules\PrimaNota',
'modules/utenti' => 'Modules\Utenti',
'modules/stato_servizi' => 'Modules\StatoServizi',
'modules/stati_intervento' => 'Modules\StatiIntervento',
'modules/stati_preventivo' => 'Modules\StatiPreventivo',
'modules/stati_contratto' => 'Modules\StatiContratto',
'modules/tipi_intervento' => 'Modules\TipiIntervento',
'modules/categorie_documenti' => 'Modules\CategorieDocumentali',
'modules/listini' => 'Modules\Listini',
'modules/impianti' => 'Modules\Impianti',
'modules/impostazioni' => 'Modules\Impostazioni',
'plugins/exportFE' => 'Plugins\ExportFE',
'plugins/importFE' => 'Plugins\ImportFE',
'plugins/receiptFE' => 'Plugins\ReceiptFE',
'plugins/dichiarazioni_intento' => 'Plugins\DichiarazioniIntento',
'plugins/pianificazione_interventi' => 'Plugins\PianificazioneInterventi',
'plugins/pianificazione_fatturazione' => 'Plugins\PianificazioneFatturazione',
'plugins/statistiche_articoli' => 'Plugins\StatisticheArticoli',
'plugins/dettagli_articolo' => 'Plugins\DettagliArticolo',
*/

93
config/queue.php Normal file
View File

@ -0,0 +1,93 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Queue Connection Name
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for every one. Here you may define a default connection.
|
*/
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
'after_commit' => false,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'default'),
'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'after_commit' => false,
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];

33
config/services.php Normal file
View File

@ -0,0 +1,33 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
];

201
config/session.php Normal file
View File

@ -0,0 +1,201 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "dynamodb", "array"
|
*/
'driver' => env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'),
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => env('SESSION_CONNECTION', null),
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Cache Store
|--------------------------------------------------------------------------
|
| While using one of the framework's cache driven session backends you may
| list a cache store that should be used for these sessions. This value
| must match with one of the application's configured cache "stores".
|
| Affects: "apc", "dynamodb", "memcached", "redis"
|
*/
'store' => env('SESSION_STORE', null),
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you when it can't be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE'),
/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true,
/*
|--------------------------------------------------------------------------
| Same-Site Cookies
|--------------------------------------------------------------------------
|
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| will set this value to "lax" since this is a secure default value.
|
| Supported: "lax", "strict", "none", null
|
*/
'same_site' => 'lax',
];

36
config/view.php Normal file
View File

@ -0,0 +1,36 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => [
resource_path('views'),
],
/*
|--------------------------------------------------------------------------
| Compiled View Path
|--------------------------------------------------------------------------
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];

View File

@ -1,115 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
if (!empty($id_record) && !empty($id_module)) {
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_record);
} elseif (empty($id_module)) {
redirect(base_path().'/index.php');
}
include_once App::filepath('include|custom|', 'top.php');
// Inclusione gli elementi fondamentali
include_once base_dir().'/actions.php';
// Widget in alto
echo '{( "name": "widgets", "id_module": "'.$id_module.'", "position": "top", "place": "controller" )}';
// Lettura eventuali plugins modulo da inserire come tab
echo '
<div class="nav-tabs-custom">
<ul class="nav nav-tabs pull-right" id="tabs" role="tablist">
<li class="pull-left active header">
<a data-toggle="tab" href="#tab_0">
<i class="'.$structure['icon'].'"></i> '.$structure['title'];
// Pulsante "Aggiungi" solo se il modulo è di tipo "table" e se esiste il template per la popup
if ($structure->hasAddFile() && $structure->permission == 'rw') {
echo '
<button type="button" class="btn btn-primary" data-toggle="modal" data-title="'.tr('Aggiungi').'..." data-href="add.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'"><i class="fa fa-plus"></i></button>';
}
echo '
</a>
</li>';
$plugins = $dbo->fetchArray('SELECT id, title FROM zz_plugins WHERE idmodule_to='.prepare($id_module)." AND position='tab_main' AND enabled = 1");
// Tab dei plugin
foreach ($plugins as $plugin) {
echo '
<li>
<a data-toggle="tab" href="#tab_'.$plugin['id'].'" id="link-tab_'.$plugin['id'].'">'.$plugin['title'].'</a>
</li>';
}
echo '
</ul>
<div class="tab-content">
<div id="tab_0" class="tab-pane active">';
include base_dir().'/include/manager.php';
echo '
</div>';
// Plugin
$module_record = $record;
foreach ($plugins as $plugin) {
$record = $module_record;
echo '
<div id="tab_'.$plugin['id'].'" class="tab-pane">';
$id_plugin = $plugin['id'];
include base_dir().'/include/manager.php';
echo '
</div>';
}
$record = $module_record;
echo '
</div>
</div>';
redirectOperation($id_module, isset($id_parent) ? $id_parent : $id_record);
// Interfaccia per la modifica dell'ordine e della visibilità delle colonne (Amministratore)
if ($user->is_admin && string_contains($module['option'], '|select|')) {
echo '
<a class="btn btn-xs btn-default pull-right" style="margin-top: -1.25rem;" onclick="modificaColonne(this)">
<i class="fa fa-th-list"></i> '.tr('Modifica colonne').'
</a><div class="clearfix" >&nbsp;</div>
<script>
function modificaColonne(button) {
openModal("'.tr('Modifica colonne').'", globals.rootdir + "/actions.php?id_module=" + globals.id_module + "&op=aggiorna_colonne")
}
</script>';
}
// Widget in basso
echo '{( "name": "widgets", "id_module": "'.$id_module.'", "position": "right", "place": "controller" )}';
include_once App::filepath('include|custom|', 'bottom.php');

302
core.php
View File

@ -1,302 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Rimozione header X-Powered-By
header_remove('X-Powered-By');
// Impostazioni di configurazione PHP
date_default_timezone_set('Europe/Rome');
// Controllo sulla versione PHP
$minimum = '5.6.0';
if (version_compare(phpversion(), $minimum) < 0) {
echo '
<p>Stai utilizzando la versione PHP '.phpversion().', non compatibile con OpenSTAManager.</p>
<p>Aggiorna PHP alla versione >= '.$minimum.'.</p>';
exit();
}
// Caricamento delle impostazioni personalizzabili
if (file_exists(__DIR__.'/config.inc.php')) {
include_once __DIR__.'/config.inc.php';
}
// Caricamento delle dipendenze e delle librerie del progetto
$loader = require_once __DIR__.'/vendor/autoload.php';
$namespaces = require_once __DIR__.'/config/namespaces.php';
foreach ($namespaces as $path => $namespace) {
$loader->addPsr4($namespace.'\\', __DIR__.'/'.$path.'/custom/src');
$loader->addPsr4($namespace.'\\', __DIR__.'/'.$path.'/src');
}
// Individuazione dei percorsi di base
App::definePaths(__DIR__);
$docroot = DOCROOT;
$rootdir = ROOTDIR;
$baseurl = BASEURL;
// Sicurezza della sessioni
//ini_set('session.cookie_samesite', 'strict');
ini_set('session.use_trans_sid', '0');
ini_set('session.use_only_cookies', '1');
session_set_cookie_params(0, base_path(), null, isHTTPS(true));
session_start();
// Lettura della configurazione
$config = App::getConfig();
// Redirect al percorso HTTPS se impostato nella configurazione
if (!empty($config['redirectHTTPS']) && !isHTTPS(true)) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
exit();
}
/* GESTIONE DEGLI ERRORI */
// Logger per la segnalazione degli errori
$logger = new Monolog\Logger('Logs');
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
$logger->pushProcessor(new Monolog\Processor\WebProcessor());
// Registrazione globale del logger
Monolog\Registry::addLogger($logger, 'logs');
use Monolog\Handler\FilterHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
$handlers = [];
if (!API\Response::isAPIRequest()) {
// File di log di base (logs/error.log, logs/setup.log)
$handlers[] = new StreamHandler(base_dir().'/logs/error.log', Monolog\Logger::ERROR);
$handlers[] = new StreamHandler(base_dir().'/logs/setup.log', Monolog\Logger::EMERGENCY);
// Messaggi grafici per l'utente
$handlers[] = new Extensions\MessageHandler(Monolog\Logger::ERROR);
// File di log ordinati in base alla data
if (App::debug()) {
$handlers[] = new RotatingFileHandler(base_dir().'/logs/error.log', 0, Monolog\Logger::ERROR);
$handlers[] = new RotatingFileHandler(base_dir().'/logs/setup.log', 0, Monolog\Logger::EMERGENCY);
}
// Inizializzazione Whoops
$whoops = new Whoops\Run();
if (App::debug()) {
$whoops->pushHandler(new Whoops\Handler\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();
// Aggiunta di Monolog a Whoops
$whoops->pushHandler(function ($exception, $inspector, $run) use ($logger) {
$logger->addError($exception->getMessage(), [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
]);
});
} else {
$handlers[] = new StreamHandler(base_dir().'/logs/api.log', Monolog\Logger::ERROR);
}
// Disabilita i messaggi nativi di PHP
ini_set('display_errors', 0);
// Ignora gli avvertimenti e le informazioni relative alla deprecazione di componenti
error_reporting(E_ALL & ~E_WARNING & ~E_CORE_WARNING & ~E_NOTICE & ~E_USER_DEPRECATED & ~E_STRICT);
$pattern = '[%datetime%] %channel%.%level_name%: %message% %context%'.PHP_EOL.'%extra% '.PHP_EOL;
$monologFormatter = new Monolog\Formatter\LineFormatter($pattern);
$monologFormatter->includeStacktraces(App::debug());
// Filtra gli errori per livello preciso del gestore dedicato
foreach ($handlers as $handler) {
$handler->setFormatter($monologFormatter);
$logger->pushHandler(new FilterHandler($handler, [$handler->getLevel()]));
}
// Imposta Monolog come gestore degli errori
$handler = new Monolog\ErrorHandler($logger);
if (!API\Response::isAPIRequest()) {
$handler->registerErrorHandler([]);
$handler->registerExceptionHandler(Monolog\Logger::ERROR);
}
$handler->registerFatalHandler(Monolog\Logger::ERROR);
// Database
$dbo = $database = database();
/* INTERNAZIONALIZZAZIONE */
// Istanziamento del gestore delle traduzioni del progetto
$lang = !empty($config['lang']) ? $config['lang'] : (isset($_GET['lang']) ? $_GET['lang'] : null);
$formatter = !empty($config['formatter']) ? $config['formatter'] : [];
$translator = trans();
$translator->addLocalePath(base_dir().'/locale');
$translator->addLocalePath(base_dir().'/modules/*/locale');
$translator->setLocale($lang, $formatter);
// Individuazione di versione e revisione del progetto
$version = Update::getVersion();
$revision = Update::getRevision();
/* ACCESSO E INSTALLAZIONE */
// Controllo sulla presenza dei permessi di accesso basilari
$continue = $dbo->isInstalled() && !Update::isUpdateAvailable() && (Auth::check() || API\Response::isAPIRequest());
if (!empty($skip_permissions)) {
Permissions::skip();
}
if (!$continue && getURLPath() != slashes(base_path().'/index.php') && !Permissions::getSkip()) {
if (Auth::check()) {
Auth::logout();
}
redirect(base_path().'/index.php');
exit();
}
/* INIZIALIZZAZIONE GENERALE */
// Operazione aggiuntive (richieste non API)
if (!API\Response::isAPIRequest()) {
// Impostazioni di Content-Type e Charset Header
header('Content-Type: text/html; charset=UTF-8');
// Controllo CSRF
if (empty($config['disableCSRF'])) {
csrfProtector::init();
}
// Aggiunta del wrapper personalizzato per la generazione degli input
if (!empty($config['HTMLWrapper'])) {
HTMLBuilder\HTMLBuilder::setWrapper($config['HTMLWrapper']);
}
// Aggiunta dei gestori personalizzati per la generazione degli input
foreach ((array) $config['HTMLHandlers'] as $key => $value) {
HTMLBuilder\HTMLBuilder::setHandler($key, $value);
}
// Aggiunta dei gestori per componenti personalizzate
foreach ((array) $config['HTMLManagers'] as $key => $value) {
HTMLBuilder\HTMLBuilder::setManager($key, $value);
}
// Registrazione globale del template per gli input HTML
register_shutdown_function('translateTemplate');
ob_start();
// Retrocompatibilità
$_SESSION['infos'] = isset($_SESSION['infos']) ? array_unique($_SESSION['infos']) : [];
$_SESSION['warnings'] = isset($_SESSION['warnings']) ? array_unique($_SESSION['warnings']) : [];
$_SESSION['errors'] = isset($_SESSION['errors']) ? array_unique($_SESSION['errors']) : [];
// Impostazione del tema grafico di default
$theme = !empty($config['theme']) ? $config['theme'] : 'default';
if ($continue) {
// Periodo di visualizzazione dei record
// Personalizzato
if (!empty($_GET['period_start'])) {
$_SESSION['period_start'] = $_GET['period_start'];
$_SESSION['period_end'] = $_GET['period_end'];
}
// Dal 01-01-yyy al 31-12-yyyy
elseif (!isset($_SESSION['period_start'])) {
$_SESSION['period_start'] = date('Y').'-01-01';
$_SESSION['period_end'] = date('Y').'-12-31';
}
$id_record = filter('id_record');
$id_parent = filter('id_parent');
Modules::setCurrent(filter('id_module'));
Plugins::setCurrent(filter('id_plugin'));
// Variabili fondamentali
$module = Modules::getCurrent();
$plugin = Plugins::getCurrent();
$structure = isset($plugin) ? $plugin : $module;
$id_module = $module ? $module['id'] : null;
$id_plugin = $plugin ? $plugin['id'] : null;
$user = Auth::user();
if (!empty($id_module)) {
// Segmenti
if (!isset($_SESSION['module_'.$id_module]['id_segment'])) {
$segments = Modules::getSegments($id_module);
$_SESSION['module_'.$id_module]['id_segment'] = isset($segments[0]['id']) ? $segments[0]['id'] : null;
}
Permissions::addModule($id_module);
}
Permissions::check();
}
// Retrocompatibilità
$post = Filter::getPOST();
$get = Filter::getGET();
}
// Inclusione dei file modutil.php
// TODO: sostituire * con lista module dir {aggiornamenti,anagrafiche,articoli}
// TODO: sostituire tutte le funzioni dei moduli con classi Eloquent relative
$files = glob(__DIR__.'/{modules,plugins}/*/modutil.php', GLOB_BRACE);
$custom_files = glob(__DIR__.'/{modules,plugins}/*/custom/modutil.php', GLOB_BRACE);
foreach ($custom_files as $key => $value) {
$index = array_search(str_replace('custom/', '', $value), $files);
if ($index !== false) {
unset($files[$index]);
}
}
$list = array_merge($files, $custom_files);
foreach ($list as $file) {
include_once $file;
}
// Inclusione dei file vendor/autoload.php di Composer
$files = glob(__DIR__.'/{modules,plugins}/*/vendor/autoload.php', GLOB_BRACE);
$custom_files = glob(__DIR__.'/{modules,plugins}/*/custom/vendor/autoload.php', GLOB_BRACE);
foreach ($custom_files as $key => $value) {
$index = array_search(str_replace('custom/', '', $value), $files);
if ($index !== false) {
unset($files[$index]);
}
}
$list = array_merge($files, $custom_files);
foreach ($list as $file) {
include_once $file;
}

190
cron.php
View File

@ -1,190 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Script dedicato alla gestione delle operazioni di cron ricorrenti del gestionale.
* Una volta attivato, questo script rimane attivo in background per gestire l'esecuzione delle diverse operazioni come pianificate nella tabella zz_tasks.
*
* Il file viene richiamato in automatico al login di un utente.
* Per garantire che lo script resti attivo in ogni situazione, si consiglia di introdurre una chiamata nel relativo crontab di sistema secondo il seguente schema:
*/
// Schema crontab: "*/5 * * * * php <percorso_root>/cron.php"
use Carbon\Carbon;
use Models\Cache;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
use Tasks\Task;
// Rimozione delle limitazioni sull'esecuzione
set_time_limit(0);
ignore_user_abort(true);
// Chiusura della richiesta alla pagina
flush();
$skip_permissions = true;
include_once __DIR__.'/core.php';
// Controllo su possibili aggiornamenti per bloccare il sistema
$database_online = $database->isInstalled() && !Update::isUpdateAvailable();
if (!$database_online) {
return;
}
// Disabilita della sessione
session_write_close();
// Aggiunta di un logger specifico
$pattern = '[%datetime%] %level_name%: %message% %context%'.PHP_EOL;
$formatter = new Monolog\Formatter\LineFormatter($pattern);
$logger = new Logger('Tasks');
$handler = new RotatingFileHandler(base_dir().'/logs/cron.log', 7);
$handler->setFormatter($formatter);
$logger->pushHandler($handler);
// Lettura della cache
$ultima_esecuzione = Cache::pool('Ultima esecuzione del cron');
$data = $ultima_esecuzione->content;
$in_esecuzione = Cache::pool('Cron in esecuzione');
$cron_id = Cache::pool('ID del cron');
$disattiva = Cache::pool('Disabilita cron');
if (!empty($disattiva->content)) {
return;
}
// Impostazioni sugli slot di esecuzione
$slot_duration = 5;
// Controllo sull'ultima esecuzione
$data = $data ? new Carbon($data) : null;
$minimo_esecuzione = (new Carbon())->subMinutes($slot_duration * 5);
if (!empty($data) && $minimo_esecuzione->lessThan($data)) {
return;
}
// Generazione e registrazione del cron
$current_id = random_string();
$cron_id->set($current_id);
// Registrazione dell'esecuzione
$adesso = new Carbon();
$ultima_esecuzione->set($adesso->__toString());
// Prima esecuzione immediata
$slot_minimo = $adesso->copy();
// Esecuzione ricorrente
$number = 1;
while (true) {
$disattiva->refresh();
$cron_id->refresh();
$in_esecuzione->refresh();
// Controllo su possibili aggiornamenti per bloccare il sistema
$database_online = $database->isInstalled() && !Update::isUpdateAvailable();
if (!$database_online || !empty($disattiva->content) || $cron_id->content != $current_id) {
return;
}
// Rimozione dei log più vecchi
$database->query('DELETE FROM zz_tasks_logs WHERE DATE_ADD(created_at, INTERVAL :interval DAY) <= NOW()', [
':interval' => 7,
]);
// Risveglio programmato tramite slot
$timestamp = $slot_minimo->getTimestamp();
time_sleep_until($timestamp);
$in_esecuzione->set(true);
// Registrazione dell'iterazione nei log
$logger->info('Cron #'.$number.' iniziato', [
'slot' => $slot_minimo->toDateTimeString(),
'slot-unix' => $timestamp,
]);
// Calcolo del primo slot disponibile per l'esecuzione successiva
$inizio_iterazione = $slot_minimo->copy();
$slot_minimo = $inizio_iterazione->copy()->startOfHour();
while ($inizio_iterazione->greaterThanOrEqualTo($slot_minimo)) {
$slot_minimo->addMinutes($slot_duration);
}
// Aggiornamento dei cron disponibili
$tasks = Task::all();
foreach ($tasks as $task) {
$adesso = new Carbon();
// Registrazione della data per l'esecuzione se non indicata
if (empty($task->next_execution_at)) {
$task->registerNextExecution($inizio_iterazione);
$task->save();
$logger->info($task->name.': data mancante', [
'timestamp' => $task->next_execution_at->toDateTimeString(),
]);
}
// Esecuzione diretta solo nel caso in cui sia prevista
if ($task->next_execution_at->copy()->addSeconds(20)->greaterThanOrEqualTo($inizio_iterazione) && $task->next_execution_at->lessThanOrEqualTo($adesso->copy()->addseconds(20))) {
// Registrazione dell'esecuzione nei log
$logger->info($task->name.': '.$task->expression);
try {
$task->execute();
} catch (Exception $e) {
// Registrazione del completamento nei log
$task->log('error', 'Errore di esecuzione', [
'code' => $e->getCode(),
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
$logger->error($task->name.': errore');
}
}
// Esecuzione mancata
elseif ($task->next_execution_at->lessThan($inizio_iterazione)) {
$logger->warning($task->name.': mancata', [
'timestamp' => $task->next_execution_at->toDateTimeString(),
]);
$task->registerMissedExecution($inizio_iterazione);
}
// Calcolo dello successivo slot
if ($task->next_execution_at->lessThan($slot_minimo)) {
$slot_minimo = $task->next_execution_at;
}
}
// Registrazione dello slot successivo nei log
$logger->info('Cron #'.$number.' concluso', [
'next-slot' => $slot_minimo->toDateTimeString(),
'next-slot-unix' => $timestamp,
]);
$in_esecuzione->set(false);
// Registrazione dell'esecuzione
$adesso = new Carbon();
$ultima_esecuzione->set($adesso->__toString());
++$number;
}

View File

@ -1,540 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/core.php';
use Carbon\Carbon;
// Disabilitazione dei campi
$read_only = $structure->permission == 'r';
if (empty($id_record) && !empty($id_module) && empty($id_plugin)) {
redirect(base_path().'/controller.php?id_module='.$id_module);
} elseif (empty($id_record) && empty($id_module) && empty($id_plugin)) {
redirect(base_path().'/index.php');
}
include_once App::filepath('include|custom|', 'top.php');
if (!empty($id_record)) {
Util\Query::setSegments(false);
$query = Util\Query::getQuery($structure, [
'id' => $id_record,
]);
Util\Query::setSegments(true);
}
// Rimozione della condizione deleted_at IS NULL per visualizzare anche i record eliminati
if (preg_match('/[`]*([a-z0-9_]*)[`]*[\.]*([`]*deleted_at[`]* IS NULL)/i', $query, $m)) {
$conditions_to_remove = [];
$condition = trim($m[0]);
if (!empty($table_name)) {
$condition = $table_name.'.'.$condition;
}
$conditions_to_remove[] = ' AND '.$condition;
$conditions_to_remove[] = $condition.' AND ';
$query = str_replace($conditions_to_remove, '', $query);
$query = str_replace($condition, '', $query);
}
$has_access = !empty($query) ? $dbo->fetchNum($query) !== 0 : true;
if ($has_access) {
// Inclusione gli elementi fondamentali
include_once base_dir().'/actions.php';
}
if (empty($record) || !$has_access) {
echo '
<div class="text-center">
<h3 class="text-muted">'.
'<i class="fa fa-question-circle"></i> '.tr('Record non trovato').'
<br><br>
<small class="help-block">'.tr('Stai cercando di accedere ad un record eliminato o non presente').'.</small>
</h3>
<br>
<a class="btn btn-default" href="'.base_path().'/controller.php?id_module='.$id_module.'">
<i class="fa fa-chevron-left"></i> '.tr('Indietro').'
</a>
</div>';
} else {
// Widget in alto
echo '{( "name": "widgets", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "position": "top", "place": "editor" )}';
$advanced_sessions = setting('Attiva notifica di presenza utenti sul record');
if (!empty($advanced_sessions)) {
$dbo->query('DELETE FROM zz_semaphores WHERE id_utente='.prepare(Auth::user()['id']).' AND posizione='.prepare($id_module.', '.$id_record));
$dbo->query('INSERT INTO zz_semaphores (id_utente, posizione, updated) VALUES ('.prepare(Auth::user()['id']).', '.prepare($id_module.', '.$id_record).', NOW())');
echo '
<div class="box box-warning box-solid text-center info-active hide">
<div class="box-header with-border">
<h3 class="box-title"><i class="fa fa-warning"></i> '.tr('Attenzione!').'</h3>
</div>
<div class="box-body">
<p>'.tr('I seguenti utenti stanno visualizzando questa pagina').':</p>
<ul class="list">
</ul>
<p>'.tr('Prestare attenzione prima di effettuare modifiche, poichè queste potrebbero essere perse a causa di multipli salvataggi contemporanei').'.</p>
</div>
</div>';
}
echo '
<div class="nav-tabs-custom">
<ul class="nav nav-tabs pull-right" id="tabs" role="tablist">
<li class="pull-left active header">
<a data-toggle="tab" href="#tab_0">
<i class="'.$structure['icon'].'"></i> '.$structure['title'];
// Pulsante "Aggiungi" solo se il modulo è di tipo "table" e se esiste il template per la popup
if ($structure->hasAddFile() && $structure->permission == 'rw') {
echo '
<button type="button" class="btn btn-primary" data-toggle="modal" data-title="'.tr('Aggiungi').'..." data-href="add.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'"><i class="fa fa-plus"></i></button>';
}
echo '
</a>
</li>';
echo '
<li class="control-sidebar-toggle">
<a style="cursor: pointer">'.tr('Plugin').'</a>
</li>
</ul>
<div class="tab-content">
<div id="tab_0" class="tab-pane active">';
if (!empty($record['deleted_at'])) {
$operation = $dbo->fetchOne("SELECT zz_operations.created_at, username FROM zz_operations INNER JOIN zz_users ON zz_operations.id_utente = zz_users.id WHERE op='delete' AND id_module=".prepare($id_module).' AND id_record='.prepare($id_record).' ORDER BY zz_operations.created_at DESC');
$info = tr('Il record è stato eliminato il <b>_DATE_</b> da <b>_USER_</b>', [
'_DATE_' => (($operation['created_at']) ? Translator::timestampToLocale($operation['created_at']) : Translator::timestampToLocale($record['deleted_at'])),
'_USER_' => ((!empty($operation['username'])) ? $operation['username'] : 'N.D.'),
]).'. ';
echo '
<div class="alert alert-warning">
<div class="row" >
<div class="col-md-8">
<i class="fa fa-warning"></i> '.$info.'
</div>
</div>
</div>
<script>
$(document).ready(function(){
$("#restore, #restore-close").click(function(){
$("input[name=op]").attr("value", "restore");
$("#submit").trigger("click");
})
});
</script>';
}
// Pulsanti di default
echo '
<div id="pulsanti">
<a class="btn btn-warning" href="'.base_path().'/controller.php?id_module='.$id_module.'">
<i class="fa fa-chevron-left"></i> '.tr("Torna all'elenco").'
</a>
<div class="pull-right">
{( "name": "button", "type": "print", "id_module": "'.$id_module.'", "id_plugin": "'.$id_plugin.'", "id_record": "'.$id_record.'" )}
{( "name": "button", "type": "email", "id_module": "'.$id_module.'", "id_plugin": "'.$id_plugin.'", "id_record": "'.$id_record.'" )}
<div class="btn-group" id="save-buttons">
<a class="btn btn-success" id="'.(!empty($record['deleted_at']) ? 'restore' : 'save').'">
<i class="fa fa-'.(!empty($record['deleted_at']) ? 'undo' : 'check').'"></i> '.(!empty($record['deleted_at']) ? tr('Salva e ripristina') : tr('Salva')).'
</a>
<a type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#" id="'.(!empty($record['deleted_at']) ? 'restore' : 'save').'-close">
<i class="fa fa-'.(!empty($record['deleted_at']) ? 'undo' : 'check-square-o').'"></i>
'.(!empty($record['deleted_at']) ? tr('Ripristina e chiudi') : tr('Salva e chiudi')).'
</a></li>
</ul>
</div>
</div>
</div>
<script>
$(document).ready(function(){
var form = $("#module-edit").find("form").first();
// Aggiunta del submit
form.prepend(\'<button type="submit" id="submit" class="hide"></button>\');
$("#save").click(function(){
//submitAjax(form);
$("#submit").trigger("click");
});
$("#save-close").on("click", function (){
form.find("[name=backto]").val("record-list");
$("#submit").trigger("click");
});';
// Pulsanti dinamici
if (!isMobile()) {
echo '
$("#pulsanti").affix({
offset: {
top: 200
}
});
if ($("#pulsanti").hasClass("affix")) {
$("#pulsanti").css("width", $("#tab_0").css("width"));
}
$("#pulsanti").on("affix.bs.affix", function(){
$("#pulsanti").css("width", $("#tab_0").css("width"));
});
$("#pulsanti").on("affix-top.bs.affix", function(){
$("#pulsanti").css("width", "100%");
});';
}
echo '
});
</script>
<div class="clearfix"></div>
<br>';
// Pulsanti personalizzati
$buttons = $structure->filepath('buttons.php');
if (!empty($buttons)) {
ob_start();
include $buttons;
$buttons = ob_get_clean();
echo '
<div class="pull-right" id="pulsanti-modulo">
'.$buttons.'
</div>
<div class="clearfix"></div>
<br>';
}
// Contenuti del modulo
echo '
<div id="module-edit">';
$path = $structure->getEditFile();
if (!empty($path)) {
include $path;
}
echo '
</div>
</div>';
// Campi personalizzati
echo '
<div class="hide" id="custom_fields_top-edit">
{( "name": "custom_fields", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "position": "top" )}
</div>
<div class="hide" id="custom_fields_bottom-edit">
{( "name": "custom_fields", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'" )}
</div>
<script>
$(document).ready(function(){
let form = $("#module-edit").parent().find("form").first();
// Ultima sezione/campo del form
let last = form.find(".panel").last();
if (!last.length) {
last = form.find(".box").last();
}
if (!last.length) {
last = form.find(".row").eq(-2);
}
// Campi a inizio form
aggiungiContenuto(form, "#custom_fields_top-edit", {}, true);
// Campi a fine form
aggiungiContenuto(last, "#custom_fields_bottom-edit", {});
});
</script>';
if ($structure->permission != '-' && $structure->use_notes && $user->gruppo != 'Clienti') {
echo '
<div id="tab_note" class="tab-pane">';
include base_dir().'/plugins/notes.php';
echo '
</div>';
}
if ($structure->permission != '-' && $structure->use_checklists) {
echo '
<div id="tab_checks" class="tab-pane">';
include base_dir().'/plugins/checks.php';
echo '
</div>';
}
// Informazioni sulle operazioni
if (Auth::admin()) {
echo '
<div id="tab_info" class="tab-pane">';
$operations = $dbo->fetchArray('SELECT `zz_operations`.*, `zz_users`.`username` FROM `zz_operations` JOIN `zz_users` ON `zz_operations`.`id_utente` = `zz_users`.`id` WHERE id_module = '.prepare($id_module).' AND id_record = '.prepare($id_record).' ORDER BY `created_at` DESC LIMIT 200');
if (!empty($operations)) {
echo '
<ul class="timeline">';
foreach ($operations as $operation) {
$description = $operation['op'];
$icon = 'pencil-square-o';
$color = null;
$timeline_class = null;
switch ($operation['op']) {
case 'add':
$description = tr('Creazione');
$icon = 'plus';
$color = 'success';
break;
case 'update':
$description = tr('Modifica');
$icon = 'pencil';
$color = 'info';
break;
case 'delete':
$description = tr('Eliminazione');
$icon = 'times';
$color = 'danger';
break;
case 'copy':
$description = tr('Duplicato');
$icon = 'clone';
$color = 'info';
break;
default:
$timeline_class = ' class="timeline-inverted"';
break;
}
echo '
<li '.$timeline_class.'>
<div class="timeline-badge '.$color.'"><i class="fa fa-'.$icon.'"></i></div>
<div class="timeline-panel">
<div class="timeline-heading">
<div class="row">
<div class="col-md-8">
<h4 class="timeline-title">'.$description.'</h4>
</div>
<div class="col-md-4 text-right">
<p><small class="label label-default tip" title="'.Translator::timestampToLocale($operation['created_at']).'"><i class="fa fa-clock-o"></i> '.Carbon::parse($operation['created_at'])->diffForHumans().'</small></p>
<p><small class="label label-default"><i class="fa fa-user"></i> '.$operation['username'].'</small></p>
</div>
</div>
</div>
<div class="timeline-body">
</div>
<div class="timeline-footer">
</div>
</div>
</li>';
}
echo '
</ul>';
} else {
echo '
<div class="alert alert-info">
<i class="fa fa-info-circle"></i>
<b>'.tr('Informazione:').'</b> '.tr('Nessun log disponibile per questa scheda').'.
</div>';
}
echo '
</div>';
}
// Plugin
$module_record = $record;
foreach ($plugins as $plugin) {
$record = $module_record;
echo '
<div id="tab_'.$plugin['id'].'" class="tab-pane">';
$id_plugin = $plugin['id'];
include base_dir().'/include/manager.php';
echo '
</div>';
}
$record = $module_record;
echo '
</div>
</div>';
}
redirectOperation($id_module, isset($id_parent) ? $id_parent : $id_record);
// Widget in basso
echo '{( "name": "widgets", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "position": "right", "place": "editor" )}';
if (!empty($record)) {
echo '
<hr>
<a class="btn btn-default" href="'.base_path().'/controller.php?id_module='.$id_module.'">
<i class="fa fa-chevron-left"></i> '.tr('Indietro').'
</a>';
}
echo '
<script>';
// Se l'utente ha i permessi in sola lettura per il modulo, converto tutti i campi di testo in span
if ($read_only || !empty($block_edit)) {
$not = $read_only ? '' : '.not(".unblockable")';
echo '
$(document).ready(function(){
$("input, textarea, select", "section.content")'.$not.'.attr("readonly", "true");
$("select, input[type=checkbox]", "section.content")'.$not.'.prop("disabled", true);
$(".checkbox-buttons label", "section.content")'.$not.'.addClass("disabled");
';
// Nascondo il plugin Note interne ai clienti
if ($user->gruppo == 'Clienti') {
echo '
$("#link-tab_note").hide();';
}
if ($read_only) {
echo '
$("a.btn, button, input[type=button], input[type=submit]", "section.content").hide();
$("a.btn-info, button.btn-info, input[type=button].btn-info", "section.content").show();';
}
echo '
});';
}
?>
var content_was_modified = false;
// Controllo se digito qualche valore o cambio qualche select
$(".content input, .content textarea, .content select").bind("change paste keyup", function(event) {
if (event.keyCode >= 32) {
content_was_modified = true;
}
});
$(".content .superselect, .content .superselectajax").on("change", function (e) {
content_was_modified = true;
});
// Tolgo il controllo se sto salvando
$(".content .btn-success, .content button[type=submit]").bind("click", function() {
content_was_modified = false;
});
$("form").bind("submit", function() {
content_was_modified = false;
});
// questo controllo blocca il modulo vendita al banco, dopo la lettura con barcode, appare il messaggio di conferma
window.onbeforeunload = function(e) {
if(content_was_modified) {
var dialogText = "Uscire senza salvare?";
e.returnValue = dialogText;
$("#main_loading").fadeOut();
return dialogText;
}
};
window.addEventListener("unload", function(e) {
$("#main_loading").show();
});
<?php
if (!empty($advanced_sessions)) {
?>
function getActiveUsers(){
$.getJSON('<?php echo base_path(); ?>/ajax.php?op=active_users', {
id_module: <?php echo $id_module; ?>,
id_record: <?php echo $id_record; ?>
},
function(data) {
if (data.length != 0) {
$(".info-active").removeClass("hide");
$(".info-active .list").html("");
$.each( data, function( key, val ) {
$(".info-active .list").append("<li>"+val.username+"</li>");
});
}
else $(".info-active").addClass("hide");
});
}
getActiveUsers();
setInterval(getActiveUsers, <?php echo setting('Timeout notifica di presenza (minuti)') * 60 * 1000; ?>);
<?php
}
?>
</script>
<?php
include_once App::filepath('include|custom|', 'bottom.php');

View File

@ -1,7 +0,0 @@
# Disable PHP rendering
<IfModule mod_php5.c>
php_flag engine off
</IfModule>
<IfModule mod_php7.c>
php_flag engine off
</IfModule>

View File

@ -1,20 +0,0 @@
[Nome]
tipo = span
valore = "Componente di esempio"
[Marca]
tipo = input
valore =
[Tipo]
tipo = select
valore =
opzioni = "Tipo 1", "Tipo 2"
[Data di installazione]
tipo = date
valore =
[Note]
tipo = textarea
valore =

View File

@ -1 +0,0 @@
Deny from all

View File

@ -1,97 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../core.php';
if (Auth::check()) {
echo '
</div>
</div><!-- /.row -->
</section><!-- /.content -->
</aside><!-- /.content-wrapper -->
<footer class="main-footer">
<a class="hidden-xs" href="'.tr('https://www.openstamanager.com').'" title="'.tr("Il gestionale open source per l'assistenza tecnica e la fatturazione").'." target="_blank"><strong>'.tr('OpenSTAManager').'</strong></a>
<span class="pull-right hidden-xs">
<strong>'.tr('Versione').'</strong> '.$version.'
<small class="text-muted">('.(!empty($revision) ? $revision : tr('In sviluppo')).')</small>
</span>
</footer>
<div id="modals">
</div>';
}
echo '
</div><!-- ./wrapper -->';
if (Auth::check()) {
if (!empty($_SESSION['keep_alive'])) {
echo '
<script> setInterval("session_keep_alive()", 5*60*1000); </script>';
}
if (App::debug()) {
echo '
<!-- Fix per le icone di debug -->
<style>div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-copy-clipboard:before, div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-database:before, div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-duration:before, div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-memory:before, div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-row-count:before, div.phpdebugbar-widgets-sqlqueries span.phpdebugbar-widgets-stmt-id:before {
font-family: FontAwesome;
}</style>
<!-- Rimozione del messaggio automatico riguardante la modifica di valori nella pagina -->
<script>
window.onbeforeunload = null;
</script>';
}
$custom_css = html_entity_decode(setting('CSS Personalizzato'));
if (!empty($custom_css)) {
echo '
<style>'.$custom_css.'</style>';
}
// Hooks
echo '
<script>
$(document).ready(function() {
// Toast
alertPush();
// Orologio
clock();
// Hooks
startHooks();
// Abilitazione del cron autonoma
$.get(globals.rootdir + "/cron.php");
});
</script>';
}
echo '
<script>$(document).ready(init)</script>
</body>
</html>';
// Retrocompatibilità
if (!empty($id_record) || basename($_SERVER['PHP_SELF']) == 'controller.php' || basename($_SERVER['PHP_SELF']) == 'index.php') {
unset($_SESSION['infos']);
unset($_SESSION['errors']);
unset($_SESSION['warnings']);
}

View File

@ -1,95 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../core.php';
// Compatibilità per controller ed editor
$structure = Modules::get($id_module);
echo '
<p>'.tr('Trascina le colonne per ordinare la struttura della tabella principale, seleziona e deseleziona le colonne per renderle visibili o meno').'.</p>
<div class="sortable">';
$fields = $dbo->fetchArray('SELECT *, (SELECT GROUP_CONCAT(zz_groups.nome) FROM zz_group_view INNER JOIN zz_groups ON zz_group_view.id_gruppo = zz_groups.id WHERE zz_group_view.id_vista = zz_views.id) AS gruppi_con_accesso FROM zz_views WHERE id_module='.prepare($id_module).' ORDER BY `order` ASC');
foreach ($fields as $field) {
echo '
<div class="panel panel-default clickable col-md-4" data-id="'.$field['id'].'">
<div class="panel-body no-selection">
<input type="checkbox" name="visibile" '.($field['visible'] ? 'checked' : '').'>
<span class="text-'.($field['visible'] ? 'success' : 'danger').'">'.$field['name'].'<br><small>( '.$field['gruppi_con_accesso'].')</small></span>
<i class="fa fa-sort pull-right"></i>
</div>
</div>';
}
echo '
</div>
<div class="clearfix"></div>
<script>
// Abilitazione dinamica delle colonne
$("input[name=visibile]").change(function() {
let panel = $(this).closest(".panel[data-id]");
let id = panel.data("id");
// Aggiornamento effettivo
$.post(globals.rootdir + "/actions.php", {
id_module: "'.$id_module.'",
op: "toggle_colonna",
id_vista: id,
visible: $(this).is(":checked") ? 1 : 0,
});
// Aggiornamento grafico
let text = panel.find("span");
if ($(this).is(":checked")) {
text.removeClass("text-danger")
.addClass("text-success");
} else {
text.removeClass("text-success")
.addClass("text-danger");
}
});
// Ricaricamento della pagina alla chiusura
$("#modals > div button.close").on("click", function() {
location.reload();
});
// Ordinamento dinamico delle colonne
$(document).ready(function() {
sortable(".sortable", {
axis: "y",
cursor: "move",
dropOnEmpty: true,
scroll: true,
})[0].addEventListener("sortupdate", function(e) {
let order = $(".panel[data-id]").toArray().map(a => $(a).data("id"))
console.log(order);
$.post(globals.rootdir + "/actions.php", {
id_module: globals.id_module,
op: "ordina_colonne",
order: order.join(","),
});
});
});
</script>';

View File

@ -1,359 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$result['idarticolo'] = isset($result['idarticolo']) ? $result['idarticolo'] : null;
$qta_minima = 0;
// Articolo
if (empty($result['idarticolo'])) {
// Sede partenza
if ($module['name'] == 'Interventi') {
echo '
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Partenza merce').'", "required": "1", "id":"idsede", "name": "idsede_partenza", "ajax-source": "sedi_azienda", "value": "'.($result['idsede_partenza'] ?: $options['idsede_partenza']).'" ]}
</div>
</div>';
}
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "idarticolo", "required": 1, "value": "'.$result['idarticolo'].'", "ajax-source": "articoli", "select-options": '.json_encode($options['select-options']['articoli']).', "icon-after": "add|'.Modules::get('Articoli')['id'].'" ]}
</div>
</div>
<input type="hidden" name="id_dettaglio_fornitore" id="id_dettaglio_fornitore" value="">';
} else {
$database = database();
$articolo = $database->fetchOne('SELECT mg_articoli.id,
mg_fornitore_articolo.id AS id_dettaglio_fornitore,
IFNULL(mg_fornitore_articolo.codice_fornitore, mg_articoli.codice) AS codice,
IFNULL(mg_fornitore_articolo.descrizione, mg_articoli.descrizione) AS descrizione,
IFNULL(mg_fornitore_articolo.qta_minima, 0) AS qta_minima
FROM mg_articoli
LEFT JOIN mg_fornitore_articolo ON mg_fornitore_articolo.id_articolo = mg_articoli.id AND mg_fornitore_articolo.id = '.prepare($result['id_dettaglio_fornitore']).'
WHERE mg_articoli.id = '.prepare($result['idarticolo']));
$qta_minima = $articolo['qta_minima'];
echo '
<p><strong>'.tr('Articolo').':</strong> '.$articolo['codice'].' - '.$articolo['descrizione'].'.</p>
<input type="hidden" name="idarticolo" id="idarticolo" value="'.$articolo['id'].'">
<script>
$(document).ready(function (){
ottieniDettagliArticolo("'.$articolo['id'].'").then(function (){
verificaPrezzoArticolo();
verificaScontoArticolo();
});
});
</script>';
}
echo '
<input type="hidden" name="qta_minima" id="qta_minima" value="'.$qta_minima.'">';
// Selezione impianto per gli Interventi
if ($module['name'] == 'Interventi') {
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Impianto su cui installare').'", "name": "idimpianto", "value": "'.$idimpianto.'", "ajax-source": "impianti-intervento", "select-options": '.json_encode($options['select-options']['impianti']).' ]}
</div>
</div>';
}
echo App::internalLoad('riga.php', $result, $options);
// Informazioni aggiuntive
$disabled = empty($result['idarticolo']);
echo '
<div class="row '.(!empty($options['nascondi_prezzi']) ? 'hidden' : '').'" id="prezzi_articolo">
<div class="col-md-4 text-center">
<button type="button" class="btn btn-sm btn-info btn-block '.($disabled ? 'disabled' : '').'" '.($disabled ? 'disabled' : '').' onclick="$(\'#prezziacquisto\').toggleClass(\'hide\'); $(\'#prezziacquisto\').load(\''.base_path()."/ajax_complete.php?module=Articoli&op=getprezziacquisto&idarticolo=' + ( $('#idarticolo option:selected').val() || $('#idarticolo').val()) + '&idanagrafica=".$options['idanagrafica'].'\');">
<i class="fa fa-shopping-cart"></i> '.tr('Ultimi prezzi di acquisto').'
</button>
<div id="prezziacquisto" class="hide"></div>
</div>
<div class="col-md-4 text-center">
<button type="button" class="btn btn-sm btn-info btn-block '.($disabled ? 'disabled' : '').'" '.($disabled ? 'disabled' : '').' onclick="$(\'#prezzi\').toggleClass(\'hide\'); $(\'#prezzi\').load(\''.base_path()."/ajax_complete.php?module=Articoli&op=getprezzi&idarticolo=' + ( $('#idarticolo option:selected').val() || $('#idarticolo').val()) + '&idanagrafica=".$options['idanagrafica'].'\');">
<i class="fa fa-handshake-o"></i> '.($options['dir'] == 'entrata' ? tr('Ultimi prezzi al cliente') : tr('Ultimi prezzi dal fornitore')).'
</button>
<div id="prezzi" class="hide"></div>
</div>
<div class="col-md-4 text-center">
<button type="button" class="btn btn-sm btn-info btn-block '.($disabled ? 'disabled' : '').'" '.($disabled ? 'disabled' : '').' onclick="$(\'#prezzivendita\').toggleClass(\'hide\'); $(\'#prezzivendita\').load(\''.base_path()."/ajax_complete.php?module=Articoli&op=getprezzivendita&idarticolo=' + ( $('#idarticolo option:selected').val() || $('#idarticolo').val()) + '&idanagrafica=".$options['idanagrafica'].'\');">
<i class="fa fa-money"></i> '.tr('Ultimi prezzi di vendita').'
</button>
<div id="prezzivendita" class="hide"></div>
</div>
</div>
<br>
<script>
var direzione = "'.$options['dir'].'";
globals.aggiunta_articolo = {
};
$(document).ready(function () {
if (direzione === "uscita") {
aggiornaQtaMinima();
$("#qta").keyup(aggiornaQtaMinima);
}
});
$("#tipo_sconto").on("change", function() {
verificaScontoArticolo();
});
$("#idarticolo").on("change", function() {
// Operazioni sui prezzi in fondo alla pagina
let prezzi_precedenti = $("#prezzi_articolo button");
if (prezzi_precedenti.length) {
prezzi_precedenti.attr("disabled", !$(this).val());
if ($(this).val()) {
prezzi_precedenti.removeClass("disabled");
} else {
prezzi_precedenti.addClass("disabled");
}
$("#prezzi").html("");
$("#prezzivendita").html("");
$("#prezziacquisto").html("");
}
if (!$(this).val()) {
return;
}
// Autoimpostazione dei campi relativi all\'articolo
let $data = $(this).selectData();
ottieniDettagliArticolo($data.id).then(function() {
if ($("#prezzo_unitario").val().toEnglish() === 0){
aggiornaPrezzoArticolo();
} else {
verificaPrezzoArticolo();
}
if ($("#sconto").val().toEnglish() === 0){
aggiornaScontoArticolo();
} else {
verificaScontoArticolo();
}
});
$("#costo_unitario").val($data.prezzo_acquisto);
$("#descrizione_riga").val($data.descrizione);
if (direzione === "entrata") {
if($data.idiva_vendita) {
$("#idiva").selectSetNew($data.idiva_vendita, $data.iva_vendita);
}
}
else {
$("#id_dettaglio_fornitore").val($data.id_dettaglio_fornitore);
$("#qta_minima").val($data.qta_minima);
aggiornaQtaMinima();
}
let id_conto = $data.idconto_'.($options['dir'] == 'entrata' ? 'vendita' : 'acquisto').';
let id_conto_title = $data.idconto_'.($options['dir'] == 'entrata' ? 'vendita' : 'acquisto').'_title;
if(id_conto) {
$("#idconto").selectSetNew(id_conto, id_conto_title);
}
$("#um").selectSetNew($data.um, $data.um);
// Aggiornamento automatico di guadagno e margine
});
$("#idsede").on("change", function() {
updateSelectOption("idsede_partenza", $(this).val());
session_set("superselect,idsede_partenza", $(this).val(), 0);
$("#idarticolo").selectReset();
});
$(document).on("change", "input[name^=qta], input[name^=prezzo_unitario], input[name^=sconto]", function() {
verificaPrezzoArticolo();
verificaScontoArticolo();
});
/**
* Restituisce il dettaglio registrato per una specifica quantità dell\'articolo.
*/
function getDettaglioPerQuantita(qta) {
const data = globals.aggiunta_articolo.dettagli;
if (!data) return null;
let dettaglio_predefinito = null;
let dettaglio_selezionato = null;
for (const dettaglio of data) {
if (dettaglio.minimo == null && dettaglio.massimo == null) {
dettaglio_predefinito = dettaglio;
continue;
}
if (qta >= dettaglio.minimo && qta <= dettaglio.massimo) {
dettaglio_selezionato = dettaglio;
}
}
if (dettaglio_selezionato == null) {
dettaglio_selezionato = dettaglio_predefinito;
}
return dettaglio_selezionato;
}
/**
* Restituisce il prezzo registrato per una specifica quantità dell\'articolo.
*/
function getPrezzoPerQuantita(qta) {
const dettaglio = getDettaglioPerQuantita(qta);
return dettaglio ? parseFloat(dettaglio.prezzo_unitario) : 0;
}
/**
* Restituisce lo sconto registrato per una specifica quantità dell\'articolo.
*/
function getScontoPerQuantita(qta) {
const dettaglio = getDettaglioPerQuantita(qta);
return dettaglio ? parseFloat(dettaglio.sconto_percentuale) : 0;
}
/**
* Funzione per registrare localmente i dettagli definiti per l\'articolo in relazione ad una specifica anagrafica.
*/
function ottieniDettagliArticolo(id_articolo) {
return $.get(globals.rootdir + "/ajax_complete.php?module=Articoli&op=dettagli_articolo&id_anagrafica='.$options['idanagrafica'].'&id_articolo=" + id_articolo + "&dir=" + direzione, function(response) {
const data = JSON.parse(response);
globals.aggiunta_articolo.dettagli = data;
});
}
/**
* Funzione per verificare se il prezzo unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione.
*/
function verificaPrezzoArticolo() {
let qta = $("#qta").val().toEnglish();
let prezzo_previsto = getPrezzoPerQuantita(qta);
let prezzo_unitario_input = $("#prezzo_unitario");
let prezzo_unitario = prezzo_unitario_input.val().toEnglish();
let div = prezzo_unitario_input.closest("div").parent().find("div[id*=errors]");
if (prezzo_previsto === prezzo_unitario) {
div.css("padding-top", "0");
div.html("");
return;
}
div.css("padding-top", "5px");
div.html(`<small class="label label-warning" >'.tr('Prezzo suggerito').': ` + prezzo_previsto.toLocale() + globals.currency + `<button type="button" class="btn btn-xs btn-info pull-right" onclick="aggiornaPrezzoArticolo()"><i class="fa fa-refresh"></i> '.tr('Aggiorna').'</button></small>`);
}
/**
* Funzione per verificare se lo sconto unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione.
*/
function verificaScontoArticolo() {
let qta = $("#qta").val().toEnglish();
let sconto_previsto = getScontoPerQuantita(qta);
let sconto_input = $("#sconto");
let sconto = sconto_input.val().toEnglish();
let div = sconto_input.parent().next();
if (sconto_previsto === 0 || sconto_previsto === sconto || $("#tipo_sconto").val() === "UNT") {
div.css("padding-top", "0");
div.html("");
return;
}
div.css("padding-top", "5px");
div.html(`<small class="label label-warning" >'.tr('Sconto suggerito').': ` + sconto_previsto.toLocale() + `%<button type="button" class="btn btn-xs btn-info pull-right" onclick="aggiornaScontoArticolo()"><i class="fa fa-refresh"></i> '.tr('Aggiorna').'</button></small>`);
}
/**
* Funzione per aggiornare il prezzo unitario sulla base dei valori automatici.
*/
function aggiornaPrezzoArticolo() {
let qta = $("#qta").val().toEnglish();
let prezzo_previsto = getPrezzoPerQuantita(qta);
$("#prezzo_unitario").val(prezzo_previsto).trigger("change");
// Aggiornamento automatico di guadagno e margine
if (direzione === "entrata") {
aggiorna_guadagno();
}
}
/**
* Funzione per aggiornare lo sconto unitario sulla base dei valori automatici.
*/
function aggiornaScontoArticolo() {
let qta = $("#qta").val().toEnglish();
let sconto_previsto = getScontoPerQuantita(qta);
$("#sconto").val(sconto_previsto).trigger("change");
// Aggiornamento automatico di guadagno e margine
if (direzione === "entrata") {
aggiorna_guadagno();
}
}
/**
* Funzione per l\'aggiornamento dinamico della quantità minima per l\'articolo.
*/
function aggiornaQtaMinima() {
let qta_minima = parseFloat($("#qta_minima").val());
let qta = $("#qta").val().toEnglish();
if (qta_minima === 0) {
return;
}
let parent = $("#qta").closest("div").parent();
let div = parent.find("div[id*=errors]");
div.html("<small>'.tr('Quantità minima').': " + qta_minima.toLocale() + "</small>");
if (qta < qta_minima) {
parent.addClass("has-error");
div.addClass("text-danger").removeClass("text-success");
} else {
parent.removeClass("has-error");
div.removeClass("text-danger").addClass("text-success");
}
}
if (direzione === "entrata") {
aggiorna_guadagno();
}
</script>';

View File

@ -1,364 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$incorpora_iva = setting('Utilizza prezzi di vendita comprensivi di IVA');
$intestazione_prezzo = ($options['dir'] == 'uscita' ? tr('Prezzo di acquisto') : ($incorpora_iva ? tr('Prezzo vendita ivato') : tr('Prezzo vendita imponibile')));
// Articolo
echo '
<div class="row">
<div class="col-md-offset-4 col-md-4">
{[ "type": "text", "label": "", "name": "barcode", "value": "", "icon-before": "<i class=\"fa fa-barcode\"></i>" ]}
</div>
</div>
<div class="alert alert-info hidden" id="articolo-missing">
<i class="fa fa-exclamation-circle"></i> '.tr('Nessuna corrispondenza trovata!').'
</div>
<div class="alert alert-warning hidden" id="articolo-qta">
<i class="fa fa-warning"></i> '.tr('Articolo con quantità non sufficiente!').'
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-stripped hide" id="articoli_barcode">
<tr>
<th>'.tr('Articolo').'</th>
<th width="25%">'.$intestazione_prezzo.'</th>
<th width="20%" class="text-center">'.tr('Sconto').'</th>
<th width="10%" class="text-center">'.tr('Q.').'</th>
<th width="5%" class="text-center">#</th>
</tr>
</table>
</div>
</div> ';
echo '
<script>
var direzione = "'.$options['dir'].'";
$(document).ready(function(){
init();
setTimeout(function(){
$("#barcode").focus();
}, 300);
$(".modal-body button").attr("disabled", true);
});
// Gestione dell\'invio da tastiera
$(document).keypress(function(event){
let key = window.event ? event.keyCode : event.which; // IE vs Netscape/Firefox/Opera
if (key == "13") {
event.preventDefault();
$("#barcode").blur()
.focus();
}
});
$("#barcode").off("keyup").on("keyup", function (event) {
let key = window.event ? event.keyCode : event.which; // IE vs Netscape/Firefox/Opera
$("#articolo-missing").addClass("hidden");
$("#articolo-qta").addClass("hidden");
if (key !== 13) {
return;
}
$("#barcode").attr("disabled", true);
var barcode = $("#barcode").val();
if (!barcode){
barcodeReset();
return;
}
$.getJSON(globals.rootdir + "/ajax_select.php?op=articoli_barcode&search=" + barcode + "&id_anagrafica='.$options['idanagrafica'].'", function(response) {
let result = response.results[0];
if(!result){
$("#articolo-missing").removeClass("hidden");
barcodeReset();
return;
}
let qta_input = $("#riga_barcode_" + result.id).find("[name^=qta]");
if (result.qta == 0) {
$("#articolo-qta").removeClass("hidden");
barcodeReset();
return;
}
// Controllo se è già presente l\'articolo, in tal caso incremento la quantità, altrimenti inserisco la riga nuova
if (qta_input.length) {
let qta = qta_input.val().toEnglish();
let nuova_qta = qta + 1;
if (result.qta < nuova_qta) {
$("#articolo-qta").removeClass("hidden");
barcodeReset();
return;
}
qta_input.val(nuova_qta).trigger("change");
} else {
let prezzo_unitario = (direzione === "uscita") ? result.prezzo_acquisto : result.prezzo_vendita;
prezzo_acquisto = parseFloat(result.prezzo_acquisto, 10).toLocale();
prezzo_vendita = parseFloat(result.prezzo_vendita, 10).toLocale();
let info_prezzi;
if(direzione === "entrata") {
info_prezzi = "Acquisto: " + (prezzo_acquisto) + " &euro;";
}else{
info_prezzi = "Vendita: " + (prezzo_vendita) + " &euro;";
}
$("#articoli_barcode").removeClass("hide");
cleanup_inputs();
var text = replaceAll($("#barcode-template").html(), "-id-", result.id);
text = text.replace("|prezzo_unitario|", prezzo_unitario)
.replace("|info_prezzi|", info_prezzi)
.replace("|descrizione|", result.descrizione)
.replace("|codice|", result.codice)
.replace("|qta|", 1)
.replace("|sconto_unitario|", 0)
.replace("|tipo_sconto|", "")
.replace("|id_dettaglio_fornitore|", result.id_dettaglio_fornitore ? result.id_dettaglio_fornitore : "")
$("#articoli_barcode tr:last").after(text);
restart_inputs();
$(".modal-body button").attr("disabled", false);
// Gestione dinamica dei prezzi
let tr = $("#riga_barcode_" + result.id);
ottieniDettagliArticolo(result.id, tr).then(function() {
if ($(tr).find("input[name^=prezzo_unitario]").val().toEnglish() === 0){
aggiornaPrezzoArticolo(tr);
} else {
verificaPrezzoArticolo(tr);
}
if ($(tr).find("input[name^=sconto]").val().toEnglish() === 0){
aggiornaScontoArticolo();
} else {
verificaScontoArticolo();
}
});
}
barcodeReset();
$("#barcode").val("");
}, function(){
$("#articolo-missing").removeClass("hidden");
barcodeReset();
});
});
$(document).on("change", "input[name^=qta], input[name^=prezzo_unitario]", function() {
let tr = $(this).closest("tr");
verificaPrezzoArticolo(tr);
});
function barcodeReset() {
setTimeout(function(){
$("#barcode")
.attr("disabled",false)
.focus();
},200);
}
function rimuoviRigaBarcode(id) {
if (confirm("'.tr('Eliminare questo articolo?').'")) {
$("#riga_barcode_" + id).remove();
// Disabilito il pulsante di aggiunta se non ci sono articoli inseriti
if ($(".inputmask-decimal").length === 0) {
$(".modal-body button").attr("disabled", true);
$("#articoli_barcode").addClass("hide");
}
}
}
/**
* Restituisce il prezzo registrato per una specifica quantità dell\'articolo.
*/
function getDettaglioPerQuantita(qta, tr) {
const data = $(tr).data("dettagli");
if (!data) return null;
let dettaglio_predefinito = null;
let dettaglio_selezionato = null;
for (const dettaglio of data) {
if (dettaglio.minimo == null && dettaglio.massimo == null) {
dettaglio_predefinito = dettaglio;
continue;
}
if (qta >= dettaglio.minimo && qta <= dettaglio.massimo) {
dettaglio_selezionato = dettaglio;
}
}
if (dettaglio_selezionato == null) {
dettaglio_selezionato = dettaglio_predefinito;
}
return dettaglio_selezionato;
}
/**
* Restituisce il prezzo registrato per una specifica quantità dell\'articolo.
*/
function getPrezzoPerQuantita(qta, tr) {
const dettaglio = getDettaglioPerQuantita(qta, tr);
return dettaglio ? parseFloat(dettaglio.prezzo_unitario) : 0;
}
/**
* Restituisce lo sconto registrato per una specifica quantità dell\'articolo.
*/
function getScontoPerQuantita(qta, tr) {
const dettaglio = getDettaglioPerQuantita(qta, tr);
return dettaglio ? parseFloat(dettaglio.sconto_percentuale) : 0;
}
/**
* Funzione per registrare localmente i dettagli definiti per l\'articolo in relazione ad una specifica anagrafica.
*/
function ottieniDettagliArticolo(id_articolo, tr) {
return $.get(globals.rootdir + "/ajax_complete.php?module=Articoli&op=dettagli_articolo&id_anagrafica='.$options['idanagrafica'].'&id_articolo=" + id_articolo + "&dir=" + direzione, function(response) {
const data = JSON.parse(response);
$(tr).data("dettagli", data);
});
}
/**
* Funzione per verificare se il prezzo unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione.
*/
function verificaPrezzoArticolo(tr) {
let qta = $(tr).find("input[name^=qta]").val().toEnglish();
let prezzo_previsto = getPrezzoPerQuantita(qta, tr);
let prezzo_unitario_input = $(tr).find("input[name^=prezzo_unitario]");
let prezzo_unitario = prezzo_unitario_input.val().toEnglish();
let div = prezzo_unitario_input.closest("div").parent().find("div[id*=errors]");
if (prezzo_previsto === prezzo_unitario) {
div.css("padding-top", "0");
div.html("");
return;
}
div.css("padding-top", "5px");
div.html(`<small class="label label-warning" >'.tr('Prezzo suggerito').': ` + prezzo_previsto.toLocale() + globals.currency + `<button type="button" class="btn btn-xs btn-info pull-right" onclick="aggiornaPrezzoArticolo(this)"><i class="fa fa-refresh"></i> '.tr('Aggiorna').'</button></small>`);
}
/**
* Funzione per aggiornare il prezzo unitario sulla base dei valori automatici.
*/
function aggiornaPrezzoArticolo(button) {
let tr = $(button).closest("tr");
let qta = tr.find("input[name^=qta]").val().toEnglish();
let prezzo_previsto = getPrezzoPerQuantita(qta, tr);
tr.find("input[name^=prezzo_unitario]").val(prezzo_previsto).trigger("change");
// Aggiornamento automatico di guadagno e margine
if (direzione === "entrata") {
aggiorna_guadagno();
}
}
/**
* Funzione per verificare se lo sconto unitario corrisponde a quello registrato per l\'articolo, e proporre in automatico una correzione.
*/
function verificaScontoArticolo(tr) {
let qta = $(tr).find("input[name^=qta]").val().toEnglish();
let sconto_previsto = getScontoPerQuantita(qta, tr);
let sconto_input = $(tr).find("input[name^=sconto]");
let sconto = sconto_input.val().toEnglish();
let div = sconto_input.parent().next();
if (sconto_previsto === 0 || sconto_previsto === sconto || $(tr).find("input[name^=tipo_sconto]").val() === "UNT") {
div.css("padding-top", "0");
div.html("");
return;
}
div.css("padding-top", "5px");
div.html(`<small class="label label-warning" >'.tr('Sconto suggerito').': ` + sconto_previsto.toLocale() + `%<button type="button" class="btn btn-xs btn-info pull-right" onclick="aggiornaScontoArticolo(this)"><i class="fa fa-refresh"></i> '.tr('Aggiorna').'</button></small>`);
}
/**
* Funzione per aggiornare lo sconto unitario sulla base dei valori automatici.
*/
function aggiornaScontoArticolo(button) {
let tr = $(button).closest("tr");
let qta = tr.find("input[name^=qta]").val().toEnglish();
let sconto_previsto = getScontoPerQuantita(qta, tr);
$("#sconto").val(sconto_previsto).trigger("change");
// Aggiornamento automatico di guadagno e margine
if (direzione === "entrata") {
aggiorna_guadagno();
}
}
</script>
<table class="hidden">
<tbody id="barcode-template">
<tr id="riga_barcode_-id-">
<td>
|codice| - |descrizione|
<br><small>|info_prezzi|</small>
<input type="hidden" name="id_dettaglio_fornitore[-id-]" value="|id_dettaglio_fornitore|">
</td>
<td>
{[ "type": "number", "name": "prezzo_unitario[-id-]", "value": "|prezzo_unitario|", "required": 0, "icon-after": "'.currency().'" ]}
</td>
<td>
{[ "type": "number", "name": "sconto[-id-]", "value": "|sconto_unitario|", "icon-after": "choice|untprc||tipo_sconto|", "help": "'.tr('Il valore positivo indica uno sconto. Per applicare una maggiorazione inserire un valore negativo.').'" ]}
</td>
<td>
{[ "type": "number", "name": "qta[-id-]", "required": 0, "value": "|qta|", "decimals": "qta" ]}
</td>
<td width="5%" class="text-center">
<button type="button" class="btn btn-xs btn-danger" onclick="rimuoviRigaBarcode(\'-id-\')">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>';

View File

@ -1,118 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Informazioni aggiuntive per Fatture
if ($module['name'] != 'Fatture di acquisto' && $module['name'] != 'Fatture di vendita') {
return;
}
// Percentuale rivalsa e Percentuale ritenuta d'acconto
if ($options['action'] == 'edit') {
$id_rivalsa_inps = $result['idrivalsainps'];
$id_ritenuta_acconto = $result['idritenutaacconto'];
$calcolo_ritenuta_acconto = $result['calcolo_ritenuta_acconto'];
} elseif ($options['action'] == 'add') {
// Fattura di acquisto
if ($options['dir'] == 'uscita') {
// TODO: Luca S. questi campi non dovrebbero essere definiti all'interno della scheda fornitore?
$id_rivalsa_inps = '';
$id_ritenuta_acconto = '';
}
// Fattura di vendita
elseif ($options['dir'] == 'entrata') {
// Caso particolare per aggiunta articolo
$id_rivalsa_inps = ($options['op'] == 'addarticolo') ? '' : setting('Percentuale rivalsa');
$id_ritenuta_acconto = $options['id_ritenuta_acconto_predefined'] ?: setting("Percentuale ritenuta d'acconto");
}
}
$calcolo_ritenuta_acconto = $calcolo_ritenuta_acconto ?: setting("Metodologia calcolo ritenuta d'acconto predefinito");
echo '
<div class="row">';
// Rivalsa INPS
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Rivalsa').'", "name": "id_rivalsa_inps", "value": "'.$id_rivalsa_inps.'", "values": "query=SELECT * FROM co_rivalse", "help": "'.(($options['dir'] == 'entrata') ? setting('Tipo Cassa Previdenziale') : null).'" ]}
</div>';
// Ritenuta d'acconto
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "id_ritenuta_acconto", "value": "'.$id_ritenuta_acconto.'", "values": "query=SELECT * FROM co_ritenutaacconto" ]}
</div>';
// Calcola ritenuta d'acconto su
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Calcola ritenuta d'acconto su").'", "name": "calcolo_ritenuta_acconto", "value": "'.$calcolo_ritenuta_acconto.'", "values": "list=\"IMP\":\"Imponibile\", \"IMP+RIV\":\"Imponibile + rivalsa\""]}
</div>';
echo '
</div>';
if (!empty($options['show-ritenuta-contributi']) || empty($options['hide_conto'])) {
$width = !empty($options['show-ritenuta-contributi']) && empty($options['hide_conto']) ? 6 : 12;
echo '
<div class="row">';
// Ritenuta contributi
if (!empty($options['show-ritenuta-contributi'])) {
echo '
<div class="col-md-'.$width.'">
{[ "type": "checkbox", "label": "'.tr('Ritenuta contributi').'", "name": "ritenuta_contributi", "value": "'.$result['ritenuta_contributi'].'" ]}
</div>';
}
// Conto
if (empty($options['hide_conto'])) {
echo '
<div class="col-md-'.$width.'">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "idconto", "required": 1, "value": "'.$result['idconto'].'", "ajax-source": "'.$options['conti'].'" ]}
</div>';
}
echo '
</div>';
}
echo '
<script>
$(document).ready(function(){
if(input("id_ritenuta_acconto").get()){
$("#calcolo_ritenuta_acconto").prop("required", true);
} else{
$("#calcolo_ritenuta_acconto").prop("required", false);
input("calcolo_ritenuta_acconto").set("");
}
$("#id_ritenuta_acconto").on("change", function(){
if(input("id_ritenuta_acconto").get()){
$("#calcolo_ritenuta_acconto").prop("required", true);
} else{
$("#calcolo_ritenuta_acconto").prop("required", false);
input("calcolo_ritenuta_acconto").set("");
}
});
});
</script>';

View File

@ -1,25 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "descrizione_riga", "value": '.json_encode($result['descrizione']).', "required": 1, "extra": "rows=\"4\"" ]}
</div>
</div>';

View File

@ -1,50 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$result['id'] = isset($result['id']) ? $result['id'] : null;
// Form di inserimento riga documento
echo '
<form action="'.base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="id_plugin" value="'.$id_plugin.'">
<input type="hidden" name="hash" value="tab_'.$id_plugin.'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="'.$options['op'].'">
<input type="hidden" name="idriga" value="'.$result['id'].'">
<input type="hidden" name="dir" value="'.$options['dir'].'">';
echo '
|response|';
$button = $options['action'] == 'add' ? tr('Aggiungi') : tr('Modifica');
$icon = $options['action'] == 'add' ? 'fa-plus' : 'fa-pencil';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa '.$icon.'"></i> '.$button.'</button>
</div>
</div>
</form>';
echo '
<script>$(document).ready(init)</script>';

View File

@ -1,601 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Inizializzazione
$documento = $options['documento'];
$documento_finale = $options['documento_finale'];
if (empty($documento)) {
return;
}
// Informazioni utili
$dir = $documento->direzione;
$original_module = Modules::get($documento->module);
$name = !empty($documento_finale) ? $documento_finale->module : $options['module'];
$final_module = Modules::get($name);
// IVA predefinita
$id_iva = $id_iva ?: setting('Iva predefinita');
$righe_totali = $documento->getRighe();
if ($final_module['name'] == 'Interventi') {
$righe = $righe_totali->where('is_descrizione', '=', 0)
->where('qta_rimanente', '>', 0);
$righe_evase = $righe_totali->where('is_descrizione', '=', 0)
->where('qta_rimanente', '=', 0);
} elseif ($final_module['name'] == 'Ordini fornitore') {
$righe = $righe_totali;
$righe_evase = collect();
} else {
$righe = $righe_totali->where('qta_rimanente', '>', 0);
$righe_evase = $righe_totali->where('qta_rimanente', '=', 0);
}
if ($righe->isEmpty()) {
echo '
<p>'.tr('Non ci sono elementi da evadere').'...</p>';
return;
}
$link = !empty($documento_finale) ? base_path().'/editor.php?id_module='.$final_module['id'].'&id_record='.$documento_finale->id : base_path().'/controller.php?id_module='.$final_module['id'];
echo '
<form action="'.$link.'" method="post">
<input type="hidden" name="op" value="'.$options['op'].'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="id_documento" value="'.$documento->id.'">
<input type="hidden" name="type" value="'.$options['type'].'">
<input type="hidden" name="class" value="'.get_class($documento).'">
<input type="hidden" name="is_evasione" value="1">';
// Creazione fattura dal documento
if (!empty($options['create_document'])) {
echo '
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Nuovo documento').'</h3>
</div>
<div class="box-body">
<div class="row">
<input type="hidden" name="create_document" value="on" />
<div class="col-md-6">
{[ "type": "date", "label": "'.tr('Data del documento').'", "name": "data", "required": 1, "value": "-now-" ]}
</div>';
// Opzioni aggiuntive per le Fatture
if (in_array($final_module['name'], ['Fatture di vendita', 'Fatture di acquisto'])) {
$id_segment = $_SESSION['module_'.$final_module['id']]['id_segment'];
$stato_predefinito = $database->fetchOne("SELECT id FROM co_statidocumento WHERE descrizione = 'Bozza'");
echo '
<input type="hidden" name="reversed" value="'.$options['reversed'].'">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Stato').'", "name": "id_stato", "required": 1, "values": "query=SELECT * FROM co_statidocumento WHERE descrizione IN (\'Emessa\', \'Bozza\')", "value": "'.$stato_predefinito['id'].'"]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Ritenuta contributi').'", "name": "id_ritenuta_contributi", "value": "$id_ritenuta_contributi$", "values": "query=SELECT * FROM co_ritenuta_contributi" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.prepare($final_module['id']).' ORDER BY name", "value": "'.$id_segment.'" ]}
</div>';
}
// Opzioni aggiuntive per gli Interventi
elseif ($final_module['name'] == 'Interventi') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Stato').'", "name": "id_stato_intervento", "required": 1, "values": "query=SELECT idstatointervento AS id, descrizione, colore AS _bgcolor_ FROM in_statiintervento WHERE deleted_at IS NULL" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Tipo').'", "name": "id_tipo_intervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento" ]}
</div>';
}
// Opzioni aggiuntive per i Contratti
elseif ($final_module['name'] == 'Contratti') {
$stato_predefinito = $database->fetchOne("SELECT * FROM co_staticontratti WHERE descrizione = 'Bozza'");
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Stato').'", "name": "id_stato", "required": 1, "values": "query=SELECT id, descrizione FROM co_staticontratti", "value": "'.$stato_predefinito['id'].'" ]}
</div>';
}
// Opzioni aggiuntive per i DDT
elseif (in_array($final_module['name'], ['Ddt di vendita', 'Ddt di acquisto'])) {
$stato_predefinito = $database->fetchOne("SELECT * FROM dt_statiddt WHERE descrizione = 'Bozza'");
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Stato').'", "name": "id_stato", "required": 1, "values": "query=SELECT * FROM dt_statiddt", "value": "'.$stato_predefinito['id'].'" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Causale trasporto').'", "name": "id_causale_trasporto", "required": 1, "ajax-source": "causali", "icon-after": "add|'.Modules::get('Causali')['id'].'", "help": "'.tr('Definisce la causale del trasporto').'" ]}
</div>';
}
// Opzioni aggiuntive per gli Ordini
elseif (in_array($final_module['name'], ['Ordini cliente', 'Ordini fornitore'])) {
$stato_predefinito = $database->fetchOne("SELECT * FROM or_statiordine WHERE descrizione = 'Bozza'");
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Stato').'", "name": "id_stato", "required": 1, "values": "query=SELECT * FROM or_statiordine WHERE descrizione IN(\'Bozza\', \'Accettato\', \'In attesa di conferma\', \'Annullato\')", "value": "'.$stato_predefinito['id'].'" ]}
</div>';
}
// Selezione fornitore per Ordine fornitore
if ($options['op'] == 'add_ordine_cliente' || $options['op'] == 'add_intervento' || $options['op'] == 'add_ordine_fornitore') {
$tipo_anagrafica = $options['op'] == 'add_intervento' ? tr('Cliente') : tr('Fornitore');
$ajax = $options['op'] == 'add_intervento' ? 'clienti' : 'fornitori';
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.$tipo_anagrafica.'", "name": "idanagrafica", "required": 1, "ajax-source": "'.$ajax.'", "icon-after": "add|'.Modules::get('Anagrafiche')['id'].'|tipoanagrafica='.$tipo_anagrafica.'" ]}
</div>';
}
echo '
</div>
</div>
</div>';
}
// Conto, rivalsa INPS, ritenuta d'acconto e ritenuta contributi
if (in_array($final_module['name'], ['Fatture di vendita', 'Fatture di acquisto']) && !in_array($original_module['name'], ['Fatture di vendita', 'Fatture di acquisto'])) {
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $documento->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $documento->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$show_ritenuta_contributi = !empty($documento_finale['id_ritenuta_contributi']);
$id_conto = $documento_finale['idconto'];
if (empty($id_conto)) {
$id_conto = $dir == 'entrata' ? setting('Conto predefinito fatture di vendita') : setting('Conto predefinito fatture di acquisto');
}
echo '
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Opzioni generali delle righe').'</h3>
</div>
<div class="box-body">';
echo '
<div class="row">';
// Rivalsa INPS
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Rivalsa').'", "name": "id_rivalsa_inps", "value": "'.$id_rivalsa_inps.'", "values": "query=SELECT * FROM co_rivalse", "help": "'.($options['dir'] == 'entrata' ? setting('Tipo Cassa Previdenziale') : null).'" ]}
</div>';
// Ritenuta d'acconto
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "id_ritenuta_acconto", "value": "'.$id_ritenuta_acconto.'", "values": "query=SELECT * FROM co_ritenutaacconto" ]}
</div>';
// Calcola ritenuta d'acconto su
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Calcola ritenuta d'acconto su").'", "name": "calcolo_ritenuta_acconto", "value": "'.$calcolo_ritenuta_acconto.'", "values": "list=\"IMP\":\"Imponibile\", \"IMP+RIV\":\"Imponibile + rivalsa\"", "required": "1" ]}
</div>';
echo '
</div>';
$width = $show_ritenuta_contributi ? 6 : 12;
echo '
<div class="row">';
// Ritenuta contributi
if ($show_ritenuta_contributi) {
echo '
<div class="col-md-'.$width.'">
{[ "type": "checkbox", "label": "'.tr('Ritenuta contributi').'", "name": "ritenuta_contributi", "value": "1" ]}
</div>';
}
// Conto
echo '
<div class="col-md-'.$width.'">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "id_conto", "required": 1, "value": "'.$id_conto.'", "ajax-source": "'.($dir == 'entrata' ? 'conti-vendite' : 'conti-acquisti').'" ]}
</div>
</div>
</div>
</div>';
}
// Righe del documento
echo '
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Righe da importare').'</h3>
</div>
<table class="box-body table table-striped table-hover table-condensed">
<thead>
<tr>
<th>'.tr('Descrizione').'</th>
<th width="10%" class="text-center">'.tr('Q.').'</th>
<th width="15%">'.tr('Q. da evadere').'</th>
<th width="20%" class="text-center">'.tr('Subtot.').'</th>';
if (!empty($options['serials'])) {
echo '
<th width="20%">'.tr('Seriali').'</th>';
}
echo '
</tr>
</thead>
<tbody id="righe_documento_importato">';
foreach ($righe as $i => $riga) {
if ($final_module['name'] == 'Ordini fornitore') {
$qta_rimanente = $riga['qta'];
} else {
$qta_rimanente = $riga['qta_rimanente'];
}
$attr = 'checked="checked"';
if ($original_module['name'] == 'Preventivi') {
if (empty($riga['confermato']) && $riga['is_descrizione'] == 0) {
$attr = '';
}
}
// Descrizione
echo '
<tr data-local_id="'.$i.'">
<td style="vertical-align:middle">
<span class="hidden" id="id_articolo_'.$i.'">'.$riga['idarticolo'].'</span>
<input type="hidden" class="righe" name="righe" value="'.$i.'"/>
<input type="hidden" id="prezzo_unitario_'.$i.'" name="subtot['.$riga['id'].']" value="'.$riga['prezzo_unitario'].'" />
<input type="hidden" id="sconto_unitario_'.$i.'" name="sconto['.$riga['id'].']" value="'.$riga['sconto_unitario'].'" />
<input type="hidden" id="max_qta_'.$i.'" value="'.($options['superamento_soglia_qta'] ? '' : $riga['qta_rimanente']).'" />';
// Checkbox - da evadere?
echo '
<input type="checkbox" '.$attr.' id="checked_'.$i.'" name="evadere['.$riga['id'].']" value="on" onclick="ricalcolaTotaleRiga('.$i.');" />';
$descrizione = ($riga->isArticolo() ? $riga->articolo->codice.' - ' : '').$riga['descrizione'];
echo '&nbsp;'.nl2br($descrizione);
echo '
</td>';
// Q.tà rimanente
echo '
<td class="text-center" style="vertical-align:middle">
'.numberFormat($qta_rimanente).'
</td>';
// Q.tà da evadere
echo '
<td style="vertical-align:middle">
{[ "type": "number", "name": "qta_da_evadere['.$riga['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$qta_rimanente.'", "decimals": "qta", "min-value": "0", "extra": "'.(($riga['is_descrizione']) ? 'readonly' : '').' onkeyup=\"ricalcolaTotaleRiga('.$i.');\"" ]}
</td>';
echo '
<td style="vertical-align:middle" class="text-right">
<span id="subtotale_'.$i.'"></span>
</td>';
// Seriali
if (!empty($options['serials'])) {
echo '
<td style="vertical-align:middle">';
if (!empty($riga['abilita_serial'])) {
$serials = $riga->serials;
$list = [];
foreach ($serials as $serial) {
$list[] = [
'id' => $serial,
'text' => $serial,
];
}
if (!empty($serials)) {
echo '
{[ "type": "select", "name": "serial['.$riga['id'].'][]", "id": "serial_'.$i.'", "multiple": 1, "values": '.json_encode($list).', "value": "'.implode(',', $serials).'", "extra": "data-maximum=\"'.intval($riga['qta_rimanente']).'\"" ]}';
}
}
echo '
</td>';
}
echo '
</tr>';
}
// Totale
echo '
</tbody>
<tr>
<td colspan="3" class="text-right">
<b>'.tr('Totale').':</b>
</td>
<td class="text-right">
<span id="totale"></span>
</td>
</tr>
</table>
</div>';
// Elenco righe evase completametne
if (!$righe_evase->isEmpty()) {
echo '
<div class="box box-info collapsable collapsed-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Righe evase completamente').'</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
</div>
</div>
<table class="box-body table table-striped table-hover table-condensed">
<thead>
<tr>
<th>'.tr('Descrizione').'</th>
<th width="10%" class="text-center">'.tr('Q.').'</th>
</tr>
</thead>
<tbody>';
foreach ($righe_evase as $riga) {
echo '
<tr>
<td>'.$riga->descrizione.'</td>
<td class="text-center">'.numberFormat($riga->qta, 'qta').' '.$riga->um.'</td>
</tr>';
}
echo '
</tbody>
</table>
</div>';
}
// Gestione articolo sottoscorta
echo '
<div class="alert alert-warning hidden" id="articoli_sottoscorta">
<table class="table table-condensed">
<thead>
<tr>
<th>'.tr('Articolo').'</th>
<th class="text-center tip" width="150" title="'.tr('Quantità richiesta').'">'.tr('Q.').'</th>
<th class="text-center tip" width="150" title="'.tr('Quantità disponibile nel magazzino del gestionale').'">'.tr('Q. magazzino').'</th>
<th class="text-center" width="150">'.tr('Scarto').'</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" id="submit_btn" class="btn btn-primary pull-right">
<i class="fa fa-plus"></i> '.$options['button'].'
</button>
</div>
</div>
</form>';
echo '
<script>$(document).ready(init)</script>';
// Individuazione scorte
$articoli = $documento->articoli->groupBy('idarticolo');
$scorte = [];
foreach ($articoli as $elenco) {
$qta = $elenco->sum('qta');
$articolo = $elenco->first()->articolo;
$descrizione_riga = $articolo->codice.' - '.$articolo->descrizione;
$text = $articolo ? Modules::link('Articoli', $articolo->id, $descrizione_riga) : $descrizione_riga;
$scorte[$articolo->id] = [
'qta' => $articolo->qta,
'descrizione' => $text,
'servizio' => $articolo->servizio,
];
}
echo '
<script type="text/javascript">
var scorte = '.json_encode($scorte).';
var permetti_documento_vuoto = '.intval(!empty($options['allow-empty'])).';
var abilita_scorte = '.intval(!$documento::$movimenta_magazzino && !empty($options['tipo_documento_finale']) && $options['tipo_documento_finale']::$movimenta_magazzino).';
function controllaMagazzino() {
if(!abilita_scorte) return;
let righe = $("#righe_documento_importato tr");
// Lettura delle righe selezionate per l\'improtazione
let richieste = {};
for(const r of righe) {
let riga = $(r);
let id = $(riga).data("local_id");
let id_articolo = riga.find("[id^=id_articolo_]").text();
if (!$("#checked_" + id).is(":checked") || !id_articolo) {
continue;
}
let qta = parseFloat(riga.find("input[id^=qta_]").val());
richieste[id_articolo] = richieste[id_articolo] ? richieste[id_articolo] + qta : qta;
}
let sottoscorta = $("#articoli_sottoscorta");
let body = sottoscorta.find("tbody");
body.html("");
for(const id_articolo in richieste) {
let qta_scorta = parseFloat(scorte[id_articolo]["qta"]);
let qta_richiesta = parseFloat(richieste[id_articolo]);
if ((qta_richiesta > qta_scorta) && (scorte[id_articolo]["servizio"] !== 1)) {
body.append(`<tr>
<td>` + scorte[id_articolo]["descrizione"] + `</td>
<td class="text-right">` + qta_richiesta.toLocale() + `</td>
<td class="text-right">` + qta_scorta.toLocale() + `</td>
<td class="text-right">` + (qta_richiesta - qta_scorta).toLocale() + `</td>
</tr>`);
}
}
if (body.html()) {
sottoscorta.removeClass("hidden");
} else {
sottoscorta.addClass("hidden");
}
}
$("input[name=righe]").each(function() {
ricalcolaTotaleRiga($(this).val());
});
function ricalcolaTotaleRiga(r) {
let prezzo_unitario = $("#prezzo_unitario_" + r).val();
let sconto = $("#sconto_unitario_" + r).val();
let max_qta_input = $("#max_qta_" + r);
let qta_max = max_qta_input.val();
prezzo_unitario = parseFloat(prezzo_unitario);
sconto = parseFloat(sconto);
qta_max = parseFloat(qta_max);
let prezzo_scontato = prezzo_unitario - sconto;
let qta = ($("#qta_" + r).val()).toEnglish();
// Se inserisco una quantità da evadere maggiore di quella rimanente, la imposto al massimo possibile
if (qta > qta_max) {
qta = qta_max;
$("#qta_" + r).val(qta);
}
// Se tolgo la spunta della casella dell\'evasione devo azzerare i conteggi
if (isNaN(qta) || !$("#checked_" + r).is(":checked")) {
qta = 0;
}
let serial_select = $("#serial_" + r);
serial_select.selectClear();
serial_select.select2("destroy");
serial_select.data("maximum", qta);
start_superselect();
let subtotale = (prezzo_scontato * qta).toLocale();
$("#subtotale_" + r).html(subtotale + " " + globals.currency);
ricalcolaTotale();
}
function ricalcolaTotale() {
let totale = 0.00;
let totale_qta = 0;
$("input[id*=qta_]").each(function() {
let qta = ($(this).val()).toEnglish();
let r = $(this).attr("id").replace("qta_", "");
if (!$("#checked_" + r).is(":checked") || isNaN(qta)) {
qta = 0;
}
let prezzo_unitario = $("#prezzo_unitario_" + r).val();
let sconto = $("#sconto_unitario_" + r).val();
prezzo_unitario = parseFloat(prezzo_unitario);
sconto = parseFloat(sconto);
let prezzo_scontato = prezzo_unitario - sconto;
if(prezzo_scontato) {
totale += prezzo_scontato * qta;
}
totale_qta += qta;
});
$("#totale").html((totale.toLocale()) + " " + globals.currency);
if (!permetti_documento_vuoto) {
if (totale_qta > 0) {
$("#submit_btn").show();
} else {
$("#submit_btn").hide();
}
}
controllaMagazzino();
}
ricalcolaTotale();
$(document).ready(function(){
if(input("id_ritenuta_acconto").get()) {
$("#calcolo_ritenuta_acconto").prop("required", true);
} else{
$("#calcolo_ritenuta_acconto").prop("required", false);
input("calcolo_ritenuta_acconto").set("");
}
$("#id_ritenuta_acconto").on("change", function(){
if(input("id_ritenuta_acconto").get()) {
$("#calcolo_ritenuta_acconto").prop("required", true);
} else{
$("#calcolo_ritenuta_acconto").prop("required", false);
input("calcolo_ritenuta_acconto").set("");
}
});
});
</script>';

View File

@ -1,176 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Descrizione
echo App::internalLoad('descrizione.php', $result, $options);
// Conti, rivalsa INPS e ritenuta d'acconto
echo App::internalLoad('conti.php', $result, $options);
// Iva
echo '
<div class="row">
<div class="col-md-4 '.(!empty($options['nascondi_prezzi']) ? 'hidden' : '').'">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$result['idiva'].'", "ajax-source": "iva", "select-options": '.json_encode($options['select-options']['iva']).' ]}
</div>';
// Quantità
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.abs($result['qta']).'", "decimals": "qta"'.(isset($result['max_qta']) ? ', "icon-after": "<span class=\"tip\" title=\"'.tr("L'elemento è collegato a un documento: la quantità massima ammessa è relativa allo stato di evasione dell'elemento nel documento di origine (quantità dell'elemento / quantità massima ammessa)").'\">/ '.numberFormat(abs($result['max_qta']), 'qta').' <i class=\"fa fa-question-circle-o\"></i></span>"' : '').', "min-value": "'.abs($result['qta_evasa']).'" ]}
</div>';
// Unità di misura
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "value": "'.$result['um'].'", "ajax-source": "misure" ]}
</div>
</div>';
echo '
<div class="row '.(!empty($options['nascondi_prezzi']) ? 'hidden' : '').'">';
$width = $options['dir'] == 'entrata' ? 4 : 6;
$label = $options['dir'] == 'entrata' ? tr('Prezzo unitario di vendita') : tr('Prezzo unitario');
if ($options['dir'] == 'entrata') {
// Prezzo di acquisto unitario
echo '
<div class="col-md-'.$width.'">
{[ "type": "number", "label": "'.tr('Prezzo unitario di acquisto').'", "name": "costo_unitario", "value": "'.$result['costo_unitario'].'", "icon-after": "'.currency().'" ]}
</div>';
// Funzione per l'aggiornamento in tempo reale del guadagno
echo '
<script>
function aggiorna_guadagno() {
var costo_unitario = $("#costo_unitario").val().toEnglish();
var prezzo = $("#prezzo_unitario").val().toEnglish();
var sconto = $("#sconto").val().toEnglish();
if ($("select[id^=\'tipo_sconto\']").val() === "PRC") {
sconto = sconto / 100 * prezzo;
}
var guadagno = prezzo - sconto - costo_unitario;
var margine = (((prezzo - sconto) * 100) / costo_unitario) - 100;
var parent = $("#costo_unitario").closest("div").parent();
var div = parent.find("div[id*=\"errors\"]");
margine = isNaN(margine) || !isFinite(margine) ? 0: margine; // Fix per magine NaN
div.html("<small>&nbsp;'.tr('Guadagno').': " + guadagno.toLocale() + " " + globals.currency + " &nbsp; '.tr('Margine').': " + margine.toLocale() + " %</small>");
if (guadagno < 0) {
parent.addClass("has-error");
div.addClass("label-danger").removeClass("label-success");
} else {
parent.removeClass("has-error");
div.removeClass("label-danger").addClass("label-success");
}
}
$("#modals > div").on("shown.bs.modal", function () {
aggiorna_guadagno();
});
$("#prezzo_unitario").keyup(aggiorna_guadagno);
$("#costo_unitario").keyup(aggiorna_guadagno);
$("#sconto").keyup(aggiorna_guadagno);
$("select[id^=\'tipo_sconto\']").change(aggiorna_guadagno);
</script>';
}
// Prezzo di vendita unitario
echo '
<div class="col-md-'.$width.'">
{[ "type": "number", "label": "'.$label.'", "name": "prezzo_unitario", "value": "'.$result['prezzo_unitario_corrente'].'", "required": 1, "icon-after": "'.currency().'", "help": "'.($options['dir'] == 'entrata' && setting('Utilizza prezzi di vendita comprensivi di IVA') ? tr('Importo IVA inclusa') : '').'" ]}
</div>';
// Sconto unitario
echo '
<div class="col-md-'.$width.'">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.($result['sconto_percentuale'] ?: $result['sconto_unitario_corrente']).'", "icon-after": "choice|untprc|'.$result['tipo_sconto'].'", "help": "'.tr('Il valore positivo indica uno sconto. Per applicare una maggiorazione inserire un valore negativo.').'" ]}
</div>
</div>';
// Data prevista evasione (per ordini)
if (in_array($module['name'], ['Ordini cliente', 'Ordini fornitore', 'Preventivi'])) {
if ($options['action'] == 'add') {
if ($module['name'] == 'Ordini cliente') {
$confermato = setting('Conferma automaticamente le quantità negli ordini cliente');
} elseif ($module['name'] == 'Ordini fornitore') {
$confermato = setting('Conferma automaticamente le quantità negli ordini fornitore');
} else {
$confermato = setting('Conferma automaticamente le quantità nei preventivi');
}
} else {
$confermato = $result['confermato'];
}
echo '
<div class="box box-warning collapsable collapsed-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Informazioni aggiuntive').'</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-4">
{[ "type": "date", "label": "'.tr('Data prevista evasione').'", "name": "data_evasione", "value": "'.$result['data_evasione'].'" ]}
</div>
<div class="col-md-4">
{[ "type": "time", "label": "'.tr('Ora prevista evasione').'", "name": "ora_evasione", "value": "'.$result['ora_evasione'].'", "disabled": 1 ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "label": "'.tr('Cambia data a tutte le righe').'", "name": "data_evasione_all", "value": "" ]}
</div>
</div>
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-4">
{[ "type": "checkbox", "label": "'.tr('Articolo confermato').'", "name": "confermato", "value": "'.$confermato.'" ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "label": "'.tr('Cambia stato a tutte le righe').'", "name": "confermato_all", "value": "" ]}
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
if(input("data_evasione").get()){
input("ora_evasione").enable();
}
});
$("#data_evasione").blur(function() {
if(input("data_evasione").get()){
input("ora_evasione").enable();
} else{
input("ora_evasione").disable();
input("ora_evasione").set();
}
});
</script>';
}

View File

@ -1,90 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Descrizione
echo App::internalLoad('descrizione.php', $result, $options);
// Conti, rivalsa INPS e ritenuta d'acconto
echo App::internalLoad('conti.php', $result, $options);
$incorpora_iva = $options['dir'] == 'entrata' && setting('Utilizza prezzi di vendita comprensivi di IVA');
// Sconto percentuale
echo '
<div class="row">';
if ($options['action'] == 'add') {
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Sconto/maggiorazione percentuale').'", "name": "sconto_percentuale", "icon-after": "%", "help": "'.tr('Il valore positivo indica uno sconto: per applicare una maggiorazione inserire un valore negativo').'" ]}
</div>';
}
// Sconto unitario
echo '
<div class="col-md-'.($options['action'] == 'add' ? 4 : 6).'">
{[ "type": "number", "label": "'.tr('Sconto/maggiorazione unitario').'", "name": "sconto_unitario", "value": "'.$result['sconto_unitario_corrente'].'", "icon-after": "'.currency().'", "help": "'.tr('Il valore positivo indica uno sconto: per applicare una maggiorazione inserire un valore negativo').'" ]}
</div>';
// Iva
echo '
<div class="col-md-'.($options['action'] == 'add' ? 4 : 6).'">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$result['idiva'].'", "ajax-source": "iva" ]}
</div>
</div>';
// Funzione per l'aggiornamento in tempo reale dello sconto
$totale_documento = $incorpora_iva ? $options['totale_documento'] : $options['totale_imponibile_documento'];
echo '
<script>
var descrizione = $("#descrizione_riga");
var form = descrizione.closest("form");
var sconto_percentuale = form.find("#sconto_percentuale");
var sconto_unitario = form.find("#sconto_unitario");
var totale = '.($totale_documento ?: 0).';
function aggiorna_sconto_percentuale() {
var sconto = sconto_percentuale.val().toEnglish();
var unitario = sconto / 100 * totale;
var msg = sconto >= 0 ? "'.tr('Sconto percentuale').'" : "'.tr('Maggiorazione percentuale').'";
sconto_unitario.val(unitario.toLocale());
if (sconto !== 0) {
descrizione.val(msg + " " + Math.abs(sconto).toLocale() + "%");
}
}
function aggiorna_sconto_unitario(){
var sconto = sconto_unitario.val().toEnglish();
var msg = sconto >= 0 ? "'.tr('Sconto unitario').'" : "'.tr('Maggiorazione unitaria').'";
sconto_percentuale.val(0);
if (sconto !== 0) {
descrizione.val(msg);
}
}
sconto_percentuale.keyup(aggiorna_sconto_percentuale);
sconto_unitario.keyup(aggiorna_sconto_unitario);
</script>';

View File

@ -1,612 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$valid_config = isset($db_host) && isset($db_name) && isset($db_username) && isset($db_password);
// Gestione del file di configurazione
if (file_exists('config.inc.php') && $valid_config && $dbo->isConnected()) {
return;
}
$pageTitle = tr('Configurazione');
include_once App::filepath('include|custom|', 'top.php');
// Controllo sull'esistenza di nuovi parametri di configurazione
if (post('db_host') !== null) {
$db_host = $_POST['db_host']; // Fix per evitare la conversione in numero
$db_name = post('db_name');
$db_username = post('db_username');
$db_password = post('db_password');
$valid_config = isset($db_host) && isset($db_name) && isset($db_username) && isset($db_password);
// Generazione di una nuova connessione al database
try {
$dbo = Database::getConnection(true, [
'db_host' => $db_host,
'db_name' => $db_name,
'db_username' => $db_username,
'db_password' => $db_password,
]);
} catch (Exception $e) {
}
// Test della configurazione
if (post('test') !== null) {
ob_end_clean();
if ($dbo->isConnected()) {
$requirements = [
'SELECT',
'INSERT',
'UPDATE',
'CREATE',
'ALTER',
'DROP',
];
$db_host = str_replace('_', '\_', $db_name);
$db_name = str_replace('_', '\_', $db_name);
$db_username = str_replace('_', '\_', $db_name);
$results = $dbo->fetchArray('SHOW GRANTS FOR CURRENT_USER');
foreach ($results as $result) {
$privileges = current($result);
if (
string_contains($privileges, ' ON `'.$db_name.'`.*') ||
string_contains($privileges, ' ON *.*')
) {
$pieces = explode(', ', explode(' ON ', str_replace('GRANT ', '', $privileges))[0]);
// Permessi generici sul database
if (in_array('ALL', $pieces) || in_array('ALL PRIVILEGES', $pieces)) {
$requirements = [];
break;
}
// Permessi specifici sul database
foreach ($requirements as $key => $value) {
if (in_array($value, $pieces)) {
unset($requirements[$key]);
}
}
}
}
// Permessi insufficienti
if (!empty($requirements)) {
$state = 1;
}
// Permessi completi
else {
$state = 2;
}
}
// Connessione fallita
else {
$state = 0;
}
echo $state;
exit();
}
// Creazione della configurazione
if ($dbo->isConnected()) {
$new_config = file_get_contents(base_dir().'/config.example.php');
$decimals = post('decimal_separator');
$thousands = post('thousand_separator');
$decimals = $decimals == 'dot' ? '.' : ',';
$thousands = $thousands == 'dot' ? '.' : $thousands;
$thousands = $thousands == 'comma' ? ',' : $thousands;
$values = [
'|host|' => $db_host,
'|username|' => $db_username,
'|password|' => $db_password,
'|database|' => $db_name,
'|lang|' => post('lang'),
'|timestamp|' => post('timestamp_format'),
'|date|' => post('date_format'),
'|time|' => post('time_format'),
'|decimals|' => $decimals,
'|thousands|' => $thousands,
];
$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 '
<div class="box box-center box-danger box-solid text-center">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Permessi di scrittura mancanti').'</h3>
</div>
<div class="box-body">
<p>'.tr('Sembra che non ci siano i permessi di scrittura sul file _FILE_', [
'_FILE_' => '<b>config.inc.php</b>',
]).'</p>
<form action="'.base_path().'/index.php?action=updateconfig&firstuse=true" method="post">
<div class="hide">
<input type="hidden" name="db_name" value="'.$db_name.'">
<input type="hidden" name="db_password" value="'.$db_password.'">
<input type="hidden" name="db_username" value="'.$db_username.'">;
<input type="hidden" name="db_host" value="'.$db_host.'">
</div>
<a class="btn btn-warning" href="'.base_path().'/index.php"><i class="fa fa-arrow-left"></i> '.tr('Torna indietro').'</a>
<button class="btn btn-info"><i class="fa fa-repeat"></i> '.tr('Riprova').'</button>
</form>
<hr>
<div class="box box-default collapsed-box">
<div class="box-header with-border">
<h4 class="box-title"><a class="clickable" data-widget="collapse">'.tr('Creazione manuale').'...</a></h4>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="box-body">
<p>'.tr('Inserire il seguente testo nel file _FILE_', [
'_FILE_' => '<b>config.inc.php</b>',
]).'</p>
<pre class="text-left">'.htmlentities($new_config).'</pre>
</div>
</div>
</div>
</div>';
}
// Continua con l'esecuzione delle operazioni previste
else {
// Creazione manifest.json
$manifest = '{
"dir" : "ltr",
"lang" : "it-IT",
"name" : "OpenSTAManager",
"scope" : "'.base_path().'",
"display" : "fullscreen",
"start_url" : "'.base_path().'",
"short_name" : "OSM",
"theme_color" : "transparent",
"description" : "OpenSTAManager",
"orientation" : "any",
"background_color" : "transparent",
"generated" : "true",
"icons" : [
{
"src": "assets/dist/img/logo.png",
"type": "image/png",
"sizes": "489x91"
}
]
}';
file_put_contents('manifest.json', $manifest);
redirect(base_path().'/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 '
<div class="box box-center box-danger box-solid text-center">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Impossibile connettersi al database').'</h3>
</div>
<div class="box-body">
<p>'.tr("Si è verificato un'errore durante la connessione al database").'.</p>
<p>'.tr('Controllare di aver inserito correttamente i dati di accesso, e che il database atto ad ospitare i dati del gestionale sia esistente').'.</p>
<a class="btn btn-info" href="'.base_path().'/index.php"><i class="fa fa-repeat"></i> '.tr('Riprova').'</a>
</div>
</div>';
}
$img = App::getPaths()['img'];
// 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 '
<div class="box box-center box-danger box-solid text-center">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Parametri non sufficienti!').'</h3>
</div>
<div class="box-body">
<p>'.tr("L'avvio del software è fallito a causa dell'assenza di alcuni paramentri nella configurazione di base").'.</p>
<p>'.tr("Si prega di controllare che il file _FILE_ contenga tutti i dati inseriti durante la configurazione iniziale (con l'eccezione di password e indirizzo email amministrativi)", [
'_FILE_' => '<b>config.inc.php</b>',
]).'.</p>
<p>'.tr("Nel caso il problema persista, rivolgersi all'assistenza ufficiale").'.</p>
<a class="btn btn-info" href="'.base_path().'/index.php"><i class="fa fa-repeat"></i> '.tr('Riprova').'</a>
</div>
</div>';
}
// Controlli per essere sicuro che l'utente abbia letto la licenza
echo '
<script>
$(document).ready(function(){
$("#smartwizard").smartWizard({
useURLhash: false,
showStepURLhash: false,
theme: "default",
transitionEffect: "slideLeft",
lang : {
next: "'.tr('Successivo').'",
previous: "'.tr('Precedente').'",
}
});
$("#smartwizard").on("leaveStep", function(e, anchorObject, stepNumber, stepDirection) {
result = true;
if(stepDirection == "forward" && $("#step-" + (stepNumber + 1) + " form").length){
result = $("#step-" + (stepNumber + 1) + " form").parsley().validate();
}
if(!result){
swal("'.tr('Impossibile procedere').'", "'.tr('Prima di proseguire devi completare i campi obbligatori!').'", "error");
}
$("html, body").animate({ scrollTop: $("#steps").offset().top }, 500);
return result;
});
$("#install").on("click", function(){
if($(this).closest("form").parsley().validate()){
prev_html = $("#install").html();
$("#install").html("<i class=\'fa fa-spinner fa-pulse fa-fw\'></i> '.tr('Attendere').'...");
$("#install").prop("disabled", true);
$("#test").prop("disabled", true);
$("#config-form").submit();
}
});
$("#test").on("click", function(){
if($(this).closest("form").parsley().validate()){
prev_html = $("#test").html();
$("#test").html("<i class=\'fa fa-spinner fa-pulse fa-fw\'></i> '.tr('Attendere').'...");
$("#test").prop("disabled", true);
$("#install").prop("disabled", true);
$(this).closest("form").ajaxSubmit({
url: "'.base_path().'/index.php",
data: {
test: 1,
},
type: "post",
success: function(data){
data = parseFloat(data.trim());
$("#test").html(prev_html);
$("#test").prop("disabled", false);
$("#install").prop("disabled", false);
if(data == 0){
swal("'.tr('Errore della configurazione').'", "'.tr('La configurazione non è corretta').'.", "error");
} else if(data == 1){
swal("'.tr('Permessi insufficienti').'", "'.tr("L'utente non possiede permessi sufficienti per il testing della connessione. Potresti rilevare problemi in fase di installazione.").'.", "error");
} else {
swal("'.tr('Configurazione corretta').'", "'.tr('Ti sei connesso con successo al database').'. '.tr('Clicca su _BTN_ per proseguire', [
'_BTN_' => "'".tr('Installa')."'",
]).'.", "success");
}
},
error: function(data) {
alert("'.tr('Errore').': " + data);
}
});
}
});
});
</script>';
echo '
<div class="box box-center-large box-warning">
<div class="box-header with-border text-center">
<img src="'.$img.'/logo.png" width="300" alt="'.tr('OSM Logo').'">
</div>
<div class="box-body" id="smartwizard">
<span class="pull-right col-md-4">
<select class="form-control hide" id="language" required="1">';
$languages = [
'it_IT' => [
'title' => tr('Italiano'),
'flag' => 'IT',
],
'en_GB' => [
'title' => tr('Inglese'),
'flag' => 'GB',
],
];
$current = trans()->getCurrentLocale();
foreach ($languages as $code => $language) {
echo '
<option data-country="'.$language['flag'].'" value="'.$code.'" '.($code == $current ? 'selected' : '').'>'.$language['title'].'</option>';
}
echo '
</select>
<script>
var flag_link = "https://lipis.github.io/flag-icon-css/flags/4x3/|flag|.svg";
$(document).ready(function() {
$.ajax({
url: flag_link.replace("|flag|", "it"),
success: function(){
initLanguage(true);
},
error: function(){
initLanguage(false);
},
timeout: 500
});
});
function initLanguage(flag) {
$("#language").removeClass("hide");
$("#language").select2({
theme: "bootstrap",
templateResult: function(item) {
if (!item.id || !flag) {
return item.text;
}
var element = $(item.element);
var img = $("<img>", {
class: "img-flag",
width: 26,
src: flag_link.replace("|flag|", element.data("country").toLowerCase()),
});
var span = $("<span>", {
text: " " + item.text
});
span.prepend(img);
return span;
}
});
$("#language").on("change", function(){
if ($(this).val()) {
var location = window.location;
var url = location.protocol + "//" + location.host + "" + location.pathname;
var parameters = getUrlVars();
parameters.lang = $(this).val();
redirect(url, parameters);
}
});
}
</script>
</span>
<ul>
<li><a href="#step-1">
<h3>'.tr('Requisiti').'</h3>
</a></li>
<li><a href="#step-2">
<h3>'.tr('Licenza').'</h3>
</a></li>
<li><a href="#step-3">
<h3>'.tr('Configurazione').'</h3>
</a></li>
</ul>
<div id="steps">
<div id="step-1">';
// Introduzione
echo '
<p>'.tr('Benvenuto in _NAME_!', [
'_NAME_' => '<strong>OpenSTAManager</strong>',
]).'</p>
<p>'.tr("Prima di procedere alla configurazione e all'installazione del software, sono necessari alcuni accorgimenti per garantire il corretto funzionamento del gestionale").'.</p>
<br>
<p>'.tr('Le estensioni e impostazioni PHP possono essere personalizzate nel file di configurazione _FILE_', [
'_FILE_' => '<b>php.ini</b>',
]).'.</p>
<hr>';
// REQUISITI PER IL CORRETTO FUNZIONAMENTO
include __DIR__.'/requirements.php';
echo '
</div>';
// LICENZA
echo '
<div id="step-2">
<p>'.tr('OpenSTAManager è tutelato dalla licenza _LICENSE_!', [
'_LICENSE_' => 'GPL 3.0',
]).'</p>
<div class="row">
<div class="col-md-8">
<span class="pull-left" title="'.tr('Visiona e accetta la licenza per proseguire').'">'.tr('Accetti la licenza GPLv3 di OpenSTAManager?').'*</span>
</div>
<form class="col-md-4">
<input type="checkbox" id="agree" name="agree" data-parsley-required="true">
<label for="agree">'.tr('Ho visionato e accetto').'.</label>
</form>
</div>
<hr>
<textarea class="form-control autosize" rows="15" readonly>'.file_get_contents('LICENSE').'</textarea><br>
<a class="pull-left" href="https://www.gnu.org/licenses/translations.en.html#GPL" target="_blank">[ '.tr('Versioni tradotte').' ]</a><br><br>
</div>';
$host = !empty($db_host) ? $db_host : '';
$username = !empty($db_username) ? $db_username : '';
$password = !empty($db_password) ? $db_password : '';
$name = !empty($db_name) ? $db_name : '';
// PARAMETRI
echo '
<div id="step-3">
<a href="https://www.openstamanager.com/contattaci/" target="_blank" ><img class="pull-right" width="32" src="'.$img.'/help.png" alt="'.tr('Aiuto').'" title="'.tr('Contatta il nostro help-desk').'"/></a>
<p>'.tr('Non hai ancora configurato OpenSTAManager').'.</p>
<p><small class="help-block">'.tr('Configura correttamente il software con i seguenti parametri (modificabili successivamente dal file _FILE_)', [
'_FILE_' => '<b>config.inc.php</b>',
]).'</small></p>
<hr>';
// Form dei parametri
echo '
<form action="?action=updateconfig&firstuse=true" method="post" id="config-form">
<input type="hidden" name="lang" value="'.trans()->getCurrentLocale().'">
<h4>'.tr('Formato date').'</h4>
<div class="row">
<div class="col-md-4">
{[ "type": "text", "label": "'.tr('Formato data lunga').'", "name": "timestamp_format", "value": "d/m/Y H:i", "required": 1 ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "'.tr('Formato data corta').'", "name": "date_format", "value": "d/m/Y", "required": 1 ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "'.tr('Formato orario').'", "name": "time_format", "value": "H:i", "required": 1 ]}
</div>
</div>
<small>'.tr('I formati sono impostabili attraverso lo standard previsto da PHP: _LINK_', [
'_LINK_' => '<a href="https://www.php.net/manual/en/function.date.php#refsect1-function.date-parameters">https://www.php.net/manual/en/function.date.php#refsect1-function.date-parameters</a>',
]).'.</small>
<hr>';
if (!extension_loaded('intl')) {
$list = [
[
'id' => 'comma',
'text' => tr('Virgola'),
],
[
'id' => 'dot',
'text' => tr('Punto'),
],
];
echo '
<h4>'.tr('Formato numeri').'</h4>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Separatore dei decimali').'", "name": "decimal_separator", "value": "comma", "values": '.json_encode($list).', "required": 1 ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Separatore delle migliaia').'", "name": "thousand_separator", "value": "dot", "values": '.json_encode($list).' ]}
</div>
</div>
<small>'.tr("Si consiglia l'abilitazione dell'estensione _EXT_ di PHP", [
'_EXT_' => 'intl',
]).'.</small>
<hr>';
}
echo '
<h4>'.tr('Database').'</h4>
<div class="row">';
// db_host
echo '
<div class="col-md-12">
{[ "type": "text", "label": "'.tr('Host del database').'", "name": "db_host", "placeholder": "'.tr('Host').'", "value": "'.$host.'", "help": "'.tr('Esempio').': localhost", "show-help": 0, "required": 1 ]}
</div>
</div>
<div class="row">';
// db_username
echo '
<div class="col-md-4">
{[ "type": "text", "label": "'.tr("Username dell'utente MySQL").'", "name": "db_username", "placeholder": "'.tr('Username').'", "value": "'.$username.'", "help": "'.tr('Esempio').': root", "show-help": 0, "required": 1 ]}
</div>';
// db_password
echo '
<div class="col-md-4">
{[ "type": "password", "label": "'.tr("Password dell'utente MySQL").'", "name": "db_password", "placeholder": "'.tr('Password').'", "value": "'.$password.'", "help": "'.tr('Esempio').': mysql", "show-help": 0 ]}
</div>';
// db_name
echo '
<div class="col-md-4">
{[ "type": "text", "label": "'.tr('Nome del database').'", "name": "db_name", "placeholder": "'.tr('Database').'", "value": "'.$name.'", "help": "'.tr('Esempio').': openstamanager", "show-help": 0, "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-4">
<span>*<small><small>'.tr('Campi obbligatori').'</small></small></span>
</div>
<div class="col-md-4 text-right">
<button type="button" id="test" class="btn btn-warning btn-block">
<i class="fa fa-file-text"></i> '.tr('Testa il database').'
</button>
</div>
<div class="col-md-4 text-right">
<button type="submit" id="install" class="btn btn-success btn-block">
<i class="fa fa-check"></i> '.tr('Installa').'
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>';
}
include_once App::filepath('include|custom|', 'bottom.php');
exit();

View File

@ -1,265 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
if (Update::isUpdateAvailable() || !$dbo->isInstalled()) {
return;
}
$has_azienda = $dbo->fetchNum("SELECT `an_anagrafiche`.`idanagrafica` FROM `an_anagrafiche`
LEFT JOIN `an_tipianagrafiche_anagrafiche` ON `an_anagrafiche`.`idanagrafica`=`an_tipianagrafiche_anagrafiche`.`idanagrafica`
LEFT JOIN `an_tipianagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica`=`an_tipianagrafiche_anagrafiche`.`idtipoanagrafica`
WHERE `an_tipianagrafiche`.`descrizione` = 'Azienda' AND `an_anagrafiche`.`deleted_at` IS NULL") != 0;
$has_user = $dbo->fetchNum('SELECT `id` FROM `zz_users`') != 0;
$settings = [
'Regime Fiscale' => true,
'Tipo Cassa Previdenziale' => false,
'Conto predefinito fatture di vendita' => true,
'Conto predefinito fatture di acquisto' => true,
"Percentuale ritenuta d'acconto" => false,
"Causale ritenuta d'acconto" => false,
'Valuta' => true,
'Utilizza prezzi di vendita comprensivi di IVA' => false,
];
if (!empty(setting("Percentuale ritenuta d'acconto"))) {
$settings["Causale ritenuta d'acconto"] = true;
}
$has_settings = true;
foreach ($settings as $setting => $required) {
if (empty(setting($setting)) && $required) {
$has_settings = false;
break;
}
}
if ($has_azienda && $has_user && $has_settings) {
return;
}
$pageTitle = tr('Inizializzazione');
include_once App::filepath('include|custom|', 'top.php');
// Controllo sull'esistenza di nuovi parametri di configurazione
if (post('action') == 'init') {
// Azienda predefinita
if (!$has_azienda) {
Filter::set('post', 'op', 'add');
$id_module = Modules::get('Anagrafiche')['id'];
include base_dir().'/modules/anagrafiche/actions.php';
// Logo stampe
if (!empty($_FILES) && !empty($_FILES['blob']['name'])) {
$upload = Uploads::upload($_FILES['blob'], [
'name' => 'Logo stampe',
'id_module' => $id_module,
'id_record' => $id_record,
]);
Settings::setValue('Logo stampe', $upload->filename);
}
}
// Utente amministratore
if (!$has_user) {
$admin = $dbo->selectOne('zz_groups', ['id'], [
'nome' => 'Amministratori',
]);
// Creazione utente Amministratore
$dbo->insert('zz_users', [
'username' => post('admin_username'),
'password' => Auth::hashPassword(post('admin_password')),
'email' => post('admin_email'),
'idgruppo' => $admin['id'],
'idanagrafica' => isset($id_record) ? $id_record : 0,
'enabled' => 1,
]);
// Creazione token API per l'amministratore
$dbo->insert('zz_tokens', [
'id_utente' => $dbo->lastInsertedID(),
'token' => secure_random_string(),
]);
}
if (!$has_settings) {
foreach ($settings as $setting => $required) {
$setting = Settings::get($setting);
$value = post('setting')[$setting['id']];
if (!empty($value)) {
Settings::setValue($setting['nome'], $value);
}
}
}
redirect(base_path(), 'js');
exit();
}
$img = App::getPaths()['img'];
// Visualizzazione dell'interfaccia di impostazione iniziale, nel caso il file di configurazione sia mancante oppure i paramentri non siano sufficienti
echo '
<div class="box box-center-large box-warning">
<div class="box-header with-border text-center">
<img src="'.$img.'/logo.png" class="logo-image" alt="'.tr('OSM Logo').'">
</div>
<div class="box-body">
<form action="" method="post" id="init-form" enctype="multipart/form-data">
<input type="hidden" name="action" value="init">';
if (!$has_user) {
echo '
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">'.tr('Amministrazione').'</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Username').'", "name": "admin_username", "value": "", "placeholder": "'.tr("Digita l'username dell'amministratore").'", "required": 1 ]}
</div>
<div class="col-md-6">
{[ "type": "password", "label": "'.tr('Password').'", "id": "password", "name": "admin_password", "value": "", "placeholder": "'.tr("Digita la password dell'amministratore").'", "required": 1, "strength": "#config" ]}
</div>
<div class="col-md-6">
{[ "type": "email", "label": "'.tr('Email').'", "name": "admin_email", "value": "", "placeholder": "'.tr("Digita l'indirizzo email dell'amministratore").'", "required": 1 ]}
</div>
</div>
</div>
</div>';
}
if (!$has_azienda) {
echo '
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">'.tr('Azienda predefinita').'</h3>
</div>
<div class="panel-body" id="bs-popup">';
$idtipoanagrafica = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Azienda'")[0]['idtipoanagrafica'];
$readonly_tipo = true;
ob_start();
include base_dir().'/modules/anagrafiche/add.php';
$anagrafica = ob_get_clean();
echo str_replace('</form>', '', $anagrafica);
echo '
<div class="box box-success collapsed-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Logo stampe').'</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<div class="box-body collapse">
<div class="col-md-12">
{[ "type": "file", "placeholder": "'.tr('File').'", "name": "blob" ]}
</div>
<p>&nbsp;</p><div class="col-md-12 alert alert-info text-center">'.tr('Per impostare il logo delle stampe, caricare un file ".jpg". Risoluzione consigliata 302x111 pixel').'.</div>
</div>
</div>';
echo '
</div>
</div>';
}
if (!$has_settings) {
echo '
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">'.tr('Impostazioni di base').'</h3>
</div>
<div class="panel-body">';
$i = 0;
foreach ($settings as $setting => $required) {
if (empty(setting($setting))) {
if ($i % 2 == 0 or $i == 0) {
echo ' <div class="row">';
}
echo '
<div class="col-md-6">
'.Settings::input($setting, $required).'
</div>';
++$i;
if ($i % 2 == 0 or $i == sizeof($settings)) {
echo ' </div>';
}
}
}
echo ' </div>
</div>';
}
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-4">
<span>*<small><small>'.tr('Campi obbligatori').'</small></small></span>
</div>
<div class="col-md-4 text-right">
<button type="submit" id="config" class="btn btn-success btn-block">
<i class="fa fa-cog"></i> '.tr('Configura').'
</button>
</div>
</div>
</form>
</div>
</div>';
echo '
<script>
$(document).ready(function(){
$("button[type=submit]").not("#config").remove();
});
</script>
<script>$(document).ready(init)</script>';
include_once App::filepath('include|custom|', 'bottom.php');
exit();

View File

@ -1,211 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Apache
$modules = [
'mod_rewrite' => [
'server' => 'HTTP_MOD_REWRITE',
'description' => tr('Fornisce un sistema di riscrittura URL basato su regole predefinite'),
],
];
if (function_exists('apache_get_modules')) {
$available_modules = apache_get_modules();
}
$apache = [];
foreach ($modules as $name => $values) {
$description = $values['description'];
$status = isset($available_modules) ? in_array($name, $available_modules) : $_SERVER[$values['server']] == 'On';
$apache[] = [
'name' => $name,
'description' => $description,
'status' => $status,
'type' => tr('Modulo'),
];
}
// PHP
$settings = [
'zip' => [
'type' => 'ext',
'description' => tr('Permette di leggere e scrivere gli archivi compressi ZIP e i file al loro interno'),
],
'mbstring' => [
'type' => 'ext',
'description' => tr('Permette di gestire i caratteri dello standard UTF-8'),
],
'pdo_mysql' => [
'type' => 'ext',
'description' => tr('Permette di effettuare la connessione al database MySQL'),
],
'dom' => [
'type' => 'ext',
'description' => tr('Permette la gestione dei file standard per la Fatturazione Elettronica'),
],
'xsl' => [
'type' => 'ext',
'description' => tr('Permette di visualizzazione grafica della Fattura Elettronica'),
],
'openssl' => [
'type' => 'ext',
'description' => tr("Permette l'utilizzo di funzioni crittografiche simmetriche e asimmetriche"),
],
'intl' => [
'type' => 'ext',
'description' => tr("Permette l'automazione della conversione dei numeri"),
],
'curl' => [
'type' => 'ext',
'description' => tr('Permette la comunicazione con servizi esterni'),
],
'soap' => [
'type' => 'ext',
'description' => tr('Permette la comunicazione con servizi esterni, quali il database europeo delle Partite IVA (facoltativo)'),
],
'gd' => [
'type' => 'ext',
'description' => tr('Permette la creazione dell\'immagine della firma per il rapportino d\'intervento (facoltativo)'),
],
//'display_errors' => [
// 'type' => 'value',
// 'description' => true,
//],
'upload_max_filesize' => [
'type' => 'value',
'description' => '>32M',
],
'post_max_size' => [
'type' => 'value',
'description' => '>32M',
],
];
$php = [];
foreach ($settings as $name => $values) {
$description = $values['description'];
if ($values['type'] == 'ext') {
$status = extension_loaded($name);
} else {
$ini = str_replace(['k', 'M'], ['000', '000000'], ini_get($name));
$real = str_replace(['k', 'M'], ['000', '000000'], $description);
if (string_starts_with($real, '>')) {
$status = $ini >= substr($real, 1);
} elseif (string_starts_with($real, '<')) {
$status = $ini <= substr($real, 1);
} else {
$status = ($real == $ini);
}
if (is_bool($description)) {
$description = !empty($description) ? 'On' : 'Off';
} else {
$description = str_replace(['>', '<'], '', $description);
}
$description = tr('Valore consigliato: _VALUE_ (Valore attuale: _INI_)', [
'_VALUE_' => $description,
'_INI_' => ini_get($name),
]);
}
$type = ($values['type'] == 'ext') ? tr('Estensione') : tr('Impostazione');
$php[] = [
'name' => $name,
'description' => $description,
'status' => $status,
'type' => $type,
];
}
// Percorsi di servizio
$dirs = [
'backup' => tr('Necessario per il salvataggio dei backup'),
'files' => tr('Necessario per il salvataggio di file inseriti dagli utenti'),
'logs' => tr('Necessario per la gestione dei file di log'),
];
$directories = [];
foreach ($dirs as $name => $description) {
$status = is_writable(base_dir().DIRECTORY_SEPARATOR.$name);
$directories[] = [
'name' => $name,
'description' => $description,
'status' => $status,
'type' => tr('Cartella'),
];
}
$requirements = [
tr('Apache') => $apache,
tr('PHP (_VERSION_)', [
'_VERSION_' => phpversion(),
]) => $php,
tr('Percorsi di servizio') => $directories,
];
// Tabelle di riepilogo
foreach ($requirements as $key => $values) {
$statuses = array_column($values, 'status');
$general_status = true;
foreach ($statuses as $status) {
$general_status &= $status;
}
echo '
<div class="box box-'.($general_status ? 'success collapsed-box' : 'danger').'">
<div class="box-header with-border">
<h3 class="box-title">'.$key.'</h3>';
if ($general_status) {
echo '
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse">
<i class="fa fa-plus"></i>
</button>
</div>';
}
echo '
</div>
<div class="box-body no-padding">
<table class="table">';
foreach ($values as $value) {
echo '
<tr class="'.($value['status'] ? 'success' : 'danger').'">
<td style="width: 10px"><i class="fa fa-'.($value['status'] ? 'check' : 'times').'"></i></td>
<td>'.$value['type'].'</td>
<td>'.$value['name'].'</td>
<td>'.$value['description'].'</td>
</tr>';
}
echo '
</table>
</div>
</div>';
}

View File

@ -1,260 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$updateRate = 20;
$scriptValue = $updateRate * 5;
/*
* Aggiornamento tramite AJAX
*/
if (filter('action') == 'do_update') {
// Aggiornamento in progresso
if (Update::isUpdateAvailable()) {
$update = Update::getCurrentUpdate();
$result = Update::doUpdate($updateRate);
if (!empty($result)) {
// Aggiunta del messaggio generico riguardante l'aggiornamento
echo '
<script>
addVersion("'.$update['name'].'");
</script>';
if (is_array($result)) {
// Aggiunta del messaggio riguardante la conclusione dell'aggiornamento del database
if (!empty($update['sql']) && $result[1] == $result[2]) {
echo '
<script>
$("#progress .info").html($("#progress .info").html() + "<p>&nbsp;&nbsp;&nbsp;&nbsp;<i class=\"fa fa-check\"></i> '.tr('Aggiornamento del database (_FILENAME_)', [
'_FILENAME_' => '<i>'.$update['filename'].'.sql</i>',
]).'</p>");
</script>';
}
$rate = $result[1] - $result[0];
} elseif (!empty($update['script'])) {
// Aggiunta del messaggio riguardante la conclusione dello script
echo '
<script>
$("#progress .info").html($("#progress .info").html() + "<p>&nbsp;&nbsp;&nbsp;&nbsp;<i class=\"fa fa-check\"></i> '.tr('Esecuzione dello script di aggiornamento (_FILENAME_)', [
'_FILENAME_' => '<i>'.$update['filename'].'.php</i>',
]).'</p>");
</script>';
$rate = $scriptValue;
}
// Aumento della percentuale di completamento totale
if (!empty($rate)) {
echo '
<script>
addProgress('.$rate.');
</script>';
}
echo '
<script>
$("#result").load("index.php?action=do_update&firstuse='.$_GET['firstuse'].'");
</script>';
} else {
// Fallimento
echo '
<div class="alert alert-danger">
<i class="fa fa-times"></i> '.tr("Errore durante l'esecuzione dell'aggiornamento alla versione _VERSION_", [
'_VERSION_' => $update['version'],
]).'
</div>';
}
}
// Aggiornamento completato
elseif (Update::isUpdateCompleted()) {
Update::updateCleanup();
echo '
<p><strong>'.tr('Aggiornamento completato').'</strong> <i class="fa fa-smile-o"></i></p>
<script>
setPercent(100);
</script>';
// Istruzioni per la prima installazione
if ($_GET['firstuse'] == 'true') {
echo '
<p class="text-danger">'.tr("E' fortemente consigliato rimuovere i permessi di scrittura dal file _FILE_", [
'_FILE_' => '<b>config.inc.php</b>',
]).'.</p>';
}
echo '
<a class="btn btn-success btn-block" href="'.base_path().'">
<i class="fa fa-check"></i> '.tr('Continua').'
</a>';
}
exit();
} elseif (Update::isUpdateAvailable()) {
// Controllo se l'aggiornamento è in esecuzione
if (Update::isUpdateLocked() && filter('force') === null) {
$pageTitle = tr('Aggiornamento in corso!');
include_once App::filepath('include|custom|', 'top.php');
echo '
<div class="box box-center box-danger box-solid text-center">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Aggiornamento in corso!').'</h3>
</div>
<div class="box-body">
<p>'.tr("E' attualmente in corso la procedura di aggiornamento del software, e pertanto siete pregati di attendere fino alla sua conclusione").'.</p>
<p>'.tr("Nel caso il problema persista, rivolgersi all'amministratore o all'assistenza ufficiale").'.</p>
<a class="btn btn-info" href="'.base_path().'/index.php"><i class="fa fa-repeat"></i> '.tr('Riprova').'</a>
</div>
</div>';
include_once App::filepath('include|custom|', 'bottom.php');
exit();
}
$firstuse = !$dbo->isInstalled() ? 'true' : 'false';
$button = !$dbo->isInstalled() ? tr('Installa!') : tr('Aggiorna!');
$pageTitle = !$dbo->isInstalled() ? tr('Installazione') : tr('Aggiornamento');
include_once App::filepath('include|custom|', 'top.php');
echo '
<div class="box box-center-large box-warning text-center">
<div class="box-header with-border">
<h3 class="box-title">'.(!$dbo->isInstalled() ? tr('Installazione') : tr('Aggiornamento')).'</h3>
</div>
<div class="box-body">';
if (!$dbo->isInstalled()) {
echo '
<p><strong>'.tr("E' la prima volta che avvii OpenSTAManager e non hai ancora installato il database").'.</strong></p>';
} else {
echo '
<p>'.tr("E' necessario aggiornare il database a una nuova versione").'.</p>';
}
echo '
<p>'.tr("Premi il tasto _BUTTON_ per procedere con l'".(!$dbo->isInstalled() ? tr('installazione') : tr('aggiornamento')).'!', [
'_BUTTON_' => '<b>"'.$button.'"</b>',
]).'</p>
<input type="button" class="btn btn-primary" value="'.$button.'" onclick="continue_update()" id="contine_button">
<script>
function continue_update(){
swal({
title: "'.(!$dbo->isInstalled() ? tr('Procedere con l\'installazione?') : tr('Procedere l\'aggiornamento?')).'",
text: "",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn btn-lg btn-success",
confirmButtonText: "'.tr('Procedi').'",
}).then(
function(){
$("#progress").show();
$("#result").load("index.php?action=do_update&firstuse='.$firstuse.'");
$("#contine_button").remove();
}, function(){});
}
</script>
<div id="progress">
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
<span>0%</span>
</div>
</div>
<hr>
<div class="box box-info text-center collapsed-box">
<div class="box-header with-border">
<h3 class="box-title"><a class="clickable" data-widget="collapse">'.tr('Log').'</a></h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
</div>
</div>
<div class="box-body info text-left"></div>
</div>
</div>
<div id="result"></div>';
$total = 0;
$updates = Update::getTodoUpdates();
foreach ($updates as $update) {
if ($update['sql'] && (!empty($update['done']) || is_null($update['done']))) {
$queries = readSQLFile(base_dir().$update['directory'].$update['filename'].'.sql', ';');
$total += count($queries);
if (intval($update['done']) > 1) {
$total -= intval($update['done']) - 2;
}
}
if ($update['script']) {
$total += $scriptValue;
}
}
echo '
<script>
$(document).ready(function(){
$(".login-box").fadeOut();
count = '.count($updates).';
current = 0;
versions = [];
progress = 0;
total = '.$total.';
});
function addProgress(rate){
progress += rate;
percent = progress / total * 100;
percent = Math.round(percent);
percent = percent > 100 ? 100 : percent;
setPercent(percent);
}
function setPercent(percent){
$("#progress .progress-bar").width(percent + "%");
$("#progress .progress-bar span").text(percent + "%");
}
function addVersion(version){
if(versions.indexOf(version) === -1){
versions.push(version);
current += 1;
$("#progress .info").html($("#progress .info").html() + "<p><strong>'.tr('Aggiornamento _DONE_ di _TODO_ (_VERSION_)', [
'_DONE_' => '" + current + "',
'_TODO_' => '" + count + "',
'_VERSION_' => '" + version.trim() + "',
]).'</strong></p>");
}
}
</script>
</div>
</div>';
}

View File

@ -1,253 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use HTMLBuilder\HTMLBuilder;
include_once __DIR__.'/../core.php';
// Compatibilità per controller ed editor
if (!empty($id_plugin)) {
$structure = Plugins::get($id_plugin);
} else {
$structure = Modules::get($id_module);
}
if (!empty($id_plugin)) {
// Inclusione di eventuale plugin personalizzato
if (!empty($structure['script'])) {
$path = $structure->getEditFile();
if (!empty($path)) {
include $path;
}
return;
}
echo '
<h4>
<span class="'.(!empty($structure['help']) ? ' tip' : '').'"'.(!empty($structure['help']) ? ' title="'.prepareToField($structure['help']).'" data-position="bottom"' : '').' >
'.$structure['title'].(!empty($structure['help']) ? ' <i class="fa fa-question-circle-o"></i>' : '').'</span>';
if ($structure->hasAddFile()) {
echo '
<button type="button" class="btn btn-primary" data-toggle="modal" data-title="'.tr('Aggiungi').'..." data-href="add.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'&id_parent='.$id_record.'"><i class="fa fa-plus"></i></button>';
}
echo '
</h4>';
}
$type = $structure['option'];
// Lettura risultato query del modulo
// include $structure->filepath('init.php');
// Caricamento file aggiuntivo su elenco record
$controller_before = $structure->filepath('controller_before.php');
if (!empty($controller_before)) {
include $controller_before;
}
/*
* Datatables con record
*/
if (!empty($type) && $type != 'menu' && $type != 'custom') {
$total = Util\Query::readQuery($structure);
if (empty($id_plugin) && count(Modules::getSegments($id_module)) > 1) {
echo '
<div class="row">
<div class="col-md-4 pull-right">
{[ "type": "select", "name": "id_segment_", "required": 0, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module = '.prepare($id_module).'", "value": "'.$_SESSION['module_'.$id_module]['id_segment'].'" ]}
</div>
</div>
<br>';
echo '
<script>
$(document).ready(function () {
$("#id_segment_").on("change", function(){
if ($(this).val() < 1){
session_set("module_'.$id_module.',id_segment", "", 1, 1);
} else {
session_set("module_'.$id_module.',id_segment", $(this).val(), 0, 1);
}
});
});
</script>';
}
// Reset della selezione precedente
$_SESSION['module_'.$id_module]['selected'] = [];
$selezione = array_keys($_SESSION['module_'.$id_module]['selected']);
$table_id = 'main_'.rand(0, 99);
echo '
<table data-idmodule="'.$id_module.'" data-idplugin="'.$id_plugin.'" data-idparent="'.$id_record.'" data-selected="'.implode(';', $selezione).'" id="'.$table_id.'" width="100%" class="main-records table table-condensed table-bordered">
<thead>
<tr>
<th id="th_selector"></th>';
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 '
<th'.$attr_td.' id="th_'.searchFieldName($name).'"';
if ($total['search'][$key] == 1) {
echo ' class="search"';
} else {
echo ' class="no-search"';
}
if ($total['slow'][$key] == 1) {
echo ' data-slow="1"';
}
echo '>'.$field.'</th>';
}
echo '
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>';
echo '
<td></td>';
foreach ($total['fields'] as $key => $field) {
echo '
<td></td>';
}
echo '
</tr>
</tfoot>
</table>';
echo '
<div class="row" data-target="'.$table_id.'">
<div class="col-md-5">
<div class="btn-group select-controller-container" role="group">
<button type="button" class="btn btn-primary btn-select-all">'.tr('Seleziona tutto').'</button>
<button type="button" class="btn btn-default btn-select-none">
'.tr('Deseleziona tutto').'
<span class="badge selected-count">0</span>
</button>
</div>
</div>
<div class="col-md-2 dropdown">';
if (!empty($bulk)) {
echo '
<button class="btn btn-primary btn-block dropdown-toggle actions-container disabled" type="button" data-toggle="dropdown" disabled>'.tr('Azioni di gruppo').' <span class="caret"></span></button>
<ul class="dropdown-menu" data-target="'.$table_id.'" role="menu">';
foreach ($bulk as $key => $value) {
$text = is_array($value) ? $value['text'] : $value;
$data = isset($value['data']) && is_array($value['data']) ? $value['data'] : [];
$extra = [];
foreach ($data as $k => $v) {
$extra[] = 'data-'.$k.'="'.prepareToField(HTMLBuilder::replace($v)).'"';
}
echo '
<li role="presentation"><a class="bulk-action clickable" data-op="'.prepareToField($key).'" data-backto="record-list" '.implode(' ', $extra).'>'.$text.'</a></li>';
}
echo '
</ul>';
}
echo '
</div>
<div class="col-md-5 text-right">
<i class="fa fa-question-circle-o tip" title="'.tr('Le operazioni di esportazione, copia e stampa sono limitate alle righe selezionate e visibili della tabella').'. '.tr('Per azioni su tutti i contenuti selezionati, utilizzare le Azioni di gruppo').'."></i>
<div class="btn-group export-container" role="group">';
if (setting('Abilita esportazione Excel e PDF')) {
echo '
<div class="btn-group">
<button type="button" class="btn btn-primary table-btn btn-csv disabled" disabled>'.tr('Esporta').'</button>
<button type="button" class="btn btn-primary table-btn disabled dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="table-btn btn-pdf disabled" disabled>'.tr('PDF').'</a></li>
<li><a class="table-btn btn-excel disabled" disabled>'.tr('Excel').'</a></li>
</ul>
</div>';
} else {
echo '
<button type="button" class="btn btn-primary table-btn btn-csv disabled" disabled>'.tr('Esporta').'</button>';
}
echo '
<button type="button" class="btn btn-default table-btn btn-copy disabled" disabled>'.tr('Copia').'</button>
<button type="button" class="btn btn-default table-btn btn-print disabled" disabled>'.tr('Stampa').'</button>
</div>
</div>
</div>';
}
/*
* Inclusione modulo personalizzato
*/
elseif ($type == 'custom') {
$path = $structure->getEditFile();
if (!empty($path)) {
include $path;
}
}
// Caricamento file aggiuntivo su elenco record
$controller_after = $structure->filepath('controller_after.php');
if (!empty($controller_after)) {
include $controller_after;
}

View File

@ -1,89 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Models\Upload;
$id_allegato = filter('id_allegato');
$allegato = Upload::find($id_allegato);
// Form di inserimento riga documento
echo '
<form action="" method="post" id="modifica-allegato">
<input type="hidden" name="id_allegato" value="'.$id_allegato.'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="modifica-allegato">
<div class="row">
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Nome').'", "name": "nome_allegato", "value": "'.$allegato->name.'" ]}
</div>
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Categoria').'", "name": "categoria_allegato", "value": "'.$allegato->category.'", "disabled": "'.intval(in_array($allegato->category, ['Fattura Elettronica'])).'" ]}
</div>
</div>
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right">
<i class="fa fa-edit"></i> '.tr('Modifica').'
</button>
</div>
</div>
</form>';
// Elenco categoria disponibili per l'autocompletamento
$where = '`id_module` '.(!empty($allegato['id_module']) && empty($allegato['id_plugin']) ? '= '.prepare($allegato['id_module']) : 'IS NULL').' AND `id_plugin` '.(!empty($allegato['id_plugin']) ? '= '.prepare($allegato['id_plugin']) : 'IS NULL').'';
$categories = $dbo->fetchArray('SELECT DISTINCT(BINARY `category`) AS `category` FROM `zz_files` WHERE '.$where.' ORDER BY `category`');
$source = array_clean(array_column($categories, 'category'));
echo '
<script>
var categorie = '.json_encode($source).';
// Auto-completamento categoria
$(document).ready(function () {
const input = $("#modifica-allegato #categoria_allegato")[0];
autocomplete({
minLength: 0,
input: input,
emptyMsg: globals.translations.noResults,
fetch: function (text, update) {
text = text.toLowerCase();
const suggestions = categorie.filter(n => n.toLowerCase().startsWith(text));
// Trasformazione risultati in formato leggibile
const results = suggestions.map(function (result) {
return {
label: result,
value: result
}
});
update(results);
},
onSelect: function (item) {
input.value = item.label;
},
});
});
</script>
<script>$(document).ready(init)</script>';

View File

@ -1,250 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
use Modules\DDT\DDT;
use Modules\Ordini\Ordine;
// Informazioni generali sulla riga
$source_type = filter('riga_type');
$source_id = filter('riga_id');
if (empty($source_type) || empty($source_id)) {
return;
}
$source = $source_type::find($source_id);
echo '
<p>'.tr('Informazioni per i riferimenti di: _DESC_', [
'_DESC_' => $source->descrizione,
]).'</p>
<div id="righe_riferimenti">';
include_once __DIR__.'/righe_riferimenti.php';
echo '
</div>
<div class="alert alert-info" id="box-loading-riferimenti">
<i class="fa fa-spinner fa-spin"></i> '.tr('Caricamento in corso').'...
</div>';
$documenti_disponibili = collect();
$direzione_richiesta = $source->getDocument()->direzione == 'entrata' ? 'uscita' : 'entrata';
// Individuazione DDT disponibili
$ddt = DDT::whereHas('stato', function ($query) {
$query->where('descrizione', '!=', 'Bozza');
})->whereHas('tipo', function ($query) use ($direzione_richiesta) {
$query->where('dir', '=', $direzione_richiesta);
})->get();
foreach ($ddt as $elemento) {
$documenti_disponibili->push([
'id' => get_class($elemento).'|'.$elemento->id,
'text' => $elemento->getReference(1),
'optgroup' => tr('Ddt in ').$source->getDocument()->direzione,
]);
}
// Individuazione ordini disponibili
$tipo_ordini = $direzione_richiesta == 'entrata' ? 'cliente' : 'fornitore';
$ordini = Ordine::whereHas('stato', function ($query) {
$query->where('descrizione', '!=', 'Bozza');
})->get();
foreach ($ordini as $elemento) {
$documenti_disponibili->push([
'id' => get_class($elemento).'|'.$elemento->id,
'text' => $elemento->getReference(1),
'optgroup' => tr('Ordini ').$tipo_ordini,
]);
}
echo '
<div class="box">
<div class="box-header">
<h3 class="box-title">'.tr('Nuovo riferimento').'</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Documento').'", "name": "documento_riferimento", "required": 1, "values": '.$documenti_disponibili->toJson().' ]}
</div>
</div>
<div id="righe_documento"></div>
<div class="alert alert-info" id="box-loading">
<i class="fa fa-spinner fa-spin"></i> '.tr('Caricamento in corso').'...
</div>
</div>
</div>';
$file = basename(__FILE__);
echo '
<script>$(document).ready(init)</script>
<script>
$(document).ready(function(){
$("#box-loading").hide();
$("#box-loading-riferimenti").hide();
});
var riferimenti = JSON.parse(\''.json_encode($elenco_riferimenti).'\');
var source_type = "'.addslashes($source_type).'";
var source_id = "'.$source_id.'";
$("#documento_riferimento").on("change", function(){
let value = $(this).val();
if (value) {
let pieces = value.split("|");
let type = pieces[0];
let id = pieces[1];
caricaRighe(type, id);
}
});
function caricaRiferimenti() {
let loader = $("#box-loading-riferimenti");
let content = $("#righe_riferimenti");
loader.show();
content.html("");
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "GET",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "visualizza_righe_riferimenti",
source_type: source_type,
source_id: source_id,
},
success: function(data) {
loader.hide();
content.html(data);
$("#documento_riferimento").trigger("change");
}
});
}
function caricaRighe(tipo_documento, id_documento){
let content = $("#righe_documento");
let loader = $("#box-loading");
loader.show();
content.html("");
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "GET",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "visualizza_righe_documento",
source_type: source_type,
source_id: source_id,
id_documento: id_documento,
tipo_documento: tipo_documento,
riferimenti: riferimenti,
},
success: function(data) {
loader.hide();
content.html(data);
}
});
}
function salvaRiferimento(btn, source_type, source_id) {
$("#main_loading").show();
let row = $(btn).closest("tr");
let target_type = row.data("type");
let target_id = row.data("id");
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "POST",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "salva_riferimento_riga",
source_type: source_type,
source_id: source_id,
target_type: target_type,
target_id: target_id,
},
success: function(data) {
$("#main_loading").fadeOut();
// Aggiunta del riferimento in memoria
let riferimento_locale = target_type + "|" + target_id;
riferimenti.push(riferimento_locale);
$(btn).removeClass("btn-info").addClass("btn-success");
caricaRiferimenti();
}
});
}
function rimuoviRiferimento(btn, source_type, source_id, idriferimento) {
$("#main_loading").show();
let row = $(btn).closest("tr");
let target_type = row.data("type");
let target_id = row.data("id");
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "POST",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "rimuovi_riferimento_riga",
source_type: source_type,
source_id: source_id,
target_type: target_type,
target_id: target_id,
idriferimento: idriferimento,
},
success: function(data) {
$("#main_loading").fadeOut();
// Rimozione del riferimento dalla memoria
let riferimento_locale = target_type + "|" + target_id;
let index = riferimenti.indexOf(riferimento_locale);
if (index > -1) {
riferimenti.splice(index, 1);
}
caricaRiferimenti();
}
});
}
</script>';

View File

@ -1,66 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
// Generazione della tabella per l'aggiunta dei riferimenti
$id_documento = filter('id_documento');
$tipo_documento = filter('tipo_documento');
if (empty($tipo_documento) || empty($id_documento)) {
return;
}
$documento = $tipo_documento::find($id_documento);
// Informazioni sulla riga
$source_type = filter('source_type');
$source_id = filter('source_id');
$riferimenti = (array) filter('riferimenti');
echo '
<table class="table table-striped table-hover table-condensed table-bordered">
<tr>
<th>'.tr('Descrizione').'</th>
<th>'.tr('Q.').' <i title="'.tr('da evadere').' / '.tr('totale').'" class="tip fa fa-question-circle-o"></i></th>
<th class="text-center">#</th>
</tr>
<tbody>';
$righe = $documento->getRighe();
foreach ($righe as $riga) {
$riga_class = get_class($riga);
$riferimento_locale = $riga_class.'|'.$riga->id;
$presente = in_array($riferimento_locale, $riferimenti);
echo '
<tr data-id="'.$riga->id.'" data-type="'.$riga_class.'">
<td>'.$riga->descrizione.'</td>
<td>'.numberFormat($riga->qta_rimanente, 'qta').' / '.numberFormat($riga->qta, 'qta').'</td>
<td class="text-center">
<button type="button" class="btn btn-'.($presente ? 'success' : 'info').' btn-xs" '.($presente ? '' : 'onclick="salvaRiferimento(this, \''.addslashes($source_type).'\',\''.$source_id.'\')"').'>
<i class="fa fa-check"></i>
</button>
</td>
</tr>';
}
echo '
</tbody>
</table>';

View File

@ -1,74 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
// Informazioni generali sulla riga
$source_type = $source_type ?: filter('source_type');
$source_id = $source_id ?: filter('source_id');
if (empty($source_type) || empty($source_id)) {
return;
}
$source = $source_type::find($source_id);
$riferimenti = $source->referenceTargets;
$elenco_riferimenti = [];
if (!$riferimenti->isEmpty()) {
echo '
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>'.tr('Riferimento').'</th>
</tr>
</thead>
<tbody>';
foreach ($riferimenti as $riferimento) {
$riga = $riferimento->target;
$riga_class = get_class($source);
echo '
<tr data-id="'.$riga->id.'" data-type="'.$riga_class.'">
<td>
<button type="button" class="btn btn-xs btn-danger pull-right" onclick="rimuoviRiferimento(this, \''.addslashes($source_type).'\', \''.$source_id.'\', \''.$riferimento->id.'\')">
<i class="fa fa-trash"></i>
</button>
'.$riferimento->target->descrizione.'
<br>
<small>'.reference($riferimento->target->getDocument()).'</small>
</td>
</tr>';
// Aggiunta all'elenco dei riferimenti
$elenco_riferimenti[] = addslashes($riga_class).'|'.$riga->id;
}
echo '
</tbody>
</table>';
} else {
echo '
<div class="alert alert-info">
<i class="fa fa-info-circle"></i> '.tr('Nessun riferimento presente').'.
</div>';
}

View File

@ -1,637 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Util\FileSystem;
include_once __DIR__.'/../core.php';
$paths = App::getPaths();
$user = Auth::user();
$pageTitle = !empty($pageTitle) ? $pageTitle : $structure->title;
$messages = flash()->getMessages();
echo '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'.$pageTitle.' - '.tr('OpenSTAManager').'</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<meta name="robots" content="noindex,nofollow">
<link href="'.$paths['img'].'/favicon.png" rel="icon" type="image/x-icon" />';
if (file_exists(base_dir().'/manifest.json')) {
echo '
<link rel="manifest" href="'.base_path().'/manifest.json">';
}
// CSS
foreach (App::getAssets()['css'] as $style) {
echo '
<link rel="stylesheet" type="text/css" media="all" href="'.$style.'"/>';
}
// Print CSS
foreach (App::getAssets()['print'] as $style) {
echo '
<link rel="stylesheet" type="text/css" media="print" href="'.$style.'"/>';
}
if (Auth::check()) {
echo '
<script>
search = []';
$array = $_SESSION['module_'.$id_module];
if (!empty($array)) {
foreach ($array as $field => $value) {
if (!empty($value) && string_starts_with($field, 'search_')) {
$field_name = str_replace('search_', '', $field);
echo '
search.push("search_'.$field_name.'");
search["search_'.$field_name.'"] = "'.addslashes($value).'";';
}
}
}
echo '
translations = {';
$translations = [
'day' => tr('Giorno'),
'week' => tr('Settimana'),
'month' => tr('Mese'),
'today' => tr('Oggi'),
'firstThreemester' => tr('I trimestre'),
'secondThreemester' => tr('II trimestre'),
'thirdThreemester' => tr('III trimestre'),
'fourthThreemester' => tr('IV trimestre'),
'firstSemester' => tr('I semestre'),
'secondSemester' => tr('II semestre'),
'thisMonth' => tr('Questo mese'),
'lastMonth' => tr('Mese scorso'),
'thisYear' => tr("Quest'anno"),
'lastYear' => tr('Anno scorso'),
'apply' => tr('Applica'),
'cancel' => tr('Annulla'),
'from' => tr('Da'),
'to' => tr('A'),
'custom' => tr('Personalizzato'),
'delete' => tr('Elimina'),
'deleteTitle' => tr('Sei sicuro?'),
'deleteMessage' => tr('Eliminare questo elemento?'),
'errorTitle' => tr('Errore'),
'errorMessage' => tr("Si è verificato un errore nell'esecuzione dell'operazione richiesta"),
'close' => tr('Chiudi'),
'filter' => tr('Filtra'),
'long' => tr('La ricerca potrebbe richiedere del tempo'),
'details' => tr('Dettagli'),
'loading' => tr('Caricamento'),
'waiting' => tr('Impossibile procedere'),
'waitingMessage' => tr('Prima di proseguire devi selezionare alcuni elementi!'),
'hooksExecuting' => tr('Hooks in esecuzione'),
'hookExecuting' => tr('Hook "_NAME_" in esecuzione'),
'hookMultiple' => tr('Hai _NUM_ notifiche'),
'hookSingle' => tr('Hai 1 notifica'),
'hookNone' => tr('Nessuna notifica'),
'singleCalendar' => tr("E' presente un solo periodo!"),
'noResults' => tr('Nessun elemento trovato'),
];
foreach ($translations as $key => $value) {
echo '
'.$key.': "'.addslashes($value).'",';
}
echo '
allegati: {
messaggio: "'.tr('Clicca o trascina qui per caricare uno o più file').'",
maxFilesize: "'.tr('Max upload: _SIZE_ MB').'",
errore: "'.tr('Errore').'",
modifica: "'.tr('Modifica allegato').'",
elimina: "'.tr('Vuoi eliminare questo file?').'",
procedi: "'.tr('Procedi').'",
},
ajax: {
"missing": {
"title": "'.tr('Errore').'",
"text": "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente').'",
},
"error": {
"title": "'.tr('Errore').'",
"text": "'.tr('Errore durante il salvataggio del record').'",
}
},
password: {
"wordMinLength": "'.tr('La password è troppo corta').'",
"wordMaxLength": "'.tr('La password è troppo lunga').'",
"wordInvalidChar": "'.tr('La password contiene un carattere non valido').'",
"wordNotEmail": "'.tr('Non usare la tua e-mail come password').'",
"wordSimilarToUsername": "'.tr('La password non può contenere il tuo nome').'",
"wordTwoCharacterClasses": "'.tr('Usa classi di caratteri diversi').'",
"wordRepetitions": "'.tr('La password contiene ripetizioni').'",
"wordSequences": "'.tr('La password contiene sequenze').'",
"errorList": "'.tr('Attenzione').':",
"veryWeak": "'.tr('Molto debole').'",
"weak": "'.tr('Debole').'",
"normal": "'.tr('Normale').'",
"medium": "'.tr('Media').'",
"strong": "'.tr('Forte').'",
"veryStrong": "'.tr('Molto forte').'",
},
datatables: {
"emptyTable": "'.tr('Nessun dato presente nella tabella').'",
"info": "'.tr('Vista da _START_ a _END_ di _TOTAL_ elementi').'",
"infoEmpty": "'.tr('Vista da 0 a 0 di 0 elementi').'",
"infoFiltered": "('.tr('filtrati da _MAX_ elementi totali').')",
"infoPostFix": "",
"lengthMenu": "'.tr('Visualizza _MENU_ elementi').'",
"loadingRecords": " ",
"processing": "'.tr('Elaborazione').'...",
"search": "'.tr('Cerca').':",
"zeroRecords": "'.tr('La ricerca non ha portato alcun risultato').'.",
"paginate": {
"first": "'.tr('Inizio').'",
"previous": "'.tr('Precedente').'",
"next": "'.tr('Successivo').'",
"last": "'.tr('Fine').'"
},
},
};
globals = {
rootdir: "'.base_path().'",
js: "'.$paths['js'].'",
css: "'.$paths['css'].'",
img: "'.$paths['img'].'",
id_module: "'.$id_module.'",
id_record: "'.$id_record.'",
is_mobile: '.isMobile().',
cifre_decimali: '.setting('Cifre decimali per importi').',
timestamp_format: "'.formatter()->getTimestampPattern().'",
date_format: "'.formatter()->getDatePattern().'",
time_format: "'.formatter()->getTimePattern().'",
decimals: "'.formatter()->getNumberSeparators()['decimals'].'",
thousands: "'.formatter()->getNumberSeparators()['thousands'].'",
currency: "'.currency().'",
search: search,
translations: translations,
locale: "'.(explode('_', $lang)[0]).'",
full_locale: "'.$lang.'",
start_date: "'.$_SESSION['period_start'].'",
start_date_formatted: "'.Translator::dateToLocale($_SESSION['period_start']).'",
end_date: "'.$_SESSION['period_end'].'",
end_date_formatted: "'.Translator::dateToLocale($_SESSION['period_end']).'",
collapse_plugin_sidebar: '.intval(setting('Nascondere la barra dei plugin di default')).',
ckeditorToolbar: [
["Undo","Redo","-","Cut","Copy","Paste","PasteText","PasteFromWord","-","SpellChecker", "Scayt", "-","Link","Unlink","-","Bold","Italic","Underline","Superscript","SpecialChar","HorizontalRule","-","JustifyLeft","JustifyCenter","JustifyRight","JustifyBlock","-","NumberedList","BulletedList","Outdent","Indent","Blockquote","-","Styles","Format","Image","Table", "TextColor", "BGColor" ],
],
ckeditorToolbar_Full: [
{ name: "document", items : [ "Source" ] },
{ name: "clipboard", items : [ "Cut","Copy","Paste","PasteText","PasteFromWord","-","Undo","Redo" ] },
{ name: "editing", items : [ "Find","Replace","-","SelectAll","-","SpellChecker", "Scayt" ] },
{ name: "forms", items : [ "Form", "Checkbox", "Radio", "TextField", "Textarea", "Select", "Button", "ImageButton",
"HiddenField" ] },
"/",
{ name: "basicstyles", items : [ "Bold","Italic","Underline","Strike","Subscript","Superscript","-","RemoveFormat" ] },
{ name: "paragraph", items : [ "NumberedList","BulletedList","-","Outdent","Indent","-","Blockquote","CreateDiv",
"-","JustifyLeft","JustifyCenter","JustifyRight","JustifyBlock","-","BidiLtr","BidiRtl" ] },
{ name: "links", items : [ "Link","Unlink","Anchor" ] },
{ name: "insert", items : [ "Image","Flash","Table","HorizontalRule","Smiley","SpecialChar","PageBreak","Iframe" ] },
"/",
{ name: "styles", items : [ "Styles","Format","Font","FontSize" ] },
{ name: "colors", items : [ "TextColor","BGColor" ] },
{ name: "tools", items : [ "Maximize", "ShowBlocks","-","About" ] }
],
order_manager_id: "'.($dbo->isInstalled() ? Modules::get('Stato dei servizi')['id'] : '').'",
dataload_page_buffer: '.setting('Lunghezza in pagine del buffer Datatables').',
tempo_attesa_ricerche: '.setting('Tempo di attesa ricerche in secondi').',
restrict_summables_to_selected: '.setting('Totali delle tabelle ristretti alla selezione').',
};
</script>';
} else {
echo '
<script>
globals = {
rootdir: "'.base_path().'",
search: {},
translations: {
password: {
"wordMinLength": "'.tr('La tua password è troppo corta').'",
"wordMaxLength": "'.tr('La tua password è troppo lunga').'",
"wordInvalidChar": "'.tr('La tua password contiene un carattere non valido').'",
"wordNotEmail": "'.tr('Non usare la tua e-mail come password').'",
"wordSimilarToUsername": "'.tr('La tua password non può contenere il tuo nome').'",
"wordTwoCharacterClasses": "'.tr('Usa classi di caratteri diversi').'",
"wordRepetitions": "'.tr('Troppe ripetizioni').'",
"wordSequences": "'.tr('La tua password contiene sequenze').'",
"errorList": "'.tr('Errori').':",
"veryWeak": "'.tr('Molto debole').'",
"weak": "'.tr('Debole').'",
"normal": "'.tr('Normale').'",
"medium": "'.tr('Media').'",
"strong": "'.tr('Forte').'",
"veryStrong": "'.tr('Molto forte').'",
},
},
timestamp_format: "'.formatter()->getTimestampPattern().'",
date_format: "'.formatter()->getDatePattern().'",
time_format: "'.formatter()->getTimePattern().'",
locale: "'.(explode('_', $lang)[0]).'",
full_locale: "'.$lang.'",
};
</script>';
}
// JS
foreach (App::getAssets()['js'] as $js) {
echo '
<script type="text/javascript" charset="utf-8" src="'.$js.'"></script>';
}
// Impostazioni di default per gli alert
echo '
<script>
swal.setDefaults({
buttonsStyling: false,
confirmButtonClass: "btn btn-lg btn-primary",
cancelButtonClass: "btn btn-lg",
cancelButtonText: "'.tr('Annulla').'",
});
</script>';
if (Auth::check()) {
if (setting('Abilita esportazione Excel e PDF')) {
echo '
<script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>';
}
if (setting('Attiva scorciatoie da tastiera')) {
echo '<script type="text/javascript" charset="utf-8" src="'.App::getPaths()['js'].'/hotkeys-js/hotkeys.min.js"></script>';
echo '
<script>
hotkeys("f1,f2,f3,f4", function(event, handler) {
switch (handler.key) {
case "f1":
event.preventDefault();
$("button[data-toggle]").first().trigger("click");
break;
case "f2":
event.preventDefault();
$("#save").first().trigger("click");
break;
case "f3":
event.preventDefault();
$("#print-button_p").first().trigger("click");
break;
case "f4":
event.preventDefault();
$("#email-button_p").first().trigger("click");
break;
default: alert(event);
}
});
</script>';
}
}
$settings_collapse = session_get('settings.sidebar-collapse') ? 1 : 0;
$hide_sidebar = Auth::check() && (setting('Nascondere la barra sinistra di default') || $settings_collapse);
echo '
</head>
<body class="skin-'.$theme.(!empty($hide_sidebar) ? ' sidebar-collapse' : '').(!Auth::check() ? ' hold-transition login-page' : '').'">
<div class="'.(!Auth::check() ? '' : 'wrapper').'">';
if (Auth::check()) {
$calendar_color_label = ($_SESSION['period_start'] != date('Y').'-01-01' || $_SESSION['period_end'] != date('Y').'-12-31') ? 'danger' : 'default';
echo '
<!-- Loader principale -->
<div id="main_loading">
<div>
<i class="fa fa-cog fa-spin text-danger"></i>
</div>
</div>
<!-- Loader secondario -->
<div id="mini-loader" style="display:none;">
<div></div>
</div>
<!-- Loader senza overlay -->
<div id="tiny-loader" style="display:none;"></div>
<header class="main-header">
<a href="'.tr('https://www.openstamanager.com').'" class="logo" title="'.tr("Il gestionale open source per l'assistenza tecnica e la fatturazione").'" target="_blank">
<!-- mini logo for sidebar mini 50x50 pixels -->
<span class="logo-mini">'.tr('OSM').'</span>
<!-- logo for regular state and mobile devices -->
<span class="logo-lg">'.tr('OpenSTAManager').'</span>
</a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
<span class="sr-only">'.tr('Mostra/nascondi menu').'</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<!-- Navbar Left Menu -->
<div class="navbar-left hidden-xs">
<ul class="nav navbar-nav hidden-xs">
<li><a href="#" id="daterange" role="button" >
<i class="fa fa-calendar" style="color:inherit"></i> <i class="fa fa-caret-down" style="color:inherit"></i>
</a></li>
<li><a style="cursor:default;padding:0px;padding-right:5px;padding-left:5px;margin-top:15px;" class="label label-'.$calendar_color_label.'">
'.Translator::dateToLocale($_SESSION['period_start']).' - '.Translator::dateToLocale($_SESSION['period_end']).'
</a></li>
</ul>
</div>
<!-- Navbar Right Menu -->
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li class="dropdown notifications-menu nav-button">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-bell-o"></i>
<span id="hooks-label" class="label label-warning">
<span id="hooks-loading"><i class="fa fa-spinner fa-spin"></i></span>
<span id="hooks-notified"></span>
<span id="hooks-counter" class="hide">0</span>
<span id="hooks-number" class="hide">0</span>
</span>
</a>
<ul class="dropdown-menu">
<li class="header"><span class="small" id="hooks-header"></span></li>
<li><ul class="menu" id="hooks">
</ul></li>
</ul>
</li>
<li class="nav-button"><a href="#" onclick="window.print()" class="tip nav-button" title="'.tr('Stampa').'">
<i class="fa fa-print"></i>
</a></li>
<li class="nav-button"><a href="'.base_path().'/bug.php" class="tip nav-button" title="'.tr('Segnalazione bug').'">
<i class="fa fa-bug"></i>
</a></li>
<li class="nav-button"><a href="'.base_path().'/log.php" class="tip nav-button" title="'.tr('Log accessi').'">
<i class="fa fa-book"></i>
</a></li>
<li class="nav-button"><a href="'.base_path().'/info.php" class="tip nav-button" title="'.tr('Informazioni').'">
<i class="fa fa-info"></i>
</a></li>
<li class="nav-button"><a href="'.base_path().'/index.php?op=logout" onclick="sessionStorage.clear()" class="bg-red tip" title="'.tr('Esci').'">
<i class="fa fa-power-off"></i>
</a></li>
</ul>
</div>
</nav>
</header>
<aside class="main-sidebar">
<section class="sidebar">
<!-- Sidebar user panel -->
<div class="user-panel text-center info" style="height: 60px">
<div class="info">
<p><a href="'.base_path().'/modules/utenti/info.php">
'.$user['username'].'
</a></p>
<p id="datetime"></p>
</div>
<a class="image" href="'.base_path().'/modules/utenti/info.php">';
$user_photo = $user->photo;
if ($user_photo) {
echo '
<img src="'.$user_photo.'" class="img-circle pull-left" alt="'.$user['username'].'" />';
} else {
echo '
<i class="fa fa-user-circle-o fa-3x pull-left" alt="'.tr('OpenSTAManager').'"></i>';
}
echo '
</a>
</div>
<!-- search form -->
<div class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" id="supersearch" placeholder="'.tr('Cerca').'..."/>
<span class="input-group-btn">
<button class="btn btn-flat" id="search-btn" name="search" type="submit">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<!-- /.search form -->
<ul class="sidebar-menu">';
echo Modules::getMainMenu();
echo '
</ul>
</section>
<!-- /.sidebar -->
</aside>';
if (string_contains($_SERVER['SCRIPT_FILENAME'], 'editor.php')) {
// Menu laterale per la visualizzazione dei plugin
echo '
<aside class="control-sidebar control-sidebar-light">
<h4 class="text-center">'.tr('Plugin disponibili').'</h4>
<ul class="nav nav-tabs nav-pills nav-stacked">
<li data-toggle="control-sidebar" class="active">
<a data-toggle="tab" href="#tab_0">
<i class="'.$structure['icon'].'"></i> '.$structure['title'].'
</a>
</li>';
// Tab dei plugin
$plugins = $dbo->fetchArray('SELECT id, title FROM zz_plugins WHERE idmodule_to='.prepare($id_module)." AND position='tab' AND enabled = 1 ORDER BY zz_plugins.order DESC");
foreach ($plugins as $plugin) {
echo '
<li data-toggle="control-sidebar">
<a data-toggle="tab" href="#tab_'.$plugin['id'].'" id="link-tab_'.$plugin['id'].'">
'.$plugin['title'].'
</a>
</li>';
}
// Tab per le note interne
if ($structure->permission != '-' && $structure->use_notes) {
$notes = $structure->recordNotes($id_record);
echo '
<li data-toggle="control-sidebar" class="bg-info">
<a data-toggle="tab" href="#tab_note" id="link-tab_note">
'.tr('Note interne').'
<span class="badge">'.($notes->count() ?: '').'</span>
</a>
</li>';
}
// Tab per le checklist
if ($structure->permission != '-' && $structure->use_checklists) {
echo '
<li data-toggle="control-sidebar" class="bg-success">
<a data-toggle="tab" href="#tab_checks" id="link-tab_checks">'.tr('Checklist').'</a>
</li>';
}
// Tab per le informazioni sulle operazioni
if (Auth::admin()) {
echo '
<li data-toggle="control-sidebar" class="bg-warning">
<a data-toggle="tab" href="#tab_info" id="link-tab_info">
'.tr('Info').'
</a>
</li>';
}
echo '
</ul>
</aside>
<div class="control-sidebar-bg"></div>';
}
echo '
<!-- Right side column. Contains the navbar and content of the page -->
<aside class="content-wrapper">
<!-- Main content -->
<section class="content">
<div class="row">';
if (string_contains($_SERVER['SCRIPT_FILENAME'], 'editor.php')) {
$location = 'editor_right';
} elseif (string_contains($_SERVER['SCRIPT_FILENAME'], 'controller.php')) {
$location = 'controller_right';
}
echo '
<div class="col-md-12">';
// Eventuale messaggio personalizzato per l'installazione corrente
$extra_file = App::filepath('include/custom/extra', 'extra.php');
if ($extra_file) {
include_once $extra_file;
}
} else {
// Eventuale messaggio personalizzato per l'installazione corrente
$extra_file = App::filepath('include/custom/extra', 'login.php');
if ($extra_file) {
include_once $extra_file;
}
if (!empty($messages['info']) || !empty($messages['warning']) || !empty($messages['error'])) {
echo '
<div class="box box-warning box-center">
<div class="box-header with-border text-center">
<h3 class="box-title">'.tr('Informazioni').'</h3>
</div>
<div class="box-body">';
}
}
// Infomazioni
if (!empty($messages['info'])) {
foreach ($messages['info'] as $value) {
echo '
<div class="alert alert-success push">
<i class="fa fa-check"></i> '.$value.'
</div>';
}
}
// Errori
if (!empty($messages['error'])) {
foreach ($messages['error'] as $value) {
echo '
<div class="alert alert-danger push">
<i class="fa fa-times"></i> '.$value.'
</div>';
}
}
// Avvisi
if (!empty($messages['warning'])) {
foreach ($messages['warning'] as $value) {
echo '
<div class="alert alert-warning push">
<i class="fa fa-warning"></i>
'.$value.'
</div>';
}
}
if (!Auth::check() && (!empty($messages['info']) || !empty($messages['warning']) || !empty($messages['error']))) {
echo '
</div>
</div>';
}
// Messaggio informativo per l'esaurimento dello spazio totale disponibile nel server
$free_space = disk_free_space('.');
$space_limit = 1; // GB
if ($free_space < ($space_limit * (1024 ** 3))) {
echo '
<div class="callout callout-warning">
<h4>
<i class="fa fa-warning"></i> '.tr('Spazio in esaurimento').'
</h4>
<p>'.tr('Lo spazio a disposizione del gestionale è in esaurimento: sono al momento disponibili _TOT_', [
'_TOT_' => FileSystem::formatBytes($free_space),
]).'.</p>
<p>'.tr('Questo può risultare un serio problema per la continuità di funzionamento del software, poichè le operazioni più espansive riguardanti lo spazio di archiviazione possono provocare malfunzionamento imprevedibili').'. '.tr('Operazioni di backup, caricamento di allegati o anche il semplice utilizzo del gestionale possono rendere i dati inaffidabili, provocando pertanto una perdita irreversibile delle informazioni salvate').'.</p>
<p>'.tr("Contatta gli amministratori di sistema oppure l'assistenza tecnica per risolvere al più presto il problema").'.</p>
</div>';
}

191
index.php
View File

@ -1,191 +0,0 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$skip_permissions = true;
include_once __DIR__.'/core.php';
$op = filter('op');
// LOGIN
switch ($op) {
case 'login':
$username = post('username');
$password = post('password');
if ($dbo->isConnected() && $dbo->isInstalled() && auth()->attempt($username, $password)) {
$_SESSION['keep_alive'] = true;
if (intval(setting('Inizio periodo calendario'))) {
$_SESSION['period_start'] = setting('Inizio periodo calendario');
} else {
$_SESSION['period_start'] = date('Y').'-01-01';
}
if (intval(setting('Fine periodo calendario'))) {
$_SESSION['period_end'] = setting('Fine periodo calendario');
} else {
$_SESSION['period_end'] = date('Y').'-12-31';
}
// Rimozione log vecchi
//$dbo->query('DELETE FROM `zz_operations` WHERE DATE_ADD(`created_at`, INTERVAL 30*24*60*60 SECOND) <= NOW()');
} else {
$status = auth()->getCurrentStatus();
flash()->error(Auth::getStatus()[$status]['message']);
redirect(base_path().'/index.php');
exit();
}
break;
case 'logout':
Auth::logout();
redirect(base_path().'/index.php');
exit();
break;
}
if (Auth::check() && isset($dbo) && $dbo->isConnected() && $dbo->isInstalled()) {
$module = Auth::firstModule();
if (!empty($module)) {
redirect(base_path().'/controller.php?id_module='.$module);
} else {
redirect(base_path().'/index.php?op=logout');
}
exit();
}
// Procedura di installazione
include_once base_dir().'/include/init/configuration.php';
// Procedura di aggiornamento
include_once base_dir().'/include/init/update.php';
// Procedura di inizializzazione
include_once base_dir().'/include/init/init.php';
$pageTitle = tr('Login');
include_once App::filepath('include|custom|', 'top.php');
// Controllo se è una beta e in caso mostro un warning
if (Update::isBeta()) {
echo '
<div class="clearfix">&nbsp;</div>
<div class="alert alert-warning alert-dismissable col-md-6 col-md-push-3 text-center fade in">
<i class="fa fa-warning"></i> <b>'.tr('Attenzione!').'</b> '.tr('Stai utilizzando una versione <b>non stabile</b> di OSM.').'
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
</div>';
}
// Controllo se è una beta e in caso mostro un warning
if (Auth::isBrute()) {
echo '
<div class="box box-danger box-center" id="brute">
<div class="box-header with-border text-center">
<h3 class="box-title">'.tr('Attenzione').'</h3>
</div>
<div class="box-body text-center">
<p>'.tr('Sono stati effettuati troppi tentativi di accesso consecutivi!').'</p>
<p>'.tr('Tempo rimanente (in secondi)').': <span id="brute-timeout">'.(Auth::getBruteTimeout() + 1).'</span></p>
</div>
</div>
<script>
$(document).ready(function(){
$(".login-box").fadeOut();
brute();
});
function brute() {
var value = parseFloat($("#brute-timeout").html()) - 1;
$("#brute-timeout").html(value);
if(value > 0){
setTimeout("brute()", 1000);
} else{
$("#brute").fadeOut();
$(".login-box").fadeIn();
}
}
</script>';
}
if (!empty(flash()->getMessage('error'))) {
echo '
<script>
$(document).ready(function(){
$(".login-box").effect("shake");
});
</script>';
}
echo '
<form action="?op=login" method="post" class="login-box box" autocomplete="off" >
<div class="box-header with-border text-center">
<img src="'.App::getPaths()['img'].'/logo.png" class="img-responsive" alt="'.tr('OSM Logo').'">
</div>
<div class="login-box-body box-body">
<div class="form-group input-group">
<span class="input-group-addon before"><i class="fa fa-user"></i> </span>
<input type="text" name="username" autocomplete="username" class="form-control" placeholder="'.tr('Nome utente').'"';
if (isset($username)) {
echo ' value="'.$username.'"';
}
echo ' required>
</div>
{[ "type": "password", "name": "password", "autocomplete": "current-password", "placeholder": "'.tr('Password').'", "icon-before": "<i class=\"fa fa-lock\"></i>" ]}
<div class="text-right">
<small><a href="'.base_path().'/reset.php">'.tr('Password dimenticata?').'</a></small>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" id="login" class="btn btn-danger btn-block">'.tr('Accedi').'</button>
</div>
<!-- box-footer -->
</form>
<!-- /.box -->
<script>
$(document).ready( function(){
$("#login").click(function(){
$("#login").text("'.tr('Autenticazione').'...");
});
if( $("input[name=username]").val() == ""){
$("input[name=username]").focus();
}
else{
$("input[name=password]").focus();
}
});
</script>';
include_once App::filepath('include|custom|', 'bottom.php');

Some files were not shown because too many files have changed in this diff Show More