#include <xvt.h>

#include <applicat.h>
#include <assoc.h>
#include <mailbox.h>
#include <progind.h>
#include <prefix.h>  
#include <relation.h>
#include <scanner.h>
#include <tabutil.h>
#include <urldefid.h>
#include <utility.h>
#include <extcdecl.h>


#if XVT_OS == XVT_OS_WIN
#include <direct.h>
#define RMDIR _rmdir
#else               
#define RMDIR rmdir
#endif

#include <causali.h>
#include <mov.h>
#include <rmov.h>
#include <saldi.h>

#include "..\cg\cglib.h"


#define usage "Errore - uso : bacnv [1|2|3|4|5|6|7|8|9|10|11|12|13] ditta"

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Applicazione di conversione archivi XBase, valida per tutti e 4 i tipi di DLL
///////////////////////////////////////////////////////////////////////////////////////////////////////

class TConversione_xbase : public TApplication
{

protected:
  virtual bool create () ;
  virtual bool destroy();
  void update();
  void convert_dir();
  int  convert_file(int logicnum);

public:
  TConversione_xbase()  {}
  ~TConversione_xbase() {}

};

bool TConversione_xbase::create() // initvar e arrmask

{
  TApplication::create();

  update();
  return FALSE;
}

bool TConversione_xbase::destroy() // releasev e arrmask

{
  return TApplication::destroy() ;
}

int TConversione_xbase::convert_file(int logicnum)
  
{
  int   err = NOERR;
  TSystemisamfile f(logicnum);
  
  err=f.pack(); // Pack data and index, so rebuild indexes according to present DLL, leaving old indexes

  return err;
}

void TConversione_xbase::convert_dir()

{         
  const TString pref(prefix().name());
  const bool is_com = prefix().is_com(); 
  TDir d;
  
  d.get(LF_DIR);                 
  const int items = (int)d.eod();
  TString80 s("Aggiornamento archivi ");

  if (pref == "com") s << "comuni";
  else s << " della ditta " << atol (pref);
  
  TProgind p((long)(items ? items : 1), s, TRUE, TRUE, 70);

  p.setstatus(1L);
  
  for (int i = 2; i <= items; i++)
  {                   
    p.setstatus((long)(i+1));
    d.get(i, _nolock, _nordir, _sysdirop);                 

    const bool to_convert = (is_com ? d.is_com() : d.is_firm());
    
    if (to_convert && d.len() > 0) 
      convert_file(i);
  }
}

void TConversione_xbase::update()

{ 
  long firm = get_firm();             
  TString pref;
  if (firm == 0) pref = prefix().name();
  
  do_events();
  begin_wait();
  
  prefix().set("com");
  convert_dir();

  TLocalisamfile ditte(LF_NDITTE);
  
  set_autoload_new_files(FALSE);
  for (ditte.first(); !ditte.eof(); ditte.next())
  {
    const long codditta = ditte.get_long("CODDITTA");
    const TRecnotype rec = ditte.recno();
    
    if (prefix().exist(codditta))
    {
      set_firm(codditta);
      convert_dir();
    }
  }
  if (firm > 0) set_firm(firm);
  else prefix().set(pref);
  set_autoload_new_files(TRUE);
  end_wait();
}



/////////////////////////////////////////////////////////////////////////////////////////
// Applicazione di conversione archivi
/////////////////////////////////////////////////////////////////////////////////////////


class TConversione_archivi : public TApplication
{
  int _nconv;
  long _codditta;
  long _oldditta;
  int _error;

protected: // TApplication
  virtual bool create() ;                         
  virtual bool destroy() ;                        
  virtual bool menu(MENU_TAG);
  
public:
  bool convert_rmov(TLocalisamfile & rmov, TArray & recs, int nrecs);
  void contropartita_rmov();

  void liala(const char* table);
  bool patch_uff(TRectype & rec, const char * const fnames[]);
  bool collate(TRectype & rec, const char * f1, const char * f2);
  void patch_com();
  void zero_770();
  void convert_patty();
  void convert_codconc();
  void convert_profili();
  void convert_caus_attiv();
  void rebuild_indexes();
  void rebuild_dir_indexes();
  void convert_codreg() const;
  void convert_lia_pim() const;
  void build_ver_table() const;
  void convert_forms() const;
  void sort_sal(int year) const;
  void convert_saldi() const;
  void convert_ca7_ql() const;
  void convert_enti_m770() const; 
  void convert_caaf_m770() const; 
  void convert_rver_m770() const;
  void remove_dta_ndx() const;

  TConversione_archivi() : _oldditta(0), _codditta(0), _error(0) {}
};

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

  if (argc() < 3)
  {
    _error = 101;
    TMessage msg("ba1100", 0, format("%d", _error));

    msg.send();
    return FALSE;
  }
  else
  {           
    _nconv = atoi(argv(1));
    if (_nconv > 1)
    {
      _oldditta = get_firm();
      _codditta = atol(argv(argc() - 1));
      if (_codditta != _oldditta) 
      {
        if (_codditta == 0) prefix().set("com");
        else set_firm(_codditta);
      }
    }
    dispatch_e_menu(MENU_ITEM(1));
    return TRUE;
  }
}

