//
// Ricezione dati: lista controllo movimenti
//       

#include <config.h>
#include <mask.h>
#include <prefix.h>
#include <printapp.h>
#include <progind.h>
#include <tabutil.h>
#include <utility.h>

#include <nditte.h>
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h> 
#include <causali.h> 
#include <clifo.h> 
#include <nditte.h> 
#include <pconti.h> 

#include "cg2103.h"
#include "cglib04.h" 
#include "cg2700.h"

HIDDEN const char* err_msg[] = {"*** Data operazione non valida",
                                "*** Data operazione non compresa in alcun esercizio",
                                "*** Data competenza non valida",
                                "*** Data competenza non compresa in alcun esercizio",
                                "--- Data competenza incompatibile con data operazione",
                                "*** Data operazione antecedente ad ultima stampa giornale",
                                "--- Data documento non valida",
                                "*** Codice causale non valido o non presente in archivio",
                                "--- Codice pagamento non valido o non presente in tabella",
                                "*** Codice registro IVA non valido o non presente in tabella",
                                "*** Codice cliente/fornitore non valido o non presente in anagrafica",
                                "--- Data 74 ter non valida",
                                "*** Data operazione antecedente ad ultima stampa registro IVA"};

HIDDEN int date2esc(const TDate& d, int* prevesc = NULL);

class TRic_ListaMov : public TPrintapp
{
  TTable*          _tab_tra,* _tab_pag,* _tab_tpd,* _tab_iva, *_tab_ese;
  TIsamtempfile*   _tmov,* _trmov,* _tiva;
  TLocalisamfile*  _caus,* _ditte,* _clifo,* _pcon, *_mov, *_rmov, *_rmoviva;
  TRelation*       _rel;
  TCursor*         _cur;
  TTransfer_file*  _trasfer;
  TLibro_giornale* _giornale;
  TString80        _pathfile, _descr_causale, _descr_conto;
  TString16        _causale, _registro, _numdoc, _tipodoc, _codval;
  TString16        _codpag, _codiva, _tipo_conto;
  TString          _record;
  bool             _mov_sez, _errore_grave, _esiste_conto;
  char             _sdt, _sezione;
  int              _ae, _anno, _gruppo, _conto, _tipocr, _tipod, _tiporeg;
  int              _gruppoc, _contoc, _n_rec, _gruppocr, _contocr;
  TDate            _datacomp, _datadoc, _datareg, _data74tr;
  real             _importo, _impo, _impos, _tot_dare, _tot_avere, _tot_doc;
  long             _codcf, _numero, _protiva, _sottoconto;
  long             _inizioZ, _inizioU, _num_rec, _sottocontoc, _sottocontocr;
  TBit_array       _err;   
  byte             _controllo;
    
public:
  virtual          bool set_print(int m);
  virtual          bool user_create() ;
  virtual          bool user_destroy();
  virtual          bool preprocess_page(int,int);
  virtual          print_action postprocess_page(int,int);
  virtual          void postclose_print();
  const char*      look_sdt();
  const char*      get_codiva_des(const char*);
  bool             DescrConto(int,int,long);
  bool             check_archivi(TProgind*);
  bool             look_pag();
  bool             errori_partita(int,int,long);
  bool             controlla_mov();
  bool             controlla_rmov();
  bool             controlla_riva();
  void             stampa_errori_mov(int);
  void             stampa_errori_rmov(int);
  void             stampa_errori_riva(int);
  void             aggiorna_trasfer_Z();
  void             aggiorna_trasfer_U();
  void             setta_parametri(const TString&, const TString&);
  void             setta_intestazione();
  TLibro_giornale& giornale() { return *_giornale; }
  TTransfer_file&  trasfer() { return *_trasfer; }
  
  TRic_ListaMov(): _err(80) {}
  virtual ~TRic_ListaMov() {}
};                  

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

HIDDEN int date2esc(const TDate& d, int* prevesc)
{                   
  if (prevesc) *prevesc = 0;
  TTable esc("ESC");
  for (int err = esc.first(); err == NOERR; err = esc.next())
  {
    const TDate ia(esc.get("D0"));   // Data inizio esercizio
    const TDate fa(esc.get("D1"));   // Data fine esercizio
    const anno = esc.get_int("CODTAB");  
    if (d >= ia && d <= fa)
      return anno;
    if (prevesc) *prevesc = anno; 
  } 
  return 0;
}

const char* TRic_ListaMov::look_sdt()
{
  TConfig conf(CONFIG_DITTA);
  return conf.get("FlStTra");
}

bool TRic_ListaMov::look_pag()
{
  TTable t ("%CPG");
  t.zero();
  t.put("CODTAB",_codpag);
  if (t.read() != NOERR) return FALSE;
  return TRUE;
}

