1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-17 03:51:06 +01:00

Compare commits

...

33 Commits

Author SHA1 Message Date
valentina
34fa2f0b53 docs: aggiornamento CHANGELOG 2024-11-15 10:44:34 +01:00
valentina
27811c5582 fix: ripristino versione compatibilità mysql 2024-11-15 10:38:06 +01:00
valentina
40dfaceb07 style: formattazione stile codice 2024-11-15 10:28:06 +01:00
valentina
e409fb262b fix: allineamento fix 2024-11-15 10:18:09 +01:00
valentina
7a3b05360a fix: allineamento fix 2024-11-15 10:12:29 +01:00
valentina
3a4fc5f2e6 fix: query di aggiornamento 2024-11-15 09:50:12 +01:00
Beppe
784d86be79 fix: correzione colorazione celle su campi formattabili 2024-11-15 09:41:04 +01:00
Beppe
fa8323fa03 Fix: Correzione filtro per tipologia in statistiche 2024-11-15 09:41:03 +01:00
Beppe
d3154fcdc8 Fix: Correzione selettore pagamento al cambio cliente nei preventivi 2024-11-15 09:41:02 +01:00
Luca
dc545c7688 fix: Elenco delle estensioni file per mime type 2024-11-15 09:41:01 +01:00
Beppe
646fdc77bd Fix: correzione filtro tipologia in statistiche 2024-11-15 09:40:38 +01:00
valentina
f5ac8ea082 fix: importazione fattura di acquisto senza riferimento 2024-11-15 09:40:38 +01:00
Matteo
b20d8141c2 fix: decrizione articoli su app 2024-11-15 09:40:37 +01:00
valentina
9ad163c9a3 fix: generazione righe vuote stampa ddt 2024-11-15 09:40:37 +01:00
valentina
81c1411b46 fix: stampa ddt e preventivi 2024-11-15 09:40:36 +01:00
valentina
d0d82b92f5 fix: aggiornamento compatibilità mysql 2024-11-15 09:40:36 +01:00
valentina
5719a47e92 fix: controlli database 2024-11-15 09:40:35 +01:00
valentina
f4c893cbbd fix: stampa bilancio senza passività 2024-11-15 09:40:35 +01:00
valentina
948afc0897 fix: impostazione RiferimentoNumeroLinea in generazione FE 2024-11-15 09:40:34 +01:00
valentina
9d04bb9d1a fix: visualizzazione giacenze in articoli solo per sedi movimentate 2024-11-15 09:40:24 +01:00
valentina
6506c6e167 fix: esportazione presentazioni bancarie 2024-11-15 09:39:42 +01:00
Luca
432d827f6a fix: KNOWN-ISSUES.md 2024-11-15 09:37:41 +01:00
valentina
6e85768320 fix: visualizzazione avviso uscita dalla pagina 2024-11-15 09:37:41 +01:00
valentina
6522a78600 fix: miglioria duplicazione fattura 2024-11-15 09:37:40 +01:00
FabioL
cbf3efabc3 fix: forzatura variabile content_was_modified 2024-11-15 09:37:39 +01:00
Matteo
bc471d195e fix: fix generazione presentazioni bancarie 2024-11-15 09:37:39 +01:00
valentina
d2b2a4127c fix: stampa fattura accompagnatoria 2024-11-15 09:37:38 +01:00
valentina
9db8bb8afa docs: aggiunta known-issue 2024-11-15 09:37:37 +01:00
valentina
49eaabb9e9 fix: registrazione contabile associata ai conti riepilogativi 2024-11-15 09:37:36 +01:00
valentina
ac086dd557 fix: ripristino campo partenza merce in stampa ddt 2024-11-15 09:37:07 +01:00
valentina
364e33adaf fix: ripristino campo partenza merce in stampa ddt 2024-11-15 09:37:01 +01:00
valentina
7c93675196 fix: duplicazione fattura con marca da bollo 2024-11-15 09:36:45 +01:00
Beppe
c02ad5c4de Fix: correzione geolocalizzazione sede 2024-11-15 09:32:18 +01:00
38 changed files with 562 additions and 292 deletions

View File

