#include "cglib04.h"
#include "cg6802.h"

bool TAnn_mov::create()
{
  TApplication::create();

  _pcon     = new TLocalisamfile (LF_PCON);
  _clifo    = new TLocalisamfile (LF_CLIFO);
  _mov      = new TLocalisamfile (LF_MOV);  
  _rmov     = new TLocalisamfile (LF_RMOV);
  _rmoviva  = new TLocalisamfile (LF_RMOVIVA);
  _part     = new TLocalisamfile (LF_PARTITE);
  _scad     = new TLocalisamfile (LF_SCADENZE);
  _pagsca   = new TLocalisamfile (LF_PAGSCA);

  _rec_mov  = new TRectype (LF_MOV);  
  
  _registra = FALSE;
  
  dispatch_e_menu (BAR_ITEM(1));

  return TRUE;
}

bool TAnn_mov::destroy()
{
  delete _pcon;
  delete _clifo;
  delete _mov;                                
  delete _rmov;
  delete _rmoviva;  
  delete _part;
  delete _scad;
  delete _pagsca;

  delete _rec_mov;  
  
  return TApplication::destroy();
}                                

void TAnn_mov::apri_temp_file()
{
  TString80 tmpmov = "%";
  tmpmov  << get_firm_dir();
  tmpmov << "\\" << TEMP_MOV;
  TString80 tmprmov = "%";
  tmprmov << get_firm_dir();         
  tmprmov << "\\" << TEMP_RMOV;  
  TString80 tmprmoviva = "%";
  tmprmoviva << get_firm_dir();     
  tmprmoviva << "\\" << TEMP_RMOVIVA;                     
  TString80 tmppart = "%";
  tmppart  << get_firm_dir();
  tmppart << "\\" << TEMP_PART;
  TString80 tmpscad = "%";
  tmpscad << get_firm_dir();         
  tmpscad << "\\" << TEMP_SCAD;  
  TString80 tmppagsca = "%";
  tmppagsca << get_firm_dir();     
  tmppagsca << "\\" << TEMP_PAGSCA;                     
  
  _tmov     = new TIsamtempfile(LF_MOV, tmpmov, 0);
  _trmov    = new TIsamtempfile(LF_RMOV, tmprmov, 0);
   
  _is_iva = FALSE; 
  TString tmp = tmprmoviva.mid(1);
  tmp << ".dbf";
  if (fexist(tmp))
  {
    _tiva     = new TIsamtempfile(LF_RMOVIVA, tmprmoviva, 0);
    _is_iva = TRUE;
  }

  _is_salda = FALSE; 
  tmp = tmppart.mid(1);
  tmp << ".dbf";
  if (fexist(tmp))
  {
    _tpart    = new TIsamtempfile(LF_PARTITE, tmppart, 0);
    _tscad    = new TIsamtempfile(LF_SCADENZE, tmpscad, 0);
    _tpagsca  = new TIsamtempfile(LF_PAGSCA, tmppagsca, 0);        
    _is_salda = TRUE;
  }  
}

void TAnn_mov::chiudi_tempfile()
{
  delete _tmov;                  
  delete _trmov;    
  if (_is_iva)
    delete _tiva;
  if (_is_salda)
  {
    delete _tpart;
    delete _tscad;
    delete _tpagsca;
  }  
}

bool TAnn_mov::set()
{
  _dittaric = get_firm();
  
  if (!esegui_controlli()) return FALSE;
  
  apri_temp_file();
  
  if (!video())
  {
    if (_registra)  
      setta_parametri_record(" ","C");
  }
  
  chiudi_tempfile();
  return FALSE;
}

bool TAnn_mov::video()
{   
  TMask* msk = new TMask("cg6802a");
  KEY     tasto;
  
  do
  { 
    tasto = msk->run();
    
    if (tasto != K_ENTER)
    {
      delete msk;
      return FALSE;
    }
    
    if (esiste_testata_mov(*msk))
    {
      TMask* mask = new TMask("cg6802b");
      
      mask->set_handler(F_REGIVA,    codice_registro_hnd);
      mask->set_handler(F_CODCAUS,   codice_causale_hnd);  
      
      setta_campi_maschera(*mask);
      
      tasto = mask->run();
      
      switch (tasto)
      {
      case K_ESC :
        break;
        
      case K_QUIT :
        break;       
        
      case K_DEL :
      {
        annulla(*mask);
        _registra = TRUE;
      }
        break;
        
      default:
        break;
      }
      delete mask;
    }
  }
  while (tasto != K_QUIT);                              //K_ENTER

  delete msk;
  return TRUE;
}