const char* TRic_ListaMov::get_codiva_des(const char* codiva)
{
  TTable iva ("%IVA");
  
  iva.zero();
  iva.put("CODTAB", codiva);
  if (iva.read() == NOERR)
    return iva.get("S0");
  else
    return NULL;             
}

bool TRic_ListaMov::DescrConto(int g, int c, long s)
{
  TString80 ragsoc;
  const char* descr = NULL;
  TLocalisamfile pconti (LF_PCON);
  pconti.setkey(1);
  pconti.zero();
  pconti.put(PCN_GRUPPO, g);
  pconti.put(PCN_CONTO,  c);
  pconti.put(PCN_SOTTOCONTO, 0L);
  if (pconti.read() == NOERR)
  {
    _tipo_conto = pconti.get(PCN_TMCF);
    if (_tipo_conto == "C" || _tipo_conto == "F")
    {
     TLocalisamfile clifo (LF_CLIFO);
     clifo.setkey(1);
     clifo.zero();
     clifo.put(CLI_TIPOCF, _tipo_conto);
     clifo.put(CLI_CODCF, s);
     if (clifo.read() != NOERR)
     {
       _descr_conto = ""; 
       return FALSE;
     }
     else
     {
       char tipoa = clifo.get_char("TIPOAPER");
       if (tipoa == 'F') //persona fisica
       { 
         TString80 cognome, nome;
         ragsoc = clifo.get("RAGSOC");
         cognome = ragsoc.mid(0,30);
         nome = ragsoc.mid(30,20);
         cognome.trim(); nome.trim();
         ragsoc = cognome;
         ragsoc << " " << nome;
         _descr_conto = ragsoc;
       } 
       else _descr_conto = clifo.get("RAGSOC");
     }   
    } 
    else
    {
     pconti.zero();
     pconti.put(PCN_GRUPPO, g);
     pconti.put(PCN_CONTO,  c);
     pconti.put(PCN_SOTTOCONTO, s);
     if (pconti.read() != NOERR)
     {
       _descr_conto = "";
       return FALSE;
     }
     else _descr_conto = pconti.get(PCN_DESCR);  
    }
  }
  else 
  {
    _descr_conto = "";
    return FALSE;
  }
  return TRUE;
}

bool TRic_ListaMov::user_create()
{
  _trasfer  = new TTransfer_file();
  
  TProgind* pnd = NULL;
  pnd = new TProgind (3,"Controllo archivi\nPrego attendere", 
                      FALSE, TRUE, 30);
  _tab_tra = new TTable ("%TRA");
  _tab_tpd = new TTable ("%TPD");
  _tab_pag = new TTable ("%CPG"); 
  _tab_iva = new TTable ("%IVA");
  _tab_ese = new TTable ("ESC");
  _caus    = new TLocalisamfile (LF_CAUSALI);
  _ditte   = new TLocalisamfile (LF_NDITTE);
  _clifo   = new TLocalisamfile (LF_CLIFO);
  _pcon    = new TLocalisamfile (LF_PCON);
  _mov     = new TLocalisamfile (LF_MOV);
  _rmov    = new TLocalisamfile (LF_RMOV);
  _rmoviva = new TLocalisamfile (LF_RMOVIVA);      
  
  if (pnd) pnd->addstatus(1);
  
  if (!check_archivi(pnd))
  {
    delete pnd;
    return FALSE;
  }
  
  if (pnd) pnd->addstatus(1);
  
  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;
  
  _tmov  = new TIsamtempfile(LF_MOV, tmpmov, 0);
  _trmov = new TIsamtempfile(LF_RMOV, tmprmov, 0);
  _tiva  = new TIsamtempfile(LF_RMOVIVA, tmprmoviva, 0);

  _rel = new TRelation(_tmov);
  _rel->add(_trmov,"NUMREG=NUMREG",1,0,0,FALSE);
  _rel->add(_tiva, "NUMREG=NUMREG",1,0,0,FALSE);
  _cur = new TCursor (_rel, "", 1);
  
  _giornale = new TLibro_giornale();
  
  add_cursor(_cur);
  
  add_file (LF_MOV);
  add_file (LF_RMOV, LF_MOV);
  add_file (LF_RMOVIVA, LF_MOV);
  
  printer().footerlen(5);
  
  delete pnd;
  
  return TRUE;
}

