#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <recarray.h>
#include <tabutil.h>
#include <textset.h>

#include <clifo.h>
#include <cfven.h>
#include "../cg/cglib01.h"
#include "../mg/anamag.h"
#include "../mg/umart.h"

#include "ps0982100a.h"

                      /////////////////////////////////
                      ////    TIMPORTA_DATI_MSK    ////
                      /////////////////////////////////

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

public:
  TImporta_dati_msk();
};
  
TImporta_dati_msk::TImporta_dati_msk() 
                    :TAutomask ("ps0982100a"){}  

bool TImporta_dati_msk::on_field_event(TOperable_field& f, TField_event e, long jolly)
{
  return true;
}

                      /////////////////////////////////
                      ////    TIMPORTA_DATI_REC    ////
                      /////////////////////////////////  

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

TRecnotype TImporta_dati_rec::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_dati_rec::TImporta_dati_rec(const char * fileName)
                  : TCSV_recordset("CSV(;)")
{
	load_file(fileName);
}

                      /////////////////////////////////
                      ////    TIMPORTA_DATI_APP    ////
                      /////////////////////////////////

//Classe TImporta_dati_app
class TImporta_dati_app : public TSkeleton_application
{
  TAssoc_array _codpag;

protected:
	virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "cg";}

  const long first_clifo(const char cof) const;
  void importa_clifo(TImporta_dati_rec& rec, const bool cliente);
  bool find_um(const TString80& codart);
  void importa_articoli(TImporta_dati_rec& rec);

public:           
  virtual void main_loop();
	bool transfer(const TMask& msk);
 
  TImporta_dati_app() {};
};

const long TImporta_dati_app::first_clifo(const char cof) const
{
  TLocalisamfile clifo(LF_CLIFO);
  long  codcf = 1L ;  
  if (!clifo.empty())
  {
    if (cof == 'C')
    {
      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);
    }
    else
    {
      clifo.last();
      if (clifo.get_char(CLI_TIPOCF) == 'F')
        codcf += clifo.get_long(CLI_CODCF);
    }
  }                 
  return codcf;
}

void TImporta_dati_app::importa_clifo(TImporta_dati_rec& rec, const bool cliente)
{
  //costruisco il messaggio a seconda di cosa sto importando
  TString80 str = "Importazione ";
  char cof;
  if (cliente)
  {
    str << "clienti";
    cof = 'C';
  }
  else
  {
    str << "fornitori";
    cof = 'F';
  }
  str << " in corso ...";  

  long codcf = first_clifo(cof);  

  TLocalisamfile clifo(LF_CLIFO);
  TLocalisamfile cfven(LF_CFVEN);
  TTable banche("%BAN");

  TProgind pi(rec.items(),str,true,true);

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

    //salto la prima riga
    if (!atoi(rec.get(0).as_string()) || rec.get(0).as_string().blank())
      continue;        

    clifo.put(CLI_TIPOCF, cof);  //Tipo C  o F
    clifo.put(CLI_CODCF, codcf); //codcf

    TString cazzone = rec.get(1).as_string();
    clifo.put(CLI_RICALT, rec.get(1).as_string());  //codice alternativo

    TString tmp = rec.get(2).as_string();  //ragione sociale, troncata a 50 caratteri
    if (tmp.len() > 50)
      tmp.cut(49);
    clifo.put(CLI_RAGSOC, tmp);

    clifo.put(CLI_STATOPAIV, rec.get(18).as_string());  //stato partita iva
    clifo.put(CLI_PAIV, rec.get(3).as_string());        //partita iva
    clifo.put(CLI_COFI, rec.get(4).as_string());        //codice fiscale 
    
    clifo.put(CLI_INDCF, rec.get(7).as_string()); //indirizzo

    const TString8 cap = rec.get(8).as_string();     //cap
    TString80 loc = rec.get(9).as_string();          //localit�
    const TString8 com = cap2comune(cap,loc);        //codice comune
    const TString80 stato = rec.get(11).as_string(); //stato

    clifo.put(CLI_CAPCF, cap);  //cap
    
    if (com.full() && !com.blank())
    {
      clifo.put(CLI_COMCF, com);  //se riesce la CAP2COMUNE, inserisco il codice comune  
      loc = "";
      clifo.put(CLI_LOCCF, loc);
    }
    else 
    {
      clifo.put(CLI_COMCF, com);
      if (stato != "ITALIA" && !stato.blank())  //altrimenti metto tutto nella localit�, eventualmente concatenando lo stato
        loc << " - " << stato;
      clifo.put(CLI_LOCCF, loc);
    }
    
    clifo.put(CLI_TEL, rec.get(12).as_string());    //telefono 1
    clifo.put(CLI_TEL2, rec.get(13).as_string());   //telefono 2
    clifo.put(CLI_TELEX, rec.get(14).as_string());  //telex
    clifo.put(CLI_FAX, rec.get(15).as_string());    //fax
    clifo.put(CLI_MAIL, rec.get(17).as_string());   //mail
    
    if (real::is_natural(rec.get(26).as_string()))
    {
      clifo.put(CLI_CODABI, rec.get(26).as_string().left(5));  //ABI
      clifo.put(CLI_CODCAB, rec.get(26).as_string().right(5)); //CAB
      clifo.put(CLI_IBAN, rec.get(29).as_string()); //IBAN
    }

    //Gestione CODPAG, che in Campo � al massimo di 4 caratteri
    //da accordi con roberto, s crivo per tutti RB60; eventuali eccezioni vanno gestite manualmente
    clifo.put(CLI_CODPAG, "RB60");  

    TString16 codpag = rec.get(27).as_string();

    if (rec.get(33).as_string() != "EUR")
      clifo.put(CLI_CODVAL, rec.get(33).as_string());

    clifo.write();

    cfven.put(CFV_TIPOCF, cof);
    cfven.put(CFV_CODCF, codcf);
    cfven.put(CFV_NONACCEFF, "01-08,31-08;21-12,31-12");
    cfven.put(CFV_NONSCADEFF, "10-09;10-01");
    cfven.write();

    if (real::is_natural(rec.get(26).as_string()))
    {
      TString8 abi = rec.get(26).as_string().left(5);
      TString16 abicab = rec.get(26).as_string();
      TString80 desc_banca = "Banca ";
      desc_banca << abi;
      TString80 desc_agenzia = "Agenzia ";
      desc_agenzia << abicab;

      banche.put("CODTAB", abi);
      int err = banche.read();    
      if (err != NOERR)
      {
        banche.put("CODTAB", abi);
        banche.put("S0", desc_banca);
        banche.write();
      }

      banche.put("CODTAB", abicab);
      err = banche.read();    
      if (err != NOERR)
      {
        banche.put("CODTAB", abicab);
        banche.put("S0", desc_agenzia);
        banche.write();
      }
    }

    codcf += 1;    
  }
}

