#include <mask.h>
#include <printapp.h>                  

#include <clifo.h> 
#include <effetti.h>
#include <reffetti.h>

#include "ef0101.h"       
#include "ef0600.h"

#define PICTURE_IMPORTO "###.###.###.##@,@@"
    
enum pt { st_undefined, st_banca_app, st_cliente,  st_distinta, st_scadenza, st_banca_pre };

////////////////////////////////////////////////////////////////////
// Classe per le stampe di controllo degli effetti in portafoglio // 
////////////////////////////////////////////////////////////////////
class TPrint_effetti_app : public TPrintapp
{    
  pt         _pr_type;           
  TRelation* _rel; 
  TPrintrow  _pr;
  TString    _ban, _banp, _cli,  _val, _data_stampa, _ban_prec;      
  TDate      _scad_prec;
  int        _cur_1, _cur_2, _cur_3, _cur_4, _cur_5, _cur_6, _cur_7;
  int        _interline, _colonne;
  long       _dist_prec, _cliente_prec;  
  char       _tipo_prec, _tipocf_prec;
  real       _tot_data, _tot_mese, _tot_banca, _tot_distinta, _tot_tip_dist, _tot_cliente, _tot_stampa;
  bool       _prima_volta;
  bool       _stampa_bancapp;
  char 			 _tipoord;
public:
  virtual bool preprocess_page(int file, int counter);
  virtual bool preprocess_print(int file, int counter);         
  virtual print_action postprocess_print(int file, int counter);
  virtual void preprocess_header();
  virtual print_action postprocess_page(int file, int counter);
  void header_scadenza();
  void header_banca_app();
  void header_banca_pre();
  void header_distinta(); 
  void header_cliente();
  virtual bool user_create();
  virtual bool user_destroy();
  virtual bool set_print(int);
  virtual void set_page (int file, int counter);
  void write_bancapp();  
  void set_scadenza();
  void set_banca_app();
  void set_banca_pre();
  void set_distinta();    
  void set_cliente();
  const char* get_field(int ln, const char* fn) {return current_cursor()->curr(ln).get(fn);}
  const char* look_tab(const char* tabname, const TString& cod,const char* fld="S0");
  const TString& look_clifo(char tipo, long codcf, TString& cli) const;
  void st_tot_scad();  
  void st_tot_mese(); 
  void st_tot_cliente(); 
  void st_tot_distinta();
  void st_tot_tipodist();
  void st_tot_banca();
  void st_header_scad(const TDate& scad);    
  void st_header_ban(const TString& ban);                        
  void st_header_dist(const char tipodist);   
  void st_header_cliente(const TString& cli);
  TPrint_effetti_app();
  virtual ~TPrint_effetti_app(){};   
};  

// Costruttore classe
TPrint_effetti_app::TPrint_effetti_app():TPrintapp(), _ban(11), _banp(11), _ban_prec(11), _cli(60), _val(3), _data_stampa(10)
{
  _rel = NULL;
  //_rec_prec = NULL;
  _interline = 1;
}                          

// restituisce la ragione sociale del cliente compattata
const TString& TPrint_effetti_app::look_clifo(char tipo, long codcf, TString& cli) const
{
  TString80 s;
  s << tipo << '|' << codcf;
  s = cache().get(LF_CLIFO, s, CLI_RAGSOC);
  cli = s.left(30); 
  cli.trim();
  s.ltrim(30);
  cli << ' ' << s;
  return cli;
}

// restituisce un campo di una tabella
const char* TPrint_effetti_app::look_tab(const char* tabname, const TString& cod, const char* fld)
{
  return cache().get(tabname, cod, fld);
}

// stampa  il totale per data di scadenza
void TPrint_effetti_app::st_tot_scad() 
{            
  _pr.put("_____________________________________________________",46);
  printer().print(_pr);
  _pr.reset();      
  _pr.put(TR("TOTALE"),46);   //sky totdata
  _pr.put(_scad_prec.string(),53);  
  _pr.put(_tot_data.string(PICTURE_IMPORTO),63);
  printer().print(_pr);
  _tot_data = 0.0;  
  _pr.reset();
}

// stampa il totale per mese delle data di scadenza
void TPrint_effetti_app::st_tot_mese() 
{            
  _pr.put(TR("TOTALE"),46);  //sky totmese
  if (_scad_prec.ok())
  {
    _pr.put(itom(_scad_prec.month()),53);  
    _pr.put(_tot_mese.string(PICTURE_IMPORTO),63);
  }  
  printer().print(_pr);
  _tot_mese = 0.0;  
  _pr.reset();                         
}               

// stampa il totale per distinta
void TPrint_effetti_app::st_tot_distinta() 
{ 
	TString80 s;           
  _pr.put("_____________________________________________________",46);
  printer().print(_pr);
  _pr.reset();
  _pr.put(TR("TOTALE"),46);
  _pr.put(_tot_distinta.string(PICTURE_IMPORTO),63); 
  printer().print(_pr);
  _pr.reset();
  s = TR("Distinta "); 
  s << _dist_prec << " " << _tipo_prec ;
  _pr.put(s,52);   
  printer().print(_pr);
  _tot_distinta = 0.0;  
  _pr.reset();                         
}     
                                
