#include #include #include #include #include #include #include #include #include "rmovana.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") { } 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 TReport { protected: //virtual bool use_mask() { return false; } //questo ci vuole quando la maschera ha un nome != dai report public: TPrint_contixcms_report() {} }; //////////////////////////////////////////////////////// // RECORDSET //////////////////////////////////////////////////////// class TPrint_contixcms_recordset : public TAS400_recordset { protected: long trova_riga(const TToken_string& 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 TToken_string& key) { long first = 0; long last = items() - 1; long riga = -1; while(first <= last) { const long guess = (first + last) / 2; move_to(guess); TToken_string guess_key; guess_key.add(get(RMOVANA_CODCMS).as_string()); //commessa guess_key.add(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(); 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) TToken_string key; key.add(codcms); key.add(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; 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"; query << "SELECT (BETWEEN(CODCMS,#DACODCMS,#ACODCMS))&&(BETWEEN(CODFASE,#DACODFASE,#ACODFASE))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n"; //query << "JOIN MOVANA INTO NUMREG==NUMREG\n"; //query << "JOIN PCON INTO GRUPPO=CODCONTO[1,3] CONTO=CODCONTO[4,6] SOTTOCONTO=CODCONTO[7,12]\n"; query << "FROM DATACOMP=#DADATA\n"; query << "TO DATACOMP=#ADATA"; TISAM_recordset recset(query); 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); conto = _mask->get_int(F_CONTOFIN); sottoconto = _mask->get_long(F_SOTTOCFIN); 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); rep.mask2report(*_mask); //setta i valori della maschera sul report //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); 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() { return TSkeleton_application::create(); } int ca1800(int argc, char* argv[]) { TPrint_contixcms a; a.run(argc, argv, TR("Stampa saldi conti per commessa")); return 0; }