#include "halib.h"
#include "hacnvlib.h"
#include "hacnv100a.h"

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <progind.h>
#include <reprint.h>
#include <reputils.h>
#include <tabutil.h>

#include <clifo.h>
#include <pconti.h>
#include "..\pr\agenti.h"
#include "..\mg\anamag.h"
#include <..\ve\condv.h>
#include <..\ve\rcondv.h>

const char* const APPNAME = TR("Conversione anagrafiche"); 

///////////////////////////////////////////////////////////
// Trasferimenti veri e propri
///////////////////////////////////////////////////////////

class THardy_pag : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_iva : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_catmerc : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_catfisc : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_ban : public THardy_transfer
{
protected:
  bool trasferisci_abi();
  bool trasferisci_cab();

public:
  virtual bool trasferisci();
};

class THardy_caucont : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_caumag : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_um : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_art : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_pcon : public THardy_transfer
{
protected:
  bool trasferisci_gruppi();
  bool trasferisci_conti();
  bool trasferisci_sottoconti();

public:
  virtual bool trasferisci();
};

class THardy_clienti : public THardy_transfer
{
protected:
  bool is_piva_doppia(const long codcf);
  int get_next_key_indsped(const char tipocf, const long codcf) const;
  bool trasferisci_clienti();
  bool trasferisci_destinazioni();

public:
  virtual bool trasferisci();
};

class THardy_fornitori : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_agenti : public THardy_transfer
{
protected:
  const TString& get_codage(const TString& key) const;
public:
  virtual bool trasferisci();
};

class THardy_listini : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_contratti : public THardy_transfer
{
public:
  virtual bool trasferisci();
};

class THardy_listinicli : public THardy_transfer
{
protected:
  int get_next_key_cli(const char tipocf, const long codcf) const;
public:
  virtual bool trasferisci();
};

///////////////////////////////////////////////////////////
// THardy_pag
///////////////////////////////////////////////////////////

bool THardy_pag::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Pagamenti ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CPG", true);
  TTable table("%CPG");
	TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_iva
///////////////////////////////////////////////////////////

bool THardy_iva::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.AliquoteIVA ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "IVA", true);
  TTable table("%IVA");
	TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_catmerc
///////////////////////////////////////////////////////////

bool THardy_catmerc::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.CategorieMerc ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "GMC", true);
  TTable table("GMC");
  TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_catfisc
///////////////////////////////////////////////////////////

bool THardy_catfisc::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.CategorieFisc ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "ASF", true);
  TTable table("%ASF");
	TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_ban
///////////////////////////////////////////////////////////

bool THardy_ban::trasferisci()
{
  bool ok = trasferisci_abi();
  if (ok)
    ok = trasferisci_cab();
  return ok;
}

bool THardy_ban::trasferisci_abi()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Banche ";
  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "ABI", true);
  TSystemisamfile table(LF_TABCOM);
  table.open(_lock); 
  TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
		TString16 codtab = get_str("IdBanca");
    codtab.lpad(5,'0');
  	rec.zero();
		rec.put("COD", "BAN");
		rec.put("CODTAB", codtab);
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  table.close();
  return write_enabled();
}

bool THardy_ban::trasferisci_cab()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Agenzie ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CAB", true);
  TSystemisamfile table(LF_TABCOM);
  table.open(_lock); 
  TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
		TString16 codtab = get_str("IdBanca");
    codtab.lpad(5,'0');
    codtab << get_str("Cab");
  	rec.zero();
    rec.put("COD", "BAN");
		rec.put("CODTAB", codtab);
    aggiorna_record(rec, lista_campi);
		test_write(table);
  }
  table.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_caucont
///////////////////////////////////////////////////////////

bool THardy_caucont::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.CausaliContab ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CAUCONT", true);
  TSystemisamfile table(LF_CAUSALI);
  table.open(_lock); 
  TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  table.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_caumag
///////////////////////////////////////////////////////////

bool THardy_caumag::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.CausaliMagaz ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CAUMAG", true);
  TTable table("%CAU");
	TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_um
///////////////////////////////////////////////////////////

