diff --git a/ca/ca0300a.h b/ca/ca0300a.h index 384f50cff..fbe45afb1 100755 --- a/ca/ca0300a.h +++ b/ca/ca0300a.h @@ -41,6 +41,7 @@ #define F_PDCI_4 136 #define F_DESPDCI_4 137 #define F_USE_PDCC 138 +#define F_PREFIX 139 #define F_CDCREQ 140 #define F_CMSREQ 141 diff --git a/ca/ca0300a.uml b/ca/ca0300a.uml index e955017f2..3645bc6db 100755 --- a/ca/ca0300a.uml +++ b/ca/ca0300a.uml @@ -315,6 +315,18 @@ BOOLEAN F_USE_PDCC BEGIN PROMPT 2 11 "Utilizza il piano dei conti contabile" FIELD UsePdcc + MESSAGE FALSE HIDE,F_PREFIX + MESSAGE TRUE SHOW,F_PREFIX +END + +LIST F_PREFIX 1 10 +BEGIN + PROMPT 54 11 "Prefisso " + ITEM "0|Nessuno" + ITEM "1|Livello 1" + ITEM "2|Livello 2" + ITEM "3|Livello 3" + FIELD PdcPrefix END TEXT -1 @@ -345,8 +357,8 @@ END STRING F_PDCI_2 20 BEGIN PROMPT 2 14 "2 " - MESSAGE EMPTY CLEAR,F_PDCI_3|CLEAR,F_DESPDCI_3|K_TAB,F_PDCI_3|RESET,F_DESPDCI_2 - MESSAGE ENABLE,F_PDCI_3|ENABLE,F_DESPDCI_3 + MESSAGE EMPTY CLEAR,F_PDCI_3|CLEAR,F_DESPDCI_3|K_TAB,F_PDCI_3|RESET,F_DESPDCI_2|CLEAR,F_PREFIX + MESSAGE ENABLE,F_PDCI_3|ENABLE,F_DESPDCI_3|ENABLE,F_PREFIX FLAGS "G" FIELD Pdci(2) END diff --git a/ca/ca3200.cpp b/ca/ca3200.cpp index 982380baa..ae3749b98 100755 --- a/ca/ca3200.cpp +++ b/ca/ca3200.cpp @@ -587,17 +587,11 @@ class TPrint_mastrini_ca_rep : public TAnal_report protected: virtual bool set_recordset(const TString& sql); - virtual bool get_usr_val(const TString& name, TVariant& var) const; public: void set_filter(const TPrint_mastrini_ca_mask& msk, int cms_row); }; -bool TPrint_mastrini_ca_rep::get_usr_val(const TString& name, TVariant& var) const -{ - return TAnal_report::get_usr_val(name, var); -} - bool TPrint_mastrini_ca_rep::set_recordset(const TString& sql) { TPrint_mastrini_ca_recordset* rs = new TPrint_mastrini_ca_recordset(sql); diff --git a/ca/ca3300.cpp b/ca/ca3300.cpp index 3c739850c..80a6ac1cc 100755 --- a/ca/ca3300.cpp +++ b/ca/ca3300.cpp @@ -6,6 +6,8 @@ #include "pconana.h" #include "rmovana.h" +#include "../cg/cglib01.h" + #include "ca3.h" #include "calib01.h" #include "calib02.h" @@ -23,6 +25,7 @@ protected: const TString& get_report_class() const; bool test_compatible_report(); + bool esistono_riclassificazioni() const; void create_sheet(); int create_sheet_fields(int lf, int& y, short& dlg, bool required); public: @@ -95,6 +98,21 @@ bool TPrint_bilancio_ca_mask::on_field_event(TOperable_field& o, TField_event e, return error_box("Impossibile trovare un report compatibile"); } break; + case F_PRE1: + case F_PRE2: + case F_PRE3: + if ((e == fe_init || e == fe_modify) && o.active()) + { + const int k = o.dlg()-F_PRE1; + set(F_PAN1_INI + k, o.get(), 0x2); + disable(F_PAN1_INI + k); + disable(F_PANDES1_INI + k); + + set(F_PAN1_FIN + k, o.get(), 0x2); + disable(F_PAN1_FIN + k); + disable(F_PANDES1_FIN + k); + } + break; default: break; } @@ -205,6 +223,11 @@ void TPrint_bilancio_ca_mask::create_sheet() } } +bool TPrint_bilancio_ca_mask::esistono_riclassificazioni() const +{ + TLocalisamfile ric(LF_PANAPDC); + return ric.first() == NOERR; +} TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask() :TAutomask("ca3300") @@ -212,62 +235,152 @@ TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask() TConfig_anal cfg; const bool use_pdcc = cfg.get_bool("UsePdcc"); - const int logicnum = use_pdcc ? LF_PCON : LF_PCONANA; + const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA); + const int pconana_levels = pconana_info.levels(); + + int pconana_prefix = cfg.get_int("PdcPrefix"); + if (pconana_prefix >= pconana_levels) + pconana_prefix = pconana_levels-1; - const int nfields = ca_create_fields(*this, 1, logicnum, 2, 1, F_PDC1_INI, F_DES1_INI, 0x0, PCONANA_CODCONTO); - ca_create_fields(*this, 1, logicnum, 2, 7, F_PDC1_FIN, F_DES1_FIN, 0x0, PCONANA_CODCONTO); + disable(F_PIANO); + set(F_PIANO, use_pdcc ? "C" : "A"); + + // Controllo se voglio (e posso) usare il conto analitico come prefisso di quello contabile + const int pref = cfg.get_int("PdcPrefix"); + if (use_pdcc && pref > 0) + { + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); + const int levels = info.levels(); + if (levels >= 2 && pref < levels && esistono_riclassificazioni()) + { + enable(F_PIANO); + ca_create_fields(*this, 1, LF_PCONANA, 2, 2, F_PRE1, F_PREDES1, 0x0, PCONANA_CODCONTO); + + // Nascondi i campi che non fanno parte del prefisso + for (int i = 0; i < levels; i++) + { + if (i < pref) + { + field(F_PRE1 + i).check_type(CHECK_REQUIRED); + field(F_PRE1 + i).set_group(6); + field(F_PREDES1 + i).set_group(6); + } + else + { + field(F_PRE1 + i).hide(); + field(F_PREDES1 + i).hide(); + } + } + } + } + + for (int g = 5; g <= 6; g++) + { + const int logicnum = g == 5 ? LF_PCON : LF_PCONANA; + const short da_dlg = g == 5 ? F_PDC1_INI : F_PAN1_INI; + const short da_des = g == 5 ? F_PDCDES1_INI : F_PANDES1_INI; + const short a_dlg = g == 5 ? F_PDC1_FIN : F_PAN1_FIN; + const short a_des = g == 5 ? F_PDCDES1_FIN : F_PANDES1_FIN; + + const int nfields = ca_create_fields(*this, 1, logicnum, 2, 8, da_dlg, da_des, 0x0, PCONANA_CODCONTO); + ca_create_fields(*this, 1, logicnum, 2, 14, a_dlg, a_des, 0x0, PCONANA_CODCONTO); + + for (int i = 0; i < nfields; i++) + { + TMask_field& daconto = field(da_dlg + i); + daconto.set_group(1); + daconto.set_group(4); + daconto.set_group(g); + daconto.check_type(CHECK_NORMAL); + + field(da_des+i).set_group(4); + field(da_des+i).set_group(g); + + TMask_field& aconto = field(a_dlg + i); + aconto.set_group(2); + aconto.set_group(4); + aconto.set_group(g); + aconto.check_type(CHECK_NORMAL); + + field(a_des+i).set_group(4); + field(a_des+i).set_group(g); + } + } - for (int i = 0; i < nfields; i++) - { - TMask_field& daconto = field(F_PDC1_INI + i); - daconto.set_group(1); - daconto.check_type(CHECK_NORMAL); - TMask_field& aconto = field(F_PDC1_FIN + i); - aconto.set_group(2); - aconto.check_type(CHECK_NORMAL); - } // creazione dei campi della seconda pagina della maschera create_sheet(); + + set_handlers(); // Setta l'andler universale a tutti i nuovi campi } //////////////////////////////////////////////////////// -// Report +// TReport_bilancio_verifica //////////////////////////////////////////////////////// -class TReport_bilancio_ca : public TAnal_report +class TReport_bilancio_verifica : public TAnal_report { protected: virtual bool set_recordset(const TString& sql); public: void set_filter(const TMask& msk, int row); - TReport_bilancio_ca(const char* name); + TReport_bilancio_verifica(const char* name); }; -bool TReport_bilancio_ca::set_recordset(const TString& /* sql */) +bool TReport_bilancio_verifica::set_recordset(const TString& /* sql */) { TPconana_recordset* rset = new TPconana_recordset(); return TReport::set_recordset(rset); } -void TReport_bilancio_ca::set_filter(const TMask& m, int row) +void TReport_bilancio_verifica::set_filter(const TMask& m, int row) { TString da_conto, a_conto, costo, commessa, fase; - for (int i = 0; m.id2pos(F_PDC1_INI+i) > 0; i++) + + const char tc = m.get(F_PIANO)[0]; // Contabile o Analitico? + const short dlg_da = tc == 'C' ? F_PDC1_INI : F_PAN1_INI; + const short dlg_al = tc == 'C' ? F_PDC1_FIN : F_PAN1_FIN; + + for (int i = 0; m.id2pos(dlg_da+i) > 0; i++) { - da_conto << m.get(F_PDC1_INI+i); - a_conto << m.get(F_PDC1_FIN+i); + da_conto << m.get(dlg_da+i); + a_conto << m.get(dlg_al+i); } - const TDate dal = m.get(F_DATADA); - const TDate al = m.get(F_DATAA); + TDate dal = m.get(F_DATADA); + TDate al = m.get(F_DATAA); int tipimov = 0; switch (m.get(F_TIPOSTAMPA)[0]) { - case 'C': tipimov = 1; break; // Consuntivo - case 'P': tipimov = 6; break; // Preventivo e variazioni - default : tipimov = 7; break; // Raffronto + case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo + case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo + default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto + } + + // 1 = per data limite; 2 = all'ultima immissione + if (m.get_int(F_STAMPA) == 2) + { + const int anno = m.get_int(F_ANNO); + if (anno > 0) + { + TEsercizi_contabili esc; + dal = esc[anno].inizio(); + al = esc[anno].fine(); + } + tipimov |= _saldanal_ultima_imm; + } + + if (tc == 'A' && m.id2pos(F_PRE1) > 0) + { + tipimov |= _saldanal_riclassify; + } + + const TMultilevel_code_info& info = ca_multilevel_code_info(tc == 'A' ? LF_PCONANA : LF_PCON); + for (int s = info.levels()+1; s <= 4; s++) + { + section('H', s).deactivate(); + section('F', s).deactivate(); } const bool movimentati = m.get_int(F_STAMPAV) == 1; @@ -283,42 +396,258 @@ void TReport_bilancio_ca::set_filter(const TMask& m, int row) fase = rel.curr().get(RMOVANA_CODFASE); TPconana_recordset* rset = (TPconana_recordset*)recordset(); - rset->set_filter(da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli); + if (rset != NULL) + rset->set_filter(tc, da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli); } -TReport_bilancio_ca::TReport_bilancio_ca(const char* name) +TReport_bilancio_verifica::TReport_bilancio_verifica(const char* name) { load(name); } +//////////////////////////////////////////////////////// +// TRecordset_sezioni_contapposte +//////////////////////////////////////////////////////// + +class TRecordset_sezioni_contrapposte : public TRecordset +{ + char _tipo_piano; + TAnal_bill _filter; + TDate _da_data, _a_data; + int _tipimov; + bool _movimentati, _nonnulli; + + TString_array _attivita, _passivita, _costi, _ricavi; + TRecnotype _pos; + + TRecordset_column_info _info[4]; + +protected: + TRecnotype items_ap() const; + TRecnotype items_cr() const; + +public: + virtual TRecnotype items() const; + virtual bool move_to(TRecnotype pos); + virtual TRecnotype current_row() const { return _pos; } + virtual void requery(); + + virtual unsigned int columns() const; + virtual const TRecordset_column_info& column_info(unsigned int column) const; + virtual const TVariant& get(unsigned int column) const; + virtual const TVariant& get(const char* field) const; + + void set_filter(char piano, const char* costo, const char* commessa, const char* fase, + const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli); + TRecordset_sezioni_contrapposte(char tipo_piano) : _tipo_piano(tipo_piano) { } +}; + +TRecnotype TRecordset_sezioni_contrapposte::items_ap() const +{ return max(_attivita.items(), _passivita.items()); } + +TRecnotype TRecordset_sezioni_contrapposte::items_cr() const +{ return max(_costi.items(), _ricavi.items()); } + +TRecnotype TRecordset_sezioni_contrapposte::items() const +{ + return items_ap() + items_cr(); +} + +bool TRecordset_sezioni_contrapposte::move_to(TRecnotype pos) +{ + _pos = pos; + return _pos < items(); +} + +void TRecordset_sezioni_contrapposte::set_filter(char piano, const char* costo, + const char* commessa, const char* fase, + const TDate& dal, const TDate& al, + word tipimov, bool movimentati, bool nonnulli) +{ + _tipo_piano = piano; + + _da_data = dal; + _a_data = al; + + _tipimov = tipimov; + _movimentati = movimentati; + _nonnulli = nonnulli; + + _filter.reset(); + _filter.set_costo(costo); + _filter.set_commessa(commessa); + _filter.set_fase(fase); +} + + +void TRecordset_sezioni_contrapposte::requery() +{ + TPconana_recordset pconana(_tipo_piano); + pconana.set_filter(_tipo_piano, NULL, NULL, _filter.costo(), _filter.commessa(), _filter.fase(), + _da_data, _a_data, _tipimov, _movimentati, _nonnulli); + + int indicatore_bilancio = 1; + for (TRecnotype i = 0; pconana.move_to(i); i++) + { + const int ib = pconana.get(PCONANA_INDBIL).as_int(); + if (ib >= 1 && ib <= 4) + indicatore_bilancio = ib; + + const TString& conto = pconana.get(PCONANA_CODCONTO).as_string(); + switch (indicatore_bilancio) + { + case 1: _attivita.add(conto); break; + case 2: _passivita.add(conto); break; + case 3: _costi.add(conto); break; + case 4: _ricavi.add(conto); break; + default: break; + } + } + move_to(0); +} + +unsigned int TRecordset_sezioni_contrapposte::columns() const +{ return 4; } + +const TRecordset_column_info& TRecordset_sezioni_contrapposte::column_info(unsigned int column) const +{ + return _info[column]; +} + +const TVariant& TRecordset_sezioni_contrapposte::get(unsigned int column) const +{ + return NULL_VARIANT; +} + +const TVariant& TRecordset_sezioni_contrapposte::get(const char* field) const +{ + return NULL_VARIANT; +} + +//////////////////////////////////////////////////////// +// TReport_bilancio_sezioni_contapposte +//////////////////////////////////////////////////////// + +class TReport_bilancio_sezioni_contrapposte : public TAnal_report +{ +protected: + virtual bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& sql); + +public: + void set_filter(const TMask& msk, int row); + TReport_bilancio_sezioni_contrapposte(const char* name) { load(name); } +}; + +bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& /* sql */) +{ + TRecordset_sezioni_contrapposte* rset = new TRecordset_sezioni_contrapposte('A'); + return TReport::set_recordset(rset); +} + +void TReport_bilancio_sezioni_contrapposte::set_filter(const TMask& m, int row) +{ + TDate dal = m.get(F_DATADA); + TDate al = m.get(F_DATAA); + + int tipimov = 0; + switch (m.get(F_TIPOSTAMPA)[0]) + { + case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo + case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo + default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto + } + + // 1 = per data limite; 2 = all'ultima immissione + if (m.get_int(F_STAMPA) == 2) + { + const int anno = m.get_int(F_ANNO); + if (anno > 0) + { + TEsercizi_contabili esc; + dal = esc[anno].inizio(); + al = esc[anno].fine(); + } + tipimov |= _saldanal_ultima_imm; + } + + const char tipo = m.get(F_PIANO)[0]; + if (tipo == 'A' && m.id2pos(F_PRE1) > 0) + { + tipimov |= _saldanal_riclassify; + } + + const bool movimentati = m.get_int(F_STAMPAV) == 1; + const bool nonnulli = m.get_int(F_STAMPAV) == 2; + + TSheet_field& sf = m.sfield(F_RIGHE); + TMask& sm = sf.sheet_mask(); + sf.update_mask(row); + TRelation rel(LF_RMOVANA); + sm.autosave(rel); + const TString80 costo = rel.curr().get(RMOVANA_CODCCOSTO); + const TString80 commessa = rel.curr().get(RMOVANA_CODCMS); + const TString16 fase = rel.curr().get(RMOVANA_CODFASE); + + TRecordset_sezioni_contrapposte* recset = new TRecordset_sezioni_contrapposte(tipo); + recset->set_filter(tipo, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli); + TAnal_report::set_recordset(recset); +}; + //////////////////////////////////////////////////////// // APPLICAZIONE //////////////////////////////////////////////////////// + class TPrint_bilancio_ca : public TSkeleton_application { +protected: + void bilancio_a_sezioni_contrapposte(TMask& mask); + void bilancio_di_verifica(TMask& msk); + public: virtual void main_loop(); }; +void TPrint_bilancio_ca::bilancio_a_sezioni_contrapposte(TMask& mask) +{ + TReport_bilancio_sezioni_contrapposte rep(mask.get(F_REPORT)); + + TSheet_field& sf = mask.sfield(F_RIGHE); + const int rows = sf.items(); + TReport_book book; + for (int i = 0; i < rows; i++) + { + rep.set_filter(mask, i); + book.add(rep); + } + book.print_or_preview(); +} + +void TPrint_bilancio_ca::bilancio_di_verifica(TMask& mask) +{ + TReport_bilancio_verifica rep(mask.get(F_REPORT)); + const int rows = mask.sfield(F_RIGHE).items(); + TReport_book book; + for (int i = 0; i < rows; i++) + { + rep.set_filter(mask, i); + book.add(rep); + } + book.print_or_preview(); +} + void TPrint_bilancio_ca::main_loop() { TPrint_bilancio_ca_mask mask; while (mask.run() != K_QUIT) { - TReport_book book; - TReport_bilancio_ca rep(mask.get(F_REPORT)); - TSheet_field& sf = mask.sfield(F_RIGHE); if (sf.empty()) sf.row(-1); // Aggiungo riga vuota - const int rows = sf.items(); - for (int i = 0; i < rows; i++) - { - rep.set_filter(mask, i); - book.add(rep); - } - - book.print_or_preview(); + + if (mask.get(F_BILANCIO) == "C") + bilancio_a_sezioni_contrapposte(mask); + else + bilancio_di_verifica(mask); } } diff --git a/ca/ca3300.h b/ca/ca3300.h index 2e0009518..b62a9948c 100755 --- a/ca/ca3300.h +++ b/ca/ca3300.h @@ -8,22 +8,47 @@ #define F_ANNO 304 #define F_BILANCIO 105 #define F_STAMPA 107 -#define F_CODICI 309 #define F_SALDO 310 #define F_STAMPAV 311 #define F_DATADA 312 #define F_DATAA 313 #define F_TIPOSTAMPA 314 -//campi generati dal pdc -#define F_PDC1_INI 316 -#define F_PDC4_INI 319 -#define F_PDC1_FIN 336 -#define F_PDC4_FIN 339 -#define F_DES1_INI 356 -#define F_DES4_INI 359 -#define F_DES1_FIN 376 -#define F_DES4_FIN 379 +//campi generati dai piani dei conti +#define F_PIANO 319 +#define F_PRE0 320 +#define F_PRE1 321 +#define F_PRE2 322 +#define F_PRE3 323 +// #define F_PRE4 324 // Non puo' e non deve esistere! +#define F_PREDES1 325 +#define F_PREDES2 326 +#define F_PREDES3 327 +// #define F_PREDES4 328 // Non puo' e non deve esistere! + +#define F_PDC0_INI 330 +#define F_PDC1_INI 331 +#define F_PDC4_INI 334 +#define F_PDCDES1_INI 335 +#define F_PDCDES4_INI 338 + +#define F_PDC0_FIN 340 +#define F_PDC1_FIN 341 +#define F_PDC4_FIN 344 +#define F_PDCDES1_FIN 345 +#define F_PDCDES4_FIN 348 + +#define F_PAN0_INI 350 +#define F_PAN1_INI 351 +#define F_PAN4_INI 354 +#define F_PANDES1_INI 355 +#define F_PANDES4_INI 358 + +#define F_PAN0_FIN 360 +#define F_PAN1_FIN 361 +#define F_PAN4_FIN 364 +#define F_PANDES1_FIN 365 +#define F_PANDES4_FIN 368 #define F_SELECT 394 #define F_REPORT 395 diff --git a/ca/ca3300.uml b/ca/ca3300.uml index 17aaa3a59..fe926086f 100755 --- a/ca/ca3300.uml +++ b/ca/ca3300.uml @@ -72,9 +72,9 @@ RADIOBUTTON F_BILANCIO 1 28 BEGIN PROMPT 2 4 "@bBilancio" ITEM "C|A sezioni contrapposte" - MESSAGE HIDE,4@|SHOW,3@ + MESSAGE CLEAR,4@|ENABLE,3@ ITEM "V|Di verifica" - MESSAGE SHOW,4@|HIDE,3@ + MESSAGE ENABLE,4@|CLEAR,3@ END LIST F_TIPOSTAMPA 11 @@ -120,12 +120,6 @@ BEGIN GROUP 4 END -BOOLEAN F_CODICI -BEGIN - PROMPT 42 8 "Non stampare codici conti " - GROUP 4 -END - STRING F_REPORT 256 66 BEGIN PROMPT 2 9 "Report " @@ -154,14 +148,31 @@ ENDPAGE PAGE "Selezioni" -1 -1 74 20 -GROUPBOX DLG_NULL 78 6 +LIST F_PIANO 1 20 BEGIN - PROMPT 1 0 "@bDa:" + PROMPT 1 0 "Piano dei conti " + ITEM "A|Analitico" + MESSAGE HIDE,5@|SHOW,6@ + ITEM "C|Contabile" + MESSAGE SHOW,5@|HIDE,6@ END -GROUPBOX DLG_NULL 78 6 +GROUPBOX F_PRE0 78 6 BEGIN - PROMPT 1 6 "@bA:" + PROMPT 1 1 "@bPrefisso del piano dei conti analitico:" + GROUP 6 +END + +GROUPBOX F_PDC0_INI 78 6 +BEGIN + PROMPT 1 7 "@bDa conto:" + GROUP 4 +END + +GROUPBOX F_PDC0_FIN 78 6 +BEGIN + PROMPT 1 13 "@bA conto:" + GROUP 4 END ENDPAGE diff --git a/ca/ca3300a.rep b/ca/ca3300a.rep index 77bfe89a7..936749af9 100755 --- a/ca/ca3300a.rep +++ b/ca/ca3300a.rep @@ -1,257 +1,34 @@ - - Bilancio di raffronto di verifica - + + Stampa mastrini contabilta' analitica +
- + #SYSTEM.RAGSOC - - #SYSTEM.DATE - - - #REPORT.PAGE - - - - #COSTO - - - MESSAGE ISAMREAD,CDC,CODCOSTO=#COSTO,DESCRIZ - - - - #COMMESSA - - - MESSAGE ISAMREAD,COMMESSE,CODCMS=#COMMESSA,DESCRIZ - - - - #FASE - - - MESSAGE ISAMREAD,FASI,CODCMSFAS=#CMSCDC!CODFASE=#FASE,DESCRIZ - - - - - - - - - - - - - - -
-
- - + +
+
- CODCONTO:2!="" - CODCONTO:1 - "CODCONTO:1" @ -"F2.101" ! - -"F2" AZZERA_TOTALI - -
-
- CODCONTO:3!="" - CODCONTO:2 - "CODCONTO:2" @ -"F3.101" ! - -"F3" AZZERA_TOTALI - -
-
- CODCONTO:4 != "" - CODCONTO:3 - "CODCONTO:3" @ -"F4.101" ! - -"F4" AZZERA_TOTALI - + CODCONTO + +
-
- - CODCONTO - CA_FORMAT_CONTO +
+
+ + #SYSTEM.DATE - - DESCR - - - SALDO:INI_DAREP - - - SALDO:INI_AVEREP - - - SALDO:MOV_DAREP - - - SALDO:MOV_AVEREP - - - SALDO:FIN_DAREP - - - SALDO:FIN_AVEREP - - - SALDO:INI_DAREC - - - SALDO:INI_AVEREC - - - SALDO:MOV_DAREC - - - SALDO:MOV_AVEREC - - - SALDO:FIN_DAREC - - - SALDO:FIN_AVEREC - - - #103-#203 - MESSAGE ADD,F4.103|ADD,F3.103|ADD,F2.103 - - - #104-#204 - MESSAGE ADD,F4.104|ADD,F3.104|ADD,F2.104 - - - #105-#205 - MESSAGE ADD,F4.105|ADD,F3.105|ADD,F2.105 - - - #106-#206 - MESSAGE ADD,F4.106|ADD,F3.106|ADD,F2.106 - - - #107-#207 - MESSAGE ADD,F4.107|ADD,F3.107|ADD,F2.107 - - - #108-#208 - MESSAGE ADD,F4.108|ADD,F3.108|ADD,F2.108 + + #REPORT.PAGE
-
-
- #101 != "" - - #THIS @ #102 ! -CA_FORMAT_CONTO - - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR - - - 103 DARE_AVERE - - - - - - - - - - - 107 DARE_AVERE - - - - -
-
- #101 != "" - - - #THIS @ #102 ! -CA_FORMAT_CONTO - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR - - - 103 DARE_AVERE - - - - - - 107 DARE_AVERE - - -
-
- #101 != "" - - - #THIS @ #102 ! -CA_FORMAT_CONTO - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR - - - 103 DARE_AVERE - - - - - - 107 DARE_AVERE - - -
- USE PCONANA SELECT LEN(CODCONTO)=10 - : AZZERA_TOTALI ( ID_SEC - ) -109 103 DO - DUP \ Duplica codice sezione - "." + \ Aggiunge punto - I + \ Aggiunge codice campo - 0 SWAP ! \ Lo azzera -LOOP -DROP -; - -: DARE_AVERE ( ID_DARE -- ) -VARIABLE _DARE -VARIABLE _AVERE -DUP -_DARE ! -1 + _AVERE ! - -_DARE @ @ \ DARE -_AVERE @ @ \ AVERE -- \ DARE-AVERE -DUP -0 C; IF \ Se negativo - -1 * \ Cambia segno - _AVERE @ ! \ Setta AVERE - 0 _DARE @ ! \ Azzera DARE -ELSE - _DARE @ ! \ Setta DARE - 0 _AVERE @ ! \ Azzera AVERE -THEN -; - +
+ USE RMOVANA +JOIN PCONANA INTO CODCONTO==CODCONTO \ No newline at end of file diff --git a/ca/ca3300b.rep b/ca/ca3300b.rep index 7e97e712c..61472d5c2 100755 --- a/ca/ca3300b.rep +++ b/ca/ca3300b.rep @@ -58,6 +58,8 @@ CODCONTO:1 "CODCONTO:1" @ "F2.101" ! +"DESCR:1" @ +"F2.102" ! "F2" AZZERA_TOTALI @@ -67,6 +69,8 @@ CODCONTO:2 "CODCONTO:2" @ "F3.101" ! +"DESCR:2" @ +"F3.102" ! "F3" AZZERA_TOTALI
@@ -75,6 +79,8 @@ CODCONTO:3 "CODCONTO:3" @ "F4.101" ! \ Copia il codice conto nel footer +"DESCR:3" @ +"F4.102" ! "F4" AZZERA_TOTALI
@@ -119,12 +125,9 @@ #101 != "" - #THIS @ #102 ! -CA_FORMAT_CONTO - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR + CA_FORMAT_CONTO + 103 DARE_AVERE @@ -140,12 +143,9 @@ CA_FORMAT_CONTO #101 != "" - #THIS @ #102 ! -CA_FORMAT_CONTO - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR + CA_FORMAT_CONTO + 103 DARE_AVERE @@ -161,12 +161,9 @@ CA_FORMAT_CONTO #101 != "" - #THIS @ #102 ! -CA_FORMAT_CONTO - - - MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR + CA_FORMAT_CONTO + 103 DARE_AVERE diff --git a/ca/ca3700.cpp b/ca/ca3700.cpp index 76b5ac488..a23ac5d6a 100755 --- a/ca/ca3700.cpp +++ b/ca/ca3700.cpp @@ -460,13 +460,11 @@ void TPrint_rendiconto_ca_alternative_recordset::set_filter(const TPrint_rendico aconto.put(PCONANA_CODCONTO, _aconto); //solo i gr/co/sottoc completi interessano!!! - int contolen = 0; + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); - for (int l = info.levels()-1; l >= 0; l--) - contolen += info.len(l); - + const int min_contolen = info.total_len(-1); TString filtro; - filtro << "LEN(CODCONTO)==" << contolen; + filtro << "STR(LEN(CODCONTO)>" << min_contolen << ')'; TCursor cur_pconana(&rel_pconana, filtro, 1, &daconto, &aconto); const long pconana_items = cur_pconana.items(); diff --git a/ca/ca3900.cpp b/ca/ca3900.cpp index 3a93268cd..ff59a29e6 100755 --- a/ca/ca3900.cpp +++ b/ca/ca3900.cpp @@ -3,6 +3,11 @@ #include #include +#include +#include + +#include "cdc.h" +#include "fasi.h" #include "movana.h" #include "pconana.h" #include "rmovana.h" @@ -11,69 +16,198 @@ #include "calib01.h" #include "../cg/cglib01.h" +class TCode_generator +{ + TRelation* _rel; + TCursor* _cur; + +public: + TRecnotype items() const { return _cur->items(); } + const TString& code(); + + TCode_generator(int logicnum); + ~TCode_generator(); +}; + +const TString& TCode_generator::code() +{ + const TRecnotype i = items(); + if (i > 0) + { + *_cur = rand() % i; + const TRectype& curr = _rel->curr(); + const int logicnum = curr.num(); + switch (logicnum) + { + case LF_CAUSALI: + return curr.get(CAU_CODCAUS); + case LF_CDC: + return curr.get(CDC_CODCOSTO); + case LF_COMMESSE: + return curr.get("CODCMS"); + case LF_FASI: + return curr.get(FASI_CODFASE); + case LF_PCON: + { + TString& tmp = get_tmp_string(12); + tmp.format("%03d%03d%06ld", + curr.get_int(PCN_GRUPPO), curr.get_int(PCN_CONTO), curr.get_long(PCN_SOTTOCONTO)); + return tmp; + } + case LF_PCONANA: + return curr.get(PCONANA_CODCONTO); + default: + break; + } + } + return EMPTY_STRING; +} + + +TCode_generator::TCode_generator(int logicnum) +{ + TWait_cursor hourglass; + TString filter; + + if (logicnum <= 0) + { + TConfig_anal cfg; + const bool use_pdcc = cfg.get_bool("UsePdcc"); + logicnum = use_pdcc ? LF_PCON : LF_PCONANA; + } + + switch (logicnum) + { + case LF_CAUSALI: + filter = "MOVIND=\"X\""; + break; + case LF_PCON: + filter = "SOTTOCONTO!=''"; + break; + case LF_PCONANA: + { + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); + const int min_len = info.total_len(-1); + filter << "STR(NUM(LEN(CODCONTO))>" << min_len << ')'; + } + break; + default: + break; + } + + _rel = new TRelation(logicnum); + _cur = new TCursor(_rel, filter); + const TRecnotype conti = _cur->items(); + _cur->freeze(); +} + +TCode_generator::~TCode_generator() +{ + delete _cur; + delete _rel; +} + //////////////////////////////////////////////////////// // APPLICAZIONE //////////////////////////////////////////////////////// class TRandom_ca : public TSkeleton_application { protected: + bool chiedi_quanti(int& mov, bool& ric); void kill_bill(); + void genera(int quanti); + void genera_riclass(); public: + void riclassify(const TString& conto); virtual void main_loop(); }; +bool TRandom_ca::chiedi_quanti(int& mov, bool& ric) +{ + TMask mask("Movimenti casuali ma perfetti", 1, 60, 6); + + TReal_field& add_number (short id, int page, const char* prompt, int x, int y, int dim, const char* flags = "", int ndec = 0); + mask.add_number(101, 0, "Numero di movimenti ", 1, 1, 4, "U"); + mask.add_boolean(102, 0, "Genera riclassificazioni", 1, 2); + mask.add_static (DLG_NULL, 0, "@bAttenzione: verranno distrutti movimenti e saldi", 1, 3); + mask.add_button(DLG_OK, 0, "", -12, -1, 10, 2); + mask.add_button(DLG_QUIT, 0, "", -22, -1, 10, 2); + mask.set(101, 100); + const bool ok = mask.run() != K_QUIT; + if (ok) + { + mov = (mask.get_int(101)+1)/2; + ric = mask.get_bool(102); + } + + return ok; +} + void TRandom_ca::kill_bill() { - const int lnum[3] = { LF_MOVANA, LF_RMOVANA, LF_SALDANA }; - for (int i = 0; i < 3; i++) + const int lnum[] = { LF_MOVANA, LF_RMOVANA, LF_SALDANA, 0 }; + for (int i = 0; lnum[i]; i++) { TSystemisamfile f(lnum[i]); f.zap(); } } -void TRandom_ca::main_loop() +void TRandom_ca::riclassify(const TString& conto) { - TMask mask("Movimenti casuali ma perfetti", 1, 60, 6); - - TReal_field& add_number (short id, int page, const char* prompt, int x, int y, int dim, const char* flags = "", int ndec = 0); - mask.add_number(101, 0, "Numero di movimenti ", 1, 1, 4, "U"); - mask.add_static (DLG_NULL, 0, "@bAttenzione: verranno distrutti movimenti e saldi", 1, 3); - mask.add_button(DLG_OK, 0, "", -12, -1, 10, 2); - mask.add_button(DLG_QUIT, 0, "", -22, -1, 10, 2); - mask.set(101, 100); - if (mask.run() == K_QUIT) - return; - - kill_bill(); - const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); - TString filter; - int len = 0; - for (int l = info.levels()-1; l >= 0; l--) - len += info.len(l); - filter << "LEN(CODCONTO)==" << len; + const int min_len = info.total_len(-1); + if (conto.len() > min_len) + { + TRecord_array ric(conto, LF_PANAPDC); - TRelation relconti(LF_PCONANA); - TCursor curconti(&relconti, filter); - const TRecnotype conti = curconti.items(); - curconti.freeze(); + TCode_generator conti(LF_PCON); + const int righe = rand() % 4 + 1; + for (int i = 1; i <= righe; i++) + { + TRectype& row = ric.row(i, true); + const TString& c = conti.code(); + row.put(PCN_GRUPPO, c.mid(0, 3)); + row.put(PCN_CONTO, c.mid(3, 3)); + row.put(PCN_SOTTOCONTO, c.mid(6, 6)); + } + ric.write(); + } +} - TRelation relcommesse(LF_COMMESSE); - TCursor curcommesse(&relcommesse); - const TRecnotype commesse = curcommesse.items(); - curcommesse.freeze(); +static bool riclass_callback(const TRelation& rel, void* jolly) +{ + TRandom_ca* myself = (TRandom_ca*)jolly; + const TString80 conto = rel.curr().get(PCONANA_CODCONTO); + myself->riclassify(conto); + return true; +} - TRelation relcaus(LF_CAUSALI); - TCursor curcaus(&relcaus, "MOVIND=\"X\""); - const TRecnotype causali = curcaus.items(); - curcaus.freeze(); +void TRandom_ca::genera_riclass() +{ + { + TSystemisamfile f(LF_PANAPDC); + f.zap(); + } + TRelation rel(LF_PCONANA); + TCursor cur(&rel); + cur.scan(riclass_callback, this, "Generazione riclassificazioni"); +} + +void TRandom_ca::genera(int quanti) +{ TEsercizi_contabili esc; - const int quanti = (mask.get_int(101)+1)/2; - TProgind pi(quanti, "Generazione in corso", FALSE, TRUE); + TCode_generator conti(0); + TCode_generator commesse(LF_COMMESSE); + TCode_generator fasi(LF_FASI); + TCode_generator costi(LF_CDC); + TCode_generator causali(LF_CAUSALI); + + TLocalisamfile fmov(LF_MOVANA); + TProgind pi(quanti, "Generazione movimenti", FALSE, TRUE); for (int m = 0; m < quanti; m++) { pi.addstatus(1); @@ -86,11 +220,7 @@ void TRandom_ca::main_loop() mov.put(MOVANA_ANNOES, esc.date2esc(data)); mov.put(MOVANA_DESCR, "Movimento random preventivo"); mov.put(MOVANA_TIPOMOV, "P"); - if (causali > 0) - { - curcaus = rand() % causali; - mov.put(MOVANA_CODCAUS, curcaus.curr().get("CODCAUS")); - } + mov.put(MOVANA_CODCAUS, causali.code()); const int rows = rand()%10+1; TImporto tot; @@ -100,17 +230,11 @@ void TRandom_ca::main_loop() TRectype& rmov = mov.new_row(); TString80 descr; descr.format("Riga casuale %d", i+1); rmov.put(RMOVANA_DESCR, descr); + rmov.put(RMOVANA_CODCONTO, conti.code()); + rmov.put(RMOVANA_CODCMS, commesse.code()); + rmov.put(RMOVANA_CODFASE, fasi.code()); + rmov.put(RMOVANA_CODCCOSTO, costi.code()); - if (conti > 0) - { - curconti = rand() % conti; - rmov.put(RMOVANA_CODCONTO, curconti.curr().get(PCONANA_CODCONTO)); - } - if (commesse > 0) - { - curcommesse = rand() % commesse; - rmov.put(RMOVANA_CODCMS, curcommesse.curr().get("CODCMS")); - } const TImporto imp(i & 0x1 ? 'A' : 'D', real(10*(rand()%1000+1))); rmov.put(RMOVANA_SEZIONE, imp.sezione()); rmov.put(RMOVANA_IMPORTO, imp.valore()); @@ -121,7 +245,6 @@ void TRandom_ca::main_loop() mov.put(MOVANA_SEZIONE, tot.sezione()); mov.put(MOVANA_TOTDOC, tot.valore()); - TLocalisamfile fmov(LF_MOVANA); mov.write(fmov); // Consuntivo @@ -151,6 +274,22 @@ void TRandom_ca::main_loop() } } +void TRandom_ca::main_loop() +{ + int quanti = 100; + bool ric = false; + if (chiedi_quanti(quanti, ric)) + { + if (quanti > 0) + { + kill_bill(); + genera(quanti); + } + if (ric) + genera_riclass(); + } +} + int ca3900(int argc, char* argv[]) { TRandom_ca a; diff --git a/ca/calib01.cpp b/ca/calib01.cpp index 355692638..e70b90791 100755 --- a/ca/calib01.cpp +++ b/ca/calib01.cpp @@ -61,6 +61,8 @@ int TMultilevel_code_info::levels() const const TString& TMultilevel_code_info::picture(int level) const { + if (level < 0 || level >= levels()) + return EMPTY_STRING; return _picture.row(level); } @@ -86,9 +88,22 @@ int TMultilevel_code_info::len(int level) const { return picture(level).len(); } + +int TMultilevel_code_info::total_len(int level) const +{ + const int max_lev = levels(); + if (level < 0) // -1 = fino al penultimo + level = max_lev+level-1; + int l = 0; + for (int i = 0; i <= level && i < max_lev; i++) + l += picture(i).len(); + return l; +} const TString& TMultilevel_code_info::prompt(int level) const { + if (level < 0 || level >= _prompt.items()) + return EMPTY_STRING; return _prompt.row(level); } diff --git a/ca/calib01.h b/ca/calib01.h index 62852c616..a3d6753d5 100755 --- a/ca/calib01.h +++ b/ca/calib01.h @@ -35,6 +35,7 @@ protected: public: int levels() const; int len(int level) const; + int total_len(int level) const; const TString& picture(int level) const; bool is_numeric_picture(int level) const; bool is_required(int level) const; diff --git a/ca/calib02.cpp b/ca/calib02.cpp index ff6094394..51298d349 100755 --- a/ca/calib02.cpp +++ b/ca/calib02.cpp @@ -4,7 +4,9 @@ #include "calib02.h" #include "../cg/cglib01.h" -#include "../include/rdoc.h" + +#include +#include #include "movana.h" #include "pconana.h" @@ -15,81 +17,151 @@ // TPconana_recordset /////////////////////////////////////////////////////////// -const TVariant& TPconana_recordset::get(const char* column_name) const +const TVariant& TPconana_recordset::get(const char* field) const { - if (strncmp(column_name, "SALDO:", 6) == 0) + const TFixed_string column_name(field); + if (*column_name == '#') { - TString16 sub_field = column_name+6; - const char last = sub_field.right(1)[0]; - int tipimov = 0; - switch (last) + if (strcmp(column_name, "#CMSCDC") == 0) { - case 'C': tipimov = 1; sub_field.rtrim(1); break; // Consuntivo - case 'P': - case 'V': tipimov = 6; sub_field.rtrim(1); break; // Preventivo o variazaione preventivo - default : tipimov = _tipimov; break; + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_FASI); + switch (info.parent()) + { + case LF_CDC : return get_tmp_var() = _bill.costo(); + case LF_COMMESSE: return get_tmp_var() = _bill.commessa(); + default : return NULL_VARIANT; + } + } + if (strcmp(column_name, "#COSTO") == 0) + return get_tmp_var() = _bill.costo(); + if (strcmp(column_name, "#COMMESSA") == 0) + return get_tmp_var() = _bill.commessa(); + if (strcmp(column_name, "#FASE") == 0) + return get_tmp_var() = _bill.fase(); + } + else + { + if (column_name.compare(PCONANA_CODCONTO, 8) == 0) + { + TString80 str; + if (_tipo == 'C') + { + const TBill b(relation()->curr()); + str = b.string(0x8); + } + else + str = TISAM_recordset::get(PCONANA_CODCONTO).as_string(); + + if (column_name[8] == ':') + { + const TMultilevel_code_info& info = ca_multilevel_code_info(_tipo == 'C' ? LF_PCON : LF_PCONANA); + const int level = column_name[9] - '1'; + str.cut(info.total_len(level)); + } + return get_tmp_var() = str; + } + if (column_name.compare(PCONANA_DESCR, 5) == 0) + { + TString80 str; + if (_tipo == 'C') + { + TBill b(relation()->curr()); + if (column_name[5] == ':') + { + if (column_name[6] == '1') + b.set(b.gruppo(), 0, 0); else + if (column_name[6] == '2') + b.set(b.gruppo(), b.conto(), 0); + } + str = b.descrizione(); + } + else + { + if (column_name[5] == ':') + { + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); + const int level = column_name[6] - '1'; + str = TISAM_recordset::get(PCONANA_CODCONTO).as_string(); + str.cut(info.total_len(level)); + str = cache().get(LF_PCONANA, str, PCONANA_DESCR); + } + else + str = TISAM_recordset::get(PCONANA_DESCR).as_string(); + } + return get_tmp_var() = str; } - ((TAnal_bill&)_bill).set_conto(relation()->curr().get(PCONANA_CODCONTO)); - const TSaldanal& s = ca_saldo(_bill, _dal, _al, tipimov); + if (column_name.compare("SALDO:", 6) == 0) + { + TString16 sub_field = column_name+6; + const char last = sub_field.right(1)[0]; + int tipimov = 0; + switch (last) + { + case 'C': tipimov = _saldanal_consuntivo; sub_field.rtrim(1); break; // Consuntivo + case 'P': + case 'V': tipimov = _saldanal_preventivi; sub_field.rtrim(1); break; // Preventivo o variazione preventivo + default : tipimov = _tipimov; break; + } - TVariant& var = get_tmp_var(); - if (strcmp(sub_field, "INI_DARE") == 0) - { - var = s._ini.sezione() == 'D' ? s._ini.valore() : ZERO; - } else - if (strcmp(sub_field, "INI_AVERE") == 0) - { - var = s._ini.sezione() == 'A' ? s._ini.valore() : ZERO; - } else - if (strcmp(sub_field, "MOV_DARE") == 0) - { - var = s._dare.valore(); - } else - if (strcmp(sub_field, "MOV_AVERE") == 0) - { - var = s._avere.valore(); - } else - if (strcmp(sub_field, "FIN_DARE") == 0) - { - var = s._fin.sezione() == 'D' ? s._fin.valore() : ZERO; - } else - if (strcmp(sub_field, "FIN_AVERE") == 0) - { - var = s._fin.sezione() == 'A' ? s._fin.valore() : ZERO; - } - return var; - } - if (strcmp(column_name, "#CMSCDC") == 0) - { - const TMultilevel_code_info& info = ca_multilevel_code_info(LF_FASI); - switch (info.parent()) - { - case LF_CDC : column_name = "#COSTO"; break; - case LF_COMMESSE: column_name = "#COMMESSA"; break; - default : return NULL_VARIANT; + ((TAnal_bill&)_bill).set_conto(get(PCONANA_CODCONTO).as_string()); + const TSaldanal& s = ca_saldo(_bill, _dal, _al, tipimov); + + TVariant& var = get_tmp_var(); + if (strcmp(sub_field, "INI_DARE") == 0) + { + var = s._ini.sezione() == 'D' ? s._ini.valore() : ZERO; + } else + if (strcmp(sub_field, "INI_AVERE") == 0) + { + var = s._ini.sezione() == 'A' ? s._ini.valore() : ZERO; + } else + if (strcmp(sub_field, "MOV_DARE") == 0) + { + var = s._dare.valore(); + } else + if (strcmp(sub_field, "MOV_AVERE") == 0) + { + var = s._avere.valore(); + } else + if (strcmp(sub_field, "FIN_DARE") == 0) + { + var = s._fin.sezione() == 'D' ? s._fin.valore() : ZERO; + } else + if (strcmp(sub_field, "FIN_AVERE") == 0) + { + var = s._fin.sezione() == 'A' ? s._fin.valore() : ZERO; + } + return var; } } - if (strcmp(column_name, "#COSTO") == 0) - return get_tmp_var() = _bill.costo(); - if (strcmp(column_name, "#COMMESSA") == 0) - return get_tmp_var() = _bill.commessa(); - if (strcmp(column_name, "#FASE") == 0) - return get_tmp_var() = _bill.fase(); - return TISAM_recordset::get(column_name); } bool TPconana_recordset::valid_record(const TRelation& rel) const { + TString80 conto; + if (_tipo == 'C') + { + const TBill b(rel.curr()); + if (b.sottoconto() <= 0 || !b.is_analitico()) + return false; + conto = b.string(0x8); + } + else + { + conto = rel.curr().get(PCONANA_CODCONTO); + if (conto.len() <= _conto_minlen) + return false; + } + if (_movimentati || _nonnulli) { - const TString& conto = rel.curr().get(PCONANA_CODCONTO); ((TAnal_bill&)_bill).set_conto(conto); const TSaldanal& s = ca_saldo(_bill, _dal, _al, _tipimov); if (_movimentati && !s._movimentato) return false; - if (_nonnulli && s._ini.is_zero() && s._dare.is_zero() && s._avere.is_zero()) + if (_nonnulli && s._fin.is_zero()) return false; } return true; @@ -102,33 +174,57 @@ bool TPconana_recordset::pianoconti_filter(const TRelation* rel) void TPconana_recordset::set_custom_filter(TCursor& cursor) const { - TString filter; - filter << "LEN(" << PCONANA_CODCONTO << ")==" << _contolen; - cursor.setfilter(filter); - - TRectype darec(LF_PCONANA), arec(LF_PCONANA); - darec.put(PCONANA_CODCONTO, _da_conto); - arec.put(PCONANA_CODCONTO, _a_conto); - cursor.setregion(darec, arec); - - if (_movimentati || _nonnulli) + if (_tipo == 'C') { - _current_recset = this; - cursor.set_filterfunction(pianoconti_filter); + TRectype darec(LF_PCON), arec(LF_PCON); + darec.put(PCN_GRUPPO, _da_conto.mid(0,3)); + darec.put(PCN_CONTO, _da_conto.mid(3,3)); + darec.put(PCN_SOTTOCONTO, _da_conto.mid(6,6)); + arec.put(PCN_GRUPPO, _a_conto.mid(0,3)); + arec.put(PCN_CONTO, _a_conto.mid(3,3)); + arec.put(PCN_SOTTOCONTO, _a_conto.mid(6,6)); + cursor.setregion(darec, arec); } else - cursor.set_filterfunction(NULL); + { + TRectype darec(LF_PCONANA), arec(LF_PCONANA); + darec.put(PCONANA_CODCONTO, _da_conto); + arec.put(PCONANA_CODCONTO, _a_conto); + cursor.setregion(darec, arec); + } + + _current_recset = this; + cursor.set_filterfunction(pianoconti_filter); } -void TPconana_recordset::set_filter(const char* da_conto, const char* a_conto, +void TPconana_recordset::set_tipo(char tipo) +{ + if (tipo != 'A' && tipo != 'C') + { + TConfig_anal cfg; + tipo = cfg.get_bool("UsePdcc") ? 'C' : 'A'; + } + _tipo = tipo; + + if (_tipo == 'A') + { + set("USE PCONANA"); + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); + _conto_minlen = info.total_len(-1); // Lunghezza fino al penultimo livello + } + else + { + set("USE PCON"); + _conto_minlen = 6; // Gruppo(3)+Conto(3) + } +} + +void TPconana_recordset::set_filter(char tipo, const char* da_conto, const char* a_conto, const char* costo, const char* commessa, const char* fase, const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli) { - _contolen = 0; - const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); - for (int l = info.levels()-1; l >= 0; l--) - _contolen += info.len(l); + set_tipo(tipo); _da_conto = da_conto; _a_conto = a_conto; @@ -146,50 +242,15 @@ void TPconana_recordset::set_filter(const char* da_conto, const char* a_conto, _bill.set_fase(fase); } -TPconana_recordset::TPconana_recordset() : TISAM_recordset("USE PCONANA") -{ } - +TPconana_recordset::TPconana_recordset(char tipo) : TISAM_recordset("USE PCONANA") +{ + set_tipo(tipo); +} /////////////////////////////////////////////////////////// // TAnal_report /////////////////////////////////////////////////////////// -bool TAnal_report::get_usr_val(const TString& name, TVariant& var) const -{ - // CODCONTO:1, CODCMS:3, FASCMS:2, ecc... - const int namelen = name.len(); - if (namelen >= 6 && name[namelen-2] == ':') - { - int logicnum = 0; - if (name.starts_with("CODCONTO:")) - logicnum = LF_PCONANA; else - if (name.starts_with("CODCMS:")) - logicnum = LF_COMMESSE; else - if (name.starts_with("CODCOSTO:")) - logicnum = LF_CDC; else - if (name.starts_with("FASCMS:")) - logicnum = LF_FASI; - if (logicnum > 0) - { - const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum); - const int level = name[namelen-1]-'1'; - if (level < mci.levels()) - { - TString16 fldname = name; fldname.cut(namelen-2); - TFieldref field = mci.fieldref(level); - field.set_name(fldname); - field.set_from(0); - fldname.cut(0) << field; // Trasformo il TFieldref in stringa! - get_record_field(fldname, var); - } - else - var.set_null(); - return true; - } - } - return TReport::get_usr_val(name, var); -} - size_t TAnal_report::get_usr_words(TString_array& words) const { TReport::get_usr_words(words); @@ -223,19 +284,9 @@ void TAnal_report::msg_format(int logicnum, TVariant_stack& stack) if (separator.not_empty()) { const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum); - TString str_out; - for (int i = 0; i < mci.levels(); i++) - { - const TFieldref& fld = mci.fieldref(i); - const TString& str = str_in.sub(fld.from(), fld.to()); - if (str.not_empty()) - { - if (i > 0) str_out << separator; - str_out << str; - } - else - break; - } + TString80 str_out = str_in; + for (int i = mci.levels()-2; i >= 0; i--) + str_out.insert(separator, mci.total_len(i)); curr_field()->set(str_out); } } @@ -251,7 +302,16 @@ void TAnal_report::msg_format_fase (TVariant_stack& stack) { msg_format(LF_FASI, stack); } void TAnal_report::msg_format_conto (TVariant_stack& stack) -{ msg_format(LF_PCONANA, stack); } +{ + // Cerca di determinare se si usa il piano contabile o analitico + const TFixed_string gruppo(PCN_GRUPPO); + TVariant var; + get_record_field(gruppo, var); + if (var.is_null()) + msg_format(LF_PCONANA, stack); + else + msg_format(LF_PCON, stack); +} void TAnal_report::msg_format_commessa_costo(TVariant_stack& stack) { @@ -368,10 +428,7 @@ bool TAnal_bill::get(const TRectype& rec) return ok; } -TAnal_bill::TAnal_bill() -{ } - -TAnal_bill::TAnal_bill(const TAnal_bill& b) +void TAnal_bill::copy(const TAnal_bill& b) { set_conto(b.conto()); set_costo(b.costo()); @@ -379,6 +436,18 @@ TAnal_bill::TAnal_bill(const TAnal_bill& b) set_fase(b.fase()); } +const TAnal_bill& TAnal_bill::operator=(const TAnal_bill& b) +{ + copy(b); + return *this; +} + +TAnal_bill::TAnal_bill() +{ } + +TAnal_bill::TAnal_bill(const TAnal_bill& b) +{ copy(b); } + TAnal_bill::TAnal_bill(const char* conto, const char* costo, const char* commessa, const char* fase) { set_conto(conto); @@ -392,90 +461,209 @@ TAnal_bill::TAnal_bill(const TRectype& rec) get(rec); } -/////////////////////////////////////////////////////////// -// TAnal_balance -/////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +// TRiclassify_cache +//////////////////////////////////////////////////////// -class TAnal_balance : public TObject +class TRiclassify_cache : public TCache { + int _conto_min; + +protected: + virtual TObject* key2obj(const char* key); + void extract(const char* conto, TString_array& conti) const; + public: - TImporto saldo_fine_anno(const TAnal_bill& bill, int annofin, word tipo) const; - bool saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const; - bool saldi(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const; + const TString_array& conti(const TString& conto); + TRiclassify_cache(); }; -TImporto TAnal_balance::saldo_fine_anno(const TAnal_bill& b, int anno, word tipo) const +void TRiclassify_cache::extract(const char* conto, TString_array& conti) const { - TImporto saldo; - - if (anno > 0) + TRecord_array table(conto, LF_PANAPDC); + for (int r = table.last_row(); r > 0; r = table.pred_row(r)) { - TString query, select; - - if (b.costo().not_empty()) - select << "(CODCOSTO=='" << b.costo() << "')"; - if (b.commessa().not_empty()) - { - if (select.not_empty()) select << "&&"; - select << "(CODCMS=='" << b.commessa() << "')"; - } - if (b.fase().not_empty()) - { - if (select.not_empty()) select << "&&"; - select << "(FASCMS=='" << b.fase() << "')"; - } - if (b.conto().not_empty()) - { - if (select.not_empty()) select << "&&"; - select << "(CONTO=='" << b.conto() << "')"; - } - - query << "USE SALDANA"; - if (select.not_empty()) - query << " SELECT " << select; - if (anno > 0) - query << "\nTO ANNO=" << anno << '\n'; - - TISAM_recordset saldini(query); - - for (int i = 0; i < saldini.items(); i++) - { - if (tipo & 1) - { - const char sez = saldini.get(SALDANA_SEZIONE).as_string()[0]; - const real imp = saldini.get(SALDANA_SALDO).as_real(); - saldo += TImporto(sez, imp); - } - if (tipo & 2) - { - const char sez = saldini.get(SALDANA_SEZIONEP).as_string()[0]; - const real imp = saldini.get(SALDANA_SALDOP).as_real(); - saldo += TImporto(sez, imp); - } - if (tipo & 4) - { - const char sez = saldini.get(SALDANA_SEZIONEV).as_string()[0]; - const real imp = saldini.get(SALDANA_SALDOV).as_real(); - saldo += TImporto(sez, imp); - } - } - saldo.normalize(); + const TRectype& row = table.row(r); + const TBill b(row); + conti.add(b.string(0x8)); } - - return saldo; } -bool TAnal_balance::saldo_movimenti(const TAnal_bill& b, - const TDate& dal, const TDate& al, word tipo, - TSaldanal& s) const +TObject* TRiclassify_cache::key2obj(const char* key) +{ + TString_array* k = new TString_array; + if (key && int(strlen(key)) > _conto_min) + { + extract(key, *k); + } + else + { + TString query = "USE PCONANA"; + if (key && *key) + { + query << "\nFROM CODCONTO=" << key; + query << "\nTO CODCONTO=" << key; + } + TISAM_recordset pconana(query); + for (TRecnotype i = 0; pconana.move_to(i); i++) + { + const TString& conto = pconana.get(PCONANA_CODCONTO).as_string(); + extract(conto, *k); + } + } + return k; +} + +const TString_array& TRiclassify_cache::conti(const TString& conto) +{ + return *(const TString_array*)objptr(conto); +} + +TRiclassify_cache::TRiclassify_cache() : TCache(7) +{ + const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); + _conto_min = info.total_len(-1); // Lunghezza conti fino al penultimo livello +} + + +//////////////////////////////////////////////////////// +// TSaldi_cache +//////////////////////////////////////////////////////// + +class TSaldi_cache : private TCache +{ + TEsercizi_contabili _esc; + TRiclassify_cache _riclass; + +protected: + virtual TObject* key2obj(const char* key); + + bool int_saldo_annuale(const TAnal_bill& bill, int annoini, int annofin, word tipo, TImporto& dare, TImporto& avere) const; + bool int_saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const; + +protected: + bool saldo_annuale(const TAnal_bill& bill, int annoini, int annofin, word tipo, TImporto& dare, TImporto& avere); + bool saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s); + bool saldi(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s); + +public: + const TSaldanal& saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 0x1); + TSaldi_cache(); +}; + +// 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 +{ + CHECKD(ad_anno > 0, "Anno saldo finale errato: ", ad_anno); + + bool movim = false; + TString query, select; + + if (b.costo().not_empty()) + select << "(COSTO=='" << b.costo() << "')"; + if (b.commessa().not_empty()) + { + if (select.not_empty()) select << "&&"; + select << "(COMMESSA=='" << b.commessa() << "')"; + } + if (b.fase().not_empty()) + { + if (select.not_empty()) select << "&&"; + select << "(FASE=='" << b.fase() << "')"; + } + if (b.conto().not_empty() && da_anno != ad_anno) + { + if (select.not_empty()) select << "&&"; + select << "(CONTO[1," << b.conto().len() << "]=='" << b.conto() << "')"; + } + + query << "USE SALDANA"; + if (select.not_empty()) + query << " SELECT " << select; + if (da_anno > 0) + { + query << "\nFROM ANNO=" << da_anno; + if (b.conto().not_empty()) + query << " CONTO='" << b.conto() << '\''; + query << '\n'; + } + + query << "\nTO ANNO=" << ad_anno; + if (b.conto().not_empty()) + query << " CONTO='" << b.conto() << '\''; + query << '\n'; + + TISAM_recordset saldini(query); + + for (TRecnotype i = 0; saldini.move_to(i); i++) + { + char sez = ' '; + real imp; + if (tipo & _saldanal_consuntivo) + { + sez = saldini.get(SALDANA_SEZIONE).as_string()[0]; + imp = saldini.get(SALDANA_SALDO).as_real(); + } + if (tipo & _saldanal_preventivo) + { + sez = saldini.get(SALDANA_SEZIONEP).as_string()[0]; + imp = saldini.get(SALDANA_SALDOP).as_real(); + } + if (tipo & _saldanal_variazione) + { + sez = saldini.get(SALDANA_SEZIONEV).as_string()[0]; + imp = saldini.get(SALDANA_SALDOV).as_real(); + } + if (sez > ' ') + { + if (sez == 'D') + dare += TImporto('D', imp); + else + avere += TImporto('A', imp); + movim = true; + } + } + + return movim; +} + +bool TSaldi_cache::saldo_annuale(const TAnal_bill& b, int da_anno, int ad_anno, word tipo, + TImporto& dare, TImporto& avere) +{ + bool movim = false; + if (ad_anno > 0) + { + if (tipo & _saldanal_riclassify) + { + // Legge tabella di riclassificazione + const TString_array& table = _riclass.conti(b.conto()); + if (!table.empty()) + { + TAnal_bill c(b); // Conto riclassificato + FOR_EACH_ARRAY_ROW(table, i, row) + { + c.set_conto(*row); + movim |= int_saldo_annuale(c, da_anno, ad_anno, tipo, dare, avere); + } + } + } + else + movim = int_saldo_annuale(b, da_anno, ad_anno, tipo, dare, avere); + } + return movim; +} + +bool TSaldi_cache::int_saldo_movimenti(const TAnal_bill& b, + const TDate& dal, const TDate& al, + word tipo, TSaldanal& s) const { TDate dataini; if (dal.ok()) { - TEsercizi_contabili esc; - const int annoprec = esc.date2prevesc(dal); + const int annoprec = _esc.date2prevesc(dal); if (annoprec > 0) - dataini = esc[annoprec].fine()+1L; + dataini = _esc[annoprec].fine()+1L; } TString query, select; @@ -504,7 +692,9 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b, query << "SELECT " << select << "\n"; // Faccio la join solo se mi serve il tipo movimento in testata - if (tipo != 0 && tipo != 7) + const bool filtra_tipo = (tipo & _saldanal_qualsiasi) != 0 && + (tipo & _saldanal_qualsiasi) != _saldanal_qualsiasi; + if (filtra_tipo) query << "JOIN MOVANA INTO NUMREG==NUMREG\n"; query << "FROM CODCONTO=" << b.conto(); @@ -519,22 +709,19 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b, TISAM_recordset rmovana(query); - s._movimentato = false; - for (int i = 0; i < rmovana.items(); i++) + for (TRecnotype i = 0; rmovana.move_to(i); i++) { - rmovana.move_to(i); - // Controllo il tipo movimento solo se necessario - if (tipo != 0 && tipo != 7) + if (filtra_tipo) { const char tipomov = rmovana.get("107.TIPOMOV").as_string()[0]; int ntipomov = 0; if (tipomov == 'P') - ntipomov = 2; else + ntipomov = _saldanal_preventivo; else if (tipomov == 'V') - ntipomov = 4; + ntipomov = _saldanal_variazione; else - ntipomov = 1; + ntipomov = _saldanal_consuntivo; if ((ntipomov & tipo) == 0) continue; } @@ -555,40 +742,69 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b, s._ini += imp; } } + return s._movimentato; +} + +bool TSaldi_cache::saldo_movimenti(const TAnal_bill& b, + const TDate& dal, const TDate& al, + word tipo, TSaldanal& s) +{ + bool movim = false; + if (tipo & _saldanal_riclassify) + { + // Legge tabella di riclassificazione + const TString_array& table = _riclass.conti(b.conto()); + if (!table.empty()) + { + TAnal_bill c(b); // Conto riclassificato + FOR_EACH_ARRAY_ROW(table, i, row) + { + c.set_conto(*row); + movim |= int_saldo_movimenti(c, dal, al, tipo, s); + } + } + } + else + movim = int_saldo_movimenti(b, dal, al, tipo, s); + return movim; +} + +bool TSaldi_cache::saldi(const TAnal_bill& bill, + const TDate& dal, const TDate& al, word tipo, + TSaldanal& s) +{ + // Calcolo i saldi fino all'anno scorso. + // In assemza di data iniziale mi torna 0 + const int anno_prec = _esc.date2prevesc(dal); + if (anno_prec > 0) + { + TImporto dare, avere; + saldo_annuale(bill, 0, anno_prec, tipo, dare, avere); + s._ini = dare; + s._ini += avere; + } + + if (tipo & _saldanal_ultima_imm) + { + // Calcolo i saldi di quest'anno + // In assemza di data iniziale somma tutti gli anni (fino al 9999) + const int anno_ini = _esc.date2esc(dal); + const int anno_fin = anno_ini > 0 ? anno_ini : 9999; + s._movimentato = saldo_annuale(bill, anno_ini, anno_fin, tipo, s._dare, s._avere); + } + else + { + saldo_movimenti(bill, dal, al, tipo, s); + } s._ini.normalize(); s._fin = s._ini; s._fin += s._dare; s._fin += s._avere; s._fin.normalize(); + return s._movimentato; } -bool TAnal_balance::saldi(const TAnal_bill& bill, - const TDate& dal, const TDate& al, word tipo, - TSaldanal& s) const -{ - TEsercizi_contabili esc; - const int annoprec = esc.date2prevesc(dal); - s._ini = saldo_fine_anno(bill, annoprec, tipo); - return saldo_movimenti(bill, dal, al, tipo, s); -} - -//////////////////////////////////////////////////////// -// TSaldi_cache -//////////////////////////////////////////////////////// - -class TSaldi_cache : private TCache -{ - TAnal_balance _bal; - -protected: - virtual TObject* key2obj(const char* key); - -public: - const TSaldanal& saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 0x1); - TSaldi_cache() : TCache(3883) { } -}; - TObject* TSaldi_cache::key2obj(const char* key) { TSaldanal* s = new TSaldanal; @@ -598,7 +814,7 @@ TObject* TSaldi_cache::key2obj(const char* key) const TDate dal = tok.get(4); // Le get precedenti avvengono in ordine inverso! const TDate al = tok.get(); const int tipo = tok.get_int(); - s->_movimentato = _bal.saldi(bill, dal, al, tipo, *s); + s->_movimentato = saldi(bill, dal, al, tipo, *s); return s; } @@ -615,6 +831,10 @@ const TSaldanal& TSaldi_cache::saldo(const TAnal_bill& bill, const TDate& dal, c return *(const TSaldanal*)objptr(key); } + +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; diff --git a/ca/calib02.h b/ca/calib02.h index 93ad522ed..93bdd71f9 100755 --- a/ca/calib02.h +++ b/ca/calib02.h @@ -14,6 +14,9 @@ class TAnal_bill : public TSortable { TString _conto, _costo, _commessa, _fase; +protected: + void copy(const TAnal_bill& bill); + public: virtual int compare(const TSortable& s) const; bool match(const TAnal_bill& b) const; @@ -32,6 +35,8 @@ public: bool get(const TRectype& rec); void reset(); + const TAnal_bill& operator=(const TAnal_bill& bill); + TAnal_bill(); TAnal_bill(const TAnal_bill& bill); TAnal_bill(const char* conto, const char* costo, const char* commessa, const char* fase); @@ -42,7 +47,13 @@ public: // TAnal_balance /////////////////////////////////////////////////////////// -// Tipi di saldo: 1 = Normale; 2 = Preventivo; 4 = Variazione preventivo; 7 = Tutti +#define _saldanal_consuntivo 0x1 +#define _saldanal_preventivo 0x2 +#define _saldanal_variazione 0x4 +#define _saldanal_preventivi 0x6 +#define _saldanal_qualsiasi 0x7 +#define _saldanal_ultima_imm 0x8 +#define _saldanal_riclassify 0x10 struct TSaldanal : public TObject { @@ -50,7 +61,7 @@ struct TSaldanal : public TObject bool _movimentato; }; -const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 1); +const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = _saldanal_consuntivo); //////////////////////////////////////////////////////// // TPconana_recordset @@ -58,9 +69,10 @@ const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& class TPconana_recordset : public TISAM_recordset { + char _tipo; word _tipimov; TString _da_conto, _a_conto; - int _contolen; + int _conto_minlen; TAnal_bill _bill; TDate _dal, _al; bool _movimentati, _nonnulli; @@ -74,12 +86,12 @@ protected: public: virtual const TVariant& get(const char* column_name) const; - void set_filter(const char* da_conto, const char* a_conto, + void set_tipo(char tipo); + void set_filter(char tipo, const char* da_conto, const char* a_conto, const char* costo, const char* commessa, const char* fase, const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli); - - TPconana_recordset(); + TPconana_recordset(char tipo = ' '); }; /////////////////////////////////////////////////////////// @@ -91,7 +103,6 @@ class TAnal_report : public TReport unsigned int _first_msg; protected: // protected is safer - virtual bool get_usr_val(const TString& name, TVariant& var) const; virtual size_t get_usr_words(TString_array& words) const; virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); virtual bool use_mask() { return false;} diff --git a/ca/f151.trr b/ca/f151.trr index b838bd1ee..ae29a37fe 100755 --- a/ca/f151.trr +++ b/ca/f151.trr @@ -12,4 +12,4 @@ SALDOP|4|18|3|Saldo (Preventivo) SEZIONEV|7|1|0|Sezione (Variazione preventivo) SALDOV|4|18|3|Saldo (Variazione preventivo) 1 -ANNO+COSTO+COMMESSA+FASE+CONTO| +ANNO+CONTO+COSTO+COMMESSA+FASE| diff --git a/ca/pconana.h b/ca/pconana.h index e8b9bc4f0..5f872ce65 100755 --- a/ca/pconana.h +++ b/ca/pconana.h @@ -1,9 +1,10 @@ #ifndef __PCONANA_H #define __PCONANA_H -#define PCONANA_CODCONTO "CODCONTO" -#define PCONANA_DESCR "DESCR" -#define PCONANA_SEZSALDI "SEZSALDI" -#define PCONANA_SOSPESO "SOSPESO" +#define PCONANA_CODCONTO "CODCONTO" +#define PCONANA_DESCR "DESCR" +#define PCONANA_SEZSALDI "SEZSALDI" +#define PCONANA_SOSPESO "SOSPESO" +#define PCONANA_INDBIL "INDBIL" #endif