#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <reputils.h>
#include <utility.h>
#include <textset.h>
#include <reprint.h>
#include <scanner.h>

#include "tc0.h"
#include "tc0600a.h"
#include "tabmod.h"

                                      ///////////////////////////////////////////////
                                      //// CLASSI DERIVATE PER IMPORTAZIONE DATI ////
                                      ///////////////////////////////////////////////  

/////////////////////////////////////////////////////////////
//	Recordset specifici per i dati da trasferire
/////////////////////////////////////////////////////////////

//Piano dei conti
class TImporta_pconto_recordset : public TCSV_recordset
{
  public:
    TImporta_pconto_recordset(const char * fileName);
};

TImporta_pconto_recordset::TImporta_pconto_recordset(const char * fileName)
                          : TCSV_recordset("CSV(\"|\")")
{
	load_file(fileName);
}

                                      ///////////////////////////////////////////////
                                      ////      DEFINIZIONE CLASSE TAutomask     ////
                                      ///////////////////////////////////////////////

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

public:
  TImportaTS_mask();
};
  
TImportaTS_mask::TImportaTS_mask() :TAutomask ("tc0600a")
{
}  

bool TImportaTS_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_PCONTI:
			if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.txt");	//files delle testate
				list_files(path, as.rows_array());
				TFilename name;
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
				{
					name = *row;
					*row = name.name();
				}
				if (as.run() == K_ENTER)
				{
					f.set(as.row(as.selected()));
				}
			}
      break;
    case F_CAUSALI:
      if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.txt");	//files delle testate
				list_files(path, as.rows_array());
				TFilename name;
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
				{
					name = *row;
					*row = name.name();
				}
				if (as.run() == K_ENTER)
				{
					f.set(as.row(as.selected()));
				}
			}
			break;
    case F_CODIVA:
      if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.txt");	//files delle testate
				list_files(path, as.rows_array());
				TFilename name;
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
				{
					name = *row;
					*row = name.name();
				}
				if (as.run() == K_ENTER)
				{
					f.set(as.row(as.selected()));
				}
			}
      break;
		default:
			break;
	}
  return true;
}

///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TDocTS : public TSkeleton_application
{
	TImportaTS_mask*  				_msk;
	
protected:
  //metodi che fanno gli inserimenti sulle tabelle di campo
  void upload_pconti (const TFilename& file, TLog_report& log) const;
  void upload_causali(const TFilename& file, TLog_report& log) const;
  void upload_codiva (const TFilename& file, TLog_report& log) const;
  
public:           
  virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
  bool transfer();
 
  TDocTS() {};
};

TDocTS& app() { return (TDocTS&) main_app(); }

//funzione che importa il piano dei conto sulla tabella corretta
void TDocTS::upload_pconti (const TFilename& file, TLog_report& log) const
{
  TImporta_pconto_recordset s(file); //crea un recordset con struttura predefinita come indicato nella classe opportuna
  TModule_table pconti("TCO");
  TProgind pi(s.items(),"Importazione Piano dei Conti in Corso...",true,true);

  for (bool ok=s.move_first();ok;ok=s.move_next())
  {
    if (!pi.addstatus(1)) 
      break;
    //salto le righe di testata del file
    //per farlo leggo il gruppo e controllo che sia numerico
    TString dconto = s.get(1).as_string();
    if (dconto.blank() || !isdigit(dconto[1]))
      continue;
    pconti.zero();
		
		TString4 gr = dconto.left(2); //leggo il gruppo
    TString4 co = dconto.mid(3,2); //leggo il conto
    TString4 sc = dconto.mid(6,3);   //leggo il sottoconto
    TString conto = gr; //leggo il gruppo
    TString desc = s.get(2).as_string(); //leggo la descrizione

		conto << ((co.blank() || co == "**") ? "00" : co);
		conto << ((sc.blank() || sc == "***") ? "000" : sc);
    pconti.put("CODTAB", conto);  //put del gruppo
    pconti.put("S0", desc); //put del conto

	  int err = pconti.write_rewrite(); //Tenta di aggiungere un record ma se esiste gia' lo aggiorna
		TString str = "Il Conto ";

		str << conto;
    if (err == NOERR)
    {
      str << " � stato inserito";
      log.log(0,str);
    }
    else
    {
      str << " non � stato inserito, errore " << err;
      log.log(2,str);
    }
  }
  return;
}

