// cg3300.cpp
// Stampa allegati iva

#include <applicat.h>
#include <prefix.h>
#include <mask.h>
#include <printapp.h>
#include <progind.h>
#include <sort.h>
#include <recarray.h>
#include <tabutil.h>
#include <utility.h>
#include <validate.h>                     

#include <comuni.h>
#include <anagr.h>
#include <anafis.h>
#include <anagiu.h>
#include <nditte.h>
#include <alleg.h>
#include <clifo.h>
#include <mov.h>
#include <rmoviva.h>
#include <causali.h>

#include "cg3.h"
#include "cg3300.h"

#include "cg3300a.h"
#include "cg3300b.h"

#define LUNGHEZZA_FOOTER      3
#define DISTANZA_HEADER_CORPO 5
#define LUNGHEZZA_RECORD      128

const int CODTABLEN = 15;

const char* const SEGNO_MENO  = "-";
const char* const BARRA_SESSO = "x";

class TStampa_allegati : public TPrintapp
{
  TFile_printer   * _my_file_printer;
  int               _records [13];   //  Contatori dei vari tipi-record
  int               _num_volume;    // numero progressivo dischetti
  word               _num_pag;       // numero di pagine
  int               _num_cf;        // numero di C/F
  int               _width_modulo;  // larghezza modulo

  const char             * _buff;  // punta al risultato di retrieve()
  SortRecord             * _RecordSort;
  Totali                 * _t;
  Record_B               * _recb; 
  Array_desc_campi       * _frm;

  TSort*                 _sort;

  TDate                    _data_stampa;
  int                      _anno_stampa;
  stampe                   _tipo_stampa;
  modi_stampa              _destinazione_stampa;

  bool          _tronc, _arrot, _ordina_desc, _distingui_att, 
  _anno_prec, _stampa_tutti, _ricalcola;

  TString       _ricerca_att;
  long          _cod_ditta_da, _cod_ditta_a;
  char          _tipoa_richiesto;

  int           _SortRecLen;
  int           _cur_null;

public:

  const desc_campo& campi (int i) const  { return _frm->campi(i); }
  int          riga (int i) const     { return _frm->riga(i); }
  const char * formato (int i) const  { return _frm->formato(i); }

  virtual bool user_create () ;                         
  virtual bool user_destroy () ;                         
  virtual bool set_print (int);

  bool set_impostazione();
  bool set_ricalcola();
  bool set_dischetti();

  void init_sort();
  virtual bool preprocess_print (int file, int counter);
  virtual bool preprocess_page (int file, int counter);

  virtual void preprocess_header ();
  virtual void preprocess_footer ();

  virtual print_action postprocess_page (int,int);
  virtual print_action postprocess_print (int,int);

  bool intesta ();

  void tronca();
  void arrotonda();

  void stampa_su_disco();
  void ricalcola(int anno);
  void pulisci_alleg(int anno_dic);

  void stampa_totali(bool);

  void calcola();

  bool da_sommare(const TRectype & alleg);
  bool buono(const TRectype & alleg);

  bool lo_devo_stampare(char tipo, long codice);

  void set_rows(int);

  void scrivi();
  bool scrivi_volume(int);

  void scrivi_inizio_elenco_clienti();
  void scrivi_coda_elenco_clienti();
  void scrivi_inizio_elenco_fornitori();
  void scrivi_coda_elenco_fornitori();

  TPrintrow * get_record_inizio_volume (int) ;
  //  bool get_clienti (bool *, bool *) ;
  bool get_clienti () ;
  //  virtual TPrintrow * get_fornitori (bool *, bool *) ;
  TPrintrow * get_fornitori () ;
  TPrintrow * get_record_fine_volume (bool) ;

  long cerca_codice_all(char tipo, long codcf) const;
  bool corrispettivo (const char * tipodoc) const;

  TStampa_allegati () {}
  virtual ~TStampa_allegati () {}
};


// ----------------------------------------------------------------
//
// Utility di carattere generale
//
// ----------------------------------------------------------------

static const char* segno (const real& val) 
{ 
  if  (val < ZERO) 
    return SEGNO_MENO;
  return " ";
}

static const char* filler (int size)
{  
  static TString_array _fill;
  
  TToken_string* dep = (TToken_string*)_fill.objptr(size);
  if (dep == NULL)
  {
    dep = new TToken_string(size);
    dep->fill(' ', size);
    _fill.add(dep, size);
  }
  return *dep;
}

long TStampa_allegati::cerca_codice_all(char tipo, long codcf) const 
{
  TString8 key; key.format("%c|%ld", tipo, codcf);
  return atol(cache().get(LF_CLIFO, key, CLI_CODALLEG));
}

bool TStampa_allegati::corrispettivo (const char* tipodoc) const
{
  const TRectype& tpd = cache().get("%TPD", tipodoc);
  const int natura_doc = tpd.get_int("I0");
  const bool corrisp = tpd.get_bool ("B0");
  return corrisp && (natura_doc == 1 || natura_doc == 9);
}

// --------------------------------------------------------------------
//
// Inizio codice
//
// --------------------------------------------------------------------

void TStampa_allegati::init_sort()
{
  _sort         = new TSort (_SortRecLen);

  if (_distingui_att)
    _sort->addsortkey ((char *) &(_RecordSort->Strutt()->codatt_dic) 
                       - (char *) (_RecordSort->Strutt()), 5);

  if (_ordina_desc)
  {
    _sort->addsortkey ( (char *) &(_RecordSort->Strutt()->ragsoc_dett) - 
                       (char *)  (_RecordSort->Strutt()), 50);
    _sort->addsortkey ( (char *) &(_RecordSort->Strutt()->codcf_dett) - 
                       (char *)  (_RecordSort->Strutt()), sizeof (long) );
  }
  else
    _sort->addsortkey ( (char *) &(_RecordSort->Strutt()->codcf_dett) - 
                       (char *) (_RecordSort->Strutt()), sizeof (long) );
  _sort->init();
}

bool TStampa_allegati::user_create()
{
  open_files(LF_TABCOM, LF_NDITTE, LF_ALLEG, LF_CLIFO, 0);

  _RecordSort   = new SortRecord;
  _SortRecLen   = _RecordSort->RecSize();
  _recb         = new Record_B;
  _frm          = new Array_desc_campi;
  _t            = new Totali;

  _cur_null     = add_cursor (NULL);
  init_sort();
  return TRUE;
}

bool TStampa_allegati::user_destroy() 
{
  //  delete _sort;  // Adesso e' nella postprocess_print()
  delete _RecordSort;
  delete _recb;
  delete _frm;
  delete _t;
  return TRUE;
}

bool TStampa_allegati::set_ricalcola()
{
  ricalcola(0);
  return FALSE;
}

bool TStampa_allegati::set_dischetti()
{
  TMask msk("cg3300c") ;
  KEY   tasto;

  tasto = msk.run();

  if (tasto == K_ENTER) 
  {
    _data_stampa     = (const char *)msk.get (F_DATA_STAMPA);
    _anno_stampa     = msk.get_int(F_ANNO_STAMPA);
    _tipo_stampa     = (stampe) atoi(msk.get (F_TIPO_STAMPA2));

    _distingui_att = (bool) (msk.get (F_ATTIVITA) == "X");
    _ordina_desc   = (bool) (msk.get (F_ORDINA_DESC) == "X");
    _ricalcola     = (bool) (msk.get (F_RICALCOLA) == "X");

    _cod_ditta_da  = msk.get_long(F_DA_DITTA);
    _cod_ditta_a   = msk.get_long(F_A_DITTA);

    _ricerca_att   = msk.get (F_RICERCA_ATT);

    switch (_tipo_stampa)
    {
    case clienti:
      _tipoa_richiesto = 'C';
      _width_modulo = 132;
      break; 
    case fornitori:
      _tipoa_richiesto = 'F';
      _width_modulo = 132;
      break; 
    default:
      break; 
    }

    //    if (_destinazione_stampa == dischetto)

    // Adesso la scelta 3, che prima era "Modulo101", si chiama "Entrambi"
    // (vedi cg3300a.uml)
    if (_tipo_stampa == modulo101) _tipo_stampa = entrambi;

    _my_file_printer = new TFile_printer ("IVAECF", "IVAE", 128, 1, 1);

    stampa_su_disco();
  }
  return FALSE;
}

