#include <automask.h>
#include <progind.h>
#include <utility.h>
#include <textset.h>

#include "ps0713.h"
#include "ps0713400a.h"

#include "../cg/cglib01.h"
#include "../mg/anamag.h"
#include "../ve/velib.h"

#include "clifo.h"
#include "doc.h"
#include "rdoc.h"

///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////

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

public:
  TImportaFatVen_mask();
};
  
TImportaFatVen_mask::TImportaFatVen_mask() :TAutomask ("ps0713400a")
{
}  

bool TImportaFatVen_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_NAME:
			if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.csv");	//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;
}

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

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

class TImportaFatVen_recordset : public TCSV_recordset
{
  protected:
    virtual TRecnotype new_rec(const char* buf = NULL);    
  
  public:
    TImportaFatVen_recordset(const char * fileName);
};

TRecnotype TImportaFatVen_recordset::new_rec(const char* buf)
{
  TToken_string str(256,'\t'); //nuovo record tab separator

  if(buf && *buf)
  {
    bool apici=false;

    for (const char* c = buf; *c ; c++)
    {
      if (*c == '"')
      {
        apici = !apici;
      }
      else
      {
        if (*c == ',')
        {
          if (!apici)
            str << str.separator();
          else
            str << *c;
        }
        else
          str << *c;

      }
    }
  }

  const TRecnotype n = TText_recordset::new_rec(str);

  if (n >= 0)
    row(n).separator(str.separator());
  
  return n;
}


TImportaFatVen_recordset::TImportaFatVen_recordset(const char * fileName)
                         : TCSV_recordset("CSV(,)")
{
	load_file(fileName);
}

///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TImportaFatVen_applicat : public TSkeleton_application
{
	virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "ve";}

	TImportaFatVen_mask*		  _msk;


protected:
  long togli_apici_numero(TImportaFatVen_recordset & s, int i);
  const TString& togli_apici(TImportaFatVen_recordset & s, int i);
  bool find_clifo(long& codcf, TString& paiv, long& abi, long& cab, TString& codpag);

public:           
  virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
	bool transfer(const TFilename& file);
 
  TImportaFatVen_applicat() {}
};

long TImportaFatVen_applicat::togli_apici_numero(TImportaFatVen_recordset & s, int i)
{
  TString80 tmp = s.get(i).as_string();
  tmp.strip("\"");
  return atol(tmp);
}

const TString& TImportaFatVen_applicat::togli_apici(TImportaFatVen_recordset & s, int i)
{
  TString& tmp = get_tmp_string();
  tmp = s.get(i).as_string();
  tmp.strip("\"");
  tmp.trim();
  return tmp;
}

bool TImportaFatVen_applicat::find_clifo(long& codcf, TString& paiv, long& abi, long& cab, TString& codpag)
{
  if (!paiv.blank())
  {
    TISAM_recordset clienti("USE CLIFO KEY 5\nFROM TIPOCF='C' STATOPAIV="" PAIV=#PAIV\nTO TIPOCF='C' STATOPAIV="" PAIV=#PAIV");
    clienti.set_var("#PAIV", TVariant(paiv));
    if (clienti.move_first())
    {
      codcf = clienti.get(CLI_CODCF).as_int(); 
      paiv = clienti.get(CLI_PAIV).as_string();
      abi = clienti.get(CLI_CODABI).as_int();
      cab = clienti.get(CLI_CODCAB).as_int();
      codpag = clienti.get(CLI_CODPAG).as_string();
      return true;
    }
  }
  return false;
}