bool TRic_ListaMov::check_archivi(TProgind* pnd)
{
  TString80 nome;
  long ditta_ric = get_firm();
  
  if (!prefix().exist(ditta_ric))
     return error_box("Rilevati errori gravi negli archivi: procedura interrotta");
  
  TTransfer_file& tr = trasfer();
  
  _pathfile = tr.path();         
  
  _pathfile = _pathfile << "\\trasfer";
  
  if (!tr.open(_pathfile))
     return error_box("Al momento non presenti trasferimenti attivi sulla ditta selezionata");
  
  if (!tr.read_control_rec())
    return error_box("Rilevati errori gravi negli archivi: procedura interrotta");
  else _record = tr.record();
  
  TString16 sd = look_sdt();
  
  if (sd.not_empty())
     _sdt = sd[0];
  else return error_box("Ricezione tabelle non effettuata: richiamare il programma relativo");
  
  if (_sdt == 'T')
     return error_box("Ricezione tabelle non effettuata: richiamare il programma relativo");
     
  if (_sdt == 'M')
     return yesno_box("Controllo gia' effettuato: si desidera ripeterlo ?");
     
  if (_sdt != '*' && _sdt != 'C')
     return error_box("Rilevati errori gravi negli archivi: procedura interrotta");
  
  TString16 ult = tr.ult_file();
  TString16 key = tr.key();
  
  ult.strip_spaces(); 
  key.strip_spaces();

  if (_sdt == 'C')
     if ( ult.not_empty() || key.not_empty() )
        return error_box("Rilevati errori gravi negli archivi: procedura interrotta");

  if (_sdt == '*')
    return warning_box("Trasferimento interamente completato: proseguire per cancellare i file"); 
  
  if (pnd) pnd->addstatus(1);
  
  return TRUE;        
}
 
void TRic_ListaMov::stampa_errori_mov(int riga)
{
  long i = _err.first_one();
  if (i != -1)
  {
    for (; i <= _err.last_one(); i++)
      if (_err[i])
        set_row(++riga, "@8g%s", (const char*) err_msg[i]);
  }  
} 
 
bool TRic_ListaMov::controlla_mov()
{
  bool check_reg = TRUE;
  TString16 causreg;
  TDate udata;
  char tipocf = ' ';
  
  _tiporeg = 0;
  
  if (!_datareg.ok())
  {
    _errore_grave = TRUE;
    _err.set(0L);
  }
  
  if (_datareg.ok())
  { 
    int pr;
    const int ar = date2esc(_datareg, &pr);    // Esercizio in corso
    if (ar == 0)    
    {
       _err.set(1);
       _errore_grave = TRUE;
    }
    if (_datacomp.ok())
    {  
      const int ae = date2esc(_datacomp);
      if (ae == 0)
      {
         _err.set(3);
         _errore_grave = TRUE;
      }
      else if (ae != ar && ae != pr && ar)
             _err.set(4);
    }
  }
  
  if (!_datacomp.ok())
  {
    _errore_grave = TRUE;
    _err.set(2);
  }
    
  TLibro_giornale& gio = giornale();
  bool ok = gio.read(_ae);  //se _ae e' zero la read considera come anno quello corrente
  if (_datareg < gio.last_print())
  {
    _errore_grave = TRUE;
    _err.set(5);
  } 
  
  TString16 dd = _datadoc.string();
  if (dd.not_empty()) 
    if (!_datadoc.ok())
      _err.set(6);
     
  //if (_causale.not_empty()) 
  //{
    TLocalisamfile caus(LF_CAUSALI);
    caus.setkey(1);
    caus.zero();
    caus.put(CAU_CODCAUS,_causale);
    if (caus.read() == NOERR)   
      _tipodoc = caus.get(CAU_TIPODOC);
    else
    {
      caus.zero();
      if (look_causale(_causale))  //se la causale e' significativa
      {
       _errore_grave = TRUE;
       _err.set(7); 
      } 
    } 
    //_tipodoc = caus.get(CAU_TIPODOC);  ho sempre quello letto sul movimento!
    causreg = caus.get(CAU_REG); 
    _descr_causale = caus.get(CAU_DESCR); 
    _mov_sez = caus.get_bool(CAU_MOVSEZ);
  //}      
  
  if (!_codpag.blank())
  {
    bool ok = look_pag(); 
    if (!ok)
      _err.set(8);
  }   
   
  if (!_registro.blank()) //movimento iva (fattura)
  {
    if (!look_causale(_causale))  //se la causale non e' significativa
    {
      _errore_grave = TRUE;
      check_reg = FALSE;
      _err.set(9);
    }
    if (check_reg && _ae)
    {
      TRegistro rg (_registro, _ae);   
      if (rg.name().empty())
      {
        _errore_grave = TRUE;
        check_reg = FALSE;
        _err.set(9);
      }
      else
      {
       _tiporeg = rg.tipo();
       udata = rg.last_print();
      }    
    }
  }
  else if (!causreg.blank() && _ae)
  {     
    TRegistro rg (causreg, _ae);   
    if (rg.name().empty())
    {
      _errore_grave = TRUE;
      check_reg = FALSE;
      _err.set(9);
    }
    else 
    {
      _tiporeg = rg.tipo();
      udata = rg.last_print();
    }   
    _registro = causreg;   
  }  
  
  if (!_registro.blank())
  {
    if (_tiporeg == 1) tipocf = 'C';
    else if (_tiporeg == 2) tipocf = 'F';
//    if (_tiporeg != 0)    //se esiste, uso quello della causale!!!
//    {   
      TTable tabtpd("%TPD");
      tabtpd.put("CODTAB", _tipodoc);
      if (tabtpd.read() == NOERR) 
      {
        bool cor = tabtpd.get_bool("B0");
        if (!cor)
          if (_codcf != 0l)
          { 
            TLocalisamfile clifo(LF_CLIFO);
            clifo.zero();
            clifo.put(CLI_CODCF, _codcf);
            clifo.put(CLI_TIPOCF,tipocf);
            if (clifo.read() != NOERR)    
            {
              _errore_grave = TRUE;
              _err.set(10);
            }
          }
          else 
          {
            _errore_grave = TRUE;
            _err.set(10);
          }
      }
      else
      {
        if (_codcf != 0l)
        { 
          TLocalisamfile clifo(LF_CLIFO);
          clifo.zero();
          clifo.put(CLI_CODCF, _codcf);
          clifo.put(CLI_TIPOCF,tipocf);
          if (clifo.read() != NOERR)    
          {
            _errore_grave = TRUE;
            _err.set(10);
          }
        }
        else 
        {
          _errore_grave = TRUE;
          _err.set(10);
        }
      }
//    }
  }
  
  TString16 d74 = _data74tr.string();
  if (d74.not_empty())
    if (!_data74tr.ok())
      _err.set(11);
     
  if (!_registro.blank() && check_reg)
     if (_datareg < udata) 
     {
       _errore_grave = TRUE;
       _err.set(12);
     } 
  
  if (_err.ones())
    return TRUE;
  
  return FALSE;   
} 