bool TStampa_allegati::set_impostazione()
{
  TMask msk("cg3300a") ;
  KEY   tasto;
  TString descr_modulo;

  tasto = msk.run();

  if (tasto == K_ENTER) 
  {
    _data_stampa     = (const char *)msk.get (F_DATA_STAMPA);
    _anno_stampa     = msk.get_int(F_ANNO_STAMPA);
    _destinazione_stampa = (modi_stampa)atoi(msk.get (F_MODO_STAMPA));

    _tipo_stampa     = (stampe)atoi(msk.get (F_TIPO_STAMPA));

    _anno_prec     = (bool) (msk.get (F_ANNO_PREC) == "X");
    _distingui_att = (bool) (msk.get (F_ATTIVITA) == "X");
    _tronc         = (bool) (msk.get (F_TRONC) != "X");
    _arrot         = (bool) (msk.get (F_ARROT) != "X");
    _ordina_desc   = (bool) (msk.get (F_ORDINA_DESC) == "X");
    _ricalcola     = (bool) (msk.get (F_RICALCOLA) == "X");

    _cod_ditta_da  = msk.get_long(F_DA_DITTA);
    _cod_ditta_a   = msk.get_long(F_A_DITTA);

    _ricerca_att   = msk.get (F_RICERCA_ATT);

    _stampa_tutti = (bool) (msk.get (F_STAMPA_TUTTI) == "X");

    switch (_tipo_stampa)
    {
    case clienti:
      _tipoa_richiesto = 'C';
      descr_modulo = "clifo"; 
      _width_modulo = 132;
      break; 
    case fornitori:
      _tipoa_richiesto = 'F';
      descr_modulo = "clifo"; 
      _width_modulo = 132;
      break; 
    case modulo101:
      _tipoa_richiesto = 'C';
      descr_modulo = "modulo101"; 
      _width_modulo = 80;
      break; 
    case modulo102:
      _tipoa_richiesto = 'F';
      descr_modulo = "modulo101"; 
      _width_modulo = 80;
      break; 
    default:
      break; 
    }
    // leggo descrizione modulo
    _frm->leggi_modulo ("cg3300.frm", descr_modulo);

    init_sort();
    _RecordSort->azzera_struttura();
    calcola();

    return TRUE;    
  }
  return FALSE;
}

bool TStampa_allegati::set_print(int scelta)
{
  switch (scelta)
  {
  case 1:
    return set_impostazione();
    break;
  case 2:
    return set_ricalcola();
    break;
  case 3:
    return set_dischetti();
    break;
  default:
    break;
  }
  return FALSE;
}

void TStampa_allegati::pulisci_alleg (int anno_dic)
{
  TString str; str.format("%s=%d", ALL_ANNO, anno_dic);                   
  TRelation rel(LF_ALLEG);
  TCursor cur(&rel, str);
  TRectype& curr = cur.curr();

  const long items = cur.items();         
  cur.freeze();
  
  str.format("Pulizia allegati %d in corso...", anno_dic);
  TProgind prn (items, str, FALSE, TRUE);
  for (cur = 0l; cur.pos() < items; ++cur)
  {
    prn.addstatus(1);
    
    
    const bool immesso = curr.get_bool (ALL_IMMESSO);

    if (immesso)
			continue;
 
    curr.zero(ALL_IMPESC);
    curr.zero(ALL_IVAESC);
    curr.zero(ALL_NIESC);
    curr.zero(ALL_E8ESC);

    curr.zero(ALL_IMPESP);
    curr.zero(ALL_IVAESP);
    curr.zero(ALL_NIESP);
    curr.zero(ALL_E8ESP);

    curr.zero(ALL_NDOCESC);
    curr.zero(ALL_NDOCESP);

    curr.zero(ALL_NALLESP);
    curr.zero(ALL_PROG101102);
    
    cur.file().rewrite(); 
  }
}

void TStampa_allegati::ricalcola(int anno_dic)
{
  //  TProgind prn;
  KEY         tasto;
  char        tipo;
  long        codcf;
  int         ndoc = 0;
  bool        vendite;
  real        imponibile;
  real        imposta;
  real        ni, imp, iva, e8, nall, prog101102;
  TString16   tipodoc;
  TString16   campo_codice_iva;
  TDate       datareg, datadoc;
  TString16   CAMPO_NALL, CAMPO_IMP, CAMPO_IVA, CAMPO_E8, CAMPO_NI, CAMPO_DOC;
  bool        flag_b;
  bool        flag_incrementa = FALSE;
  int         ndocesc;
  
  TLocalisamfile all(LF_ALLEG);
  all.setkey(2);  // Ricerca per anno-tipo-codice

  if (anno_dic <= 0)
  {
    TMask m ("cg3300b");
    tasto=m.run();
    if (tasto == K_ENTER)
      anno_dic = m.get_int(F_ANNO_RICALCOLA);
    else
      return; 
  }

  TRelation rel (LF_MOV);  
  rel.add (LF_RMOVIVA, "NUMREG=NUMREG"); 
  rel.add ("REG", "CODTAB=DATAREG[7,12]+REG"); 
  rel.add (LF_CAUSALI, "CODCAUS=CODCAUS"); 
  rel.add ("%IVA", "CODTAB=CODIVA",1,LF_RMOVIVA, 883); 
  
  TCursor cur(&rel, format("ANNOES=%04d", anno_dic));

  pulisci_alleg(anno_dic);

  const long items = cur.items();
  cur.freeze();
  TString str; str.format(TR("Ricalcolo anno %d..."), anno_dic);
  TProgind pi(items, str, FALSE, TRUE);

  const TRectype& mov_curr  = cur.curr(LF_MOV);
  TRectype& all_curr  = all.curr();
  const TRectype& reg = cur.file("REG").curr();
  const TRectype& cau = cur.curr(LF_CAUSALI);
  const TRectype& iva_rec = cur.file("%IVA").curr();
  for (cur = 0L; cur.pos() < items; ++cur )
  {
    pi.addstatus(1);
  
    const int tiporeg = reg.get_int("I0");
    if ((tiporeg != 2) && (tiporeg != 1))
      continue;

    if (tiporeg == 1)
    {
      bool sosp = reg.get_bool ("B0");
      if (sosp) continue;
      vendite = TRUE;
    }
    else
      vendite = FALSE;
    
    tipodoc = cau.get (CAU_TIPODOC);
    if (corrispettivo (tipodoc))
      continue;

    if (vendite)
    {
      campo_codice_iva = "S7";
      flag_b           = iva_rec.get_bool("B0");
    }
    else
    {
      campo_codice_iva = "S8";
      flag_b           = iva_rec.get_bool("B1");
    }

    tipo  = mov_curr.get_char(MOV_TIPO);
    codcf = mov_curr.get_long (MOV_CODCF);
    if (codcf <= 0L)
      continue;

    const long nuovo_codcf = cerca_codice_all (tipo, codcf);
    if (nuovo_codcf != 0)
      codcf = nuovo_codcf;

    all_curr.put (ALL_ANNO, anno_dic);
    all_curr.put (ALL_TIPOCF, tipo);
    all_curr.put (ALL_CODCF, codcf);
    all_curr.put (ALL_CODATT, reg.get("S8"));

    datareg = mov_curr.get_date (MOV_DATAREG);
    datadoc = mov_curr.get_date (MOV_DATADOC);

    if (datareg.year() == datadoc.year())
    {
      CAMPO_IMP  = ALL_IMPESC;
      CAMPO_IVA  = ALL_IVAESC;
      CAMPO_NI   = ALL_NIESC;
      CAMPO_E8   = ALL_E8ESC;
      CAMPO_NALL = ALL_NALLESC;
      CAMPO_DOC  = ALL_NDOCESC;
    }
    else
    {
      CAMPO_IMP  = ALL_IMPESP;
      CAMPO_IVA  = ALL_IVAESP;
      CAMPO_NI   = ALL_NIESP;
      CAMPO_E8   = ALL_E8ESP;
      CAMPO_NALL = ALL_NALLESP;
      CAMPO_DOC  = ALL_NDOCESP;
    }

    flag_incrementa = FALSE;
    ndoc = 0;

    const TRectype& rmi = cur.curr(LF_RMOVIVA);
		bool all_to_save = FALSE;
    while (cur.next_match (LF_RMOVIVA))
    {
      int err = all.read();

      if (err == NOERR)    // aggiungo un record se non presente
			{
	      if (all_curr.get_bool (ALL_IMMESSO))
					continue;        // scarta i record immessi
			}
			else
      {          
        all_curr.zero();
        all_curr.put (ALL_ANNO, anno_dic);
        all_curr.put (ALL_TIPOCF, tipo);
        all_curr.put (ALL_CODCF, codcf);
		    all_curr.put (ALL_CODATT, reg.get("S8"));
        err = all.write();
      }

			all_to_save = TRUE;
      imponibile = rmi.get_real (RMI_IMPONIBILE);
      imposta    = rmi.get_real (RMI_IMPOSTA);

      const int codice_iva = iva_rec.get_int(campo_codice_iva);
      if ((codice_iva == 1) || (codice_iva == 2) || (codice_iva == 3)) 
        flag_incrementa = TRUE;

      if (codice_iva == 1)
      {
        imp = all.get_real(CAMPO_IMP);
        iva = all.get_real(CAMPO_IVA);
        
        imp += imponibile;
        iva += imposta;

        all.put (CAMPO_IMP, imp);
        all.put (CAMPO_IVA, iva);
      }
      else
        if (codice_iva == 2)
        {
          ni = all.get_real(CAMPO_NI);
          ni += imponibile;
          all.put (CAMPO_NI, ni);
        }
        else
          if (codice_iva == 3)
          {
            e8 = all.get_real(CAMPO_E8);
            e8 += imponibile;
            all.put (CAMPO_E8, e8);
          }
          else
          {
            nall = all.get_real (CAMPO_NALL);
            nall += imponibile;
            all.put(CAMPO_NALL, nall);
          }
      
      if (flag_b) 
      {
        prog101102 = all.get_real (ALL_PROG101102);
        prog101102 += imponibile;
      }

      if (flag_incrementa)
      {
        ndoc++;
        ndocesc = all.get_int (CAMPO_DOC);
        ndocesc += ndoc;
        all.put(CAMPO_DOC, ndocesc);
      }
    }        // while next_match()

    if (all_to_save)
			all.rewrite();
  }          // for cur=0; ++cur
  cur.freeze(FALSE);
}

