#include "hacnvlib.h" #include "halib.h" #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // THardy_iterator /////////////////////////////////////////////////////////// bool THardy_iterator::cancelled() const { return _pi != NULL && _pi->iscancelled(); } bool THardy_iterator::ok() const { if (cancelled()) return _ht->log_cancelled(); return _rec >= 0 && _rec < _ht->recordset().items(); } THardy_iterator& THardy_iterator::operator=(TRecnotype n) { if (_pi != NULL) _pi->setstatus(n+1); _ht->recordset().move_to(_rec = n); return *this; } THardy_iterator& THardy_iterator::operator++() { return *this = ++_rec; } THardy_iterator::THardy_iterator(THardy_transfer* ht) : _ht(ht), _pi(NULL) { const TRecnotype tot = _ht->recordset().items(); TString title; title << _ht->title() << ": " << tot << ' ' << TR("righe"); if (tot > 1) _pi = new TProgind(tot, title, true, true); else ::begin_wait(); if (tot > 0) _ht->log(title); _rec = -1; } THardy_iterator::~THardy_iterator() { if (_pi != NULL) delete _pi; else ::end_wait(); } /////////////////////////////////////////////////////////// // Cache tabelle /////////////////////////////////////////////////////////// class TCache_tab : public TCache_th { protected: virtual TObject* key2obj(const char* key); public: virtual const TString& decode(const TToken_string& cod_codtab); TCache_tab(THardy_transfer* ht) : TCache_th(ht) {} }; const TString& TCache_tab::decode(const TToken_string& cod_codtab) { TString4 cod; cod_codtab.get(0, cod); if (cod.full()) { const TRectype& rec = *(const TRectype*)objptr(cod_codtab); if (!rec.empty()) { const char* field = "CODTAB"; if (cod == "%TPM" || cod == "%TPP" || cod == "%TPI") // Tipo trasporto e porto field = "S6"; return rec.get(field); } } return EMPTY_STRING; } TObject* TCache_tab::key2obj(const char* key) { TToken_string tok(key); TString4 tab = tok.get(); tab.upper(); TString80 cod = tok.get(); cod.upper(); if (tab == "%IVA") { // Campo non digerisce i codici IVA numerici di un solo carattere if (cod.len() < 2 && isdigit(cod[0])) cod.right_just(2, '0'); // per cui aggiungo uno 0 iniziale } TTable table(tab); table.put("CODTAB", cod); if (table.read() != NOERR) { table.zero(); table.put("CODTAB", cod); table.put("S0", cod); test_write(table); } return table.curr().dup(); } /////////////////////////////////////////////////////////// // THardy_transfer /////////////////////////////////////////////////////////// void THardy_transfer::init(const char* title, const char* qry_hdr, THardy_log& log) { _log = &log; _log->reset(); _log->set_title(title); _query_header = qry_hdr; _write_enabled = true; } const TString& THardy_transfer::title() const { return _log->title(); } void THardy_transfer::log(const char* msg, int sev) const { _log->log(sev, msg); } TRecordset& THardy_transfer::create_recordset(const char* query) { if (_recset != NULL) { delete _recset; _recset = NULL; } if (_outset != NULL) { _outset->exec("COMMIT TRANS"); delete _outset; _outset = NULL; } TString qry = query; if (!qry.starts_with("US") && !qry.starts_with("ODBC")) qry.insert(query_header()); _recset = ::create_recordset(qry); return *_recset; } const TRecordset& THardy_transfer::recordset() const { CHECK(_recset != NULL, "NULL recordset"); return *_recset; } TRecordset& THardy_transfer::recordset() { CHECK(_recset != NULL, "NULL recordset"); return *_recset; } long THardy_transfer::odbc_exec(const char* cmd) { long err = 0; if (_write_enabled) { if (_outset == NULL) { _outset = new TODBC_recordset(query_header()); err = _outset->exec("BEGIN TRANS"); } if (err >= 0) { err = _outset->exec(cmd); if (err < 0) { log("", 0); // Salto una riga TParagraph_string msg(cmd, 100); FOR_EACH_TOKEN(msg, str) log(str, 0); // Riporto tutta la query log_error(TR("ERRORE in esecuzione della query.")); } } else { TString msg; msg << TR("ERRORE di connessione a ") << _outset->dsn() << " : BEGIN TRANS"; log_error(msg); } } return err; } bool THardy_transfer::log_error(const char* msg) { log(msg, 2); if (_write_enabled) { _write_enabled = false; log(""); log(TR("LA SCRITTURA SUGLI ARCHIVI VIENE DISABILITATA DA QUESTO MOMENTO IN POI"), 2); log(""); } return false; } bool THardy_transfer::log_cancelled() { return log_error(TR("Procedura interrotta dall'utente")); } void THardy_transfer::show_log() { _log->preview(); _log->destroy(); } bool THardy_transfer::test_write(TBaseisamfile& file) { int err = NOERR; if (_write_enabled) { err = file.write_rewrite(); if (err != NOERR) { TString msg; TString80 code, desc; const int logic = file.num(); if (logic == LF_TAB || logic == LF_TABCOM || logic == LF_TABMOD) { code = file.get("CODTAB"); desc = file.get("S0"); } else { code = file.curr().build_key(1); desc = file.curr().build_key(2); } msg.format(FR("Errore %d durante la scrittura sul file %d: %s - %s"), err, logic, (const char*)code, (const char*)desc); log_error(msg); } } return err == NOERR; } const TString& THardy_transfer::get_str(const char* field) const { return recordset().get(field).as_string(); } const TString& THardy_transfer::get_real_str(const char* campo) const { const TVariant& var = recordset().get(campo); if (var.is_zero()) return EMPTY_STRING; return var.as_string(); } real THardy_transfer::get_real(const char* field) const { return recordset().get(field).as_real(); } long THardy_transfer::get_long(const char* field) const { return recordset().get(field).as_int(); } const TString& THardy_transfer::decode_value(const char* tab, const TString& cod) { if (cod.full()) { if (_tab == NULL) _tab = new TCache_tab(this); TToken_string tok; tok.add(tab); tok.add(cod); return _tab->decode(tok); } return EMPTY_STRING; } const TString& THardy_transfer::decode_field(const char* tab, const char* field) { const TString& cod = get_str(field); return decode_value(tab, cod); } const TString& THardy_transfer::build_insert_query(const char* table, const char* f, const char* v) const { TString qry(255); qry << "INSERT INTO " << table; TAuto_token_string fields(f); TToken_string values(v); if (fields.items() > 0) { qry << " ("; FOR_EACH_TOKEN(fields, tok) qry << tok << ','; qry.rtrim(1); qry << ')'; } qry << " VALUES ("; TString tmp; FOR_EACH_TOKEN(values, tok) { tmp = tok; if (tmp.full() && !tmp.starts_with("0") && real::is_natural(tmp)) qry << tok; else { if (tmp[0] != '\'') { for (int i = tmp.len()-1; i >= 0; i--) { if (tmp[i] == '\'') tmp.insert("'", i); } qry << '\'' << tmp << '\''; } else qry << tmp; } qry << ','; } qry.rtrim(1); qry << ')'; return get_tmp_string() = qry; } THardy_transfer::THardy_transfer() : _log(NULL), _config("hacnv100a.ini"), _recset(NULL), _outset(NULL), _tab(NULL) {} THardy_transfer::~THardy_transfer() { if (_tab != NULL) delete _tab; if (_outset != NULL) { _outset->exec("COMMIT TRANS"); delete _outset; } if (_recset != NULL) delete _recset; } void THardy_transfer::aggiorna_record(TRectype& rec, const TString_array& lista_campi) { TString campo_dest, campo_orig, valore, str; FOR_EACH_ARRAY_ROW(lista_campi,i,row) { row->get(0, campo_dest); row->get(1, campo_orig); if (campo_orig.full()) { if (campo_orig[0] == '_') { if (campo_orig.starts_with("_SCONTO")) // è uno sconto (ca..o!) { valore.cut(0); real sconto; TString8 field; for (int i = 1; i < 6; i++) { field.format("Sconto%1d",i); sconto = get_real(field); sconto.round(2); if (sconto != ZERO) { valore << sconto.string(); valore << "+"; } } if (valore.len()>0) valore = valore.left(valore.len()-1); } else if (campo_orig.starts_with("_REAL")) // è un real { const TString80 campo = campo_orig.after(','); valore = get_real_str(campo); } else if (campo_orig.starts_with("_ROUND")) // arrotondo a due decimali { const TString80 campo = campo_orig.after(','); real contenuto = get_real(campo); contenuto.round(2); valore = contenuto.string(); } else if (campo_orig.starts_with("_FISSO")) // valore fisso indicato in configurazione { valore = campo_orig.after(','); valore.trim(); } else if (campo_orig.starts_with("_STREXPR")) // formato _STREXPR, espressione { TExpression expr(campo_orig.after(','), _strexpr); for (int v = 0; v < expr.numvar(); v++) { const char* varname = expr.varname(v); expr.setvar(v, get_str(varname)); } valore = expr.as_string(); valore.trim(); } else if (campo_orig.starts_with("_TAB")) // formato _TAB,,, { TToken_string elabora(campo_orig, ','); const TString4 tab = elabora.get(1); // tabella da leggere const TString16 codtab = get_str(elabora.get()); const TString16 campotab = elabora.get(); valore = cache().get(tab, codtab, campotab); } else if (campo_orig.starts_with("_TRADUCI")) { const TString80 campo = campo_orig.after(','); const TString80 contenuto = get_str(campo); TConfig& ini = config(); valore = ini.get(contenuto,campo); } else valore.cut(0); } else valore = get_str(campo_orig); rec.put(campo_dest, valore); } } } void THardy_transfer::aggiorna_ini(TConfig& conf, const TString_array& lista_campi) { TString campo_dest, campo_orig, valore, str; FOR_EACH_ARRAY_ROW(lista_campi,i,row) { row->get(0, campo_dest); row->get(1, campo_orig); if (campo_orig.full()) { if (campo_orig[0] == '_') { if (campo_orig.starts_with("_FISSO")) // valore fisso indicato in configurazione { valore = campo_orig.after(','); valore.trim(); } else if (campo_orig.starts_with("_STREXPR")) // formato _STREXPR, espressione { TExpression expr(campo_orig.after(','), _strexpr); for (int v = 0; v < expr.numvar(); v++) { const char* varname = expr.varname(v); expr.setvar(v, get_str(varname)); } valore = expr.as_string(); valore.trim(); } else if (campo_orig.starts_with("_TAB")) // formato _TAB,,, { TToken_string elabora(campo_orig, ','); const TString4 tab = elabora.get(1); // tabella da leggere const TString16 codtab = get_str(elabora.get()); const TString16 campotab = elabora.get(); valore = cache().get(tab, codtab, campotab); } else if (campo_orig.starts_with("_TRADUCI")) { const TString80 campo = campo_orig.after(','); const TString80 contenuto = get_str(campo); TConfig& ini = config(); valore = ini.get(contenuto,campo); } else valore.cut(0); } else valore = get_str(campo_orig); conf.set(campo_dest, valore); } } }