#include #include #include #include #include #include #include #include #include #include #include "at8.h" #include "at8800a.h" #include "atlib.h" #include "contsan.h" #include "donaz.h" #include "idoneita.h" #include "soggetti.h" #define ATFILENAME "pippo.txt" ///////////////////////////////////////////////////// // Classe TCtbo2at_file customizzata dalla TFile_text // ///////////////////////////////////////////////////// class TCtbo2at_file: public TFile_text { protected: virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); public: virtual int autosave(TRelation& rel, const TRecord_text& rec); TCtbo2at_file(const TString& file_name, const TString& config_name); virtual ~TCtbo2at_file() { } }; TCtbo2at_file::TCtbo2at_file(const TString& file_name, const TString& config_name) : TFile_text(file_name, config_name) { } int TCtbo2at_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(); switch(tipo_campo) { case _datefld: { 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: 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 TCtbo2at: applicazione principale // ///////////////////////////////////////////////////// class TCtbo2at: public TSkeleton_application { TMask* _msk; TCtbo2at_file* _trasfile; 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); public: const TMask& msk() const { return *_msk; } TCtbo2at() {} virtual ~TCtbo2at() {} }; // restituisce un riferimento all' applicazione inline TCtbo2at& app() { return (TCtbo2at&) main_app();} // creazione dell'applicazione bool TCtbo2at::create() { open_files(LF_SOGGETTI, LF_DONAZ, LF_CONTSAN, LF_IDONEITA, 0); _msk = new TMask("at8800a"); _msk->set(F_FILENAME,ATFILENAME); _trasfile = NULL; return TSkeleton_application::create(); } // distruzione dell'applicazione bool TCtbo2at::destroy() { delete _msk; return TSkeleton_application::destroy(); } // carica la maschera void TCtbo2at::main_loop() { // Preimposta gli eventuali valori specificati sulla riga di comando //error_box("Attenzione: manca la configurazione del trasferimento!"); KEY key = K_ENTER; while (key != K_QUIT) { key = _msk->run(); if (key == K_ENTER) transfer(); } } bool TCtbo2at::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); donazioni.insert_row(rec); donazioni.write(TRUE); calcola_donazioni_lib(recsog, &donazioni); // questo metodo sistema tutto!!! return TRUE; } bool TCtbo2at::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); const int r = idoneita.last_row(); //se trova una data idoneita >= di quella in esame, quest'ultima if (r > 0) //viene ignorata { 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 rec->put(IDO_IDO_SOS, "ID"); rec->put(IDO_INTERVALLO, inter); idoneita.add_row(rec); idoneita.write(); con_reord(recsog, &controlli, &idoneita); return TRUE; } // trasferimento dati da file CT su programma avis void TCtbo2at::transfer() { TFilename ctboini = "ctbo2at.ini"; _trasfile = new TCtbo2at_file(_msk->get(F_FILENAME), ctboini); inizializza_file(); TRelation rel(LF_SOGGETTI); TRectype& sogg = rel.curr(); TString8 str; // Stringa jolly di lavoro TRecord_text curr; while (_trasfile->read(curr) == NOERR) { str = curr.get(2); sogg.put(SOG_CODICE, str); if (rel.read() != NOERR) sogg.zero(); _trasfile->autosave(rel, curr); //const long codsog = atol(curr.get(2)); const char* tipo[] = { "SI", "PL", "PI", "PP" }; for (int i = 0; i < 4; i++) { bool update = FALSE; TDate datadon(TODAY); str = curr.get(23+i); if (!str.blank()) { datadon = TDate(str); str = curr.get(32); if (str == "UROM ") str = "013"; else if (str == "UROB ") str = "O.BE"; else if (str == "IMOLA ") str = "70"; update |= test_donation(sogg, tipo[i], datadon, str); } str = curr.get(27+i); if (!real::is_null(str)) { update |= test_inter(sogg, tipo[i], datadon, atoi(str)); } if (update) rel.rewrite(); } } _trasfile->close(); message_box("Operazione terminata"); } //inizializza il file di testo su cui emettere i dati void TCtbo2at::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 TCtbo2at::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; } // gestione dei messaggi estesi nei campi void TCtbo2at_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) { const TString code(s.get(0)); TString valore; if (code == "_TOTALE") { } else if (code == "_ULTIMA") { } else NFCHECK("Macro non definita: %s", (const char *)code); str = valore; } int at8800(int argc, char* argv[]) { TCtbo2at a ; a.run(argc, argv, "Acquisizione dati da CT Bologna"); return 0; }