// Invio contabilita'

#include <execp.h>
#include <mailbox.h>
#include <prefix.h>
#include <tabutil.h>

#include "cg6900.h"
#include "cg6900a.h"

#include "cg6901.h"
#include "cg6903.h"
#include "cg6905.h"

#include <nditte.h>

TInv_cont::TInv_cont(char mov) : _scelta(toupper(mov))
{
  switch (_scelta)
  {       
  case 'S': _titolo = TR("Invio a Sistema"); break;
  case 'P': _titolo = TR("Invio a PC"); break;    
  default : break;
  }
}
                                   
bool TInv_cont::messaggio_hnd(TMask_field& f, KEY k)
{
  if (k == K_TAB)
    return message_box("Rilevato STATO DI RIPARTENZA: il trasferimento ripartira' automaticamente");
  
  return TRUE;
}
                                   
void TInv_cont::main_loop()
{                     
  bool ripartenza = false;
  
  if (!esiste_tabella_studio()) 
    return;
  
  if (!esegui_controlli()) 
    return;
  
  TMask* msk = new TMask("cg6900a");
  
  if (_ditta != 0)       
  {
    msk->set(F_DITTAINV, _ditta);
    msk->disable(F_DITTAINV);
    codifica_ditta(*msk);
    msk->set(F_NUMULINV, _num);
    msk->set(F_DATAULIN, _data.string());
    msk->set(F_STATO,    _stato);
    
    TString uselab = _tras_file.ult_file();
    TString chiave = _tras_file.key();
    msk->set(F_USELAB,  uselab);
    msk->set(F_CHIAVE,  chiave);
    msk->set(F_DATALIM, _data.string());
    msk->disable(F_DATALIM);
    
    if (_scelta == 'S' && _ditta > 9999)
    {
      msk->show(F_DITTAAS); 
      msk->disable(F_DITTAAS);
      long ditta = atol(_control_rec.sub(300,304));
      msk->set(F_DITTAAS, ditta);
    }                            
    else
      msk->hide(F_DITTAAS);
    
    ripartenza = TRUE;
  }
  
  msk->disable(F_NUMULINV);
  msk->disable(F_DATAULIN);
  msk->disable(F_STATO);
  msk->disable(F_USELAB);
  msk->disable(F_CHIAVE);

  if (!ripartenza)
    msk->set_handler(F_DITTAINV, setta_maschera_hnd);
  else
    msk->set_handler(F_NUMULINV, messaggio_hnd);  
  
  const KEY tasto = msk->run();
  if (tasto != K_ENTER)
  {
    delete msk;
    return;
  }
  
  _dittaAS = msk->get_long(F_DITTAAS);//Se la ditta per l'invio ad AS non viene compilata perche' trattasi di invio a PC
  if (_dittaAS == 0)                  //o perche' il codice e' di 4, gli assegno la ditta corrente. Nel caso di invio a
    _dittaAS = _ditta;                //PC non servirebbe il codice aggiuntivo, ma lo metto ugualmente per avere una situazione analoga
              
// Nel caso di invio PC --> SISTEMA eseguo prima la
// Lista controllo archivi per rilevare eventuali
// differenze.
  
  long ditta = msk->get_long(F_DITTAINV);
  set_firm(ditta);

  TConfig conf(CONFIG_DITTA, "cg");           
  const TString& std = conf.get("FlStInv");
  
  if (_scelta == 'S' && std != "D")
  {  
     const char* const appname = "cg6 -8 L";
     TString corpo   = "";
     
     TDate data = msk->get(F_DATALIM);
     
     corpo << data.string();
  
     TMessage mess (appname,"",(const char*)corpo);
     TMailbox mb;
     mb.send(mess);
     
     TExternal_app a (appname);
     a.run();
     
     TMailbox m;
     TMessage* msg = m.next_s("");
     int subj;
     
     if (msg != NULL)
     {
       subj = atoi(msg->body());
       if (subj)
       {
         delete msk;
         return;
       }
     }
  }  
  
  _datalimsk = msk->get(F_DATALIM);
  
  if (!ripartenza)
  {                            
    crea_marker(*msk);                 //Crea il record con le informazioni sul marker                 
    setta_parametri_record("F");       //Aggiorna parametri contabili ditta           
    setta_tabella_studio(*msk);        //Aggiorna la tabella studio per invio
    setta_tabella_ditta(*msk,"F");     //Aggiorna la tabella ditta per invio
    crea_record_controllo(*msk);       //Crea il record di controllo sul file header
  }                
  else
  { 
    TString str,app;
    
    int num = msk->get_int(F_NUMULINV);
    TString data (msk->get(F_DATALIM));
    if (_scelta == 'S')
    {
      app = riconverti_data(data,FALSE);
      str.format("%03d%6s", num, (const char*) app);
      aggiorna_marker(str,14);
    }
    else
      if (_scelta == 'P')
      {
        app = riconverti_data(data,TRUE);
        str.format("%03d%8s", num, (const char*) app);
        aggiorna_marker(str,15);      
      }
  }

  apri_file_temp();
    
  if (!invio_tempfile(*msk))
  {
    delete msk;
    return;
  }
  
//  calcola_totale_record();
//  str.format("%06ld", _tot_rec);

  if (_scelta == 'S')
  {                             
//    aggiorna_marker(str,23);  
    
    _trasf = firm2dir(0);
    _trasf.add("trasfer"); 
    ::remove(_trasf);
    _tras_file.open(_trasf,TRUE);
                            
//    if (std != "D")
      invio_contabilita();              //Costruisce il trasfer nella directory comune
    
    TMask* mask = new TMask("cg6900b");
    KEY k;
    TFilename floppy,percorso;
    int     num_disk;
    
    bool ok        = FALSE;
    bool abbandona = FALSE;
    do
    {
      k = mask->run();
      
      if (k != K_ENTER) 
      {
        abbandona = TRUE;
        break;
      }
      floppy   = mask->get(F_FLOPPY); 
			floppy << ':';
      num_disk = calcola_numero_dischi(*mask,floppy);
      percorso = mask->get(F_PATH);     
      if (percorso.not_empty())  
      {
        floppy.add(percorso);
        if (floppy.exist()) 
          ok = TRUE;
        else
          error_box("Il percorso indicato non e' corretto");  
      }
      else
        ok = TRUE;  // Se scelgo il dischetto non eseguo il controllo sulla correttezza del path
    }
    while (!ok);
      
    if (!abbandona)
    {  
      TString4 str;
      str.format("%02d", num_disk);
      aggiorna_marker(str,29);

      const TFilename from(_trasf);          // File da splittare

      TFilename work = floppy;
			work.add(from.name());
    
      FILE* i = fopen(from, "rb");                                             
    
      if (i == NULL) 
      {
        error_box("Impossibile aprire il file '%s'", from);
        return;
      }
      
      const char* message = TR("Trasferimento in corso... Prego attendere");
        
      TProgind w(_dim_tot, message, true, true);
      
      bool continua = TRUE;
      for (int j = 0; j < num_disk; j++)
      {
        continua = scrivi_disco(floppy,j+1,work,i,w);
      }
      fclose(i);
      
      if (!continua) 
        return;  // Nel caso in cui l'utente decida di annullare l'operazione
      
      setta_tabella_studio(*msk,FALSE);    //Aggiorna la tabella studio per invio
      setta_tabella_ditta(*msk," ",FALSE); //Aggiorna la tabella ditta per invio
      setta_parametri_record(" ");         //Aggiorna parametri contabili ditta           
    
      _tras_file.open(_header);
      leggi_record_controllo();
      TString record(1024);  
      record.spaces();
      _control_rec.overwrite(record,0);
      _tras_file.write_control_rec(_control_rec,1024);

      chiudi_file_temp();      
    }                
    else
    {
      delete msk;
      delete mask;
      return;
    }
    delete mask;
  }
  else
    if (_scelta == 'P')
    {
      _trasf = firm2dir(0);
      _trasf.add("trasfer");
      ::remove(_trasf);
      _tras_file.open(_trasf,TRUE);
                            
      invio_contabilita_PC(); //Costruisce il trasfer nella directory comune
      chiudi_file_temp();
    
      TMask* mask = new TMask("cg6900b");
      KEY k;
      TFilename floppy,percorso;
      int     num_disk;

      bool ok        = FALSE; 
      bool abbandona = FALSE;
      do
      {
        k = mask->run();
      
        if (k != K_ENTER)
        {      
          abbandona = TRUE;
          break;
        }        
        floppy   = mask->get(F_FLOPPY);
        floppy << ':';
        num_disk = calcola_numero_dischi(*mask,floppy);   
        percorso = mask->get(F_PATH);   
        if (percorso.not_empty())  
        {
          floppy << SLASH << percorso;  
          if (floppy.exist()) 
            ok = TRUE;
          else
            error_box("Il percorso indicato non e' corretto");  
        }
        else
          ok = TRUE;  // Se scelgo il dischetto non eseguo il controllo sulla correttezza del path
      }
      while (!ok);

      if (!abbandona)
      {  
        TString4 str; str.format("%02d", num_disk);
        aggiorna_marker(str, 32);

        const TFilename from(_trasf); // File da splittare

        TFilename work = floppy;   
        work.add(from.name());        // File su dischetto
    
        FILE* i = fopen(from, "rb");                                             
    
        if (i == NULL) 
        {
          error_box("Impossibile aprire il file '%s'", from);
          return;
        }
        const char* message= "Trasferimento in corso... Prego attendere";
    
        TProgind w(_dim_tot, message, true, true);
        
        bool continua = TRUE;
        for (int j = 0; j < num_disk && continua; j++)
        {
          continua = scrivi_disco(floppy,j+1,work,i,w);
        }
        fclose(i);
        
        if (!continua) 
          return;    // Nel caso in cui l'utente decida di annullare l'operazione
        
        setta_tabella_studio(*msk,FALSE);    //Aggiorna la tabella studio per invio
        setta_tabella_ditta(*msk," ",FALSE); //Aggiorna la tabella ditta per invio
        setta_parametri_record(" ");         //Aggiorna parametri contabili ditta           
    
        _tras_file.open(_header);
        leggi_record_controllo();
        TString record(1024);  
        record.spaces();
        _control_rec.overwrite(record,0);
        _tras_file.write_control_rec(_control_rec,1024);

//        chiudi_file_temp();      
      }                
      else
      {
        delete msk;
        delete mask;
        return;
      }
      delete mask;
    }
                       
  _tras_file.remove_all(FALSE);                        
  ::remove(_marker);
  _trasf = ""; 
  _trasf = firm2dir(0);
  _trasf << "\\trasfer";  
  ::remove(_trasf);
  
  delete msk;
}