bool TAnn_mov::esiste_testata_mov(TMask& m)
{
  _numreg = m.get_long(F_NUMREG);
  
  _tmov->setkey(1);
  _tmov->zero();
  _tmov->put(MOV_NUMREG, _numreg);
  
  if (_tmov->read() == NOERR)
    *_rec_mov = _tmov->curr();  
  else
    return error_box(TR("Registrazione richiesta NON PRESENTE tra i movimenti in trasferimento"));
  
  return TRUE;
}

void TAnn_mov::setta_campi_maschera(TMask& m)
{  
  TDate   datareg (_rec_mov->get_date(MOV_DATAREG));
  TDate   datadoc (_rec_mov->get_date(MOV_DATADOC));
  TString numdoc    = _rec_mov->get     (MOV_NUMDOC);
  TString regiva    = _rec_mov->get     (MOV_REG);
//  regiva.trim();
  long    protiva   = _rec_mov->get_long(MOV_PROTIVA);
  TString codcaus   = _rec_mov->get     (MOV_CODCAUS);
  
  m.set(F_NUMREG,    _numreg);
  m.set(F_DATAREG,   datareg.string());
  m.set(F_DATADOC,   datadoc.string());
  m.set(F_NUMDOC,    numdoc);
  m.set(F_REGIVA,    regiva);
  m.set(F_PROTIVA,   protiva);
  m.set(F_CODCAUS,   codcaus);

  m.disable(F_NUMREG);
  m.disable(F_DATAREG);
  m.disable(F_DATADOC);
  m.disable(F_NUMDOC);
  m.disable(F_REGIVA);
  m.disable(F_PROTIVA);
  m.disable(F_CODCAUS);
}   

void TAnn_mov::annulla(TMask& m)
{
  TRectype* rec_rmov,* rec_riva;
  rec_rmov = new TRectype (LF_RMOV);

// Cancello la testata del movimento

  long numreg = m.get_long(F_NUMREG);

  _tmov->setkey(1);
  _tmov->zero();
  _tmov->put(MOV_NUMREG, numreg); 
  if (_tmov->read() == NOERR)    
    _tmov->remove();

// Cancello tutte le righe di Primanota  

  _trmov->setkey(1);
  _trmov->zero();
  _trmov->put(RMV_NUMREG, numreg); 
  *rec_rmov = _trmov->curr();
  
  for (_trmov->read(); !_trmov->eof(); _trmov->next())
  {
    if (_trmov->curr() > *rec_rmov) break;
    
    _trmov->remove();
  }
  
  delete rec_rmov;

// Cancello tutte le righe iva
  
  rec_riva = new TRectype (LF_RMOVIVA);

  _tiva->setkey(1);
  _tiva->zero();
  _tiva->put(RMI_NUMREG, numreg); 
  *rec_riva = _tiva->curr();
  
  for (_tiva->read(); !_tiva->eof(); _tiva->next())
  {
    if (_tiva->curr() > *rec_riva) break;
    
    _tiva->remove();
  }
  
  delete rec_riva;  
  
  if (_is_salda)
  { 
    TRectype* rec_part;
    
    rec_part = new TRectype (LF_PARTITE);

    _tpart->setkey(2);
    _tpart->zero();
    _tpart->put(PART_NREG, numreg); 
    *rec_part = _tpart->curr();
  
    for (_tpart->read(_isgteq); !_tpart->eof(); _tpart->next())
    {  
      if (_tpart->curr() != *rec_part) break;
      
      int     tipomov    = _tpart->get_int (PART_TIPOMOV);
      char    tipocf     = _tpart->get_char(PART_TIPOCF);
      int     gruppo     = _tpart->get_int (PART_GRUPPO);
      int     conto      = _tpart->get_int (PART_CONTO);
      long    codcf      = _tpart->get_long(PART_SOTTOCONTO);  
      int     anno       = _tpart->get_int (PART_ANNO);
      TString numpart    = _tpart->get     (PART_NUMPART);  
      int     nriga      = _tpart->get_int (PART_NRIGA);

      if (!controlla_abbuoni_diffcam(tipocf,gruppo,conto,codcf,anno,numpart,nriga,0))
        continue;
      
      if (tipomov == 1)
      {
        _tscad->zero();
        _tscad->put(SCAD_TIPOCF,       tipocf);
        if (gruppo != 0)
          _tscad->put(SCAD_GRUPPO,     gruppo);
        if (conto != 0)
          _tscad->put(SCAD_CONTO,      conto);
        if (codcf != 0)
          _tscad->put(SCAD_SOTTOCONTO, codcf);
        _tscad->put(SCAD_ANNO,         anno);
        _tscad->put(SCAD_NUMPART,      numpart);
        _tscad->put(SCAD_NRIGA,        nriga);  
    
        TRectype scad (_tscad->curr());
    
        for (_tscad->read(_isgteq); !_tscad->eof(); _tscad->next())
        {    
          TString rec  = scad.get(SCAD_NUMPART);
          TString file = _tscad->get(SCAD_NUMPART);
                                                      
          if (_tscad->curr() != scad || file != rec) break;
                            
          int nrata = _tscad->get_int (SCAD_NRATA);
          
          sgancia_pagamenti(tipocf,gruppo,conto,codcf,anno,numpart,nriga,nrata);                            
          
          _tscad->remove();
        }
      }
    
      if (tipomov != 1)
      {
        _tpagsca->zero();
        _tpagsca->put(PAGSCA_TIPOC,      tipocf);  
        if (gruppo != 0)
          _tpagsca->put(PAGSCA_GRUPPO,     gruppo);
        if (conto != 0)
          _tpagsca->put(PAGSCA_CONTO,      conto);
        if (codcf != 0)
          _tpagsca->put(PAGSCA_SOTTOCONTO, codcf);
        _tpagsca->put(PAGSCA_ANNO,       anno);
        _tpagsca->put(PAGSCA_NUMPART,    numpart);
    
        TRectype pagsca (_tpagsca->curr());
    
        for (_tpagsca->read(_isgteq); !_tpagsca->eof(); _tpagsca->next())
        {                                               
          int nrigp = _tpagsca->get_int(PAGSCA_NRIGP);         
           
          TString rec  = pagsca.get(PAGSCA_NUMPART);
          TString file = _tpagsca->get(PAGSCA_NUMPART);
           
          if (_tpagsca->curr() != pagsca || file != rec) break;
        
          if (nriga != nrigp) continue;
          
          _tpagsca->remove();
        }
      }  
      _tpart->remove();
    }
    delete rec_part;  
  }
}

