// 774200.cpp - Calcolo riporti dei Quadri
// 
// Per l'interfaccia vedere 774200.h. 
// Il metodo pubblico che fa tutto il lavoro dalla gestione di
// un singolo quadro e' set().
//
// 774 -1 D  : riporto sul quadro I del dichiarante
//
// 774 -1 S  : livello di studio  oppure
// richiamare la funzione set all' interno
// di ogni programma di gestione quadri.
// 
// ATTENZIONE: 
// Se si aggiungono o tolgono quadri in build_fill_string()
// bisogna cambiare il numero dei quadri.
//
// 15.3.96 Allungata la stringa QCOMP per far spazio ai quadri A1-2-3                
//
#include <applicat.h>
#include <mask.h>
#include <progind.h>
#include <relation.h>
#include <tabutil.h>
#include <utility.h>
#include <config.h>
#include <urldefid.h>     
#include <recarray.h>
#include <xvtility.h>

#include "774200.h"
#include "quadroa.h" 
#include "quadroa3.h"
#include "quadrob.h"
#include "quadrob1.h"
#include "dipend.h"
#include "quadroh.h"
#include "quadroc.h"
#include "quadrod.h"
#include "quadrod1.h"
#include "quadroe.h"
#include "quadroe1.h"
#include "prospe1.h"
#include "quadroe2.h"
#include "quadrif.h"
#include "quadrog.h"
#include "quadrogd.h"
#include "quadrog1.h"
#include "774200a.h"
#include "77lib.h"

// Costanti
#define TIPOQUA "TIPOQUA"

// inizializzato in TRiporti::set() - usato in filter_func()
HIDDEN TRiporti* this_riporti = NULL;

HIDDEN TString80  __tmp;

// Costanti usate per il calcolo dei fogli compilati
const int QB_PERCIPIENTI_PER_FOGLIO  = 16;
const int QC_PERCIPIENTI_PER_FOGLIO  = 27;
const int QD_PERCIPIENTI_PER_FOGLIO  = 22;
const int QDB_PERCIPIENTI_PER_FOGLIO = 22;
const int QD1_PERCIPIENTI_PER_FOGLIO = 27;
const int QE_PERCIPIENTI_PER_FOGLIO  = 27;
const int QE1_PERCIPIENTI_PER_FOGLIO = 25;
const int QE2_PERCIPIENTI_PER_FOGLIO = 13;
const int QF1_PERCIPIENTI_PER_FOGLIO = 13;
const int QF2_PERCIPIENTI_PER_FOGLIO = 13;
const int QGD_PERCIPIENTI_PER_FOGLIO = 13;

HIDDEN long fogli_compilati(const long fisiche, const long nofisiche, const int fisiche_x_foglio, const int nofisiche_x_foglio);
HIDDEN const char* build_fill_string(TString& qcomp);

class TRiporta_quadri : public TApplication
{
    char                _liv;
    TRiporti*   _riporta;
    TMask*              _msk;
    int                 _anno_dic;
    static bool codditta_handler(TMask_field& f, KEY k);
  public:
    virtual bool create();
    virtual bool menu(MENU_TAG m);
    virtual bool destroy();

    TRiporti&    riporta() { return *_riporta; }

    TRiporta_quadri(char livello) : _liv(toupper(livello)) {}
    ~TRiporta_quadri() {}
};

TRiporta_quadri& app() { return (TRiporta_quadri&)main_app(); }

bool TRiporta_quadri::codditta_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB && !(f.mask().is_running()) )
  {
    TString16 codditta;
    codditta << get_firm_770();

    if (codditta != "0")
    {
      f.set(codditta);
      f.check();
    }
  }
  return TRUE;
}

bool TRiporta_quadri::menu(MENU_TAG m)
{
  if (m == BAR_ITEM(1))
    if (_liv == 'D')
    {
      TConfig conf(CONFIG_STUDIO);
      _anno_dic = (int)conf.get_long(ANNO_SEL, NULL);
      _msk->set(F_ANNODIC, _anno_dic);
      KEY tast = _msk->run();
      if (tast != K_ENTER) 
        return FALSE;
      const int annod = (int)_msk->get_long(F_ANNODIC);
      _riporta->riporti_dich(get_firm_770(), annod);
      message_box("Generazione riporti terminata");
    }
  return FALSE;
}

bool TRiporta_quadri::create()
{
  TApplication::create();
  _riporta  = new TRiporti;
  _msk = new TMask("774200a");
  _msk->set_handler(F_CODDITTA, codditta_handler);
  dispatch_e_menu (BAR_ITEM(1));
  return TRUE;
}

bool TRiporta_quadri::destroy()
{
  delete _riporta;
  delete _msk;
  return TApplication::destroy();
}

int riporti_dich(int argc, char* argv[])
{
  TRiporta_quadri a(*argv[2]);
  a.run(argc, argv, "Generazione riporti");
  return 0;
}

const char* build_fill_string(TString& qcomp)
{
// NB cambiare qui il numero dei quadri
  const int NUM_QUADRI = 28;     // sono 29 posizioni perche' parte da 0
  const int agg = NUM_QUADRI - qcomp.len();
  __tmp.cut(agg); 
  __tmp.fill(' ', agg);
  return __tmp;
}

///////////////////////////////////////////////////////////
// TConta_persone
///////////////////////////////////////////////////////////

class TConta_persone
{  
  TRelation _rel;
  TLocalisamfile _base, _basebis;
  long _firm;
  TRectype _totale;
  long _righe, _fisici, _giuridici;
  long _fisici_distinti, _giuridici_distinti;
  
public:
  void sum(TRectype& dst, const TRectype& src) const;
  
  int read_base(const long dich);
  long compute(const char* filter = NULL); 
  TLocalisamfile& base() { return _base; } 
  int read_basebis(const long dich);                      
  TLocalisamfile& basebis() { return _basebis; } 
  
  long persone_fisiche() const { return _fisici; }
  long persone_giuridiche() const { return _giuridici; }
  long righe() const { return _righe; }

  long persone_fisiche_distinte() const { return _fisici_distinti; }
  long persone_giuridiche_distinte() const { return _giuridici_distinti; }
  long persone_distinte() const { return _fisici_distinti + _giuridici_distinti; }
  const TRectype& totale() const { return _totale; }
  
  int fogli_compilati(int fis, int giu = 0) const;
  
  TConta_persone(int logicnum, long firm);
};

TConta_persone::TConta_persone(int logicnum, long firm) 
              : _rel(logicnum), _firm(firm),
                _totale(logicnum), _base(LF_BASE), _basebis(LF_BASEBIS)
{ 
}

void TConta_persone::sum(TRectype& dst, const TRectype& src) const
{
  for (int i = dst.items()-1; i >= 0; i--)
  {              
    const char* name = dst.fieldname(i);
    if (dst.type(name) == _realfld && dst.length(name) >= 9)
    {
      real num = dst.get_real(name);
      num += src.get_real(name);
      dst.put(name, num);
    }
  }
}

int TConta_persone::read_base(const long dich)
{
  _base.setkey(1);
  _base.zero();
  if (dich)
  {
    _base.put("TIPOQUA", COD_QUA_I_DIC);
    _base.put(BSE_CODDITTA, dich);
  }
  else
    _base.put(BSE_CODDITTA, _firm);

  int err = _base.read(_isequal, _lock);
  if (err != NOERR)
    error_box("Immpossibile aggiornare la dichiarazione della ditta %ld.", 
              dich ? dich : _firm);
  return err;
}

int TConta_persone::read_basebis(const long dich)
{
  _basebis.setkey(1);
  _basebis.zero();
  if (dich)
  {
    _basebis.put("TIPOQUA", COD_QUA_I_DIC);
    _basebis.put(BSE_CODDITTA, dich);
  }
  else
    _basebis.put(BSE_CODDITTA, _firm);

  int err = _basebis.read(_isequal, _lock);
  if (err != NOERR)
    error_box("Immpossibile aggiornare la dichiarazione della ditta %ld.", 
              dich ? dich : _firm);
  return err;  
}