bool TInv_cont::create()
{
  _caus     = new TLocalisamfile (LF_CAUSALI);
  _rcaus    = new TLocalisamfile (LF_RCAUSALI);
  _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);       
  _occas    = new TLocalisamfile (LF_OCCAS);
  _part     = new TLocalisamfile (LF_PARTITE);
  _scad     = new TLocalisamfile (LF_SCADENZE);
  _pagsca   = new TLocalisamfile (LF_PAGSCA);       

  return TSkeleton_application::create();
}

bool TInv_cont::destroy()
{                                           
  delete _caus;
  delete _rcaus;
  delete _clifo;
  delete _pcon;
  delete _mov;
  delete _rmov;
  delete _rmoviva;
  delete _occas;  
  delete _part;
  delete _scad;
  delete _pagsca;

  return TApplication::destroy();
}                                

void TInv_cont::apri_file_temp()
{ 
  _tras_file.open(_header);
  leggi_record_controllo();
  _sigle = _tras_file.sigle_file();
  _sigle.trim();
  
  for (int i = 0; i < _sigle.len(); i++)
  {                       
    TFilename tmp;
    char sigla = _sigle[i];
    
    if (sigla == 'W')
    {
      TFilename tmpcaus = "%";
      tmpcaus << firm2dir(0);
      tmpcaus << "\\" << TEMP_CAUS;          
      tmp = tmpcaus.mid(1);
      tmp << ".dbf";
      _tcaus    = new TIsamtempfile(LF_CAUSALI, tmpcaus, !tmp.exist());  
      TFilename tmprcaus = "%";
      tmprcaus << firm2dir(0);
      tmprcaus << "\\" << TEMP_RCAUS;
      tmp = tmprcaus.mid(1);
      tmp << ".dbf";
      _trcaus   = new TIsamtempfile(LF_RCAUSALI, tmprcaus, !tmp.exist());
    }
    if (sigla == 'A')
    {
      TFilename tmpclifo = "%";
      tmpclifo << firm2dir(0);
      tmpclifo << "\\" << TEMP_CLIFO;
      tmp = tmpclifo.mid(1);
      tmp << ".dbf";
      _tclifo    = new TIsamtempfile(LF_CLIFO, tmpclifo, !tmp.exist());
    }
    if (sigla == 'P')
    {
      TFilename tmppcon = "%";
      tmppcon << firm2dir(0);
      tmppcon << "\\" << TEMP_PCON;
      tmp = tmppcon.mid(1);
      tmp << ".dbf";
      _tpcon    = new TIsamtempfile(LF_PCON, tmppcon, !tmp.exist());
    }
    if (sigla == 'Z')
    {
      TFilename tmpmov = "%";
      tmpmov << firm2dir(0);
      tmpmov << "\\" << TEMP_MOV;
      tmp = tmpmov.mid(1);
      tmp << ".dbf";
      _tmov     = new TIsamtempfile(LF_MOV, tmpmov, !tmp.exist());
      TFilename tmprmov = "%";
      tmprmov << firm2dir(0);
      tmprmov << "\\" << TEMP_RMOV;
      tmp = tmprmov.mid(1);
      tmp << ".dbf"; 
      _trmov    = new TIsamtempfile(LF_RMOV, tmprmov, !tmp.exist());
      TFilename tmpoccas = "%";
      tmpoccas << firm2dir(0);
      tmpoccas << "\\" << TEMP_OCC;
      tmp = tmpoccas.mid(1);
      tmp << ".dbf";
      _toccas   = new TIsamtempfile(LF_OCCAS, tmpoccas, !tmp.exist());
    }
    if (sigla == 'U')
    {
      TFilename tmpriva = "%";
      tmpriva << firm2dir(0);
      tmpriva << "\\" << TEMP_RMOVIVA;
      tmp = tmpriva.mid(1);
      tmp << ".dbf";
      _triva    = new TIsamtempfile(LF_RMOVIVA, tmpriva, !tmp.exist());
    }
    if (sigla == 'B')
    {
      TFilename tmppart = "%";
      tmppart << firm2dir(0);
      tmppart << "\\" << TEMP_PART;
      tmp = tmppart.mid(1);
      tmp << ".dbf";
      _tpart    = new TIsamtempfile(LF_PARTITE, tmppart, !tmp.exist());
      TFilename tmpscad = "%";
      tmpscad << firm2dir(0);
      tmpscad << "\\" << TEMP_SCAD;
      tmp = tmpscad.mid(1);
      tmp << ".dbf"; 
      _tscad    = new TIsamtempfile(LF_SCADENZE, tmpscad, !tmp.exist());
      TFilename tmppagsca = "%";
      tmppagsca << firm2dir(0);
      tmppagsca << "\\" << TEMP_PAGSCA;
      tmp = tmppagsca.mid(1);
      tmp << ".dbf";
      _tpagsca  = new TIsamtempfile(LF_PAGSCA, tmppagsca, !tmp.exist());
    }    
  }
}