bool TConversione_archivi::destroy()
{
  if (_nconv > 1 && _codditta != _oldditta)
  {
    if (_oldditta == 0) prefix().set("com");
    else set_firm(_oldditta);
  }
  if (_error > 0)
  {
    TMessage msg("ba1100", 0, format("%d", _error));
    msg.send();
  }
  return TRUE;
}

bool TConversione_archivi::menu(MENU_TAG)
{
  switch (_nconv)
  {
  case 1:
  {
    TSystemisamfile f(atoi(argv(2)));
    TFilename lf;

    lf.format("%sstd/%s", __ptprf, argv(3));
    if (fexist(lf))
      f.load(lf, '|', '\0', '\n', TRUE, TRUE);
  }
  break;
  case 2:
    liala("LIA"); 
    liala("PLA"); 
    break;   
  case 3:
    if (_codditta == 0)
      patch_com();
  case 4:
    if (_codditta == 0)
      zero_770();
  case 5:
    convert_patty();    
  case 6:
    if (_codditta == 0) 
    {
      convert_codconc();

      TSystemisamfile comuni(LF_COMUNI);
   
      comuni.load(format("%sstd/ncom02.txt", __ptprf)); 
      
      //Cancella tutti i vecchi profili, sostituendoli con i nuovi
      convert_profili();
    }  
  case 7:
    if (_codditta == 0)
      convert_caus_attiv();
    break;
  case 8:
    if (_codditta == 0)
      rebuild_indexes(); 
    break;
  case 9: 
    if (_codditta == 0)
      convert_codreg();
    break;
  case 10:
    convert_lia_pim();
    if (_codditta == 0)
      build_ver_table();
    break;  
  case 11:
    if (_codditta == 0)
      convert_ca7_ql();
    break;
  case 12:
    remove_dta_ndx();
    if (_codditta == 0)
    {
      // Rimuove ITALIA dalla tabella stati
      TTable sta("%STA");
      sta.zero();
      if (sta.read() == NOERR) sta.remove();
      // converte i profili
      convert_forms();
    }
    else
      convert_saldi();
    break;
  case 13:
    if (_codditta == 0)
    {
      convert_enti_m770();
      convert_caaf_m770();
      convert_rver_m770();
    }
    break;
  default:
    break;  
}
  return FALSE;
}

///////////////////////////////////////////////////////////
// Cambia i movimenti contabili in modo che abbiano un
// conto di contropartita e non una riga di riferimento
///////////////////////////////////////////////////////////

bool TConversione_archivi::convert_rmov(TLocalisamfile & rmov, TArray & recs, int nrecs)
{
  const TRecnotype pos = rmov.recno();

  for (int i = 0; i < nrecs; i++)
  {
    TRectype & r0 = (TRectype &) recs[i];
    const int rcontr = r0.get_int(RMV_RCONTR) - 1;

    if (rcontr >= 0 && rcontr < nrecs)
    {
      const TRectype & r1 = (const TRectype &) recs[rcontr];

      r0.put(RMV_TIPOCC, r1.get(RMV_TIPOC));
      r0.put(RMV_GRUPPOC, r1.get_int(RMV_GRUPPO));
      r0.put(RMV_CONTOC, r1.get_int(RMV_CONTO));
      r0.put(RMV_SOTTOCONTOC, r1.get_long(RMV_SOTTOCONTO));
    }
    r0.zero(RMV_RCONTR);
    if (rmov.rewrite(r0) != NOERR)
    {
      const long reg = r0.get_long(RMV_NUMREG);
      error_box("Non riesco ad aggiornare la riga contabile %ld / %d\nErrore n. %d", reg, i + 1, rmov.status());
      rmov.readat(pos);
      _error = 102;
      return FALSE;
    }
  }
  rmov.readat(pos);
  return TRUE;
}

void TConversione_archivi::contropartita_rmov()
{
  TDir d;
  d.get(LF_RMOV);
  if (d.eox() == 0) return;

  TLocalisamfile rmov(LF_RMOV);
  const TRecnotype nitems = rmov.items();
  TArray recs;
  long oldreg = -1;
  long reg = -1;
  int nrow = 0;
  TProgind p(nitems ? nitems : 1,
             format("Conversione righe di movimento della ditta %ld", get_firm()),
             FALSE, TRUE, 70);
  for (rmov.first(); rmov.good(); rmov.next())
  {
    p.addstatus(1);
    reg = rmov.get_long(RMV_NUMREG);
    if (oldreg != reg)
    {
      if (oldreg > 0)
        if (convert_rmov(rmov, recs, nrow) == FALSE)
          return;
      oldreg = reg;
      nrow = 0;
    }
    recs.add(rmov.curr(), nrow++);
    CHECKD(nrow == rmov.get_int(RMV_NUMRIG), "Missed row ", nrow); 
  } 
  if (oldreg > 0)
    if (convert_rmov(rmov, recs, nrow) == FALSE)
      return;
}


