fetchArray($query); $numero = $rs[0]['max_numerofattura'] + 1; return $numero; } /** * Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni. */ function get_new_numerosecondariofattura($data) { global $dbo; global $dir; global $idtipodocumento; // DATE_FORMAT( data, '%Y' ) = '".date("Y", strtotime($data))."' $query = "SELECT numero_esterno FROM co_documenti WHERE DATE_FORMAT( data, '%Y' ) = ".prepare(date('Y', strtotime($data))).' AND idtipodocumento IN(SELECT id FROM co_tipidocumento WHERE dir='.prepare($dir).') ORDER BY CAST(numero_esterno AS UNSIGNED) DESC LIMIT 0,1'; $rs = $dbo->fetchArray($query); $numero_secondario = $rs[0]['numero_esterno']; // Calcolo il numero secondario se stabilito dalle impostazioni e se documento di vendita $formato_numero_secondario = get_var('Formato numero secondario fattura'); if ($numero_secondario == '') { $numero_secondario = $formato_numero_secondario; } if ($formato_numero_secondario != '' && $dir == 'entrata') { $numero_esterno = get_next_code($numero_secondario, 1, $formato_numero_secondario); } else { $numero_esterno = ''; } return $numero_esterno; } /** * Elimina una scadenza in base al codice documento. */ function elimina_scadenza($iddocumento) { global $dbo; $query2 = 'DELETE FROM co_scadenziario WHERE iddocumento='.prepare($iddocumento); $dbo->query($query2); } /** * Funzione per ricalcolare lo scadenziario di una determinata fattura * $iddocumento string E' l'id del documento di cui ricalcolare lo scadenziario * $pagamento string Nome del tipo di pagamento. Se è vuoto lo leggo da co_pagamenti_documenti, perché significa che devo solo aggiornare gli importi. */ function aggiungi_scadenza($iddocumento, $pagamento = '') { global $dbo; $totale_da_pagare = 0.00; $totale_fattura = get_totale_fattura($iddocumento); $netto_fattura = get_netto_fattura($iddocumento); $imponibile_fattura = get_imponibile_fattura($iddocumento); $totale_iva = sum(abs($totale_fattura), -abs($imponibile_fattura)); // Lettura data di emissione fattura $query3 = 'SELECT ritenutaacconto, data FROM co_documenti WHERE id='.prepare($iddocumento); $rs = $dbo->fetchArray($query3); $data = $rs[0]['data']; $ritenutaacconto = $rs[0]['ritenutaacconto']; // Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale $query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); $rs2 = $dbo->fetchArray($query2); $dir = $rs2[0]['dir']; /* Inserisco la nuova scadenza (anche più di una riga per pagamenti multipli */ // Se il pagamento non è specificato lo leggo dal documento if ($pagamento == '') { $query = 'SELECT descrizione FROM co_pagamenti WHERE id=(SELECT idpagamento FROM co_documenti WHERE id='.prepare($iddocumento).')'; $rs = $dbo->fetchArray($query); $pagamento = $rs[0]['descrizione']; } $query4 = 'SELECT * FROM co_pagamenti WHERE descrizione='.prepare($pagamento); $rs = $dbo->fetchArray($query4); for ($i = 0; $i < sizeof($rs); ++$i) { // X giorni esatti if ($rs[$i]['giorno'] == 0) { $scadenza = date('Y-m-d', strtotime($data.' +'.$rs[$i]['num_giorni'].' day')); } // Ultimo del mese elseif ($rs[$i]['giorno'] < 0) { $date = new DateTime($data); $add = floor($rs[$i]['num_giorni'] / 30); for ($c = 0; $c < $add; ++$c) { $date->modify('last day of next month'); } // Ultimo del mese più X giorni $giorni = -$rs[$i]['giorno'] - 1; if ($giorni > 0) { $date->modify('+'.($giorni).' day'); } $scadenza = $date->format('Y-m-d'); } // Giorno preciso del mese else { $scadenza = date('Y-m-'.$rs[$i]['giorno'], strtotime($data.' +'.$rs[$i]['num_giorni'].' day')); } // All'ultimo ciclo imposto come cifra da pagare il totale della fattura meno gli importi già inseriti in scadenziario per evitare di inserire cifre arrotondate "male" if ($i == (sizeof($rs) - 1)) { $da_pagare = sum($netto_fattura, -$totale_da_pagare); } // Totale da pagare (totale x percentuale di pagamento nei casi pagamenti multipli) else { $da_pagare = sum($netto_fattura / 100 * $rs[$i]['prc'], 0); } $totale_da_pagare = sum($da_pagare, $totale_da_pagare); if ($dir == 'uscita') { $da_pagare = -$da_pagare; } $dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare($scadenza).', '.prepare($da_pagare).", 0, 'fattura')"); } // Se c'è una ritenuta d'acconto, la aggiungo allo scadenzario if ($dir == 'uscita' && $ritenutaacconto > 0) { $dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare(date('Y-m', strtotime($data.' +1 month')).'-15').', '.prepare(-$ritenutaacconto).", 0, 'ritenutaacconto')"); } return true; } /** * Funzione per aggiornare lo stato dei pagamenti nello scadenziario * $iddocumento int ID della fattura * $totale_pagato float Totale importo pagato * $data_pagamento datetime Data in cui avviene il pagamento (yyyy-mm-dd). */ function aggiorna_scadenziario($iddocumento, $totale_pagato, $data_pagamento) { global $dbo; // Lettura righe scadenziario $query = "SELECT * FROM co_scadenziario WHERE iddocumento='$iddocumento' AND ABS(pagato) < ABS(da_pagare) ORDER BY scadenza ASC"; $rs = $dbo->fetchArray($query); $netto_fattura = get_netto_fattura($iddocumento); $rimanente = $netto_fattura; $rimanente_da_pagare = abs($rs[0]['pagato']) + $totale_pagato; // Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale $query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); $rs2 = $dbo->fetchArray($query2); $dir = $rs2[0]['dir']; // Ciclo tra le rate dei pagamenti per inserire su `pagato` l'importo effettivamente pagato. // Nel caso il pagamento superi la rata, devo distribuirlo sulle rate successive for ($i = 0; $i < sizeof($rs); ++$i) { if ($rimanente_da_pagare > 0) { // ...riempio il pagato della rata con il totale della rata stessa se ho ricevuto un pagamento superiore alla rata stessa if (abs($rimanente_da_pagare) >= abs($rs[$i]['da_pagare'])) { $pagato = abs($rs[$i]['da_pagare']); $rimanente_da_pagare -= abs($rs[$i]['da_pagare']); } else { // Se si inserisce una somma maggiore al dovuto, tengo valido il rimanente per saldare il tutto... if (abs($rimanente_da_pagare) > abs($rs[$i]['da_pagare'])) { $pagato = abs($rs[$i]['da_pagare']); $rimanente_da_pagare -= abs($rs[$i]['da_pagare']); } // ...altrimenti aggiungo l'importo pagato else { $pagato = abs($rimanente_da_pagare); $rimanente_da_pagare -= abs($rs[$i]['da_pagare']) - abs($rs[$i]['pagato']); } } if ($dir == 'uscita') { $rimanente_da_pagare = -$rimanente_da_pagare; } if ($pagato > 0) { if ($dir == 'uscita') { $dbo->query('UPDATE co_scadenziario SET pagato='.prepare(-$pagato).', data_pagamento='.prepare($data_pagamento).' WHERE id='.prepare($rs[$i]['id'])); } else { $dbo->query('UPDATE co_scadenziario SET pagato='.prepare($pagato).', data_pagamento='.prepare($data_pagamento).' WHERE id='.prepare($rs[$i]['id'])); } } } } } /** * Elimina i movimenti collegati ad una fattura. */ function elimina_movimento($iddocumento, $anche_prima_nota = 0) { global $dbo; $query2 = 'DELETE FROM co_movimenti WHERE iddocumento='.prepare($iddocumento).' AND primanota='.prepare($anche_prima_nota); $dbo->query($query2); } /** * Funzione per aggiungere la fattura in prima nota * $iddocumento string E' l'id del documento da collegare alla prima nota * $dir string Direzione dell'importo (entrata, uscita) * $primanota boolean Indica se il movimento è un movimento di prima nota o un movimento normale (di default movimento normale). */ function aggiungi_movimento($iddocumento, $dir, $primanota = 0) { global $dbo; // Totale marca da bollo, inps, ritenuta, idagente $query = 'SELECT data, bollo, ritenutaacconto, rivalsainps FROM co_documenti WHERE id='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $totale_bolli = $rs[0]['bollo']; $totale_ritenutaacconto = $rs[0]['ritenutaacconto']; $totale_rivalsainps = $rs[0]['rivalsainps']; $data_documento = $rs[0]['data']; $netto_fattura = get_netto_fattura($iddocumento); $totale_fattura = get_totale_fattura($iddocumento); $imponibile_fattura = get_imponibile_fattura($iddocumento); // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); $rsi = $dbo->fetchArray($qi); $iva_rivalsainps = $totale_rivalsainps / 100 * $rsi[0]['percentuale']; // Lettura iva indetraibile fattura $query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $iva_indetraibile_fattura = $rs[0]['iva_indetraibile']; // Lettura iva delle righe in fattura $query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $iva_fattura = $rs[0]['iva'] + $iva_rivalsainps - $iva_indetraibile_fattura; // Imposto i segni + e - in base se la fattura è di acquisto o vendita if ($dir == 'uscita') { $segno_mov1_cliente = -1; $segno_mov2_ricavivendite = 1; $segno_mov3_iva = 1; $segno_mov4_inps = 1; $segno_mov5_ritenutaacconto = -1; $segno_mov6_bollo = 1; // Lettura conto fornitore $query = 'SELECT idconto_fornitore FROM an_anagrafiche INNER JOIN co_documenti ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_documenti.id='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $idconto_controparte = $rs[0]['idconto_fornitore']; if ($idconto_controparte == '') { $query = "SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo fornitori'"; $rs = $dbo->fetchArray($query); $idconto_controparte = $rs[0]['idconto_fornitore']; } } else { $segno_mov1_cliente = 1; $segno_mov2_ricavivendite = -1; $segno_mov3_iva = -1; $segno_mov4_inps = -1; $segno_mov5_ritenutaacconto = 1; $segno_mov6_bollo = -1; // Lettura conto cliente $query = 'SELECT idconto_cliente FROM an_anagrafiche INNER JOIN co_documenti ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_documenti.id='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $idconto_controparte = $rs[0]['idconto_cliente']; if ($idconto_controparte == '') { $query = "SELECT id FROM co_pianodeiconti3 WHERE descrizione='Riepilogativo clienti'"; $rs = $dbo->fetchArray($query); $idconto_controparte = $rs[0]['idconto_cliente']; } } // Lettura info fattura $query = 'SELECT *, co_documenti.note, co_documenti.idpagamento, co_documenti.id AS iddocumento, co_statidocumento.descrizione AS `stato`, co_tipidocumento.descrizione AS `descrizione_tipodoc` FROM ((co_documenti LEFT OUTER JOIN co_statidocumento ON co_documenti.idstatodocumento=co_statidocumento.id) INNER JOIN an_anagrafiche ON co_documenti.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $n = sizeof($rs); $data = $rs[0]['data']; $idanagrafica = $rs[0]['idanagrafica']; $ragione_sociale = $rs[0]['ragione_sociale']; $stato = $rs[0]['stato']; $idconto = $rs[0]['idconto']; // Scrivo il movimento solo se è stato selezionato un conto if ($idconto != '') { $idmastrino = get_new_idmastrino(); // Prendo il numero doc. esterno se c'è, altrimenti quello normale if (!empty($rs[0]['numero_esterno'])) { $numero = $rs[0]['numero_esterno']; } else { $numero = $rs[0]['numero']; } $descrizione = $rs[0]['descrizione_tipodoc']." numero $numero"; /* Il mastrino si apre con almeno 3 righe di solito (esempio fattura di vendita): 1) dare imponibile+iva al conto cliente 2) avere imponibile sul conto dei ricavi 3) avere iva sul conto dell'iva a credito (ed eventuale iva indetraibile sul rispettivo conto) aggiuntivo: 4) eventuale rivalsa inps 5) eventuale ritenuta d'acconto 6) eventuale marca da bollo */ // 1) Aggiungo la riga del conto cliente $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_controparte).', '.prepare(($totale_fattura + $totale_bolli) * $segno_mov1_cliente).', '.prepare($primanota).' )'; $dbo->query($query2); // 2) Aggiungo il totale sul conto dei ricavi/spese scelto // Lettura descrizione conto ricavi/spese per ogni riga del documento $righe = $dbo->fetchArray('SELECT idconto, SUM(subtotale - sconto) AS imponibile FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento).' GROUP BY idconto'); foreach ($righe as $riga) { // Retrocompatibilità $idconto_riga = !empty($riga['idconto']) ? $riga['idconto'] : $idconto; $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_riga).', '.prepare($riga['imponibile'] * $segno_mov2_ricavivendite).', '.prepare($primanota).')'; $dbo->query($query2); } // 3) Aggiungo il totale sul conto dell'iva // Lettura id conto iva if ($iva_fattura != 0) { $descrizione_conto_iva = ($dir == 'entrata') ? 'Iva su vendite' : 'Iva su acquisti'; $query = 'SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='.prepare($descrizione_conto_iva); $rs = $dbo->fetchArray($query); $idconto_iva = $rs[0]['id']; $descrizione_conto_iva = $rs[0]['descrizione']; $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_iva).', '.prepare($iva_fattura * $segno_mov3_iva).', '.prepare($primanota).')'; $dbo->query($query2); } // Lettura id conto iva indetraibile if ($iva_indetraibile_fattura != 0) { $descrizione_conto_iva2 = 'Iva indetraibile'; $query = 'SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='.prepare($descrizione_conto_iva2); $rs = $dbo->fetchArray($query); $idconto_iva2 = $rs[0]['id']; $descrizione_conto_iva2 = $rs[0]['descrizione']; $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_iva2).', '.prepare($iva_indetraibile_fattura * $segno_mov3_iva).', '.prepare($primanota).')'; $dbo->query($query2); } // 4) Aggiungo la rivalsa INPS se c'è // Lettura id conto inps if ($totale_rivalsainps != 0) { $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='Erario c/INPS'"; $rs = $dbo->fetchArray($query); $idconto_inps = $rs[0]['id']; $descrizione_conto_inps = $rs[0]['descrizione']; $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_inps).', '.prepare($totale_rivalsainps * $segno_mov4_inps).', '.prepare($primanota).')'; $dbo->query($query2); } // 5) Aggiungo la ritenuta d'acconto se c'è // Lettura id conto ritenuta e la storno subito if ($totale_ritenutaacconto != 0) { $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione=\"Erario c/ritenute d'acconto\""; $rs = $dbo->fetchArray($query); $idconto_ritenutaacconto = $rs[0]['id']; $descrizione_conto_ritenutaacconto = $rs[0]['descrizione']; // DARE nel conto ritenuta $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_ritenutaacconto).', '.prepare($totale_ritenutaacconto * $segno_mov5_ritenutaacconto).', '.prepare($primanota).')'; $dbo->query($query2); // AVERE nel riepilogativo clienti $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_controparte).', '.prepare(($totale_ritenutaacconto * $segno_mov5_ritenutaacconto) * -1).', '.prepare($primanota).')'; $dbo->query($query2); } // 6) Aggiungo la marca da bollo se c'è // Lettura id conto marca da bollo if ($totale_bolli != 0) { $query = "SELECT id, descrizione FROM co_pianodeiconti3 WHERE descrizione='Rimborso spese marche da bollo'"; $rs = $dbo->fetchArray($query); $idconto_bolli = $rs[0]['id']; $descrizione_conto_bolli = $rs[0]['descrizione']; $query2 = 'INSERT INTO co_movimenti(idmastrino, data, data_documento, iddocumento, idanagrafica, descrizione, idconto, totale, primanota) VALUES('.prepare($idmastrino).', '.prepare($data).', '.prepare($data_documento).', '.prepare($iddocumento).", '', ".prepare($descrizione.' del '.date('d/m/Y', strtotime($data)).' ('.$ragione_sociale.')').', '.prepare($idconto_bolli).', '.prepare($totale_bolli * $segno_mov6_bollo).', '.prepare($primanota).')'; $dbo->query($query2); } } } /** * Funzione per generare un nuovo codice per il mastrino. */ function get_new_idmastrino() { global $dbo; $query = 'SELECT MAX(idmastrino) AS maxidmastrino FROM co_movimenti'; $rs = $dbo->fetchArray($query); return intval($rs[0]['maxidmastrino']) + 1; } /** * Calcolo imponibile fattura (totale_righe - sconto). */ function get_imponibile_fattura($iddocumento) { global $dbo; $query = 'SELECT SUM(co_righe_documenti.subtotale - co_righe_documenti.sconto) AS imponibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); return $rs[0]['imponibile']; } /** * Calcolo totale fattura (imponibile + iva). */ function get_totale_fattura($iddocumento) { global $dbo; // Sommo l'iva di ogni riga al totale $query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); // Aggiungo la rivalsa inps se c'è $query2 = 'SELECT rivalsainps FROM co_documenti WHERE id='.prepare($iddocumento); $rs2 = $dbo->fetchArray($query2); // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); $rsi = $dbo->fetchArray($qi); $iva_rivalsainps = $rs2[0]['rivalsainps'] / 100 * $rsi[0]['percentuale']; return get_imponibile_fattura($iddocumento) + $rs[0]['iva'] + $iva_rivalsainps + $rs2[0]['rivalsainps']; } /** * Calcolo netto a pagare fattura (totale - ritenute - bolli). */ function get_netto_fattura($iddocumento) { global $dbo; $query = 'SELECT ritenutaacconto, bollo FROM co_documenti WHERE id='.prepare($iddocumento); $rs = $dbo->fetchArray($query); return get_totale_fattura($iddocumento) - $rs[0]['ritenutaacconto'] + $rs[0]['bollo']; } /** * Calcolo iva detraibile fattura. */ function get_ivadetraibile_fattura($iddocumento) { global $dbo; $query = 'SELECT SUM(iva)-SUM(iva_indetraibile) AS iva_detraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); return $rs[0]['iva_detraibile']; } /** * Calcolo iva indetraibile fattura. */ function get_ivaindetraibile_fattura($iddocumento) { global $dbo; $query = 'SELECT SUM(iva_indetraibile) AS iva_indetraibile FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); return $rs[0]['iva_indetraibile']; } /** * Ricalcola i costi aggiuntivi in fattura (rivalsa inps, ritenuta d'acconto, marca da bollo) * Deve essere eseguito ogni volta che si aggiunge o toglie una riga * $iddocumento int ID della fattura * $idrivalsainps int ID della rivalsa inps da applicare. Se omesso viene utilizzata quella impostata di default * $idritenutaacconto int ID della ritenuta d'acconto da applicare. Se omesso viene utilizzata quella impostata di default * $bolli float Costi aggiuntivi delle marche da bollo. Se omesso verrà usata la cifra predefinita. */ function ricalcola_costiagg_fattura($iddocumento, $idrivalsainps = '', $idritenutaacconto = '', $bolli = '') { global $dbo; global $dir; // Se ci sono righe in fattura faccio i conteggi, altrimenti azzero gli sconti e le spese aggiuntive (inps, ritenuta, marche da bollo) $query = 'SELECT COUNT(id) AS righe FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); if ($rs[0]['righe'] > 0) { $totale_imponibile = get_imponibile_fattura($iddocumento); $totale_fattura = get_totale_fattura($iddocumento); // Leggo gli id dei costi aggiuntivi if ($dir == 'uscita') { $query2 = 'SELECT bollo FROM co_documenti WHERE id='.prepare($iddocumento); $rs2 = $dbo->fetchArray($query2); $bollo = $rs2[0]['bollo']; } $query = 'SELECT SUM(rivalsainps) AS rivalsainps, SUM(ritenutaacconto) AS ritenutaacconto FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento='.prepare($iddocumento); $rs = $dbo->fetchArray($query); $rivalsainps = $rs[0]['rivalsainps']; $ritenutaacconto = $rs[0]['ritenutaacconto']; if ($dir == 'entrata') { // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); $rsi = $dbo->fetchArray($qi); $iva_rivalsainps = $rivalsainps / 100 * $rsi[0]['percentuale']; } else { // Leggo l'iva predefinita per calcolare l'iva aggiuntiva sulla rivalsa inps $qi = 'SELECT percentuale FROM co_iva WHERE id='.prepare(get_var('Iva predefinita')); $rsi = $dbo->fetchArray($qi); $iva_rivalsainps = $rivalsainps / 100 * $rsi[0]['percentuale']; } // Leggo la ritenuta d'acconto se c'è $totale_fattura = get_totale_fattura($iddocumento); $query = 'SELECT percentuale FROM co_ritenutaacconto WHERE id='.prepare($idritenutaacconto); $rs = $dbo->fetchArray($query); $netto_a_pagare = $totale_fattura - $ritenutaacconto; // Leggo la marca da bollo se c'è e se il netto a pagare supera la soglia $bolli = str_replace(',', '.', $bolli); $bolli = floatval($bolli); if ($dir == 'uscita') { if ($bolli != 0.00) { $bolli = str_replace(',', '.', $bolli); if (abs($bolli) > 0 && abs($netto_a_pagare > get_var("Soglia minima per l'applicazione della marca da bollo"))) { $marca_da_bollo = str_replace(',', '.', $bolli); } else { $marca_da_bollo = 0.00; } } } else { $bolli = str_replace(',', '.', get_var('Importo marca da bollo')); if (abs($bolli) > 0 && abs($netto_a_pagare) > abs(get_var("Soglia minima per l'applicazione della marca da bollo"))) { $marca_da_bollo = str_replace(',', '.', $bolli); } else { $marca_da_bollo = 0.00; } // Se l'importo è negativo può essere una nota di accredito, quindi cambio segno alla marca da bollo if ($netto_a_pagare < 0) { $marca_da_bollo *= -1; } } $dbo->query('UPDATE co_documenti SET ritenutaacconto='.prepare($ritenutaacconto).', rivalsainps='.prepare($rivalsainps).', iva_rivalsainps='.prepare($iva_rivalsainps).', bollo='.prepare($marca_da_bollo).' WHERE id='.prepare($iddocumento)); } else { $dbo->query("UPDATE co_documenti SET ritenutaacconto='0', bollo='0', rivalsainps='0', iva_rivalsainps='0' WHERE id=".prepare($iddocumento)); } } /** * Questa funzione aggiunge un articolo in fattura. E' comoda quando si devono inserire * degli interventi con articoli collegati o preventivi che hanno interventi con articoli collegati! * $iddocumento integer id della fattura * $idarticolo integer id dell'articolo da inserire in fattura * $idiva integer id del codice iva associato all'articolo * $qta float quantità dell'articolo in fattura * $prezzo float prezzo totale dell'articolo (prezzounitario*qtà) * $idintervento integer id dell'intervento da cui arriva l'articolo (per non creare casini quando si rimuoverà un articolo dalla fattura). */ function add_articolo_infattura($iddocumento, $idarticolo, $descrizione, $idiva, $qta, $prezzo, $sconto = 0, $sconto_unitario = 0, $tipo_sconto = 'UNT', $idintervento = 0, $lotto = '', $serial = '', $altro = '', $idgruppo = 0, $idconto = 0, $idum = 0) { global $dbo; global $dir; global $idddt; if ($idddt == '') { $idddt = 0; } // Lettura unità di misura dell'articolo if (empty($idum)) { $query = 'SELECT um FROM mg_articoli WHERE id='.prepare($idarticolo); $rs = $dbo->fetchArray($query); $um = $rs[0]['valore']; } else { $um = $idum; } if (empty($idgruppo)) { $idgruppo = $dbo->fetchArray('SELECT IFNULL(MAX(`idgruppo`) + 1, 0) AS idgruppo FROM co_righe_documenti AS t WHERE iddocumento='.prepare($iddocumento))[0]['idgruppo']; } // Lettura iva dell'articolo $rs2 = $dbo->fetchArray('SELECT * FROM co_iva WHERE id='.prepare($idiva)); $iva = ($prezzo - $sconto) / 100 * $rs2[0]['percentuale']; $desc_iva = $rs2[0]['descrizione']; if ($qta > 0) { $rsart = $dbo->fetchArray('SELECT abilita_serial FROM mg_articoli WHERE id='.prepare($idarticolo)); $qta_in = !empty($rsart[0]['abilita_serial']) ? $qta : 1; for ($i = 0; $i < $qta_in; ++$i) { /* $iva = $iva / $qta_in; $qta = $qta / $qta_in; $ubtotale = $subtotale / $qta_in; $sconto = $sconto / $qta_in; $iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile']; */ $dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idintervento, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, qta, abilita_serial, serial, idconto, um, idgruppo, `order`) VALUES ('.prepare($iddocumento).', '.prepare($idarticolo).', '.(!empty($idintervento) ? prepare($idintervento) : 'NULL').', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($qta).', '.prepare($rsart[0]['abilita_serial']).', '.prepare($serial).', '.prepare($idconto).', '.prepare($um).', '.prepare($idgruppo).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($iddocumento).'))'); } $idriga = $dbo->lastInsertedID(); /* Fatture di vendita */ if ($dir == 'entrata') { // Se il documento non è generato da un ddt o intervento allora movimento il magazzino if (empty($idddt) && empty($idintervento)) { add_movimento_magazzino($idarticolo, -$qta, ['iddocumento' => $iddocumento]); } } /* Fatture di acquisto */ elseif ($dir == 'uscita') { // Se il documento non è generato da un ddt allora movimento il magazzino if (empty($idddt)) { add_movimento_magazzino($idarticolo, $qta, ['iddocumento' => $iddocumento]); } } // Inserisco il riferimento del ddt alla riga $dbo->query('UPDATE co_righe_documenti SET idddt='.prepare($idddt).' WHERE id='.prepare($idriga)); } return $idriga; } /** * Questa funzione rimuove un articolo dalla fattura data e lo riporta in magazzino nel primo lotto libero * a partire dal lotto più vecchio * $idarticolo integer codice dell'articolo da scollegare dalla fattura * $iddocumento integer codice della fattura da cui scollegare l'articolo. */ function rimuovi_articolo_dafattura($idarticolo, $iddocumento, $idrigadocumento) { global $dbo; global $dir; // Leggo la quantità di questo articolo in fattura $query = 'SELECT idgruppo, qta, idintervento, idpreventivo, idordine, idddt, subtotale, descrizione, lotto, serial, altro FROM co_righe_documenti WHERE id='.prepare($idrigadocumento); $rs = $dbo->fetchArray($query); $idintervento = $rs[0]['idintervento']; $idpreventivo = $rs[0]['idpreventivo']; $idddt = $rs[0]['idddt']; $idordine = $rs[0]['idordine']; $qta = $rs[0]['qta']; $subtotale = $rs[0]['subtotale']; $idgruppo = $rs[0]['idgruppo']; $descrizione = $rs[0]['descrizione']; $lotto = $rs[0]['lotto']; $serial = $rs[0]['serial']; $altro = $rs[0]['altro']; if ($dir == 'uscita') { $non_rimovibili = $dbo->fetchArray("SELECT COUNT(*) AS non_rimovibili FROM co_righe_documenti WHERE serial IN (SELECT serial FROM vw_serials WHERE dir = 'entrata') AND idgruppo=".prepare($idgruppo).' AND iddocumento='.prepare($iddocumento))[0]['non_rimovibili']; if ($non_rimovibili != 0) { return false; } } // Se l'articolo è stato aggiunto in fattura perché era collegato ad un intervento o // preventivo o ddt o ordine non devo riportarlo in magazzino quando lo tolgo dalla fattura, perché // se lo scollegassi poi anche dall'intervento aggiungerei in magazzino la quantità 2 volte!! if ($qta > 0) { if (empty($idintervento) && empty($idddt)) { // Fatture di vendita if ($dir == 'entrata') { add_movimento_magazzino($idarticolo, $qta, ['iddocumento' => $iddocumento]); } // Fatture di acquisto else { add_movimento_magazzino($idarticolo, -$qta, ['iddocumento' => $iddocumento]); } } // Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa if (!empty($idddt)) { $dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idddt='.prepare($idddt).' AND lotto='.prepare($rs[0]['lotto']).' AND serial='.prepare($rs[0]['serial']).' AND altro='.prepare($rs[0]['altro'])); } // Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa if (!empty($idordine)) { $dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idordine='.prepare($idordine)); } } if ($dir == 'uscita') { // Elimino eventuali articoli caricati in mg_prodotti esclusivamente con la fattura di acquisto $query = 'SELECT lotto, serial, altro, idarticolo FROM co_righe_documenti WHERE id='.prepare($idrigadocumento).' AND idddt = 0 AND idordine = 0'; $rs = $dbo->fetchArray($query); if (sizeof($rs) > 0) { $dbo->query('DELETE FROM `mg_prodotti` WHERE lotto='.prepare($rs[0]['lotto']).' AND serial='.prepare($rs[0]['serial']).' AND altro='.prepare($rs[0]['altro']).' AND idarticolo='.prepare($rs[0]['idarticolo'])); } } // Elimino la riga dal documento $dbo->query('DELETE FROM `co_righe_documenti` WHERE idgruppo='.prepare($idgruppo).' AND iddocumento='.prepare($iddocumento)); // Elimino i movimenti avvenuti nel magazzino per questo articolo lotto, serial, altro $dbo->query('DELETE FROM `mg_movimenti` WHERE idarticolo = '.prepare($idarticolo).' AND iddocumento = '.prepare($iddocumento).' AND id = '.prepare($idrigadocumento)); return true; } function rimuovi_riga($iddocumento, $idriga) { } function aggiorna_sconto($tables, $fields, $id_record, $options = []) { $dbo = Database::getConnection(); $descrizione = strtoupper(tr('Sconto')); // Rimozione dello sconto precedente $dbo->query('DELETE FROM '.$tables['row']." WHERE descrizione LIKE '%".$descrizione."%' 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 if (!empty($sconto[0]['sconto_globale'])) { if ($sconto[0]['tipo_sconto_globale'] == 'PRC') { $subtotale = $dbo->fetchArray('SELECT SUM(subtotale - sconto) AS imponibile FROM (SELECT '.$tables['row'].'.subtotale, '.$tables['row'].'.sconto FROM '.$tables['row'].' WHERE '.$fields['row'].'='.prepare($id_record).((!isset($options['idgruppo']) || !empty($options['idgruppo'])) ? ' GROUP BY idgruppo' : '').') AS t')[0]['imponibile']; $subtotale = -$subtotale / 100 * $sconto[0]['sconto_globale']; $descrizione = $descrizione.' '.Translator::numberToLocale($sconto[0]['sconto_globale']).'%'; } else { $subtotale = -$sconto[0]['sconto_globale']; } // Calcolo dell'IVA da scontare $idiva = get_var('Iva predefinita'); $rsi = $dbo->select('co_iva', ['descrizione', 'percentuale'], ['id' => $idiva]); $iva = $subtotale / 100 * $rsi[0]['percentuale']; $values = [ $fields['row'] => $id_record, 'descrizione' => $descrizione, 'subtotale' => $subtotale, 'qta' => 1, 'idiva' => $idiva, 'desc_iva' => $rsi[0]['descrizione'], 'iva' => $iva, '#order' => '(SELECT IFNULL(MAX(`order`) + 1, 0) FROM '.$tables['row'].' AS t WHERE '.$fields['row'].'='.prepare($id_record).')', ]; // Opzione per disabilitare l'idgruppo (per preventivi) if (!isset($options['idgruppo']) || !empty($options['idgruppo'])) { $values['#idgruppo'] = '(SELECT IFNULL(MAX(`idgruppo`) + 1, 0) FROM '.$tables['row'].' AS t WHERE '.$fields['row'].'='.prepare($id_record).')'; } $dbo->insert($tables['row'], $values); } }