#include #include #include #include #include #include #include #include #include #include #include "rmovana.h" #include "calib01.h" #include "calib02.h" #include "ca1800a.h" //////////////////////////////////////////////////////// // MASCHERA //////////////////////////////////////////////////////// class TPrint_contixcms_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TPrint_contixcms_mask(); }; TPrint_contixcms_mask::TPrint_contixcms_mask() : TAutomask("ca1800a") { const bool has_ca = dongle().active(CAAUT); //se la chiave ha CA mostra i campi gruppo 2 (codice e descrizione commessa).. if (has_ca) { hide(-1); show(-2); //se le fasi sono figlie di nessuno può visualizzare il gruppo 3 (da fase a fase) TConfig& cfg = ca_config(); const TString& fath_fasi = cfg.get("FathFasi"); if (fath_fasi.empty()) show(-3); else hide(-3); } else //..se invece ha CM mostra i campi gruppo 1 (da cms a cms) e gruppo 3 (da fase a fase) { hide(-2); show(-1); show(-3); } } bool TPrint_contixcms_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch(o.dlg()) { case DLG_PRINT: if (e == fe_button) { main_app().print(); return false; } break; case DLG_PREVIEW: if (e == fe_button) { main_app().preview(); return false; } break; default: break; } return true; } //////////////////////////////////////////////////////// // REPORT //////////////////////////////////////////////////////// class TPrint_contixcms_report : public TAnal_report { protected: virtual bool use_mask() { return false; } public: TPrint_contixcms_report() {} }; //////////////////////////////////////////////////////// // RECORDSET //////////////////////////////////////////////////////// class TPrint_contixcms_recordset : public TAS400_recordset { protected: long trova_riga(const TString& key); public: bool aggiungi_riga(TISAM_recordset& recset); TPrint_contixcms_recordset(); }; TPrint_contixcms_recordset::TPrint_contixcms_recordset() : TAS400_recordset("AS400(80)") { create_field(RMOVANA_CODCMS, -1, 20, _alfafld, true); create_field(RMOVANA_CODFASE, -1, 10, _alfafld, false); create_field(RMOVANA_CODCONTO, -1, 12, _alfafld, true); create_field("INDBIL", -1, 1, _intfld, true); create_field(RMOVANA_DATACOMP, -1, 8, _datefld, true); create_field(RMOVANA_IMPORTO, -1, 18, _realfld, true); create_field(RMOVANA_SEZIONE, -1, 1, _alfafld, true); } //cerca se una riga con chiave key esiste già long TPrint_contixcms_recordset::trova_riga(const TString& key) { long first = 0; long last = items() - 1; long riga = -1; TString80 guess_key; while(first <= last) { const long guess = (first + last) / 2; move_to(guess); guess_key = get(RMOVANA_CODCMS).as_string(); //commessa guess_key.left_just(20); guess_key << get(RMOVANA_CODCONTO).as_string(); //conto const int diff = guess_key.compare(key); if (diff == 0) { riga = guess; break; } if (diff > 0) { last = guess - 1; } else { first = guess + 1; } } return riga; } //funzione di ordinamento per il campo codcms/codconto //sono 2 stringhe static int compare_cms_conto(const TObject** o1, const TObject** o2) { TString& s1 = *(TString*)*o1; TString& s2 = *(TString*)*o2; const TString& cms1 = s1.left(20); const TString& cms2 = s2.left(20); int cmp = cms1.compare(cms2); if (cmp == 0) { const TString& cnt1 = s1.mid(30, 12); const TString& cnt2 = s2.mid(30, 12); cmp = cnt1.compare(cnt2); } return cmp; } //metodo per aggiungere righe al recordset da stampare bool TPrint_contixcms_recordset::aggiungi_riga(TISAM_recordset& recset) { //raccatta i dati che servono alla riga da stampare prendendoli dal record corrente del.. //..recordset in esame riempito dalla query iniziale const TString& codcms = recset.get(RMOVANA_CODCMS).as_string(); const TString& codfase = recset.get(RMOVANA_CODFASE).as_string(); const TString& codconto = recset.get(RMOVANA_CODCONTO).as_string(); TAnal_bill zio(codconto); const TIndbil ib = zio.indicatore_bilancio(); //solo i conti di tipo costo/ricavo possono essere considerati (no attività/passività o non definiti) if (ib == ib_costi || ib == ib_ricavi) { const TDate& datacomp = recset.get(RMOVANA_DATACOMP).as_date(); const real curr_valore = recset.get(RMOVANA_IMPORTO).as_real(); const char curr_sezione = recset.get(RMOVANA_SEZIONE).as_string()[0]; TImporto curr_imp(curr_sezione, curr_valore); //importo riga correntemente in esame //chiave della riga (solo su commessa e conto!; la fase è solo un filtro in input) TString80 key; key = codcms; key.left_just(20); key << codconto; //cerca se per caso la riga non esista già con questa chiave long numriga = trova_riga(key); //se la riga con la chiave key non esiste nel printrecordset la aggiunge if (numriga < 0) { new_rec(""); set(RMOVANA_CODCMS, TVariant(codcms)); set(RMOVANA_CODFASE, TVariant(codfase)); set(RMOVANA_CODCONTO, TVariant(codconto)); set("INDBIL", TVariant(long(ib))); set(RMOVANA_DATACOMP, TVariant(datacomp)); //deve ordinare il recordset sort(compare_cms_conto); //dopo che la riga è stata aggiunta riesegue la trova_riga in modo da ottenere il numero di riga numriga = trova_riga(key); } //importo riga con indice numriga const char tot_sezione = get(RMOVANA_SEZIONE).as_string()[0]; const real tot_valore = get(RMOVANA_IMPORTO).as_real(); TImporto tot_imp(tot_sezione, tot_valore); //aggiunge l'importo alla riga (nuova o vecchia) tot_imp += curr_imp; //normalizza e risalva il valore aggiornato sulla riga tot_imp.normalize(); TString4 str_sez; str_sez << tot_imp.sezione(); set(RMOVANA_SEZIONE, str_sez); set(RMOVANA_IMPORTO, tot_imp.valore()); } return true; } //////////////////////////////////////////////////////// // APPLICAZIONE //////////////////////////////////////////////////////// class TPrint_contixcms : public TSkeleton_application { TPrint_contixcms_mask* _mask; bool _has_ca; protected: virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM virtual bool create(); virtual void print(); virtual void preview(); virtual void print_or_preview(const bool stampa); TPrint_contixcms_recordset* elabora() const; public: virtual void main_loop(); }; //metodo di alto livello per la gestione dell'elaborazione TPrint_contixcms_recordset* TPrint_contixcms::elabora() const { //creazione dell'as400 recordset che verra' riempito dai record del recordset righe TPrint_contixcms_recordset* printset = new TPrint_contixcms_recordset(); //creazione della query per la creazione del recordset TString query; query << "USE RMOVANA KEY 3\n"; if (_has_ca) query << "SELECT (BETWEEN(CODCMS,#CODCMS,#CODCMS))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n"; else query << "SELECT (BETWEEN(CODCMS,#DACODCMS,#ACODCMS))&&(BETWEEN(CODFASE,#DACODFASE,#ACODFASE))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n"; query << "FROM DATACOMP=#DADATA\n"; query << "TO DATACOMP=#ADATA"; TISAM_recordset recset(query); if (_has_ca) recset.set_var("#CODCMS", TVariant(_mask->get(F_CODCMS))); else { recset.set_var("#DACODCMS", TVariant(_mask->get(F_DACODCMS))); recset.set_var("#ACODCMS", TVariant(_mask->get(F_ACODCMS))); recset.set_var("#DACODFASE", TVariant(_mask->get(F_DACODFASE))); recset.set_var("#ACODFASE", TVariant(_mask->get(F_ACODFASE))); } //per il conto va gestito il fatto che il conto è contabile e non analitico ed è 0-filled TString contone; int gruppo = _mask->get_int(F_GRUPPOINI); int conto = _mask->get_int(F_CONTOINI); long sottoconto = _mask->get_long(F_SOTTOCINI); contone.format("%03d%03d%06ld", gruppo, conto, sottoconto); recset.set_var("#DACODCONTO", contone); gruppo = _mask->get_int(F_GRUPPOFIN); if (gruppo == 0) gruppo = 999; conto = _mask->get_int(F_CONTOFIN); if (conto == 0) conto = 999; sottoconto = _mask->get_long(F_SOTTOCFIN); if (sottoconto == 0) sottoconto = 999999L; contone.format("%03d%03d%06ld", gruppo, conto, sottoconto); recset.set_var("#ACODCONTO", contone); //e alla fine le decisivissime date (che sono l'intervallo di scelta più importante) recset.set_var("#DADATA", _mask->get_date(F_DATAINI)); recset.set_var("#ADATA", _mask->get_date(F_DATAFIN)); //se ci sono record che soddisfano le pesanti richieste dell'utonto... const long recset_items = recset.items(); if (recset_items > 0) { //E crea pure la progind.. TProgind pi(recset_items, TR("Elaborazione dati per la stampa..."), true, true); //Scansione del recordset trovato for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; //scrive sul CSV i campi che servono al report printset->aggiungi_riga(recset); } } return printset; } //fantastico metodo per gestire stampa o anteprima void TPrint_contixcms::print_or_preview(const bool stampa) { if (_mask->check_fields()) { //l'utonto può scegliere che report usare (personalizzato!) TString rep_name = _mask->get(F_REPORT); //se il rep non è selezionato usa quello standard if (rep_name.empty()) rep_name << "ca1800a.rep"; TPrint_contixcms_report rep; rep.load(rep_name); //metodo per la generazione del recordset che contiene tutti i dati da stampare //insomma, il vero programma! TPrint_contixcms_recordset* printset = elabora(); //appioppa il recordset al report rep.set_recordset(printset); //setta i valori della maschera sul report (dopo la set_recordset, sennò.. //..sarebbero sovrascritti dalla set_recordset) rep.mask2report(*_mask); //se l'utonto vuole il dettaglio sottocontesco if (_mask->get_bool(F_HIDESOTT)) rep.section('B', 1).hide(); TReport_book book; book.add(rep); if (stampa) book.print(); else book.preview(); } } void TPrint_contixcms::print() { print_or_preview(true); } void TPrint_contixcms::preview() { print_or_preview(false); } void TPrint_contixcms::main_loop() { _mask = new TPrint_contixcms_mask; _mask->run(); delete _mask; _mask = NULL; } bool TPrint_contixcms::create() { //controlla se la chiave ha il modulo CA (e non solo CM) NON è ammesso CA E CM _has_ca = dongle().active(CAAUT); //in tal caso il programma è utilizzabile solo se si ha il piano dei conti contabile.. if (_has_ca) { TConfig& cfg = ca_config(); const bool usepdcc = cfg.get_bool("UsePdcc"); if (!usepdcc) return error_box(TR("Il programma non è utilizzabile con la corrente configurazione CA!")); } return TSkeleton_application::create(); } int ca1800(int argc, char* argv[]) { TPrint_contixcms a; a.run(argc, argv, TR("Stampa conti per commessa")); return 0; }