#include <config.h>
#include <mask.h>
#include <printapp.h>
#include <tabutil.h>
#include <utility.h>                      
#include <relation.h>
#include <real.h> 
#include <printer.h>
#include <clifo.h> 
#include "ef0101.h"       
#include "ef0600.h"
    
enum pt {undefined = 0, st_banca = 1, st_cliente = 2,  st_distinta = 3, st_scadenza = 4};

//////////////////////////////////////////////////////////////////////
// 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, _cli,  _val, _data_stampa, _ban_prec;      
  TDate      _scad_prec;
  TRectype*  _rec_prec;
  int        _cur_1, _cur_2, _cur_3, _cur_4, _interline;
  long       _dist_prec,  _cliente_prec;                     
  char       _tipo_prec;
  real       _tot_data, _tot_mese,  _tot_banca, _tot_distinta, _tot_tip_dist, _tot_cliente, _tot_stampa;
  bool       _prima_volta;
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();
  void header_scadenza();
  void header_banca();
  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 set_scadenza();
  void set_banca();
  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(long codcf);
  void st_tot_scad();  
  void st_tot_mese(); 
  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), _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(long codcf)
{
  TLocalisamfile clifo(LF_CLIFO);        
  clifo.put(CLI_TIPOCF,'C');
  clifo.put(CLI_CODCF, codcf);
  clifo.read();                
  TString s,cli;
  cli = (clifo.get(CLI_RAGSOC));        
  s = cli.mid(30,50);
  s.trim();
  cli = cli.mid(0,30);
  cli.trim();
  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)
{
  TTable tab(tabname);
  tab.curr().zero();
  tab.curr().put("CODTAB",cod);
  tab.read();
  if (tab.bad()) tab.curr().zero();
  return tab.curr().get(fld);
}

