2017-08-04 16:28:16 +02:00
< ? php
/**
* Funzione per generare un nuovo numero per la fattura .
*/
function get_new_numerofattura ( $data )
{
global $dir ;
2018-03-21 22:30:15 +01:00
global $id_segment ;
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2018-03-22 15:40:20 +01:00
if ( $dir == 'uscita' ) {
2018-03-21 22:30:15 +01:00
// recupero maschera per questo segmento
2018-05-04 19:25:45 +02:00
$rs_maschera = $dbo -> fetchArray ( 'SELECT pattern FROM zz_segments WHERE id = ' . prepare ( $id_segment ));
2018-03-21 22:30:15 +01:00
// esempio: ####/YY
$maschera = $rs_maschera [ 0 ][ 'pattern' ];
// estraggo blocchi di caratteri standard da sostituire
2018-03-22 15:40:20 +01:00
preg_match ( '/[#]+/' , $maschera , $m1 );
preg_match ( '/[Y]+/' , $maschera , $m2 );
2018-03-21 22:30:15 +01:00
2018-05-04 19:25:45 +02:00
$query = " SELECT numero FROM co_documenti WHERE DATE_FORMAT(data,'%Y') = " . prepare ( date ( 'Y' , strtotime ( $data ))) . ' AND id_segment = ' . prepare ( $id_segment );
2018-03-22 15:40:20 +01:00
$pos1 = strpos ( $maschera , $m1 [ 0 ]);
2018-05-04 19:25:45 +02:00
if ( $pos1 == 0 ) {
$query .= ' ORDER BY CAST(numero AS UNSIGNED) DESC LIMIT 0,1' ;
} else {
2018-03-22 15:40:20 +01:00
$query .= ' ORDER BY numero DESC LIMIT 0,1' ;
2018-05-04 19:25:45 +02:00
}
2018-03-22 15:40:20 +01:00
$rs_ultima_fattura = $dbo -> fetchArray ( $query );
2018-03-21 22:30:15 +01:00
$numero = Util\Generator :: generate ( $maschera , $rs_ultima_fattura [ 0 ][ 'numero' ]);
2018-03-22 15:40:20 +01:00
} else {
$query = " SELECT IFNULL(MAX(numero),'0') AS max_numerofattura 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 AS UNSIGNED) DESC LIMIT 0, 1' ;
2018-03-21 22:30:15 +01:00
$rs = $dbo -> fetchArray ( $query );
2017-08-04 16:28:16 +02:00
2018-03-21 22:30:15 +01:00
$numero = $rs [ 0 ][ 'max_numerofattura' ] + 1 ;
}
2017-08-04 16:28:16 +02:00
return $numero ;
}
/**
* Funzione per calcolare il numero secondario successivo utilizzando la maschera dalle impostazioni .
*/
function get_new_numerosecondariofattura ( $data )
{
global $dir ;
2018-03-21 16:57:31 +01:00
global $id_segment ;
2017-08-04 16:28:16 +02:00
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2018-03-21 16:57:31 +01:00
// recupero maschera per questo segmento
2018-05-04 19:25:45 +02:00
$rs_maschera = $dbo -> fetchArray ( 'SELECT pattern FROM zz_segments WHERE id = ' . prepare ( $id_segment ));
2018-03-19 19:07:32 +01:00
// esempio: ####/YY
2018-03-21 16:57:31 +01:00
$maschera = $rs_maschera [ 0 ][ 'pattern' ];
2018-03-07 23:50:28 +01:00
// estraggo blocchi di caratteri standard da sostituire
2018-03-22 15:40:20 +01:00
preg_match ( '/[#]+/' , $maschera , $m1 );
preg_match ( '/[Y]+/' , $maschera , $m2 );
2018-03-07 23:50:28 +01:00
2018-05-04 19:25:45 +02:00
$query = " SELECT numero_esterno FROM co_documenti WHERE DATE_FORMAT(data,'%Y') = " . prepare ( date ( 'Y' , strtotime ( $data ))) . ' AND id_segment=' . prepare ( $id_segment );
2018-03-07 23:50:28 +01:00
// Marzo 2017
// nel caso ci fossero lettere prima della maschera ### per il numero (es. FT-0001-2017)
2018-03-22 15:40:20 +01:00
// è necessario l'ordinamento alfabetico "ORDER BY numero_esterno" altrimenti
2018-03-07 23:50:28 +01:00
// nel caso di maschere del tipo 001-2017 è necessario l'ordinamento numerico "ORDER BY CAST(numero_esterno AS UNSIGNED)"
2018-03-22 15:40:20 +01:00
$pos1 = strpos ( $maschera , $m1 [ 0 ]);
2018-05-04 19:25:45 +02:00
if ( $pos1 == 0 ) {
$query .= ' ORDER BY CAST(numero_esterno AS UNSIGNED) DESC LIMIT 0,1' ;
} else {
2018-03-22 15:40:20 +01:00
$query .= ' ORDER BY numero_esterno DESC LIMIT 0,1' ;
2018-05-04 19:25:45 +02:00
}
2018-03-22 15:40:20 +01:00
$rs_ultima_fattura = $dbo -> fetchArray ( $query );
2018-03-08 00:45:32 +01:00
2018-03-22 15:40:20 +01:00
$numero_esterno = Util\Generator :: generate ( $maschera , $rs_ultima_fattura [ 0 ][ 'numero_esterno' ]);
2017-08-04 16:28:16 +02:00
return $numero_esterno ;
}
/**
* Elimina una scadenza in base al codice documento .
*/
function elimina_scadenza ( $iddocumento )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$query2 = 'DELETE FROM co_scadenziario WHERE iddocumento=' . prepare ( $iddocumento );
$dbo -> query ( $query2 );
}
/**
2018-05-18 19:04:39 +02:00
* Funzione per ricalcolare lo scadenzario di una determinata fattura
* $iddocumento string E ' l' id del documento di cui ricalcolare lo scadenzario
2017-08-04 16:28:16 +02:00
* $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 = '' )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$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 ) {
2017-08-31 16:23:26 +02:00
$date = new DateTime ( $data );
$add = floor ( $rs [ $i ][ 'num_giorni' ] / 30 );
for ( $c = 0 ; $c < $add ; ++ $c ) {
$date -> modify ( 'last day of next month' );
}
2017-08-04 16:28:16 +02:00
// Ultimo del mese più X giorni
2017-08-31 16:23:26 +02:00
$giorni = - $rs [ $i ][ 'giorno' ] - 1 ;
if ( $giorni > 0 ) {
$date -> modify ( '+' . ( $giorni ) . ' day' );
2018-06-22 17:04:37 +02:00
} else {
$date -> modify ( 'last day of this month' );
}
2017-08-31 16:23:26 +02:00
$scadenza = $date -> format ( 'Y-m-d' );
2017-08-04 16:28:16 +02:00
}
// 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 )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
// 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 ) {
2018-05-15 10:52:33 +02:00
if ( $rimanente_da_pagare != 0 ) {
2017-08-04 16:28:16 +02:00
// ...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 )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$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 )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
// 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 );
2018-05-11 18:15:36 +02:00
// Calcolo l'iva della rivalsa inps
$iva_rivalsainps = 0 ;
2018-06-22 17:04:37 +02:00
$rsr = $dbo -> fetchArray ( 'SELECT idiva, rivalsainps FROM co_righe_documenti WHERE iddocumento=' . prepare ( $iddocumento ));
for ( $r = 0 ; $r < sizeof ( $rsr ); ++ $r ) {
$qi = 'SELECT percentuale FROM co_iva WHERE id=' . prepare ( $rsr [ $r ][ 'idiva' ]);
2018-05-11 18:15:36 +02:00
$rsi = $dbo -> fetchArray ( $qi );
$iva_rivalsainps += $rsr [ $r ][ 'rivalsainps' ] / 100 * $rsi [ 0 ][ 'percentuale' ];
}
2017-08-04 16:28:16 +02:00
// 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
2018-04-16 10:39:11 +02:00
$query = 'SELECT iva FROM co_righe_documenti WHERE iddocumento=' . prepare ( $iddocumento );
2017-08-04 16:28:16 +02:00
$rs = $dbo -> fetchArray ( $query );
2018-06-14 14:56:15 +02:00
$iva_fattura = sum ( array_column ( $rs , 'iva' ), null ) + $iva_rivalsainps - $iva_indetraibile_fattura ;
2017-08-04 16:28:16 +02:00
// 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 .
*/
2018-05-04 19:25:45 +02:00
function get_new_idmastrino ( $table = 'co_movimenti' )
2017-08-04 16:28:16 +02:00
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
2018-05-04 17:57:46 +02:00
$query = 'SELECT MAX(idmastrino) AS maxidmastrino FROM ' . $table ;
2017-08-04 16:28:16 +02:00
$rs = $dbo -> fetchArray ( $query );
return intval ( $rs [ 0 ][ 'maxidmastrino' ]) + 1 ;
}
/**
* Calcolo imponibile fattura ( totale_righe - sconto ) .
*/
function get_imponibile_fattura ( $iddocumento )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$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 );
2018-06-22 17:04:37 +02:00
2018-05-11 16:57:34 +02:00
return $rs [ 0 ][ 'imponibile' ];
2017-08-04 16:28:16 +02:00
}
/**
* Calcolo totale fattura ( imponibile + iva ) .
*/
function get_totale_fattura ( $iddocumento )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
// Sommo l'iva di ogni riga al totale
2018-06-14 14:56:15 +02:00
$query = 'SELECT SUM(iva) AS iva FROM co_righe_documenti GROUP BY iddocumento HAVING iddocumento=' . prepare ( $iddocumento );
2017-08-04 16:28:16 +02:00
$rs = $dbo -> fetchArray ( $query );
// Aggiungo la rivalsa inps se c'è
$query2 = 'SELECT rivalsainps FROM co_documenti WHERE id=' . prepare ( $iddocumento );
$rs2 = $dbo -> fetchArray ( $query2 );
2018-05-11 18:15:36 +02:00
$iva_rivalsainps = 0 ;
2018-06-22 17:04:37 +02:00
$rsr = $dbo -> fetchArray ( 'SELECT idiva, rivalsainps FROM co_righe_documenti WHERE iddocumento=' . prepare ( $iddocumento ));
for ( $r = 0 ; $r < sizeof ( $rsr ); ++ $r ) {
$qi = 'SELECT percentuale FROM co_iva WHERE id=' . prepare ( $rsr [ $r ][ 'idiva' ]);
2018-05-11 18:15:36 +02:00
$rsi = $dbo -> fetchArray ( $qi );
$iva_rivalsainps += $rsr [ $r ][ 'rivalsainps' ] / 100 * $rsi [ 0 ][ 'percentuale' ];
}
2018-06-22 17:04:37 +02:00
2018-06-14 14:56:15 +02:00
$iva = $rs [ 0 ][ 'iva' ];
2018-05-11 16:28:18 +02:00
$totale_iva = sum ( $iva , $iva_rivalsainps );
2018-06-22 17:04:37 +02:00
2018-05-11 16:28:18 +02:00
$totale = sum ([
get_imponibile_fattura ( $iddocumento ),
$rs2 [ 0 ][ 'rivalsainps' ],
$totale_iva ,
]);
return $totale ;
2017-08-04 16:28:16 +02:00
}
/**
* Calcolo netto a pagare fattura ( totale - ritenute - bolli ) .
*/
function get_netto_fattura ( $iddocumento )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$query = 'SELECT ritenutaacconto, bollo FROM co_documenti WHERE id=' . prepare ( $iddocumento );
$rs = $dbo -> fetchArray ( $query );
2018-05-11 16:28:18 +02:00
$netto_a_pagare = sum ([
get_totale_fattura ( $iddocumento ),
$rs [ 0 ][ 'bollo' ],
- $rs [ 0 ][ 'ritenutaacconto' ],
]);
2018-06-22 17:04:37 +02:00
2018-05-11 16:28:18 +02:00
return $netto_a_pagare ;
2017-08-04 16:28:16 +02:00
}
/**
* Calcolo iva detraibile fattura .
*/
function get_ivadetraibile_fattura ( $iddocumento )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$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 )
{
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
$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 $dir ;
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
// 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' ];
2018-05-11 18:15:36 +02:00
$iva_rivalsainps = 0 ;
2018-06-22 17:04:37 +02:00
$rsr = $dbo -> fetchArray ( 'SELECT idiva, rivalsainps FROM co_righe_documenti WHERE iddocumento=' . prepare ( $iddocumento ));
for ( $r = 0 ; $r < sizeof ( $rsr ); ++ $r ) {
$qi = 'SELECT percentuale FROM co_iva WHERE id=' . prepare ( $rsr [ $r ][ 'idiva' ]);
2017-08-04 16:28:16 +02:00
$rsi = $dbo -> fetchArray ( $qi );
2018-05-11 18:15:36 +02:00
$iva_rivalsainps += $rsr [ $r ][ 'rivalsainps' ] / 100 * $rsi [ 0 ][ 'percentuale' ];
2017-08-04 16:28:16 +02:00
}
// 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
2018-07-04 12:57:53 +02:00
$bolli = ( $dir == 'uscita' ) ? $bolli : get_var ( 'Importo marca da bollo' );
$bolli = Translator :: getFormatter () -> parse ( $bolli );
2017-08-04 16:28:16 +02:00
2018-07-04 12:57:53 +02:00
$marca_da_bollo = 0 ;
if ( abs ( $bolli ) > 0 && abs ( $netto_a_pagare > get_var ( " Soglia minima per l'applicazione della marca da bollo " ))) {
$marca_da_bollo = $bolli ;
2017-08-04 16:28:16 +02:00
}
2018-07-04 12:57:53 +02:00
// Se l'importo è negativo può essere una nota di accredito, quindi cambio segno alla marca da bollo
$marca_da_bollo = abs ( $marca_da_bollo );
2017-08-04 16:28:16 +02:00
$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 ) .
*/
2018-07-24 18:36:29 +02:00
function add_articolo_infattura ( $iddocumento , $idarticolo , $descrizione , $idiva , $qta , $prezzo , $sconto = 0 , $sconto_unitario = 0 , $tipo_sconto = 'UNT' , $idintervento = 0 , $idconto = 0 , $idum = 0 , $idrivalsainps = '' , $idritenutaacconto = '' , $calcolo_ritenutaacconto = '' )
2017-08-04 16:28:16 +02:00
{
global $dir ;
global $idddt ;
2018-06-25 11:44:06 +02:00
global $idordine ;
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
if ( empty ( $idddt )) {
2017-08-04 16:28:16 +02:00
$idddt = 0 ;
}
2018-06-26 14:30:26 +02:00
2018-06-25 11:44:06 +02:00
if ( empty ( $idordine )) {
$idordine = 0 ;
}
2017-08-04 16:28:16 +02:00
// 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 ;
}
// 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' ];
2018-07-24 18:36:29 +02:00
if ( ! empty ( $idrivalsainps )){
// Calcolo rivalsa inps
$rs = $dbo -> fetchArray ( 'SELECT * FROM co_rivalsainps WHERE id=' . prepare ( $idrivalsainps ));
$rivalsainps = ( $prezzo - $sconto ) / 100 * $rs [ 0 ][ 'percentuale' ];
}
if ( ! empty ( $idritenutaacconto )){
// Calcolo ritenuta d'acconto
$query = 'SELECT * FROM co_ritenutaacconto WHERE id=' . prepare ( $idritenutaacconto );
$rs = $dbo -> fetchArray ( $query );
if ( $calcolo_ritenutaacconto == 'Imponibile' ) {
$ritenutaacconto = ( $prezzo - $sconto ) / 100 * $rs [ 0 ][ 'percentuale' ];
} else if ( $calcolo_ritenutaacconto == 'Imponibile + rivalsa inps' ) {
$ritenutaacconto = ( $prezzo - $sconto + $rivalsainps ) / 100 * $rs [ 0 ][ 'percentuale' ];
}
}
2017-08-04 16:28:16 +02:00
2018-07-03 17:28:02 +02:00
if ( $qta != 0 ) {
2017-08-04 16:28:16 +02:00
$rsart = $dbo -> fetchArray ( 'SELECT abilita_serial FROM mg_articoli WHERE id=' . prepare ( $idarticolo ));
2018-07-24 18:36:29 +02:00
$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, idconto, um, `order`, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, calcolo_ritenutaacconto) 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 ( $idconto ) . ', ' . prepare ( $um ) . ', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento=' . prepare ( $iddocumento ) . '), ' . prepare ( $idritenutaacconto ) . ', ' . prepare ( $ritenutaacconto ) . ', ' . prepare ( $idrivalsainps ) . ', ' . prepare ( $rivalsainps ) . ', ' . prepare ( $calcolo_ritenutaacconto ) . ')' );
2017-08-04 16:28:16 +02:00
$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 ));
2018-06-26 14:30:26 +02:00
2018-06-25 11:44:06 +02:00
// Inserisco il riferimento dell'ordine alla riga
$dbo -> query ( 'UPDATE co_righe_documenti SET idordine=' . prepare ( $idordine ) . ' WHERE id=' . prepare ( $idriga ));
2017-08-04 16:28:16 +02:00
}
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 $dir ;
2018-06-22 17:04:37 +02:00
$dbo = Database :: getConnection ();
2017-08-04 16:28:16 +02:00
// Leggo la quantità di questo articolo in fattura
2017-09-05 18:20:02 +02:00
$query = 'SELECT qta, idintervento, idpreventivo, idordine, idddt, subtotale, descrizione FROM co_righe_documenti WHERE id=' . prepare ( $idrigadocumento );
2017-08-04 16:28:16 +02:00
$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' ];
$descrizione = $rs [ 0 ][ 'descrizione' ];
$lotto = $rs [ 0 ][ 'lotto' ];
$serial = $rs [ 0 ][ 'serial' ];
$altro = $rs [ 0 ][ 'altro' ];
2017-09-05 17:31:58 +02:00
$non_rimovibili = seriali_non_rimuovibili ( 'id_riga_documento' , $idrigadocumento , $dir );
if ( ! empty ( $non_rimovibili )) {
return false ;
2017-08-04 16:28:16 +02:00
}
// 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 ]);
}
}
2017-09-05 18:20:02 +02:00
// TODO: possibile ambiguità tra righe molto simili tra loro
2017-08-04 16:28:16 +02:00
// Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa
if ( ! empty ( $idddt )) {
2017-09-05 18:20:02 +02:00
$dbo -> query ( 'UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-' . $qta . ' WHERE qta=' . prepare ( $qta ) . ' AND idarticolo=' . prepare ( $idarticolo ) . ' AND idddt=' . prepare ( $idddt ));
2017-08-04 16:28:16 +02:00
}
2017-09-05 18:20:02 +02:00
// TODO: possibile ambiguità tra righe molto simili tra loro
2017-08-04 16:28:16 +02:00
// 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 ));
}
}
2018-07-04 12:57:53 +02:00
2017-08-04 16:28:16 +02:00
// Elimino la riga dal documento
2017-09-05 17:31:58 +02:00
$dbo -> query ( 'DELETE FROM `co_righe_documenti` WHERE id=' . prepare ( $idrigadocumento ) . ' AND iddocumento=' . prepare ( $iddocumento ));
2018-06-26 14:30:26 +02:00
2018-07-04 12:57:53 +02:00
// Aggiorno lo stato dell'ordine
2018-06-26 14:30:26 +02:00
if ( get_var ( 'Cambia automaticamente stato ordini fatturati' ) && ! empty ( $idordine )) {
2018-06-25 11:44:06 +02:00
$dbo -> query ( 'UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="' . get_stato_ordine ( $idordine ) . '") WHERE id = ' . prepare ( $idordine ));
}
2018-06-26 14:30:26 +02:00
2018-07-04 12:57:53 +02:00
// Aggiorno lo stato del ddt
2018-06-26 14:30:26 +02:00
if ( get_var ( 'Cambia automaticamente stato ddt fatturati' ) && ! empty ( $idddt )) {
2018-06-25 11:44:06 +02:00
$dbo -> query ( 'UPDATE dt_ddt SET idstatoddt=(SELECT id FROM dt_statiddt WHERE descrizione="' . get_stato_ddt ( $idddt ) . '") WHERE id = ' . prepare ( $idddt ));
}
2017-08-04 16:28:16 +02:00
// 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 ));
2017-09-06 10:48:59 +02:00
// Elimino i seriali utilizzati dalla riga
$dbo -> query ( 'DELETE FROM `mg_prodotti` WHERE id_articolo = ' . prepare ( $idarticolo ) . ' AND id_riga_documento = ' . prepare ( $idrigadocumento ));
2017-08-04 16:28:16 +02:00
return true ;
}
2017-08-28 12:15:30 +02:00
function aggiorna_sconto ( $tables , $fields , $id_record , $options = [])
{
$dbo = Database :: getConnection ();
2017-09-10 14:35:41 +02:00
$descrizione = tr ( 'Sconto' , [], [ 'upper' => true ]);
2017-08-28 12:15:30 +02:00
// Rimozione dello sconto precedente
2017-09-11 11:28:39 +02:00
$dbo -> query ( 'DELETE FROM ' . $tables [ 'row' ] . ' WHERE sconto_globale = 1 AND ' . $fields [ 'row' ] . '=' . prepare ( $id_record ));
2017-08-28 12:15:30 +02:00
// 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
2018-02-16 13:12:07 +01:00
$iva = 0 ;
2018-02-18 19:53:23 +01:00
2017-08-28 12:15:30 +02:00
if ( ! empty ( $sconto [ 0 ][ 'sconto_globale' ])) {
if ( $sconto [ 0 ][ 'tipo_sconto_globale' ] == 'PRC' ) {
2018-05-04 19:25:45 +02:00
$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' );
2018-02-16 13:12:07 +01:00
$subtotale = $rs [ 0 ][ 'imponibile' ];
$iva += $rs [ 0 ][ 'iva' ] / 100 * $sconto [ 0 ][ 'sconto_globale' ];
2017-08-28 12:15:30 +02:00
$subtotale = - $subtotale / 100 * $sconto [ 0 ][ 'sconto_globale' ];
2018-05-04 19:25:45 +02:00
$descrizione = $descrizione . ' ' . Translator :: numberToLocale ( $sconto [ 0 ][ 'sconto_globale' ]) . '%' ;
2017-08-28 12:15:30 +02:00
} else {
2018-05-04 19:25:45 +02:00
$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' );
2018-03-27 15:31:29 +02:00
$subtotale = $rs [ 0 ][ 'imponibile' ];
2018-05-04 19:25:45 +02:00
$iva += $sconto [ 0 ][ 'sconto_globale' ] * $rs [ 0 ][ 'iva' ] / $subtotale ;
2017-08-28 12:15:30 +02:00
$subtotale = - $sconto [ 0 ][ 'sconto_globale' ];
}
// Calcolo dell'IVA da scontare
$idiva = get_var ( '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' ],
2018-02-16 13:12:07 +01:00
'iva' => - $iva ,
2017-09-11 11:28:39 +02:00
'sconto_globale' => 1 ,
2017-08-28 12:15:30 +02:00
'#order' => '(SELECT IFNULL(MAX(`order`) + 1, 0) FROM ' . $tables [ 'row' ] . ' AS t WHERE ' . $fields [ 'row' ] . '=' . prepare ( $id_record ) . ')' ,
];
2017-09-05 17:31:58 +02:00
$dbo -> insert ( $tables [ 'row' ], $values );
}
}
function controlla_seriali ( $field , $id_riga , $old_qta , $new_qta , $dir )
{
$dbo = Database :: getConnection ();
2018-07-04 12:57:53 +02:00
$new_qta = abs ( $new_qta );
$old_qta = abs ( $old_qta );
2017-09-05 17:31:58 +02:00
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' ]));
}
}
2017-08-28 12:15:30 +02:00
}
2017-09-05 17:31:58 +02:00
}
2017-08-28 12:15:30 +02:00
2017-09-05 17:31:58 +02:00
return true ;
}
2018-06-22 17:52:51 +02:00
/**
* Individua i seriali non rimuovibili poichè utilizzati in documenti rilasciati .
*
* @ param string $field
* @ param int $id_riga
* @ param string $dir
*
* @ return array
*/
2017-09-05 17:31:58 +02:00
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 ));
2017-08-28 12:15:30 +02:00
}
2017-09-05 17:31:58 +02:00
return $results ;
2017-08-28 12:15:30 +02:00
}
2018-05-04 19:25:45 +02:00
2018-06-22 17:52:51 +02:00
/**
* Calcola gli sconti in modo automatico .
*
* @ param array $data
*
* @ return float
*/
2018-05-04 19:25:45 +02:00
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 ;
}
2018-06-22 17:52:51 +02:00
/**
* 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 [];
}
2018-07-04 12:57:53 +02:00
function rimuovi_riga_fattura ( $id_documento , $id_riga , $dir )
{
$dbo = Database :: getConnection ();
// Leggo la quantità di questo articolo in fattura
$riga = $dbo -> fetchOne ( 'SELECT * FROM co_righe_documenti WHERE id=' . prepare ( $id_riga ));
$non_rimovibili = seriali_non_rimuovibili ( 'id_riga_documento' , $id_riga , $dir );
if ( ! empty ( $non_rimovibili )) {
return false ;
}
$serials = $dbo -> fetchArray ( 'SELECT serial FROM mg_prodotti WHERE serial IS NOT NULL AND id_riga_documento=' . prepare ( $id_riga ));
// Elimino la riga dal documento
$dbo -> query ( 'DELETE FROM `co_righe_documenti` WHERE id=' . prepare ( $id_riga ) . ' AND iddocumento=' . prepare ( $id_documento ));
if ( empty ( $riga [ 'qta' ])) {
return true ;
}
// Operazioni per la rimozione degli articoli
if ( ! empty ( $riga [ 'idarticolo' ])) {
// Movimentazione articoli se da interventi o ddt
if ( empty ( $riga [ 'idintervento' ]) && empty ( $riga [ 'idddt' ])) {
add_movimento_magazzino ( $riga [ 'idarticolo' ], ( $dir == 'entrata' ) ? $riga [ 'qta' ] : - $riga [ 'qta' ], [ 'iddocumento' => $id_documento ]);
}
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa
if ( ! empty ( $riga [ 'idddt' ])) {
$dbo -> query ( 'UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-' . $riga [ 'qta' ] . ' WHERE qta=' . prepare ( $riga [ 'qta' ]) . ' AND idarticolo=' . prepare ( $riga [ 'idarticolo' ]) . ' AND idddt=' . prepare ( $riga [ 'idddt' ]));
}
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa
if ( ! empty ( $riga [ 'idordine' ])) {
$dbo -> query ( 'UPDATE or_righe_ordini SET qta_evasa=qta_evasa-' . $riga [ 'qta' ] . ' WHERE qta=' . prepare ( $riga [ 'qta' ]) . ' AND idarticolo=' . prepare ( $riga [ 'idarticolo' ]) . ' AND idordine=' . prepare ( $riga [ 'idordine' ]));
}
// Nota di accredito
if ( ! empty ( $riga [ 'ref_riga_documento' ])) {
$dbo -> query ( 'UPDATE co_righe_documenti SET qta_evasa = qta_evasa+' . $riga [ 'qta' ] . ' WHERE id=' . prepare ( $riga [ 'ref_riga_documento' ]));
$serials = array_column ( $serials , 'serial' );
$serials = array_filter ( $serials , function ( $value ) { return ! empty ( $value ); });
$dbo -> attach ( 'mg_prodotti' , [ 'id_riga_documento' => $riga [ 'ref_riga_documento' ], 'dir' => $dir , 'id_articolo' => $riga [ 'idarticolo' ]], [ 'serial' => $serials ]);
}
}
2018-07-27 15:04:30 +02:00
// Rimozione articoli collegati ad un preventivo importato con riga unica
if ( empty ( $riga [ 'idarticolo' ]) && $riga [ 'is_preventivo' ]){
//rimetto a magazzino gli articoli collegati al preventivo
$rsa = $dbo -> fetchArray ( 'SELECT idarticolo, qta FROM co_righe_preventivi WHERE idpreventivo = ' . prepare ( $riga [ 'idpreventivo' ]));
for ( $i = 0 ; $i < sizeof ( $rsa ); ++ $i ) {
if ( ! empty ( $rsa [ $i ][ 'idarticolo' ]))
add_movimento_magazzino ( $rsa [ $i ][ 'idarticolo' ], $rsa [ $i ][ 'qta' ], [ 'iddocumento' => $id_documento ]);
}
}
// Rimozione articoli collegati ad un contratto importato con riga unica
if ( empty ( $riga [ 'idarticolo' ]) && $riga [ 'is_contratto' ]){
//rimetto a magazzino gli articoli collegati al contratto
$rsa = $dbo -> fetchArray ( 'SELECT idarticolo, qta FROM co_righe_contratti WHERE idcontratto = ' . prepare ( $riga [ 'idcontratto' ]));
for ( $i = 0 ; $i < sizeof ( $rsa ); ++ $i ) {
if ( ! empty ( $rsa [ $i ][ 'idarticolo' ]))
add_movimento_magazzino ( $rsa [ $i ][ 'idarticolo' ], $rsa [ $i ][ 'qta' ], [ 'iddocumento' => $id_documento ]);
}
}
2018-07-04 12:57:53 +02:00
// Aggiorno lo stato dell'ordine
if ( ! empty ( $riga [ 'idordine' ]) && get_var ( 'Cambia automaticamente stato ordini fatturati' )) {
$dbo -> query ( 'UPDATE or_ordini SET idstatoordine = (SELECT id FROM or_statiordine WHERE descrizione = ' . prepare ( get_stato_ordine ( $riga [ 'idordine' ])) . ') WHERE id = ' . prepare ( $riga [ 'idordine' ]));
}
// Aggiorno lo stato del ddt
if ( ! empty ( $riga [ 'idddt' ]) && get_var ( 'Cambia automaticamente stato ddt fatturati' )) {
$dbo -> query ( 'UPDATE dt_ddt SET idstatoddt = (SELECT id FROM dt_statiddt WHERE descrizione = ' . prepare ( get_stato_ddt ( $riga [ 'idddt' ])) . ') WHERE id = ' . prepare ( $riga [ 'idddt' ]));
}
// Elimino i movimenti avvenuti nel magazzino per questo articolo lotto, serial, altro
$dbo -> query ( 'DELETE FROM `mg_movimenti` WHERE idarticolo = ' . prepare ( $riga [ 'idarticolo' ]) . ' AND iddocumento = ' . prepare ( $id_documento ) . ' AND id = ' . prepare ( $id_riga ));
// Elimino i seriali utilizzati dalla riga
$dbo -> query ( 'DELETE FROM `mg_prodotti` WHERE id_articolo = ' . prepare ( $riga [ 'idarticolo' ]) . ' AND id_riga_documento = ' . prepare ( $id_riga ));
return true ;
}