bool TAnn_mov::controlla_abbuoni_diffcam(char tipo,int g,int c,long s,int anno,TString& npart,int nriga,int nrata)
{
  TIsamtempfile& pagsca = *_tpagsca;
  
  pagsca.setkey(1);
  pagsca.zero();
  pagsca.put(PAGSCA_TIPOC,      tipo);
  pagsca.put(PAGSCA_GRUPPO,     g);
  pagsca.put(PAGSCA_CONTO,      c);
  pagsca.put(PAGSCA_SOTTOCONTO, s);
  pagsca.put(PAGSCA_ANNO,       anno);
  pagsca.put(PAGSCA_NUMPART,    npart);
  pagsca.put(PAGSCA_NRIGA,      nriga);
  if (nrata != 0)
    pagsca.put(PAGSCA_NRATA,    nrata);
      
  TRectype pagamenti (pagsca.curr());
  
  for (pagsca.read(_isgteq); !pagsca.eof(); pagsca.next())
  {        
    TString rec  = pagamenti.get(PAGSCA_NUMPART);
    TString file = pagsca.get(PAGSCA_NUMPART);
    
    if (pagsca.curr() != pagamenti || file != rec) break;
    
    real abbuoni = pagsca.get_real(PAGSCA_ABBUONI);
    real diffcam = pagsca.get_real(PAGSCA_DIFFCAM);
    if (abbuoni != ZERO || diffcam != ZERO)
      return FALSE;
  }                
  return TRUE;              
}

void TAnn_mov::sgancia_pagamenti(char tipo,int g,int c,long s,int anno,TString& npart,int nriga,int nrata)
{
  TIsamtempfile& pagsca = *_tpagsca;
  
  pagsca.setkey(1);
  pagsca.zero();
  pagsca.put(PAGSCA_TIPOC,      tipo);
  pagsca.put(PAGSCA_GRUPPO,     g);
  pagsca.put(PAGSCA_CONTO,      c);
  pagsca.put(PAGSCA_SOTTOCONTO, s);
  pagsca.put(PAGSCA_ANNO,       anno);
  pagsca.put(PAGSCA_NUMPART,    npart);
  pagsca.put(PAGSCA_NRIGA,      nriga);
  pagsca.put(PAGSCA_NRATA,      nrata);
  
  TRectype pagamenti (pagsca.curr());
  
  for (pagsca.read(_isgteq); !pagsca.eof(); pagsca.next())
  {   
    TString rec  = pagamenti.get(PAGSCA_NUMPART);
    TString file = pagsca.get(PAGSCA_NUMPART);
    
    if (pagsca.curr() != pagamenti || file != rec) break;
    
    TRectype pag (pagsca.curr());
    
    pag.put(PAGSCA_NRIGA, 9999);
    pag.put(PAGSCA_NRATA, 9999);
    
    TRecnotype nrec = pagsca.recno();
    pagsca.remove();
    pagsca.curr() = pag;
    if (pagsca.read() == NOERR)
    { 
      real importo  = pagsca.get_real(PAGSCA_IMPORTO) + pag.get_real(PAGSCA_IMPORTO);
      real impval   = pagsca.get_real(PAGSCA_IMPORTOVAL) + pag.get_real(PAGSCA_IMPORTOVAL);
      real ritenute = pagsca.get_real(PAGSCA_RITENUTE) + pag.get_real(PAGSCA_RITENUTE);
      pagsca.put(PAGSCA_IMPORTO,    importo);
      pagsca.put(PAGSCA_IMPORTOVAL, impval);
      pagsca.put(PAGSCA_RITENUTE,   ritenute);
      pagsca.put(PAGSCA_ACCSAL, "A");    
      pagsca.rewrite();
    }
    else      
    {
      pagsca.curr() = pag;
      pagsca.write();     
    }             
                  
    pagsca.readat(nrec);
  }                              
}