// stampa il totale per cliente                                
void TPrint_effetti_app::st_tot_cliente() 
{                                      
  _pr.put(TR("TOTALE"),46);  //sky totcli
  _pr.put(_tot_cliente.string(PICTURE_IMPORTO),63);  
  printer().print(_pr);
  _pr.reset();   
  TString80 cli;
  _pr.put((look_clifo(_tipocf_prec, _cliente_prec, cli)),52);   
  printer().print(_pr);
  _tot_cliente = 0.0;  
  _pr.reset();     
}               
                               
// stampa il totale per banca                               
void TPrint_effetti_app::st_tot_banca() 
{          
	TString80 s;                            
	_pr.put(TR("TOTALE"),46);
  _pr.put(_tot_banca.string(PICTURE_IMPORTO),63);  
  printer().print(_pr);
  _pr.reset();   
  s = (look_tab("%BAN",_ban_prec));
  if (s.empty())
  	s = TR("Banca assente");
 	_pr.put(s,52);   
 	printer().print(_pr);
 	_tot_banca = 0.0; 
 	_pr.reset();                         
}

// stampa il toale per tipo distinta
void TPrint_effetti_app::st_tot_tipodist()
{ 
	TString80 s;            
	if (_dist_prec == 0)
 	{
  	_pr.put("_____________________________________________________",46);
    printer().print(_pr);
    _pr.reset();
	}
	_pr.put(TR("TOTALE"),46); 
	_pr.put(_tot_tip_dist.string(PICTURE_IMPORTO),63);
	printer().print(_pr);  
	_pr.reset();
	s = TR("Distinte");
 	switch(_tipo_prec)
 	{
    case 'B':
      s << TR(" Salvo Buon Fine");
      break;
    case 'I':     
      s << TR(" All'Incasso");
      break;
    case 'S': 
      s << TR(" Allo Sconto");
      break;                  
    case 0:
      s = TR("Nessuna Distinta");
      break; 
 	}
 	_pr.put(s,52); 
 	printer().print(_pr);        
 	_tot_tip_dist = 0.0;  
 	_pr.reset();     
 	
} 	

// stampa l'intestazione per mese data scadenza
// (dopo la "rottura" per mese)
void TPrint_effetti_app::st_header_scad(const TDate& scad)
{             
  if (scad.ok())
  {
    TString16 year = scad.string();
    year = year.right(4);
    _pr.put(itom(scad.month()),1);   
    _pr.put(year,10); 
  }  
  printer().print(_pr);          
  _pr.reset();
}              

// stampa intestazione per banca di appoggio
// (dopo la "rottura" per banca)
void TPrint_effetti_app::st_header_ban(const TString& ban)
{            
  TString80 s = look_tab("%BAN",ban);
  if (s.empty())
    s = TR("Banca assente");
  _pr.put(s,1);   
  printer().print(_pr);          
  _pr.reset();
}             

// stampa intestazione per distinta di presentazione
// (dopo la "rottura" per distinta)                 
void TPrint_effetti_app::st_header_dist(const char tipodist)
{
  TString s = TR("Distinte");
  switch(tipodist)
  {
    case 'B':
      s << TR(" Salvo Buon Fine");
      break;
    case 'I':     
      s << TR(" All'Incasso");
      break;
    case 'S': 
      s << TR(" Allo Sconto");
      break;                  
    case 0:
      s = TR("Nessuna Distinta");
      break; 
  }                                       
  _pr.put(s,1);          
  printer().print(_pr);          
  _pr.reset();
  
}     

// stampa intestazione per cliente (dopo la "rottura" per cliente)
void TPrint_effetti_app::st_header_cliente(const TString& cli)
{            
  _pr.put(cli,1);   
  printer().print(_pr);          
  _pr.reset();
}             

// viene settato l'header delle diverse stampe
void  TPrint_effetti_app::preprocess_header()
{  
  reset_header();
  const long firm = get_firm();  
  int  j = 1;     
  const TRectype & ditte = cache().get(LF_NDITTE, firm);
  TString80 s;
  TString80 ditta(ditte.get("RAGSOC"));

  s = ditta.mid(30);

  s.trim();
	if (!s.empty())
	{
		ditta = ditta.left(30);
		ditta.trim();
		ditta << " " << s;  
	}
  set_header(j, FR("@bDitta:  %ld %s@125gPag @#"), firm, (const char*) ditta);
  set_header(j++, FR("@b@102gData %s"), (const char*) _data_stampa);

  switch(_pr_type)
  {
  case st_scadenza:
    header_scadenza();
    break;
  case st_banca_app:
    header_banca_app();
    break;
  case st_distinta:
    header_distinta();
    break;
  case st_cliente:
    header_cliente();
    break;  
  case st_banca_pre:
    header_banca_pre();
  default:
    break;
  }
}  