// stampa  il totale per data di scadenza
void TPrint_effetti_app::st_tot_scad() 
{            
  _pr.put("-------------------------------------------",50);
  printer().print(_pr);
  _pr.reset();      
  _pr.put("TOTALE",50);   
  _pr.put(_scad_prec.string(),57);  
  _pr.put(_tot_data.string("###.###.##@,@@"),72);
  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("TOTALE ",50);   
  _pr.put(itom(_scad_prec.month()),57);  
  _pr.put(_tot_mese.string("###.###.##@,@@"),72);
  printer().print(_pr);
  _tot_mese = 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)
{ 
  TString  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 presentazione
// (dopo la "rottura" per banca)
void TPrint_effetti_app::st_header_ban(const TString* ban)
{            
  TString s = (look_tab("%BAN",*ban));
  if (s.empty())
     s = "Nessuna Banca di Presentazione";
  _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 = "Distinte";
  switch(tipodist)
  {
    case 'B':
      s << " Salvo Buon Fine";
      break;
    case 'I':     
      s << " All'Incasso";
      break;
    case 'S': 
      s << " Allo Sconto";
      break;                  
    case 0:
      s = "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;     
  TLocalisamfile ditte(LF_NDITTE);
  ditte.zero();
  ditte.put("CODDITTA", firm);
  ditte.read();
  if (ditte.bad()) ditte.zero();
  TString s,
          ditta(ditte.get("RAGSOC"));
  s = ditta.mid(30,50);
  s.trim();
  ditta = ditta.mid(0,30);
  ditta.trim();
  ditta << " " << s;  
  set_header(j, "Ditta:  %ld %s@125gPag @#", firm, (const char*) ditta);
  set_header(j++, "@102gData %s", (const char*) _data_stampa);

  switch(_pr_type)
  {
    case st_scadenza:
      header_scadenza();
      break;
    case st_banca:
      header_banca();
      break;
    case st_distinta:
      header_distinta();
      break;
    case st_cliente:
      header_cliente();
      break;  
    default:
      break;
  }
}  

// setta l'header per la stampa per data di scadenza
void TPrint_effetti_app::header_scadenza()
{
  int j =2;
  set_header(j, "@52gSTAMPA RI.BA. PER SCADENZA");  j++;
  set_header(j++, (const char *)(TString(132).fill('-')));
  set_header(j++, "  Scadenza     Banca      Cliente                 N.Riba     N.Dist          Importo    Val   N.Rata   St.Def. Fattura del.   N.");
  set_header(j, (const char *)(TString(132).fill('-')));
}

// setta l'header per la stampa per banca di presentazione
void TPrint_effetti_app::header_banca()
{
  int  j = 2;     
  set_header(j, "@45gSTAMPA RI.BA. PER BANCHE DI PRESENTAZIONE");  j++;
  set_header(j++, (const char *)(TString(132).fill('-')));
  set_header(j++, "   Banca       Scadenza       Cliente                 N.Riba     N.Dist       Importo      Val.  N.Rata  St.Def.  Fattura del.   N.");
  set_header(j, (const char *)(TString(132).fill('-')));
}

// setta l'header per la stampa per distinta di presentazione
void TPrint_effetti_app::header_distinta()
{
  int  j = 2;     
  set_header(j, "@55gSTAMPA RI.BA. PER DISTINTE");  j++;
  set_header(j++, (const char *)(TString(132).fill('-')));
  set_header(j++, "   Distinta ");
  set_header(j++, "@1gTipo    Num.   N.Riba      Scadenza       Banca        Cliente               Importo      Val.  N.Rata  St.Def.  Fattura del.  N.");
  set_header(j, (const char *)(TString(132).fill('-')));
}

// setta l'header per la stampa per cliente 
void TPrint_effetti_app::header_cliente()
{
  int j = 2;
  set_header(j, "@52gSTAMPA RI.BA. PER CLIENTE");  j++;
  set_header(j++, (const char *)(TString(132).fill('-')));
  set_header(j++, "     Cliente            Scadenza     Banca        N.Riba     N.Dist          Importo    Val   N.Rata   St.Def. Fattura del.   N.");
  set_header(j, (const char *)(TString(132).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 (_tot_data != 0.0) 
     st_tot_scad();
  if(_tot_mese != 0.0)
     st_tot_mese();
  if (_tot_banca != 0.0)
  {                            
     _pr.put("TOTALE",50);
     _pr.put(_tot_banca.string("###.###.##@,@@"),72);  
     printer().print(_pr);
     _pr.reset();   
     s = (look_tab("%BAN",_ban_prec));
     if (s.empty())
        s = "Nessuna Banca di Presentazione";
     _pr.put(s,52);   
     printer().print(_pr);
     _tot_banca = 0.0; 
     _pr.reset();                         
  }                                
  if (_tot_distinta != 0.0 &&_dist_prec != 0)
  {
     _pr.put("-------------------------------------------",50);
     printer().print(_pr);
     _pr.reset();
     _pr.put("TOTALE",50);   
     s = "Distinta "; 
     s << _dist_prec << " " << _tipo_prec ;
     _pr.put(s,57);   
     _pr.put(_tot_distinta.string("###.###.##@,@@"),72);
     printer().print(_pr);
     _tot_distinta = 0.0;  
     _pr.reset();                         
  }
  if (_tot_tip_dist != 0.0)
  {  
     if (_dist_prec == 0)
     {
       _pr.put("-------------------------------------------",50);
       printer().print(_pr);
       _pr.reset();
     }
     _pr.put("TOTALE",50); 
     _pr.put(_tot_tip_dist.string("###.###.##@,@@"),72);
     printer().print(_pr);  
     _pr.reset();
     s = "Distinte";
     switch(_tipo_prec)
     {
       case 'B':
         s << " Salvo Buon Fine";
         break;
       case 'I':     
         s << " All'Incasso";
         break;
       case 'S': 
         s << " Allo Sconto";
         break;                  
       case 0:
         s = "Nessuna Distinta";
         break; 
     }
     _pr.put(s,52); 
     printer().print(_pr);        
     _tot_tip_dist = 0.0;  
     _pr.reset();     
  } 
  if (_tot_cliente != 0.0)
  {
     _pr.put("TOTALE",50);
     _pr.put(_tot_cliente.string("###.###.##@,@@"),72);  
     printer().print(_pr);
     _pr.reset();   
     _pr.put((look_clifo(_cliente_prec)),52);      
     printer().print(_pr);
     _tot_cliente = 0.0; 
     _pr.reset();                       
  }
  if (_tot_stampa != 0.0) 
  {
     _pr.reset();   
     _pr.put("-------------------------------------------",50);
     printer().print(_pr);
     _pr.reset();
     _pr.put("TOTALE ",50);   
     _pr.put(_tot_stampa.string("###.###.##@,@@"),72);
     printer().print(_pr);                                         
     _pr.reset();
     _pr.put("RI.BA. STAMPATE",52);
     printer().print(_pr);
     _pr.reset();      
     _pr.put("-------------------------------------------",50);
     printer().print(_pr);
     _pr.reset();     
     _tot_stampa = 0.0;  
  }    
  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:
      set_banca();
      break;
    case st_distinta:
      set_distinta();
      break;
    case st_cliente:
      set_cliente();
      break; 
    default:
      break;
  }
}

// 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#t@50g@pn@59g@pn@72g@pn@88g#t@95g@pn@103g@s@111g@s@125g@n",
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_ban,
                  &_cli,
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_IMPORTO, "###.###.##@,@@"),
                  &_val,
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_EFFETTI, EFF_EFFSTAMP),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT));
                  
   for(int i = 0; i < _interline; i++)    set_row(i+1," ");
}


