TRUE -> true git-svn-id: svn://10.65.10.50/branches/R_10_00@22782 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1682 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1682 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <printapp.h>
 | ||
| 
 | ||
| #include "../cg/cgsaldac.h"
 | ||
| #include "sc2.h"
 | ||
| #include "sc2200.h" 
 | ||
| #include "sc2201.h" 
 | ||
| 
 | ||
| #include <nditte.h>
 | ||
| #include <clifo.h> 
 | ||
| #include <pconti.h>
 | ||
| #include <causali.h>
 | ||
| 
 | ||
| #define SCADCLIFO_ALIAS 51
 | ||
| #define CLIFOSCAD_ALIAS 52
 | ||
| #define SCADPCON_ALIAS  53
 | ||
| #define PCONSCAD_ALIAS  54
 | ||
| #define MaxRowsForTotal 17
 | ||
| 
 | ||
| #define TPString TParagraph_string   // Comodita'...
 | ||
| 
 | ||
| struct _LinearTotal : public TObject  // Oggetto base per gli elementi di tlg, tlm, tlp
 | ||
| {                                     // Contiene i totali da stampare su una linea
 | ||
|   real _is, // Importo in scadenza
 | ||
|        _ip, // Importo pagato
 | ||
|        _rd, // Rimesse dirette
 | ||
|        _ri, // Ri.ba/Tratte
 | ||
|        _bo, // Bonifici
 | ||
|        _al; // Altri 
 | ||
|   virtual TObject* dup() const { return new _LinearTotal(*this); }
 | ||
|   _LinearTotal() {_is = 0.0; _ip = 0.0; _rd = 0.0; _ri = 0.0; _bo = 0.0; _al = 0.0; }
 | ||
| };
 | ||
| 
 | ||
| enum tipo_st {nessuno=0, tutti=1, clienti=2, fornitori=3, altri=4};
 | ||
| enum tipo_pe {daily, monthly, period, single, bank};
 | ||
| 
 | ||
| class TStampaScadenzario : public TPrintapp
 | ||
| { 
 | ||
|   TRelation     *_rel1, *_rel2, *_rel3;                      // Relazioni di lavoro...
 | ||
|   int           _cur1, _cur11,                               // Identificatori dei cursori di lavoro... 
 | ||
|                 _cur2, _cur3, _cur4, _cur41,                 // piu' avanti spiega tutto.
 | ||
|                 _cur5, _cur6, _cur7;                          
 | ||
|   TSelection_ext_mask *_m;              
 | ||
|   TPartita      *_p;                                         // Oggetto partita corrente. Viene ricaricato ad ogni cambio partita,
 | ||
|                                                              // ovvero ogni volta che la rata corrente cambia i "connotati"
 | ||
|   TLocalisamfile *_pagsca;               
 | ||
|   TString        _annopart,_datareg,_numdoc,_datadoc,        // Anno partita (2 cifre), data registrazione, nr. documento, data doc.
 | ||
|                  _protiva, _codval;                          // Numero di protocollo IVA (TString perche' se vale 0 non stampa nulla), e codice valuta
 | ||
|   TString        _last_ban, _desc_ban;                       // Banca correntemente in corso di raggruppamento                
 | ||
|   TPString      *_descrizione,*_ragsoc,*_des_conto;          // Descrizione (da LF_PARTITE), ragione sociale (da LF_CLIFO)
 | ||
|                                                              // Descrizione conto (da LF_PCON)
 | ||
|   TString _imp_scad,_imp_pag,_rimdir,_riba,_altri,_bonifico, // Valori calcolati in preprocess_page: rimesse dirette, Ri.ba e altri
 | ||
|           _cur_gr_s, _cur_co_s, _cur_codcf_s;                // _imp_scad e _imp_pag vengono anch'essi calcolati in preprocess_page.
 | ||
|   TDate     _datai, _dataf, _datas,                          // Data inizio, fine e stampa
 | ||
|             _cur_data;                                       // Data di scadenza riferita al record corrente
 | ||
|   long      _cur_codcf;                                      // Cli/Fo riferito al record corrente
 | ||
|   int       _cur_gr,_cur_co;                                 // Gruppo/Conto riferito al record corrente.
 | ||
|   tipo_st   _tipost;                                         // Tipo di stampa impostato
 | ||
| 	bool			_notot;																					 // VERO=non stampa i totali intermedi per cliente/fornitore/conto
 | ||
|   bool      _modified,                                       // VERO=E' stato stampato il totale giornaliero (mensile)
 | ||
|             _end_printed,                                    // VERO=riepilogo finale da stampare
 | ||
|             _ratesald,                                       // VERO=stampa anche le rate saldate
 | ||
|             _ordata,                                         // VERO=ordine primario per data, FALSO=ordine primario impostato da _ordcod
 | ||
|             _ordcod,                                         // VERO=ordine per codice, FALSO=ordine per ragione sociale
 | ||
|             _stvaluta,                                       // Vero se abilitata la stampa in valuta;
 | ||
|             _group_ban,                                      // Vero se abilitato il raggruppamento per banca                     
 | ||
|             _totbank_printed;																 // Vero se <20> stato stampato il totale per banca
 | ||
|                                                              // Se _tipost=tutti non e' possibile impostare l'ordine primario per 
 | ||
|                                                              // ragione sociale o descrizione. L'unico tipo stampa possibile e' quello 
 | ||
|                                                              // in ordine di data scadenza
 | ||
|                                                              // Se _tipost=altri scorre il piano dei conti. 
 | ||
|                                                              // Se _tipost=clienti || fornitori scorre clifo.
 | ||
|   int       _striepilogo;                                    // 0 = non stampa 1 = stampa il riepilogo giornaliero per pagamento 2 = stampa il riepilogo mensile per pagamento
 | ||
| 	TString16	_codag; 																				 // codice agente selezionato                                                            
 | ||
| 	int _tipopag;																							 // tipo pagamento selezionato
 | ||
| 	TRecnotype _last_bank_rec;																 // ultimo record con banca stampato
 | ||
|   real      _w_imp_pag, _w_imp_res;                          // Qui dentro memorizza i valori calcolati in calcola_pagamenti,
 | ||
|                                                              // rispettivamente l'importo pagato e l'importo residuo, relativo alla rata.
 | ||
|   TAssoc_array _tm, _tp;                                     // Dentro a codesti array vi sono i totali per la stampa prospetti:
 | ||
|                                                              // durante l'elaborazione cerca la chiave relativa, aggiungendo o
 | ||
|                                                              // aggiornando l'elemento se necessario; una volta pronto per stampare 
 | ||
|                                                              // il prospetto viene "ordinato" tramite la TAssoc_array::get_keys() 
 | ||
|                                                              // e il sort di TArray_string. _tm e' il totale del mese o del cli/fo/conto 
 | ||
|                                                              // (nel caso di ordinamento diversa da data), _tp e' il totale del periodo.
 | ||
|                                                              // La chiave e' cosi' composta: Tipo pag.+ult. class.+cod valuta
 | ||
|                                                              //
 | ||
|                                                              // Qui memorizza i totali "lineari". Analogamente ai 2 precedenti
 | ||
|                                                              // TAssoc_array, durante l'elaborazione cerca la chiave relativa, aggiungendo o
 | ||
|                                                              // aggiornando l'elemento se necessario; esegue un sort prima di stamparlo.
 | ||
|                                                              // Se l'ordinamento principale non e' per data utilizza tlm per i totali 
 | ||
|                                                              // del cli/fo/conto e tlp per i totali del periodo. La chiave e' per:
 | ||
|                                                              // codice valuta
 | ||
|   TArray      _tl;                                           // Contiene tlg, tlm, tlp (vedi user_create()), cosi' vi accedo tramite un indice.
 | ||
|   TArray      _uns_cache;                                    // cache dei non assegnati: l'elemento [0] contiene un TAssoc_array dei non assegnati normali,
 | ||
|                                                              // l'elemento [1] contiene un TAssoc_array dei non assegnati relativi a nonte dei credito. La
 | ||
|                                                              // chiave per tali TAssoc_array e': TIPO+GRUPPO+CONTO+SOTTOCONTO+ANNO+NUMPART.
 | ||
|                                                              // prima di ricalcolare i non assegnati e' necessario guardare in questa cache, se esiste la
 | ||
|                                                              // chiave relativa alla partita, ed eventualmente utilizzare tale valore in memoria.
 | ||
|   static bool filter_func(const TRelation *);                // Funzione di filtro [_datai.._dataf]
 | ||
|   
 | ||
| public:             
 | ||
|   // print functions
 | ||
|   virtual bool preprocess_page(int file, int counter);           // Qui stampa i totali e i riepiloghi
 | ||
|   virtual bool preprocess_print(int file, int counter);          // Qui non fa proprio nulla!
 | ||
|   virtual print_action postprocess_print(int file, int counter); // Qui setta i flags per stampare il riepilogo finale!
 | ||
|   virtual print_action postprocess_page(int file, int counter);  // Qui fa molte cose...
 | ||
|   virtual void preprocess_header() {};                           // Very Very Dummy...
 | ||
|   virtual bool user_create();                                    // Qui creo i cursori...
 | ||
|   virtual bool user_destroy();                                   // e qui li distruggo.
 | ||
|   virtual bool set_print(int);                                   // Qui c'e' la maschera di selezione.
 | ||
| 	void add_filter_fatt(TCursor * cur, const char * filter);		   // aggiungo il gfiltro per data fattura
 | ||
|   virtual void set_page (int file, int counter);                 // Setta le righe di stampa.
 | ||
|   void    set_page_clifo(int nriga);                             // Frammenti di set_page
 | ||
|   void    set_page_pcon (int nriga);
 | ||
|   void    print_header();                                        // Stampa l'header.
 | ||
|   // Le seguenti funzioni valgono con ordinamento principale per data.
 | ||
|   void    print_rows_riepilogo(int& nriga, bool type, TAssoc_array& tot);          // Stampa effettivamente lo specchietto 
 | ||
|   void    print_riepilogo(int &nriga, bool type);                          // type == false prints month totals, type == true prints period totals.
 | ||
|   void    print_rows_totali(int &nriga, tipo_pe p);                  
 | ||
|   void    print_totali(int &nriga, bool month_changed, bool ended);        // month_changed indica se il mese e' cambiato. 
 | ||
|                                                                            //ended indica il raggiungimento di fine periodo.   
 | ||
|   // La seguente funzione serve per il riepilogo dei totali nel caso l'ordinamento principale non sia per data.
 | ||
|   void    print_totali_c(int &nriga, bool ended);                          // ended indica di stampare anche il riepilogo del periodo
 | ||
|   
 | ||
|   void    print_totali_bank(int &nriga);
 | ||
| 
 | ||
|   // Funzioni per calcolo dei pagamenti e di aggiornamento totali
 | ||
|   void    check_add_key_to_tp(int t, char u);                              // controlla e aggiunge i valori relativi alla chiave k ai totali del prospetto
 | ||
|   void    check_add_key_to_tl(tipo_pe p, int t);                           // controlla e aggiunge i valori elaborati all'assoc array indicato dal periodo (_tlxxx)
 | ||
|   // Ritorna true se la partita corrente _p non e' piu' riferita alla scadenza corrente
 | ||
|   bool    scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump); 
 | ||
|   // Ritorna true se la scadenza corrente ha una banca diversa dalla precedente
 | ||
|   // bool    bank_will_change();
 | ||
|   // Totalizza i pagamenti non assegnati per la partita corrente (NB si spera che siano tutti nella stessa valuta)
 | ||
|   bool    in_cache(const TString& k);                  // ritorna vero se ci sono gia' non assegnati in _uns_cache;
 | ||
|   void    look_in_cache(real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k);
 | ||
|   void    calcola_unassigned(const TString& k);  
 | ||
