#include <recarray.h>

#include <../mg/anamag.h>
#include <../mg/umart.h>

#include <clifo.h>
#include <comuni.h>

#include "ps0077700.h"

///////////////////////////////////////////////////////////
// TGalileo_clifo
///////////////////////////////////////////////////////////

bool select_clifo(const TRectype & rec, TObject * myself)
{
	TGalileo_clifo * c = (TGalileo_clifo *) myself;
	const TString80 key = rec.build_key();
	return c->keys().objptr(key) != NULL; 
}

int TGalileo_clifo::cancella_clifo(TLocalisamfile& clifo) const
{     
	return NOERR;
}

long TGalileo_clifo::get_next_key(const char tipocf) const
{
  TLocalisamfile clifo(LF_CLIFO);
  long codcf = 1L;
  if (!clifo.empty())
  {
    if (tipocf == 'C')
    {
      clifo.put(CLI_TIPOCF, 'F');
      clifo.read(_isgteq);
      if (clifo.good())
        clifo.prev();
      clifo.setstatus(NOERR);
    }
    else 
      clifo.last();
    if (clifo.good())
    {
      const char tipo = clifo.get(CLI_TIPOCF)[0]; 
      if (tipocf == tipo)
        codcf += clifo.get_long(CLI_CODCF);
    }
  }                 
  return codcf;
}

long TGalileo_clifo::get_codcf(const char tipocf, const char* ricalt) const
{
  TLocalisamfile clifo(LF_CLIFO);
  long codcf = -1;
	clifo.setkey(6);
	clifo.put(CLI_TIPOCF, tipocf);
	clifo.put(CLI_RICALT, ricalt);
	if (clifo.read() == NOERR) 
		codcf = clifo.get_long(CLI_CODCF);
  return codcf;
}

bool TGalileo_clifo::dump()
{
  if (!_path.exist())
    return true;

	TConfig& ini = config();
	TString_array lista_clifo;
	ini.list_variables(lista_clifo, true, "CLIFO", true);
	TToken_string lista_dump;
	lista_dump.add(CLI_TIPOCF);
	lista_dump.add(CLI_CODCF);
	lista_dump.add(CLI_COMCF);
	TString16 campo_dest, campo_orig;
	FOR_EACH_ARRAY_ROW(lista_clifo,i,row)
	{
		row->get(0, campo_dest); 
		row->get(1, campo_orig);
		if (campo_orig.full())
			lista_dump.add(campo_dest);
	}
	TFilename path = _path; path.add("clifo.txt");
	TSystemisamfile clifo(LF_CLIFO);

  int err = clifo.dump(path, lista_dump, 1, '|', '\0', '\n', true, false, NULL, select_clifo, this);
  if (err == NOERR)
    log("Errore di scrittura del file clifo.txt", 0);
	return true;
}

bool TGalileo_clifo::trasferisci()
{
  TString query = 
		"SELECT CLFOCP, CONTCA, DSCOCP, DSULCP, INDICA, LOCACA, PROVCA, CAPOCA, "
		"NAZICA, CISOCA, PIVACA, CDFICA, NTELCA, NFAXCA \n"
		"FROM CGANA01J \n";
	if (!_data.empty())
	{
		query << "WHERE DTMNCA >= ";
  	query << _data.date2ansi();
	}

  TRecordset& recset = create_recordset(query);

	TString str;

	TConfig& ini = config();
	TString_array lista_clifo;
	ini.list_variables(lista_clifo, true, "CLIFO", true);
	TIsamfile clifo(LF_CLIFO);
	TRectype& rec_clifo = clifo.curr();

	_keys.destroy();
	clifo.open_ex(_excllock);
	TRecord_cache cache_comuni(LF_COMUNI, 2);
  TGalileo_iterator pi(this);

	while (++pi)
  {
		const TString& contca = get_str("CONTCA");
		const char tipocf = get_str("CLFOCP")[0];
		long codcf = get_codcf(tipocf, contca); // mi restiuisce  il codice del clinete  se esiste oppure -1 se da aggiungere

    bool needs_creation = codcf <= 0;
	  bool good = true;

    if (!needs_creation)
		{
			// il cliente/fornitore va aggiornato
      rec_clifo.zero();
			rec_clifo.put(CLI_TIPOCF, tipocf);
			rec_clifo.put(CLI_CODCF, codcf);
			const TString16 key(rec_clifo.build_key(1));

			_keys.add(key, key);
			good = clifo.read() == NOERR;
			if (!good)
        needs_creation = true;
		}
    
		if (needs_creation)
		{
			// il cliente/fornitore va inserito in campo 
      if (codcf <= 0)
			  codcf = get_next_key(tipocf);
			rec_clifo.zero();
			rec_clifo.put(CLI_TIPOCF, tipocf);
			rec_clifo.put(CLI_CODCF, codcf);
			good &= test_write(clifo);
		}
		
		if (good)
		{
			// aggiormento comune
			TString80 dencom = get_str("LOCACA");
			dencom.trim(); dencom.upper();
			const TRectype& reccom = cache_comuni.get(dencom);
			if (dencom == reccom.get(COM_DENCOM))
				rec_clifo.put(CLI_COMCF, reccom.get(COM_COM));
			else
			{
				rec_clifo.zero(CLI_COMCF);
				rec_clifo.put(CLI_LOCCF, dencom);

				log("");
				str.format(FR("Cliente/Fornitore %c %ld: comune non trovato %s"), tipocf, codcf, (const char*)dencom);
				log(str);
			}
			aggiorna_record(clifo, lista_clifo);
		}
	}	
	clifo.close();
  return write_enabled();
}