///////////////////////////////////////////////////////////
// Passa le tabelle LIA e PLA a %LIA e %PLA
///////////////////////////////////////////////////////////

void TConversione_archivi::liala(const char* table)
{                                                 
  TString16 tab(table);                                            
  TTable lia(tab);
  tab.insert("%", 0);
  TTable cia(tab);

  const long n = lia.items()+1;
  TProgind p(n, format("Conversione tabella %s della ditta %ld", table, get_firm()), FALSE, TRUE, 70);
  
  TString16 firm; firm.format("%05ld", get_firm());
  TString16 codtab;
  
  for (lia.first(); lia.good(); lia.next())
  {
    codtab = lia.get("CODTAB");
    codtab.insert(firm, 0);
    lia.put("CODTAB", codtab);
    cia.write(lia.curr());
  }
  
  for (lia.first(); lia.good(); lia.next())
    lia.remove();
}

///////////////////////////////////////////////////////////
// Sposta i codici uffici imposte e uffici IVA nei comuni
///////////////////////////////////////////////////////////

bool TConversione_archivi::collate(TRectype & rec, const char * f1, const char * f2)
{ 
  if (rec.get(f1).empty())
  {                              
    TString16 s(rec.get(f2)); 
    
    if (s.not_empty())
    {
      rec.put(f1, s);
      rec.zero(f2); 
      return TRUE;
    }   
  }               
  return FALSE;
}

bool TConversione_archivi::patch_uff(TRectype & rec, const char * const fnames[])
{  
  bool updated = collate(rec, fnames[1], fnames[2]);
  updated |= collate(rec, fnames[0], fnames[1]);
  updated |= collate(rec, fnames[1], fnames[2]);
  return updated;
}

void TConversione_archivi::patch_com()
{
  TLocalisamfile comuni(LF_COMUNI);    
  const char * const uff_iidd[] = {"UFFIIDD1", "UFFIIDD2", "UFFIIDD3"} ;
  const char * const uff_iva[] = {"UFFIVA1", "UFFIVA2", "UFFIVA3"} ;
  const TRecnotype nitems = comuni.items();
  TProgind p(nitems ? nitems : 1, format("Conversione comuni"), FALSE, TRUE, 70);
  
  for (comuni.first(); comuni.good(); comuni.next())
  {      
    p.addstatus(1);
    bool updated = patch_uff(comuni.curr(), uff_iidd);
    updated = patch_uff(comuni.curr(), uff_iva) || updated;
    if (updated)
      comuni.rewrite();
  }                                                    
}

void TConversione_archivi::zero_770()
{ 
  for (int i = LF_BASE ; i <= LF_DETH; i++)
  {
    TDir d;      
    
    d.get(i, _lock, _nordir, _sysdirop); 
    d.eod() = 0L;             
    d.eox() = 0L;
    d.put(i,  _nordir, _sysdirop);  
  }      
  TToken_string files;
  
  if (fexist(format("%scom/770", __ptprf)))
  {       
    files.format("%scom/770/%s", __ptprf, "*");   
    list_files(files);
    for (const char * s = files.get(); s != NULL; s = files.get())
      remove(s);               
    RMDIR(format("%scom/770", __ptprf)); 
  }
  if (fexist(format("%s770", __ptprf)))
  {       
    files.format("%s770/%s", __ptprf, "*");   
    list_files(files);
    for (const char * s = files.get(); s != NULL; s = files.get())
      remove(s);               
    RMDIR(format("%s770", __ptprf)); 
  }
}