bool TImporta_dati_app::find_um(const TString80& codart)
{
  TToken_string key;
  key.add(codart);
  key.add(1);
  const TRectype& rec_um = cache().get(LF_UMART, key);
  
  return !rec_um.empty();
}

void TImporta_dati_app::importa_articoli(TImporta_dati_rec& rec)
{
  TProgind pi(rec.items(),"Importazione articoli in corso ...",true,true);

  TLocalisamfile anamag(LF_ANAMAG);
  TLocalisamfile umart(LF_UMART);
  TTable cat_mer("GRC");

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

    //salto la prima riga
    if (rec.get(0).as_string() == "OldItem" || rec.get(0).as_string().blank())
      continue;

    TString80 codart = rec.get(1).as_string();
    
    anamag.put(ANAMAG_CODART, codart);                  //codart
    anamag.put(ANAMAG_DESCR, rec.get(3).as_string());   //descrizione 
    anamag.put(ANAMAG_SOSPESO, !rec.get(4).as_bool());  //sospeso
    anamag.put(ANAMAG_CODIVA, rec.get(5).as_string());  //IVA
    
    //se non trovo l'unit� di misura relativa a questo articolo, inserisco tutto
    if (!find_um(codart))
    {
      umart.put(UMART_CODART, codart);
      umart.put(UMART_NRIGA, 1);
      umart.put(UMART_UM, rec.get(6).as_string());
      umart.put(UMART_PREZZO, rec.get(7).as_real());

      umart.write();
    }

    //sconto
    TString80 sconto = rec.get(8).as_string();
    sconto << '+';
    sconto << rec.get(9).as_string();
    anamag.put(ANAMAG_SCONTO, sconto);

    //articolo di produzione
    TString16 artprod = rec.get(12).as_string();
    if (artprod == "PRODFIN" || artprod == "SEMICON")
      anamag.put(ANAMAG_ARTPROD, true);

    //categoria merceologica
    anamag.put(ANAMAG_GRMERC, rec.get(13).as_string());

    //OFFSET
    anamag.put(ANAMAG_USER1, rec.get(16).as_string());  //SaleOffset
    anamag.put(ANAMAG_USER2, rec.get(17).as_string());  //PurchaseOffset

    cat_mer.put("CODTAB", rec.get(13).as_string());
    int err = cat_mer.read();
    if (err != NOERR)
    {
      cat_mer.put("CODTAB", rec.get(13).as_string());
      cat_mer.put("S0", rec.get(13).as_string());
      cat_mer.write();
    }

    anamag.write();
  }
}

bool TImporta_dati_app::transfer(const TMask& msk)
{
  //genero il nome del file da caricare
  TFilename name = msk.get(F_PATH);
  name.add(msk.get(F_NAME));
  TImporta_dati_rec rec(name);

  //leggo dalla maschera cosa sto importando
  const int tpimp = msk.get_int(F_TPIMP);  
  switch (tpimp)
  {
  case 0: importa_clifo(rec, true); break;
  case 1: importa_clifo(rec, false); break;
  case 2: importa_articoli(rec); break; 
  default: break;
  }   
  return true;
}


void TImporta_dati_app::main_loop()
{
  TImporta_dati_msk msk;
	
  if (msk.run() == K_ENTER)
  {		
		if (transfer(msk))		
      message_box(TR("Importazione dati completata"));		
  }   
}


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


int ps0982100 (int argc, char* argv[])
{
  TImporta_dati_app main_app;
  main_app.run(argc, argv, TR("Importazione Dati"));
  return true;
}