#include <applicat.h>
#include <tabapp.h>  
#include <strings.h>
#include <stdtypes.h>
#include <tabutil.h>
#include <utility.h> 
#include <prefix.h>    
#include <nditte.h>

#include "..\ba\batbind.h"
#include "cglib04.h"

HIDDEN      TString80 TEMP;

class Tabinv_application : public Tab_application
{
private:
  TMask*         _msk;     
  TString        _tabname;
  TTransfer_file _tras_file;
  
  TString _trasf,_control_rec;                   
  long    _ditta_tab, _ditta_tras;  
  bool    _disable,_ditte_uguali,_salta_hnd;
  
public:
  bool user_create();
  virtual void init_query_mode(TMask&);
  virtual void init_modify_mode(TMask&);
  virtual void init_insert_mode(TMask&);
  virtual int  write(const TMask& m);
  virtual int  rewrite(const TMask& m);

  void leggi_trasfer();
  void confronta_ditta();
  char cerca_stato(long codditta);
  void codifica_ditta(TMask& m);
  void tabella_ditta(TMask& m);
  
  //void esegui_controlli(TMask& m);                                                      
  static bool controlli_hnd (TMask_field& f, KEY k);
  
  static bool nascosto_handler(TMask& m, KEY k);    
  static bool stato_invio     (TMask_field& f, KEY k);
  
  static bool ditta_handler (TMask_field& f, KEY k); 
  static bool almeno_un_flag(TMask_field& f, KEY k);
  static bool clifo_comune  (TMask_field& f, KEY k);
  static bool pcon_comune   (TMask_field& f, KEY k);    
  static bool prima_nota    (TMask_field& f, KEY k);    
  static bool data_invio    (TMask_field& f, KEY k);
  static bool sigla_file    (TMask_field& f, KEY k);    
  static bool chiave_file   (TMask_field& f, KEY k);

  static bool nome_id       (TMask_field& f, KEY k);

  const char* riconverti(TString& data_PC);
  
  Tabinv_application() {}
  virtual ~Tabinv_application() {}
};

HIDDEN inline Tabinv_application& app() {return (Tabinv_application&) main_app();}

const char* Tabinv_application::riconverti (TString& data_PC)
{
  TEMP = data_PC.mid(8,2);
  TEMP << data_PC.mid(3,2);
  TEMP << data_PC.mid(0,2);
  return TEMP;
}

char Tabinv_application::cerca_stato(long ditta)
{
  TTable ind ("%IND");
  TString dep;
  char    stato = '\0';
  
  dep = format("%05d", ditta);
  
  ind.zero();
  ind.put("CODTAB", dep);
  if (ind.read() == NOERR)
    stato = ind.get_char("S6");
  
  return stato;  
}

bool Tabinv_application::nascosto_handler(TMask& m, KEY k)
{
  if (k == K_SHIFT+K_F12)
  { 
    if (app()._tabname == "%IND")
    {             
      app()._disable = FALSE;
      
      m.enable(F_NUMULINV);
      m.enable(F_DATAULIN);
      m.enable(F_STATO);

      if (app()._ditta_tab == app()._ditta_tras)    
      {
        m.enable(F_USELAB);
        m.enable(F_CHIAVE);
      }
    }
    else
      if (app()._tabname == "%INS")
      {
        m.enable(F_DITTAINV);
        app()._salta_hnd = TRUE;
      }
  }
  
  return TRUE;
}

bool Tabinv_application::stato_invio(TMask_field& f, KEY k)
{
  if ( (k == K_ENTER || k == K_TAB) && f.mask().mode() != MODE_QUERY )
  {                                
    if ( k == K_ENTER)
    {                  
      TString stato = f.get();
      int num = f.mask().get_int(F_NUMULINV);
      
      if (num == 0 && stato != "")
        return warning_box("Numero ultimo invio NON INDICATO: impossibile indicare lo stato ultimo invio");  
    }
    
    if (k == K_TAB)
    { 
      long codditta = f.mask().get_long(F_DITTAINV);
      
      char stato = app().cerca_stato(codditta);
      
      if (stato != '\0' && app()._disable)
        return warning_box("Rilevato STATO DI RIPARTENZA: prima concludere il trasferimento");    
    }
  }
  
  return TRUE;
}

bool Tabinv_application::ditta_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB && f.mask().mode() == MODE_QUERY)
  { 
    long codditta = f.mask().get_long(F_DITTAINV);
    
    if (codditta != 0)
    {
      if (!prefix().exist(codditta))
      {
        f.error_box("La ditta selezionata non e' abilitata per la contabilita' ");
        return FALSE;
      }
    }  
  }      
  return TRUE;
}