// setta l'header per la stampa per data di scadenza
void TPrint_effetti_app::header_scadenza()
{
  int j =2;
  set_header(j, FR("@52g@bSTAMPA RI.BA. PER SCADENZA"));  j++;
  set_header(j++, (const char *)(TString(_colonne).fill('_')));  
  TString head = FR("@b  Scadenza      Banca     Cliente                N.Riba  N.Dist           Importo    Imp. in valuta Val Rata Data fattura        N.");
  if (_stampa_bancapp)
    head << FR("@b    ABI   CAB Banca d'appoggio");
  set_header(j++, head);
  set_header(j, (const char *)(TString(_colonne).fill('_')));
}

// setta l'header per la stampa per banca di appoggio
void TPrint_effetti_app::header_banca_app()
{
  int  j = 2;     
  set_header(j, FR("@45g@bSTAMPA RI.BA. PER BANCA D'APPOGGIO"));  j++;
  set_header(j++, (const char *)(TString(_colonne).fill('_')));
  TString head = FR("@b    Banca      Scadenza   Cliente                N.Riba  N.Dist           Importo    Imp. in valuta Val Rata Data fattura        N.");
  if (_stampa_bancapp)
    head << FR("@b    ABI   CAB Banca d'appoggio");  
  set_header(j++, head);
  set_header(j, (const char *)(TString(_colonne).fill('_')));
}

// setta l'header per la stampa per banca di presentazione
void TPrint_effetti_app::header_banca_pre()
{
  int  j = 2;     
  set_header(j, FR("@45g@bSTAMPA RI.BA. PER BANCA DI PRESENTAZIONE"));  j++;
  set_header(j++, (const char *)(TString(_colonne).fill('_')));
  TString head = FR("@b    Banca      Scadenza   Cliente                N.Riba  N.Dist           Importo    Imp. in valuta Val Rata Data fattura        N.");
  set_header(j++, head);
  set_header(j, (const char *)(TString(_colonne).fill('_')));
}


// setta l'header per la stampa per distinta di presentazione
void TPrint_effetti_app::header_distinta()
{
  int  j = 2;     
  set_header(j, FR("@55g@bSTAMPA RI.BA. PER DISTINTE"));  j++;
  set_header(j++, (const char *)(TString(_colonne).fill('_')));
  set_header(j++, FR("@b Distinta "));
  TString head = FR("@bTp.    Num. N.Riba   Scadenza    Banca    Cliente                         Importo    Imp. in valuta Val Rata Data fattura        N.");
  if (_stampa_bancapp)
    head << FR("@b    ABI   CAB Banca d'appoggio");
  set_header(j++, head);
  set_header(j, (const char *)(TString(_colonne).fill('_')));
}

// setta l'header per la stampa per cliente 
void TPrint_effetti_app::header_cliente()
{
  int j = 2;
  set_header(j, FR("@52g@bSTAMPA RI.BA. PER CLIENTE"));  j++;
  set_header(j++, (const char *)(TString(_colonne).fill('_')));
  TString head = FR("@b     Cliente             Scadenza       Banca    N.Riba  N.Dist           Importo    Imp. in valuta Val Rata Data fattura        N.");
  if (_stampa_bancapp)
    head << FR("@b    ABI   CAB Banca d'appoggio");
  set_header(j++, head);
  set_header(j, (const char *)(TString(_colonne).fill('_'))); 
} 

// svolge operazioni di chiusura dei totali pendenti dalla stampa
// che � ormai terminata
print_action TPrint_effetti_app::postprocess_print(int file, int counter)
{
  TString s;
  if (_tipoord == 'D')
  {
	  if (_tot_data != 0.0) 
	     st_tot_scad();
	  if(_tot_mese != 0.0)
	     st_tot_mese();
	}     
	else if (_tot_cliente != 0.0)
  	st_tot_cliente();
	
  if (_tot_banca != 0.0)
  	st_tot_banca();

  if (_tot_distinta != 0.0 &&_dist_prec != 0)
  	st_tot_distinta();

  if (_tot_tip_dist != 0.0)
  	st_tot_tipodist();

  if (_tot_cliente != 0.0)
   	st_tot_cliente();

  if (_tot_stampa != 0.0) 
  {
     _pr.reset();   
     _pr.put("_____________________________________________________",46);
     printer().print(_pr);
     _pr.reset();
     _pr.put(TR("TOTALE "),46);   
     _pr.put(_tot_stampa.string(PICTURE_IMPORTO),63);
     printer().print(_pr);                                         
     _pr.reset();
     _pr.put(TR("RI.BA. STAMPATE"),52);
     printer().print(_pr);
     _pr.reset();      
     _pr.put("_____________________________________________________",46);
     printer().print(_pr);
     _pr.reset();     
     _tot_stampa = 0.0;  
  }    
  return NEXT_PAGE;                   
}  