bool TRic_ListaMov::errori_partita(int g, int c, long s)
{
  TLocalisamfile pconti (LF_PCON);
  pconti.setkey(1);
  pconti.zero();
  pconti.put(PCN_GRUPPO, g);
  pconti.put(PCN_CONTO,  c);
  pconti.put(PCN_SOTTOCONTO, 0L);
  if (pconti.read() == NOERR)
  {
    char tipo = pconti.get(PCN_TMCF)[0];
    if (tipo == 'C' || tipo == 'F')
    {
     TLocalisamfile clifo (LF_CLIFO);
     clifo.setkey(1);
     clifo.zero();
     clifo.put(CLI_TIPOCF, tipo);
     clifo.put(CLI_CODCF, s);
     if (clifo.read() != NOERR)
        return FALSE; 
    } 
    else
    {
     pconti.zero();
     pconti.put(PCN_GRUPPO, g);
     pconti.put(PCN_CONTO,  c);
     pconti.put(PCN_SOTTOCONTO, s);
     if (pconti.read() != NOERR)
        return FALSE;
    }
  }
  else return FALSE;
  
  return TRUE;
}

bool TRic_ListaMov::controlla_rmov()
{
  TLocalisamfile& rmov = current_cursor()->file(LF_RMOV);
  int gruppo, conto, gruppoc, contoc;
  long sottoconto, sottocontoc;
  char sezione;
  real importo, dare, avere;
  
  if (current_cursor()->is_first_match(LF_RMOV))
  {
    dare = avere = ZERO;
    TRecnotype nrec = rmov.recno();
    rmov.zero();
    rmov.setkey(1);
    rmov.put(RMV_NUMREG, _numero);
    TRectype recc (rmov.curr());
    for (rmov.read(_isgteq); !rmov.eof() ;rmov.next())
    {
      TRectype rec (rmov.curr());
      if (rec > recc) break;
      gruppo = rec.get_int(RMV_GRUPPO);
      conto  = rec.get_int(RMV_CONTO);
      sottoconto = rec.get_long(RMV_SOTTOCONTO);
      gruppoc = rec.get_int(RMV_GRUPPOC);
      contoc  = rec.get_int(RMV_CONTOC);
      sottocontoc = rec.get_long(RMV_SOTTOCONTOC);
      sezione = rec.get_char(RMV_SEZIONE);
      importo = rec.get_real(RMV_IMPORTO); 
            
       _tipo_conto = "";
    
      if (gruppo != 0 && conto != 0 && sottoconto != 0l)
        _esiste_conto = DescrConto(gruppo,conto,sottoconto);
      else
      {
       _esiste_conto = FALSE;
       _descr_conto = "";
      } 
      
      _num_rec = rec.get_long(RMV_ANNOES);
      aggiorna_trasfer_Z();
      
      if (sezione == 'D') 
        dare += importo;
      if (sezione == 'A')
        avere += importo;
      
      if (gruppo == 0 || conto == 0 || sottoconto == 0l)
      { 
        rmov.readat(nrec);
        return TRUE; 
      }
      else
      { 
        bool ok = errori_partita(gruppo,conto,sottoconto);
        if (!ok) 
        {
          rmov.readat(nrec);
          return TRUE;
        }
      }
  
      if ( (importo != ZERO && sezione == '\0') || 
           (sezione != 'D' && sezione != 'A' && sezione != '\0') )
      {
        rmov.readat(nrec);
        return TRUE;
      }
  
      if (gruppoc != 0 || contoc != 0 || sottocontoc != 0l)
      { 
        bool ok = errori_partita(gruppoc,contoc,sottocontoc);
        if (!ok)
        {
          rmov.readat(nrec);
          return TRUE;
        }
      } 
      
      if (!_mov_sez && importo == ZERO)
      {
        rmov.readat(nrec);
        return TRUE;
      }                
    }
    if (dare != avere)
    {
     rmov.readat(nrec);
     return TRUE;
    }   
    rmov.readat(nrec);
  }
  return FALSE;  
}

