// ve6300.cpp: programma di generazione effetti // Muliebrica parodia... // Il cavo delirante che irrompe nel silenzio dell'apogeo // * * * * * * * // * // _ _______ _____________ ___================ // _I_I___oo_____ii__| |_|| | | \ | |O| |_| |_| // | | - - | I | | | L M S | | | | // _|___|________|____ I____|_|=|_____________|=II=|__|_|_____________ // I=| o (_)--(_)--(_)--(_) O--O O-O +++++ O-O \--/ ()==() ++++ //======================================================================= // // // ____||____============____||___ ___=============================== // /__| OOOOOOOOOOOOO [_] | | |[]| [_] [_] [_] [_] // / S N C F | | | | // \________________________________|_ii_|__|__|___________________________ // ()==() === ++++ === ()==() ()==() +++ +++ ++++++++ //========================================================================= // // Have you ever heard MK ? #include #include #include #include #include #include #include #include #include #include #include "../cg/saldacon.h" #include "velib01.h" #include "ve6300a.h" enum error_type { no_error, elaboration_error, nr_doc_error, chg_stat_error, datadoc_error, codpag_error, generic_error }; // TGenerazioneEffetti_app // Applicazione di generazione effetti class TGenerazioneEffetti_app : public TApplication { TString16 _cod_el; // codice elaborazione immesso TDate _data_reg; // data di registrazione immessa TDate _data_ini; // data di inizio intervallo TDate _data_fine; // data di fine intervallo TMask *_msk; // maschera di selezione dati TRelation *_clifo; // relazione dei clienti e fornitori + cfven TLocalisamfile *_docfile, // file dei documenti (per far funzionare TDocumento) *_rdocfile; // file delle righe documento (per far funzionare TDocumento) TTable *_cpg; // tabella condizioni di pagamento TDocumento *_doc; // documento corrente TPagamento *_pagamento; // pagamento corrente, ricalcolato prima di scrivere le scadenze TArray_sheet *_num_sheet; // Array sheet selezionabile dei codici numerazione TString_array _tipi_doc; // Array di stringhe contenente i tipi documenti da elaborare error_type _error; // Errore rilevato durante l'elaborazione long _total_bills; // Totale effetti generati bool _can_write; // se TRUE e' abilitata la scrittura. Non appena rileva un errore rimane a FALSE for this instance char _final_doc_status; // Valore per lo stato finale del documento protected: // TApplication // scrive il movimento e le scadenze error_type write_all() { return no_error; } // Cambia lo stato del documento error_type change_doc_status(); // Coontrolla se lo stato ed il tipo del documento sono validi e rispettano la selezione bool doc_tipo_stato_ok(); // Visualizza l'ultimo errore rilevato void display_error(); // Genera l'effetto void generate_bill(); // Genera gli effetti void generate(); // Le 4 seguenti non hanno bisogno di commenti virtual bool menu(MENU_TAG mt); virtual bool create(); virtual bool destroy(); // Handler del codice elaborazione differita static bool handle_cod_eld(TMask_field& f, KEY k); // Handler dell'intervallo di date static bool handle_data_range(TMask_field& f, KEY k); // Handler del pulsante di selezione codici numerazione static bool handle_select(TMask_field& f, KEY k); // Ritorna il TArray_sheet contenente le selezioni sui codici numerazione TArray_sheet* get_num_sheet() const { return _num_sheet; } // Costruisce lo sheet dei codici numerazione void build_num_sheet(); public: // Verifica se non ci sono stati errori bool good() const { return _error == no_error;} error_type status() { return _error; } void set_status(error_type e) { _error = e; } TGenerazioneEffetti_app() {_msk = NULL; _num_sheet = NULL;} virtual ~TGenerazioneEffetti_app() { } }; inline TGenerazioneEffetti_app& app() { return (TGenerazioneEffetti_app&) main_app(); } bool TGenerazioneEffetti_app::handle_data_range(TMask_field& f, KEY k) { if (k==K_ENTER && f.dirty()) { TMask& m = f.mask(); TDate da(m.get_date(F_DATA_INI)); TDate a(m.get_date(F_DATA_FIN)); //m.field(F_DATA_REG).set_dirty(); //if (a == botime || da == botime) return TRUE; if (a < da) { f.error_box("La data di inizio deve essere minore della data di fine."); return FALSE; } //if ((a - da) > 15) //{ // f.error_box("L'intervallo tra le date non puo' eccedere i 15 giorni."); // return FALSE; //} } return TRUE; } bool TGenerazioneEffetti_app::handle_cod_eld(TMask_field& f, KEY k) { if (f.to_check(k) && k == K_TAB) // se e' cambiato ricostruisce anche lo sheet dei codici numerazione { app()._cod_el = f.get(); // aggiorna il codice elaborazione per la build_num_sheet() f.mask().disable(DLG_OK); app().build_num_sheet(); } return TRUE; } bool TGenerazioneEffetti_app::handle_select(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask& m = f.mask(); TArray_sheet* s = app().get_num_sheet(); if (s->run()) { if (s->checked() != 0) // Hai selezionato qualcosa ? m.enable(DLG_OK); // allora abilita il pulsante di conferma else m.disable(DLG_OK); } } return TRUE; } void TGenerazioneEffetti_app::build_num_sheet() { _num_sheet->destroy(); TTable eld("%ELD"); TTable num("%NUM"); TString s1,s2,s3; TString16 tipon1,tipon2,tipon3,tipon4,tipon5; // tipi documento validi per la numerazione long pos; eld.put("CODTAB",_cod_el); if (eld.read() == NOERR) { TToken_string t; s1.format("%-20s",(const char*)eld.get("S2")); s3 = eld.get("S7"); _final_doc_status = eld.get("S4")[0]; for (int i=0;i<5;i++) { t = s1.mid(i*4,4); // Tipo documento if (t.trim().empty()) break; t.add(s3.mid(i,1)); // Stato iniziale _tipi_doc.add(t); // Aggiunge questo tipo documento alla lista } for (pos=0,num.first();num.good();num.next(),pos++) // scorre tutte le numerazioni possibili { TToken_string t; t.add(" "); t.add(num.get("CODTAB")); t.add(num.get("S0")); _num_sheet->add(t); s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione tipon1 = s2.mid(0,4); tipon2 = s2.mid(4,4); tipon3 = s2.mid(8,4); tipon4 = s2.mid(12,4); tipon5 = s2.mid(16,4); const int n1 = s1.find(tipon1); const int n2 = s1.find(tipon2); const int n3 = s1.find(tipon3); const int n4 = s1.find(tipon4); const int n5 = s1.find(tipon5); if ((tipon1.empty() || n1<0) && (tipon2.empty() || n2<0) && (tipon3.empty() || n3<0) && (tipon4.empty() || n4<0) && (tipon5.empty() || n5<0)) _num_sheet->disable_row(pos); else _num_sheet->enable_row(pos); } } } bool TGenerazioneEffetti_app::create() { TApplication::create(); _error = no_error; _can_write = TRUE; _pagamento = NULL; _msk = new TMask("ve6300a"); _msk->set_handler(F_CODICE_ELAB,handle_cod_eld); _msk->set_handler(F_DATA_INI,handle_data_range); _msk->set_handler(F_DATA_FIN,handle_data_range); _msk->set_handler(DLG_USER,handle_select); _num_sheet = new TArray_sheet(-1,-1,-4,-4,"Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); _doc = new TDocumento; _cpg = new TTable("%CPG"); _clifo = new TRelation(LF_CLIFO); _clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF"); dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TGenerazioneEffetti_app::destroy() { if (_msk) delete _msk; if (_num_sheet) delete _num_sheet; if (_docfile) delete _docfile; if (_rdocfile) delete _rdocfile; if (_doc) delete _doc; if (_cpg) delete _cpg; if (_clifo) delete _clifo; return TApplication::destroy(); } bool TGenerazioneEffetti_app::menu(MENU_TAG mt) { while (_msk->run() == K_ENTER) { _cod_el = _msk->get(F_CODICE_ELAB); _data_ini = _msk->get_date(F_DATA_INI); _data_fine = _msk->get_date(F_DATA_FIN); generate(); } return FALSE; } bool TGenerazioneEffetti_app::doc_tipo_stato_ok() // Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione // differita selezionata { const int items = _tipi_doc.items(); bool found = FALSE; const TString16 tipo(_doc->tipo().codice()); const char stato = _doc->stato(); for (int i=0;istato(_final_doc_status); if (_doc->head().rewrite(d) != NOERR) _error = chg_stat_error; return _error; } void TGenerazioneEffetti_app::display_error() { TString msg; TString numerazione = _doc->numerazione(); const long numero = _doc->numero(); switch (_error) { case elaboration_error: msg.format("Il documento %s/%ld non rientra tra i tipi documento validi per l'elaborazione." "Verificare i tipi documento ed il loro stato iniziale sul codice elaborazione inserito.",(const char*)numerazione,numero); break; case nr_doc_error: msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld." "Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero); break; case chg_stat_error: msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld." "Verificare l'integrita' del file documenti.",(const char*)numerazione,numero); break; case datadoc_error: msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld." "Verificare l'informazione inserita.",(const char*)numerazione,numero); break; case codpag_error: msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld." "Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero); break; default: msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.", (const char*)numerazione,numero); break; } warning_box(msg); _error = no_error; // reset error, as any other one would do, so you can show me the other ones. _can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred. } void TGenerazioneEffetti_app::generate_bill() // bill in inglese significa anche effetto eheheh ;-) { if (good() && _can_write) if (write_all() == no_error) // Se la scrittura e' andata ok... { _total_bills++; change_doc_status(); } } void TGenerazioneEffetti_app::generate() { TRelation doc_rel(LF_DOC); TLocalisamfile righe_doc(LF_RIGHEDOC); TRectype da(LF_DOC),a(LF_DOC); const long items = _num_sheet->items(); int year_from = _data_ini.year(); int year_to = _data_fine.year(); TString16 codnum; TString msg,filt_expr; _total_bills = 0; da.put("DATADOC",_data_ini); da.put("PROVV","D"); da.put("ANNO",year_from); a.put("DATADOC",_data_fine); a.put("PROVV","D"); a.put("ANNO",year_to); for (long i=0L; ichecked(i)) // Se la numerazione corrente e' stata selezionata { // istanzia un cursore per la numerazione corrente, con i limiti di data codnum = _num_sheet->row(i).get(1); filt_expr = "CODNUM=\""; filt_expr << codnum << "\""; TCursor doc_cur(&doc_rel,filt_expr,3,&da,&a); const long cur_items = doc_cur.items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato if (cur_items == 0) { warning_box("Non vi sono effetti da generare per il codice numerazione %s",(const char*)codnum); continue; } msg = "Generazione effetti "; msg << codnum << " dal "; msg << _data_ini.string() << " al "; msg << _data_fine.string(); #ifdef DBG TProgind p(cur_items,msg,TRUE,TRUE,1); #else TProgind p(cur_items,msg,FALSE,TRUE,1); #endif long j = 0; #ifdef DBG for (;jread(doc_cur.curr()); // legge il documento if (codnum != _doc->get(DOC_CODNUM)) continue; // patch del cazzo if (doc_tipo_stato_ok()) // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata generate_bill(); else { // ATTENZIONE!: se non ha ancora cominciato a contabilizzare, eventuali // documenti con tipo o stato differenti vengono semplicemente scartati // senza segnalare errori if (_total_bills > 0) _error = elaboration_error; } if (!good()) display_error(); } #ifdef DBG if (p.iscancelled()) break; #endif } if (_total_bills > 0) message_box("Totale effetti generati: %ld",_total_bills); } int ve6300 (int argc, char **argv) { TGenerazioneEffetti_app a; a.run(argc,argv,"Generazione effetti"); return TRUE; }