// Chiusura/Apertura Conti

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

#include "cglib.h"
#include "cg4.h"
#include "cg4600.h"
#include "cg2101.h"

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

bool mask_datac    (TMask_field&, KEY);
bool mask_dataap   (TMask_field&, KEY);
bool mask_distinti (TMask_field&, KEY);
bool attivo_passivo(TMask_field&, KEY);
bool costi_ricavi  (TMask_field&, KEY);   

#define MAX 98

class CG4600_application : public TApplication
{
  friend bool mask_datac    (TMask_field&, KEY);
  friend bool mask_dataap   (TMask_field&, KEY);
  friend bool mask_distinti (TMask_field&, KEY);
  
  TTable*         _reg; 
  TRelation*      _rel;
  TMovimentoPN*   _pn;
  TLocalisamfile* _saldi;
  TRectype*       _rec;
  TLocalisamfile* _mov;
  TCursor*        _cur;
  TSaldo_agg*     _sld;
  TSaldo*         _sale;   
  TProgind*       _prog;  
  TConto          _tcbilch,_tcproper,_tcbilap,_tcutilp,_tcperdp,_tcutile,_tcperde, _conto_corrente;

  real    _saldo, _totale_saldo, _capitale_netto;
  int     _annoesch, _annoesap;
  long    _numreg;
  TDate   _dataregap, _dataregch, _datacompch, _datacompap;
  TString _codcausap, _codcausch;
  
public:           
  TTable* _esc;
  
  virtual bool create();
  virtual bool destroy();
  virtual bool menu(MENU_TAG m);
  void costi ();
  void ricavi();
  void chiudi_attivita();
  void chiudi_passivita();
  void chiudi_conti_ordine();                                              
  void apri_attivita();
  void apri_passivita();     
  void apri_conti_ordine();
  void rmov_proper (int, long, TDate&, TRectype&, TConto&, real&, bool);
  void ultima_registrazione();
  void compila_testata(int anno,TDate& datareg,TString& codcaus,TDate& datacomp);
  void chiusura_conto_economico();
  void chiusura_conto_patrimoniale();
  void apertura_capitale_netto();
  bool  set();
  //    bool  epilogo_conti();   
  void data_competenza(int anno,TDate& datacomp);
  
  CG4600_application() {}
};

CG4600_application& app() { return (CG4600_application&) main_app(); }
                                      
HIDDEN bool abilita_anni(TMask& m, KEY k)
{
  if (k == K_SHIFT+K_F12)
  { 
    m.enable(F_ANNOCH);
    m.enable(F_ANNO);
  }
  
  return TRUE;
}
                                         
HIDDEN bool anni_contigui (int annoch, int annoap)
{
  TString16 dep(format("%04d", annoch));
    
  TTable esc ("ESC");
    
  esc.zero();
  esc.put("CODTAB", dep);
  esc.read();
  esc.next();
  int anno = atoi(esc.get("CODTAB"));
  if (anno != annoap)
    return warning_box("I due esercizi indicati non risultano contigui");
  
  return TRUE;
}

HIDDEN TRectype& cerca_esercizio(int anno)
{
//  TTable TabEs ("ESC"); 
  TTable& TabEs = *(app()._esc); 
  TString16 dep (format("%04d", anno));
  
  TabEs.zero();
  TabEs.put("CODTAB", dep);
  if (TabEs.read() == NOERR)
    return TabEs.curr();
  else
    warning_box("Esercizio non presente in tabella esercizi");
    
  TabEs.zero();
  
  return TabEs.curr();
}
                                         
bool mask_datac (TMask_field& f, KEY k)
{ 
  //TTable TabEs ("ESC");
  TTable TabReg("REG");
  TString annos (4);
  int anno = 0;;
  bool ok = TRUE;
  TRectype TabEsch(LF_TAB);
  TRectype TabEsap(LF_TAB);
  int annoch = 0;
  int annoap = 0;
    
  if ( (k == K_ENTER) && f.to_check(k) )
  {                                          
    annoch = f.mask().get_int(F_ANNOCH);
    annoap = f.mask().get_int(F_ANNO);                                        
    
    if (!anni_contigui(annoch,annoap))
      return FALSE;
          
    TabEsch = cerca_esercizio(annoap);
    TDate inizio  = TabEsch.get_date("D0");
    TDate fine    = TabEsch.get_date("D1");
    TDate scarico = TabEsch.get_date("D2");

    TabEsap = cerca_esercizio(annoch);
    TDate iniziop = TabEsap.get_date("D0");                     
    TDate finep   = TabEsap.get_date("D1");   
    TDate data    = f.get();
/*  
    TabEs.last();
    TDate inizio  = TabEs.get_date("D0");
    TDate fine    = TabEs.get_date("D1");
    TDate scarico = TabEs.get_date("D2");
    TabEs.prev();
    TDate iniziop = TabEs.get_date("D0");                     
    TDate finep   = TabEs.get_date("D1");   
    TDate data    = f.get();
*/    
    TString istr = inizio.string();
    TString fstr = fine.string();
    
    TString ipstr = iniziop.string();
    TString fpstr = finep.string();
    
    TString scastr = scarico.string();
    
    TString datastr = f.get();
    
    if (data < finep)
    {
      f.warning_box ("La data di chiusura non puo' essere inferiore alla data di fine esercizio precedente");
      return FALSE;
    }
    if (data > fine)
    {
      f.warning_box ("La data di chiusura non puo' essere superiore alla data di fine esercizio in corso");
      return FALSE;
    }
    if ( scarico.ok() && (data <= scarico) )
    {
      f.warning_box ("La data di chiusura non puo' essere inferiore o uguale alla data di scarico"); 
      return FALSE;
    }
    if ( (data >= inizio) && (data <= fine) ) //la data di chiusura e' cioe' relativa all'esercizio in corso   
      anno = fine.year();
    else if ( (data >= iniziop) && (data <= finep) ) //la data di chiusura e' cioe' relativa all'esercizio precedente 
           anno = finep.year();
    
    TabReg.zero();
    annos = format ("%04d", anno);
    TabReg.put ("CODTAB", annos);
    TRectype r (TabReg.curr());
    TabReg.read(_isgteq);
    for (; !TabReg.eof(); TabReg.next())
    {
      if (TabReg.curr() != r) break;
      
      int tiporeg = TabReg.get_int("I0");
      if (tiporeg == 5)
      {
        TDate datast = TabReg.get_date("D3");
        if (data < datast.string())
        {
          ok = FALSE;
          break;
        }  
      }     
    }
    if (!ok)
    {
      f.warning_box("La data di chiusura non puo' essere inferiore alla data ultima stampa bollato"); 
      return FALSE;
    }
  }     
  return TRUE;
}