void TConversione_archivi::convert_patty()
{                                      
{
  TTable ivd("%IVD");
  ivd.zero();
  ivd.put("CODTAB", "9E0023");
  if (ivd.read(_isequal, _lock) == NOERR)
    ivd.remove();
  ivd.put("CODTAB", "9E  23");
  if (ivd.read(_isequal, _lock) == NOERR)
    ivd.remove();  
  ivd.put("CODTAB", "9E    23");
  if (ivd.read(_isequal, _lock) == NOERR)
    ivd.remove();  
}
{
  TTable doc("%TPD");
  doc.zero();
  doc.put("CODTAB", "AN");
  if (doc.read(_isequal, _lock) == NOERR)
    doc.remove();
  doc.zero();
  doc.put("CODTAB", "IN");
  if (doc.read(_isequal, _lock) == NOERR)
    doc.remove();
  doc.zero();
  doc.put("CODTAB", "PG");
  if (doc.read(_isequal, _lock) == NOERR)
    doc.remove();
  doc.zero();
  doc.put("CODTAB", "NA");
  if (doc.read(_isequal, _lock) == NOERR)
    doc.remove();
  doc.zero();
  doc.put("CODTAB", "NC");
  if (doc.read(_isequal, _lock) == NOERR)
  {
    doc.put("S0", "Nota di credito");
    doc.put("I0", "9");
    doc.rewrite();
  }
} 
TAssoc_array causarr;

TDir d;
d.get(LF_CAUSALI,_nolock,_nordir,_sysdirop);
if (d.is_com())
  d.get(LF_CAUSALI,_nolock,_comdir);

  if (d.eod() > 0L)
{
  TLocalisamfile caus(LF_CAUSALI);
  for (caus.first(_lock); caus.good(); caus.next(_lock))
  {
    const TString16 tpd(caus.get("TIPODOC"));
    const TString16 incimm(caus.get("CODCAUSIM"));
    
    if (incimm.not_empty())
      causarr.add(incimm, incimm);
    if (tpd == "AN") caus.zero("TIPODOC");
    else
      if (tpd == "IN") caus.zero("TIPODOC");
      else
        if (tpd == "PG") caus.zero("TIPODOC");
        else
          if (tpd == "NA") caus.put("TIPODOC","NC");   
    
    caus.rewrite();
  }                  
}             
const bool topatch = causarr.items() > 0;

d.get(LF_MOV);
if (d.eod() > 0L)
{
  TLocalisamfile mov(LF_MOV);
  
  for (mov.first(_lock); mov.good(); mov.next(_lock))
  {
    const TString16 tpd(mov.get("TIPODOC"));
    if (topatch)
    {
      const TString16 codcaus(mov.get("CODCAUS"));
      
      if (causarr.objptr(codcaus) != NULL)
      {
        mov.zero("DATA74TER");
        mov.zero("REG");
        mov.zero("PROTIVA");
        mov.zero("UPROTIVA");
        mov.zero("REGST");
        mov.zero("TIPO");
        mov.zero("CODCF");
        mov.zero("TOTDOC");
        mov.zero("RITFIS");
        mov.zero("RITSOC");
        mov.zero("PROVVIS");
        mov.zero("CODVALI");
        mov.zero("CAMBIOI");
        mov.zero("CORRLIRE");
        mov.zero("CORRVALUTA");
        mov.zero("OCFPI");
        mov.zero("CODPAG");
      }
    }
    if (tpd == "AN") mov.zero("TIPODOC");
    else
      if (tpd == "IN") mov.zero("TIPODOC");
      else
        if (tpd == "PG") mov.zero("TIPODOC");
        else
          if (tpd == "NA") mov.put("TIPODOC","NC");
    mov.rewrite();
  }
}       
{

}
if (_codditta == 0)
{     
  TDir d;
  TSystemisamfile f(LF_FORM);
  TFilename lf;
         
  d.get(LF_FORM);
  lf.format("%sstd/lf0054.txt", __ptprf);
  if (fexist(lf) && fexist(d.filename()))
    f.load(lf);
}
}                                         

void TConversione_archivi::convert_caus_attiv()
{                                            
  {
    TLocalisamfile attiv(LF_ATTIV); 
    TProgind p(attiv.items(), "Conversione archivio attivita'", FALSE, TRUE,20);
    p.setstatus(1L);
    for (attiv.first(); !attiv.eof(); attiv.next())
    {
      bool val = attiv.get_bool("ART74/4");
      attiv.put("ART74_4", val);
      attiv.rewrite();
      p.addstatus(1L);
    }                           
  }    
  {
    TLocalisamfile ditte(LF_NDITTE);
    TProgind p(ditte.items(), "Conversione archivi causali", FALSE, TRUE,5);
    p.setstatus(1L);
    set_autoload_new_files(FALSE);
    for (ditte.first(); !ditte.eof(); ditte.next())
    {
      const long codditta = ditte.get_long("CODDITTA");
      if (prefix().exist(codditta))
      {
        p.set_text(format("Ditta: %ld",codditta));
        set_firm(codditta);
        TLocalisamfile caus(LF_CAUSALI);
        caus.zero();
        caus.put("CODCAUS","C08");      
        if (caus.read() == NOERR)       
           caus.put("TIPODOC","FS");    
        caus.rewrite();
      }             
      p.addstatus(1);
    }                               
    p.setstatus(ditte.items());
    prefix().set("com");
    set_autoload_new_files(TRUE);
  }
}

void TConversione_archivi::convert_profili()
{
  TSystemisamfile form(LF_FORM),rform(LF_RFORM);
  TDir d;
  TFilename lf;
       
  d.get(LF_FORM, _nolock, _comdir, _sysdirop);
  d.eod() = 0;
  d.put(LF_FORM, _comdir, _sysdirop);
  form.pack();
  lf.format("%sstd/lf0054.txt", __ptprf);
  if (fexist(lf)) form.load(lf);
  d.get(LF_RFORM, _nolock, _comdir, _sysdirop);
  d.eod() = 0;
  d.put(LF_RFORM, _comdir, _sysdirop);
  rform.pack();
}

