#include #include #include #include #include #include #include #include #include #include #include "cgsaldac.h" #include "../ve/velib.h" #include "cg3800a.h" #include "cg3800.h" //=============================================================================================== //maschera class TDouble_fatt_mask: public TAutomask { public: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); TDouble_fatt_mask():TAutomask("cg3800a") {} }; bool TDouble_fatt_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { /* switch (o.dlg()) { default: break; }*/ return true; } //=========================================================================================== //Dichiarazione APPLICAZIONE; necessaria qui per farla conoscere al form class TDouble_fatt_form; class TDouble_fatt : public TSkeleton_application { TAssoc_array _movimenti; //assocarray con tutti i movimenti TPointer_array _duplicati; TDouble_fatt_mask* _mask; TDouble_fatt_form* _form; bool _print_again; protected: virtual void main_loop(); virtual bool create(); virtual bool destroy(); static bool mov_callback(const TRelation& rel, void* pJolly); void store_mov(const TRectype& mov); public: void print_again() { _print_again = true; } }; TDouble_fatt& app() {return (TDouble_fatt&) main_app(); } //=============================================================================================== //form class TDouble_fatt_form : public TForm { TPointer_array& _duplicati; protected: virtual bool validate(TForm_item &cf, TToken_string &s); virtual long records() const {return _duplicati.items();} const TRectype& get_mov (int i, int j) const; static bool process_link(int id, const char * lnk); public: void fill_header_last(int i); void fill_body_odd(int i , int j); void print(const TMask& m); TDouble_fatt_form(TPointer_array&); virtual ~TDouble_fatt_form(); }; bool TDouble_fatt_form::validate(TForm_item &cf, TToken_string &s) { return TForm::validate(cf,s); } bool TDouble_fatt_form::process_link(int id, const char * lnk) { TRectype mov(LF_MOV); mov.put(MOV_NUMREG, lnk); mov.edit(); //fighissimo modo per lanciare l'editor del record (programma scelto in automatico!!) if (yesno_box(TR("Si desidera aggiornare la stampa?"))) { dispatch_e_char(cur_win(), K_ESC); //chiude l'anteprima di stampa app().print_again(); } return true; } const TRectype& TDouble_fatt_form::get_mov (int i, int j) const { const TPointer_array& dup = (const TPointer_array&)_duplicati[i]; const long numreg = dup.get_long(j); return cache().get(LF_MOV, numreg); } void TDouble_fatt_form::fill_header_last(int i) { const TRectype& mov = get_mov(i,0); TPrint_section& header = section('H', last_page); header.reset(); header.find_field(FR_ANNODOC).set(mov.get(MOV_DATADOC).right(4)); header.find_field(FR_NDOC).set(mov.get(MOV_NUMDOC)); const TString& codcf = mov.get(MOV_CODCF); TString16 key; key.format("F|%s",(const char *)codcf); const TRectype& clifo = cache().get(LF_CLIFO, key); header.find_field(FR_CODCF).set(codcf); header.find_field(FR_RAGSOC).set(clifo.get(CLI_RAGSOC)); header.update(); for (word k = 0; k < header.height(); k++) printer().print(header.row(k)); } void TDouble_fatt_form::fill_body_odd(int i, int j) { const TRectype& mov = get_mov(i,j); TPrint_section& body = section('B', odd_page); body.reset(); body.find_field(FR_NUMREG).set(mov.get(MOV_NUMREG)); body.find_field(FR_DATAREG).set(mov.get(MOV_DATAREG)); body.find_field(FR_DESCREG).set(mov.get(MOV_DESCR)); body.update(); for (word k = 0; k < body.height(); k++) printer().print(body.row(k)); } void TDouble_fatt_form::print(const TMask& m) { const TDate dataini = m.get_date(F_DADATA); const TDate datafine = m.get_date(F_ADATA); TPrint_section& header = section('H', odd_page); header.find_field(FR_DADATA).set(dataini); header.find_field(FR_ADATA).set(datafine); header.update(); set_background(1, TRUE); set_header(1, TRUE); set_footer(1, FALSE); printer().open(); for (int i = 0; i < _duplicati.items(); i++) //scan dell'array dei movimenti che presentano duplicati { const TPointer_array& dup = (const TPointer_array&)_duplicati[i]; //controlla se le date di registrazione dei movimenti sono incluse nell'intervallo proposto nella maschera bool stampa = false; for (int j = 0; j < dup.items(); j++) { const TRectype& mov = get_mov(i,j); const TDate datareg = mov.get_date(MOV_DATAREG); if ((datareg >= dataini)&&(datareg <= datafine)) { stampa = true; break; } } if (stampa) { fill_header_last(i); for (int k = 0; k < dup.items(); k++) fill_body_odd(i,k); } } printer().close(); } TDouble_fatt_form::TDouble_fatt_form(TPointer_array& dupl) :TForm ("cg3800a"), _duplicati(dupl) {// setta i links presenti nel form (sono gli elementi scritti in blu(b) su bianco(w)) // procedimento standard in questi casi TArray& arr = printer().links(); if (arr.items() == 0) arr.add(new TToken_string("Ordina|b|w")); printer().setlinkhandler(process_link); } TDouble_fatt_form::~TDouble_fatt_form() { } //=============================================================================================== //Applicazione bool TDouble_fatt::create() { _mask = new TDouble_fatt_mask; _form = new TDouble_fatt_form(_duplicati); return TSkeleton_application::create(); } bool TDouble_fatt::destroy() { delete _mask; delete _form; return TRUE; } // Mettere in libreria al piu' presto!!!! typedef bool (*SCAN_FUNC)(const TRelation& rel, void* pJolly); bool scan_cursor(TCursor& cur, const char* msg, SCAN_FUNC func, void* pJolly) { TRecnotype items = 0; // Temporarily TProgind pi(items, msg, true, true); { TWait_cursor hourglass; items = cur.items(); } bool ok = true; if (items > 0) { cur.freeze(); pi.setmax(items); for (cur = 0; cur.pos() < items; ++cur) { pi.addstatus(1); if (pi.iscancelled()) { ok = false; break; } if (!func(*cur.relation(), pJolly)) { ok = false; break; } } cur.freeze(false); } return ok; } void TDouble_fatt::store_mov(const TRectype& mov) { TString key; key << mov.get(MOV_CODCF) << '_' << mov.get_date(MOV_DATADOC).year() << '_' << mov.get(MOV_NUMDOC); const long numreg = mov.get_long(MOV_NUMREG); TPointer_array* pa = (TPointer_array*)_movimenti.objptr(key); //elemento dell' assocarray if (pa == NULL) //se non c'e' il valore lo aggiungo all'assocarray { pa = new TPointer_array; _movimenti.add(key,pa); } pa->add_long(numreg); if (pa->items() > 1) _duplicati.add(pa); } bool TDouble_fatt::mov_callback(const TRelation& rel, void* pJolly) { TDouble_fatt* app = (TDouble_fatt*)pJolly; app -> store_mov(rel.curr()); return true; } void TDouble_fatt::main_loop() { TDate d(TODAY); _mask->set(F_ADATA, d); d.set_day(1); d.set_month(1); _mask->set(F_DADATA, d); while (_mask->run() == K_ENTER) { do { _print_again = false; TRelation rel(LF_MOV); TRectype darec(LF_MOV), arec(LF_MOV); const TDate dataini(1,1,_mask->get_date(F_DADATA).year()-1); const TDate datafin(31,12,_mask->get_date(F_ADATA).year()+1); darec.put(MOV_DATAREG, dataini); arec.put(MOV_DATAREG, datafin); TCursor cur(&rel, "TIPO=='F'", 2, &darec, &arec); _movimenti.destroy(); _duplicati.destroy(); scan_cursor(cur, "Ricerca fatture doppie...", mov_callback, this); if (_duplicati.items() > 0) _form->print(*_mask); } while(_print_again); } } int cg3800(int argc, char* argv[]) { TDouble_fatt a; a.run(argc,argv,TR("Stampa lista fatture doppie")); return 0; }