bool mask_dataap (TMask_field& f, KEY k)
{
  TTable TabEs ("ESC");
  TTable TabReg("REG"); 
  int anno = 0;
  TString annos (4);
  bool ok = TRUE;            
  TRectype TabEsch(LF_TAB);
  TRectype TabEsap(LF_TAB);
  int annoch = 0;
  int annoap = 0;

  if ( (k == K_ENTER) && f.to_check(k) )
  { 
    annoch = f.mask().get_int(F_ANNOCH);
    annoap = f.mask().get_int(F_ANNO);                                        
    
    if (!anni_contigui(annoch,annoap))
      return FALSE;
          
    TabEsch = cerca_esercizio(annoap);
    TDate inizio  = TabEsch.get_date("D0");
    TDate fine    = TabEsch.get_date("D1");
    TDate scarico = TabEsch.get_date("D2");

    TabEsap = cerca_esercizio(annoch);
    TDate iniziop = TabEsap.get_date("D0");                     
    TDate finep   = TabEsap.get_date("D1");   
    TDate data    = f.get();  
/*  
    TabEs.last();
    TDate inizio  = TabEs.get_date("D0");
    TDate fine    = TabEs.get_date("D1");
    TDate scarico = TabEs.get_date("D2");
    TabEs.prev();
    TDate iniziop = TabEs.get_date("D0");
    TDate finep   = TabEs.get_date("D1");
    TDate data    = f.get();
*/    
    TString istr = inizio.string();
    TString fstr = fine.string();
    
    TString ipstr = iniziop.string();
    TString fpstr = finep.string();
    
    TString scastr = scarico.string();
    
    TString datastr = f.get();

    if (data < inizio)
    {
      f.warning_box ("La data di apertura non puo' essere inferiore alla data di inizio esercizio in corso");
      return FALSE;
    }
    if (data > fine)
    {
      f.warning_box ("La data di apertura non puo' essere superiore alla data di fine esercizio in corso");
      return FALSE;
    }
    if ( scarico.ok() && (data <= scarico) )
    {
      f.warning_box ("La data di apertura non puo' essere inferiore o uguale alla data di scarico"); 
      return FALSE;
    }
    
    if ( (data >= inizio) && (data <= fine) ) //la data di apertura e' cioe' relativa all'esercizio in corso   
      anno = fine.year();
    else if( (data >= iniziop) && (data <= finep) ) //la data di apertura e' cioe' relativa all'esercizio precedente 
           anno = finep.year();
    
    TabReg.zero();
    annos = format ("%04d", anno);
    TabReg.put ("CODTAB", annos);
    TRectype r (TabReg.curr());
    TabReg.read(_isgteq);
    for (; !TabReg.eof(); TabReg.next())
    {
      if (TabReg.curr() != r) break;
      
      int tiporeg = TabReg.get_int("I0");
      if (tiporeg == 5)
      {
        TDate datast = TabReg.get_date("D3");
        if (data < datast)
        {
          ok = FALSE;
          break;
        }  
      }     
    }
    if (!ok)
    {
      f.warning_box("La data di apertura non puo' essere inferiore alla data ultima stampa bollato"); 
      return FALSE;
    }
  }     
  return TRUE;
}  

bool mask_distinti (TMask_field& f, KEY k)
{
  int idg,idc,ids,idg1,idc1,ids1;

  if (k == K_ENTER)
  {
    idg = 108;
    idc = 109;
    ids = 110;

    for (int i = 0; i < 7; i++)
    {
      int  g = f.mask().get_int(idg);
      int  c = f.mask().get_int(idc);
      long s = f.mask().get_long(ids);
      
      idg1 = idg;
      idc1 = idc;
      ids1 = ids;
      
      for (int j = i+1; j < 7; j++)
      {
        idg1 = idg1 + 3;
        idc1 = idc1 + 3;
        ids1 = ids1 + 3;
        
        int  gruppo = f.mask().get_int(idg1);
        int  conto  = f.mask().get_int(idc1);
        long sottoc = f.mask().get_long(ids1);
        
        if ((g == gruppo)&&(c == conto)&&(s == sottoc))
        {
          f.warning_box("Nessun sottoconto puo' essere ripetuto!");
          return FALSE;
        }
      }
      
      idg = idg + 3;
      idc = idc + 3;
      ids = ids + 3;
      
    }   
  }
  return TRUE;
}

bool attivo_passivo (TMask_field& f, KEY k)
{
  TLocalisamfile pcon (LF_PCON);

  if (k == K_ENTER) 
  {
    int g,c;
    int id = f.dlg();
    
    if (id == F_UTILPC)
      g = f.mask().get_int(F_UTILPG);
    else
      if (id == F_PERDPC)
        g = f.mask().get_int(F_PERDPG);
        
    c = atoi(f.get());
    
    pcon.setkey(1);
    pcon.zero();
    pcon.put(PCN_GRUPPO, g);
    pcon.put(PCN_CONTO,  c);
    if (pcon.read() == NOERR)
    {
      int indbil = pcon.get_int(PCN_INDBIL);
      if (indbil != 1 && indbil != 2 && indbil != 5)
        return f.warning_box("Indicatore di bilancio errato");
    }      
  }     
  return TRUE;
}  

