#include #include #include #include #include #include #include #include #include #include #include #include #include #include "../cg/cg2101.h" #include "calib01.h" #include "../ve/velib04.h" #include "fasi.h" #include "movana.h" #include "rmovana.h" #include "rip.h" #include "rrip.h" #include "cacnva.h" #define usage "Errore - uso : cacnv [0|1]" //-------------------------------------------------------------- // IMPORTO DESCRITTO (utilizzato nella conversione movimenti) //-------------------------------------------------------------- class TImporto_descritto : public TImporto { TString _descr; public: const TString& descrizione() const {return _descr;} TImporto_descritto(const char* descr) : _descr(descr) {} }; //---------------------------------------------------------- // MASCHERA COVERSIONE //---------------------------------------------------------- class TConversione_anal_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TConversione_anal_msk() : TAutomask("cacnva") {} }; bool TConversione_anal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DATAINI: if (e == fe_init) { const TDate data_att = ca_config().get("DtAttCa"); if (data_att.ok()) o.set(data_att.string()); } if (e == fe_modify || e == fe_close) { //controllo sulla data attivazione Contabilita' analitica nel file di configurazione const TDate data_att = ca_config().get("DtAttCa"); if (data_att.ok()) { const TDate& dataini = get_date(F_DATAINI); if (dataini < data_att) return error_box(TR("La data inizio non puo' essere antecedente la data di attivazione")); } } break; case F_TIPOCONV: if (e == fe_modify) { const TDate data_att = ca_config().get("DtAttCa"); set(F_DATAINI, data_att); } break; default: break; } return true; } //---------------------------------------------------------- // APPLICAZIONE //---------------------------------------------------------- class TConversione_cm2ca : public TSkeleton_application { virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM TCache_ripartizioni _cache_rip; protected: virtual void main_loop(); void create_new_movana(long numreg_cg, bool definitiva, TAssoc_array& cg_lines_to_anal); bool test_configuration(); void ripartisci(TRectype& recpcon); void check_phase(const TRectype& analriga); public: bool convert_clerks(); bool convert_phases(); bool set_anal(); bool convert_movs(TConversione_anal_msk& mask); TConversione_cm2ca() {} ~TConversione_cm2ca() {} }; bool TConversione_cm2ca::test_configuration() { const TString& first_level = ca_config().get("Level(1)"); return first_level.not_empty(); } //gestione del menu (vari tipi di conversione) void TConversione_cm2ca::main_loop() { TConversione_anal_msk mask; while (mask.run() == K_ENTER) { if (mask.get_bool(F_TABELLE)) { if (set_anal()) //setta il flag anal nel pcon { convert_clerks(); //da tabella cms a commesse convert_phases(); //da tabella fsc a fasi } } if (mask.get_bool(F_MOVIMENTI)) { //controlla se compilata la configurazione della CA dul ditta.ini bool ok = test_configuration(); if (!ok) { if (yesno_box(TR("Per procedere alla conversione e' necessario avere configurato\nla Contabilita' Analitica\nSi desidera procedere alla configurazione?"))) { TExternal_app app("ca0 -2"); app.run(); ok = test_configuration(); } } //solo se e' stata fatta la configurazione minima e' possibile procedere alla conversione if (ok) convert_movs(mask); //converte i movimenti di contabilita' (da CG a CA) } //end get_bool(F_MOVIMENTI) } //end while } //------------------------------------------------- // ** TRASFERIMENTO DATI COMMESSE/FASI ** //------------------------------------------------- //------------------------------------------------------------------------------------------------ // trasferisce i dati dalle tabelle Commesse e Fasi ai nuovi file di analitica (COMMESSE e FASI) //------------------------------------------------------------------------------------------------ bool TConversione_cm2ca::convert_clerks() { TLocalisamfile commesse(LF_COMMESSE); //la conversione blocca in automatico gli altri utenti //non e' necessario un TSystemisamfile con _excllock const long items = commesse.items(); //trasferimento dati possibile solo se il file di destinazione e' vuoto if (items > 0) { if (yesno_box(TR("File delle commesse non vuoto!\nSi desidera azzerarlo?"))) if (yesno_box(TR("File delle commesse non vuoto!\nSi desidera veramente azzerarlo?"))) { TSystemisamfile cms(LF_COMMESSE); //sono zappabili solo i Systemisamfiles cms.zap(); } else return true; else return true; } TRelation relcms("CMS"); TCursor curcms(&relcms); const TRectype& cms = relcms.curr(); const long nrectab = curcms.items(); curcms.freeze(); TRectype& commesse_rec = commesse.curr(); TProgind pi(nrectab, "Conversione tabella commesse"); for (curcms = 0; curcms.pos() < nrectab; ++curcms) { pi.addstatus(1); commesse_rec.zero(); //azzerare il record prima di cominciare... commesse_rec.put("CODCMS", cms.get("CODTAB")); commesse_rec.put("DESCRIZ", cms.get("S0")); commesse_rec.put("CODCF", cms.get("I0")); commesse_rec.put("REGIVA", cms.get("S7")); commesse_rec.put("PRORATA", cms.get("B4")); commesse_rec.put("PUBBLICA", cms.get("B0")); commesse_rec.put("RENDIC", cms.get("B1")); commesse_rec.put("DATAINIZIO", cms.get("D0")); commesse_rec.put("DATAFINE", cms.get("D1")); commesse_rec.put("CHIUSA", cms.get("B3")); commesse_rec.put("PROROGA", cms.get("B2")); commesse_rec.put("CODRESP", cms.get("S4")); commesse.write(); } return true; } bool TConversione_cm2ca::convert_phases() { //se sono gia' state configurate le fasi nel ditta.ini non procede oltre! //fara' la conversione delle fasi nel trasferimento dei movimenti const TString& fathfasi = ca_config().get( "FathFasi"); if (fathfasi.not_empty()) return false; TLocalisamfile fasi(LF_FASI); const long items = fasi.items(); if (items > 0) { if (yesno_box(TR("File delle fasi non vuoto!\nSi desidera azzerarlo?"))) if (yesno_box(TR("File delle fasi non vuoto!\nSi desidera veramente azzerarlo?"))) { TSystemisamfile fsc(LF_FASI); fsc.zap(); } else return true; else return true; } TRelation relfsc("FSC"); TCursor curfsc(&relfsc); const TRectype& fsc = relfsc.curr(); const long nrectab = curfsc.items(); curfsc.freeze(); TRectype& fasi_rec = fasi.curr(); TProgind pi(nrectab, "Conversione tabella fasi"); TRelation* relazione = NULL; TCursor* cursore = NULL; for (curfsc = 0; curfsc.pos() < nrectab; ++curfsc) { pi.addstatus(1); if (cursore == NULL) { fasi_rec.zero(); fasi_rec.put("CODFASE", fsc.get("CODTAB")); fasi_rec.put("DESCRIZ", fsc.get("S0")); fasi.write(); } } return true; } //------------------------------------------------------------------------------------------------ // mette il flag di ANALITICA nei gr.co.stc. aventi codcms e/o codfsc //------------------------------------------------------------------------------------------------ void TConversione_cm2ca::ripartisci(TRectype& recpcon) { const int gruppo = recpcon.get_int(PCN_GRUPPO); const int conto = recpcon.get_int(PCN_CONTO); const long sottoconto = recpcon.get_long(PCN_SOTTOCONTO); const TString80 codcms = recpcon.get(PCN_CODCMS); const TString16 fascms = recpcon.get(PCN_FASCMS); if (codcms.empty() && fascms.empty()) return; //cerca nel file rip se esiste gia' un record con la medesima chiave (chiave 3!!) TLocalisamfile rip_file(LF_RIP); rip_file.last(); rip_file.put(RIP_TIPO, "I"); rip_file.put(RIP_CODICE, "ZZZZZZZZ"); if (rip_file.read(_isgreat) == NOERR) rip_file.prev(); const long last_cod = atol(rip_file.get(RIP_CODICE)) + 1L; rip_file.setkey(3); rip_file.put(RIP_GRUPPO, gruppo); rip_file.put(RIP_CONTO, conto); rip_file.put(RIP_SOTTOCONTO, sottoconto); if (rip_file.read() != NOERR) { TAnal_rip rip; TString80 cod; cod.format("%08ld", last_cod); rip.head().put(RIP_TIPO, "I"); rip.put(RIP_CODICE, cod); rip.put(RIP_GRUPPO, gruppo); rip.put(RIP_CONTO, conto); rip.put(RIP_SOTTOCONTO, sottoconto); TRectype& rrip = rip.new_row(); rrip.put(RRIP_RIPARTO, 100); rrip.put(RRIP_CODCMS, codcms); rrip.put(RRIP_CODFASE, fascms); if (ca_config().get_bool("UsePdcc")) //solo se in CA si usa il piano dei conti contabile.. { TString80 codconto; codconto.format("%03d%03d%06ld", gruppo, conto, sottoconto); rrip.put(RRIP_CODCONTO, codconto); } rip.write(); //scrive sia rip che rrip con nuova chiave 1 (TIPO+CODICE) } } bool TConversione_cm2ca::set_anal() { TRelation relpcon(LF_PCON); TCursor curpcon(&relpcon); TRectype& recpcon = relpcon.curr(); if (!recpcon.exist(PCN_ANALITICA)) //check se gia' avvenuta la conversione con aggiunta del campo ANAL return error_box(TR("Prima del controllo e' necessario eseguire una conversione archivi")); else { const long nrecpcon = curpcon.items(); curpcon.freeze(); TProgind pi(nrecpcon, "Controllo commesse e fasi sul piano dei conti"); for (curpcon = 0; curpcon.pos() < nrecpcon; ++curpcon) { pi.addstatus(1); if (recpcon.get(PCN_CODCMS).not_empty() || recpcon.get(PCN_FASCMS).not_empty()) { recpcon.put(PCN_ANALITICA, "X"); relpcon.rewrite(); //deve creare una testata e una riga di ripartizione (se non esistono con lo stesso gr/co/sott) ripartisci(recpcon); } } return true; } } //---------------------------------------------------------- // ** CONVERSIONE MOVIMENTI CONTABILI ** //---------------------------------------------------------- //---------------------------------------------------------------------------------------------------- // trasferisce i movimenti e le righe relative (MOV,RMOV) nei nuovi file di analitica (MOVANA,RMOVANA) // --------------------------------------------------------------------------------------------------- void TConversione_cm2ca::check_phase(const TRectype& analriga) { const TString16 codfase = analriga.get(RMOVANA_CODFASE); if (codfase.blank()) return; const TString& fathfasi = ca_config().get("FathFasi"); if (fathfasi.blank()) return; TLocalisamfile file_fasi(LF_FASI); if (fathfasi == "CDC") file_fasi.put(FASI_CODCMSFAS, analriga.get(RMOVANA_CODCCOSTO)); else //se non e' "CDC", il FathFasi puo' essere solo "CMS" file_fasi.put(FASI_CODCMSFAS, analriga.get(RMOVANA_CODCMS)); file_fasi.put(FASI_CODFASE, codfase); const int err = file_fasi.read(); if (err != NOERR) { const TString& descrfase = cache().get("FSC", codfase, "S0"); file_fasi.put(FASI_DESCRIZ, descrfase); file_fasi.write(); } } void TConversione_cm2ca::create_new_movana(long numreg_cg, bool definitiva, TAssoc_array& cg_lines_to_anal) { TLocalisamfile f(LF_MOVANA); TAnal_mov analmov; //testata movimento analitico //riempie le righe di testata del movimento prima nota mov TMovimentoPN mov; TRectype& mov_head = mov.curr(); mov_head.put(MOV_NUMREG, numreg_cg); mov.read(); analmov.put(MOVANA_ANNOES, mov_head.get(MOV_ANNOES)); analmov.put(MOVANA_DATAREG, mov_head.get(MOV_DATAREG)); analmov.put(MOVANA_DATACOMP, mov_head.get(MOV_DATACOMP)); analmov.put(MOVANA_DATADOC, mov_head.get(MOV_DATADOC)); analmov.put(MOVANA_NUMREGCG, mov_head.get(MOV_NUMREG)); analmov.put(MOVANA_NUMDOC, mov_head.get(MOV_NUMDOC)); analmov.put(MOVANA_TIPODOC, mov_head.get(MOV_TIPODOC)); analmov.put(MOVANA_DESCR, mov_head.get(MOV_DESCR)); analmov.put(MOVANA_CODCAUS, mov_head.get(MOV_CODCAUS)); if (definitiva) analmov.put(MOVANA_TIPOMOV, " "); else analmov.put(MOVANA_TIPOMOV, "T"); //deve mettere "Temporaneo" (conversione NON definitiva) const char provv = mov_head.get_char(MOV_DPROVV); analmov.put(MOVANA_DPROVV, provv); const int danno = mov_head.get_int(MOV_DANNO); analmov.put(MOVANA_DANNO, danno); const TString4 dcodnum = mov_head.get(MOV_DCODNUM); analmov.put(MOVANA_DCODNUM, dcodnum); const long dndoc = mov_head.get_long(MOV_DNDOC); analmov.put(MOVANA_DNDOC, dndoc); //se la chiave del documento origine e' completa puo' completare tale documento riempiendo il.. //..campo NUMREGCA (con lo stesso numero di NUMREGCG, visto che sta trasportando i dati dalla.. //..CG alla CA if (provv != ' ' && danno > 0 && dcodnum.not_empty() && dndoc > 0) { TDocumento dadoc(provv, danno, dcodnum, dndoc); dadoc.put(DOC_NUMREGCA, numreg_cg); dadoc.write(); } //MOVANA_TOTDOC e' il totale di tutte le sue righe;ancora non si conosce;sara' compilato.. //..successivamente utilizzando importone //deve scorrere tutte le righe del movimento e sommare gli importi di quelle che hanno la.. //..stessa chiave CODCMS+CODFSC TAssoc_array righe_cms; //array con le righe del movimento che sono da trasferire TToken_string chiave; //scansione righe movimentoPN for (int l = 0; l < mov.cg_items(); l++) { const TRectype& rmov = mov.cg(l); chiave = ""; chiave.add(rmov.get("CODCMS")); chiave.add(rmov.get("FASCMS")); //se ci sono la commessa e/o la fase nella riga movimento e la riga iva non e' tipo T.. //..procede al calcolo dell'importo if (!chiave.empty_items() && rmov.get(RMV_ROWTYPE) != "T") { //alla chiave va aggiunto il vecchio gr/co/stc TString16 conto_cg; conto_cg.format("%03d|%03d|%06ld", rmov.get_int(RMV_GRUPPO), rmov.get_int(RMV_CONTO), rmov.get_long(RMV_SOTTOCONTO)); chiave.add(conto_cg); TImporto_descritto* importo = (TImporto_descritto*)righe_cms.objptr(chiave); if (importo == NULL) //la chiave non esisteva nell'assoc { importo = new TImporto_descritto(rmov.get(RMV_DESCR)) ; righe_cms.add(chiave, importo); } const char sezione = rmov.get_char(RMV_SEZIONE); const real valore = rmov.get(RMV_IMPORTO); *importo += TImporto(sezione, valore); //crea un importo e lo somma a quello dell'array //aggiunge gr/co/sottoc all'assoc_array dei conti da trasformare in analitici sul piano dei conti cg_lines_to_anal.add(conto_cg, NULL); } } TImporto importone; //importo totale del movimento (totale di testata) FOR_EACH_ASSOC_OBJECT(righe_cms, m, n, a) //giro sull'assoc array delle righe movimento da trasferire { //aggiunge l'importo della riga all'importo totale TImporto_descritto& importo = *(TImporto_descritto*)a; importo.normalize(); importone += importo; chiave = n; //chiave = commessa|fase|gruppo|conto|sottoconto const int gruppo = chiave.get_int(2); const int conto = chiave.get_int(); const long sottoconto = chiave.get_long(); //controlla se il gr/co/stc del movimento deve essere ripartito;in caso affermativo procede.. //..alla ripartizione delle righe del movimento //Per prima cosa crea l'array delle righe di ripartizione con questo gr/co/stc const TRecord_array& righe_ripartizione = _cache_rip.righe(gruppo, conto, sottoconto); if (righe_ripartizione.rows() > 0) //ci sono righe ripartizione: da 1 riga mov CG a N righe mov CA { // Importo totale da distribuire arrotondato ai decimali della valuta di conto TGeneric_distrib distrib(importo.valore(), TCurrency::get_firm_dec()); // Calcola tutte le percentuali da ripartire int i; for (i = 1; i <= righe_ripartizione.rows(); i++) distrib.add(righe_ripartizione[i].get_real(RRIP_RIPARTO)); //Compila le righe del movimento di analitica in base alle righe ripartizione for (i = 1; i <= righe_ripartizione.rows(); i++) { const TRectype& rrip = righe_ripartizione.row(i); TRectype& analriga = analmov.new_row(); const real imp = distrib.get(); // Legge la quota da distribuire analriga.put(RMOVANA_SEZIONE, importo.sezione()); analriga.put(RMOVANA_IMPORTO, imp); //e la mette nella nuova riga analriga.put(RMOVANA_DESCR, importo.descrizione()); analriga.put(RMOVANA_ANNOES, analmov.get(MOVANA_ANNOES)); analriga.put(RMOVANA_DATACOMP, analmov.get(MOVANA_DATAREG)); //parametri da prendere dalle righe ripartizione!! analriga.put(RMOVANA_CODCCOSTO, rrip.get(RRIP_CODCOSTO)); analriga.put(RMOVANA_CODCMS, rrip.get(RRIP_CODCMS)); analriga.put(RMOVANA_CODFASE, rrip.get(RRIP_CODFASE)); analriga.put(RMOVANA_CODCONTO, rrip.get(RRIP_CODCONTO)); //controlla la coppia fase/(cdc-commessa) e decide se aggiungerla al file delle fasi check_phase(analriga); } } else //nessuna riga ripartizione -> da 1 riga movimento CG ad 1 riga movimento CA { if (ca_config().get_bool("UsePdcc")) //solo se in CA si usa il piano dei conti contabile.. { //..e' possibile costruire la riga movimento //Compila la riga del movimentodi analitica TRectype& analriga = analmov.new_row(); analriga.put(RMOVANA_SEZIONE, importo.sezione()); analriga.put(RMOVANA_IMPORTO, importo.valore()); analriga.put(RMOVANA_DESCR, importo.descrizione()); analriga.put(RMOVANA_ANNOES, analmov.get(MOVANA_ANNOES)); analriga.put(RMOVANA_DATACOMP, analmov.get(MOVANA_DATAREG)); analriga.put(RMOVANA_CODCMS, chiave.get(0)); analriga.put(RMOVANA_CODFASE, chiave.get(1)); TString16 codconto; codconto.format("%03d%03d%06ld", gruppo, conto, sottoconto); analriga.put(RMOVANA_CODCONTO, codconto); //controlla la coppia fase/(cdc-commessa) e decide se aggiungerla al file delle fasi check_phase(analriga); } else //qui va aggiunta la lista dei conti che non hanno ripartizione quando NON si usa il.. //..piano dei conti contabile in analitica error_box(TR("Manca la ripartizione di un conto")); } } //end FOR_EACH.. //e alla fine riesce a mettere anche l'importone in testata importone.normalize(); //x evitare problemi di segno... analmov.put(MOVANA_SEZIONE, importone.sezione()); analmov.put(MOVANA_TOTDOC, importone.valore()); //Seconda parte del trasferimento: compatta e riscrive i movimenti(+righe) originali! //Se e' riuscita la scrittura dei movimenti di analitica (MOVANA,RMOVANA)ed e' una conversione.. //..DEFINITIVA,riordina le righe e le testate dei movimenti originari (MOV,RMOV,RMOVIVA).. //..riscrivendole if (analmov.write(f) == NOERR && definitiva) { //RIGHE MOVIMENTI CONTABILI TArray cg_records; for (int m = 0; m < mov.cg_items(); m++) { const TRectype& rmov = mov.cg(m); int add_to = -1; //se la riga movimento contabile ha un ROWTYPE... if (rmov.get(RMV_ROWTYPE).not_empty()) { //cerca nell'array dei record riga mov(cg_records) partendo dall'ultima a scalare.. for(add_to = cg_records.last(); add_to >=0; add_to--) { //prende il record add_to-esimo.. const TRectype& rec = (TRectype&)cg_records[add_to]; //se i campi gr.co.sottoc. di un record dell'array(cg_records) = a quelli della riga //movimento contabile in esame(rmov) -> esce con add_to = al numero del record dell' //array che soddisfa la condizione (quindi add_to > 0) if (rmov.get_int(RMV_GRUPPO) == rec.get_int(RMV_GRUPPO) && rmov.get_int(RMV_CONTO) == rec.get_int(RMV_CONTO) && rmov.get_long(RMV_SOTTOCONTO) == rec.get_long(RMV_SOTTOCONTO)) break; } } //se add_to e' rimasto = -1 (la condizione di eguaglianza gr.co.sott. non e' stata soddisfatta //da alcuna riga dell'array cg_records).. if (add_to < 0) { TRectype* rec = new TRectype(rmov); //azzera i campi codice commessa e fase in RMOV di origine... rec->zero("CODCMS"); rec->zero("FASCMS"); //e aggiunge all'array cg_records il nuovo record ripulito cg_records.add(rec); rec->put(RMV_NUMRIG, cg_records.items()); } //se ivece add_to > 0 (vedi test su condizione gr.co.sott. sopra).. else { //prende il record(rec) dell'array che soddsfaceva la condizione e somma ad esso importo e sezione //di quello in esame(rmov) TRectype& rec = (TRectype&)cg_records[add_to]; TImporto imp_tot(rec.get_char(RMV_SEZIONE), rec.get_real(RMV_IMPORTO)); TImporto imp_original(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO)); imp_tot += imp_original; imp_tot.normalize(); rec.put(RMV_SEZIONE, imp_tot.sezione()); rec.put(RMV_IMPORTO, imp_tot.valore()); //notare che i campi descrittivi resteranno sempre quelli del primo record di cg_records //che ha gr.co.sottoc. soddisfacenti la condizione sopra! } } //cancella solo le righe contabili del movimento originale.. mov.destroy_cg_row(-1); //e le sostituisce con le nuove che sono contenute (compattate) in cg-records FOR_EACH_ARRAY_ITEM(cg_records, cg_i, cg_obj) { mov.cg(cg_i) = *(TRectype*)cg_obj; } //RIGHE MOVIMENTI IVA (rifa' tutto il giochetto di prima per rmoviva) TArray iva_records; for (int n = 0; n < mov.iva_items(); n++) { const TRectype& rmoviva = mov.iva(n); int add_to = -1; for(add_to = iva_records.last(); add_to >=0; add_to--) { const TRectype& rec = (TRectype&)iva_records[add_to]; if (rmoviva.get_int(RMI_GRUPPO) == rec.get_int(RMI_GRUPPO) && rmoviva.get_int(RMI_CONTO) == rec.get_int(RMI_CONTO) && rmoviva.get_long(RMI_SOTTOCONTO) == rec.get_long(RMI_SOTTOCONTO) && rmoviva.get(RMI_CODIVA) == rec.get(RMI_CODIVA) && rmoviva.get_int(RMI_TIPODET) == rec.get_int(RMI_TIPODET)) break; } if (add_to < 0) { TRectype* rec = new TRectype(rmoviva); rec->zero("CODCMS"); rec->zero("FASCMS"); iva_records.add(rec); rec->put(RMI_NUMRIG, iva_records.items()); } else { TRectype& rec = (TRectype&)iva_records[add_to]; //imponibile.. real tot = rec.get_real(RMI_IMPONIBILE); real original = rmoviva.get_real(RMI_IMPONIBILE); tot += original; rec.put(RMI_IMPONIBILE, tot); //..e imposta tot = rec.get_real(RMI_IMPOSTA); original = rmoviva.get_real(RMI_IMPOSTA); tot += original; rec.put(RMI_IMPOSTA, tot); } } mov.destroy_iva_row(-1); FOR_EACH_ARRAY_ITEM(iva_records, iva_i, iva_obj) { mov.iva(iva_i) = *(TRectype*)iva_obj; } //puo' finalmente riscrivere i files di origine puliti e compattati (sia iva che non) mov.rewrite(); } } bool TConversione_cm2ca::convert_movs(TConversione_anal_msk& mask) { //scandisce il file RMOV,alla ricerca dei record con codice fase o codice commessa compilato TRelation rel_rmov(LF_RMOV); //aggiunge MOV alla relazione per avere le DATACOMP da usare nel filtro rel_rmov.add(LF_MOV, "NUMREG==NUMREG"); const bool definitiva = mask.get_int(F_TIPOCONV) != 0; //costruzione filtro con date (in caso di conversione provvisoria) TString filtro; filtro << "((CODCMS!='')||(FASCMS!=''))&&(ROWTYPE!='T')"; const TDate dataini = mask.get_date(F_DATAINI); if (dataini.ok()) filtro << "&&(ANSI(23->DATACOMP)>=" << dataini.string(ANSI) << ")"; const TDate datafin = mask.get_date(F_DATAFIN); if (datafin.ok()) filtro << "&&(ANSI(23->DATACOMP)<=" << datafin.string(ANSI) << ")"; TCursor cur_rmov(&rel_rmov, filtro); TRectype& rec_rmov = rel_rmov.curr(); const long rmov_items = cur_rmov.items(); if (rmov_items > 0) { cur_rmov.freeze(); TProgind pi(rmov_items, "Trasferimento righe movimenti", false); long last_numreg_cg = 0; //numero registrazione originaria TAssoc_array cg_lines_to_anal; //record array da riempire con gr/co/sott delle righe trasferite for (cur_rmov = 0; cur_rmov.pos() < rmov_items; ++cur_rmov) { pi.addstatus(1); const long curr_numreg_cg = rec_rmov.get_long(RMV_NUMREG); if (curr_numreg_cg != last_numreg_cg) { //se il numreg di questa riga e' nuovo -> crea un nuovo movimento di analitica (testata) create_new_movana(curr_numreg_cg, definitiva, cg_lines_to_anal); last_numreg_cg = curr_numreg_cg; } } //aggiorna il piano dei conti flaggando i conti "analitici" if (cg_lines_to_anal.items() > 0) { TLocalisamfile pcon(LF_PCON); FOR_EACH_ASSOC_OBJECT(cg_lines_to_anal, h, k, object) { TToken_string tok = k; const int gruppo = tok.get_int(0); const int conto = tok.get_int(1); const long sottoconto = tok.get_long(2); //cerca il record con gr/co/sottoc sul file del piano dei conti... pcon.put(PCN_GRUPPO, gruppo); pcon.put(PCN_CONTO, conto); pcon.put(PCN_SOTTOCONTO, sottoconto); //..se lo trova e non e' gia' anale... if (pcon.read() == NOERR && !pcon.get_bool(PCN_ANALITICA)) { pcon.put(PCN_ANALITICA, "X"); //..lo analizza!.. pcon.rewrite(); //..e lo riscrive } } } } //end if(rmov_items>0) return true; } /////////////////////////////////////////////////////////// // Programma di conversione da CM a CA /////////////////////////////////////////////////////////// int main(int argc,char** argv) { TConversione_cm2ca a; a.run(argc,argv, "Trasferimento dati a Contabilita' Analitica"); return 0; }