bool TGalileo_clifo::aggiorna_record(TIsamfile& file, const TString_array& lista_campi)
{
	TRectype& rec = file.curr();	
	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] == '_')
			{
				TToken_string elabora(campo_orig.mid(1),',');
				const TString& str = elabora.get();
				if (str == "TAB") // formato _TAB, <tabella da leggere>,<valore CODTAB>, <campo da leggere>
				{
					const TString4 tab = elabora.get(); // tabella da leggere
					const TString80 campo = elabora.get();
					const TString16 codtab = get_str(campo);
					const TString80 campotab = elabora.get();
					valore = cache().get(tab, codtab, campotab);
				}
				else if (str == "FISSO") 
					valore = elabora.get(); // valore fisso indicato in configurazione
      }
      else
			  valore = get_str(campo_orig);
			rec.put(campo_dest, valore);
		}
	}
	return test_rewrite(file);
}

TGalileo_clifo::TGalileo_clifo()
{
}

TGalileo_clifo::~TGalileo_clifo()
{
}

///////////////////////////////////////////////////////////
// TGalileo_articoli
///////////////////////////////////////////////////////////

bool select_umart(const TRectype & rec, TObject * myself)
{
	TGalileo_articoli * c = (TGalileo_articoli *) myself;
	const TString key(rec.build_key(1));
	return c->keys_umart().objptr(key) != NULL; 
}

bool select_articoli(const TRectype & rec, TObject * myself)
{
	TGalileo_articoli * c = (TGalileo_articoli *) myself;
	const TString key(rec.build_key(1));
	return c->keys_articoli().objptr(key) != NULL; 
}

int TGalileo_articoli::cancella_articolo(TLocalisamfile& anamag) const
{     
	return NOERR;
}

bool TGalileo_articoli::dump()
{
  if (!_path.exist())
    return true;

	TConfig& ini = config();
	TString_array lista_anamag;
	ini.list_variables(lista_anamag, true, "ANAMAG", true);
	TToken_string lista_dump;
	lista_dump.add(ANAMAG_CODART);
	TString16 campo_dest, campo_orig;
	FOR_EACH_ARRAY_ROW(lista_anamag,i,row)
	{
		row->get(0, campo_dest); 
		row->get(1, campo_orig);
		if (campo_orig.full())
			lista_dump.add(campo_dest);
	}
	lista_dump.add(ANAMAG_ULTCOS1);

	TString_array lista_umart;
	TToken_string lista_dump_umart;

	ini.list_variables(lista_umart, true, "UMART", true);
	FOR_EACH_ARRAY_ROW(lista_umart,k,rowu)
	{
		rowu->get(0, campo_dest); 
		lista_dump_umart.add(campo_dest);
	}
	TSystemisamfile anamag(LF_ANAMAG);
	TSystemisamfile umart(LF_UMART);
	TFilename path = _path;
	path.add("umart.txt");
	int err = umart.dump(path, lista_dump_umart, 1, '|', '\0', '\n', true, false, 
                       NULL, select_umart, this);
  if (err != NOERR)
    log("Errore di scrittura umart.txt", 2);
	path = _path;	path.add("anamag.txt");
	err = anamag.dump(path, lista_dump, 1, '|', '\0', '\n', true, false, 
                    NULL, select_articoli, this);
  if (err != NOERR)
    log("Errore di scrittura anamag.txt", 0);

  return true;
}