void TInv_cont::chiudi_file_temp()
{
  for (int i = 0; i < _sigle.len(); i++)
  {
    char sigla = _sigle[i];

    if (sigla == 'W')
    {
      delete _tcaus;
      delete _trcaus;
    }
    if (sigla == 'A')
      delete _tclifo;
    if (sigla == 'P')
      delete _tpcon;
    if (sigla == 'Z')
    {
      delete _tmov;
      delete _trmov;
    }
    if (sigla == 'U')
    {
      delete _triva;
      delete _toccas;
    }
    if (sigla == 'B')
    {
      delete _tpart;
      delete _tscad;
      delete _tpagsca;
    }    
  }
}

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

bool TInv_cont::esiste_tabella_studio()
{
  TTable ins("%INS");
  if (ins.first() == NOERR)
  {
    _nome_simbolico = ins.get("S0");
    _ditta = ins.get_long("I0");
    _esiste_ditta = _ditta != 0L;
  }
  else
    return error_box("Codice STUDIO NON ATTIVATO in tabella invii");  
  
  return true;  
}  


bool TInv_cont::leggi_header()
{ 
  _header = firm2dir(0);
  _header.add(HEADER);
  
  _tras_file.open(_header);
  
  if (_tras_file.exist())           
  {  
    if (_tras_file.read_control_rec())
    {
      _control_rec = _tras_file.record();
      if (!record_controllo())
        return FALSE;
    }
    else
      return FALSE;
  } 
  else
    return FALSE;
  
  return TRUE; 
}

bool TInv_cont::record_controllo() const
{
/*
  TString tiporecord = _control_rec.sub(0,2);
  if (tiporecord != " 1")
    return FALSE;
  return TRUE;
*/
  const TString& tiporecord = _control_rec.sub(0,2);
  return atoi(tiporecord) == 1;
}

bool TInv_cont::esegui_controlli()
{  
  _esiste_record = leggi_header();
  return controlli();
}

void TInv_cont::setta_parametri_record(const TString& flag) const
{  
  ini_set_string(CONFIG_DITTA, "cg", "FlStInv", flag);
}

bool TInv_cont::controlli()
{ 
  if (_esiste_ditta && !_esiste_record)
    return error_box(FR("Rilevato stato di ripartenza con dati contradditori:\n"
                        "Ditta %ld in tabella studio per invio senza record."), _ditta);
  
  if (!_esiste_ditta && _esiste_record)
  {
    return error_box("Rilevato stato di ripartenza con dati contradditori:\n"
                     "esiste un record senza nessuna ditta in %%INS.");
  }
  
  if (_esiste_ditta && _esiste_record)
  {
    if (!sub_controlli())
      return error_box(FR("Rilevato stato di ripartenza con dati contradditori:\n"
                        "Ditta %ld in tabella studio per invio con record errato."), _ditta);
  }
  
  return true; //Mi trovo in una condizione normale
}   

bool TInv_cont::sub_controlli()
{
  const long ditta_trasfer = _tras_file.ditta();
  
  if (_ditta == ditta_trasfer)
  {
    if (!prefix().exist(_ditta))
      return FALSE;
    
    if (!tabella_ditta())
      return FALSE;
  }          
  else
    return FALSE;

  if (!controlla_stato_invio())  
    return FALSE;
  
  if (!numero_data())
    return FALSE;    
  
  return TRUE;  
}

bool TInv_cont::tabella_ditta()
{
  TTable ind ("%IND");
  TString dep;
  
  dep.format("%05ld", _ditta);
  
  ind.zero();
  ind.put("CODTAB", dep);
  if (ind.read() == NOERR) 
  {
    _stato = ind.get("S6");
    _num   = ind.get_int("I0");
    _data  = ind.get_date("D0");
    
    _files = "";
    
    // Si mette prima l'invio del piano dei conti, e poi delle anagrafiche in modo che eventuali ricezioni
    // possano aggiornare correttamente il tipoconto memorizzato nelle causali
    if (ind.get_bool("B2") && (_pcon->items() != 0) )
      _files << "P";        
    
    if (ind.get_bool("B1") && (_clifo->items() != 0) )
      _files << "A";
    
    if (ind.get_bool("B0") && (_caus->items() != 0) )
      _files << "W";
    
    if (ind.get_bool("B3") && (_mov->items() != 0) )
      _files << "Z";
    
    if (ind.get_bool("B4") && (_rmoviva->items() != 0) )
      _files << "U";
    
    if (ind.get_bool("B5") && (_part->items() != 0) )
      _files << "B";
      
    _flag_provvis = ind.get_bool("B6");  
      
    _flag_bollato = ind.get_bool("B7");

    // Compila l'array contenente le causali di corrispondenza per l'invio extracontabile      
    dep = "";
    TString s5(ind.get("S5"));
    _tab_cau.destroy();
    _tab_cau.add(s5.mid(0,3)); 
    _tab_cau.add(s5.mid(3,3));
    _tab_cau.add(s5.mid(6,3));
    _tab_cau.add(dep); // corrisponde al tipo dell'abbuono.
    _tab_cau.add(s5.mid(9,3));
    _tab_cau.add(s5.mid(12,3));
    _cpg_nc = ind.get("S7"); // condizione pagamento (rimessa diretta) per le note di credito
    
    return TRUE;
  }  
  
  return FALSE;  
}