print_action TPrint_effetti_app::postprocess_page(int file, int counter)
{
  reset_print();
  return NEXT_PAGE;                   
}

// setta, secondo il tipo di stampa scelto, la pagina logica
void  TPrint_effetti_app::set_page(int file, int counter)
{  
  switch(_pr_type)
  {
  case st_scadenza:
    set_scadenza();
    break;
  case st_banca_app:
    set_banca_app();
    break;
  case st_distinta:
    set_distinta();
    break;
  case st_cliente:
    set_cliente();
    break; 
  case st_banca_pre:
    set_banca_pre();
    break;
  default:
    break;
  }
}

// scrive,se richiesto nella maschera, ABI CAB descABI descCAB della banca di APPOGGIO dell'effetto
void TPrint_effetti_app::write_bancapp()
{                      
  if (_stampa_bancapp)
  { 
    const TRectype& rec = current_cursor()->curr();       
    const TString8 codabi = rec.get(EFF_CODABI); 
    TString16 codcab; codcab << codabi << rec.get(EFF_CODCAB);
    TString80 desccab = look_tab("%BAN", codcab);
    set_row(2,"@133g@pn @pn %s",
              FLD(LF_EFFETTI, EFF_CODABI, "@@@@@"),
              FLD(LF_EFFETTI, EFF_CODCAB, "@@@@@"),
              (const char*)desccab);
  }
}

// setta la pagina logica nel caso di stampa per data di scadenza
void TPrint_effetti_app::set_scadenza()
{                        
  set_row(1," ");
  set_row(2,"@1g@s@13g#t@26g@pn@33g#t@49g@pn@55g@pn@63g@pn@105g@pn@111g@s@125g@n",
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_banp,
                  FLD(LF_EFFETTI, EFF_CODCF,"@@@@@@"),
                  &_cli,
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_IMPORTO, PICTURE_IMPORTO),
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT,"######"));
                  
  const TString8 valuta = current_cursor()->curr().get(EFF_CODVAL);
  if (!is_firm_value(valuta))  //effetto in valuta diversa da quella di conto
  {  
    set_row(2,"@81g@pn@100g%s",
              FLD(LF_EFFETTI, EFF_IMPORTOVAL, PICTURE_IMPORTO),
              (const char *)valuta);
  }   
  write_bancapp();               
  for(int i = 0; i < _interline; i++)
    set_row(i+1," ");
}

// setta la pagina logica nel caso di stampa per banca di appoggio
void TPrint_effetti_app::set_banca_app()
{
  set_row(1," ");
  set_row(2,"@1g#t@14g@s@26g#t@49g@pn@55g@pn@63g@pn@105g@pn@111g@s@125g@pn",
            &_banp,
            FLD(LF_EFFETTI, EFF_DATASCAD),
            &_cli,
            FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
            FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
            FLD(LF_EFFETTI, EFF_IMPORTO, PICTURE_IMPORTO),
            FLD(LF_REFFETTI, REFF_NRATA,"##@"),
            FLD(LF_REFFETTI, REFF_DATAFATT),
            FLD(LF_REFFETTI, REFF_NFATT,"######"));

  const TString& valuta = current_cursor()->curr().get(EFF_CODVAL);
  if (!is_firm_value(valuta))  //effetto in valuta diversa da quella di conto
  {  
    set_row(2,"@81g@pn@100g%s",
              FLD(LF_EFFETTI, EFF_IMPORTOVAL, PICTURE_IMPORTO),
              (const char *)valuta);
  }                  
  write_bancapp();
  for(int i = 0; i < _interline; i++)    
    set_row(i+1,"");   
}

// setta la pagina logica nel caso di stampa per banca di appoggio
void TPrint_effetti_app::set_banca_pre()
{
  set_row(1," ");
  set_row(2,"@1g#t@14g@s@26g#t@49g@pn@55g@pn@63g@pn@105g@pn@111g@s@125g@pn",
            &_banp,
            FLD(LF_EFFETTI, EFF_DATASCAD),
            &_cli,
            FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
            FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
            FLD(LF_EFFETTI, EFF_IMPORTO, PICTURE_IMPORTO),
            FLD(LF_REFFETTI, REFF_NRATA,"##@"),
            FLD(LF_REFFETTI, REFF_DATAFATT),
            FLD(LF_REFFETTI, REFF_NFATT,"######"));

  const TString& valuta = current_cursor()->curr().get(EFF_CODVAL);
  if (!is_firm_value(valuta))  //effetto in valuta diversa da quella di conto
  {  
    set_row(2,"@81g@pn@100g%s",
                  FLD(LF_EFFETTI, EFF_IMPORTOVAL, PICTURE_IMPORTO),
                  (const char *)valuta);
  }                  
  write_bancapp();
  for(int i = 0; i < _interline; i++)    
    set_row(i+1,"");   
}