@ -4,7 +4,7 @@ Tutti i maggiori cambiamenti di questo progetto saranno documentati in questo fi
Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://keepachangelog.com/), e il progetto segue il [Semantic Versioning](http://semver.org/) per definire le versioni delle release.
- [2.5.7 (2024-11-20)](#257-2024-11-20)
- [2.5.6 (2024-10-30)](#256-2024-10-30)
- [2.5.5 (2024-09-27)](#255-2024-09-27)
- [2.5.4 (2024-08-28)](#254-2024-08-28)
@ -73,6 +73,36 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- [2.2 (2016-11-10)](#22-2016-11-10)
- [2.1 (2015-04-02)](#21-2015-04-02)
## 2.5.7 (2024-11-20)
### Modificato (Changed)
- Ripristinato il campo partenza merce in stampa ddt
- Migliorata la duplicazione delle fatture
- Migliorato il widget Note interne con la visualizzazione delle note dello Scadenzario
- Ripristinata la funzionalità di esportazione degli XML delle fatture di acquisto tramite azioni di gruppo
### Fixed
- Corretta la geolocalizzazione della sede
- Corretta la duplicazione di fatture con marca da bollo
- Corretto il filtro delle sedi in base al gruppo di utenti
- Corretta la registrazione contabile associata ai conti riepilogativi
- Corretta la stampa della fattura accompagnatoria
- Corretta la generazione delle presentazioni bancarie
- Corretto l'avviso di modifica del contenuto della pagina
- Corretta la visualizzazione del plugin e l'esportazione di presentazioni bancarie
- Corretta la visualizzazione di giacenze nell'header articoli solo per sedi movimentate
- Corretta l'impostazione del RiferimentoNumeroLinea nella generazione delle fatture elettroniche
- Corretta la stampa bilancio in assenza di passività
- Corretti i controlli a database
- Corretta la generazione di righe vuote nelle stampe ddt, preventivi, ordini e fatture
- Corretta la visualizzazione della descrizione articoli sull'app
- Corretta l'importazione di fatture di acquisto
- Corretto il filtro Tipologia in statistiche
- Corretto il segmento Non completate in Attività
- Corretto il selettore del metodo di pagamento al cambio del cliente nei preventivi
- Corretto il caricamento degli allegati da app
- Corretta la visualizzazione dell'Oggetto delle email in presenta di apici
- Corretta la colorazione delle celle sui campi formattabili
## 2.5.6 (2024-10-30)
### Modificato (Changed)
- Migliorato il footer fatture di vendita

View File

@ -1,6 +1,15 @@
In questo file verranno riassunte le problematiche del gestionale che sono già note alla community.
Le problematiche saranno raggruppate per release e le relative correzioni (se applicabili) saranno riportate sotto la sezione **Soluzione**.
#### 2.5.6 - 31/10/2024
##### Problemi noti
- registrazioni contabili con conto impostato Riepilogativo clienti o Riepilogativo fornitori
##### Soluzione
Aggiornare alla versione 2.6 o eseguire lo script: https://github.com/devcode-it/openstamanager/commit/37d8c7c34fc4e81f3a4f2f79c180365b7d447891
#### 2.5.3 - 07/08/2024
##### Problemi noti

View File

@ -153,6 +153,19 @@ if (!empty($query)) {
if (preg_match('/^color_(.+?)$/', $field, $m)) {
$value = isset($r['color_title_'.$m[1]]) ? $r['color_title_'.$m[1]] : '';
// 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);
}
}
$column['class'] = 'text-center small';
$column['data-background'] = $r[$field];
}

View File

@ -135,7 +135,7 @@ echo '
<div class="row">
<div class="col-md-8">
{[ "type": "text", "label": "'.tr('Oggetto').'", "name": "subject", "value": "'.$subject.'", "required": 1 ]}
{[ "type": "text", "label": "'.tr('Oggetto').'", "name": "subject", "value": "'.prepare($subject).'", "required": 1 ]}
</div>
<div class="col-md-4">

View File

@ -77,7 +77,6 @@ $effettua_controllo = filter('effettua_controllo');
if (empty($effettua_controllo)) {
echo '
<div id="righe_controlli">
</div>
<div class="alert alert-info" id="card-loading">
@ -133,7 +132,6 @@ $info = Update::getDatabaseStructure();
$results = integrity_diff($data, $info);
$results_added = integrity_diff($info, $data);
$contents = file_get_contents(base_dir().'/settings.json');
$data_settings = json_decode($contents, true);
@ -143,25 +141,26 @@ $results_settings_added = settings_diff($settings, $data_settings);
// Schermata di visualizzazione degli errori
if (!empty($results) || !empty($results_added) || !empty($results_settings) || !empty($results_settings_added)) {
if (!empty($results)) {
if ($results) {
echo '
<p>'.tr("Segue l'elenco delle tabelle del database che presentano una struttura diversa rispetto a quella prevista nella versione ufficiale del gestionale").'.</p>
<div class="alert alert-warning">
<i class="fa fa-warning"></i>
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_ e la versione di _MYSQL_VERSION_ di _DBMS_TYPE_ rilevata a sistema', [
<p>'.tr("Segue l'elenco delle tabelle del database che presentano una struttura diversa rispetto a quella prevista nella versione ufficiale del gestionale").'.</p>
<div class="alert alert-warning">
<i class="fa fa-warning"></i>
'.tr('Attenzione: questa funzionalità può presentare dei risultati falsamente positivi, sulla base del contenuto del file _FILE_ e la versione di _MYSQL_VERSION_ di _DBMS_TYPE_ rilevata a sistema', [
'_FILE_' => '<b>'.$file_to_check_database.'</b>',
'_MYSQL_VERSION_' => '<b>'.$database->getMySQLVersion().'</b>',
'_DBMS_TYPE_' => '<b>'.$database->getType().'</b>',
]).'.
</div>';
</div>';
foreach ($results as $table => $errors) {
echo '
<h3>'.$table.'</h3>';
<h3>'.$table.'</h3>';
if (array_key_exists('current', $errors) && $errors['current'] == null) {
echo '
<div class="alert alert-danger" ><i class="fa fa-times"></i> '.tr('Tabella assente').'</div>';
<div class="alert alert-danger" ><i class="fa fa-times"></i> '.tr('Tabella assente').'
</div>';
continue;
}
@ -170,15 +169,15 @@ if (!empty($results) || !empty($results_added) || !empty($results_settings) || !
if (!empty($errors)) {
echo '
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Colonna').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Colonna').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<tbody>';
<tbody>';
foreach ($errors as $name => $diff) {
$query = '';
$null = '';
@ -202,62 +201,62 @@ if (!empty($results) || !empty($results_added) || !empty($results_settings) || !
}
echo '
<tr class="bg-warning" >
<td>
'.$name.'
</td>
<td>
'.$query.';
</td>
</tr>';
<tr class="bg-warning" >
<td>
'.$name.'
</td>
<td>
'.$query.';
</td>
</tr>';
}
echo '
</tbody>
</table>';
</tbody>
</table>';
}
if (!empty($foreign_keys)) {
echo '
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Foreign keys').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Foreign keys').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<tbody>';
<tbody>';
foreach ($foreign_keys as $name => $diff) {
echo '
<tr class="bg-warning" >
<td>
'.($name ?: $diff['expected']['title']).'
</td>
<td>
ALTER TABLE '.$table.' ADD CONSTRAINT '.$name.' FOREIGN KEY ('.$diff['expected']['column'].') REFERENCES '.$diff['expected']['referenced_table'].'(`'.$diff['expected']['referenced_column'].'`) ON DELETE '.$diff['expected']['delete_rule'].' ON UPDATE '.$diff['expected']['update_rule'].';
</td>
</tr>';
<tr class="bg-warning" >
<td>
'.($name ?: $diff['expected']['title']).'
</td>
<td>
ALTER TABLE '.$table.' ADD CONSTRAINT '.$name.' FOREIGN KEY ('.$diff['expected']['column'].') REFERENCES '.$diff['expected']['referenced_table'].'(`'.$diff['expected']['referenced_column'].'`) ON DELETE '.$diff['expected']['delete_rule'].' ON UPDATE '.$diff['expected']['update_rule'].';
</td>
</tr>';
}
echo '
</tbody>
</table>';
</tbody>
</table>';
}
}
}
if (!empty($results_added)) {
if ($results_added) {
foreach ($results_added as $table => $errors) {
if ($results[$table] && array_keys($results[$table]) != array_keys($errors)) {
if (($results[$table] && array_keys($results[$table]) != array_keys($errors)) || (empty($results[$table]) && !empty($errors))) {
echo '
<h3>'.$table.'</h3>';
<h3>'.$table.'</h3>';
if (array_key_exists('current', $errors) && $errors['current'] == null) {
echo '
<div class="alert alert-danger" ><i class="fa fa-times"></i> '.tr('Tabella assente').'</div>';
<div class="alert alert-danger" ><i class="fa fa-times"></i> '.tr('Tabella assente').'
</div>';
continue;
}
@ -266,88 +265,89 @@ if (!empty($results) || !empty($results_added) || !empty($results_settings) || !
if (!empty($errors)) {
echo '
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Colonna').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Colonna').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<tbody>';
<tbody>';
foreach ($errors as $name => $diff) {
$query = '';
if ((!isset($results[$table][$name]))) {
if (isset($diff['key'])) {
if ($diff['key']['expected'] == '') {
$query = 'Chiave non prevista';
} else {
$query = 'Chiave mancante';
foreach ($errors as $name => $diff) {
$query = '';
if (!isset($results[$table][$name])) {
if (isset($diff['key'])) {
if ($diff['key']['expected'] == '') {
$query = 'Chiave non prevista';
} else {
$query = 'Chiave mancante';
}
} else {
$query = 'Campo non previsto';
}
echo '
<tr class="bg-info" >
<td>
'.$name.'
</td>
<td>
'.$query.'
</td>
</tr>';
}
} else {
$query = 'Campo non previsto';
}
echo '
<tr class="bg-info" >
<td>
'.$name.'
</td>
<td>
'.$query.'
</td>
</tr>';
}
}
echo '
</tbody>
</table>';
</tbody>
</table>';
}
if (!empty($foreign_keys)) {
echo '
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Foreign keys').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<table class="table table-bordered">
<thead>
<tr>
<th>'.tr('Foreign keys').'</th>
<th>'.tr('Conflitto').'</th>
</tr>
</thead>
<tbody>';
<tbody>';
foreach ($foreign_keys as $name => $diff) {
echo '
<tr class="bg-info" >
<td>
'.$name.'
</td>
<td>
Chiave esterna non prevista
</td>
</tr>';
<tr class="bg-info" >
<td>
'.$name.'
</td>
<td>
Chiave esterna non prevista
</td>
</tr>';
}
echo '
</tbody>
</table>';
</tbody>
</table>';
}
}
}
}
if (!empty($results_settings)) {
if ($results_settings) {
echo '
<table class="table table-bordered">
<thead>
<h3>Problemi impostazioni</h3>
<tr>
<th>'.tr('Nome').'</th>
<th>'.tr('Valore attuale').'</th>
<th>'.tr('Valore atteso').'</th>
</tr>
</thead>
<thead>
<h3>Problemi impostazioni</h3>
<tr>
<th>'.tr('Nome').'</th>
<th>'.tr('Valore attuale').'</th>
<th>'.tr('Valore atteso').'</th>
</tr>
</thead>
<tbody>';
foreach ($results_settings as $key => $setting) {
if (!$setting['current']) {
@ -356,44 +356,45 @@ if (!empty($results) || !empty($results_added) || !empty($results_settings) || !
$class = 'warning';
}
echo '
<tr class="bg-'.$class.'" >
<td>
'.$key.'
</td>
<td>
'.($setting['current'] ?: '⚠️ Impostazione mancante').'
</td>
<td>
'.$setting['expected'].'
</td>
</tr>';
<tr class="bg-'.$class.'" >
<td>
'.$key.'
</td>
<td>
'.($setting['current'] ?: '⚠️ Impostazione mancante').'
</td>
<td>
'.$setting['expected'].'
</td>
</tr>';
}
echo '
</tbody>
</table>';
}
if (!empty($results_settings_added)) {
if ($results_settings_added) {
echo '
<table class="table table-bordered">
<thead>
<h3>Impostazioni non previste</h3>
<tr>
<th>'.tr('Nome').'</th>
<th>'.tr('Valore attuale').'</th>
</tr>
</thead>
<thead>
<h3>Impostazioni non previste</h3>
<tr>
<th>'.tr('Nome').'</th>
<th>'.tr('Valore attuale').'</th>
</tr>
</thead>
<tbody>';
foreach ($results_settings_added as $key => $setting) {
if ($setting['current'] == null) {
echo '
<tr class="bg-info" >
<td>
'.$key.'
</td>
<td>
'.$setting['expected'].'
</td>
</tr>';
<tr class="bg-info" >
<td>
'.$key.'
</td>
<td>
'.$setting['expected'].'
</td>
</tr>';
}
}
echo '
@ -403,6 +404,6 @@ if (!empty($results) || !empty($results_added) || !empty($results_settings) || !
} else {
echo '
<div class="alert alert-info">
<i class="fa fa-info-circle"></i> '.tr('Il database non presenta problemi di integrità').'.
<i class="fa fa-info-circle"></i> '.tr('Il database non presenta problemi di integrità').'.
</div>';
}

View File

@ -393,8 +393,10 @@ switch ($resource) {
$where[] = '`idanagrafica`='.prepare($id_azienda);
// filtro in base alle sedi abilitate all'anagrafica
$filter[] = '`id` IN('.implode(',', $user->sedi).')';
// filtro in base alle sedi abilitate dell'utente
if ($user->gruppo != 'Amministratori') {
$filter[] = '`id` IN('.implode(',', $user->sedi).')';
}
if (!empty($search)) {
$search_fields[] = '`nomesede` LIKE '.prepare('%'.$search.'%');

View File

@ -20,9 +20,7 @@
namespace Modules\Anagrafiche;
use Common\SimpleModelTrait;
use Geocoder\Provider\GoogleMaps;
use Illuminate\Database\Eloquent\Model;
use Ivory\HttpAdapter\CurlHttpAdapter;
class Sede extends Model
{
@ -120,17 +118,17 @@ class Sede extends Model
$this->lat = $data[0]->lat;
$this->lng = $data[0]->lon;
} elseif (setting('Gestore mappa') == 'Google Maps') {
$curl = new CurlHttpAdapter();
$geocoder = new GoogleMaps($curl, 'IT-it', null, true, $google);
$apiKey = setting('Google Maps API key per Tecnici');
$url = 'https://maps.googleapis.com/maps/api/geocode/json?address='.$indirizzo.'&key='.$apiKey;
// Ricerca indirizzo
$address = $geocoder->geocode($indirizzo)->first();
$coordinates = $address->getCoordinates();
$response = file_get_contents($url);
$data = json_decode($response, true);
// Salvataggio informazioni
$this->gaddress = $data[0]->display_name;
$this->lat = $coordinates->getLatitude();
$this->lng = $coordinates->getLongitude();
if ($data['status'] == 'OK') {
$this->lat = $data['results'][0]['geometry']['location']['lat'];
$this->lng = $data['results'][0]['geometry']['location']['lng'];
$this->gaddress = $data['results'][0]['formatted_address'];
}
}
}
}

View File

@ -36,14 +36,23 @@ echo '
</div>
<div class="col-md-9">';
// Articolo
if ($articolo->marchio) {
echo '
<p class="float-right"><i class="fa fa-tag"></i>
'.$articolo->marchio->link ? '<a href="'.$articolo->marchio->link.'" target="_blank" rel="noopener noreferrer"> '.$articolo->marchio->name.'</a>' : $articolo->marchio->name.'
</p>';
}
if ($articolo->id_categoria) {
echo '
<p class="text-muted">'.$articolo->categoria->getTranslation('title').
($articolo->sottocategoria ? ' <small><i class="fa fa-chevron-right"></i></small> '.$articolo->sottocategoria->getTranslation('title') : '').
'</p>';
}
echo '
'.($articolo->id_categoria ? '<p class="text-muted"> '.$articolo->categoria->getTranslation('title') : '').($articolo->id_sottocategoria ? ' <small><i class="fa fa-chevron-right"></i></small> '.$articolo->sottocategoria->getTranslation('title') : '').'</p>
<h4><b>'.$articolo->getTranslation('title').'</b> '.($articolo->attivo ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i> ').'</h4>
<p><h4><b>'.$articolo->getTranslation('title').'</b> '.($articolo->attivo ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i> ').'</h4></p>
<p><b>'.$articolo->codice.'</b> '.($articolo->barcode ? ' - <i class="fa fa-barcode"></i> '.$articolo->barcode.'</p>' : '').'</p>
'.($articolo->note ? '<p class="text-danger"><i class="fa fa-pencil-square-o"></i> '.$articolo->note.'</p>' : '').'
</div>
</div>
</div>
@ -81,12 +90,14 @@ if ($articolo->servizio) {
</thead>
<tbody>';
foreach ($sedi as $sede) {
echo '
if ($giacenze[$sede['id']][0] != 0) {
echo '
<tr class="'.($giacenze[$sede['id']][0] < $articolo->threshold_qta ? 'text-danger' : '').'">
<td>'.$sede['nomesede'].'</td>
<td class="text-right">'.numberFormat($giacenze[$sede['id']][0], 'qta').' '.$articolo->um.'</td>
'.($articolo->fattore_um_secondaria != 0 ? '<td class="text-right"><i class="fa fa-chevron-right pull-left"></i> '.$giacenze[$sede['id']][0] * $articolo->fattore_um_secondaria.' '.$articolo->um_secondaria.'</td>' : '').'
</tr>';
}
}
echo '
</tbody>

View File

@ -23,10 +23,12 @@ use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Models\Module;
use Models\Plugin;
use Modules\AttributiCombinazioni\ValoreAttributo;
use Modules\CombinazioniArticoli\Combinazione;
use Modules\Interventi\Components\Articolo as ArticoloIntervento;
use Modules\Iva\Aliquota;
use Modules\Preventivi\Components\Articolo as ArticoloPreventivo;
use Plugins\ListinoFornitori\DettaglioFornitore;
use Traits\RecordTrait;
@ -82,6 +84,42 @@ class Articolo extends Model
$this->save();
}
if (Plugin::where('name', 'Distinta base')->first()->id) {
$descrizione_ricorsivo = '';
if (!empty($array['reference_type']) && !empty($array['reference_id'])) {
$object = new $array['reference_type']();
$document = $object::find($array['reference_id']);
$dir = $document->direzione;
}
if (!$this->componenti->isEmpty() && setting('Produci articoli della distinta base in fase di vendita') && $manuale == false && $dir == 'entrata' && $descrizone != "tr('Produzione articolo')" && $descrizone != "tr('Scomposizione articolo')") {
if ($qta < 0) {
$descrizione_ricorsivo = tr('Produzione articolo');
} else {
$descrizione_ricorsivo = tr('Scomposizione articolo');
}
$this->movimenta(-$qta, $descrizione_ricorsivo, $data, false);
$this->movimentaRicorsivo($qta, $descrizione_ricorsivo);
}
if (!$this->componenti->isEmpty() && setting('Scomponi articolo padre in fase di acquisto') && $manuale == false && $dir == 'uscita' && $descrizone != "tr('Produzione articolo')" && $descrizone != "tr('Scomposizione articolo')") {
if ($qta < 0) {
$descrizione_ricorsivo = tr('Produzione articolo');
} else {
$descrizione_ricorsivo = tr('Scomposizione articolo');
}
$this->movimenta(-$qta, $descrizione_ricorsivo, $data, false);
$this->movimentaRicorsivo($qta, $descrizione_ricorsivo);
}
if (!$this->componenti->isEmpty() && setting('Movimenta gli articoli figlio tramite i movimenti manuali') && $manuale) {
if ($qta < 0) {
$descrizione_ricorsivo = tr('Produzione articolo');
} else {
$descrizione_ricorsivo = tr('Scomposizione articolo');
}
$this->movimenta(-$qta, $descrizione_ricorsivo, $data, false);
$this->movimentaRicorsivo($qta, $descrizione_ricorsivo);
}
}
return $id;
}
@ -346,4 +384,123 @@ class Articolo extends Model
{
return self::$translated_fields;
}
/**
* @version distinta_base
*/
public function componenti()
{
return $this->belongsToMany(Articolo::class, 'mg_articoli_distinte', 'id_articolo', 'id_figlio')->withPivot('qta');
}
public function parti()
{
return $this->belongsToMany(Articolo::class, 'mg_articoli_distinte', 'id_figlio', 'id_articolo')->withPivot('qta');
}
/**
* @version distinta_base
*/
public function triggerChange(Articolo $trigger)
{
if ($this->sincronizza_prezzo_vendita) {
$this->prezzo_vendita = $this->totale_vendita;
}
if ($this->sincronizza_prezzo_acquisto) {
$this->prezzo_acquisto = $this->totale_acquisto;
}
$this->save();
}
/**
* @version distinta_base
*/
public function save(array $attributes = [])
{
if (Plugin::where('name', 'Distinta base')->first()->id) {
// Supporto al plugin Fornitori (prodotto per il coefficiente relativo)
if (!$this->componenti->isEmpty()) {
if ($this->sincronizza_prezzo_vendita) {
$this->prezzo_vendita = $this->totale_vendita;
}
if ($this->sincronizza_prezzo_acquisto) {
$this->prezzo_acquisto = $this->totale_acquisto;
}
}
$result = parent::save($attributes);
$parti = $this->parti;
foreach ($parti as $parte) {
$parte->pivot->qta = 1; // Fix per le quantità inverse
$parte->triggerChange($this);
}
return $result;
} else {
return parent::save($attributes);
}
}
/**
* Funzione per inserire i movimenti di magazzino.
*
* @version distinta_base
*
* @param null $descrizone
* @param null $data
* @param bool $manuale
* @param array $array
*
* @return bool
*/
public function movimentaRicorsivo($qta, $descrizone = null, $data = null, $manuale = false, $array = [])
{
$componenti = $this->componenti;
$suffix = ' (di.ba.)';
$descrizone = str_contains((string) $descrizone, $suffix) ? $descrizone : $descrizone.$suffix;
foreach ($componenti as $componente) {
$qta_componente = $qta * $componente->pivot->qta;
$componente->movimenta($qta_componente, $descrizone, $data, $manuale, $array);
}
}
public function getTotaleAcquistoAttribute()
{
$componenti = $this->componenti;
$prezzo_acquisto = 0;
foreach ($componenti as $componente) {
$prezzo_acquisto += $componente->prezzo_acquisto * $componente->pivot->qta;
}
return $prezzo_acquisto;
}
public function getTotaleVenditaAttribute()
{
$componenti = $this->componenti;
$prezzo_vendita = 0;
foreach ($componenti as $componente) {
$prezzo_vendita += $componente->prezzo_vendita * $componente->pivot->qta;
}
return $prezzo_vendita;
}
/**
* @version distinta_base
*/
public function componenti_preventivo($idrigapreventivo = null)
{
return database()->select('mg_articoli_distinte_preventivi', ['id_figlio', 'qta', 'prezzo_acquisto', 'prezzo_vendita', 'sconto', 'tipo_sconto'], [
'idrigapreventivo' => $idrigapreventivo,
'id_articolo' => $this->id,
]);
}
public function triggerChangePreventivo($idrigapreventivo)
{
$riga = ArticoloPreventivo::find($idrigapreventivo);
$riga->costo_unitario = $riga->totale_acquisto ?: 0;
$riga->setPrezzoUnitario($riga->totale_vendita, $riga->idiva);
$riga->save();
}
}

View File

@ -392,8 +392,7 @@ class IBAN
$this->nation = $nation = substr($iban, 0, 2);
$info = self::$countries[$nation];
$structure = $info['structure'];
$structure = str_replace(' ', '', $structure);
$structure = $info['structure'] ? str_replace(' ', '', $info['structure']) : '';
$regex = $nation;
$keys = array_keys(self::$parsers);

View File

@ -481,6 +481,7 @@ $(document).ready(function() {
$("#barcode").focus();
caricaRighe(null);
content_was_modified = false;
});
$("#idanagrafica_c").change(function() {

View File

@ -597,6 +597,7 @@ $(document).ready(function() {
});
$("#barcode").focus();
content_was_modified = false;
});
$("#idanagrafica").change(function() {

View File

@ -402,6 +402,9 @@ switch ($op) {
$new_riga->save();
}
// Forzo il salvataggio della fattura per far scattare gli automatismi legati alle righe
$new->save();
flash()->info(tr('Fattura duplicata correttamente!'));
break;

View File

@ -212,7 +212,7 @@ switch (post('op')) {
$dst = $fe->getFilename();
$src = $dbo->selectOne('zz_files', 'filename', ['original' => $dst])['filename'];
} else {
$src = basename($fattura->uploads()->where('name', 'Fattura Elettronica')->first()->filepath);
$src = basename($fattura->uploads()->where('name', 'Fattura Elettronica')->first()->filename);
$dst = basename($fattura->uploads()->where('name', 'Fattura Elettronica')->first()->original_name);
}
@ -271,7 +271,7 @@ switch (post('op')) {
foreach ($fatture as $r) {
$fattura = Fattura::find($r['id']);
$zz_file = $dbo->table('zz_files')->where('id_module', '=', $id_module)->where('id_record', '=', $fattura->id)->where('name', 'like', 'Ricevuta%')->first();
$src = basename($fattura->uploads()->where('id', $zz_file->id)->first()->filepath);
$src = basename($fattura->uploads()->where('id', $zz_file->id)->first()->filename);
$dst = basename($fattura->uploads()->where('id', $zz_file->id)->first()->original_name);
$file = slashes($module->upload_directory.'/'.$src);
@ -709,30 +709,28 @@ $operations['exportFE-bulk'] = [
'blank' => true,
],
];
$operations['export-ricevute-bulk'] = [
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta ricevute').'</span>',
'data' => [
'title' => '',
'msg' => tr('Vuoi davvero esportare le ricevute selezionate in un archivio ZIP?'),
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
'blank' => true,
],
];
$operations['export-xml-bulk'] = [
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta XML').'</span>',
'data' => [
'title' => '',
'msg' => tr('Vuoi davvero esportare le fatture elettroniche selezionate in un archivio ZIP?'),
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
'blank' => true,
],
];
if ($module->getTranslation('title') == 'Fatture di vendita') {
$operations['export-ricevute-bulk'] = [
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta ricevute').'</span>',
'data' => [
'title' => '',
'msg' => tr('Vuoi davvero esportare le ricevute selezionate in un archivio ZIP?'),
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
'blank' => true,
],
];
$operations['export-xml-bulk'] = [
'text' => '<span class="'.((!extension_loaded('zip')) ? 'text-muted disabled' : '').'"><i class="fa fa-file-archive-o"></i> '.tr('Esporta XML').'</span>',
'data' => [
'title' => '',
'msg' => tr('Vuoi davvero esportare le fatture elettroniche selezionate in un archivio ZIP?'),
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
'blank' => true,
],
];
$operations['genera-xml'] = [
'text' => '<span><i class="fa fa-file-code-o"></i> '.tr('Genera fatture elettroniche').'</span>',
'data' => [

View File

@ -1215,6 +1215,8 @@ if ($dir == 'entrata') {
});
bolloAutomatico();
content_was_modified = false;
});
input("bollo_automatico").change(function () {
bolloAutomatico();

View File

@ -98,6 +98,7 @@ class Bollo
$riga->descrizione = setting('Descrizione addebito bollo');
$riga->id_iva = $righe_bollo->idiva ?: database()->fetchOne('SELECT `id` FROM `co_iva` WHERE `name` = "Escluso art. 15"')['id'];
$riga->idconto = setting('Conto predefinito per la marca da bollo');
$riga->iddocumento = $this->fattura->id ?: 0;
// Applico la rivalsa alla marca da bollo se previsto
if ((setting('Regime Fiscale') == 'RF19') && (!empty(setting('Cassa previdenziale predefinita')))) {

View File

@ -566,6 +566,7 @@ echo '
});
$("#barcode").focus();
content_was_modified = false;
});
var anagrafica = input("idanagrafica");

View File

@ -133,7 +133,7 @@ echo '
echo Modules::link('Pagamenti', $record['idpagamento'], null, null, 'class="pull-right"');
}
?>
{[ "type": "select", "label": "<?php echo tr('Pagamento'); ?>", "name": "idpagamento", "values": "query=SELECT `co_pagamenti`.`id`, `title` AS descrizione FROM `co_pagamenti` LEFT JOIN `co_pagamenti_lang` ON (`co_pagamenti`.`id` = `co_pagamenti_lang`.`id_record` AND `co_pagamenti_lang`.`id_lang` = <?php echo prepare(Models\Locale::getDefault()->id); ?>) GROUP BY `title` ORDER BY `title`", "value": "$idpagamento$" ]}
{[ "type": "select", "label": "<?php echo tr('Pagamento'); ?>", "name": "idpagamento", "ajax-source": "pagamenti", "value": "$idpagamento$" ]}
</div>
<div class="col-md-2">
@ -413,6 +413,7 @@ $(document).ready(function() {
});
$("#barcode").focus();
content_was_modified = false;
});
async function salvaArticolo() {

View File

@ -355,7 +355,7 @@ echo '
</div>';
// Numero interventi per tipologia
$tipi = $dbo->fetchArray('SELECT * FROM `in_tipiintervento` LEFT JOIN `in_tipiintervento_lang` ON (`in_tipiintervento`.`id` = `in_tipiintervento_lang`.`id_record` AND `in_tipiintervento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).')');
$tipi = $dbo->fetchArray('SELECT *, in_tipiintervento.id AS idtipointervento FROM `in_tipiintervento` LEFT JOIN `in_tipiintervento_lang` ON (`in_tipiintervento`.`id` = `in_tipiintervento_lang`.`id_record` AND `in_tipiintervento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).')');
$dataset = '';
foreach ($tipi as $tipo) {
@ -368,7 +368,7 @@ foreach ($tipi as $tipo) {
`in_interventi`
LEFT JOIN(SELECT `in_interventi_tecnici`.`idintervento`, MAX(`orario_fine`) AS orario_fine FROM `in_interventi_tecnici` GROUP BY `idintervento`) sessioni ON `in_interventi`.`id` = `sessioni`.`idintervento`
WHERE
`in_interventi`.`idtipointervento` = '.prepare($tipo['id']).'
`in_interventi`.`idtipointervento` = '.prepare($tipo['idtipointervento']).'
AND `sessioni`.`orario_fine` BETWEEN '.prepare($start).' AND '.prepare($end).'
GROUP BY
YEAR(`sessioni`.`orario_fine`),
@ -431,7 +431,7 @@ $(document).ready(function() {
// Ore interventi per tipologia
$dataset = '';
foreach ($tipi as $tipo) {
$interventi = $dbo->fetchArray('SELECT ROUND(SUM(in_interventi_tecnici.ore), 2) AS result, YEAR(in_interventi_tecnici.orario_fine) AS year, MONTH(in_interventi_tecnici.orario_fine) AS month FROM in_interventi INNER JOIN in_interventi_tecnici ON in_interventi.id=in_interventi_tecnici.idintervento WHERE in_interventi.idtipointervento = '.prepare($tipo['id']).' AND in_interventi.data_richiesta BETWEEN '.prepare($start).' AND '.prepare($end).' AND in_interventi_tecnici.orario_fine BETWEEN '.prepare($start).' AND '.prepare($end).' GROUP BY YEAR(in_interventi_tecnici.orario_fine), MONTH(in_interventi_tecnici.orario_fine) ORDER BY YEAR(in_interventi_tecnici.orario_fine) ASC, MONTH(in_interventi_tecnici.orario_fine) ASC');
$interventi = $dbo->fetchArray('SELECT ROUND(SUM(in_interventi_tecnici.ore), 2) AS result, YEAR(in_interventi_tecnici.orario_fine) AS year, MONTH(in_interventi_tecnici.orario_fine) AS month FROM in_interventi INNER JOIN in_interventi_tecnici ON in_interventi.id=in_interventi_tecnici.idintervento WHERE in_interventi.idtipointervento = '.prepare($tipo['idtipointervento']).' AND in_interventi.data_richiesta BETWEEN '.prepare($start).' AND '.prepare($end).' AND in_interventi_tecnici.orario_fine BETWEEN '.prepare($start).' AND '.prepare($end).' GROUP BY YEAR(in_interventi_tecnici.orario_fine), MONTH(in_interventi_tecnici.orario_fine) ORDER BY YEAR(in_interventi_tecnici.orario_fine) ASC, MONTH(in_interventi_tecnici.orario_fine) ASC');
$interventi = Stats::monthly($interventi, $start, $end);
@ -791,7 +791,11 @@ $(".shorten").shorten({
});
$("#idtipiintervento").change(function(){
let idtipi = JSON.stringify($(this).val());
let tipi = "";
if( $(this).val() ){
idtipi = JSON.stringify($(this).val());
}
session_set("superselect,idtipiintervento",idtipi,0);
location.reload();
});

View File

@ -1162,7 +1162,7 @@ class FatturaElettronica implements \Stringable
if (!empty($element['riferimento_linea']['id'])) {
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea']['id'];
} elseif (!empty($element['riferimento_linea'])) {
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'];
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'][0];
}
$dati['IdDocumento'] = $element['id_documento'];
@ -1666,7 +1666,7 @@ class FatturaElettronica implements \Stringable
$co_scadenziario = $database->fetchArray('SELECT * FROM `co_scadenziario` WHERE `iddocumento` = '.prepare($documento['id']));
foreach ($co_scadenziario as $scadenza) {
$co_pagamenti = Pagamento::find($scadenza['id_pagamento']);
$banca = ($co_pagamenti && $co_pagamenti->isRiBa()) ? Banca::find($scadenza['id_banca_controparte']) : ($scadenza['id_banca_azienda'] ?? Banca::where('id_anagrafica', $scadenza['idanagrafica'])->where('predefined', 1)->first());
$banca = Banca::find(($co_pagamenti && $co_pagamenti->isRiBa()) ? $scadenza['id_banca_controparte'] : ($scadenza['id_banca_azienda'])) ?? Banca::where('id_anagrafica', $scadenza['idanagrafica'])->where('predefined', 1)->first();
$pagamento = [
'ModalitaPagamento' => $co_pagamenti['codice_modalita_pagamento_fe'],
'DataScadenzaPagamento' => $scadenza['scadenza'],

View File

@ -314,7 +314,7 @@ class FatturaOrdinaria extends FatturaElettronica
[$riferimento_precedente, $nuovo_riferimento] = $obj->impostaOrigine($riga_origine);
// Correzione della descrizione
$obj->descrizione = str_replace($riferimento_precedente, '', $obj->descrizione);
$obj->descrizione = $riferimento_precedente ? str_replace($riferimento_precedente, '', $obj->descrizione) : '';
$obj->descrizione .= $nuovo_riferimento;
$serials_rif = $riga_origine->serials;

View File

@ -95,8 +95,9 @@ class RiBa
if ($intestazione->soggetto_veicolatore != '') {
$ib->tipo_flusso = 1;
$ib->qualificatore_flusso = '$';
$ib->soggetto_veicolatore = $intestazione->soggetto_veicolatore;
}
$ib->soggetto_veicolatore = $intestazione->soggetto_veicolatore;
$contenuto .= $ib->toCBI().$eol;
// Iterazione tra le ricevute interne al RiBa
@ -154,7 +155,7 @@ class RiBa
$r50->numero_progressivo = $progressivo;
$r50->partita_iva_o_codice_fiscale_creditore = $intestazione->partita_iva_o_codice_fiscale_creditore;
$r50->riferimento_debito_1 = $ricevuta->descrizione;
$r50->riferimento_debito_2 = $ricevuta->descrizione_origine;
$r50->riferimento_debito_2 = $ricevuta->descrizione_origine ?: '';
$contenuto .= $r50->toCBI().$eol;
// Record 51

View File

@ -172,7 +172,7 @@ class Gestore
if (in_array($pagamento->codice_modalita_pagamento_fe, ['MP19', 'MP21'])) {
$method = 'B2B';
} elseif (in_array($pagamento->codice_modalita_pagamento_fe, ['MP20'])) {
} elseif (in_array($pagamento->codice_modalita_pagamento_fe, ['MP20', 'MP09'])) {
$method = 'CORE';
}
@ -191,7 +191,7 @@ class Gestore
return false;
}
public function aggiungiRiBa(int $identifier, Anagrafica $controparte, Banca $banca_controparte, string $descrizione, int $totale, \DateTime $data_prevista)
public function aggiungiRiBa(int $identifier, Anagrafica $controparte, Banca $banca_controparte, string $descrizione, float $totale, \DateTime $data_prevista)
{
$data_scadenza = $data_prevista->format('dmy');

View File

@ -49,7 +49,7 @@ class Articoli extends AppResource
`mg_articoli`.`id` AS id,
`mg_articoli`.`codice`,
`mg_articoli`.`barcode`,
`mg_articoli_lang`.`title`,
`mg_articoli_lang`.`title` AS descrizione,
`mg_articoli`.`prezzo_vendita`,
`mg_articoli`.`prezzo_acquisto`,
`mg_articoli`.`qta`,

View File

@ -28,7 +28,6 @@ class Impianti extends AppResource
{
public function getCleanupData($last_sync_at)
{
// TODO: modificare introducendo deleted_at su my_impianti
return database()
->table('zz_operations')
->select('zz_operations.id_record')

View File

@ -29,7 +29,6 @@ class SessioniInterventi extends AppResource
{
public function getCleanupData($last_sync_at)
{
// TODO: modificare introducendo deleted_at su sessioni
return database()
->table('zz_operations')
->select('zz_operations.id_record')

View File

@ -29,13 +29,22 @@ class Upload extends Model
{
use SimpleModelTrait;
/** @var array Elenco delle estensioni file per mime type */
/**
* Elenco delle estensioni file per mime type.
* Fonte: https://www.iana.org/assignments/media-types/media-types.xhtml.
*
* @var array
*/
protected static $extension_association = [
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/jpg' => 'jpg',
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/heic' => 'heic',
'image/webp' => 'webp',
'image/svg+xml' => 'svg',
'image/tiff' => 'tiff',
];
protected $table = 'zz_files';

View File

@ -40,19 +40,20 @@ class Autofill
public function setRows($rows, $additional = null, $first_page = null)
{
$this->max_rows = $rows;
$this->max_additional = $additional ?: $this->max_rows;
$this->max_additional = $additional ?? $this->max_rows;
$this->max_rows_first_page = $first_page ?? $this->max_rows_first_page;
}
public function count($text, $small = false)
public function count($text, $small = null)
{
$count = ceil(strlen((string) $text) / $this->char_number);
// Ricerca dei caratteri a capo
preg_match_all("/(\r\n|\r|\n)/", (string) $text, $matches);
// Ricerca dei caratteri a capo e <br>
preg_match_all("/(\r\n|\r|\n|<br\s*\/?>)/", (string) $text, $matches);
$count += count($matches[0]);
$count = ($count == 1 ? $count : $count / 1.538461538);
if ($small || $count != 1) {
$count /= 1.538461538;
}
$this->set($count);
}
@ -83,12 +84,12 @@ class Autofill
if ($page > 1) {
$rows = $this->space - $this->max_rows_first_page * ($page - 1);
} else {
$rows = floor($this->space);
$rows = ceil($this->space);
}
$number = $this->max_additional - $rows;
$number = $this->max_rows - $rows;
return $number > 0 ? $number : 0;
return $number;
}
public function generate()

View File

@ -192,7 +192,7 @@ if ($utile_perdita < 0) {
</tr>
<tr>
<td colspan="2"><h6><b>Totale a pareggio</b></h6></td>
<td class="text-right" style="font-size:8pt;"><b>'.numberFormat(abs($totale_passivita) + abs($utile_perdita), 2).'</b></td>
<td class="text-right" style="font-size:8pt;"><b>'.($totale_passivita ? numberFormat(abs($totale_passivita), 2) : '').'</b></td>
</tr>';
}
echo '

View File

@ -22,12 +22,9 @@ include_once __DIR__.'/../../core.php';
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
// Creazione righe fantasma
$autofill = new Util\Autofill($options['pricing'] ? 6 : 3);
$rows_per_page = $rows_per_page ?: 18;
if (!empty($options['last-page-footer'])) {
$rows_per_page += 10;
}
$autofill->setRows($rows_per_page);
$autofill = new Util\Autofill($options['pricing'] ? 6 : 3, 70);
$rows_per_page = $options['pricing'] ? 20 : 18;
$autofill->setRows($rows_per_page, 0, $options['pricing'] ? 20 : 18);
// Intestazione tabella per righe
echo "
@ -78,8 +75,6 @@ foreach ($righe as $riga) {
++$num;
$r = $riga->toArray();
$autofill->count($r['descrizione']);
echo '
<tr>
<td class="text-center" style="vertical-align: middle">';
@ -112,26 +107,22 @@ foreach ($righe as $riga) {
<td>
'.nl2br($text);
$autofill->count($text);
}
}
$r['descrizione'] = preg_replace("/Rif\.(.*)/s", '', (string) $r['descrizione']);
$autofill->count($r['descrizione']);
}
$source_type = $riga::class;
$autofill->count($r['descrizione']);
if (!setting('Visualizza riferimento su ogni riga in stampa')) {
echo $num.'
</td>
<td>'.$r['descrizione'];
} else {
echo $num.'
</td>
<td>'.nl2br((string) $r['descrizione']);
}
echo $num.'
</td>
<td>'.nl2br((string) $r['descrizione']);
if ($riga->isArticolo()) {
echo '<br><small>'.$riga->codice.'</small>';
$autofill->count($riga->codice);
} else {
echo '-';
}

View File

@ -102,6 +102,15 @@ echo '
<td class="text-right">
<small>$c_codicefiscale$</small>
</td>
</tr>
<tr>
<td class="border-bottom">
<p class="small-bold text-muted">'.tr('Partenza merce', [], ['upper' => true]).'</p>
</td>
<td class="border-bottom text-right">
<p><small>'.$partenza.'</small></p>
</td>
</tr>';
if (!empty($destinazione)) {

View File

@ -26,7 +26,7 @@ $prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
// Creazione righe fantasma
$autofill = new Util\Autofill(6, 70);
$rows_per_page = $rows_per_page ?: ($fattura_accompagnatoria ? 13 : 26);
$rows_per_page = $rows_per_page ?: ($fattura_accompagnatoria ? 24 : 26);
$autofill->setRows($rows_per_page, 0);
// Intestazione tabella per righe
@ -77,8 +77,6 @@ foreach ($righe as $riga) {
++$num;
$r = $riga->toArray();
$autofill->count($r['descrizione']);
$v_iva[$r['desc_iva']] = sum($v_iva[$r['desc_iva']], $riga->iva);
$v_totale[$r['desc_iva']] = sum($v_totale[$r['desc_iva']], $riga->totale_imponibile);
@ -97,11 +95,11 @@ foreach ($righe as $riga) {
$text = $text.'<b>Ordine n. '.$riga_ordine['numero_cliente'].' del '.Translator::dateToLocale($riga_ordine['data_cliente']).'</b><br>';
}
}
$r['descrizione'] = str_replace('Rif. '.strtolower((string) $key), '', $r['descrizione']);
$r['descrizione'] = str_replace("\nRif. ".strtolower((string) $key), '', $r['descrizione']);
if (preg_match("/Rif\.(.*)/s", $r['descrizione'], $rif2)) {
$r['descrizione'] = str_replace('Rif.'.strtolower($rif2[1] ?: ''), '', $r['descrizione']);
$text .= '<b>'.$rif2[0].'</b>';
$r['descrizione'] = str_replace('\nRif.'.strtolower($rif2[1] ?: ''), '', $r['descrizione']);
$text .= '<b>'.$rif2[0].'</b><br>';
}
$text .= '<b>'.$key.'</b></td><td></td><td></td><td></td><td></td></tr><tr><td class="text-center" nowrap="nowrap" style="vertical-align: middle">';
@ -111,25 +109,22 @@ foreach ($righe as $riga) {
<td>
'.nl2br($text);
$autofill->count($text);
}
}
$r['descrizione'] = preg_replace("/Rif\.(.*)/s", ' ', (string) $r['descrizione']);
$autofill->count($r['descrizione']);
$r['descrizione'] = preg_replace("/(\r\n|\r|\n)Rif\.(.*)/s", '', (string) $r['descrizione']);
}
$source_type = $riga::class;
if (setting('Visualizza riferimento su ogni riga in stampa')) {
echo $num.'
</td>
<td>'.nl2br((string) $r['descrizione']).'<br>';
} else {
echo $num.'
</td>
<td>'.nl2br((string) $r['descrizione']);
}
$autofill->count($r['descrizione']);
echo $num.'
</td>
<td>'.nl2br((string) $r['descrizione']);
if ($riga->isArticolo()) {
echo '<small>'.$riga->codice.'</small>';
echo '<small><br>'.$riga->codice.'</small>';
$autofill->count($riga->codice, true);
}
if ($riga->isArticolo()) {
@ -217,6 +212,10 @@ foreach ($righe as $riga) {
$autofill->next();
}
foreach ($v_iva as $desc_iva => $tot_iva) {
$autofill->count($desc_iva, true);
}
echo '
|autofill|
</tbody>
@ -252,7 +251,8 @@ echo '
if (!empty($record['note'])) {
echo '
<p class="small-bold text-muted">'.tr('Note', [], ['upper' => true]).':</p>
<p>'.nl2br((string) $record['note']).'</p>';
<p><small>'.nl2br((string) $record['note']).'</small></p>';
$autofill->count($record['note'], true);
}
echo '

View File

@ -49,20 +49,17 @@ $has_image = $righe->search(fn ($item) => !empty($item->articolo->immagine)) !==
if ($has_image) {
++$columns;
$char_number = $options['pricing'] ? 26 : 63;
}
if ($documento->direzione == 'uscita') {
$columns += 2;
$char_number = $options['pricing'] ? 26 : 63;
} else {
$char_number = $options['pricing'] ? 45 : 82;
}
$columns = $options['pricing'] ? $columns : $columns - 3;
// Creazione righe fantasma
$autofill = new Util\Autofill($columns);
$autofill->setRows(20, 10);
$autofill->setRows(27, 0, 32);
// Intestazione tabella per righe
echo "
@ -107,8 +104,6 @@ foreach ($righe as $riga) {
++$num;
$r = $riga->toArray();
$autofill->count($r['descrizione']);
echo '
<tr>
<td class="text-center" style="vertical-align: middle">';
@ -122,11 +117,11 @@ foreach ($righe as $riga) {
if (!empty($riga_ordine['numero_cliente']) && !empty($riga_ordine['data_cliente'])) {
$text = $text.'<b>Ordine n. '.$riga_ordine['numero_cliente'].' del '.Translator::dateToLocale($riga_ordine['data_cliente']).'</b><br>';
}
$r['descrizione'] = str_replace('Rif. '.strtolower((string) $key), '', $r['descrizione']);
$r['descrizione'] = str_replace("\nRif. ".strtolower((string) $key), '', $r['descrizione']);
if (preg_match("/Rif\.(.*)/s", $r['descrizione'], $rif2)) {
$r['descrizione'] = str_replace('Rif.'.strtolower($rif2[1] ?: ''), '', $r['descrizione']);
$text .= '<b>'.$rif2[0].'</b>';
$r['descrizione'] = str_replace('\nRif.'.strtolower($rif2[1] ?: ''), '', $r['descrizione']);
$text .= '<b>'.$rif2[0].'</b><br>';
}
$text .= '<b>'.$key.'</b></td>';
@ -149,46 +144,31 @@ foreach ($righe as $riga) {
echo '
<td>
'.nl2br($text);
$autofill->count($text);
}
}
$r['descrizione'] = preg_replace("/Rif\.(.*)/s", '', (string) $r['descrizione']);
$autofill->count($r['descrizione']);
$r['descrizione'] = preg_replace("/(\r\n|\r|\n)Rif\.(.*)/s", '', (string) $r['descrizione']);
}
$source_type = $riga::class;
if (!setting('Visualizza riferimento su ogni riga in stampa')) {
echo $num.'</td>';
if ($has_image) {
if ($riga->isArticolo() && !empty($riga->articolo->image)) {
echo '
<td align="center">
<img src="'.$riga->articolo->image.'" style="max-height: 80px; max-width:120px">
</td>';
} else {
echo '
<td></td>';
}
}
echo '
<td>'.$r['descrizione'];
} else {
echo $num.'
$autofill->count($r['descrizione']);
echo $num.'</td>';
if ($has_image) {
if ($riga->isArticolo() && !empty($riga->articolo->image)) {
echo '
<td align="center">
<img src="'.$riga->articolo->image.'" style="max-height: 80px; max-width:120px">
</td>';
if ($has_image) {
if ($riga->isArticolo() && !empty($riga->articolo->image)) {
echo '
<td align="center">
<img src="'.$riga->articolo->image.'" style="max-height: 80px; max-width:120px">
</td>';
} else {
echo '
<td></td>';
}
} else {
echo '
<td></td>';
}
echo '
<td>'.nl2br((string) $r['descrizione']);
}
echo '
<td>'.nl2br((string) $r['descrizione']);
if ($documento->direzione == 'uscita') {
echo '
<td class="text-center" style="vertical-align: middle">
@ -282,6 +262,7 @@ foreach ($righe as $riga) {
echo '
<td></td>
<td></td>
<td></td>
<td></td>';
}
}
@ -410,5 +391,5 @@ if (!empty($documento['note'])) {
echo '
<br>
<p class="small-bold text-muted">'.tr('Note', [], ['upper' => true]).':</p>
<p>'.nl2br((string) $documento['note']).'</p>';
<p><small>'.nl2br((string) $documento['note']).'</small></p>';
}

View File

@ -60,6 +60,30 @@ echo '
</td>
</tr>
</table>
<table class="table table-striped border-bottom">
<tr>
<td class="small-bold text-muted" style="width:33%">
'.tr('Porto', [], ['upper' => true]).'
</td>
<td class="small-bold text-muted" style="width:33%">
'.tr('Tipo di spedizione', [], ['upper' => true]).'
</td>
<td class="small-bold text-muted" style="width:33%">
'.tr('Vettore', [], ['upper' => true]).'
</td>
</tr>
<tr>
<td class="cell-padded">
$porto$ &nbsp;
</td>
<td class="cell-padded">
$spedizione$ &nbsp;
</td>
<td class="cell-padded">
$vettore$ &nbsp;
</td>
</tr>
</table>
</div>
<!-- Dati Cliente/Fornitore -->

View File

@ -65,7 +65,7 @@ if ($has_image) {
// Creazione righe fantasma
$autofill = new Util\Autofill($columns);
$autofill->setRows(20, 10);
$autofill->setRows(22, 0, 36);
echo '
<div class="col-xs-5">

View File

@ -29,7 +29,6 @@ delete($files);
* in quanto veniva calcolato lo sconto ivato erroneamente.
*/
// TODO: aggiornare procedura con query SQL esplicite invece che con i metodi che possono cambiare nel tempo
// Fix sconti contratti
$righe = $dbo->fetchArray('SELECT id, idiva, sconto_percentuale, sconto_unitario, tipo_sconto, prezzo_unitario FROM co_righe_contratti WHERE sconto_percentuale != 0 AND tipo_sconto="PRC"');

23
update/2_5_7.php Normal file
View File

@ -0,0 +1,23 @@
<?php
use Modules\Fatture\Fattura;
include_once __DIR__.'/core.php';
// Fix conto per registrazione contabile associate ai conti riepilogativi
$riepilogativo_fornitori = $dbo->fetchOne('SELECT id FROM co_pianodeiconti3 WHERE descrizione = "Riepilogativo fornitori"')['id'];
$riepilogativo_clienti = $dbo->fetchOne('SELECT id FROM co_pianodeiconti3 WHERE descrizione = "Riepilogativo clienti"')['id'];
$fatture = $dbo->fetchArray('SELECT iddocumento FROM `co_movimenti` WHERE `idconto` IN('.$riepilogativo_clienti.', '.$riepilogativo_fornitori.')');
foreach ($fatture as $fattura) {
$fattura = Fattura::find($fattura['iddocumento']);
$conto_cliente = $fattura->anagrafica->idconto_cliente;
$conto_fornitore = $fattura->anagrafica->idconto_fornitore;
if ($conto_fornitore) {
$dbo->query('UPDATE co_movimenti SET idconto = '.$conto_fornitore.' WHERE iddocumento = '.$fattura->id.' AND idconto = '.$riepilogativo_fornitori);
}
if ($conto_cliente) {
$dbo->query('UPDATE co_movimenti SET idconto = '.$conto_cliente.' WHERE iddocumento = '.$fattura->id.' AND idconto = '.$riepilogativo_clienti);
}
}

2
update/2_5_7.sql Normal file
View File

@ -0,0 +1,2 @@
-- Fix filtro segmento Non completate in Attività
UPDATE `zz_segments` SET `clause` = 'in_interventi.idstatointervento NOT IN(SELECT in_statiintervento.id FROM in_statiintervento WHERE is_completato=1)' WHERE `zz_segments`.`name` = 'Non completate' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Interventi');