long TConta_persone::compute(const char* filter)
{    
  TWait_cursor hourglass;
  TString str(80); 

  TRectype rec(_rel.lfile().num());
  rec.put("CODDITTA", _firm);
  
  TCursor cur(&_rel, filter, 1, &rec, &rec);
  _righe = cur.items();

  _totale.zero();
  
  if (_righe > 0)
  {
    str.cut(0);
    str << "Calcolo riporti " << _rel.lfile().description()
        << " della ditta " << _firm;
  
    TProgind pi(_righe, str, FALSE, TRUE, 60);
   
    TAssoc_array fisici, giuridici;
      
    TRectype& curr = cur.curr();
    long i;
    for (i = 0, cur = 0; i < _righe; i++, ++cur)
    {
      pi.addstatus(1);
      
      if (curr.exist("TIPOA"))
      {
        char tipoa = curr.get_char("TIPOA");
        const TString& cod = curr.get("CODANAGR");
        if (tipoa == 'F')
        { 
          _fisici++;
          fisici.add(cod);
        }  
        else
        {  
          _giuridici++;
          giuridici.add(cod);
        }
      }  
      
      sum(_totale, curr);
    }
    
    _fisici_distinti = fisici.items();
    _giuridici_distinti = giuridici.items();
  }
  else
  {
    _fisici_distinti    = 0;
    _giuridici_distinti = 0;
  }
  
  return _righe;
}

int TConta_persone::fogli_compilati(int fis, int giu) const
{ 
  int fogli = 0;   
  if (_righe > 0)
  {
    if (giu > 0)
    {
      int fogli_fis = int((_fisici - 1) / fis + (_fisici > 0));
      int fogli_giu = int((_giuridici - 1) / giu + (_giuridici > 0));
      fogli = fogli_fis > fogli_giu ? fogli_fis : fogli_giu;
    }
    else
      fogli = int((_righe - 1) / fis + 1);  
  }    
  return fogli;
}

///////////////////////////////////////////////////////////
// TRiporti
///////////////////////////////////////////////////////////

void TRiporti::setta_flag_quadri_comp(const long codditta, const int quadro, const bool almeno_una_riga, TLocalisamfile& basebis, const long dich)
{
/*
  TLocalisamfile basebis(LF_BASEBIS);
  basebis.setkey(1);
  basebis.zero();
  basebis.put(BSE_CODDITTA, codditta);
  if (basebis.read(_isequal, _lock) == NOERR)
  { */
    TString qcomp(basebis.get(BSE_QCOMP)); 
    TString dep(build_fill_string(qcomp));
    qcomp << dep;

    if (almeno_una_riga)
      qcomp[(int)quadro] = 'X';
    else
      qcomp[(int)quadro] = ' ';

    basebis.put(BSE_QCOMP, qcomp);
    basebis.rewrite();
/*  }
  else
    warning_box("Dichiarazione non presente: impossibile registrare il campo Quadri compilati");
*/
//
// Setta flag quadri compilati del dichiarante; cio' va fatto in 3 casi:
//
// 1. dalla gestione dei singoli quadri di una ditta "estinta".
// 2. dal prg "Riporti" del dichiarante.                       
// 3. dalla gestione dei quadri del dichiarante stesso.
// 
  const long codic = sogg_estinto(codditta);
  const long ha_dichiarante = dich ? dich : codic;
  const bool sono_dichiarante = sogg_dic(codditta);
                           
  if (ha_dichiarante || sono_dichiarante)
  {
    const long lRecno=basebis.recno();
    basebis.setkey(1);
    basebis.zero();
    basebis.put("TIPOQUA", COD_QUA_I_DIC);
    basebis.put(BSE_CODDITTA, sono_dichiarante ? codditta : ha_dichiarante);
    if (basebis.read(_isequal, _lock) == NOERR)
    {
      TString qcomp(basebis.get(BSE_QCOMP)); 
      TString dep(build_fill_string(qcomp));
      qcomp << dep;
  
      if (almeno_una_riga)
        qcomp[(int)quadro] = 'X';
      else
        qcomp[(int)quadro] = ' ';
  
      basebis.put(BSE_QCOMP, qcomp);
      basebis.rewrite();   
      basebis.readat(lRecno);
    }
    else
      warning_box("Dichiarazione non presente: impossibile registrare il campo Quadri compilati");
  }
}

void TRiporti::setta_flag_quadro_I(const long codditta, const long dich)
{
  bool compilato = FALSE;          
  TLocalisamfile base    (LF_BASE);  
  TLocalisamfile basebis (LF_BASEBIS);

  base.setkey(1);
  base.zero();
  base.put(BSE_CODDITTA, codditta);
  base.read(_isequal, _lock);

  basebis.setkey(1);
  basebis.zero();
  basebis.put(BSB_CODDITTA, codditta);
  basebis.read(_isequal, _lock);

  TString qcomp(basebis.get(BSE_QCOMP)); 
  TString dep(build_fill_string(qcomp));
  qcomp << dep;
//  TString qcomp (format("%25s", (const char*) app));

// I campi del quadro I sono in parte su base in parte su basebis
  for (int i = 0; i < CAMPI_IB1; i++)
    if (base.get_real(_campi_I1[i]) != ZERO)
    {
      compilato = TRUE;
      break;
    }
  base.reread(_unlock);
  
  if (!compilato)
  {
/*    TLocalisamfile basebis (LF_BASEBIS);
    basebis.setkey(1);
    basebis.zero();
    basebis.put(BSB_CODDITTA, codditta);
    basebis.read();*/
    for (int i = 0; i < CAMPI_IB2; i++)
      if (basebis.get_real(_campi_I2[i]) != ZERO)
      {
        compilato = TRUE;
        break;
      }
  }

  if (compilato)
    qcomp[(int)I] = 'X';
  else
    qcomp[(int)I] = ' ';

  basebis.put(BSE_QCOMP, qcomp);
  basebis.rewrite();
}


HIDDEN bool filter_func (const TRelation * rel)
{
  int   anno,annod;
  annod = this_riporti->_annodic;
  anno  = rel->lfile().get_int(QUH_H1ANNO);
  return anno == annod;
}

bool TRiporti::riporti_dich(const long dich, const int anno)
{       
  long  codditta=0L;
  long  codic=0L;
                         
// Crea il record I "globale" se non c'e'
  enter_dichiar_770(dich, anno, TRUE);
  
  TLocalisamfile base(LF_BASE);
  base.setkey(2);
  base.zero();
  base.put("CODDIC", (long)dich);
//  TRectype dep(base.curr());

// 1. Riporto dai quadri degli estinti al quadro I globale del dichiarante
  for (base.read(); !base.eof(); base.next())
  {
    codic = base.get_long("CODDIC");
    if (codic != dich) break;
//    if (base.curr() > dep) break;
    codditta = base.get_long("CODDITTA");  
    if (codditta == dich) continue;        // scarta il dichiarante stesso
    set("*", anno, codditta, dich);
  }

// 2. Somma del quadro I "locale" del dichiarante a quello globale
  riporta_I_globale(dich);

  return TRUE;
}