bool THardy_um::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.UnitaMisura ";
  TRecordset& recset = create_recordset(query);
	TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "UM", true);
  TTable table("%UMS");
	TRectype& rec = table.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
  	rec.zero();
    aggiorna_record(rec, lista_campi);
    test_write(table);
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_art
///////////////////////////////////////////////////////////

bool THardy_art::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Articoli ";
  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	TString_array lista_campi_anamag, lista_campi_umart;
	ini.list_variables(lista_campi_anamag, true, "ANAMAG", true);
	ini.list_variables(lista_campi_umart, true, "UMART", true);
  TSystemisamfile anamag(LF_ANAMAG);
  anamag.open(_lock); 
  TRectype& rec_anamag = anamag.curr();
  TSystemisamfile umart(LF_UMART);
  umart.open(_lock); 
  TRectype& rec_umart = umart.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    aggiorna_record(rec_anamag, lista_campi_anamag);
    int gr, co;
    long so;
    TString16 key = get_str("IdContoRicavo");
    gr = 0;
    co = 0;
    so = 0;
    hd_key2conto(key, gr, co,so);
    rec_anamag.put(ANAMAG_GRUPPOV, gr);
    rec_anamag.put(ANAMAG_CONTOV, co);
    rec_anamag.put(ANAMAG_SOTTOCV, so);
    key = get_str("IdContoCosto");
    hd_key2conto(key, gr, co,so);
    rec_anamag.put(ANAMAG_GRUPPOA, gr);
    rec_anamag.put(ANAMAG_CONTOA, co);
    rec_anamag.put(ANAMAG_SOTTOCA, so);
    test_write(anamag);
    aggiorna_record(rec_umart, lista_campi_umart);
    test_write(umart);
  }
  anamag.close();
  umart.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_conti
///////////////////////////////////////////////////////////

bool THardy_pcon::trasferisci()
{
  if (trasferisci_gruppi())
    if (trasferisci_conti())
      return trasferisci_sottoconti();
  return false;
}

bool THardy_pcon::trasferisci_gruppi()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Mastri "
    "WHERE Livello=2";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi;
	ini.list_variables(lista_campi, true, "MASTRI", true);
  
  TSystemisamfile pcon(LF_PCON);
  pcon.open(_lock); 
  TRectype& rec = pcon.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    // costruisco la chiave gr.co.sc 
    const TString16 key = get_str("IdMastro");
    const TString& gruppo = key.mid(0,2);
    rec.zero();
    rec.put(PCN_GRUPPO, gruppo);
    aggiorna_record(rec, lista_campi);
    test_write(pcon);
  }
  pcon.close();
  return write_enabled();
}
bool THardy_pcon::trasferisci_conti()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Mastri "
    "WHERE Livello=1";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi_pcon;
	ini.list_variables(lista_campi_pcon, true, "MASTRI", true);
  const TString& esclusi = ini.get("PCON", "PARAMETRI");
 
  TSystemisamfile pcon(LF_PCON);
  pcon.open(_lock); 
  TRectype& rec_pcon = pcon.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    // costruisco la chiave gr.co
    const TString16 key = get_str("IdMastro");
    const int gr = atoi(key.mid(0,2));
    int co = atoi(key.mid(2,2));
    const int so = atoi(key.mid(4,3));
    if ((gr != 0) && (co != 0))
    {
      if (esclusi.find(key.mid(0,2))>=0)
        co = co*10+so;
      rec_pcon.zero();
      rec_pcon.put(PCN_GRUPPO, gr);
      rec_pcon.put(PCN_CONTO, co);
      aggiorna_record(rec_pcon, lista_campi_pcon);
      test_write(pcon);
    }
  }
  pcon.close();
  return write_enabled();
}