bool TStampa_allegati::lo_devo_stampare(char tipo, long codcf) 
{
  TString16 key ;
	
	key.format("%c|%ld", tipo, codcf);

	const TRectype & clifo = cache().get(LF_CLIFO, key);

  if (!clifo.empty())
  {
    const int codice_all = clifo.get_int(CLI_ALLEG);
    if ((codice_all == 0) || (codice_all == 3) || (codice_all == 4) )
      return TRUE;
    else 
      return FALSE;
  }

  return TRUE;
}


bool TStampa_allegati::da_sommare(const TRectype & alleg)
{
  TString tipocf2;
  long    codcf2;
  int anno2;
  TString codatt_dett;
  TString comodo;
  tipocf2      = alleg.get (ALL_TIPOCF);
  codcf2       = alleg.get_long (ALL_CODCF);
  anno2        = alleg.get_int(ALL_ANNO);
  codatt_dett  = alleg.get (ALL_CODATT);

  if (_RecordSort->codcf_dett() == -1) 
  {
    _RecordSort->compila(alleg);
    return TRUE;     // vuol dire che e' il primo => va messo nella struttura
  }
  
  comodo = _RecordSort->Strutt()->tipopers_dett;
  
  // Se l'anno e' compilato prendo solo i record di quell'anno altrimenti
  // se e' lasciato in bianco li considero tutti

  if (_anno_stampa > 0)
    if (_anno_stampa != anno2)
      return FALSE;

  if ((comodo == tipocf2) && (_RecordSort->Strutt()->codcf_dett == codcf2))
  {
    if (_distingui_att)
      if (codatt_dett != _RecordSort->Strutt()->codatt_dic)
        return FALSE;
  }
  else
    return FALSE;

  return TRUE;
}

//
// Ritorna vero se il record corrente di alleg 
// contiene dati che vanno bene per la stampa
//
// QUI COMPILO IL RECORD B PER I FORNITORI
//
bool TStampa_allegati::buono(const TRectype & alleg)
{
  if (!alleg.empty()) 
	{
	  char tipo  = alleg.get_char(ALL_TIPOCF);
		long codcf = alleg.get_long(ALL_CODCF);

  //
  // Se stampo i clienti scarto chi non ha codcf = "C"
  // 
		if (_tipoa_richiesto != tipo)
			return FALSE;

  // --------------------------------------------------------------------
  //                          GESTIONE RECORD B
  // --------------------------------------------------------------------
		if ((_tipo_stampa == fornitori) || (_tipo_stampa == modulo102))
		{
			if (tipo == 'B')
			{
				_recb->compila(alleg);
				return FALSE;
			}
		}
  
		if (_ricerca_att != "")
		{
			//    strcpy (_RecordSort->Strutt()->codatt_dett, _alleg->curr().get (ALL_CODATT));
			const TString& dep = alleg.get (ALL_CODATT);
			if (_ricerca_att != dep)
				return FALSE;
		}
  
		if (_anno_stampa > 0)
		{ 
			const int anno = alleg.get_int(ALL_ANNO);
			if (anno != _anno_stampa)
				return FALSE;
		}

		// se la stampa e' di controllo e voglio tutti i clienti mov. stampo tutti
		if ((_destinazione_stampa == controllo) && _stampa_tutti)
			return TRUE;

		if (!lo_devo_stampare(tipo, codcf))
			return FALSE;
	}

  return TRUE; 
}


// ----------------------------------------------------------------
// CALCOLA
//
// Richiamata dalla preprocess_print()
//
// Scorre _nditte
// Fa le somme su _alleg per ogni ditta
//
// ----------------------------------------------------------------
void TStampa_allegati::calcola ()
{
  static bool fatto_clienti   = FALSE;
  static bool fatto_fornitori = FALSE;

  const long ditta_da = _cod_ditta_da <= 0 ? 1 : _cod_ditta_da;
  const long ditta_a  = _cod_ditta_a <= 0 ? 99999L : _cod_ditta_a;

  _num_cf = 0;  // contatore C/F

  TRelation relditte(LF_NDITTE);
	TRectype from(relditte.curr());
	TRectype to(relditte.curr());

	from.put(NDT_CODDITTA, ditta_da);
	to.put(NDT_CODDITTA, ditta_a);
	
	TCursor ditte(&relditte, "", 1, &from, &to);
	const long items = ditte.items();
	const TRectype & ditta = ditte.curr();
  
	ditte.freeze();
  for (ditte = 0L; ditte.pos() < items; ++ditte) 
  {
    const long nuova_ditta = ditta.get_long(NDT_CODDITTA);

    if (prefix().exist(nuova_ditta))    // TBC *** fv mi sembrava ci volesse 
		{
	    set_firm(nuova_ditta);
    
		  if (_ricalcola) 
			  ricalcola(_anno_stampa);
      
			// Legge i dati anagrafici del dichiarante 
			_RecordSort->fill_dati_anag_dic(ditta);
    
			// ---------------------------------------------------------------------
			// ELABORAZIONE ALLEGATI
			// ---------------------------------------------------------------------
			TRelation relalleg(LF_ALLEG);
			TRectype from(relalleg.curr());

			from.put (ALL_ANNO, _anno_stampa);
			from.put (ALL_TIPOCF, _tipoa_richiesto);
			if (_ricerca_att != "") 
				from.put(ALL_CODATT, _ricerca_att);
			TCursor alleg(&relalleg, "", _distingui_att ? 1 : 2, &from, &from);
			const long items = alleg.items();
			const TRectype & recalleg = alleg.curr();

			alleg.freeze();
			
			TProgind prnd(items, TR("Elaborazione allegati in corso..."), FALSE, TRUE); 

			for (alleg = 0L; alleg.pos() < items; ++alleg)
			{
				prnd.addstatus(1);

				if (buono(recalleg))
				{
					if (da_sommare (recalleg))
						_RecordSort->somma(recalleg, _tipo_stampa);   // somma nella struttura
					else         
					{
						if (!_RecordSort->importo().is_zero()) 
						{
							_sort->sort (_RecordSort->Strutt_str());
							_num_cf += 1;     // incremento contatore numero di C/F
						}
						_t->incrementa_totali(_RecordSort->Strutt(), _tipo_stampa);
						_RecordSort->compila(recalleg);
					}  
				}   // if buono()
			}
		}
  }    // for su nditte

  //
  // Riazzero nuova_ditta dopo il for altrimenti non riesco a fare due stampe
  // prima di una ditta e poi di un'altra (si posiziona sulla successiva 
  // in nditte)
  //

  //
  // Se la stampa e' su disco non chiamo subito endsort() perche'
  // potrei richiamare calcola() per mettere nel sort l'elenco fornitori
  //
  if (_destinazione_stampa == dischetto)
  {
    if (_tipoa_richiesto == 'C')
      fatto_clienti = TRUE;
    
    if (_tipoa_richiesto == 'F')
      fatto_fornitori = TRUE;

    switch (_tipo_stampa)
    {
    case entrambi:
      if ((fatto_clienti) && (fatto_fornitori))
        _sort->endsort();
      break;
    case clienti:
      if (fatto_clienti)
        _sort->endsort();
      break;
    case fornitori: 
      if (fatto_fornitori)
        _sort->endsort();
      break;
    default:
      break;
    }
    
  }
  else   // stampa NON su disco
    _sort->endsort();

  //
  // CALCOLO IL NUMERO DI PAGINE CHE STAMPO FACENDO:
  //
  // NUMERO DI C/F  /  NUMERO DI RIGHE PER MODULO (letto dal .frm)
  //

  int righe_mod = _frm->righe_modulo();

  if ((_num_cf != 0) && (righe_mod != 0))
    _num_pag = (_num_cf / righe_mod) + 1;
  
}

