//AB2102.CPP Trasferimento tabelle #include //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 "relana.h" //Contiene le definizioni di costanti relative ai nomi dei campi di LF_RELANA #include "ab2100.h" #include "ab2100a.h" #include #include #include #define FLAG_COGE "CG" #define FLAG_DETT "DT" #define FLAG_CLIENTE "CL" #define FLAG_FORNITORE "FO" #define FLAG_MOVIMENTO "MO" // così i movs sono alla fine //Classe derivata per il trasferimento class TTrasferimento:public TRiceTras { public: virtual bool menu(MENU_TAG); static bool inseriscipercorso(TMask_field& f, KEY k); //Esegue il ciclo di ricezione void converti(int); void trasferisci_albero(TRectype &,TRecord_text&, TAssoc_array&); bool cerca_padre(TLocalisamfile &, TRectype &); long my_num(TLocalisamfile&, TAssoc_array&); bool mov_da_scrivere(TRectype &); void formatta(TRecord_text&,TRectype&,int&); TTrasferimento() {} virtual ~TTrasferimento() {} }; const char* get_ordinamento(TVariable_rectype & rec) { if (rec.get(ABMD_TIPODETT) == FLAG_DETT || rec.get(ABMD_TIPODETT) == FLAG_COGE ) { //E' un record di MOVI3 return (MOVIMENTO3); } if (rec.get(ABMD_TIPODETT) == FLAG_CLIENTE) {//E' un record di MOVI4 return (MOVIMENTO4); } if (rec.get(ABMD_TIPODETT) == FLAG_FORNITORE) {//E' un record di MOVI5 return (MOVIMENTO5); } if (rec.get(ABMD_TIPODETT) == FLAG_MOVIMENTO) {//Può essere MOVI 1 2 real r(rec.get(ABMD_IMPORTO)); if (r > 0) //Se è un saldo il record va in MOVI1 return (MOVIMENTO1); //Se è un progressivo o una riclassificazione va in MOVI2 return (MOVIMENTO2); } //A questo punto la funzione non dovrebbe mai arrivare CHECK (FALSE,"La funzione get_ordinamento ritorna un valore non valido"); return NULL; } bool TTrasferimento::cerca_padre(TLocalisamfile & padre, TRectype &node) { padre.put(ABMD_CODDITTA,node.get(ABMD_CODDITTA)); padre.put(ABMD_ANNO,node.get(ABMD_ANNO)); padre.put(ABMD_CODPDB,node.get(ABMD_CODPDB)); padre.put(ABMD_TIPOBIL,node.get(ABMD_TIPOBIL)); padre.put(ABMD_CODCBL,node.get(ABMD_CODCBL)); padre.put(ABMD_ID,node.get(ABMD_IDPADRE)); if (padre.read() == NOERR) return TRUE; return FALSE; } long TTrasferimento::my_num(TLocalisamfile& mov, TAssoc_array& progressivi) { long ret = 1; TToken_string my_key; my_key.add(mov.get(ABMD_CODDITTA)); my_key.add(mov.get(ABMD_ANNO)); my_key.add(mov.get(ABMD_CODPDB)); my_key.add(mov.get(ABMD_TIPOBIL)); my_key.add(mov.get(ABMD_CODCBL)); my_key.add(mov.get(ABMD_ID)); if (progressivi.is_key(my_key)) { ret = atol(*(TString*)progressivi.objptr(my_key)); } else { long id_prec =mov.get_long(ABMD_IDPREC); // if (id_prec != ID_NULLO) // Se il padre di un movimento è nullo significa che è un movimento di un saldo // { mov.put(ABMD_ID,id_prec); if (mov.read()== NOERR) { ret=my_num(mov,progressivi)+1; } // else // CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!"); //} TString16 str_ret; str_ret << ret; progressivi.add(my_key,str_ret); } return ret; } void TTrasferimento::trasferisci_albero(TRectype &node, TRecord_text &rec, TAssoc_array &progressivi) { TLocalisamfile mov(LF_MOVDETT); //Se è un COGE scrivo il CODICE_COGE nel relativo campo if (node.get(ABMD_TIPODETT) == FLAG_COGE) rec.add(node.get(ABMD_CODDETT),CONTO_COGE_MOVDETT); //Se è un movimento ... if (node.get(ABMD_TIPODETT)== FLAG_MOVIMENTO) { //... sono all'ultimo livello: trovo il padre if (cerca_padre(mov,node)) {//Questo è il padre del movimento if (mov.get(ABMD_TIPODETT) == FLAG_COGE) //Se il padre è un COGE scrivo il CONTO COGE nel relativo campo rec.add(node.get(ABMD_CODDETT),CONTO_COGE_MOVDETT); //altrimenti, se il padre è un dettaglio, non scrivo nessuna informazione aggiuntiva } // Se il padre del movimento non esiste, allora è un movimento di un saldo // else // {//Non dovrebbe mai succedere: non esiste il padre del movimento // CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!"); // } //Questa parte esegue la "numerazione progressiva" dei movimenti: assegna il numero di riga TString16 num_riga; mov.curr()=node; num_riga << my_num(mov,progressivi); rec.add(num_riga,NUMERO_RIGA_MOVDETT); //Trovo il padre se esiste long id_padre = atol(node.get(ABMD_IDPADRE)); real r(node.get(ABMD_CODDETT)); if ((id_padre != ID_NULLO) && (r == 0)) //Se esiste il padre e non sono un COGE devo assegnarmi //nel campo PROGRESSIVO_DETT il numero progressivo del padre {//Leggo il padre mov.curr()=node; mov.put(ABMD_ID,id_padre); if (mov.read()==NOERR) { TString16 num_prog; num_prog << my_num(mov,progressivi); rec.add(num_prog,PROGRESSIVO_DETT_MOVDETT); //Questo è un record di tipo MOVIMENTI } else CHECK (FALSE,"Si è verificata una inconsistenza nei dati: è stato trovato un movimento senza il padre!"); } }//Fine parte "ricostruzione" albero dei movimenti //Questa parte "ricostruisce" l'albero dei dettaglio if (node.get(ABMD_TIPODETT)== FLAG_DETT) { mov.curr()=node; TString16 num; num << my_num(mov,progressivi); rec.add(num,PROGRESSIVO_DETT_MOVDETT); //Questo è un record di tipo DETTAGLI } } bool TTrasferimento::mov_da_scrivere(TRectype &node) { TLocalisamfile dett(LF_MOVDETT); if (node.get_long(ABMD_IDPADRE) == ID_NULLO) //Sono al primo livello return TRUE; if (cerca_padre(dett,node)) { if (dett.get_long(ABMD_IDPADRE) == ID_NULLO) //Sono al secondo livello return TRUE; else { if (dett.get(ABMD_TIPODETT) == FLAG_COGE) //Sono al terzo livello, ma ammetto solo i COGE return TRUE; } } return FALSE; //Tutti i livelli superiori a 2 e tutti i casi che non riesco a gestire } void TTrasferimento::formatta(TRecord_text &rec, TRectype &node, int &logic_num) { if (logic_num == LF_MOVDETT) { if ((rec.type() == MOVIMENTO1) || (rec.type() == MOVIMENTO2)) {//Se c'è un valore significativo in IMPORTO significa che questo valore va //inserito nel campo IMPORTO del file di testo e settato il flag D/A //Il tipo record (già settato) è MOVI1 real r(node.get(ABMD_IMPORTO)); if (r > 0) { TString imp = node.get(ABMD_IMPORTO); rec.add(node.get(ABMD_FLDA),FLAG_DA_MOVDETT); rec.add(imp.rtrim(4),IMPORTO_MOVDETT); } else {//Questi valori vanno inseriti in IMPORTO di MOVI2 real rpd(node.get(ABMD_PDARE)); real rpa(node.get(ABMD_PAVERE)); real rrd(node.get(ABMD_RDARE)); real rra(node.get(ABMD_RAVERE)); if (rpd > 0) { TString imp =node.get(ABMD_PDARE); rec.add("D",FLAG_DA_MOVDETT); rec.add(imp.rtrim(4),IMPORTO_MOVDETT); } if (rpa > 0) { TString imp = node.get(ABMD_PAVERE); rec.add("A",FLAG_DA_MOVDETT); rec.add(imp.rtrim(4),IMPORTO_MOVDETT); } if (rrd > 0) { TString imp = node.get(ABMD_RDARE); rec.add("X",FLAG_RICLASSIFICAZIONE_MOVDETT); rec.add("D",FLAG_DA_MOVDETT); rec.add(imp.rtrim(4),IMPORTO_MOVDETT); } if (rra > 0) { TString imp = node.get(ABMD_RAVERE); rec.add("X",FLAG_RICLASSIFICAZIONE_MOVDETT); rec.add("A",FLAG_DA_MOVDETT); rec.add(imp.rtrim(4),IMPORTO_MOVDETT); } } } else {//Questi sono gli importi dei dettagli TString sld = rec.row(SALDO_INIZIO_ANNO_MOVDETT); rec.add(sld.rtrim(4),SALDO_INIZIO_ANNO_MOVDETT); TString pda = rec.row(PROGRESSIVO_DARE_MOVDETT); rec.add(pda.rtrim(4),PROGRESSIVO_DARE_MOVDETT); TString pav = rec.row(PROGRESSIVO_AVERE_MOVDETT); rec.add(pav.rtrim(4),PROGRESSIVO_AVERE_MOVDETT); TString rda = rec.row(RICLASSIFICAZIONE_DARE_MOVDETT); rec.add(rda.rtrim(4),RICLASSIFICAZIONE_DARE_MOVDETT); TString rav = rec.row(RICLASSIFICAZIONE_AVERE_MOVDETT); rec.add(rav.rtrim(4),RICLASSIFICAZIONE_AVERE_MOVDETT); } }// end if LF_MOVDETT if (logic_num == LF_ABSALDI) { TString sld = rec.row(SALDO_INIZIO_ANNO_SLD_MOVDETT); rec.add(sld.rtrim(4),SALDO_INIZIO_ANNO_SLD_MOVDETT); TString pda = rec.row(PROGRESSIVO_DARE_SLD_MOVDETT); rec.add(pda.rtrim(4),PROGRESSIVO_DARE_SLD_MOVDETT); TString pav = rec.row(PROGRESSIVO_AVERE_SLD_MOVDETT); rec.add(pav.rtrim(4),PROGRESSIVO_AVERE_SLD_MOVDETT); TString rda = rec.row(RICLASSIFICAZIONE_DARE_SLD_MOVDETT); rec.add(rda.rtrim(4),RICLASSIFICAZIONE_DARE_SLD_MOVDETT); TString rav = rec.row(RICLASSIFICAZIONE_AVERE_SLD_MOVDETT); rec.add(rav.rtrim(4),RICLASSIFICAZIONE_AVERE_SLD_MOVDETT); }// end if LF_ABSALDI if (logic_num == LF_TABCOM && rec.type() == TIPO_TABELLA_PERIODI) { rec.add(SIGLA_TABELLA_PERIODI,SIGLA_TAB_PER); } } void TTrasferimento::converti(int logic_num) { TRelation *tr_relation=_trasfile->t_rec(logic_num)->relation(); TRecord_text rec(_trasfile->t_rec(logic_num)->type()); //Istanzio un tipo record_text TCursor *cur=NULL; TAssoc_array progressivi; if (logic_num == LF_MOVDETT) { TVariable_rectype *vrec_rmov= new TVariable_rectype(LF_MOVDETT); vrec_rmov->add_field(new TVariable_field (ABMD_TIPO_TRACCIATO,get_ordinamento,5)); //Costruisco la chiave del TSorted_cursor TToken_string exp(ABMD_TIPO_TRACCIATO); exp.add(ABMD_CODDITTA); exp.add(ABMD_ANNO); exp.add(ABMD_CODPDB); exp.add(ABMD_TIPOBIL); exp.add(ABMD_CODCBL); exp.add(ABMD_ID); cur = new TSorted_cursor(tr_relation,exp); cur->file().set_curr(vrec_rmov); } else cur = new TCursor(tr_relation); //Leggo il numero di records da convertire long items =cur->items(); //Barra scorrevole di attesa TProgind idle(items,"Attendere: conversione in corso ...",TRUE,TRUE,60); //Ciclo principale di conversione for (*cur=0;cur->pos()lfile().get(ABMD_TIPO_TRACCIATO)); _trasfile->autoload(rec,*cur,&rec.type()); if (mov_da_scrivere(tr_relation->lfile().curr())) { trasferisci_albero(tr_relation->lfile().curr(),rec,progressivi); formatta(rec,tr_relation->lfile().curr(),logic_num); _trasfile->write(rec); } } else {//in tutti gli altri casi la conversione è semplice _trasfile->autoload(rec,logic_num); if (logic_num == LF_ABSALDI || logic_num == LF_TABCOM) formatta(rec,tr_relation->lfile().curr(),logic_num); _trasfile->write(rec); } } delete cur; } //Handler per l'inserimento del percorso completo bool TTrasferimento::inseriscipercorso(TMask_field& f, KEY k) { TString percorso; percorso=f.get(); //Leggo il contenuto del campo return TRUE; } //Funzione membro che esegue la conversione di trasferimento bool TTrasferimento::menu(MENU_TAG) { 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.hide(F_TIPO_BILANCIO); //nascondo questo campo poichè non mi serve msk.hide(F_TESTO_TIPOBIL); //nascondo questo campo poichè non mi serve msk.hide(F_VOCI); //nascondo questo campo poichè non mi serve msk.hide(F_RELAZ); //nascondo questo campo poichè non mi serve msk.hide(F_SRELAZ); //nascondo questo campo poichè non mi serve //A questo punto il percorso e' corretto if (msk.run()== K_ENTER) //Eseguo la maschera { percorso=msk.get(F_PERCORSO); //Leggo il contenuto di F_PERCORSO set_config_name(config_file,msk, percorso); _trasfile = new TABfile_text(percorso, config_file); //Leggo il file di configurazione _trasfile->open(percorso,'w'); //Apro il file di testo in rettura if (msk.get_bool(F_PIANO_CONTI)==TRUE) //Controllo se si è scelto di convertire il piano dei conti { converti(LF_ABPCON); //Conversione } if (msk.get_bool(F_PERIODI_BILANCI)==TRUE) //Scelta di convertire la tabella periodi bilanci { converti(LF_TABCOM); } if (msk.get_bool(F_ANALISI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio { converti(LF_ANALISI); } if (msk.get_bool(F_MOVIMENTI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio { converti(LF_MOVDETT); } if (msk.get_bool(F_SALDI)==TRUE) //scelta di cnverite la tabella tipi analisi di bilancio { converti(LF_ABSALDI); } _trasfile->close(); delete _trasfile; //messaggio finale message_box(" ... aggiornamento delle tabelle effettuato"); } //end if (msk.run()) return FALSE; } int ab2102(int argc, char **argv) { TTrasferimento a; a.run(argc,argv,"Trasferimento su file di testo"); return 0; }