#include #include #include #include #include #include "at8.h" #include "at8a00a.h" #include "atlib.h" #include "contsan.h" #include "donaz.h" #include "idoneita.h" #include "soggetti.h" #include "convoc.h" #include "rconvoc.h" #include "storico.h" #define ATFILENAME "aggiorna.txt" //////////////////////////////////////////////////////// // Classe TCtDonpr2at_file customizzata dalla TFile_text // //////////////////////////////////////////////////////// class TCtDonpr2at_file: public TFile_text { protected: virtual void preformat_field(const TFieldref&field,TString &str,TRelation& rel,const TString &tipo_tr); virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); public: virtual int autosave(TRelation& rel, const TRecord_text& rec); TCtDonpr2at_file(const TString& file_name, const TString& config_name); virtual ~TCtDonpr2at_file() { } }; TCtDonpr2at_file::TCtDonpr2at_file(const TString& file_name, const TString& config_name) : TFile_text(file_name, config_name) { } void TCtDonpr2at_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) { const TString code(s.get(0)); TString valore; if (code == "_UPPERCASE") { valore.upper(); } else NFCHECK("Macro non definita: %s", (const char *)code); str = valore; } int TCtDonpr2at_file::autosave(TRelation& rel, const TRecord_text& rec) { const TString& type = rec.type();//prendo il tracciato record del tipo del record_text TTracciato_record& tr = *t_rec(type); TArray& a_tc = tr.tracciati_campo(); const int items = a_tc.items(); TString valore; for (int i = 0; i < items; i++) { const TTracciato_campo& tc = tr.get(i); TFieldref field(tc.field()); if (field.name().not_empty()) { if (field.file()==0) field.set_file(rel.lfile().num()); valore = rec.row(i); // formatta il campo del file di testo secondo le specifiche del campo su file isam preformat_field(field,valore,rel,tr.type()); const TRectype& rel_rec = rel.curr(field.file()); TFieldtypes tipo_campo = rel_rec.type(field.name()); bool vuoto = valore.blank(); if (valore[0] == '@') //se trovo il carattere @ -> azzero il campo valore.cut(0); switch(tipo_campo) //in base al tipo di campo formatta i valori seguendo le specifiche del tracciato { case _datefld: //tipo data... { if (real::is_null(valore)) { valore.cut(0); vuoto = TRUE; } TDate data(valore); format_date(data, fpicture(tc), valore);//formatta la data secondo le specifiche del tracciato } break; case _realfld: //tipi numerici case _intfld: case _longfld: { const real numero(valore); vuoto = numero.is_zero(); valore = numero.string(fpicture(tc));//formatta il numero secondo le specifiche del tracciato int length = flength(tc,rel_rec); if (falign(tc) == 'L') valore.left_just(length, ffiller(tc)); else valore.right_just(length, ffiller(tc)); } break; default: valore = format_field(tc, rel.lfile().num(), valore);//formatta il campo secondo le specifiche del record break; } if (!vuoto && rel.exist(field.file())) field.write(valore, rel);//faccio una write sulla relazione del fieldref } } int err = NOERR; if (pre_writerel(rel,rec)) { err= rel.write(); if (err == _isdupkey || err ==_isreinsert) err = rel.rewrite(); } return err; } ///////////////////////////////////////////////////// // Classe TCtDonpr2at: applicazione principale // ///////////////////////////////////////////////////// class TCtDonpr2at: public TSkeleton_application { TMask* _msk; TCtDonpr2at_file* _trasfile; int _numdon1, _numdon2; TString4 _catini1, _catfin1, _catini2, _catfin2; bool _sttess2, _dataisc; protected: virtual bool create(void); virtual void main_loop(); virtual bool destroy(void) ; void transfer(void); void inizializza_file(void); static bool annulla_handler(TMask_field& f, KEY k); bool test_donation(TRectype& recsog, const char* tipo, const TDate& datadon, const TString& luogodon); bool test_inter(TRectype& recsog, const char* tipo, const TDate& datadon, int inter); void calcola_categoria(TRectype& recsog); bool print_header(); void print_line(const TString& rigastampa); void print_footer(); void new_sogg(TRectype& sogg, const TRecord_text& curr); public: const TMask& msk() const { return *_msk; } TCtDonpr2at() {} virtual ~TCtDonpr2at() {} }; // restituisce un riferimento all' applicazione inline TCtDonpr2at& app() { return (TCtDonpr2at&) main_app();} // creazione dell'applicazione bool TCtDonpr2at::create() { open_files(LF_SOGGETTI, LF_DONAZ, LF_CONTSAN, LF_IDONEITA, LF_CONVOC, LF_RCONVOC, LF_STORICO, 0); _msk = new TMask("at8a00a"); _msk->set(F_FILENAME,ATFILENAME); _trasfile = NULL; TConfig config(CONFIG_STUDIO); _numdon1 = config.get_int("NumDon1"); _numdon2 = config.get_int("NumDon2"); _catini1 = config.get("CatIni1"); _catfin1 = config.get("CatFin1"); _catini2 = config.get("CatIni2"); _catfin2 = config.get("CatFin2"); _sttess2 = config.get_bool("StTess2"); _dataisc = config.get_bool("DataIsc"); return TSkeleton_application::create(); } // distruzione dell'applicazione bool TCtDonpr2at::destroy() { delete _msk; return TSkeleton_application::destroy(); } // carica la maschera void TCtDonpr2at::main_loop() { KEY key = K_ENTER; while (key != K_QUIT) { key = _msk->run(); if (key == K_ENTER) transfer(); } } bool TCtDonpr2at::test_donation(TRectype& recsog, const char* tipo, const TDate& datadon, const TString& luogodon) { //ricostruisce le donazioni del soggetto in esame TRectype* key = new TRectype(LF_DONAZ); key->put(DON_CODICE, recsog.get(SOG_CODICE)); TRecord_array donazioni(LF_DONAZ,DON_PROGDON); donazioni.read(key); // verificare se ha fatto una donazione di tipo con data successiva all'ultima donazione const int r=donazioni.last_row(); if (r > 0) { const TRectype& lastdon = donazioni[r]; if (lastdon.get_date(DON_DATADON) >= datadon) return FALSE; } //aggiunge la nuova donazione // compila i dati della donazione in esame TRectype* rec = new TRectype(LF_DONAZ); rec->put(DON_CODICE, recsog.get(SOG_CODICE)); rec->put(DON_PROGDON,r+1); rec->put(DON_DATADON, datadon); rec->put(DON_TIPODON, tipo); rec->put(DON_CODSEZ,recsog.get(SOG_CODSEZ)); rec->put(DON_CODSOT,recsog.get(SOG_CODSOT)); rec->put(DON_LUOGODON, luogodon); if (r == 0) //puó essere una prima donazione... rec->put(DON_PRIMADON,"X"); donazioni.insert_row(rec); donazioni.write(TRUE); calcola_donazioni_lib(recsog, &donazioni); // questo metodo sistema tutto!!! calcola_categoria(recsog); // aggiorno data e utente ultimo aggiornamento const TDate oggi(TODAY); recsog.put(SOG_DATAULTAGG,oggi); recsog.put(SOG_UTENULTAGG,"SIT"); return TRUE; } void TCtDonpr2at::calcola_categoria(TRectype& recsog) { TString256 rigastampa; TTable ctd("CTD"); TString4 catdon = recsog.get(SOG_CATDON); const int totdon = recsog.get_int(SOG_TOTDON); ctd.put("CODTAB",catdon); if (ctd.read() == NOERR) { bool dimissione = ctd.get_bool("B0"); if (dimissione) { rigastampa.format("Categoria: attuale %s", (const char*) catdon); const TString& cat_coll = ctd.get("S6"); if (cat_coll.not_empty()) { catdon = cat_coll; //recsog.put(SOG_CATDON, catdon); } } if ((catdon == _catini1 || _catini1.empty()) && (totdon>=_numdon1) && _catfin1.not_empty()) { if (!dimissione) recsog.put(SOG_CATDON, _catfin1); catdon = _catfin1; } bool tstampata = recsog.get_bool(SOG_T_STAMPATA); if ((catdon == _catini2 || _catini2.empty()) && (totdon>=_numdon2) && _catfin2.not_empty() && (!_sttess2 || tstampata)) { if (!dimissione) recsog.put(SOG_CATDON, _catfin2); catdon = _catfin2; } if (dimissione) { rigastampa << " - calcolata " << catdon; print_line(rigastampa); } } } bool TCtDonpr2at::test_inter(TRectype& recsog, const char* tipo, const TDate& datadon, int inter) { TRectype* key_cont = new TRectype(LF_CONTSAN); key_cont->put(CON_CODICE, recsog.get(SOG_CODICE)); TRecord_array controlli(LF_CONTSAN,CON_PROGCON); controlli.read(key_cont); TRectype* key = new TRectype(LF_IDONEITA); key->put(IDO_CODICE, recsog.get(SOG_CODICE)); TRecord_array idoneita(LF_IDONEITA,IDO_PROGIDO); idoneita.read(key); TString4 stato = recsog.get(SOG_STATO); if (modstato_tcs(stato) != 'S' && stato.not_empty()) return FALSE; if (tipo == "SI") stato = recsog.get(SOG_STATOSI); else stato = recsog.get(SOG_STATOAF); if (modstato_tcs(stato) != 'S' && stato.not_empty()) return FALSE; const int r = idoneita.last_row(); //se trova una data idoneita >= di quella in esame, quest'ultima viene ignorata if (r > 0) { const TRectype& lastido = idoneita[r]; if (lastido.get_date(IDO_DATAIDO) >= datadon) return FALSE; } TRectype* rec = new TRectype(LF_IDONEITA); rec->put(IDO_CODICE, recsog.get(SOG_CODICE)); rec->put(IDO_PROGIDO, r+1); rec->put(IDO_DATAIDO, datadon); rec->put(IDO_TIPOIDO, _stricmp(tipo, "SI") != 0 ? "AF" : "SI"); // Il mondo è bello perchè c'é l'AVIS (tutte le donaz. non SI sono AF! mah?!) rec->put(IDO_IDO_SOS, "ID"); rec->put(IDO_INTERVALLO, inter); // aggiunto da cristina il 18/09/2002 altrimenti non so che quella riga é stata aggiunta da CT rec->put(IDO_RESPONSAB, "TRASF. DA SIT"); idoneita.add_row(rec); idoneita.write(); con_reord(recsog, &controlli, &idoneita); // aggiorno data e utente ultimo aggiornamento (Cristina 18/09/2002) const TDate oggi(TODAY); recsog.put(SOG_DATAULTAGG,oggi); recsog.put(SOG_UTENULTAGG,"SIT"); return TRUE; } bool TCtDonpr2at::print_header() { if (printer().open()) { TDate oggi(TODAY); TPrintrow row; TString256 rigastampa; rigastampa = "TRASFERIMENTO DATI DA CETRAPLUS"; rigastampa.center_just(132); row.put(rigastampa); row.put("@>", 1); row.put("Pag. @#", 115); printer().setheaderline(2, row); rigastampa = ""; rigastampa.fill('-',132); row.reset(); row.put(rigastampa); printer().setheaderline(3, row); return TRUE; } else return error_box("Errore in apertura stampante."); } void TCtDonpr2at::print_line(const TString& rigastampa) { TPrintrow row; row.put((const char*) rigastampa); printer().print(row); } void TCtDonpr2at::print_footer() { printer().formfeed(); printer().close(); } void TCtDonpr2at::new_sogg(TRectype& sogg, const TRecord_text& curr) { TLocalisamfile soggetti(LF_SOGGETTI); soggetti.last(); long codice = soggetti.get_long(SOG_CODICE); sogg.put(SOG_CODICE, codice+1); sogg.put(SOG_CATDON, "NU"); TString str; str = curr.get(32); if (str[0] == '0') str = str.sub(1); sogg.put(SOG_CODSEZ, str.sub(0,2)); sogg.put(SOG_CODSOT, str.sub(2,4)); const TDate oggi(TODAY); sogg.put(SOG_DATAULTAGG,oggi); sogg.put(SOG_UTENULTAGG,"SIT"); } // trasferimento dati da file CT su programma avis void TCtDonpr2at::transfer() { if (print_header()) { TFilename ctprini = "ctpr2at.ini"; _trasfile = new TCtDonpr2at_file(_msk->get(F_FILENAME), ctprini); inizializza_file(); const long dimension = fsize(_msk->get(F_FILENAME)); //TProgind pi(dimension,"Acquisizione in corso..."); TRelation rel(LF_SOGGETTI); rel.lfile().setkey(2); TRectype& sogg = rel.curr(); TString256 rigastampa; TString80 cognome, nome, datanasc, str; TString8 tipodon_at, luogodon_at; char tipoacc, tipodon; TDate dataacc; bool update; TRecord_text curr; bool cancelled = FALSE; while ((_trasfile->read(curr) == NOERR) && (!cancelled)) { //pi.setstatus(_trasfile->read_file()->tellg()); // cerco il donatore con cognome, nome e data nascita cognome = curr.get(1); str = cognome.left(7); if (str != "COGNOME") { sogg.put(SOG_COGNOME, cognome); nome = curr.get(2); sogg.put(SOG_NOME, nome); datanasc = curr.get(4); sogg.put(SOG_DATANASC, datanasc); if (rel.read(_isequal) != NOERR) { // segnalo l'errore rigastampa.format("Inserito soggetto %s %s %s", (const char*) cognome, (const char*) nome, (const char*) datanasc); print_line(rigastampa); // nuovo donatore sogg.zero(); sogg.put(SOG_COGNOME, cognome); sogg.put(SOG_NOME, nome); sogg.put(SOG_DATANASC, datanasc); new_sogg(sogg, curr); } //esegue l'effettivo passaggio dati basandosi sulla formattazione del file .ini _trasfile->autosave(rel, curr); update = FALSE; tipoacc = curr.get(25)[0]; str = curr.get(24); dataacc = TDate(str); // se l'accesso è una donazione if (tipoacc == 'D') { tipodon = curr.get(27)[0]; switch (tipodon) { case '1': tipodon_at = "SI"; break; case '2': tipodon_at = "PL"; break; case '3': tipodon_at = "PT"; break; default: tipodon_at = ""; break; } str = curr.get(26); if ((str.left(2) == "52") || (str.left(2) == "53") || (str.left(2) == "54") || (str.left(2) == "55")) luogodon_at = "0001"; else { if (sogg.get(SOG_CODSEZ) == "13") luogodon_at = "1301"; else luogodon_at = "0000"; } if (tipodon_at.not_empty()) update |= test_donation(sogg, tipodon_at, dataacc, luogodon_at); if (update) { rel.rewrite(); rigastampa.format("Inserita donazione del %s a %s %s %s", (const char*) dataacc.string(), (const char*) cognome, (const char*) nome, (const char*) datanasc); print_line(rigastampa); } } // aggiungere le visite e i controlli } //cancelled = pi.iscancelled(); } _trasfile->close(); print_footer(); //if (cancelled) // message_box("Operazione annullata: il trasferimento non è stato completato"); //else // message_box("Operazione terminata"); } else error_box("Errore in apertura stampante."); } //inizializza il file di testo su cui emettere i dati void TCtDonpr2at::inizializza_file() { TFilename filect = _msk->get(F_FILENAME); //aggiungere lettura automatica nomi file _trasfile->open(filect,'r'); } // handler per gestire la conferma dell'annullamento dei dati inseriti // nella maschera bool TCtDonpr2at::annulla_handler(TMask_field& f, KEY k) { TMask &m = f.mask(); if (k == K_SPACE) { if (yesno_box("Vuoi veramente annullare i dati inseriti")) m.reset(); } return TRUE; } void TCtDonpr2at_file::preformat_field(const TFieldref&field,TString &str,TRelation& rel,const TString &tipo_tr) { TString tmp; TString80 fieldname = field.name(); if (fieldname == "SESSO") { const char sesso = str[0]; if (sesso == 'M') str = "1"; else if (sesso == 'F') str = "2"; else str = " "; } else if (fieldname == "PREFERENZE") // giorno preferito donazione { str << "XXXXXXX"; str = str.sub(0,7); for (int i = 0; i< 7; i++) { if (str[i] != 'X') str[i] = 'X'; else str[i] = ' '; } } else if ((fieldname == "CODCF") || (fieldname == "TESSSSN")) { tmp = rel.curr(field.file()).get(fieldname); if (tmp.not_empty()) str.cut(0); } } int at8a00(int argc, char* argv[]) { TCtDonpr2at a; a.run(argc, argv, "Acquisizione donazioni da SIT Parma"); return 0; }