print_action TStampa_allegati::postprocess_print(int file, int counter)
{
  delete _sort;   // E' proprio necessario ???
  return NEXT_PAGE;
}

print_action TStampa_allegati::postprocess_page(int file, int counter)
{
  int pagina_corrente = printer().getcurrentpage();

  switch (_tipo_stampa)
  {
  case clienti:
  case fornitori:
    if ( (_buff = _sort->retrieve()) != NULL)
    {
      return REPEAT_PAGE;  
    }
    break;

  default:
    break;

  }

  printer().formfeed();
  //
  // Se sono in una pagina dispari devo fare 2 formfeed
  //
  if (pagina_corrente & 1) 
    printer().formfeed(); 

  return NEXT_PAGE;
}

bool TStampa_allegati::preprocess_print (int file, int counter)
{
  printer().footerlen (LUNGHEZZA_FOOTER);
  reset_print();

  //  init_sort();
  //  _RecordSort->azzera_struttura();
  //  set_auto_ff (TRUE);

  select_cursor (_cur_null);  

  //
  // Crea e inizializza il sort.
  // Scorre _nditte
  // Fa le somme su _alleg per ogni ditta
  //

  //    calcola();


  // Leggo il primo record dal sort.
  // Le successive letture avvengono nella postprocess_page()
  //
  if ((_buff = _sort->retrieve()) == NULL)
    return FALSE;

  return TRUE;

}

void TStampa_allegati::arrotonda()
{
  struct alleg_sort *_rec = (struct alleg_sort *) _buff;
  
  const int arr = TCurrency::get_firm_dec() == 0 ? -3 : 0;
  
  _rec->impesc.round(arr); 
  _rec->ivaesc.round(arr);
  _rec->niesc.round(arr);
  _rec->e8esc.round(arr);

  _rec->tot_rigac.round(arr);
  
  _rec->impesp.round(arr);
  _rec->ivaesp.round(arr);
  _rec->niesp.round(arr);
  _rec->e8esp.round(arr);
  
  _rec->tot_rigap.round(arr);
}

void TStampa_allegati::tronca()
{
  real dep;

  alleg_sort *_rec = (alleg_sort *) _buff;
  
  dep = _rec->impesc / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->impesc = dep; 
  
  dep = _rec->ivaesc / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->ivaesc = dep; 
  
  dep = _rec->niesc / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->niesc = dep; 
  
  dep = _rec->e8esc / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->e8esc = dep; 
  
  dep = _rec->tot_rigac / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->tot_rigac = dep; 
  
  dep = _rec->impesp / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->impesp = dep; 
  
  dep = _rec->ivaesp / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->ivaesp = dep; 
  
  dep = _rec->niesp / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->niesp = dep; 
  
  dep = _rec->e8esp / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->e8esp = dep; 
  
  dep = _rec->tot_rigap / 1000.00;
  dep.trunc();
  dep = dep * 1000.00;
  _rec->tot_rigap = dep; 
  
}

void TStampa_allegati::set_rows(int counter)
{
  TString cog, nom; 
  TString tipo;

  struct alleg_sort *_rec = (struct alleg_sort *) _buff;

  tipo = _rec->tipopers_dett;
  if (tipo == "F") 
  {
    cog = _rec->cognome_dett;
    nom = _rec->nome_dett;
  }

  if (_arrot)
    arrotonda();

  if (_tronc)
    tronca();

  // -------------------------------------------------------------------------
  // RIGA DETTAGLIO 
  // -------------------------------------------------------------------------
  set_row ( riga(COG_DETT), formato(COG_DETT), _rec->cognome_dett);
  set_row ( riga(NOM_DETT), formato(NOM_DETT), _rec->nome_dett);
  set_row ( riga(VIA_DETT), formato(VIA_DETT), _rec->via_dett);
  set_row ( riga(COM_DETT), formato(COM_DETT), _rec->comune_dett);
  set_row ( riga(PRO_DETT), formato(PRO_DETT), _rec->prov_dett);

  // numero progressivo 
  set_row (riga(PROG_DETT), formato(PROG_DETT), counter);

  if (tipo == "F")
    set_row (riga(CASELLA_PAIVA), formato(CASELLA_PAIVA), "x" );

  set_row (riga(PAIVA_DETT), formato(PAIVA_DETT), _rec->paiva_dett);

  set_row (riga(ESC_DETT), formato(ESC_DETT), &_rec->ndocesc);

  if (_rec->impesc < 0)
    set_row (riga(SEGNO_IMPESC), formato(SEGNO_IMPESC), SEGNO_MENO);

  set_row (riga(IMPESC_DETT), formato(IMPESC_DETT), &_rec->impesc);

  if (_rec->ivaesc < 0)
    set_row (riga(SEGNO_IVAESC), formato(SEGNO_IVAESC), SEGNO_MENO);

  set_row (riga(IVAESC_DETT), formato(IVAESC_DETT), &_rec->ivaesc);

  if (_rec->niesc < 0)
    set_row (riga(SEGNO_NIESC), formato(SEGNO_NIESC), SEGNO_MENO);

  set_row (riga(NIESC_DETT), formato(NIESC_DETT), &_rec->niesc);

  if (_rec->e8esc < 0)
    set_row (riga(SEGNO_E8ESC), formato(SEGNO_E8ESC), SEGNO_MENO);

  set_row (riga(E8ESC_DETT), formato(E8ESC_DETT), &_rec->e8esc);

  if (_rec->tot_rigac < 0)
    set_row (riga(SEGNO_TOTC), formato(SEGNO_TOTC), SEGNO_MENO);

  set_row (riga(TOTC_DETT), formato(TOTC_DETT), &_rec->tot_rigac);

  set_row (riga(ESP_DETT), formato(ESP_DETT), &_rec->ndocesp);

  if (_rec->impesp < 0)
    set_row (riga(SEGNO_IMPESP), formato(SEGNO_IMPESP), SEGNO_MENO);

  set_row (riga(IMPESP_DETT), formato(IMPESP_DETT), &_rec->impesp);

  if (_rec->ivaesp < 0)
    set_row (riga(SEGNO_IVAESP), formato(SEGNO_IVAESP), SEGNO_MENO);

  set_row (riga(IVAESP_DETT), formato(IVAESP_DETT), &_rec->ivaesp);

  if (_rec->niesp < 0)
    set_row (riga(SEGNO_NIESP), formato(SEGNO_NIESP), SEGNO_MENO);

  set_row (riga(NIESP_DETT), formato(NIESP_DETT), &_rec->niesp);

  if (_rec->e8esp < 0)
    set_row (riga(SEGNO_E8ESP), formato(SEGNO_E8ESP), SEGNO_MENO);

  set_row ( riga(E8ESP_DETT), formato(E8ESP_DETT), &_rec->e8esp);

  if (_rec->tot_rigap < 0)
    set_row (riga(SEGNO_TOTP), formato(SEGNO_TOTP), SEGNO_MENO);

  set_row (riga(TOTP_DETT), formato(TOTP_DETT), &_rec->tot_rigap);

  int p = _frm->passo();

  for (int i=0; i<p; i++)
    set_row ( (riga(TOTP_DETT)+i), "%s", "\0");

}

