diff --git a/modules/interventi/actions.php b/modules/interventi/actions.php index ba1d132a0..3738e2774 100644 --- a/modules/interventi/actions.php +++ b/modules/interventi/actions.php @@ -60,6 +60,7 @@ switch (post('op')) { $intervento->idsede_destinazione = post('idsede_destinazione'); $intervento->id_preventivo = post('idpreventivo'); $intervento->id_contratto = $idcontratto; + $intervento->id_ordine = post('idordine'); $intervento->id_documento_fe = post('id_documento_fe'); $intervento->num_item = post('num_item'); @@ -152,6 +153,7 @@ switch (post('op')) { $intervento->id_preventivo = post('idpreventivo'); $intervento->id_contratto = post('idcontratto'); + $intervento->id_ordine = post('idordine'); $intervento->richiesta = post('richiesta_add'); $intervento->idsede_destinazione = $idsede_destinazione; $intervento->data_scadenza = $data_scadenza; diff --git a/modules/interventi/add.php b/modules/interventi/add.php index b5ea915b7..db593374a 100755 --- a/modules/interventi/add.php +++ b/modules/interventi/add.php @@ -175,6 +175,10 @@ echo '
+
+ {[ "type": "select", "label": "'.tr('Ordine').'", "name": "idordine", "ajax-source": "ordini" ]} +
+
{[ "type": "timestamp", "label": "'.tr('Data/ora richiesta').'", "name": "data_richiesta", "required": 1, "value": "'.($data_richiesta ?: '-now-').'" ]}
@@ -182,14 +186,14 @@ echo '
{[ "type": "select", "label": "'.tr('Tipo').'", "name": "idtipointervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione ASC", "value": "'.$id_tipo.'", "ajax-source": "tipiintervento" ]}
- -
- {[ "type": "select", "label": "'.tr('Stato').'", "name": "idstatointervento", "required": 1, "values": "query=SELECT idstatointervento AS id, descrizione, colore AS _bgcolor_ FROM in_statiintervento WHERE deleted_at IS NULL", "value": "'.$id_stato.'" ]} -
-
+
+ {[ "type": "select", "label": "'.tr('Stato').'", "name": "idstatointervento", "required": 1, "values": "query=SELECT idstatointervento AS id, descrizione, colore AS _bgcolor_ FROM in_statiintervento WHERE deleted_at IS NULL", "value": "'.$id_stato.'" ]} +
+ +
{[ "type": "ckeditor", "label": "'.tr('Richiesta').'", "name": "richiesta_add", "required": 1, "value": "'.$richiesta.'", "extra": "style=\'max-height:80px;\'" ]}
'; diff --git a/modules/interventi/edit.php b/modules/interventi/edit.php index 19730ebeb..5b96de230 100755 --- a/modules/interventi/edit.php +++ b/modules/interventi/edit.php @@ -103,6 +103,24 @@ echo '
+ +
+
'; + + $idcontratto_riga = $dbo->fetchOne('SELECT id FROM co_promemoria WHERE idintervento='.prepare($id_record))['id']; + + if (!empty($record['idordine'])) { + echo ' + '.Modules::link('Ordini cliente', $record['idordine'], null, null, 'class="pull-right"'); + } + echo ' + + {[ "type": "select", "label": "'.tr('Ordine').'", "name": "idordine", "value": "'.$record['id_ordine'].'", "ajax-source": "ordini", "select-options": '.json_encode(['idanagrafica' => $record['idanagrafica']]).', "readonly": "'.$record['flag_completato'].'" ]} + + +
+
+ '; diff --git a/modules/interventi/init.php b/modules/interventi/init.php index 8d02d895d..5aebcfe74 100755 --- a/modules/interventi/init.php +++ b/modules/interventi/init.php @@ -30,6 +30,7 @@ if (isset($id_record)) { IF((in_interventi.idsede_destinazione = 0), (SELECT idzona FROM an_anagrafiche WHERE idanagrafica = in_interventi.idanagrafica), (SELECT idzona FROM an_sedi WHERE id = in_interventi.idsede_destinazione)) AS idzona, (SELECT colore FROM in_statiintervento WHERE idstatointervento=in_interventi.idstatointervento) AS colore, in_interventi.id_preventivo as idpreventivo, - in_interventi.id_contratto as idcontratto + in_interventi.id_contratto as idcontratto, + in_interventi.id_ordine as idordine FROM in_interventi WHERE id='.prepare($id_record)); } diff --git a/modules/ordini/ajax/select.php b/modules/ordini/ajax/select.php new file mode 100644 index 000000000..effa90414 --- /dev/null +++ b/modules/ordini/ajax/select.php @@ -0,0 +1,48 @@ +. + */ + +include_once __DIR__.'/../../../core.php'; + +switch ($resource) { + /* + * Opzioni utilizzate: + * - idanagrafica + */ + case 'ordini': + if (isset($superselect['idanagrafica'])) { + $query = 'SELECT or_ordini.id AS id, or_ordini.idanagrafica, CONCAT("Ordine ", numero, " del ", DATE_FORMAT(data, "%d/%m/%Y"), " [", (SELECT `descrizione` FROM `or_statiordine` WHERE `or_statiordine`.`id` = `idstatoordine`) , "]") AS descrizione, (SELECT SUM(subtotale) FROM or_righe_ordini WHERE idordine=or_ordini.id GROUP BY idordine) AS totale, (SELECT SUM(sconto) FROM or_righe_ordini WHERE idordine=or_ordini.id GROUP BY idordine) AS sconto FROM or_ordini INNER JOIN an_anagrafiche ON or_ordini.idanagrafica=an_anagrafiche.idanagrafica |where| ORDER BY id'; + + foreach ($elements as $element) { + $filter[] = 'id='.prepare($element); + } + + if (empty($elements)) { + $where[] = 'an_anagrafiche.idanagrafica='.prepare($superselect['idanagrafica']); + + $stato = !empty($superselect['stato']) ? $superselect['stato'] : 'completato'; + $where[] = 'idstatoordine IN (SELECT `id` FROM `or_statiordine` WHERE '.$stato.' = 1)'; + } + + if (!empty($search)) { + $search_fields[] = 'nome LIKE '.prepare('%'.$search.'%'); + } + } + + break; +} \ No newline at end of file diff --git a/modules/ordini/plugins/ordini.consuntivo.php b/modules/ordini/plugins/ordini.consuntivo.php new file mode 100644 index 000000000..bfda56557 --- /dev/null +++ b/modules/ordini/plugins/ordini.consuntivo.php @@ -0,0 +1,288 @@ +. + */ + +include_once __DIR__.'/../../../core.php'; + +use Modules\Interventi\Intervento; + +// CONSUNTIVO + +// Tabella con riepilogo interventi +$interventi = Intervento::where('id_ordine', $id_record)->get(); +if (!empty($interventi)) { + echo ' + + + + + + + + + '; + + // Tabella con i dati + foreach ($interventi as $intervento) { + // Riga per il singolo intervento + echo ' + + + + + + + + + + + + + '; + + // Riga con dettagli + echo ' + + + '; + } + + $array_interventi = $interventi->toArray(); + $totale_ore = sum(array_column($array_interventi, 'ore_totali')); + $totale_km = sum(array_column($array_interventi, 'km_totali')); + $totale_costo = sum(array_column($array_interventi, 'spesa')); + $totale_addebito = sum(array_column($array_interventi, 'imponibile')); + $totale = sum(array_column($array_interventi, 'totale_imponibile')); + + // Totali + echo ' + + '; + + echo ' + '; + + echo ' + '; + + echo ' + '; + + echo ' + '; + + echo ' + + '; + + $stati = $interventi->groupBy('idstatointervento'); + if (count($stati) > 0) { + // Totali per stato + echo ' + + + '; + + foreach ($stati as $interventi_collegati) { + $stato = $interventi_collegati->first()->stato; + $totale_stato = sum(array_column($interventi_collegati->toArray(), 'totale_imponibile')); + + echo ' + + + + + + + '; + } + } + + echo ' +
'.tr('Attività').''.tr('Ore').''.tr('Km').''.tr('Costo').''.tr('Addebito').''.tr('Tot. scontato').'
+ + '.Modules::link('Interventi', $intervento->id, tr('Intervento num. _NUM_ del _DATE_', [ + '_NUM_' => $intervento->codice, + '_DATE_' => Translator::dateToLocale($intervento->inizio), + ])).' + + '.numberFormat($intervento->ore_totali).' + + '.numberFormat($intervento->km_totali).' + + '.moneyFormat($intervento->spesa).' + + '.moneyFormat($intervento->imponibile).' + + '.moneyFormat($intervento->totale_imponibile).' +
'; + + // Lettura sessioni di lavoro + $sessioni = $intervento->sessioni; + if (!empty($sessioni)) { + echo ' + + + + + + + + + + + + + '; + + foreach ($sessioni as $sessione) { + // Visualizzo lo sconto su ore o km se c'è + $sconto_ore = !empty($sessione->sconto_totale_manodopera) ? '
'.moneyFormat(-$sessione->sconto_totale_manodopera).'' : ''; + $sconto_km = !empty($sessione->sconto_totale_viaggio) ? '
'.moneyFormat(-$sessione->sconto_totale_viaggio).'' : ''; + + echo ' + + + + + + + + + + + + '; + } + + echo ' +
'.tr('Tecnico').''.tr('Tipo attività').''.tr('Ore').''.tr('Km').''.tr('Costo ore').''.tr('Costo km').''.tr('Diritto ch.').''.tr('Prezzo ore').''.tr('Prezzo km').''.tr('Diritto ch.').'
'.$sessione->anagrafica->ragione_sociale.''.$sessione->tipo->descrizione.''.numberFormat($sessione->ore).''.numberFormat($sessione->km).''.moneyFormat($sessione->costo_manodopera).''.moneyFormat($sessione->costo_viaggio).''.moneyFormat($sessione->costo_diritto_chiamata).''.moneyFormat($sessione->prezzo_manodopera).$sconto_ore.''.moneyFormat($sessione->prezzo_viaggio).$sconto_km.''.moneyFormat($sessione->prezzo_diritto_chiamata).'
'; + } + + // Lettura articoli utilizzati + $articoli = $intervento->articoli; + if (!$articoli->isEmpty()) { + echo ' + + + + + + + '; + + foreach ($articoli as $articolo) { + $sconto = !empty($articolo->sconto) ? '
'.moneyFormat(-$articolo->sconto).'' : ''; + + echo ' + + + + + + '; + } + + echo ' +
'.tr('Materiale').''.tr('Q.tà').''.tr('Prezzo di acquisto').''.tr('Prezzo di vendita').'
+ '.Modules::link('Articoli', $articolo->idarticolo, $articolo->descrizione).' + '.numberFormat($articolo->qta, 'qta').''.moneyFormat($articolo->spesa).''.moneyFormat($articolo->imponibile).$sconto.'
'; + } + + // Lettura spese aggiuntive + $righe = $intervento->righe; + if (!$righe->isEmpty()) { + echo ' + + + + + + + '; + + foreach ($righe as $riga) { + $sconto = !empty($riga->sconto) ? '
'.moneyFormat(-$riga->sconto).'' : ''; + + echo ' + + + + + + '; + } + + echo ' +
'.tr('Altre spese').''.tr('Q.tà').''.tr('Prezzo di acquisto').''.tr('Prezzo di vendita').'
+ '.$riga->descrizione.' + '.numberFormat($riga->qta, 'qta').''.moneyFormat($riga->spesa).''.moneyFormat($riga->imponibile).$sconto.'
'; + } + + echo ' +
+ '.tr('Totale').' + + '.numberFormat($totale_ore).' + + '.numberFormat($totale_km).' + + '.moneyFormat($totale_costo).' + + '.moneyFormat($totale_addebito).' + + '.moneyFormat($totale).' +
+
'.tr('Totale interventi per stato', [], ['upper' => true]).' +
+ '.$stato->descrizione.': + + '.moneyFormat($totale_stato).' +
'; +} + +// Bilancio del preventivo +$budget = $ordine->totale_imponibile; +$diff = sum($budget, -$totale); + +echo ' +
+
+ '.tr('Rapporto budget/spesa').':
'; +if ($diff > 0) { + echo ' + +'.moneyFormat($diff).''; +} elseif ($diff < 0) { + echo ' + '.moneyFormat($diff).''; +} else { + echo ' + '.moneyFormat($diff).''; +} + echo ' +
+

