From 589a23f49a9207f5838e22d4f1f9a40337821505 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 16 Apr 2009 09:41:08 +0000 Subject: [PATCH] Patch level :10.0 Files correlati : Ricompilazione Demo : [ ] Commento :riportata esportazione rendiconto git-svn-id: svn://10.65.10.50/trunk@18715 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ca/ca3700.cpp | 470 +++++++++++++++++++++++++++++++------------------ ca/ca3700a.rep | 97 +++++----- ca/calib01.cpp | 6 +- ca/calib02.cpp | 33 ++-- 4 files changed, 371 insertions(+), 235 deletions(-) diff --git a/ca/ca3700.cpp b/ca/ca3700.cpp index 5fb533563..a7180df2f 100755 --- a/ca/ca3700.cpp +++ b/ca/ca3700.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include "../cg/cg2103.h" @@ -146,7 +147,7 @@ bool TPrint_rendiconto_ca_mask::on_field_event(TOperable_field& o, TField_event _print_mode = 'A'; stop_run(K_ENTER); return false; - } + } break; case DLG_EXPORT: if (e == fe_button) @@ -259,7 +260,6 @@ TPrint_rendiconto_ca_mask::TPrint_rendiconto_ca_mask() class TPrint_rendiconto_ca_recordset : public TISAM_recordset { - TExternisamfile* _tmp; bool _riclassificato; bool _reverse_cos_ric; bool _implode_rows; @@ -273,40 +273,38 @@ protected: bool _vitaintera; long _danumreg, _anumreg; TString _daconto, _aconto, _codcosto, _codcms, _codfas; - -protected: //da libreria - virtual const TVariant& get(const char* column_name) const; protected: static bool mov_filter(const TRelation* rel); bool valid_record(const TRelation& rel) const; virtual void set_custom_filter(TCursor& cur) const; - void crea_righe_da_rmovana(); - void crea_righe_da_rdoc(const TPrint_rendiconto_ca_mask& msk); + void crea_righe_da_rmovana(TLocalisamfile& tmp, TLog_report& log); + void crea_righe_da_rdoc(TLocalisamfile& tmp, const TPrint_rendiconto_ca_mask& msk, TLog_report& log); void crea_trr(const TFilename& trr) const; - void scrive_riga(const TRectype& rmovana, const TRectype& movana, const TDocumento* doc); - void scrive_riga_speciale(const TDocumento* doc, const TString_array& special_docs); + void scrive_riga(TLocalisamfile& tmp, const TRectype& rmovana, const TRectype& movana, const TDocumento* doc, + TLog_report& log); + void scrive_riga_speciale(TLocalisamfile& tmp, const TDocumento* doc, const TString_array& special_docs); int sort_indbil(int indbil) const; const TString& riclassifica(const TBill& zio, TRectype& tmpcurr) const; const TString& riclassifica(const TString& contone, TRectype& tmpcurr) const; - real get_budget(const TString& conto, char tipo) const; bool is_causale_rateo_risconto(const char* codcaus); +public: //da libreria + virtual const TVariant& get(const char* column_name) const; public: - virtual void set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row); + void set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row, TLog_report& log); + void set_cms_cdc_fase(const char* cdc, const char* cms, const char* fase); + real get_budget(const TString& conto, char tipo) const; + TPrint_rendiconto_ca_recordset(const TString& sql); ~TPrint_rendiconto_ca_recordset(); }; - -static TPrint_rendiconto_ca_recordset* myself = NULL; - - TPrint_rendiconto_ca_recordset::TPrint_rendiconto_ca_recordset(const TString& sql) - : TISAM_recordset(sql), _riclassificato(false), _tmp(NULL) + : TISAM_recordset(sql), _riclassificato(false) { //Controlla sul file di configurazione di CA (ditta.ini,[ca]) se esistono causali di tipo.. //..rateo/risconto che devono essere calcolate come solo maturato (Eva Braun request) @@ -326,55 +324,57 @@ TPrint_rendiconto_ca_recordset::~TPrint_rendiconto_ca_recordset() { } +//filtro ulteriore sul file rendy.dbf già creato void TPrint_rendiconto_ca_recordset::set_custom_filter(TCursor& cur) const { - relation()->replace(_tmp); //sostituisce il vero file rmovana con quello temporaneo - - //filtro sul file esterno (_tmp, cioè 1000) sui conti selezionati sulla maschera - TRectype darec(cur.curr()), arec(cur.curr()); //curr perchè è il file externisamfile - darec.zero(); - arec.zero(); - - if (_daconto.not_empty()) - { - darec.put("ORDCONT", 1); - darec.put("CONTO", _daconto); - } - if (_aconto.not_empty()) - { - arec.put("ORDCONT", 5); - arec.put("CONTO", _aconto); - } + //la region serve solo nella chiave 1!!! + if (cur.key() == 1) + { + //filtro sul file esterno (tmp, cioè rendy.dbf) sui conti selezionati sulla maschera + TRectype darec(cur.curr()), arec(cur.curr()); //curr perchè è il file externisamfile + darec.zero(); + arec.zero(); + if (_daconto.not_empty()) + { + darec.put("ORDCONT", 1); + darec.put("CONTO", _daconto); + } + if (_aconto.not_empty()) + { + arec.put("ORDCONT", 5); + arec.put("CONTO", _aconto); + } + cur.setregion(darec, arec); + } //filtro sulla data(non avendo anche codnum non ho la chiave completa per mettere la data nella setregion) TString filtro; - if (_dadata.ok()) - filtro << "(ANSI(DATA)>=" << _dadata << ")"; + if (_dadata.ok() || _adata.ok()) + { + if (_vitaintera) + filtro << "(BETWEEN(DATA," << _dadata.date2ansi() << ",0))"; + else + filtro << "(BETWEEN(DATA," << _dadata.date2ansi() << "," << _adata.date2ansi() << "))"; + } - if (_adata.ok() && !_vitaintera) //se vitaintera non si può avere una data limite superiore + //vera selezione sui conti + if (_daconto.full() || _aconto.full()) { if (filtro.not_empty()) filtro << "&&"; - filtro << "(ANSI(DATA)<=" << _adata << ")"; + if (_daconto == _aconto) + filtro << "(CONTO[1," << _daconto.len() << "]==\"" << _daconto << "\")"; + else + filtro << "(BETWEEN(CONTO,\"" << _daconto << "\",\"" << _aconto << "~\"))"; } - if (_daconto.not_empty()) - { - if (filtro.not_empty()) - filtro << "&&"; - filtro << "(CONTO>='" << _daconto << "')"; - } - - if (_aconto.not_empty()) - { - if (filtro.not_empty()) - filtro << "&&"; - filtro << "(CONTO<='" << _aconto << "~')"; - } - - cur.setregion(darec, arec); cur.setfilter(filtro); +} - myself = (TPrint_rendiconto_ca_recordset*)this; +void TPrint_rendiconto_ca_recordset::set_cms_cdc_fase(const char* cdc, const char* cms, const char* fase) +{ + _codcosto = cdc; + _codcms = cms; + _codfas = fase; } //sconvolgente metodo per la normalizzazione dei conti @@ -590,15 +590,26 @@ bool TPrint_rendiconto_ca_recordset::is_causale_rateo_risconto(const char* codca } //compila i campi del file temporaneo che sara' poi stampato -void TPrint_rendiconto_ca_recordset::scrive_riga(const TRectype& rmovana, const TRectype& movana, const TDocumento* doc) +void TPrint_rendiconto_ca_recordset::scrive_riga(TLocalisamfile& tmp, const TRectype& rmovana, const TRectype& movana, + const TDocumento* doc, TLog_report& log) { - TRectype& tmpcurr = _tmp->curr(); + TRectype& tmpcurr = tmp.curr(); tmpcurr.zero(); TString8 codnum_desc; //codnum da usare sia per compilare il campo "CODNUM" codnum_desc.cut(0); //----- CONTI -----// - TString codconto = rmovana.get(RMOVANA_CODCONTO); + const TString80 codconto_originale = rmovana.get(RMOVANA_CODCONTO); + if (codconto_originale.blank()) + { + TString error_string; + const long error_numreg = rmovana.get_long(RMOVANA_NUMREG); + const int error_numrig = rmovana.get_int(RMOVANA_NUMRIG); + error_string.format("NON esiste il conto sulla riga %d del movimento %ld !!", error_numrig, error_numreg); + log.log(2, error_string); + return; + } + TString80 codconto = codconto_originale; TString codcontocg; int indbil = 0; @@ -738,7 +749,7 @@ void TPrint_rendiconto_ca_recordset::scrive_riga(const TRectype& rmovana, const { //Controlla se il documento di origine (padre del documento da cui deriva l'attuale riga.. //..di analitica) era una FDR/FDE... - const TCodice_numerazione& kodice_num = cached_numerazione(babbo_codnum); + const TCodice_numerazione kodice_num(babbo_codnum); //Se lo era... if (kodice_num.fattura_emettere_ricevere()) { @@ -902,6 +913,12 @@ F=IMF*/ //----Scrittura Conti sul file----// //Scrittura dei conti (i valori delle variabili sono stati settati nella parte iniziale del metodo) //mette i conti nel file (se piano dei conti puramente contabile i valori coincidono) + if (codconto.blank()) + { + TString error_message; + error_message.format("Il conto %s non è riclassificato!", codcontocg); + log.log(2, error_message); + } tmpcurr.put("CONTO", codconto); //conto tmpcurr.put("CONTOCG", codcontocg); //conto_cg @@ -931,7 +948,7 @@ F=IMF*/ //scrive sul file di appoggio il record appena riempito - int err = _tmp->write(); + int err = tmp.write(); //se e' in modalita' di ricompattamento righe ripartite.. if (_implode_rows) @@ -942,7 +959,7 @@ F=IMF*/ { const int new_nriga = tmpcurr.get_int("NRIGA") + 1; tmpcurr.put("NRIGA", new_nriga); - err = _tmp->write(); + err = tmp.write(); } } @@ -951,7 +968,7 @@ F=IMF*/ //compila i campi del file temporaneo che sara' poi stampato per i documenti speciali.. //..quali le fatture da emettere e ricevere, la cui lista e' nel ca_config -void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc, const TString_array& special_docs) +void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(TLocalisamfile& tmp, const TDocumento* doc, const TString_array& special_docs) { //prende il tipocf che gli serve un po' ovunque in seguito.. const char tipocf = doc->get_char(DOC_TIPOCF); @@ -963,7 +980,7 @@ void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc, if (special_docs.find(rigadoc.get(RDOC_DACODNUM)) > 0) { - TRectype& tmpcurr = _tmp->curr(); + TRectype& tmpcurr = tmp.curr(); tmpcurr.zero(); TString8 codnum_desc; codnum_desc.cut(0); @@ -1095,7 +1112,7 @@ void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc, tmpcurr.put("FATTURATO", importo); } - _tmp->write(); + tmp.write(); } //if(special_docs... } // for (inti=1;i<=rows... @@ -1103,7 +1120,7 @@ void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc, //scanning delle righe dei movimenti di analitica -void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana() +void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana(TLocalisamfile& tmp, TLog_report& log) { TRelation rel_rmovana(LF_RMOVANA); rel_rmovana.add(LF_MOVANA, "NUMREG==NUMREG"); //aggiunge le testate x avere tipi mov e descr @@ -1187,7 +1204,7 @@ void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana() const int last_row = righe_compattate.last_row(); for (int i = righe_compattate.first_row(); i > 0 && i <= last_row; i = righe_compattate.succ_row(i)) - scrive_riga(righe_compattate.row(i), old_movana, NULL); + scrive_riga(tmp, righe_compattate.row(i), old_movana, NULL, log); } //aggiorna il valore di testata con quella nuova per il prossimo movimento old_movana = movana; @@ -1211,14 +1228,15 @@ void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana() { if (!pi.addstatus(1)) break; - scrive_riga(rmovana, movana, NULL); + scrive_riga(tmp, rmovana, movana, NULL, log); } } } } //scanning delle righe dei documenti -void TPrint_rendiconto_ca_recordset::crea_righe_da_rdoc(const TPrint_rendiconto_ca_mask& msk) +void TPrint_rendiconto_ca_recordset::crea_righe_da_rdoc(TLocalisamfile& tmp, const TPrint_rendiconto_ca_mask& msk, + TLog_report& log) { TRelation rel_rdoc(LF_RIGHEDOC); rel_rdoc.add(LF_DOC, "CODNUM==CODNUM|ANNO==ANNO|PROVV==PROVV|NDOC==NDOC"); //aggiunge le testate @@ -1395,13 +1413,13 @@ void TPrint_rendiconto_ca_recordset::crea_righe_da_rdoc(const TPrint_rendiconto_ if (_codfas.not_empty() && rmov.get(RMOVANA_CODFASE) != _codfas) continue; - scrive_riga(rmov, mov, &doc); //documenti "normali" + scrive_riga(tmp, rmov, mov, &doc, log); //documenti "normali" } //for int j... } else { //righe di documento configurate come da emettere/ricevere (documenti speciali) - scrive_riga_speciale(&doc, num_fdr); + scrive_riga_speciale(tmp, &doc, num_fdr); } } //if (numregca==0... @@ -1445,17 +1463,19 @@ void TPrint_rendiconto_ca_recordset::crea_trr(const TFilename& trr) const of << "DATADOCRIF|5|8|0|Data documento riferimento" << endl; of << "DESC|1|50|0|Descrizione movimento o documento" << endl; of << "DESCRIGA|1|50|0|Descrizione riga movimento o documento" << endl; - of << "DOCORIG|11|10|0|Riferimenti ordine/bolla" << endl; + of << "DOCORIG|1|50|0|Riferimenti ordine/bolla" << endl; of << "FATTURATO|4|18|5|Fatturato" << endl; of << "MATURATO|4|18|5|Maturato" << endl; of << "IMPEGNATO|4|18|5|Impegnato" << endl; of << "CONTOCG|1|12|0|Conto contabile" << endl; of << "HIDDEN|8|1|0|Record nascosto" << endl; - of << 1 << endl; + of << 3 << endl; of << "ORDCONT+CONTO+DATA+CODNUM+NUMRD+NUMREG+NRIGA" << endl; + of << "CODCMS+CONTO+DATA|X" << endl; + of << "CODCOSTO+CONTO+DATA|X" << endl; } -void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row) +void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row, TLog_report& log) { //se esiste il file temporano con tracciato persomalizzato lo cancella e lo ricrea vuoto TFilename trr; //file tracciato record @@ -1468,13 +1488,10 @@ void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask& //crea il file .trr in base ai parametri del metodo crea_trr(trr); - //svuota la memoria dal vecchio file temporaneo - if (_tmp != NULL) - delete _tmp; //crea in memoria il nuovo file temporaneo e lo azzera (non si sa mai..) - _tmp = new TExternisamfile(dbf, trr); - _tmp->zap(); + TExternisamfile tmp(dbf, trr, true); + tmp.zap(); //prende un po' di dati dalla maschera... _piano, _daconto, _aconto, _codcosto, _codcms, _codfas = ""; @@ -1537,9 +1554,9 @@ void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask& //metodi per riempire il file da cui generare il report //dati estratti dalle righe movimenti di contabilita' analitica - crea_righe_da_rmovana(); + crea_righe_da_rmovana(tmp, log); //dati estratti dalle righe documenti - crea_righe_da_rdoc(msk); + crea_righe_da_rdoc(tmp, msk, log); } @@ -1554,7 +1571,7 @@ protected: virtual bool get_usr_val(const TString& name, TVariant& var) const; public: - void set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row); + void set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row, const int recset_key, TLog_report& log); }; bool TPrint_rendiconto_ca_rep::get_usr_val(const TString& name, TVariant& var) const @@ -1568,15 +1585,17 @@ bool TPrint_rendiconto_ca_rep::set_recordset(const TString& sql) return TAnal_report::set_recordset(rs); } -void TPrint_rendiconto_ca_rep::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row) +void TPrint_rendiconto_ca_rep::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row, const int recset_key, TLog_report& log) { TAnal_report::set_recordset(NULL); // Forza azzeramento file Rendy.dbf prima di ricostruirlo - const char* query ="USE 1000\nJOIN MOVANA INTO NUMREG==NUMRD\nJOIN RMOVANA INTO NUMREG==NUMRD NUMRIG==NRIGA"; + TString query ="USE RENDY.DBF"; + query << " KEY " << recset_key << "\n"; + query << "JOIN MOVANA INTO NUMREG==NUMRD\nJOIN RMOVANA INTO NUMREG==NUMRD NUMRIG==NRIGA"; TPrint_rendiconto_ca_recordset* recset = new TPrint_rendiconto_ca_recordset(query); - recset->set_filter(msk, cms_row); + recset->set_filter(msk, cms_row, log); TAnal_report::set_recordset(recset); } @@ -1588,10 +1607,10 @@ class TPrint_rendiconto_ca : public TSkeleton_application TPrint_rendiconto_ca_mask* _msk; protected: - void print_or_preview(bool pr); - virtual void print() { print_or_preview(true); } - virtual void preview() { print_or_preview(false); } - void esporta_csv(TRecordset& rendy, const int r); + virtual void print(); + void esporta_csv_row(ostream& file_to_date, const int first_level, const TString& cod_cms_cdc, + const real importi[5][4], real importi_totali[5][4]); + void esporta_csv(TPrint_rendiconto_ca_recordset& rendy, const int r); void incrementa(TToken_string& riga, const int col, const real& valore) const; public: @@ -1599,10 +1618,10 @@ public: virtual void main_loop(); }; -void TPrint_rendiconto_ca::print_or_preview(bool pr) +void TPrint_rendiconto_ca::print() { if (_msk != NULL) - _msk->send_key(K_SPACE, pr ? DLG_PRINT : DLG_PREVIEW); + _msk->send_key(K_SPACE, DLG_PRINT); } void TPrint_rendiconto_ca::incrementa(TToken_string& riga, const int col, const real& valore) const @@ -1612,88 +1631,176 @@ void TPrint_rendiconto_ca::incrementa(TToken_string& riga, const int col, const riga.add(r.string(), col); } -//metodo di alto livello per l'esportazione dei dati di totale in un file per excel -void TPrint_rendiconto_ca::esporta_csv(TRecordset& rendy, const int r) +void TPrint_rendiconto_ca::esporta_csv_row(ostream& file_to_date, const int first_level, const TString& cod_cms_cdc, + const real importi[5][4], real importi_totali[5][4]) { - TMask& mask = *_msk; - TSheet_field& sheet = mask.sfield(F_RIGHE); - TString codcms; ca_extract_sheet_field(sheet, r, LF_COMMESSE, codcms); - TString cdc; ca_extract_sheet_field(sheet, r, LF_CDC, cdc); - TString codfase; ca_extract_sheet_field(sheet, r, LF_FASI, codfase); - //crea una token string su cui mettere i valori dei record letti dal file .dbf TToken_string riga(512, '\t'); - if (get_first_level().logic() == LF_COMMESSE) + riga.add(cod_cms_cdc); + //decodifica della commessa/cdc (non è ammessa una commessa "TOTALI" che lo incasina + if (cod_cms_cdc != "TOTALI") + riga.add(cache().get(first_level, cod_cms_cdc, "DESCRIZ")); + + //in base al valore di indbil e budget i valori degli importi vengono posizionati nel record + for (int indbil = 1; indbil <= 4; indbil++) { - riga.add(codcms); - riga.add(cache().get(LF_COMMESSE, codcms, COMMESSE_DESCRIZ)); - riga.add(cdc); - riga.add(codfase); - } - else - { - riga.add(cdc); - riga.add(cache().get(LF_CDC, cdc, CDC_DESCRIZ)); - riga.add(codcms); - riga.add(codfase); - } - - //recordset sul file .dbf, da scandire tutto uno per volta - for (bool ok = rendy.move_first(); ok; ok = rendy.move_next()) - { - const int indbil = rendy.get("ORDCONT").as_int(); - const bool budget = rendy.get("HIDDEN").as_bool(); - - const real impegnato = rendy.get("IMPEGNATO").as_real(); - const real fatturato = rendy.get("FATTURATO").as_real(); - const real maturato = rendy.get("MATURATO").as_real(); - - //in base al valore di indbil e budget i valori degli importi vengono posizionati nel record - int col; + int col = 0; switch (indbil) { - case 1: col = 18; break; //attività - case 2: col = 25; break; //passività - case 3: col = 4; break; //costi - case 4: col = 11; break; //ricavi + case 1: col = 16; break; //attività + case 2: col = 23; break; //passività + case 3: col = 2; break; //costi (o ricavi se selezionato il flag di inversione sulla maschera) + case 4: col = 9; break; //ricavi (o costi se selezionato il flag di inversione sulla maschera) + default: break; } -//simpatico metodo algoritmico per stabilire la colonna iniziale di sezione, invalidato da richieste dinamica/crpa - //const int col = 4 + (7*(indbil-1)); + //colonne budget/impegnato/maturato/fatturato + for (int j = 0; j < 4; j++) + { + riga.add(importi[indbil][j].string(), col + j); + importi_totali[indbil][j] += importi[indbil][j]; + } - //lo schema è questo: budget\impegnato\fatturato\maturato\da impegnare\da fatturare\da maturare - if (budget) - { - incrementa(riga, col, impegnato); - } - else - { - incrementa(riga, col + 1, impegnato); - incrementa(riga, col + 2, fatturato); - incrementa(riga, col + 3, maturato); - //il da maturare è più incasinato, perchè deve tener conto di valori già totalizzati sulla riga - const real imp_budget = riga.get(col); - const real imp_consuntivo = riga.get(col + 1); - const real da_impegnare = imp_budget - imp_consuntivo; - riga.add(da_impegnare.string(), col + 4); //da impegnare - incrementa(riga, col + 5, impegnato - fatturato); //da fatturare - incrementa(riga, col + 6, impegnato - maturato); //da maturare - } - } //for (bool ok = rendy.move_first()... - for (int i = 4; i < 32; i++) + //colonne da_impegnare/da_maturare/da_fatturare + const real da_impegnare = importi[indbil][0] - importi[indbil][1]; + riga.add(da_impegnare.string(), col + 4); + + const real da_maturare = importi[indbil][1] - importi[indbil][2]; + riga.add(da_maturare.string(), col + 5); + + const real da_fatturare = importi[indbil][1] - importi[indbil][3]; + riga.add(da_fatturare.string(), col + 6); + } + //scrive in excel mode + for (int i = 2; i < 30; i++) { const real r = riga.get(i); if (!r.is_zero()) - riga.add(r.stringe(), i); + { + TString80 str; + str << r; + str.replace('.', ','); + riga.add(str, i); + } } + //aggiunge la riga al file da esportare + file_to_date << riga << endl; +} + +//metodo di alto livello per l'esportazione dei dati di totale in un file per excel +void TPrint_rendiconto_ca::esporta_csv(TPrint_rendiconto_ca_recordset& rendy, const int r) +{ + //primo livello di configurazione + const int first_level = get_first_level().logic(); + //piano dei conti riclassificato? + TConfig& cfg = ca_config(); + const bool riclassificato = cfg.get_bool("UsePdcc"); + //aggiorna il file da esportare appendendo la nuova riga - TFilename path = mask.get(F_PATH); + TFilename path = _msk->get(F_PATH); path.lower(); path.add("rendiconto.xls"); ofstream file_to_date(path, ios::app); - file_to_date << riga << endl; + + //array bidimensionale con gli importi per indbil e colonna + real importi[5][4]; + //array bidimensionale con gli importi totali finali + real importi_totali[5][4]; + TString80 last_codice, curr_codice, last_conto, curr_conto; + + //recordset sul file .dbf, da scandire tutto uno per volta + rendy.requery(); + for (bool ok = rendy.move_first(); ok; ok = rendy.move_next()) + { + curr_codice = rendy.get(first_level == LF_COMMESSE ? "CODCMS" : "CODCOSTO").as_string(); + + //operazioni da fare al cambio commessa/cdc (codice primo livello) + if (curr_codice != last_codice) + { + //controlla se last_codice sia pieno per non aggiungere una inutile riga di zeri all'inizio + if (last_codice.full()) + esporta_csv_row(file_to_date, first_level, last_codice, importi, importi_totali); + + memset(importi, 0, sizeof(importi)); //Allah! Azzeratore dell'array con i totali per commessa (o cdc) + last_codice = curr_codice; //memorizza il cambio codice + last_conto = ""; //azzera l'ultimo conto + } + + curr_conto = rendy.get("CONTO").as_string(); + + //gestione dei budget: va fatta attraverso i saldi!!! come nella stampa, onde evitare pericolose dimenticanze.. + //..di movimenti budget in anni diversi da quello considerato + const bool hidden = rendy.get("HIDDEN").as_bool(); + const int indbil = rendy.get("ORDCONT").as_int(); + + if (hidden && curr_conto.full() && (curr_conto != last_conto)) + { + //preparazione dei parametri per il calcolo dei saldi + TSheet_field& sf = _msk->sfield(F_RIGHE); + TString80 codcms, codcdc, codfas; + if (first_level == LF_CDC) + { + codcdc = curr_codice; + ca_extract_sheet_field(sf, r, LF_COMMESSE, codcms); + ca_extract_sheet_field(sf, r, LF_FASI, codfas); + } + else + { + codcms = curr_codice; + ca_extract_sheet_field(sf, r, LF_CDC, codcdc); + ca_extract_sheet_field(sf, r, LF_FASI, codfas); + } + //calcola i saldana usando la get_budget come in stampa + rendy.set_cms_cdc_fase(codcdc, codcms, codfas); + real budget = rendy.get_budget(curr_conto, 'P'); + budget += rendy.get_budget(curr_conto, 'V'); + importi[indbil][0] += budget; + + last_conto = curr_conto; + } + + //lo schema è questo: budget\impegnato\maturato\fatturato\da impegnare\da maturare\da fatturare + //aggiorna budget + + //aggiorna tutti gli altri campi + if (!hidden) + { + const real impegnato = rendy.get("IMPEGNATO").as_real(); + const real fatturato = rendy.get("FATTURATO").as_real(); + const real maturato = rendy.get("MATURATO").as_real(); + + importi[indbil][1] += impegnato; + importi[indbil][2] += maturato; + importi[indbil][3] += fatturato; + } + + } //for (bool ok = rendy.move_first()... + + //gestione speciale dell'ultima riga + if (last_codice.full()) + { + esporta_csv_row(file_to_date, first_level, last_codice, importi, importi_totali); + + //aggiunge la riga con i totali + TToken_string str_tot = _msk->sfield(F_RIGHE).row(r); + //la riga con i totali ci va solo se non è stato specificato il primo livello (es. commessa o cdc) + const TFixed_string first_field = str_tot.get(0); + if (first_field.blank()) + { + str_tot.replace('|', ' '); + str_tot.strip_double_spaces(); + str_tot.insert("TOTALI\t"); + //riga con gli importi totali;per ottenerla basta chiamare la esporta_csv_row con gli array invertiti, in modo che.. + //..venga aggiornato l'array degli importi_totali; l'altro verrà sputtanato ma chi se ne frega! è già stato.. + //..esportato qualche riga sopra + esporta_csv_row(file_to_date, first_level, str_tot, importi_totali, importi); + //doppia riga vuota di stacco + file_to_date << endl << endl; + } + } + } //metodo per accattarsi o' primo livello della configurazione CA @@ -1709,6 +1816,7 @@ void TPrint_rendiconto_ca::main_loop() { _msk = new TPrint_rendiconto_ca_mask; TPrint_rendiconto_ca_mask& mask = *_msk; + const int first_level = get_first_level().logic(); //primo livello nella configurazione CA while (true) { @@ -1717,6 +1825,10 @@ void TPrint_rendiconto_ca::main_loop() if (key != K_ENTER && key != K_F6) break; + //chiave di ordinamento del recordset; di base è 1 (utilizzato per la stampa); va lasciata qui per essere resettata.. + //..ad ogni giro, in modo da sistemarsi quando si passa da esportazione a stampa e viceversa! + int recset_key = 1; + //resetta e prepara le intestazioni del file rendiconto.xls if (key == K_F6) { @@ -1727,11 +1839,19 @@ void TPrint_rendiconto_ca::main_loop() //intestazione primaria TToken_string intestazione_1(512, '\t'); - - intestazione_1.add("Commessa"); - intestazione_1.add("Descr. commessa"); - intestazione_1.add("C.d.C."); - intestazione_1.add("Fase"); + //l'intestazione primaria dipende anche dalla configurazione dei livelli! + if (first_level == LF_COMMESSE) //commessa-cdc + { + intestazione_1.add("Commessa"); + intestazione_1.add("Descr. commessa"); + recset_key = 2; //chiave del recordset per commessa + } + else //cdc-commessa + { + intestazione_1.add("C.d.C."); + intestazione_1.add("Descr. cdc"); + recset_key = 3; //chiave del recordset per centro di costo + } const bool reverse_cos_ric = mask.get_bool(F_REV_COSRIC); //occhio al flag di rovesciamento @@ -1765,9 +1885,10 @@ void TPrint_rendiconto_ca::main_loop() //intestazione secondaria TToken_string intestazione_2(512, '\t'); - - for (int k = 0; k < 4; k++) + //campi descrittivi iniziali vuoti (solo intestazione_1) + for (int k = 0; k < 2; k++) intestazione_2.add(""); + for (int l = 0; l < 4; l++) { for (int n = 0; n < 7; n++) @@ -1776,16 +1897,16 @@ void TPrint_rendiconto_ca::main_loop() { case 0: intestazione_2.add("Budget"); break; case 1: intestazione_2.add("Impegnato"); break; - case 2: intestazione_2.add("Fatturato"); break; - case 3: intestazione_2.add("Maturato"); break; + case 2: intestazione_2.add("Maturato"); break; + case 3: intestazione_2.add("Fatturato"); break; case 4: intestazione_2.add("Da impegnare"); break; - case 5: intestazione_2.add("Da fatturare"); break; - case 6: intestazione_2.add("Da maturare"); break; + case 5: intestazione_2.add("Da maturare"); break; + case 6: intestazione_2.add("Da fatturare"); break; } } } file_to_date << intestazione_2 << endl; - } + } //if(key==K_F6) //report e book dei report TReport_book book; @@ -1795,6 +1916,10 @@ void TPrint_rendiconto_ca::main_loop() TPrint_rendiconto_ca_rep rep; rep.load(path); + //log report con segnalazioni su errori (tipo conti inesistenti o robaccia simile..) + TLog_report log(TR("Errori rilevati")); + log.kill_duplicates(); + TSheet_field& sheet = mask.sfield(F_RIGHE); TString video_string; //stringa che compare nella progind if (sheet.empty()) //se non ci sono righe sullo sheet (selezione su tutte le cms/cdc)... @@ -1819,13 +1944,13 @@ void TPrint_rendiconto_ca::main_loop() for (int l = liv1.levels()-2; l >= 0; l--) //se la struttura è a più livelli costruisce la tokenstring row.insert("|", liv1.total_len(l)); - rep.set_filter(mask, 0); //fa la set filter sulla prima riga (che è quella usata) + rep.set_filter(mask, 0, recset_key, log); //fa la set filter sulla prima riga (che è quella usata) //se stampa o anteprima.. if (key == K_ENTER) book.add(rep); - else //esportazione in excel - esporta_csv(*rep.recordset(), 0); + else //esportazione in excel + esporta_csv((TPrint_rendiconto_ca_recordset&)*rep.recordset(), 0); } sheet.destroy(); //cancella le commesse aggiunte in automatico sullo sheet } @@ -1833,22 +1958,25 @@ void TPrint_rendiconto_ca::main_loop() { FOR_EACH_SHEET_ROW(sheet, r, row) //per ogni cdc/cms che appare nello sheet di pag.1 della msk.. { - rep.set_filter(mask, r); //..chiama il metodone globale che crea e compila il file.. + rep.set_filter(mask, r, recset_key, log); //..chiama il metodone globale che crea e compila il file.. //..temporaneo i cui dati riempiranno il report //se stampa o anteprima if (key == K_ENTER) book.add(rep); //aggiunge il report relativo alla cdc/cms corrente al book - else //esportazione in excel - esporta_csv(*rep.recordset(), r); + else //esportazione in excel + esporta_csv((TPrint_rendiconto_ca_recordset&)*rep.recordset(), r); //il recordset è del tipo TPrint_rendiconto } } //se stampa o anteprima - if (key == K_ENTER) + if (log.recordset()->items() > 0) + log.preview(); + + if (key == K_ENTER) //stampa o anteprima { if (mask.print_mode() == 'A') book.preview(); else - book.print(); + book.print(); } } //while(true)... diff --git a/ca/ca3700a.rep b/ca/ca3700a.rep index b6ec8bda0..ef06407e4 100755 --- a/ca/ca3700a.rep +++ b/ca/ca3700a.rep @@ -11,7 +11,7 @@ - + #SYSTEM.DATE @@ -33,13 +33,14 @@ - - - + + +
+ MESSAGE RESET,F1 @@ -144,12 +145,7 @@
ORDCONT+CONTO - MESSAGE RESET,F2.400 -MESSAGE RESET,F2.500 -MESSAGE RESET,F2.600 -MESSAGE RESET,F2.700 -MESSAGE RESET,F2.800 -MESSAGE RESET,F2.900 + MESSAGE RESET,F2 CONTO @@ -235,15 +231,15 @@ MESSAGE RESET,F2.900 DOCORIG - + FATTURATO MESSAGE ADD,F2.400 - + MATURATO MESSAGE ADD,F2.600 - + IMPEGNATO MESSAGE ADD,F2.800 @@ -310,7 +306,7 @@ MESSAGE RESET,F2.900 - + @@ -322,7 +318,7 @@ MESSAGE RESET,F2.900 - + @@ -334,7 +330,7 @@ MESSAGE RESET,F2.900 - + @@ -346,99 +342,99 @@ MESSAGE RESET,F2.900 - + - + - + - + - + - + - + - + - + #801-#401 - + #802-#402 - + #803-#403 - + #804-#404 - + - + - + - + - + #801-#601 - + #802-#602 - + #803-#603 - + #804-#604 - + - + - + - + - + #301-#801 - + #302-#802 - + #303-#803 - + #304-#804 @@ -451,7 +447,7 @@ MESSAGE RESET,F2.900 - + #THIS @ \ prende il proprio valore "F1." \ decide il campo destinazione in base al valore di INDBIL,che gli viene passato dal programma.. @@ -462,11 +458,11 @@ MESSAGE RESET,F2.900 +! \ esegue la ADD sul campo di destinazione - + #800-#400 - + #THIS @ "F1." @@ -476,11 +472,11 @@ MESSAGE RESET,F2.900 + +! - + #800-#600 - + #THIS @ "F1." @@ -490,7 +486,7 @@ MESSAGE RESET,F2.900 + +! - + #H2.700+#H2.800-#800 @@ -498,5 +494,4 @@ MESSAGE RESET,F2.900
0 #B1.100 !
- USE 1000 \ No newline at end of file diff --git a/ca/calib01.cpp b/ca/calib01.cpp index 0c2f11e92..6d181c37a 100755 --- a/ca/calib01.cpp +++ b/ca/calib01.cpp @@ -736,7 +736,11 @@ bool TSimple_anal_msk::on_field_event(TOperable_field& o, TField_event e, long j TEdit_field& e = efield(id); e.set(tok); e.show(); - last = &e; + //attenzione!!! modifica necessaria per poter ripulire in automatico i campi inutili al cambio struttura.. + //..del piano dei conti (selezionandone una diversa sull'albero della maschera) e per non avere un warning.. + //..dalla last->check() che andrebbe a fare la check su un campo vuoto + if (tok && *tok) + last = &e; } if (last != NULL) { diff --git a/ca/calib02.cpp b/ca/calib02.cpp index ba71d9ec5..a8ba24d37 100755 --- a/ca/calib02.cpp +++ b/ca/calib02.cpp @@ -725,6 +725,13 @@ public: TSaldi_cache(); }; +static TImporto get_imp(const TRecordset& rs, const char* sez, const char* imp) +{ + const char sezione = rs.get(sez).as_string()[0]; + const real importo = rs.get(imp).as_real(); + return TImporto(sezione, importo); +} + // Calcolo saldo annuale di un conto reale NON riclassificato bool TSaldi_cache::int_saldo_annuale(const TAnal_bill& b, int da_anno, int ad_anno, word tipo, TImporto& dare, TImporto& avere) const @@ -774,29 +781,26 @@ bool TSaldi_cache::int_saldo_annuale(const TAnal_bill& b, int da_anno, int ad_an for (TRecnotype i = 0; saldini.move_to(i); i++) { - char sez = ' '; - real imp; + TImporto imp; if (tipo & _saldanal_consuntivo) { - sez = saldini.get(SALDANA_SEZIONE).as_string()[0]; - imp = saldini.get(SALDANA_SALDO).as_real(); + imp += get_imp(saldini, SALDANA_SEZIONE, SALDANA_SALDO); } if (tipo & _saldanal_preventivo) { - sez = saldini.get(SALDANA_SEZIONEP).as_string()[0]; - imp = saldini.get(SALDANA_SALDOP).as_real(); + imp += get_imp(saldini, SALDANA_SEZIONEP, SALDANA_SALDOP); } if (tipo & _saldanal_variazione) { - sez = saldini.get(SALDANA_SEZIONEV).as_string()[0]; - imp = saldini.get(SALDANA_SALDOV).as_real(); + imp += get_imp(saldini, SALDANA_SEZIONEV, SALDANA_SALDOV); } - if (sez > ' ') + if (!imp.is_zero()) { - if (sez == 'D') - dare += TImporto('D', imp); + if (imp.sezione() == 'D') + dare += imp; else - avere += TImporto('A', imp); + avere += imp; + movim = true; } } @@ -1027,6 +1031,11 @@ TSaldi_cache::TSaldi_cache() : TCache(3881) // Numero primo const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi) { static TSaldi_cache* cache = NULL; + if (tipi == 0 && cache != NULL) + { + delete cache; + cache = NULL; + } if (cache == NULL) cache = new TSaldi_cache; return cache->saldo(bill, dal, al, tipi);