// setta la pagina logica nel caso di stampa per distinta di presentazione
void TPrint_effetti_app::set_distinta()
{
  set_row(1," ");
  set_row(2,"@1g@s@3g@pn@12g@pn@19g@ld@30g#t@42g#-20t@63g@pn@105g@pn@111g@s@125g@pn",
                  FLD(LF_EFFETTI, EFF_TIPODIST),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_banp,
                  &_cli,
                  FLD(LF_EFFETTI, EFF_IMPORTO, PICTURE_IMPORTO),
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT,"######"));

  const TString8 valuta = current_cursor()->curr().get(EFF_CODVAL);
  if (!is_firm_value(valuta))  //effetto in valuta diversa da quella di conto
  {  
    set_row(2,"@81g@pn@100g%s",
                  FLD(LF_EFFETTI, EFF_IMPORTOVAL, PICTURE_IMPORTO),
                  (const char *)valuta);
  }
	else
	{
		set_row(2,"@100g%s", (const char *)TCurrency::get_firm_val());
	}
  write_bancapp();               
  for(int i = 0; i < _interline; i++)    set_row(i+1,"");
}

// setta la pagina logica nel caso di stampa per cliente
void TPrint_effetti_app::set_cliente()
{
  set_row(1," ");
  set_row(2,"@5g@pn@25g@s@37g#t@49g@pn@55g@pn@63g@pn@105g@pn@111g@s@125g@pn",
                  FLD(LF_EFFETTI, EFF_CODCF,"@@@@@@"),
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_banp,
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_IMPORTO, PICTURE_IMPORTO),
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT,"######"));
                  
  const TString8 valuta = current_cursor()->curr().get(EFF_CODVAL);
  if (!is_firm_value(valuta))  //effetto in valuta diversa da quella di conto
  {  
    set_row(2,"@81g@pn@100g%s",
                  FLD(LF_EFFETTI, EFF_IMPORTOVAL, PICTURE_IMPORTO),
                  (const char *)valuta);
  }
   write_bancapp();               
   for(int i = 0; i < _interline; i++)    set_row(i+1," ");
} 