bool Tabinv_application::almeno_un_flag(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY) 
  {          
    bool cau   = f.mask().get_bool(F_CAUSALI);
    bool clifo = f.mask().get_bool(F_CLIFO);
    bool pcon  = f.mask().get_bool(F_PCON);
    bool pn    = f.mask().get_bool(F_MOV);
    bool iva   = f.mask().get_bool(F_IVA);
    bool fat   = f.mask().get_bool(F_FATT);
    
    if (!cau && !clifo && !pcon && !pn && !iva && !fat)
      return warning_box("E' necessario indicare almeno una sigla file da trasferire");            
    
    long ditta = f.mask().get_long(F_DITTAINV);
    
    app().set_firm(ditta);            
    
    TConfig conf (CONFIG_DITTA);

    TString pcon_cau = conf.get("PcTcCm","cg");
    
    bool causali = f.mask().get_bool(F_CAUSALI);    
    
    if (causali && pcon_cau != "")
      return warning_box("Tabella causali in comune: impossibile trasferirla");
  }
  
  return TRUE;
}

bool Tabinv_application::clifo_comune(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    long ditta = f.mask().get_long(F_DITTAINV);
    
    app().set_firm(ditta);            
    
    TConfig conf (CONFIG_DITTA);

    TString ana_com  = conf.get("AnCfCm","cg");
    
    bool clifo = f.mask().get_bool(F_CLIFO);
    
    if (clifo && ana_com != "")
      return warning_box("Anagrafica clienti / fornitori in comune: impossibile trasferirla");
  }
  
  return TRUE;
}

bool Tabinv_application::pcon_comune(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    long ditta = f.mask().get_long(F_DITTAINV);
    
    app().set_firm(ditta);            
    
    TConfig conf (CONFIG_DITTA);
    
    TString pcon_cau = conf.get("PcTcCm","cg");
    
    bool pcon = f.mask().get_bool(F_PCON);
    
    if (pcon && pcon_cau != "")
      return warning_box("Anagrafica Piano dei conti in comune: impossibile trasferirla");
  }
  
  return TRUE;
}

bool Tabinv_application::prima_nota(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    bool pn = f.mask().get_bool(F_MOV);

    if (!pn && (f.mask().get_bool(F_IVA) || f.mask().get_bool(F_FATT)) )
      return warning_box("Se si vuole inviare l' iva e' obbligatorio inviare anche la primanota");            
  }

  return TRUE;
}

bool Tabinv_application::data_invio    (TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    int   num = f.mask().get_int(F_NUMULINV);
    TDate data (f.get());
    
    if (num != 0 && !data.ok())
      return warning_box("Se indicato il numero deve essere indicata anche la data di invio");
    
    if (num == 0 && data.ok())
      return warning_box("Se non indicato il numero non puo' essere indicata la data di invio");
  }
  
  return TRUE;
}

bool Tabinv_application::sigla_file(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    int     num   = f.mask().get_int(F_NUMULINV);
    TString sigla = f.get();
    
    if (num == 0 && sigla != "")
      return warning_box("Numero ultimo invio NON INDICATO: impossibile indicare la sigla ultimo file elaborato");
    
    TString stato = f.mask().get(F_STATO);
    
    if (stato != "F" && sigla != "")
      return warning_box("La sigla ultimo file elaborato puo' essere indicata solo se lo stato ultimo invio e' F");  
  }
  
  return TRUE;
}

bool Tabinv_application::chiave_file(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().mode() != MODE_QUERY)
  {
    TString sigla  = f.mask().get(F_USELAB);
    TString chiave = f.get();
    
    if (sigla == "" && chiave != "")
      return warning_box("Sigla ultimo file elaborato NON INDICATA: impossibile indicare la chiave ultimo record elaborato");
    
    TString stato = f.mask().get(F_STATO);
    
    if (stato != "F" && chiave == "" && sigla != "")
      return warning_box("La chiave ultimo record elaborato deve essere indicata obbligatoriamente");  
  }
  
  return TRUE;
}


bool Tabinv_application::nome_id(TMask_field& f, KEY k)
{
  if (k == K_TAB && !app()._salta_hnd)
  { 
    long codditta = f.mask().get_long(F_DITTAINV);
    
    if (codditta != 0)
      return warning_box("Rilevato STATO DI RIPARTENZA: prima concludere il trasferimento");
  }      
  return TRUE;
}