bool TInv_cont::controlla_stato_invio()
{ 
  set_firm(_ditta);
  
  TConfig conf(CONFIG_DITTA, "cg");           
  _std = conf.get("FlStInv");
  
  if (_stato != _std)
    return FALSE;
  else
  {                  
    TString uselab = _tras_file.ult_file();
    
    if (_stato == "D" && uselab != "")
      return FALSE;
  }                
  
  return TRUE;
}

bool TInv_cont::numero_data()
{                                        
  int num = _tras_file.nultras();
  TString str = _tras_file.dataultras();
  TDate data (str);
  
  if (_num != num || data != _data)
    return FALSE;
  
  return TRUE;
}

void TInv_cont::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)
  {
    const TString& ragsoc = ditte.get(NDT_RAGSOC);
    m.set(F_RAGSOC, ragsoc);
  }
}

bool TInv_cont::setta_maschera_hnd(TMask_field& f, KEY k)
{
  if ( (k == K_TAB || k == K_ENTER) && f.mask().is_running())
  {    
    long& d = app()._ditta;
    d = f.mask().get_long(F_DITTAINV);
    if (d == 0L) return TRUE;
    if (!prefix().exist(d))
      return error_box("La ditta indicata non e' abilitata alla contabilita'");

    if (!app().tabella_ditta())
      return error_box("La ditta indicata non e' presente sulla tabella ditta per invio");
   
    if (app()._stato != "")
      return error_box("Rilevato STATO DI RIPARTENZA NON RECUPERABILE sulla ditta richiesta");
    
    f.mask().set(F_DITTAINV, d);
    app().codifica_ditta(f.mask());
    f.mask().set(F_NUMULINV, app()._num);
    f.mask().set(F_DATAULIN, app()._data.string());
    f.mask().set(F_STATO,    app()._stato);
                                     
    long ditta = atol(f.get());
    
    if (app()._scelta == 'S' && ditta > 9999)
      f.mask().show(F_DITTAAS);            
    else
      f.mask().hide(F_DITTAAS);
  }
  
  return TRUE;
}

void TInv_cont::crea_marker(TMask& m)
{
  _marker = firm2dir(0);
  _marker.add("marker");
  
  const word size = 64;
  TString buffer(size); 
  buffer.spaces();
  
  FILE* i = fopen(_marker,"w+t");
  if (i != NULL)
  { 
    TString str;

    if (_scelta == 'S')
    {
      str.format("%-10s", (const char*)_nome_simbolico);
      buffer.overwrite(str,0);
      long ditta = m.get_long(F_DITTAINV); 
      if (ditta > 9999)
        ditta = _dittaAS;
      str.format("%04d", ditta);
      buffer.overwrite(str,10);
      int num = m.get_int(F_NUMULINV);
      num++;
      if (num >= 1000)
        num = 1;
      str.format("%03d", num);
      buffer.overwrite(str,14);
      TString16 data = m.get(F_DATALIM);
      str = riconverti_data(data, false);
      buffer.overwrite(str,17);               
    }
    else
      if (_scelta == 'P')
      {
        str.format("%-10s", (const char*) _nome_simbolico);
        buffer.overwrite(str,0);
        long ditta = m.get_long(F_DITTAINV);
        str.format("%05ld", ditta);
        buffer.overwrite(str,10);
        int num = m.get_int(F_NUMULINV);
        num++;
        if (num >= 1000)
          num = 1;
        str.format("%03d", num);
        buffer.overwrite(str,15);
        TString data (m.get(F_DATALIM));
        str = riconverti_data(data,TRUE);
        buffer.overwrite(str,18);      
      }
      
    buffer.cut(64); //Sicurezza: le stringhe dimensionate in realta' sono
                    //leggermente piu' lunghe della dimensione specificata
    const word scritti = fwrite(buffer,1,size,i);
    
    fclose(i);
  }    
}

void TInv_cont::aggiorna_marker(const TString& token, int pos)
{   
  _marker = firm2dir(0);
  _marker.add("marker");
  
  const int size = 64;
  TString buffer(size); 
  
  FILE* i = fopen(_marker,"r+t");
  if (i != NULL)
  { 
    const word letti = fread(buffer.get_buffer(),1,size,i);
    buffer.overwrite(token,pos);

    buffer.cut(size); //Sicurezza: le stringhe dimensionate in realta' sono
                      //leggermente piu' lunghe della dimensione specificata    
    fseek(i, 0L, SEEK_SET);
    const word scritti = fwrite(buffer,1,size,i);
    
    fclose(i);
  }    
}

void TInv_cont::calcola_totale_record()
{
  _tras_file.open(_header);
  leggi_record_controllo();
  
  TString sigle = _tras_file.sigle_file();
  sigle.trim();
  
  _tot_rec = 0;
  
  for (int i = 0; i < sigle.len(); i++)
  {
    long tot_rec = atol(_control_rec.mid((i * 6) + 95,6));
    _tot_rec += tot_rec;
  }             
  _tot_rec += 1;
}

void TInv_cont::setta_tabella_studio(TMask& m,bool flag_ditta)
{
  TTable ins ("%INS");
  TString dep;
  long ditta;
  
  if (flag_ditta)
    ditta = m.get_long(F_DITTAINV);
  else
    ditta = 0;
  
  dep.format("%-3s", (const char*) "INS");
  
  ins.zero();
  ins.put("CODTAB", dep);
  if (ins.read() == NOERR)
  {
    ins.put("I0", ditta);
    ins.rewrite();
  }
  else
    warning_box("Tabella studio per invio NON AGGIORNATA");
}

void TInv_cont::setta_tabella_ditta(TMask& m,const char* flag, bool comp)
{
  TTable ind ("%IND");
  
  TString8 dep;
  const long ditta = m.get_long(F_DITTAINV);
  dep.format("%05ld", ditta);
  ind.put("CODTAB", dep);
  
  if (ind.read() == NOERR) 
  {                    
    ind.put("S6", flag);                                
    if (comp)
    {
      const long num = m.get_int(F_NUMULINV)+1;
      const TDate data (m.get(F_DATALIM)); 
      ind.put("I0", num);
      ind.put("D0", data);
    }
    ind.rewrite();
  }  
  else
    warning_box("Tabella ditta per invio NON AGGIORNATA");  
}