bool TStampa_allegati::preprocess_page(int file,int counter)
{
  static long codditta_curr;
  static TString16 codatt_curr("     ");  // Sono 5 spazi
  struct alleg_sort * buff = (struct alleg_sort *) _buff;
  int pagina_corrente = printer().getcurrentpage();

  // Stampo intestazione se cambia la ditta...
  if (pagina_corrente > 1)
  {
    if ( buff->codditta_dic != codditta_curr )
    {
      codditta_curr = buff->codditta_dic;
      printer().formfeed();
      if (pagina_corrente & 1) 
        printer().formfeed();
      _t->azzera_totali();
    }
    else
    {
      // .. e se cambia l'attivita'
      if (_distingui_att && codatt_curr != buff->codatt_dic)
      {
        codatt_curr = buff->codatt_dic;
        printer().formfeed();
        if (pagina_corrente & 1) 
          printer().formfeed();
      }
    }
  }

  set_rows(counter);
  
  return TRUE;
}

void TStampa_allegati::preprocess_header()
{
  word pagina_corrente;

  //  printer().footerlen (LUNGHEZZA_FOOTER);
  pagina_corrente = printer().getcurrentpage();
  
  if (pagina_corrente & 1)
    intesta();
  else
    reset_header();
}

void TStampa_allegati::preprocess_footer()
{
  word pagina_corrente;
  bool ultima=FALSE;

  pagina_corrente = printer().getcurrentpage();

  // Per sapere se deve stampare il record B
  if (pagina_corrente >= _num_pag)
    ultima = TRUE;

  if (pagina_corrente == 1)
    _t->azzera_totali();

  if ((pagina_corrente & 1) == 0)
    stampa_totali(ultima);
}


void TStampa_allegati::stampa_totali(bool ultima)
{
  real    tot, tot_impes, tot_ivaes, tot_nies, tot_e8es;
  int     tot_es;

  if ((_tipo_stampa == fornitori) || (_tipo_stampa == modulo102))
    _recb->somma();
  else
    _recb->azzera();
  
  tot         = _t->RipTotTotRiga() + _t->TotTotRigac() + _t->TotTotRigap() 
    + _recb->tot_real();
  tot_es      = _t->RipTotEs() + _t->TotEsc() + _t->TotEsp() 
    + _recb->esc_int();
  tot_impes   = _t->RipTotImpes() + _t->TotImpesc() + _t->TotImpesp() 
    + _recb->impesc_real();
  tot_ivaes   = _t->RipTotIvaes() + _t->TotIvaesc() + _t->TotIvaesp()
    + _recb->ivaesc_real();
  tot_nies    = _t->RipTotNies()  + _t->TotNiesc() + _t->TotNiesp() ;
  tot_e8es    = _t->RipTotE8es()  + _t->TotE8esc() + _t->TotE8esp() ;

  // ------------------------------------------------------------
  // Record B (dati relativi alle importazioni
  // ------------------------------------------------------------

  if (_tipo_stampa == fornitori)
    if (ultima)
    {
      set_footer (riga(RECB_ESC), formato(RECB_ESC), _recb->esc_int() );
      set_footer (riga(RECB_IMPESC), formato(RECB_IMPESC), _recb->impesc_str() );
      set_footer (riga(RECB_IVAESC), formato(RECB_IVAESC), _recb->ivaesc_str() );

      if (_recb->tot_real() < 0)
        set_footer (riga(RECB_SEGNO_TOT), formato(RECB_SEGNO_TOT), SEGNO_MENO);
      
      set_footer (riga(RECB_TOT), formato(RECB_TOT), _recb->tot_str() );
    }
  
  // ------------------------------------------------------------
  // Riporti dalla pagina precedente
  // ------------------------------------------------------------

  set_footer (riga(RIP_ESC), formato(RIP_ESC), _t->RipTotEs());

  set_footer (riga(RIP_SEGNO_IMPESP), formato(RIP_SEGNO_IMPESP), segno(_t->RipTotImpes()));
  set_footer (riga(RIP_IMPESP), formato(RIP_IMPESP), _t->RipTotImpes().string(12,0));

  set_footer (riga(RIP_SEGNO_IVAESP), formato(RIP_SEGNO_IVAESP), segno(_t->RipTotIvaes()));
  set_footer (riga(RIP_IVAESP), formato(RIP_IVAESP), _t->RipTotIvaes().string(12,0));

  set_footer (riga(RIP_SEGNO_NIESP), formato(RIP_SEGNO_NIESP), segno(_t->RipTotNies()));
  set_footer (riga(RIP_NIESP), formato(RIP_NIESP), _t->RipTotNies().string(12,0));

  set_footer (riga(RIP_SEGNO_E8ESP), formato(RIP_SEGNO_E8ESP),
              segno(_t->RipTotE8es()));
  set_footer (riga(RIP_E8ESP), formato(RIP_E8ESP),
              _t->RipTotE8es().string(12,0));

  // ------------------------------------------------------------
  // Totali
  // ------------------------------------------------------------

  set_footer (riga(TOT_ESC), formato(TOT_ESC), tot_es);

  set_footer (riga(TOT_SEGNO_IMPESP), formato(TOT_SEGNO_IMPESP), 
              segno(tot_impes));
  set_footer (riga(TOT_IMPESP), formato(TOT_IMPESP), tot_impes.string(12,0));

  set_footer (riga(TOT_SEGNO_IVAESP), formato(TOT_SEGNO_IVAESP), 
              segno(tot_ivaes));
  set_footer (riga(TOT_IVAESP), formato(TOT_IVAESP), tot_ivaes.string(12,0));

  set_footer (riga(TOT_SEGNO_NIESP), formato(TOT_SEGNO_NIESP), 
              segno(tot_nies));
  set_footer (riga(TOT_NIESP), formato(TOT_NIESP), tot_nies.string(12,0));

  set_footer (riga(TOT_SEGNO_E8ESP), formato(TOT_SEGNO_E8ESP), 
              segno(tot_e8es));
  set_footer (riga(TOT_E8ESP), formato(TOT_E8ESP), tot_e8es.string(12,0));
}