bool costi_ricavi (TMask_field& f, KEY k)
{
  TLocalisamfile pcon (LF_PCON);

  if (k == K_ENTER) 
  {
    int g,c;
    int id = f.dlg();
    
    if (id == F_UTILEC)
      g = f.mask().get_int(F_UTILEG);
    else
      if (id == F_PERDEC)
        g = f.mask().get_int(F_PERDEG);
        
    c = atoi(f.get());
    
    pcon.setkey(1);
    pcon.zero();
    pcon.put(PCN_GRUPPO, g);
    pcon.put(PCN_CONTO,  c);
    if (pcon.read() == NOERR)
    {
      int indbil = pcon.get_int(PCN_INDBIL);
      if (indbil != 3 && indbil != 4)
        return f.warning_box("Indicatore di bilancio errato");
    }      
  }     
  return TRUE;
}  

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

  _rel   = new TRelation (LF_PCON);

  _cur   = new TCursor(_rel,"((GRUPPO!=\"\")&&(CONTO!=\"\")&&(SOTTOCONTO==\"\"))",1);
  
  _pn    = new TMovimentoPN();
  _saldi = new TLocalisamfile (LF_SALDI);
  _rec   = new TRectype(LF_SALDI);
  _mov   = new TLocalisamfile (LF_MOV);
  _esc   = new TTable ("ESC");
  _reg   = new TTable ("REG");
  _sld   = new TSaldo_agg();
  _sale  = new TSaldo();
         
  _capitale_netto = ZERO;
       
  dispatch_e_menu (BAR_ITEM(1));

  return TRUE;
}

bool CG4600_application::destroy()
{
  delete _saldi;
  delete _sale;
  delete _mov;
  delete _esc;
  delete _reg;
  delete _pn;
  delete _rel;
  delete _cur;
  delete _sld;
  delete _rec;
  
  return TApplication::destroy();
}

void CG4600_application::ultima_registrazione()
{
  long numregmov;

  _mov->setkey(1);                        //Leggo il numero di registrazione
  _mov->last();                           //dell'ultimo record di mov, e lo 
  numregmov = _mov->get_long(MOV_NUMREG); //incremento di uno per ottenere
  _numreg    = numregmov + 1;             //un numero di registrazione 
                                          //sicuramente non esistente.
}

void CG4600_application::data_competenza(int anno, TDate& datacomp)
{
  TString16 dep (format("%04d", anno));
  
  _esc->zero();
  _esc->put("CODTAB", dep);
  if (_esc->read() == NOERR)
    datacomp = _esc->get_date("D1");
}