void TInv_cont::crea_record_controllo(TMask& m)
{            
  int size = 1024;
  TString buffer(size);
  TString str;
  
  if (_tras_file.exist())
    _tras_file.open(_header);
  else 
  {
    _tras_file.open(_header, true);   //Metto il parametro TRUE (che di default e' FALSE), perche' voglio creare un file che non e' ancore esistente
    
    buffer.spaces();   
    buffer.overwrite(" 1",0);                             //Tipo record
    
    str.format("%-10s", (const char*) _nome_simbolico);
    buffer.overwrite(str,60);                             //Nome studio
    
    long ditta = m.get_long(F_DITTAINV);
    str.format("%05ld", ditta);
    buffer.overwrite(str,70);                             //Ditta inviante
    
    int num = m.get_int(F_NUMULINV);
    num++; 
    if (num >= 1000)
      num = 1;
    str.format("%03d", num);
    buffer.overwrite(str,75); // Numero progr. invio
    
    TString16 data (m.get(F_DATALIM));
    str = riconverti_data(data, true);
    buffer.overwrite(str,78); // Data limite invio
    
    str.format("%-9s", (const char*)_files);
    buffer.overwrite(str,86);
    
    str = _files.sub(0,1);
    buffer.overwrite(str,240); 
    
    str.format("%054d", 0);
    buffer.overwrite(str,95); 
    
    if (_scelta == 'S')
      str.format("%04ld", _dittaAS);
    else
      str.format("%05ld", _dittaAS);
    buffer.overwrite(str, 301);    
    
    if (!_tras_file.write_control_rec(buffer, size))   
      warning_box("Il record di controllo del file trasfer non e' stato aggiornato correttamente");
  }  
  _tras_file.close();  
} 

void TInv_cont::cerca_provincia(const TString& comcf, TString& provincia) const
{
  TString8 k; k << " |" << comcf;
  provincia = cache().get(LF_COMUNI, k, COM_PROVCOM);
}

bool TInv_cont::invio_tempfile(TMask& m)
{
  char    uselab;
  TString record(256),key,nrec;
  int     posiz,i;
  char    sigla;               

  _tras_file.open(_header);
  
  leggi_record_controllo();
  
  uselab = (_tras_file.ult_file())[0];
  
  if (uselab == '\0')            //Significa che sono in caso di ripartenza ma ho
    return TRUE;                //gia' trasferito tutti gli archivi e devo solo fare la copia su dischi
  
  posiz  = _files.find(uselab); //Ritorna la posizione della sigla all'interno della schiera
  key    = _tras_file.key(); 
  key.trim();                 
  nrec   = _tras_file.nrec_file();
  
  for (i = posiz; i < _files.len();i++)
  {                 
    sigla    = _files[i];
    _numrec  = atol(nrec.mid(i * 6,6));
    switch (sigla)        
    {
    case 'W': causali2tempfile(key,m); break; 
    case 'A': clifo2tempfile(key,m);   break;      
    case 'P': pcon2tempfile(key,m);    break;      
    case 'Z': movPN2tempfile(key,m);   break;      
    case 'U': movIVA2tempfile(key,m);  break;      
    case 'B': movSC2tempfile(key,m);   break;
    default : break;
    }
    key = "";
  }                    

  // Finito di trasferire tutti gli archivi pulisco la sigla ultimo file da elaborare  
  _tras_file.open(_header);
  leggi_record_controllo();
  _control_rec.overwrite(" ",240);
  _tras_file.write_control_rec(_control_rec,1024);
  _tras_file.close();

  setta_tabella_ditta(m,"D",FALSE);
  setta_parametri_record("D");  
  
  return TRUE;
}                         

void TInv_cont::causali2tempfile(TString& key, TMask& m)
{
  int size = 1024;

  _tras_file.open(_header);
                                         
  long items = _caus->items();
  _prog = new TProgind(items, TR("Invio tabella causali in corso"), false);
  
  _caus->setkey(1);
                    
  if (key.empty())
    _caus->first();
  else
  {             
    const TString& causale = key.mid(0,3);
    _caus->zero();
    _caus->put(CAU_CODCAUS, causale);
    _caus->read();
  }
  
  for(; !_caus->eof(); _caus->next())
  { 
    _prog->addstatus(1);
                               
    const TString4 codcaus = _caus->get(CAU_CODCAUS);
    
    _tcaus->curr() = _caus->curr(); 
    
    if (_tcaus->read() == NOERR)  // Esiste la testata
    {
      scrivi_righe_causali(codcaus,'W');
            
      _tcaus->zero();
      _tcaus->curr() = _caus->curr();
      _tcaus->rewrite();
    }  
    else
    {
      scrivi_righe_causali(codcaus,'W');
            
      _tcaus->zero();
      _tcaus->curr() = _caus->curr();
      _tcaus->write();
    }
          
    leggi_record_controllo();
    TString4 chiave;
    chiave.format("%3s",(const char*) codcaus);      
    _control_rec.overwrite("W",240);
    _control_rec.overwrite(chiave,241);

    _tras_file.write_control_rec(_control_rec,size);
  }
  delete _prog;
  
  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.

  leggi_record_controllo();
  TString chiave,app,sigla;
  app.format("%-60s", (const char*) chiave);
  char sigla_p = _tras_file.ult_file()[0];
  int posiz    = _files.find(sigla_p);
  TString nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  _control_rec.overwrite(app,241);
  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();
  
//  setta_tabella_ditta(m,"D",FALSE);
//  setta_parametri_record("D");  
}

void TInv_cont::cancella_righe_causali(const TString& codcaus)
{
  _trcaus->setkey(1);
  _trcaus->zero();
  _trcaus->put(RCA_CODCAUS, codcaus);
  TRectype rcau (LF_RCAUSALI);
  rcau = _trcaus->curr();
  for (_trcaus->read(); !_trcaus->eof(); _trcaus->next())
  {
    if (_trcaus->curr() > rcau) break;
    
    _trcaus->remove();
  }
}

void TInv_cont::scrivi_righe_causali(const TString& codcaus, char uselab)
{
  cancella_righe_causali(codcaus);
                                   
  _rcaus->setkey(1);
  _rcaus->zero();
  _rcaus->put(RCA_CODCAUS, codcaus);
  TRectype rcau (LF_RCAUSALI);                               
  rcau = _rcaus->curr();
  for (_rcaus->read(); !_rcaus->eof(); _rcaus->next())
  {
    if (_rcaus->curr() > rcau) break;
      
    _trcaus->curr() = _rcaus->curr();
    _trcaus->write();
      
    leggi_record_controllo();
    TString chiave;
    chiave.format("%3s",(const char*) codcaus);
    TString sigla; 
    sigla.format("%c", uselab);
    _control_rec.overwrite(sigla,240);
    _control_rec.overwrite(chiave,241);
    _tras_file.write_control_rec(_control_rec,1024);      
  }
}