// effettua operazioni preliminari alla stampa
bool  TPrint_effetti_app::preprocess_page(int file, int counter)
{                                                   
    TString s;                                           
    // scarico i dati, dal record corrente del cursore, che mi 
    // necessitano per effettuare la "rorrura della stampa"
    TRectype& rec = current_cursor()->curr(); 
    const TDate scad = rec.get_date (EFF_DATASCAD);
    long  dist = rec.get_long (EFF_NDIST);
    char tipodist = rec.get_char(EFF_TIPODIST);
    long cliente =   rec.get_long (EFF_CODCF);
    char tipocf = rec.get_char(EFF_TIPOCF);
    real importo =  rec.get_real(EFF_IMPORTO);
    // elaboro le seguenti  stringhe per la stampa
    _ban = get_field(LF_EFFETTI, EFF_CODABI);
    if (real::is_null(_ban)) 
       _ban.cut(0);
    else
    {
      s = get_field(LF_EFFETTI, EFF_CODCAB);
      if (!real::is_null(s)) 
        _ban << ' ' << s;                                
    }

    _banp = get_field(LF_EFFETTI, EFF_CODABIP);
    if (real::is_null(_banp)) 
      _banp.cut(0);             
    else
    {
      s = get_field(LF_EFFETTI, EFF_CODCABP);
      if (!real::is_null(s)) 
        _banp << ' ' << s;                                
    }
    
    TString16 ban;
    if (_pr_type == st_banca_pre)
      ban = _banp;
    else
      ban = _ban;
    ban.strip(" "); // Toglie lo spazio tra ABI e CAB

    _cli =  get_field(LF_CLIFO, CLI_RAGSOC);
    s = _cli.mid(30,50); s.trim();
    _cli = _cli.mid(0,30); _cli.trim();
    _cli << " " << s;

    if (_pr_type != st_cliente)
      _cli = _cli.left(25);
             
    _val = get_field(LF_EFFETTI, EFF_CODVAL);  

    // se � la prima volta che stampo devo inizializzare i dati di 
    // controllo "rottura stampa" e stampare l' header relativo
    // alla stampa selezionata
    if (_prima_volta)
    {                            
      _prima_volta = FALSE; 
      _scad_prec = scad;      
      switch(_pr_type)
      {
      case st_scadenza:
          st_header_scad(scad); 
          break;   
      case st_banca_app:              
      case st_banca_pre:              
          _ban_prec = ban; // ban vale automaticamente appoggio o presentazione
          st_header_ban(ban);    
          break;  
      case st_distinta:
          _dist_prec = dist; 
          _tipo_prec = tipodist;
          _cliente_prec = cliente;
          _tipocf_prec = tipocf;
          st_header_dist(tipodist); 
          if (_tipoord == 'D')
            st_header_scad(scad);
          break;  
      case st_cliente:
          _cliente_prec = cliente; 
          _tipocf_prec = tipocf;
          st_header_cliente(_cli); 
          break;       
      default: 
           break; 
      } 
    } 
    //else
    {
     // se effetto raggruppato stampo la lista delle fatture a cui si 
     // riferisce (dalla seconda poich� la prima viene sempre stampata
     // nella pagina logica) 
     TEffetto effetto(rec);// = *_rec_prec;
     long num = effetto.numero();                       
     // prendo dall'effetto tutti i dati relativi alle fatture, che 
     // vengono inseriti nella Token_String nell'ordine
     // NUMERO FATTURA|DATA FATTURA|IMPORTO FATTURA
     TToken_string dati; effetto.dati_fatt(num, FALSE, dati);
     int elem = dati.items();
     if (elem > 3)
     {
       TString descfatt;
       int j=3;
       for (int i = 3; i < elem; i+=3)
       {
          descfatt = dati.get(i+1);// prendo la data della fattura
          descfatt << "    ";  
          descfatt << dati.get(i);// prendo il numero della fattura
          _pr.reset();
          if (_pr_type == st_scadenza || _pr_type == st_cliente )
             _pr.put(descfatt, 111);
          else
             _pr.put(descfatt, 114);  
          //printer().print(_pr);
          set_row(j++,_pr);
         _pr.reset();
       } 
     } 
    }   
    // a seconda del tipo di stampa che devo effettuare  svolgo i controlli per la "rottura stampa"
    switch(_pr_type)
    {       
      case st_scadenza: 
         // � cambiata la data di scadenza, stampo il relativo totale
         if (scad != _scad_prec) 
            st_tot_scad(); 
         // � cambiato il mese della la data di scadenza, stampo il relativo totale 
         // ed il nuovo header del mese
         if (scad.month() !=_scad_prec.month())
         {  
            st_tot_mese();            
            _pr.reset();     
            printer().print(_pr);
            st_header_scad(scad);
         } 
         _scad_prec = scad;  
         _tot_data += importo;
         _tot_mese += importo;         
         _tot_stampa += importo ;
         break;                    
      case st_banca_app:  
      case st_banca_pre:  
         // � cambiata la data di scadenza, stampo il relativo totale
         if (scad != _scad_prec)
            st_tot_scad();
         // � cambiato il mese della la data di scadenza,
         // stampo il relativo totale 
         if (scad.month() !=_scad_prec.month())
            st_tot_mese();
         // stampo i totali di data e di mese nel caso in cui cambi 
         // la banca ma non la data o il mese
         if (ban !=_ban_prec) 
         {                                
            if (scad == _scad_prec)
               st_tot_scad(); 
            if (scad.month() ==_scad_prec.month())
               st_tot_mese(); 
            // stampo totale  banca    
            st_tot_banca();

            printer().print(_pr);    
            // stampo nuovo header banca
            st_header_ban(ban);
         } 
         _scad_prec = scad;
         _ban_prec = ban;     
         _tot_data += importo;
         _tot_banca += importo;
         _tot_mese += importo;   
         _tot_stampa += importo ;
         break;    
      case st_distinta:  
         // � cambiato il numero distinta, stampo il relativo totale 
         // � cambiato il mese della la data di scadenza, stampo il relativo totale 
         // ed il nuovo header del mese
      	if (_tipoord == 'D')
        {
	        if (scad != _scad_prec) 
	           st_tot_scad(); 
	        if (scad.month() !=_scad_prec.month())
	        {  
	        	st_tot_mese();            
	          _pr.reset();     
	          printer().print(_pr);
	          st_header_scad(scad);
	        }
        } 
        else if (_tipoord == 'C')
        {
        	if (tipocf != _tipocf_prec || cliente !=_cliente_prec) 
   					st_tot_cliente();      		
        }
        if (dist !=_dist_prec)
        {                                
       	  if (_tipoord == 'D')
       	 	{
          	if (scad.month() ==_scad_prec.month())
            	 st_tot_mese(); 
          }   
          //il totale per nessuna distinta si fa solo per tipo
          if (_dist_prec != 0)
          	st_tot_distinta();
          // � cambiato il tipo distinta, stampo il relativo totale
          if(tipodist != _tipo_prec)
          {
          	st_tot_tipodist();
            printer().print(_pr);
            st_header_dist(tipodist);      
          } 
        } 
        _scad_prec = scad;
        _dist_prec = dist;     
        _tipo_prec = tipodist;
        _cliente_prec = cliente;
        _tipocf_prec = tipocf;
				
				if (_tipoord == 'C')
        	_tot_cliente += importo;      
        _tot_distinta += importo;      
        _tot_tip_dist += importo;  
        _tot_data += importo;
        _tot_mese += importo;   
        _tot_stampa += importo ;
        break;  

      case st_cliente:                 
         // � cambiata la data di scadenza, stampo il relativo totale
         if (scad != _scad_prec)
            st_tot_scad();
         // � cambiato il mese della la data di scadenza, 
         // stampo il relativo totale 
         if (scad.month() !=_scad_prec.month())
            st_tot_mese();
         // stampo i totali di data e di mese nel caso in cui cambi 
         // il cliente ma non la data o il mese                                     
         if (tipocf != _tipocf_prec || cliente !=_cliente_prec) 
         {  
            if (scad == _scad_prec)
                st_tot_scad();
            if (scad.month() ==_scad_prec.month())
                st_tot_mese();
            // stampo totale  cliente      
            st_tot_cliente();

            printer().print(_pr);
            st_header_cliente(_cli);
         } 
         _cliente_prec = cliente;     
         _tipocf_prec = tipocf;
         _scad_prec = scad;
         _tot_cliente += importo;      
         _tot_data += importo;     
         _tot_mese += importo;   
         _tot_stampa += importo ;                
         break;
      default:
         break;    
    } 
    return TRUE;  
}
 
