Skip to content

Commit f910af0

Browse files
feat: gestione tariffe tipi interventi in base alla sede cliente
1 parent d9574ac commit f910af0

5 files changed

Lines changed: 261 additions & 18 deletions

File tree

modules/interventi/ajax/select.php

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
switch ($resource) {
2626
case 'tipiintervento':
27-
$query = 'SELECT `in_tipiintervento`.`id`, CASE WHEN ISNULL(`tempo_standard`) OR `tempo_standard` <= 0 THEN CONCAT(`codice`, \' - \', `title`, IF(`in_tipiintervento`.`deleted_at` IS NULL, "", " ('.tr('eliminato').')")) WHEN `tempo_standard` > 0 THEN CONCAT(`codice`, \' - \', `title`, \' (\', REPLACE(FORMAT(`tempo_standard`, 2), \'.\', \',\'), \' ore)\', IF(`in_tipiintervento`.`deleted_at` IS NULL, "", " ('.tr('eliminato').')")) END AS descrizione, `tempo_standard`
27+
$query = 'SELECT `in_tipiintervento`.`id`, CASE WHEN ISNULL(`tempo_standard`) OR `tempo_standard` <= 0 THEN CONCAT(`codice`, \' - \', `title`, IF(`in_tipiintervento`.`deleted_at` IS NULL, "", " ('.tr('eliminato').')")) WHEN `tempo_standard` > 0 THEN CONCAT(`codice`, \' - \', `title`, \' (\', REPLACE(FORMAT(`tempo_standard`, 2), \'.\', \',\'), \' ore)\', IF(`in_tipiintervento`.`deleted_at` IS NULL, "", " ('.tr('eliminato').')")) END AS descrizione, `tempo_standard`
2828
FROM `in_tipiintervento`
2929
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).')
3030
|where|
@@ -110,23 +110,57 @@
110110

111111
$intervento = Intervento::find($id_intervento);
112112