bool CG4600_application::set()
{
  TTable TabEs ("ESC");
  TMask m ("cg4600a");
  KEY     tasto;
  int     gbilch, cbilch , gproper, cproper, gbilap, cbilap, gutilp;
  int     cutilp, gperdp, cperdp, gutile, cutile, gperde, cperde;
  long    sbilch, sproper, sbilap, sutilp, sperdp, sutile, sperde;


  TConfig conf(CONFIG_DITTA);
  
  m.set(F_CHIUSURA, conf.get("CoCaCh"));
  m.set(F_APERTURA, conf.get("CoCaAp"));
  
  TabEs.last();
  int   annoap   = TabEs.get_int ("CODTAB"); 
  TDate inizio = TabEs.get_date("D0"); //data inizio es. in corso
  TabEs.prev();
  int   annoch   = TabEs.get_int ("CODTAB");
  TDate fine   = TabEs.get_date("D1"); //data fine es. precedente
  m.set(F_ANNO,   annoap);
  m.set(F_ANNOCH, annoch);
  m.set(F_DATAC, fine.string());
  m.set(F_DATAAP,inizio.string());  
  
  m.set(F_BILCHG,  conf.get("CsBiChG"));
  m.set(F_BILCHC,  conf.get("CsBiChC"));
  m.set(F_BILCHS,  conf.get("CsBiChS"));
  m.set(F_PROPERG, conf.get("CsPrPeG"));
  m.set(F_PROPERC, conf.get("CsPrPeC"));
  m.set(F_PROPERS, conf.get("CsPrPeS"));
  m.set(F_BILAPG,  conf.get("CsBiApG"));
  m.set(F_BILAPC,  conf.get("CsBiApC"));
  m.set(F_BILAPS,  conf.get("CsBiApS"));
  m.set(F_UTILPG,  conf.get("CsUeCpG"));
  m.set(F_UTILPC,  conf.get("CsUeCpC"));
  m.set(F_UTILPS,  conf.get("CsUeCpS"));
  m.set(F_PERDPG,  conf.get("CsPeCpG"));
  m.set(F_PERDPC,  conf.get("CsPeCpC"));
  m.set(F_PERDPS,  conf.get("CsPeCpS"));
  m.set(F_UTILEG,  conf.get("CsUeCeG"));
  m.set(F_UTILEC,  conf.get("CsUeCeC"));
  m.set(F_UTILES,  conf.get("CsUeCeS"));
  m.set(F_PERDEG,  conf.get("CsPeCeG"));
  m.set(F_PERDEC,  conf.get("CsPeCeC"));
  m.set(F_PERDES,  conf.get("CsPeCeS"));
  
  m.set_handler (F_DATAC,  mask_datac);
  m.set_handler (F_DATAAP, mask_dataap);
  m.set_handler (F_PERDES, mask_distinti);
  m.set_handler (F_UTILPC, attivo_passivo);
  m.set_handler (F_PERDPC, attivo_passivo);
  m.set_handler (F_UTILEC, costi_ricavi);
  m.set_handler (F_PERDEC, costi_ricavi);
  m.set_handler (abilita_anni);
  
  tasto = m.run();

  if (tasto == K_ENTER)
  {
    _annoesch   = m.get_int(F_ANNOCH);
    _annoesap   = m.get_int(F_ANNO);
    _dataregch  = m.get     (F_DATAC);
    _codcausch  = m.get     (F_CHIUSURA);
    _dataregap  = m.get     (F_DATAAP);
    _codcausap  = m.get     (F_APERTURA);  
    data_competenza(_annoesch,_datacompch);  // Modifica del 28-11-95 per la data
//    data_competenza(_annoesap,_datacompap);  // di competenza
    gbilch      = m.get_int (F_BILCHG);
    cbilch      = m.get_int (F_BILCHC);
    sbilch      = m.get_long(F_BILCHS);
    gproper     = m.get_int (F_PROPERG);
    cproper     = m.get_int (F_PROPERC);
    sproper     = m.get_long(F_PROPERS);
    gbilap      = m.get_int (F_BILAPG);
    cbilap      = m.get_int (F_BILAPC);
    sbilap      = m.get_long(F_BILAPS);
    gutilp      = m.get_int (F_UTILPG);
    cutilp      = m.get_int (F_UTILPC);
    sutilp      = m.get_long(F_UTILPS);
    gperdp      = m.get_int (F_PERDPG);
    cperdp      = m.get_int (F_PERDPC);
    sperdp      = m.get_long(F_PERDPS);
    gutile      = m.get_int (F_UTILEG);
    cutile      = m.get_int (F_UTILEC);
    sutile      = m.get_long(F_UTILES);
    gperde      = m.get_int (F_PERDEG);
    cperde      = m.get_int (F_PERDEC);
    sperde      = m.get_long(F_PERDES);         

    _tcbilch.set (gbilch,cbilch,sbilch);
    _tcproper.set(gproper,cproper,sproper);
    _tcbilap.set (gbilap,cbilap,sbilap);
    _tcutilp.set (gutilp,cutilp,sutilp);
    _tcperdp.set (gperdp,cperdp,sperdp);
    _tcutile.set (gutile,cutile,sutile);
    _tcperde.set (gperde,cperde,sperde);

    long cicli = (_cur->items() * 8) + 4;
    _prog  = new TProgind(cicli,"Chiusura/Apertura conti in corso... Prego attendere",FALSE);

    //ultima_registrazione();
    //    anno_ese_precedente();
    
    _numreg = 0;
    
    (*_cur) = 0L;

    _sld->set_anno_es(_annoesch);
    _sld->set_movprovv(FALSE);
    _sld->set_movap(FALSE);
    
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    costi ();

    //_sld->reset();        //Azzera la tabella dei conti dell'oggetto TSaldo_agg
    //ultima_registrazione();
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;

    ricavi();
    //_sld->reset();

    chiusura_conto_economico();
    _totale_saldo = ZERO;
    //_sld->reset();

    //ultima_registrazione();
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;

    chiudi_attivita();
    //_sld->reset();

    //ultima_registrazione();
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;
    
    chiudi_passivita();
    //_sld->reset();   
    
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;
    
    chiudi_conti_ordine();
    
    chiusura_conto_patrimoniale();
    _totale_saldo = ZERO;
  
    _sld->set_anno_es(_annoesap);
    _sld->set_movap(TRUE);    
    _sld->set_movimentato(TRUE);
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;

    apri_attivita();
    
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;

    apri_passivita();
    
//    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
    *_cur = 0l;

    apri_conti_ordine();

    apertura_capitale_netto();
    
    _sld->registra();
    
    delete _prog;
    
    message_box("Apertura/chiusura conti completata");
    
    return FALSE;
  }                              //K_ENTER
  return FALSE;
}

void CG4600_application::compila_testata(int annoes,TDate& datareg,TString& codcaus,TDate& datacomp)
{
  _pn->lfile().zero(); 
  _pn->lfile().put(MOV_ANNOES,   annoes);     //Viene generato un movimento
  _pn->lfile().put(MOV_DATAREG,  datareg);    //a rottura di conto
  _pn->lfile().put(MOV_CODCAUS,  codcaus);    
  _pn->lfile().put(MOV_NUMREG,   _numreg); 
  _pn->lfile().put(MOV_DATACOMP, datacomp);
}

void CG4600_application::rmov_proper(int anno,long numrig,TDate& datareg,TRectype& rmov,                                    
                                     TConto& tc,real& tot_saldo,bool sezione_opposta)
{
  char sez_rmov = ' ';
  char sezione  = ' ';  
  real totale = tot_saldo;

  rmov.zero();
  rmov.put(RMV_ANNOES,     anno);
  rmov.put(RMV_NUMREG,     _numreg); 
  rmov.put(RMV_NUMRIG,     numrig);
  rmov.put(RMV_DATAREG,    datareg);
  rmov.put(RMV_GRUPPO,     tc.gruppo());
  rmov.put(RMV_CONTO,      tc.conto());
  rmov.put(RMV_SOTTOCONTO, tc.sottoconto());
  
  if (totale > ZERO)
  {       
    sez_rmov  = 'A';
    sezione   = 'D';
  }
  else
    if (totale < ZERO)
    {
      sez_rmov = 'D';
      sezione  = 'A';
      totale   = -totale;
    }
  
  if (sezione_opposta)
  {
    rmov.put(RMV_SEZIONE,    sez_rmov);
    _sld->aggiorna(tc,TImporto(sez_rmov,totale)); //Aggiorno anche i saldi con
                                                  // l'oggetto TSaldo_agg
  }
  else
  {
    rmov.put(RMV_SEZIONE,    sezione);
    _sld->aggiorna(tc,TImporto(sezione,totale)); //Aggiorno anche i saldi con 
                                                 //l'oggetto TSaldo_agg
  }
  rmov.put(RMV_IMPORTO,    totale);
}