bool TGalileo_articoli::trasferisci()
{
  TString query = 
		"SELECT RICOD, RDES1, RDES2, RDES3, RSUMS, RITIP, RISIG \n"
		"FROM BRISO00F, BTABE00F \n"
		"WHERE (SUBSTR(BTABE00F.TBDAT , 9 , 1)=RITIP) AND (BTABE00F.TBTIP='COD') AND (BTABE00F.TBELE='RIS')";
	if (!_data.empty())
	{
 		query << " AND (RIDTX >= ";
		query << _data.date2ansi() << ")";
	}

  TRecordset& recset = create_recordset(query);

	TString str;

	TConfig& ini = config();
	TString_array lista_anamag, lista_umart;
	ini.list_variables(lista_anamag, true, "ANAMAG", true);
	ini.list_variables(lista_umart, true, "UMART", true);
	TIsamfile anamag(LF_ANAMAG);
	TIsamfile umart(LF_UMART);
	
	anamag.open_ex(_excllock);
	umart.open_ex(_excllock);
	
	TRectype& rec_anamag = anamag.curr();
	TRectype& rec_umart = umart.curr();
	_keys_articoli.destroy();
	_keys_umart.destroy();

  TGalileo_iterator pi(this);
  while (++pi)
  {	
		const TString& codart = get_str("RICOD");
    rec_anamag.zero();
		rec_anamag.put(ANAMAG_CODART, codart);

		const TString80 key(rec_anamag.build_key(1));

		_keys_articoli.add(key, key);

		bool good = anamag.read() == NOERR;

		if (!good)
		{
			rec_anamag.zero();
			rec_anamag.put(ANAMAG_CODART, codart);
			good = test_write(anamag);
		}
		if (good)
		{
			aggiorna_record(anamag, lista_anamag);
	    rec_umart.zero();
			rec_umart.put(UMART_CODART, codart);
			rec_umart.put(UMART_NRIGA, 1);

			const TString80 key_umart(rec_umart.build_key(1));
		
			_keys_umart.add(key_umart, key_umart);
			bool good = umart.read() == NOERR;
			if (!good)
			{
				rec_umart.zero();
				rec_umart.put(UMART_CODART, codart);
				rec_umart.put(UMART_NRIGA, 1);
				good = (umart.write() == NOERR);
			}
			if (good)
			{
				rec_umart.put(UMART_UM, get_str("RSUMS"));
				rec_umart.put(UMART_FC, 1);
				umart.rewrite();
			}
		}
	}	
	anamag.close();
	umart.close();
  return write_enabled();
}

bool TGalileo_articoli::trasferisci_costi(const TString & ditta, const TString & cms, const TString & can)
{
  TString query = 
	"SELECT M2RIS, M2CMD FROM GMRIS00F\n"
	"WHERE (M2AZI='";
	query << ditta <<"') AND (M2COM='" << cms <<"') AND (M2CAN='" << can << "')";
  TRecordset& recset = create_recordset(query);
	TIsamfile anamag(LF_ANAMAG);
 	TRectype& rec_anamag = anamag.curr();
	TGalileo_iterator pi(this);
	TString80 codart;
	anamag.open_ex(_excllock);
	while (++pi)
  {	
		codart = get_str("M2RIS");
		rec_anamag.zero();
		rec_anamag.put(ANAMAG_CODART, codart);
		bool good = anamag.read() == NOERR;
		if (good)
		{
			anamag.put(ANAMAG_ULTCOS1, get_str("M2CMD"));
			test_rewrite(anamag);
		}
	}
	anamag.close();
  return write_enabled();
}

bool TGalileo_articoli::aggiorna_record(TIsamfile& file, const TString_array& lista_campi)
{
	TRectype& rec = file.curr();	
	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] == '_')
			{
				TToken_string elabora(campo_orig.mid(1),',');
				const TString& str = elabora.get();
				if (str == "TAB") // formato _TAB, <tabella da leggere>,<valore CODTAB>, <campo da leggere>
				{
					const TString4 tab = elabora.get(); // tabella da leggere
					const TString80 campo = elabora.get();
					const TString16 codtab = get_str(campo);
					const TString80 campotab = elabora.get();
					valore = cache().get(tab, codtab, campotab);
				}
				else if (str == "FISSO") 
					valore = elabora.get(); // valore fisso indicato in configurazione
      } else
      if (campo_orig[0] == '"' || campo_orig[0] == '\'')
      {
        valore = campo_orig;
        valore.ltrim(1);
        valore.rtrim(1); 
      }
      else
			  valore = get_str(campo_orig);
			rec.put(campo_dest, valore);
		}
	}
	return test_rewrite(file);
}

TGalileo_articoli::TGalileo_articoli()
{
	TConfig c(CONFIG_DITTA);

	_ditta = c.get_long("GalDitta");
	_cms = c.get("GalCommessa");
	_can = c.get("GalCantiere");
}

TGalileo_articoli::~TGalileo_articoli()
{
}