2010-09-01 15:47:38 +00:00
# include <applicat.h>
# include <automask.h>
# include <progind.h>
# include <recarray.h>
# include <recset.h>
# include <reputils.h>
# include <doc.h>
# include <rdoc.h>
# include "../cg/cglib01.h"
2013-03-25 13:46:24 +00:00
# include "../cg/cgsaldac.h"
# include "../ef/ef0101.h"
2010-09-01 15:47:38 +00:00
# include "../ve/velib.h"
# include "halib.h"
# include "ha0.h"
# include "ha0500a.h"
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////
class THardy_elab_docs_mask : public TAutomask
{
protected :
virtual bool on_field_event ( TOperable_field & o , TField_event e , long jolly ) ;
public :
2011-10-07 15:59:54 +00:00
THardy_elab_docs_mask ( ) : TAutomask ( " ha0500a " ) { }
2010-09-01 15:47:38 +00:00
} ;
bool THardy_elab_docs_mask : : on_field_event ( TOperable_field & o , TField_event e , long jolly )
{
switch ( o . dlg ( ) )
{
case F_ADATA :
if ( e = = fe_close | | e = = fe_modify )
{
//se la data iniziale <20> piena -> l'anno deve essere lo stesso nelle 2 date;
//se invece <20> vuota -> la data iniziale viene presa come la data iniziale dell'esercizio della data finale...
//..ma questo qui non serve e viene rinviato alla query principale del recordset
const TDate adata = get_date ( F_ADATA ) ;
TEsercizi_contabili esc ;
const int adata_esc = esc . date2esc ( adata ) ;
TDate dadata = o . get ( ) ;
if ( dadata . ok ( ) )
{
const int dadata_esc = esc . date2esc ( dadata ) ;
if ( adata_esc ! = dadata_esc )
2012-01-17 12:08:54 +00:00
return error_box ( TR ( " Le date devono appartenere allo stesso esercizio! " ) ) ;
2010-09-01 15:47:38 +00:00
}
}
break ;
//in caso di elaborazione definitiva <20> obbligatorio..
//..eliminare tutte le NAC provvisorie generate in precedenza
case F_DEFINITIVO :
if ( e = = fe_modify )
{
if ( o . get ( ) = = " X " )
{
set ( F_KILLPROVV , " X " ) ;
disable ( F_KILLPROVV ) ;
}
else
{
enable ( F_KILLPROVV ) ;
set ( F_KILLPROVV , " " ) ;
}
}
break ;
default :
break ;
}
return true ;
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class THardy_elab_docs : public TSkeleton_application
{
protected :
//metodi alto livello
void elabora ( const TMask & mask ) ;
int kill_provv_nac ( const TMask & mask ) ;
long genera_recordset ( const TMask & mask , TISAM_recordset & recset ) ;
void elabora_documenti ( const TMask & mask , TISAM_recordset & recset , TLog_report & log ) ;
//metodi medio livello
2013-01-30 16:58:06 +00:00
bool aggiorna_contratto ( const TRiga_documento & rdoc , TContratto_premi & contratto , TLog_report & log ) ;
bool elabora_contratti ( TDocumento & curr_doc , TArray & contratti_cliente , const TDate & data_fine , TLog_report & log ) ;
2013-03-25 13:46:24 +00:00
bool genera_nac ( const TMask & mask , TArray & contratti_cliente , TAssoc_array & nac_nolo , TLog_report & log ) ;
bool genera_fat ( const TMask & mask , TContratto_premi & contratto , TToken_string & nakey , TLog_report & log ) ;
bool genera_eff ( const TDocumento & fat , const real & tot_nac , TLog_report & log ) ;
2010-09-01 15:47:38 +00:00
//metodi basso livello
2013-03-25 13:46:24 +00:00
int find_contratti_cliente ( const long codcfatt , const TMask & mask , int flags , TArray & contratti_cliente ) ;
2010-09-01 15:47:38 +00:00
void check_date ( const TDate & datafine , TDate & dataini ) ;
int find_numerazioni ( const TString & tipo_to_elab , TString_array & num_doc ) ;
2013-03-25 13:46:24 +00:00
int month_diff ( const TDate & inizio , const TDate & fine ) const ;
2010-09-01 15:47:38 +00:00
public :
virtual void main_loop ( ) ;
virtual bool create ( ) ;
} ;
//metodo per ricavare la data iniziale di elaborazione qualora l'utonto non la metta e l'esercizio da usare
void THardy_elab_docs : : check_date ( const TDate & datafine , TDate & dataini )
{
TEsercizi_contabili esc ;
TDate datafine_tmp = datafine ;
const int esercizio = esc . date2esc ( datafine ) ;
esc . code2range ( esercizio , dataini , datafine_tmp ) ;
}
int THardy_elab_docs : : find_numerazioni ( const TString & tipo_to_elab , TString_array & num_doc )
{
TISAM_recordset num_recset ( " USE %NUM " ) ;
for ( bool ok = num_recset . move_first ( ) ; ok ; ok = num_recset . move_next ( ) ) //giro sui vari tipi numerazione
{
const TString4 codtab = num_recset . get ( " CODTAB " ) . as_string ( ) ;
const TCodice_numerazione numerazione ( codtab ) ;
for ( int t = numerazione . ntipi_doc ( ) - 1 ; t > = 0 ; t - - )
{
const TString & tipo_doc = numerazione . tipo_doc ( t ) ;
if ( tipo_doc = = tipo_to_elab )
{
if ( num_doc . find ( codtab ) < 0 ) // Evito aggiunta di doppioni
num_doc . add ( codtab ) ;
break ;
}
} //for (int t = codnum..
} //for (bool ok = num_recset...
return num_doc . items ( ) ;
}
//metodo per accoppare tutte le NAC provvisorie generate in precedenza
int THardy_elab_docs : : kill_provv_nac ( const TMask & mask )
{
const TDate & adata = mask . get_date ( F_ADATA ) ;
2013-03-25 13:46:24 +00:00
const int anno = adata . year ( ) ;
2010-09-01 15:47:38 +00:00
TConfig config ( CONFIG_DITTA , " ha " ) ;
TToken_string numerazioni ;
numerazioni . add ( config . get ( " NaAntNum " ) ) ;
2013-03-25 13:46:24 +00:00
numerazioni . add ( config . get ( " NaNoloNum " ) ) ;
2010-09-01 15:47:38 +00:00
numerazioni . add ( config . get ( " NaPostNum " ) ) ;
2013-03-25 13:46:24 +00:00
numerazioni . add ( config . get ( " NaRifaNum " ) ) ;
2010-09-01 15:47:38 +00:00
2013-03-25 13:46:24 +00:00
int nac_killed = 0 ;
TRelation rel_doc ( LF_DOC ) ;
TRectype & rec = rel_doc . curr ( ) ;
2010-09-01 15:47:38 +00:00
2013-03-25 13:46:24 +00:00
FOR_EACH_TOKEN ( numerazioni , codnum ) if ( * codnum > ' ' )
{
rec . zero ( ) ;
rec . put ( DOC_PROVV , ' P ' ) ;
rec . put ( DOC_ANNO , anno ) ;
2010-09-01 15:47:38 +00:00
rec . put ( DOC_CODNUM , codnum ) ;
TCursor cur_doc ( & rel_doc , " " , 1 , & rec , & rec ) ;
2013-03-25 13:46:24 +00:00
const TRecnotype items = cur_doc . items ( ) ;
2010-09-01 15:47:38 +00:00
cur_doc . freeze ( ) ;
2013-03-25 13:46:24 +00:00
TProgind progind ( items , TR ( " Eliminazione NAC provvisorie in corso... " ) ) ;
2010-09-01 15:47:38 +00:00
for ( cur_doc = 0 ; cur_doc . pos ( ) < items ; + + cur_doc )
{
2013-03-25 13:46:24 +00:00
if ( ! progind . addstatus ( 1 ) )
break ;
2010-09-01 15:47:38 +00:00
TDocumento doc ( rec ) ;
2013-03-25 13:46:24 +00:00
if ( doc . remove ( ) = = NOERR )
2010-09-01 15:47:38 +00:00
nac_killed + + ;
}
}
2013-03-25 13:46:24 +00:00
2010-09-01 15:47:38 +00:00
return nac_killed ;
}
//metodo che filtra tutti i documenti in base ai parametri della maschera
long THardy_elab_docs : : genera_recordset ( const TMask & mask , TISAM_recordset & recset )
{
//parametri di elaborazione
//per prima cosa controlla se il cliente <20> stato specificato; questo influisce sulla scelta della chiave di ricerca sul file
int key = 3 ;
const long codcf = mask . get_long ( F_CODCF ) ;
if ( codcf > 0 )
key = 2 ;
//e costruiamola 'sta query!
//usa i documenti con chiave variabile (vedi sopra)
TString query ;
query < < " USE DOC KEY " < < key ;
//lo stato dipende da quanto sta scritto sulla elaborazione differita (stato iniziale dei docs da considerare)
//viene messo CODNUM nella SELECT perch<63> , essendoci un range di date nelle chiavi, la numerazione verrebbe ignorata! (provato!)
2012-09-14 12:54:44 +00:00
query < < " \n SELECT (STATO>=#STATOINI)&&(STATO<'9') " ;
2010-09-01 15:47:38 +00:00
//in base al tipo documento che si deve elaborare (settato in configurazione), ci possono essere pi<70> numerazioni da considerare!
TConfig config ( CONFIG_DITTA , " ha " ) ;
2012-01-17 12:08:54 +00:00
const TString4 tipo_doc_to_elab1 = config . get ( " TipoFatt " ) ;
const TString4 tipo_doc_to_elab2 = config . get ( " TipoFatt2 " ) ;
2011-10-11 16:54:32 +00:00
// Inutile testare tutte le numerazioni, basta il tipo documento
2012-01-17 12:08:54 +00:00
query < < " &&(( " < < DOC_TIPODOC < < " ==' " < < tipo_doc_to_elab1 < < " ')||( " < < DOC_TIPODOC < < " ==' " < < tipo_doc_to_elab2 < < " ')) " ;
2011-10-11 16:54:32 +00:00
2010-09-01 15:47:38 +00:00
//se c'<27> l'agente specificato...
const TString & agente = mask . get ( F_CODAGE ) ;
2013-01-30 16:58:06 +00:00
//ordinamento (agente)-codcf-ndoc
query < < " \n BY " < < DOC_CODCF < < " " < < DOC_NDOC ;
2010-09-01 15:47:38 +00:00
//from-to dipendente da chiave
switch ( key )
{
case 2 : //chiave per tipocf-codcf-provv-anno-datadoc-codnum
2013-01-30 16:58:06 +00:00
query < < " \n FROM TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#DADATA "
< < " \n TO TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#ADATA " ;
2010-09-01 15:47:38 +00:00
break ;
case 3 : //chiave per datadoc-provv-anno-codnum
2013-01-30 16:58:06 +00:00
query < < " \n FROM DATADOC=#DADATA PROVV=D ANNO=#ANNO "
< < " \n TO DATADOC=#ADATA PROVV=D ANNO=#ANNO " ;
2010-09-01 15:47:38 +00:00
break ;
default :
break ;
}
//setta la nuova query al recordset (inizialmente nato dequeryzzato)
recset . set ( query ) ;
//settaggio delle variabili
const TDate adata = mask . get_date ( F_ADATA ) ;
TDate dadata = mask . get_date ( F_DADATA ) ;
//se la data iniziale <20> vuota deve coincidere con l'inizio dell'esercizio della data finale (obbligatoria!)
if ( ! dadata . ok ( ) )
check_date ( adata , dadata ) ;
//lo stato dei documenti da considerare va a raccatarlo nel config
const TString & stato_ini = config . get ( " StatoIniFatt " ) ;
recset . set_var ( " #STATOINI " , stato_ini ) ;
if ( agente . full ( ) )
recset . set_var ( " #CODAG " , agente ) ;
if ( codcf > 0 )
recset . set_var ( " #CODCF " , codcf ) ;
2013-01-30 16:58:06 +00:00
recset . set_var ( " #ANNO " , long ( adata . year ( ) ) ) ;
2010-09-01 15:47:38 +00:00
recset . set_var ( " #DADATA " , dadata ) ;
recset . set_var ( " #ADATA " , adata ) ;
return recset . items ( ) ;
}
//metodo che riempie un array con tutti i contratti del cliente passatogli (in base alla tipologia di contratti da elaborare)
2013-04-09 15:07:10 +00:00
// flags: 0x7 = tutti tranne nolo; 0x8 = nolo
2013-03-25 13:46:24 +00:00
int THardy_elab_docs : : find_contratti_cliente ( const long codcfatt , const TMask & mask , int flags , TArray & contratti_cliente )
2010-09-01 15:47:38 +00:00
{
contratti_cliente . destroy ( ) ;
2013-03-25 13:46:24 +00:00
const TDate data_fine_elab = mask . get_date ( F_ADATA ) ;
TDate data_ini_elab = mask . get_date ( F_DADATA ) ;
if ( ! data_ini_elab . ok ( ) )
check_date ( data_fine_elab , data_ini_elab ) ;
2013-04-09 15:07:10 +00:00
// settaggio delle variabili
// il codice numerazione lo trova nella configurazione Hardy,
// lo deve scegliere in base alla tipologia di contratti che sta esaminando!
2013-03-25 13:46:24 +00:00
for ( int f = 0 ; f < 4 ; f + + ) if ( flags & ( 1 < < f ) )
2012-01-17 12:08:54 +00:00
{
2013-03-25 13:46:24 +00:00
TString4 codnum , tipodoc ;
switch ( f )
{
case 0 :
codnum = ini_get_string ( CONFIG_DITTA , " ha " , " CoAntNum " ) ;
tipodoc = ini_get_string ( CONFIG_DITTA , " ha " , " CoAntTip " ) ;
break ;
case 1 :
codnum = ini_get_string ( CONFIG_DITTA , " ha " , " CoRifaNum " ) ;
tipodoc = ini_get_string ( CONFIG_DITTA , " ha " , " CoRifaTip " ) ;
break ;
case 2 :
codnum = ini_get_string ( CONFIG_DITTA , " ha " , " CoPostNum " ) ;
tipodoc = ini_get_string ( CONFIG_DITTA , " ha " , " CoPostTip " ) ;
break ;
case 3 :
codnum = ini_get_string ( CONFIG_DITTA , " ha " , " CoNoloNum " ) ;
tipodoc = ini_get_string ( CONFIG_DITTA , " ha " , " CoNoloTip " ) ;
break ;
default :
break ;
}
2013-01-30 16:58:06 +00:00
2013-03-25 13:46:24 +00:00
const TString & agente = mask . get ( F_CODAGE ) ;
//deve cercare tutti i contratti del cliente e metterli nell'array
2012-01-17 12:08:54 +00:00
TString query ;
query < < " USE DOC KEY 5 " ;
2013-03-25 13:46:24 +00:00
query < < " \n SELECT (TIPODOC=#TIPODOC)&&(STATO!=9) " ;
if ( codcfatt > 0 ) query < < " &&(STR(DOC2=#CODCF)) " ;
2013-01-30 16:58:06 +00:00
if ( agente . full ( ) ) query < < " &&(CODAG=#CODAG) " ;
2013-03-25 13:46:24 +00:00
query < < " \n FROM PROVV=D CODNUM= " < < codnum ;
query < < " \n TO PROVV=D CODNUM= " < < codnum ;
2012-01-17 12:08:54 +00:00
TISAM_recordset recset ( query ) ;
2013-03-25 13:46:24 +00:00
recset . set_var ( " #TIPODOC " , tipodoc ) ;
if ( codcfatt > 0 )
recset . set_var ( " #CODCF " , codcfatt ) ;
if ( agente . full ( ) )
recset . set_var ( " #CODAG " , agente ) ;
2010-09-01 15:47:38 +00:00
2012-01-17 12:08:54 +00:00
const long n_contratti = recset . items ( ) ; //questo serve solo al sagace programmatore
2010-09-01 15:47:38 +00:00
2012-01-17 12:08:54 +00:00
//aggiunge i contratti all'array: solo quelli in auge nel periodo di calcolo selezionato sulla maschera!
for ( bool ok = recset . move_first ( ) ; ok ; ok = recset . move_next ( ) )
{
//contratti anticipo 'A': datainizio esiste sempre, datafine non esiste (va ad esaurimento)
2013-03-25 13:46:24 +00:00
//contratti nolo 'N': datainizio esiste sempre, datafine esiste sempre
2012-01-17 12:08:54 +00:00
//contratti posticipo 'P': datainizio esiste sempre, datafine pu<70> non esistere
//contratti rifatturazione 'R': come contratti anticipo
//controlla validit<69> del contratto con le date scelte per l'elaborazione dei documenti
const TDate data_ini_contratto = recset . get ( DOC_DATACOMP ) . as_date ( ) ;
//quindi la datainizio vale per tutti allo stesso modo (<28> obbligatoria nei contratti)
//se l'elaborazione finisce prima che cominci il contratto -> il contratto non serve a nulla
if ( data_ini_contratto > data_fine_elab )
2010-09-27 14:30:54 +00:00
continue ;
2013-03-25 13:46:24 +00:00
//la data fine vale invece solo per i contratti 'P' e potrebbe non esserci (contratti senza scadenza)
TDate data_fine_contratto = recset . get ( DOC_DATAFCOMP ) . as_date ( ) ;
if ( f = = 3 ) // if (tipo_contratto == "N")
2010-09-01 15:47:38 +00:00
{
2013-03-25 13:46:24 +00:00
const TDate data_recesso = recset . get ( DOC_DATASCIMP ) . as_date ( ) ;
if ( data_recesso . ok ( ) )
data_fine_contratto = data_recesso ;
else
{
const int rate = recset . get ( DOC_NCOLLI ) . as_int ( ) ;
const int paga = recset . get ( DOC_NUMANT ) . as_int ( ) ;
if ( paga > = rate ) // Fine pagamento rate
continue ;
}
2012-01-17 12:08:54 +00:00
}
2013-03-25 13:46:24 +00:00
//se la data fine contratto non <20> valida (ma <20> presente!) non dobbiamo fare nulla, perch<63> il contratto non va elaborato
if ( data_fine_contratto . ok ( ) & & data_fine_contratto < data_ini_elab )
continue ;
2012-01-17 12:08:54 +00:00
//ci tocca istanziarci un contratto_premi
TContratto_premi * curr_contratto = new TContratto_premi ( recset . cursor ( ) - > curr ( ) ) ;
//azzeratore del campo con il totale reso per elaborazione, nel caso di contratti Anticipo/Rifatturazione, riga spese
const char tipo_contr = curr_contratto - > tipo_contratto ( ) ;
2013-01-30 16:58:06 +00:00
2013-03-25 13:46:24 +00:00
FOR_EACH_PHYSICAL_RDOC ( * curr_contratto , r , rdoc )
2012-01-17 12:08:54 +00:00
{
2013-03-25 13:46:24 +00:00
const TString & tr = rdoc - > get ( RDOC_TIPORIGA ) ;
if ( tr = = HARDY_TIPORIGA_SOMMA & & ( tipo_contr = = ' A ' | | tipo_contr = = ' R ' ) )
2010-09-27 14:30:54 +00:00
{
2013-03-25 13:46:24 +00:00
rdoc - > zero ( RCA_2_RESO_CORRENTE ) ;
2013-01-30 16:58:06 +00:00
2013-03-25 13:46:24 +00:00
const real prezzo = rdoc - > prezzo ( false , false ) ;
const real resost = rdoc - > get ( RCA_2_RESO_STORICO ) ;
if ( resost > = prezzo ) // Contratto esaurito da ignorare
{
delete curr_contratto ;
curr_contratto = NULL ;
2012-01-17 12:08:54 +00:00
}
2013-03-25 13:46:24 +00:00
break ;
} else
if ( tr = = HARDY_TIPORIGA_MERCE )
rdoc - > zero ( RDOC_QTA ) ;
2010-09-01 15:47:38 +00:00
}
2013-01-30 16:58:06 +00:00
if ( curr_contratto ! = NULL ) // Ignora contratti chiusi
contratti_cliente . add ( curr_contratto ) ;
2010-09-01 15:47:38 +00:00
}
}
return contratti_cliente . items ( ) ;
}
2013-03-25 13:46:24 +00:00
int THardy_elab_docs : : month_diff ( const TDate & inizio , const TDate & fine ) const
{
const int i = inizio . year ( ) * 12 + inizio . month ( ) ;
const int f = fine . year ( ) * 12 + fine . month ( ) ;
return f - i ;
}
2010-09-01 15:47:38 +00:00
2013-01-30 16:58:06 +00:00
bool THardy_elab_docs : : aggiorna_contratto ( const TRiga_documento & rdoc , TContratto_premi & contratto , TLog_report & log )
2010-09-01 15:47:38 +00:00
{
bool elaborato = false ;
2010-09-27 14:30:54 +00:00
const char tipo_contratto = contratto . tipo_contratto ( ) ;
2010-09-13 13:39:46 +00:00
//parametri della riga fattura
2012-09-14 12:54:44 +00:00
TString80 rdoc_codart = rdoc . get ( RDOC_CODART ) ; rdoc_codart . trim ( ) ;
2010-09-13 13:39:46 +00:00
const real rdoc_qta = rdoc . get_real ( RDOC_QTA ) ;
const TString4 rdoc_umqta = rdoc . get ( RDOC_UMQTA ) ;
2010-09-01 15:47:38 +00:00
FOR_EACH_PHYSICAL_RDOC ( contratto , rm , rigamerce )
{
const TString & rigamerce_codart = rigamerce - > get ( RDOC_CODART ) ;
//se trova il codart in una delle righe di contratto...
if ( rdoc_codart = = rigamerce_codart )
{
const real rigamerce_premio = rigamerce - > get_real ( RC_1_PREMIO ) ;
2010-09-13 13:39:46 +00:00
//se il premio non <20> nullo procede all'aggiornamento del restituito (solo contratti A/R e righe spese) e del bonus (tutti i contratti e righe merce)
2010-09-01 15:47:38 +00:00
if ( rigamerce_premio ! = ZERO )
{
2010-09-13 13:39:46 +00:00
//normalizzazione della qta
const TString & umqta_tot = rigamerce - > get ( RDOC_UMQTA ) ; //prende la UM dal contratto che far<61> da riferimento!
TArticolo articolo ( rdoc_codart ) ;
const real normalized_rdoc_qta = articolo . convert_to_um ( rdoc_qta , umqta_tot , rdoc_umqta , true ) ;
2013-03-25 13:46:24 +00:00
//aggiornamento delle righe di tipo spesa (verig02) per aggiornare le somme restituite nel caso di contratti di anticipo/rifatturazione
2010-09-13 13:39:46 +00:00
if ( tipo_contratto = = ' A ' | | tipo_contratto = = ' R ' )
2010-09-01 15:47:38 +00:00
{
2010-09-13 13:39:46 +00:00
FOR_EACH_PHYSICAL_RDOC ( contratto , ra , rigacontratto )
2010-09-01 15:47:38 +00:00
{
2010-09-13 13:39:46 +00:00
//cerca una riga anticipo da evadere sul contratto per aggiornare la somma restituita sull'anticipo
if ( rigacontratto - > is_spese ( ) )
{
//la somma restituita deve essere incrementata per la qta di merce (caff<66> ) che c'<27> sulla riga della fattura in esame...
//..moltiplicata per il premio che c'<27> nella riga di tipo merce del contratto in esame
2012-09-14 12:54:44 +00:00
const real reso = normalized_rdoc_qta * rigamerce_premio ;
rigacontratto - > add ( RCA_2_RESO_CORRENTE , reso ) ;
2010-09-13 13:39:46 +00:00
elaborato = true ;
break ;
}
} //FOR_EACH_PHYSICAL.. fine casino sulla riga di tipo spese
} //if(tipo_contratto == "A"...
//questo va bene invece per ogni riga merce (verigh01), sia per contratti di tipo A/R che di tipo P
2010-09-01 15:47:38 +00:00
if ( rigamerce - > is_merce ( ) )
{
2012-09-14 12:54:44 +00:00
const real bonus = normalized_rdoc_qta * rigamerce_premio ;
rigamerce - > add ( RC_1_BONUS , bonus ) ;
2010-09-13 13:39:46 +00:00
rigamerce - > add ( RDOC_QTA , normalized_rdoc_qta ) ; //riscrive sul campo di appoggio del contratto
2010-09-01 15:47:38 +00:00
elaborato = true ;
2012-09-14 12:54:44 +00:00
TString msg ;
2013-01-30 16:58:06 +00:00
msg . format ( " Doc. %d/%s %ld - %s: %s %s -> Bonus %s Contr. %d/%s %ld " ,
2012-09-14 12:54:44 +00:00
rdoc . get_int ( RDOC_ANNO ) , ( const char * ) rdoc . get ( RDOC_CODNUM ) , rdoc . get_long ( RDOC_NDOC ) ,
( const char * ) rdoc_codart , normalized_rdoc_qta . stringa ( 4 , 0 ) , ( const char * ) rdoc_umqta , bonus . stringa ( 7 , 2 ) ,
contratto . get_int ( DOC_ANNO ) , ( const char * ) contratto . get ( DOC_CODNUM ) , contratto . get_long ( DOC_NDOC ) ) ;
log . log ( 0 , msg ) ;
2010-09-01 15:47:38 +00:00
}
2010-09-13 13:39:46 +00:00
} //if(rigamerce_premio != ZERO...
2010-09-01 15:47:38 +00:00
} //if(rdoc_codart...
} //FOR_EACH_PHYSICAL..
return elaborato ;
}
//aggiorna, in base al documento in esame curr_doc, le somme restituite nelle righe di tipo verigh02 nei contratti validi..
//..del cliente
2013-01-30 16:58:06 +00:00
bool THardy_elab_docs : : elabora_contratti ( TDocumento & curr_doc , TArray & contratti_cliente , const TDate & data_fine , TLog_report & log )
2010-09-01 15:47:38 +00:00
{
2013-01-30 16:58:06 +00:00
const TDate datadoc = curr_doc . get ( DOC_DATADOC ) ;
2010-09-01 15:47:38 +00:00
bool elaborato = false ;
2012-09-14 12:54:44 +00:00
FOR_EACH_PHYSICAL_RDOC ( curr_doc , r , rdoc ) if ( rdoc - > is_merce ( ) ) //giro su tutte le righe merce delle fatture
2010-09-01 15:47:38 +00:00
{
2013-01-30 16:58:06 +00:00
//controlla se il codart della riga esiste in uno o pi<70> contratti validi
2010-09-01 15:47:38 +00:00
for ( int i = 0 ; i < contratti_cliente . items ( ) ; i + + )
{
2010-09-27 14:30:54 +00:00
TContratto_premi & contratto = ( TContratto_premi & ) contratti_cliente [ i ] ;
2013-01-30 16:58:06 +00:00
if ( ! contratto . data_valida ( datadoc ) )
continue ;
// Calcola l'inizio di validit<69> dei documenti in base alla frequenza (14-01-2013)
TDate data_inizio ( 1 , 1 , data_fine . year ( ) ) ;
switch ( contratto . frequenza ( ) )
{
2013-03-25 13:46:24 +00:00
case ' M ' : data_inizio . set_month ( data_fine . month ( ) ) ; break ; // Solo contratti NOLO
2013-01-30 16:58:06 +00:00
case ' S ' : data_inizio . set_month ( data_fine . month ( ) > 6 ? 7 : 1 ) ; break ;
case ' T ' : data_inizio . set_month ( max ( 1 , data_fine . month ( ) - 2 ) ) ; break ;
default : break ;
}
// Elabora solo i documenti che ricadano nell'intervallo valido
if ( datadoc > = data_inizio & & datadoc < = data_fine )
elaborato | = aggiorna_contratto ( * rdoc , contratto , log ) ;
2010-09-01 15:47:38 +00:00
} //for(int i..
} //FOR_EACH...
return elaborato ;
}
2013-03-25 13:46:24 +00:00
bool THardy_elab_docs : : genera_nac ( const TMask & mask , TArray & contratti_cliente ,
2013-05-27 12:01:21 +00:00
TAssoc_array & fat_nolo , TLog_report & log )
2010-09-01 15:47:38 +00:00
{
2013-03-25 13:46:24 +00:00
if ( contratti_cliente . empty ( ) )
2013-01-30 16:58:06 +00:00
return false ;
2010-09-01 15:47:38 +00:00
//si informa se l'elaborazione <20> definitiva o meno
const bool definitivo = mask . get_bool ( F_DEFINITIVO ) ;
//giro su tutti i contratti del cliente che stanno nell'array (ogni contratto genera una NAC)
FOR_EACH_ARRAY_ITEM ( contratti_cliente , r , riga )
{
2010-09-27 14:30:54 +00:00
TContratto_premi & contratto = * ( TContratto_premi * ) riga ;
2011-10-11 16:54:32 +00:00
const long ndoc = contratto . numero ( ) ; // il numdoc del contratto serve nelle segnalazioni
const long codcf = contratto . codcf ( ) ; // il codice cliente ci serve nella generazione della NAC...
const char tipo_contratto = contratto . tipo_contratto ( ) ; // ...e pure il tipo di contratto in esame!
2010-09-01 15:47:38 +00:00
//segnaliamo l'elaborazione del contratto sul log
2010-09-27 14:30:54 +00:00
TString log_msg ;
2013-01-30 16:58:06 +00:00
log_msg . format ( FR ( " Contratto:%6ld Cliente:%6ld " ) , ndoc , codcf ) ;
2010-09-01 15:47:38 +00:00
// generazione del documento NAC dal contratto
// -------------------------------------------
// TESTATA
//alcuni parametri delle righe vanno presi dalla configurazione
TString4 nac_codnum , nac_tipo ;
TString8 cod_riga ;
switch ( tipo_contratto )
{
case ' A ' :
2013-03-25 13:46:24 +00:00
nac_codnum = ini_get_string ( CONFIG_DITTA , " ha " , " NaAntNum " ) ;
nac_tipo = ini_get_string ( CONFIG_DITTA , " ha " , " NaAntTip " ) ;
cod_riga = ini_get_string ( CONFIG_DITTA , " ha " , " NaAntSpe " ) ;
break ;
case ' N ' :
nac_codnum = ini_get_string ( CONFIG_DITTA , " ha " , " NaNoloNum " ) ;
nac_tipo = ini_get_string ( CONFIG_DITTA , " ha " , " NaNoloTip " ) ;
cod_riga = ini_get_string ( CONFIG_DITTA , " ha " , " NaNoloSpe " ) ;
2010-09-01 15:47:38 +00:00
break ;
case ' R ' :
2013-03-25 13:46:24 +00:00
nac_codnum = ini_get_string ( CONFIG_DITTA , " ha " , " NaRifaNum " ) ;
nac_tipo = ini_get_string ( CONFIG_DITTA , " ha " , " NaRifaTip " ) ;
cod_riga = ini_get_string ( CONFIG_DITTA , " ha " , " NaRifaSpe " ) ;
2010-09-01 15:47:38 +00:00
break ;
default :
2013-03-25 13:46:24 +00:00
nac_codnum = ini_get_string ( CONFIG_DITTA , " ha " , " NaPostNum " ) ;
nac_tipo = ini_get_string ( CONFIG_DITTA , " ha " , " NaPostTip " ) ;
cod_riga = ini_get_string ( CONFIG_DITTA , " ha " , " NaPostSpe " ) ;
2010-09-01 15:47:38 +00:00
break ;
}
2012-01-23 16:34:23 +00:00
const TString8 codage = contratto . get ( DOC_CODAG ) ;
2012-01-18 17:19:53 +00:00
if ( codage . full ( ) ) // Controlla se esiste una spesa su misura per l'agente
{
TString8 codspesa = cod_riga ;
2012-01-23 16:34:23 +00:00
codspesa < < codage . right ( 3 ) ;
2012-01-18 17:19:53 +00:00
const TRectype & rec_spp = cache ( ) . get ( " SPP " , codspesa ) ;
if ( ! rec_spp . empty ( ) )
cod_riga = codspesa ;
}
2013-05-27 12:01:21 +00:00
const TDate datadoc = mask . get ( tipo_contratto = = ' N ' ? F_DATANOLO : F_DATAELAB ) ;
2013-01-30 16:58:06 +00:00
const int anno = datadoc . year ( ) ;
2012-02-24 14:57:04 +00:00
//solo in caso di elaborazione definitiva si scrivono NAC di tipo D;
//senn<6E> di tipo P, che sono uccidibili all'inizio di ogni nuova elaborazione
2012-09-14 12:54:44 +00:00
const char provv = definitivo ? ' D ' : ' P ' ;
2010-09-01 15:47:38 +00:00
TDocumento nac ( provv , anno , nac_codnum , 0 ) ; //num_doc = 0 perch<63> viene aggiornato in fase di registrazione
nac . set_tipo ( nac_tipo ) ;
nac . put ( DOC_STATO , 1 ) ;
2013-01-30 16:58:06 +00:00
nac . put ( DOC_DATADOC , datadoc ) ;
2010-09-01 15:47:38 +00:00
nac . put ( DOC_TIPOCF , ' C ' ) ;
nac . put ( DOC_CODCF , codcf ) ;
2012-01-23 16:34:23 +00:00
nac . put ( DOC_CODAG , codage ) ;
nac . put ( DOC_CODPAG , contratto . get ( DOC_CODPAG ) ) ;
2012-01-30 09:43:46 +00:00
nac . put ( DOC_DOC1 , contratto . get ( DOC_DOC1 ) ) ;
2013-05-27 12:01:21 +00:00
TToken_string cnkey ; // Chiave contratto
cnkey . add ( contratto . get ( DOC_PROVV ) ) ;
cnkey . add ( contratto . get ( DOC_ANNO ) ) ;
cnkey . add ( contratto . get ( DOC_CODNUM ) ) ;
cnkey . add ( contratto . get ( DOC_NDOC ) ) ;
TToken_string * fatkey = ( TToken_string * ) fat_nolo . objptr ( cnkey ) ;
if ( fatkey ! = NULL )
{
// Skip fatkey->get(0) = PROVV
nac . put ( DOC_ANNORIF , fatkey - > get ( 1 ) ) ;
nac . put ( DOC_CODNUMRIF , fatkey - > get ( ) ) ;
nac . put ( DOC_NUMDOCRIF , fatkey - > get ( ) ) ;
nac . put ( DOC_DATADOCRIF , fatkey - > get ( ) ) ;
}
else
nac . put ( DOC_DATADOCRIF , contratto . get ( DOC_DATADOCRIF ) ) ;
2010-09-01 15:47:38 +00:00
// RIGHE
//ogni riga di tipo merce (verigh01) del contratto origina una riga della NAC
//noto il codice di riga spesa (che far<61> le veci del codart), troviamo il tipo riga dalla tabella SPP e tutte le features che servono
const TRectype & rec_spp = cache ( ) . get ( " SPP " , cod_riga ) ;
2013-03-25 13:46:24 +00:00
const TString4 tipo_riga_spp = rec_spp . get ( " S8 " ) ;
2010-09-01 15:47:38 +00:00
const TString80 descr_riga_spp = rec_spp . get ( " S0 " ) ;
const TString4 codiva = rec_spp . get ( " S3 " ) ;
2013-03-25 13:46:24 +00:00
TDate adata = mask . get_date ( F_ADATA ) ;
2013-01-30 16:58:06 +00:00
TDate dadata = mask . get_date ( F_DADATA ) ;
if ( ! dadata . ok ( ) )
check_date ( adata , dadata ) ;
TDate dmin ( 1 , 1 , adata . year ( ) ) ;
switch ( contratto . frequenza ( ) )
{
2013-03-25 13:46:24 +00:00
case ' M ' : dmin . set_month ( adata . month ( ) ) ; break ; // Solo nolo
2013-01-30 16:58:06 +00:00
case ' S ' : dmin . set_month ( adata . month ( ) > 6 ? 7 : 1 ) ; break ;
case ' T ' : dmin . set_month ( max ( 1 , adata . month ( ) - 2 ) ) ; break ;
default : break ;
}
if ( dmin > dadata )
dadata = dmin ;
if ( ! contratto . data_valida ( dadata ) )
dadata = contratto . data_inizio ( ) ;
if ( ! contratto . data_valida ( adata ) )
adata = contratto . data_fine ( ) ;
TString msg_date ; msg_date < < " " < < dadata < < " -- " < < adata ;
2010-09-01 15:47:38 +00:00
//giro sulle righe del contratto, che originano le righe NAC
for ( int i = 1 ; i < = contratto . rows ( ) ; i + + )
{
const TRiga_documento & riga_contratto = contratto [ i ] ; //le righe di un documento partono da 1! (standard del mercoled<65> )
const TString & tiporiga = riga_contratto . get ( RDOC_TIPORIGA ) ;
2010-09-27 14:30:54 +00:00
TString80 riga_contratto_codart = riga_contratto . get ( RDOC_CODART ) ;
2010-09-01 15:47:38 +00:00
//solo le righe di tipo merce (verigh01) dei contratti devono comparire nelle NAC
2010-09-27 14:30:54 +00:00
if ( tiporiga = = HARDY_TIPORIGA_MERCE )
2010-09-01 15:47:38 +00:00
{
const real riga_contratto_qta = riga_contratto . get_real ( RDOC_QTA ) ;
const TString4 riga_contratto_um = riga_contratto . get ( RDOC_UMQTA ) ;
const real riga_contratto_premio = riga_contratto . get_real ( RC_1_PREMIO ) ;
2010-09-27 14:30:54 +00:00
// riga merce NAC
2013-03-25 13:46:24 +00:00
TRiga_documento & nac_row = nac . new_row ( tipo_riga_spp ) ;
2010-09-01 15:47:38 +00:00
nac_row . put ( RDOC_CODART , cod_riga ) ;
//panegirico della descrizione
nac_row . put ( RDOC_DESCR , descr_riga_spp ) ;
2013-01-30 16:58:06 +00:00
nac_row . put ( RDOC_DESCEST , msg_date ) ;
2010-09-01 15:47:38 +00:00
nac_row . put ( RDOC_DESCLUNGA , " X " ) ;
//importi, qta, umqta
nac_row . put ( RDOC_UMQTA , riga_contratto_um ) ;
nac_row . put ( RDOC_QTA , riga_contratto_qta ) ;
nac_row . put ( RDOC_PREZZO , riga_contratto_premio ) ;
//iva
nac_row . put ( RDOC_CODIVA , codiva ) ;
2012-09-14 12:54:44 +00:00
//Imposta riga contratto di provenienza
nac_row . set_original_rdoc_key ( riga_contratto ) ;
} else
2010-09-27 14:30:54 +00:00
//trattazione speciale delle righe spese (verigh02) (solo 'A'nticipi e 'R'ifatturazioni)
if ( tiporiga = = HARDY_TIPORIGA_SOMMA & & ( tipo_contratto = = ' A ' | | tipo_contratto = = ' R ' ) )
{
const real somma_anticipata = riga_contratto . get_real ( RCA_2_ANTICIPATO ) ;
real somma_resa_storica = riga_contratto . get_real ( RCA_2_RESO_STORICO ) ;
real somma_resa_corrente = riga_contratto . get_real ( RCA_2_RESO_CORRENTE ) ;
const real esubero = somma_resa_storica + somma_resa_corrente - somma_anticipata ;
if ( esubero > ZERO )
{
somma_resa_corrente - = esubero ;
//se c'<27> un esubero nel rimborso dell'anticipo esister<65> solo una riga nella NAC, con una cifra pari alla somma..
//..che mancava a pareggiare l'anticipo (anche se l'esubero eccedesse tale differenza, sulla NAC ci va la somma a..
//..pareggio! cos<6F> freghiamo qualcosa al cliente)
nac . destroy_rows ( ) ;
// riga spesa NAC
2013-03-25 13:46:24 +00:00
TRiga_documento & nac_row = nac . new_row ( tipo_riga_spp ) ;
2010-09-27 14:30:54 +00:00
nac_row . put ( RDOC_CODART , cod_riga ) ;
//panegirico della descrizione
nac_row . put ( RDOC_DESCR , descr_riga_spp ) ;
2013-01-30 16:58:06 +00:00
nac_row . put ( RDOC_DESCEST , msg_date ) ;
2010-09-27 14:30:54 +00:00
nac_row . put ( RDOC_DESCLUNGA , " X " ) ;
//importi, qta
nac_row . put ( RDOC_QTA , 1 ) ;
nac_row . put ( RDOC_PREZZO , somma_resa_corrente ) ;
//iva
nac_row . put ( RDOC_CODIVA , codiva ) ;
2012-09-14 12:54:44 +00:00
//Imposta riga contratto di provenienza
nac_row . set_original_rdoc_key ( riga_contratto ) ;
2010-09-27 14:30:54 +00:00
}
}
2010-09-01 15:47:38 +00:00
}
// salvataggi vari
// ---------------
2010-09-27 14:30:54 +00:00
// NAC
// viene scritta comunque, con provv='D' se elaborazione definitiva
2010-09-01 15:47:38 +00:00
int err = nac . write ( ) ;
if ( err = = NOERR )
2010-09-27 14:30:54 +00:00
{
2013-01-30 16:58:06 +00:00
TString wrk_msg ;
2010-09-27 14:30:54 +00:00
wrk_msg . format ( " -- Generata NAC: %-4s%-4s%c %7ld " , ( const char * ) nac_codnum , ( const char * ) nac_tipo , provv , nac . get_long ( DOC_NDOC ) ) ;
log_msg < < wrk_msg ;
}
2010-09-01 15:47:38 +00:00
else
2010-09-27 14:30:54 +00:00
log_msg < < " -- Impossibile generare NAC !! " ;
// CONTRATTO
//se il contratto <20> di tipo A/R aggiorna la riga spese speciale (verigh02)
2013-03-25 13:46:24 +00:00
if ( err = = NOERR ) switch ( tipo_contratto )
2010-09-27 14:30:54 +00:00
{
2013-03-25 13:46:24 +00:00
case ' A ' :
case ' R ' :
2010-09-27 14:30:54 +00:00
{
2013-03-25 13:46:24 +00:00
FOR_EACH_PHYSICAL_RDOC ( contratto , r , rdoc )
2010-09-27 14:30:54 +00:00
{
2013-03-25 13:46:24 +00:00
if ( rdoc - > get ( RDOC_TIPORIGA ) = = HARDY_TIPORIGA_SOMMA )
{
const real anticipato = rdoc - > get_real ( RCA_2_ANTICIPATO ) ;
real reso_storico = rdoc - > get_real ( RCA_2_RESO_STORICO ) ;
reso_storico + = rdoc - > get_real ( RCA_2_RESO_CORRENTE ) ;
rdoc - > put ( RCA_2_RESO_STORICO , reso_storico ) ;
//se il contratto <20> andato a pareggio avverte diligentemente l'operatore
if ( reso_storico > = anticipato )
log_msg < < " -- Contratto pareggiato! " ;
} //if (rdoc->get(RDOC_TIPORIGA)...
} //FOR_EACH_PHYSICAL_RDOC(contratto...
}
break ;
case ' N ' :
2013-05-27 12:01:21 +00:00
if ( fatkey ! = NULL )
{
const char provv = fatkey - > get_char ( 0 ) ;
const int anno = fatkey - > get_int ( ) ;
const char * codnum = fatkey - > get ( ) ;
const long ndoc = fatkey - > get_long ( ) ;
const TDocumento fat ( provv , anno , codnum , ndoc ) ;
genera_eff ( fat , nac . totale_doc ( ) , log ) ;
2013-03-25 13:46:24 +00:00
}
break ;
default :
break ;
}
2010-09-01 15:47:38 +00:00
// se non ci sono errori -> in caso di elaborazione definitiva procede alla registrazione..
//.. del contratto (ricordiamo che in memoria il contratto ha gi<67> le righe aggiornate
2013-03-25 13:46:24 +00:00
if ( err = = NOERR & & definitivo )
2010-09-01 15:47:38 +00:00
{
//alla fine della fiera aggiorna il contratto
err = contratto . rewrite ( ) ;
2010-09-27 14:30:54 +00:00
2010-09-01 15:47:38 +00:00
if ( err = = NOERR )
2010-09-27 14:30:54 +00:00
log_msg < < " -- Contratto aggiornato " ;
2010-09-01 15:47:38 +00:00
else
2013-03-25 13:46:24 +00:00
log_msg < < " -- Impossibile aggiornare contratto: errore " < < err ;
2010-09-01 15:47:38 +00:00
}
2010-09-27 14:30:54 +00:00
log . log ( 0 , log_msg ) ;
2010-09-01 15:47:38 +00:00
log . log ( 0 , " " ) ;
2013-03-25 13:46:24 +00:00
} //FOR_EACH_ARRAY_ITEM(... giro sui contratti cliente
2010-09-01 15:47:38 +00:00
//il metodo ritorner<65> il successo o meno della registrazione
return true ;
}
2013-05-27 12:01:21 +00:00
bool THardy_elab_docs : : genera_fat ( const TMask & mask , TContratto_premi & contratto , TToken_string & fat_nolo , TLog_report & log )
2013-03-25 13:46:24 +00:00
{
//si informa se l'elaborazione <20> definitiva o meno
const char provv = mask . get_bool ( F_DEFINITIVO ) ? ' D ' : ' P ' ;
const TDate datadoc = mask . get ( F_DATAELAB ) ;
const TString4 fat_codnum = ini_get_string ( CONFIG_DITTA , " ha " , " NaNoloNum " ) ;
const TString4 fat_tipodoc = ini_get_string ( CONFIG_DITTA , " ha " , " FtNoloTip " ) ;
const TString4 fat_codpag = ini_get_string ( CONFIG_DITTA , " ha " , " CodPagFat " ) ;
2013-05-06 08:47:52 +00:00
const TString8 cod_spesa = ini_get_string ( CONFIG_DITTA , " ha " , " FtNoloSpe " ) ;
2013-03-25 13:46:24 +00:00
TDocumento fat ( provv , datadoc . year ( ) , fat_codnum , 0 ) ; //num_doc = 0 perch<63> viene aggiornato in fase di registrazione
fat . set_tipo ( fat_tipodoc ) ;
fat . put ( DOC_STATO , 1 ) ;
fat . put ( DOC_DATADOC , datadoc ) ;
fat . put ( DOC_TIPOCF , ' C ' ) ;
2013-04-09 15:07:10 +00:00
fat . put ( DOC_CODCF , contratto . get ( DOC_CODCF ) ) ;
2013-05-06 08:47:52 +00:00
fat . cli2doc ( ) ;
2013-03-25 13:46:24 +00:00
fat . put ( DOC_CODAG , contratto . get ( DOC_CODAG ) ) ;
fat . put ( DOC_DOC1 , contratto . get ( DOC_NDOC ) ) ;
fat . put ( DOC_DATADOCRIF , contratto . get ( DOC_DATADOC ) ) ;
2013-05-06 08:47:52 +00:00
fat . put ( DOC_CODPAG , fat_codpag ) ;
2013-03-25 13:46:24 +00:00
2013-05-06 08:47:52 +00:00
const TRectype & rec_spp = cache ( ) . get ( " SPP " , cod_spesa ) ;
2013-03-25 13:46:24 +00:00
const TString80 descr_riga_spp = rec_spp . get ( " S0 " ) ;
2013-05-06 08:47:52 +00:00
const TString4 codiva = rec_spp . get ( " S3 " ) ;
const TString4 tipo_riga_spp = rec_spp . get ( " S8 " ) ;
TString msg_rata ;
2013-03-25 13:46:24 +00:00
real importo = contratto . get_real ( DOC_IMPPAGATO ) ;
const TDate recesso = contratto . data_recesso ( ) ;
if ( recesso . ok ( ) & & recesso < = mask . get_date ( F_ADATA ) )
{
const real rate_da_pagare = contratto . get_int ( DOC_NCOLLI ) - contratto . get_int ( DOC_NUMANT ) ;
importo * = rate_da_pagare ;
contratto . put ( DOC_NUMANT , contratto . get ( DOC_NCOLLI ) ) ; // Chiude contratto forzosamente
2013-05-06 08:47:52 +00:00
msg_rata = TR ( " \n Rata di cessazione contratto " ) ;
2013-03-25 13:46:24 +00:00
}
else
2013-05-06 08:47:52 +00:00
{
const TDate d = mask . get ( F_ADATA ) ;
2013-03-25 13:46:24 +00:00
contratto . add ( DOC_NUMANT , UNO ) ; // Incrementa numero di rate pagate
2013-05-06 08:47:52 +00:00
msg_rata < < TR ( " \n Rata " ) < < contratto . get ( DOC_NUMANT ) < < ' / ' < < contratto . get_int ( DOC_NCOLLI )
< < ' ' < < itom ( d . month ( ) ) < < ' ' < < d . year ( ) ;
}
2013-04-09 15:07:10 +00:00
2013-03-25 13:46:24 +00:00
if ( provv = = ' D ' )
{
const int err = contratto . rewrite ( ) ;
if ( err ! = NOERR )
2013-05-06 08:47:52 +00:00
log . log ( 2 , TR ( " Impossibile aggiornare il numero di rate pagate sul contratto " ) ) ;
2013-03-25 13:46:24 +00:00
}
TRiga_documento & rdoc = fat . new_row ( tipo_riga_spp ) ;
2013-05-06 08:47:52 +00:00
rdoc . put ( RDOC_CODART , cod_spesa ) ;
2013-03-25 13:46:24 +00:00
rdoc . put ( RDOC_DESCR , descr_riga_spp ) ;
2013-05-06 08:47:52 +00:00
rdoc . put ( RDOC_DESCEST , msg_rata ) ;
rdoc . put ( RDOC_DESCLUNGA , " X " ) ;
2013-03-25 13:46:24 +00:00
rdoc . put ( RDOC_QTA , UNO ) ;
rdoc . put ( RDOC_PREZZO , importo ) ;
2013-05-06 08:47:52 +00:00
rdoc . put ( RDOC_CODIVA , codiva ) ;
2013-03-25 13:46:24 +00:00
const int err = fat . write ( ) ;
if ( err = = NOERR )
{
TString log_msg ;
log_msg . format ( " Generata FATTURA: %-4s%-4s%c %7ld " ,
( const char * ) fat_codnum , ( const char * ) fat_tipodoc , fat . get_char ( DOC_PROVV ) , fat . get_long ( DOC_NDOC ) ) ;
log . log ( 0 , log_msg ) ;
2013-05-27 12:01:21 +00:00
fat_nolo = fat . get ( DOC_PROVV ) ;
fat_nolo . add ( fat . get ( DOC_ANNO ) ) ;
fat_nolo . add ( fat . get ( DOC_CODNUM ) ) ;
fat_nolo . add ( fat . get ( DOC_NDOC ) ) ;
fat_nolo . add ( fat . get ( DOC_DATADOC ) ) ;
2013-03-25 13:46:24 +00:00
}
else
{
log . log ( 2 , TR ( " Impossibile generare la FATTURA " ) ) ;
}
return err = = NOERR ;
}
bool THardy_elab_docs : : genera_eff ( const TDocumento & fat , const real & tot_nac , TLog_report & log )
{
# ifdef NDEBUG
if ( fat . get_char ( DOC_PROVV ) ! = ' D ' )
return false ;
# endif
const real tot_fat = fat . totale_doc ( ) ;
if ( tot_fat = = tot_nac )
return false ;
const bool credito = tot_fat > tot_nac ;
const real importo = credito ? ( tot_fat - tot_nac ) : ( tot_nac - tot_fat ) ;
TDate datascad = fat . get ( DOC_DATADOC ) ; datascad . set_end_month ( ) ;
TEffetto eff ;
eff . put ( EFF_DATASCAD , datascad ) ;
eff . put ( EFF_TIPOPAG , credito ? tp_rid : tp_bonifico ) ;
eff . put ( EFF_TIPOCF , fat . get ( DOC_TIPOCF ) ) ;
eff . put ( EFF_CODCF , fat . get ( DOC_CODCF ) ) ;
eff . put ( EFF_CODABI , fat . get ( DOC_CODABIA ) ) ;
eff . put ( EFF_CODCAB , fat . get ( DOC_CODCABA ) ) ;
TRectype & reff = eff . row_r ( 1 , true ) ;
reff . put ( REFF_ANNO , fat . get ( DOC_ANNO ) ) ;
reff . put ( REFF_NUMPART , fat . get ( DOC_NDOC ) ) ;
reff . put ( REFF_NRIGA , 1 ) ;
reff . put ( REFF_NRATA , 1 ) ;
reff . put ( REFF_PROVV , fat . get ( DOC_PROVV ) ) ;
reff . put ( REFF_ANNODOC , fat . get ( DOC_ANNO ) ) ;
reff . put ( REFF_CODNUM , fat . get ( DOC_CODNUM ) ) ;
reff . put ( REFF_NFATT , fat . get ( DOC_NDOC ) ) ;
reff . put ( REFF_DATAFATT , fat . get ( DOC_DATADOC ) ) ;
reff . put ( REFF_IMPFATT , tot_fat ) ;
reff . put ( REFF_IMPORTO , importo ) ;
reff . put ( REFF_ACCSAL , ' A ' ) ;
TLocalisamfile file ( LF_EFFETTI ) ;
int err = eff . write ( file ) ;
if ( err = = NOERR )
{
TString msg ;
msg < < " Registrato effetto " < < eff . numero ( ) ;
log . log ( 0 , msg ) ;
}
else
log . log ( 2 , " Impossibile registrare l'effetto " ) ;
return err = = NOERR ;
}
2010-09-01 15:47:38 +00:00
2010-09-27 14:30:54 +00:00
void THardy_elab_docs : : elabora_documenti ( const TMask & mask , TISAM_recordset & fatture , TLog_report & log )
2010-09-01 15:47:38 +00:00
{
2013-03-25 13:46:24 +00:00
TProgind pi ( fatture . items ( ) , TR ( " Elaborazione documenti in corso... " ) ) ;
2010-09-01 15:47:38 +00:00
//inizializza variabili da usare nella scansione del recordset
long old_codcf = 0L ;
//array con l'insieme dei contratti e dei documenti elaborati per un singolo cliente!
TArray contratti_cliente , documenti_cliente ;
2013-05-27 12:01:21 +00:00
TAssoc_array fat_nolo ;
2010-09-01 15:47:38 +00:00
2013-04-09 15:07:10 +00:00
const int tc = mask . get_int ( F_TIPOCONTR ) ; // 0x7 (tutti tranne nolo) o 0x8 (solo nolo)
2013-05-27 12:01:21 +00:00
if ( tc & 0x8 ) // Elaborazione nolo?
{
// Elabora tutti i contratti di nolo per generare fatture ed effetti
const int cn = find_contratti_cliente ( mask . get_long ( F_CODCF ) , mask , 0x8 , contratti_cliente ) ;
FOR_EACH_ARRAY_ROW ( contratti_cliente , n_nolo , r_nolo )
{
TContratto_premi & contratto = * ( TContratto_premi * ) r_nolo ;
TToken_string fatkey ;
if ( genera_fat ( mask , contratto , fatkey , log ) )
{
TToken_string cnkey ; // Chiave contratto
cnkey . add ( contratto . get ( DOC_PROVV ) ) ;
cnkey . add ( contratto . get ( DOC_ANNO ) ) ;
cnkey . add ( contratto . get ( DOC_CODNUM ) ) ;
cnkey . add ( contratto . get ( DOC_NDOC ) ) ;
fat_nolo . add ( cnkey , fatkey ) ;
}
}
}
2010-09-13 13:39:46 +00:00
//giro sulle fatture (<28> il giro di pi<70> alto livello che viene esteso all'interno delle elabora_contratti)
2010-09-27 14:30:54 +00:00
for ( bool ok = fatture . move_first ( ) ; ok ; ok = fatture . move_next ( ) )
2010-09-01 15:47:38 +00:00
{
if ( ! pi . addstatus ( 1 ) )
break ;
2010-09-27 14:30:54 +00:00
const long codcf = fatture . get ( DOC_CODCF ) . as_int ( ) ;
2013-04-09 15:07:10 +00:00
// al cambio cliente deve controllare i contratti di quel cliente nel periodo di elaborazione!!
2010-09-01 15:47:38 +00:00
if ( codcf ! = old_codcf )
{
2010-09-27 14:30:54 +00:00
//generazione NAC del cliente precedente (una per contratto cliente)
2013-01-30 16:58:06 +00:00
if ( old_codcf > 0 & & ! documenti_cliente . empty ( ) )
2013-05-27 12:01:21 +00:00
genera_nac ( mask , contratti_cliente , fat_nolo , log ) ;
2010-09-27 14:30:54 +00:00
2010-09-01 15:47:38 +00:00
//aggiorna old_codcf in modo da poter controllare i contratti solo al cambio codcf
old_codcf = codcf ;
2013-05-27 12:01:21 +00:00
const int n_contratti = find_contratti_cliente ( codcf , mask , tc , contratti_cliente ) ;
2012-09-14 12:54:44 +00:00
TString8 key ; key . format ( " C|%ld " , codcf ) ;
TString msg ; msg < < TR ( " Cliente " ) < < ' ' < < codcf < < ' ' < < cache ( ) . get ( LF_CLIFO , key , CLI_RAGSOC ) ;
2013-05-27 12:01:21 +00:00
if ( n_contratti > 0 )
2010-09-01 15:47:38 +00:00
{
2013-05-27 12:01:21 +00:00
log . log ( 0 , msg ) ;
}
else
{
if ( tc & 0x8 ) // Elaborazione nolo?
{
// Nulla di grave se non esistono contratti di nolo
}
else
{
log . log ( 0 , msg ) ;
msg = TR ( " Non ha un contratto valido nel periodo selezionato pur avendo fatture. " ) ;
log . log ( 1 , msg ) ;
}
2010-09-01 15:47:38 +00:00
}
}
if ( contratti_cliente . items ( ) > 0 )
{
2013-01-30 16:58:06 +00:00
const TDate data_fine = mask . get ( F_ADATA ) ;
2010-09-01 15:47:38 +00:00
//se ha trovato uno o pi<70> contratti validi nel periodo passa alla elaborazione dei documenti del cliente
2010-09-27 14:30:54 +00:00
TDocumento * curr_doc = new TDocumento ( fatture . cursor ( ) - > curr ( ) ) ;
2010-09-01 15:47:38 +00:00
//elabora il documento corrente aggiornando le somme restituite sui contratti validi
2013-01-30 16:58:06 +00:00
if ( elabora_contratti ( * curr_doc , contratti_cliente , data_fine , log ) )
2010-09-01 15:47:38 +00:00
documenti_cliente . add ( curr_doc ) ;
else
delete ( curr_doc ) ;
}
} //for (bool ok = recset.move_first()...
2010-09-27 14:30:54 +00:00
//generazione NAC dell'ultimo cliente (una per contratto cliente)
2013-03-25 13:46:24 +00:00
if ( ! contratti_cliente . empty ( ) )
2013-05-27 12:01:21 +00:00
genera_nac ( mask , contratti_cliente , fat_nolo , log ) ;
2010-09-13 13:39:46 +00:00
//se elaborazione definitiva -> cambia lo stato ai documenti di vendita elaborati, mettendolo uguale..
//..a quello deciso in configurazione
const bool definitivo = mask . get_bool ( F_DEFINITIVO ) ;
2013-03-25 13:46:24 +00:00
if ( definitivo & & ! documenti_cliente . empty ( ) )
2010-09-13 13:39:46 +00:00
{
2013-01-30 16:58:06 +00:00
const TString4 stato_finale = ini_get_string ( CONFIG_DITTA , " ha " , " StatoFinFatt " ) ;
2010-09-13 13:39:46 +00:00
FOR_EACH_ARRAY_ITEM ( documenti_cliente , r , riga )
{
TDocumento & fattura = * ( TDocumento * ) riga ;
fattura . put ( DOC_STATO , stato_finale ) ;
fattura . rewrite ( ) ;
}
}
2010-09-01 15:47:38 +00:00
}
//metodo di alto livello con i punti principali del programma (come da analisi...)
void THardy_elab_docs : : elabora ( const TMask & mask )
{
//1) eventuale accoppamento di tutti i documenti provvisori creati con precedenti elaborazioni precedenti
int nac_killed = 0 ;
if ( mask . get_bool ( F_KILLPROVV ) )
nac_killed = kill_provv_nac ( mask ) ;
//log report con segnalazioni sui clienti trattati (bene o male)
TLog_report log ( " Sintesi elaborazione " ) ;
log . log ( 0 , " " ) ;
//2) recordset ordinato codag-codcf-numdoc con tutti i docs che soddisfano i parametri dell'utente
// ---------------------------------------------------------------------------------------------
TISAM_recordset recset ( " " ) ;
const long items = genera_recordset ( mask , recset ) ;
if ( items = = 0 )
2013-01-30 16:58:06 +00:00
log . log ( 1 , TR ( " Non esistono documenti di vendita che soddisfino i parametri selezionati! " ) ) ;
2010-09-01 15:47:38 +00:00
//3) elaborazione documenti e contratti, generazione NAC, salvataggi
// ---------------------------------------------------------------
elabora_documenti ( mask , recset , log ) ;
//3) scrittura log
// -------------
log . print_or_preview ( ) ;
}
void THardy_elab_docs : : main_loop ( )
{
THardy_elab_docs_mask mask ;
while ( mask . run ( ) = = K_ENTER )
elabora ( mask ) ;
}
bool THardy_elab_docs : : create ( )
{
2013-03-25 13:46:24 +00:00
open_files ( LF_TABCOM , LF_TAB , LF_CLIFO , LF_DOC , LF_RIGHEDOC , LF_ANAMAG , 0 ) ;
2010-09-01 15:47:38 +00:00
return TSkeleton_application : : create ( ) ;
}
int ha0500 ( int argc , char * argv [ ] )
{
2010-09-27 14:30:54 +00:00
THardy_elab_docs elabapp ;
elabapp . run ( argc , argv , TR ( " Generazione NAC " ) ) ;
return 0 ;
2013-03-25 13:46:24 +00:00
}
2013-05-27 12:01:21 +00:00