bool THardy_pcon::trasferisci_sottoconti()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Conti ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi_pcon, lista_cf;
	ini.list_variables(lista_campi_pcon, true, "CONTI", true);
  const TString& esclusi = ini.get("PCON", "PARAMETRI");
  
  TSystemisamfile pcon(LF_PCON);
  pcon.open(_lock); 
  TRectype& rec_pcon = pcon.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    // costruisco la chiave gr.co.sc 
    const TString16 key = get_str("IdConto");
    int gr, co;
    long so;
    gr = 0;
    co = 0;
    so = 0;
    hd_key2conto(key, gr, co,so);
    rec_pcon.zero();
    rec_pcon.put(PCN_GRUPPO, gr);
    if ((gr != 0) && (co != 0) && (so!= 0))
    {
      if (esclusi.find(key.mid(1,2))>=0)
        rec_pcon.put(PCN_CONTO, co*10+so);
      else
      {
        rec_pcon.put(PCN_CONTO, co);
        rec_pcon.put(PCN_SOTTOCONTO, so);
      }
      aggiorna_record(rec_pcon, lista_campi_pcon);
      test_write(pcon);
    }
  }
  pcon.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_clienti
///////////////////////////////////////////////////////////

bool THardy_clienti::trasferisci()
{
  bool ok = trasferisci_clienti();
  if (ok)
    ok = trasferisci_destinazioni();
  return ok;
}

// trasferisce i clienti
bool THardy_clienti::trasferisci_clienti()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Clienti ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CLIENTI", true);
  
  TSystemisamfile clienti(LF_CLIFO);
  clienti.open(_lock);
  TRectype& rec = clienti.curr();

  TSystemisamfile cfven(LF_CFVEN);
  cfven.open(_lock);
  TRectype& cfv_rec = cfven.curr();

  THardy_iterator hi(this);
  while (++hi)
  {
    // costruisco la chiave 
    const TString& key = get_str("IdConto");
    const long codcf = hd_key2cli(key);
    if (codcf > 0)
    {
      rec.zero();
      rec.put(CLI_TIPOCF, "C");
      rec.put(CLI_CODCF, codcf);

      const TString8 idmastro = get_str("IdMastro");
      TToken_string conto = ini.get(idmastro, "IdMastro_CLI");
      const int gruppo = conto.get_int(0);
      if (gruppo != 0)
      {
        rec.put(CLI_GRUPPO, gruppo);
        rec.put(CLI_CONTO, conto.get_int());
      }

      // banca
  		TString8 codabi = get_str("IdBanca");
      codabi.lpad(5,'0');
  		TString8 codcab = get_str("IdAgenzia");
      codcab.lpad(5,'0');
      TString16 codtab = codabi;
      codtab << codcab;
      const TRectype& ban = cache().get("%BAN", codtab);

      if (ban.empty())
      {
        codabi = "";
        codcab = "";
      }
      rec.put(CLI_CODABI, codabi);
      rec.put(CLI_CODCAB, codcab);     
      // ricerca comune
      const TString8 cap = get_str("IdCap");     //cap
      TString80 loc = get_str("Localita");       //localit�
      const TString4 com = cap2comune(cap,loc);  //codice comune
      const TString4 stato = get_str("IdNazione"); //stato

      rec.put(CLI_CAPCF, cap);   
      if (com.full())
      {
        rec.put(CLI_COMCF, com);  //se riesce la CAP2COMUNE, inserisco il codice comune  
        loc = "";
        rec.put(CLI_LOCCF, loc);
      }
      else 
      {
        rec.put(CLI_COMCF, com);
        if (stato != "IT" && !stato.blank())  //altrimenti metto tutto nella localit�, eventualmente concatenando lo stato
          loc << " - " << stato;
        rec.put(CLI_LOCCF, loc);
      }
      aggiorna_record(rec, lista_campi);
      if (test_write(clienti))
      {
  			TString msg;
	  		msg << TR("Inserito cliente ") << " '" << key << "\' -> " 
            << codcf << " - " << rec.get(CLI_RAGSOC);
		  	log(msg);
      }

      //Adesso tocca all'agente che va messo in cfven
      cfv_rec.zero();
      cfv_rec.put(CFV_TIPOCF, "C");
      cfv_rec.put(CFV_CODCF, codcf);
      const TString4 codzona = get_str("IdZona");
      cfv_rec.put(CFV_CODZONA, codzona);    
      TString8 codag = get_str("IdAgente1");  //agente principale
      codag.right_just(5, '0');
      cfv_rec.put(CFV_CODAG, codag);
      TString8 codlist = get_str("IdListino");
      cfv_rec.put(CFV_CODLIST, codlist);

      test_write(cfven);
    }
    else
    {
			TString msg;
			msg << TR("Impossibile determinare il codice del cliente") << " '" << key << '\'';
			log(msg);
    }
  }
  cfven.close();
  clienti.close();
  return write_enabled();
}