void CG4600_application::costi()
{                                   
  bool      compila_mov = TRUE;
  long      s;
  char      sez_rmov = ' ', sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0; 
  
  _totale_saldo = ZERO;
  tot_saldo     = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int     indbil = _cur->curr().get_int(PCN_INDBIL);
    int     g      = _cur->curr().get_int(PCN_GRUPPO);
    int     c      = _cur->curr().get_int(PCN_CONTO);
    TString tmcf   = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
    
    if (indbil == 3)
    { 
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      (*_rec) = _saldi->curr();
      
      j      = 0;
      numrig = 0;
      
      for (_saldi->read(); ; _saldi->next())
      {
        _saldo = ZERO;
        
        if (_saldi->curr() > (*_rec) || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesch,numrig,_dataregch,_pn->cg(j),_tcproper,tot_saldo,FALSE);
            
            tot_saldo = ZERO;
          }
          break;
        }

        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 1 Chiusura Costi
          compila_mov = FALSE;
        }

        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        //sale.calcola_ultima_immissione(_annoesch,0,g,c,s,indbil);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();

        if (_saldo.is_zero()) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).

          //      numrig++;
          if (tot_saldo != ZERO)
            rmov_proper (_annoesch,numrig,_dataregch,_pn->cg(j),_tcproper,tot_saldo,FALSE);
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
          
          j      = 0;
          numrig = 1;
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 1 Chiusura Costi
          compila_mov = FALSE;
          tot_saldo   = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          sez_rmov   = 'A';       // finito di leggere i sottoconti, oppure
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            sez_rmov   = 'D';
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
        
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesch);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregch); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sez_rmov);   //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sez_rmov,_saldo));    //l'oggetto TSaldo_agg
          j++;
        }
        if (_saldi->eof()) break;
      }                        //for saldi
      if (j >= 1)
      {
        _pn->write();
        //_sld->registra();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                          // if (indbil == 3)                   
  }                            // for pcon
}

void CG4600_application::ricavi()
{ 
  bool      compila_mov = TRUE;
  long      s;
  char      sez_rmov = ' ', sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0;
    
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int  indbil  = _cur->curr().get_int(PCN_INDBIL);
    int  g       = _cur->curr().get_int(PCN_GRUPPO);
    int  c       = _cur->curr().get_int(PCN_CONTO);
    TString tmcf = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
        
    if (indbil == 4)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      (*_rec) = _saldi->curr();
      
      j      = 0;
      numrig = 0;

      for (_saldi->read(); ; _saldi->next())
      {
        _saldo = ZERO;

        if (_saldi->curr() > (*_rec) || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesch,numrig,_dataregch,_pn->cg(j),_tcproper,tot_saldo,FALSE);
            
            tot_saldo = ZERO;
          }
          break;
        }
      
        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 2 Chiusura Ricavi
          compila_mov = FALSE;
        }
      
        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        //sale.calcola_ultima_immissione(_annoesch,0,g,c,s,indbil);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();

        if (_saldo.is_zero()) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).

          //      numrig++;
          if (tot_saldo != ZERO)
            rmov_proper (_annoesch,numrig,_dataregch,_pn->cg(j),_tcproper,tot_saldo,FALSE);
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.

          j      = 0;
          numrig = 1;        
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 2 Chiusura Ricavi         
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          sez_rmov   = 'A';       // finito di leggere i sottoconti, oppure
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
         if (sezione == 'A')      // alla somma, mandando a zero   
         {                        // il saldo di quel movimento.
           sez_rmov   = 'D';
           tot_saldo -= _saldo;
           _totale_saldo -= _saldo; 
         }
        
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesch);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregch); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sez_rmov);   //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sez_rmov,_saldo));    //l'oggetto TSaldo_agg
          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        //_sld->registra();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                        // if (indbil == 4)                   
  }                          // for pcon
}

void CG4600_application::chiusura_conto_economico()
{
  _capitale_netto = _totale_saldo; //Mi serve per fare la riapertura del capitae netto
  
  if (_totale_saldo > ZERO)
  {
    int j;

    //Compilo la testata per perdite di es. c.economico a Profitti e Perdite
    //Chiusura conto economico
    
    j = 0;
    ultima_registrazione();
    compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);  //Reg. 3 Chiusura Conto Economico  

    TRectype& rmov1 = _pn->cg(j);
    long numrig = 1;
    rmov_proper(_annoesch,numrig,_dataregch,rmov1,_tcproper,_totale_saldo,TRUE);
    numrig++;
    j++;
    TRectype& rmov2 = _pn->cg(j);
    rmov_proper(_annoesch,numrig,_dataregch,rmov2,_tcperde,_totale_saldo,FALSE);
    
    _pn->write();          
    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.    
    //_sld->registra();
    //_sld->reset();

    //Compilo la testata per perdite di es. c.patrimon. a Perdita di es. c. econom.
    //Chiusura capitale netto

    j = 0;
    ultima_registrazione();

    compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);  //Reg. 4 Chiusura Capitale netto
    
    TRectype& rmov3 = _pn->cg(j);
    numrig = 1;
    rmov_proper(_annoesch,numrig,_dataregch,rmov3,_tcperde,_totale_saldo,TRUE);
    numrig++;
    j++;
    TRectype& rmov4 = _pn->cg(j);
    rmov_proper(_annoesch,numrig,_dataregch,rmov4,_tcperdp,_totale_saldo,FALSE);

    _pn->write();
    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.    
  }
  else
    if (_totale_saldo < ZERO)
    {
      int j;

      //Compilo la testata per Profitti e perdite a Utile di es. c.economico
      //Chiusura conto economico

      j = 0;
      ultima_registrazione();
      compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);    //Reg. 3 Chiusura Conto Economico

      TRectype& rmov1 = _pn->cg(j);
      long numrig = 1;
      rmov_proper(_annoesch,numrig,_dataregch,rmov1,_tcutile,_totale_saldo,FALSE);
      numrig++;
      j++;
      TRectype& rmov2 = _pn->cg(j);
      rmov_proper(_annoesch,numrig,_dataregch,rmov2,_tcproper,_totale_saldo,TRUE);

      _pn ->write();         
      _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.      
      //_sld->registra();
      //_sld->reset();
      
      //Compilo la testata per Utile di es. c.economico a Utile di es. c.patrimoniale
      //Chiusura capitale netto

      j = 0;
      ultima_registrazione();
      compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);   //Reg. 4 Chiusura Capitale netto
      
      TRectype& rmov3 = _pn->cg(j);
      numrig = 1;
      rmov_proper(_annoesch,numrig,_dataregch,rmov3,_tcutilp,_totale_saldo,FALSE);
      numrig++;
      j++;
      TRectype& rmov4 = _pn->cg(j);
      rmov_proper(_annoesch,numrig,_dataregch,rmov4,_tcutile,_totale_saldo,TRUE);

      _pn ->write();         
      _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.      
    }
}