// setta la pagina logica nel caso di stampa per banca di presentazione
void TPrint_effetti_app::set_banca()
{
   set_row(1," ");
   set_row(2,"@1g#t@14g@s@26g#t@54g@pn@63g@pn@72g@pn@91g#t@98g@pn@106g@s@114g@s@128g@n",
                  &_ban,
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_cli,
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_IMPORTO, "###.###.##@,@@"),
                  &_val,
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_EFFETTI, EFF_EFFSTAMP),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT));
                  
   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,"@3g@s@5g@pn@16g@pn@27g@s@41g#t@55g#t@72g@pn@91g#t@98g@pn@106g@s@114g@s@128g@n",
                  FLD(LF_EFFETTI, EFF_TIPODIST),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_ban,
                  &_cli,
                  FLD(LF_EFFETTI, EFF_IMPORTO, "###.###.##@,@@"),
                  &_val,
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_EFFETTI, EFF_EFFSTAMP),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT));
                  
   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@50g@pn@59g@pn@72g@pn@88g#t@95g@pn@103g@s@111g@s@125g@n",
                  FLD(LF_EFFETTI, EFF_CODCF,"@@@@@@"),
                  FLD(LF_EFFETTI, EFF_DATASCAD),
                  &_ban,
                  FLD(LF_EFFETTI, EFF_NPROGTR, "#####@"),
                  FLD(LF_EFFETTI, EFF_NDIST, "#######@"),
                  FLD(LF_EFFETTI, EFF_IMPORTO, "###.###.##@,@@"),
                  &_val,
                  FLD(LF_REFFETTI, REFF_NRATA,"##@"),
                  FLD(LF_EFFETTI, EFF_EFFSTAMP),
                  FLD(LF_REFFETTI, REFF_DATAFATT),
                  FLD(LF_REFFETTI, REFF_NFATT));
                  
   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(); 
    TDate  scad = rec.get_date (EFF_DATASCAD);
    TString  ban = rec.get (EFF_CODABIP);
    long  dist = rec.get_long (EFF_NDIST);
    char tipodist = rec.get_char(EFF_TIPODIST);
    long cliente =   rec.get_long (EFF_CODCF);
    real importo =  rec.get_real(EFF_IMPORTO);
    // elaboro le seguenti  stringhe per la stampa
    if (ban=="00000") 
       ban = "";                                  
    _ban = get_field(LF_EFFETTI, EFF_CODABIP);
    if (_ban=="00000") 
       _ban = "";             
    s =   get_field(LF_EFFETTI, EFF_CODCABP);
    if (s=="00000") 
       s = "";                  
    _ban << " " << s;                                
       
    _cli =  get_field(LF_CLIFO, CLI_RAGSOC);
    s = _cli.mid(30,50); s.trim();
    _cli = _cli.mid(0,30); _cli.trim();
    _cli << " " << s;       
             
    s = get_field(LF_EFFETTI, EFF_CODVAL);  
    (s.empty())?_val = s:_val = "Lit.";

    // 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; 
      _rec_prec = &rec;   
      switch(_pr_type)
      {
        case st_scadenza:
            _scad_prec = scad;      
            st_header_scad(&scad); 
            break;   
        case st_banca:              
            _scad_prec = scad; 
            _ban_prec = ban;              
            st_header_ban(&ban);    
            break;  
        case st_distinta:
            _scad_prec = scad; 
            _dist_prec = dist; 
            _tipo_prec = tipodist;
            st_header_dist(tipodist); 
            break;  
        case st_cliente:
            _scad_prec = scad; 
            _cliente_prec = cliente; 
            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_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);
     int elem = dati->items();
     if (elem > 3)
     {
       TString descfatt;
       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);
          if  (_pr_type == st_banca || _pr_type == st_distinta )
             _pr.put(descfatt, 114);  
          printer().print(_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:  
         // è 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    
            _pr.put("TOTALE",50);
            _pr.put(_tot_banca.string("###.###.##@,@@"),72);  
            printer().print(_pr);
            _pr.reset();   
            s = (look_tab("%BAN",_ban_prec));
            if (s.empty())
               s = "Nessuna Banca di Presentazione";
            _pr.put(s,52);   
            printer().print(_pr);
            _tot_banca = 0.0;  
            _pr.reset();      
            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 
         if (dist !=_dist_prec)
         {                                
            //il totale per nessuna distinta si fa solo per tipo
            if (_dist_prec != 0)
            {
               _pr.put("-------------------------------------------",50);
               printer().print(_pr);
               _pr.reset();
               _pr.put("TOTALE",50); 
               s = "Distinta ";
               s  << _tipo_prec << " "<< _dist_prec;
               _pr.put(s,57);   
               _pr.put(_tot_distinta.string("###.###.##@,@@"),72);
               printer().print(_pr);
               _tot_distinta = 0.0;  
               _pr.reset();                         
            }
            // è cambiato il tipo distinta, stampo il relativo totale
            if(tipodist != _tipo_prec)
            {
               if (_dist_prec == 0)
               {
                  _pr.put("-------------------------------------------",50);
                  printer().print(_pr);
                  _pr.reset();
               }
               _pr.put("TOTALE",50); 
               _pr.put(_tot_tip_dist.string("###.###.##@,@@"),72);
               printer().print(_pr);  
               _pr.reset();
               s = "Distinte";
               switch(_tipo_prec)
               {
                  case 'B':
                    s << " Salvo Buon Fine";
                    break;
                  case 'I':     
                    s << " All'Incasso";
                    break;
                  case 'S': 
                    s << " Allo Sconto";
                    break;                  
                  case 0:
                    s = "Nessuna Distinta";
                    break; 
               }
               _pr.put(s,52); 
               printer().print(_pr);        
               _tot_tip_dist = 0.0;  
               _pr.reset();     
               printer().print(_pr);
               st_header_dist(tipodist);      
            } 
         } 
         _dist_prec = dist;     
         _tipo_prec = tipodist;
         _tot_distinta += importo;      
         _tot_tip_dist += 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 (cliente !=_cliente_prec) 
         {  
            if (scad == _scad_prec)
                st_tot_scad();
            if (scad.month() ==_scad_prec.month())
                st_tot_mese();
            // stampo totale  cliente      
            _pr.put("TOTALE",50);
            _pr.put(_tot_cliente.string("###.###.##@,@@"),72);  
            printer().print(_pr);
            _pr.reset();   
            _pr.put((look_clifo(_cliente_prec)),52);   
            printer().print(_pr);
            _tot_cliente = 0.0;  
            _pr.reset();     
            printer().print(_pr);
            st_header_cliente(&_cli);
         } 
         _cliente_prec = cliente;     
         _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)
{                                                
  disable_links();
  set_multiple_link(FALSE);
  // richiamo la maschera di scelta del tipo di stampa   
  TMask mask("ef0600a.msk");
  mask.run();
  force_setpage(FALSE);
  if (mask.last_key() == K_QUIT)
     return FALSE;
  _pr_type     = (pt) mask.get_int(RDB_TIPOST);       
  TDate data_stampa (mask.get(F_DATA_STAMPA));
  _data_stampa = data_stampa.string();
  // inizializzo i record di scelta del cursore
  TRectype from(current_cursor()->curr());
  from.zero();
  TRectype to(from);  
  TString cod_from, cod_to, filter;  
  // 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); 
      select_cursor(_cur_1);    
      break;
    case st_banca:
      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 di presentazione
      	cod_to = "99999";     
      filter = "";
      filter << "(CODABIP>=" << cod_from << ")&&(CODABIP<=" << cod_to << ")";
      select_cursor(_cur_2);
      break;
    case st_distinta:
     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);        
     if (cod_from.empty()) 
     	cod_from = "00000000"; // per selezionare tutte
     if (cod_to.empty())       // le distinte
        cod_to = "99999999";     
     filter = "";
     filter << "(NDIST>=" << cod_from << ") && (NDIST<=" << cod_to << ")" ;
     cod_from = mask.get(F_DATIPODIST);
     cod_to = mask.get(F_ATIPODIST);     
     if ((!cod_from.empty())&&(!cod_to.empty())&&(cod_from==cod_to))     // per selezionare un tipo 
        filter << "&&(TIPODIST==\"" << cod_from << "\")";                          //   di distinta
     select_cursor(_cur_3);    
     break;
    case st_cliente:
      cod_from = mask.get(F_DA_DATA4);
      cod_to = mask.get(F_A_DATA4);  
      from.put(EFF_CODCF,cod_from);
      to.put(EFF_CODCF,cod_to); 
      cod_from = mask.get(F_DACLI);
      cod_to = mask.get(F_ACLI);
      if (cod_from.empty()) 
      	cod_from = "000000"; // per selezionare tutti 
      if (cod_to.empty())    //  i clienti
        cod_to = "999999";     
      filter = "";
      filter << "(CODCF>=" << cod_from << ")&&(CODCF<=" << cod_to << ")" ;
      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("###.###.##@,@@");
  _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");
  // 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=='C'|CODCF==CODCF");
  //STAMPA PER SCADENZA
  _cur_1 = add_cursor(new TCursor(_rel,"",3));
  //STAMPA PER BANCA
  TString ordine  = "CODABIP|DATASCAD|NPROGTR";
  _cur_2 = add_cursor(new TSorted_cursor(_rel,ordine,"",3));  
  //STAMPA PER DISTINTA 
  ordine  = "TIPODIST|NDIST|NRIGADIST|DATASCAD|NPROGTR";
  _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));; 
  add_file(LF_EFFETTI);
  enable_print_menu();
  return TRUE;
}

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

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