// verifica se esiste un altro cliente con stessa partita iva (solo tra 200000 e 300000) 
// per decidere se fare scambio dati tra destinazioni e clienti oppure inserire un indirizzo di spedizione
bool THardy_clienti::is_piva_doppia(const long codcf)
{
  TToken_string tok; tok.add("C"); tok.add(codcf);
  const TRectype& cli = cache().get(LF_CLIFO, tok);
  const TString& statopaiv = cli.get(CLI_STATOPAIV);
  const TString& paiv = cli.get(CLI_PAIV);
  
  TISAM_recordset clifo("USE CLIFO KEY 5\n"
                        "SELECT (CODCF>200000)&&(CODCF<300000)\n"
                        "FROM TIPOCF='C' STATOPAIV=#STATOPAIV PAIV=#PAIV\n"
                        "TO TIPOCF='C' STATOPAIV=#STATOPAIV PAIV=#PAIV");
  clifo.set_var("#STATOPAIV", TVariant(statopaiv));
  clifo.set_var("#PAIV", TVariant(paiv));
  return (clifo.items() > 1); // Spiegare??????????
}

// restituisce il codice indirizzo di spedizione da usare per inserimento record
int THardy_clienti::get_next_key_indsped(const char tipocf, const long codcf) const
{
  TISAM_recordset indsped("USE INDSPED\nFROM TIPOCF=#TIPO CODCF=#CODE\nTO TIPOCF=#TIPO CODCF=#CODE");
	TString4 str;	str << tipocf;
  indsped.set_var("#TIPO", TVariant(str));
  indsped.set_var("#CODE", TVariant(codcf));
  int codind = 1;
  if (indsped.items() > 0) // La move_last da errore fatale su recordset vuoti!
  {
    indsped.move_last();
    codind += indsped.get("CODIND").as_int();
  }
	return codind;
}

// trasferisce la tabella Destinazioni che vale sia come indirizzi di spedizione sia come verifica dei dati sui clienti
// in caso di partita iva doppia (solo clienti tra 200000 e 300000) prende i dati su Destinazioni 
// come dati anagrafici del clienti (esempio Esselunga)
bool THardy_clienti::trasferisci_destinazioni()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Destinazioni";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
  TString_array lista_campi, lista_campi_indsped;
	ini.list_variables(lista_campi, true, "DESTINAZIONI", true);
	ini.list_variables(lista_campi_indsped, true, "INDSPED", true);
  
  TSystemisamfile clifo(LF_CLIFO);
  TSystemisamfile indsped(LF_INDSP);
  clifo.open(_lock); 
  indsped.open(_lock); 
  TRectype& rec = clifo.curr();
  TRectype& rec_indsped = indsped.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    // costruisco la chiave 
    const TString& key = get_str("IdConto");
    const long codcf = hd_key2cli(key);
    rec.zero();
		rec.put(CLI_TIPOCF, "C");
		rec.put(CLI_CODCF, codcf);
		bool good = clifo.read() == NOERR;
		if (good)
		{
      if (codcf > 200000 && codcf < 300000 && is_piva_doppia(codcf))
      {
        // cambio dati tra clienti e destinazione
        
        // ricerca comune
        const TString8 cap = get_str("IdCap");     //cap
        TString80 loc = get_str("Localita");       //localit�
        const TString4 com = cap2comune(cap,loc);  //codice comune
        const TString4 stato = get_str("IdNazione"); //stato

        rec.put(CLI_CAPCF, cap);   
        if (com.full() && !com.blank())
        {
          rec.put(CLI_COMCF, com);  //se riesce la CAP2COMUNE, inserisco il codice comune  
          loc = "";
          rec.put(CLI_LOCCF, loc);
        }
        else 
        {
          rec.put(CLI_COMCF, com);
          if (stato != "IT" && !stato.blank())  //altrimenti metto tutto nella localit�, eventualmente concatenando lo stato
            loc << " - " << stato;
          rec.put(CLI_LOCCF, loc);
        }
        aggiorna_record(rec, lista_campi);
        if (test_write(clifo))
        {
  			  TString msg;
	  		  msg << TR("Modificato cliente ") << " '" << key << '\'' << TR(" con codice ") << codcf ;
		  	  log(msg);
        }
      }
      else
      {
        // inserisco indirizzo di spedizione
    		int codind = get_next_key_indsped('C', codcf);
				rec_indsped.zero();
				rec_indsped.put(IND_TIPOCF, "C");
				rec_indsped.put(IND_CODCF, codcf);
				rec_indsped.put(IND_CODIND, codind);
        aggiorna_record(rec_indsped, lista_campi_indsped);
        if (test_write(indsped))
        {
  			  TString msg;
	  		  msg << TR("Inserito indirizzo di spedizione ") << " '" << key << '\'' ;
		  	  log(msg);
        }
      }
    }
    else
    {
			TString msg;
			msg << TR("Impossibile stabilire cliente del codice destinazione") << " '" << key << '\'';
			log(msg);
    } 
  }
  clifo.close();
  indsped.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_fornitori