void TInv_cont::clifo2tempfile(TString& key, TMask& m)
{
  int     size = 1024;
  
  _tras_file.open(_header);
    
  long items = _clifo->items();
  _prog = new TProgind(items,"Invio Clienti / Fornitori in corso... Prego attendere.",FALSE);
                                       
  _clifo->setkey(1);
                    
  if (key.empty())
    _clifo->first();
  else
  {         
    char tipo   = (key.mid(0,1))[0];     
    long codice = atol(key.mid(1,6));
    _clifo->zero();
    _clifo->put(CLI_TIPOCF, tipo);
    _clifo->put(CLI_CODCF,  codice);
    _clifo->read();
  }
  
  for(; !_clifo->eof(); _clifo->next())
  { 
    _prog->addstatus(1);
    
    char tipocf = _clifo->get_char(CLI_TIPOCF);                            
    long codcf  = _clifo->get_long(CLI_CODCF);
    
    _tclifo->curr() = _clifo->curr(); 
    
    if (_tclifo->read() == NOERR)  // Esiste gia' il cliente
    {
      _tclifo->zero();
      _tclifo->curr() = _clifo->curr();
      _tclifo->rewrite();
    }  
    else
    {
      _tclifo->zero();
      _tclifo->curr() = _clifo->curr();
      _tclifo->write();
    }
          
    leggi_record_controllo();
    TString chiave;
    chiave.format("%c%06ld", tipocf, codcf);      
    TString sigla;
    sigla.format("%c", 'A');
    _control_rec.overwrite(sigla,240);
    _control_rec.overwrite(chiave,241);

    _tras_file.write_control_rec(_control_rec,size);          
  }     
  delete _prog;  

  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.
  
  leggi_record_controllo();
  TString chiave,app,sigla;
  app.format("%-60s", (const char*) chiave);
  char sigla_p = _tras_file.ult_file()[0];
  int posiz    = _files.find(sigla_p);
  TString nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  _control_rec.overwrite(app,241);
  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();

//  setta_tabella_ditta(m,"D",FALSE);
//  setta_parametri_record(m,"D");  
}


void TInv_cont::pcon2tempfile(TString& key, TMask& m)
{
  const int size = 1024;

  _tras_file.open(_header);
  
  long items = _pcon->items();
  _prog = new TProgind(items,"Invio Piano dei Conti in corso... Prego attendere.",FALSE);
                                       
  _pcon->setkey(1);
                    
  if (key.empty())
    _pcon->first();
  else
  {             
    int  gruppo = atoi(key.mid(0,3));
    int  conto  = atoi(key.mid(3,3));
    long sottoc = atol(key.mid(6,6));
    
    _pcon->zero();
    _pcon->put(PCN_GRUPPO, gruppo);
    if (conto != 0)
      _pcon->put(PCN_CONTO, conto);
    if (sottoc != 0)
      _pcon->put(PCN_SOTTOCONTO, sottoc);
    _pcon->read();
  }
  
  for(; !_pcon->eof(); _pcon->next())
  { 
    _prog->addstatus(1);
    
    int  g = _pcon->get_int (PCN_GRUPPO);
    int  c = _pcon->get_int (PCN_CONTO);
    long s = _pcon->get_long(PCN_SOTTOCONTO);
    
    _tpcon->curr() = _pcon->curr(); 
    
    if (_tpcon->read() == NOERR)  // Esiste gia' il cliente
    {
      _tpcon->zero();
      _tpcon->curr() = _pcon->curr();
      _tpcon->rewrite();
    }  
    else
    {
      _tpcon->zero();
      _tpcon->curr() = _pcon->curr();
      _tpcon->write();
    }

    leggi_record_controllo();
    TString16 chiave;
    chiave.format("%3d%3d%6ld", g, c, s);      
    TString sigla;
    sigla.format("%c", 'P');
    _control_rec.overwrite(sigla,240);
    _control_rec.overwrite(chiave,241);

    _tras_file.write_control_rec(_control_rec,size);
  }     
  delete _prog;  

  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.
  
  leggi_record_controllo();
  TString chiave,app,sigla;
  app.format("%-60s", (const char*) chiave);
  char sigla_p = _tras_file.ult_file()[0];
  int posiz    = _files.find(sigla_p);
  TString nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  _control_rec.overwrite(app,241);
  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();

//  setta_tabella_ditta(m,"D",FALSE);
//  setta_parametri_record(m,"D");  
}

void TInv_cont::primanota_inviata(long numreg)
{
  _mov->setkey(1);
  _mov->zero();
  _mov->put(MOV_NUMREG, numreg);
  if (_mov->read() == NOERR)
  {
    _mov->put(MOV_INVIATO, "X");
    if (_flag_bollato)
      _mov->put(MOV_STAMPATO, "X");
      
    _mov->rewrite();
  }
}

void TInv_cont::scrivi_righePN(long numreg)
{
 //  int     size = 1024;    
                   
  _tras_file.open(_header);
                                   
  _rmov->setkey(1);
  _rmov->zero();
  _rmov->put(RMV_NUMREG, numreg);
  for (_rmov->read(); !_rmov->eof(); _rmov->next())
  {
    if (_rmov->get_long(RMV_NUMREG) != numreg) 
      break;
      
    _trmov->curr() = _rmov->curr();
    _trmov->write();    
  } 
}

