#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 TImporta_fatven_msk : public TAutomask
{
protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);

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

bool TImporta_fatven_msk::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 TImporta_fatven_recset : public TCSV_recordset
{
  protected:
    virtual TRecnotype new_rec(const char* buf = NULL);    
  
  public:
    TImporta_fatven_recset(const char * fileName);
};

TRecnotype TImporta_fatven_recset::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;
}


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

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

	TImporta_fatven_msk*		  _msk;


protected:
  long togli_apici_numero(TImporta_fatven_recset& s, int i);
  const TString& togli_apici(TImporta_fatven_recset& 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);
 
  TImporta_fatven_app() {}
};

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

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

bool TImporta_fatven_app::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 TImporta_fatven_app::transfer(const TFilename& file)
{
  const TString4 codnum = "F01"; //??????????????????????????
  const TString4 tpdoc = "F01";  //??????????????????????????

  TImporta_fatven_recset s(file);

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

  long ndoc_old;

  s.move_first();
  //campi documento
  const long ndoc = ndoc_old = togli_apici_numero(s,0);  //ndoc
  const TDate datadoc = togli_apici(s,1);                //datadoc  
  const int anno = datadoc.year();                       //anno documento
  
  TDocumento doctmp('D', anno, codnum, ndoc_old);
  if (doctmp.rows() > 0)
  {
    warning_box(TR("I documenti che si sta cercando di importare esistono gi�"));
    return 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  
    const int anno = datadoc.year();            //anno documento
    
    //correggo l'imponibile dell'ultima riga del documento precedente per far tornare i conti
    if (ndoc != ndoc_old)
    {
      //carico il documento
      TDocumento doc('D', anno, codnum, ndoc_old);

      s.move_prev();
      real tot_doc = togli_apici(s,18);
      real tot_imp = doc.get_real("TOTVALORE");

      //se � necessario, faccio la modifica sull'ultima riga
      if (tot_imp != tot_doc)
      {
        //calcolo la differenza
        real diff = tot_doc - tot_imp;
        
        //estraggo l'imponibile dell'ultima riga        
        TRiga_documento& rdoc = doc[doc.rows()];
        real imp = rdoc.get_real(RDOC_PREZZO);

        //calcolo l'imponibile esatto e lo inserisco nella riga documento
        imp += diff;
        rdoc.put(RDOC_PREZZO, imp);
        doc.write();
      }
      //passo al nuovo documento
      ndoc_old = ndoc;
      s.move_next();
    }

    //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
    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 TImporta_fatven_app::create()
{
  _msk = new TImporta_fatven_msk();
         
  return TSkeleton_application::create();
}

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

void TImporta_fatven_app::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);		
  }   
}


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


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