///////////////////////////////////////////////////////////

bool THardy_fornitori::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Fornitori ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi;
	ini.list_variables(lista_campi, true, "FORNITORI", true);
  
  TSystemisamfile clienti(LF_CLIFO);
  clienti.open(_lock); 
  TRectype& rec = clienti.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    const TString& key = get_str("IdConto");
    const long codcf = hd_key2forn(key);
    if (codcf > 0)
    {
      rec.zero();
      rec.put(CLI_TIPOCF, "F");
      rec.put(CLI_CODCF, codcf);

      const TString8 idmastro = get_str("IdMastro");
      TToken_string conto = ini.get(idmastro, "IdMastro_FOR");
      const int gruppo = conto.get_int(0);
      if (gruppo != 0)
      {
        rec.put(CLI_GRUPPO, gruppo);
        rec.put(CLI_CONTO, conto.get_int());
      }

      // contropartita
      const TString16 key = get_str("IdContropartita");
      int gr, co;
      long so;
      gr = 0;
      co = 0;
      so = 0;
      hd_key2conto(key, gr, co, so);
      rec.put(CLI_GRUPPORIC, gr);
      rec.put(CLI_CONTORIC, co);
      rec.put(CLI_SOTTOCRIC, so);

      // ricerca comune
      const TString8 cap = get_str("IdCap");     //cap
      TString80 loc = get_str("Localita");       //localit�
      const TString4 com = cap2comune(cap,loc);  //codice comune
      const TString4 stato = get_str("IdNazione"); //stato

      rec.put(CLI_CAPCF, cap);   
      if (com.full())
      {
        rec.put(CLI_COMCF, com);  //se riesce la CAP2COMUNE, inserisco il codice comune  
        loc = "";
        rec.put(CLI_LOCCF, loc);
      }
      else 
      {
        rec.put(CLI_COMCF, com);
        if (stato != "IT" && !stato.blank())  //altrimenti metto tutto nella localit�, eventualmente concatenando lo stato
          loc << " - " << stato;
        rec.put(CLI_LOCCF, loc);
      }
      aggiorna_record(rec, lista_campi);
      test_write(clienti);
    }
    else
    {
			TString msg;
			msg << TR("Impossibile determinare il codice del fornitore") << " '" << key << '\'';
			log(msg);
    }
  }
  clienti.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_agenti
///////////////////////////////////////////////////////////
const TString& THardy_agenti::get_codage(const TString& key) const
{ 
  TString& codage = get_tmp_string();
  codage = key;
  codage.right_just(5,'0');
  return codage;
}