void CG4600_application::chiudi_attivita()
{     
  bool      compila_mov = TRUE;
  long      s;
  char      sez_rmov = ' ', sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0; 
    
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int  indbil  = _cur->curr().get_int(PCN_INDBIL);
    int  g       = _cur->curr().get_int(PCN_GRUPPO);
    int  c       = _cur->curr().get_int(PCN_CONTO);
    TString tmcf = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
         
    if (indbil == 1)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
//      TRectype rec (_saldi->curr());
      *_rec = _saldi->curr();      
      
      j      = 0; 
      numrig = 0;
      
      for (_saldi->read(_isgteq); ; _saldi->next())
      {
        if (_saldi->curr() > (*_rec) || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura
            
            tot_saldo = ZERO;
          }
          break;
        }

        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 5 Chiusura Attivita'
          compila_mov = FALSE;
        }

        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        //sale.calcola_ultima_immissione(_annoesch,0,g,c,s,indbil);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();
        //_saldo = ZERO;
        const int dbkey = _saldi->getkey();
        _saldi->setkey(1);
//        TString sldstr = _saldo.string();
        
        if (_saldo == ZERO) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).

          //      numrig++;
          if (tot_saldo != ZERO)
            rmov_proper (_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;      
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 5 Chiusura Attivita'
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          sez_rmov   = 'A';       // finito di leggere i sottoconti, oppure
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            sez_rmov   = 'D';
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
  
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesch);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregch); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sez_rmov);   //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sez_rmov,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        //_sld->registra();
        //_sld->reset();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                        // if (indbil == 1)                   
  }                          // for pcon
}

void CG4600_application::chiudi_passivita()
{     
  bool      compila_mov = TRUE;
  long      s;
  char      sez_rmov = ' ', sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0;
  
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int     indbil = _cur->curr().get_int(PCN_INDBIL);
    int     g      = _cur->curr().get_int(PCN_GRUPPO);
    int     c      = _cur->curr().get_int(PCN_CONTO);
    TString tmcf   = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
    
    if (indbil == 2)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      TRectype rec (_saldi->curr());
      
      j      = 0; 
      numrig = 0;
      
      for (_saldi->read(); ; _saldi->next())
      {
        if (_saldi->curr() > rec || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura
            
            tot_saldo = ZERO;
          }
          break;
        }
      
        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 6 Chiusura Passivita'
          compila_mov = FALSE;
        }
      
        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        //sale.calcola_ultima_immissione(_annoesch,0,g,c,s,indbil);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();
        
        if (_saldo.is_zero()) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).

          //      numrig++;
          if (tot_saldo != ZERO)
            rmov_proper (_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;      
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 6 Chiusura Passivita'         
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          sez_rmov   = 'A';       // finito di leggere i sottoconti, oppure
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            sez_rmov   = 'D';
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
        
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesch); //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregch);  //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);        //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);        //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);        //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sez_rmov); //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);    //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sez_rmov,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        //_sld->registra();
        //_sld->reset();
        j = 0;
        _pn->destroy_rows(_numreg);
      }
    }                        // if (indbil == 2)                   
  }                          // for pcon                
}

void CG4600_application::chiudi_conti_ordine()
{     
  bool      compila_mov = TRUE;
  long      s;
  char      sez_rmov = ' ', sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0; 
    
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int  indbil  = _cur->curr().get_int(PCN_INDBIL);
    int  g       = _cur->curr().get_int(PCN_GRUPPO);
    int  c       = _cur->curr().get_int(PCN_CONTO);
    TString tmcf = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
         
    if (indbil == 5)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
//      TRectype rec (_saldi->curr());
      *_rec = _saldi->curr();      
      
      j      = 0; 
      numrig = 0;
      
      for (_saldi->read(_isgteq); ; _saldi->next())
      {
        if (_saldi->curr() > (*_rec) || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura
            
            tot_saldo = ZERO;
          }
          break;
        }

        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); 
          compila_mov = FALSE;
        }

        s               = _saldi->get_long(SLD_SOTTOCONTO);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();
        const int dbkey = _saldi->getkey();
        _saldi->setkey(1);
        
        if (_saldo == ZERO) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).

          if (tot_saldo != ZERO)
            rmov_proper (_annoesch,numrig,_dataregch,_pn->cg(j),_tcbilch,tot_saldo,FALSE); //Chiusura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;      
          ultima_registrazione();
          compila_testata(_annoesch,_dataregch,_codcausch,_datacompch); //Reg. 5 Chiusura Attivita'
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          sez_rmov   = 'A';       // finito di leggere i sottoconti, oppure
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            sez_rmov   = 'D';
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
  
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesch);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregch); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sez_rmov);   //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sez_rmov,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                        // if (indbil == 1)                   
  }                          // for pcon
}