// permette di eseguire qualcosa prima della richiesta del un processo
// di stampa 
bool TPrint_effetti_app::preprocess_print(int file, int counter)
{    
  // forza la rilettura di set_page
  reset_print();     
  return TRUE;
} 


bool  TPrint_effetti_app::set_print(int)
{                 
  TMask mask("ef0600a.msk");
  if (mask.run() == K_QUIT)
    return FALSE;

  _tipoord = 'D';                               
  disable_links();
  set_multiple_link(FALSE);
  // richiamo la maschera di scelta del tipo di stampa   
  force_setpage(FALSE);
  _pr_type = (pt)mask.get_int(RDB_TIPOST);       
  TDate data_stampa (mask.get(F_DATA_STAMPA));
  _data_stampa = data_stampa.string();
  _stampa_bancapp = mask.get_bool(F_BANCA_APP);
  _colonne = _stampa_bancapp ? 198 : 132;
  
  // inizializzo i record di scelta del cursore
  TRectype from(current_cursor()->curr());
  from.zero();
  TRectype to(from);  
  TString cod_from, cod_to, filter;  
  char tipocf;
  // a seconda del tipo di stampa scelta , seleziono  il curore 
  // da utilizzare ed imposto i campi per la regione e il filtro 
  // del cursore
  switch(_pr_type)
  {
    case st_scadenza: 
    {
      cod_from = mask.get(F_DA_DATA);       
      cod_to = mask.get(F_A_DATA);  
      from.put(EFF_DATASCAD,cod_from);
      to.put(EFF_DATASCAD,cod_to); 
      tipocf = mask.get(F_TIPOCF)[0];
      filter.cut(0) << "(TIPOCF=='" << tipocf << "')";
      select_cursor(_cur_1);    
    }  
    break;
    case st_banca_app:
    {
      cod_from = mask.get(F_DA_DATA2);
      cod_to = mask.get(F_A_DATA2);  
      from.put(EFF_DATASCAD,cod_from);
      to.put(EFF_DATASCAD,cod_to); 
      cod_from = mask.get(F_DABAN);
      cod_to = mask.get(F_ABAN);
      if (cod_from.empty()) 
        cod_from = "00000"; // per selezionare tutte 
      if (cod_to.empty())   // le banche 
        cod_to = "99999";     
      tipocf = mask.get(F_TIPOCF2)[0];
      filter = "";
      filter << "(CODABI>=" << cod_from << ")&&(CODABI<=" << cod_to << ")";
      filter << "&&(TIPOCF=='" << tipocf << "')";
      select_cursor(_cur_2);
    }  
    break;
    case st_banca_pre:
    {
      from.put(EFF_DATASCAD,mask.get(F_DA_DATA2));
      to.put(EFF_DATASCAD,mask.get(F_A_DATA2)); 
      cod_from = mask.get(F_DABAN);
      cod_to = mask.get(F_ABAN);
      filter = "(NDIST!='')";
      if (cod_from.not_empty())
        filter << "&&(CODABIP>='" << cod_from << "')";
      if (cod_to.not_empty())
        filter << "&&(CODABIP<='" << cod_to << "')";
      tipocf = mask.get(F_TIPOCF2)[0];
      filter << "&&(TIPOCF=='" << tipocf << "')";
      select_cursor(_cur_7);
    }  
    break;
    case st_distinta:   
    {                         
    	_tipoord = mask.get(F_TIPOORD)[0];
    	if (_tipoord != 'N')
    	{
      	cod_from = mask.get(F_DA_DATA3);
      	cod_to = mask.get(F_A_DATA3);    
      	from.put(EFF_DATASCAD,cod_from);
      	to.put(EFF_DATASCAD,cod_to); 
      }	
      cod_from = mask.get(F_DADIST);
      cod_to = mask.get(F_ADIST);        
      filter.cut(0);
      const TString16 tipodist(mask.get(F_DATIPODIST));
	        
      if (tipodist.not_empty())
      {
        if (cod_from.not_empty()) 
          filter << "STR(NDIST>=" << cod_from << ")&&";
        if (cod_to.not_empty())       // le distinte
          filter << "STR(NDIST<=" << cod_to << ")&&";
        filter << "(TIPODIST==\"" << tipodist << "\")";
      }
      else                                  
        filter << "(NDIST<=\"\")";
      tipocf = mask.get(F_TIPOCF3)[0];
      filter << "&&(TIPOCF=='" << tipocf << "')";
    	switch (_tipoord)
    	{
    	case 'D':
	      select_cursor(_cur_3);
	    break;
	    case 'N':
	    {                                                            
	    	cod_from = mask.get_date(F_DA_DATA3).string(ANSI);
	    	cod_to = mask.get_date(F_A_DATA3).string(ANSI);
	    	filter << "&&(ANSI(14->" << REFF_DATAFATT << ")>=\"" << cod_from << "\")";
	    	filter << "&&(ANSI(14->" << REFF_DATAFATT << ")<=\"" << cod_to << "\")";
 				select_cursor(_cur_5);  	
 			}	
 			break;	
 			case 'C':
	  		select_cursor(_cur_6);  	
	  	}	
    }    
    break;
    case st_cliente:
      {
        cod_from = mask.get(F_DA_DATA4);
        from.put(EFF_DATASCAD,cod_from);
        cod_to = mask.get(F_A_DATA4);  
        to.put(EFF_DATASCAD,cod_to); 
        filter = "";
        filter << "(" << EFF_TIPOCF << "== \"" << mask.get(F_TIPOCF4) << "\")";
        cod_from = mask.get(F_DACLI);
        if (cod_from.full()) 
					filter << "&&STR(" << EFF_CODCF << ">=" << cod_from << ")" ;
        cod_to = mask.get(F_ACLI);
        if (cod_to.full()) 
					filter << "&&STR(" << EFF_CODCF << "<=" << cod_to << ")" ;
				
				const TDate from_datafatt = mask.get_date(F_DA_DATA4F);
				const TDate to_datafatt = mask.get_date(F_A_DATA4F);
				if (from_datafatt.ok() ||to_datafatt.ok())
	        filter << "&&(BETWEEN(" << LF_REFFETTI << "->" << REFF_DATAFATT << ",\"" << from_datafatt.string() << "\",\"" << to_datafatt.string() << "\"))" ;
        select_cursor(_cur_4);                                                
      }
      break;
    default:
      break;
  }  
  current_cursor()->setfilter(filter,TRUE);
  current_cursor()->setregion(from, to);  
  // setta il formato di stampa di tutti i reali  
  set_real_picture(PICTURE_IMPORTO);
  _prima_volta=TRUE;
  return TRUE; 
}  