bool THardy_agenti::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.Agenti ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	
  TString_array lista_campi;
	ini.list_variables(lista_campi, true, "AGENTI", true);
  
  TSystemisamfile agenti(LF_AGENTI);
  agenti.open(_lock); 
  TRectype& rec = agenti.curr();
  THardy_iterator hi(this);
  while (++hi)
  {
    const TString8 key = get_str("IdAgente");
    if (!real::is_null(key))
    {
      rec.zero();
      rec.put(AGE_CODAGE, get_codage(key));
      aggiorna_record(rec, lista_campi);
      if (test_write(agenti))
      {
  			TString msg;
	  		msg << TR("Inserito agente ") << " '" << key << "\' -> " 
            << rec.get(AGE_CODAGE) << " - " << rec.get(AGE_RAGSOC);
		  	log(msg);
      }

    }
    else
    {
			TString msg;
			msg << TR("Impossibile determinare il codice dell'agente") << " '" << key << '\'';
			log(msg);
    }
  }
  agenti.close();
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_listini
///////////////////////////////////////////////////////////

bool THardy_listini::trasferisci()
{
  // trasferisce tabella Listini (condv L)
  TString query = 
    "SELECT * "
		"FROM dbo.Listini ";
  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "LISTINI", true);
  TSystemisamfile condv(LF_CONDV);
  condv.open(_lock); 
  TRectype& rec = condv.curr();
  THardy_iterator hi(this);

  // array per la conversione tra IdListino e kListino
  TAssoc_array listini;

  TString8 idlistino;

  while (++hi)
  {
    const TString8 klistino = get_str("KListino");
    idlistino = get_str("IdListino");
    listini.add(klistino, idlistino);
    aggiorna_record(rec, lista_campi);
    test_write(condv);
  }
  condv.close();
  // trasferisce tabella ListiniD (RCONDV)
  if (write_enabled())
  {
    TString query = 
      "SELECT * "
		  "FROM dbo.ListiniD ";
    TRecordset& recset = create_recordset(query);
    TConfig& ini = config();
	  TString_array lista_campi;
	  ini.list_variables(lista_campi, true, "LISTINID", true);
    TSystemisamfile rcondv(LF_RCONDV);
    rcondv.open(_lock); 
    TRectype& rec = rcondv.curr();
    THardy_iterator hi(this);
    while (++hi)
    {
      const char* key = get_str("KListino");
      if (listini.is_key(key))
      {
        TString8& idlistino = (TString8&) listini[key];
        rec.put(RCONDV_COD, idlistino);
        aggiorna_record(rec, lista_campi);
        test_write(rcondv);
      }
      else
      {
			  TString msg;
  		  msg << TR("Impossibile stabilire codice del listino ") << " '" << key << '\'';
	  	  log(msg);
      }
    }
    rcondv.close();
  }
  return write_enabled();
}

///////////////////////////////////////////////////////////
// THardy_contratti
///////////////////////////////////////////////////////////

// trasferisce tabella contrattiT contrattiR e contrattiD
// inserisco una testata per ogni cliente e tutte le righe relative agli articoli di quel cliente
// tralasciando le righe con DataFine < data impostata da parametri
bool THardy_contratti::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.ContrattiT, dbo.ContrattiR "
    "WHERE dbo.ContrattiT.KContrattoT=dbo.ContrattiR.KContrattoT "
    "ORDER BY dbo.ContrattiR.IdConto ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	TString_array lista_campi;
	ini.list_variables(lista_campi, true, "CONTRATTI", true);
  TSystemisamfile condv(LF_CONDV);
  condv.open(_lock); 
  TRectype& rec = condv.curr();
  THardy_iterator hi(this);

  // array per la conversione tra kContrattoT e nostra chiave assegnata al contratto
  TAssoc_array contratti;

  TString8 idcontratto;

  long curr_cliente = 0;
  int curr_contratto = 0;

  while (++hi)
  {
    const TString8 kcontrattot = get_str("KContrattoT");
    idcontratto = get_str("IdContratto");
    const TString& key = get_str("IdConto");
    const long codcf = hd_key2cli(key);
    if (curr_cliente != codcf)
      curr_contratto=0;
    curr_contratto++; 
    aggiorna_record(rec, lista_campi);
    rec.put(CONDV_CODCF, codcf);
    rec.put(CONDV_COD, curr_contratto);
    contratti.add(kcontrattot, rec);
    test_write(condv);
  }
  condv.close();
  // trasferisce tabella ContrattiD (RCONDV)
  if (write_enabled())
  {
    TString query = 
      "SELECT * "
		  "FROM dbo.ContrattiD ";
    TRecordset& recset = create_recordset(query);
    TConfig& ini = config();
	  TString_array lista_campi;
	  ini.list_variables(lista_campi, true, "CONTRATTID", true);
    TSystemisamfile rcondv(LF_RCONDV);
    rcondv.open(_lock); 
    TRectype& rec = rcondv.curr();
    THardy_iterator hi(this);
    while (++hi)
    {
      const char* key = get_str("KContrattoT");
      if (contratti.is_key(key))
      {
        TRectype& rec_condv = (TRectype&) contratti[key];
        rec.put(RCONDV_COD, rec_condv.get(CONDV_COD));
        rec.put(RCONDV_CODCF, rec_condv.get(CONDV_CODCF));
        aggiorna_record(rec, lista_campi);
        test_write(rcondv);
      }
      else
      {
			  TString msg;
  		  msg << TR("Impossibile stabilire codice del contratto ") << " '" << key << '\'';
	  	  log(msg);
      }
    }
    rcondv.close();
  }
  return write_enabled();
}