+
'; + +/* + Stampa consuntivo +*/ +echo ' +
+ '.Prints::getLink('Consuntivo ordine', $id_record, 'btn-primary', tr('Stampa consuntivo')).' +
'; \ No newline at end of file diff --git a/modules/ordini/src/Ordine.php b/modules/ordini/src/Ordine.php index b3b3b82d7..c66f22565 100755 --- a/modules/ordini/src/Ordine.php +++ b/modules/ordini/src/Ordine.php @@ -26,6 +26,7 @@ use Modules\DDT\DDT; use Traits\RecordTrait; use Traits\ReferenceTrait; use Util\Generator; +use Modules\Interventi\Intervento; class Ordine extends Document { @@ -148,6 +149,11 @@ class Ordine extends Document return $this->hasMany(Components\Descrizione::class, 'idordine'); } + public function interventi() + { + return $this->hasMany(Intervento::class, 'id_ordine'); + } + /** * Effettua un controllo sui campi del documento. * Viene richiamato dalle modifiche alle righe del documento. diff --git a/templates/ordini_cons/bottom.php b/templates/ordini_cons/bottom.php new file mode 100644 index 000000000..ee5ccfd70 --- /dev/null +++ b/templates/ordini_cons/bottom.php @@ -0,0 +1,66 @@ +. + */ + +include_once __DIR__.'/../riepilogo_interventi/bottom.php'; + +$budget = get_imponibile_ordine($id_record); + +$rapporto = floatval($budget) - floatval($somma_totale_imponibile); + +if ($pricing && empty($options['dir'])) { + // Totale imponibile + echo ' +'; + + // TOTALE + echo ' + + + + '; + + // BUDGET + echo ' + + + + '; + + // RAPPORTO + echo ' + + + + '; + + echo ' +
+ '.tr('Totale consuntivo (no iva)', [], ['upper' => true]).': + + '.moneyFormat($somma_totale_imponibile).' +
+ '.tr('Budget (no IVA)', [], ['upper' => true]).': + + '.moneyFormat($budget).' +
+ '.tr('Rapporto budget/spesa (no IVA)', [], ['upper' => true]).': + + '.moneyFormat($rapporto).' +
'; +} diff --git a/templates/ordini_cons/init.php b/templates/ordini_cons/init.php new file mode 100644 index 000000000..d15783aa5 --- /dev/null +++ b/templates/ordini_cons/init.php @@ -0,0 +1,30 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +use Modules\Ordini\Ordine; + +$documento = Ordine::find($id_record); +$records = $documento->interventi; + +$id_cliente = $documento['idanagrafica']; +$id_sede = $documento['idsede']; + +$pricing = $options['pricing']; diff --git a/templates/ordini_cons/piece.php b/templates/ordini_cons/piece.php new file mode 100644 index 000000000..bd834a869 --- /dev/null +++ b/templates/ordini_cons/piece.php @@ -0,0 +1,20 @@ +. + */ + +include __DIR__.'/../riepilogo_interventi/piece.php'; diff --git a/templates/ordini_cons/top.php b/templates/ordini_cons/top.php new file mode 100644 index 000000000..41975153e --- /dev/null +++ b/templates/ordini_cons/top.php @@ -0,0 +1,83 @@ +. + */ + +include_once __DIR__.'/../../core.php'; + +echo ' +
+
+
+