void TConversione_archivi::convert_codconc()
{     
// costruisce le tabelle di confronto                                 
  TAssoc_array conc_cessate;
  TScanner oc(format("%sstd/oconc00.txt", __ptprf)); 
    
  for (TString16  s(oc.line()); s.not_empty(); s = oc.line()) 
    conc_cessate.add(s);
// (fase 1)
// scorre il file anagrafica  
  TLocalisamfile anagr(LF_ANAG);
  TLocalisamfile comuni(LF_COMUNI);
  int nerr = 0;
// se il file anagrafica non é vuoto
  const long anag_items = anagr.items();
  if (anag_items > 0)
  {
    TProgind p(anag_items, "Conversione archivio anagrafica", FALSE, TRUE, 70);
    
    p.setstatus(1L);

// per ogni anagrafica  blocca il record
    for (anagr.first(_lock); anagr.good(); anagr.next(_lock))
    {
//   legge il codice comune
      TString16 com = anagr.get("COMRF");

      p.addstatus(1);                           
      if (com.empty())
        com = anagr.get("COMRES");
//   se il comune non é vuoto recupera il comune       
      if (com.not_empty())
      {                                                                             
        comuni.zero();
        comuni.put("COM", com);
// se non é un comune di una nuova provincia e il comune esiste    
        if (!conc_cessate.is_key(com))
        {
          if (comuni.read() == NOERR)
          {                  
//   legge il codice concessione
            TString16 conc(comuni.get("UFFCONC"));
//   se il codice concessione é cessato
            if (conc_cessate.is_key(conc))
            {   
//     scrive il codice concessione sull' anagrafica
              anagr.put("UFFCONC", conc);
              anagr.rewrite();
            }
//   altrimenti sblocca il record              
            else
              anagr.read(_iscurr, _unlock);                  
         }
//   altrimenti sblocca il record e conteggia l' errore
          else
          {
            anagr.read(_iscurr, _unlock);
            nerr++;
          }  
        }
      } 
//   altrimenti sblocca il record              
      else
        anagr.read(_iscurr, _unlock);
    }
  }                              
// segnala gli errori
#ifdef DBG
  if (nerr)
    error_box("La conversione della anagrafiche non ha trovato %d comuni", nerr);
  nerr = 0; 
#endif

// (fase 2) 
// vuota la tabella concessioni
  {
    TTable uffconc("%UCC");
  
    for (uffconc.first(_lock); uffconc.good(); uffconc.next(_lock))
      uffconc.remove();
   }
// carica la nuova            
   {
     TSystemisamfile tabcom(LF_TABCOM);
   
     tabcom.load(format("%sstd/nconc00.txt", __ptprf)); 
   }  
// (fase 3)
// scorre il file con i codici comuni e le nuove concessioni
  TScanner nc(format("%sstd/ncom00.txt", __ptprf)); 
  TProgind p(comuni.items(), "Conversione archivio comuni", FALSE, TRUE, 70);  
  TToken_string comass;
#ifdef DBG   
  TTable uffconc("%UCC");
  TToken_string concerr;
#endif       

  p.setstatus(1L);
// per ogni comune
  for (TToken_string ts(nc.line()); ts.not_empty(); ts = nc.line()) 
  {                          
    p.addstatus(1);
//  cerca il comune
    comuni.zero();
    comuni.put("COM", ts.get());
// se esiste
    if (comuni.read(_isequal, _lock) == NOERR)                     
    {
//   aggiorna il codice concessione sul comune in oggetto
      comuni.put("UFFCONC", ts.get());
      comuni.rewrite();
#ifdef DBG   
      uffconc.zero();
      uffconc.put("CODTAB", comuni.get("UFFCONC"));
      if (uffconc.read() != NOERR)
        concerr.add(comuni.get("UFFCONC")); 
#endif       
    }
//   altrimenti sblocca il record e conteggia l' errore
    else                                               
    {
      comuni.read(_iscurr, _unlock);
      comass.add(ts.get(0));
      nerr++;    
    }
  } 
// segnala gli errori
#ifdef DBG
  if (nerr)
    error_box("La conversione dei comuni non ne ha trovati %d\n Codici : %s", nerr, (const char *) comass);
  if (concerr.not_empty())
    error_box("Le seguenti concessioni sono inesistenti %s", (const char *) concerr);
#endif       
}                                                      

void TConversione_archivi::rebuild_indexes()
{  
  do_events();
  begin_wait();
  prefix().set("com");
  rebuild_dir_indexes();
  TSystemisamfile ditte(LF_NDITTE);
  ditte.open();
  
  for (ditte.first(); !ditte.eof(); ditte.next())
  {
    const long codditta = ditte.get_long("CODDITTA");
    const TRecnotype rec = ditte.recno();
    
    if (prefix().exist(codditta))
    {
      ditte.close();
      set_firm(codditta);
      rebuild_dir_indexes();
      ditte.open();
    }
    ditte.readat(rec);
  }
  ditte.close();
  end_wait();
}                                            