void TDocTS::upload_causali(const TFilename& file, TLog_report& log) const
{
  TScanner s(file); //legge il file che gli passo riga per riga
  TString curr = s.line();
  TModule_table causa("TCA");
  TProgind pi(fsize(file),"Importazione Causali in Corso...",true,true);

  while (s.ok())
  {
    if (!pi.addstatus(s.tellg())) 
      break;
    causa.zero();
    curr = s.line();

		TString8 cod = curr.mid(1,6);
    TString desc = curr.mid(7,16);
    
    //salto le righe di testata del file
		cod.trim();
    if (cod.blank() || !real::is_natural(cod))
      continue;
		cod.lpad(3, '0');
    if (cod.len() > 3)
    {
      TString errore = "ERRORE:";
      
			errore <<" la causale con codice " << cod << " non pu� essere inserita (codice max 3 caratteri)";
      log.log(2,errore);
    }
    causa.put("CODTAB",cod);
    causa.put("S0",desc);

		int err = causa.write_rewrite(); //Tenta di aggiungere un record ma se esiste gia' lo aggiorna
    TString str = "La Causale con codice ";

		str << cod;
    if (err == NOERR)
    {
      str << " � stata inserita";
      log.log(0,str);
    }
    else
    {
      str << " non � stata inserita, errore " << err;
      log.log(2,str);
    }

      
  }
  return;
};
  
//funzione che importa i codici IVA sulla tabella corretta
void TDocTS::upload_codiva(const TFilename& file, TLog_report& log) const
{
  TScanner s(file); //crea un recordset con struttura predefinita come indicato nella classe opportuna
  TModule_table iva("TIV"); //instanzio l'ISAM file che lavota sulla tabella IVA
  TProgind pi(fsize(file),"Importazione Dati IVA in Corso...",true,true);

  while(s.ok())
  {
    if (!pi.addstatus(s.tellg())) 
      break;
    //salto le righe di testata del file
    iva.zero();

		TString curr = s.line();
    TString8 cod = curr.mid(1,8);
    TString desc = curr.mid(9,18);
    
    //salto le righe di testata del file
    cod.trim();
    if (cod.blank() || !real::is_natural(cod))
      continue;
		cod.lpad(3, '0');
    if (cod.len() > 3)
    {
      TString errore = "ERRORE:";

			errore <<" i dati IVA  con codice " << cod << " non possono essere inseriti (codice max 3 caratteri)";
      log.log(2,errore);
    }
    iva.put("CODTAB",cod);   
    iva.put("S0",desc);
    
    int err = iva.write_rewrite(); //Tenta di aggiungere un record ma se esiste gia' lo aggiorna

    TString str = "I dati IVA con codice ";

		str << cod;
    if (err == NOERR)
    {
      str << " sono stati inseriti";
      log.log(0,str);
    }
    else
    {
      str << " non sono stati inseriti, errore " << err;
      log.log(2,str);
    }
  }
  return;
};

bool TDocTS::transfer()
{
  TLog_report log("Importazione documenti da TeamSystem");
    
  //prelevo il path dei file da caricare dalla maschera
  TFilename path = _msk->get(F_PATH);
  
  const short ids [] = {F_PCONTI,F_CAUSALI,F_CODIVA,0};

  //eseguo tutte le importazioni (una alla volta)
  for (int i = 0; ids[i]; i++)
  {
    //prelevo di volta in volta il nome del file giusto dalla maschera:
    //prima il file Anagrafiche, poi quello delle fatture e poi quello delle ricevute
    TFilename name = _msk->get(ids[i]);
        
    //se sono riuscito a prelevare un nome di file, allora:
    if (name.full())
    {
      //costruisco il nome del file
      TFilename full = path;
      full.add(name);
      
      //se eiste il file, esegui l'elaborazione corretta
      if (full.exist())
      {
        switch (i)
        {
        case 0: upload_pconti (full, log); break;
        case 1: upload_causali(full, log); break;
        case 2: upload_codiva (full, log); break;
        default: break;
        }
      }
    }
  }

  TReport_book buc;
  
	buc.add(log);
  if (buc.pages()>0)
	  buc.preview(); //visualizzo il log di importazione dei documenti
  
  return true;
}

bool TDocTS::create()
{
  _msk = new TImportaTS_mask();
         
  return TSkeleton_application::create();
}

bool TDocTS::destroy()
{
	delete _msk;
  return TApplication::destroy();
}

void TDocTS::main_loop()
{
  KEY	tasto;
	tasto = _msk->run();
  if (tasto == K_ENTER)
  {
		if (transfer())
		{
			message_box(TR("Importazione documenti completata"));
		}
  }   
}

int tc0600 (int argc, char* argv[])
{
  TDocTS main_app;
  main_app.run(argc, argv, TR("Importazione Tabelle"));
  return true;
}