void TRic_ListaMov::stampa_errori_rmov(int riga)
{
  if (_gruppo == 0 || _conto == 0 || _sottoconto == 0l) 
  {
    _errore_grave = TRUE;
    set_row(++riga, "@8g*** Sottoconto partita non valido o non presente in archivio");
  }
  else
  { 
    if (!_esiste_conto)
    {    
      _errore_grave = TRUE;
      set_row(++riga, "@8g*** Sottoconto partita non valido o non presente in archivio");
    }
  }
                                        
  if ( (_importo != ZERO && _sezione == '\0') || 
       (_sezione != 'D' && _sezione != 'A' && _sezione != '\0') )
  {     
    _errore_grave = TRUE;
    set_row(++riga, "@8g*** Segnale dare/avere non valido");
  }
  
  if (_sezione == 'D')
     _tot_dare += _importo;
  if (_sezione == 'A')
     _tot_avere += _importo;       
  
  if (_gruppoc != 0 || _contoc != 0 || _sottocontoc != 0l)
  // set_row(++riga, "@8g*** Sottoconto contropartita non valido o non presente in archivio");
  // else
  { 
    bool ok = errori_partita(_gruppoc,_contoc,_sottocontoc);
    if (!ok)
      set_row(++riga, "@8g--- Sottoconto contropartita non valido o non presente in archivio");
  } 
  
  if (!_mov_sez && _importo == ZERO)
    set_row(++riga, "@8g--- Importo riga uguale a zero");
} 

bool TRic_ListaMov::controlla_riva()
{
  TLocalisamfile& rmoviva = current_cursor()->file(LF_RMOVIVA);
  TTable  tab_iva("%IVA");
  TString16 codiva;
  int tipodet, tipocr, gruppocr, contocr;
  long sottocontocr;  
  real impo, impos;
  
  if (current_cursor()->is_first_match(LF_RMOVIVA))
  {
    TRecnotype nrec = rmoviva.recno();
    rmoviva.setkey(1);
    rmoviva.zero();
    rmoviva.put(RMI_NUMREG, _numero);
    TRectype recc (rmoviva.curr());
    for (rmoviva.read(_isgteq); !rmoviva.eof() ;rmoviva.next())
    {
      TRectype rec (rmoviva.curr());
      if (rec > recc) break;
      _n_rec = rec.get_int(RMI_ANNOES);
      codiva = rec.get(RMI_CODIVA);
      tipodet = rec.get_int(RMI_TIPODET);
      tipocr  = rec.get_int(RMI_TIPOCR);
      gruppocr = rec.get_int(RMI_GRUPPO);
      contocr = rec.get_int(RMI_CONTO);
      sottocontocr = rec.get_long(RMI_SOTTOCONTO);
      impo  = rec.get_real(RMI_IMPONIBILE);
      impos = rec.get_real(RMI_IMPOSTA);
      
      TString impostr = impo.string();
      TString impostastr = impos.string();
      
      _tot_doc += impo + impos;
      
      TString totdocstr = _tot_doc.string();
      
      _impo = impo;
      _impos = impos; 
     
      if (!_tipodoc.blank())
      {   
        TTable tabtpd("%TPD");
        tabtpd.put("CODTAB", _tipodoc);
        if (tabtpd.read() == NOERR) 
        {
         bool cor = tabtpd.get_bool("B0");
         if (cor)
         {
          _impo  = impo + impos;
          _impos = ZERO;
         }
        }  
      }  
      
      aggiorna_trasfer_U();
      
      TTable iva ("%IVA");
      iva.zero();
      iva.put("CODTAB", codiva);
      if (iva.read() != NOERR)
      {
        rmoviva.readat(nrec);
        return TRUE;
      }
      if (!(tipocr >= 0 && tipocr <= 9))
      { 
        rmoviva.readat(nrec);
        return TRUE;
      }
      if (gruppocr == 0 || contocr == 0 || sottocontocr == 0l)
      { 
        rmoviva.readat(nrec);
        return TRUE; 
      }
      else if (gruppocr != 0 && contocr != 0 && sottocontocr != 0l)
      {
        bool ok = errori_partita(gruppocr,contocr,sottocontocr);
        if (!ok) 
        { 
         rmoviva.readat(nrec);
         return TRUE;
        }
      }  
      if (tipodet != 0 && tipodet != 1 && tipodet != 3 && tipodet != 9)
      {  
       rmoviva.readat(nrec);
       return TRUE;
      }
    }    
    rmoviva.readat(nrec);    
  }
  return FALSE; 
}       