// restituisce il codice contratto da usare per l'inserimento in condv
int THardy_listinicli::get_next_key_cli(const char tipocf, const long codcf) const
{
  TISAM_recordset condv("USE CONDV\nFROM TIPO=#TIPO CATVEN=#CATVEN TIPOCF=#TIPOCF CODCF=#CODCF\nTO TIPO=#TIPO CATVEN=#CATVEN TIPOCF=#TIPOCF CODCF=#CODCF");
	TString4 str;
  str = "C";
  condv.set_var("#TIPO", TVariant(str));
  str = "  ";
  condv.set_var("#CATVEN", TVariant(str));
  str = "C";
  condv.set_var("#TIPOCF", TVariant(str));
  condv.set_var("#CODCF", TVariant(codcf));
  int cod = 1;
  if (condv.items() > 0) // La move_last da errore fatale su recordset vuoti!
  {
    condv.move_last();
    cod += condv.get("COD").as_int();
  }
	return cod;
}

bool THardy_listinicli::trasferisci()
{
  TString query = 
    "SELECT * "
		"FROM dbo.ListiniCF "
    "ORDER BY dbo.ListiniCF.IdConto, dbo.ListiniCF.IdProdotto ";

  TRecordset& recset = create_recordset(query);
  TConfig& ini = config();
	TString_array lista_campi, lista_campi_rcondv;
	ini.list_variables(lista_campi, true, "LISTINICF", true);
	ini.list_variables(lista_campi_rcondv, true, "LISTINICF_RIGHE", true);
  TSystemisamfile condv(LF_CONDV);
  condv.open(_lock); 
  TRectype& rec = condv.curr();
  TSystemisamfile rcondv(LF_RCONDV);
  rcondv.open(_lock); 
  TRectype& rec_rcondv = rcondv.curr();

  THardy_iterator hi(this);

  long curr_cliente = 0;
  int curr_contratto = 0;

  const TDate oggi(TODAY);

  while (++hi)
  {
    const TDate datafine = TDate(get_str("DataFine"));
    if (datafine >= oggi)
    {
      const TString& key = get_str("IdConto");
      const long codcf = hd_key2cli(key);
      // scrivo la testata del listino cliente (CONDV C)
      if (curr_cliente != codcf)
      {
        curr_cliente = codcf;
        const int cod = get_next_key_cli('C', codcf);
        rec.put(CONDV_CODCF, codcf);
        rec.put(CONDV_COD, cod);
        aggiorna_record(rec, lista_campi);
        test_write(condv);
      }
      rec_rcondv.put(RCONDV_COD, rec.get(CONDV_COD));
      rec_rcondv.put(RCONDV_CODCF, rec.get(CONDV_CODCF));
      aggiorna_record(rec_rcondv, lista_campi_rcondv);
      test_write(rcondv);
    }
  }
  condv.close();
  rcondv.close();
  return write_enabled();
}


///////////////////////////////////////////////////////////
// TImportazioneHardy_mask
///////////////////////////////////////////////////////////