//void Tabinv_application::esegui_controlli(TMask& m)
bool Tabinv_application::controlli_hnd(TMask_field& f, KEY k)
{                                                            
  if (k == K_TAB && !f.mask().field(F_NUMULINV).enabled()) 
  {
    int   num  = f.mask().get_int(F_NUMULINV);
    TDate data (f.mask().get(F_DATAULIN));
    
    if (num != 0 && !data.ok())
      return warning_box("Se indicato il numero deve essere indicata anche la data di invio");
    
    if (num == 0 && data.ok())
      return warning_box("Se non indicato il numero non puo' essere indicata la data di invio");

    TString sigla = f.mask().get(F_USELAB);
    
    if (num == 0 && sigla != "")
      return warning_box("Numero ultimo invio NON INDICATO: impossibile indicare la sigla ultimo file elaborato");
    
    TString stato = f.mask().get(F_STATO);
    
    if (stato != "F" && sigla != "")
      return warning_box("La sigla ultimo file elaborato puo' essere indicata solo se lo stato ultimo invio e' F");  

    TString chiave = f.mask().get(F_CHIAVE);
    
    if (sigla == "" && chiave != "")
      return warning_box("Sigla ultimo file elaborato NON INDICATA: impossibile indicare la chiave ultimo record elaborato");
    
    if (stato != "F" && chiave == "" && sigla != "")
      return warning_box("La chiave ultimo record elaborato deve essere indicata obbligatoriamente");  
  }
  return TRUE;
}

void Tabinv_application::leggi_trasfer()
{                           
  _trasf = ""; 
  _trasf = firm2dir(0);
  _trasf << "\\trasfer";
  
  _tras_file.open(_trasf);
  
  if (_tras_file.exist())
  {  
    if (_tras_file.read_control_rec())  
    {
      _control_rec = _tras_file.record();
      _ditta_tras  = atol(_control_rec.sub(25,29));
    }
    else
      _ditta_tras = 0;
  } 
  else
    _ditta_tras = 0;
}

void Tabinv_application::confronta_ditta()
{
  _ditta_tab = _msk->get_long(F_DITTAINV);
  
  if (_ditta_tab == _ditta_tras)
  {
    TString uselab = _tras_file.ult_file();
    TString chiave = _tras_file.key();
    
    _msk->set(F_USELAB, uselab);
    _msk->set(F_CHIAVE, chiave);
    _ditte_uguali = TRUE;
  }                      
  else
    _ditte_uguali = FALSE;
}

void Tabinv_application::codifica_ditta(TMask& m)
{
  TLocalisamfile ditte ( LF_NDITTE);
  
  long ditta = m.get_long(F_DITTAINV);
  
  ditte.setkey(1);
  ditte.zero();
  ditte.put(NDT_CODDITTA, ditta);
  if (ditte.read() == NOERR)
  {
    TString ragsoc = ditte.get(NDT_RAGSOC);
    m.set(F_RAGSOC, ragsoc);
  } 
}

void Tabinv_application::tabella_ditta(TMask& m)
{
  TTable ind ("%IND");
  TString dep;
  
  long ditta = m.get_long(F_DITTAINV);
  
  if (ditta != 0)
  {
    dep = format("%05d", ditta);
    
    ind.zero();
    ind.put("CODTAB", dep);
    if (ind.read() == NOERR)
    {
      TString stato = ind.get_char("S6");
      int     num   = ind.get_int ("I0");
      TDate   data  = ind.get_date("D0");
      
      m.set(F_STATO,    stato);
      m.set(F_NUMULINV, num);
      m.set(F_DATAULIN, data.string());
    }
  }
}

void Tabinv_application::init_query_mode(TMask& m)
{
  leggi_trasfer();
  _disable = TRUE;    

  if (_tabname == "%INS")
  {
    m.disable(F_DITTAINV);
    long ditta = m.get_long(F_DITTAINV);
    if (ditta != 0)
    {
      codifica_ditta(m);
      tabella_ditta(m);
      confronta_ditta(); 
    }
    else
    {
      m.reset(F_NUMULINV);
      m.reset(F_DATAULIN);
      m.reset(F_STATO);
      m.reset(F_USELAB);
      m.reset(F_CHIAVE);
      m.reset(F_RAGSOC);
    }
  }  
  
  m.disable(F_NUMULINV);
  m.disable(F_DATAULIN);
  m.disable(F_STATO);
  m.disable(F_USELAB);
  m.disable(F_CHIAVE);
}

void Tabinv_application::init_modify_mode(TMask& m)
{  
  if (_tabname == "%IND")
  {               
    leggi_trasfer();
    confronta_ditta(); 
    codifica_ditta(m);
    //esegui_controlli(m);
  }
  
  if (_tabname == "%INS")
  {
    m.disable(F_DITTAINV);
    long ditta = m.get_long(F_DITTAINV);
    if (ditta != 0)
    {
      codifica_ditta(m);
      tabella_ditta(m);
      confronta_ditta(); 
    }
    else
    {
      m.reset(F_NUMULINV);
      m.reset(F_DATAULIN);
      m.reset(F_STATO);
      m.reset(F_USELAB);
      m.reset(F_CHIAVE);
      m.reset(F_RAGSOC);    
    }
  }
  
  m.disable(F_NUMULINV);
  m.disable(F_DATAULIN);
  m.disable(F_STATO);
  m.disable(F_USELAB);
  m.disable(F_CHIAVE);  
}

