512 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			512 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "hacnvlib.h"
 | ||
| #include "halib.h"
 | ||
| 
 | ||
| #include <applicat.h>
 | ||
| #include <automask.h>
 | ||
| #include <defmask.h>
 | ||
| #include <progind.h>
 | ||
| #include <reprint.h>
 | ||
| #include <reputils.h>
 | ||
| #include <tabutil.h>
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // THardy_iterator
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| bool THardy_iterator::cancelled() const
 | ||
| {
 | ||
|   return _pi != NULL && _pi->is_cancelled();
 | ||
| }
 | ||
| 
 | ||
| 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->set_status(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");
 | ||
|   _pi = new TProgress_monitor(tot, title);
 | ||
| 
 | ||
|   if (tot > 0)
 | ||
|     _ht->log(title);
 | ||
| 
 | ||
|   _rec = -1;
 | ||
| }
 | ||
| 
 | ||
| THardy_iterator::~THardy_iterator()
 | ||
| {
 | ||
|   delete _pi;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // 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();
 | ||
| }
 | ||
| 
 | ||
| TDate THardy_transfer::get_date(const char* field) const
 | ||
| {
 | ||
|   return recordset().get(field).as_date();
 | ||
| }
 | ||
| 
 | ||
| long THardy_transfer::get_cli(const char* field) const
 | ||
| {
 | ||
|    const TString& key = get_str(field);
 | ||
|    return hd_key2cli(key);
 | ||
| }
 | ||
| 
 | ||
| long THardy_transfer::get_for(const char* field) const
 | ||
| {
 | ||
|    const TString& key = get_str(field);
 | ||
|    return hd_key2for(key);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 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")) // <20> 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")) // <20> 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,<tabella da leggere>,<valore CODTAB>, <campo da leggere>
 | ||
| 				{
 | ||
|   				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,<tabella da leggere>,<valore CODTAB>, <campo da leggere>
 | ||
| 				{
 | ||
|   				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);
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 |