22557d5d80
servivano. Le maschere sono state modificate solo dal punto di vista estetico. Il modulo ab2 (invio e ricezione) è stato completato: esegue ricezioni da as400 e interne, ed esegue invii ad as400 (tranne la parte di analisi) e invii interni. Il file ab2100a.ini è il file di configurazione per as400 Il file ab2100b.ini è il file di configurazione per l'interno git-svn-id: svn://10.65.10.50/trunk@6073 c028cbd2-c16b-5b4b-a496-9718f37d4682
1225 lines
45 KiB
C++
Executable File
1225 lines
45 KiB
C++
Executable File
//AB2101.CPP: Ricezione tabelle
|
|
#include <utility.h> //Definizione di fexit
|
|
#include "movdett.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_MOVDETT
|
|
#include "saldi.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_SALDI
|
|
#include "voci.h" //Contiene le definizioni di costanti relative ai nomi dei cmapi di LF_VOCI
|
|
#include "relvoci.h" //Contiene le definizioni di costanti relative ai nomi dei cmapi di LF_RELVOCI
|
|
#include "relana.h" //Contiene le definizioni di costanti relative ai nomi dei cmapi di LF_RELANA
|
|
#include "caradd.h" //Contiene le definizioni di costanti relative ai nomi dei cmapi di LF_CARADD
|
|
#include "colldich.h" //Contiene le definizioni di costanti relative ai nomi dei cmapi di LF_COLLDICH
|
|
#include "ab2100.h" //Definizione della classe principale e di constanti che indicano l'indice nel file di configurazione
|
|
#include "ab2100a.h" //Campi della maschera
|
|
#include <progind.h>
|
|
#include <assoc.h>
|
|
|
|
TToken_string TAlbero_record ::wrk_string;
|
|
|
|
|
|
/* ********************************************************************************************************* */
|
|
/* TFile_text_AS400 */
|
|
/*********************************************************************************************************** */
|
|
|
|
//Costruttore di TFile_text_AS400: lo inizializzo a 0
|
|
TFile_text_AS400::TFile_text_AS400(const char* file_name, const char* config_name)
|
|
: TFile_text(file_name, config_name),_idncomp(1),_tipo_bilancio("")
|
|
{
|
|
}
|
|
|
|
|
|
inline TRicezione& app()
|
|
{
|
|
return (TRicezione&) main_app();
|
|
}
|
|
|
|
|
|
void TFile_text_AS400::cambia_anno(TString& str)
|
|
{
|
|
//Trasformo dal formato aa al formato aaaa solo se la data è nel formato aa:
|
|
//se str > 99 allora significa che la data è già in formato aaaa e quindi non deve eseguire nessun cambio
|
|
if ((atoi(str)>0) && (atoi(str) < 99))
|
|
{
|
|
if (str > "50")
|
|
str.insert("19");
|
|
else
|
|
str.insert("20");
|
|
}
|
|
}
|
|
|
|
void TFile_text_AS400::cambia_data(TString &str)
|
|
{
|
|
if (atoi(str)>0)
|
|
{
|
|
int aa= atoi(str.left(2));
|
|
int mm= atoi(str.mid(2,2));
|
|
int gg= atoi(str.right(2));
|
|
|
|
if (aa > 50)
|
|
aa=aa+1900;
|
|
else
|
|
aa=aa+2000;
|
|
|
|
TDate data(gg,mm,aa);
|
|
str=data.string();
|
|
}
|
|
}
|
|
|
|
//Questa funzione esegue la conversione dell'anno dal formato aa al formato aaaa
|
|
//void TFile_text_AS400::preformat_field(TRelation& rel,const TFieldref&field,const TRecord_text& rec,TString &str)
|
|
void TFile_text_AS400::preformat_field(const TFieldref& field, TString &str,TRelation& rel,const TString &tipo_tr)
|
|
{
|
|
if (field.file()==LF_MOVDETT)
|
|
{//Parte riservata ai MOVIMENTI/DETTAGLI
|
|
if (field.name()==ABMD_ANNO)
|
|
cambia_anno(str); //formatto l'anno: aa --> aaaa
|
|
|
|
if (field.name()==ABMD_DREG || field.name()==ABMD_DDOC)
|
|
cambia_data(str); //formatta la data aammgg --> aaaammgg
|
|
}//Fine MOVIMENTI/DETTAGLI
|
|
|
|
if (field.file()==LF_ABSALDI)
|
|
{//Parte riservata ai SALDI
|
|
if (field.name()==ABMD_ANNO) //formatto l'anno: aa ---> aaaa
|
|
cambia_anno(str);
|
|
}//Fine parte riservata ai SALDI
|
|
|
|
if (field.file()==LF_VOCI)
|
|
{//Va cambiato il TIPOVC da S a C, tutti gli altri casi rimangono inalterati
|
|
if((field.name()==ABVC_TIPOVC) && (str == FLAG_SOTTOD))
|
|
str = FLAG_COMPOSTA;
|
|
}
|
|
if (field.file()==LF_RELVOCI)
|
|
{
|
|
if((field.name()==ABRL_CODCOMP))
|
|
{//Lo accorcio di 5 caratteri
|
|
str.ltrim(5);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Assegno valori temporanei a IDPADRE, IDFIGLIO, IDSUCC, IDPREC
|
|
void TFile_text_AS400::scrivi_temp_link(TRelation& rel,const TRecord_text& rec)
|
|
{
|
|
if ((rec.type() == MOVIMENTO3) || (rec.type() == MOVIMENTO4) || (rec.type() == MOVIMENTO5))
|
|
{
|
|
real r(rec.get(PROGRESSIVO_DETT_MOVDETT));//Eseguo una conversione per un controllo numerico
|
|
if (r > 0) //E' un PROGRESSIVO DETTAGLIO
|
|
{
|
|
TString16 str1,str2;
|
|
str1 << FLAG_DETT << rec.get(PROGRESSIVO_DETT_MOVDETT).left(5);
|
|
rel.lfile().put(ABMD_IDPADRE,str1);
|
|
str2 << rec.get(PROGRESSIVO_DETT_MOVDETT).right(5);
|
|
rel.lfile().put(ABMD_IDFIGLIO,str2);
|
|
rel.lfile().put(ABMD_IDSUCC,0); //Assegno il numero di registrazione 0
|
|
rel.lfile().put(ABMD_IDPREC,0); //Assegno il numero di riga 0
|
|
}
|
|
else //E' un COGE
|
|
{
|
|
TString16 str1,str2;
|
|
str1 << FLAG_COGE << rec.get(CONTO_COGE_MOVDETT).left(5);
|
|
rel.lfile().put(ABMD_IDPADRE,str1);
|
|
str2 << rec.get(CONTO_COGE_MOVDETT).right(5);
|
|
rel.lfile().put(ABMD_IDFIGLIO,str2);
|
|
rel.lfile().put(ABMD_IDSUCC,0); //Assegno il numero di registrazione 0
|
|
rel.lfile().put(ABMD_IDPREC,0); //Assegno il numero di riga 0
|
|
}
|
|
}
|
|
else
|
|
{ //E' un movimento: tipo_rec =movi1 o movi2
|
|
TString16 str1,str2;
|
|
//Se è un movimento di progressivo
|
|
real r(rec.get(PROGRESSIVO_DETT_MOVDETT)); //Eseguo una conversione per un controllo numerico
|
|
if (r > 0)
|
|
{
|
|
str1 << FLAG_MOVIMENTO << rec.get(PROGRESSIVO_DETT_MOVDETT).left(5);
|
|
str2 << rec.get(PROGRESSIVO_DETT_MOVDETT).right(5);
|
|
}
|
|
else //... è un movimento di un saldo o di un coge
|
|
{
|
|
real r(rec.get(CONTO_COGE_MOVDETT)); //Eseguo una conversione per un controllo numerico
|
|
if (r > 0)
|
|
{
|
|
str1 << FLAG_MOVIMENTO << rec.get(CONTO_COGE_MOVDETT).left(5);
|
|
str2 << rec.get(CONTO_COGE_MOVDETT).right(5);
|
|
}
|
|
else
|
|
{ //C'è scritto la stessa cosa dell'if, in reltà CONTO_COGE contiene solo zeri
|
|
//e mi serve per riempire correttamente str1 che deve essere del tipo FCCCCC dove
|
|
//F è il flag_movimento e C è la prima parte del CONTO_COGE: se non avessi messo
|
|
//così str1 sarebbe stata del tipo F
|
|
str1 << FLAG_MOVIMENTO << rec.get(CONTO_COGE_MOVDETT).left(5);
|
|
str2 << rec.get(CONTO_COGE_MOVDETT).right(5);
|
|
}
|
|
}
|
|
|
|
rel.lfile().put(ABMD_IDPADRE,str1);
|
|
rel.lfile().put(ABMD_IDFIGLIO,str2);
|
|
rel.lfile().put(ABMD_IDSUCC,rec.get(NUMERO_REG_MOVDETT)); //Assegno il numero di registrazione
|
|
rel.lfile().put(ABMD_IDPREC,rec.get(NUMERO_RIGA_MOVDETT)); //Assegno il numero di riga
|
|
}
|
|
}
|
|
|
|
|
|
void TFile_text_AS400::aggiorna_rel_link(TLocalisamfile &relvoc)
|
|
{
|
|
if (relvoc.get_long(ABRL_IDCOMP) > 1)
|
|
{ //Ci deve essere un precedente
|
|
//Recupero la relazione precedente
|
|
TLocalisamfile temp(LF_RELVOCI);
|
|
temp.put(ABRL_TIPOCOD,relvoc.get(ABRL_TIPOCOD));
|
|
temp.put(ABRL_CODVC,relvoc.get(ABRL_CODVC));
|
|
temp.put(ABRL_IDCOMP,relvoc.get_long(ABRL_IDCOMP)-1);
|
|
if (temp.read() == NOERR)
|
|
{//Ho recuperato la relazione precedente
|
|
temp.put(ABRL_NEXTCOMP,relvoc.get(ABRL_IDCOMP)); //Aggiorno la relazione precedente
|
|
relvoc.put(ABRL_PREVCOMP,relvoc.get_long(ABRL_IDCOMP)-1); //Aggiorno la relazione attuale
|
|
temp.rewrite();// Scrivo la precedente
|
|
}
|
|
else
|
|
CHECK (FALSE, "Non ho trovato il prevcomp di una relazione che dovrebbe averlo");
|
|
}
|
|
else
|
|
{ //Non c'è la relazione precedente
|
|
relvoc.put(ABRL_PREVCOMP,ID_NULLO); //Aggiorno la relazione attuale
|
|
}
|
|
}
|
|
|
|
bool TFile_text_AS400::pre_writerel(TRelation& rel,const TRecord_text& rec)
|
|
{
|
|
int logic_num=rel.lfile().num(); //Carico il numero logico del file che sto utilizzando
|
|
|
|
if (logic_num==LF_ABSALDI)
|
|
{//Parte riservata ai SALDI: modifico (immetto) il tipo di bilancio con il valore passato da maschera
|
|
//solo se questo campo è vuoto, nel caso contratio lascio il valore letto
|
|
// TString prova = get_tipo_bil();
|
|
rel.lfile().put(ABMD_TIPOBIL,get_tipo_bil());
|
|
return TRUE;
|
|
}//Fine parte riservata ai SALDI
|
|
|
|
|
|
if (logic_num==LF_MOVDETT)
|
|
{ //Parte riservata ai DETTAGLI e MOVIMENTI
|
|
//Inserisco nel file isam tutti i dati che mi servono
|
|
//per la costruzione dell'albero.
|
|
//Si divide in 3 parti.
|
|
|
|
//PARTE 1: Assegno degli id temporanei
|
|
TString id = "1";
|
|
|
|
//Costruisco un chiave composta con i vari campi letti che interessano
|
|
TToken_string key;
|
|
key.add(rec.get(CODICE_DITTA_MOVDETT));
|
|
key.add(rec.get(ANNO_BILANCIO_MOVDETT));
|
|
key.add(rec.get(CODICE_PERIODO_MOVDETT));
|
|
key.add(rec.get(CODICE_TABELLA_MOVDETT));
|
|
|
|
//Controllo che esiste nell'assoc_array un elemento con chiave uguale a quella appena generata
|
|
//se esiste last_id contiene l'ultimo indice associato a quella chiave
|
|
TString *last_id=(TString*)_last_id.objptr(key);
|
|
if (last_id)
|
|
{
|
|
long val=atol(*last_id); //Se esiste incremento l'indice
|
|
val++;
|
|
id.format("%ld",val);
|
|
}
|
|
_last_id.add(key,id,TRUE); //se esiste già una chiave giusta, sovrascrivo l'indice aggiornato
|
|
//se non esiste creo la nuova chiave con indice 1
|
|
|
|
rel.lfile().put(ABMD_ID,id); //scrivo sulla relazione assegnando a ABMD_ID l'indice calcolato
|
|
//FINE PARTE 1
|
|
|
|
//PARTE 2: inserisco il TIPODETT, TIPOBIL e evenutalmente CODDETT
|
|
if ((rec.type() == MOVIMENTO3) || (rec.type() == MOVIMENTO4) || (rec.type() == MOVIMENTO5))
|
|
{ //E' di tipo "dettaglio" o "conto contabile": non può essere "movimento"
|
|
real r(rec.get(CONTO_COGE_MOVDETT)); //Eseguo una conversione per un controllo numerico
|
|
if (r > 0)
|
|
{//E' un COGE e quindi inserisco anche il Coddett
|
|
rel.lfile().put(ABMD_TIPODETT,"CG");
|
|
rel.lfile().put(ABMD_CODDETT,rec.get(CONTO_COGE_MOVDETT));
|
|
rel.lfile().put(ABMD_TIPOBIL,get_tipo_bil());
|
|
}
|
|
else
|
|
{//In questo caso inserisco Coddett = 0 per azzerare eventuali altri valori
|
|
//già scritti precedentemente
|
|
rel.lfile().put(ABMD_TIPODETT,"DT");
|
|
rel.lfile().put(ABMD_CODDETT,0);
|
|
rel.lfile().put(ABMD_TIPOBIL,get_tipo_bil());
|
|
}
|
|
}
|
|
else
|
|
{//Può essere solo un "movimento" perchè il tipo record è MOVI1 o MOVI2
|
|
rel.lfile().put(ABMD_TIPODETT,"MO");
|
|
rel.lfile().put(ABMD_TIPOBIL,get_tipo_bil());
|
|
rel.lfile().put(ABMD_CODDETT,0); //Azzero il contenuto del campo da valori precedenti
|
|
real r(rec.get(CONTO_COGE_MOVDETT)); //Eseguo una conversione per un controllo numerico
|
|
if (r > 0)
|
|
{//E' un movimento di un COGE e quindi devo scrivere anche CODDETT
|
|
rel.lfile().put(ABMD_CODDETT,rec.get(CONTO_COGE_MOVDETT));
|
|
}
|
|
}//FINE PARTE 2
|
|
|
|
//PARTE 3. Nel caso in cui il record sia un movimento, devo gestire diversamente il saldo:
|
|
//Se il flag di riclassificazione è attivato, l'importo del movimento va scritto in RDARE o RAVERE
|
|
//a seconda del flag D/A
|
|
//Se il flag di riclassificazione non è ativato
|
|
// l'importo va inserito nel saldo (e settato il flag D/A) se il record è MOVI1
|
|
// l'importo va inserito in PDARE o PAVERE a seconda del flag D/A
|
|
|
|
if (rec.type() == MOVIMENTO1 || rec.type() == MOVIMENTO2)
|
|
{
|
|
if (rec.get(FLAG_RICLASSIFICAZIONE_MOVDETT) == "X")
|
|
{//L'importo va comunque in RDARE o RAVERE
|
|
if (rec.get(FLAG_DA_MOVDETT) == "D")
|
|
rel.lfile().put(ABMD_RDARE,rec.get(IMPORTO_MOVDETT));
|
|
else
|
|
rel.lfile().put(ABMD_RAVERE,rec.get(IMPORTO_MOVDETT));
|
|
}
|
|
else
|
|
{//L'importo va nel campo IMPORTO se MOVIMENTO1
|
|
if (rec.type() == MOVIMENTO1)
|
|
{
|
|
rel.lfile().put(ABMD_IMPORTO,rec.get(IMPORTO_MOVDETT));
|
|
rel.lfile().put(ABMD_FLDA,rec.get(FLAG_DA_MOVDETT));
|
|
}
|
|
else
|
|
{// ... oppure in PDARE o PAVERE se MOVI2
|
|
if (rec.get(FLAG_DA_MOVDETT) == "D")
|
|
rel.lfile().put(ABMD_PDARE,rec.get(IMPORTO_MOVDETT));
|
|
else
|
|
rel.lfile().put(ABMD_PAVERE,rec.get(IMPORTO_MOVDETT));
|
|
}
|
|
}
|
|
}//FINE PARTE 3
|
|
|
|
//PARTE 4
|
|
scrivi_temp_link(rel,rec);
|
|
//FINE PARTE 4
|
|
return TRUE;
|
|
}//Fine parte riservata ai DETTAGLI e MOVIMENTI
|
|
|
|
if (logic_num==LF_VOCI)
|
|
{//Parte riservata alle voci
|
|
bool write_rec=TRUE;
|
|
TAdditional_cars &caradd= (TAdditional_cars &)(rel.lfile(LF_CARADD));
|
|
TAdditional_cols &col= (TAdditional_cols &)(rel.lfile(LF_COLLDICH));
|
|
|
|
if ((rec.get(TIPO_VOCE_VOCI) != FLAG_INDICE) )
|
|
{//Scrivo la chiave anche sul file secondario della relazione
|
|
real idcaradd_ra;
|
|
idcaradd_ra = 0;
|
|
// TString prova = *idcaradd_ra.string();
|
|
TLocalisamfile fil(LF_VOCI);
|
|
fil.curr()=rel.curr();
|
|
if (fil.read() != NOERR)
|
|
{
|
|
// Voce non ancora inserita; la caradd diventa il default
|
|
caradd.write();
|
|
rel.lfile().put(ABVC_IDCARADD,caradd.get(ABCA_ID));
|
|
} else {
|
|
// non scrivero' la voce
|
|
write_rec=FALSE;
|
|
// cerco il default
|
|
if (!caradd.current().same_as(rel.lfile().get_real(ABVC_IDCARADD)))
|
|
{
|
|
// diverso dal default: va scritto in relana
|
|
caradd.write();
|
|
idcaradd_ra=caradd.get_real(ABCA_ID);
|
|
}
|
|
}
|
|
if (atol(rec.get(NCA_VOCI)) > 0)
|
|
{//Aggiorno anche radici: inserisco solo le "voci" di primo livello
|
|
//e sono le tabelle di analisi, cioè le radici dell'albero
|
|
|
|
//Aggiorno RELVOCI
|
|
TLocalisamfile & relvoc=rel.lfile(LF_RELVOCI);
|
|
relvoc.put(ABRL_TIPOCOD,FLAG_ANALISI); //Analisi di bilancio
|
|
relvoc.put(ABRL_CODCOMP,rel.lfile().get(ABVC_CODVC));
|
|
relvoc.put(ABRL_NEXTCOMP,ID_NULLO); //La relazione successiva non la vedo ancora
|
|
aggiorna_rel_link(relvoc);
|
|
relvoc.write(); //Scrivo effettivamente sull'isamfile
|
|
|
|
//Aggiorno il collegamento a dichiarazione
|
|
col.write();
|
|
|
|
//Aggiorno RELANA
|
|
TLocalisamfile &ran=rel.lfile(LF_RELANA);
|
|
ran.put(ABRA_CODAN,(relvoc.get(ABRL_CODVC)).sright(2));
|
|
ran.put(ABRA_ID,relvoc.get(ABRL_IDCOMP)); //Assegno questo "ID" provvisorio per poterlo rintracciare dopo
|
|
ran.put(ABRA_DESCRIZ,rel.lfile().get(ABVC_DESCR));
|
|
ran.put(ABRA_TIPOCOD,FLAG_ANALISI);
|
|
ran.put(ABRA_CODVC,relvoc.get(ABRL_CODVC));
|
|
ran.put(ABRA_NCOMP,relvoc.get(ABRL_IDCOMP));
|
|
ran.put(ABRA_IDCARADD,idcaradd_ra.string("############"));
|
|
ran.put(ABRA_USACARADD,idcaradd_ra==ID_NULLO ? FALSE : TRUE);
|
|
ran.put(ABRA_IDCOLDICH,col.get_long(ABCD_ID));
|
|
ran.write();
|
|
|
|
}
|
|
} else
|
|
// tipo di voce non più supportata
|
|
write_rec=FALSE;
|
|
return write_rec;
|
|
}//Fine parte riservata alle voci
|
|
|
|
if (logic_num==LF_RELVOCI)
|
|
{//Parte riservata alle relazioni
|
|
rel.lfile().put(ABRL_TIPOCOD,FLAG_VOCI);
|
|
rel.lfile().put(ABRL_NEXTCOMP,ID_NULLO); //La relazione successiva non la vedo ancora
|
|
aggiorna_rel_link(rel.lfile());
|
|
return TRUE;
|
|
}//Fine parte riservata alle relaizioni
|
|
|
|
if (logic_num==LF_RELANA)
|
|
{//Parte riservata a SOTTORELAZIONI e COLLEGAMENTO A DICHIARAZIONE
|
|
|
|
TAdditional_cars &caradd = (TAdditional_cars &)(rel.lfile(LF_CARADD));
|
|
TAdditional_cols &col = (TAdditional_cols &)(rel.lfile(LF_COLLDICH));
|
|
|
|
//Abilito la scrittura sulle relazioni collegate
|
|
rel.write_enable(LF_COLLDICH,TRUE);
|
|
col.write();
|
|
rel.write_enable(LF_COLLDICH,FALSE);
|
|
rel.lfile().put(ABRA_IDCOLDICH,col.get_long(ABCD_ID)); //Assegno l'ID del collegamento alla relazione principale
|
|
|
|
//Parte riservata a SOTTORELAZIONI e CARATTERISTICHE ADDIZIONALI
|
|
TString codice_voce=rel.lfile().get(ABRA_CODVC);//Estraggo da RELANA il codice di ricerca su VOCI
|
|
// codice_voce.ltrim(2); //e la formatto
|
|
|
|
TLocalisamfile voc(LF_VOCI);
|
|
voc.put(ABVC_CODVC,codice_voce);
|
|
if (voc.read() == NOERR)
|
|
{ //Ho trovato la voce
|
|
//Ricerco la caratteristica addizionale di default
|
|
//Confronto le caratteristiche addizionali del record che
|
|
//sta per essere salvato e le caratteristiche di default
|
|
if (! caradd.current().same_as(voc.get_real(ABVC_IDCARADD)))
|
|
{
|
|
//Non ho trovato la VOCE o CARATTERISTICA ADDIZIONALE oppure è diversa
|
|
caradd.write();
|
|
rel.lfile().put(ABRA_USACARADD,TRUE); //Setto il flag
|
|
// long prova = atol (caradd.get(ABCA_ID)); //Solo per debug
|
|
rel.lfile().put(ABRA_IDCARADD,caradd.get(ABCA_ID)); //Aggiungo il collegamento alla carat. add.
|
|
}
|
|
else
|
|
{
|
|
rel.lfile().put(ABRA_USACARADD,FALSE); //Setto il flag
|
|
rel.lfile().put(ABRA_IDCARADD, ID_NULLO ); //Aggiungo il collegamento alla carat. add. di default
|
|
}
|
|
}
|
|
else
|
|
CHECK (FALSE,"Si è verificato una inconsistenza nei dati: ho trovato una sottorelazione \n che non ha la relativa voce");
|
|
|
|
return TRUE;
|
|
} // Fine LF_RELANA
|
|
return TRUE;
|
|
}
|
|
|
|
/* ********************************************************************************************************* */
|
|
/* TTrasfer */
|
|
/*********************************************************************************************************** */
|
|
|
|
//Questo Handler viene "richiamato" da tre campi:
|
|
// F_PERCORSO, F_PERCORSO_UTENTE, F_TIPO_RICE
|
|
bool TTrasfer::inseriscipercorso(TMask_field& f, KEY k)
|
|
{
|
|
bool modificato = FALSE; //Questa mi dice quando c'è stata una modifica sulla maschera
|
|
if ((k==K_TAB) &&
|
|
(f.focusdirty()) &&
|
|
((f.dlg()==F_PERCORSO) || (f.dlg() == F_PERCORSO_UTENTE)))
|
|
//Entro in questo if solo se ho eseguito delle modifiche al campo F_PERCORSO
|
|
//o F_PERCORSO_UTENTE e all'uscita degli stessi
|
|
//Per il campo F_PERCORSO_UTENTE mi serve solo controllare che esista il percorso e il file indicati
|
|
{
|
|
TString percorso =f.get(); //Leggo il contenuto del campo
|
|
bool esiste=fexist(percorso); //Controllo l'esistenza del file
|
|
if (!esiste)
|
|
return f.error_box("Il percorso o il file specificato non esiste.");
|
|
modificato=TRUE;
|
|
}
|
|
|
|
if ((k==K_SPACE) && (f.dlg()==F_TIPO_RICE) && f.focusdirty())
|
|
{//Entro in questo if solo dopo aver modificato il contenuto del campo
|
|
//F_TIPO_RICE e all'uscita dallo stesso
|
|
TString percorso =f.mask().get(F_PERCORSO); //Leggo il contenuto del campo
|
|
bool esiste=fexist(percorso); //Controllo l'esistenza del file
|
|
if (!esiste)
|
|
return f.error_box("Il percorso o il file specificato non esiste.");
|
|
modificato=TRUE;
|
|
}
|
|
|
|
if (((f.dlg() == F_PERCORSO) || (f.dlg() == F_TIPO_RICE ))&& modificato)
|
|
{//Entro in questo if tutte le volte che è stato modificato il campo F_PERCORSO
|
|
//o F_TIPO_RICE
|
|
if (f.mask().get_int(F_TIPO_RICE) == RICEZIONE_AS400)
|
|
{ //Questa parte dell'handler è riservata solo al campo F_PERCORSO
|
|
//se è abilitata la ricezione da AS400: in tutti gli altri casi
|
|
//non è garantito che ci sia un record di testa
|
|
TWait_cursor hourglass;
|
|
TRecord_text rec_temp; //Istanzio un tipo record_text
|
|
|
|
TString config_file_temp(f.mask().get(F_PERCORSO_UTENTE));//Nome del file di configurazione
|
|
TFilename percorso_temp(f.mask().get(F_PERCORSO)); //Contiene il percorso completo del file sorgente
|
|
int tipo_ricezione = f.mask().get_int(F_TIPO_RICE);
|
|
app().set_transfer(tipo_ricezione,percorso_temp,config_file_temp);
|
|
|
|
TFile_text *file_temp=NULL;
|
|
file_temp=app().trans_file();
|
|
file_temp->open('r'); //Apro il file di testo in rettura
|
|
int err = file_temp->read(rec_temp); //Leggo la prima riga del file di testo (dovrebbe contenere il record di testata)
|
|
if((err == NOERR) && (rec_temp.type() == RECORD_TESTA)) //Controllo la lettura e che ci sia il record di testa
|
|
{//La lettura della testata ha avuto successo
|
|
bool abilita_piaco = (rec_temp.get(AB_PIANO_CONTI) == ABILITATO);
|
|
f.mask().enable(F_PIANO_CONTI,abilita_piaco);
|
|
|
|
bool abilita_periodi = (rec_temp.get(AB_PERIODI_BIL) == ABILITATO);
|
|
f.mask().enable(F_PERIODI_BILANCI,abilita_periodi);
|
|
|
|
bool abilita_analisi = (rec_temp.get(AB_ANALISI) == ABILITATO);
|
|
f.mask().enable(F_ANALISI,abilita_analisi);
|
|
|
|
bool abilita_saldi_movimenti = (rec_temp.get(AB_SALDI) == ABILITATO) ||
|
|
(rec_temp.get(AB_DETT) == ABILITATO) ||
|
|
(rec_temp.get(AB_MOV) == ABILITATO);
|
|
f.mask().enable(F_SALDI,abilita_saldi_movimenti);
|
|
f.mask().enable(F_MOVIMENTI,abilita_saldi_movimenti);
|
|
}
|
|
else //non sono riuscito a trovare la testato o il tipo record dove me lo aspettavo
|
|
error_box ("Non ho trovato il record di testata o non riesco a leggere il file di configurazione");
|
|
file_temp->close();
|
|
delete file_temp;
|
|
file_temp =NULL;
|
|
}
|
|
else
|
|
{//Ho scelto una ricezione INTERNA o USER_DEFINED: abilito tutti gli altri campi
|
|
//poichè non è previsto che ci sia un campo di testata
|
|
f.mask().enable(F_PIANO_CONTI,TRUE);
|
|
f.mask().enable(F_PERIODI_BILANCI,TRUE);
|
|
f.mask().enable(F_ANALISI,TRUE);
|
|
f.mask().enable(F_SALDI,TRUE);
|
|
f.mask().enable(F_MOVIMENTI,TRUE);
|
|
f.mask().enable(F_VOCI,TRUE);
|
|
f.mask().enable(F_RELAZ,TRUE);
|
|
f.mask().enable(F_SRELAZ,TRUE);
|
|
}
|
|
}// Non sono sul campo F_PERCORSO
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* ********************************************************************************************************* */
|
|
/* TRicezione */
|
|
/*********************************************************************************************************** */
|
|
/*
|
|
bool TRicezione::create()
|
|
{
|
|
_files.add(new TLocalisamfile(LF_CARADD),1);
|
|
_files.add(new TLocalisamfile(LF_COLLDICH),2);
|
|
dispatch_e_menu(BAR_ITEM(1)); //Simula la scelta di una voce di menu
|
|
return TRUE;
|
|
}
|
|
|
|
bool TRicezione::destroy() //Distruttore
|
|
{
|
|
return TRUE;
|
|
} */
|
|
|
|
|
|
|
|
//Funzione membro che effettua la conversione
|
|
//bool TRicezione::menu(MENU_TAG)
|
|
void TRicezione::main_loop()
|
|
{
|
|
_files.add(new TLocalisamfile(LF_CARADD),1);
|
|
_files.add(new TLocalisamfile(LF_COLLDICH),2);
|
|
|
|
TString config_file; //Nome del file di configurazione
|
|
TMask msk("AB2100A"); //Maschera dove si chiede di immettere il percorso del file sorgente
|
|
TFilename percorso; //Contiene il percorso completo del file sorgente
|
|
msk.set_handler(F_PERCORSO, inseriscipercorso); //Assegno un handler al campo F_PERCORSO
|
|
//inseriscipercorso controlla che il percorso (e il file) esista e sia corretto
|
|
msk.set_handler(F_PERCORSO_UTENTE, inseriscipercorso);
|
|
msk.set_handler(F_TIPO_RICE, inseriscipercorso);
|
|
//A questo punto il percorso e' corretto
|
|
if (msk.run()== K_ENTER) //Eseguo la maschera
|
|
{
|
|
//Visualizza una finestra di attesa
|
|
TIndwin idle(0,"Attendere: aggiornamento della tabella in corso. \n L'operazione potrebbe richiedere qualche minuto ... ",FALSE,FALSE,60);
|
|
percorso=msk.get(F_PERCORSO); //Leggo il contenuto di F_PERCORSO
|
|
|
|
|
|
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_AS400)
|
|
{
|
|
_rice = new TRicezione_AS400(percorso);
|
|
}
|
|
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_INTERNA)
|
|
{
|
|
_rice = new TObject_reception(percorso);
|
|
}
|
|
if (msk.get_int(F_TIPO_RICE) == RICEZIONE_USER_DEFINED)
|
|
{
|
|
_rice = new TObject_reception(percorso);
|
|
}
|
|
|
|
_rice->ricevi(msk);
|
|
|
|
/* if ((msk.get_int(F_TIPO_RICE) == RICEZIONE_AS400) &&
|
|
(msk.get_bool(F_MOVIMENTI)))
|
|
{
|
|
build_balancetree(LF_MOVDETT);
|
|
} */
|
|
//La chiusura del _trasfile non può essere eseguita prima poichè questo
|
|
//serve nella costruzione dell'albero dei movimenti
|
|
/* if (msk.get_bool(F_SRELAZ))
|
|
build_relana(config_file,msk,percorso); */
|
|
//messaggio finale
|
|
message_box(" ... aggiornamento delle tabelle selezionate effettuato");
|
|
} //end if (msk.run())
|
|
// return FALSE;
|
|
}
|
|
|
|
|
|
void TObject_reception::ricevi(TMask & msk)
|
|
{
|
|
TRecord_text rec; //Istanzio un tipo record_text
|
|
|
|
if ((msk.get_bool(F_VOCI)) &&
|
|
(msk.get_int(F_TIPO_RICE) == RICEZIONE_AS400))
|
|
{//Eseguo questa parte solo per la ricezione AS400
|
|
TRelation *r=_trasfile->t_rec(LF_VOCI)->relation();
|
|
TAdditional_cars * ca=new TAdditional_cars(_excllock);
|
|
r->replacef(ca,LF_CARADD);
|
|
TAdditional_cols * co=new TAdditional_cols();
|
|
r->replacef(co,LF_COLLDICH);
|
|
}
|
|
|
|
//Ciclo di lettura-scrittura fino a quando la lettura è possibile
|
|
while (_trasfile->ok_r())
|
|
{
|
|
if(_trasfile->read(rec) == NOERR)
|
|
{
|
|
if (msk.get_bool(F_PIANO_CONTI)) //Controllo se si è scelto di convertire il piano dei conti
|
|
{
|
|
_trasfile->autosave(rec,LF_ABPCON);
|
|
}
|
|
if (msk.get_bool(F_PERIODI_BILANCI)) //Scelta di convertire la tabella periodi bilanci
|
|
{
|
|
_trasfile->autosave(rec,LF_TABCOM);
|
|
}
|
|
if (msk.get_bool(F_ANALISI)) //scelta di cnverite la tabella tipi analisi di bilancio
|
|
{
|
|
_trasfile->autosave(rec,LF_ANALISI);
|
|
}
|
|
if (msk.get_bool(F_MOVIMENTI)) //scelta di cnverite la tabella tipi analisi di bilancio
|
|
{
|
|
_trasfile->autosave(rec,LF_MOVDETT);
|
|
}
|
|
if (msk.get_bool(F_SALDI)) //scelta di cnverite la tabella tipi analisi di bilancio
|
|
{
|
|
_trasfile->autosave(rec,LF_ABSALDI);
|
|
}
|
|
if (msk.get_bool(F_VOCI))
|
|
{
|
|
_trasfile->autosave(rec,LF_VOCI);
|
|
}
|
|
if (msk.get_bool(F_RELAZ))
|
|
{
|
|
_trasfile->autosave(rec,LF_RELVOCI);
|
|
if (msk.get_int(F_TIPO_RICE) != RICEZIONE_AS400)
|
|
{// Se è abilitito è abilitato la RICEZIONE_INTERNA devo ricevere anche questi files
|
|
_trasfile->autosave(rec,LF_RELANA);
|
|
_trasfile->autosave(rec,LF_CARADD);
|
|
_trasfile->autosave(rec,LF_COLLDICH);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//Finita prima fase di aggionamento, si passa eventualmente alla seconda
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ********************************************************************************************************* */
|
|
/* TAlbero_record */
|
|
/*********************************************************************************************************** */
|
|
|
|
// visita in dept first e aggiunge man mano i link corretti ai nodi
|
|
void TAlbero_record::dept_first(TToken_string key, TRectype * padre, TRectype * prec, int &curr_id,
|
|
TString_array & allkeys, TToken_string ** prog_key) // param . per ricerche COGE
|
|
{
|
|
TRectype * myself=(TRectype * )objptr(key);
|
|
// *********
|
|
// insert this node
|
|
myself->put(ABMD_ID,curr_id);
|
|
myself->put(ABMD_IDPADRE,padre ? padre->get(ABMD_ID):ID_NULLO);
|
|
myself->put(ABMD_IDFIGLIO,ID_NULLO);
|
|
myself->put(ABMD_IDPREC,prec ? prec->get(ABMD_ID) : ID_NULLO);
|
|
myself->put(ABMD_IDSUCC,ID_NULLO);
|
|
if (prec==NULL) // il primo figlio aggiorna il tipodett del padre
|
|
if (padre)
|
|
{
|
|
padre->put(ABMD_DETTFIGLIO,myself->get(ABMD_TIPODETT));
|
|
}
|
|
else
|
|
{ // il padre è un saldo
|
|
TLocalisamfile rel(LF_ABSALDI); //Creo un nuova relazione
|
|
//compongo la chiave che mi interessa
|
|
rel.put(ABS_CODDITTA,myself->get(ABMD_CODDITTA));
|
|
rel.put(ABS_ANNO,myself->get(ABMD_ANNO));
|
|
rel.put(ABS_CODPDB,myself->get(ABMD_CODPDB));
|
|
rel.put(ABS_TIPOBIL,myself->get(ABMD_TIPOBIL));
|
|
rel.put(ABS_CODCBL,myself->get(ABMD_CODCBL));
|
|
//ricerco la chiave
|
|
if (rel.read()==NOERR)
|
|
{//se esiste aggiorno il campo
|
|
rel.put(ABS_DETTFIGLIO,myself->get(ABMD_TIPODETT));
|
|
rel.rewrite();
|
|
}
|
|
else
|
|
{// ... questa situazione non dovrebbe accadere: se succede si è verificata una
|
|
//inconsistenza nei dati
|
|
fatal_box("Si è verificato una inconsistenza nei dati: \n controllare che tutti i movimenti abbiano il relativo saldo");
|
|
}
|
|
}
|
|
TToken_string key_figlio, key_fratello;
|
|
// *********
|
|
// scende sul figlio
|
|
key_figlio=cerca_figlio(key,allkeys,prog_key);
|
|
if (key_figlio.not_empty()) // esiste il figlio
|
|
{
|
|
curr_id++;
|
|
myself->put(ABMD_IDFIGLIO,curr_id);
|
|
|
|
dept_first(key_figlio, myself, NULL ,curr_id, allkeys, prog_key);
|
|
}
|
|
// *********
|
|
// passa al fratello
|
|
|
|
key_fratello=cerca_fratello(key,allkeys,prog_key);
|
|
if (key_fratello.not_empty()) // esiste il fratello
|
|
{
|
|
curr_id++;
|
|
myself->put(ABMD_IDSUCC,curr_id);
|
|
dept_first(key_fratello, padre, myself ,curr_id, allkeys, prog_key);
|
|
}
|
|
}
|
|
|
|
//key is: FLAG|CODDETT|NREG|NRIG
|
|
TToken_string& TAlbero_record ::cerca_figlio (TToken_string &key,
|
|
TString_array& allkeys, // parametri ricerca COGE
|
|
TToken_string ** next_key
|
|
)
|
|
{
|
|
|
|
TString cod_dett(key.get(1));
|
|
wrk_string.cut(0);
|
|
if (*key.get(0)==FLAG_COGE)
|
|
{
|
|
// sono un COGE? il figlio può essere un mov o un COGE
|
|
// cerco un MOV
|
|
wrk_string.cut(0);
|
|
wrk_string.add(FLAG_MOVIMENTO);
|
|
wrk_string.add(cod_dett);
|
|
wrk_string.add("0");
|
|
wrk_string.add("1");
|
|
if (!is_key(wrk_string))
|
|
{
|
|
// il mov non c'è, cerco un COGE
|
|
wrk_string.cut(0);
|
|
TString cod_grp(cod_dett.left(2)),
|
|
cod_con(cod_dett.mid(2,4)),
|
|
cod_scon(cod_dett.right(4));
|
|
|
|
if (atoi(cod_scon) > 0) // sono all'ultimo livello
|
|
return wrk_string;
|
|
|
|
if (*next_key)
|
|
{
|
|
TString cod_dett_succ=(*next_key)->get(1);
|
|
if (atoi(cod_con) > 0)
|
|
{
|
|
// il figlio di un conto è un sottoconto e ha lo stesso gruppo/conto
|
|
if (cod_dett_succ.left(2)!=cod_grp ||cod_dett_succ.mid(2,4)!=cod_con)
|
|
return wrk_string;
|
|
} else {
|
|
// il figlio di un gruppo è un conto e ha lo stesso gruppo
|
|
if (cod_dett_succ.left(2)!=cod_grp)
|
|
return wrk_string;
|
|
}
|
|
wrk_string.add(FLAG_COGE);
|
|
wrk_string.add(cod_dett_succ);
|
|
wrk_string.add("0");
|
|
wrk_string.add("0");
|
|
*next_key=(TToken_string *)allkeys.succ_item();
|
|
}
|
|
}
|
|
}
|
|
else if (*key.get(0)==FLAG_DETT)
|
|
{
|
|
// sono un dettaglio immesso
|
|
// il figlio può solo essere un mov
|
|
wrk_string.add(FLAG_MOVIMENTO);
|
|
wrk_string.add(cod_dett);
|
|
wrk_string.add("0");
|
|
wrk_string.add("1");
|
|
}
|
|
// else ... sono un movimento? non ho figli!
|
|
else
|
|
return wrk_string;
|
|
|
|
if (!is_key(wrk_string))
|
|
wrk_string.cut(0);
|
|
return wrk_string;
|
|
}
|
|
|
|
|
|
//key is: FLAG|CODDETT|NREG|NRIG
|
|
TToken_string& TAlbero_record ::cerca_fratello (TToken_string &key,
|
|
TString_array& allkeys, // parametri ricerca COGE
|
|
TToken_string ** next_key
|
|
)
|
|
{
|
|
TString cod_dett(key.get(1));
|
|
wrk_string.cut(0);
|
|
if (*key.get(0)==FLAG_COGE)
|
|
{
|
|
// sono un COGE?
|
|
// cerco la chiave successiva
|
|
|
|
TString cod_grp(cod_dett.left(2)),
|
|
cod_con(cod_dett.mid(2,4)),
|
|
cod_scon(cod_dett.right(4));
|
|
|
|
if (*next_key)
|
|
{
|
|
TString cod_dett_succ=(*next_key)->get(1);
|
|
if (atoi(cod_scon) > 0)
|
|
{
|
|
// fratello di un sottoconto
|
|
if (cod_dett_succ.left(2)!=cod_grp ||cod_dett_succ.mid(2,4)!=cod_con)
|
|
return wrk_string;
|
|
}
|
|
else if (atoi(cod_con) > 0)
|
|
{
|
|
// fratello di un conto
|
|
if (cod_dett_succ.left(2)!=cod_grp)
|
|
return wrk_string;
|
|
} else {
|
|
// fratello di un gruppo
|
|
if (*(*next_key)->get(0)!=FLAG_COGE)
|
|
return wrk_string;
|
|
}
|
|
wrk_string.add(FLAG_COGE);
|
|
wrk_string.add(cod_dett_succ);
|
|
wrk_string.add("0");
|
|
wrk_string.add("0");
|
|
*next_key=(TToken_string *)allkeys.succ_item();
|
|
}
|
|
}
|
|
else if (*key.get(0)==FLAG_DETT)
|
|
{
|
|
real r(cod_dett); //Eseguo una conversione per una operazione numerica
|
|
r+=1;
|
|
TString cod_dett_succ=r.string();
|
|
|
|
cod_dett_succ.right_just(10,'0');
|
|
// sono un dettaglio immesso
|
|
wrk_string.add(FLAG_DETT);
|
|
wrk_string.add(cod_dett_succ);
|
|
wrk_string.add("0");
|
|
wrk_string.add("0");
|
|
}
|
|
else
|
|
{
|
|
// sono un movimento
|
|
TString nrig(key.get(3));
|
|
nrig.format("%d",atoi(nrig)+1);
|
|
wrk_string.add(FLAG_MOVIMENTO);
|
|
wrk_string.add(cod_dett);
|
|
wrk_string.add(key.get(2));
|
|
wrk_string.add(nrig);
|
|
}
|
|
if (!is_key(wrk_string))
|
|
wrk_string.cut(0);
|
|
return wrk_string;
|
|
}
|
|
|
|
|
|
/* ********************************************************************************************************* */
|
|
/* TRicezione_AS400 */
|
|
/*********************************************************************************************************** */
|
|
|
|
// prepara l'albero di record per la navigazione e lo naviga
|
|
void TRicezione_AS400::naviga_array(TAlbero_record &a)
|
|
{
|
|
int curr_id=1;
|
|
TString_array allkeys;
|
|
a.get_keys(allkeys);
|
|
allkeys.sort();
|
|
TToken_string radice,*next_key;
|
|
radice=(TToken_string &)*allkeys.first_item();// radice
|
|
next_key=(TToken_string *)allkeys.succ_item();// chiave seguente (figlio? fratello?)
|
|
|
|
a.dept_first(radice, NULL,NULL, curr_id,allkeys,&next_key);
|
|
}
|
|
|
|
void TRicezione_AS400::scrivi_array(TAssoc_array &s_rec, int logic_num)
|
|
{
|
|
|
|
TRectype *rec; //Creo un tipo di record dove inserire il record
|
|
int i=s_rec.items();
|
|
TRelation *rel=_trasfile->t_rec(logic_num)->relation();
|
|
|
|
rec=(TRectype*)s_rec.first_item(); //Metto il primo record dell'assoc_array in un tipo_record
|
|
for (i=0; i < s_rec.items(); i++)
|
|
{
|
|
rel->curr()=*rec; //Metto sul record corrente della relazione il record letto
|
|
int err = rel->rewrite(); //Scrivo sulla relazione
|
|
//non dovrebbe mai succedere
|
|
if (err != NOERR)
|
|
{
|
|
message_box("Si è verificato un errore nella costruzione dell'albero");
|
|
err = rel->write();
|
|
}
|
|
rec=(TRectype*)s_rec.succ_item();
|
|
}
|
|
}
|
|
|
|
void TRicezione_AS400::leggi_temp_link(TRectype& cur_rec,TToken_string& k)
|
|
{
|
|
TString campo1 = cur_rec.get(ABMD_IDPADRE);
|
|
TString campo2 = cur_rec.get(ABMD_IDFIGLIO);
|
|
|
|
k.add(campo1.left(1));
|
|
campo1=campo1.ltrim(1);
|
|
campo2.right_just(5,'0');
|
|
campo1 = campo1 << campo2;
|
|
k.add(campo1);
|
|
k.add(atol(cur_rec.get(ABMD_IDSUCC)));
|
|
k.add(atol(cur_rec.get(ABMD_IDPREC)));
|
|
}
|
|
|
|
|
|
void TRicezione_AS400::build_balancetree(int logic_num)
|
|
{
|
|
TAlbero_record seleziona_record; //Dichiarazione di un assoc_array
|
|
TRelation rel(logic_num); //Creo un nuova relazione
|
|
TRectype prev_rec(logic_num); //Creo un tipo di record temporaneo dove inserire il record precedente
|
|
TRectype& cur_rec =rel.lfile().curr(); //Creo un tipo di record dove inserire il record attuale
|
|
|
|
for (int err = rel.first(); err == NOERR; err = rel.next())
|
|
{
|
|
if (cur_rec.compare_key(prev_rec,1,1) != 0) //Confronto la chiave precedente con quella appena letta escludendo
|
|
//l'ultimo campo della chiave
|
|
{//La chiave è diversa, quindi l'assoc array è completo
|
|
|
|
if (seleziona_record.items() > 0)
|
|
{
|
|
naviga_array(seleziona_record); //Aggiorno gli indici
|
|
scrivi_array(seleziona_record,logic_num); //e riscrivo tutto sul file isam
|
|
}
|
|
seleziona_record.destroy(); //Vuoto completamente l'array
|
|
prev_rec = cur_rec; //Aggiorno il record precedente
|
|
}
|
|
//Se arriva qui, significa che ho trovato una chiave uguale e deve essere inserita nell'array
|
|
|
|
//Questa parte ricostruisce la chiave originaria
|
|
TToken_string k; //Chiave dell'assoc_array
|
|
|
|
leggi_temp_link(cur_rec,k);
|
|
//La chiave è stata ricostruita
|
|
|
|
cur_rec.put(ABMD_IDPADRE,0); //Azzero i campi da riscrivere
|
|
cur_rec.put(ABMD_IDFIGLIO,0);
|
|
cur_rec.put(ABMD_IDSUCC,0);
|
|
cur_rec.put(ABMD_IDPREC,0);
|
|
|
|
//Aggiorno l'assoc_array con la chiave corretta
|
|
seleziona_record.add(k,cur_rec);
|
|
}
|
|
if (seleziona_record.items() > 0)
|
|
{
|
|
//Queste due servono per l'ultima tipo di chiave letta
|
|
naviga_array(seleziona_record);
|
|
scrivi_array(seleziona_record,logic_num);
|
|
}
|
|
}
|
|
|
|
void TRicezione_AS400::build_relana(TString& config_file, const TMask &msk, const TFilename& percorso)
|
|
{
|
|
TString16 curr_ana;
|
|
TToken_string key;
|
|
TLocalisamfile radici(LF_RELVOCI);
|
|
TRelation rel(LF_RELANA);
|
|
TAssoc_array tabtree;
|
|
TRecord_text rec; //Creo un record text
|
|
TFile_text *ft=NULL; //Dichiaro un nuovo file_text
|
|
rel.add(LF_COLLDICH,"ID=IDCOLDICH");
|
|
rel.add(LF_CARADD,"ID=IDCARADD");
|
|
|
|
//ft = set_config_name(config_file,msk,percorso);
|
|
ft = trans_file();
|
|
// ft->close(); //Chiudo il file
|
|
ft->open('r'); //Apro il file di testo in lettura
|
|
|
|
//Inizia il ciclo sulle Analisi in radici
|
|
if (radici.first() != NOERR) //Mi posiziono sul primo record di LF_RELVOCI
|
|
return; //e controllo che i dati siano "corretti"
|
|
CHECK(radici.get(ABRL_TIPOCOD)==FLAG_ANALISI, "Ci sono voci ma non tabelle ???");
|
|
|
|
TAdditional_cars * ca=new TAdditional_cars(_excllock);
|
|
rel.replacef(ca,LF_CARADD);
|
|
TAdditional_cols * co=new TAdditional_cols();
|
|
rel.replacef(co,LF_COLLDICH);
|
|
|
|
//Posiziona la lettura sul file di testo
|
|
do
|
|
{
|
|
ft->read(rec);
|
|
} while (rec.type() != TIPO_SRELAZ);
|
|
//Aggiorno il tipo di analisi corrente
|
|
curr_ana = radici.get(ABRL_CODVC);
|
|
do
|
|
{
|
|
tabtree.destroy(); //Azzero l'assoc_array
|
|
long currid=1;
|
|
|
|
|
|
// Questa parte stampa in un file di testo la struttura ad albro
|
|
// dell'analisi: da usare solo in fase di debug
|
|
// ***************
|
|
// ***************
|
|
/* int level=0;
|
|
FILE * stream=fopen("\\st1.txt","w");
|
|
|
|
print_ana_tree(level,radici.curr(),stream);
|
|
fclose(stream); */
|
|
// ***************
|
|
// ***************
|
|
|
|
build_ana_tree(currid,radici.curr(),NULL,NULL,tabtree); // costruisce l'albero in memoria
|
|
|
|
// legge dal file di testo e completa i record in tabtree
|
|
do
|
|
{
|
|
// chiave per l'assoc array
|
|
key.cut(0);
|
|
key.add(FLAG_VOCI);
|
|
key.add(rec.get(CODVC_SOTTOREL));
|
|
|
|
real k1(rec.get(NCOMP_SOTTOREL));
|
|
key.add(k1.string());
|
|
|
|
real k2(rec.get(NSREL_SOTTOREL));
|
|
key.add(k2.string());
|
|
// rintraccia il record sull'assoc array
|
|
rel.lfile().curr() = (TRectype & )tabtree[key];
|
|
//Aggiorno il TIPOCOD: non può essere fatto in PRE_WRITE perchè può assumere valori diversi
|
|
rel.lfile().put(ABRA_TIPOCOD,FLAG_VOCI);
|
|
// modifica e scarica il record
|
|
|
|
|
|
// TRectype prova(LF_COLLDICH);
|
|
// prova= rel.lfile(LF_COLLDICH).curr();
|
|
ft->autosave(rel,rec); //La relazione principale è basata su RELANA
|
|
tabtree.remove(key);
|
|
} while ((ft->read(rec) == NOERR) && (rec.type() == TIPO_SRELAZ));
|
|
|
|
//A questo punto ho scritto sull'isamfile tutte le voci: ora devo
|
|
//scrivere le analisi
|
|
tabtree.restart();
|
|
for (int i=tabtree.items(); i > 0 ; i--)
|
|
{
|
|
THash_object *obj;
|
|
obj=tabtree.get_hashobj(); //Ritorna il primo elemento dell'assoc_array completo di chiave
|
|
TToken_string key = obj->key(); //Estraggo la chiave dell'oggetto estratto dall'assoc_array
|
|
rel.lfile().write((TRectype&)obj->obj()); //Aggiorno il file isam
|
|
tabtree.remove(key); //Tolgo il record dall'assoc_array
|
|
}
|
|
|
|
// passa alla prossima Analisi
|
|
while (radici.next() == NOERR && curr_ana == radici.get(ABRL_CODVC));
|
|
//Aggiorno il tipo di analisi corrente
|
|
curr_ana = radici.get(ABRL_CODVC);
|
|
//Riposiziono la lettura sul testo
|
|
do
|
|
{
|
|
ft->read(rec);
|
|
} while ((rec.type() != TIPO_SRELAZ) && (rec.get(CODVC_VOCI) == curr_ana.sright(2))); //Formatto la chiave
|
|
} while (radici.get(ABRL_TIPOCOD)=="A");
|
|
}
|
|
|
|
|
|
// naviga per ricostruire il numero di sottorelazione
|
|
void TRicezione_AS400::build_ana_tree(long &currid, TRectype & nodo, TRectype * father, TRectype * brother, TAssoc_array & tabtree)
|
|
{
|
|
TRectype *ana_node;
|
|
TToken_string key;
|
|
|
|
// calcola il numero di sottorelazione
|
|
int c=1;
|
|
do {
|
|
key.cut(0); //Vuota la chiave
|
|
key.add(nodo.get(ABRL_TIPOCOD));
|
|
key.add(nodo.get(ABRL_CODVC));
|
|
key.add(nodo.get(ABRL_IDCOMP));
|
|
key.add(c);
|
|
c++;
|
|
} while (tabtree.objptr(key)!=NULL);
|
|
|
|
ana_node = new TRectype(LF_RELANA);
|
|
//ana_node->zero(' '); //Solo per vederlo a livello di debug
|
|
// setta il nodo
|
|
if (father == NULL)
|
|
{//Sono la radice principale e leggo i dati già inseriti con la vecchia chiave
|
|
TLocalisamfile rela(LF_RELANA);
|
|
|
|
TString codan = key.get(1); //Questa chiave letta da LF_RELVOCI è in realtà lunga 10 caratteri
|
|
rela.put(ABRA_CODAN,codan.sright(2)); //mentre quella di LF_RELANA è lunga solo 2 (i due caratteri più a destra)
|
|
TString16 old_id = key.get();
|
|
rela.put(ABRA_ID,atol(old_id));
|
|
if (rela.read() == NOERR) //Leggo i dati inseriti precedentemente
|
|
{
|
|
*ana_node=rela.curr();
|
|
rela.remove(); //E li elimino dal file_isam per aggiornare la chiave
|
|
}
|
|
else
|
|
CHECK (FALSE,"Errore di consistenza nei dati");
|
|
}
|
|
//Aggiorno la chiave
|
|
ana_node->put(ABRA_ID, currid);
|
|
ana_node->put(ABRA_IDPADRE, father ? father->get(ABRA_ID) : ID_NULLO);
|
|
ana_node->put(ABRA_IDPREC, brother ? brother->get(ABRA_ID) : ID_NULLO);
|
|
tabtree.add(key,ana_node);
|
|
|
|
// passa al figlio leggendo su RELVOCI se esso esiste
|
|
TLocalisamfile relvoci(LF_RELVOCI);
|
|
relvoci.put(ABRL_TIPOCOD,'V'); //Deve essere una voce
|
|
relvoci.put(ABRL_CODVC,nodo.get(ABRL_CODCOMP));//Prendo il codice del mio figlio
|
|
relvoci.put(ABRL_IDCOMP,1); //Prendo la prima componente
|
|
if (relvoci.read()==NOERR)
|
|
{
|
|
currid++;
|
|
ana_node->put(ABRA_IDFIGLIO, currid);
|
|
build_ana_tree(currid,relvoci.curr(),ana_node,NULL,tabtree); //Richiamo questa funzione
|
|
}
|
|
else
|
|
ana_node->put(ABRA_IDFIGLIO, ID_NULLO);
|
|
|
|
// passa al fratello
|
|
relvoci.curr().zero();
|
|
relvoci.put(ABRL_TIPOCOD,nodo.get(ABRL_TIPOCOD));
|
|
relvoci.put(ABRL_CODVC,nodo.get(ABRL_CODVC));
|
|
relvoci.put(ABRL_IDCOMP,nodo.get_int(ABRL_IDCOMP)+1);
|
|
|
|
if (relvoci.read()==NOERR)
|
|
{
|
|
currid++;
|
|
ana_node->put(ABRA_IDSUCC, currid);
|
|
build_ana_tree(currid,relvoci.curr(),father,ana_node,tabtree);
|
|
}
|
|
else
|
|
ana_node->put(ABRA_IDSUCC, ID_NULLO);
|
|
}
|
|
|
|
/*
|
|
// Questa funzione serve solo in fase di debug:
|
|
// naviga per ricostruire il numero di sottorelazione
|
|
void TRicezione_AS400::print_ana_tree(int &level,TRectype & nodo,FILE * stream)
|
|
{
|
|
TToken_string key;
|
|
|
|
TString codvoce;
|
|
codvoce.fill(' ',3*level);
|
|
codvoce << nodo.get(ABRL_CODCOMP);
|
|
fprintf(stream,"%s\n",(const char *) codvoce);
|
|
// calcola il numero di sottorelazione
|
|
// passa al figlio leggendo su RELVOCI se esso esiste
|
|
TLocalisamfile relvoci(LF_RELVOCI);
|
|
relvoci.put(ABRL_TIPOCOD,'V'); //Deve essere una voce
|
|
relvoci.put(ABRL_CODVC,nodo.get(ABRL_CODCOMP));//Prendo il codice del mio figlio
|
|
relvoci.put(ABRL_IDCOMP,1); //Prendo la prima componente
|
|
if (relvoci.read()==NOERR)
|
|
{
|
|
level ++;
|
|
print_ana_tree(level,relvoci.curr(),stream); //Richiamo questa funzione
|
|
level --;
|
|
}
|
|
// passa al fratello
|
|
relvoci.curr().zero();
|
|
relvoci.put(ABRL_TIPOCOD,nodo.get(ABRL_TIPOCOD));
|
|
relvoci.put(ABRL_CODVC,nodo.get(ABRL_CODVC));
|
|
relvoci.put(ABRL_IDCOMP,nodo.get_int(ABRL_IDCOMP)+1);
|
|
|
|
if (relvoci.read()==NOERR)
|
|
{
|
|
// && relvoci.get(RELVOCI_CODANA)==curr_ana
|
|
print_ana_tree(level,relvoci.curr(),stream);
|
|
}
|
|
}
|
|
*/
|
|
|
|
void TRicezione_AS400::ricevi(TMask & msk)
|
|
{
|
|
trasfile()->set_tipo_bilancio(msk.get(F_TIPO_BILANCIO));
|
|
// Eseguo la ricezione normale
|
|
TObject_reception::ricevi(msk);
|
|
|
|
// E aggiungo il resto ...
|
|
if (msk.get_bool(F_MOVIMENTI))
|
|
{
|
|
build_balancetree(LF_MOVDETT);
|
|
}
|
|
|
|
if (msk.get_bool(F_SRELAZ))
|
|
{
|
|
TString config_file;
|
|
TFilename percorso;
|
|
percorso=msk.get(F_PERCORSO); //Leggo il contenuto di F_PERCORSO: è stato controllato prima
|
|
build_relana(config_file,msk,percorso);
|
|
}
|
|
//La chiusura del _trasfile non può essere eseguita prima poichè questo
|
|
//serve nella costruzione dell'albero dei movimenti
|
|
if (_trasfile != NULL)
|
|
{
|
|
_trasfile->close();
|
|
delete _trasfile;
|
|
_trasfile =NULL;
|
|
}
|
|
}
|
|
|
|
TObject_reception::TObject_reception(const TFilename &percorso)
|
|
{
|
|
if (_trasfile != NULL)
|
|
delete _trasfile;
|
|
_trasfile = new TFile_text(percorso, "C:/SAURO/TEMP/AB2100B.INI"); /*DA CAMBIARE*/
|
|
_trasfile->open('r'); //apro il TFile_text in lettura
|
|
//_trasfile = new TFile_text(percorso, config); //Leggo il file di configurazione
|
|
}
|
|
|
|
TRicezione_AS400::TRicezione_AS400(const TFilename &percorso)
|
|
{
|
|
|
|
if (_trasfile != NULL)
|
|
delete _trasfile;
|
|
TString config("ab2100a.ini");
|
|
_trasfile = new TFile_text_AS400(percorso, config); //Leggo il file di configurazione
|
|
_trasfile->open('r'); //apro il TFile_text in lettura
|
|
}
|
|
|
|
TRicezione_userdef ::TRicezione_userdef(const TString & config, const TFilename &percorso)
|
|
{
|
|
if (_trasfile != NULL)
|
|
delete _trasfile;
|
|
_trasfile = new TFile_text(percorso, config); //Leggo il file di configurazione
|
|
_trasfile->open('r'); //apro il TFile_text in lettura
|
|
}
|
|
|
|
|
|
|
|
|
|
int ab2101(int argc, char **argv)
|
|
{
|
|
TRicezione a;
|
|
a.run(argc,argv,"Ricezione da file di testo");
|
|
return 0;
|
|
} |