void TRic_ListaMov::stampa_errori_riva(int riga)
{
  TTable iva ("%IVA");
  
  iva.zero();
  iva.put("CODTAB", _codiva);
  if (iva.read() != NOERR)
    set_row(++riga, "@8g--- Codice IVA non valido o non presente in tabella");

  if (!(_tipocr >= 0 && _tipocr <= 9))
    set_row(++riga, "@8g--- Tipo costo/ricavo non valido");

  if (_gruppocr == 0 || _contocr == 0 || _sottocontocr == 0l)
    set_row(++riga, "@8g--- Sottoconto costo/ricavo non valido o non presente in archivio");
  else if (_gruppocr != 0 && _contocr != 0 && _sottocontocr != 0l)
  {
    bool ok = errori_partita(_gruppocr,_contocr,_sottocontocr);
    if (!ok) 
     set_row(++riga, "@8g--- Sottoconto costo/ricavo non valido o non presente in archivio");
  }  

  if (_tipod != 0 && _tipod != 1 && _tipod != 3 && _tipod != 9)
    set_row(++riga, "@8g--- Tipo indetraibilita' non valido");
} 

bool TRic_ListaMov::preprocess_page(int file,int counter)
{
  TCursor* cur = current_cursor();

  if (counter) return TRUE;
  
  reset_print();
  
  if (file == LF_MOV)
  {
    _anno     = cur->curr(LF_MOV).get_int(MOV_ANNOES);
    _datacomp = cur->curr(LF_MOV).get_date(MOV_DATACOMP);
    _datadoc  = cur->curr(LF_MOV).get_date(MOV_DATADOC);
    _data74tr = cur->curr(LF_MOV).get_date(MOV_DATA74TER);
    _causale  = cur->curr(LF_MOV).get(MOV_CODCAUS);
    _registro = cur->curr(LF_MOV).get(MOV_REG);  
    format_if_zero(_registro, 3);
    _tipodoc  = cur->curr(LF_MOV).get(MOV_TIPODOC);
    _numdoc   = cur->curr(LF_MOV).get(MOV_NUMDOC);
    _datareg  = cur->curr(LF_MOV).get_date(MOV_DATAREG);
    _codcf    = cur->curr(LF_MOV).get_long(MOV_CODCF);
    _numero   = cur->curr(LF_MOV).get_long(MOV_NUMREG);
    _protiva  = cur->curr(LF_MOV).get_long(MOV_PROTIVA);
    _codval   = cur->curr(LF_MOV).get(MOV_CODVALI);
    _codpag   = cur->curr(LF_MOV).get(MOV_CODPAG);
    
    _tot_dare = _tot_avere = ZERO;
    _tot_doc = ZERO;
    
    _ae = date2esc(_datareg);
    
    //_num_rec = cur->curr(LF_MOV).get_long(MOV_NUMGIO);
    
    bool controlla = controlla_mov(); //se TRUE => ci sono errori nella testata
    bool veriva    = controlla_riva();
    bool verrmov   = controlla_rmov();
    bool verifica  = (veriva || verrmov);
    
    if ( (_controllo == 1 && controlla) || _controllo == 2 ||
         (_controllo == 1 && verifica) ) 
    {
      TString16 datareg_str = _datareg.string();
      // "Fai vedere lo stesso ..-..-.... anche se non c'e' la data..."    
      if (datareg_str.empty())
        datareg_str = "  -  -    ";
      TString16 datadoc_str = _datadoc.string();
      if (datadoc_str.empty())
        datadoc_str = "  -  -    "; 
      int r = 1;
      set_row(r++, ""); 
      set_row(r,"Operazione n. %-7ld", _numero);
      set_row(r," del %s", (const char*)datareg_str);
      set_row(r," doc. n. %-7s", (const char*)_numdoc);
      set_row(r," del %s", (const char*)datadoc_str);
      if (!_registro.blank())  //e' una fattura
      {
       set_row(r," registro IVA %-3s", (const char*)_registro);
       set_row(r," protocollo n. %-5ld", _protiva);
      } 
      set_row(r, " comp. %d", _anno); 
     
      stampa_errori_mov(r);  
      
      return TRUE;
    }
    return FALSE;
  }   
  else if (file == LF_RMOV)
  {
    _gruppo = cur->curr(LF_RMOV).get_int(RMV_GRUPPO);
    _conto  = cur->curr(LF_RMOV).get_int(RMV_CONTO);
    _sottoconto = cur->curr(LF_RMOV).get_long(RMV_SOTTOCONTO); 
    _gruppoc = cur->curr(LF_RMOV).get_int(RMV_GRUPPOC);
    _contoc  = cur->curr(LF_RMOV).get_int(RMV_CONTOC);
    _sottocontoc = cur->curr(LF_RMOV).get_long(RMV_SOTTOCONTOC);     
    _importo = cur->curr(LF_RMOV).get_real(RMV_IMPORTO);
    _sezione = cur->curr(LF_RMOV).get(RMV_SEZIONE)[0];
    TString80 descr = cur->curr(LF_RMOV).get(RMV_DESCR);
    int numrig = cur->curr(LF_RMOV).get_int(RMV_NUMRIG); 
    
    _tipo_conto = "";
    
    if (_gruppo != 0 && _conto != 0 && _sottoconto != 0l)
      _esiste_conto = DescrConto(_gruppo,_conto,_sottoconto);
    else
    {
     _esiste_conto = FALSE;
     _descr_conto = "";
    } 

    int r = 1;          
    set_row(r, "P%d", numrig);
    set_row(r, "@5g%3s %-.20s @30g%-.24s @56g%03d %03d %06ld @71g%-.28s", (const char*) _causale, 
           (const char*) _descr_causale, (const char*) descr, _gruppo, _conto, _sottoconto, 
           (const char*) _descr_conto);
    if (_sezione == 'D')
      set_row(r, "@99g%r", &_importo);
    else if (_sezione == 'A')
           set_row(r, "@116g%r", &_importo);
         else set_row(r, "@107g%r", &_importo);

    stampa_errori_rmov(r);
  }
  else if (file == LF_RMOVIVA)
  {
    real impo = cur->curr(LF_RMOVIVA).get_real(RMI_IMPONIBILE);
    real impos = cur->curr(LF_RMOVIVA).get_real(RMI_IMPOSTA);
    int numrig = cur->curr(LF_RMOVIVA).get_int(RMI_NUMRIG); 
    _tipocr = cur->curr(LF_RMOVIVA).get_int(RMI_TIPOCR);
    _tipod  = cur->curr(LF_RMOVIVA).get_int(RMI_TIPODET);
    _codiva = cur->curr(LF_RMOVIVA).get(RMI_CODIVA);  
    //_n_rec  = cur->curr(LF_RMOVIVA).get_int(RMI_ANNOES); 
    _gruppocr = cur->curr(LF_RMOVIVA).get_int(RMI_GRUPPO); 
    _contocr  = cur->curr(LF_RMOVIVA).get_int(RMI_CONTO);
    _sottocontocr = cur->curr(LF_RMOVIVA).get_long(RMI_SOTTOCONTO);
    
    TString80 codiva_des(get_codiva_des(_codiva));
    
    //_tot_doc += impo + impos;
    
    _impo = impo;
    _impos = impos; 
     
    if (!_tipodoc.blank())
    {   
      TTable tabtpd("%TPD");
      tabtpd.put("CODTAB", _tipodoc);
      if (tabtpd.read() == NOERR) 
      {
        bool cor = tabtpd.get_bool("B0");
        if (cor)
        {
          _impo  = impo + impos;
          _impos = ZERO;
        }
      }
    }  

    int r = 1;          
    set_row(r, "I%d", numrig);
    set_row(r, "@5gImponibile@16g%r",&_impo);
    set_row(r, "@32gImposta@40g%r", &_impos);      
    set_row(r, "@56gCodice@63g%4s", (const char*) _codiva);
    set_row(r, "@68g%s", (const char*) codiva_des);
             
    if (_tipod != 0)
      set_row(r," %d", _tipod);
              
    stampa_errori_riva(r);        
  }
  return TRUE;
}