bool TImportaFatVen_applicat::transfer(const TFilename& file)
{
  const TString4 codnum = "F01"; //??????????????????????????
  const TString4 tpdoc = "F01";  //??????????????????????????

  TImportaFatVen_recordset s(file);

  TProgind pi(s.items(),"Importazione fatture in corso ...",true,true);

  for (bool ok=s.move_first();ok;ok=s.move_next())
  {
    if (!pi.addstatus(1)) 
      break;

    if (s.get(0).as_string().blank())
      break;

    //leggo il contenuto del tracciato record
    //campi documento
    const long ndoc = togli_apici_numero(s,0);            //ndoc
    const TDate datadoc = togli_apici(s,1);               //datadoc  
    //campi articolo 1
    TString descr1 = togli_apici(s,2);                    //descrizione aritcolo 1
    const TString80 art1 = togli_apici(s,3);              //articolo 1
    const real imp1 = togli_apici(s,4);                   //imponibile articolo 1
    //campi articolo 2
    const TString descr2 = togli_apici(s,5);              //descrizione articolo 2
    const real imp2 = togli_apici(s,6);                   //imponibile articolo 2
    //campi articolo 3
    const TString16 descr3 = togli_apici(s,7);            //articolo 3
    const real impives = togli_apici(s,8);                //imponibile iva esente

    //partita iva, mi serve per sapere se un cliente esiste gi� in clifo
    TString16 paiv = togli_apici(s,9);              //partita iva

    //prendo codiva da anamag
    const TRectype& anamag = cache().get(LF_ANAMAG,art1);
    const TString16 codiva = anamag.get(ANAMAG_CODIVA);

    //codice commessa
    const TString16 codcms = togli_apici(s,17);
    
    //cerco gli altri dati di interesse
    const int anno = datadoc.year();                      //anno documento
    long codcf;
    long abi;
    long cab;
    TString4 codpag;


    if (!find_clifo(codcf, paiv, abi, cab, codpag))
    {
      //campi cliente (da utilizzare se non esiste gi�)

      const TString80 ragsoc = togli_apici(s,10);           //ragione sociale
      const TString80 ind = togli_apici(s,11);              //indirizzo
      const TString4 nciv = togli_apici_numero(s,12);       //numero civico
      const long cap = togli_apici_numero(s,13);            //CAP
      const TString80 comune = togli_apici(s,14);           //comune
      const TString80 loc = togli_apici(s,15);              //localit�
      const TString4 prov = togli_apici(s,16);     //provincia

      const TString& codcom = cap2comune(cap, comune);      //codice comune

      TLocalisamfile clifo(LF_CLIFO);

      //calcolo il prossimo codice cliente libero
      codcf = 1L ;  
      if (!clifo.empty())
      {
        clifo.put(CLI_TIPOCF, 'F');
        if (clifo.read(_isgteq) == NOERR)
          clifo.prev();
		    else
			    clifo.last();

        if (clifo.get_char(CLI_TIPOCF) == 'C')
          codcf += clifo.get_long(CLI_CODCF);
      }

      //inserisco i dati di interesse
      clifo.put(CLI_TIPOCF, "C");
      clifo.put(CLI_CODCF, codcf);
      clifo.put(CLI_RAGSOC, ragsoc);
      clifo.put(CLI_PAIV, paiv);
      clifo.put(CLI_INDCF, ind);
      clifo.put(CLI_CIVCF, nciv);
      clifo.put(CLI_CAPCF, cap);
      clifo.put(CLI_COMCF, codcom);
      clifo.put(CLI_LOCCF, loc);

      clifo.write();
      abi = 0;
      cab = 0;
      codpag = "";
    }
                
    TDocumento doc('D', anno, codnum, ndoc);

    doc.put(DOC_TIPODOC, tpdoc);
    doc.put(DOC_DATADOC, datadoc);
    doc.put(DOC_TIPOCF, 'C');
    doc.put(DOC_CODCF, codcf);
    doc.put(DOC_CODABIA, abi);
    doc.put(DOC_CODCABA, cab);
    doc.put(DOC_CODPAG, codpag);
    doc.put(DOC_CODCMS, codcms);

    if (imp1 != 0)
    {
      TRiga_documento& rdoc = doc.new_row("01");

      if (descr1.len() <= 50)
        rdoc.put(RDOC_DESCR, descr1);
      else
      {
        rdoc.put(RDOC_DESCR, descr1.sub(0,49));
        rdoc.put(RDOC_DESCLUNGA, true);
        rdoc.put(RDOC_DESCEST, descr1.sub(50));
      }
      rdoc.put(RDOC_PREZZO, imp1);
      rdoc.put(RDOC_QTA, 1);
      rdoc.put(RDOC_CODART, art1);
      rdoc.put(RDOC_CODARTMAG, art1);
      rdoc.put(RDOC_CHECKED, "X");
      rdoc.put(RDOC_CODIVA, codiva);
    }
      
    if (imp2 != 0)
    {
      TRiga_documento& rdoc = doc.new_row("01");

      rdoc.put(RDOC_DESCR, descr2);
      rdoc.put(RDOC_PREZZO, imp2);
      rdoc.put(RDOC_QTA, 1);
      rdoc.put(RDOC_CODART, art1);
      rdoc.put(RDOC_CODARTMAG, art1);
      rdoc.put(RDOC_CHECKED, "X");
      rdoc.put(RDOC_CODIVA, codiva);
    }

    if (impives != 0)
    {
      TRiga_documento& rdoc = doc.new_row("01");      

      rdoc.put(RDOC_PREZZO, impives);
      rdoc.put(RDOC_QTA, 1);     
      rdoc.put(RDOC_CHECKED, "X");
      rdoc.put(RDOC_CODIVA, codiva); //??????????????????????????????????
    }      
    doc.write();
  }
  return true;
}

bool TImportaFatVen_applicat::create()
{
  _msk = new TImportaFatVen_mask();
         
  return TSkeleton_application::create();
}

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

void TImportaFatVen_applicat::main_loop()
{
  KEY	tasto;
	tasto = _msk->run();
  if (tasto == K_ENTER)
  {		
    //genero il nome del file da caricare
    TFilename name = _msk->get(F_PATH);
    name.add(_msk->get(F_NAME));
    transfer(name);		
  }   
}


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


int ps0713400 (int argc, char* argv[])
{
  TImportaFatVen_applicat main_app;
  main_app.run(argc, argv, TR("Importazione Fatture"));
  return true;
}