#include #include #include #include #include //#include #include #include #include #include #include "../ca/pconana.h" #include "../ca/movana.h" #include "../ca/rmovana.h" #include "../ca/calib01.h" #include "../ca/calib02.h" #include "crpa1a.h" //--------------------------------- // TAutomask //--------------------------------- class TBudget_Import_mask : public TAutomask { protected: bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool select_file_ext(const char* ext, TFilename& filename); public: TBudget_Import_mask(); virtual ~TBudget_Import_mask(){}; }; TBudget_Import_mask::TBudget_Import_mask() :TAutomask ("crpa1a") { } bool TBudget_Import_mask::select_file_ext(const char* ext, TFilename& filename) { TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@48"); TFilename path = get(F_PATH); path.add("*"); path.ext(ext); list_files(path, as.rows_array()); TFilename name; FOR_EACH_ARRAY_ROW(as.rows_array(), i, row) { name = *row; *row = name.name(); } bool ok = as.run() == K_ENTER; if (ok) { filename = as.row(as.selected()); } return ok; } bool TBudget_Import_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) { switch (f.dlg()) { //giochetto per avere la lista dei files validi nella directory di trasferimento! case F_NAMEFILE: if (e == fe_button) { TFilename name; if (select_file_ext("csv", name)) f.set(name); if (f.get() == get(F_LASTFILE)) return error_box(FR("Questo file l'hai gia' importato!\nCaro %s ti consiglio di NON proseguire!"), (const char*)user()); } break; case F_KILLOLD: if (e == fe_close) { if (f.get().full()) { return yesno_box(FR("Ehi %s, hai scelto di eliminare tutti i record di tipo Preventivo\nnei files dei movimenti e dei saldi!\nSei sicuro di voler proseguire?"), (const char*)user()); } } break; default: break; } return true; } //-------------------------------- // TFile_text //-------------------------------- class TBudget_Import_file: public TFile_text { protected: virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); public: TBudget_Import_file(const TString& file_name); virtual ~TBudget_Import_file() { } }; TBudget_Import_file::TBudget_Import_file(const TString& file_name) : TFile_text(file_name, "crpa1.ini") { } void TBudget_Import_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) { const TString code(s.get(0)); TString valore = str; if (code == "_UPPERCASE") { valore.upper(); } else NFCHECK("Macro non definita: %s", (const char *)code); str = valore; } //---------------------------------- // TSkeleton_application //---------------------------------- class TBudget_Import : public TSkeleton_application { TBudget_Import_mask* _msk; TBudget_Import_file* _trasfile; TConfig* _configfile; TRelation* _relmovana; TCursor* _cur; TProgind* _prog; TString _lastfile; TString4 _codcaus; virtual const char * extra_modules() const {return "ba";} protected: void mask2ini(); void ini2mask(); bool transfer(); void transfer_movimento(const TRecord_text& curr); //, TError_log& log); const TString& ana2bill(const TString& contone) const; long get_next_key(); public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); TBudget_Import() {} }; long TBudget_Import::get_next_key() { TLocalisamfile& lfile = _relmovana->lfile(); long numreg = 1L ; if (!lfile.empty()) { lfile.zero() ; lfile.setkey(1) ; lfile.read(_isgteq); if (lfile.good()) //se e' tutto ok,si posiziona sull'ultimo record lfile.last(); if (lfile.good()) numreg += lfile.get_long(MOVANA_NUMREG); } return numreg; } const TString& TBudget_Import::ana2bill(const TString& contone) const { TToken_string key; key = contone; key.add("1"); const TRectype& rec = cache().get(LF_PANAPDC, key); if (rec.empty()) return EMPTY_STRING; TString& tmp = get_tmp_string(); tmp.format("%03d%03d%06ld", rec.get_int("GRUPPO"), rec.get_int("CONTO"), rec.get_long("SOTTOCONTO")); return tmp; } void TBudget_Import::transfer_movimento(const TRecord_text& curr) //, TError_log& log) { //formato definitivo del tracciato record dei CSV da importare (vedi anche il file crpa1.ini): //codice commessa|conto|importo|inizio cms|fine cms TString codcms = curr.get(0); codcms.replace('_', '/'); const TString codconto = curr.get(1); const real soldini = curr.get(2); const TString16 str_dataini = curr.get(3); const TString16 str_datafine = curr.get(4); TString4 gg = str_dataini.left(2); TString4 mm = str_dataini.mid(3,2); TString4 yy = str_dataini.right(2); yy.insert("20", 0); const TDate dataini(atoi(gg),atoi(mm),atoi(yy)); const int annoes = dataini.year(); gg = str_datafine.left(2); mm = str_datafine.mid(3,2); yy = str_datafine.right(2); yy.insert("20", 0); const TDate datafine(atoi(gg),atoi(mm),atoi(yy)); //cerca il primo posto libero in movana long numreg = get_next_key(); //TESTATA //crea il movimento di prima nota da aggiungere a movana TAnal_mov movana(numreg); movana.zero(); //azzera per sicurezza //sbatte i dati nei campi movana.put(MOVANA_NUMREG, numreg); movana.put(MOVANA_ANNOES, annoes); movana.put(MOVANA_DATAREG, dataini); movana.put(MOVANA_DATACOMP, dataini); movana.put(MOVANA_DESCR, "Movimento di budget importato"); movana.put(MOVANA_CODCAUS, _codcaus); movana.put(MOVANA_TIPOMOV, 'P'); movana.put(MOVANA_TOTDOC, soldini); TString query; TString tmp_codconto; tmp_codconto << "'" << codconto << "'"; query << "USE PCONANA KEY 1 \n"; query << "SELECT CODCONTO[10,15]=" << tmp_codconto; TISAM_recordset pconana(query); const TRecnotype items = pconana.items(); if (items <= 0) warning_box(FR("Il sottoconto %s NON esiste!"), (const char*)codconto); if (items > 1) warning_box(FR("Esiste piu' di un sottoconto %s!"), (const char*)codconto); pconana.move_last(); //si posiziona sul record corretto const TString& contone = pconana.get(PCONANA_CODCONTO).as_string(); const TString& contcon = ana2bill(contone); if (contcon.empty()) warning_box(FR("Il conto analitico %s non corrisponde ad alcun conto contabile!"), (const char*)contone); const TString& sezione = pconana.get(PCONANA_SEZSALDI).as_string(); //mette quella bastarda di sezione nel record movana.put(MOVANA_SEZIONE, sezione); //RIGA //la riga sara' solo 1 per testata, almeno secondo l'attuale modalita' di import/export del CRPA TRectype& rec_rmovana = movana.new_row(); rec_rmovana.put(RMOVANA_ANNOES, annoes); rec_rmovana.put(RMOVANA_NUMREG ,numreg); rec_rmovana.put(RMOVANA_NUMRIG ,1); rec_rmovana.put(RMOVANA_SEZIONE ,sezione); rec_rmovana.put(RMOVANA_DATACOMP ,dataini); rec_rmovana.put(RMOVANA_CODCMS ,codcms); rec_rmovana.put(RMOVANA_CODCONTO, contcon); rec_rmovana.put(RMOVANA_DESCR, "Riga movimento di budget importato"); rec_rmovana.put(RMOVANA_IMPORTO, soldini); //scrive testata e riga e aggiorna i saldi (write() magggica!) TLocalisamfile testate(LF_MOVANA); movana.write(testate); } bool TBudget_Import::transfer() { //azzeramento preventivo di movimenti, righe e saldi di tipo P if (_msk->get(F_KILLOLD)) { TRelation relmovana(LF_MOVANA); TCursor curmovana(&relmovana, "TIPOMOV=='P'"); const TRectype& recmovana = relmovana.curr(); const long nrec = curmovana.items(); curmovana.freeze(); TProgind pi(nrec, "Eliminazione movimenti preventivi in corso..."); TLocalisamfile movana(LF_MOVANA); //questo serve alla remove() for (curmovana = 0; curmovana.pos() < nrec; ++curmovana) { TAnal_mov anal_kill(curmovana.curr()); anal_kill.remove(movana); //la remove() accoppa anche le righe collegate } } //file da trasferire //costruire il nome del file con path TFilename file = _msk->get(F_PATH); file.add(_msk->get(F_NAMEFILE)); file.ext("csv"); _trasfile = new TBudget_Import_file(file); _trasfile->open(file,'r'); //la causale!!! _codcaus = _msk->get(F_COD_CAUS); //*** prima va inserito il log in libreria preparazione del log // TError_log log; // log.set_header(TR("Importazione movimenti")); const long dimension = fsize(file); TProgind pi(dimension,TR("Importazione movimenti in corso...")); int err = NOERR; TRecord_text curr; while (_trasfile->read(curr) == NOERR && !pi.iscancelled() && err == NOERR) { pi.setstatus(_trasfile->read_file()->tellg()); transfer_movimento(curr); //, log); } _trasfile->close(); delete _trasfile; // log.show(); _lastfile = _msk->get(F_NAMEFILE); return true; } void TBudget_Import::mask2ini() { //aggiorna l'ultimo file inviato su msk e ini _msk->set(F_LASTFILE, _lastfile); _configfile->set_paragraph("BUDGET"); _configfile->set("PATH", _msk->get(F_PATH)); _configfile->set("LASTFILE", _lastfile); _msk->set(F_COD_CAUS, _codcaus); _configfile->set("CODCAUS", _msk->get(F_COD_CAUS)); } void TBudget_Import::ini2mask() { //carica i parametri del file di configurazione _configfile->set_paragraph("BUDGET"); TString path = _configfile->get("PATH"); _msk->set(F_PATH, path); _lastfile = _configfile->get("LASTFILE"); _msk->set(F_LASTFILE, _lastfile); _codcaus = _configfile->get("CODCAUS"); _msk->set(F_COD_CAUS, _codcaus); } bool TBudget_Import::create() { _configfile = new TConfig("crpa1conf.ini"); _msk = new TBudget_Import_mask(); open_files(LF_MOVANA, LF_RMOVANA, LF_PCONANA, 0); _relmovana = new TRelation(LF_MOVANA); return TSkeleton_application::create(); } bool TBudget_Import::destroy() { delete _msk; delete _configfile; return TApplication::destroy(); } void TBudget_Import::main_loop() { KEY tasto; ini2mask(); tasto = _msk->run(); if (tasto == K_ENTER) { if (transfer()) message_box(TR("Importazione movimenti completata")); } mask2ini(); } int main(int argc, char** argv) { TBudget_Import a; a.run(argc, argv, TR("Importazione movimenti di budget per CRPA")); return 0; }