// --------------------------------------------------------------------
// INTESTA 
// --------------------------------------------------------------------
bool TStampa_allegati::intesta()
{
  TString tipoa;
  struct alleg_sort * buff = (struct alleg_sort *) _buff;
  //  struct dati_dic * buff = _dati_dic;
  word num_pagina;

  num_pagina = printer().getcurrentpage();

  //  my_formfeed();
  //  reset_header();

  set_header (riga(PAIVA_DIC), formato(PAIVA_DIC), buff->paiva_dic); 
  set_header (riga(PAG_NUM), formato(PAG_NUM), num_pagina); 
  set_header (riga(NUM_PAG_TOT), formato(NUM_PAG_TOT), _num_pag); // qui verificare
  set_header (riga(NUM_REC), formato(NUM_REC), (const char*)_num_cf);

  tipoa << buff->tipopers_dic;
  if (tipoa == "F")
  {
    set_header (riga(COGNOME_DIC), formato(COGNOME_DIC), buff->cognome_dic);

    set_header (riga(NOME_DIC), formato(NOME_DIC), buff->nome_dic);

    TString gg_na, mm_na, aa_na;

    gg_na << buff->datana_dic.day();
    mm_na << buff->datana_dic.month();
    aa_na << buff->datana_dic.year ();
    aa_na = aa_na.mid(2);

    set_header (riga(GG_NA), formato(GG_NA), (const char *)gg_na);
    set_header (riga(MM_NA), formato(MM_NA), (const char *)mm_na);
    set_header (riga(AA_NA), formato(AA_NA), (const char *)aa_na);

    if (buff->sesso_dic[0] == 'M')
      set_header (riga(MASCHIO), formato(MASCHIO), BARRA_SESSO);
    else
      set_header (riga(FEMMINA), formato(FEMMINA), BARRA_SESSO);
    
    set_header (riga(COMUNE_NA), formato(COMUNE_NA), 
                (const char *)buff->comunena_dic);

    set_header (riga(PROV_NA), formato(PROV_NA), (const char *)buff->provna_dic);

    set_header (riga(IND_FIS), formato(IND_FIS), (const char *)buff->viafis_dic);
    
    set_header (riga(COMUNE_FIS), formato(COMUNE_FIS), 
                (const char *)buff->comunefis_dic);

    set_header (riga(PROV_FIS), formato(PROV_FIS), 
                (const char *)buff->provfis_dic);

    set_header (riga(PAIVA_FIS), formato(PAIVA_FIS), 
                (const char *)buff->paiva_dic);

    set_header (riga(ATT_FIS), formato(ATT_FIS), 
                (const char *)buff->attivita_dic);

    set_header (riga(CODATT_FIS), formato(CODATT_FIS), 
                (const char *)buff->codatt_dic);
  }
  else
    //
    // Persona giuridica
    //
  {
    set_header (riga(RAGSOC_DIC), formato(RAGSOC_DIC), 
                (const char*)buff->ragsoc_dic);

    set_header (riga(NAT_GIU), formato(NAT_GIU), buff->natgiu_dic);

    set_header (riga(IND_FIS), formato(IND_FIS),
                (const char*)buff->viafis_dic);

    set_header (riga(COMUNE_FIS), formato(COMUNE_FIS),  
                (const char*)buff->comunefis_dic);

    set_header (riga(PROV_FIS), formato(PROV_FIS),  
                (const char*)buff->provfis_dic);

    set_header (riga(PAIVA_GIU), formato(PAIVA_GIU),  
                (const char*)buff->paiva_dic);

    set_header (riga(ATT_GIU), formato(ATT_GIU),  
                (const char*)buff->attivita_dic);

    set_header (riga(CODATT_GIU), formato(CODATT_GIU),  
                (const char*)buff->codatt_dic);

  }

  for (int i = 0; i < DISTANZA_HEADER_CORPO; i++)
    set_header ( (riga(NUM_REC)+i), "%s"," ");

  return TRUE;     
}

// ----------------------------------------------------------------------
//
// STAMPA SU DISCO
//
// ----------------------------------------------------------------------

void TStampa_allegati::stampa_su_disco()
{
  TPrinter old = printer();
  
  if (_tipo_stampa == clienti)
  {
    _tipoa_richiesto = 'C';
    calcola();
  }

  if (_tipo_stampa == fornitori)
  {
    _tipoa_richiesto = 'F';
    calcola();
  }

  if (_tipo_stampa == entrambi)
  {
    _tipoa_richiesto = 'C';
    calcola();
    _tipoa_richiesto = 'F';
    calcola();
  }

  //  TApplication::set_printer (_my_file_printer);
  _my_file_printer->set();

  scrivi();

  _my_file_printer->genera_dischetti();
  //  TApplication::set_printer (&old);
}

void TStampa_allegati::scrivi()
{
  bool finito = FALSE;

  while (!finito)
  {
    finito=scrivi_volume(_my_file_printer->num_volumi());
    _my_file_printer->inc_volume();
  }
}

bool TStampa_allegati::scrivi_volume(int volume)
{
  bool finito = FALSE;
  TPrintrow * riga;
  TFilename dep ("");
  bool res = FALSE;
  bool inizio_elenco_clienti = TRUE; 
//  bool inizio_elenco_fornitori = TRUE; 
  bool finito_clienti   = FALSE;
  bool finito_fornitori = FALSE;
  //  static bool fclienti = TRUE;
  //  static bool ffornitori = FALSE;

  dep.temp("TMP$$");
  _my_file_printer->add_file(dep);
  //  _tmp_files.add(dep.temp("TMP$$"));

  _my_file_printer->set_printerfile (dep);

  riga = get_record_inizio_volume(volume);
  _my_file_printer->print(*riga);

  for (int i = 0; i < _my_file_printer->num_rec_volume(); i++)
  {
    switch (_tipo_stampa)
    {
    case clienti:
      if (!finito_clienti) 
      {
        if (inizio_elenco_clienti) {
          scrivi_inizio_elenco_clienti();
          inizio_elenco_clienti = FALSE; 
        }
        //          res = get_clienti(&fclienti, &ffornitori);
        res = get_clienti();
        
        if (res == FALSE) {
          scrivi_coda_elenco_clienti();
          finito_clienti = TRUE; 
        }
      }
      break;

    default:
      break;
    }

    /*******************
      if ((_tipo_stampa == entrambi) || (_tipo_stampa == clienti)) 
      {
      if (!finito_clienti) 
      {
      if (inizio_elenco_clienti) {
      scrivi_inizio_elenco_clienti();
      inizio_elenco_clienti = FALSE; }

      res = get_clienti(&fclienti, &ffornitori);

      if (res == FALSE) {
      scrivi_coda_elenco_clienti();
      finito_clienti = TRUE; }
      }
      }
      else 
      {
      if ((_tipo_stampa == entrambi) || (_tipo_stampa == fornitori))
      {
      if (!finito_fornitori) 
      {
      if (inizio_elenco_fornitori) {
      scrivi_inizio_elenco_fornitori();
      inizio_elenco_fornitori = FALSE; }
      
      //          riga = get_fornitori(&fclienti, &ffornitori);
      riga = get_fornitori();

      if (riga == NULL) {
      scrivi_coda_elenco_fornitori();
      finito_fornitori = TRUE; }
      else
      _my_file_printer->print(*riga);
      }
      }
      }    // else
      *******************/

  }      // for

  finito = finito_clienti && finito_fornitori;

  riga = get_record_fine_volume(finito);
  _my_file_printer->print(*riga);

  return (finito); 
}

void TStampa_allegati::scrivi_coda_elenco_clienti()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  char   segno[8];
  
  record.fill (' '); 

  if (_t->TotImpesc() < 0)
    segno[0] = '-';
  else
    segno[0] = ' ';

  if (_t->TotImpesp() < 0)
    segno[1] = '-';
  else
    segno[1] = ' ';

  if (_t->TotIvaesc() < 0)
    segno[2] = '-';
  else
    segno[2] = ' ';

  if (_t->TotIvaesp() < 0)
    segno[3] = '-';
  else
    segno[3] = ' ';

  if (_t->TotNiesc() < 0)
    segno[4] = '-';
  else
    segno[4] = ' ';

  if (_t->TotNiesp() < 0)
    segno[5] = '-';
  else
    segno[5] = ' ';

  if (_t->TotTotRigac() < 0)
    segno[6] = '-';
  else
    segno[6] = ' ';

  if (_t->TotTotRigap() < 0)
    segno[7] = '-';
  else
    segno[7] = ' ';

  record.format ("%2s%06d%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%24s",
                 "05",
                 _records[3],
                 (const char *)_t->TotImpesc().string("@@@@@@@@@@@"),
                 segno[0],
                 (const char *)_t->TotImpesp().string("@@@@@@@@@@@"),
                 segno[1],
                 (const char *)_t->TotIvaesc().string("@@@@@@@@@@@"),
                 segno[2],
                 (const char *)_t->TotIvaesp().string("@@@@@@@@@@@"),
                 segno[3],
                 (const char *)_t->TotNiesc().string("@@@@@@@@@@@"),
                 segno[4],
                 (const char *)_t->TotNiesp().string("@@@@@@@@@@@"),
                 segno[5],
                 (const char *)_t->TotTotRigac().string("@@@@@@@@@@@"),
                 segno[6],
                 (const char *)_t->TotTotRigap().string("@@@@@@@@@@@"),
                 segno[7],
                 filler(24)
                 );

  _records[5]++;
  riga->put(record);
  _my_file_printer->print(*riga);

}