// crea l'applicazione
bool TPrint_effetti_app::user_create()
{
  _rel = new TRelation(LF_EFFETTI);   
  _rel->add(LF_REFFETTI, "NPROGTR==NPROGTR", true);
  // aggiunto solo per poter usare l'oggetto TEffetto (serve il file 
  // aperto anche se non viene usato direttamente) 
  _rel->add(LF_CESS, "NPROGTR==NPROGTR");
  _rel->add(LF_CLIFO, "TIPOCF==TIPOCF|CODCF==CODCF");
  //STAMPA PER SCADENZA
  _cur_1 = add_cursor(new TCursor(_rel,"",3));
  //STAMPA PER BANCA DI APPOGGIO
  TString ordine  = "CODABI|CODCAB|DATASCAD|NPROGTR";
  _cur_2 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));  
  //STAMPA PER DISTINTA ordinata per data scadenze
  ordine = "TIPODIST|NDIST|DATASCAD|NPROGTR|NRIGADIST";
  _cur_3 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));
  //STAMPA PER CLIENTE 
  ordine = "CODCF|NPROGTR";
  _cur_4 =  add_cursor(new TSorted_cursor(_rel,ordine,"",3));; 
  //STAMPA PER DISTINTA ordinata per numero fattura
  ordine = "TIPODIST|NDIST|NRIGADIST|14->NFATT|DATASCAD|NPROGTR";
  _cur_5 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));
  //STAMPA PER DISTINTA ordinata per cliente/fornitore
  ordine = "TIPODIST|NDIST|NRIGADIST|TIPOCF|CODCF|DATASCAD|NPROGTR";
  _cur_6 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));
  //STAMPA PER BANCA DI PRESENTAZIONE
  ordine  = "CODABIP|CODCABP|DATASCAD|NPROGTR";
  _cur_7 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));  

  add_file(LF_EFFETTI);
  enable_print_menu();
  return TRUE;
}

// distrugge l'applicazione
bool TPrint_effetti_app::user_destroy()
{
  if (_rel) 
    delete _rel;                                                          
  return TRUE;
}

int ef0600(int argc, char* argv[])
{
  TPrint_effetti_app app;
  app.run(argc, argv, TR("Stampe Controllo Effetti"));    
  return 0;
}