class TImportazioneHardy_mask : public TAutomask
{
protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  void serialize(bool bSave);

public:
  void trasferisci();

  TImportazioneHardy_mask();
  virtual ~TImportazioneHardy_mask();
};

// Funzione di trasferimento dati da/verso file .ini con lo stesso nome della maschera
// Andrebbe messo in libreria
void TImportazioneHardy_mask::serialize(bool bSave)
{
  TFilename n = source_file(); n.ext("ini");  // Construisce il nome del .ini in base al .msk
  TConfig cfg(n, "Main");                     // Crea il file di configurazione
  TString4 id; 
  for (int i = fields()-1; i >= 0; i--)       // Scandisce tutti i campi della maschera ...   
  {
    TMask_field& f = fld(i);
    if (f.active() && f.is_loadable())        // ... selezionando solo quelli editabili
    {
      id.format("%d", f.dlg());
      if (bSave)                              // A seconda del flag di scrittura ... 
        cfg.set(id, f.get());                 // ... o scrive sul .ini 
      else 
        f.set(cfg.get(id));                   // ... o legge dal .ini
    }
  }
}

void TImportazioneHardy_mask::trasferisci()
{
  TString query_header;
  query_header << "ODBC(" << get(F_DSN) << ',' << get(F_USR) << ',' << get(F_PWD) << ")\n";

  TReport_book book;
  THardy_log log;

  bool rep_to_print = false;
  bool go_on = true;

  if (go_on && get_bool(F_PAG))
  {
    THardy_pag pc;
    pc.init(TR("Condizioni di pagamento"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_IVA))
  {
    THardy_iva pc;
    pc.init(TR("Aliquote IVA"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CATMERC))
  {
    THardy_catmerc pc;
    pc.init(TR("Categorie merceologiche"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CATFISC))
  {
    THardy_catfisc pc;
    pc.init(TR("Categorie fiscali"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_BAN))
  {
    THardy_ban pc;
    pc.init(TR("Banche"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CAUCONT))
  {
    THardy_caucont pc;
    pc.init(TR("Causali contabili"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CAUMAG))
  {
    THardy_caumag pc;
    pc.init(TR("Causali magazzino"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_UM))
  {
    THardy_um pc;
    pc.init(TR("Unit� di misura"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_ARTICOLI))
  {
    THardy_art pc;
    pc.init(TR("Articoli"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_PCON))
  {
    THardy_pcon pc;
    pc.init(TR("Piano dei conti"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CLI))
  {
    THardy_clienti pc;
    pc.init(TR("Clienti"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_FOR))
  {
    THardy_fornitori pc;
    pc.init(TR("Fornitori"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_AGENTI))
  {
    THardy_agenti pc;
    pc.init(TR("Agenti"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_LISTINI))
  {
    THardy_listini pc;
    pc.init(TR("Listini"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_CONTRATTI))
  {
    THardy_contratti pc;
    pc.init(TR("Contratti"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }
  if (go_on && get_bool(F_LISTINICLI))
  {
    THardy_listinicli pc;
    pc.init(TR("Listini clienti"), query_header, log);
    go_on = pc.trasferisci();
    book.add(log);
		rep_to_print = true;
  }

  if (rep_to_print && book.pages() > 0)
		book.preview();
}

bool TImportazioneHardy_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {
  case DLG_OK:
    if (e == fe_button)
      serialize(true);
    break;
  default:
    break;
  }
  return true;
}

TImportazioneHardy_mask::TImportazioneHardy_mask() : TAutomask("hacnv100a")
{
  serialize(false);
}

TImportazioneHardy_mask::~TImportazioneHardy_mask()
{ }

///////////////////////////////////////////////////////////
// TImportazioneHardy
///////////////////////////////////////////////////////////

class TImportazioneHardy : public TSkeleton_application
{
protected:
  virtual void main_loop();
};

void TImportazioneHardy::main_loop()
{
  TImportazioneHardy_mask mask;
  while (mask.run() == K_ENTER)
    mask.trasferisci();
}

int hacnv100(int argc, char* argv[])
{
  TImportazioneHardy ih;
  ih.run(argc, argv, APPNAME);
  return 0;
}