diff --git a/composer.json b/composer.json index 00756c642..b84f6e2c4 100644 --- a/composer.json +++ b/composer.json @@ -59,6 +59,7 @@ }, "files": [ "lib/functions.php", + "lib/common.php", "lib/helpers.php", "lib/util.php", "lib/deprecated.php" diff --git a/lib/common.php b/lib/common.php new file mode 100644 index 000000000..c44ec7be0 --- /dev/null +++ b/lib/common.php @@ -0,0 +1,277 @@ +getPrecision(); + + $bcadd = function_exists('bcadd'); + + foreach ($array as $value) { + $value = round($value, $decimals); + + if ($bcadd) { + $result = bcadd($result, $value, $decimals); + } else { + $result += $value; + } + } + + return floatval($result); +} + +function aggiorna_sconto($tables, $fields, $id_record, $options = []) +{ + $dbo = Database::getConnection(); + + $descrizione = tr('Sconto', [], ['upper' => true]); + + // Rimozione dello sconto precedente + $dbo->query('DELETE FROM '.$tables['row'].' WHERE sconto_globale = 1 AND '.$fields['row'].'='.prepare($id_record)); + + // Individuazione del nuovo sconto + $sconto = $dbo->select($tables['parent'], ['sconto_globale', 'tipo_sconto_globale'], [$fields['parent'] => $id_record]); + $sconto[0]['sconto_globale'] = floatval($sconto[0]['sconto_globale']); + + // Aggiorno l'eventuale sconto gestendolo con le righe in fattura + $iva = 0; + + if (!empty($sconto[0]['sconto_globale'])) { + if ($sconto[0]['tipo_sconto_globale'] == 'PRC') { + $rs = $dbo->fetchArray('SELECT SUM(subtotale - sconto) AS imponibile, SUM(iva) AS iva FROM (SELECT '.$tables['row'].'.subtotale, '.$tables['row'].'.sconto, '.$tables['row'].'.iva FROM '.$tables['row'].' WHERE '.$fields['row'].'='.prepare($id_record).') AS t'); + $subtotale = $rs[0]['imponibile']; + $iva += $rs[0]['iva'] / 100 * $sconto[0]['sconto_globale']; + $subtotale = -$subtotale / 100 * $sconto[0]['sconto_globale']; + + $descrizione = $descrizione.' '.Translator::numberToLocale($sconto[0]['sconto_globale']).'%'; + } else { + $rs = $dbo->fetchArray('SELECT SUM(subtotale - sconto) AS imponibile, SUM(iva) AS iva FROM (SELECT '.$tables['row'].'.subtotale, '.$tables['row'].'.sconto, '.$tables['row'].'.iva FROM '.$tables['row'].' WHERE '.$fields['row'].'='.prepare($id_record).') AS t'); + $subtotale = $rs[0]['imponibile']; + $iva += $sconto[0]['sconto_globale'] * $rs[0]['iva'] / $subtotale; + + $subtotale = -$sconto[0]['sconto_globale']; + } + + // Calcolo dell'IVA da scontare + $idiva = setting('Iva predefinita'); + $rsi = $dbo->select('co_iva', ['descrizione', 'percentuale'], ['id' => $idiva]); + + $values = [ + $fields['row'] => $id_record, + 'descrizione' => $descrizione, + 'subtotale' => $subtotale, + 'qta' => 1, + 'idiva' => $idiva, + 'desc_iva' => $rsi[0]['descrizione'], + 'iva' => -$iva, + 'sconto_globale' => 1, + '#order' => '(SELECT IFNULL(MAX(`order`) + 1, 0) FROM '.$tables['row'].' AS t WHERE '.$fields['row'].'='.prepare($id_record).')', + ]; + + $dbo->insert($tables['row'], $values); + } +} + +function controlla_seriali($field, $id_riga, $old_qta, $new_qta, $dir) +{ + $dbo = Database::getConnection(); + + $new_qta = abs($new_qta); + $old_qta = abs($old_qta); + + if ($old_qta >= $new_qta) { + // Controllo sulla possibilità di rimuovere i seriali (se non utilizzati da documenti di vendita) + if ($dir == 'uscita' && $new_qta < count(seriali_non_rimuovibili($field, $id_riga, $dir))) { + return false; + } else { + // Controllo sul numero di seriali effettivi da rimuovere + $count = $dbo->fetchArray('SELECT COUNT(*) AS tot FROM mg_prodotti WHERE '.$field.'='.prepare($id_riga))[0]['tot']; + if ($new_qta < $count) { + $deletes = $dbo->fetchArray("SELECT id FROM mg_prodotti WHERE serial NOT IN (SELECT serial FROM mg_prodotti WHERE dir = 'entrata' AND ".$field.'!='.prepare($id_riga).') AND '.$field.'='.prepare($id_riga).' ORDER BY serial DESC LIMIT '.abs($count - $new_qta)); + + // Rimozione + foreach ($deletes as $delete) { + $dbo->query('DELETE FROM mg_prodotti WHERE id = '.prepare($delete['id'])); + } + } + } + } + + return true; +} + +/** + * Individua i seriali non rimuovibili poichè utilizzati in documenti rilasciati. + * + * @param string $field + * @param int $id_riga + * @param string $dir + * + * @return array + */ +function seriali_non_rimuovibili($field, $id_riga, $dir) +{ + $dbo = Database::getConnection(); + + $results = []; + + if ($dir == 'uscita') { + $results = $dbo->fetchArray("SELECT serial FROM mg_prodotti WHERE serial IN (SELECT serial FROM mg_prodotti WHERE dir = 'entrata') AND ".$field.'='.prepare($id_riga)); + } + + return $results; +} + +/** + * Calcola gli sconti in modo automatico. + * + * @param array $data + * + * @return float + */ +function calcola_sconto($data) +{ + if ($data['tipo'] == 'PRC') { + $result = 0; + + $price = floatval($data['prezzo']); + + $percentages = explode('+', $data['sconto']); + foreach ($percentages as $percentage) { + $discount = $price / 100 * floatval($percentage); + + $result += $discount; + $price -= $discount; + } + } else { + $result = floatval($data['sconto']); + } + + if (!empty($data['qta'])) { + $result = $result * $data['qta']; + } + + return $result; +} + +/** + * Restistuisce le informazioni sull'eventuale riferimento ai documenti. + * + * @param array $data + * @param string $dir + * + * @return array + */ +function doc_references($info, $dir, $ignore = []) +{ + $dbo = Database::getConnection(); + + // Rimozione valori da non controllare + foreach ($ignore as $field) { + if (isset($info[$field])) { + unset($info[$field]); + } + } + + $module = null; + $id = null; + + // Ordine + if (!empty($info['idordine'])) { + $data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM or_ordini WHERE id=".prepare($info['idordine'])); + + $module = ($dir == 'entrata') ? 'Ordini cliente' : 'Ordini fornitore'; + $id = $info['idordine']; + + $document = tr('Ordine'); + } + + // DDT + elseif (!empty($info['idddt'])) { + $data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM dt_ddt WHERE id=".prepare($info['idddt'])); + + $module = ($dir == 'entrata') ? 'Ddt di vendita' : 'Ddt di acquisto'; + $id = $info['idddt']; + + $document = tr('Ddt'); + } + + // Preventivo + elseif (!empty($info['idpreventivo'])) { + $data = $dbo->fetchArray('SELECT numero, data_bozza AS data FROM co_preventivi WHERE id='.prepare($info['idpreventivo'])); + + $module = 'Preventivi'; + $id = $info['idpreventivo']; + + $document = tr('Preventivo'); + } + + // Contratto + elseif (!empty($info['idcontratto'])) { + $data = $dbo->fetchArray('SELECT numero, data_bozza AS data FROM co_contratti WHERE id='.prepare($info['idcontratto'])); + + $module = 'Contratti'; + $id = $info['idcontratto']; + + $document = tr('Contratto'); + } + + // Intervento + elseif (!empty($info['idintervento'])) { + $data = $dbo->fetchArray('SELECT codice AS numero, IFNULL( (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE in_interventi_tecnici.idintervento=in_interventi.id), data_richiesta) AS data FROM in_interventi WHERE id='.prepare($info['idintervento'])); + + $module = 'Interventi'; + $id = $info['idintervento']; + + $document = tr('Intervento'); + } + + // Testo relativo + if (!empty($module) && !empty($id)) { + $document = Stringy\Stringy::create($document)->toLowerCase(); + + if (!empty($data)) { + $description = tr('Rif. _DOC_ num. _NUM_ del _DATE_', [ + '_DOC_' => $document, + '_NUM_' => $data[0]['numero'], + '_DATE_' => Translator::dateToLocale($data[0]['data']), + ]); + } else { + $description = tr('_DOC_ di riferimento _ID_ eliminato', [ + '_DOC_' => $document->upperCaseFirst(), + '_ID_' => $id, + ]); + } + + return [ + 'module' => $module, + 'id' => $id, + 'description' => $description, + ]; + } + + return []; +} diff --git a/lib/deprecated.php b/lib/deprecated.php index c5c38a598..4fc4fbfe0 100644 --- a/lib/deprecated.php +++ b/lib/deprecated.php @@ -35,3 +35,156 @@ function get_var($nome, $sezione = null, $descrizione = false, $again = false) { return setting($nome, $again); } + +/** + * Crea le thumbnails di $filename da dentro $dir e le salva in $dir. + * + * @param string $tmp + * @param string $filename + * @param string $dir + * + * @return bool + */ +function create_thumbnails($tmp, $filename, $dir) +{ + $infos = pathinfo($filename); + $name = $infos['filename']; + $extension = strtolower($infos['extension']); + + if (!directory($dir)) { + return false; + } + + $driver = extension_loaded('gd') ? 'gd' : 'imagick'; + Intervention\Image\ImageManagerStatic::configure(['driver' => $driver]); + + $img = Intervention\Image\ImageManagerStatic::make($tmp); + + $img->resize(600, null, function ($constraint) { + $constraint->aspectRatio(); + }); + $img->save(slashes($dir.'/'.$name.'.'.$extension)); + + $img->resize(250, null, function ($constraint) { + $constraint->aspectRatio(); + }); + $img->save(slashes($dir.'/'.$name.'_thumb250.'.$extension)); + + $img->resize(100, null, function ($constraint) { + $constraint->aspectRatio(); + }); + $img->save(slashes($dir.'/'.$name.'_thumb100.'.$extension)); + + return true; +} + +/** + * Verifica che il nome del file non sia già usato nella cartella inserita, nel qual caso aggiungo un suffisso. + * + * @param string $filename + * @param string $dir + * + * @return string + */ +function unique_filename($filename, $dir) +{ + $f = pathinfo($filename); + $suffix = 1; + while (file_exists($dir.'/'.$filename)) { + $filename = $f['filename'].'_'.$suffix.'.'.$f['extension']; + ++$suffix; + } + + return $filename; +} + +/** + * Individua la differenza tra le date indicate. + * $interval può essere: + * yyyy - Number of full years + * q - Number of full quarters + * m - Number of full months + * y - Difference between day numbers + * (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".) + * d - Number of full days + * w - Number of full weekdays + * ww - Number of full weeks + * h - Number of full hours + * n - Number of full minutes + * s - Number of full seconds (default). + * + * @param unknown $interval + * @param unknown $datefrom + * @param unknown $dateto + * @param string $using_timestamps + */ +function datediff($interval, $datefrom, $dateto, $using_timestamps = false) +{ + if (!$using_timestamps) { + $datefrom = strtotime($datefrom, 0); + $dateto = strtotime($dateto, 0); + } + $difference = $dateto - $datefrom; // Difference in seconds + switch ($interval) { + case 'yyyy': // Number of full years + $years_difference = floor($difference / 31536000); + if (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom), date('j', $datefrom), date('Y', $datefrom) + $years_difference) > $dateto) { + --$years_difference; + } + if (mktime(date('H', $dateto), date('i', $dateto), date('s', $dateto), date('n', $dateto), date('j', $dateto), date('Y', $dateto) - ($years_difference + 1)) > $datefrom) { + ++$years_difference; + } + $datediff = $years_difference; + break; + case 'q': // Number of full quarters + $quarters_difference = floor($difference / 8035200); + while (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom) + ($quarters_difference * 3), date('j', $dateto), date('Y', $datefrom)) < $dateto) { + ++$months_difference; + } + --$quarters_difference; + $datediff = $quarters_difference; + break; + case 'm': // Number of full months + $months_difference = floor($difference / 2678400); + while (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom) + ($months_difference), date('j', $dateto), date('Y', $datefrom)) < $dateto) { + ++$months_difference; + } + --$months_difference; + $datediff = $months_difference; + break; + case 'y': // Difference between day numbers + $datediff = date('z', $dateto) - date('z', $datefrom); + break; + case 'd': // Number of full days + $datediff = floor($difference / 86400); + break; + case 'w': // Number of full weekdays + $days_difference = floor($difference / 86400); + $weeks_difference = floor($days_difference / 7); // Complete weeks + $first_day = date('w', $datefrom); + $days_remainder = floor($days_difference % 7); + $odd_days = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder? + if ($odd_days > 7) { // Sunday + --$days_remainder; + } + if ($odd_days > 6) { // Saturday + --$days_remainder; + } + $datediff = ($weeks_difference * 5) + $days_remainder; + break; + case 'ww': // Number of full weeks + $datediff = floor($difference / 604800); + break; + case 'h': // Number of full hours + $datediff = floor($difference / 3600); + break; + case 'n': // Number of full minutes + $datediff = floor($difference / 60); + break; + default: // Number of full seconds (default) + $datediff = $difference; + break; + } + + return $datediff; +} diff --git a/lib/functions.php b/lib/functions.php index caf1e5e6f..9476e7e4e 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -1,5 +1,10 @@ - * - * @version 1.0.1 - * - * @see http://aidanlister.com/repos/v/function.copyr.php - * - * @param string $source - * Source path - * @param string $dest - * Destination path - * @param array|string $ignores - * Paths to ingore + * @param string $source Source path + * @param string $dest Destination path + * @param array|string $ignores Paths to ingore * * @return bool Returns TRUE on success, FALSE on failure */ @@ -209,97 +219,6 @@ function checkZip($zip_file) } } -/** - * Individua la differenza tra le date indicate. - * $interval può essere: - * yyyy - Number of full years - * q - Number of full quarters - * m - Number of full months - * y - Difference between day numbers - * (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".) - * d - Number of full days - * w - Number of full weekdays - * ww - Number of full weeks - * h - Number of full hours - * n - Number of full minutes - * s - Number of full seconds (default). - * - * @param unknown $interval - * @param unknown $datefrom - * @param unknown $dateto - * @param string $using_timestamps - */ -function datediff($interval, $datefrom, $dateto, $using_timestamps = false) -{ - if (!$using_timestamps) { - $datefrom = strtotime($datefrom, 0); - $dateto = strtotime($dateto, 0); - } - $difference = $dateto - $datefrom; // Difference in seconds - switch ($interval) { - case 'yyyy': // Number of full years - $years_difference = floor($difference / 31536000); - if (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom), date('j', $datefrom), date('Y', $datefrom) + $years_difference) > $dateto) { - --$years_difference; - } - if (mktime(date('H', $dateto), date('i', $dateto), date('s', $dateto), date('n', $dateto), date('j', $dateto), date('Y', $dateto) - ($years_difference + 1)) > $datefrom) { - ++$years_difference; - } - $datediff = $years_difference; - break; - case 'q': // Number of full quarters - $quarters_difference = floor($difference / 8035200); - while (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom) + ($quarters_difference * 3), date('j', $dateto), date('Y', $datefrom)) < $dateto) { - ++$months_difference; - } - --$quarters_difference; - $datediff = $quarters_difference; - break; - case 'm': // Number of full months - $months_difference = floor($difference / 2678400); - while (mktime(date('H', $datefrom), date('i', $datefrom), date('s', $datefrom), date('n', $datefrom) + ($months_difference), date('j', $dateto), date('Y', $datefrom)) < $dateto) { - ++$months_difference; - } - --$months_difference; - $datediff = $months_difference; - break; - case 'y': // Difference between day numbers - $datediff = date('z', $dateto) - date('z', $datefrom); - break; - case 'd': // Number of full days - $datediff = floor($difference / 86400); - break; - case 'w': // Number of full weekdays - $days_difference = floor($difference / 86400); - $weeks_difference = floor($days_difference / 7); // Complete weeks - $first_day = date('w', $datefrom); - $days_remainder = floor($days_difference % 7); - $odd_days = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder? - if ($odd_days > 7) { // Sunday - --$days_remainder; - } - if ($odd_days > 6) { // Saturday - --$days_remainder; - } - $datediff = ($weeks_difference * 5) + $days_remainder; - break; - case 'ww': // Number of full weeks - $datediff = floor($difference / 604800); - break; - case 'h': // Number of full hours - $datediff = floor($difference / 3600); - break; - case 'n': // Number of full minutes - $datediff = floor($difference / 60); - break; - default: // Number of full seconds (default) - $datediff = $difference; - break; - } - - return $datediff; -} - /** * Recupera informazioni sistema operativo dell'utente. * @@ -337,68 +256,6 @@ function getOS() return tr('Altro'); } -/** - * Verifica che il nome del file non sia già usato nella cartella inserita, nel qual caso aggiungo un suffisso. - * - * @param string $filename - * @param string $dir - * - * @return string - */ -function unique_filename($filename, $dir) -{ - $f = pathinfo($filename); - $suffix = 1; - while (file_exists($dir.'/'.$filename)) { - $filename = $f['filename'].'_'.$suffix.'.'.$f['extension']; - ++$suffix; - } - - return $filename; -} - -/** - * Crea le thumbnails di $filename da dentro $dir e le salva in $dir. - * - * @param string $tmp - * @param string $filename - * @param string $dir - * - * @return bool - */ -function create_thumbnails($tmp, $filename, $dir) -{ - $infos = pathinfo($filename); - $name = $infos['filename']; - $extension = strtolower($infos['extension']); - - if (!directory($dir)) { - return false; - } - - $driver = extension_loaded('gd') ? 'gd' : 'imagick'; - Intervention\Image\ImageManagerStatic::configure(['driver' => $driver]); - - $img = Intervention\Image\ImageManagerStatic::make($tmp); - - $img->resize(600, null, function ($constraint) { - $constraint->aspectRatio(); - }); - $img->save(slashes($dir.'/'.$name.'.'.$extension)); - - $img->resize(250, null, function ($constraint) { - $constraint->aspectRatio(); - }); - $img->save(slashes($dir.'/'.$name.'_thumb250.'.$extension)); - - $img->resize(100, null, function ($constraint) { - $constraint->aspectRatio(); - }); - $img->save(slashes($dir.'/'.$name.'_thumb100.'.$extension)); - - return true; -} - /** * Ottiene l'indirizzo IP del client. * @@ -483,28 +340,6 @@ function translateTemplate() echo $template; } -/** - * Sostituisce la prima occorenza di una determinata stringa. - * - * @param string $str_pattern - * @param string $str_replacement - * @param string $string - * - * @since 2.3 - * - * @return string - */ -function str_replace_once($str_pattern, $str_replacement, $string) -{ - if (strpos($string, $str_pattern) !== false) { - $occurrence = strpos($string, $str_pattern); - - return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern)); - } - - return $string; -} - /** * Restituisce il percorso del filesystem in modo indipendente dal sistema operativo. * @@ -531,43 +366,6 @@ function isAjaxRequest() return \Whoops\Util\Misc::isAjaxRequest() && filter('ajax') !== null; } -/** - * Esegue una somma precisa tra due interi/array. - * - * @param array|float $first - * @param array|float $second - * @param int $decimals - * - * @since 2.3 - * - * @return float - */ -function sum($first, $second = null, $decimals = 4) -{ - $first = (array) $first; - $second = (array) $second; - - $array = array_merge($first, $second); - - $result = 0; - - $decimals = is_numeric($decimals) ? $decimals : Translator::getFormatter()->getPrecision(); - - $bcadd = function_exists('bcadd'); - - foreach ($array as $value) { - $value = round($value, $decimals); - - if ($bcadd) { - $result = bcadd($result, $value, $decimals); - } else { - $result += $value; - } - } - - return floatval($result); -} - /** * Effettua le operazioni automatiche di redirect tra le pagine. * diff --git a/lib/helpers.php b/lib/helpers.php index ad13c5583..bb38174d1 100644 --- a/lib/helpers.php +++ b/lib/helpers.php @@ -1,5 +1,11 @@ fetchArray($q); $prezzo_ore = 0.00; for ($i = 0; $i < count($rs); ++$i) { $prezzo_ore_unitario = $rs[$i]['prezzo_ore_unitario']; + $ore = calcola_ore_intervento($orario_inizio, $orario_fine); - $t = datediff('n', $timeStart, $timeEnd); - $t = floatval(round($t / 60, 1)); - $prezzo_ore += $t * $prezzo_ore_unitario; + $prezzo_ore += $ore * $prezzo_ore_unitario; } if (count($rs) > 0) { // Aggiornamento orario tecnico - $dbo->query('UPDATE in_interventi_tecnici SET orario_inizio = '.prepare($timeStart).', orario_fine = '.prepare($timeEnd).', ore='.prepare($t).', prezzo_ore_consuntivo='.prepare($t * $prezzo_ore_unitario).' WHERE id='.prepare($sessione)); + $dbo->query('UPDATE in_interventi_tecnici SET orario_inizio = '.prepare($orario_inizio).', orario_fine = '.prepare($orario_fine).', ore='.prepare($ore).', prezzo_ore_consuntivo='.prepare($t * $prezzo_ore_unitario).' WHERE id='.prepare($sessione)); echo 'ok'; } else { echo tr('Attività completata, non è possibile modificarla!'); diff --git a/modules/fatture/modutil.php b/modules/fatture/modutil.php index 382765d69..704f1c8af 100644 --- a/modules/fatture/modutil.php +++ b/modules/fatture/modutil.php @@ -799,239 +799,6 @@ function rimuovi_articolo_dafattura($idarticolo, $iddocumento, $idrigadocumento) return true; } -function aggiorna_sconto($tables, $fields, $id_record, $options = []) -{ - $dbo = Database::getConnection(); - - $descrizione = tr('Sconto', [], ['upper' => true]); - - // Rimozione dello sconto precedente - $dbo->query('DELETE FROM '.$tables['row'].' WHERE sconto_globale = 1 AND '.$fields['row'].'='.prepare($id_record)); - - // Individuazione del nuovo sconto - $sconto = $dbo->select($tables['parent'], ['sconto_globale', 'tipo_sconto_globale'], [$fields['parent'] => $id_record]); - $sconto[0]['sconto_globale'] = floatval($sconto[0]['sconto_globale']); - - // Aggiorno l'eventuale sconto gestendolo con le righe in fattura - $iva = 0; - - if (!empty($sconto[0]['sconto_globale'])) { - if ($sconto[0]['tipo_sconto_globale'] == 'PRC') { - $rs = $dbo->fetchArray('SELECT SUM(subtotale - sconto) AS imponibile, SUM(iva) AS iva FROM (SELECT '.$tables['row'].'.subtotale, '.$tables['row'].'.sconto, '.$tables['row'].'.iva FROM '.$tables['row'].' WHERE '.$fields['row'].'='.prepare($id_record).') AS t'); - $subtotale = $rs[0]['imponibile']; - $iva += $rs[0]['iva'] / 100 * $sconto[0]['sconto_globale']; - $subtotale = -$subtotale / 100 * $sconto[0]['sconto_globale']; - - $descrizione = $descrizione.' '.Translator::numberToLocale($sconto[0]['sconto_globale']).'%'; - } else { - $rs = $dbo->fetchArray('SELECT SUM(subtotale - sconto) AS imponibile, SUM(iva) AS iva FROM (SELECT '.$tables['row'].'.subtotale, '.$tables['row'].'.sconto, '.$tables['row'].'.iva FROM '.$tables['row'].' WHERE '.$fields['row'].'='.prepare($id_record).') AS t'); - $subtotale = $rs[0]['imponibile']; - $iva += $sconto[0]['sconto_globale'] * $rs[0]['iva'] / $subtotale; - - $subtotale = -$sconto[0]['sconto_globale']; - } - - // Calcolo dell'IVA da scontare - $idiva = setting('Iva predefinita'); - $rsi = $dbo->select('co_iva', ['descrizione', 'percentuale'], ['id' => $idiva]); - - $values = [ - $fields['row'] => $id_record, - 'descrizione' => $descrizione, - 'subtotale' => $subtotale, - 'qta' => 1, - 'idiva' => $idiva, - 'desc_iva' => $rsi[0]['descrizione'], - 'iva' => -$iva, - 'sconto_globale' => 1, - '#order' => '(SELECT IFNULL(MAX(`order`) + 1, 0) FROM '.$tables['row'].' AS t WHERE '.$fields['row'].'='.prepare($id_record).')', - ]; - - $dbo->insert($tables['row'], $values); - } -} - -function controlla_seriali($field, $id_riga, $old_qta, $new_qta, $dir) -{ - $dbo = Database::getConnection(); - - $new_qta = abs($new_qta); - $old_qta = abs($old_qta); - - if ($old_qta >= $new_qta) { - // Controllo sulla possibilità di rimuovere i seriali (se non utilizzati da documenti di vendita) - if ($dir == 'uscita' && $new_qta < count(seriali_non_rimuovibili($field, $id_riga, $dir))) { - return false; - } else { - // Controllo sul numero di seriali effettivi da rimuovere - $count = $dbo->fetchArray('SELECT COUNT(*) AS tot FROM mg_prodotti WHERE '.$field.'='.prepare($id_riga))[0]['tot']; - if ($new_qta < $count) { - $deletes = $dbo->fetchArray("SELECT id FROM mg_prodotti WHERE serial NOT IN (SELECT serial FROM mg_prodotti WHERE dir = 'entrata' AND ".$field.'!='.prepare($id_riga).') AND '.$field.'='.prepare($id_riga).' ORDER BY serial DESC LIMIT '.abs($count - $new_qta)); - - // Rimozione - foreach ($deletes as $delete) { - $dbo->query('DELETE FROM mg_prodotti WHERE id = '.prepare($delete['id'])); - } - } - } - } - - return true; -} - -/** - * Individua i seriali non rimuovibili poichè utilizzati in documenti rilasciati. - * - * @param string $field - * @param int $id_riga - * @param string $dir - * - * @return array - */ -function seriali_non_rimuovibili($field, $id_riga, $dir) -{ - $dbo = Database::getConnection(); - - $results = []; - - if ($dir == 'uscita') { - $results = $dbo->fetchArray("SELECT serial FROM mg_prodotti WHERE serial IN (SELECT serial FROM mg_prodotti WHERE dir = 'entrata') AND ".$field.'='.prepare($id_riga)); - } - - return $results; -} - -/** - * Calcola gli sconti in modo automatico. - * - * @param array $data - * - * @return float - */ -function calcola_sconto($data) -{ - if ($data['tipo'] == 'PRC') { - $result = 0; - - $price = floatval($data['prezzo']); - - $percentages = explode('+', $data['sconto']); - foreach ($percentages as $percentage) { - $discount = $price / 100 * floatval($percentage); - - $result += $discount; - $price -= $discount; - } - } else { - $result = floatval($data['sconto']); - } - - if (!empty($data['qta'])) { - $result = $result * $data['qta']; - } - - return $result; -} - -/** - * Restistuisce le informazioni sull'eventuale riferimento ai documenti. - * - * @param array $data - * @param string $dir - * - * @return array - */ -function doc_references($info, $dir, $ignore = []) -{ - $dbo = Database::getConnection(); - - // Rimozione valori da non controllare - foreach ($ignore as $field) { - if (isset($info[$field])) { - unset($info[$field]); - } - } - - $module = null; - $id = null; - - // Ordine - if (!empty($info['idordine'])) { - $data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM or_ordini WHERE id=".prepare($info['idordine'])); - - $module = ($dir == 'entrata') ? 'Ordini cliente' : 'Ordini fornitore'; - $id = $info['idordine']; - - $document = tr('Ordine'); - } - - // DDT - elseif (!empty($info['idddt'])) { - $data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM dt_ddt WHERE id=".prepare($info['idddt'])); - - $module = ($dir == 'entrata') ? 'Ddt di vendita' : 'Ddt di acquisto'; - $id = $info['idddt']; - - $document = tr('Ddt'); - } - - // Preventivo - elseif (!empty($info['idpreventivo'])) { - $data = $dbo->fetchArray('SELECT numero, data_bozza AS data FROM co_preventivi WHERE id='.prepare($info['idpreventivo'])); - - $module = 'Preventivi'; - $id = $info['idpreventivo']; - - $document = tr('Preventivo'); - } - - // Contratto - elseif (!empty($info['idcontratto'])) { - $data = $dbo->fetchArray('SELECT numero, data_bozza AS data FROM co_contratti WHERE id='.prepare($info['idcontratto'])); - - $module = 'Contratti'; - $id = $info['idcontratto']; - - $document = tr('Contratto'); - } - - // Intervento - elseif (!empty($info['idintervento'])) { - $data = $dbo->fetchArray('SELECT codice AS numero, IFNULL( (SELECT MIN(orario_inizio) FROM in_interventi_tecnici WHERE in_interventi_tecnici.idintervento=in_interventi.id), data_richiesta) AS data FROM in_interventi WHERE id='.prepare($info['idintervento'])); - - $module = 'Interventi'; - $id = $info['idintervento']; - - $document = tr('Intervento'); - } - - // Testo relativo - if (!empty($module) && !empty($id)) { - $document = Stringy\Stringy::create($document)->toLowerCase(); - - if (!empty($data)) { - $description = tr('Rif. _DOC_ num. _NUM_ del _DATE_', [ - '_DOC_' => $document, - '_NUM_' => $data[0]['numero'], - '_DATE_' => Translator::dateToLocale($data[0]['data']), - ]); - } else { - $description = tr('_DOC_ di riferimento _ID_ eliminato', [ - '_DOC_' => $document->upperCaseFirst(), - '_ID_' => $id, - ]); - } - - return [ - 'module' => $module, - 'id' => $id, - 'description' => $description, - ]; - } - - return []; -} - function rimuovi_riga_fattura($id_documento, $id_riga, $dir) { $dbo = Database::getConnection(); diff --git a/modules/interventi/actions.php b/modules/interventi/actions.php index d55b30f9d..21d5332e1 100644 --- a/modules/interventi/actions.php +++ b/modules/interventi/actions.php @@ -79,9 +79,7 @@ switch (post('op')) { $orario_fine = post('orario_fine')[$idriga]; // Ricalcolo le ore lavorate - $inizio = new DateTime($orario_inizio); - $diff = $inizio->diff(new DateTime($orario_fine)); - $ore = $diff->h + ($diff->days * 24); + $ore = calcola_ore_intervento($orario_inizio, $orario_fine); $km = post('km')[$idriga]; diff --git a/modules/interventi/modutil.php b/modules/interventi/modutil.php index 1defc2573..fbe69eaec 100644 --- a/modules/interventi/modutil.php +++ b/modules/interventi/modutil.php @@ -315,3 +315,20 @@ function get_costi_intervento($id_intervento) return $result; } + +/** + * Calcola le ore presenti tra due date. + * + * @param string $orario_inizio + * @param string $orario_fine + * + * @return float + */ +function calcola_ore_intervento($orario_inizio, $orario_fine) +{ + $inizio = new DateTime($orario_inizio); + $diff = $inizio->diff(new DateTime($orario_fine)); + $ore = $diff->h + ($diff->days * 24); + + return $ore; +} diff --git a/templates/contratti_cons/body.php b/templates/contratti_cons/body.php index 875597e95..0a8f123da 100644 --- a/templates/contratti_cons/body.php +++ b/templates/contratti_cons/body.php @@ -2,7 +2,7 @@ include_once __DIR__.'/../../core.php'; -include_once $docroot.'/modules/interventi/modutil.php'; +include_once Modules::filepath('Interventi', 'modutil.php'); $report_name = 'contratto_'.$records[0]['numero'].'_cons.pdf'; @@ -126,7 +126,7 @@ if (!empty($interventi)) { // Calcolo il totale delle ore lavorate $tecnici = $dbo->fetchArray('SELECT orario_inizio, orario_fine FROM in_interventi_tecnici WHERE idintervento='.prepare($int['id'])); foreach ($tecnici as $tecnico) { - $totale_ore_impiegate += datediff('n', $tecnico['orario_inizio'], $tecnico['orario_fine']) / 60; + $totale_ore_impiegate += calcola_ore_intervento($tecnico['orario_inizio'], $tecnico['orario_fine']); } $ore[] = $int['ore']; diff --git a/templates/ddt/body.php b/templates/ddt/body.php index 7d5cd3b4c..06f21761a 100644 --- a/templates/ddt/body.php +++ b/templates/ddt/body.php @@ -2,7 +2,7 @@ include_once __DIR__.'/../../core.php'; -include_once DOCROOT.'/modules/fatture/modutil.php'; +include_once Modules::filepath('Fatture di vendita', 'modutil.php'); $report_name = 'ddt_'.$numero.'.pdf'; diff --git a/templates/fatture/body.php b/templates/fatture/body.php index 7e6dae52d..93057302a 100644 --- a/templates/fatture/body.php +++ b/templates/fatture/body.php @@ -2,7 +2,7 @@ include_once __DIR__.'/../../core.php'; -include_once DOCROOT.'/modules/fatture/modutil.php'; +include_once Modules::filepath('Fatture di vendita', 'modutil.php'); $report_name = 'fattura_'.$numero.'.pdf'; diff --git a/templates/interventi/body.php b/templates/interventi/body.php index 48edf6121..b492d9a4a 100644 --- a/templates/interventi/body.php +++ b/templates/interventi/body.php @@ -2,7 +2,7 @@ include_once __DIR__.'/../../core.php'; -include_once $docroot.'/modules/interventi/modutil.php'; +include_once Modules::filepath('Interventi', 'modutil.php'); $report_name = 'intervento_'.$records[0]['codice'].'.pdf'; diff --git a/templates/interventi/init.php b/templates/interventi/init.php index 2aa3489fc..755f9ac5b 100644 --- a/templates/interventi/init.php +++ b/templates/interventi/init.php @@ -2,7 +2,7 @@ include_once __DIR__.'/../../core.php'; -include_once $docroot.'/modules/interventi/modutil.php'; +include_once Modules::filepath('Interventi', 'modutil.php'); $module_name = 'Interventi'; diff --git a/templates/preventivi_cons/body.php b/templates/preventivi_cons/body.php index 8dff64427..65cde70b6 100644 --- a/templates/preventivi_cons/body.php +++ b/templates/preventivi_cons/body.php @@ -2,8 +2,9 @@ include_once __DIR__.'/../../core.php'; -include_once $docroot.'/modules/interventi/modutil.php'; -include_once $docroot.'/modules/preventivi/modutil.php'; +include_once Modules::filepath('Interventi', 'modutil.php'); +include_once Modules::filepath('Preventivi', 'modutil.php'); + $report_name = 'preventivo_'.$records[0]['numero'].'_cons.pdf'; echo '