bool TAnn_mov::leggi_trasfer()
{ 
  _trasf = _tras_file.path(_dittaric);
  _trasf << HEADER;
  
  _tras_file.open(_trasf);
  
  if (_tras_file.exist())
  {  
    if (_tras_file.read_control_rec())
      _control_rec = _tras_file.record();
    else
      return error_box(TR("Rilevati gravi errori negli archivi:procedura interrotta"));
  } 
  else
    return error_box(TR("Al momento non presenti trasferimenti attivi sulla ditta selezionata"));
  
  return TRUE; 
}

bool TAnn_mov::codice_registro_hnd(TMask_field& f, KEY k)
{ 
  TTable reg ("REG");
  TString descr,dep;
  
  if (k == K_TAB)
  {              
    TString codreg = f.get();
    TDate   datareg (f.mask().get(F_DATAREG));
    int     anno   = date2esc(datareg);
    
    reg.zero();
    reg.put("CODTAB", codreg);
    if (reg.read() == NOERR)
    {
      descr = reg.get("S0");
      f.mask().set(F_DESCRREG, descr);
    }
  } 
  
  return TRUE;
}

bool TAnn_mov::codice_causale_hnd(TMask_field& f, KEY k)
{
  TLocalisamfile cau (LF_CAUSALI);
  TString descr;
  
  if (k == K_TAB)
  {         
    TString codcau = f.get();
    
    cau.setkey(1);
    cau.zero();
    cau.put("CODCAUS", codcau);
    if (cau.read() == NOERR)
    {
      descr = cau.get("DESCR");
      f.mask().set(F_DESCRCAU, descr);
    }                                 
  }            

  return TRUE;
}

bool TAnn_mov::esegui_controlli()
{                    
  TConfig conf(CONFIG_DITTA);           
  
  _std = conf.get("FlStTra");

  if (!prefix().exist(_dittaric))
    return error_box(TR("Rilevati GRAVI ERRORI negli archivi: procedura interrotta"));

  if (!leggi_trasfer())
    return FALSE;      
  
  if (!controlli())
    return FALSE;
  
  return TRUE;
}

bool TAnn_mov::controlli()
{                
  TString16 chiave,sigla;
  
  chiave = _control_rec.sub(241,256);
  chiave.trim();        
  sigla  = _control_rec.sub(240,241);
  sigla.trim();

  if (_std == "M" && sigla == "Z" && chiave != "")
    return error_box(TR("Variazione NON POSSIBILE: trasferimento movimenti gia' iniziato"));           
  
  if (_std == "M" && sigla == "U")
    return error_box(TR("Variazione NON POSSIBILE: trasferimento movimenti gia' iniziato"));           

  if (_std == "M" && sigla == "B")
    return error_box(TR("Variazione NON POSSIBILE: trasferimento movimenti gia' iniziato"));           
  
  if (_std == "*") 
  {
    warning_box(TR("Trasferimento interamente completato: proseguire per cancellare il file"));    
    _tras_file.remove_all();
    setta_parametri_record(""," ");
    return FALSE;
  }

  if (_std == "T")
    return error_box(TR("Variazione NON POSSIBILE: eseguire prima la ricezione delle tabelle"));           
  
  return TRUE;
}

void TAnn_mov::leggi_record_controllo()
{
  _tras_file.read_control_rec();
  _control_rec = _tras_file.record();
}

void TAnn_mov::setta_parametri_record(const TString& sigla,const TString& flag)
{ 
  TConfig conf (CONFIG_DITTA);
  
  conf.set("FlStTra", flag);

  leggi_record_controllo();
  _control_rec.overwrite(sigla,240);
    
  const int size = 1024;
    
  _tras_file.write_control_rec(_control_rec, size);
}

bool TAnn_mov::menu(MENU_TAG m)
{
  if (m == BAR_ITEM(1))
    return set(); 
  return FALSE;
}