2017-02-09 14:42:17 +00:00
# include "lilib01.h"
2019-12-12 16:32:13 +01:00
# include "letint.h"
# include "sqlset.h"
2017-11-08 10:55:31 +00:00
# include <utility.h>
2017-12-12 14:07:36 +00:00
# include <progind.h>
2017-02-09 14:42:17 +00:00
2017-02-16 14:39:57 +00:00
# define SOLUZIONE_UNICA 1
# define FINO_A_PLAFOND 2
2017-02-09 14:42:17 +00:00
2019-12-12 16:32:13 +01:00
class TSQL_recordset ;
2018-10-23 10:21:33 +02:00
const TString make_key ( const int anno , const int numplaf )
{
static TString key ;
key . cut ( 0 ) . format ( " %04d|%06d " , anno , numplaf ) ;
return key ;
}
2019-07-23 17:23:41 +02:00
void TLi_manager : : elab_tipi_stati ( )
2017-02-09 14:42:17 +00:00
{
2019-07-23 17:23:41 +02:00
create_tipi_stati ( _tipi , _stati ) ;
2017-02-09 14:42:17 +00:00
}
2019-07-23 17:23:41 +02:00
const TToken_string & TLi_manager : : get_use ( TDocumento & d , const bool write )
2017-11-20 08:52:18 +00:00
{
static TToken_string & ret = get_tmp_string ( ) ;
2019-07-23 17:23:41 +02:00
TAssoc_array tab_iva = d . tabella_iva ( true ) ;
TString4 num_doc = d . numerazione ( ) ;
2017-11-20 08:52:18 +00:00
2019-07-23 17:23:41 +02:00
real pla_util = ZERO ;
2017-11-20 08:52:18 +00:00
2019-07-23 17:23:41 +02:00
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
if ( check_iva ( totali - > cod_iva ( ) . codice ( ) ) ) // Se l'iva del documento <20> diversa non mi interessa
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
pla_util + = totali - > imp_orig ( ) ;
2017-11-20 08:52:18 +00:00
}
}
2019-07-23 17:23:41 +02:00
if ( pla_util > ZERO )
2017-11-20 08:52:18 +00:00
{
if ( d . is_nota_credito ( ) )
{
2019-07-23 17:23:41 +02:00
ret . cut ( 0 ) < < incr_plaf ( d , pla_util , write ) ;
2017-11-20 08:52:18 +00:00
}
else
{
2019-07-23 17:23:41 +02:00
ret . cut ( 0 ) < < cons_plaf ( pla_util , write ) ;
2017-11-20 08:52:18 +00:00
if ( ret . starts_with ( " ERRORE " ) )
2019-07-23 17:23:41 +02:00
ret < < " al documento " < < d . numerazione ( ) < < " n. " < < d . numero ( ) < < " \n Totale plafond da utilizzare: " < < pla_util . string ( ) < < " \n Totale rimasto: " < < get_plafond ( ) . string ( ) ;
2017-11-20 08:52:18 +00:00
}
}
return ret ;
}
2019-07-23 17:23:41 +02:00
const TToken_string & TLi_manager : : cons_plaf ( real & plaf_used , const bool write )
2017-11-08 10:55:31 +00:00
{
2017-11-20 08:52:18 +00:00
static TToken_string used ( " " , ' , ' ) ; used . cut ( 0 ) ;
2019-07-23 17:23:41 +02:00
if ( ! _valid_plafond | | plaf_used > get_plafond ( ) )
2017-11-08 10:55:31 +00:00
{
used < < " ERRORE NEL CALCOLO DEL PLAFOND " ;
return used ;
}
bool close = false ;
2019-07-23 17:23:41 +02:00
TToken_string this_plaf ( " " , ' , ' ) ;
while ( plaf_used > ZERO )
2017-11-08 10:55:31 +00:00
{
// Calcolo quanto plafond ho usato
2019-07-23 17:23:41 +02:00
TString this_numprot = _plafondi . begin ( ) - > first ;
real this_amount = _plafondi . begin ( ) - > second ;
2017-11-08 10:55:31 +00:00
2019-07-23 17:23:41 +02:00
real this_utilizzato ;
2017-11-08 10:55:31 +00:00
2019-07-23 17:23:41 +02:00
if ( plaf_used > = this_amount )
2017-11-08 10:55:31 +00:00
{
close = true ;
2019-07-23 17:23:41 +02:00
this_utilizzato = this_amount ;
2017-11-08 10:55:31 +00:00
// Rimuovo il plafond dalla lista,
2019-07-23 17:23:41 +02:00
_plafondi . erase ( this_numprot ) ;
2017-11-08 10:55:31 +00:00
if ( write )
{
// lo chiudo
2019-07-23 17:23:41 +02:00
change_stato ( this_numprot , true ) ;
2017-11-08 10:55:31 +00:00
}
// e diminuisco tutto
2019-07-23 17:23:41 +02:00
_plafond - = this_amount ;
plaf_used - = this_amount ;
2017-11-08 10:55:31 +00:00
}
else
{
close = false ;
2019-07-23 17:23:41 +02:00
this_utilizzato = plaf_used ;
2017-11-08 10:55:31 +00:00
// e diminuisco tutto
2019-07-23 17:23:41 +02:00
_plafond - = plaf_used ;
_plafondi [ this_numprot ] - = plaf_used ;
plaf_used = ZERO ;
2017-11-08 10:55:31 +00:00
}
// Segno di aver usato il plafond
2017-11-10 09:07:00 +00:00
static TToken_string u ; u . cut ( 0 ) ;
2019-07-23 17:23:41 +02:00
u . add ( this_numprot , _planno ) ;
u . add ( this_utilizzato . string ( ) , _plimporto ) ;
2017-11-10 09:07:00 +00:00
u . add ( close ? " X " : " " , _plchiusura ) ;
used . add ( u ) ;
2017-11-08 10:55:31 +00:00
}
// Controllo di avere ancora plafond rimanente
2019-07-23 17:23:41 +02:00
if ( _plafond < = ZERO )
_valid_plafond = false ;
2017-11-08 10:55:31 +00:00
// Tolgo la virgola finale
used . cut ( used . len ( ) - 1 ) ;
return used ;
}
/* Aggiungo al plafond quello che trovo */
2019-07-23 17:23:41 +02:00
const TToken_string & TLi_manager : : incr_plaf ( TDocumento & d , real imp_nc , const bool write )
2017-11-08 10:55:31 +00:00
{
2017-11-20 08:52:18 +00:00
static TToken_string used ( " " , ' , ' ) ; used . cut ( 0 ) ;
2017-11-08 10:55:31 +00:00
// Controllo se questa nota credito si riferisce a un singolo documento, in quel caso aggiorno faccio un aggiornamento sulle lettere di intento
// Se si rif<69> a pi<70> documenti o non <20> specificato salta, meglio stare bassi
2019-07-23 17:23:41 +02:00
if ( d . get ( " NUMDOCRIF " ) . blank ( ) | | d . get ( " CODNUMRIF " ) . blank ( ) | | d . get ( " ANNORIF " ) . blank ( ) | | _ini_dic_int . year ( ) ! = d . get_int ( " ANNORIF " ) )
2017-11-08 10:55:31 +00:00
{
return used ;
}
TDocumento ds ( ' D ' , d . get_int ( " ANNORIF " ) , d . get ( " CODNUMRIF " ) , d . get_int ( " NUMDOCRIF " ) ) ;
2019-07-23 17:23:41 +02:00
TToken_string le_plafs ( ds . get ( " PLAFOND " ) , ' , ' ) ; // [ANNO|NUMPROT|UTILIZZATO],...
2017-11-20 08:52:18 +00:00
// Se il documento di riferimento non ha nulla inserito nel plafond esco, non mi interessa
2019-07-23 17:23:41 +02:00
if ( le_plafs . items ( ) = = 0 )
2017-11-08 10:55:31 +00:00
return used ;
// Controllo se non ho gi<67> ricevuto la quantit<69> da stornare di plafond nella nota credito
2019-07-23 17:23:41 +02:00
if ( imp_nc = = ZERO )
2017-11-08 10:55:31 +00:00
{
// In caso negativo la calcolo
2019-07-23 17:23:41 +02:00
TAssoc_array tab_iva = d . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
if ( check_iva ( totali - > cod_iva ( ) . codice ( ) ) )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
imp_nc + = totali - > imp_orig ( ) ;
2017-11-08 10:55:31 +00:00
}
}
}
// Controllo se ho del plafond da stornare
2019-07-23 17:23:41 +02:00
if ( imp_nc < = ZERO )
2017-11-08 10:55:31 +00:00
return used ;
bool open = false ;
2019-07-23 17:23:41 +02:00
TToken_string this_plaf ( " " , ' | ' ) ;
for ( int i = le_plafs . items ( ) - 1 ; i > = 0 & & imp_nc > ZERO ; i - - )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
le_plafs . get ( i , this_plaf ) ;
2017-11-08 10:55:31 +00:00
2017-11-10 09:07:00 +00:00
// Importo utilizzato del plafond
2019-07-23 17:23:41 +02:00
real importo_plaf = this_plaf . get ( _plimporto ) ;
2017-11-10 09:07:00 +00:00
// Importo gi<67> riaccreditato da altre NC
2019-07-23 17:23:41 +02:00
real importo_nc = this_plaf . get ( _plNC ) ;
2017-11-10 09:07:00 +00:00
// Importo possibile di plafond da stornare
2019-07-23 17:23:41 +02:00
real rimanente = importo_plaf - importo_nc ;
2017-11-10 09:07:00 +00:00
if ( rimanente = = ZERO )
// This isn't the plafond you're looking for
continue ;
2019-07-23 17:23:41 +02:00
if ( rimanente < imp_nc )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
imp_nc - = rimanente ;
2017-11-08 10:55:31 +00:00
}
else
{
2019-07-23 17:23:41 +02:00
rimanente = imp_nc ;
imp_nc = ZERO ;
2017-11-08 10:55:31 +00:00
}
2017-11-10 09:07:00 +00:00
// Salvo la quantit<69> utilizzata nelle TToken_string
2019-07-23 17:23:41 +02:00
this_plaf . add ( rimanente , _plNC ) ;
le_plafs . add ( this_plaf , i ) ;
2017-11-10 09:07:00 +00:00
2017-11-08 10:55:31 +00:00
// Aggiungo a plafond
2019-07-23 17:23:41 +02:00
const TString key = make_key ( this_plaf . get_int ( _planno ) , this_plaf . get_int ( _plnumprot ) ) ;
2017-11-08 10:55:31 +00:00
2019-07-23 17:23:41 +02:00
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-08 10:55:31 +00:00
{
open = false ;
// Incremento!
2019-07-23 17:23:41 +02:00
_plafondi [ key ] + = rimanente ;
2017-11-08 10:55:31 +00:00
}
else
{
// Va aggiunto ex novo!
// Calcolo l'importo delle righe che rientrano nel plafond
open = true ;
2019-07-23 17:23:41 +02:00
_plafondi . insert ( std : : pair < TString , real > ( key , rimanente ) ) ;
2017-11-08 10:55:31 +00:00
// Se devo scrivere abilito il plafond
if ( write )
{
2019-07-23 17:23:41 +02:00
change_stato ( key , false ) ;
2017-11-08 10:55:31 +00:00
}
}
// Segno di aver usato il plafond
2017-11-10 09:07:00 +00:00
static TToken_string u ; u . cut ( 0 ) ;
u . add ( key , _planno ) ;
2017-11-20 08:52:18 +00:00
u . add ( rimanente . string ( ) , _plimporto ) ;
2017-11-10 09:07:00 +00:00
u . add ( open ? " X " : " " , _plchiusura ) ;
used . add ( u ) ;
2017-11-08 10:55:31 +00:00
}
2017-11-10 09:07:00 +00:00
2017-11-20 08:52:18 +00:00
// Rigiro used, nelle note credito sono invertiti i plafond
2019-07-23 17:23:41 +02:00
static TToken_string used_app ( " " , ' , ' ) ; used_app . cut ( 0 ) ;
2017-11-20 08:52:18 +00:00
for ( int i = used . items ( ) ; i > 0 ; i - - )
2019-07-23 17:23:41 +02:00
used_app . add ( used . get ( used . items ( ) - i ) , i - 1 ) ;
2017-11-20 08:52:18 +00:00
2017-11-10 09:07:00 +00:00
// Sovrascrivo il documento
2019-07-23 17:23:41 +02:00
ds . put ( " PLAFOND " , le_plafs ) ;
2017-11-10 09:07:00 +00:00
ds . rewrite ( ) ;
// Tolgo la virgola finale
used . cut ( used . len ( ) - 1 ) ;
2017-11-20 08:52:18 +00:00
// Succedono cose in memoria, devo rimediare cos<6F>
2019-07-23 17:23:41 +02:00
return used_app ;
2017-11-08 10:55:31 +00:00
}
2017-11-20 08:52:18 +00:00
/*
void TLi_manager : : stornaDoc ( const TDocumento & d , const bool write )
2017-11-08 10:55:31 +00:00
{
// Devo ricaricare le righe sui plafond che ho
TToken_string plafs ( d . get ( " PLAFOND " ) , ' , ' ) ;
for ( int i = 0 ; i < plafs . items ( ) ; i + + )
{
TToken_string thisPlafond = plafs . get ( i ) ;
static TString key ; key . cut ( 0 ) < < thisPlafond . get ( _planno ) < < " | " < < thisPlafond . get ( _plnumprot ) ;
real thisImporto = thisPlafond . get ( _plimporto ) ;
TString asd = thisImporto . string ( ) ;
if ( d . is_nota_credito ( ) )
{
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
if ( thisImporto < plafondi [ key ] )
{
// Sottraggo
plafondi [ key ] - = thisImporto ;
}
else
{
if ( DEBUG_ENABLED )
{
if ( thisImporto > plafondi [ key ] )
error_box ( " Importo maggiore del plafond rimanente " ) ;
}
plafondi . erase ( key ) ;
}
}
else if ( DEBUG_ENABLED )
{
error_box ( " Houston abbiamo un problema...perch<63> non trovo questo plafond attivo!? " ) ;
}
}
else
{
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
//Sommo
plafondi [ key ] + = thisImporto ;
}
else
{
// Aggiungo ai plafond
plafondi . insert ( std : : pair < TString , real > ( key , thisImporto ) ) ;
// Se devo scrivere abilito il plafond
if ( write )
{
changeStato ( key , false ) ;
}
}
}
}
}
2017-11-20 08:52:18 +00:00
// Storna i documenti dopo a quello che riceve
void TLi_manager : : stornaDocs ( const TDocumento & d , const bool write )
{
TLista_documenti din ; // Legge tutti i documenti di input
// Trovo tutti i documenti che mi interessano
2019-07-23 17:23:41 +02:00
din . read ( ' D ' , _tipocf , _codcli , iniDicInt . year ( ) , tipi , stati , d . data ( ) , finDicInt ) ;
2017-11-20 08:52:18 +00:00
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
if ( d . numero ( ) < din [ i ] . numero ( ) )
{
stornaDoc ( din [ i ] , write ) ;
}
}
}
*/
2019-07-23 17:23:41 +02:00
const TToken_string & TLi_manager : : storna_doc ( const TDocumento & d , real imp_dc , const bool write )
2017-11-20 08:52:18 +00:00
{
static TToken_string used ( " " , ' , ' ) ; used . cut ( 0 ) ;
// True se devo stornare tutto il Doc
2019-07-23 17:23:41 +02:00
const bool totale = imp_dc . is_zero ( ) ;
2017-11-20 08:52:18 +00:00
bool ok = true ;
// Devo ricaricare le righe sui plafond che ho
TToken_string plafs ( d . get ( " PLAFOND " ) , ' , ' ) ;
2019-07-23 17:23:41 +02:00
for ( int i = 0 ; i < plafs . items ( ) & & imp_dc > ZERO ; i + + )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
TToken_string this_plafond = plafs . get ( i ) ;
const TString key = make_key ( this_plafond . get_int ( _planno ) , this_plafond . get_int ( _plnumprot ) ) ;
real this_importo = this_plafond . get ( _plimporto ) ;
2017-11-20 08:52:18 +00:00
if ( totale )
{
2019-07-23 17:23:41 +02:00
if ( this_importo > = imp_dc )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
this_importo = imp_dc ;
2017-11-20 08:52:18 +00:00
// Controllo se vado a stornare solo una parte o tutto, nel primo caso cambio la Token, nel secondo elimino normalmente
2019-07-23 17:23:41 +02:00
if ( this_importo > imp_dc )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
this_plafond . add ( imp_dc , _plimporto ) ;
plafs . add ( this_plafond , i ) ;
2017-11-20 08:52:18 +00:00
}
else
plafs . destroy ( i ) ;
2019-07-23 17:23:41 +02:00
imp_dc = ZERO ;
2017-11-20 08:52:18 +00:00
}
else
{
2019-07-23 17:23:41 +02:00
imp_dc - = this_importo ;
2017-11-20 08:52:18 +00:00
plafs . destroy ( i ) ;
}
}
2019-07-23 17:23:41 +02:00
TString asd = this_importo . string ( ) ;
2017-11-20 08:52:18 +00:00
if ( d . is_nota_credito ( ) )
{
2019-07-23 17:23:41 +02:00
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
if ( this_importo < _plafondi [ key ] )
2017-11-20 08:52:18 +00:00
{
// Sottraggo
2019-07-23 17:23:41 +02:00
_plafondi [ key ] - = this_importo ;
2017-11-20 08:52:18 +00:00
}
else
{
// Errore
used . cut ( 0 ) < < " ERRORE: Non <20> presente abbastanza plafond rimanente per stornare la Nota Credito " ;
return used ;
}
}
else
{
// Errore
if ( DEBUG_ENABLED )
error_box ( " Houston abbiamo un problema...perch<63> non trovo questo plafond attivo!? " ) ;
used . cut ( 0 ) < < " ERRORE: La lettera d'intento a cui si rif<69> questa Nota Credito non <20> aperta " ;
return used ;
}
}
else
{
2019-07-23 17:23:41 +02:00
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-20 08:52:18 +00:00
{
//Sommo
2019-07-23 17:23:41 +02:00
_plafondi [ key ] + = this_importo ;
2017-11-20 08:52:18 +00:00
}
else
{
// Aggiungo ai plafond
2019-07-23 17:23:41 +02:00
_plafondi . insert ( std : : pair < TString , real > ( key , this_importo ) ) ;
2017-11-20 08:52:18 +00:00
// Se devo scrivere abilito il plafond
if ( write )
{
2019-07-23 17:23:41 +02:00
change_stato ( key , false ) ;
2017-11-20 08:52:18 +00:00
}
}
}
}
used . cut ( 0 ) < < plafs ;
return used ;
}
// Where did you come from Cotton Eye Joe!
2017-11-08 10:55:31 +00:00
2017-11-20 08:52:18 +00:00
/*
bool TLi_manager : : recalcAfter ( const TDocumento & d , TLog_report & lerr )
{
TLista_documenti din ; // Legge tutti i documenti di input
bool ok = true ;
int first = - 1 ;
// Trovo tutti i documenti che mi interessano
2019-07-23 17:23:41 +02:00
din . read ( ' D ' , _tipocf , _codcli , iniDicInt . year ( ) , tipi , stati , d . data ( ) , finDicInt ) ;
2017-11-20 08:52:18 +00:00
for ( int i = 0 ; i < din . items ( ) & & ok ; i + + )
{
if ( d . numero ( ) < din [ i ] . numero ( ) )
{
if ( first = = - 1 ) first = i ;
const TToken_string & use = getUse ( din [ i ] , true ) ;
if ( use . starts_with ( " ERRORE " ) )
{
ok = false ;
lerr . log ( 2 , use ) ;
}
else
din [ i ] . put ( " PLAFOND " , use ) ;
}
}
if ( ok )
{
// Se va tutto bene scrivo tutti i documenti
for ( ; first < din . items ( ) ; first + + )
din [ first ] . rewrite ( ) ;
}
return ok ;
}
*/
2017-11-08 10:55:31 +00:00
/* Faccio un analisi di tutti i plafond aperti e li sommo salvandomeli in plafonds */
2019-07-23 17:23:41 +02:00
void TLi_manager : : elab_plafond ( )
2017-02-09 14:42:17 +00:00
{
2019-07-23 17:23:41 +02:00
_valid_plafond = false ;
2017-12-12 14:07:36 +00:00
// Controllo preventivo per evitare di fare calcoli su anni precedenti al plafond
2019-07-23 17:23:41 +02:00
if ( _ini_dic_int . year ( ) < 2017 )
2017-12-12 14:07:36 +00:00
return ;
2017-02-09 14:42:17 +00:00
TRelation letint ( LF_LETINT ) ;
TRectype filtro ( letint . curr ( ) ) ;
2019-07-23 17:23:41 +02:00
filtro . add ( " CODCLI " , _codcli ) ;
filtro . add ( " ANNO " , _ini_dic_int . year ( ) ) ;
2017-02-09 14:42:17 +00:00
// Creo un cursore ordinato e prelevo la prima riga non chiusa
2017-02-27 11:25:39 +00:00
TCursor c_dicint ( & letint , " " , 2 , & filtro , & filtro ) ;
2017-02-09 14:42:17 +00:00
if ( c_dicint . items ( ) > 0 )
{
2017-11-08 10:55:31 +00:00
// Cerco finch<63> non arrivo alla fine o non trovo una soluzione
2019-07-23 17:23:41 +02:00
for ( c_dicint = 0 ; c_dicint . pos ( ) < c_dicint . items ( ) & & ! _soluzione ; + + c_dicint )
2017-02-09 14:42:17 +00:00
{
TRectype row = c_dicint . curr ( ) ;
2017-11-08 10:55:31 +00:00
// Esco se raggiungo una data successiva al nostro documento
2019-07-23 17:23:41 +02:00
if ( row . get_date ( " DAL " ) > _fin_dic_int )
2017-11-08 10:55:31 +00:00
break ;
2017-02-09 14:42:17 +00:00
if ( ! row . get_bool ( " CHIUSA " ) )
{
2017-03-09 15:29:54 +00:00
if ( row . get_int ( " TIPOOP " ) ! = FINO_A_PLAFOND & & row . get_int ( " TIPOOP " ) ! = SOLUZIONE_UNICA ) break ;
2017-02-15 13:29:34 +00:00
2017-11-08 10:55:31 +00:00
if ( row . get_int ( " TIPOOP " ) = = SOLUZIONE_UNICA )
{
// Faccio un controllo in pi<70> per bloccare un utente con plafond di diverso tipo
2019-07-23 17:23:41 +02:00
if ( _valid_plafond )
2017-11-08 10:55:31 +00:00
{
// ERRORE! Esiste gi<67> un plafond e ho trovato una soluzione unica!
2019-07-23 17:23:41 +02:00
_valid_plafond = false ;
_plafondi . clear ( ) ;
_plafond = - UNO ;
2017-11-08 10:55:31 +00:00
return ;
}
2019-07-23 17:23:41 +02:00
_soluzione = true ;
2017-11-08 10:55:31 +00:00
}
2019-07-23 17:23:41 +02:00
if ( ! _valid_plafond )
_ini_dic_int = row . get_date ( " DAL " ) ;
2017-11-08 10:55:31 +00:00
// Aggiungo il plafond trovato all'elenco dei plafond
2018-10-23 10:21:33 +02:00
const TString key = make_key ( row . get_int ( " ANNO " ) , row . get_int ( " NUMPROT " ) ) ;
2019-07-23 17:23:41 +02:00
_plafondi . insert ( std : : pair < TString , real > ( key , row . get_real ( " IMPORTO " ) ) ) ;
2017-11-08 10:55:31 +00:00
// Aggiungo il valore del plafond al totale
2019-07-23 17:23:41 +02:00
_plafond + = row . get_real ( " IMPORTO " ) ;
_valid_plafond = true ;
2017-02-09 14:42:17 +00:00
}
}
}
2019-07-23 17:23:41 +02:00
if ( ! _valid_plafond )
_plafond = - UNO ;
2017-02-09 14:42:17 +00:00
}
2019-07-23 17:23:41 +02:00
const real TLi_manager : : get_pla_res ( )
2017-02-15 13:29:34 +00:00
{
2019-07-23 17:23:41 +02:00
return elab_pla_res ( ) ;
2017-02-15 13:29:34 +00:00
}
2019-07-23 17:23:41 +02:00
const real TLi_manager : : get_pla_res ( TToken_string tipi , TToken_string stati )
2017-02-15 13:29:34 +00:00
{
2019-07-23 17:23:41 +02:00
return elab_pla_res ( tipi , stati ) ;
2017-02-15 13:29:34 +00:00
}
2019-07-23 17:23:41 +02:00
const real TLi_manager : : elab_pla_res ( TToken_string t , TToken_string s , TDate ad )
2017-02-09 14:42:17 +00:00
{
2019-07-23 17:23:41 +02:00
if ( _elab_pr )
return _plafond ;
2017-11-20 08:52:18 +00:00
else
2019-07-23 17:23:41 +02:00
_elab_pr = true ;
2017-11-20 08:52:18 +00:00
if ( t . full ( ) & & s . full ( ) )
{
2019-07-23 17:23:41 +02:00
_tipi = t ;
_stati = s ;
2017-11-20 08:52:18 +00:00
}
if ( ! ad . ok ( ) )
2019-07-23 17:23:41 +02:00
ad = _fin_dic_int ;
_plafond = - UNO ;
if ( ! _valid_plafond )
return _plafond ;
2017-02-09 14:42:17 +00:00
TLista_documenti din ; // Legge tutti i documenti di input
2019-07-23 17:23:41 +02:00
// Trovo tutti i documenti che mi interessano e sottraggo l'imponibile al _plafond
din . read ( ' D ' , _tipocf , _codcli , _ini_dic_int . year ( ) , _tipi , _stati , _ini_dic_int , ad ) ;
2017-02-10 09:37:04 +00:00
for ( int i = 0 ; i < din . items ( ) ; i + + )
2017-02-09 14:42:17 +00:00
{
2017-11-08 10:55:31 +00:00
TToken_string plaf ( din [ i ] . get ( " PLAFOND " ) , ' , ' ) ;
2017-11-10 09:07:00 +00:00
for ( int j = 0 ; j < plaf . items ( ) ; j + + )
2017-02-09 14:42:17 +00:00
{
2019-07-23 17:23:41 +02:00
TToken_string the_pla ( plaf . get ( j ) ) ;
const TString key = make_key ( the_pla . get_int ( _planno ) , the_pla . get_int ( _plnumprot ) ) ;
static TString chiusura ; chiusura . cut ( 0 ) < < the_pla . get ( _plchiusura ) ; // La get ritorna un const char*
2017-11-08 10:55:31 +00:00
if ( din [ i ] . tipo ( ) . nota_credito ( ) )
{
2019-07-23 17:23:41 +02:00
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-08 10:55:31 +00:00
{
2017-11-10 09:07:00 +00:00
if ( DEBUG_ENABLED & & chiusura = = " X " & & yesno_box ( " Attenzione! La lettera con codice %s riferito alla nota credito %s, %d l'ho trovata ma dovevo aprirla adesso! \n Che faccio, azzero? " , key , din [ i ] . numerazione ( ) , din [ i ] . numero ( ) ) )
{
2019-07-23 17:23:41 +02:00
_plafondi [ key ] = ZERO ;
2017-11-10 09:07:00 +00:00
}
2019-07-23 17:23:41 +02:00
_plafondi [ key ] + = static_cast < real > ( the_pla . get ( _plimporto ) ) ;
2017-11-08 10:55:31 +00:00
}
else
{
// Va aggiunto ex novo!
2017-11-10 09:07:00 +00:00
if ( DEBUG_ENABLED & & chiusura ! = " X " & & yesno_box ( " Attenzione! La lettera con codice %s riferito alla nota credito %s, %d non l'ho trovata ma doveva gi<67> essere aperta! \n Che faccio, annullo? " , key , din [ i ] . numerazione ( ) , din [ i ] . numero ( ) ) )
{
2019-07-23 17:23:41 +02:00
_valid_plafond = false ;
return _plafond ;
2017-11-10 09:07:00 +00:00
}
2017-11-08 10:55:31 +00:00
// Calcolo l'importo delle righe che rientrano nel plafond
2019-07-23 17:23:41 +02:00
_plafondi . insert ( std : : pair < TString , real > ( key , static_cast < real > ( the_pla . get ( _plimporto ) ) ) ) ;
2017-11-08 10:55:31 +00:00
}
}
2017-11-10 09:07:00 +00:00
else
2017-02-24 13:35:42 +00:00
{
2019-07-23 17:23:41 +02:00
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-08 10:55:31 +00:00
{
2017-11-10 09:07:00 +00:00
if ( chiusura = = " X " )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
if ( DEBUG_ENABLED & & _plafondi [ key ] ! = static_cast < real > ( the_pla . get ( _plimporto ) ) & &
! yesno_box ( TR ( " Questa lettera di intento <20> incongruente, \n Totale attivo: %s \n Totale da disattivare: %s \n Continuare? " ) , _plafondi [ key ] . string ( ) , the_pla . get ( _plimporto ) ) )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
_valid_plafond = false ;
return _plafond ;
2017-11-08 10:55:31 +00:00
}
2019-07-23 17:23:41 +02:00
_plafondi . erase ( key ) ;
2017-11-08 10:55:31 +00:00
}
2017-11-10 09:07:00 +00:00
else
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
_plafondi [ key ] - = static_cast < real > ( the_pla . get ( _plimporto ) ) ;
2017-11-08 10:55:31 +00:00
}
}
}
}
2017-02-09 14:42:17 +00:00
}
2017-11-10 09:07:00 +00:00
// Calcolo il totale da mappa scansionata
2019-07-23 17:23:41 +02:00
_plafond = ZERO ;
for ( auto it = _plafondi . begin ( ) ; it ! = _plafondi . end ( ) ; + + it )
_plafond + = it - > second ;
2017-11-10 09:07:00 +00:00
2019-07-23 17:23:41 +02:00
return _plafond ;
2017-02-09 14:42:17 +00:00
}
2017-11-08 10:55:31 +00:00
2019-07-23 17:23:41 +02:00
const real TLi_manager : : elab_util ( TToken_string tipi , TToken_string stati , TDate ad )
2017-02-20 10:06:13 +00:00
{
2019-07-23 17:23:41 +02:00
if ( ! _valid_plafond )
2017-02-20 10:06:13 +00:00
return - UNO ;
2017-03-02 14:23:21 +00:00
if ( tipi . items ( ) = = 0 )
return ZERO ;
2017-02-20 10:06:13 +00:00
real utilizzato = ZERO ;
TLista_documenti din ; // Legge tutti i documenti di input
// Trovo tutti i documenti che mi interessano e sottraggo l'imponibile al plafond
2019-07-23 17:23:41 +02:00
din . read ( ' D ' , _tipocf , _codcli , _ini_dic_int . year ( ) , tipi , stati , _ini_dic_int , ad ) ;
2017-02-20 10:06:13 +00:00
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
2019-07-23 17:23:41 +02:00
TAssoc_array tab_iva = din [ i ] . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
2017-02-20 10:06:13 +00:00
{
2019-07-23 17:23:41 +02:00
if ( check_iva ( totali - > cod_iva ( ) . codice ( ) ) )
2017-02-24 13:35:42 +00:00
{
utilizzato + = cache ( ) . get ( " %TIP " , din [ i ] . tipo ( ) . codice ( ) ) . get_bool ( " B7 " ) ? - totali - > imp_orig ( ) : totali - > imp_orig ( ) ;
}
2017-02-20 10:06:13 +00:00
}
// Nel caso il plafond trovato fosse una soluzione unica e ho gi<67> trovato dei documenti vuol dire che il plafond non <20> pi<70> valido
2019-07-23 17:23:41 +02:00
if ( _soluzione )
2017-02-20 10:06:13 +00:00
{
utilizzato = - UNO ;
break ;
}
}
return utilizzato ;
}
2019-07-23 17:23:41 +02:00
bool TLi_manager : : test_plafond ( TLista_documenti & dout , TLog_report & lerr )
2017-02-09 14:42:17 +00:00
{
2017-02-10 09:37:04 +00:00
bool err = false ;
2017-11-20 08:52:18 +00:00
static TToken_string & use = get_tmp_string ( ) ;
2017-02-09 14:42:17 +00:00
// Faccio un ragionamento identico a getPlaRes, ma in input ho la lista di documenti appena elaborati
2017-11-20 08:52:18 +00:00
for ( int i = 0 ; i < dout . items ( ) & & ! err ; i + + )
2017-02-09 14:42:17 +00:00
{
2019-07-23 17:23:41 +02:00
use . cut ( 0 ) < < get_use ( dout [ i ] , true ) ;
2017-11-20 08:52:18 +00:00
if ( use . starts_with ( " ERRORE " ) )
2017-02-09 14:42:17 +00:00
{
2017-11-20 08:52:18 +00:00
TString msgerr ;
msgerr < < " Superata dichiarazione di intento cliente N. " < < dout [ i ] . codcf ( ) < < " \n " < < use ;
lerr . log ( 2 , msgerr ) ;
2019-07-23 17:23:41 +02:00
revert_modifiche ( ) ;
clear_modifiche ( ) ;
2017-11-20 08:52:18 +00:00
err = true ;
}
2017-02-09 14:42:17 +00:00
}
2017-02-10 09:37:04 +00:00
return err ;
2017-02-09 14:42:17 +00:00
}
2017-11-20 08:52:18 +00:00
/* Per scelte implementative non ha una accuratezza del 100% */
2019-07-23 17:23:41 +02:00
bool TLi_manager : : check_utilizzo ( TDocumento & d , real imp_nc )
2017-02-09 14:42:17 +00:00
{
2017-12-12 14:07:36 +00:00
bool ok = true ;
2019-07-23 17:23:41 +02:00
TToken_string le_plafs ( d . get ( " PLAFOND " ) , ' , ' ) ;
2017-11-08 10:55:31 +00:00
2017-11-20 08:52:18 +00:00
// Se me lo passa la funzione evito di calcolarlo
2019-07-23 17:23:41 +02:00
if ( imp_nc . is_zero ( ) )
2017-11-20 08:52:18 +00:00
{
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) d . tabella_iva ( true ) . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) d . tabella_iva ( true ) . get ( ) )
2019-07-23 17:23:41 +02:00
if ( check_iva ( totali - > cod_iva ( ) . codice ( ) ) ) // Se l'iva del documento <20> diversa non mi interessa
imp_nc + = totali - > imp_orig ( ) ;
2017-11-20 08:52:18 +00:00
}
/* Per sapere se non ho usato il plafond di questa NC controllo innanzitutto se c'<27> ne abbastanza
* rimasto per coprire la NC , non <EFBFBD> il controllo della vita ma toglie gi <EFBFBD> un po ' di calcoli */
2019-07-23 17:23:41 +02:00
ok = get_pla_res ( ) > imp_nc ;
2017-11-08 10:55:31 +00:00
2017-11-20 08:52:18 +00:00
// Sucessivamente vado in dettaglio a verificare se sono sempre maggiori (getPlaRes() mi carica anche la variabile "plafondi" per gli altri calcoli)
2019-07-23 17:23:41 +02:00
for ( int i = 0 ; i < le_plafs . items ( ) & & ok ; i + + )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
TToken_string this_plaf ( le_plafs . get ( i ) ) ;
const TString key = make_key ( this_plaf . get_int ( _planno ) , this_plaf . get_int ( _plnumprot ) ) ;
if ( _plafondi . find ( key ) ! = _plafondi . end ( ) )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
ok = _plafondi [ key ] > static_cast < real > ( le_plafs . get ( _plimporto ) ) ;
2017-11-20 08:52:18 +00:00
}
else
ok = false ;
2017-11-08 10:55:31 +00:00
}
2017-11-20 08:52:18 +00:00
return ok ;
2017-02-15 13:29:34 +00:00
}
2019-07-23 17:23:41 +02:00
void TLi_manager : : change_stato ( const TString & key , const bool stato )
2017-11-08 10:55:31 +00:00
{
TRectype Jean_Baptiste_Le_Rond_dAlembert = cache ( ) . get ( LF_LETINT , key ) ; // Che nome di classe!
Jean_Baptiste_Le_Rond_dAlembert . put ( " CHIUSA " , stato ) ;
Jean_Baptiste_Le_Rond_dAlembert . rewrite ( TLocalisamfile ( LF_LETINT ) ) ;
TString skey ; skey < < key < < " | " < < stato ? " " : " X " ; // Ottimizzazione portami via...
2019-07-23 17:23:41 +02:00
_modifiche . insert ( std : : pair < int , TString > ( _modifiche . size ( ) + 1 , skey ) ) ;
2017-11-08 10:55:31 +00:00
}
2019-07-23 17:23:41 +02:00
void TLi_manager : : revert_modifiche ( )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
if ( ! has_modifiche ( ) )
2017-11-08 10:55:31 +00:00
return ;
TLocalisamfile baguette ( LF_LETINT ) ;
2019-07-23 17:23:41 +02:00
for ( auto it = _modifiche . begin ( ) ; it ! = _modifiche . end ( ) ; + + it )
2017-11-08 10:55:31 +00:00
{
TToken_string key = it - > second ;
TRectype Jean_Baptiste_Le_Rond_dAlembert = cache ( ) . get ( LF_LETINT , key . get ( 0 ) ) ; // Che nome di classe!
Jean_Baptiste_Le_Rond_dAlembert . put ( " CHIUSA " , key . get ( 1 ) ) ;
Jean_Baptiste_Le_Rond_dAlembert . rewrite ( baguette ) ;
}
2019-07-23 17:23:41 +02:00
clear_modifiche ( ) ;
2017-11-08 10:55:31 +00:00
}
2017-02-16 14:39:57 +00:00
2017-11-20 08:52:18 +00:00
TLi_manager : : TLi_manager ( const char t , const long c , TDate iniDic , TDate finDic )
2019-07-23 17:23:41 +02:00
: _tipocf ( t ) , _codcli ( c ) , _ini_dic_int ( iniDic ) , _fin_dic_int ( finDic ) ,
_codiva_def ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ) ,
_codiva_alt ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ) ,
_plafond ( ZERO ) , _valid_plafond ( false ) , _soluzione ( false ) , _elab_pr ( false )
2017-11-20 08:52:18 +00:00
{
2019-07-23 17:23:41 +02:00
elab_tipi_stati ( ) ;
elab_plafond ( ) ;
2017-11-20 08:52:18 +00:00
}
TLi_manager : : TLi_manager ( const char t , const long c , TDate finDic )
2019-07-23 17:23:41 +02:00
: _tipocf ( t ) , _codcli ( c ) , _fin_dic_int ( finDic ) ,
_codiva_def ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ) ,
_codiva_alt ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ) ,
_plafond ( ZERO ) , _valid_plafond ( false ) , _soluzione ( false ) , _elab_pr ( false )
2017-11-08 10:55:31 +00:00
{
2019-07-23 17:23:41 +02:00
_ini_dic_int . set_day ( 01 ) ;
_ini_dic_int . set_month ( 01 ) ;
_ini_dic_int . set_year ( finDic . year ( ) ) ;
elab_tipi_stati ( ) ;
elab_plafond ( ) ;
2017-12-12 14:07:36 +00:00
}
2019-07-23 17:23:41 +02:00
static void create_tipi_stati ( TToken_string & tipi , TToken_string & stati )
2017-12-12 14:07:36 +00:00
{
static const TToken_string tipidoc ( ini_get_string ( CONFIG_DITTA , " li " , " TIPIDOC " ) ) ;
if ( tipi . blank ( ) & & stati . blank ( ) )
{
for ( int i = 0 ; i < tipidoc . items ( ) ; i + + )
{
TString app ( " " ) ;
tipidoc . get ( i , app ) ;
TToken_string statidoc ( ini_get_string ( CONFIG_DITTA , " li " , app ) , ' , ' ) ;
for ( int j = statidoc . get_int ( 0 ) ; j < = statidoc . get_int ( 1 ) ; j + + )
{
tipi . add ( app ) ;
stati . add ( j ) ;
}
}
}
}
2019-07-23 17:23:41 +02:00
bool genera_li_storico ( const TDate & data_ini )
2017-12-12 14:07:36 +00:00
{
// Apro la tabella dei plafonds con chiave 2 (CODCLI+ANNO+NUMPROT) e per ogni cliente calcolo i plafond dal 2017
TRelation rletint ( LF_LETINT ) ;
2019-07-23 17:23:41 +02:00
TString filter = " DAL>= " ; filter < < data_ini . date2ansi ( ) ;
2017-12-12 14:07:36 +00:00
TCursor cletint ( & rletint , filter , 2 ) ;
static TToken_string tipi , stati ;
2019-07-23 17:23:41 +02:00
create_tipi_stati ( tipi , stati ) ;
2017-12-12 14:07:36 +00:00
2019-07-23 17:23:41 +02:00
static TString cod_ivap = ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ;
static TString cod_ivas = ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ;
2017-12-12 14:07:36 +00:00
TProgress_monitor status ( cletint . items ( ) , " Aggiornamento plafond " ) ;
for ( cletint = 0 ; cletint . pos ( ) < cletint . items ( ) ; ) // Il cursore avanza sotto
{
if ( ! status . add_status ( ) )
break ;
TRectype rletint = cletint . curr ( ) ;
+ + cletint ;
TRectype rletintn = cletint . curr ( ) ;
// Controllo subuto che non sia una dichiarazione a tempo
if ( rletint . get_int ( " TIPOOP " ) = = 3 )
continue ;
// Date
2019-07-23 17:23:41 +02:00
TDate start_curr = rletint . get_date ( " DAL " ) , end_curr ;
end_curr = rletint . get_int ( " CODCLI " ) = = rletintn . get_int ( " CODCLI " ) ? - - rletintn . get_date ( " DAL " ) : NULLDATE ;
2017-12-12 14:07:36 +00:00
// Dati lettera
2019-07-23 17:23:41 +02:00
real imp_li = rletint . get_real ( " IMPORTO " ) ;
2017-12-12 14:07:36 +00:00
bool soluzione = rletint . get_int ( " TIPOOP " ) = = SOLUZIONE_UNICA ;
// Adesso che so le date apro tutti i documenti
TLista_documenti din ;
2019-07-23 17:23:41 +02:00
din . read ( ' D ' , ' C ' , rletint . get_long ( " CODCLI " ) , start_curr . year ( ) , tipi , stati , start_curr , end_curr ) ;
2017-12-12 14:07:36 +00:00
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
# ifdef DBG
if ( din [ i ] . numero ( ) = = 1202 & & din [ i ] . anno ( ) = = 2017 )
bool tolla = true ;
# endif
real utilizzato = ZERO ;
2019-07-23 17:23:41 +02:00
TAssoc_array tab_iva = din [ i ] . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
2017-12-12 14:07:36 +00:00
{
2019-07-23 17:23:41 +02:00
if ( totali - > cod_iva ( ) . codice ( ) = = cod_ivap | | totali - > cod_iva ( ) . codice ( ) = = cod_ivas )
2017-12-12 14:07:36 +00:00
utilizzato + = cache ( ) . get ( " %TIP " , din [ i ] . tipo ( ) . codice ( ) ) . get_bool ( " B7 " ) ? - totali - > imp_orig ( ) : totali - > imp_orig ( ) ;
}
if ( utilizzato . is_zero ( ) )
{
if ( DEBUG_ENABLED )
{
static bool erase = yesno_box ( " Vuoi resettare anche i documenti con utilizzo a zero? \n Ci metter<65> pi<70> tempo " ) ;
din [ i ] . put ( " PLAFOND " , " " ) ;
din [ i ] . rewrite ( ) ;
}
continue ;
}
// Controllo di non superare il plafond
2019-07-23 17:23:41 +02:00
if ( imp_li > = utilizzato )
2017-12-12 14:07:36 +00:00
{
// Creo la chiave da scrivere e metto tutto dentro
2018-10-23 10:21:33 +02:00
const TString key = make_key ( rletint . get_int ( " ANNO " ) , rletint . get_int ( " NUMPROT " ) ) ;
2017-12-12 14:07:36 +00:00
din [ i ] . put ( " PLAFOND " , key ) ;
din [ i ] . rewrite ( ) ;
}
else
{
// Error!
if ( DEBUG_ENABLED )
warning_box ( " Superato plafond, si passa alla nuova lettera " ) ;
break ;
}
// Solo per una lettera
if ( soluzione )
break ;
}
}
return true ;
2018-01-25 14:15:16 +00:00
}
2019-07-23 17:23:41 +02:00
bool popola_plafond ( TLista_documenti & din , const TDate & data_elab )
2018-01-25 14:15:16 +00:00
{
std : : map < int , TLi_manager * > plafs ;
2019-07-23 17:23:41 +02:00
TProgress_monitor m_doc ( din . items ( ) , " Generazione plafond nelle fatture " ) ;
2018-01-25 14:15:16 +00:00
bool ok = true ;
for ( int i = 0 ; i < din . items ( ) & & ok ; i + + )
{
2019-07-23 17:23:41 +02:00
if ( ! m_doc . add_status ( ) )
2018-01-25 14:15:16 +00:00
return false ;
// Per ogni fattura richiamo il plafond dell'intestatario e faccio le mie elaborazioni
if ( plafs . find ( din [ i ] . codcf ( ) ) = = plafs . end ( ) )
{
TLi_manager * app = new TLi_manager ( din [ i ] . tipocf ( ) , din [ i ] . codcf ( ) , data_elab ) ;
plafs . insert ( std : : pair < int , TLi_manager * > ( din [ i ] . codcf ( ) , app ) ) ;
}
2019-07-23 17:23:41 +02:00
TLi_manager & this_pla = * plafs [ din [ i ] . codcf ( ) ] ; // Forget about optimization!
if ( ! this_pla . has_valid_plafond ( ) ) continue ;
2018-01-25 14:15:16 +00:00
// Calcolo quanto plafond sta utilizzando
real utilizzato = ZERO ;
2019-07-23 17:23:41 +02:00
TAssoc_array tab_iva = din [ i ] . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
2018-01-25 14:15:16 +00:00
{
2019-07-23 17:23:41 +02:00
if ( this_pla . check_iva ( totali - > cod_iva ( ) . codice ( ) ) )
2018-01-25 14:15:16 +00:00
utilizzato + = cache ( ) . get ( " %TIP " , din [ i ] . tipo ( ) . codice ( ) ) . get_bool ( " B7 " ) ? - totali - > imp_orig ( ) : totali - > imp_orig ( ) ;
}
// Passo a un altro doc se non usa plafond
if ( utilizzato . is_zero ( ) ) continue ;
TToken_string used ;
if ( din [ i ] . tipo ( ) . nota_credito ( ) )
{
2019-07-23 17:23:41 +02:00
used = this_pla . incr_plaf ( din [ i ] , utilizzato , true ) ;
2018-01-25 14:15:16 +00:00
}
else
{
// Il controllo <20> andato bene, adesso mi segno i plafond che ho utilizzato nel memo del documento
2019-07-23 17:23:41 +02:00
used = this_pla . cons_plaf ( utilizzato , true ) ;
2018-01-25 14:15:16 +00:00
}
// Rincontrollo che l'utilizzo del pladond sia tutto ok, meglio una volta in pi<70> che una in meno!
if ( used . starts_with ( " ERRORE " ) )
{
error_box ( " Errore! Superato l'utilizzo del plafond per il documento %s %d, del cli/fo %c%d, come <20> possibile? " , din [ i ] . tipo ( ) . codice ( ) , din [ i ] . numero ( ) , din [ i ] . tipocf ( ) , din [ i ] . codcf ( ) ) ;
ok = false ;
}
else
{
din [ i ] . put ( " PLAFOND " , used ) ;
}
}
for ( auto it = plafs . begin ( ) ; it ! = plafs . end ( ) ; + + it )
delete it - > second ;
return ok ;
}
2019-12-12 16:32:13 +01:00
void scrivi_plafond ( TLista_documenti & din , const TDate & data_elab )
{
std : : map < int , TLi_manager * > plafonds ; // Mappa di clienti-plafond: il plafond e' l'insieme delle lettere
TProgress_monitor m_doc ( din . items ( ) , " Generazione plafond nelle fatture " ) ;
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
if ( ! m_doc . add_status ( ) )
return ;
// Per ogni fattura richiamo il plafond dell'intestatario e faccio le mie elaborazioni
if ( plafonds . find ( din [ i ] . codcf ( ) ) = = plafonds . end ( ) )
{
TLi_manager * plaf = new TLi_manager ( din [ i ] . tipocf ( ) , din [ i ] . codcf ( ) , data_elab ) ;
plafonds . insert ( std : : pair < int , TLi_manager * > ( din [ i ] . codcf ( ) , plaf ) ) ;
}
TLi_manager & this_pla = * plafonds [ din [ i ] . codcf ( ) ] ; // Forget about optimization!
if ( ! this_pla . has_valid_plafond ( ) )
continue ;
// Prima di tutto guardo se il documento ha righe esenti, altrimenti vado avanti
real esenz_this_doc = ZERO ;
TAssoc_array tab_iva = din [ i ] . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
{
if ( this_pla . check_iva ( totali - > cod_iva ( ) . codice ( ) ) )
esenz_this_doc + = cache ( ) . get ( " %TIP " , din [ i ] . tipo ( ) . codice ( ) ) . get_bool ( " B7 " ) ? - totali - > imp_orig ( ) : totali - > imp_orig ( ) ;
}
if ( esenz_this_doc . is_zero ( ) )
continue ;
// Non mi fido di cosa e' stato scritto sui documenti, ricontrollo a caldo che le lettere siano ancora aperte (ogni volta... lo so...)
// Prendo tutti i documenti, prendo tutte le righe di esenzione e le vado a sottrarre alla prima lettera. Se la supero guardo se ce ne sono altre.
// Se sto dentro sono a posto e so che sto usando ancora quella dichiarazione, se invece la supero e non c'e' un'altra ho sforato il plafond.
TLocalisamfile lint ( LF_LETINT ) ;
TSQL_recordset rec_lint ( " " ) ;
TString sql ; sql < < " SELECT * FROM LETINT WHERE ANNO= " < < din [ i ] . anno ( ) < < " AND CODCLI= " < < din [ i ] . clifor ( ) . codice ( ) ;
rec_lint . set ( sql ) ;
int n_letint = rec_lint . items ( ) ;
if ( n_letint > 0 )
rec_lint . move_next ( ) ;
lint . put ( LETINT_ANNO , din [ i ] . anno ( ) ) ;
lint . put ( LETINT_NUMPROT , rec_lint . get ( rec_lint . find_column ( LETINT_NUMPROT ) ) . as_string ( ) ) ;
lint . read ( ) ;
bool ok = true ;
TSQL_recordset docs ( " " ) ;
TToken_string tipi , stati ;
create_tipi_stati ( tipi , stati ) ;
sql . cut ( 0 ) < < " SELECT * FROM DOC \n "
" WHERE ANNO= " < < din [ i ] . anno ( ) < < " AND TIPOCF=' " < < din [ i ] . clifor ( ) . tipo ( ) < < " ' AND CODCF= " < < din [ i ] . clifor ( ) . codice ( ) < < " AND ( " ;
sql < < " CODNUM=' " < < tipi . get ( 0 ) < < " ' AND STATO= " < < stati . get ( 0 ) ;
for ( int z = 1 ; z < tipi . items ( ) ; + + z )
sql < < " OR CODNUM=' " < < tipi . get ( z ) < < " ' AND STATO= " < < stati . get ( z ) ;
sql < < " ) \n ORDER BY NDOC " ;
docs . set ( sql ) ;
real valore = rec_lint . get ( rec_lint . find_column ( LETINT_IMPORTO ) ) . as_real ( ) ;
for ( bool ok_d = docs . move_next ( ) ; ok_d ; ok_d = docs . move_next ( ) )
{
int ndoc = docs . get ( docs . find_column ( DOC_NDOC ) ) . as_int ( ) ;
const char * codnum = docs . get ( docs . find_column ( DOC_CODNUM ) ) . as_string ( ) ;
TDocumento p_doc ( ' D ' , din [ i ] . anno ( ) , codnum , ndoc ) ;
// Calcolo quanto plafond sta utilizzando
real esenzione = ZERO ;
// Calcolo quant'e' l'importo di esenzione sommando tutte le righe che hanno il codice esenzione iva per plafond
tab_iva . destroy ( ) ;
tab_iva = p_doc . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tab_iva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tab_iva . get ( ) )
{
if ( this_pla . check_iva ( totali - > cod_iva ( ) . codice ( ) ) )
esenzione + = cache ( ) . get ( " %TIP " , p_doc . tipo ( ) . codice ( ) ) . get_bool ( " B7 " ) ? - totali - > imp_orig ( ) : totali - > imp_orig ( ) ;
}
if ( ! p_doc . is_nota_credito ( ) )
valore - = esenzione ;
else
valore + = esenzione ;
if ( valore < ZERO )
{
lint . put ( LETINT_CHIUSA , " X " ) ; // Chiudo
lint . write ( ) ;
lint . rewrite ( ) ;
real resto = ZERO ;
if ( rec_lint . move_next ( ) ) // Passo alla successiva se c'e'
{
lint . put ( LETINT_ANNO , din [ i ] . anno ( ) ) ; // Dopo la move
lint . put ( LETINT_NUMPROT , rec_lint . get ( rec_lint . find_column ( LETINT_NUMPROT ) ) . as_string ( ) ) ;
lint . read ( ) ;
resto = - valore ;
valore = rec_lint . get ( rec_lint . find_column ( LETINT_IMPORTO ) ) . as_real ( ) - resto ;
}
else if ( valore < ZERO )
{
ok = false ;
break ;
}
}
}
if ( ! ok )
message_box ( " Attenzione c'e' almeno un documento che sfora il plafond per questo cliente: %d " , din [ i ] . clifor ( ) . codice ( ) ) ;
// Scrivo sul documento le lettere di intento utilizzate e l'importo di ciascuna
// N._riferimento_lettera1|anno1|importo_usato1,N._riferimento_lettera2|anno2|importo_usato2,...
TToken_string used ( " " , ' , ' ) ;
TToken_string single_used ( " " , ' | ' ) ;
if ( valore . not_zero ( ) )
{
// Guardo se ci sta tutto nella prima lettera o devo usare anche la successiva
single_used . add ( lint . get ( LETINT_ANNO ) ) ;
2019-12-18 14:08:22 +01:00
single_used . add ( TString ( lint . get ( LETINT_NUMPROT ) ) ) ;
2019-12-12 16:32:13 +01:00
real this_letint_importo = lint . get_real ( LETINT_IMPORTO ) ;
real resto = valore - esenz_this_doc ;
single_used . add ( resto > = ZERO ? esenz_this_doc : valore ) ;
used . add ( single_used ) ; // Aggiungo primo riferimento
single_used = " " ;
if ( valore < esenz_this_doc )
{
lint . put ( LETINT_CHIUSA , " X " ) ; // Chiudo
lint . write ( ) ;
lint . rewrite ( ) ;
if ( rec_lint . move_next ( ) ) // Se sforo la prima guardo se c'e' un'altra lettera altrimenti ho sforato veramente
{
lint . put ( LETINT_ANNO , din [ i ] . anno ( ) ) ;
lint . put ( LETINT_NUMPROT , rec_lint . get ( rec_lint . find_column ( LETINT_NUMPROT ) ) . as_string ( ) ) ;
lint . read ( ) ;
single_used . add ( lint . get ( LETINT_ANNO ) ) ;
2019-12-18 14:08:22 +01:00
single_used . add ( TString ( lint . get ( LETINT_NUMPROT ) ) ) ;
2019-12-12 16:32:13 +01:00
if ( lint . get_real ( LETINT_IMPORTO ) < - resto )
message_box ( " Errore... impossibile inserire ulteriori lettere di intento per questo documento. " ) ;
if ( lint . get_real ( LETINT_IMPORTO ) = = - resto )
{
lint . put ( LETINT_CHIUSA , " X " ) ; // Chiudo
lint . write ( ) ;
lint . rewrite ( ) ;
}
single_used . add ( - resto ) ;
used . add ( single_used ) ;
}
else
message_box ( " Attenzione c'e' un documento che sfora il plafond per questo cliente: \n %d, %s " , din [ i ] . clifor ( ) . codice ( ) , din [ i ] . clifor ( ) . get ( CLI_RAGSOC ) ) ;
}
else if ( valore = = esenz_this_doc ) // Se uguale chiudo la lettera
{
lint . put ( LETINT_CHIUSA , " X " ) ;
lint . write ( ) ;
lint . rewrite ( ) ;
}
}
din [ i ] . put ( " PLAFOND " , used ) ;
}
for ( auto it = plafonds . begin ( ) ; it ! = plafonds . end ( ) ; + + it )
delete it - > second ;
}