113-
// Query per i tipi di intervento in base al contratto o al tecnico
114-
if (!empty($intervento->id_contratto)) {
115-
$query = 'SELECT `in_tipiintervento`.`id`, CONCAT(`codice`, \' - \', `title`) AS descrizione, `co_contratti_tipiintervento`.`costo_ore` AS prezzo_ore_unitario, `co_contratti_tipiintervento`.`costo_km` AS prezzo_km_unitario, `co_contratti_tipiintervento`.`costo_dirittochiamata` AS prezzo_dirittochiamata
116-
FROM `in_tipiintervento`
117-
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).')
118-
INNER JOIN `co_contratti_tipiintervento` ON `in_tipiintervento`.`id` = `co_contratti_tipiintervento`.`idtipointervento`
119-
|where|
120-
ORDER BY `title`';
121-
122-
$where[] = '`co_contratti_tipiintervento`.`idtecnico` = '.prepare($idtecnico);
113+
// Query per i tipi di intervento in base alla sede al contratto o al tecnico
114+
// Priorità: tariffe contratto > tariffe sede > tariffe tecnico
115+
if (!empty($intervento->idsede_destinazione)) {
116+
// Se c'è una sede configurata: prova prima tariffe contratto, poi sede, poi tecnico
117+
$query = 'SELECT `in_tipiintervento`.`id`, CONCAT(`codice`, \' - \', `title`) AS descrizione,
118+
COALESCE(`co_contratti_tipiintervento`.`costo_ore`, `in_tariffe_sedi`.`costo_ore`, `in_tariffe`.`costo_ore`) AS prezzo_ore_unitario,
119+
COALESCE(`co_contratti_tipiintervento`.`costo_km`, `in_tariffe_sedi`.`costo_km`, `in_tariffe`.`costo_km`) AS prezzo_km_unitario,
120+
COALESCE(`co_contratti_tipiintervento`.`costo_dirittochiamata`, `in_tariffe_sedi`.`costo_dirittochiamata`, `in_tariffe`.`costo_dirittochiamata`) AS prezzo_dirittochiamata
121+
FROM `in_tipiintervento`
122+
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).')
123+
LEFT JOIN `co_contratti_tipiintervento` ON `in_tipiintervento`.`id` = `co_contratti_tipiintervento`.`idtipointervento` AND `co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).'
124+
LEFT JOIN `in_tariffe_sedi` ON `in_tipiintervento`.`id` = `in_tariffe_sedi`.`idtipointervento` AND `in_tariffe_sedi`.`idsede` = '.prepare($intervento->idsede_destinazione).'
125+
LEFT JOIN `in_tariffe` ON `in_tipiintervento`.`id` = `in_tariffe`.`idtipointervento` AND `in_tariffe`.`idtecnico` = '.prepare($idtecnico).'
126+
|where|
127+
ORDER BY `title`';
128+
129+
// Filtro: mostra tipi con tariffe contratto, o sede, o tecnico
130+
$where[] = '(
131+
`co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).'
132+
OR `in_tariffe_sedi`.`idsede` = '.prepare($intervento->idsede_destinazione).'
133+
OR `in_tariffe`.`idtecnico` = '.prepare($idtecnico).'
134+
)';
135+
} elseif (!empty($intervento->id_contratto)) {
136+
// Se c'è un contratto: prova tariffe contratto, poi tecnico
137+
$query = 'SELECT `in_tipiintervento`.`id`, CONCAT(`codice`, \' - \', `title`) AS descrizione,
138+
COALESCE(`co_contratti_tipiintervento`.`costo_ore`, `in_tariffe`.`costo_ore`) AS prezzo_ore_unitario,
139+
COALESCE(`co_contratti_tipiintervento`.`costo_km`, `in_tariffe`.`costo_km`) AS prezzo_km_unitario,
140+
COALESCE(`co_contratti_tipiintervento`.`costo_dirittochiamata`, `in_tariffe`.`costo_dirittochiamata`) AS prezzo_dirittochiamata
141+
FROM `in_tipiintervento`
142+
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).')
143+
LEFT JOIN `co_contratti_tipiintervento` ON `in_tipiintervento`.`id` = `co_contratti_tipiintervento`.`idtipointervento` AND `co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).'
144+
LEFT JOIN `in_tariffe` ON `in_tipiintervento`.`id` = `in_tariffe`.`idtipointervento` AND `in_tariffe`.`idtecnico` = '.prepare($idtecnico).'
145+
|where|
146+
ORDER BY `title`';
147+
148+
// Filtro: mostra tipi con tariffe contratto o tecnico
149+
$where[] = '(
150+
`co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).'
151+
OR `in_tariffe`.`idtecnico` = '.prepare($idtecnico).'
152+
)';
123153
} else {
124-
$query = 'SELECT `in_tipiintervento`.`id`, CONCAT(`codice`, \' - \', `title`) AS descrizione, `in_tariffe`.`costo_ore` AS prezzo_ore_unitario, `in_tariffe`.`costo_km` AS prezzo_km_unitario, `in_tariffe`.`costo_dirittochiamata` AS prezzo_dirittochiamata
125-
FROM `in_tipiintervento`
126-
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).')
127-
INNER JOIN `in_tariffe` ON `in_tipiintervento`.`id` = `in_tariffe`.`idtipointervento`
128-
|where|
129-
ORDER BY `title`';
154+
// Altrimenti usa solo tariffe tecnico
155+
$query = 'SELECT `in_tipiintervento`.`id`, CONCAT(`codice`, \' - \', `title`) AS descrizione,
156+
`in_tariffe`.`costo_ore` AS prezzo_ore_unitario,
157+
`in_tariffe`.`costo_km` AS prezzo_km_unitario,
158+
`in_tariffe`.`costo_dirittochiamata` AS prezzo_dirittochiamata
159+
FROM `in_tipiintervento`
160+
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).')
161+
INNER JOIN `in_tariffe` ON `in_tipiintervento`.`id` = `in_tariffe`.`idtipointervento` AND `in_tariffe`.`idtecnico` = '.prepare($idtecnico).'
162+
|where|
163+
ORDER BY `title`';
130164

131165
$where[] = '`in_tariffe`.`idtecnico` = '.prepare($idtecnico);
132166
}

modules/interventi/src/Components/Sessione.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,16 @@ protected function getTariffa($id_tipo)
465465
// Costi unitari dalla tariffa del tecnico
466466
$result = $database->fetchOne('SELECT * FROM in_tariffe WHERE idtecnico='.prepare($this->anagrafica->id).' AND idtipointervento = '.prepare($id_tipo));
467467