void CG4600_application::chiusura_conto_patrimoniale()
{
  int  j;
  long numrig;
            
  if (_totale_saldo > ZERO)
  {
    //Compilo la testata per Bilancio di chiusura a Perdita di es. c. patrimoniale
    //Chiusura conto patrimoniale

    j = 0;
    ultima_registrazione();
    compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);   //Reg. 7 Chiusura Conto Patrimoniale
    
    TRectype& rmov1 = _pn->cg(j);
    numrig = 1;
    rmov_proper(_annoesch,numrig,_dataregch,rmov1,_tcutilp,_totale_saldo,FALSE);
    numrig++;
    j++;
    TRectype& rmov2 = _pn->cg(j);
    rmov_proper(_annoesch,numrig,_dataregch,rmov2,_tcbilch,_totale_saldo,TRUE);

    _pn->write();          
    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.    
    //_sld->registra();

  }
else
  if (_totale_saldo < ZERO)
  {
    //Compilo la testata per Utile di es. c.patrimon. a Bilancio di chiusura
    //Chiusura conto patrimoniale

    j = 0;
    ultima_registrazione();
    compila_testata(_annoesch,_dataregch,_codcausch,_datacompch);    //Reg. 7 Chiusura Conto Patrimoniale
    
    TRectype& rmov1 = _pn->cg(j);
    numrig = 1;
    rmov_proper(_annoesch,numrig,_dataregch,rmov1,_tcbilch,_totale_saldo,TRUE);
    numrig++;
    j++;
    TRectype& rmov2 = _pn->cg(j);
    rmov_proper(_annoesch,numrig,_dataregch,rmov2,_tcperdp,_totale_saldo,FALSE);

    _pn ->write();         
    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.    
    //_sld->registra();
  }
}

void CG4600_application::apri_attivita()
{       
  bool      compila_mov = TRUE;
  long      s;
  char      sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0; 
      
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int  indbil  = _cur->curr().get_int(PCN_INDBIL);
    int  g       = _cur->curr().get_int(PCN_GRUPPO);
    int  c       = _cur->curr().get_int(PCN_CONTO);
    TString tmcf = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
         
    if (indbil == 1)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      TRectype rec (_saldi->curr());
             
      j      = 0;
      numrig = 0;       
      
      for (_saldi->read(); ; _saldi->next())
      {
        if (_saldi->curr() > rec || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Apertura
            
            tot_saldo = ZERO;
          }
          break;
        }

        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 8 Apertura Attivita'
          compila_mov = FALSE;
        }

        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();

        if (_saldo == ZERO) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (tot_saldo != ZERO)
            rmov_proper (_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Chiusura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;      
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 8 Apertura Attivita'
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
  
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesap);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregap); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sezione);    //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sezione,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                        // if (indbil == 1)                   
  }                          // for pcon
}

void CG4600_application::apri_passivita()
{       
  bool      compila_mov = TRUE;
  long      s;
  char      sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0;
    
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int     indbil = _cur->curr().get_int(PCN_INDBIL);
    int     g      = _cur->curr().get_int(PCN_GRUPPO);
    int     c      = _cur->curr().get_int(PCN_CONTO);
    TString tmcf   = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
    
    if (indbil == 2)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      TRectype rec (_saldi->curr());
      
      j      = 0;
      numrig = 0;
      
      for (_saldi->read(); ; _saldi->next())
      {
        if (_saldi->curr() > rec || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Apertura
            
            tot_saldo = ZERO;
          }
          break;
        }
      
        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 9 Apertura Passivita'
          compila_mov = FALSE;
        }
      
        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();

        if (_saldo.is_zero()) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (tot_saldo != ZERO)
            rmov_proper (_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Apertura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 9 Apertura Passivita'          
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')        // ---> Tengo una variabile in cui salvo gli
        {                          // importi trovati sui saldi. Quando ho 
          tot_saldo += _saldo;     // finito di leggere i sottoconti, oppure
          _totale_saldo += _saldo; // quando ho raggiunto un massimo di 99
        }                          // righe di movimento, genero un' altra    
        else                       // riga con importo di sezione opposta   
          if (sezione == 'A')      // alla somma, mandando a zero   
          {                        // il saldo di quel movimento.
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
        
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesap);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregap); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sezione);    //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sezione,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        j = 0;
        _pn->destroy_rows(_numreg);
      }
    }                        // if (indbil == 2)                   
  }                          // for pcon
}

