1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2024-12-22 13:26:38 +01:00

Aggiunta Eloquent

Aggiunta di Eloquent per l'introduzione delle classi dedicate alla gestione dei singoli moduli.
Esempio fornito in Fatture.
This commit is contained in:
Thomas Zilio 2018-08-08 19:32:20 +02:00
parent 367214e267
commit 0a8d4488a4
11 changed files with 531 additions and 106 deletions

View File

@ -28,7 +28,7 @@ $element['edit_file'] = !empty($php) ? $php : $html;
$upload_dir = DOCROOT.'/'.Uploads::getDirectory($id_module, $id_plugin);
$dbo->query('START TRANSACTION');
//$dbo->query('START TRANSACTION');
// GESTIONE UPLOAD
if (filter('op') == 'link_file' || filter('op') == 'unlink_file') {
@ -242,4 +242,4 @@ if (Modules::getPermission($id_module) == 'rw') {
}
}
$dbo->query('COMMIT');
//$dbo->query('COMMIT');

View File

@ -29,6 +29,7 @@
"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",
"maximebf/debugbar": "^1.15",

View File

@ -156,6 +156,20 @@ if (!API::isAPIRequest()) {
// Impostazioni di Content-Type e Charset Header
header('Content-Type: text/html; charset=UTF-8');
// Barra di debug
if (App::debug()) {
$debugbar = new DebugBar\DebugBar();
$debugbar->addCollector(new DebugBar\DataCollector\MemoryCollector());
$debugbar->addCollector(new DebugBar\DataCollector\PhpInfoCollector());
$debugbar->addCollector(new DebugBar\DataCollector\RequestDataCollector());
$debugbar->addCollector(new DebugBar\DataCollector\TimeDataCollector());
$debugbar->addCollector(new DebugBar\Bridge\MonologCollector($logger));
$debugbar->addCollector(new Extension\EloquentCollector($dbo->getCapsule()));
}
// Controllo CSRF
csrfProtector::init();
@ -231,3 +245,12 @@ if (!API::isAPIRequest()) {
$post = Filter::getPOST();
$get = Filter::getGET();
}
$f = Modules\Fatture\Fattura::find(7);
$result = Modules\Fatture\Fattura::create([
'idanagrafica' => 1,
'data' => '2018-11-11 12:13:21',
'id_segment' => 1,
'idtipodocumento' => 1,
]);

View File

@ -149,17 +149,6 @@ echo '
if (Auth::check()) {
// Barra di debug
if (App::debug()) {
$debugbar = new DebugBar\DebugBar();
$debugbar->addCollector(new DebugBar\DataCollector\MemoryCollector());
$debugbar->addCollector(new DebugBar\DataCollector\PhpInfoCollector());
$debugbar->addCollector(new DebugBar\DataCollector\RequestDataCollector());
$debugbar->addCollector(new DebugBar\DataCollector\TimeDataCollector());
$debugbar->addCollector(new DebugBar\Bridge\MonologCollector($logger));
$debugbar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($dbo->getPDO()));
$debugbarRenderer = $debugbar->getJavascriptRenderer();
$debugbarRenderer->setIncludeVendors(false);
$debugbarRenderer->setBaseUrl($paths['assets'].'/php-debugbar');

345
modules/fatture/Fattura.php Normal file
View File

@ -0,0 +1,345 @@
<?php
namespace Modules\Fatture;
use Illuminate\Database\Eloquent\Model;
use Util\Generator;
class Fattura extends Model
{
protected $table = 'co_documenti';
/** @var array Opzioni abilitate per la creazione */
protected $fillable = [
'idanagrafica',
'data',
'id_segment',
];
/** @var array Conti rilevanti della fattura */
protected $conti = [];
/**
* Crea una nuova fattura.
*
* @param int $id_anagrafica
* @param string $data
* @param int $id_segment
*/
public static function create(array $attributes = [])
{
$model = static::query()->create($attributes);
$tipo_documento = Tipo::find($attributes['idtipodocumento']);
$stato_documento = Stato::where('descrizione', 'Bozza')->first();
$direzione = $tipo_documento->dir;
$data = $attributes['data'];
$id_anagrafica = $attributes['idanagrafica'];
$id_segment = $attributes['id_segment'];
$dbo = database();
// Calcolo dei numeri fattura
$numero = static::getNumero($data, $direzione, $id_segment);
$numero_esterno = static::getNumeroSecondario($data, $direzione, $id_segment);
if ($direzione == 'entrata') {
$id_conto = setting('Conto predefinito fatture di vendita');
$conto = 'vendite';
} else {
$id_conto = setting('Conto predefinito fatture di acquisto');
$conto = 'acquisti';
}
// Tipo di pagamento e banca predefinite dall'anagrafica
$pagamento = $dbo->fetchOne('SELECT id, (SELECT idbanca_'.$conto.' FROM an_anagrafiche WHERE idanagrafica = ?) AS idbanca FROM co_pagamenti WHERE id = (SELECT idpagamento_'.$conto.' AS pagamento FROM an_anagrafiche WHERE idanagrafica = ?)', [
$id_anagrafica,
$id_anagrafica,
]);
$id_pagamento = $pagamento['id'];
$id_banca = $pagamento['idbanca'];
// Se la fattura è di vendita e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni
if ($direzione == 'entrata' && empty($id_pagamento)) {
$id_pagamento = setting('Tipo di pagamento predefinito');
}
// Se non è impostata la banca dell'anagrafica, uso quella del pagamento.
if (empty($id_banca)) {
$id_banca = $dbo->fetchOne('SELECT id FROM co_banche WHERE id_pianodeiconti3 = (SELECT idconto_'.$conto.' FROM co_pagamenti WHERE id = :id_pagamento)', [
':id_pagamento' => $id_pagamento,
])['id'];
}
$id_sede = $dbo->selectOne('an_anagrafiche', 'idsede_fatturazione', ['idanagrafica' => $id_anagrafica])['idsede_fatturazione'];
// Salvataggio delle informazioni
$model->numero = $numero;
$model->numero_esterno = $numero_esterno;
$model->idconto = $id_conto;
$model->idpagamento = $id_pagamento;
$model->idbanca = $id_banca;
$model->idsede = $id_sede;
$model->tipo()->associate($tipo_documento);
$model->stato()->associate($stato_documento);
$model->save();
return $model;
}
/**
* Calcola il nuovo numero di fattura.
*
* @param string $data
* @param string $direzione
* @param int $id_segment
*
* @return string
*/
protected static function getNumero($data, $direzione, $id_segment)
{
$dbo = database();
if ($direzione == 'uscita') {
$maschera = static::getMaschera($id_segment);
$ultima_fattura = $dbo->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [
':year' => date('Y', strtotime($data)),
':id_segment' => $id_segment,
]);
$numero = Generator::generate($maschera, $ultima_fattura['numero']);
} else {
$rs = $dbo->fetchOne("SELECT IFNULL(MAX(numero), '0') AS max_numerofattura FROM co_documenti WHERE YEAR(data) = :year AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir = :direzione) ORDER BY CAST(numero AS UNSIGNED) DESC", [
':year' => date('Y', strtotime($data)),
':direzione' => $direzione,
]);
$numero = $rs['max_numerofattura'] + 1;
}
return $numero;
}
/**
* Calcola il nuovo numero secondario di fattura.
*
* @param string $data
* @param string $direzione
* @param int $id_segment
*
* @return string
*/
protected static function getNumeroSecondario($data, $direzione, $id_segment)
{
if ($direzione == 'uscita') {
return '';
}
$dbo = database();
// Recupero maschera per questo segmento
$maschera = static::getMaschera($id_segment);
$ultima_fattura = $dbo->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [
':year' => date('Y', strtotime($data)),
':id_segment' => $id_segment,
]);
$numero_esterno = Generator::generate($maschera, $ultima_fattura['numero_esterno']);
return $numero_esterno;
}
/**
* Restituisce la maschera specificata per il segmento indicato.
*
* @param int $id_segment
*
* @return string
*/
protected static function getMaschera($id_segment)
{
$dbo = database();
$maschera = $dbo->fetchOne('SELECT pattern FROM zz_segments WHERE id = :id_segment', [
':id_segment' => $id_segment,
])['pattern'];
return $maschera;
}
/**
* Metodo per l'individuazione del tipo di ordine da impostare per la corretta interpretazione della maschera.
* Esempi:
* - maschere con testo iniziale (FT-####-YYYY) necessitano l'ordinamento alfabetico
* - maschere di soli numeri (####-YYYY) è necessario l'ordinamento numerico forzato.
*
* @param string $maschera
*
* @return string
*/
protected static function getMascheraOrder($maschera)
{
// Estraggo blocchi di caratteri standard
preg_match('/[#]+/', $maschera, $m1);
//preg_match('/[Y]+/', $maschera, $m2);
$pos1 = strpos($maschera, $m1[0]);
if ($pos1 == 0) {
$query = 'ORDER BY CAST(numero_esterno AS UNSIGNED) DESC';
} else {
$query = 'ORDER BY numero_esterno DESC';
}
return $query;
}
/**
* Calcola l'imponibile della fattura (totale delle righe - sconto).
*
* @return float
*/
public function getImponibile()
{
if (isset($this->conti['imponibile'])) {
return $this->conti['imponibile'];
}
$result = database()->fetchOne('SELECT SUM(co_righe_documenti.subtotale - co_righe_documenti.sconto) AS imponibile FROM co_righe_documenti WHERE iddocumento = :id', [
':id' => $this->id,
]);
return $result['imponibile'];
}
/**
* Calcola il totale della fattura (imponibile + iva).
*
* @return float
*/
public function getTotale()
{
if (isset($this->conti['totale'])) {
return $this->conti['totale'];
}
$dbo = database();
// Sommo l'iva di ogni riga al totale
$iva = $dbo->fetchArray('SELECT SUM(iva) AS iva FROM co_righe_documenti WHERE iddocumento = :id', [
':id' => $this->id,
])['iva'];
$iva_rivalsainps = $dbo->fetchArray('SELECT SUM(rivalsainps / 100 * percentuale) AS iva_rivalsainps FROM co_righe_documenti INNER JOIN co_iva ON co_iva.id = co_righe_documenti.idiva WHERE iddocumento = :id', [
':id' => $this->id,
])['iva_rivalsainps'];
$totale = sum([
$this->getImponibile(),
$this->rivalsainps,
$iva,
$iva_rivalsainps,
]);
return $totale;
}
/**
* Calcola il netto a pagare della fattura (totale - ritenute - bolli).
*
* @return float
*/
public function getNetto($iddocumento)
{
if (isset($this->conti['netto'])) {
return $this->conti['netto'];
}
$netto = sum([
$this->getTotale(),
$this->bollo,
-$this->ritenutaacconto,
]);
return $netto;
}
/**
* Calcola l'iva detraibile della fattura.
*
* @return float
*/
public function getIvaDetraibile()
{
if (isset($this->conti['iva_detraibile'])) {
return $this->conti['iva_detraibile'];
}
$result = database()->fetchOne('SELECT SUM(iva) - SUM(iva_indetraibile) AS iva_detraibile FROM co_righe_documenti WHERE iddocumento = :id', [
':id' => $this->id,
]);
return $result['iva_detraibile'];
}
/**
* Calcolo l'iva indetraibile della fattura.
*
* @return float
*/
public function getIvaIndetraibile()
{
if (isset($this->conti['iva_indetraibile'])) {
return $this->conti['iva_indetraibile'];
}
$result = database()->fetchOne('SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti WHERE = :id', [
':id' => $this->id,
]);
return $result['iva_indetraibile'];
}
/**
* Restituisce l'elenco delle note di accredito collegate.
*
* @return array
*/
public function getNoteDiAccredito()
{
return database()->fetchArray("SELECT co_documenti.id, IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM co_documenti WHERE idtipodocumento IN (SELECT id FROM co_tipidocumento WHERE reversed = 1) AND ref_documento = :id", [
':id' => $this->id,
]);
}
/**
* Controlla se la fattura è una nota di accredito.
*
* @return bool
*/
public function isNotaDiAccredito()
{
return $this->getTipo()['reversed'] == 1;
}
public function tipo()
{
return $this->belongsTo(Tipo::class, 'idtipodocumento');
}
public function stato()
{
return $this->belongsTo(Stato::class, 'idstatodocumento');
}
public function righe()
{
return $this->hasMany(Riga::class, 'iddocumento');
}
}