|   void    calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill);   // calcola i pagamenti effettuati per questa rata e il residuo eventuale
 | ||
| 	const char * tipi_tab(int tipo);
 | ||
|   
 | ||
|   TLocalisamfile& pagamenti() const { return *_pagsca; }
 | ||
| 
 | ||
|   void    print_intestazione_banca(int &nriga);                  
 | ||
|   
 | ||
|   TStampaScadenzario();
 | ||
| };
 | ||
| 
 | ||
| inline TStampaScadenzario& app() {return (TStampaScadenzario&)main_app();}
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TScadenza_rec : public TRectype
 | ||
| {    
 | ||
|   TString _codice;
 | ||
| 
 | ||
| protected:
 | ||
|   virtual const TString& get_str(const char* fieldname) const;
 | ||
|   
 | ||
| public:
 | ||
|   TScadenza_rec() : TRectype(LF_SCADENZE) { }
 | ||
| };
 | ||
| 
 | ||
| const TString& TScadenza_rec::get_str(const char* fieldname) const
 | ||
| {   
 | ||
|   if (strcmp(fieldname, SCAD_CODABIPR) == 0 || strcmp(fieldname, SCAD_CODCABPR) == 0 || 
 | ||
|       strcmp(fieldname, SCAD_CODAG) == 0)
 | ||
|   {               
 | ||
|     TRectype rec(LF_PAGSCA);
 | ||
|     rec.put(PAGSCA_TIPOC,      TRectype::get_str(SCAD_TIPOCF));
 | ||
|     rec.put(PAGSCA_GRUPPO,     TRectype::get_str(SCAD_GRUPPO));
 | ||
|     rec.put(PAGSCA_CONTO,      TRectype::get_str(SCAD_CONTO));
 | ||
|     rec.put(PAGSCA_SOTTOCONTO, TRectype::get_str(SCAD_SOTTOCONTO));
 | ||
|     rec.put(PAGSCA_ANNO,       TRectype::get_str(SCAD_ANNO));
 | ||
|     rec.put(PAGSCA_NUMPART,    TRectype::get_str(SCAD_NUMPART));
 | ||
|     rec.put(PAGSCA_NRIGA,      TRectype::get_str(SCAD_NRIGA));
 | ||
|     rec.put(PAGSCA_NRATA,      TRectype::get_str(SCAD_NRATA));
 | ||
|     
 | ||
|     TLocalisamfile& pagamenti = app().pagamenti();
 | ||
|     TRectype& curpag = pagamenti.curr();
 | ||
|     bool found = curpag.compare_key(rec,1,1) == 0;
 | ||
|     if (!found)
 | ||
|     {
 | ||
|       curpag = rec;
 | ||
|       const int err = pagamenti.read(_isgteq);
 | ||
|       found = (err == NOERR) && (curpag.compare_key(rec,1,1) == 0);
 | ||
|     }   
 | ||
|     
 | ||
|     TString& cod = ((TScadenza_rec*)this)->_codice; // Fool the compiler
 | ||
|     cod = TRectype::get_str(fieldname); // Valore di default sulla scadenza
 | ||
|     if (found)
 | ||
|     {
 | ||
|       const TString& val = curpag.get(fieldname);
 | ||
|       if (val.not_empty())
 | ||
|         cod = val;                                 // Valore presente sul pagamento effettivo 
 | ||
|     }                    
 | ||
|     if (strcmp(fieldname, SCAD_CODABIPR) == 0 || strcmp(fieldname, SCAD_CODCABPR) == 0)
 | ||
|     	cod.format("%05ld", atol(_codice));   // riformatta codice banca
 | ||
|     return _codice;
 | ||
|   }
 | ||
|   return TRectype::get_str(fieldname);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
|                   
 | ||
| 
 | ||
| HIDDEN void print_real(TString& dest, const real& num, const char* val)
 | ||
| {
 | ||
|   const TCurrency cur(num, val);
 | ||
|   dest = cur.string(true);
 | ||
|   dest.right_just(15);
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::filter_func(const TRelation *r) 
 | ||
| {
 | ||
|   if (app()._group_ban)
 | ||
|   {  
 | ||
|     const TMask& m = *(app()._m);
 | ||
|     const long fromabi = m.get_long(F_FROMABI);
 | ||
|     const long toabi = m.get_long(F_TOABI);
 | ||
|     if (fromabi > 0 || toabi > 0)
 | ||
|     {
 | ||
|       const TRectype& rec = r->curr();                
 | ||
|       const long abi = rec.get_long(SCAD_CODABIPR);
 | ||
|       const long cab = rec.get_long(SCAD_CODCABPR);
 | ||
|       if (fromabi > 0)
 | ||
|       {
 | ||
|         if (abi < fromabi)
 | ||
|           return false;
 | ||
|         const long fromcab = m.get_long(F_FROMCAB);
 | ||
|         if (fromcab > 0 && abi == fromabi)
 | ||
|         {
 | ||
|           if (cab < fromcab)
 | ||
|             return false;  
 | ||
|         }
 | ||
|       }
 | ||
|       if (toabi > 0)
 | ||
|       {
 | ||
|         if (abi > toabi)
 | ||
|           return false;
 | ||
|         const long tocab = m.get_long(F_TOCAB);
 | ||
|         if (tocab > 0 && abi == toabi)
 | ||
|         {
 | ||
|           if (cab > tocab)
 | ||
|             return false;  
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   if (app()._codag.not_empty())
 | ||
|   {
 | ||
|   	const TRectype& rec = r->curr();                
 | ||
|     const TString16 codag = rec.get(SCAD_CODAG);
 | ||
| 		if (app()._codag != codag)  	
 | ||
| 			return false;
 | ||
|   }
 | ||
|   if (app()._tipopag != 0)
 | ||
|   {
 | ||
|   	const TRectype& rec = r->curr();                
 | ||
|     const int tipopag = rec.get_int(SCAD_TIPOPAG);
 | ||
| 		if (app()._tipopag != tipopag)  	
 | ||
| 			return false;
 | ||
|   }
 | ||
|   return true;  
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::check_add_key_to_tl(tipo_pe p, int t)
 | ||
| // Aggiorna i totali per i totali sulla linea
 | ||
| {                                            
 | ||
|   TString kl(_codval);
 | ||
|   _LinearTotal newtot;
 | ||
|   int index = 0;  // Default DAILY
 | ||
|   switch (p) // Seleziona l'assoc array da usare
 | ||
|   { 
 | ||
|     case monthly:
 | ||
|     case single:    
 | ||
|       index = 1;
 | ||
|       break;
 | ||
|     case period:
 | ||
|       index = 2;    
 | ||
|       break;
 | ||
|     case bank:
 | ||
|       index = 3;    
 | ||
|       break;
 | ||
|     default:   // Se p == daily e' gia settato di default (vedi sopra)
 | ||
|       break;        
 | ||
|   }
 | ||
|   TAssoc_array& xassoc = (TAssoc_array&) _tl[index];
 | ||
|   const bool is_key = xassoc.is_key(kl); // Esiste l'elemento ?
 | ||
|   // Se si' allora prendi quello, altrimenti prendine uno nuovo (newtot)
 | ||
|   _LinearTotal& xtotal = (is_key ? (_LinearTotal&) xassoc[kl] : newtot);
 | ||
|   //Aggiorna xtotal (importi in scadenza, pagati, riba, rimesse e altri)
 | ||
|   xtotal._is += (_w_imp_pag + _w_imp_res);
 | ||
|   xtotal._ip += _w_imp_pag;
 | ||
|   switch (t)  
 | ||
|   {
 | ||
|     case 1:  
 | ||
|       xtotal._rd += _w_imp_res;
 | ||
|     break;
 | ||
|     case 2:  
 | ||
|     case 3:
 | ||
|       xtotal._ri += _w_imp_res;
 | ||
|     break;
 | ||
|     case 9:
 | ||
|       xtotal._bo += _w_imp_res;
 | ||
|       break;
 | ||
|     default:            
 | ||
|       xtotal._al += _w_imp_res;
 | ||
|     break;
 | ||
|   }
 | ||
|   xassoc.add(kl,xtotal,is_key); 
 | ||
|   
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::check_add_key_to_tp(int t, char u)
 | ||
| // Aggiorna i totali per i prospetti finali
 | ||
| {                                     
 | ||
|   TString k;                // compone la chiave, valida per _tm e _tp
 | ||
|   k << t;
 | ||
|   if (u == '\0') u = ' ';   // Per indicare che non c'e' ult class
 | ||
|   k << u << _codval ; 
 | ||
| 
 | ||
|   if (_tm.is_key(k))                   // Se esiste gia' in _tm allora 
 | ||
|   {                                    // gli aggiunge il valore attuale
 | ||
|     real& r=(real&)_tm[k];
 | ||
|     r += _w_imp_res;
 | ||
|     _tm.add(k,r,true);
 | ||
|   }
 | ||
|   else
 | ||
|     _tm.add(k,_w_imp_res);
 | ||
|   if (_tp.is_key(k))                   // Se esiste gia' in _tp allora 
 | ||
|   {                                    // gli aggiunge il valore attuale
 | ||
|     real& r=(real&)_tp[k];
 | ||
|     r += _w_imp_res;
 | ||
|     _tp.add(k,r,true);
 | ||
|   }
 | ||
|   else
 | ||
|     _tp.add(k,_w_imp_res);
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump)
 | ||
| {                                    
 | ||
|   if (_p == NULL) 
 | ||
|     return true;
 | ||
|   TRiga_partite& rp = _p->riga(_p->first());
 | ||
|   if (tipo != rp.get_char(PART_TIPOCF) || gruppo != rp.get_int(PART_GRUPPO) ||
 | ||
|       conto != rp.get_int(PART_CONTO) || codcf != rp.get_long(PART_SOTTOCONTO) ||
 | ||
|       anno != rp.get_int(PART_ANNO) || nump != rp.get(PART_NUMPART))
 | ||
|     return true;
 | ||
|   return false;
 | ||
| }   
 | ||
| 
 | ||
| /*
 | ||
| bool TStampaScadenzario::bank_will_change()
 | ||
| {
 | ||
|   bool yes = false;
 | ||
|   if (_group_ban)
 | ||
|   {   
 | ||
|     TCursor& cur = *current_cursor();
 | ||
|     if (cur.pos() > 0 && cur.pos() < cur.items()-1)
 | ||
|     {                   
 | ||
|       const TRectype& rc = cur.curr();
 | ||
|       const TString8 oldabi = rc.get(SCAD_CODABIPR);
 | ||
|       const TString8 oldcab = rc.get(SCAD_CODCABPR);
 | ||
|       ++cur;
 | ||
|       const TString8 newabi = rc.get(SCAD_CODABIPR);
 | ||
|       const TString8 newcab = rc.get(SCAD_CODCABPR);
 | ||
|       yes = oldabi != newabi || oldcab != newcab;
 | ||
|       --cur;
 | ||
|     }
 | ||
|     else
 | ||
|       yes = true;
 | ||
|   }
 | ||
|   return yes;
 | ||
| }
 | ||
| */
 | ||
| 
 | ||
| bool TStampaScadenzario::in_cache(const TString& k)
 | ||
| {   
 | ||
|   TAssoc_array& uns   = (TAssoc_array&) _uns_cache[0];
 | ||
|   TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1];
 | ||
|   TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2];
 | ||
|   bool rt = uns.is_key(k) || unsnc.is_key(k) || unsins.is_key(k);
 | ||
|   return rt;
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::calcola_unassigned(const TString& k)
 | ||
| // Calcola i pagamenti non assegnati normali, e quelli riferiti a note di credito
 | ||
| // ovvero quelli con tipo di movimento 2. Vanno percio' tenuti separati due totali:
 | ||
| // _uns_cache[0] per i non assegnati normali, utilizzato per i pagamenti;
 | ||
| // _uns_cache[1] per i non assegnati, riferiti a note di credito, da scalare all'importo in scadenza
 | ||
| {
 | ||
|   TAssoc_array& uns    = (TAssoc_array&) _uns_cache[0];
 | ||
|   TAssoc_array& unsnc  = (TAssoc_array&) _uns_cache[1];
 | ||
|   TAssoc_array& unsins  = (TAssoc_array&) _uns_cache[2];
 | ||
|   
 | ||
|   real a,b,c;
 | ||
|   
 | ||
|   TRecord_array& ra = _p->unassigned();
 | ||
|   for (int r = ra.last_row(); r > 0; r = ra.pred_row(r))
 | ||
|   {     
 | ||
|     const TRectype& rec = ra.row(r);
 | ||
|     const TRiga_partite& sum = _p->riga(rec.get_int(PAGSCA_NRIGP));
 | ||
|     const char* field = (_stvaluta && sum.in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO);
 | ||
|     
 | ||
|     const tipo_movimento tm = (tipo_movimento)sum.get_int(PART_TIPOMOV);
 | ||
|     switch (tm)
 | ||
|     {
 | ||
|     case tm_nota_credito      : b += rec.get_real(field); break; // Is it a credit note?
 | ||
|     case tm_insoluto          : c += rec.get_real(field); break; // Is unsolved?
 | ||
|     case tm_pagamento_insoluto: c -= rec.get_real(field); break; // Is unsolved payed?
 | ||
|     default                   : a += rec.get_real(field); break;
 | ||
|     }
 | ||
|   }    
 | ||
| 
 | ||
|   if (a != ZERO) // Aggiungilo a TAssoc_array dei non assegnati    
 | ||
|     uns.add(k,a,true); 
 | ||
|   if (b != ZERO) // Aggiungilo a TAssoc_array delle note di credito
 | ||
|     unsnc.add(k,b,true); 
 | ||
|   if (c != ZERO) // Aggiungilo a TAssoc_array degli insoluti
 | ||
|     unsins.add(k,c,true); 
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::look_in_cache(real& a, real& b, real& c, 
 | ||
|                                        TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, 
 | ||
|                                        TString& k)
 | ||
| //Estrae dai tassoc_array i valori, relativi alla partita corrente, di uns e unsnc, mettendoli in a e b
 | ||
| {
 | ||
|   TRiga_partite& rp = _p->riga(_p->first());
 | ||
|   k << rp.get_char(PART_TIPOCF) << rp.get_int(PART_GRUPPO);
 | ||
|   k << rp.get_int(PART_CONTO) << rp.get_long(PART_SOTTOCONTO);
 | ||
|   k << rp.get_int(PART_ANNO);
 | ||
|   k << rp.get(PART_NUMPART);
 | ||
|   
 | ||
|   a = b = c = ZERO;
 | ||
|   if (uns.is_key(k)) a = (real&)uns[k];
 | ||
|   if (unsnc.is_key(k)) b = (real&)unsnc[k];
 | ||
|   if (unsins.is_key(k)) c = (real&)unsins[k];
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill)
 | ||
| {                               
 | ||
|   TAssoc_array& uns = (TAssoc_array&) _uns_cache[0];
 | ||
|   TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1];
 | ||
|   TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2];
 | ||
| 
 | ||
|   if (!_p->esiste(riga, rata))
 | ||
|   {
 | ||
|     error_box("Nella partita %c %ld %d %s la rata %d non corrisponde ad una riga di fattura (%d)",
 | ||
|               bill.tipo(), bill.codclifo(), _p->anno(), (const char*)_p->numero(), rata, riga);
 | ||
|     return;
 | ||
|   }
 | ||
| 
 | ||
|   const TRiga_scadenze& rs = _p->rata(riga, rata);   
 | ||
|   const char ssez = _p->riga(riga).sezione();
 | ||
|   const char* field  = (_stvaluta && rs.in_valuta()) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
 | ||
|   const char* sfield = (_stvaluta && rs.in_valuta()) ? SCAD_IMPORTOVAL : SCAD_IMPORTO;
 | ||
|   TImporto totalep,     // Totale dei pagamenti
 | ||
|            scdz;        // Importo in scadenza  
 | ||
|   scdz += TImporto(ssez,rs.get_real(sfield));
 | ||
|   totalep += rs.importo_pagato(_stvaluta); // Quanto e' stato pagato per questa scadenza?
 | ||
|   for (int p = rs.last(); p > 0; p = rs.pred(p))   // Calcola il totale pagamenti e discrimina 
 | ||
|   {                                          // Il TIPOMOV: 1,5      : fattura insoluto
 | ||
|     const TRectype pag = rs.row(p);          //             2        : nota di credito
 | ||
|     const TRiga_partite& sum = _p->riga(p);  //             3,4,6    : incasso/pagamento/abbuono/pag.insoluto/diff.cambio/rit.prof
 | ||
|     const char sez = sum.sezione();
 | ||
|     const tipo_movimento tipomov = (tipo_movimento)sum.get_int(PART_TIPOMOV);
 | ||
|     // se tipomov e' 2 (Nota di credito assegnata)
 | ||
|     // storna da scdz. In entrambi i casi si ha l'operatore +=, perche' nel TImporto e' gia'
 | ||
|     // compresa la sezione opposta
 | ||
|     if (tipomov == tm_nota_credito)
 | ||
|     { 
 | ||
|       const TImporto work_imp = TImporto(sez,pag.get_real(field));
 | ||
|       scdz += work_imp;
 | ||
|       totalep -= work_imp;
 | ||
|     }
 | ||
|   }
 | ||
|   char norm = 'D';
 | ||
|   if (_tipost == fornitori) 
 | ||
|     norm = 'A';
 | ||
|   else 
 | ||
|     if (_tipost == altri && bill.find()) 
 | ||
|       norm = bill.sezione();
 | ||
|   totalep.normalize((norm=='D') ? 'A' : 'D'); 
 | ||
|   scdz.normalize(norm);
 | ||
|   _w_imp_pag = totalep.valore();
 | ||
|   imp_scad = scdz.valore();             
 | ||
|   real a,b,c;
 | ||
|   TString80 k;
 | ||
|   look_in_cache(a,b,c,uns,unsnc,unsins,k);
 | ||
|   if (b > ZERO) // Scala le note di credito dalle scadenze
 | ||
|   {
 | ||
|     const real gap = b > imp_scad ? imp_scad : b;
 | ||
|     imp_scad -= gap;
 | ||
|     b -= gap;
 | ||
|     if (b > ZERO)
 | ||
|       unsnc.add(k,b,true);
 | ||
|     else            
 | ||
|       unsnc.remove(k); // Free some space when 0 reached.
 | ||
|   }
 | ||
|   if (a > ZERO && imp_scad > _w_imp_pag)
 | ||
|   {                                 
 | ||
|     // Lo scalare dei non assegnati e' progressivo a partire dalla rata piu' vecchia.
 | ||
|     // Se ce n'e' in piu' vengono ignorati.
 | ||
|     const real gap = a > imp_scad ?  imp_scad : a;
 | ||
|     _w_imp_pag += gap;
 | ||
|     a -= gap;
 | ||
|     if (a > ZERO)
 | ||
|       uns.add(k,a,true);
 | ||
|     else
 | ||
|       uns.remove(k);     // Free some space when 0 reached
 | ||
|   }
 | ||
|   if (c > ZERO)
 | ||
|   {
 | ||
|     const real gap = c > _w_imp_pag ? _w_imp_pag : c;
 | ||
|     _w_imp_pag -= gap;
 | ||
|     c -= gap;
 | ||
|     if (c > ZERO)
 | ||
|       unsins.add(k,c,true);
 | ||
|     else
 | ||
|       unsins.remove(k);     // Free some space when 0 reached
 | ||
|   }
 | ||
|   
 | ||
|   _w_imp_res = imp_scad - _w_imp_pag; 
 | ||
| }
 | ||
| 
 | ||
| const char * TStampaScadenzario::tipi_tab(int tipo)
 | ||
| {
 | ||
| 	switch (tipo)
 | ||
| 	{
 | ||
| 		case 0:
 | ||
| 			return TR("Altro");
 | ||
| 			break;
 | ||
| 		case 1:
 | ||
| 			return TR("Rimesse dirette");
 | ||
| 			break;
 | ||
| 		case 2:
 | ||
| 			return TR("Tratte");
 | ||
| 			break;
 | ||
| 		case 3:
 | ||
| 			return TR("Ricevute bancarie");
 | ||
| 			break;
 | ||
| 		case 4:
 | ||
| 			return TR("Cessioni");
 | ||
| 			break;
 | ||
| 		case 5:
 | ||
| 			return TR("Paghero'");
 | ||
| 			break;
 | ||
| 		case 6:
 | ||
| 			return TR("Lettere di acc.");
 | ||
| 			break;
 | ||
| 		case 7:
 | ||
| 			return TR("Tratte accettate");
 | ||
| 			break;
 | ||
| 		case 8:
 | ||
| 			return TR("Rapp. interb. dir.");
 | ||
| 			break;
 | ||
| 		case 9:
 | ||
| 			return TR("Bonifici");
 | ||
| 			break;
 | ||
| 		default:
 | ||
| 			return "";
 | ||
| 			break;
 | ||
|                  
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::preprocess_page(int file, int counter)
 | ||
| // Se ritorna false salta questa scadenza e va alla prossima.
 | ||
| {   
 | ||
|   const TRectype &rc   = current_cursor()->curr(LF_SCADENZE);
 | ||
|   const char  tipoc    = rc.get_char(SCAD_TIPOCF);     // Tipo
 | ||
|   const int   gruppo   = rc.get_int(SCAD_GRUPPO);      // Gruppo
 | ||
|   const int   conto    = rc.get_int(SCAD_CONTO);       // Conto
 | ||
|   const long  codcf    = rc.get_long(SCAD_SOTTOCONTO); // Codice Cliente/Fornitore/Conto
 | ||
|   const int   annop    = rc.get_int(SCAD_ANNO);        // Anno partita
 | ||
|   const TString8 nump  = rc.get(SCAD_NUMPART);         // Nr partita    
 | ||
|   const int   nrigap   = rc.get_int(SCAD_NRIGA);       // Nr riga      
 | ||
|   const int   nratap   = rc.get_int(SCAD_NRATA);       // Nr rata
 | ||
|   const TDate datascad = rc.get_date(SCAD_DATASCAD);   // Data scadenza
 | ||
|   const int   tipo_pag = rc.get_int(SCAD_TIPOPAG);     // Tipo di pagamento
 | ||
|   const char  ult_cla  = rc.get_char(SCAD_ULTCLASS);   // Ulteriore classificazione
 | ||
| 
 | ||
|   real imp_scad ;
 | ||
|                    
 | ||
|                                                      // Importo in scadenza (vale IMPORTO o
 | ||
|                                                      // IMPORTOVAL a seconda sia stata impostata la
 | ||
|                                                      // stampa in valuta.
 | ||
|   
 | ||
|   if (_end_printed && (file == LF_CLIFO || file == LF_PCON))
 | ||
|     return false; // Dopo aver stampato i totali finali non deve rientrare per stampare
 | ||
|                   // LF_CLIFO o LF_PCON 
 | ||
|   
 | ||
|   if (_end_printed)
 | ||
|   {                // Qui controlla se ci sono totali da stampare
 | ||
|     TAssoc_array& tp = (TAssoc_array&)_tl[2];
 | ||
|     if (tp.items() == 0) 
 | ||
|       return false;
 | ||
|   }                
 | ||
|   
 | ||
|   if (file == LF_SCADENZE && !_end_printed)
 | ||
|   {  
 | ||
|     TBill bill(rc);
 | ||
|     if (!_m->selected(bill))
 | ||
|       return false;
 | ||
| 
 | ||
|     _descrizione->restart();
 | ||
|     if (scad_changed(tipoc,gruppo,conto,codcf,annop,nump))
 | ||
|     {
 | ||
|       TRectype rp(LF_PARTITE);
 | ||
|       rp.put(PART_TIPOCF,tipoc);
 | ||
|       rp.put(PART_GRUPPO,gruppo);
 | ||
|       rp.put(PART_CONTO,conto);
 | ||
|       rp.put(PART_SOTTOCONTO,codcf);
 | ||
|       rp.put(PART_ANNO,annop);
 | ||
|       rp.put(PART_NUMPART,nump);
 | ||
|       if (_p) delete _p;
 | ||
|       _p = new TPartita(rp);
 | ||
|       
 | ||
|       TString80 k; // compone la chiave dei tassoc_array dentro a _uns_cache
 | ||
|       k << tipoc << gruppo ;
 | ||
|       k << conto << codcf;
 | ||
|       k << annop << nump;
 | ||
|       if (!in_cache(k))
 | ||
|         calcola_unassigned(k);
 | ||
|       TRiga_partite& row = _p->riga(nrigap);
 | ||
|       _datareg = row.get_date(PART_DATAREG).string(brief);
 | ||
|       _datadoc = row.get_date(PART_DATADOC).string(brief);
 | ||
|       _numdoc  = row.get(PART_NUMDOC);
 | ||
|       _protiva.format("%5ld",row.get_long(PART_PROTIVA));
 | ||
|       *_descrizione = row.get(PART_DESCR); 
 | ||
|       _codval  = row.get(PART_CODVAL);              
 | ||
|       //Per indicare che non e' indicata la valuta o e' LIRA (se la stampa in valuta is disabled)
 | ||
|       if (_codval.empty() || !_stvaluta) _codval = "   "; 
 | ||
|       if (_descrizione->items() == 0)  // Se sulla partita non c'e' descrizione allora va leggerla sulla causale.
 | ||
| 	      *_descrizione = cache().get(LF_CAUSALI, row.get(PART_CODCAUS), CAU_DESCR); 
 | ||
|     }
 | ||
|     calcola_pagamenti(imp_scad,nrigap,nratap, bill);
 | ||
|     
 | ||
|     // Se la rata e' stata saldata e non e' abilitato il flag di stampa 
 | ||
|     // oppure l'importo in scadenza e' 0 allora salta alla prossima scadenza
 | ||
|     
 | ||
|     if (!_ratesald && _w_imp_res == 0.0)
 | ||
|       return false;
 | ||
|     
 | ||
|     _annopart.format("%d",annop);
 | ||
|     _annopart.ltrim(2);
 | ||
|     _rimdir = "";
 | ||
|     _riba = "";
 | ||
|     _bonifico = "";
 | ||
|     _altri = "";
 | ||
|     _imp_pag = "";
 | ||
| 
 | ||
|     const bool print_in_valuta = _stvaluta && is_true_value(_codval);
 | ||
| 
 | ||
|     print_real(_imp_scad, imp_scad, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
| 
 | ||
|     if (_w_imp_pag != ZERO)
 | ||
|       print_real(_imp_pag, _w_imp_pag, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
| 
 | ||
|     if (_w_imp_res != ZERO) 
 | ||
|       switch (tipo_pag)
 | ||
|       {
 | ||
|         case 1:     // Rimesse dirette
 | ||
|           print_real(_rimdir, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
|           break;
 | ||
|         case 2:     // ri.ba / Tratte
 | ||
|         case 3:
 | ||
|           print_real(_riba, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
|           break;
 | ||
|         case 9:     // Bonifici
 | ||
|           print_real(_bonifico, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
|           break;
 | ||
|         default:    // Altri
 | ||
|           print_real(_altri, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING);
 | ||
|           break;
 | ||
|       } 
 | ||
|   }  //if (file == LF_SCADENZE && !_end_printed)...         
 | ||
| 
 | ||
|   if (file == LF_CLIFO)
 | ||
|   {      
 | ||
|     TString80 xxx(current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC));
 | ||
|     *_ragsoc = xxx.strip_double_spaces();
 | ||
|   }
 | ||
|   if (file == LF_PCON)
 | ||
|     *_des_conto = current_cursor()->curr(LF_PCON).get(PCN_DESCR);
 | ||
| 
 | ||
|   // Se l'ordinamento principale e' per data scadenza stampa il totale del giorno e del mese
 | ||
|   if (_ordata && !_end_printed)                   
 | ||
|     if ((file == LF_SCADENZE && _tipost == tutti) ||
 | ||
|         (file == LF_PCON && _tipost == altri) ||
 | ||
|         (file == LF_CLIFO && (_tipost == clienti || _tipost == fornitori)))
 | ||
|       {   
 | ||
|         bool date_changed = false;
 | ||
|         if (_cur_data.ok())
 | ||
|           date_changed = _cur_data != datascad;
 | ||
|         if (date_changed)
 | ||
|         {
 | ||
|           // Se la data di scadenza e' cambiata e non e' il primo record della relazione
 | ||
|           // allora stampa i totali del giorno. 
 | ||
|           // Controlla poi se e' cambiato il mese, in caso affermativo stampa anche i 
 | ||
|           // totali del mese e lo schema riepilogativo mensile
 | ||
|           const bool month_changed = _cur_data.month() != datascad.month();
 | ||
|           
 | ||
|           for (int i=1; i<MaxRowsForTotal; i++) reset_row(i);
 | ||
|           int n = 1;
 | ||
|           set_row(n++,"");
 | ||
|           print_totali(n,month_changed,false);
 | ||
|           switch (_tipost)
 | ||
|           {
 | ||
|             case clienti:
 | ||
|             case fornitori:
 | ||
|               set_page_clifo(n);
 | ||
|             break;
 | ||
|             case altri:
 | ||
|               set_page_pcon(n);
 | ||
|             break;
 | ||
|             case nessuno:
 | ||
|             default:
 | ||
|             break;
 | ||
|           }
 | ||
|           _modified=true;
 | ||
|           // Azzera i totali del giorno in ogni caso.
 | ||
|           TAssoc_array& tlg = (TAssoc_array&) _tl[0];
 | ||
|           tlg.destroy();
 | ||
|           // Controlla se e' cambiato il mese azzera i relativi totali 
 | ||
|           if (month_changed)
 | ||
|           {  
 | ||
|             _tm.destroy(); // Cancella tutti gli elementi del mese dopo averli stampati
 | ||
|             TAssoc_array& tlm = (TAssoc_array&) _tl[1];
 | ||
|             tlm.destroy();
 | ||
|           }
 | ||
|           if (_group_ban && _totbank_printed)
 | ||
|           {
 | ||
|             TAssoc_array& tlb = (TAssoc_array&) _tl[3];
 | ||
|             tlb.destroy();
 | ||
|             _totbank_printed = false;
 | ||
|           }	
 | ||
|         }
 | ||
|         // Tiene aggiornati tutti i totali mese/giorno/periodo (Totali lineari per valuta)
 | ||
|         check_add_key_to_tl(daily, tipo_pag);
 | ||
|         check_add_key_to_tl(monthly, tipo_pag);
 | ||
|         check_add_key_to_tl(period, tipo_pag);
 | ||
|         if (_group_ban) 
 | ||
|         	check_add_key_to_tl(bank, tipo_pag); // totali per banca
 | ||
|         // Tiene aggiornati tutti i totali mese/periodo (Totali dei prospetti
 | ||
|         check_add_key_to_tp(tipo_pag, ult_cla);
 | ||
|         _cur_data = datascad;
 | ||
|         _cur_codcf_s.format("%6ld",codcf);
 | ||
|      }      
 | ||
|   // Qui stampa il totale generale e lo specchietto colonnello.
 | ||
|   // Vale con l'ordinamento principale per data di scadenza.
 | ||
|   // N.B viene eseguito solo come ultimo blocco, grazie ad una REPEAT_PAGE in postprocess_print()
 | ||
|   if (_end_printed && file == LF_SCADENZE && _ordata)
 | ||
|   {
 | ||
|     reset_print();
 | ||
|     int n=1;
 | ||
|     set_row(n++,"");
 | ||
|     print_totali(n,true,true);
 | ||
|   }   
 | ||
|   // Qui stampa il totale di ogni cli/fo o conto, nel caso che l'ordinamento
 | ||
|   // primario non sia per data di scadenza
 | ||
|   if (!_ordata && !_end_printed && file!=LF_SCADENZE)  
 | ||
|   {
 | ||
|     bool changed = true;
 | ||
|     // Vale anche con ordinamento primario per descrizione o ragione sociale: se essa cambia
 | ||
|     // cambia anche il trio Gr/Co/So.
 | ||
|     if (_cur_gr != -1 && _cur_co != -1 && _cur_codcf != -1)
 | ||
|       if (_cur_gr != gruppo || _cur_co != conto || _cur_codcf != codcf)
 | ||
|       { 
 | ||
|         for (int i=1; i<MaxRowsForTotal; i++) reset_row(i);
 | ||
|         int n = 1;
 | ||
|         set_row(n++,"");
 | ||
|         print_totali_c(n,false);
 | ||
|         if (_tipost == altri)
 | ||
|           set_page_pcon(n);
 | ||
|         else
 | ||
|           set_page_clifo(n);
 | ||
|         _modified=true;
 | ||
|         TAssoc_array& tlm = (TAssoc_array&) _tl[1];
 | ||
|         tlm.destroy();
 | ||
|         _tm.destroy();  // Cancella i valori del cli/fo/conto dopo averli stampati
 | ||
|       }
 | ||
|       else
 | ||
|       { // If group/count/codcf Remains The Same  don't repeat _ragsoc, _des_conto...
 | ||
|         *_ragsoc = "";
 | ||
|         *_des_conto = "";
 | ||
|         _cur_gr_s = "";
 | ||
|         _cur_co_s = "";
 | ||
|         _cur_codcf_s = "";
 | ||
|         changed = false;
 | ||
|       }  
 | ||
| 
 | ||
|     if (_group_ban && _totbank_printed)
 | ||
|     {
 | ||
|       TAssoc_array& tlb = (TAssoc_array&) _tl[3];
 | ||
|       tlb.destroy();
 | ||
|       _totbank_printed = false;
 | ||
|     }	
 | ||
| 
 | ||
|     if (changed)
 | ||
|     {
 | ||
|       _cur_gr_s.format("%3d",gruppo);
 | ||
|       _cur_co_s.format("%3d",conto);
 | ||
|       _cur_codcf_s.format("%6ld",codcf);
 | ||
|     }
 | ||
|     _cur_gr=gruppo;
 | ||
|     _cur_co=conto;
 | ||
|     _cur_codcf=codcf;
 | ||
|     // Tiene aggiornati i totali per cli/fo/conto e periodo (Totali lineari per valuta)
 | ||
|     check_add_key_to_tl(single, tipo_pag);
 | ||
|     check_add_key_to_tl(period, tipo_pag);
 | ||
|     if (_group_ban)
 | ||
|     	check_add_key_to_tl(bank, tipo_pag); // totali per banca
 | ||
|   // Tiene aggiornati i totali per cli/fo/conto e periodo (Totali per i prospetti)
 | ||
|     check_add_key_to_tp(tipo_pag, ult_cla);
 | ||
|   }
 | ||
|   // Qui stampa il totale generale e lo schema riepilogativo.
 | ||
|   // Vale con l'ordinamento principale per codice/descrizione/ragione sociale.
 | ||
|   // N.B viene eseguito solo come ultime blocco, grazie ad una REPEAT_PAGE in postprocess_print()
 | ||
|   if (_end_printed && file == LF_SCADENZE && !_ordata)
 | ||
|   {                              
 | ||
|     reset_print();
 | ||
|     int n=1;
 | ||
|     set_row(n++,"");                         
 | ||
|     // Il confronto posso farlo solo su clienti/fornitori/altri, anche perche'
 | ||
|     // per tutti e' obbligatorio l'ordinamento principale per data.
 | ||
|     print_totali_c(n,true);
 | ||
|   }
 | ||
| 
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::preprocess_print(int file, int counter)
 | ||
| { 
 | ||
|   return true;
 | ||
| }
 | ||
|               
 | ||
| print_action TStampaScadenzario::postprocess_print(int file, int counter)
 | ||
| {  
 | ||
|   print_action rt = NEXT_PAGE;            
 | ||
|   // Setta _end_printed e ripete la pagina. Questa condizione puo' accadere
 | ||
|   // solo alla fine dei record di LF_SCADENZE, percio' solo dopo aver stampato
 | ||
|   // tutti gli altri; sia per LF_CLIFO che per LF_PCON, purche' LF_SCADENZE 
 | ||
|   // sia sempre il file principale della relazione e dell'albero di stampa.
 | ||
|   // Ritornando REPEAT_PAGE resettera' le righe di stampa, e all'interno della
 | ||
|   // preprocess_page formera' le righe dei riepiloghi finali.
 | ||
|   // Se LF_PCON o LF_CLIFO sono i file principali della relazione e' necessario aggiungere
 | ||
|   // una seconda condzione, valevole solamente se l'ordine principale non e' per data scadenza.
 | ||
|   if (!_end_printed)      // Se non e' ancora stato stampato il totale generale...
 | ||
|   {
 | ||
|     if (file == LF_SCADENZE) //&& _ordata) || (file !=LF_SCADENZE && !_ordata))
 | ||
|     {             
 | ||
|       rt = REPEAT_PAGE;
 | ||
|       _end_printed = true;
 | ||
|     }
 | ||
|   }
 | ||
|   return rt;
 | ||
| }
 | ||
| 
 | ||
| print_action TStampaScadenzario::postprocess_page(int file, int counter)
 | ||
| {   
 | ||
|   if (_modified)
 | ||
|     reset_print();
 | ||
| 
 | ||
|   return NEXT_PAGE;
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::user_create()
 | ||
| {                                                
 | ||
|   _rel1 = new TRelation(LF_SCADENZE);           // Scadenze per data scadenza + CliFo (Codice & Ragione sociale)
 | ||
|   _rel1->lfile().set_curr(new TScadenza_rec);
 | ||
|   _rel1->add(LF_CLIFO,"TIPOCF=TIPOC|CODCF=SOTTOCONTO",1,0,SCADCLIFO_ALIAS);
 | ||
|   _cur1 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2));
 | ||
|   // Per data scadenza + ragione sociale e' necessario un TSorted_cursor con update del file collegato:
 | ||
|   _cur11 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|UPPER(20->RAGSOC)|ANNO|NUMPART|NRIGA|NRATA","",2));
 | ||
|   
 | ||
|   // Scadenze per CliFo (Codice & Ragione sociale) + data scadenza
 | ||
|   _cur2 = add_cursor(new TSorted_cursor(_rel1,"SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); 
 | ||
|   _cur3 = add_cursor(new TSorted_cursor(_rel1,"UPPER(20->RAGSOC)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2));
 | ||
|   
 | ||
|   _rel2 = new TRelation(LF_SCADENZE);           // Scadenze per data scadenza + piano dei conti (Codice & Descrizione)
 | ||
|   _rel2->lfile().set_curr(new TScadenza_rec);
 | ||
|   _rel2->add(LF_PCON,"GRUPPO=GRUPPO|CONTO=CONTO|SOTTOCONTO=SOTTOCONTO",1,0,SCADPCON_ALIAS);
 | ||
|   _cur4 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|GRUPPO|CONTO|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2)); 
 | ||
|   // Per data scadenza + descrizione e' necessario un TSorted_cursor con update del file collegato:
 | ||
|   _cur41 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|UPPER(19->DESCR)|ANNO|NUMPART|NRIGA|NRATA","",2));
 | ||
|   
 | ||
|   // Scadenze per Conti (Codice & descrizione) + data scadenza 
 | ||
|   _cur5 = add_cursor(new TSorted_cursor(_rel2,"GRUPPO|CONTO|SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); 
 | ||
|   _cur6 = add_cursor(new TSorted_cursor(_rel2,"UPPER(19->DESCR)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2));
 | ||
|   
 | ||
|   _rel3 = new TRelation(LF_SCADENZE);           // Scadenze (Tutte) per data scadenza
 | ||
|   _rel3->lfile().set_curr(new TScadenza_rec);
 | ||
|   _cur7 = add_cursor(new TCursor(_rel3,"",2));
 | ||
|   
 | ||
|   open_files(LF_TABCOM, LF_TAB, LF_CAUSALI, LF_PARTITE, LF_PAGSCA, 0);
 | ||
| 	
 | ||
|   _pagsca   = new TLocalisamfile(LF_PAGSCA);
 | ||
|   _descrizione = new TParagraph_string("",17);
 | ||
|   _ragsoc = new TParagraph_string("",17);
 | ||
|   _des_conto = new TParagraph_string("",17);
 | ||
|   
 | ||
|   _tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array);
 | ||
|   _uns_cache.add(new TAssoc_array);  // Pagamenti
 | ||
|   _uns_cache.add(new TAssoc_array);  // Note di credito
 | ||
|   _uns_cache.add(new TAssoc_array);  // Insoluti
 | ||
|   
 | ||
|   TConfig conf (CONFIG_DITTA,"cg");
 | ||
|   _m = new TSelection_ext_mask("sc2200a");
 | ||
|   _m->enable(F_VALUTA,conf.get_bool("GesVal")); 
 | ||
|   
 | ||
|   enable_print_menu();               
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::user_destroy()
 | ||
| {
 | ||
| // 
 | ||
| // Color che di Printapp conoscon nulla,
 | ||
| // evitar, dovrebber, il delete che trastulla
 | ||
| // onde la nausea, ch'assale il tuo fardello,
 | ||
| // mejo la new lasciar nel suo castello.
 | ||
| //
 | ||
| // Nota del trastullatore:
 | ||
| // Mai fare la delete di un cursore usato
 | ||
| // dalla printapp, poiche' e' lei stessa che
 | ||
| // effettua tale operazione nella propria destroy().
 | ||
| // 
 | ||
|   if (_rel1)  delete _rel1;
 | ||
|   if (_rel2)  delete _rel2;
 | ||
|   if (_rel3)  delete _rel3;
 | ||
|   if (_pagsca)
 | ||
|     delete _pagsca;   
 | ||
|   if (_descrizione)
 | ||
|     delete _descrizione;
 | ||
|   if (_des_conto)
 | ||
|     delete _des_conto;
 | ||
|   if (_ragsoc)
 | ||
|     delete _ragsoc;
 | ||
|   _tl.destroy();
 | ||
|   _uns_cache.destroy();
 | ||
|   _tm.destroy();
 | ||
|   _tp.destroy();
 | ||
|   if (_m) delete _m;
 | ||
| // la delete di _tl viene fatta nel distruttore dell'applicazione.
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::add_filter_fatt(TCursor * cur, const char * filter)
 | ||
| {
 | ||
| 	if (cur->relation()->log2ind(LF_PARTITE) < 0)
 | ||
| 		cur->relation()->add(LF_PARTITE, "TIPOC==TIPOC|GRUPPO==GRUPPO|CONTO==CONTO|SOTTOCONTO==SOTTOCONTO|ANNO==ANNO|NUMPART==NUMPART|NRIGA==NRIGA");
 | ||
| 	TString newfilter(cur->filter());
 | ||
| 
 | ||
| 	if (newfilter.full())
 | ||
| 		newfilter << "&&";
 | ||
| 	newfilter << filter;
 | ||
| 	cur->setfilter(newfilter, true);
 | ||
| }
 | ||
| 
 | ||
| bool TStampaScadenzario::set_print(int)
 | ||
| { 
 | ||
| 	_m->reset(F_SORTBAN);
 | ||
| 	_m->reset(F_CODAG);
 | ||
| 	_m->reset(F_TIPOPAG);
 | ||
|   const bool ok = _m->run() == K_ENTER;
 | ||
|   if (ok)
 | ||
|   {                               
 | ||
|   	_last_bank_rec = 0;
 | ||
|     _end_printed = false;
 | ||
|     _totbank_printed = false;
 | ||
|     reset_files();
 | ||
|     reset_print();
 | ||
|     // Inizializza i membri necessari al calcolo totali nel caso sia stato scelto l'ordine
 | ||
|     // primario secondo la data di scadenza.
 | ||
|     if (_m->get_who() == 'P') _tipost = altri;
 | ||
|     else if (_m->get_who() == 'C') _tipost = clienti;
 | ||
|          else _tipost = fornitori;
 | ||
|     _ordcod = _m->get_key() == 1; // Stampa ordinata per codice?
 | ||
|     _group_ban = _m->get_bool(F_SORTBAN); // Raggruppamento per banca di presentazione
 | ||
|     _codag = _m->get(F_CODAG); // codice agente selezionato
 | ||
|     _tipopag = _m->get_int(F_TIPOPAG); // tipo pagamento selezionato
 | ||
| 		_notot = _m->get_bool(F_NOTOT);	// non stampare i totali intermedi
 | ||
|     _cur_data = botime;
 | ||
|     _tm.destroy(); _tp.destroy();                    // Totali per i prospetti
 | ||
|     for (int it=0; it < _tl.items(); it++)
 | ||
|     {
 | ||
|       TAssoc_array& aa = (TAssoc_array&) _tl[it];
 | ||
|       aa.destroy();  // Totali lineari (tlg, tlm, tlp)
 | ||
|     }
 | ||
|     // Inizializza i membri necessari al calcolo totali nel caso sia stato scelto l'ordine 
 | ||
|     // primario per codice/gr.co.so. ragione sociale/descrizione
 | ||
|     _cur_codcf      = -1;
 | ||
|     _cur_gr=_cur_co = -1;
 | ||
|     // Per calcolare i totali nel caso l'ordine primario non sia per data scadenze
 | ||
|     // utilizzera' le variabili _tp_* per il totale generale e _tm_* per i singoli totali.
 | ||
|     // E' necessario resettare anche queste TParagraph_string... Puo' servire in futuro...
 | ||
|     *_ragsoc      = "";
 | ||
|     *_des_conto   = "";                                                                   
 | ||
|     *_descrizione = "";     
 | ||
|     _ratesald = _m->get_bool(F_RATESALDATE);
 | ||
|     _ordata   = _m->get_bool(F_ORDDATA);
 | ||
|     _stvaluta = _m->get_bool(F_VALUTA);
 | ||
|     _striepilogo = _m->get_int(F_RIEPILOGO);
 | ||
| 
 | ||
| 		const bool sel_datafatt = _m->get_bool(F_SELDATAFAT);
 | ||
| 
 | ||
| 		if (sel_datafatt)
 | ||
| 		{
 | ||
| 			_datai    = _m->get_date(F_DATAFATTI);
 | ||
| 			_dataf    = _m->get_date(F_DATAFATTF);
 | ||
| 		}
 | ||
| 		else
 | ||
| 		{
 | ||
| 			_datai    = _m->get_date(F_DATASCADENZAI);
 | ||
| 			_dataf    = _m->get_date(F_DATASCADENZAF);
 | ||
| 		}
 | ||
|     _datas    = _m->get_date(F_DATASTAMPA);
 | ||
| 
 | ||
|     // N.B I cursori sono tutti TSorted_cursor; alcuni di questi(_cur11 e _cur41) referenziano a campi di sort
 | ||
|     // presenti anche su altri file (LF_CLIFO o LF_PCON), percio' e' necessario che il metodo filtercursor() 
 | ||
|     // (v. TCursor o TSorted_cursor) forzi un update della relazione ad ogni record che viene processato.
 | ||
|     // I cursori 1,2,4 e 6 sono TSorted_cursor anch'essi, siccome la funzione di filtro deve reperire il nr.
 | ||
|     // di record del file inerente alla selezione, e' necessario fare l'update ogni volta.
 | ||
|     // I cursori hanno tutti la stessa funzione di filtro, per la stampa della rate saldate.
 | ||
|     // L'unico TCursor e' _cur7, poiche' e' utilizzato per stampare solo i record di LF_SCADENZE.
 | ||
|     get_cursor(_cur1)->set_filterfunction(filter_func,true); // Cursore 1: Datascad + Clifo (codice)
 | ||
|     get_cursor(_cur11)->set_filterfunction(filter_func,true);// Cursore 1.1: Datascad + Clifo (ragione sociale) 
 | ||
|     get_cursor(_cur2)->set_filterfunction(filter_func,true); // Cursore 2: Clifo(codice) + Datascad
 | ||
|     get_cursor(_cur3)->set_filterfunction(filter_func,true); // Cursore 3: Clifo(ragione sociale) + Datascad
 | ||
|     get_cursor(_cur4)->set_filterfunction(filter_func,true); // Cursore 4: Datascad + PCon  (codice)
 | ||
|     get_cursor(_cur41)->set_filterfunction(filter_func,true);// Cursore 4.1: Datascad + PCon (descrizione)
 | ||
|     get_cursor(_cur5)->set_filterfunction(filter_func,true); // Cursore 5: PCon (Codice) + Datascad  
 | ||
|     get_cursor(_cur6)->set_filterfunction(filter_func,true); // Cursore 6: PCon (descrizione) + Datascad  
 | ||
|     get_cursor(_cur7)->set_filterfunction(filter_func);      // Cursore 7: Datascad
 | ||
|     
 | ||
|     // Setta l'intervallo di data. Si puo' fare per tutti i cursori, poiche' 
 | ||
|     // il file principale e' sempre LF_SCADENZE.
 | ||
| 
 | ||
| 		if (!sel_datafatt)
 | ||
| 		{
 | ||
| 	    TRectype da_data(LF_SCADENZE), a_data(LF_SCADENZE);
 | ||
| 			da_data.put(SCAD_DATASCAD,_datai);
 | ||
| 			a_data.put(SCAD_DATASCAD,_dataf);
 | ||
| 			get_cursor(_cur1)->setregion(da_data,a_data);    
 | ||
| 			get_cursor(_cur11)->setregion(da_data,a_data);
 | ||
| 			get_cursor(_cur2)->setregion(da_data,a_data); 
 | ||
| 			get_cursor(_cur3)->setregion(da_data,a_data); 
 | ||
| 			get_cursor(_cur4)->setregion(da_data,a_data); 
 | ||
| 			get_cursor(_cur41)->setregion(da_data,a_data);
 | ||
| 			get_cursor(_cur5)->setregion(da_data,a_data); 
 | ||
| 			get_cursor(_cur6)->setregion(da_data,a_data); 
 | ||
| 			get_cursor(_cur7)->setregion(da_data,a_data); 
 | ||
| 		}
 | ||
| 		get_cursor(_cur1)->setfilter("");    
 | ||
| 		get_cursor(_cur11)->setfilter("");
 | ||
| 		get_cursor(_cur2)->setfilter("");
 | ||
| 		get_cursor(_cur3)->setfilter("");
 | ||
| 		get_cursor(_cur4)->setfilter("");
 | ||
| 		get_cursor(_cur41)->setfilter("");
 | ||
| 		get_cursor(_cur5)->setfilter(""); 
 | ||
| 		get_cursor(_cur6)->setfilter("");
 | ||
| 		get_cursor(_cur7)->setfilter("");
 | ||
| 		switch (_tipost)
 | ||
|     {       
 | ||
|      case tutti:
 | ||
|        select_cursor(_cur7);
 | ||
|        add_file(LF_SCADENZE);
 | ||
|        break;
 | ||
|      case clienti:
 | ||
|      case fornitori:
 | ||
|        if (_ordata)                    // Ordine primario per data
 | ||
|        {                               // Controlla l'ordine secondario (codice o ragione sociale)
 | ||
|          if (_ordcod)                  // Per codice...
 | ||
|          {
 | ||
|           select_cursor(_cur1);
 | ||
|           if (_tipost==clienti)
 | ||
|             get_cursor(_cur1)->setfilter("(TIPOC=\"C\")");
 | ||
|           else
 | ||
|             get_cursor(_cur1)->setfilter("(TIPOC=\"F\")");  
 | ||
|          }
 | ||
|          else
 | ||
|          {
 | ||
|           select_cursor(_cur11);    // Per ragione sociale
 | ||
|           if (_tipost==clienti)
 | ||
|           get_cursor(_cur11)->setfilter("(TIPOC=\"C\")");
 | ||
|           else
 | ||
|           get_cursor(_cur11)->setfilter("(TIPOC=\"F\")");  
 | ||
|          }
 | ||
|        }
 | ||
|        else                            // Ordine primario per codice o ragione sociale
 | ||
|        {                               
 | ||
|          if (_ordcod)                  // Codice...
 | ||
|          {
 | ||
|            select_cursor(_cur2);               
 | ||
|            if (_tipost==clienti)
 | ||
|              get_cursor(_cur2)->setfilter("(TIPOC=\"C\")");
 | ||
|            else
 | ||
|              get_cursor(_cur2)->setfilter("(TIPOC=\"F\")");
 | ||
|          }
 | ||
|          else                          // Ragione sociale
 | ||
|          {
 | ||
|            select_cursor(_cur3);
 | ||
|            if (_tipost==clienti)
 | ||
|              get_cursor(_cur3)->setfilter("(TIPOC=\"C\")");
 | ||
|            else
 | ||
|              get_cursor(_cur3)->setfilter("(TIPOC=\"F\")");
 | ||
|          }
 | ||
|        }
 | ||
|        add_file(LF_SCADENZE);
 | ||
|        add_file(LF_CLIFO,LF_SCADENZE);
 | ||
|        break;
 | ||
|      case altri:
 | ||
|        if (_ordata)                            // Ordine primario per data
 | ||
|        {                                       // Controlla l'ordine secondario (Codice o descrizione)
 | ||
|          if (_ordcod)                          // Per codice ...
 | ||
|          {
 | ||
|             select_cursor(_cur4);
 | ||
|             get_cursor(_cur4)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali!
 | ||
|          }
 | ||
|          else
 | ||
|          {
 | ||
|             select_cursor(_cur41);            // Per descrizione.
 | ||
|             get_cursor(_cur41)->setfilter("(TIPOC=\"\")");
 | ||
|          }
 | ||
|        }
 | ||
|        else                                    // Ordine primario per codice o descrizione
 | ||
|        {
 | ||
|          if (_ordcod)                          // Codice...
 | ||
|          {
 | ||
|            select_cursor(_cur5);
 | ||
|            get_cursor(_cur5)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali!
 | ||
|          }
 | ||
|          else                                  // Descrizione
 | ||
|          {
 | ||
|            select_cursor(_cur6);
 | ||
|            get_cursor(_cur6)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali!
 | ||
|          }
 | ||
|        }
 | ||
|        add_file(LF_SCADENZE);
 | ||
|        add_file(LF_PCON,LF_SCADENZE);
 | ||
|        break;
 | ||
|      default:
 | ||
|       break;
 | ||
|     }
 | ||
|     
 | ||
| 		if (sel_datafatt)
 | ||
| 		{
 | ||
| 			TString filter("(BETWEEN(");
 | ||
| 
 | ||
| 			filter << LF_PARTITE << "->" << PART_DATADOC << ",\"" << _datai.string() << "\",\"" << _dataf.string() << "\"))";
 | ||
| 			add_filter_fatt(get_cursor(_cur1), filter);    
 | ||
| 			add_filter_fatt(get_cursor(_cur11), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur2), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur3), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur4), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur41), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur5), filter); 
 | ||
| 			add_filter_fatt(get_cursor(_cur6), filter);
 | ||
| 			add_filter_fatt(get_cursor(_cur7), filter);
 | ||
| 		}
 | ||
|     if (current_cursor()->is_sorted())  // Should always be true!
 | ||
|     {
 | ||
|       TSorted_cursor* sorcur = (TSorted_cursor*)current_cursor(); 
 | ||
|       TToken_string sortexpr = sorcur->get_order(); 
 | ||
| 
 | ||
|       const bool has_ban = sortexpr.starts_with(SCAD_CODABIPR);
 | ||
|       if (_group_ban != has_ban)
 | ||
|       {
 | ||
|         if (_group_ban)
 | ||
|           sortexpr.insert("CODABIPR|CODCABPR|");
 | ||
|         else
 | ||
|           sortexpr.ltrim(18);
 | ||
|         sorcur->change_order(sortexpr);  
 | ||
|       }
 | ||
|       _last_ban.cut(0);  // Azzera ultima banca stampata
 | ||
|     }
 | ||
|   }     
 | ||
| 
 | ||
|   if (_p) 
 | ||
|   {
 | ||
|     delete _p;     // Questo deve essere cancellato, altrimenti rimane in memoria,
 | ||
|     _p = NULL;     // provocando casini al prossimo "giro"
 | ||
|   }
 | ||
| 
 | ||
|   TAssoc_array& a =(TAssoc_array&) _uns_cache[0];
 | ||
|   TAssoc_array& b =(TAssoc_array&) _uns_cache[1];
 | ||
|   a.destroy(); b.destroy(); // Libera i TAssoc_array impiegati.
 | ||
|   
 | ||
|   return ok;
 | ||
| }                    
 | ||
| 
 | ||
| void TStampaScadenzario::print_header()
 | ||
| // Setta le righe dell'intestazione
 | ||
| {
 | ||
|   int soh = 1;    
 | ||
| 	const long firm = get_firm();
 | ||
|   const TRectype & ditta = cache().get(LF_NDITTE, firm);
 | ||
| 
 | ||
| 	reset_header ();
 | ||
|   TString s;
 | ||
|   s = ditta.get(NDT_RAGSOC);    
 | ||
|   TString data = _datas.string();
 | ||
|   TString datai = _datai.string();
 | ||
|   TString dataf = _dataf.string();
 | ||
| 
 | ||
|   switch (_tipost)
 | ||
|   {
 | ||
|    case fornitori:
 | ||
|    case clienti:    
 | ||
|    {                           
 | ||
|     TString rw(201);
 | ||
|     TString s1,s2;
 | ||
|     
 | ||
|     set_header (soh++, "Ditta : %ld %s@148gData@153g%s  @190gPag. @#",
 | ||
|                firm,  (const char *)s,  (const char *)data);
 | ||
| 
 | ||
|     if (_tipost==fornitori)   
 | ||
|     {  
 | ||
|      set_header(soh++,FR("@72g** SCADENZARIO FORNITORI **"));
 | ||
|      s1 = "Ns."; s2 = "Banca";
 | ||
|     }
 | ||
|     else                   
 | ||
|     {
 | ||
|      set_header(soh++,FR("@73g** SCADENZARIO CLIENTI **"));
 | ||
|      s1 =""; s2 = "";
 | ||
|     }
 | ||
|     set_header (soh++,FR("@64gPer il periodo dal %s al %s"),(const char*)datai,(const char*)dataf);
 | ||
| 		
 | ||
| 		if (_codag.not_empty())
 | ||
|     	set_header (soh++,FR("@bAgente: %s %s@r"),(const char*)_codag,(const char*)_m->get(F_CODAG_D));
 | ||
| 		if (_tipopag != 0)
 | ||
| 		{ 
 | ||
| 			TList_field& fld_tipopag = (TList_field&) _m->field(F_TIPOPAG);
 | ||
| 			TToken_string pagam(fld_tipopag.get_values());
 | ||
|     	set_header (soh++,FR("@bTipo pagamento: %d %s@r"),_tipopag, (const char*)pagam.get(_tipopag));
 | ||
|     }
 | ||
| 
 | ||
|     rw.fill('_');
 | ||
|     set_header(soh++, (const char *) rw);                          
 | ||
|     set_header(soh++,FR("@28gRif.@38gData@47gData@77gCd/Tp@91g%s"),(const char*)s1);
 | ||
|     set_header(soh++,FR("Codice@9gRagione sociale@28gpartita@38gscadenza@47gRegistr."
 | ||
|                         "@56gDescrizione@77gPag.@86gRata@91g%s@96gVal."
 | ||
|                         "@103gImp. in sca.@119gImp. pagati@135gRimesse dir.@151gRi.ba./Tratte@171gBonifici@190gAltri@197gBlc"), (const char*)s2);
 | ||
|     set_header(soh++,FR("@28gData e Nr doc. @46gProt. IVA"));
 | ||
|     set_header(soh++,(const char *)rw);
 | ||
|     break;
 | ||
|    }
 | ||
|    case altri:   // Piano dei conti
 | ||
|    {
 | ||
|     TString rw(201);
 | ||
|     set_header (soh++, FR("Ditta : %ld %s@152gData@157g%s  @190gPag. @#"),
 | ||
|                firm,  (const char *)s,  (const char *)data);
 | ||
|     set_header(soh++,FR("@79g** SCADENZARIO **"));
 | ||
|     set_header (soh++,FR("@66gPer il periodo dal %s al %s"),(const char*)datai,(const char*)dataf);
 | ||
| 
 | ||
| 		if (_codag.not_empty())
 | ||
|     	set_header (soh++,FR("@bAgente: %s %s@r"),(const char*)_codag,(const char*)_m->get(F_CODAG_D));
 | ||
| 		if (_tipopag != 0)
 | ||
| 		{ 
 | ||
| 			TList_field& fld_tipopag = (TList_field&) _m->field(F_TIPOPAG);
 | ||
| 			TToken_string pagam(fld_tipopag.get_values());
 | ||
|     	set_header (soh++,FR("@bTipo pagamento: %d %s@r"),_tipopag, (const char*)pagam.get(_tipopag));
 | ||
|     }
 | ||
|     
 | ||
|     rw.fill('_');
 | ||
|     set_header(soh++, (const char *) rw);                    
 | ||
|     set_header(soh++,FR("@33gRif.@43gData@53gData@82gCd/Tp"));
 | ||
|     set_header(soh++,FR("Gr. Co. So.@16gDescrizione@33gpartita@43gscadenza@53gRegistr."
 | ||
|                      "@61gDescrizione@82gPag.@89gRata@96gVal."
 | ||
|                      "@103gImp. in sca.@119gImp. pagati@135gRimesse dir.@151gRi.ba./Tratte@171gBonifici@190gAltri@197gBlc"));                 
 | ||
|     set_header(soh++,FR("@36gData e Nr doc. @54gProt. IVA"));
 | ||
|   
 | ||
|     set_header(soh++,(const char *)rw);
 | ||
|     break;
 | ||
|    }
 | ||
|    default:
 | ||
|     break;
 | ||
|   }
 | ||
|   set_header(soh,"");
 | ||
| }                          
 | ||
| 
 | ||
| void TStampaScadenzario::set_page_clifo(int nriga)
 | ||
| // Setta le righe per stampare le scadenze clienti/fornitori
 | ||
| {                
 | ||
| 	if (_group_ban)
 | ||
| 		print_intestazione_banca(nriga);
 | ||
|   set_row(nriga++,"");           
 | ||
|   set_row(nriga,"@b#6t@r",&_cur_codcf_s);
 | ||
|   set_row(nriga,"@b@9g#a@r",_ragsoc);
 | ||
|   set_row(nriga,"@28g#2t",&_annopart);
 | ||
|   set_row(nriga,"@30g/@7s",FLD(LF_SCADENZE,SCAD_NUMPART));
 | ||
|   set_row(nriga,"@38g@d",FLD(LF_SCADENZE,SCAD_DATASCAD));
 | ||
|   set_row(nriga,"@47g#t",&_datareg);
 | ||
|   set_row(nriga,"@56g#a",_descrizione);
 | ||
|   set_row(nriga,"@77g@4,rs/@1n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG));
 | ||
|   set_row(nriga,"@86g@4n",FLD(LF_SCADENZE,SCAD_NRATA));
 | ||
|   if (_tipost == fornitori)
 | ||
|     set_row(nriga,"@91g@5pn",FLD(LF_SCADENZE,SCAD_CODABIPR,"@@@@@"));
 | ||
|   set_row(nriga,"@96g#t", &_codval);
 | ||
|   set_row(nriga,"@100g#15t",&_imp_scad); 
 | ||
|   set_row(nriga,"@116g#15t",&_imp_pag);
 | ||
|   set_row(nriga,"@132g#15t",&_rimdir);    // rimesse dirette
 | ||
|   set_row(nriga,"@148g#15t",&_riba);      // Ri.ba. / tratte
 | ||
|   set_row(nriga,"@164g#15t",&_bonifico);  // Bonifico
 | ||
|   set_row(nriga,"@180g#15t",&_altri);     // Altri tipi di pagamento
 | ||
| 	set_row(nriga,"@198g@1s",FLD(LF_SCADENZE,SCAD_BLOCCATA));
 | ||
| 	nriga++;
 | ||
|   set_row(nriga,"@31g#t",&_datadoc);
 | ||
|   set_row(nriga,"@40g#t",&_numdoc);
 | ||
|   set_row(nriga,"@49g#-5t",&_protiva);
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::set_page_pcon(int nriga)
 | ||
| // Setta le righe per stampare le scadenze degli altri conti. 
 | ||
| {
 | ||
| 	if (_group_ban)
 | ||
| 		print_intestazione_banca(nriga);
 | ||
|   set_row(nriga++,"");
 | ||
|   set_row(nriga,"@b#3t@5g#3t@9g#6t@r",&_cur_gr_s,&_cur_co_s,&_cur_codcf_s);
 | ||
|   set_row(nriga,"@b@16g#a@r",_des_conto);
 | ||
|   set_row(nriga,"@33g#2t/@7s",&_annopart,FLD(LF_SCADENZE,SCAD_NUMPART));
 | ||
|   set_row(nriga,"@43g@d@53g#t",FLD(LF_SCADENZE,SCAD_DATASCAD),&_datareg);
 | ||
|   set_row(nriga,"@61g#a",_descrizione);
 | ||
|   set_row(nriga,"@82g@4,rs/@1n@89g@4n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG),
 | ||
|           FLD(LF_SCADENZE,SCAD_NRATA));
 | ||
|   set_row(nriga,"@96g#t", &_codval);
 | ||
|   set_row(nriga,"@100g#15t",&_imp_scad);
 | ||
|   set_row(nriga,"@116g#15t",&_imp_pag);
 | ||
|   set_row(nriga,"@132g#15t",&_rimdir);    // rimesse dirette
 | ||
|   set_row(nriga,"@148g#15t",&_riba);      // Ri.ba. / tratte
 | ||
|   set_row(nriga,"@164g#15t",&_bonifico);  // Bonifico
 | ||
|   set_row(nriga,"@180g#15t",&_altri);     // Altri tipi di pagamento
 | ||
| 	set_row(nriga,"@198g@1s",FLD(LF_SCADENZE,SCAD_BLOCCATA));
 | ||
| 	nriga++;
 | ||
|   set_row(nriga,"@36g#t@45g#t@54g#-5t",&_datadoc,&_numdoc,&_protiva);
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::set_page(int file, int counter)
 | ||
| { 
 | ||
|   print_header();
 | ||
|   
 | ||
|   switch (_tipost)
 | ||
|   {
 | ||
|    case fornitori:
 | ||
|    case clienti:
 | ||
|      if (file == LF_CLIFO)
 | ||
|        set_page_clifo(1);
 | ||
|      break;
 | ||
|    case altri:
 | ||
|      if (file == LF_PCON)
 | ||
|        set_page_pcon(1); 
 | ||
|      break;
 | ||
|    default:
 | ||
|      break;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_rows_riepilogo(int& nriga, bool type, TAssoc_array& tot)
 | ||
| {
 | ||
|   TString_array as;
 | ||
|   TAssoc_array& t = (type ? _tp : _tm);
 | ||
|   const int items = t.items();
 | ||
|   
 | ||
|   t.get_keys(as);
 | ||
|   as.sort();
 | ||
|   for (int i = 0; i < items; i++)
 | ||
|   {
 | ||
|     const TString& k = as.row(i);     
 | ||
|     real& v = (real&)t[k];
 | ||
|     if (v.is_zero())
 | ||
|       continue;
 | ||
| 
 | ||
|     TString16 val = k.right(3);
 | ||
|     const int tipo = k[0]-'0';
 | ||
|     const char ult = k[1];
 | ||
|     
 | ||
|     TString80 ult_class;
 | ||
|     if (ult > ' ')
 | ||
|     {
 | ||
|       const char cod[3] = { tipo+'0', ult, '\0' };
 | ||
|       ult_class = cache().get("%CLR", cod).get("S0");
 | ||
|       ult_class.cut(27);
 | ||
|     }
 | ||
| 
 | ||
|     const bool stampa_in_valuta = _stvaluta && !val.blank();
 | ||
|     TString80 value;
 | ||
|     print_real(value, v, stampa_in_valuta ? val : "_FIRM");
 | ||
|     set_row(nriga++,"@0g! %s@25g! %s@55g! %s@61g!@64g%18s@82g!",
 | ||
|             tipi_tab(tipo), (const char*)ult_class, (const char*)val, (const char*)value);
 | ||
|     
 | ||
|     // Cerca la valuta "val" nell'assoc array dei totali per il prospetto
 | ||
|     if (tot.is_key(val))
 | ||
|     {
 | ||
|       real& tv = (real&) tot[val];
 | ||
|       tv += v;
 | ||
|       tot.add(val,tv,true);
 | ||
|     }
 | ||
|     else // Se non esiste aggiunge il valore
 | ||
|       tot.add(val,v);
 | ||
|   }  
 | ||
| }                     
 | ||
| 
 | ||
| void TStampaScadenzario::print_riepilogo(int &nriga, bool type)
 | ||
| // Setta le righe di stampa per lo schema riepilogativo con ordinamento primario per data
 | ||
| // Con type == 1 stampa il riepilogo del periodo; viceversa quello del mese.
 | ||
| {                 
 | ||
|   TString s(83);       
 | ||
|   TAssoc_array totali;  // Assoc array per i totali distinti per valuta
 | ||
|   TString_array as;
 | ||
|   
 | ||
|   s.fill('-', 83);   
 | ||
|   nriga++;                                
 | ||
|   set_row(nriga++,"%s",(const char *)s);
 | ||
|   if (!type)
 | ||
|   {               
 | ||
|     if (_ordata)                     
 | ||
|     {
 | ||
| 			if (_striepilogo == 2)
 | ||
| 	      set_row(nriga++,"@0g! %s@82g!", itom(_cur_data.month()));
 | ||
| 			else
 | ||
| 	      set_row(nriga++,"@0g! %s@82g!", _cur_data.string(brief));
 | ||
|       set_row(nriga++,"%s",(const char*)s);
 | ||
|     }    
 | ||
|   } 
 | ||
|   else
 | ||
|   {
 | ||
|     set_row(nriga,FR("!@5gTotali dal %s al "),_datai.string(brief));
 | ||
|     set_row(nriga++,"%s@82g!",_dataf.string(brief));
 | ||
|     set_row(nriga++,"%s",(const char *)s);
 | ||
|   }
 | ||
|   print_rows_riepilogo(nriga, type, totali);
 | ||
|   totali.get_keys(as);
 | ||
|   as.sort();
 | ||
|   const int items = totali.items();
 | ||
| 
 | ||
|   TString val, value;
 | ||
|   for (int i = 0; i < items; i++)
 | ||
|   {
 | ||
|     val = as.row(i);        
 | ||
|     const bool stampa_in_valuta = _stvaluta && is_true_value(val);
 | ||
|     const real& tot = (real&)totali[val];
 | ||
| 
 | ||
|     print_real(value, tot, stampa_in_valuta ? val : EMPTY_STRING);
 | ||
| 
 | ||
|     if (tot != ZERO)
 | ||
|     {
 | ||
|       if (i == 0)
 | ||
|         set_row(nriga++,"%s",(const char *)s);    // Se c'e' almeno un totale != 0 allora stampa il separe'
 | ||
|       set_row(nriga++,"@55g! %s@61g!@64g%18s@82g!",(const char*) val, (const char*) value);
 | ||
|     }
 | ||
|     else 
 | ||
|     {
 | ||
|       if (!is_true_value(val)) 
 | ||
|         val = TCurrency::get_firm_val();
 | ||
|       set_row(nriga++,FR("! Partite pareggiate in %s. @82g!"),(const char*) val);
 | ||
|     }
 | ||
|   }
 | ||
|   set_row(nriga++,"%s",(const char *)s);   
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_rows_totali(int &nriga, tipo_pe p)
 | ||
| {                                                   
 | ||
|   int index = 0;  // Default of DAILY
 | ||
|   switch (p)
 | ||
|   {
 | ||
|     case monthly:                
 | ||
|     case single:
 | ||
|       index = 1;
 | ||
|       break;
 | ||
|     case period:
 | ||
|       index = 2;
 | ||
|       break;
 | ||
|     case bank:
 | ||
|     	index = 3;
 | ||
|     break;  
 | ||
|     default:
 | ||
|       break;
 | ||
|   }
 | ||
|   TAssoc_array& xassoc = (TAssoc_array&) _tl[index];
 | ||
|   TString_array as;
 | ||
|   const int items = xassoc.items();
 | ||
|   xassoc.get_keys(as);
 | ||
|   as.sort();
 | ||
| 
 | ||
|   TString k, value;
 | ||
|   for (int i = 0; i < items; i++)
 | ||
|   {
 | ||
|     k = as.row(i); // Chiave di ordinamento(valuta)
 | ||
|     const bool stampa_in_valuta = _stvaluta && is_true_value(k);
 | ||
|     _LinearTotal& v = (_LinearTotal&)xassoc[k];
 | ||
| 
 | ||
|     if (is_true_value(k))
 | ||
|       set_row(nriga,"@96g%3s",(const char*)k);
 | ||
| 
 | ||
|     if (!stampa_in_valuta)
 | ||
|       k.cut(0);
 | ||
| 
 | ||
|     print_real(value, v._is, k);
 | ||
| 
 | ||
|     if (v._is != ZERO)
 | ||
|       set_row(nriga,"@100g%15s",(const char*) value);
 | ||
| 
 | ||
|     print_real(value, v._ip, k);
 | ||
| 
 | ||
|     if (v._ip != ZERO)
 | ||
|       set_row(nriga,"@116g%15s",(const char*) value);
 | ||
| 
 | ||
|     print_real(value, v._rd, k);
 | ||
| 
 | ||
|     if (v._rd != ZERO)
 | ||
|       set_row(nriga,"@132g%15s",(const char*) value);
 | ||
| 
 | ||
|     print_real(value, v._ri, k);
 | ||
| 
 | ||
|     if (v._ri != ZERO)
 | ||
|       set_row(nriga,"@148g%15s",(const char*) value);
 | ||
| 
 | ||
|     print_real(value, v._bo, k);
 | ||
| 
 | ||
|     if (v._bo != ZERO)
 | ||
|       set_row(nriga,"@164g%15s",(const char*) value);
 | ||
| 
 | ||
|     print_real(value, v._al, k);
 | ||
| 
 | ||
|     if (v._al != ZERO)
 | ||
|       set_row(nriga,"@180g%15s",(const char*) value);
 | ||
| 
 | ||
|     set_row(++nriga,"");                           
 | ||
|   }  
 | ||
|   set_row(++nriga,"");                           
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_totali(int &nriga, bool month_changed, bool ended)
 | ||
| // Setta le righe per stampare i totali (giorno e mese) delle scadenze clienti/fornitori
 | ||
| // Ordinamento primario per data!
 | ||
| {                                    
 | ||
|   set_row(nriga,FR("@36g** TOTALI DEL @51g%s"),_cur_data.string(brief));
 | ||
|   print_rows_totali(nriga, daily);
 | ||
|   if (month_changed)
 | ||
|   {
 | ||
|     set_row(nriga,FR("@36g** TOTALI DI @51g%s"),itom(_cur_data.month()));
 | ||
|     print_rows_totali(nriga, monthly);
 | ||
|     if (_striepilogo > 0) 
 | ||
|       print_riepilogo(nriga,false);                           
 | ||
|   }  
 | ||
| 	else
 | ||
|     if (_striepilogo == 1) 
 | ||
|       print_riepilogo(nriga,false);                           
 | ||
|   if (ended)
 | ||
|   {
 | ||
|   	if (_group_ban)
 | ||
|   	{
 | ||
|   		print_totali_bank(nriga);
 | ||
| 	    set_row(nriga++,"");
 | ||
|   	}	
 | ||
|     set_row(nriga++,"");
 | ||
|     set_row(nriga,FR("@36g** TOTALI PERIODO"));
 | ||
|     print_rows_totali(nriga, period);
 | ||
|     if (_striepilogo > 0)
 | ||
| 			print_riepilogo(nriga,true);
 | ||
|     set_row(nriga++,"");set_row(nriga++,"");
 | ||
|     set_row(nriga++,"");set_row(nriga++,"");
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_totali_c(int &nriga, bool ended)
 | ||
| // Setta le righe per stampare i totali delle scadenze clienti/fornitori/conti
 | ||
| // Ordinamento primario per codice o ragione sociale!
 | ||
| {
 | ||
| 	// se non si vogliono i totali intermedi per cli/for/conto tanto vale uscire da questo posto!
 | ||
| 	if (_notot)
 | ||
| 		return;
 | ||
| 	//In caso contrario continua l'avventura...
 | ||
|   if (_tipost==clienti)									// per cliente
 | ||
|     set_row(nriga,FR("@70g** TOTALE CLIENTE"));
 | ||
|   else
 | ||
|   if (_tipost ==fornitori)							// per fornitore
 | ||
|     set_row(nriga,FR("@70g** TOTALE FORNITORE")); 
 | ||
|   else                                   // per conto
 | ||
|     set_row(nriga,FR("@70g** TOTALE CONTO"));
 | ||
| 
 | ||
|   print_rows_totali(nriga, single);
 | ||
|   if (_striepilogo > 0 )
 | ||
| 		print_riepilogo(nriga,false);                           
 | ||
|   if (ended)
 | ||
|   {
 | ||
|   	if (_group_ban)
 | ||
|   	{
 | ||
|   		print_totali_bank(nriga);
 | ||
| 	    set_row(nriga++,"");set_row(nriga++,"");
 | ||
|   	}	
 | ||
|     set_row(nriga,FR("@70g** TOTALE GENERALE"));
 | ||
|     print_rows_totali(nriga, period);
 | ||
|     if (_striepilogo > 0 )
 | ||
| 			print_riepilogo(nriga,true);
 | ||
|     set_row(nriga++,"");set_row(nriga++,"");
 | ||
|     set_row(nriga++,"");set_row(nriga++,"");
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_totali_bank(int &nriga)
 | ||
| // Setta le righe per stampare i totali della banca
 | ||
| // Ordinamento primario per codice o ragione sociale!
 | ||
| {
 | ||
|   if (!real::is_null(_last_ban))
 | ||
|   {
 | ||
|     if (_ordata) // Errore 158 - Non stampa il totale del giorno se cambia solo la banca e non il giorno
 | ||
|     {
 | ||
|       const TRectype &rc = current_cursor()->curr(LF_SCADENZE);
 | ||
|       const TDate datascad = rc.get(SCAD_DATASCAD);
 | ||
|       if (datascad == _cur_data)           // Non e' cambiato il giorno
 | ||
|       {
 | ||
|         nriga++;                           // Salto una riga
 | ||
|         print_totali(nriga, true, false);  // Stampa totali del giorno e del mese
 | ||
|         ((TAssoc_array&)_tl[0]).destroy(); // Azzera totali del giorno
 | ||
|         ((TAssoc_array&)_tl[1]).destroy(); // Azzera totali del mese
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     nriga++;
 | ||
|     if (_ordata)
 | ||
|       set_row(nriga,FR("@36g** TOTALI BANCA"));
 | ||
|     else
 | ||
|   	  set_row(nriga,FR("@70g** TOTALE BANCA"));
 | ||
|     print_rows_totali(nriga, bank);
 | ||
|     _totbank_printed = true;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TStampaScadenzario::print_intestazione_banca(int &nriga)
 | ||
| { 
 | ||
|   const TRectype &rc = current_cursor()->curr(LF_SCADENZE);
 | ||
|   const TString8 abi = rc.get(SCAD_CODABIPR);
 | ||
|   const TString8 cab = rc.get(SCAD_CODCABPR);
 | ||
|   TString16 curr_ban; curr_ban << abi << cab;
 | ||
|   
 | ||
|   bool print_bank = false;
 | ||
|   if (curr_ban != _last_ban)
 | ||
|   {                      
 | ||
|     _last_ban = curr_ban;
 | ||
|     if (abi != "00000")
 | ||
|     {
 | ||
|       _desc_ban.cut(0) << abi << ' ' << cab;
 | ||
|       _desc_ban << ' ' << cache().get("%BAN", abi, "S0");
 | ||
|       if (cab > 0)
 | ||
|         _desc_ban << " - " << cache().get("%BAN", _last_ban, "S0");
 | ||
|     }
 | ||
|     else
 | ||
|       _desc_ban = FR("NON INDICATA");
 | ||
|     _last_bank_rec = current_cursor()->pos();
 | ||
|     print_bank = true;
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     print_bank = current_cursor()->pos() == _last_bank_rec;
 | ||
|   }
 | ||
|   
 | ||
|   if (print_bank)
 | ||
|   {                                 
 | ||
|   	// stampa totali banca precedente
 | ||
|   	if (_last_bank_rec != 0)
 | ||
|   		print_totali_bank(nriga);
 | ||
|   	
 | ||
|     set_row(nriga++, "");
 | ||
| 	  set_row(nriga++, FR("@bBANCA DI PRESENTAZIONE %s@r"), (const char*)_desc_ban);
 | ||
|     set_row(nriga++, "");
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| TStampaScadenzario::TStampaScadenzario()
 | ||
| {
 | ||
|   _rel1=_rel2=_rel3=NULL;
 | ||
|   _p = NULL;
 | ||
| }
 | ||
| 
 | ||
| int sc2200(int argc, char** argv)
 | ||
| {
 | ||
|   TStampaScadenzario app;
 | ||
|   app.run(argc, argv, FR("Stampa Scadenzario"));    
 | ||
|   return 0;
 | ||
| }
 |