print_action TRic_ListaMov::postprocess_page(int file,int count)
{
  if (count) return NEXT_PAGE;
  if (file == LF_MOV)
  {       
   // aggiorna_trasfer_Z();
    reset_print();
    _err.reset();
    int n = 1;
    if (_tot_dare != _tot_avere)
    {
       _errore_grave = TRUE;
       set_row(n++, "@8g*** Il movimento risulta sbilanciato. Totali rilevati:@99g%r@116g%r",
               &_tot_dare, &_tot_avere);
       return REPEAT_PAGE;           
    }   
  }
  /*
  if (file == LF_RMOVIVA)
     aggiorna_trasfer_U();
  */   
  return NEXT_PAGE;
}       

void TRic_ListaMov::postclose_print()
{ 
  if (_errore_grave)
     message_box("Rilevati errori gravi durante il controllo movimenti: \n trasferimento interrotto");
  else 
  {
   TConfig conf (CONFIG_DITTA);
   conf.set("FlStTra", "M"); 
   
   TTransfer_file& tr = trasfer();
   _record.overwrite("Z",240);  //_record e' letto nella read_control_rec()
   const int size = 256;
   tr.write_control_rec(_record, size);    
  }
}

void TRic_ListaMov::aggiorna_trasfer_Z()
{
  TLocalisamfile& mov = current_cursor()->file(LF_MOV); 
  
  int i=0;
  while (_registro[i]=='0' || _registro[i]==' ') i++;
  
  TString16 registro = "";  
  registro << _registro[i]; 
  registro.left_just(3, ' ');

  mov.put(MOV_REG, registro);
  mov.put(MOV_TIPODOC, _tipodoc);
  mov.rewrite();
  
  TString16 str;
  TTransfer_file& tr = trasfer();
  long num = _inizioZ + _num_rec;
  if (tr.read_rec_trasfer(num) > 0)
  {
   tr.put(_tipodoc, "Z1", 12); 
   if (_tiporeg != 0)
   { 
     str = format("%d", _tiporeg);
     tr.put(str, "Z1", 26);
   }                                           
   TString totdocstr = _tot_doc.string();
   str = format("%011s", (const char*) _tot_doc.string());
   tr.put(str, "Z1", 13);
   tr.put(_tipo_conto, "Z1", 11);   
   tr.write(num);
  }
}