void TStampa_allegati::scrivi_inizio_elenco_clienti()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  TString8 aa; aa.format("%02d", _anno_stampa%100);
  TString tipopers;
  TString datana; 
  int     cod_nat_giu=0;
  
  record.fill (' '); 
  tipopers = _RecordSort->Strutt()->tipopers_dic;

  datana = format ("%6s", _RecordSort->Strutt()->datana_dic.day(),
                   _RecordSort->Strutt()->datana_dic.month(),
                   _RecordSort->Strutt()->datana_dic.year() );

  if (tipopers == "F")
    cod_nat_giu = 0;

  if (tipopers == "F")
    record.format ("%2s%2d%11s%3s%2d%35s%24s%6s%1s%25s%2s", 
                   "01", (const char *)aa, 
                   (const char *)_RecordSort->Strutt()->paiva_dic, (const char *)filler(3), 
                   cod_nat_giu, 
                   (const char *)_RecordSort->Strutt()->cognome_dic, 
                   (const char *)_RecordSort->Strutt()->nome_dic, 
                   (const char *)_RecordSort->Strutt()->sesso_dic, 
                   (const char *)datana, 
                   (const char *)_RecordSort->Strutt()->comunena_dic,
                   (const char *)_RecordSort->Strutt()->provna_dic);

  else
    record.format ("%2s%2d%11s%3s%2d%60s%34s%13s", 
                   "01", (const char *)aa, 
                   _RecordSort->Strutt()->paiva_dic, filler(3), cod_nat_giu, 
                   _RecordSort->Strutt()->ragsoc_dic,
                   filler (34),
                   filler (13) );

  _records[1]++;   

  riga->put(record);
  _my_file_printer->print(*riga);

  record.format ("%2s%24s%34s%2s%65s", 
                 "02", (const char *)_RecordSort->Strutt()->comunefis_dic, 
                 (const char *)_RecordSort->Strutt()->viafis_dic, 
                 (const char *)_RecordSort->Strutt()->provfis_dic,
                 filler (65) );

  _records[2]++;   

  riga->put(record);
  _my_file_printer->print(*riga);

}

void TStampa_allegati::scrivi_inizio_elenco_fornitori ()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  TString8 aa; aa.format("%02d", _anno_stampa%100);
  TString tipopers;
  TString datana; 
  int     cod_nat_giu=0;
  
  record.fill (' '); 
  tipopers = _RecordSort->Strutt()->tipopers_dic;

  datana = format ("%6s", _RecordSort->Strutt()->datana_dic.day(),
                   _RecordSort->Strutt()->datana_dic.month(),
                   _RecordSort->Strutt()->datana_dic.year() );

  if (tipopers == "F")
    cod_nat_giu = 0;

  if (tipopers == "F")
    record.format ("%2s%2d%11s%3s%2d%35s%24s%6s%1s%25s%2s", 
                   "01", (const char *)aa, 
                   (const char *)_RecordSort->Strutt()->paiva_dic, (const char *)filler(3), 
                   cod_nat_giu, 
                   (const char *)_RecordSort->Strutt()->cognome_dic, 
                   (const char *)_RecordSort->Strutt()->nome_dic, 
                   (const char *)_RecordSort->Strutt()->sesso_dic, 
                   (const char *)datana, 
                   (const char *)_RecordSort->Strutt()->comunena_dic,
                   (const char *)_RecordSort->Strutt()->provna_dic);

  else
    record.format ("%2s%2d%11s%3s%2d%60s%34s%13s", 
                   "01", (const char *)aa, 
                   _RecordSort->Strutt()->paiva_dic, filler(3), cod_nat_giu, 
                   _RecordSort->Strutt()->ragsoc_dic,
                   filler (34),
                   filler (13) );

  _records[6]++;   

  riga->put(record);
  _my_file_printer->print(*riga);

  record.format ("%2s%24s%34s%2s%65s", 
                 "02", (const char *)_RecordSort->Strutt()->comunefis_dic, 
                 (const char *)_RecordSort->Strutt()->viafis_dic, 
                 (const char *)_RecordSort->Strutt()->provfis_dic,
                 filler (65) );

  _records[7]++;   

  riga->put(record);
  _my_file_printer->print(*riga);

}

//TPrintrow * TStampa_allegati::get_fornitori (bool* clienti, bool *fornitori)
TPrintrow * TStampa_allegati::get_fornitori ()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  TString tipoa;
  TString rag;
  TString stato, paiva;
  char    flag_paiva;
  char    flag_tipo_fornitore;
  static int progr = 0;
  char   segno[10];
  
  record.fill (' '); 

  _buff = _sort->retrieve();

  if (_buff == NULL) 
  {
    //    *clienti = TRUE;
    //    *fornitori = FALSE;
    return FALSE;
  }

  arrotonda();
  tronca();

  struct alleg_sort *_rec = (struct alleg_sort*) _buff;

  tipoa = _rec->tipopers_dett;

  if (tipoa != "F") return FALSE;

  //
  // METTEERE CONTROLLO VALIDITA PAIVA!!!! QUI !!!!
  //
  paiva = _rec->paiva_dett;
  stato = _rec->statopaiva_dett;

  if (pi_check (stato, paiva))
    flag_paiva = '0';
  else
    flag_paiva = '1';

  rag = _rec->ragsoc_dett;

  if (rag.not_empty())  // persona giuridica
  {
    flag_tipo_fornitore = '1';
    record.format ("%2s%06d%60s%34s%24s%2s",
                   "08",
                   ++progr,
                   (const char *)_rec->ragsoc_dett,
                   (const char *)_rec->via_dett,
                   (const char *)_rec->comune_dett,
                   (const char *)_rec->prov_dett);
  }
  else
  {
    flag_tipo_fornitore = '0';
    record.format ("%2s%06d%35s%25s%34s%24s%2s",
                   "08",
                   ++progr,
                   (const char *)_rec->cognome_dett,
                   (const char *)_rec->nome_dett,
                   (const char *)_rec->via_dett,
                   (const char *)_rec->comune_dett,
                   (const char *)_rec->prov_dett);
  }

  _records[8]++;
  riga->put(record);
  _my_file_printer->print(*riga);

  if (_rec->impesc < 0)
    segno[0] = '-';
  else
    segno[0] = ' ';

  if (_rec->impesp < 0)
    segno[1] = '-';
  else
    segno[1] = ' ';

  if (_rec->ivaesc < 0)
    segno[2] = '-';
  else
    segno[2] = ' ';

  if (_rec->ivaesp < 0)
    segno[3] = '-';
  else
    segno[3] = ' ';

  if (_rec->niesc < 0)
    segno[4] = '-';
  else
    segno[4] = ' ';

  if (_rec->niesp < 0)
    segno[5] = '-';
  else
    segno[5] = ' ';

  if (_rec->e8esc < 0)
    segno[6] = '-';
  else
    segno[6] = ' ';

  if (_rec->e8esp < 0)
    segno[7] = '-';
  else
    segno[7] = ' ';

  if (_rec->tot_rigac < 0)
    segno[8] = '-';
  else
    segno[8] = ' ';

  if (_rec->tot_rigap < 0)
    segno[9] = '-';
  else
    segno[9] = ' ';

  record.format ("%2s%11s%1c%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%17s",
                 "09",
                 (const char *)_rec->paiva_dett,
                 flag_paiva,
                 flag_tipo_fornitore,
                 (const char *)_rec->impesc.string("@@@@@@@@@@@"),
                 segno[0],
                 (const char *)_rec->impesp.string("@@@@@@@@@@@"),
                 segno[1],
                 (const char *)_rec->ivaesc.string("@@@@@@@@@@@"),
                 segno[2],
                 (const char *)_rec->ivaesp.string("@@@@@@@@@@@"),
                 segno[3],
                 (const char *)_rec->niesc.string("@@@@@@@@@@@"),
                 segno[4],
                 (const char *)_rec->niesp.string("@@@@@@@@@@@"),
                 segno[5],
                 (const char *)_rec->e8esc.string("@@@@@@@@@@@"),
                 segno[6],
                 (const char *)_rec->e8esp.string("@@@@@@@@@@@"),
                 segno[7],
                 filler(17)
                 );

  _records[9]++;
  riga->put(record);
  _my_file_printer->print(*riga);

  record.format ("%2s%11s%1c%11s%1c%5d%5d92s",
                 "10",
                 (const char *)_rec->tot_rigac.string("@@@@@@@@@@@"),
                 segno[6],
                 (const char *)_rec->tot_rigap.string("@@@@@@@@@@@"),
                 segno[7],
                 _rec->ndocesc,
                 _rec->ndocesp,
                 filler(92)
                 );

  _records[10]++;
  riga->put(record);

  return (riga);
}