void Tabinv_application::init_insert_mode(TMask& m)
{  
  if (_tabname == "%IND")
  {                 
    leggi_trasfer();
    confronta_ditta();
    codifica_ditta(m);
    //esegui_controlli(m);  
  }
  
  if (_tabname == "%INS")
  {
    m.disable(F_DITTAINV);
    long ditta = m.get_long(F_DITTAINV);
    if (ditta != 0)
    {
      codifica_ditta(m);
      tabella_ditta(m);  
      confronta_ditta();
    }                   
    else
    {
      m.reset(F_NUMULINV);
      m.reset(F_DATAULIN);
      m.reset(F_STATO);
      m.reset(F_USELAB);
      m.reset(F_CHIAVE);
      m.reset(F_RAGSOC);     
    }
  }
  
  m.disable(F_NUMULINV);
  m.disable(F_DATAULIN);
  m.disable(F_STATO);
  m.disable(F_USELAB);
  m.disable(F_CHIAVE);  
}

int Tabinv_application::write(const TMask& m)
{                                            
  if (_tabname == "%IND")
  {
    TString str;
    
    TString std = m.get(F_STATO);
    
    TConfig conf (CONFIG_DITTA);
    conf.set("FlStInv", std);
    
    int     num    = m.get_int(F_NUMULINV);
    TString data   = m.get    (F_DATAULIN);
    TString sigla  = m.get    (F_USELAB);        
    TString chiave = m.get    (F_CHIAVE);
    
    if (sigla == "")
      sigla = " ";
    
    if (_tras_file.read_control_rec())  
    {                               
      if (_ditte_uguali)
      {
        _control_rec = _tras_file.record();
        str = format("%03d", num);
        _control_rec.overwrite(str,29);
        str = riconverti(data);
        _control_rec.overwrite(str,32);
        _control_rec.overwrite(sigla,240);
        str = format("%-15s", (const char*) chiave);
        _control_rec.overwrite(str,241);
        
        _tras_file.write_control_rec(_control_rec,256);
      }
    }
  }      
  
  return Tab_application::write(m);
}

int Tabinv_application::rewrite(const TMask& m)
{    
  if (_tabname == "%IND")
  {
    TString str;
    
    TString std = m.get(F_STATO);
    
    TConfig conf (CONFIG_DITTA);
    conf.set("FlStInv", std);
    
    int     num    = m.get_int(F_NUMULINV);
    TString data   = m.get    (F_DATAULIN);
    TString sigla  = m.get    (F_USELAB);        
    TString chiave = m.get    (F_CHIAVE);
    
    if (sigla == "")
      sigla = " ";
    
    if (_tras_file.read_control_rec())  
    {  
      if (_ditte_uguali)
      {
        _control_rec = _tras_file.record();
        str = format("%03d", num);
        _control_rec.overwrite(str,29);
        str = riconverti(data);
        _control_rec.overwrite(str,32);
        _control_rec.overwrite(sigla,240);
        str = format("%-15s", (const char*) chiave);
        _control_rec.overwrite(str,241);
        
        _tras_file.write_control_rec(_control_rec,256);
      }
    }
  }    
  
  return Tab_application::rewrite(m);  
}

bool Tabinv_application::user_create()
{ 
  Tab_application::user_create();

  _msk     = get_mask();
  _tabname = get_tabname();

  if (_tabname == "%IND") 
  {                    
    _msk->set_handler(nascosto_handler);
    _msk->set_handler(F_STATO,    stato_invio);                 
    _msk->set_handler(F_DITTAINV, ditta_handler);
    _msk->set_handler(F_CAUSALI,  almeno_un_flag);
    _msk->set_handler(F_CLIFO,    clifo_comune);
    _msk->set_handler(F_PCON,     pcon_comune);
    _msk->set_handler(F_MOV,      prima_nota);
    _msk->set_handler(F_DATAULIN, data_invio);
    _msk->set_handler(F_USELAB,   sigla_file);
    _msk->set_handler(F_CHIAVE,   chiave_file);
    _msk->set_handler(F_GHOST_FIELD, controlli_hnd);
  }                               
  
  if (_tabname == "%INS")
  {
    _msk->set_handler(nascosto_handler);  
    _msk->set_handler(F_DITTAINV, nome_id);  
    _salta_hnd = FALSE;
  }

  return TRUE;
}

cg2500(int argc, char* argv[])
{
  Tabinv_application a;
  
  a.run(argc,argv, "Tabelle");
  return 0;
}