468+
// Costi unitari specifici per la sede
469+
$id_sede = $this->intervento->idsede_destinazione;
470+
if (!empty($id_sede) && $this->intervento->anagrafica->isTipo('Cliente')) {
471+
$tariffa_sede = $database->fetchOne('SELECT costo_ore, costo_km, costo_dirittochiamata FROM in_tariffe_sedi WHERE idsede = '.prepare($id_sede).' AND idtipointervento = '.prepare($id_tipo));
472+
473+
if (!empty($tariffa_sede)) {
474+
$result = array_merge($result, $tariffa_sede);
475+
}
476+
}
477+
468478
// Costi unitari del contratto
469479
$id_contratto = $this->intervento->id_contratto;
470480
if (!empty($id_contratto)) {

plugins/sedi/actions.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@
104104
$sede->descrizione = post('descrizione');
105105
$sede->save();
106106

107+
// Salva le tariffe specifiche per la sede
108+
salvaTariffeSede($id_record, $id_parent);
109+
107110
$referenti = $dbo->fetchArray('SELECT id FROM an_referenti WHERE idsede = '.$id_record);
108111
$id_referenti = (array) post('id_referenti');
109112
$refs = array_diff($referenti, $id_referenti);
@@ -138,3 +141,62 @@
138141

139142
break;
140143
}
144+
145+
// Funzione per salvare le tariffe della sede
146+
function salvaTariffeSede($id_sede, $id_parent)
147+
{
148+
global $dbo;
149+
150+
$costo_ore = (array)post('costo_ore');
151+
$costo_km = (array)post('costo_km');
152+
$costo_dirittochiamata = (array)post('costo_dirittochiamata');
153+
$tariffa_attiva = (array)post('tariffa_attiva');
154+
155+
// Verifica se l'anagrafica è di tipo Cliente
156+
$anagrafica = Anagrafica::find($id_parent);
157+
if (!$anagrafica->isTipo('Cliente')) {
158+
return;
159+
}
160+
161+
// Recupera i tipi di intervento
162+
$tipi_interventi = $dbo->fetchArray('SELECT id FROM in_tipiintervento WHERE deleted_at IS NULL');
163+
164+
// Recupera le tariffe esistenti per questa sede
165+
$tariffe_esistenti = $dbo->fetchArray('SELECT id, idtipointervento FROM in_tariffe_sedi WHERE idsede = '.prepare($id_sede));
166+
$tariffe_map = [];
167+
foreach ($tariffe_esistenti as $tariffa) {
168+
$tariffe_map[$tariffa['idtipointervento']] = $tariffa['id'];
169+
}
170+
171+
// Salva le tariffe
172+
foreach ($tipi_interventi as $tipo) {
173+
$id_tipo = $tipo['id'];
174+
$attivo = $tariffa_attiva[$id_tipo];
175+
176+
if ($attivo) {
177+
// Se attivo, salva o aggiorna la tariffa
178+
if (isset($tariffe_map[$id_tipo])) {
179+
$dbo->update('in_tariffe_sedi', [
180+
'costo_ore' => $costo_ore[$id_tipo],
181+
'costo_km' => $costo_km[$id_tipo],
182+
'costo_dirittochiamata' => $costo_dirittochiamata[$id_tipo],
183+
], [
184+
'id' => $tariffe_map[$id_tipo],
185+
]);
186+
} else {
187+
$dbo->insert('in_tariffe_sedi', [
188+
'idsede' => $id_sede,
189+
'idtipointervento' => $id_tipo,
190+
'costo_ore' => $costo_ore[$id_tipo],
191+
'costo_km' => $costo_km[$id_tipo],
192+
'costo_dirittochiamata' => $costo_dirittochiamata[$id_tipo],
193+
]);
194+
}
195+
} else {
196+
// Se disattivo, elimina la tariffa se esiste
197+
if (isset($tariffe_map[$id_tipo])) {
198+
$dbo->query('DELETE FROM in_tariffe_sedi WHERE id = '.prepare($tariffe_map[$id_tipo]));
199+
}
200+
}
201+
}
202+
}

plugins/sedi/edit.php

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,31 @@
2121
include_once __DIR__.'/../../core.php';
2222
use Models\Module;
2323
use Models\Plugin;
24+
use Modules\Anagrafiche\Anagrafica;
2425

2526
$referenti = $dbo->select('an_referenti', 'id', [], ['idsede' => $id_record, 'idanagrafica' => $id_parent]);
2627
$referenti = implode(',', array_column($referenti, 'id'));
2728