void TStampa_allegati::scrivi_coda_elenco_fornitori()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  char   segno[10] = "         ";
  
  record.fill (' '); 

  if (_t->TotImpesc() < 0)
    segno[0] = '-';
  else
    segno[0] = ' ';

  if (_t->TotImpesp() < 0)
    segno[1] = '-';
  else
    segno[1] = ' ';

  if (_t->TotIvaesc() < 0)
    segno[2] = '-';
  else
    segno[2] = ' ';

  if (_t->TotIvaesp() < 0)
    segno[3] = '-';
  else
    segno[3] = ' ';

  if (_t->TotNiesc() < 0)
    segno[4] = '-';
  else
    segno[4] = ' ';

  if (_t->TotNiesp() < 0)
    segno[5] = '-';
  else
    segno[5] = ' ';

  if (_t->TotE8esc() < 0)
    segno[6] = '-';
  else
    segno[6] = ' ';

  if (_t->TotE8esp() < 0)
    segno[7] = '-';
  else
    segno[7] = ' ';

  if (_t->TotTotRigac() < 0)
    segno[8] = '-';
  else
    segno[8] = ' ';

  if (_t->TotTotRigap() < 0)
    segno[9] = '-';
  else
    segno[9] = ' ';

  record.format ("%2s%06d%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%24s",
                 "11",
                 _records[3],
                 _t->TotImpesc().string("@@@@@@@@@@@"),
                 segno[0],
                 _t->TotImpesp().string("@@@@@@@@@@@"),
                 segno[1],
                 _t->TotIvaesc().string("@@@@@@@@@@@"),
                 segno[2],
                 _t->TotIvaesp().string("@@@@@@@@@@@"),
                 segno[3],
                 _t->TotNiesc().string("@@@@@@@@@@@"),
                 segno[4],
                 _t->TotNiesp().string("@@@@@@@@@@@"),
                 segno[5],
                 _t->TotE8esc().string("@@@@@@@@@@@"),
                 segno[6],
                 _t->TotE8esp().string("@@@@@@@@@@@"),
                 segno[7],
                 _t->TotTotRigac().string("@@@@@@@@@@@"),
                 segno[8],
                 _t->TotTotRigap().string("@@@@@@@@@@@"),
                 segno[9]
                 );

  _records[11]++;
  riga->put(record);
  _my_file_printer->print(*riga);

  record.format ("%2s%11s%11s%11s%5d%88s", 
                 "12",
                 _recb->impesc_str(),
                 _recb->ivaesc_str(),
                 _recb->tot_str(),
                 _recb->esc_int(),
                 filler(88)
                 );

  _records[12]++;
  riga->put(record);
  _my_file_printer->print(*riga);
}

// bool TStampa_allegati::get_clienti (bool * clienti, bool * fornitori)
bool TStampa_allegati::get_clienti ()
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  TString tipoa;
  TString rag;
  TString paiva, stato;
  char    flag_paiva;
  char    flag_tipo_cliente;
  static int progr = 0;
  char   segno[8];
  
  record.fill (' '); 

  _buff = _sort->retrieve();

  if (_buff == NULL) 
  {
    //    *clienti = FALSE;
    //   *fornitori = TRUE;
    return FALSE;
  }

  arrotonda();
  tronca();

  struct alleg_sort *_rec = (struct alleg_sort*) _buff;

  tipoa = _rec->tipopers_dett;

  if (tipoa != "C") return FALSE;

  //
  // METTEERE CONTROLLO VALIDITA PAIVA!!!! QUI !!!!
  //
  paiva = _rec->paiva_dett;
  stato = _rec->statopaiva_dett;

  if (pi_check (stato, paiva))
    flag_paiva = '0';
  else
    flag_paiva = '1';

  rag = _rec->ragsoc_dett;

  if (rag.not_empty())  // persona giuridica
  {
    flag_tipo_cliente = '1';
    record.format ("%2s%06d%60s%34s%24s%2s",
                   "03",
                   ++progr,
                   (const char *)_rec->ragsoc_dett,
                   (const char *)_rec->via_dett,
                   (const char *)_rec->comune_dett,
                   (const char *)_rec->prov_dett);
  }
  else
  {
    flag_tipo_cliente = '0';
    record.format ("%2s%06d%35s%25s%34s%24s%2s",
                   "03",
                   ++progr,
                   (const char *)_rec->cognome_dett,
                   (const char *)_rec->nome_dett,
                   (const char *)_rec->via_dett,
                   (const char *)_rec->comune_dett,
                   (const char *)_rec->prov_dett);
  }

  _records[3]++;
  riga->put(record);
  _my_file_printer->print(*riga);

  if (_rec->impesc < 0)
    segno[0] = '-';
  else
    segno[0] = ' ';

  if (_rec->impesp < 0)
    segno[1] = '-';
  else
    segno[1] = ' ';

  if (_rec->ivaesc < 0)
    segno[2] = '-';
  else
    segno[2] = ' ';

  if (_rec->ivaesp < 0)
    segno[3] = '-';
  else
    segno[3] = ' ';

  if (_rec->niesc < 0)
    segno[4] = '-';
  else
    segno[4] = ' ';

  if (_rec->niesp < 0)
    segno[5] = '-';
  else
    segno[5] = ' ';

  if (_rec->tot_rigac < 0)
    segno[6] = '-';
  else
    segno[6] = ' ';

  if (_rec->tot_rigap < 0)
    segno[7] = '-';
  else
    segno[7] = ' ';

  record.format ("%2s%11s%1c%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%11s%1c%17s",
                 "04",
                 (const char *)_rec->paiva_dett,
                 flag_paiva,
                 flag_tipo_cliente,
                 (const char *)_rec->impesc.string("@@@@@@@@@@@"),
                 segno[0],
                 (const char *)_rec->impesp.string("@@@@@@@@@@@"),
                 segno[1],
                 (const char *)_rec->ivaesc.string("@@@@@@@@@@@"),
                 segno[2],
                 (const char *)_rec->ivaesp.string("@@@@@@@@@@@"),
                 segno[3],
                 (const char *)_rec->niesc.string("@@@@@@@@@@@"),
                 segno[4],
                 (const char *)_rec->niesp.string("@@@@@@@@@@@"),
                 segno[5],
                 (const char *)_rec->tot_rigac.string("@@@@@@@@@@@"),
                 segno[6],
                 (const char *)_rec->tot_rigap.string("@@@@@@@@@@@"),
                 segno[7],
                 filler(17)
                 );

  _records[4]++;
  riga->put(record);
  _my_file_printer->print(*riga);

  return TRUE;
}

TPrintrow * TStampa_allegati::get_record_inizio_volume (int volume_progr)
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  TString16 aa; aa.format("%02d", _anno_stampa%100);

  record.format ("%2s%02d%1s%2s%121s", "00", volume_progr, "2",
                 (const char *) aa, filler(121));

  riga->put(record);
  return riga; 
}

TPrintrow * TStampa_allegati::get_record_fine_volume (bool finito)
{
  TPrintrow * riga = new TPrintrow(); 
  TString record (LUNGHEZZA_RECORD);
  char    fine_volume;

  if (finito)
    fine_volume = 'F';
  else
    fine_volume = 'S';

  record.format ("%2s%1c%06ul%06ul%06ul%06ul%06ul%06ul%06ul%06ul%06ul%06ul%06ul%06ul%49s",
                 "13",
                 fine_volume,
                 _records[1],
                 _records[2],
                 _records[3],
                 _records[4],
                 _records[5],
                 _records[6],
                 _records[7],
                 _records[8],
                 _records[9],
                 _records[10],
                 _records[11],
                 _records[12],
                 filler(49)
                 );

  riga->put(record);
  return riga;
}

int cg3300(int argc, char* argv[])
{
  TStampa_allegati a;
  a.run(argc, argv, TR("Stampa Allegati"));
  return 0;
}