void TConversione_archivi::rebuild_dir_indexes()
{                                            
  const TString pref(prefix().name());
  const bool is_com = prefix().is_com();
  TDir d;  
  
  d.get(LF_DIR);                 
  const int items = (int)d.eod();
  TString80 s("Ricostruzione indici ");

  if (is_com) s << "comuni";
  else s << " della ditta " << atol (pref);
  
  TProgind p(items ? items : 1, s, TRUE, TRUE, 70);

  p.setstatus(1);
  
  for (int i = 2; i <= items; i++)
  {  
    p.addstatus(1);
    if (d.len() > 0)
    { 
      d.get(i, _nolock, _nordir, _sysdirop); 
      bool to_create = (is_com ? d.is_com() : d.is_firm());
    
      if (to_create)
      {              
        TBaseisamfile f(i);
        d.get(i);
        TFilename s(d.name());
        s.ext("dbf");
        if (f.is_valid() == NOERR && fexist(s))
        {
          TSystemisamfile f(i);
          f.packindex();         
        }
      }
    }
  }
}


void TConversione_archivi::convert_codreg() const
{ 
// (fase 1)
// allinea i comuni alle nuove provincie e carica il codice regione
// costruisce la tabella comuni -> nuove provincie
#ifdef DBG
  int nerr = 0;
#endif      
  TAssoc_array compro;
  
  {
    TScanner oc(format("%sstd/tbcompro.txt", __ptprf)); 
    
    for (TToken_string s(oc.line()); s.not_empty(); s = oc.line()) 
    {
      TString16 codcom(s.get(0));
      
      compro.add(codcom, s);
    }                         
  }

// costruisce la tabella provincie -> regioni
  TAssoc_array proreg;
  
  {
    TScanner oc(format("%sstd/tbproreg.txt", __ptprf)); 
    
    for (TToken_string s(oc.line()); s.not_empty(); s = oc.line()) 
    {
      TString16 prov(s.get(0));
      TString16 codreg(s.get());
      
      proreg.add(prov, codreg);
    }                         
  }
// scorre il file comuni
  TLocalisamfile comuni(LF_COMUNI);
// se il file comuni non é vuoto
  const long com_items = comuni.items();
  if (com_items > 0)
  {
    TProgind p(com_items, "Conversione archivio comuni", FALSE, TRUE, 70);
    
    p.setstatus(1L);

// per ogni comune
    for (comuni.first(); comuni.good(); comuni.next())
    {                               
      bool rewrite = FALSE;
      
      p.addstatus(1);               
      const TString & cod = comuni.get("COM");             
      TToken_string * t = (TToken_string *) compro.objptr(cod);
      
      if (t != NULL)
      {                    
        comuni.put("PROVCOM", t->get(1));
        comuni.put("CODISTAT", t->get());
        comuni.put("UFFIVA1", t->get());
        comuni.zero("UFFIVA2");
        comuni.zero("UFFIVA3");
        rewrite = TRUE;
      } 
      
      const TString & prov = comuni.get("PROVCOM");             
      TString16 * s = (TString16 *) proreg.objptr(prov);  
      
      if (s != NULL)
      {                    
        comuni.put("CODREG", *s);
        rewrite = TRUE;
      }       
#ifdef DBG
      else
        nerr++;
#endif      
      if (rewrite)
        comuni.rewrite();
    }
  }                              

// (fase 2) 
// compatta la tabella            
  {
     TSystemisamfile tabcom(LF_TABCOM);
   
     tabcom.pack(TRUE,FALSE);
  }         
// vuota la tabella concessioni
  {
    TTable uffconc("%UCC");
  
    for (uffconc.first(_lock); uffconc.good(); uffconc.next(_lock))
      uffconc.remove();
  }
// carica la nuova            
  {
     TSystemisamfile tabcom(LF_TABCOM);
   
     tabcom.load(format("%sstd/nconc01.txt", __ptprf)); 
  }         
// (fase 3)
// vuota la tabella regioni
  {
    TTable regioni("%RGI");
  
    for (regioni.first(_lock); regioni.good(); regioni.next(_lock))
      regioni.remove();
  }
// carica la nuova            
  {
    TSystemisamfile tabcom(LF_TABCOM);
   
    tabcom.load(format("%sstd/nreg00.txt", __ptprf)); 
  }                        
}


void TConversione_archivi::convert_lia_pim() const
{
// converte le Tokenstring contenute in  S1 e S2 di PIM e %LIA, sostituendo | con !
  TString80 s1,s2;
  if (_codditta == 0)    
  {
    TProgind p(10, "Conversione tabella LIA", FALSE, FALSE, 10);
    TTable lia("%LIA");
    for (lia.first(); lia.good(); lia.next())
    {
      s1 = lia.get("S1");
      if (s1.not_empty())
        if (s1.replace('|','!') > 0)
        {
          lia.put("S1",s1);
          lia.rewrite();
        }
    }
  }
  else
  {
    TProgind p(10, "Conversione tabella PIM", FALSE, FALSE, 10);
    TTable pim("PIM");
    for (pim.first(); pim.good(); pim.next())
    {
      s1 = pim.get("S1");
      s2 = pim.get("S2");
      if (s1.not_empty() || s2.not_empty())
        if ((s1.replace('|','!')+s2.replace('|','!')) > 0)
        {
          pim.put("S1",s1);
          pim.put("S2",s2);
          pim.rewrite();
        }
    }
  }
}