void TInv_cont::movPN2tempfile(TString& key, TMask& m)
{
  int size = 1024;                                       

  _tras_file.open(_header);
  
  long items = _mov->items();
  _prog = new TProgind(items,"Invio movimenti di Primanota in corso... Prego attendere.",FALSE);

  _mov->setkey(1);
                    
  if (key.empty())
    _mov->first();
  else
  {             
    long numreg = atol(key.mid(0,7));
    _mov->zero();
    _mov->put(MOV_NUMREG, numreg);
    _mov->read();
  }
  
  for(; !_mov->eof(); _mov->next())
  { 
    _prog->addstatus(1);
    if ( _mov->get_bool(MOV_INVIATO) ) 
      continue; 

    if (_mov->get_char(MOV_PROVVIS) > ' ') 
    {
      if (_scelta == 'S' || !_flag_provvis)
        continue;
    }

    TDate datareg (_mov->get_date(MOV_DATAREG)); 
    if (datareg > _datalimsk ) 
      continue; 
    
    const long nreg = _mov->get_long(MOV_NUMREG);

    _tmov->curr() = _mov->curr();
    
    if (_tmov->read() == NOERR)  
    {                  
      _tmov->zero();
      _tmov->curr() = _mov->curr();
      _tmov->rewrite();
    }
    else
    {
      _tmov->zero();
      _tmov->curr() = _mov->curr();
      _tmov->write();
      
    }
    scrivi_righePN(nreg);
          
    leggi_record_controllo();
    TString8 chiave;
    chiave.format("%07ld", nreg);      
    TString4 sigla;
    sigla.format("%c", 'Z');
    _control_rec.overwrite(sigla,240);
    _control_rec.overwrite(chiave,241);
    _tras_file.write_control_rec(_control_rec,size);
    
    primanota_inviata(nreg);
  }                                
  delete _prog;  

  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.
  
  leggi_record_controllo();
  TString chiave,app,sigla;
  app.format("%-60s", (const char*) chiave);
  char sigla_p = _tras_file.ult_file()[0];
  int posiz    = _files.find(sigla_p);
  TString nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  _control_rec.overwrite(app,241);
  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();
  
//  setta_tabella_ditta(m,"D",FALSE);
//  setta_parametri_record(m,"D");  
}

bool TInv_cont::occasionali(const TString& cfpi)
{  
  _occas->setkey(1);
  _occas->zero();
  _occas->put("CFPI", cfpi);

  int err = _occas->read();
  if (err == NOERR)
  {
    _toccas->curr() = _occas->curr();
    err = _toccas->write_rewrite();               
  }
  return err == NOERR;  
}

void TInv_cont::iva_inviata(long numreg)
{
  _mov->setkey(1);
  _mov->zero();
  _mov->put(MOV_NUMREG, numreg);
  if (_mov->read() == NOERR)
  {
    _mov->put(MOV_INVIVA, "X");
    if (_flag_bollato)
      _mov->put(MOV_REGST, "X");
    _mov->rewrite();
  }
}

void TInv_cont::movIVA2tempfile(const TString& key, TMask& m)
{
  const int size = 1024;

  TString16 ocfpi;
  TDate datareg;
  bool inviva;
  bool provvis;  

  _tras_file.open(_header);
                                         
  const long items = _rmoviva->items();
  _prog = new TProgind(items, TR("Invio movimenti Iva"), FALSE);

  _rmoviva->setkey(1);
                    
  if (key.empty())
    _rmoviva->first();
  else
  {             
    const long numreg = atol(key.mid(0,7));
    _rmoviva->zero();
    _rmoviva->put(RMI_NUMREG, numreg);
    _rmoviva->put(RMI_NUMRIG, 1);
    _rmoviva->read();
  }

  long nreg_p = -1;
  
  for(; !_rmoviva->eof(); _rmoviva->next())
  { 
    _prog->addstatus(1);
                               
    const long nreg = _rmoviva->get_long(RMI_NUMREG);

    if (nreg != nreg_p)
    {
      _mov->setkey(1);
      _mov->zero();
      _mov->put(MOV_NUMREG, nreg);
      if (_mov->read() == NOERR)
      {
        datareg = _mov->get_date(MOV_DATAREG);
        inviva  = _mov->get_bool(MOV_INVIVA);        
        ocfpi   = _mov->get     (MOV_OCFPI);
        provvis = _mov->get_char(MOV_PROVVIS) > ' ';
      } 
    }
    else
      inviva = false;
   
    // Controlla data limite invio
    if ( inviva || datareg > _datalimsk ) 
      continue;
    
    // Controlla se deve inviare i movimenti provvisori
    if (provvis && (_scelta == 'S' || !_flag_provvis))
      continue;
    
    if (ocfpi.not_empty())
      occasionali(ocfpi);
                                                     
    _triva->zero();
    _triva->curr() = _rmoviva->curr();
    
    if (_triva->read() == NOERR) 
    {                            
      _triva->zero();
      _triva->curr() = _rmoviva->curr();
      _triva->rewrite();             
    }
    else
    {
      _triva->zero();
      _triva->curr() = _rmoviva->curr();
      _triva->write();    
    }  
          
    leggi_record_controllo();
    TString8 chiave; chiave.format("%07ld", nreg);      
    _control_rec.overwrite("U",240); // Sigla
    _control_rec.overwrite(chiave,241);

    _tras_file.write_control_rec(_control_rec,size);          
    
    if (nreg != nreg_p)
      iva_inviata(nreg);
    
    nreg_p = nreg;
  }                                
  delete _prog;  

  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.
  
  leggi_record_controllo();
  
  const char sigla_p = _tras_file.ult_file()[0];
  const int posiz    = _files.find(sigla_p);
  TString4 nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  
  TString80 app; app.spaces(60);
  _control_rec.overwrite(app,241);

  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();
  
//  setta_tabella_ditta(m,"D",FALSE);
//  setta_parametri_record(m,"D");  
}

void TInv_cont::SC_inviato(char tipo,int gruppo,int conto,long sottoc,
                           int anno,const TString& numpart,int nriga)
{
  _part->setkey(1);
  _part->zero();
  _part->put(PART_TIPOCF,     tipo);
  _part->put(PART_GRUPPO,     gruppo);
  _part->put(PART_CONTO,      conto);
  _part->put(PART_SOTTOCONTO, sottoc);
  _part->put(PART_ANNO,       anno);
  _part->put(PART_NUMPART,    numpart);
  _part->put(PART_NRIGA,      nriga);

  if (_part->read() == NOERR)
  {
    _part->put(PART_INVIATA, "X");
    _part->rewrite();
  }
}