void CG4600_application::apri_conti_ordine()
{       
  bool      compila_mov = TRUE;
  long      s;
  char      sezione = ' ';
  real      tot_saldo;
  long      numrig   = 0;
  TSaldo&   sale     = *_sale;
  int       j        = 0; 
      
  tot_saldo = ZERO;

  TRecnotype items_pcon  = _cur->items();
  
  for (int i = 0; i < items_pcon; i++, ++(*_cur))
  {
    int  indbil  = _cur->curr().get_int(PCN_INDBIL);
    int  g       = _cur->curr().get_int(PCN_GRUPPO);
    int  c       = _cur->curr().get_int(PCN_CONTO);
    TString tmcf = _cur->curr().get    (PCN_TMCF);
    
    _prog->addstatus(1);
         
    if (indbil == 5)
    {
      compila_mov = TRUE;
      
      _saldi->setkey(1);
      _saldi->zero();
      _saldi->put(SLD_ANNOES, _annoesch);
      _saldi->put(SLD_GRUPPO, g);
      _saldi->put(SLD_CONTO,  c);
      
      TRectype rec (_saldi->curr());
             
      j      = 0;
      numrig = 0;       
      
      for (_saldi->read(); ; _saldi->next())
      {
        if (_saldi->curr() > rec || _saldi->eof()) 
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso conto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (j >= 1)
          {
            numrig++;
            if (tot_saldo != ZERO)
              rmov_proper(_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Apertura
            
            tot_saldo = ZERO;
          }
          break;
        }

        if (compila_mov)
        {
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 8 Apertura Attivita'
          compila_mov = FALSE;
        }

        //numrig++;
        s               = _saldi->get_long(SLD_SOTTOCONTO);
        sale.ultima_immissione_bilancio(_annoesch,g,c,s,indbil, 1);
        _saldo          = sale.saldo();

        if (_saldo == ZERO) continue;
        
        numrig++;
        
        if (j >= MAX || _saldi->eof())
        {
          // Aggiungo un ulteriore riga di movimento contenente la somma
          // di tutti i saldi aventi lo stesso sottoconto, indicandola
          // con una sezione opposta al risultato (della somma).
          
          if (tot_saldo != ZERO)
            rmov_proper (_annoesap,numrig,_dataregap,_pn->cg(j),_tcbilap,tot_saldo,TRUE); //Chiusura  
          _pn->write();
          _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
  
          j      = 0;
          numrig = 1;      
          ultima_registrazione();
          compila_testata(_annoesap,_dataregap,_codcausap,_dataregap); //Reg. 8 Apertura Attivita'
          compila_mov = FALSE;
          tot_saldo = ZERO;
        }

        if (_saldo > ZERO)
          sezione = 'D';
        else
          if (_saldo < ZERO)
          {
            sezione = 'A';
            _saldo = -_saldo;
          }

        if (sezione == 'D')       // ---> Tengo una variabile in cui salvo gli
        {                         // importi trovati sui saldi. Quando ho
          tot_saldo += _saldo;    // quando ho raggiunto un massimo di 99
          _totale_saldo += _saldo;
        }                         // righe di movimento, genero un' altra    
        else                      // riga con importo di sezione opposta   
          if (sezione == 'A')     // alla somma, mandando a zero   
          {                       // il saldo di quel movimento.
            tot_saldo -= _saldo;
            _totale_saldo -= _saldo; 
          }
  
        if (!_saldi->eof())
        {
          TRectype& rmov = _pn->cg(j);
          
          rmov.zero();  
          rmov.put(RMV_ANNOES,     _annoesap);  //Compilo una riga di movimento
          rmov.put(RMV_DATAREG,    _dataregap); //per ogni sottoconto che leggo
          rmov.put(RMV_GRUPPO,     g);          //sui saldi. Siccome queste
          rmov.put(RMV_CONTO,      c);          //righe servono per mandare a 0
          rmov.put(RMV_SOTTOCONTO, s);          //il saldo dei movimenti, la
          rmov.put(RMV_SEZIONE,    sezione);    //sezione sara' opposta a 
          rmov.put(RMV_IMPORTO,    _saldo);     //quella letta sui saldi.
          rmov.put(RMV_NUMREG,     _numreg);
          rmov.put(RMV_NUMRIG,     numrig);
          rmov.put(RMV_TIPOC,      tmcf);
          
          TBill tc(g,c,s); 
          _sld->aggiorna(tc,TImporto(sezione,_saldo));    //l'oggetto TSaldo_agg

          j++;
        }
        if (_saldi->eof()) break;
      }                       //for saldi
      if (j >= 1)
      {
        _pn->write();
        j = 0;
        _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.
      }
    }                        // if (indbil == 1)                   
  }                          // for pcon
}

void CG4600_application::apertura_capitale_netto()
{ 
  int numrig;
  
  if (_capitale_netto > ZERO)
  {
    //Compilo la testata per Perdita es. c/to patrimoniale a Bilancio di apertura
    //Apertura capitale netto
    
    int j = 0;
    ultima_registrazione();

    compila_testata(_annoesap,_dataregap,_codcausap,_dataregap);  //Reg. 10 Apertura Capitale netto
    
    TRectype& rmov1 = _pn->cg(j);
    numrig = 1;
    rmov_proper(_annoesap,numrig,_dataregap,rmov1,_tcbilap,_capitale_netto,TRUE);
    numrig++;
    j++;
    TRectype& rmov2 = _pn->cg(j);
    rmov_proper(_annoesap,numrig,_dataregap,rmov2,_tcperdp,_capitale_netto,FALSE);

    _pn->write();          
    _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.    
  }
  else
    if (_capitale_netto < ZERO)
    {
      //Compilo la testata per Bilancio di apertura  a Utile es. c/to patrimoniale
      //Apertura capitale netto
      
      int j = 0;
      ultima_registrazione();

      compila_testata(_annoesap,_dataregap,_codcausap,_dataregap);  //Reg. 10 Apertura Capitale netto
      
      TRectype& rmov1 = _pn->cg(j);
      numrig = 1;
      rmov_proper(_annoesap,numrig,_dataregap,rmov1,_tcbilap,_capitale_netto,TRUE);
      numrig++;
      j++;
      TRectype& rmov2 = _pn->cg(j);
      rmov_proper(_annoesap,numrig,_dataregap,rmov2,_tcutilp,_capitale_netto,FALSE);

      _pn->write();          
      _pn->destroy_rows(_numreg);  //Azzero l'oggetto pn.      
    }
}

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

int cg4600 (int argc, char* argv[])
{
  CG4600_application main_app;
  main_app.run(argc, argv, "Apertura/Chiusura Conti");
  return TRUE;
}