void TRic_ListaMov::aggiorna_trasfer_U()
{
  TTransfer_file& tr = trasfer();
  long num = _inizioU + _n_rec;
  if (tr.read_rec_trasfer(num) > 0)
  {   
   TString str = format("%011s", (const char*)_impo.string());
   tr.put(str, "U1", 14);
   str = format("%09s", (const char*)_impos.string());
   tr.put(str, "U1", 15);
   tr.write(num);
  } 
}

bool TRic_ListaMov::user_destroy()
{
  delete _giornale;
  delete _trasfer;
  delete _rel;
  delete _cur;
  delete _tmov;
  delete _trmov;
  delete _tiva;
  delete _caus;
  delete _ditte; 
  delete _clifo; 
  delete _pcon;    
  delete _mov;
  delete _rmov;
  delete _rmoviva;
  delete _tab_tra;
  delete _tab_pag;
  delete _tab_tpd;
  delete _tab_iva;
  delete _tab_ese;
  
  return TRUE;
}                                

bool TRic_ListaMov::set_print(int m)
{
  TMask msk ("cg2700a");
  
  TTransfer_file& tr = trasfer();
  
  msk.set(F_NUMERO, tr.nultras());
  msk.set(F_DATALIMITE, tr.dataultras());
  msk.set(F_SDT, look_sdt());
  msk.set(F_SIGLA, tr.ult_file());
  msk.set(F_CHIAVE, tr.key());
  
  if (msk.run() != K_ENTER) return FALSE;
  
  _controllo = msk.get_int(F_LISTA);
  
  if (_sdt == '*')
    fremove(_pathfile);
  
  setta_parametri(" ", "C"); 
  
  set_real_picture("###.###.###.###");
  
  printer().footerlen(5);
  
  setta_intestazione();
  
  _errore_grave = FALSE;
  _err.reset();
  _inizioZ = tr.start('Z');
  _inizioU = tr.start('U');
  
  return TRUE;
}

void TRic_ListaMov::setta_intestazione()
{
  int soh = 1;       
  TString sep(132);
  TString ragsoc(50);
 
  TLocalisamfile nditte(LF_NDITTE); 
  nditte.zero();
  nditte.put(NDT_CODDITTA, get_firm());   
  if (nditte.read() == NOERR) 
    ragsoc = nditte.get(NDT_RAGSOC);
  
  reset_header();

  sep << "Ditta  " << get_firm();
  sep << " " << ragsoc;
  sep.left_just(132);
  
  set_header (soh++, (const char*) sep);
  
  sep = "";
  sep << "Data @< Pag. @#";
  
  sep.right_just(127);
  
  sep.overwrite ("LISTA DI CONTROLLO MOVIMENTI IN TRASFERIMENTO");
  set_header (soh++, (const char*)sep);
  sep.fill('-');
  set_header (soh++, (const char *) sep);
  set_header (soh++, "Rig  Cod.causale  @30gDescriz.aggiuntiva  @56gCod.conto  @71gDescriz.conto  @99gDare  @116gAvere");
  set_header (soh, (const char *) sep);
}

void TRic_ListaMov::setta_parametri(const TString& sigla, const TString& flag)
{ 
  TTransfer_file& tr = trasfer();
  
  TConfig conf (CONFIG_DITTA);
  conf.set("FlStTra", flag);
  
  TString rec = tr.record();
  rec.overwrite(sigla,240);
    
  const int size = 256;
  tr.write_control_rec(rec, size);
}

int cg2700 (int argc, char* argv[])
{                                
  TRic_ListaMov a;
  a.run(argc, argv,"Lista controllo movimenti");
  return TRUE;
}