bool TRiporti::riporta_I_globale(const long dich)
{
  int   ret1, ret2;
  long  c0nfcom, c0nlass, d0nfcom, d0nlaut, d1nfcom, d1nper;
  long  e0nfcom, e0nper, e1nfcom, e1nper;
  real  h0codlav, h0coldip;
  real  c0snsrit, c0rope, c0actot, d0actot, d0snsrit, d0rope, d1tacor, d1snsrit;
  real  d1rope, e0aimp, e0snsrit, e0rope, e1scor, e1bcom, e1rope, e1acom;
  real  e1bcom2, e1rope2;
  long  cc0nfcom, cc0nlass, dd0nfcom, dd0nlaut, dd1nfcom, dd1nper;
  long  ee0nfcom, ee0nper, ee1nfcom, ee1nper;
  real  ee0snsrit, ee0rope, ee0aimp, hh0codlav, hh0coldip;
  real  cc0snsrit, cc0rope, cc0actot, dd0actot, dd0snsrit, dd0rope, dd1tacor;
  real  dd1snsrit, dd1rope;
  real  ee1scor, ee1bcom, ee1rope, ee1acom, ee1bcom2, ee1rope2;

  c0nfcom = c0nlass = d0nfcom = d0nlaut = d1nfcom = d1nper = 0;
  e1nfcom = e1nper = 0;

  h0codlav = h0coldip = ZERO;
  c0snsrit = c0rope  = c0actot = d0actot = ZERO;
  d0snsrit = d0rope  = d1tacor = ZERO;
  e1scor   = e1bcom  = e1rope  = ZERO;
  e1acom   = e1bcom2 = e1rope2 = ZERO;

// 1. Lettura quadro I "locale" del dichiarante
  TLocalisamfile base(LF_BASE);
  TLocalisamfile basebis(LF_BASEBIS);
  base.zero();
  base.put("CODDITTA", dich);
  if (base.read() != NOERR) return FALSE;
  basebis.zero();
  basebis.put("CODDITTA", dich);
  if (basebis.read() != NOERR) return FALSE;

  d1nfcom  = base.get_int(BSE_D1NFCOM);
  d1nper   = base.get_int(BSE_D1NPER);
  d1tacor  = base.get_real(BSE_D1TACOR);
  d1snsrit = base.get_real(BSE_D1SNSRIT);
  d1rope   = base.get_real(BSE_D1ROPE);
  e1nfcom  = basebis.get_int(BSB_E1NFCOM);
  e1nper   = basebis.get_int(BSB_E1NPER);
  e1scor   = basebis.get_real(BSB_E1SCOR);
  e1bcom   = basebis.get_real(BSB_E1BCOM);
  e1rope   = basebis.get_real(BSB_E1ROPE);
  e1acom   = basebis.get_int(BSB_E1ACOM);
  e1bcom2  = basebis.get_real(BSB_E1BCOM2);
  e1rope2  = basebis.get_real(BSB_E1ROPE2);

  e0nfcom  = basebis.get_int(BSB_E0NFCOM);
  e0nper   = basebis.get_int(BSB_E0NPER);
  e0aimp   = basebis.get_real(BSB_E0AIMP);
  e0snsrit = basebis.get_real(BSB_E0SNSRIT);
  e0rope   = basebis.get_real(BSB_E0ROPE);

  h0codlav = basebis.get_real(BSB_H0CODLAV);
  h0coldip = basebis.get_real(BSB_H0COLDIP);
  c0nfcom  = base.get_int(BSE_C0NFCOM);
  c0nlass  = base.get_int(BSE_C0NLASS);
  c0actot  = base.get_real(BSE_C0ACTOT);
  c0snsrit = base.get_real(BSE_C0SNSRIT);
  c0rope   = base.get_real(BSE_C0ROPE);

  d0nfcom  = base.get_int(BSE_D0NFCOM);
  d0nlaut  = base.get_int(BSE_D0NLAUT);
  d0actot  = base.get_real(BSE_D0ACTOT);
  d0snsrit = base.get_real(BSE_D0SNSRIT);
  d0rope   = base.get_real(BSE_D0ROPE);

// 2. Riporto nel quadro I globale
  base.zero();
//  base.setkey(2);
  base.put(TIPOQUA,   COD_QUA_I_DIC);
  base.put("CODDITTA", (long)dich);
  TRectype dep(base.curr());
  ret1 = base.read();
  if (ret1 == _iskeynotfound)
  {
    base.curr() = dep;
    base.write();
  }
  basebis.zero();
  basebis.put(TIPOQUA, COD_QUA_I_DIC);
  basebis.put("CODDITTA", (long)dich);
  TRectype dep2(basebis.curr());
  ret2 = basebis.read();
  if (ret2 == _iskeynotfound)
  {
    basebis.curr() = dep2;
    basebis.write();
  }

  dd1nfcom  = base.get_int(BSE_D1NFCOM);
  dd1nper   = base.get_int(BSE_D1NPER);
  dd1tacor  = base.get_real(BSE_D1TACOR);
  dd1snsrit = base.get_real(BSE_D1SNSRIT);
  dd1rope   = base.get_real(BSE_D1ROPE);
  ee1nfcom  = basebis.get_int(BSB_E1NFCOM);
  ee1nper   = basebis.get_int(BSB_E1NPER);
  ee1scor   = basebis.get_real(BSB_E1SCOR);
  ee1bcom   = basebis.get_real(BSB_E1BCOM);
  ee1rope   = basebis.get_real(BSB_E1ROPE);
  ee1acom   = basebis.get_int(BSB_E1ACOM);
  ee1bcom2  = basebis.get_real(BSB_E1BCOM2);
  ee1rope2  = basebis.get_real(BSB_E1ROPE2);

  ee0nfcom  = basebis.get_int(BSB_E0NFCOM);
  ee0nper   = basebis.get_int(BSB_E0NPER);
  ee0aimp   = basebis.get_real(BSB_E0AIMP);
  ee0snsrit = basebis.get_real(BSB_E0SNSRIT);
  ee0rope   = basebis.get_real(BSB_E0ROPE);

  hh0codlav = basebis.get_real(BSB_H0CODLAV);
  hh0coldip = basebis.get_real(BSB_H0COLDIP);
  cc0nfcom  = base.get_int(BSE_C0NFCOM);
  cc0nlass  = base.get_int(BSE_C0NLASS);
  cc0actot  = base.get_real(BSE_C0ACTOT);
  cc0snsrit = base.get_real(BSE_C0SNSRIT);
  cc0rope   = base.get_real(BSE_C0ROPE);

  dd0nfcom  = base.get_int(BSE_D0NFCOM);
  dd0nlaut  = base.get_int(BSE_D0NLAUT);
  dd0actot  = base.get_real(BSE_D0ACTOT);
  dd0snsrit = base.get_real(BSE_D0SNSRIT);
  dd0rope   = base.get_real(BSE_D0ROPE);

  d1nfcom  +=  dd1nfcom   ;
  d1nper   +=  dd1nper    ;
  d1tacor  +=  dd1tacor  ;
  d1snsrit +=  dd1snsrit  ;
  d1rope   +=  dd1rope    ;
  e1nfcom  +=  ee1nfcom   ;
  e1nper   +=  ee1nper    ;
  e1scor   +=  ee1scor    ;
  e1bcom   +=  ee1bcom    ;
  e1rope   +=  ee1rope    ;
  e1acom   +=  ee1acom    ;
  e1bcom2  +=  ee1bcom2   ;
  e1rope2  +=  ee1rope2   ;
  e0nfcom  +=  ee0nfcom    ;
  e0nper   +=  ee0nper     ;
  e0aimp   +=  ee0aimp     ;
  e0snsrit +=  ee0snsrit   ;
  e0rope   +=  ee0rope     ;
  h0codlav +=  hh0codlav   ;
  h0coldip +=  hh0coldip   ;
  c0nfcom  +=  cc0nfcom    ;
  c0nlass  +=  cc0nlass    ;
  c0actot  +=  cc0actot    ;
  c0snsrit +=  cc0snsrit   ;
  c0rope   +=  cc0rope     ;
  d0nfcom  +=  dd0nfcom    ;
  d0nlaut  +=  dd0nlaut    ;
  d0actot  +=  dd0actot    ;
  d0snsrit +=  dd0snsrit   ;
  d0rope   +=  dd0rope     ;

  base.put(BSE_D1NFCOM,  d1nfcom);
  base.put(BSE_D1NPER,   d1nper);
  base.put(BSE_D1TACOR,  d1tacor);
  base.put(BSE_D1SNSRIT, d1snsrit);
  base.put(BSE_D1ROPE,   d1rope);
  basebis.put(BSB_E1NFCOM, e1nfcom);
  basebis.put(BSB_E1NPER,  e1nper);
  basebis.put(BSB_E1SCOR,  e1scor);
  basebis.put(BSB_E1BCOM,  e1bcom);
  basebis.put(BSB_E1ROPE,  e1rope);
  basebis.put(BSB_E1ACOM,  e1acom);
  basebis.put(BSB_E1BCOM2, e1bcom2);
  basebis.put(BSB_E1ROPE2, e1rope2);

  basebis.put(BSB_E0NFCOM, e0nfcom);
  basebis.put(BSB_E0NPER,  e0nper);
  basebis.put(BSB_E0AIMP,  e0aimp);
  basebis.put(BSB_E0SNSRIT, e0snsrit);
  basebis.put(BSB_E0ROPE,   e0rope);

  basebis.put(BSB_H0CODLAV, h0codlav);
  basebis.put(BSB_H0COLDIP, h0coldip);
  base.put(BSE_C0NFCOM,     c0nfcom);
  base.put(BSE_C0NLASS,     c0nlass);
  base.put(BSE_C0ACTOT,     c0actot);
  base.put(BSE_C0SNSRIT,    c0snsrit);
  base.put(BSE_C0ROPE,      c0rope);

  base.put(BSE_D0NFCOM,  d0nfcom);
  base.put(BSE_D0NLAUT,  d0nlaut);
  base.put(BSE_D0ACTOT,  d0actot);
  base.put(BSE_D0SNSRIT, d0snsrit);
  base.put(BSE_D0ROPE,   d0rope);

  ret1 = base.rewrite();
  ret2 = basebis.rewrite();

  return TRUE;
}