29+
// Verifica se l'anagrafica è di tipo Cliente
30+
$anagrafica = Anagrafica::find($id_parent);
31+
$is_cliente = $anagrafica->isTipo('Cliente');
32+
33+
// Recupera i tipi di intervento
34+
$tipi_interventi = $dbo->fetchArray('SELECT `in_tipiintervento`.`id`, `in_tipiintervento_lang`.`title`, `in_tipiintervento`.`costo_orario`, `in_tipiintervento`.`costo_km`, `in_tipiintervento`.`costo_diritto_chiamata`
35+
FROM `in_tipiintervento`
36+
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).')
37+
WHERE `in_tipiintervento`.`deleted_at` IS NULL
38+
ORDER BY `title`');
39+
40+
// Recupera le tariffe esistenti per questa sede
41+
$tariffe_sedi = [];
42+
if ($is_cliente) {
43+
$tariffe_db = $dbo->fetchArray('SELECT * FROM in_tariffe_sedi WHERE idsede = '.prepare($id_record));
44+
foreach ($tariffe_db as $tariffa) {
45+
$tariffe_sedi[$tariffa['idtipointervento']] = $tariffa;
46+
}
47+
}
48+
2849
$id_azienda = setting('Azienda predefinita');
2950
if ($id_parent == $id_azienda) {
3051
$utenti = $dbo->fetchNum('SELECT id_user FROM zz_user_sedi WHERE idsede = '.prepare($id_record));
@@ -259,6 +280,75 @@
259280
</div>
260281
</div>';
261282

283+
// Sezione tariffe specifiche per le sedi dei clienti
284+
if ($is_cliente) {
285+
echo '
286+
<!-- TARIFFE SPECIFICHE SEDE -->
287+
<div class="card card-info collapsable collapsed-card">
288+
<div class="card-header with-border">
289+
<h3 class="card-title">'.tr('Tariffe specifiche per la sede').'</h3>
290+
<div class="card-tools pull-right">
291+
<button type="button" class="btn btn-tool" data-card-widget="collapse">
292+
<i class="fa fa-plus"></i>
293+
</button>
294+
</div>
295+
</div>
296+
297+
<div class="card-body">
298+
<div class="row">
299+
<div class="col-md-12 alert alert-warning">
300+
'.tr('Configura i costi specifici per questa sede per ogni tipologia di intervento. Se non configurati nessuno dei tre campi, verranno utilizzati i costi standard del tipo di intervento.').'
301+
</div>
302+
</div>
303+
<div class="row">
304+
<div class="col-md-12">
305+
<table class="table table-bordered table-striped">
306+
<thead>
307+
<tr>
308+
<th>'.tr('Tipo intervento').'</th>
309+
<th width="8%"></th>
310+
<th width="21%">'.tr('Addebito orario').'</th>
311+
<th width="21%">'.tr('Addebito km').'</th>
312+
<th width="21%">'.tr('Addebito diritto chiamata').'</th>
313+
</tr>
314+
</thead>
315+
<tbody>';
316+
317+
foreach ($tipi_interventi as $tipo_intervento) {
318+
$id_tipo = $tipo_intervento['id'];
319+
$tariffa = isset($tariffe_sedi[$id_tipo]) ? $tariffe_sedi[$id_tipo] : [];
320+
$attivo = !empty($tariffa) ? 1 : 0;
321+
$costo_ore = isset($tariffa['costo_ore']) ? $tariffa['costo_ore'] : $tipo_intervento['costo_orario'];
322+
$costo_km = isset($tariffa['costo_km']) ? $tariffa['costo_km'] : $tipo_intervento['costo_km'];
323+
$costo_dirittochiamata = isset($tariffa['costo_dirittochiamata']) ? $tariffa['costo_dirittochiamata'] : $tipo_intervento['costo_diritto_chiamata'];
324+
325+
echo '
326+
<tr data-id="'.$id_tipo.'">
327+
<td>'.$tipo_intervento['title'].'</td>
328+
<td class="text-center">
329+
{[ "type": "checkbox", "name": "tariffa_attiva['.$id_tipo.']", "value": "'.$attivo.'", "class": "tariffa-checkbox" ]}
330+
</td>
331+
<td>
332+
{[ "type": "number", "name": "costo_ore['.$id_tipo.']", "value": "'.$costo_ore.'", "icon-after": "<i class=\'fa fa-euro\'></i>", "class": "costo-ore-'.$id_tipo.'" ]}
333+
</td>
334+
<td>
335+
{[ "type": "number", "name": "costo_km['.$id_tipo.']", "value": "'.$costo_km.'", "icon-after": "<i class=\'fa fa-euro\'></i>", "class": "costo-km-'.$id_tipo.'" ]}
336+
</td>
337+
<td>
338+
{[ "type": "number", "name": "costo_dirittochiamata['.$id_tipo.']", "value": "'.$costo_dirittochiamata.'", "icon-after": "<i class=\'fa fa-euro\'></i>", "class": "costo-dirittochiamata-'.$id_tipo.'" ]}
339+
</td>
340+
</tr>';
341+
}
342+
343+
echo '
344+
</tbody>
345+
</table>
346+
</div>
347+
</div>
348+
</div>
349+
</div>';
350+
}
351+
262352
echo '
263353
<!-- PULSANTI -->
264354
<div class="modal-footer">
@@ -373,4 +463,38 @@ function rimuoviSede(button) {
373463
});
374464
}).catch(swal.noop);
375465
}
466+
467+
function toggleTariffa(idTipo, attivo, costoOreStandard, costoKmStandard, costoDirittochiamataStandard) {
468+
let inputOre = input("costo_ore[" + idTipo + "]");
469+
let inputKm = input("costo_km[" + idTipo + "]");
470+
let inputDirittochiamata = input("costo_dirittochiamata[" + idTipo + "]");
471+
472+
if (attivo) {
473+
// Se attivo, abilita i campi
474+
inputOre.enable();
475+
inputKm.enable();
476+
inputDirittochiamata.enable();
477+
} else {
478+
// Se disattivo, disabilita i campi e imposta i valori standard
479+
inputOre.disable();
480+
inputKm.disable();
481+
inputDirittochiamata.disable();
482+
}
483+
}
484+
485+
$(document).ready(function() {
486+
// Inizializza lo stato dei campi al caricamento
487+
$(".tariffa-checkbox").each(function() {
488+
let idTipo = $(this).closest("tr").data("id");
489+
let attivo = $(this).is(":checked");
490+
toggleTariffa(idTipo, attivo);
491+
});
492+
493+
// Aggiunge event listener per il cambio del checkbox
494+
$(document).on("change", ".tariffa-checkbox", function() {
495+
let idTipo = $(this).closest("tr").data("id");
496+
let attivo = $(this).is(":checked");
497+
toggleTariffa(idTipo, attivo);
498+
});
499+
});
376500
</script>';