void TConversione_archivi::build_ver_table() const
// Costruisce la tabella %VER con i valori in vigore da Gennaio 1993
{
  TProgind p(10, "Creazione tabella VER", FALSE, FALSE, 10);
  TTable ver("%VER");
  
  ver.zero();
  // Come chiave si l'inizio del periodo di validita'
  ver.put("CODTAB","199301");
  // Percentuali interessi su versamento IVA per trimestri
  // prima erano memorizzati in prassis.ini, nei parametri studio.
  ver.put("R0","1.5");  ver.put("R1","1.5");
  ver.put("R2","1.5");  ver.put("R3","1.5");  ver.put("R4","1.5");
  // Importi limite versamenti. Prima erano defines all'interno
  // del programma di liquidazione
  ver.put("R5","50500"); ver.put("R7","200000");
  // Percentuale calcolo acconti Base anno precedente
  ver.put("R11","88");ver.put("R12","88");
  
  if (ver.write() != NOERR) ver.rewrite();
}

void TConversione_archivi::convert_ca7_ql() const
// Converte la tabella %CA7 e QUADROL
{
  TTable ca7("%CA7");

  for (ca7.first(); ca7.good(); ca7.next())
  {
    TString s(ca7.get("S1"));
    real i1(ca7.get("I1"));
    ca7.put("R4",i1);
    ca7.zero("I1");
    if (ca7.get_bool("B1"))
      ca7.put("S2","N");
    if (!ca7.get_bool("B0") && s=="D1")
      ca7.put("S3","F");
    ca7.rewrite();
  }
  
  // Ora converte il quadro L
  TLocalisamfile quadrol(LF_QUAL);
  TString serie,numero;
  for (quadrol.first(); quadrol.good(); quadrol.next())
    if (quadrol.get_char("QLTV") == 'B')
    {
      TRectype com_rec(quadrol.curr());
      serie.format("%05ld",quadrol.get_long("QLSERIE"));
      numero.format("%05ld",quadrol.get_long("QLNUMERO"));
      com_rec.put("QLSERIE",serie);
      com_rec.put("QLNUMERO",numero);
      quadrol.write(com_rec);
      quadrol.remove();
    }
}


// conversione in formato numerico del codice ente
// in modo che i codici inferiori a 10 non siano registrati
// nella forma "1 ","2 ", ecc.
// ma nella forma "01","02", ecc.
void TConversione_archivi::convert_enti_m770() const
{     
  TTable tab("%ENT");
  TString new_cod;
  TString old_cod; 
  int err;      
  
  for (err = tab.first(); err == NOERR; err = tab.next())
  {
  	old_cod = tab.get("CODTAB");
  	if (old_cod.len() < 2)
  	{
  		TRectype new_rec(tab.curr());
  	  new_cod.format("%02d",atoi(old_cod));  
 			new_rec.put("CODTAB", new_cod); 
 			tab.write(new_rec);
 			tab.remove();
 		}
  }
}   

// conversione in formato numerico del codice caaf
// in modo che i codici inferiori a 10000 non siano registrati
// nella forma "1    ","2    ", ecc.
// ma nella forma "00001","00002", ecc.
void TConversione_archivi::convert_caaf_m770() const
{     
  TTable tab("%CAF");
  TString old_cod;
  TString new_cod; 
  int err;      
  
  for (err = tab.first(); err == NOERR; err = tab.next())
  {
  	old_cod = tab.get("CODTAB");
  	if (old_cod.len() < 5)
  	{
  		TRectype new_rec(tab.curr());
  		new_cod.format("%05ld",atol(old_cod));  
 			new_rec.put("CODTAB", new_cod);  
 			tab.write(new_rec);
 			tab.remove();
 		}
  }
}   


// conversione del numero progressivo banca 
// per renderlo senmpre zerofilled
void TConversione_archivi::convert_rver_m770() const
{     
  TLocalisamfile lf(LF_RVER);
  long progr_banca; 
  int err;      
  
  for (err = lf.first(); err == NOERR; err = lf.next())
  {
  	progr_banca = lf.get_long("PROGBANC");  
  	lf.put("PROGBANC", progr_banca);  
 		lf.rewrite();
  }
}   


void TConversione_archivi::remove_dta_ndx() const
{
  TToken_string list;
  TString s;
  
  for (int j = 0; j < 2; j++)
  {
    s = firm2dir(_codditta);
    s << "/" ;
    s << (j == 0 ? "*.dta" : "*.ndx");
    list = s;
    const int items = list_files(list);
    for (int i=0; i<items;i++)
      remove(list.get(i));
  }
}