15
modules/fatture/Riga.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Fatture;
use Illuminate\Database\Eloquent\Model;
class Riga extends Model
{
protected $table = 'co_righe_documenti';
public function fattura()
{
return $this->belongsTo(Fattura::class, 'iddocumento');
}
}

15
modules/fatture/Stato.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Fatture;
use Illuminate\Database\Eloquent\Model;
class Stato extends Model
{
protected $table = 'co_statidocumento';
public function fatture()
{
return $this->hasMany(Fattura::class, 'idstatodocumento');
}
}

15
modules/fatture/Tipo.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Fatture;
use Illuminate\Database\Eloquent\Model;
class Tipo extends Model
{
protected $table = 'co_tipidocumento';
public function fatture()
{
return $this->hasMany(Fattura::class, 'idtipodocumento');
}
}

View File

@ -322,15 +322,17 @@ class Auth extends \Util\Singleton
public function getFirstModule()
{
if (empty($this->first_module)) {
$parameters = [];
$query = 'SELECT id FROM zz_modules WHERE enabled = 1';
if (!$this->isAdmin()) {
$query .= " AND id IN (SELECT idmodule FROM zz_permissions WHERE idgruppo = (SELECT id FROM zz_groups WHERE nome = :group) AND permessi IN ('r', 'rw'))";
$parameters[':group'] = $this->getUser()['gruppo'];
}
$database = Database::getConnection();
$results = $database->fetchArray($query." AND options != '' AND options != 'menu' AND options IS NOT NULL ORDER BY `order` ASC", [
':group' => $this->getUser()['gruppo'],
]);
$results = $database->fetchArray($query." AND options != '' AND options != 'menu' AND options IS NOT NULL ORDER BY `order` ASC", $parameters);
if (!empty($results)) {
$module = null;

View File

@ -1,5 +1,7 @@
<?php
use Illuminate\Database\Capsule\Manager as Capsule;
/**
* Classe per gestire la connessione al database.
*
@ -7,27 +9,17 @@
*/
class Database extends Util\Singleton
{
/** @var string Host del database */
protected $host;
/** @var int Porta di accesso del database */
protected $port;
/** @var string Username di accesso */
protected $username;
/** @var string Password di accesso */
protected $password;
/** @var \Illuminate\Database\Capsule\Manager Gestore di connessione Laravel */
protected $capsule;
/** @var string Nome del database */
protected $database_name;
/** @var string Charset della comunicazione */
protected $charset;
/** @var array Opzioni riguardanti la comunicazione (PDO) */
protected $option = [];
/** @var DebugBar\DataCollector\PDO\TraceablePDO Classe PDO tracciabile */
protected $pdo;
/** @var bool Stato di connessione del database */
protected $is_connected;
/** @var bool Stato di installazione del database */
protected $is_installed;
/** @var string Versione corrente di MySQL */
protected $mysql_version;
@ -40,13 +32,12 @@ class Database extends Util\Singleton
* @param string $password
* @param string $database_name
* @param string $charset
* @param array $option
*
* @since 2.3
*
* @return Database
*/
protected function __construct($server, $username, $password, $database_name, $charset = null, $option = [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION])
protected function __construct($server, $username, $password, $database_name, $charset = null)
{
if (is_array($server)) {
$host = $server['host'];
@ -60,48 +51,39 @@ class Database extends Util\Singleton
// Possibilità di specificare una porta per il servizio MySQL diversa dalla standard 3306
$port = !empty(App::getConfig()['port']) ? App::getConfig()['port'] : $port;
$this->host = $host;
if (!empty($port) && is_int($port * 1)) {
$this->port = $port;
}
$this->username = $username;
$this->password = $password;
$this->database_name = $database_name;
$this->charset = $charset;
$this->option = $option;
if (!empty($this->host) && !empty($this->database_name)) {
if (!empty($host) && !empty($database_name)) {
try {
$pdo = new PDO(
'mysql:host='.$this->host.(!empty($this->port) ? ';port='.$this->port : '').';dbname='.$this->database_name,
$this->username,
$this->password,
$this->option
);
// Istanziamento di Eloquent
$this->capsule = new Capsule();
$this->capsule->addConnection([
'driver' => 'mysql',
'host' => $host,
'database' => $database_name,
'username' => $username,
'password' => $password,
'charset' => 'utf8',
'prefix' => '',
'port' => $port,
]);
if (App::getConfig()['debug']) {
$pdo = new \DebugBar\DataCollector\PDO\TraceablePDO($pdo);
}
$this->is_connected = !empty($this->getPDO());
$this->pdo = $pdo;
if (empty($this->charset) && version_compare($this->getMySQLVersion(), '5.5.3') >= 0) {
$this->charset = 'utf8mb4';
// Impostazione del charset della comunicazione
if (empty($charset) && version_compare($this->getMySQLVersion(), '5.5.3') >= 0) {
$this->getPDO()->exec("SET NAMES 'utf8mb4'");
}
// Fix per problemi di compatibilità delle password MySQL 4.1+ (da versione precedente)
$this->pdo->query('SET SESSION old_passwords = 0');
//$this->pdo->query('SET PASSWORD = PASSWORD('.$this->prepare($this->password).')');
// Impostazione del charset della comunicazione
if (!empty($this->charset)) {
$this->pdo->query("SET NAMES '".$this->charset."'");
}
$this->getPDO()->exec('SET SESSION old_passwords = 0');
//$this->getPDO()->exec('SET PASSWORD = PASSWORD('.$this->prepare($this->password).')');
// Reset della modalità di esecuzione MySQL per la sessione corrente
$this->pdo->query("SET sql_mode = ''");
$this->getPDO()->exec("SET sql_mode = ''");
$this->capsule->setAsGlobal();
$this->capsule->bootEloquent();
} catch (PDOException $e) {
if ($e->getCode() == 1049 || $e->getCode() == 1044) {
$e = new PDOException(($e->getCode() == 1049) ? tr('Database non esistente!') : tr('Credenziali di accesso invalide!'));
@ -149,7 +131,12 @@ class Database extends Util\Singleton
*/
public function getPDO()
{
return $this->pdo;
return $this->capsule->getConnection()->getPDO();
}
public function getCapsule()
{
return $this->capsule;
}
/**
@ -161,7 +148,7 @@ class Database extends Util\Singleton
*/
public function isConnected()
{
return !empty($this->pdo);
return $this->is_connected;
}
/**
@ -223,7 +210,7 @@ class Database extends Util\Singleton
public function query($query, $parameters = [], $signal = null, $options = [])
{
try {
$statement = $this->pdo->prepare($query);
$statement = $this->getPDO()->prepare($query);
$statement->execute($parameters);
$id = $this->lastInsertedID();
@ -252,7 +239,7 @@ class Database extends Util\Singleton
try {
$mode = empty($numeric) ? PDO::FETCH_ASSOC : PDO::FETCH_NUM;
$statement = $this->pdo->prepare($query);
$statement = $this->getPDO()->prepare($query);
$statement->execute($parameters);
$result = $statement->fetchAll($mode);
@ -340,15 +327,11 @@ class Database extends Util\Singleton
public function tableExists($table)
{
$results = null;
if ($this->isConnected()) {
$results = $this->fetchArray('SHOW TABLES LIKE :table', [
':table' => $table,
]);
return $this->capsule->schema()->hasTable($table);
}
return !empty($results);
return null;
}
/**
@ -374,7 +357,7 @@ class Database extends Util\Singleton
public function lastInsertedID()
{
try {
return $this->pdo->lastInsertId();
return $this->getPDO()->lastInsertId();
} catch (PDOException $e) {
$this->signal($e, tr("Impossibile ottenere l'ultimo identificativo creato"));
}
@ -392,7 +375,7 @@ class Database extends Util\Singleton
*/
public function prepare($parameter)
{
return $this->pdo->quote($parameter);
return $this->getPDO()->quote($parameter);
}
/**
@ -418,11 +401,10 @@ class Database extends Util\Singleton
*
* @param string $table
* @param array $array
* @param bool $return
*
* @return string|array
*/
public function insert($table, $array, $return = false)
public function insert($table, $array)
{
if (!is_string($table) || !is_array($array)) {
throw new UnexpectedValueException();
@ -432,31 +414,7 @@ class Database extends Util\Singleton
$array = [$array];
}
// Chiavi dei valori
$keys = [];
$temp = array_keys($array[0]);
foreach ($temp as $value) {
$keys[] = $this->quote($value);
}
// Valori da inserire
$inserts = [];
foreach ($array as $values) {
foreach ($values as $key => $value) {
$values[$key] = $this->prepareValue($key, $value);
}
$inserts[] = '('.implode(array_values($values), ', ').')';
}
// Costruzione della query
$query = 'INSERT INTO '.$this->quote($table).' ('.implode(',', $keys).') VALUES '.implode($inserts, ', ');
if (!empty($return)) {
return $query;
} else {
return $this->query($query);
}
return Capsule::table($table)->insert($array);
}
/**
@ -807,7 +765,7 @@ class Database extends Util\Singleton
for ($i = $start; $i < $end; ++$i) {
try {
$this->pdo->query($queries[$i]);
$this->getPDO()->exec($queries[$i]);
} catch (PDOException $e) {
$this->signal($e, $queries[$i], [
'throw' => false,

View File

@ -0,0 +1,62 @@
<?php
namespace Extension;
class EloquentCollector extends \DebugBar\DataCollector\PDO\PDOCollector
{
protected $capsule;
public function __construct($capsule)
{
parent::__construct();
$this->capsule = $capsule;
$this->addConnection($this->getTraceablePdo(), 'Eloquent PDO');
}
/**
* @return Illuminate\Database\Capsule\Manager;
*/
protected function getEloquentCapsule()
{
return $this->capsule;
}
/**
* @return PDO
*/
protected function getEloquentPdo()
{
return $this->getEloquentCapsule()->getConnection()->getPdo();
}
/**
* @return \DebugBar\DataCollector\PDO\TraceablePDO
*/
protected function getTraceablePdo()
{
return new \DebugBar\DataCollector\PDO\TraceablePDO($this->getEloquentPdo());
}
// Override
public function getName()
{
return 'eloquent_pdo';
}
// Override
public function getWidgets()
{
return [
'eloquent' => [
'icon' => 'inbox',
'widget' => 'PhpDebugBar.Widgets.SQLQueriesWidget',
'map' => 'eloquent_pdo',
'default' => '[]',
],
'eloquent:badge' => [
'map' => 'eloquent_pdo.nb_statements',
'default' => 0,
],
];
}
}