'.tr('Consuntivo', [], ['upper' => true]).'

+ '.tr('Ordine num. _NUM_ del _DATE_', [ + '_NUM_' => (!empty($documento['numero_esterno'])?$documento['numero_esterno']:$documento['numero']), + '_DATE_' => Translator::dateToLocale($documento['data']), + ], ['upper' => true]).' +
+
+ +
+ + + + + + + + + + + + + + +
+

'.tr('Spett.le', [], ['upper' => true]).'

+

$c_ragionesociale$

+

$c_indirizzo$ $c_citta_full$

+
+

'.tr('Partita IVA', [], ['upper' => true]).'

+
+ $c_piva$ +
+

'.tr('Codice fiscale', [], ['upper' => true]).'

+
+ $c_codicefiscale$ +
+
+
'; + +// Descrizione +if (!empty($documento['descrizione'])) { + echo ' +

'.nl2br($documento['descrizione']).'

+
'; +} + +echo ' + + + + + + + + + + + '; diff --git a/update/2_4_22.sql b/update/2_4_22.sql index d73f6b0a9..c47f6c519 100644 --- a/update/2_4_22.sql +++ b/update/2_4_22.sql @@ -304,3 +304,14 @@ UPDATE `zz_views` SET `query` = '(righe.totale + `co_documenti`.`rivalsainps` + UPDATE `zz_views` SET `order` = 5, `name`='Conto avere_new' WHERE `name`='Conto dare'; UPDATE `zz_views` SET `order` = 8, `name`='Conto dare' WHERE `name`='Conto avere'; UPDATE `zz_views` SET `name`='Conto avere' WHERE `name`='Conto avere_new'; + +-- Aggiunta campo per scelta ordine in intervento +ALTER TABLE `in_interventi` ADD `id_ordine` INT NOT NULL AFTER `id_contratto`; + +-- Aggiunta plugin consuntivo per ordini +INSERT INTO `zz_plugins` (`id`, `name`, `title`, `idmodule_from`, `idmodule_to`, `position`, `script`, `enabled`, `default`, `order`, `compatibility`, `version`, `options2`, `options`, `directory`, `help`) VALUES +(NULL, 'Consuntivo', 'Consuntivo', (SELECT `id` FROM `zz_modules` WHERE name='Ordini cliente'), (SELECT `id` FROM `zz_modules` WHERE name='Ordini cliente'), 'tab', 'ordini.consuntivo.php', 1, 0, 0, '', '', NULL, NULL, '', ''); + +-- Stampa consuntivo ordini +INSERT INTO `zz_prints` (`id`, `id_module`, `is_record`, `name`, `title`, `filename`, `directory`, `previous`, `options`, `icon`, `version`, `compatibility`, `order`, `predefined`, `default`, `enabled`) VALUES +(NULL, (SELECT `id` FROM `zz_modules` WHERE name='Ordini cliente'), 1, 'Consuntivo ordine', 'Consuntivo ordine', 'Consuntivo ordine num. {numero} del {data}', 'ordini_cons', 'idordine', '{\"pricing\":true}', 'fa fa-print', '', '', 0, 0, 1, 1); \ No newline at end of file
'.tr('Documento', [], ['upper' => true]).''.tr('Imponibile', [], ['upper' => true]).''.tr('Sconto', [], ['upper' => true]).''.tr('Totale imponibile', [], ['upper' => true]).'