void TInv_cont::movSC2tempfile(TString& key, TMask& m)
{
  const int size = 1024;                                       

  _tras_file.open(_header);
  
  const long items = _part->items();
  _prog = new TProgind(items, TR("Invio movimenti di Saldaconto."), FALSE);

  _part->setkey(1);
                    
  if (key.empty())
    _part->first();
  else
  { 
    char    tipo    = key.mid(0,1)[0];
    int     gruppo  = atoi(key.mid(1,3));
    int     conto   = atoi(key.mid(4,3));
    long    sottoc  = atol(key.mid(7,6));
    int     anno    = atoi(key.mid(13,4));
    TString8 numpart= key.mid(17,7);
    int     nriga   = atoi(key.mid(24,4));        
    _part->zero();
    _part->put(PART_TIPOCF,     tipo);
    _part->put(PART_GRUPPO,     gruppo);
    _part->put(PART_CONTO,      conto);
    _part->put(PART_SOTTOCONTO, sottoc);
    _part->put(PART_ANNO,       anno);
    _part->put(PART_NUMPART,    numpart);
    _part->put(PART_NRIGA,      nriga);
    _part->read();
  }
  
  for(; !_part->eof(); _part->next())
  { 
    _prog->addstatus(1);
                               
    char    tipo    = _part->get_char(PART_TIPOCF);
    int     gruppo  = _part->get_int (PART_GRUPPO);
    int     conto   = _part->get_int (PART_CONTO);
    long    sottoc  = _part->get_long(PART_SOTTOCONTO);
    int     anno    = _part->get_int (PART_ANNO);
    TString numpart = _part->get     (PART_NUMPART);
    int     nriga   = _part->get_int (PART_NRIGA);        
    int     tipomov = _part->get_int (PART_TIPOMOV);
    
    if (nriga == 9999) continue;
      
    TDate datareg (_part->get_date(PART_DATAREG)); 
    
    if ( _part->get_bool(PART_INVIATA) || datareg > _datalimsk ) continue; 
    
    _tpart->curr() = _part->curr();
    
    if (_tpart->read() == NOERR)  
    {                  
      _tpart->zero();
      _tpart->curr() = _part->curr();
      _tpart->rewrite();
    }
    else
    {
      _tpart->zero();
      _tpart->curr() = _part->curr();
      _tpart->write();
    }
    
    if (tipomov == 1)
      scrivi_righeSCAD(tipo,gruppo,conto,sottoc,anno,numpart,nriga);
    else  
      scrivi_righePAGSCA(tipo,gruppo,conto,sottoc,anno,numpart,nriga);
          
    leggi_record_controllo();
    TString80 chiave;
    chiave.format("%c%03d%03d%06ld%04d%7s%04d", tipo,gruppo,conto,sottoc,anno,(const char*)numpart,nriga);      
    
    _control_rec.overwrite("B",240); // Sigla
    _control_rec.overwrite(chiave,241);
    _tras_file.write_control_rec(_control_rec,size);
    
    SC_inviato(tipo,gruppo,conto,sottoc,anno,numpart,nriga);
  }                                
  delete _prog;  

  //Inizializzo l'ultima sigla file elaborato su trasfer con la sigla del file successivo da inviare
  //e inizializzo la chiave, altrimenti se si blocca l'invio subito dopo aver finito un file si rischia di 
  //ritrasferire l'ultimo record quando si riparte; inoltre non si riesce a inviare il file successivo perche'
  //la chiave e' compilata con i dati del file precedente.
  
  leggi_record_controllo();
  TString chiave,app,sigla;
  app.format("%-60s", (const char*) chiave);
  char sigla_p = _tras_file.ult_file()[0];
  int posiz    = _files.find(sigla_p);
  TString nuova_sigla = " ";
  if (posiz < _files.len())
    nuova_sigla = _files.mid(posiz+1,1);
  
  _control_rec.overwrite(nuova_sigla,240);
  _control_rec.overwrite(app,241);
  _tras_file.write_control_rec(_control_rec,size);
  _tras_file.close();
}

void TInv_cont::scrivi_righeSCAD(char tipocf,int gruppo,int conto,long sottoc,
                                 int anno,const TString& numpart,int nriga)
{
  _scad->zero();
  _scad->put(SCAD_TIPOCF,     tipocf);
  if (gruppo != 0)
    _scad->put(SCAD_GRUPPO,     gruppo);
  if (conto != 0)
    _scad->put(SCAD_CONTO,      conto);
  if (sottoc != 0)
    _scad->put(SCAD_SOTTOCONTO, sottoc);
  _scad->put(SCAD_ANNO,       anno);
  _scad->put(SCAD_NUMPART,    numpart);
  _scad->put(SCAD_NRIGA,      nriga);  
    
  const TRectype scad = _scad->curr();
  const TString16 numpart_rec = scad.get(SCAD_NUMPART);  
  
  for (_scad->read(_isgteq); !_scad->eof(); _scad->next())
  { 
    const TString& numpart_file = _scad->get(SCAD_NUMPART);                                               
    if (_scad->curr() != scad || numpart_file != numpart_rec) 
      break;

    _tscad->curr() = _scad->curr();
    
    if (_tscad->read() == NOERR)  
    {                  
      _tscad->curr() = _scad->curr();
      _tscad->rewrite();
    }
    else
    {
      _tscad->curr() = _scad->curr();
      _tscad->write();
    }
  }
}

void TInv_cont::scrivi_righePAGSCA(char tipocf,int gruppo,int conto,long sottoc,
                                   int anno,TString& numpart,int nriga)                                 
{
  _pagsca->zero();
  _pagsca->put(PAGSCA_TIPOC,      tipocf);  
  if (gruppo != 0)
    _pagsca->put(PAGSCA_GRUPPO,     gruppo);
  if (conto != 0)
    _pagsca->put(PAGSCA_CONTO,      conto);
  if (sottoc != 0)
    _pagsca->put(PAGSCA_SOTTOCONTO, sottoc);
  _pagsca->put(PAGSCA_ANNO,       anno);
  _pagsca->put(PAGSCA_NUMPART,    numpart);
    
  const TRectype pagsca  = _pagsca->curr();
  const TString16 rec = pagsca.get(PAGSCA_NUMPART);
    
  for (_pagsca->read(_isgteq); !_pagsca->eof(); _pagsca->next())
  {                                               
    const TString& file = _pagsca->get(PAGSCA_NUMPART);       
    if (_pagsca->curr() != pagsca || file != rec) 
      break;
        
    const int nrigp = _pagsca->get_int(PAGSCA_NRIGP);         
    if (nriga != nrigp) 
      continue;

    _tpagsca->curr() = _pagsca->curr();
    
    if (_tpagsca->read() == NOERR)  
    {                  
      _tpagsca->curr() = _pagsca->curr();
      _tpagsca->rewrite();
    }
    else
    {
      _tpagsca->curr() = _pagsca->curr();
      _tpagsca->write();
    }
  }
}
                                  
int cg6900 (int argc, char* argv[])
{         
  const char t = argc > 2 ? argv[2][0] : ' ';
  switch (t)
  {
  case 'S':
    {
      TInv_cont* main_app = new TInv_cont('S');       
      main_app->run(argc, argv,main_app->_titolo);
      delete main_app;
    }
    break;
  case 'P':
    {
      TInv_cont* main_app = new TInv_cont('P');
      main_app->run(argc, argv,main_app->_titolo);
      delete main_app;
    }
    break;
  case 'L':
    {   
      TLista_archivi* a = new TLista_archivi;       
      a->run(argc, argv, TR("Lista controllo archivi"));
      delete a;
    }         
    break;
  case 'R':
    {   
      TRip_flag* a = new TRip_flag;       
      a->run(argc, argv,TR("Ripristino flag movimenti"));
      delete a;
    }         
    break;
  case 'C':
    {   
      TCanc_file_invio a;       
      a.run(argc, argv,TR("Eliminazione file invio"));
    }         
    break;
  default:
    break;
  }

  return 0;
}