#include #include #include #include "ce3.h" #include "celib.h" #include "../cg/cglib01.h" #include "ce2101.h" #include "ce3300a.h" #include "ce3300.h" #include "ammce.h" #include "ammmv.h" #include "cespi.h" #include "movam.h" #include "movce.h" #include "salce.h" //===============================================================================================// //-----FORM--------------------------------------------------------------------------------------// class TForm_prospettocesp : public TForm_cespiti { public: virtual bool validate(TForm_item &cf, TToken_string &s); void set_testata() {set_header(1,TRUE);} void set_pedata() {set_footer(1,FALSE); set_footer(1,TRUE);} TPrint_section& get_body() {return section('B', odd_page);} TForm_prospettocesp(); virtual ~TForm_prospettocesp(); }; TForm_prospettocesp::TForm_prospettocesp() :TForm_cespiti ("ce3300a") //costruttore { } TForm_prospettocesp::~TForm_prospettocesp() { } bool TForm_prospettocesp::validate(TForm_item &cf, TToken_string &s) { return TForm_cespiti::validate(cf,s); //richiama la validate standard della classe genitore (TForm_cespiti) } //==============================================================================================// //-----AUTOMASK---------------------------------------------------------------------------------// class TStampaprospetto_mask : public TAutomask { TRelation * _rel; TCursor * _cur; protected: bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TStampaprospetto_mask(); virtual ~TStampaprospetto_mask(){}; }; TStampaprospetto_mask::TStampaprospetto_mask() :TAutomask ("ce3300a") { ditta_cespiti().init_mask(* this); } bool TStampaprospetto_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_SITFISC : if (e == fe_close) { if (!get_bool(F_SITFISC) && !get_bool(F_SITCIV) && !get_bool(F_SITGEST)) //deve essere selezionata almeno 1 situaz. return error_box(TR("Selezionare almeno una delle Situazioni da stampare")); } break; default: break; } return TRUE; } //=======================================================================================================================// struct TTotali : public TObject { real _tot_csto; real _tot_riv; real _tot_riveser; real _tot_acqincr; real _tot_cesselim2; real _tot_fondinieser; real _tot_incr; real _tot_cesselim3; real _tot_reinplus; real _tot_ammnor; real _tot_ammacc; real _tot_ammant; void azzera(); TTotali& operator += (const TTotali& t); }; void TTotali::azzera() { _tot_csto = 0; _tot_riv = 0; _tot_riveser = 0; _tot_acqincr = 0; _tot_cesselim2 = 0; _tot_fondinieser = 0; _tot_incr = 0; _tot_cesselim3 = 0; _tot_reinplus = 0; _tot_ammnor = 0; _tot_ammacc = 0; _tot_ammant = 0; } //-----------------------------------------------------------------------------------------------------------------------// TTotali& TTotali::operator += (const TTotali& t) { _tot_csto += t._tot_csto; _tot_riv += t._tot_riv; _tot_riveser += t._tot_riveser; _tot_acqincr += t._tot_acqincr; _tot_cesselim2 += t._tot_cesselim2; _tot_fondinieser += t._tot_fondinieser; _tot_incr += t._tot_incr; _tot_cesselim3 += t._tot_cesselim3; _tot_reinplus += t._tot_reinplus; _tot_ammnor += t._tot_ammnor; _tot_ammacc += t._tot_ammacc; _tot_ammant += t._tot_ammant; return *this; //ritorna se stesso, quindi i valori dei totali } //=======================================================================================================================// //-----SKELETON APPLICATION----------------------------------------------------------------------------------------------// class TStampa_prospetto : public TSkeleton_application { TStampaprospetto_mask * _mask; TForm_prospettocesp * _form; protected: virtual bool create(); virtual bool destroy(); virtual void main_loop(); void set_intestazione( const int tipo, const int ordinamento); void set_pavimentazione(); void stampa_totali_cat(const TString& codicecat, const TString& descrcat); //stampa sul form i valori totali per categoria void stampa_totali_tipo(TTipo_cespite tcesp); //stampa sul form i valori totali per tipo cespite (materiale, immateriale, pluriennale) void stampa_totali_generali(); //stampa sul form i valori totali per tutti i cespiti void fill_body(const TTotali& tot); //riempie il campo body con tutti i totali void print_body(); //stampa effettivamente il body void set_field(int id, const real& val); //mette in un campo del body odd un valore numerico void set_field(int id, const char* val); //mette in un campo del body odd una stringa void aggiorna_totali(TCursor& cur, const int tipo, TTipo_cespite tcesp); //calcola effettivamente i totali di ciascuna categoria public: TStampa_prospetto() {} private: TDate _dataini; TDate _datafine; TTotali _cat, _mtr, _gen; //sono i tre set di totali (categoria, materiali, generali) }; bool TStampa_prospetto::create() { open_files(LF_CESPI, LF_SALCE, LF_AMMCE, LF_MOVCE, LF_AMMMV, 0); _mask = new TStampaprospetto_mask; _form = new TForm_prospettocesp; return TSkeleton_application::create(); } bool TStampa_prospetto::destroy() { delete _mask; delete _form; return TSkeleton_application::destroy(); } //------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::set_intestazione( const int tipo, const int ordinamento) { // scrive l'header first, contenente i dati della ditta e dell'esercizio _form->find_field('H', first_page, FR_CODDITTA).set(_mask->get(F_CODDITTA)); _form->find_field('H', first_page, FR_RAGSOC).set(_mask->get(F_DESCRDITTA)); _form->find_field('H', first_page, FR_GRUPPO).set(_mask->get(F_GRUPPO)); _form->find_field('H', first_page, FR_D_GRUPPO).set(_mask->get(F_D_GRUPPO)); _form->find_field('H', first_page, FR_SPECIE).set(_mask->get(F_SPECIE)); _form->find_field('H', first_page, FR_D_SPECIE).set(_mask->get(F_D_SPECIE)); _form->find_field('H', first_page, FR_DATAINIZIO).set(_dataini); _form->find_field('H', first_page, FR_DATAFINE).set(_datafine); // in base all'ordinamento (per categoria o per impianto) scrive la riga con codice e descrizione if (ordinamento == 0) { _form->find_field('H', first_page, FR_INT_COD).set(FR("@bCat.@r")); _form->find_field('H', first_page, FR_INT_DESC).set(FR("@bDescrizione categoria@r")); } else { _form->find_field('H', first_page, FR_INT_COD).set(TR("Imp.")); _form->find_field('H', first_page, FR_INT_DESC).set(TR(" Descr. impianto")); } //in base al(ai) tipo(i) di situazione cambia una riga dell'header switch(tipo) { case 1: _form->find_field('H', first_page, FR_SITUAZIONE).set(TR("fiscale")); break; case 2: _form->find_field('H', first_page, FR_SITUAZIONE).set(TR("civilistica")); break; case 3: _form->find_field('H', first_page, FR_SITUAZIONE).set(TR("gestionale")); break; } _form->set_testata(); } //-----------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::set_pavimentazione() { _form->set_pedata(); } //-----------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::print_body() { set_pavimentazione(); // stampa il fondo pagina TPrint_section& body = _form->get_body(); body.update(); if (body.height() > printer().rows_left()) printer().formfeed(); for (word i = 0; i < body.height(); i++) // stampa le righe del body printer().print(body.row(i)); } //-----------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::stampa_totali_cat(const TString& codicecat, const TString& descrcat ) { // scrive codice e descrizione della categoria di cui stampa i valori set_field(FR_TC_CAT,codicecat); set_field(FR_TC_D_CAT,descrcat); // riempie il body con i totali per categoria fill_body(_cat); // stampa effettivamente il body sul form print_body(); // somma sui totali materiali _mtr += _cat; _gen += _cat; } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::stampa_totali_tipo(TTipo_cespite tcesp) { // scrive il tipo di cespiti di cui calcola il totale set_field(FR_TC_CAT,""); TString80 tipodescr = TR("TOTALI BENI "); switch (tcesp) { case tc_pluriennale: tipodescr << TR("PLURIENNALI"); break; case tc_immateriale: tipodescr << TR("IMMATERIALI"); break; default: tipodescr << TR("MATERIALI"); break; } set_field(FR_TC_D_CAT,tipodescr); // riempie il body con i totali per tipologia cespite (per situazione) fill_body(_mtr); // stampa effettivamente il body sul form print_body(); } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::stampa_totali_generali() { // scrive TOTALI GENERALI set_field(FR_TC_CAT,""); set_field(FR_TC_D_CAT,TR("TOTALI GENERALI")); // riempie il body con i totali generali per situazione selezionata fill_body(_gen); // stampa effettivamente il body sul form print_body(); } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::set_field(int id, const real& val) { _form->find_field('B', odd_page, id).set(val.string()); } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::set_field(int id, const char* val) { _form->find_field('B', odd_page, id).set(val); } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::fill_body(const TTotali& tot) { // riempie il body odd, contenente i totali; lo fa chiamando la set_field per ogni campo set_field(FR_TC_CSTO,tot._tot_csto); set_field(FR_TC_TOTRIV,tot._tot_riv); real tempval1 = tot._tot_csto+tot._tot_riv; set_field(FR_TC_VALINIES,tempval1); set_field(FR_TC_RIVALES,tot._tot_riveser); set_field(FR_TC_ACQINCR,tot._tot_acqincr); set_field(FR_TC_CESSELIM2,tot._tot_cesselim2); tempval1 += tot._tot_riveser + tot._tot_acqincr - tot._tot_cesselim2; set_field(FR_TC_VALBIL,tempval1); set_field(FR_TC_FONDINIES,tot._tot_fondinieser); set_field(FR_TC_INCR,tot._tot_incr); set_field(FR_TC_CESSELIM3,tot._tot_cesselim3); set_field(FR_TC_REINPLUS,tot._tot_reinplus); set_field(FR_TC_AMMNOR,tot._tot_ammnor); set_field(FR_TC_AMMACC,tot._tot_ammacc); set_field(FR_TC_AMMANT,tot._tot_ammant); real tempval2 = tot._tot_fondinieser + tot._tot_incr - tot._tot_cesselim3 + tot._tot_reinplus + tot._tot_ammnor + tot._tot_ammacc +tot._tot_ammant; set_field(FR_TC_FONDBIL,tempval2); tempval2 = tempval1 - tempval2; set_field(FR_TC_RESBIL,tempval2); } //-------------------------------------------------------------------------------------------------------------------------// void TStampa_prospetto::aggiorna_totali(TCursor& cur, const int tipo, TTipo_cespite tcesp) { // valori della riga 1 (dipendenti da tipo solo le rivgf/rivgc) TRectype& recsalce = cur.curr(LF_SALCE); real csto = recsalce.get_real(SALCE_CSTO); _cat._tot_csto += csto; if (tipo == 2) _cat._tot_csto -= recsalce.get_real(SALCE_VNONAMMC); else _cat._tot_csto -= recsalce.get_real(SALCE_VNONAMM); _cat._tot_csto -= recsalce.get_real(SALCE_VNONAMM06); real rivsalce = recsalce.get_real(SALCE_RIV75); rivsalce += recsalce.get_real(SALCE_RIV83); rivsalce += recsalce.get_real(SALCE_RIV90); rivsalce += recsalce.get_real(SALCE_RIV91); _cat._tot_riv += rivsalce; if (tipo == 2) _cat._tot_riv += recsalce.get_real(SALCE_RIVGC); else _cat._tot_riv += recsalce.get_real(SALCE_RIVGF); // valori della riga 2 (e, giá che si fa la scansione dei movimenti, anche i valori dei movam della riga 3) // (i valori della riga 2 non dipendono da tipo, mentre quelli della riga 3 si, in quanto hanno movam) TRectype recmovce(LF_MOVCE); recmovce.put(MOVCE_IDCESPITE, cur.curr().get(CESPI_IDCESPITE)); TRelation relmovce(LF_MOVCE); // viene aggiunta la relazione su movam (che contiene il filtro su tpamm dovuto al tipo di situazione scelto nella maschera).. TString expr; expr << "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==" << tipo; relmovce.add(LF_MOVAM, expr); //.. e quindi viene aggiunta la relazione su ammmv (che contiene il filtro su tpamm dovuto al tipo di situazione scelto nella // maschera) utilizzando la stessa espressione di filtro, in quanto la chiave di ammmv é identica a quella di movam (olé!) relmovce.add(LF_AMMMV, expr); TCursor curmovce (&relmovce, "", 2, &recmovce, &recmovce); long num1 = curmovce.items(); curmovce.freeze(); real amv_ammnor; real amv_ammacc; real amv_ammant; for (curmovce=0; curmovce.pos()= _dataini && dtmov <= _datafine) { const TString8 codmov = mov.get(MOVCE_CODMOV); const char tmc = cache().get("%TMC", codmov, "S6")[0]; //prende il valore del campo S6 nella tabella tipi movimento const char segno = mov.get_char(MOVCE_SEGNO); const real signum = segno == '-' ? -1.0 : +1.0; //serve per sommare i movimenti con il loro segno effettivo real rivmovce = mov.get_real(MOVCE_RIV75); rivmovce += mov.get_real(MOVCE_RIV83); rivmovce += mov.get_real(MOVCE_RIV90); rivmovce += mov.get_real(MOVCE_RIV91); csto = mov.get_real(MOVCE_CSTO); // inquietante modo di selezionare la rivg (rivgf o rivgc) in base al tipo senza usare una if else! const real rivg = mov.get_real(tipo == 2 ? MOVCE_RIVGC : MOVCE_RIVGF); real vnonamm2; if (tipo == 2) vnonamm2 = recsalce.get_real(SALCE_VNONAMMC); else vnonamm2 = recsalce.get_real(SALCE_VNONAMM); vnonamm2 += recsalce.get_real(SALCE_VNONAMM06); //non si puo' avere un valore non ammortizzabile maggiore del costo prima delle //rivalutazioni if (vnonamm2 > csto) vnonamm2 = csto; real qmovam = amm.get_real(MOVAM_QNOR); qmovam += amm.get_real(MOVAM_QACC); qmovam += amm.get_real(MOVAM_QANT); if (tmc == 'R') _cat._tot_riveser += (rivmovce + rivg) * signum; if (tmc == 'I' || (tmc <= ' ' && segno == '+')) { _cat._tot_acqincr += (csto - vnonamm2 + rivmovce + rivg) * signum; _cat._tot_incr += qmovam * signum; } if (tmc == 'E' || (tmc <= ' ' && segno == '-')) { _cat._tot_cesselim2 += (csto - vnonamm2 + rivmovce + rivg) * (-signum); _cat._tot_cesselim3 += qmovam * (-signum); } if (tmc == 'P') _cat._tot_reinplus += (mov.get_real(MOVCE_PLUSREIN)) * signum; // solo nei casi con tipo =2 e/o 3 viene preso l'ammortamento da ammmv (che verrá poi sommato nella riga 4, piú sotto, a quello // preso da ammce); l'ammortamento viene preso qui in quanto é relativo ai movimenti che vengono qui scanditi if (tipo != 1) { amv_ammnor += (amv.get_real(AMMMV_QNOR)) * signum; amv_ammacc += (amv.get_real(AMMMV_QACC)) * signum; amv_ammant += (amv.get_real(AMMMV_QANT)) * signum; } } //fine controllo sulle date } //fine scansione sui movimenti // valori delle righe 3 e 4 di ammce (questi valori dipendono dal tipo di situazione selezionato nella maschera) // record con chiave idcespite,codes,tpamm TRectype recammce(LF_AMMCE); recammce.put(AMMCE_IDCESPITE, cur.curr().get(CESPI_IDCESPITE)); recammce.put(AMMCE_CODES, _mask->get(F_ESERCIZIO)); // filtro sul tpamm (va messo per non prendere tutti gli ammortamenti (dei 3 tipi) assieme) expr.cut(0); expr << AMMCE_TPAMM << "=" << tipo; TRelation relammce(LF_AMMCE); TCursor curammce (&relammce, expr, 1, &recammce, &recammce); long num2 = curammce.items(); curammce.freeze(); // scandisce gli ammce del cespite (al massimo 2 per ogni codes, ovvero iniziale e finale) for (curammce=0; curammce.pos()set(F_SITFISC,"X"); while (_mask->run() == K_ENTER) { // record su esercizio,gruppo,specie TRectype rec(LF_CESPI); const int esercizio = _mask->get_int(F_ESERCIZIO); rec.put(CESPI_CODCGRA, _mask->get(F_GRUPPO)); rec.put(CESPI_CODSPA, _mask->get(F_SPECIE)); // relazione su lf_cespi e lf_salce TRelation relcespi(LF_CESPI); TString espr; espr << "IDCESPITE==IDCESPITE|CODES==" << esercizio; relcespi.add(LF_SALCE,espr); // filtro su esercizio gruppo specie e data acquisto cespite sia <= alla data fine esercizio selezionato TString filtro; _dataini = _mask->get_date(F_INIZIO_ES); _datafine = _mask->get_date(F_FINE_ES); filtro << "(CODCGRA=\"" << _mask->get_int(F_GRUPPO)<< "\")&&" ; filtro << "(CODSPA=\"" << _mask->get(F_SPECIE)<< "\")&&" ; filtro << "(" << LF_SALCE << "->CODES=" << esercizio << ")&&" ; filtro << "(ANSI(" << LF_CESPI << "->DTCOMP)<=" << _datafine.string(ANSI) << ")"; // prepara il cursore di tipo sorted perché ho due tipi di ordinamento possibili: per categoria e per impianto const int ordinamento = _mask->get_int(F_ORDINA); TString ordin = ordinamento == 0 ? CESPI_CODCAT : CESPI_CODIMP; ordin << "|" <get_bool(F_SITFISC)) continue; if (j == 2 && !_mask->get_bool(F_SITCIV)) continue; if (j == 3 && !_mask->get_bool(F_SITGEST)) continue; // setta l'intestazione del form... set_intestazione(j, ordinamento); // ed il fondo pagina set_pavimentazione(); // gestione categorie ed effettivo main loop di stampa // azzera i totali generali (se mai non lo fossero) _gen.azzera(); // scansiona sui 3 tipi di cespite (materiale, immateriale, pluriennale) for (int i = 0; i <= 2; i++) { const TTipo_cespite tipocespite = (TTipo_cespite)i; // trasforma l'intero i in un tipo cespite TString16 currcodcat = "@@"; //codice categoria iniziale (non si puó metterlo nullo perché potrebbe esistere) TString80 currdescat = ""; _mtr.azzera(); // azzeratore tipi cespite (materiali, immateriali, pluriennali) for (sortcur=0; sortcur.pos()