// Calcola i riporti dai quadri al quadro I per la ditta codditta. 
// Esegue i riporti anche su dichiarante se specificato
bool TRiporti::set(const TString& quadro, int anno, const long codditta, const long dichiarante)
{
  TString16     filt;
  TRelation*    rel;
  TCursor*      cur;
  long          codditta_dich = 0L;

  _codditta = codditta ? codditta : get_firm_770();
  _annodic  = anno ? anno : anno_770();
  _quadro   = quadro;
  
  // Filtro magico uguale per tutti
  filt.format("CODDITTA=%ld", _codditta);

  this_riporti = this;

  if (quadro == "A" || quadro == "*")
  {
    rel = new TRelation (LF_QUAA);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_A(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "A1" || quadro == "*")
  {
    rel = new TRelation (LF_QUAA1);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_A1(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "A2" || quadro == "*")
  {
    rel = new TRelation (LF_QUAA2);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_A2(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "A3" || quadro == "*")
  {
    rel = new TRelation (LF_QUAA3);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_A3(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "B" || quadro == "*")
  {
    rel = new TRelation (LF_QUAB);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_B(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "B1" || quadro == "*")
  {
    rel = new TRelation (LF_QUAB1);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    calcola_riporti_B1(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "H" || quadro == "*")
  {
    rel = new TRelation (LF_QUAH);
    filt.format("CODDITTA=%ld", _codditta);
    cur   = new TCursor(rel,filt,1);
    cur->set_filterfunction (filter_func);
    calcola_riporti_H(cur, dichiarante);
    delete cur; delete rel;
  }

  if (quadro == "C" || quadro == "*")
  {
    calcola_riporti_C(dichiarante);
  }

  if (quadro == "D" || quadro == "*")
  {
    calcola_riporti_D(dichiarante);
  }

  if (quadro == "DB" || quadro == "*")
  {
    calcola_riporti_Dbis(dichiarante);
  }

  if (quadro == "D1" || quadro == "*")
  {
    calcola_riporti_D1(dichiarante);
  }

  if (quadro == "E" || quadro == "*")
  {
    calcola_riporti_E(dichiarante);
  }

  if (quadro == "E1" || quadro == "*")
  {
    calcola_riporti_E1(dichiarante);
  }

  if (quadro == "E2" || quadro == "*")
  {
    calcola_riporti_E2(dichiarante);
  }

  if (quadro == "F" || quadro == "*")
  {
    calcola_riporti_F (dichiarante);
  }

  if (quadro == "F1" || quadro == "*")
  {
    calcola_riporti_F1 (dichiarante);
  }

  if (quadro == "F2" || quadro == "*")
  {
    calcola_riporti_F2 (dichiarante);
  }

  if (quadro == "G" || quadro == "*")
  {
    calcola_riporti_G (dichiarante);
  }

  if (quadro == "G1" || quadro == "*")
  {
    calcola_riporti_G1 (dichiarante);
  }
  setta_flag_quadro_I(_codditta);
  return TRUE;
}

const int NUM_DIP_A = 9;

void TRiporti::calcola_riporti_A(TCursor* cur, const long dich)
{                   
  TLocalisamfile base (LF_BASE);
  real    totale,somme,ritenute;
  bool    almeno_una_riga = FALSE;
  long    dipendenti,num_rec;
  
  real    a0cobb,a0cnet,a0eprev,a0iitra,a0cter,a0timp,a0ilor,a0tdet,a0rter,a0rdat;
  real    a0erit,a0carr,a0aarr,a0darr,a0rarr,a0cinps,a0ciiaut,a0crimpras,a0incdet;
  
  a0cobb = ZERO; a0cnet = ZERO; a0eprev = ZERO; a0iitra = ZERO; a0cter = ZERO;
  a0timp = ZERO; a0ilor = ZERO; a0tdet  = ZERO; a0rter  = ZERO; a0rdat = ZERO;
  a0erit = ZERO; a0carr = ZERO; a0aarr  = ZERO; a0darr  = ZERO; a0rarr = ZERO;
  a0cinps = ZERO; a0ciiaut = ZERO; a0crimpras = a0incdet = ZERO;
  
  dipendenti = 0;
  num_rec    = 0;
  
  (*cur) = 0L;

  TRecnotype items  = cur->items();
  TString    scritta(60);

  scritta.format("Calcolo riporti del quadro A per la ditta %ld", _codditta);

  TProgind  progn(items, scritta, FALSE, TRUE);

  long coddipp = -1;

  for (int i = 0; i < items; i++, ++(*cur))
  { 
    progn.addstatus(1);  
    
    long coddip = cur->curr().get_long(QUA_CODIP);
    
    bool compilato = FALSE;

    if (!almeno_una_riga)
      almeno_una_riga = TRUE;    

    for (int i = 0; i < CAMPI_A; i++)
      if (cur->curr().get_real(_campi_A[i]) != ZERO)
      {
        compilato = TRUE;
        break;
      }
    
    if (!compilato)
      continue;
    
    num_rec++;
    
    if (coddip != coddipp) 
      if (!is_erede(_codditta,coddip))
        dipendenti++;

      coddipp = coddip;
  
    int     causa  = cur->curr().get_int (QUA_CAUSA);
    TString codfis = cur->curr().get     (QUA_CODFISDL);
    char    retcon = cur->curr().get_char(QUA_RETCON);
    
    if (retcon != 'B' && codfis.empty())  
    {
      a0cobb     += cur->curr().get_real(QUA_COBBDIP); 
      a0cnet     += cur->curr().get_real(QUA_COMPNETTI); 
      a0eprev    += cur->curr().get_real(QUA_AIENTIPREV); 
      a0iitra    += cur->curr().get_real(QUA_TOTIMP); 
//      a0cter     += cur->curr().get_real(QUA_CCTAMMCONT) + cur->curr().get_real(QUA_CCTAMNACON);
      a0cter     += cur->curr().get_real(QUA_CCTAMMCONT);
      a0timp     += cur->curr().get_real(QUA_TOTIMP2); 
      a0ilor     += cur->curr().get_real(QUA_ICTOTIMP); 
      a0tdet     += cur->curr().get_real(QUA_TOTDET); 
      a0rter     += cur->curr().get_real(QUA_AMRIOT); 
      a0rdat     += cur->curr().get_real(QUA_AMRIODL);
      a0erit     += cur->curr().get_real(QUA_ECCRITRIMB); 
      a0carr     += cur->curr().get_real("COBBDIP2"); // cas.46
      a0aarr     += cur->curr().get_real(QUA_AMMIMP); 
      a0darr     += cur->curr().get_real(QUA_DETIMPOS); 
      a0rarr     += cur->curr().get_real(QUA_RITESEG); 
      a0incdet   += cur->curr().get_real("INCDETFC"); // cas.38    
    }
  }

  long fogli = num_rec / NUM_DIP_A;
  if (num_rec % NUM_DIP_A)
    fogli++;

  base.zero();
  if (dich)
  {
    base.put("TIPOQUA", COD_QUA_I_DIC);
    base.put(BSE_CODDITTA, dich);
  }
  else
    base.put(BSE_CODDITTA, _codditta);

  if (base.read(_isequal,_lock) == NOERR)
  {
    base.put(BSE_A0NFCOM,    fogli);
    base.put(BSE_A0NLDIP,    (long)dipendenti);
    base.put(BSE_A0COBB,     a0cobb);
    base.put(BSE_A0CNET,     a0cnet);
    base.put(BSE_A0EPREV,    a0eprev);
    base.put(BSE_A0IITRA,    a0iitra);
    base.put(BSE_A0CTER,     a0cter);
    base.put(BSE_A0TIMP,     a0timp);
    base.put(BSE_A0ILOR,     a0ilor);
    base.put(BSE_A0TDET,     a0tdet);
    base.put(BSE_A0RTER,     a0rter);
    base.put(BSE_A0RDAT,     a0rdat);
    base.put(BSE_A0ERIT,     a0erit);
    base.put(BSE_A0CARR,     a0carr);
    base.put(BSE_A0AARR,     a0aarr);
    base.put(BSE_A0DARR,     a0darr);
    base.put(BSE_A0RARR,     a0rarr);
    base.put("A0INCDET",     a0incdet);
    base.rewrite();                                                    
    TLocalisamfile basebis(LF_BASEBIS);
    basebis.setkey(1);
    basebis.zero();
    basebis.put(BSE_CODDITTA, _codditta);
    if (basebis.read(_isequal, _lock) == NOERR)
      setta_flag_quadri_comp(_codditta, A, almeno_una_riga, basebis, dich);
    else
      warning_box("Lock fallito in calcola_riporti A");
  }                 
  else
    warning_box("Dichiarazione non presente. Impossibile registrare i riporti");
}

const int NUM_DIPENDENTI_MODULO_A3 = 35;

void TRiporti::calcola_riporti_A3(TCursor* cur, const long dich)
{                   
  TLocalisamfile base (LF_BASE);
  bool  almeno_una_riga = FALSE;
  long  dipendenti=0L, num_rec=0L;
  real  a3rept10=ZERO,a3rept12=ZERO;
  
  (*cur) = 0L;
  TRecnotype items  = cur->items();
  TString    scritta(60);
  scritta.format("Calcolo riporti del quadro A3 per la ditta %ld", _codditta);
  TProgind  progn(items, scritta, FALSE, TRUE);
// fogli per l'elenco delle trasf.
  int iFogliTrasf=0;  
  int iDipTrasf=0;            
  
  for (int i = 0; i < items; i++, ++(*cur))
  { 
    progn.addstatus(1);  
    const long coddip = cur->curr().get_long(QUA_CODIP);
    const long nprog  = cur->curr().get_long(QUA_NPROG);
    
    if (!almeno_una_riga)
      almeno_una_riga = TRUE;    

// Non conta quelli con redditto corrisposto = ZERO
    if ((cur->curr().get_real(QA3_REDCOR16) == ZERO) && (cur->curr().get_real(QA3_REDCOR18) == ZERO))
      continue;

// nprog=2 se e' il record della trasformata. Conto i dip.con trasf. per 
// contare i fogli
    if (nprog == 2)                                                 
      iDipTrasf++;

    dipendenti++;

    a3rept10 += cur->curr().get_real(QA3_REDCOR16); 
    a3rept12 += cur->curr().get_real(QA3_REDCOR18); 
  }

  long fogli = dipendenti / NUM_DIPENDENTI_MODULO_A3;
  if (dipendenti % NUM_DIPENDENTI_MODULO_A3)
    fogli++;
  iFogliTrasf = iDipTrasf / NUM_DIPENDENTI_MODULO_A3;
  if (iDipTrasf % NUM_DIPENDENTI_MODULO_A3)
    iFogliTrasf++;
  fogli += iFogliTrasf;
    
  base.zero();
  if (dich)
  {
    base.put("TIPOQUA", COD_QUA_I_DIC);
    base.put(BSE_CODDITTA, dich);
  }
  else
    base.put(BSE_CODDITTA, _codditta);

  if (base.read(_isequal,_lock) == NOERR)
  {
    base.put(BSE_A3NFCOM,    fogli);
    base.put(BSE_A3NUMPER,   (long)dipendenti);
    base.put(BSE_A3REPT10,   a3rept10);
    base.put(BSE_A3REPT12,   a3rept12);
    base.rewrite();
    TLocalisamfile basebis(LF_BASEBIS);
    basebis.setkey(1);
    basebis.zero();
    basebis.put(BSE_CODDITTA, _codditta);
    if (basebis.read(_isequal, _lock) == NOERR)
      setta_flag_quadri_comp(_codditta, A3, almeno_una_riga, basebis, dich);
    else
      warning_box("Lock fallito in calcola_riporti A3");
  }                 
  else
    warning_box("Dichiarazione non presente. Impossibile registrare i riporti");
}

void TRiporti::calcola_riporti_A1(TCursor* cur, const long dich)
{                   
  bool    almeno_una_riga = FALSE;
  
  (*cur) = 0L;

  TRecnotype items  = cur->items();
  TString    scritta(60);

  scritta.format("Calcolo riporti del quadro A1 per la ditta %ld", _codditta);

//  da attivare qualora anche il quadro A1 effettui riporti su quadro I
//  TProgind  progn(items, scritta, FALSE, TRUE);

  for (int i = 0; i < items; i++, ++(*cur))
  { 

//  da attivare qualora anche il quadro A1 effettui riporti su quadro I
//  progn.addstatus(1);

    if (!almeno_una_riga)
      almeno_una_riga = TRUE;    
  }
  TLocalisamfile basebis(LF_BASEBIS);
  basebis.setkey(1);
  basebis.zero();
  basebis.put(BSE_CODDITTA, _codditta);
  if (basebis.read(_isequal, _lock) == NOERR)
    setta_flag_quadri_comp(_codditta, A1, almeno_una_riga, basebis, dich);
  else
    warning_box("Lock fallito in calcola_riporti A1");
}

void TRiporti::calcola_riporti_A2(TCursor* cur, const long dich)
{                   
  bool    almeno_una_riga = FALSE;
  (*cur) = 0L;
  TRecnotype items  = cur->items();
  TString    scritta(60);
  scritta.format("Calcolo riporti del quadro A2 per la ditta %ld", _codditta);

//  da attivare qualora anche il quadro A2 effettui riporti su quadro I
//  TProgind  progn(items, scritta, FALSE, TRUE);

  for (int i = 0; i < items; i++, ++(*cur))
  { 
//  da attivare qualora anche il quadro A2 effettui riporti su quadro I
//  progn.addstatus(1);

    if (!almeno_una_riga)
      almeno_una_riga = TRUE;    
  }
  TLocalisamfile basebis(LF_BASEBIS);
  basebis.setkey(1);
  basebis.zero();
  basebis.put(BSE_CODDITTA, _codditta);
  if (basebis.read(_isequal, _lock) == NOERR)
    setta_flag_quadri_comp(_codditta, A2, almeno_una_riga, basebis, dich);
  else
    warning_box("Lock fallito in calcola_riporti A2");
}

void TRiporti::calcola_riporti_H(TCursor* cur, const long dich)
{
  TLocalisamfile basebis (LF_BASEBIS);
  real    ritdat,ritlav;
  bool    almeno_una_riga = FALSE;

  ritdat = ZERO;
  ritlav = ZERO;

  (*cur) = 0L;

  TRecnotype items  = cur->items();
//  if (items == 0L) return;
  TString    scritta(60);
  scritta.format("Calcolo riporti del quadro H per la ditta %ld", _codditta);

  TProgind  progn(items, scritta, FALSE, TRUE);

  for (int i = 0; i < items; i++, ++(*cur))
  {
    ritdat += cur->curr().get_real(QUH_H1DAT);
    ritlav += cur->curr().get_real(QUH_H1LAV);

    if (!almeno_una_riga)
      almeno_una_riga = TRUE;

    progn.addstatus(1);
  }

  basebis.setkey(1);
  basebis.zero();
  if (dich)
  {
    basebis.put("TIPOQUA", COD_QUA_I_DIC);
    basebis.put(BSB_CODDITTA, dich);
  }
  else
    basebis.put(BSB_CODDITTA, _codditta);

  if (basebis.read(_isequal, _lock) == NOERR)
  {
    basebis.put(BSB_H0CODLAV, ritdat);
    basebis.put(BSB_H0COLDIP, ritlav);
    basebis.rewrite();
    setta_flag_quadri_comp(_codditta, H, almeno_una_riga,basebis,dich);
  }
  else
    warning_box("Dichiarazione non presente. Impossibile registrare i riporti");
}

void TRiporti::calcola_riporti_C(const long dich)
{                    
  TConta_persone conta(LF_QUAC, _codditta);
  int err = conta.read_base(dich);
  if (err == NOERR)
  {              
    conta.compute();

    const TRectype& totale = conta.totale();
    TRectype& base = conta.base().curr();
    base.put(BSE_C0NFCOM,   conta.fogli_compilati(QC_PERCIPIENTI_PER_FOGLIO));
    base.put(BSE_C0NLASS,   conta.persone_distinte());
    base.put(BSE_C0ACTOT,   totale.get("AMMLORDO"));
    base.put(BSE_C0CONTSSN, totale.get("CONTROBB"));
    base.put(BSE_C0SNSRIT,  totale.get("SOMNONSOGG"));
    base.put(BSE_C0TOTIMP,  totale.get("IMPONIBILE"));
    base.put(BSE_C0ROPE,    totale.get("IMPOSTA"));            
    base.put(BSE_C0TOTDET,  totale.get("TOTDET"));            
    base.put(BSE_C0RITOPE,  totale.get("RITENUTE"));            
    conta.base().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, C, conta.righe() > 0, conta.basebis(), dich);
  }                 
}

void TRiporti::calcola_riporti_D(const long dich)
{
  TConta_persone conta(LF_QUAD, _codditta);
  int err = conta.read_base(dich);
  if (err == NOERR)
  {                           
    conta.compute();

    const TRectype& totale = conta.totale();
    TRectype& base = conta.base().curr();
  
    base.put(BSE_D0NFCOM,   conta.fogli_compilati(QD_PERCIPIENTI_PER_FOGLIO));
    base.put(BSE_D0NLAUT,   conta.persone_distinte());
    base.put(BSE_D0ACTOT,   totale.get("TOTALE"));
    base.put(BSE_D0SNSRIT,  totale.get("SOMME"));
    base.put(BSE_D0NSRITRC, totale.get("SOMREGCONV"));
    base.put(BSE_D0ROPE,    totale.get("IMPORTO"));
    conta.base().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, D, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_Dbis(const long dich)
{
  TConta_persone conta(LF_QUADBIS, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {                           
    conta.compute();

    const TRectype& totale = conta.totale();
    TRectype& basebis = conta.basebis().curr();
    
    basebis.put(BSE_DBAMMCOR,  totale.get("TOTALE"));
    basebis.put(BSE_DBNSRIT,   totale.get("SOMME"));
    basebis.put(BSE_DBNSRITRC, totale.get("IMPONIBILE"));
    basebis.put(BSE_DBRITOPE,  totale.get("IMPORTO"));
    conta.basebis().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, DB, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_D1(const long dich)
{
  TConta_persone conta(LF_QUAD1, _codditta);
  int err = conta.read_base(dich);
  if (err == NOERR)
  {                           
    conta.compute();

    const TRectype& totale = conta.totale();
    TRectype& base = conta.base().curr();
    base.put(BSE_D1NFCOM,  conta.fogli_compilati(QD1_PERCIPIENTI_PER_FOGLIO));
    base.put(BSE_D1NPER,   conta.persone_distinte());
    base.put(BSE_D1TACOR,  totale.get("TOTALE"));
    base.put(BSE_D1SNSRIT, totale.get("SPESEANT"));
    base.put(BSE_D1ROPE,   totale.get("IMPORTO"));
    conta.base().rewrite();
  
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, D1, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_E(const long dich)
{
  TConta_persone conta(LF_QUAE, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {                           
    conta.compute();

    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    base.put(BSB_E0NFCOM,  conta.fogli_compilati(QE_PERCIPIENTI_PER_FOGLIO));
    base.put(BSB_E0NPER,   conta.persone_distinte());
    base.put(BSB_E0AIMP,   totale.get(QUE_IMPONIBILE));
    base.put(BSB_E0SNSRIT, totale.get(QUE_SOMME));
    base.put(BSB_E0ROPE,   totale.get(QUE_IMPORTO));
    conta.basebis().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, E, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_E1(const long dich)
{
  TConta_persone conta(LF_QUAE1, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {                 
    TLocalisamfile prosp_e1(LF_PROSPE1);
    prosp_e1.put(PRE_CODDITTA, _codditta);
    TRectype tot_prosp(LF_PROSPE1);          // Totale delle due righe di prospetto
    for (int err = prosp_e1.read(_isgteq); err == NOERR; err = prosp_e1.next())
    {
      if (prosp_e1.get_long(PRE_CODDITTA) != _codditta)
        break;
      char caus = prosp_e1.get_char(PRE_CODCAUS);
      if (caus == 'C' || caus == 'D')        // Ignora causali dell'anno scorso
        conta.sum(tot_prosp, prosp_e1.curr());
    }
    
    conta.compute();
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    base.put(BSB_E1NFCOM, conta.fogli_compilati(QE1_PERCIPIENTI_PER_FOGLIO));
    base.put(BSB_E1NPER,  conta.persone_distinte());
    base.put(BSB_E1BCOM,  totale.get(QE1_AMMONTARE));
    base.put(BSB_E1SCOR,  totale.get(QE1_SOMME));
    base.put(BSB_E1ROPE,  totale.get(QE1_IMPORTO));
    base.put(BSB_E1ACOM,  tot_prosp.get(PRE_COMPENSO));
    base.put(BSB_E1BCOM2, tot_prosp.get(PRE_IMPONIBILE));
    base.put(BSB_E1ROPE2, tot_prosp.get(PRE_RITENUTA));
    conta.basebis().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, E1, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_E2(const long dich)
{
  TConta_persone conta(LF_QUAE2, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {                           
    conta.compute();
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    base.put(BSB_E2NFCOM, conta.fogli_compilati(QE2_PERCIPIENTI_PER_FOGLIO));
    base.put(BSB_E2NPER,  conta.persone_distinte());
    base.put(BSB_E2SSRIT, totale.get(QE2_SOGGRIT));
    base.put(BSB_E2ROPE,  totale.get(QE2_ROPE));
    conta.basebis().rewrite();
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, E2, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_F(const long dich)
{                      
  TConta_persone conta(LF_RIGHEF, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {
    long righe = conta.compute("TIPOPRO!=\"H\"");
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();

    base.put(BSB_F0SSRITBF, totale.get(RQF0_SOGRIT));
    base.put(BSB_F0ROPEBF,  totale.get(RQF0_ROPE));
    
    righe += conta.compute("TIPOPRO=\"H\"");
    base.put(BSB_F0AMMPRO, totale.get(RQF0_SOGRIT));
    base.put(BSB_F0PREOPE, totale.get(RQF0_ROPE));

    conta.basebis().rewrite();

    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, F, righe > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_F1(const long dich)
{
  TConta_persone conta(LF_RIGHEF1, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {
    conta.compute();
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    
    base.put(BSB_F1NFCOM, conta.fogli_compilati(QF1_PERCIPIENTI_PER_FOGLIO));
    base.put(BSB_F1NPER,  conta.persone_distinte());
    base.put(BSB_F1SSRIT, totale.get(RQF1_SOGRIT));
    base.put(BSB_F1ROPE,  totale.get(RQF1_ROPE));
    
    conta.basebis().rewrite();

    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, F1, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_F2(const long dich)
{                    
  TConta_persone conta(LF_RIGHEF2, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {
    conta.compute();
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    
    base.put(BSB_F2SSRIT, totale.get(RQF2_SOGRIT));
    base.put(BSB_F2ROPE,  totale.get(RQF2_ROPE));
    
    conta.basebis().rewrite();

    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, F2, conta.righe() > 0, conta.basebis(), dich);
  }
}

//
// fogli_compilati
//
// Determina il numero di fogli compilati:
// Divide il numero di persone (F o G) trovate per il numero
// di posti previsto nel modulo. 
// Se il resto e' diverso da 0 conta un foglio in piu'
//
HIDDEN long fogli_compilati(const long fisiche, const long no_fisiche, const int fisiche_x_foglio, const int nofisiche_x_foglio)
{
  long fogli_compilati=0L, fogli_fisiche=0L, fogli_nofisiche=0L;
  
  if (fisiche > 0L)
  {
    fogli_fisiche = fisiche / fisiche_x_foglio;
    if (fisiche % fisiche_x_foglio)
      fogli_fisiche += 1;
  }   
  
  if (no_fisiche > 0L)
  {
    fogli_nofisiche = no_fisiche / nofisiche_x_foglio;
    if (no_fisiche % nofisiche_x_foglio)
      fogli_nofisiche += 1;
  }  
  fogli_compilati = fogli_fisiche > fogli_nofisiche ? fogli_fisiche : fogli_nofisiche;
  return fogli_compilati;
}

void TRiporti::calcola_riporti_G(const long dich)
{
  TConta_persone conta(LF_QUAGD, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  {
    TWait_cursor hourglass;
    int numero_fogli = 0;
    TString str(80); 
    real i28_7, i28_8, i28_9, i28_10, i28_11, i29_12, i29_13;
    
    TLocalisamfile quadro(LF_QUAG);
    quadro.put("CODDITTA", _codditta);
    if (quadro.read() == NOERR)
    {
      i28_7 = quadro.get_real("UTILIAP21") + quadro.get_real("UTILIAP22");
      i28_8 = quadro.get_real("UTILI21") + quadro.get_real("UTILI22");
      if (i28_7 != ZERO || i28_8 != ZERO)
        numero_fogli = 1;
    }
    
    TRelation rel(LF_QUAGP);
    TRectype rec(LF_QUAGP);
    rec.put("CODDITTA", _codditta);
    TCursor cur(&rel, "PROSPETTO=2", &rec, &rec);
    long righe = cur.items();
    if (righe > 0)
    {
      const char* const precompiled[6] = { "00,00",  "10,00A", "10,00I", 
                                           "12,50I", "15,00I", "32,40I" };
      int righe_inserite[2] = { 0, 0 };
          
      str.cut(0);
      str << "Calcolo riporti Quadro G della ditta " << _codditta;
      TProgind pi(righe, str, FALSE, TRUE, 60);
    
      TRectype& curr = cur.curr();
      long i;
      for (i = 0, cur = 0; i < righe; i++, ++cur)
      {
        pi.addstatus(1);
  
        const real campo3 = curr.get("UTILI1S");
        const real campo4 = curr.get("UTILI2S");
        const real campo7 = curr.get("ROPE");
        const char titolo = toupper(curr.get_char("TITOLO"));
        i28_9  += campo3; 
        i28_10 += campo4;
        switch(titolo)
        {
        case 'A': i28_11 += campo7; break;
        case 'I': i29_12 += campo7; break;
        default : i29_13 += campo3 + campo4; break;
        }
        
        const real aliquota = curr.get("PERC");
        str = aliquota.string("@@,@@"); str << titolo;
        for (int p = 5; p >= 0 && str != precompiled[p]; p--);
        if (p < 0) // E' una riga non precompilata
        {
          const int sez = curr.get_int("SEZIONE");
          CHECK(sez == 1 || sez == 2, "Prospetto ignobile");
          righe_inserite[sez-1]++;
        }
      }  
      
      const int ri = max(righe_inserite[0], righe_inserite[1]);
      const int fc = (ri-1) / 3 + (righe > 0); // Fogli necessari
      if (fc > numero_fogli)
        numero_fogli = fc;
    }  
    
    // Calcola fogli necessari per il prospetto 1
    cur.setfilter("PROSPETTO=1");
    righe = cur.items();
    if (righe > 0)
    {
      const int fc = int(righe - 1) / 4 + 1;
      if (fc > numero_fogli)
        numero_fogli = fc;
    }
    
    // Calcolo distinta del quadro G
    righe = conta.compute();

    // Calcolo fogli necessari per la distinta
    if (righe > 0)
    {
      const int fc = conta.fogli_compilati(QGD_PERCIPIENTI_PER_FOGLIO);
      if (fc > numero_fogli)
        numero_fogli = fc;
    }
    
    const TRectype& totale = conta.totale();
    TRectype& base = conta.basebis().curr();
    
    base.put(BSB_G0NFCOM,    numero_fogli);
    base.put(BSB_G0NPER,     conta.persone_distinte());   
    base.put(BSB_G0USPE,     totale.get("UTSPET"));
    base.put(BSB_G0RITSPET,  totale.get("ROPESPET"));
    base.put(BSB_G0UPAG,     totale.get("UTPAG"));
    base.put(BSB_G0ROPE,     totale.get("ROPE"));
    base.put(BSB_G0UTDACOR,  i28_7);
    base.put(BSB_G0UTDELDIS, i28_8);
    base.put(BSB_G0UTCOR1S,  i28_9);
    base.put(BSB_G0UTCOR2S,  i28_10);
    base.put(BSB_G0RACC3,    i28_11);
    base.put(BSB_G0RIMP3,    i29_12);
    base.put(BSB_G0UNSRIT3,  i29_13);
    conta.basebis().rewrite();
    
    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, G, numero_fogli > 0, conta.basebis(), dich);
  }  
}


void TRiporti::calcola_riporti_G1 (const long dich)
{
  TConta_persone conta(LF_QUAG1, _codditta);
  int err = conta.read_basebis(dich);
  if (err == NOERR)
  { 
    TRectype& base = conta.basebis().curr();
    const TRectype& totale = conta.totale();
       
    real i31_7, i31_8;
    long righe = conta.compute("ALIQUOTA=0");
    if (righe > 0)
    {
      i31_7 = totale.get_real(QG1_UTILI1S);
      i31_8 = totale.get_real(QG1_UTILI2S);
    }
    
    righe = conta.compute();
    base.put(BSB_G1UTCOR1S, totale.get(QG1_UTILI1S));
    base.put(BSB_G1UTCOR2S, totale.get(QG1_UTILI2S));
    base.put(BSB_G1RITAV1,  totale.get(QG1_RACCVER1S));
    base.put(BSB_G1RITAV2,  totale.get(QG1_RACCVER2S));
    base.put(BSB_G1RITIV1,  totale.get(QG1_RIMPVER1S));
    base.put(BSB_G1RITIV2,  totale.get(QG1_RIMPVER2S));
    base.put(BSB_G1UTNSR1S, i31_7);
    base.put(BSB_G1UTNSR2S, i31_8);
    conta.basebis().rewrite();

    err = conta.read_basebis(0);
    if (err == NOERR)
      setta_flag_quadri_comp(_codditta, G1, conta.righe() > 0, conta.basebis(), dich);
  }
}

void TRiporti::calcola_riporti_B (TCursor* cur, const long dich)
{
  TLocalisamfile    base (LF_BASE);
  real              c3,c4,c5,c6,c7,c8,c9,c10;
  real              tc3,tc4,tc5,tc6,tc7,tc8,tc9,tc10;
  int       c2=0;
  long        c1=0L;
  bool              almeno_una_riga = FALSE;
  int       NumPerc=0;  
  long        fogli_comp=0L; 
  TBit_array    baGiaVisto;
  
  c3=c4=c5=c6=c7=c8=c9=c10=ZERO;
  tc3=tc5=tc6=tc7=tc8=tc9=tc10=ZERO;
  (*cur) = 0L;
  TRecnotype items  = cur->items();
  almeno_una_riga = items > 0L;

  TString    scritta(60);
  scritta.format("Calcolo riporti del quadro B per la ditta %ld", _codditta);
  TProgind  progn(items, scritta, FALSE, TRUE);

  for (int i = 0; i < items; i++, ++(*cur))
  {
    const long codditta = cur->curr().get_long(QB_CODDITTA);
    const long coddip   = cur->curr().get_long(QB_CODDIP);
    
    if (!baGiaVisto[coddip])
    {
      baGiaVisto.set(coddip);
      if (!is_erede(codditta, coddip))
        NumPerc++;
    }
    
    c3 = cur->curr().get_real(QB_C20);
    c4 = cur->curr().get_real(QB_C24);
    c5 = cur->curr().get_real(QB_C25);
    c6 = cur->curr().get_real(QB_C26);
    c7 = cur->curr().get_real(QB_C27);
    c8 = cur->curr().get_real(QB_C36);
    c9 = cur->curr().get_real(QB_C37);
    c10 = cur->curr().get_real(QB_C43);
    
    tc3 += c3;
    tc4 += c4;
    tc5 += c5;
    tc6 += c6;
    tc7 += c7;
    tc8 += c8;
    tc9 += c9;
    tc10 += c10;
    
    if (!almeno_una_riga)
      almeno_una_riga = TRUE;

    progn.addstatus(1);
  }

  fogli_comp = fogli_compilati(items,0L,QB_PERCIPIENTI_PER_FOGLIO,0);

  c1 = fogli_comp;
  c2 = NumPerc;
    
  base.setkey(1);
  base.zero();
  if (dich)
  {
    base.put("TIPOQUA", COD_QUA_I_DIC);
    base.put(BSE_CODDITTA, dich);
  }
  else
    base.put(BSE_CODDITTA, _codditta);

  if (base.read(_isequal, _lock) == NOERR)
  {
    base.put(I8_1,c1);
    base.put(I8_2,(long)c2);
    base.put(I8_3,tc3);
    base.put(I8_4,tc4);    
    base.put(I8_5,tc5);    
    base.put(I8_6,tc6);    
    base.put(I9_7,tc7);    
    base.put(I9_8,tc8);
    base.put(I9_9,tc9);
    base.put(I9_10,tc10);            
    base.rewrite();                                           
    TLocalisamfile basebis(LF_BASEBIS);
    basebis.setkey(1);
    basebis.zero();
    basebis.put(BSE_CODDITTA, _codditta);
    if (basebis.read(_isequal, _lock) == NOERR)
      setta_flag_quadri_comp(_codditta, B, almeno_una_riga,basebis,dich);
    else
      warning_box("Lock fallito in calcola_riporti B");
  }
  else
    warning_box("Dichiarazione non presente. Impossibile registrare i riporti");

  progn.addstatus(1);
}

HIDDEN const int QB1_NUMPERC_PER_FOGLIO = 14;

void TRiporti::calcola_riporti_B1(TCursor* cur, const long dich)
{
  TLocalisamfile    base (LF_BASE);
  real              c3,c4,c5;
  real              tc3,tc4,tc5;
  int       c2=0;
  bool              almeno_una_riga = FALSE;
  int       NumPerc=0;  
  long        fogli_comp=0L, c1=0L;   
  
  c3=c4=c5=ZERO;
  tc3=tc4=tc5=ZERO;  
  (*cur) = 0L;
  TRecnotype items  = cur->items();
  almeno_una_riga = items > 0L;

  TString    scritta(60);
  scritta.format("Calcolo riporti del quadro B-1 per la ditta %ld", _codditta);
  TProgind  progn(items, scritta, FALSE, TRUE);

  for (int i = 0; i < items; i++, ++(*cur))
  {
    c3 = cur->curr().get_real(QB1_C11);
    c4 = cur->curr().get_real(QB1_C12);
    c5 = cur->curr().get_real(QB1_C18);

    tc3 += c3;
    tc4 += c4;
    tc5 += c5;
        
    NumPerc++;
    
    if (!almeno_una_riga)
      almeno_una_riga = TRUE;

    progn.addstatus(1);
  }

  fogli_comp = fogli_compilati(items,0L,QB1_NUMPERC_PER_FOGLIO,0);

  c1 = fogli_comp;
//  c2 = items;
    
  base.setkey(1);
  base.zero();
  if (dich)
  {
    base.put("TIPOQUA", COD_QUA_I_DIC);
    base.put(BSE_CODDITTA, dich);
  }
  else
    base.put(BSE_CODDITTA, _codditta);

  if (base.read(_isequal, _lock) == NOERR)
  {
    base.put(I11_1,c1);
    base.put(I11_2,(long)items);
    base.put(I11_3,tc3);
    base.put(I11_4,tc4);    
    base.put(I11_5,tc5);         
    base.rewrite();                
    TLocalisamfile basebis(LF_BASEBIS);
    basebis.setkey(1);
    basebis.zero();
    basebis.put(BSE_CODDITTA, _codditta);
    if (basebis.read(_isequal, _lock) == NOERR)
      setta_flag_quadri_comp(_codditta, B1, almeno_una_riga,basebis,dich);
    else
      warning_box("Lock fallito in calcola_riporti B1");
  }
  else
    warning_box("Dichiarazione non presente. Impossibile registrare i riporti");

  progn.addstatus(1);
}


void TRiporti::set_compilato(const long codditta, const int posquadro, const bool compilato)
{             
  TLocalisamfile basebis(LF_BASEBIS);
  basebis.setkey(1);
  basebis.zero();
  basebis.put(BSE_CODDITTA, codditta);
  if (basebis.read(_isequal, _lock) == NOERR)
    setta_flag_quadri_comp(codditta,posquadro,compilato,basebis); 
  else
    warning_box("Lock fallito in set_compilato");
}