1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-03 09:17:37 +01:00
This commit is contained in:
MatteoPistorello 2023-11-10 16:39:18 +01:00
commit 6b9776e0a9
22 changed files with 827 additions and 85 deletions

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Geocoder\Provider\GoogleMaps;
use Ivory\HttpAdapter\CurlHttpAdapter;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Export\CSV;
@ -67,6 +69,32 @@ switch (post('op')) {
break;
case 'ricerca-coordinate-google':
$curl = new CurlHttpAdapter();
$geocoder = new GoogleMaps($curl, null, null, true, $google);
foreach ($id_records as $id) {
$anagrafica = Anagrafica::find($id);
if (empty($anagrafica->lat) && empty($anagrafica->lng) && !empty($anagrafica->sedeLegale->indirizzo) && !empty($anagrafica->sedeLegale->citta) && !empty($anagrafica->sedeLegale->cap)) {
$indirizzo = urlencode($anagrafica->sedeLegale->indirizzo.' '.$anagrafica->sedeLegale->citta.' '.$anagrafica->sedeLegale->cap);
try {
// Ricerca indirizzo
$address = $geocoder->geocode($indirizzo)->first();
$coordinates = $address->getCoordinates();
// Salvataggio informazioni
$anagrafica->lat = $coordinates->getLatitude();
$anagrafica->lng = $coordinates->getLongitude();
$anagrafica->save();
} catch (Exception $e) {
flash()->error("Impossibile recuperare le coordinate dell'anagrafica ".$anagrafica->ragione_sociale." per l'indirizzo ".$anagrafica->sedeLegale->indirizzo.' '.$anagrafica->sedeLegale->citta.' '.$anagrafica->sedeLegale->cap);
}
}
}
break;
case 'export-csv':
$file = temp_file();
$exporter = new CSV($file);
@ -125,6 +153,15 @@ if (App::debug()) {
'class' => 'btn btn-lg btn-warning',
],
];
$operations['ricerca-coordinate-google'] = [
'text' => '<span><i class="fa fa-map"></i> '.tr('Ricerca coordinate (google)').'</span>',
'data' => [
'msg' => tr('Ricercare le coordinate per le anagrafiche selezionate senza latitudine e longitudine?'),
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
],
];
}
$operations['cambia-relazione'] = [

View File

@ -460,10 +460,10 @@ class CSV extends CSVImporter
protected function aggiornaDettaglioPrezzi(Articolo $articolo, $dettagli)
{
// Listini
if ($dettagli['partita_iva']){
if ($dettagli['partita_iva']) {
$anagrafica = Anagrafica::where('piva', $dettagli['partita_iva'])->first();
}
if (empty($anagrafica)) {
$anagrafica = Anagrafica::build($dettagli['anagrafica_listino']);
$anagrafica->piva = $dettagli['partita_iva'];

View File

@ -28,43 +28,75 @@ switch (filter('op')) {
$nome = filter('nome');
$nota = filter('nota');
$colore = filter('colore');
$id_original = filter('id_original') ?: null;
if (isset($nome) && isset($nota) && isset($colore)) {
$dbo->query('UPDATE `my_impianti_categorie` SET `nome`='.prepare($nome).', `nota`='.prepare($nota).', `colore`='.prepare($colore).' WHERE `id`='.prepare($id_record));
$database->table('my_impianti_categorie')
->where('id', '=', $id_record)
->update([
'nome' => $nome,
'nota' => $nota,
'colore' => $colore,
]);
flash()->info(tr('Salvataggio completato!'));
} else {
flash()->error(tr('Ci sono stati alcuni errori durante il salvataggio!'));
}
// Redirect alla categoria se si sta modificando una sottocategoria
if ($id_original != null) {
$database->commitTransaction();
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_record='.($id_original ?: $id_record));
exit();
}
break;
case 'add':
$nome = post('nome');
$nota = post('nota');
$colore = post('colore');
$nome = filter('nome');
$nota = filter('nota');
$colore = filter('colore');
// Verifico che il nome non sia duplicato
$count = $dbo->fetchNum('SELECT `id` FROM `my_impianti_categorie` WHERE `nome`='.prepare($nome));
$id_original = filter('id_original') ?: null;
if ($count != 0) {
flash()->error(tr('Categoria _NAME_ già esistente!', [
'_NAME_' => $nome,
// Ricerca corrispondenze con stesso nome
$corrispondenze = $database->table('my_impianti_categorie')
->where('nome', '=', $nome);
if (!empty($id_original)) {
$corrispondenze = $corrispondenze->where('parent', '=', $id_original);
} else {
$corrispondenze = $corrispondenze->whereNull('parent');
}
$corrispondenze = $corrispondenze->get();
// Eventuale creazione del nuovo record
if ($corrispondenze->count() == 0) {
$id_record = $database->table('my_impianti_categorie')
->insertGetId([
'nome' => $nome,
'nota' => $nota,
'colore' => $colore,
'parent' => $id_original,
]);
flash()->info(tr('Aggiunta nuova tipologia di _TYPE_', [
'_TYPE_' => 'categoria',
]));
} else {
if (isset($nome)) {
$dbo->query('INSERT INTO `my_impianti_categorie` (`nome`, `colore`, `nota`) VALUES ('.prepare($nome).', '.prepare($colore).', '.prepare($nota).')');
$id_record = $dbo->lastInsertedID();
if (isAjaxRequest()) {
echo json_encode(['id' => $id_record, 'text' => $nome]);
}
flash()->info(tr('Aggiunta nuova tipologia di _TYPE_', [
'_TYPE_' => 'categoria',
]));
}
$id_record = $corrispondenze->first()->id;
flash()->error(tr('Esiste già una categoria con lo stesso nome!'));
}
if (isAjaxRequest()) {
echo json_encode(['id' => $id_record, 'text' => $nome]);
} else {
// Redirect alla categoria se si sta aggiungendo una sottocategoria
$database->commitTransaction();
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_record='.($id_original ?: $id_record));
exit();
}
break;
case 'delete':
@ -73,14 +105,14 @@ switch (filter('op')) {
$id = $id_record;
}
if ($dbo->fetchNum('SELECT * FROM `my_impianti` WHERE `id_categoria`='.prepare($id)) == 0) {
if ($dbo->fetchNum('SELECT * FROM `my_impianti` WHERE (`id_categoria`='.prepare($id).' OR `id_sottocategoria`='.prepare($id).' OR `id_sottocategoria` IN (SELECT id FROM `my_impianti_categorie` WHERE `parent`='.prepare($id).')) AND `deleted_at` IS NULL') == 0) {
$dbo->query('DELETE FROM `my_impianti_categorie` WHERE `id`='.prepare($id));
flash()->info(tr('Tipologia di _TYPE_ eliminata con successo!', [
flash()->info(tr('_TYPE_ eliminata con successo!', [
'_TYPE_' => 'categoria',
]));
} else {
flash()->error(tr('Esistono ancora alcuni articoli sotto questa categoria!'));
flash()->error(tr('Esistono alcuni impianti collegati a questa categoria. Impossibile eliminarla.'));
}
break;

View File

@ -25,9 +25,18 @@ if (isset($id_record)) {
include __DIR__.'/init.php';
}
?><form action="" method="post" id="add-form">
?><form action="<?php
if (isset($id_original)) {
echo base_path().'/controller.php?id_module='.$id_module;
if (isset($id_record)) {
echo '&id_record='.$id_record;
}
}
?>" method="post" id="add-form">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="add">
<input type="hidden" name="id_original" value="<?php echo $id_original; ?>">
<input type="hidden" name="op" value="<?php echo $id_record ? 'update' : 'add'; ?>">
<div class="row">
<div class="col-md-8">
@ -48,14 +57,30 @@ if (isset($id_record)) {
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<?php
if (isset($id_record)) {
?>
<button type="submit" class="btn btn-success"><i class="fa fa-save"></i> <?php echo tr('Salva'); ?></button>
<?php
} else {
?>
<button type="submit" class="btn btn-primary"><i class="fa fa-plus"></i> <?php echo tr('Aggiungi'); ?></button>
<?php
}
?>
</div>
</div>
</form>
<script>
$(document).ready( function() {
$('.colorpicker').colorpicker({ format: 'hex' }).on('changeColor', function() {
$('#modals > div .colorpicker').colorpicker({ format: 'hex' }).on('changeColor', function() {
$('#modals > div #colore_').parent().find('.square').css('background', $('#modals > div #colore_').val());
});
$('#modals > div #colore_').parent().find('.square').css('background', $('#modals > div #colore_').val());
$('#modals > div .colorpicker').colorpicker({ format: 'hex' }).on('changeColor', function() {
$('#modals > div #colore_').parent().find('.square').css('background', $('#modals > div #colore_').val());
});

View File

@ -50,6 +50,36 @@ include_once __DIR__.'/../../core.php';
</form>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><?php echo tr('Sottocategorie'); ?></h3>
</div>
<div class="panel-body">
<div class="pull-left">
<a class="btn btn-primary" data-href="<?php echo base_path(); ?>/add.php?id_module=<?php echo $id_module; ?>&id_original=<?php echo $id_record; ?>" data-toggle="modal" data-title="<?php echo tr('Aggiungi riga'); ?>"><i class="fa fa-plus"></i> <?php echo tr('Sottocategoria'); ?></a><br>
</div>
<div class="clearfix"></div>
<hr>
<div class="row">
<div class="col-md-12">
<table class="table table-striped table-hover table-condensed">
<tr>
<th><?php echo tr('Nome'); ?></th>
<th><?php echo tr('Colore'); ?></th>
<th><?php echo tr('Nota'); ?></th>
<th width="20%"><?php echo tr('Opzioni'); ?></th>
</tr>
<?php include base_dir().'/modules/'.Modules::get($id_module)['directory'].'/row-list.php'; ?>
</table>
</div>
</div>
</div>
</div>
<script>
$(document).ready( function() {
$('.colorpicker').colorpicker({ format: 'hex' }).on('changeColor', function() {
@ -62,13 +92,37 @@ include_once __DIR__.'/../../core.php';
<?php
$res = $dbo->fetchArray('SELECT * FROM `my_impianti` WHERE `id_categoria`='.prepare($id_record));
$elementi = $dbo->fetchArray('SELECT `my_impianti`.`id`, `my_impianti`.`matricola`, `my_impianti`.`nome` FROM `my_impianti` WHERE (`id_categoria`='.prepare($id_record).' OR `id_sottocategoria`='.prepare($id_record).' OR `id_sottocategoria` IN (SELECT id FROM `my_impianti_categorie` WHERE `parent`='.prepare($id_record).'))');
if ($res) {
if (!empty($elementi)) {
echo '
<div class="alert alert-danger">
<p>'.tr('Ci sono '.sizeof($res).' impianti collegati a questa categoria. Non è possibile eliminarla.').'</p>
</div>';
<div class="box box-warning collapsable collapsed-box">
<div class="box-header with-border">
<h3 class="box-title"><i class="fa fa-warning"></i> '.tr('Impianti collegati: _NUM_', [
'_NUM_' => count($elementi),
]).'</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">
<ul>';
foreach ($elementi as $elemento) {
$descrizione = tr('Impianto _MATRICOLA_', [
'_MATRICOLA_' => $elemento['matricola'],
]);
$modulo = 'Impianti';
$id = $elemento['id'];
echo '
<li>'.Modules::link($modulo, $id, $descrizione).'</li>';
}
echo '
</ul>
</div>
</div>';
} else {
echo '
<a class="btn btn-danger ask" data-backto="record-list">

View File

@ -0,0 +1,38 @@
<?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';
$subcategorie = $dbo->fetchArray('SELECT * FROM `my_impianti_categorie` WHERE `parent`='.prepare($id_record).' ORDER BY nome ASC ');
foreach ($subcategorie as $sub) {
$n_impianti = $dbo->fetchNum('SELECT * FROM `my_impianti` WHERE `id_sottocategoria`='.prepare($sub['id']).' AND deleted_at IS NULL');
echo '
<tr>
<td>'.$sub['nome'].'</td>
<td>'.$sub['colore'].'</td>
<td>'.$sub['nota'].'</td>
<td>
<a class="btn btn-warning btn-sm" title="Modifica riga" onclick="launch_modal(\''.tr('Modifica sottocategoria').'\', \''.base_path().'/add.php?id_module='.$id_module.'&id_record='.$sub['id'].'&id_original='.$id_record.'\');"><i class="fa fa-edit"></i></a>
<a class="btn btn-sm btn-danger ask '.(($n_impianti > 0) ? 'disabled tip' : '').'" data-backto="record-edit" data-id="'.$sub['id'].'" title="'.(($n_impianti > 0) ? 'Sottocategoria collegata a '.$n_impianti.' articoli' : '').'">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>';
}

View File

@ -37,6 +37,7 @@ switch ($op) {
'nome' => post('nome'),
'matricola' => $matricola,
'id_categoria' => post('id_categoria') ?: null,
'id_sottocategoria' => post('subcategoria') ?: null,
'descrizione' => post('descrizione'),
'idsede' => post('idsede'),
'data' => post('data') ?: null,

View File

@ -62,17 +62,23 @@ if (!empty($record['immagine'])) {
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "required": 1, "value": "$idanagrafica$", "extra": "", "ajax-source": "clienti" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Tecnico predefinito'); ?>", "name": "idtecnico", "ajax-source": "tecnici", "value": "$idtecnico$" ]}
</div>
</div>
<div class ="row">
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Categoria'); ?>", "name": "id_categoria", "required": 0, "value": "$id_categoria$", "values": "query=SELECT id, nome AS descrizione FROM my_impianti_categorie", "icon-after": "add|<?php echo Modules::get('Categorie impianti')['id']; ?>" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Sottocategoria'); ?>", "name": "subcategoria", "value": "$id_sottocategoria$", "values": "query=SELECT id, nome AS descrizione FROM my_impianti_categorie WHERE parent = $id_categoria$", "select-options": <?php echo json_encode(['id_categoria' => $record['id_categoria']]); ?>, "icon-after": "add|<?php echo Modules::get('Categorie impianti')['id']; ?>|id_original=<?php echo $record['id_categoria']; ?>" ]}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "<?php echo tr('Tecnico predefinito'); ?>", "name": "idtecnico", "ajax-source": "tecnici", "value": "$idtecnico$" ]}
</div>
<div class="col-md-4">
{[ "type": "date", "label": "<?php echo tr('Data installazione'); ?>", "name": "data", "value": "$data$" ]}

View File

@ -38,7 +38,7 @@ if (filter('op') == 'link_impianti') {
'id_module' => $id_module,
'id_record' => $id_record,
'id_module_from' => $modulo_impianti['id'],
'id_record_from' => $matricola
'id_record_from' => $matricola,
]);
$components = $dbo->fetchArray('SELECT * FROM my_componenti WHERE id_impianto = '.prepare($matricola));
@ -54,7 +54,7 @@ if (filter('op') == 'link_impianti') {
if (!in_array($matricola, $matricole_old)) {
$dbo->query('INSERT INTO my_impianti_interventi(idimpianto, idintervento) VALUES('.prepare($matricola).', '.prepare($id_record).')');
$checks_impianti = $dbo->fetchArray('SELECT * FROM zz_checks WHERE id_module = '.prepare( $modulo_impianti['id']).' AND id_record = '.prepare($matricola));
$checks_impianti = $dbo->fetchArray('SELECT * FROM zz_checks WHERE id_module = '.prepare($modulo_impianti['id']).' AND id_record = '.prepare($matricola));
foreach ($checks_impianti as $check_impianto) {
$id_parent_new = null;
if ($check_impianto['id_parent']) {
@ -141,22 +141,22 @@ if (!empty($impianti)) {
<th class="text-center" width="5%">Checklist</th>
</tr>';
$impianti_collegati = $dbo->fetchArray('SELECT * FROM my_impianti_interventi INNER JOIN my_impianti ON my_impianti_interventi.idimpianto = my_impianti.id WHERE idintervento = '.prepare($id_record));
foreach ($impianti_collegati as $impianto) {
$checks = Check::where('id_module_from', $modulo_impianti['id'])->where('id_record_from', $impianto['id'])->where('id_module', $id_module)->where('id_record', $id_record)->where('id_parent', null)->get();
$impianti_collegati = $dbo->fetchArray('SELECT * FROM my_impianti_interventi INNER JOIN my_impianti ON my_impianti_interventi.idimpianto = my_impianti.id WHERE idintervento = '.prepare($id_record));
foreach ($impianti_collegati as $impianto) {
$checks = Check::where('id_module_from', $modulo_impianti['id'])->where('id_record_from', $impianto['id'])->where('id_module', $id_module)->where('id_record', $id_record)->where('id_parent', null)->get();
$type = 'muted';
$class = 'disabled';
$icon = 'circle-o';
$icon2 = 'remove';
if (sizeof($checks)) {
$class = '';
$icon = 'plus';
$checks_not_verified = $checks->where('checked_at', null)->count();
$type = $checks_not_verified ? 'warning' : 'success';
$icon2 = $checks_not_verified ? 'clock-o' : 'check';
}
echo '
$type = 'muted';
$class = 'disabled';
$icon = 'circle-o';
$icon2 = 'remove';
if (sizeof($checks)) {
$class = '';
$icon = 'plus';
$checks_not_verified = $checks->where('checked_at', null)->count();
$type = $checks_not_verified ? 'warning' : 'success';
$icon2 = $checks_not_verified ? 'clock-o' : 'check';
}
echo '
<tr>
<td class="text-left">
<button type="button" class="btn btn-xs btn-default '.$class.'" onclick="toggleDettagli(this)">
@ -173,10 +173,10 @@ if (!empty($impianti)) {
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="id_impianto" value="'.$impianto['id'].'">';
$inseriti = $dbo->fetchArray('SELECT * FROM my_componenti_interventi WHERE id_intervento = '.prepare($id_record));
$ids = array_column($inseriti, 'id_componente');
$inseriti = $dbo->fetchArray('SELECT * FROM my_componenti_interventi WHERE id_intervento = '.prepare($id_record));
$ids = array_column($inseriti, 'id_componente');
echo '
echo '
{[ "type": "select", "multiple": 1, "name": "componenti[]", "id": "componenti_'.$impianto['id'].'", "ajax-source": "componenti", "select-options": {"matricola": '.$impianto['id'].'}, "value": "'.implode(',', $ids).'", "readonly": "'.!empty($readonly).'", "disabled": "'.!empty($disabled).'", "icon-after": "<button type=\"submit\" class=\"btn btn-success\" '.$disabled.'> <i class=\"fa fa-check\"></i> '.tr('Salva').'</button>" ]}
</form>
</td>
@ -187,16 +187,16 @@ if (!empty($impianti)) {
<td colspan="7">
<table class="table">
<tbody class="sort check-impianto" data-sonof="0">';
foreach ($checks as $check) {
echo renderChecklist($check);
}
echo '
foreach ($checks as $check) {
echo renderChecklist($check);
}
echo '
</tbody>
</table>
</td>
</tr>';
}
echo '
}
echo '
</table>
</div>
</div>';

View File

@ -0,0 +1,48 @@
<?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/>.
*/
namespace Modules\Impianti;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Model;
use Traits\HierarchyTrait;
class Categoria extends Model
{
use SimpleModelTrait;
use HierarchyTrait;
protected $table = 'my_impianti_categorie';
protected static $parent_identifier = 'parent';
public static function build($nome)
{
$model = new static();
$model->nome = $nome;
$model->save();
return $model;
}
public function impianti()
{
return $this->hasMany(Impianto::class, 'id_categoria');
}
}

View File

@ -34,4 +34,23 @@ class Impianto extends Model
{
return $this->belongsTo(Anagrafica::class, 'idanagrafica');
}
public static function build($matricola, $nome, Categoria $categoria, $anagrafica)
{
$model = new static();
$model->matricola = $matricola;
$model->nome = $nome;
$model->categoria()->associate($categoria);
$model->save();
return $model;
}
public function categoria()
{
return $this->belongsTo(Categoria::class, 'id_categoria');
}
}

View File

@ -0,0 +1,223 @@
<?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/>.
*/
namespace Modules\Impianti\Import;
use Importer\CSVImporter;
use Models\Upload;
use Modules;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Sede;
use Modules\Impianti\Categoria;
use Modules\Impianti\Impianto;
use Uploads;
/**
* Struttura per la gestione delle operazioni di importazione (da CSV) degli Impianti.
*
* @since 2.4.52
*/
class CSV extends CSVImporter
{
public function getAvailableFields()
{
return [
[
'field' => 'matricola',
'label' => 'Matricola',
'primary_key' => true,
],
[
'field' => 'immagine',
'label' => 'Immagine',
'names' => [
'Immagine',
'Foto',
],
],
[
'field' => 'import_immagine',
'label' => 'Import immagine',
],
[
'field' => 'nome',
'label' => 'Nome',
],
[
'field' => 'cliente',
'label' => 'Cliente',
],
[
'field' => 'telefono',
'label' => 'Telefono',
],
[
'field' => 'id_categoria',
'label' => 'Categoria',
],
[
'field' => 'id_sottocategoria',
'label' => 'Sottocategoria',
],
[
'field' => 'sede',
'label' => 'Sede',
],
[
'field' => 'descrizione',
'label' => 'Descrizione',
],
[
'field' => 'data',
'label' => 'Data installazione',
],
];
}
public function import($record)
{
$database = database();
$primary_key = $this->getPrimaryKey();
if (!empty($record['telefono'])) {
$anagrafica = Anagrafica::where('telefono', $record['telefono'])->first();
}
if (!empty($anagrafica)) {
$url = $record['immagine'];
unset($record['immagine']);
// Gestione categoria e sottocategoria
$categoria = null;
$sottocategoria = null;
if (empty($record['id_categoria'])) {
$record['id_categoria'] = 'Nessuna';
}
// Categoria
$categoria = Categoria::where('nome', strtolower($record['id_categoria']))->first();
if (empty($categoria)) {
$categoria = Categoria::build($record['id_categoria']);
}
// Sotto-categoria
if (!empty($record['id_sottocategoria'])) {
$sottocategoria = Categoria::where('nome', $record['id_sottocategoria'])
->where('parent', $categoria->id)
->first();
if (empty($sottocategoria)) {
$sottocategoria = Categoria::build($record['id_sottocategoria']);
$sottocategoria->parent()->associate($categoria);
$sottocategoria->save();
}
}
// Individuazione impianto e generazione
$impianto = null;
// Ricerca sulla base della chiave primaria se presente
if (!empty($primary_key)) {
$impianto = Impianto::where($primary_key, $record[$primary_key])->first();
}
if (empty($impianto)) {
$impianto = Impianto::build($record['matricola'], $record['nome'], $categoria, $record['cliente']);
}
if (!empty($record['data'])) {
$impianto->data = $record['data'];
$impianto->save();
}
$impianto->id_sottocategoria = $sottocategoria['id'];
$impianto->idanagrafica = $anagrafica->idanagrafica;
$impianto->save();
if (!empty($record['sede'])) {
$sede = Sede::where('nomesede', $record['sede'])
->where('idanagrafica', $anagrafica->idanagrafica)
->first();
$impianto->idsede = $sede->id;
$impianto->save();
}
//Gestione immagine
if (!empty($url) && !empty($record['import_immagine'])) {
$file_content = file_get_contents($url);
if (!empty($file_content)) {
if ($record['import_immagine'] == 2 || $record['import_immagine'] == 4) {
Uploads::deleteLinked([
'id_module' => Modules::get('Impianti')['id'],
'id_record' => $impianto->id,
]);
$database->update('mg_articoli', [
'immagine' => '',
], [
'id' => $impianto->id,
]);
}
$name = 'immagine_'.$impianto->id.'.'.Upload::getExtensionFromMimeType($file_content);
$upload = Uploads::upload($file_content, [
'name' => 'Immagine',
'category' => 'Immagini',
'original_name' => $name,
'id_module' => Modules::get('Impianti')['id'],
'id_record' => $impianto->id,
], [
'thumbnails' => true,
]);
$filename = $upload->filename;
if ($record['import_immagine'] == 1 || $record['import_immagine'] == 2) {
if (!empty($filename)) {
$database->update('mg_articoli', [
'immagine' => $filename,
], [
'id' => $impianto->id,
]);
}
}
}
}
unset($record['import_immagine']);
}
}
public static function getExample()
{
return [
['Matricola', 'Nome', 'Categoria', 'Immagine', 'Data installazione', 'Cliente', 'Telefono', 'Sede'],
['00001', 'Marca', 'Lavatrice', 'https://immagini.com/immagine.jpg', '01/10/2023', 'Mario Rossi', '04444444', 'Sede2'],
['00002', 'Marca2', 'Lavastoviglie', 'https://immagini.com/immagine2.jpg', '12/09/2023', 'Mario Rossi', '04444444', 'Sede2'],
['00003', 'Marca3', 'Frigorifero', 'https://immagini.com/immagine3.jpg', '20/09/2023', 'Mario Rossi', '04444444', 'Sede2'],
['00004', 'Marca4', 'Caldaia', 'https://immagini.com/immagine4.jpg', '06/11/2023', 'Mario Rossi', '04444444', 'Sede2'],
[],
['Import immagine = 1 -> Permette di importare l\'immagine come principale dell\'impianto mantenendo gli altri allegati già presenti'],
['Import immagine = 2 -> Permette di importare l\'immagine come principale dell\'impianto rimuovendo tutti gli allegati presenti'],
['Import immagine = 3 -> Permette di importare l\'immagine come allegato dell\'impianto mantenendo gli altri allegati già presenti'],
['Import immagine = 4 -> Permette di importare l\'immagine come allegato dell\'impianto rimuovendo tutti gli allegati presenti'],
];
}
}

View File

@ -0,0 +1,193 @@
<?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/>.
*/
namespace Modules\Interventi\Import;
use Importer\CSVImporter;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Impianti\Impianto;
use Modules\Interventi\Components\Sessione;
use Modules\Interventi\Intervento;
use Modules\Interventi\Stato;
use Modules\TipiIntervento\Tipo as TipoIntervento;
/**
* Struttura per la gestione delle operazioni di importazione (da CSV) degli Interventi.
*
* @since 2.4.52
*/
class CSV extends CSVImporter
{
public function getAvailableFields()
{
return [
[
'field' => 'codice',
'label' => 'Codice',
'primary_key' => true,
],
[
'field' => 'telefono',
'label' => 'Telefono',
],
[
'field' => 'data',
'label' => 'Data',
],
[
'field' => 'data_richiesta',
'label' => 'Data richiesta',
],
[
'field' => 'ora_inizio',
'label' => 'Ora inizio',
],
[
'field' => 'ora_fine',
'label' => 'Ora fine',
],
[
'field' => 'tecnico',
'label' => 'Tecnico',
],
[
'field' => 'tipo',
'label' => 'Tipo',
],
[
'field' => 'note',
'label' => 'Note',
],
[
'field' => 'impianto',
'label' => 'Impianto',
],
[
'field' => 'richiesta',
'label' => 'Richiesta',
],
[
'field' => 'descrizione',
'label' => 'Descrizione',
],
[
'field' => 'stato',
'label' => 'Stato',
],
];
}
public function import($record)
{
$database = database();
$primary_key = $this->getPrimaryKey();
if (!empty($record['telefono'])) {
$anagrafica = Anagrafica::where('telefono', $record['telefono'])->first();
}
if (!empty($record['impianto'])) {
$impianto = Impianto::where('matricola', $record['impianto'])->first();
}
if (!empty($anagrafica) && !empty($impianto)) {
$intervento = null;
// Ricerca sulla base della chiave primaria se presente
if (!empty($primary_key)) {
$intervento = Intervento::where($primary_key, $record[$primary_key])->first();
}
// Verifico tipo e stato per creare l'intervento
if (empty($record['tipo'])) {
$tipo = TipoIntervento::where('codice', 'GEN')->first();
} else {
$tipo = TipoIntervento::where('codice', $record['tipo'])->first();
}
unset($record['tipo']);
if (empty($record['stato'])) {
$stato = Stato::where('descrizione', 'Completato')->first();
} else {
$stato = Stato::where('descrizione', $record['stato'])->first();
}
unset($record['stato']);
// Crea l'intervento
if (empty($intervento)) {
$intervento = Intervento::build($anagrafica, $tipo, $stato, $record['data_richiesta']);
}
unset($record['codice']);
unset($record['data']);
unset($record['ora_inizio']);
unset($record['telefono']);
$collegamento = $database->table('my_impianti_interventi')->where('idimpianto', $impianto['id'])->where('idintervento', $intervento['id'])->first();
if (empty($collegamento)) {
// Collega l'impianto all'intervento
$database->query('INSERT INTO my_impianti_interventi(idimpianto, idintervento) VALUES('.prepare($impianto['id']).', '.prepare($intervento['id']).')');
}
unset($record['impianto']);
// Inserisce la data richiesta e la richiesta
$intervento->data_richiesta = $record['data_richiesta'];
$intervento->richiesta = $record['richiesta'];
// Inserisce la descrizione se presente
if (!empty($record['descrizione'])) {
$intervento->descrizione = $record['descrizione'];
}
// Inserisce le note se presenti
if (!empty($record['note'])) {
$intervento->informazioniaggiuntive = $record['note'];
}
$intervento->save();
$inizio = date('Y-m-d H:i', strtotime($record['data'].' '.$record['ora_inizio']));
$fine = date('Y-m-d H:i', strtotime($record['data'].' '.$record['ora_fine']));
// Verifica il tecnico e inserisce la sessione
$anagrafica_t = Anagrafica::where('ragione_sociale', $record['tecnico'])->first();
$tipo = $database->fetchOne('SELECT idtipoanagrafica FROM an_tipianagrafiche_anagrafiche WHERE idanagrafica = '.prepare($anagrafica_t['idanagrafica']));
$tecnico = TipoAnagrafica::where('descrizione', 'Tecnico')->first();
if ($tipo = $tecnico['idtipoanagrafica']) {
$anagrafica_t['tipo'] = $tecnico['descrizione'];
}
if (!empty($record['data']) && !empty($record['ora_inizio']) && !empty($record['tecnico'])) {
$sessione = Sessione::build($intervento, $anagrafica_t, $inizio, $fine);
$sessione->save();
}
}
}
public static function getExample()
{
return [
['Codice', 'Telefono', 'Data', 'Data richiesta', 'Ora', 'Tecnico', 'Tipo', 'Note', 'Impianto', 'Richiesta', 'Descrizione', 'Stato'],
['001', '044444444', '07/11/2023', '03/11/2023', '18:30', 'Stefano Bianchi', '', '', '00000000001', 'Manutenzione ordinaria', 'eseguito intervento di manutenzione', 'Bozza'],
['002', '044444444', '08/11/2023', '04/11/2023', '11:20', 'Stefano Bianchi', '', '', '00000000002', 'Manutenzione ordinaria', 'eseguito intervento di manutenzione', ''],
];
}
}

View File

@ -836,5 +836,44 @@ switch (post('op')) {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
// Duplica ordine
case 'copy':
$new = $ordine->replicate();
$new->numero = Ordine::getNextNumero(post('data'), $ordine->tipo->dir, $ordine->id_segment);
$new->numero_esterno = Ordine::getNextNumeroSecondario(post('data'), $ordine->tipo->dir, $ordine->id_segment);
$new->idstatoordine = post('idstatoordine');
$new->data = post('data');
$new->save();
$id_record = $new->id;
if (!empty(post('copia_righe'))) {
$righe = $ordine->getRighe();
foreach ($righe as $riga) {
$new_riga = $riga->replicate();
$new_riga->setDocument($new);
$new_riga->qta_evasa = 0;
$new_riga->save();
}
}
//copia allegati
if (!empty(post('copia_allegati'))) {
$allegati = $ordine->uploads();
foreach ($allegati as $allegato) {
$allegato->copia([
'id_module' => $new->getModule()->id,
'id_record' => $new->id,
]);
}
}
flash()->info(tr('Aggiunto ordine numero _NUM_!', [
'_NUM_' => $new->numero,
]));
break;
}

View File

@ -160,7 +160,7 @@ echo '
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-12">
<?php echo input([
'type' => 'ckeditor',
'use_full_ckeditor' => 1,
@ -472,6 +472,9 @@ $elementi = $dbo->fetchArray('SELECT `co_documenti`.`id`, `co_documenti`.`data`,
UNION
SELECT `or_ordini`.`id`, `or_ordini`.`data`, `or_ordini`.`numero`, `or_ordini`.`numero_esterno`, `or_tipiordine`.`descrizione`, IF(`or_tipiordine`.`dir` = \'entrata\', \'Ordini cliente\', \'Ordini fornitore\') FROM `or_ordini` JOIN `or_righe_ordini` ON `or_righe_ordini`.`idordine` = `or_ordini`.`id` JOIN `or_tipiordine` ON `or_tipiordine`.`id` = `or_ordini`.`idtipoordine` WHERE `or_righe_ordini`.`idpreventivo` = '.prepare($id_record).'
UNION
SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione`, IF(`dt_tipiddt`.`dir` = \'entrata\', \'Ddt di vendita\', \'Ddt di acquisto\') FROM `dt_ddt` JOIN `dt_righe_ddt` ON `dt_righe_ddt`.`idddt` = `dt_ddt`.`id` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` WHERE `dt_righe_ddt`.`original_document_id` = '.prepare($preventivo->id).' AND `dt_righe_ddt`.`original_document_type` = \'Modules\\\\Preventivi\\\\Preventivo\'
UNION
SELECT `in_interventi`.`id`, `in_interventi`.`data_richiesta`, `in_interventi`.`codice`, NULL, \'Attività\', \'Interventi\' FROM `in_interventi` JOIN `in_righe_interventi` ON `in_righe_interventi`.`idintervento` = `in_interventi`.`id` WHERE (`in_righe_interventi`.`original_document_id` = '.prepare($preventivo->id).' AND `in_righe_interventi`.`original_document_type` = '.prepare(get_class($preventivo)).') OR `in_interventi`.`id_preventivo` = '.prepare($id_record).'

View File

@ -1132,7 +1132,7 @@ class FatturaElettronica
if (!empty($element['riferimento_linea']['id'])) {
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea']['id'];
} else if (!empty($element['riferimento_linea'])) {
} elseif (!empty($element['riferimento_linea'])) {
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'];
}

View File

@ -130,6 +130,7 @@ switch ($operazione) {
$riga->setPrezzoUnitario($prezzo_unitario, $r->idiva);
$riga->setSconto(($r->tipo_sconto == 'PRC' ? $r->sconto_percentuale : $r->sconto_unitario), $r->tipo_sconto);
$riga->qta = $qta_riga;
$riga->setProvvigione(($r->provvigione_percentuale ? $r->provvigione_percentuale : $r->provvigione_unitaria), $r->tipo_provvigione);
$riga->idpianificazione = $pianificazioni[$rata];
$riga->save();

View File

@ -34,10 +34,10 @@ $data_conclusione = $contratto['data_conclusione'];
$id_anagrafica = $contratto['idanagrafica'];
// Impianti del contratto
$impianti = $dbo->fetchArray('SELECT `idimpianto` FROM `my_impianti_contratti` WHERE `idcontratto` = :id', [
$impianti = $dbo->fetchArray('SELECT `idimpianti` FROM `co_promemoria` WHERE `id` = '.$id_record.' AND `idcontratto` = :id', [
':id' => $id_parent,
]);
$id_impianti = array_column($impianti, 'idimpianto');
$id_impianti = explode(',', $impianti[0]['idimpianti']);
// solo se ho selezionato un solo impianto nel contratto, altrimenti non so quale sede e tecnico prendere
if (count($id_impianti) == 1) {

View File

@ -90,7 +90,10 @@ switch ($operazione) {
'enable_newsletter' => empty($opt_out_newsletter),
], ['id' => $id_record]);
$referenti = $dbo->fetchArray('SELECT id FROM an_referenti WHERE idsede = '.$id_record);
$id_referenti = (array) post('id_referenti');
$refs = array_diff($referenti, $id_referenti);
foreach ($id_referenti as $id_referente) {
$dbo->update('an_referenti', [
'idsede' => $id_record,
@ -99,6 +102,14 @@ switch ($operazione) {
]);
}
foreach ($refs as $ref) {
$dbo->update('an_referenti', [
'idsede' => 0,
], [
'id' => $ref,
]);
}
flash()->info(tr('Salvataggio completato!'));
break;

View File

@ -116,22 +116,6 @@ UPDATE `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_module
UPDATE `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_modules`.`id` SET `zz_views`.`query` = "IF(my_impianti.idsede > 0, sede.info, CONCAT('', IF (clienti.telefono!='',CONCAT(clienti.telefono,'<br>'),''), IF(clienti.cellulare!='', CONCAT(clienti.cellulare,'<br>'),''),IF(clienti.citta!='',clienti.citta,''),IF(clienti.indirizzo!='',CONCAT(' - ',clienti.indirizzo),'')))" WHERE `zz_modules`.`name` = 'Impianti' AND `zz_views`.`name` = 'Sede';
UPDATE `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_modules`.`id` SET `zz_views`.`query` = 'tecnici.ragione_sociale' WHERE `zz_modules`.`name` = 'Impianti' AND `zz_views`.`name` = 'Tecnico';
UPDATE `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_modules`.`id` SET `zz_views`.`query` = 'my_impianti_categorie.nome' WHERE `zz_modules`.`name` = 'Impianti' AND `zz_views`.`name` = 'Categoria';
UPDATE `zz_modules` SET `options` = "SELECT
|select|
FROM
`my_impianti`
LEFT JOIN `an_anagrafiche` AS clienti ON `clienti`.`idanagrafica` = `my_impianti`.`idanagrafica`
LEFT JOIN `an_anagrafiche` AS tecnici ON `tecnici`.`idanagrafica` = `my_impianti`.`idtecnico`
LEFT JOIN `my_impianti_categorie` ON `my_impianti_categorie`.`id` = `my_impianti`.`id_categoria`
LEFT JOIN (SELECT an_sedi.id, CONCAT(an_sedi.nomesede, '<br />',IF(an_sedi.telefono!='',CONCAT(an_sedi.telefono,'<br />'),''),IF(an_sedi.cellulare!='',CONCAT(an_sedi.cellulare,'<br />'),''),an_sedi.citta,IF(an_sedi.indirizzo!='',CONCAT(' - ',an_sedi.indirizzo),'')) AS info FROM an_sedi
) AS sede ON sede.id = my_impianti.idsede
WHERE
1=1
HAVING
2=2
ORDER BY
`matricola`" WHERE `name` = 'Impianti';
-- Ottimizzazione query vista Movimenti
UPDATE `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_modules`.`id` SET `zz_views`.`query` = 'zz_modules.id' WHERE `zz_modules`.`name` = 'Movimenti' AND `zz_views`.`name` = '_link_module_';

View File

@ -71,4 +71,4 @@ INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`,
DELETE FROM `em_print_template` WHERE `em_print_template`.`id_print` IN (SELECT `id` FROM `zz_prints` WHERE `zz_prints`.`is_record` = 0);
-- Il widget Notifiche interne è ora Note interne
UPDATE `zz_widgets` SET `text` = 'Note interne' WHERE `zz_widgets`.`name` = "Note interne";
UPDATE `zz_widgets` SET `text` = 'Note interne' WHERE `zz_widgets`.`name` = "Note interne";

28
update/2_4_52.sql Normal file
View File

@ -0,0 +1,28 @@
-- Aggiunta importazione impianti
INSERT INTO `zz_imports` (`name`, `class`) VALUES ('Impianti', 'Modules\\Impianti\\Import\\CSV');
-- Aggiunta importazione attività
INSERT INTO `zz_imports` (`name`, `class`) VALUES ('Attività', 'Modules\\Interventi\\Import\\CSV');
ALTER TABLE `my_impianti_categorie` ADD `parent` INT NULL DEFAULT NULL;
ALTER TABLE `my_impianti` ADD `id_sottocategoria` INT NULL DEFAULT NULL AFTER `id_categoria`;
UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM `my_impianti_categorie` WHERE 1=1 AND parent IS NULL HAVING 2=2' WHERE `zz_modules`.`name` = 'Categorie impianti';
-- Aggiornamento vista Impianti
INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `html_format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES ((SELECT `id` FROM `zz_modules` WHERE `name` = 'Impianti'), 'Sottocategoria', 'sub.nome', '7', '1', '0', '0', '0', '', '', '1', '0', '0');
UPDATE `zz_modules` SET `options` = "SELECT
|select|
FROM
`my_impianti`
LEFT JOIN `an_anagrafiche` AS clienti ON `clienti`.`idanagrafica` = `my_impianti`.`idanagrafica`
LEFT JOIN `an_anagrafiche` AS tecnici ON `tecnici`.`idanagrafica` = `my_impianti`.`idtecnico`
LEFT JOIN `my_impianti_categorie` ON `my_impianti_categorie`.`id` = `my_impianti`.`id_categoria`
LEFT JOIN `my_impianti_categorie` as sub ON sub.`id` = `my_impianti`.`id_sottocategoria`
LEFT JOIN (SELECT an_sedi.id, CONCAT(an_sedi.nomesede, '<br />',IF(an_sedi.telefono!='',CONCAT(an_sedi.telefono,'<br />'),''),IF(an_sedi.cellulare!='',CONCAT(an_sedi.cellulare,'<br />'),''),an_sedi.citta,IF(an_sedi.indirizzo!='',CONCAT(' - ',an_sedi.indirizzo),'')) AS info FROM an_sedi
) AS sede ON sede.id = my_impianti.idsede
WHERE
1=1
HAVING
2=2
ORDER BY
`matricola`" WHERE `name` = 'Impianti';