2017-02-09 14:42:17 +00:00
# include "lilib01.h"
2017-02-13 14:33:49 +00:00
# include <recarray.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
2017-11-20 08:52:18 +00:00
void TLi_manager : : elabTipiStati ( )
2017-02-09 14:42:17 +00:00
{
2017-12-12 14:07:36 +00:00
createTipiStati ( tipi , stati ) ;
2017-02-09 14:42:17 +00:00
}
2017-11-20 08:52:18 +00:00
const TToken_string & TLi_manager : : getUse ( TDocumento & d , const bool write )
{
static TToken_string & ret = get_tmp_string ( ) ;
TAssoc_array tabIva = d . tabella_iva ( true ) ;
real plaUtil = ZERO ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tabIva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tabIva . get ( ) )
{
if ( checkIva ( totali - > cod_iva ( ) . codice ( ) ) ) // Se l'iva del documento <20> diversa non mi interessa
{
plaUtil + = totali - > imp_orig ( ) ;
}
}
if ( plaUtil > ZERO )
{
if ( d . is_nota_credito ( ) )
{
ret . cut ( 0 ) < < incrPlaf ( d , plaUtil , write ) ;
}
else
{
ret . cut ( 0 ) < < consPlaf ( plaUtil , write ) ;
if ( ret . starts_with ( " ERRORE " ) )
ret < < " al documento " < < d . numerazione ( ) < < " n. " < < d . numero ( ) < < " \n Totale plafond da consumare: " < < plaUtil . string ( ) < < " \n Totale rimasto: " < < getPlafond ( ) . string ( ) ;
}
}
return ret ;
}
2017-11-10 09:07:00 +00:00
const TToken_string & TLi_manager : : consPlaf ( real & plafUsed , 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
if ( ! validPlafond | | plafUsed > getPlafond ( ) )
{
used < < " ERRORE NEL CALCOLO DEL PLAFOND " ;
return used ;
}
bool close = false ;
TToken_string thisPlaf ( " " , ' , ' ) ;
while ( plafUsed > ZERO )
{
// Calcolo quanto plafond ho usato
TString thisNumprot = plafondi . begin ( ) - > first ;
real thisAmount = plafondi . begin ( ) - > second ;
real thisUtilizzato ;
if ( plafUsed > = thisAmount )
{
close = true ;
thisUtilizzato = thisAmount ;
// Rimuovo il plafond dalla lista,
plafondi . erase ( thisNumprot ) ;
if ( write )
{
// lo chiudo
changeStato ( thisNumprot , true ) ;
}
// e diminuisco tutto
plafond - = thisAmount ;
plafUsed - = thisAmount ;
}
else
{
close = false ;
thisUtilizzato = plafUsed ;
// e diminuisco tutto
plafond - = plafUsed ;
plafondi [ thisNumprot ] - = plafUsed ;
plafUsed = ZERO ;
}
// Segno di aver usato il plafond
2017-11-10 09:07:00 +00:00
static TToken_string u ; u . cut ( 0 ) ;
u . add ( thisNumprot , _planno ) ;
u . add ( thisUtilizzato . string ( ) , _plimporto ) ;
u . add ( close ? " X " : " " , _plchiusura ) ;
used . add ( u ) ;
2017-11-08 10:55:31 +00:00
}
// Controllo di avere ancora plafond rimanente
if ( plafond < = ZERO )
validPlafond = false ;
// Tolgo la virgola finale
used . cut ( used . len ( ) - 1 ) ;
return used ;
}
/* Aggiungo al plafond quello che trovo */
2017-11-10 09:07:00 +00:00
const TToken_string & TLi_manager : : incrPlaf ( TDocumento & d , real impNC , 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
if ( d . get ( " NUMDOCRIF " ) . blank ( ) | | d . get ( " CODNUMRIF " ) . blank ( ) | | d . get ( " ANNORIF " ) . blank ( ) | | iniDicInt . year ( ) ! = d . get_int ( " ANNORIF " ) )
{
return used ;
}
TDocumento ds ( ' D ' , d . get_int ( " ANNORIF " ) , d . get ( " CODNUMRIF " ) , d . get_int ( " NUMDOCRIF " ) ) ;
TToken_string lePlafs ( 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
2017-11-08 10:55:31 +00:00
if ( lePlafs . items ( ) = = 0 )
return used ;
// Controllo se non ho gi<67> ricevuto la quantit<69> da stornare di plafond nella nota credito
2017-11-10 09:07:00 +00:00
if ( impNC = = ZERO )
2017-11-08 10:55:31 +00:00
{
// In caso negativo la calcolo
TAssoc_array tabIva = d . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tabIva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tabIva . get ( ) )
{
if ( checkIva ( totali - > cod_iva ( ) . codice ( ) ) )
{
2017-11-10 09:07:00 +00:00
impNC + = totali - > imp_orig ( ) ;
2017-11-08 10:55:31 +00:00
}
}
}
// Controllo se ho del plafond da stornare
if ( impNC < = ZERO )
return used ;
bool open = false ;
2017-11-10 09:07:00 +00:00
TToken_string thisPlaf ( " " , ' | ' ) ;
2017-11-08 10:55:31 +00:00
for ( int i = lePlafs . items ( ) - 1 ; i > = 0 & & impNC > ZERO ; i - - )
{
lePlafs . get ( i , thisPlaf ) ;
2017-11-10 09:07:00 +00:00
// Importo utilizzato del plafond
2017-11-08 10:55:31 +00:00
real importoPlaf = thisPlaf . get ( _plimporto ) ;
2017-11-10 09:07:00 +00:00
// Importo gi<67> riaccreditato da altre NC
real importoNC = thisPlaf . get ( _plNC ) ;
// Importo possibile di plafond da stornare
real rimanente = importoPlaf - importoNC ;
if ( rimanente = = ZERO )
// This isn't the plafond you're looking for
continue ;
if ( rimanente < impNC )
2017-11-08 10:55:31 +00:00
{
2017-11-10 09:07:00 +00:00
impNC - = rimanente ;
2017-11-08 10:55:31 +00:00
}
else
{
2017-11-10 09:07:00 +00:00
rimanente = impNC ;
2017-11-08 10:55:31 +00:00
impNC = ZERO ;
}
2017-11-10 09:07:00 +00:00
// Salvo la quantit<69> utilizzata nelle TToken_string
thisPlaf . add ( rimanente , _plNC ) ;
lePlafs . add ( thisPlaf , i ) ;
2017-11-08 10:55:31 +00:00
// Aggiungo a plafond
static TString key ; key . cut ( 0 ) < < thisPlaf . get ( _planno ) < < " | " < < thisPlaf . get ( _plnumprot ) ;
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
open = false ;
// Incremento!
2017-11-20 08:52:18 +00: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 ;
2017-11-20 08:52:18 +00: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 )
{
changeStato ( key , false ) ;
}
}
// 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
static TToken_string usedApp ( " " , ' , ' ) ; usedApp . cut ( 0 ) ;
for ( int i = used . items ( ) ; i > 0 ; i - - )
usedApp . add ( used . get ( used . items ( ) - i ) , i - 1 ) ;
2017-11-10 09:07:00 +00:00
// Sovrascrivo il documento
ds . put ( " PLAFOND " , lePlafs ) ;
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>
return usedApp ;
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
din . read ( ' D ' , tipocf , codcli , iniDicInt . year ( ) , tipi , stati , d . data ( ) , finDicInt ) ;
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
if ( d . numero ( ) < din [ i ] . numero ( ) )
{
stornaDoc ( din [ i ] , write ) ;
}
}
}
*/
const TToken_string & TLi_manager : : stornaDoc ( const TDocumento & d , real impDC , const bool write )
{
static TToken_string used ( " " , ' , ' ) ; used . cut ( 0 ) ;
// True se devo stornare tutto il Doc
bool totale = impDC . is_zero ( ) ;
bool ok = true ;
// Devo ricaricare le righe sui plafond che ho
TToken_string plafs ( d . get ( " PLAFOND " ) , ' , ' ) ;
for ( int i = 0 ; i < plafs . items ( ) & & impDC > ZERO ; i + + )
{
TToken_string thisPlafond = plafs . get ( i ) ;
static TString key ; key . cut ( 0 ) < < thisPlafond . get ( _planno ) < < " | " < < thisPlafond . get ( _plnumprot ) ;
real thisImporto = thisPlafond . get ( _plimporto ) ;
if ( totale )
{
if ( thisImporto > = impDC )
{
thisImporto = impDC ;
// Controllo se vado a stornare solo una parte o tutto, nel primo caso cambio la Token, nel secondo elimino normalmente
if ( thisImporto > impDC )
{
thisPlafond . add ( impDC , _plimporto ) ;
plafs . add ( thisPlafond , i ) ;
}
else
plafs . destroy ( i ) ;
impDC = ZERO ;
}
else
{
impDC - = thisImporto ;
plafs . destroy ( i ) ;
}
}
TString asd = thisImporto . string ( ) ;
if ( d . is_nota_credito ( ) )
{
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
if ( thisImporto < plafondi [ key ] )
{
// Sottraggo
plafondi [ key ] - = thisImporto ;
}
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
{
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 ) ;
}
}
}
}
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
din . read ( ' D ' , tipocf , codcli , iniDicInt . year ( ) , tipi , stati , d . data ( ) , finDicInt ) ;
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 */
2017-02-09 14:42:17 +00:00
void TLi_manager : : elabPlafond ( )
{
2017-12-12 14:07:36 +00:00
validPlafond = false ;
// Controllo preventivo per evitare di fare calcoli su anni precedenti al plafond
if ( iniDicInt . year ( ) < 2017 )
return ;
2017-02-09 14:42:17 +00:00
TRelation letint ( LF_LETINT ) ;
TRectype filtro ( letint . curr ( ) ) ;
filtro . add ( " CODCLI " , codcli ) ;
2017-11-20 08:52:18 +00:00
filtro . add ( " ANNO " , iniDicInt . 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
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
if ( row . get_date ( " DAL " ) > finDicInt )
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
if ( validPlafond )
{
// ERRORE! Esiste gi<67> un plafond e ho trovato una soluzione unica!
validPlafond = false ;
plafondi . clear ( ) ;
plafond = - UNO ;
return ;
}
soluzione = true ;
}
if ( ! validPlafond )
iniDicInt = row . get_date ( " DAL " ) ;
// Aggiungo il plafond trovato all'elenco dei plafond
static TString key ;
key . cut ( 0 ) < < row . get ( " ANNO " ) < < " | " < < row . get ( " NUMPROT " ) ;
plafondi . insert ( std : : pair < TString , real > ( key , row . get_real ( " IMPORTO " ) ) ) ;
// Aggiungo il valore del plafond al totale
plafond + = row . get_real ( " IMPORTO " ) ;
2017-02-09 14:42:17 +00:00
validPlafond = true ;
}
}
}
2017-02-15 13:29:34 +00:00
if ( ! validPlafond )
plafond = - UNO ;
2017-02-09 14:42:17 +00:00
}
const real TLi_manager : : getPlaRes ( )
2017-02-15 13:29:34 +00:00
{
2017-11-20 08:52:18 +00:00
return elabPlaRes ( ) ;
2017-02-15 13:29:34 +00:00
}
const real TLi_manager : : getPlaRes ( TToken_string tipi , TToken_string stati )
{
return elabPlaRes ( tipi , stati ) ;
}
2017-11-20 08:52:18 +00:00
const real TLi_manager : : elabPlaRes ( TToken_string t , TToken_string s , TDate ad )
2017-02-09 14:42:17 +00:00
{
2017-11-20 08:52:18 +00:00
if ( elabPR )
return plafond ;
else
elabPR = true ;
if ( t . full ( ) & & s . full ( ) )
{
tipi = t ;
stati = s ;
}
if ( ! ad . ok ( ) )
ad = finDicInt ;
2017-11-10 09:07:00 +00:00
plafond = - UNO ;
2017-02-09 14:42:17 +00:00
if ( ! validPlafond )
2017-11-10 09:07:00 +00:00
return plafond ;
2017-02-09 14:42:17 +00:00
TLista_documenti din ; // Legge tutti i documenti di input
// Trovo tutti i documenti che mi interessano e sottraggo l'imponibile al plafond
2017-03-02 14:23:21 +00:00
din . read ( ' D ' , tipocf , codcli , iniDicInt . year ( ) , tipi , stati , iniDicInt , 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
{
2017-11-10 09:07:00 +00:00
TToken_string thePla ( plaf . get ( j ) ) ;
static TString key ; key . cut ( 0 ) < < thePla . get ( _planno ) < < " | " < < thePla . get ( _plnumprot ) ;
static TString chiusura ; chiusura . cut ( 0 ) < < thePla . get ( _plchiusura ) ; // La get ritorna un const char*
2017-11-08 10:55:31 +00:00
if ( din [ i ] . tipo ( ) . nota_credito ( ) )
{
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
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 ( ) ) )
{
plafondi [ key ] = ZERO ;
}
2017-11-20 08:52:18 +00:00
plafondi [ key ] + = static_cast < real > ( thePla . 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 ( ) ) )
{
validPlafond = false ;
return plafond ;
}
2017-11-08 10:55:31 +00:00
// Calcolo l'importo delle righe che rientrano nel plafond
2017-11-20 08:52:18 +00:00
plafondi . insert ( std : : pair < TString , real > ( key , static_cast < real > ( thePla . 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
{
2017-11-08 10:55:31 +00:00
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
2017-11-10 09:07:00 +00:00
if ( chiusura = = " X " )
2017-11-08 10:55:31 +00:00
{
2017-11-20 08:52:18 +00:00
if ( DEBUG_ENABLED & & plafondi [ key ] ! = static_cast < real > ( thePla . get ( _plimporto ) ) & &
2017-11-10 09:07:00 +00:00
! yesno_box ( TR ( " Questa lettera di intento <20> incongruente, \n Totale attivo: %s \n Totale da disattivare: %s \n Continuare? " ) , plafondi [ key ] . string ( ) , thePla . get ( _plimporto ) ) )
2017-11-08 10:55:31 +00:00
{
2017-11-10 09:07:00 +00:00
validPlafond = false ;
return plafond ;
2017-11-08 10:55:31 +00:00
}
2017-11-10 09:07:00 +00: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
{
2017-11-20 08:52:18 +00:00
plafondi [ key ] - = static_cast < real > ( thePla . 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
plafond = ZERO ;
for ( auto it = plafondi . begin ( ) ; it ! = plafondi . end ( ) ; + + it )
plafond + = it - > second ;
2017-11-08 10:55:31 +00:00
return plafond ;
2017-02-09 14:42:17 +00:00
}
2017-11-08 10:55:31 +00:00
2017-02-20 10:06:13 +00:00
const real TLi_manager : : elabUtil ( TToken_string tipi , TToken_string stati , TDate ad )
{
if ( ! validPlafond )
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
2017-03-02 14:23:21 +00:00
din . read ( ' D ' , tipocf , codcli , iniDicInt . year ( ) , tipi , stati , iniDicInt , ad ) ;
2017-02-20 10:06:13 +00:00
for ( int i = 0 ; i < din . items ( ) ; i + + )
{
TAssoc_array tabIva = din [ i ] . tabella_iva ( true ) ;
2017-02-24 13:35:42 +00:00
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tabIva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tabIva . get ( ) )
2017-02-20 10:06:13 +00:00
{
2017-11-08 10:55:31 +00:00
if ( checkIva ( 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
if ( soluzione )
{
utilizzato = - UNO ;
break ;
}
}
return utilizzato ;
}
2017-11-20 08:52:18 +00:00
bool TLi_manager : : testPlafond ( 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
{
2017-11-20 08:52:18 +00:00
use . cut ( 0 ) < < getUse ( dout [ i ] , true ) ;
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 ) ;
revertModifiche ( ) ;
clearModifiche ( ) ;
err = true ;
}
else
{
dout [ i ] . put ( " PLAFOND " , use ) ;
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% */
bool TLi_manager : : checkUtilizzo ( TDocumento & d , real impNC )
2017-02-09 14:42:17 +00:00
{
2017-12-12 14:07:36 +00:00
bool ok = true ;
2017-11-20 08:52:18 +00:00
TToken_string lePlafs ( 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
if ( impNC . is_zero ( ) )
{
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) d . tabella_iva ( true ) . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) d . tabella_iva ( true ) . get ( ) )
if ( checkIva ( totali - > cod_iva ( ) . codice ( ) ) ) // Se l'iva del documento <20> diversa non mi interessa
impNC + = totali - > imp_orig ( ) ;
}
/* 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 */
ok = getPlaRes ( ) > impNC ;
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)
for ( int i = 0 ; i < lePlafs . items ( ) & & ok ; i + + )
2017-11-08 10:55:31 +00:00
{
2017-11-20 08:52:18 +00:00
TToken_string thisPlaf ( lePlafs . get ( i ) ) ;
static TString key ; key . cut ( 0 ) < < thisPlaf . get ( _planno ) < < " | " < < thisPlaf . get ( _plnumprot ) ;
if ( plafondi . find ( key ) ! = plafondi . end ( ) )
{
ok = plafondi [ key ] > static_cast < real > ( lePlafs . get ( _plimporto ) ) ;
}
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
}
2017-11-08 10:55:31 +00:00
void TLi_manager : : changeStato ( const TString & key , const bool stato )
{
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...
modifiche . insert ( std : : pair < int , TString > ( modifiche . size ( ) + 1 , skey ) ) ;
}
void TLi_manager : : revertModifiche ( )
{
if ( ! hasModifiche ( ) )
return ;
TLocalisamfile baguette ( LF_LETINT ) ;
for ( auto it = modifiche . begin ( ) ; it ! = modifiche . end ( ) ; + + it )
{
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 ) ;
}
clearModifiche ( ) ;
}
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 )
: tipocf ( t ) , codcli ( c ) , iniDicInt ( iniDic ) , finDicInt ( finDic ) ,
codivaDef ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ) ,
codivaAlt ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ) ,
plafond ( ZERO ) , validPlafond ( false ) , soluzione ( false ) , elabPR ( false )
{
elabTipiStati ( ) ;
elabPlafond ( ) ;
}
TLi_manager : : TLi_manager ( const char t , const long c , TDate finDic )
: tipocf ( t ) , codcli ( c ) , finDicInt ( finDic ) ,
codivaDef ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ) ,
codivaAlt ( ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ) ,
plafond ( ZERO ) , validPlafond ( false ) , soluzione ( false ) , elabPR ( false )
2017-11-08 10:55:31 +00:00
{
2017-11-20 08:52:18 +00:00
iniDicInt . set_day ( 01 ) ;
iniDicInt . set_month ( 01 ) ;
iniDicInt . set_year ( finDic . year ( ) ) ;
elabTipiStati ( ) ;
2017-11-08 10:55:31 +00:00
elabPlafond ( ) ;
2017-12-12 14:07:36 +00:00
}
static void createTipiStati ( TToken_string & tipi , TToken_string & stati )
{
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 ) ;
}
}
}
}
bool generaLiStorico ( TDate dataIni )
{
// Apro la tabella dei plafonds con chiave 2 (CODCLI+ANNO+NUMPROT) e per ogni cliente calcolo i plafond dal 2017
TRelation rletint ( LF_LETINT ) ;
TString filter = " DAL>= " ; filter < < dataIni . date2ansi ( ) ;
TCursor cletint ( & rletint , filter , 2 ) ;
static TToken_string tipi , stati ;
createTipiStati ( tipi , stati ) ;
static TString codIVAP = ini_get_string ( CONFIG_DITTA , " li " , " CODIVA " ) ;
static TString codIVAS = ini_get_string ( CONFIG_DITTA , " li " , " CODIVALT " ) ;
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
TDate startCurr = rletint . get_date ( " DAL " ) , endCurr ;
endCurr = rletint . get_int ( " CODCLI " ) = = rletintn . get_int ( " CODCLI " ) ? rletintn . get_date ( " DAL " ) - - : NULLDATE ;
// Dati lettera
real impLI = rletint . get_real ( " IMPORTO " ) ;
bool soluzione = rletint . get_int ( " TIPOOP " ) = = SOLUZIONE_UNICA ;
// Adesso che so le date apro tutti i documenti
TLista_documenti din ;
din . read ( ' D ' , ' C ' , rletint . get_long ( " CODCLI " ) , startCurr . year ( ) , tipi , stati , startCurr , endCurr ) ;
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 ;
TAssoc_array tabIva = din [ i ] . tabella_iva ( true ) ;
for ( TRiepilogo_iva * totali = ( TRiepilogo_iva * ) tabIva . get ( ) ; totali ! = NULL ; totali = ( TRiepilogo_iva * ) tabIva . get ( ) )
{
if ( totali - > cod_iva ( ) . codice ( ) = = codIVAP | | totali - > cod_iva ( ) . codice ( ) = = codIVAS )
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
if ( impLI > = utilizzato )
{
// Creo la chiave da scrivere e metto tutto dentro
TString key ; key < < rletint . get ( " ANNO " ) < < " | " < < rletint . get ( " NUMPROT " ) < < " | " < < utilizzato . string ( ) ;
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 ;
2017-02-09 14:42:17 +00:00
}