void TConversione_archivi::convert_forms() const
// Converte i profili, aggiungendo il valore dell'offset verticale. Solo
// per i forms != PEC
{
  TLocalisamfile rform(LF_RFORM),form(LF_FORM);
  TString nome,nomeprec,cod,codprec;
  int y,ipy;
  TProgind p(5,"Conversione profili in corso...",FALSE,FALSE);
  for (form.first();form.good();form.next())
  {
    nome = form.get("TIPOPROF");
    cod = form.get("CODPROF");
    ipy = form.get_int("IPY");
    if (nome == "PEC" || ipy == 0) continue;
    rform.put("TIPOPROF",nome);
    rform.put("CODPROF",cod);
    for (rform.read(_isgteq);rform.good();rform.next())
    {
      nomeprec = rform.get("TIPOPROF");
      codprec = rform.get("CODPROF");
      if (nomeprec != nome || codprec != cod) break;
      y = rform.get_int("Y");
      if (y > 0)
      {
        y += ipy;
        rform.put("Y",y);
        rform.rewrite();
      }
    }
  }
}

void TConversione_archivi::sort_sal(int year) const
{
  TSystemisamfile saldi(LF_SALDI);  saldi.open(_excllock);
  TLocalisamfile rmov(LF_RMOV);
  TLocalisamfile causali(LF_CAUSALI);
  TLocalisamfile mov(LF_MOV);
  TSaldo_agg sal;

  int gruppo, conto;
  long oldnumreg = 0L, sottoconto;
  TString msg("Riordino archivio saldi ditta ");
  msg << _codditta;
  msg << " in corso\nLettura archivio movimenti..."; 
  TProgind prnd(rmov.items(),msg, FALSE,TRUE,30);

  causali.zero();
  mov.setkey(1);
  rmov.first(); 
  sal.reset();
  sal.set_anno_es(year);
  sal.clear_saldi(year);
  long numreg = 0L;
  tiposal tsal = normale;
  bool provvis = FALSE;
  TDate datareg;
  
  while (!rmov.eof())
  {
    if (year == rmov.get_int(RMV_ANNOES))
    {
      numreg = rmov.get_long(RMV_NUMREG);
      
      gruppo = rmov.get_int(RMV_GRUPPO);
      conto = rmov.get_int(RMV_CONTO);
      sottoconto = rmov.get_long(RMV_SOTTOCONTO);                     
      bool scaricato = FALSE;
      
      if (numreg != oldnumreg)
      {
        if (oldnumreg !=0)
        {
          if (sal.items() > 0)
            sal.registra();
        }
        oldnumreg = numreg;
        mov.zero();
        mov.put(MOV_NUMREG, numreg);
        mov.read();
        CHECK(mov.good(),"Archivi movimenti e righe inconsistenti");

        causali.zero();
        const char* codcaus = mov.get(MOV_CODCAUS); 
        
        tsal = normale;
        if (*codcaus)   // cerca causale per determinare il tipoo del saldo
        {
          causali.put(CAU_CODCAUS, codcaus);
          const int err = causali.read();
          if (err == NOERR)
          {
            const char ac = causali.get_char(CAU_MOVAP);
            if (ac == 'A') 
              tsal = apertura;
            else 
              if (ac == 'C') 
                tsal = chiusura;
          }  
        }

        scaricato = mov.get_bool(MOV_SCARCON);
        provvis   = mov.get(MOV_PROVVIS).not_empty();
        datareg   = mov.get_date(MOV_DATAREG);

        sal.reset();
        sal.set_anno_es(year);
        sal.set_tipo_saldo(tsal);
        sal.set_movprovv(provvis);
        sal.set_data_ulmov(datareg);
        sal.set_num_ulmov(oldnumreg);
      }
      const char sezione = rmov.get(RMV_SEZIONE)[0];
      real importo(rmov.get(RMV_IMPORTO));

      sal.aggiorna(gruppo, conto, sottoconto, importo, sezione, TRUE, scaricato);
    }
    rmov.next();
    prnd.addstatus(1);
    do_events();
  }

  if (sal.items() > 0)
    sal.registra();

  saldi.close();
}


void TConversione_archivi::convert_saldi() const
// Effettua il ricalcolo saldi per tutti gli esercizi della ditta corrente
{
  TTable esc("ESC");

  for (esc.first();esc.good();esc.next())
  {
    const int year = atoi(esc.get("CODTAB"));
    if (year == 0) continue;
      sort_sal(year);
  }
}

///////////////////////////////////////////////////////////
// Programma di conversione archivi speciale
///////////////////////////////////////////////////////////

int main(int argc,char** argv)
{
  const int r = (argc > 1) ? atoi(argv[1]) : 0;
  
  if (r < 0 || r > 13)
  {
    error_box(usage);
    return 100;
  }
  else
    if (r==0)
    {
      TConversione_xbase a;
      a.run(argc,argv, "Conversione archivi di xBase");
    }
    else
    {
      TConversione_archivi a ;
      a.run(argc, argv, "Conversione archivi");
    }

  return 0;
}