update/2_10.sql

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,17 @@ UPDATE `zz_prints_lang` SET `filename` = 'Travel register {nome} {targa}' WHERE
457457

458458
-- Aggiunta gestione delle scadenze per il pagamento automatico
459459
ALTER TABLE `co_pagamenti` ADD `registra_pagamento_automatico` BOOLEAN NOT NULL;
460-
INSERT INTO `zz_tasks` (`id`, `name`, `class`, `expression`, `next_execution_at`, `last_executed_at`, `created_at`, `updated_at`, `enabled`) VALUES (NULL, 'Pagamento automatico', 'Modules\\PrimaNota\\PagamentoAutomaticoTask', '0 */24 * * *', NULL, NULL, NULL, NULL, '1');
460+
INSERT INTO `zz_tasks` (`id`, `name`, `class`, `expression`, `next_execution_at`, `last_executed_at`, `created_at`, `updated_at`, `enabled`) VALUES (NULL, 'Pagamento automatico', 'Modules\\PrimaNota\\PagamentoAutomaticoTask', '0 */24 * * *', NULL, NULL, NULL, NULL, '1');
461+
462+
-- Creazione tabella per le tariffe delle sedi
463+
CREATE TABLE IF NOT EXISTS `in_tariffe_sedi` (
464+
`id` INT NOT NULL AUTO_INCREMENT,
465+
`idsede` INT NOT NULL,
466+
`idtipointervento` INT NOT NULL,
467+
`costo_ore` DECIMAL(12,4) NOT NULL,
468+
`costo_km` DECIMAL(12,4) NOT NULL,
469+
`costo_dirittochiamata` DECIMAL(12,4) NOT NULL,
470+
PRIMARY KEY (`id`)
471+
);
472+
ALTER TABLE `in_tariffe_sedi` ADD CONSTRAINT `in_tariffe_sedi_ibfk_1` FOREIGN KEY (`idsede`) REFERENCES `an_sedi`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
473+
ALTER TABLE `in_tariffe_sedi` ADD CONSTRAINT `in_tariffe_sedi_ibfk_2` FOREIGN KEY (`idtipointervento`) REFERENCES `in_tipiintervento`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;

0 commit comments

Comments
 (0)