1394 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1394 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <utility.h>
 | 
						|
#include "pagament.h"
 | 
						|
 | 
						|
#include <mov.h>
 | 
						|
#include <partite.h>
 | 
						|
#include <scadenze.h>
 | 
						|
#include <pagsca.h>
 | 
						|
 | 
						|
int TPagamento::_rata_ifield(int n, int f) const
 | 
						|
{                                     
 | 
						|
  TToken_string& t = (TToken_string&)_rate[n];
 | 
						|
  return t.get_int(f);
 | 
						|
}                            
 | 
						|
 | 
						|
long TPagamento::_rata_lfield(int n, int f) const
 | 
						|
{                                     
 | 
						|
  TToken_string& t = (TToken_string&)_rate[n];
 | 
						|
  return t.get_long(f);
 | 
						|
}                            
 | 
						|
 | 
						|
real TPagamento::_rata_rfield(int n, int f) const
 | 
						|
{                                     
 | 
						|
  TToken_string& t = (TToken_string&)_rate[n];
 | 
						|
  return real(t.get(f));
 | 
						|
}                            
 | 
						|
 | 
						|
TDate TPagamento::_rata_dfield(int n, int f) const
 | 
						|
{                                     
 | 
						|
  TToken_string& t = (TToken_string&)_rate[n];
 | 
						|
  return TDate(t.get(f));
 | 
						|
}                                 
 | 
						|
 | 
						|
const char* TPagamento::_rata_sfield(int n, int f) const
 | 
						|
{                                     
 | 
						|
  static char kak[16];
 | 
						|
  TToken_string& t = (TToken_string&)_rate[n];
 | 
						|
  const char* k = t.get(f);
 | 
						|
  if (k != NULL) 
 | 
						|
    strncpy(kak, k, 16); 
 | 
						|
  else           
 | 
						|
    kak[0] = '\0';
 | 
						|
  return kak;
 | 
						|
}                                 
 | 
						|
 | 
						|
void TPagamento::set_intervallo_rate(int in)
 | 
						|
{
 | 
						|
  _dirty = TRUE;                    
 | 
						|
  _int_rate = in;
 | 
						|
  if (_mcomm  && (in % 30) != 0)
 | 
						|
    _mcomm = FALSE;
 | 
						|
  for (int i = 0; i < n_rate(); i++)
 | 
						|
  {       
 | 
						|
    TToken_string& ts = rata(i);
 | 
						|
    ts.add(i == 0 ? (scad_rata(0) == 0 ? 0 : in) : in, 0);    
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_mese_commerciale(bool v, int& sscad)
 | 
						|
{
 | 
						|
  _dirty = FALSE;
 | 
						|
  if (_mcomm == v) return;  
 | 
						|
  if (sscad < 0) sscad = 30;
 | 
						|
  
 | 
						|
  if ((sscad % 30) != 0) sscad = 30 * ((sscad/30)+1);
 | 
						|
  set_intervallo_rate(sscad);
 | 
						|
  
 | 
						|
  _mcomm = v; 
 | 
						|
}        
 | 
						|
 | 
						|
void TPagamento::set_rate_differenziate(int v)
 | 
						|
{                           
 | 
						|
  _dirty = FALSE;
 | 
						|
  if (_rdiff ^ v == 2) return; 
 | 
						|
  
 | 
						|
  if (v == 2 && (100 % n_rate()) == 0)
 | 
						|
  {
 | 
						|
    int p = 100 / n_rate();
 | 
						|
    for (int i = _tpr < 4 ? 0 : 1; i < n_rate(); i++)
 | 
						|
    {
 | 
						|
      TToken_string& tt = rata(i);
 | 
						|
      tt.add(p,1);
 | 
						|
    }
 | 
						|
  }                           
 | 
						|
  _rdiff = (v != 2);
 | 
						|
  _dirty = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_tipo_prima_rata(int v, int sscad)
 | 
						|
{                           
 | 
						|
  _dirty = FALSE;
 | 
						|
  if (_tpr == v) return;
 | 
						|
  
 | 
						|
  if (v < 4  && _tpr > 3)
 | 
						|
  {
 | 
						|
    for (int i = n_rate() - 1; i > 0; i--)
 | 
						|
    {
 | 
						|
      TToken_string& tt = rata(i);
 | 
						|
      tt.add(scad_rata(i-1),0);
 | 
						|
      tt.add(tipo_rata(i-1),2);
 | 
						|
      tt.add(ulc_rata(i-1),5);
 | 
						|
    }
 | 
						|
    _rate.destroy(0);
 | 
						|
    _rate.pack(); 
 | 
						|
  }
 | 
						|
  else 
 | 
						|
    if ( _tpr < 4 && v > 3)                    
 | 
						|
    {   
 | 
						|
      TToken_string* ttn = new TToken_string(32);
 | 
						|
      ttn->add(0,  0);
 | 
						|
      ttn->add(0,  1);
 | 
						|
      ttn->add(1,  2);
 | 
						|
      ttn->add("", 3);
 | 
						|
      ttn->add("", 4);
 | 
						|
      ttn->add("", 5);
 | 
						|
      _rate.insert(ttn,0);
 | 
						|
      for (int i = 0; i < (n_rate()-1); i++)
 | 
						|
      {
 | 
						|
        TToken_string& tt = rata(i);   
 | 
						|
        tt.add(scad_rata(i+1),0);
 | 
						|
        tt.add(tipo_rata(i+1),2);
 | 
						|
        tt.add(ulc_rata(i+1), 5);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  _tpr = v;    
 | 
						|
  _dirty = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_numero_rate(int n, int sscad, int rdiff)
 | 
						|
{                         
 | 
						|
  _dirty = FALSE;
 | 
						|
  if (n == 0 || n == n_rate()) return; 
 | 
						|
  
 | 
						|
  real p = real(100) / real(n); 
 | 
						|
  p.round(2);
 | 
						|
  int nr = n_rate();
 | 
						|
  int first = _tpr < 4 ? 0 : 1;
 | 
						|
  real sum = 0.0;
 | 
						|
  int i = 0;
 | 
						|
 | 
						|
  if (_inited || (!_inited && rdiff == 1))   // se e' inited rdiff e' 2 per forza
 | 
						|
  { 
 | 
						|
    real tot = _inited ? (_tpr < 4 ? _firstr  : _secndr) : real(100.0);
 | 
						|
    if (n == 1)
 | 
						|
    {
 | 
						|
      if (_inited) set_imprata(first, tot); 
 | 
						|
      set_percrata(first, real(100.0));
 | 
						|
      if (_inited && _tpr > 0 && _tpr < 4)                 
 | 
						|
        set_imprata(first, tpay_rata(first) + _secndr);
 | 
						|
      i = first + 1; // per rimozione successiva
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {   
 | 
						|
 | 
						|
      if (nr == first + 1)
 | 
						|
      {               
 | 
						|
        // suddividi equamente e riaggiusta la percentuale di conseguenza  
 | 
						|
        real div  = tot / real(n);
 | 
						|
        real perc = real(100.0)*(div/tot);  
 | 
						|
        for (i = first; i < n; i++)
 | 
						|
        {
 | 
						|
          if (i > 0) 
 | 
						|
            add_rata(perc, (sscad == -1 ? scad_rata(0) : sscad), tipo_rata(0));
 | 
						|
          if (_inited) set_imprata (i, div); 
 | 
						|
          set_percrata(i, perc);
 | 
						|
        }
 | 
						|
        if (_inited && _tpr > 0 && _tpr < 4)                 
 | 
						|
          set_imprata(0, tpay_rata(0) + _secndr);
 | 
						|
      }
 | 
						|
      else if (nr > first + 1)
 | 
						|
      {
 | 
						|
        // dalla prima nota e' abilitato solo se rdiff == 2
 | 
						|
        // e' selezionato UGUALI: devo: lasciare la prima
 | 
						|
        // rata com'e' (a meno che non ce ne sia una sola) e 
 | 
						|
        // suddividere il resto dell'importo tra le altre
 | 
						|
        real rfirst = _inited ? tpay_rata(first) : perc_rata(first);
 | 
						|
        if (_inited && _tpr > 0 && _tpr < 4) rfirst -= _secndr;  
 | 
						|
        
 | 
						|
        real rest = tot - rfirst;
 | 
						|
        const real div = rest / real(n - 1);
 | 
						|
        real perc = real(100.0)*(div/tot);
 | 
						|
 | 
						|
        for (i = first+1; i < n; i++)
 | 
						|
        {
 | 
						|
          if (i >= nr) 
 | 
						|
            add_rata(perc, (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad),
 | 
						|
                     tipo_rata(nr-1));
 | 
						|
          if (_inited) set_imprata (i, div); 
 | 
						|
          set_percrata(i, perc);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } 
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    for (i = first; sum < real(100.0); i++)
 | 
						|
    {
 | 
						|
      if ((real(100.0) - sum) < p) 
 | 
						|
        p = real(100.0) - sum;  
 | 
						|
        
 | 
						|
      sum += p;           
 | 
						|
      
 | 
						|
      // if necessary add remainder on first one
 | 
						|
      if ((real(100.0) - sum) /* still */ < p)
 | 
						|
      {      
 | 
						|
        real prc = perc_rata(first);
 | 
						|
        prc += real(100.0) - sum; 
 | 
						|
        TToken_string& rt = rata(first);
 | 
						|
        rt.add(prc.string(),1), 
 | 
						|
        sum = 100;  
 | 
						|
      }
 | 
						|
      
 | 
						|
      set_rata(i, real(p), 
 | 
						|
         i == 0 ? (i < nr ? scad_rata(0) : 0):
 | 
						|
         (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad),
 | 
						|
         (i < nr ? tipo_rata(i) : tipo_rata(nr-1)));
 | 
						|
     } 
 | 
						|
  }         
 | 
						|
  // erase remaining  
 | 
						|
  for (; i < nr; i++) 
 | 
						|
    _rate.destroy(i);
 | 
						|
  _rate.pack();
 | 
						|
  
 | 
						|
  _dirty = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_cambio(const real& cambio)
 | 
						|
{
 | 
						|
  if (cambio.sign() <= 0)
 | 
						|
    _cambio = 1.0;
 | 
						|
  else
 | 
						|
    _cambio = cambio;
 | 
						|
  set_round(_cambio == 1.0 ? 0 : 2);
 | 
						|
  
 | 
						|
  const bool in_valuta = _cambio != 1.0;
 | 
						|
  real lit;
 | 
						|
  for (int i = _rate.items()-1; i >= 0; i--)
 | 
						|
  {   
 | 
						|
    TToken_string& row = (TToken_string&)_rate[i];
 | 
						|
    if (in_valuta)
 | 
						|
    {
 | 
						|
      lit = tpay_rata(i) * _cambio;
 | 
						|
      row.add(lit.string(), 7);
 | 
						|
    }  
 | 
						|
    else
 | 
						|
      row.add("", 7);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPagamento::next_scad(TDate& d, int scad, bool mcomm, int rata)
 | 
						|
{
 | 
						|
  if (mcomm)
 | 
						|
    {
 | 
						|
      int nm   = scad / 30;
 | 
						|
      int ny   = nm   / 12;
 | 
						|
      nm  %= 12;
 | 
						|
      
 | 
						|
      int newm = d.month() + nm;
 | 
						|
      if (newm > 12) { newm -= 12; ny++; }
 | 
						|
      
 | 
						|
      bool last = d.is_end_month() && inizio_scadenza() == 'M';
 | 
						|
      
 | 
						|
      int dy = d.day();
 | 
						|
      
 | 
						|
      // la palla del febbraio & c.                                    
 | 
						|
      if (rata > 1)
 | 
						|
        {
 | 
						|
        TDate oldd(data_rata(rata-2));
 | 
						|
        if (oldd.day() > dy) dy = oldd.day();
 | 
						|
        } 
 | 
						|
      
 | 
						|
      d.set_day(1);  // il giorno 1 ce l'hanno tutti
 | 
						|
      d.set_month(newm);
 | 
						|
      d.set_year(d.year()+ny);
 | 
						|
      
 | 
						|
      d.set_end_month();  
 | 
						|
      if (!last && dy < d.day()) 
 | 
						|
      d.set_day(dy);
 | 
						|
    }
 | 
						|
    else 
 | 
						|
    {
 | 
						|
    d += scad;
 | 
						|
    }    
 | 
						|
    
 | 
						|
    // riaggiusta se ci sono scadenze fissate
 | 
						|
    if (_fixd[0] != 0 || _fixd[1] != 0 || _fixd[2] != 0)
 | 
						|
    {
 | 
						|
      for (int i = 0; i < 3; i++)
 | 
						|
      {
 | 
						|
        if (_fixd[i] > d.day())
 | 
						|
        { 
 | 
						|
          if (d.last_day(d.month(), d.year()) <= _fixd[i]) 
 | 
						|
            d.set_day(_fixd[i]);  
 | 
						|
          else d.set_end_month();
 | 
						|
          break;
 | 
						|
        } 
 | 
						|
      } 
 | 
						|
      
 | 
						|
      if (i == 3)
 | 
						|
      {
 | 
						|
        if (_fixd[0] > 0 && _fixd[0] < d.day())
 | 
						|
        {
 | 
						|
          d.set_day(_fixd[0]);  
 | 
						|
          d.set_month(d.month() == 12 ? 1 : d.month() + 1);  
 | 
						|
        }
 | 
						|
      }
 | 
						|
      
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPagamento::set_default_type(int type, bool change_existing)
 | 
						|
{                                                                     
 | 
						|
   _def_tpr = type;
 | 
						|
   if (change_existing)
 | 
						|
   {
 | 
						|
      for (int i = 0; i < n_rate(); i++)
 | 
						|
      {
 | 
						|
        TToken_string& tt = rata(i);
 | 
						|
        tt.add(type, 2);
 | 
						|
      }               
 | 
						|
      _dirty = TRUE;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_default_ulc(const char* ulc, bool change_existing)
 | 
						|
{    
 | 
						|
   _def_ulc = ulc;
 | 
						|
   if (change_existing)
 | 
						|
   {
 | 
						|
      for (int i = 0; i < n_rate(); i++)
 | 
						|
      {
 | 
						|
        TToken_string& tt = rata(i);
 | 
						|
        tt.add(ulc, 5);       
 | 
						|
      }     
 | 
						|
      _dirty = TRUE;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::remove_rata(int i)
 | 
						|
{                         
 | 
						|
  // non fa nessun ricalcolo, si limita ad impacchettare se 
 | 
						|
  // necessario
 | 
						|
  _rate.destroy(i);
 | 
						|
  _rate.pack();
 | 
						|
  _dirty = TRUE;
 | 
						|
}             
 | 
						|
 | 
						|
TToken_string& TPagamento::add_rata(real perc, int day, int type, const char* ulc)
 | 
						|
{
 | 
						|
  TToken_string* tt = new TToken_string(64);
 | 
						|
  
 | 
						|
  tt->add(day);                // scadenza
 | 
						|
  tt->add(perc.string());      // percentuale
 | 
						|
  tt->add(type);               // tipo
 | 
						|
  tt->add("");                 // data
 | 
						|
  tt->add("");                 // importo
 | 
						|
  tt->add(ulc);                // ulc
 | 
						|
  
 | 
						|
  _rate.add(tt);             
 | 
						|
  _dirty = TRUE;
 | 
						|
  return *tt;
 | 
						|
}
 | 
						|
 | 
						|
TToken_string& TPagamento::set_rata (int index, real perc, int day, int type,
 | 
						|
            const char* ulc, const char* imp, const char* data)
 | 
						|
{                                   
 | 
						|
  TToken_string* tt = (TToken_string*)_rate.objptr(index);
 | 
						|
  const bool nwr = (tt == NULL);
 | 
						|
  if (nwr) tt = new TToken_string(64); 
 | 
						|
  
 | 
						|
  tt->add(day,0);                // scadenza
 | 
						|
  tt->add(perc.string(),1);      // percentuale
 | 
						|
  tt->add(type,2);               // tipo 
 | 
						|
  tt->add(data == NULL ? "" : data, 3);
 | 
						|
  tt->add(imp  == NULL ? "" : imp,  4);
 | 
						|
  tt->add(ulc  == NULL ? "" : ulc,  5);
 | 
						|
  if (imp && *imp > ' ' && _cambio != 1.0)
 | 
						|
  {
 | 
						|
    real implit(imp);
 | 
						|
    implit *= _cambio;
 | 
						|
    implit.round();
 | 
						|
    tt->add(implit.string(), 7);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (!nwr)
 | 
						|
  {
 | 
						|
    if (index > _rate.items()) 
 | 
						|
    {   
 | 
						|
      error_box("Rate non contigue");
 | 
						|
      delete tt;
 | 
						|
    }
 | 
						|
  } 
 | 
						|
  else 
 | 
						|
  {
 | 
						|
    _rate.add(tt,index);   
 | 
						|
    _dirty = TRUE;
 | 
						|
  }
 | 
						|
  return *tt;
 | 
						|
}                                
 | 
						|
 | 
						|
void TPagamento::set_imprata(int i, const real& r)
 | 
						|
{
 | 
						|
  TToken_string& tt = (TToken_string&)_rate[i];  
 | 
						|
  TDate d = _inizio; 
 | 
						|
  
 | 
						|
  for (int n = 0; n <= i; n++)
 | 
						|
    next_scad(d, scad_rata(n), _mcomm, n); 
 | 
						|
  
 | 
						|
  tt.add((const char*)d, 3);
 | 
						|
  tt.add(r.string(), 4);
 | 
						|
  if (_cambio != 1.0)
 | 
						|
  {
 | 
						|
    const real lit = r * _cambio;
 | 
						|
    tt.add(lit.string(), 7);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    tt.add("", 7);
 | 
						|
}
 | 
						|
 | 
						|
void TPagamento::set_percrata(int i, real r)
 | 
						|
{
 | 
						|
  TToken_string& tt = (TToken_string&)_rate[i];  
 | 
						|
  TDate d = _inizio; 
 | 
						|
  tt.add(r.string(), 1);
 | 
						|
}
 | 
						|
 | 
						|
                                        
 | 
						|
TToken_string& TPagamento::set_rata(int index, const real& howmuch, const real& quanto,
 | 
						|
  const TDate& date, int type,const char* ulc, bool pagato)
 | 
						|
{
 | 
						|
  // calcola percentuali e scadenze a partire dagli importi 
 | 
						|
  TToken_string* tt = (TToken_string*)_rate.objptr(index);
 | 
						|
  int first    = _tpr < 4 ? 0 : 1;        
 | 
						|
  
 | 
						|
  const bool nwr = (tt == NULL);  // nuova rata
 | 
						|
  
 | 
						|
  if (nwr) tt = new TToken_string(64); 
 | 
						|
 | 
						|
  const TDate oldd = index > 0 ? data_rata(index -1) : _inizio;
 | 
						|
  const long day = date - oldd; 
 | 
						|
  const real toshare(_tpr < 4 ? _firstr : _secndr);
 | 
						|
  
 | 
						|
  real hm = howmuch;
 | 
						|
  if (index == first && _tpr > 0 && _tpr < 4) 
 | 
						|
    hm -= _secndr;
 | 
						|
      
 | 
						|
  real perc = (_tpr > 3 && index == 0) ? ZERO : hm/toshare; 
 | 
						|
  perc *= real(100.0);
 | 
						|
  perc.round(2);
 | 
						|
  
 | 
						|
  tt->cut(0);
 | 
						|
  tt->add(day);                // 0 - scadenza
 | 
						|
  tt->add(perc.string());      // 1 - percentuale
 | 
						|
  tt->add(type);               // 2 - tipo 
 | 
						|
  tt->add(date.string());      // 3 - data
 | 
						|
  tt->add(howmuch.string());   // 4 - importo
 | 
						|
  tt->add(ulc);                // 5 - ulc(era?)
 | 
						|
  tt->add(pagato ? "X" : " "); // 6 - pagata
 | 
						|
  tt->add(quanto.string());    // 7 - Importo in lire
 | 
						|
  if (!nwr)
 | 
						|
  {
 | 
						|
    if (index > _rate.items()) 
 | 
						|
    {   
 | 
						|
      error_box("Rate non contigue");
 | 
						|
      delete tt;
 | 
						|
    }
 | 
						|
  } 
 | 
						|
  else 
 | 
						|
  {
 | 
						|
    _rate.add(tt, index);   
 | 
						|
    _dirty = TRUE;
 | 
						|
  }
 | 
						|
  return *tt;
 | 
						|
}
 | 
						|
                                        
 | 
						|
                                        
 | 
						|
 | 
						|
word TPagamento::validate() const
 | 
						|
{
 | 
						|
  word res = 0x0000; 
 | 
						|
  real r(0.0);
 | 
						|
  
 | 
						|
  int first    = _tpr < 4 ? 0 : 1;        
 | 
						|
  real toshare(_tpr < 4 ? _firstr : _secndr);    
 | 
						|
//  TDistrib ds(toshare,0);          
 | 
						|
  
 | 
						|
  // check percentages & prepare slicer
 | 
						|
  for (int i = first; i < n_rate(); i++)
 | 
						|
    {                
 | 
						|
      real p(perc_rata(i));
 | 
						|
//      ds.add(p);
 | 
						|
      r += p; 
 | 
						|
    }
 | 
						|
  
 | 
						|
  if (r != real(100.0))
 | 
						|
    res |= P_RSUM;            
 | 
						|
  
 | 
						|
  
 | 
						|
  if (_inited)
 | 
						|
    {
 | 
						|
//   RIMOSSO in quanto con rate uguali non si usa la percentuale,
 | 
						|
//   per evitare merdaglia
 | 
						|
//      ds.init(toshare);
 | 
						|
      // check importi rate consistenti con la percentuale
 | 
						|
//      for (int i = first; i < n_rate(); i++)
 | 
						|
//  {                 
 | 
						|
//    real r1(tpay_rata(i));  
 | 
						|
//    real r2(ds.get());
 | 
						|
//    if (r1 != r2) 
 | 
						|
//      { res |= P_IMPNC; break; }    
 | 
						|
//  }     
 | 
						|
      
 | 
						|
      // check errori date scadenze (se istanziate)
 | 
						|
      TDate d(data_rata(0));
 | 
						|
      if (d < _inizio) 
 | 
						|
        res |= P_INIZIO;
 | 
						|
      for (i = 1; i < n_rate(); i++)
 | 
						|
  {
 | 
						|
    if (data_rata(i) <= d) 
 | 
						|
      { res |= P_SCAD; break; }
 | 
						|
    d = data_rata(i);
 | 
						|
  }     
 | 
						|
    }
 | 
						|
  return res;
 | 
						|
}                                                                     
 | 
						|
 | 
						|
 | 
						|
void TPagamento::strerr(word err, TString& s)
 | 
						|
{
 | 
						|
  s = "Errore:";
 | 
						|
  if (err & P_RSUM)
 | 
						|
    s << "\n   Le percentuali non sommano a 100";
 | 
						|
  if (err & P_IMPNC)
 | 
						|
    s << "\n   Le percentuali sono inconsistenti con gli importi";
 | 
						|
  if (err & P_SCAD)
 | 
						|
    s << "\n   Le scadenze non sono consecutive";
 | 
						|
  if (err & P_INIZIO)
 | 
						|
    s << "\n   La prima rata e' antecedente alla data movimento";
 | 
						|
  if (err & P_NEG)
 | 
						|
    s << "\n   L'importo dato e' inferiore al minimo possibile";
 | 
						|
  if (err & P_TROP)
 | 
						|
    s << "\n   L'importo dato e' superiore al massimo possibile";
 | 
						|
}
 | 
						|
 | 
						|
const char* TPagamento::desc_tpr() const
 | 
						|
{            
 | 
						|
  const char* o;
 | 
						|
  switch (_tpr)
 | 
						|
  {
 | 
						|
    case 0: o = "Totale su tutte le rate"; break;
 | 
						|
    case 1: o = "Tutte le imposte su 1a"; break;
 | 
						|
    case 2: o = "Tutte le spese su 1a"; break;
 | 
						|
    case 3: o = "Imposte + spese su 1a"; break;
 | 
						|
    case 4: o = "Spese + merce su 1a"; break;
 | 
						|
    case 5: o = "Merce + imposte su 1a"; break;
 | 
						|
    case 6: o = "Tutta la merce su 1a"; break; 
 | 
						|
    default: o = ""; break;
 | 
						|
  } 
 | 
						|
  return o;
 | 
						|
}                        
 | 
						|
 | 
						|
const char* TPagamento::desc_tipo(int i) const
 | 
						|
{         
 | 
						|
  const char* o;
 | 
						|
  switch (i)
 | 
						|
  {   
 | 
						|
    case 1:  o = "Rimessa diretta o contanti"; break;
 | 
						|
    case 2:  o = "Tratta"; break;
 | 
						|
    case 3:  o = "Ricevuta bancaria"; break;
 | 
						|
    case 4:  o = "Cessione"; break;
 | 
						|
    case 5:  o = "Paghero'"; break;
 | 
						|
    case 6:  o = "Lettera di credito"; break;
 | 
						|
    case 7:  o = "Tratta accettata"; break;                   
 | 
						|
    case 8:  o = "Rapporti interb. diretti"; break;
 | 
						|
    case 9:  o = "Bonifici"; break;
 | 
						|
    default: o = "Altro pagamento"; break;
 | 
						|
  } 
 | 
						|
  return o;            
 | 
						|
}
 | 
						|
 | 
						|
word TPagamento::recalc_rate(int row, bool is_perc_modified, 
 | 
						|
                            const char* new_value, const char* scad, 
 | 
						|
                            const char* typ, int rdiff, bool mcomm,
 | 
						|
                            bool& need_recalc)
 | 
						|
     // ricalcola le rate sulla base di parametri modificati sulla riga row
 | 
						|
     // parametri: tutti i const char* possono essere NULL, il che vuol dire
 | 
						|
     //              che i dati corrispondenti non sono stati modificati;
 | 
						|
     //            se new_value non e' NULL puo' essere la percentuale (e 
 | 
						|
     //              allora is_perc_modified e' TRUE) o l'importo. Non e'
 | 
						|
     //              possibile modificare entrambi; se succede viene data
 | 
						|
     //              priorita' alla percentuale.
 | 
						|
{                                     
 | 
						|
  CHECK(!(!is_perc_modified &&  new_value != NULL && !_inited), 
 | 
						|
        "A'stronzo! E famme 'na pippa! Me dai n'importo che nun ce sta? Ma Vaffanculo!");
 | 
						|
  
 | 
						|
  if (_rate.items() == 0) return P_OK;
 | 
						|
  
 | 
						|
  real rsum(0.0), newv(0.0), rmax(0.0); 
 | 
						|
  int oldtype    = tipo_rata(0);
 | 
						|
  int oldscad    = scad_rata(0);
 | 
						|
  TDate lastdate = data_rata(0);  
 | 
						|
  int first      = _tpr < 4 ? 0 : 1;
 | 
						|
  TString_array srate(_rate);   // rate come erano   
 | 
						|
  
 | 
						|
  if (srate.items() > 1)
 | 
						|
  {
 | 
						|
    // calcola defaults per tipo pagamento e scadenza
 | 
						|
    // nel caso di rate nuove
 | 
						|
    oldscad = scad_rata(1);
 | 
						|
    if (_mcomm)
 | 
						|
    {
 | 
						|
      int mesi = oldscad / 30;
 | 
						|
      if (mesi == 0) mesi = 1;
 | 
						|
      oldscad = 30 * mesi;
 | 
						|
    }
 | 
						|
    
 | 
						|
  }       
 | 
						|
  
 | 
						|
  if (oldscad <= 0) oldscad = 30;
 | 
						|
  if (oldtype <= 0) oldtype = 1;
 | 
						|
  
 | 
						|
  if (new_value != NULL)
 | 
						|
  {     
 | 
						|
    newv = new_value;                       
 | 
						|
    rmax = is_perc_modified ? real(100.0) : (_tpr < 4 ? _firstr : _secndr);
 | 
						|
    if (newv > rmax) return P_RSUM;
 | 
						|
  }                                                   
 | 
						|
  
 | 
						|
  bool exhausted = FALSE;
 | 
						|
  
 | 
						|
  for (int i = first; i < srate.items(); i++)
 | 
						|
  {
 | 
						|
    if (i == row)
 | 
						|
    {  
 | 
						|
      if (typ != NULL)
 | 
						|
      { 
 | 
						|
        for (int k = 0; k < srate.items(); k++)
 | 
						|
        { 
 | 
						|
          // deve farlo per tutte dalla 1 in poi se rdiff == 2, 
 | 
						|
          // soltanto per row diversamente           
 | 
						|
          if ((rdiff == 2 && row > 0 && k > 0) || k == row)
 | 
						|
          {            
 | 
						|
          TToken_string& tt = rata(k);
 | 
						|
          TToken_string& ss = (TToken_string&)srate[k];
 | 
						|
          tt.add(typ,2);
 | 
						|
          ss.add(typ,2);  
 | 
						|
          need_recalc = TRUE;                        
 | 
						|
          // no error is possible  
 | 
						|
        }        
 | 
						|
      }
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (scad != NULL)
 | 
						|
    {   
 | 
						|
      // if !_inited scad e' il n. giorni, se no e' la rata 
 | 
						|
      if (_inited)
 | 
						|
      {
 | 
						|
        TToken_string& tt = rata(row);
 | 
						|
        TToken_string& ss = (TToken_string&)srate[row];
 | 
						|
        lastdate = scad;                             
 | 
						|
        // controlla errore sulla data scadenza
 | 
						|
        if (i > 0) 
 | 
						|
        {
 | 
						|
          oldscad  =  (int)(lastdate - data_rata(i-1)); 
 | 
						|
          if (oldscad <= 0l) return P_SCAD;
 | 
						|
        }
 | 
						|
        else if (lastdate < _inizio) return P_INIZIO;
 | 
						|
        tt.add(scad,3);
 | 
						|
        ss.add(scad,3);      
 | 
						|
        // ricalcola rate successive: se si vuole modificarne solo una
 | 
						|
        // ci si fotte e si disabilita il ricalcolo
 | 
						|
        TDate ddd (lastdate);
 | 
						|
        for (int j = row+1; j < srate.items(); j++)
 | 
						|
        { 
 | 
						|
          TToken_string& tt = rata(j);
 | 
						|
          TToken_string& ss = (TToken_string&)srate[j];
 | 
						|
          next_scad(ddd,scad_rata(j),mcomm,j);
 | 
						|
          tt.add(ddd.string(),3);
 | 
						|
          ss.add(ddd.string(),3);
 | 
						|
          need_recalc = TRUE;      
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      { 
 | 
						|
        // nulla di speciale visto che si memorizza la derivata
 | 
						|
        int sc = atoi(scad);
 | 
						|
        for (int i = 0; i < row; i ++)
 | 
						|
          sc -= scad_rata(i);
 | 
						|
        if (sc < 0 || (row > 0 && sc == 0)) return P_SCAD;
 | 
						|
        if (_mcomm && (sc % 30) != 0) _mcomm = FALSE;
 | 
						|
        TToken_string& tt = rata(row);
 | 
						|
        TToken_string& ss = (TToken_string&)srate[row];
 | 
						|
        tt.add(sc,0);
 | 
						|
        ss.add(sc,0);
 | 
						|
        need_recalc = TRUE;       
 | 
						|
      }       
 | 
						|
    }                 
 | 
						|
    
 | 
						|
    // here's the bell
 | 
						|
    if (new_value != NULL)
 | 
						|
    {                       
 | 
						|
      if (newv == ZERO || (rsum+newv) > rmax) 
 | 
						|
        return P_RSUM; 
 | 
						|
      // did not sforate
 | 
						|
      rsum += newv;         
 | 
						|
      TToken_string& rt = rata(row);
 | 
						|
      // setta nuovo valore e ricalcola cio' che ne consegue
 | 
						|
      if (is_perc_modified) rt.add(new_value,1);
 | 
						|
      else rt.add(new_value,4);
 | 
						|
      // riaggiusta le rate rimanenti
 | 
						|
      real remainder(0.0); remainder = rmax - rsum;
 | 
						|
      if (!(exhausted = (remainder == real(0.0))))
 | 
						|
      {           
 | 
						|
        // se inited e scelto UGUALI (2) occorre dividere in N e 
 | 
						|
        // aggiungere il resto sulla 1a rata                               
 | 
						|
        // controlla se rdiff e' compatibile con
 | 
						|
        // i dati e se e' il caso riaggiusta
 | 
						|
        if (rdiff == 3 && !((remainder % newv.integer()) == ZERO))
 | 
						|
          rdiff = 2;
 | 
						|
// *** 10/8/95: se uguali e non e' multiplo intero lo teniamo cosi' e poi
 | 
						|
// *** aggiungiamo alla prima rata utile
 | 
						|
//      if (rdiff == 2 && !((rmax % newv.integer()) == ZERO)) 
 | 
						|
//        rdiff = 1;                        
 | 
						|
// *** 5/9/85: UGUALI (2) significa la seguente menata: se c'e' una sola rata
 | 
						|
// *** uguale al totale importo, come prima; diversamente, la prima rata
 | 
						|
// *** va mantenuta uguale comunque sia, e occorre ridefinire le restanti in
 | 
						|
// *** modo che siano uguali. In questo caso deve far fede il NUMERO di RATE
 | 
						|
// *** indicato, che in prima nota non c'e' e va quindi inserito (porcoddio).
 | 
						|
 | 
						|
          // si registrano rate UGUALI soltanto se specificato UGUALI
 | 
						|
          // il che non e' sorprendente, ma coi tempi che corrono... 
 | 
						|
      _rdiff = (rdiff == 1 || rdiff == 3 || rdiff == 4);
 | 
						|
      
 | 
						|
      // procedi      
 | 
						|
      if (rdiff == 1) 
 | 
						|
        {
 | 
						|
          // cancella tutte le rate successive, aggiungi un'unica rata 
 | 
						|
          // con il resto dell'importo                                
 | 
						|
          if (row < (srate.items()-1))
 | 
						|
          {
 | 
						|
            TToken_string& trt = rata(row+1);
 | 
						|
            trt.add(remainder.string(), is_perc_modified ? 1 : 4);     
 | 
						|
            for(int j = row+2; j < srate.items(); j++)
 | 
						|
              _rate.destroy(j);
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
            // l'importante e' esagerare
 | 
						|
            for(int j = row+1; j < srate.items(); j++)
 | 
						|
              _rate.destroy(j); 
 | 
						|
        
 | 
						|
            TToken_string& trt = add_rata(is_perc_modified ? remainder : (real) 0.0,
 | 
						|
                                          oldscad, oldtype);
 | 
						|
            if (!is_perc_modified) trt.add(remainder.string(),4);
 | 
						|
            if (_inited)
 | 
						|
            { 
 | 
						|
              TDate dd = data_rata(row); 
 | 
						|
              next_scad(dd,oldscad,mcomm,row);
 | 
						|
              trt.add(dd.string(),3); 
 | 
						|
            }
 | 
						|
          } 
 | 
						|
        }
 | 
						|
        else  // rate non differenziate (dall'inizio o da row)
 | 
						|
        {
 | 
						|
          // ripartisci l'importo nel numero necessario di rate per
 | 
						|
          // mantenere costante il valore 
 | 
						|
          real sum(0.0);
 | 
						|
          if (_inited) lastdate = data_rata(rdiff == 2 ? first : row);
 | 
						|
          
 | 
						|
          TDate dd(lastdate);
 | 
						|
          int type = oldtype;
 | 
						|
          int nscd = oldscad;                        
 | 
						|
          
 | 
						|
          const int  frs = (rdiff == 3 || rdiff == 4) ? row+1     : first;
 | 
						|
          const real mx  = (rdiff == 3 || rdiff == 4) ? remainder : rmax;
 | 
						|
          
 | 
						|
          // cancelliamo tutto, va'
 | 
						|
         for (int j = srate.items()-1; j >= frs; j--) _rate.destroy(j);
 | 
						|
         
 | 
						|
         const int n = srate.items(); // questo rimane per forza costante
 | 
						|
         if (rdiff == 2 && n > 1)
 | 
						|
         {
 | 
						|
           // HERE
 | 
						|
           real tot   = is_perc_modified ? real(100.0) : (_tpr < 4 ? _firstr  : _secndr);
 | 
						|
           real delta = is_perc_modified ? ZERO : 
 | 
						|
                        ((_tpr > 0 && _tpr) < 4 ?  _secndr : ZERO);
 | 
						|
           real nimp(new_value);
 | 
						|
 | 
						|
           // se ho modificato la prima, divido il resto nelle successive
 | 
						|
           // lasciando costante il numero rate
 | 
						|
           if (row == first)
 | 
						|
           {                                    
 | 
						|
             if (!delta.is_zero()) nimp -= delta;
 | 
						|
             // inferiore al minimo 
 | 
						|
             if (nimp.sign() < 0) { _rate = srate; return P_NEG; }
 | 
						|
             real remainder = tot - nimp;  
 | 
						|
             real div = remainder / real(n - 1);                  
 | 
						|
             div.round(is_perc_modified ? 2 : _round);
 | 
						|
             nimp = tot - (div * real(n-1));
 | 
						|
 | 
						|
             for (int k = first; k < n; k++)
 | 
						|
             {
 | 
						|
               TToken_string& trt = (TToken_string&)srate[k];
 | 
						|
               if (_inited) dd   = trt.get(3);
 | 
						|
               type = atoi(trt.get(2));
 | 
						|
               nscd = k == 0 ? 0 : atoi(trt.get(0));  
 | 
						|
               if (type == 0) type = 1;
 | 
						|
               if (k > 0 && nscd == 0) nscd = oldscad;
 | 
						|
               if (_inited && dd == lastdate && k > 0) 
 | 
						|
                 next_scad(dd,nscd,mcomm,k);
 | 
						|
                   
 | 
						|
               set_rata(k, is_perc_modified ? (k == first ? nimp : div) : ZERO,
 | 
						|
               nscd, type, NULL, NULL, _inited ? dd.string() : NULL);
 | 
						|
               if (!is_perc_modified)
 | 
						|
                 set_imprata (k, k == first ? (nimp + delta) : div);
 | 
						|
             }
 | 
						|
           }
 | 
						|
           else
 | 
						|
           { 
 | 
						|
           // se ho modificato la seconda o oltre, faccio tutte uguali dalla
 | 
						|
           // seconda in poi; la prima resta com'e' se possibile, mentre se 
 | 
						|
           // c'e' un resto glielo sommo.
 | 
						|
           // Dunque: prendo la prima, calcolo il resto, divido per quella nuova,
 | 
						|
           // se resto lo sommo alla prima, e faccio quante rate servono 
 | 
						|
             
 | 
						|
         TToken_string& trt = (TToken_string&)srate[first];
 | 
						|
             real rfirst(is_perc_modified ? trt.get(1) :  trt.get(4));   
 | 
						|
             if (!delta.is_zero()) rfirst -= delta;
 | 
						|
             real rest      = tot - rfirst;
 | 
						|
             real div       = rest / nimp;
 | 
						|
             if (div < real(1.0)) { _rate = srate; return P_TROP; } 
 | 
						|
 | 
						|
             int nr = (int)div.integer() + (_tpr > 4 ? 2 : 1);
 | 
						|
             real reminder = rest - (nimp * real(nr -1));
 | 
						|
             rfirst += reminder;
 | 
						|
                 for (int k = first; k < nr; k++)
 | 
						|
                 {                    
 | 
						|
                   nscd = oldscad;
 | 
						|
                   type = _def_tpr;        
 | 
						|
                   TString16 ulc(_def_ulc);
 | 
						|
                   
 | 
						|
                   if (srate.items() > k)
 | 
						|
                   {
 | 
						|
             TToken_string& trt = (TToken_string&)srate[k];
 | 
						|
             if (_inited) dd   = trt.get(3);
 | 
						|
             type = atoi(trt.get(2));
 | 
						|
             nscd = atoi(trt.get(0));  
 | 
						|
             ulc  = trt.get(5);
 | 
						|
           }
 | 
						|
           
 | 
						|
           if (type == 0) type = 1;
 | 
						|
 | 
						|
           if (_inited && dd == lastdate && k > 0) 
 | 
						|
             next_scad(dd,nscd,mcomm,k);
 | 
						|
                   
 | 
						|
             set_rata(k, is_perc_modified ? (k == first ? rfirst : nimp) : ZERO,
 | 
						|
                nscd, type, ulc);
 | 
						|
                   if (!is_perc_modified)
 | 
						|
                     set_imprata (k, k == first ? (rfirst + delta) : nimp);
 | 
						|
                 }
 | 
						|
           }
 | 
						|
         } 
 | 
						|
        
 | 
						|
        else if (rdiff != 4)  
 | 
						|
      for (j = frs; sum < mx; j++)
 | 
						|
        { 
 | 
						|
          // se c'e' la vecchia rata si tengono i parametri
 | 
						|
          // altrimenti si calcolano 
 | 
						|
          if (j < srate.items())
 | 
						|
            {   
 | 
						|
           TToken_string& trt = (TToken_string&)srate[j];
 | 
						|
           if (_inited) dd   = trt.get(3);
 | 
						|
           type = atoi(trt.get(2));
 | 
						|
           nscd = j == 0 ? 0 : atoi(trt.get(0));  
 | 
						|
           if (type == 0) type = 1;
 | 
						|
           if (j > 0 && nscd == 0) nscd = oldscad;
 | 
						|
           if (_inited && dd == lastdate && j > 0) 
 | 
						|
            next_scad(dd,nscd,mcomm,j);
 | 
						|
            }
 | 
						|
            else if (_inited) 
 | 
						|
            {
 | 
						|
            if (dd <= botime) dd = lastdate;
 | 
						|
            next_scad(dd,nscd,mcomm,j); 
 | 
						|
            } 
 | 
						|
            else nscd = _int_rate;
 | 
						|
          
 | 
						|
             TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO,
 | 
						|
                            nscd, type); 
 | 
						|
            if (_inited)
 | 
						|
              ttr.add(dd.string(), 3);
 | 
						|
            if (!is_perc_modified)
 | 
						|
            {       
 | 
						|
              ttr.add(newv.string(),4);       
 | 
						|
                  }
 | 
						|
                  if ((mx - sum) < newv) 
 | 
						|
                  {
 | 
						|
                    // add remainder on first rate      
 | 
						|
                    newv += (mx - sum);    
 | 
						|
                    if (!is_perc_modified)
 | 
						|
                       set_imprata(frs, newv);  
 | 
						|
                    else { 
 | 
						|
                      TToken_string& t = rata(frs);  
 | 
						|
                      t.add(newv.string(), 1);
 | 
						|
                    }
 | 
						|
                    remove_rata(j);
 | 
						|
                    break;
 | 
						|
                  }
 | 
						|
//            }
 | 
						|
            sum += newv;
 | 
						|
        }     
 | 
						|
          else  // rdiff == 4; uguali finche' possibile
 | 
						|
      {
 | 
						|
        bool basta = FALSE;       
 | 
						|
        for (j = frs; ; j++)
 | 
						|
          { 
 | 
						|
            // ultima rata puo' differire dalle precedenti     
 | 
						|
            if (mx - sum <= newv) 
 | 
						|
        {
 | 
						|
          newv = mx - sum;
 | 
						|
          basta = TRUE;
 | 
						|
        }
 | 
						|
            // se c'e' la vecchia rata si tengono i parametri
 | 
						|
            // altrimenti si calcolano 
 | 
						|
            if (j < srate.items())
 | 
						|
        {   
 | 
						|
          TToken_string& trt = (TToken_string&)srate[j];
 | 
						|
          if (_inited) dd   = trt.get(3);
 | 
						|
          type = atoi(trt.get(2));
 | 
						|
          nscd = j == 0 ? 0 : atoi(trt.get(0)); 
 | 
						|
          if (type == 0) type = 1;
 | 
						|
          if (j > 0 && nscd == 0) nscd = oldscad;
 | 
						|
          if (_inited && dd == lastdate && j > 0)
 | 
						|
            next_scad(dd,nscd,mcomm,j);
 | 
						|
        }
 | 
						|
            else if (_inited) next_scad(dd,nscd,mcomm,j);  
 | 
						|
            
 | 
						|
            TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO,
 | 
						|
                  nscd, type); 
 | 
						|
            if (_inited)
 | 
						|
        ttr.add(dd.string(), 3);
 | 
						|
            if (!is_perc_modified)
 | 
						|
        ttr.add(newv.string(),4);
 | 
						|
            if (basta) break; 
 | 
						|
            sum += newv;
 | 
						|
          }         
 | 
						|
      }
 | 
						|
        }          
 | 
						|
      
 | 
						|
    }
 | 
						|
    else  // exhausted
 | 
						|
      {
 | 
						|
        for(int j = row+1; j < srate.items(); j++)
 | 
						|
          _rate.destroy(j);        
 | 
						|
      }             
 | 
						|
        
 | 
						|
        
 | 
						|
        if (_inited)
 | 
						|
    {                                    
 | 
						|
      // ricalcola il valore secondario (non modificato)
 | 
						|
      real toshare(100.0); 
 | 
						|
      if (is_perc_modified) 
 | 
						|
        toshare = (_tpr < 4 ? _firstr : _secndr);  
 | 
						|
      TDistrib dt(toshare, is_perc_modified ? _round : 3);                 
 | 
						|
 | 
						|
      for (int j = first; j < _rate.items(); j++)
 | 
						|
        {   
 | 
						|
          real rvl = is_perc_modified ? perc_rata(j) : tpay_rata(j); 
 | 
						|
          // togli pezxo di troppo
 | 
						|
          if (!is_perc_modified && j == first && _tpr > 0 && _tpr < 4)
 | 
						|
            rvl -= _secndr;                     
 | 
						|
          real zpx = rvl/rmax; // percentuale
 | 
						|
          dt.add(zpx);        
 | 
						|
        }    
 | 
						|
      for (j = first; j < _rate.items(); j++)
 | 
						|
        { 
 | 
						|
          real rfirst(0.0);              
 | 
						|
          TToken_string& tr = rata(j);    
 | 
						|
         
 | 
						|
          real rvl = dt.get(); 
 | 
						|
          
 | 
						|
          if (j == first) 
 | 
						|
          {  
 | 
						|
            rfirst = rvl; 
 | 
						|
            if (rdiff == 2)
 | 
						|
            {
 | 
						|
              real reminder  = toshare - rfirst;
 | 
						|
              real rdiv = reminder / real(_rate.items() - (1+first));  
 | 
						|
              rdiv.round( is_perc_modified ? _round : 2);
 | 
						|
              rfirst   += reminder - (rdiv * real(_rate.items() - (1+first)));
 | 
						|
              rvl       = rdiv;
 | 
						|
            }
 | 
						|
          }
 | 
						|
           
 | 
						|
          if (is_perc_modified &&  j == first && _tpr > 0 && _tpr < 4)
 | 
						|
            rfirst += _secndr;   
 | 
						|
            
 | 
						|
          tr.add((j == first ? rfirst.string() : rvl.string()), is_perc_modified ? 4 : 1);        
 | 
						|
          
 | 
						|
          if (_cambio != 1.0)
 | 
						|
          {
 | 
						|
            real implit(tpay_rata(j));
 | 
						|
            implit *= _cambio;
 | 
						|
            implit.round();
 | 
						|
            tr.add(implit.string(), 7);
 | 
						|
          }
 | 
						|
        }  
 | 
						|
        
 | 
						|
      // se e' il caso aggiungi l'importo fisso sulla prima rata
 | 
						|
//      if (_inited && _tpr > 0 && _tpr < 4)
 | 
						|
//      {
 | 
						|
//          TToken_string& tr = rata(0);   
 | 
						|
//          real tot = tpay_rata(0) + _secndr;
 | 
						|
//          tr.add(tot.string(), 4);
 | 
						|
//      } 
 | 
						|
        
 | 
						|
    }
 | 
						|
        
 | 
						|
        need_recalc = TRUE;            
 | 
						|
        return  P_OK;     
 | 
						|
      } // new_value != NULL
 | 
						|
  }
 | 
						|
  else  // i != row modified
 | 
						|
    {                                
 | 
						|
      if (rdiff == 2) continue;
 | 
						|
        if (i > 0 && !((perc_rata(i-1) == perc_rata(i))))
 | 
						|
        {
 | 
						|
          if (rdiff == 2) rdiff = 1;
 | 
						|
            _rdiff = FALSE;
 | 
						|
        }
 | 
						|
        if (is_perc_modified)
 | 
						|
          rsum    += perc_rata(i);
 | 
						|
        else
 | 
						|
          rsum    += tpay_rata(i);  
 | 
						|
      
 | 
						|
      lastdate = data_rata(i);
 | 
						|
      oldtype  = tipo_rata(i);
 | 
						|
      oldscad  = scad_rata(i); 
 | 
						|
      if (_inited && i > 0) 
 | 
						|
      {
 | 
						|
        if (data_rata(i) <= data_rata(i-1)) 
 | 
						|
          return P_SCAD;
 | 
						|
      }
 | 
						|
      else if (lastdate < _inizio)
 | 
						|
        return P_INIZIO;
 | 
						|
    }    
 | 
						|
  }
 | 
						|
  
 | 
						|
  return P_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TPagamento::read(TTable* t, TTable* r)
 | 
						|
{                                                         
 | 
						|
  // puo' chiamarla chiunque
 | 
						|
  bool istnew = FALSE;
 | 
						|
  if (t == NULL) 
 | 
						|
  { 
 | 
						|
    t = new TTable("%CPG"); 
 | 
						|
    istnew = TRUE; 
 | 
						|
  }
 | 
						|
  t->zero(); t->put("CODTAB", _code);
 | 
						|
  if (t->read() != NOERR) return FALSE;   
 | 
						|
  
 | 
						|
  _slicer.init(real(0.0), TRUE);
 | 
						|
  _rate.destroy();
 | 
						|
  
 | 
						|
  // set everything 
 | 
						|
  _rdiff   = t->get_bool("B1");
 | 
						|
  _mcomm   = t->get_bool("B0");
 | 
						|
  _tpr     = atoi(t->get("S3"));
 | 
						|
  _inscad  = *((const char*)(t->get("S1")));
 | 
						|
  _code    = t->get("CODTAB");
 | 
						|
  _name    = t->get("S0");
 | 
						|
  _fixd[0] = t->get_int("I0");
 | 
						|
  _fixd[1] = t->get_int("I1");
 | 
						|
  _fixd[2] = t->get_int("I2");
 | 
						|
  
 | 
						|
  // TBI aggiusta _inizio secondo INSCAD; vedi mese commerciale etc.                         
 | 
						|
  if (_inscad == 'M')
 | 
						|
    {
 | 
						|
      if (_mcomm) _inizio.set_month(_inizio.month() == 2 ? 28 : 30);
 | 
						|
      else        _inizio.set_end_month();
 | 
						|
    }
 | 
						|
  else if (_inscad == 'F' && _mcomm && _inizio.month() == 31) 
 | 
						|
    _inizio.set_month(30);
 | 
						|
  
 | 
						|
  // leggi rate e scadenze          
 | 
						|
  bool isrnew = FALSE;
 | 
						|
  if (r == NULL) 
 | 
						|
  { 
 | 
						|
    r = new TTable("%RPG"); 
 | 
						|
    isrnew = TRUE; 
 | 
						|
  }
 | 
						|
 
 | 
						|
  TString16 s; 
 | 
						|
  for (int i = 0; ;i++)
 | 
						|
  {   
 | 
						|
    r->zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r->put("CODTAB", (const char*)s);
 | 
						|
    if (r->read() != NOERR) 
 | 
						|
      break;
 | 
						|
    TToken_string* tt = new TToken_string(16);
 | 
						|
    tt->add((const char*)(r->get("I0")));  // scadenza
 | 
						|
    tt->add((const char*)(r->get("R0")));  // percentuale
 | 
						|
    tt->add((const char*)(r->get("I1")));  // tipo 
 | 
						|
    // data e importo         
 | 
						|
    TDate d = _inizio; 
 | 
						|
    next_scad(d,(int)(r->get_long("I0")),_mcomm,i);
 | 
						|
    tt->add((const char*)d);  
 | 
						|
    tt->add("");                         
 | 
						|
    tt->add(r->get("S1"));
 | 
						|
    _slicer.add((real)r->get("R0"));
 | 
						|
    _rate.add(tt);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (istnew) delete t;
 | 
						|
  if (isrnew) delete r;
 | 
						|
  
 | 
						|
  return TRUE;          
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TPagamento::write(TTable& r)
 | 
						|
{   
 | 
						|
  // Scrive soltanto le righe di pagamento; si assume sia stata chiamata da una
 | 
						|
  // relapp, che ha scritto il file principale                                 
 | 
						|
  
 | 
						|
  TString16 s; 
 | 
						|
  int err = NOERR;    
 | 
						|
  
 | 
						|
  for (int i = 0; err == NOERR && i < n_rate(); i++)
 | 
						|
  {
 | 
						|
    r.zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r.put("CODTAB", s);
 | 
						|
    r.put("I0", (long)scad_rata(i));
 | 
						|
    r.put("R0", perc_rata(i).string());
 | 
						|
    r.put("I1", (long)tipo_rata(i));
 | 
						|
    r.put("S1", ulc_rata(i));
 | 
						|
    err = r.write();
 | 
						|
  }                                      
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TPagamento::rewrite(TTable& r)
 | 
						|
{
 | 
						|
  TString16 s; int err = NOERR;
 | 
						|
  
 | 
						|
  for (int i = 0; err == NOERR && i < n_rate(); i++)
 | 
						|
  {
 | 
						|
    r.zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r.put("CODTAB", s);
 | 
						|
    bool was = (r.read() == NOERR);
 | 
						|
    r.zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r.put("CODTAB", (const char*)s);
 | 
						|
    r.put("I0", (long)scad_rata(i));
 | 
						|
    r.put("R0", perc_rata(i).string());
 | 
						|
    r.put("I1", (long)tipo_rata(i));
 | 
						|
    r.put("S1", ulc_rata(i));
 | 
						|
    err = (was ? r.rewrite() : r.write());
 | 
						|
  }                                      
 | 
						|
  
 | 
						|
  // erase possible rates > current n. rates
 | 
						|
  for (;err == NOERR;i++)
 | 
						|
  { 
 | 
						|
    r.zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r.put("CODTAB", (const char*)s);
 | 
						|
    if (r.read() == NOERR) err = r.remove();
 | 
						|
    else break;
 | 
						|
  }
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TPagamento::remove(TTable& r)
 | 
						|
{          
 | 
						|
  TString s(16); int err = NOERR;
 | 
						|
  for (int i = 0 ; err == NOERR; i++)
 | 
						|
  { 
 | 
						|
    r.zero(); s.format("%s%3d",(const char*)_code, i);
 | 
						|
    r.put("CODTAB", (const char*)s);
 | 
						|
    if (r.read() == NOERR) err = r.remove();
 | 
						|
    else break;
 | 
						|
  }  
 | 
						|
  return err;
 | 
						|
}                               
 | 
						|
 | 
						|
void TPagamento::set_rate_auto()
 | 
						|
{
 | 
						|
  // vedi rate esistenti e tipo prima rata 
 | 
						|
  // deve fare riferimento ad un tipo pagamento esistente
 | 
						|
  // e sensato
 | 
						|
  int first = 0;                           
 | 
						|
  
 | 
						|
  real toslice = _firstr;
 | 
						|
  
 | 
						|
  if (n_rate() == 0 || !_inited || (_tpr > 3 && n_rate() == 1))  return;
 | 
						|
 | 
						|
  if (_tpr > 3)           // ripartisci _firstr su tutte le rate
 | 
						|
    {
 | 
						|
      first = 1; 
 | 
						|
      toslice = _secndr;
 | 
						|
    }
 | 
						|
  
 | 
						|
  _slicer.init(toslice);
 | 
						|
  
 | 
						|
  if (_tpr > 3)
 | 
						|
    // prima rata obbligatoria
 | 
						|
    set_imprata(0, _firstr); 
 | 
						|
                            
 | 
						|
  // se rate uguali dividi l'importo totale per il numero di rate                           
 | 
						|
  real r1(0.0), ro(0.0); 
 | 
						|
  if (!_rdiff)
 | 
						|
  {              
 | 
						|
    int rut = _tpr > 3 ? n_rate() - 1 : n_rate();
 | 
						|
    
 | 
						|
    // usa la percentuale per la prima rata
 | 
						|
    r1 = (toslice * perc_rata(first))/real(100.0); 
 | 
						|
    r1.round(_round);
 | 
						|
    real reminder = toslice - r1;
 | 
						|
    if (!reminder.is_zero()) 
 | 
						|
    {
 | 
						|
      ro = reminder/real(rut-1); ro.trunc(_round);
 | 
						|
      r1 = (toslice - (ro*real(rut-1)));
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  for (int i = first; i < n_rate(); i++)        
 | 
						|
    // setta le fette e le date di scadenza
 | 
						|
    set_imprata(i, _rdiff ? _slicer.get() : (i == first ? r1 : ro));
 | 
						|
                                          
 | 
						|
  // se e' nei primi tre casi, si somma l'importo da non dividere alla
 | 
						|
  // prima rata                                        
 | 
						|
  if (_tpr > 0 && _tpr < 4)
 | 
						|
    set_imprata(0, tpay_rata(0) + _secndr);  
 | 
						|
}                                     
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void TPagamento::set_total(const real& imponibile, const real& imposta, const real& spese)
 | 
						|
{
 | 
						|
  _imponibile = imponibile;
 | 
						|
  _imposta    = imposta;
 | 
						|
  _spese      = spese;
 | 
						|
  _inited     = TRUE;
 | 
						|
  
 | 
						|
  // istanzia _firstr e _secndr a seconda di _tpr  
 | 
						|
  switch(_tpr)
 | 
						|
  {          
 | 
						|
    case 0:                                         
 | 
						|
      _firstr = _imponibile + _imposta + _spese;
 | 
						|
      _secndr = 0.0;
 | 
						|
      break;              
 | 
						|
    case 1: 
 | 
						|
      _secndr = _imposta;
 | 
						|
      _firstr = _imponibile + _spese;
 | 
						|
      break;
 | 
						|
    case 2: 
 | 
						|
      _secndr = _spese;
 | 
						|
      _firstr = _imposta + _imponibile;
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      _secndr = _imposta + _spese; 
 | 
						|
      _firstr = _imponibile;
 | 
						|
      break;
 | 
						|
    case 4: 
 | 
						|
      _firstr = _spese + _imponibile;
 | 
						|
      _secndr = _imposta;
 | 
						|
      break;  
 | 
						|
    case 5:     
 | 
						|
      _firstr = _imponibile + _imposta;
 | 
						|
      _secndr = _spese;
 | 
						|
      break;  
 | 
						|
    case 6:            
 | 
						|
      _firstr = _imponibile;
 | 
						|
      _secndr = _imposta + _spese;
 | 
						|
      break;  
 | 
						|
  }
 | 
						|
               
 | 
						|
  real toslice = _tpr > 1 ? _secndr : _firstr;
 | 
						|
               
 | 
						|
  _slicer.init(toslice, TRUE);
 | 
						|
  
 | 
						|
  for (int i = 0; i < _rate.items(); i++)
 | 
						|
    {
 | 
						|
      TToken_string& t = (TToken_string&)_rate[i]; 
 | 
						|
      real rr(t.get(1));
 | 
						|
      _slicer.add(rr);
 | 
						|
    }                   
 | 
						|
}                            
 | 
						|
 | 
						|
 | 
						|
void TPagamento::set_sheet(TSheet_field& sf, int sscad)
 | 
						|
{
 | 
						|
  if (_inited && _rate.items() > 0)
 | 
						|
  { 
 | 
						|
    const bool in_valuta = _cambio != 1.0;
 | 
						|
                     
 | 
						|
    // si istanzia uno sheet di primanota
 | 
						|
    for (int i = 0; i < n_rate(); i++)
 | 
						|
    {                                        
 | 
						|
      TToken_string& ts = sf.row(i);
 | 
						|
      
 | 
						|
      ts.add((const char*)data_rata(i), 0);           // 0 - Data scadenza
 | 
						|
      if (in_valuta)
 | 
						|
      {
 | 
						|
        ts.add(tlit_rata(i).string(), 1);             // 1 - Importo in lire
 | 
						|
        ts.add(tpay_rata(i).string(), 2);             // 2 - Importo in valuta
 | 
						|
      }  
 | 
						|
      else                                            
 | 
						|
      {
 | 
						|
        ts.add(tpay_rata(i).string(), 1);             // 1 - Importo
 | 
						|
        ts.add("", 2);
 | 
						|
      }
 | 
						|
      ts.add(perc_rata(i).string(), 3);               // 3 - Percentuale
 | 
						|
      ts.add(tipo_rata(i), 4);                        // 4 - Tipo rata
 | 
						|
      ts.add(desc_tipo(tipo_rata(i)), 5);             // 5 - Descrizione tipo rata  
 | 
						|
                                                      // 6,7,8,9 - Banche
 | 
						|
      const bool paid = ratapagata(i);                
 | 
						|
      ts.add(paid ? "X" : "", 10);                    // 10 - Pagaya
 | 
						|
      sf.enable_cell(i,1,!paid);                      // importo
 | 
						|
      sf.enable_cell(i,2,!paid);                      // in valuta
 | 
						|
      sf.enable_cell(i,3,!paid);                      // percentuale    
 | 
						|
    }                   
 | 
						|
    
 | 
						|
    // destroy remaining
 | 
						|
    while (sf.items() > i)
 | 
						|
      sf.destroy(sf.items()-1); 
 | 
						|
      
 | 
						|
    sf.enable_column(2, in_valuta);
 | 
						|
  }
 | 
						|
  else 
 | 
						|
  if (_rate.items() > 0)  // not inited: set edit sheet
 | 
						|
  {
 | 
						|
    sf.destroy();
 | 
						|
    for (int i = 0, scr = 0; i < n_rate(); i++)
 | 
						|
    {
 | 
						|
      TToken_string& s = sf.row(-1);
 | 
						|
      scr += scad_rata(i);      
 | 
						|
      s.add(scr);
 | 
						|
      s.add(perc_rata(i).string());
 | 
						|
      s.add(tipo_rata(i));
 | 
						|
      s.add(desc_tipo(tipo_rata(i)));
 | 
						|
      s.add(ulc_rata(i));       
 | 
						|
    } 
 | 
						|
  }
 | 
						|
  else  // new: set with 1 or 2 rates according to tpr
 | 
						|
  {        
 | 
						|
    if (_tpr > 3) 
 | 
						|
      add_rata(ZERO, sscad == -1 ? 0 : sscad, _def_tpr, _def_ulc);
 | 
						|
    add_rata(real(100.0), sscad == -1 ? (_tpr < 4 ? 0 : 30) : sscad, _def_tpr, _def_ulc);  
 | 
						|
      
 | 
						|
    _dirty = TRUE;
 | 
						|
      
 | 
						|
    for (int i = 0, scr = 0; i < n_rate(); i++)
 | 
						|
    {
 | 
						|
       TToken_string& s = sf.row(-1);
 | 
						|
       scr += scad_rata(i);
 | 
						|
       s.add(scr);
 | 
						|
       s.add(perc_rata(i).string());
 | 
						|
       s.add(tipo_rata(i));
 | 
						|
       s.add(desc_tipo(tipo_rata(i)));
 | 
						|
       s.add(ulc_rata(i));  
 | 
						|
    }      
 | 
						|
  }            
 | 
						|
  
 | 
						|
  if (_tpr > 3)
 | 
						|
  {     
 | 
						|
      // disabilita campi da non toccare sulla prima rata
 | 
						|
    if (_inited)
 | 
						|
    {        
 | 
						|
      sf.disable_cell(0,1); // importo
 | 
						|
      sf.disable_cell(0,2); // in valuta
 | 
						|
      sf.disable_cell(0,3); // percentuale
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      sf.disable_cell(0,1); // percentuale
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  sf.force_update();   
 | 
						|
}
 | 
						|
 | 
						|
TPagamento::TPagamento(const char* codtab, const char* data) : 
 | 
						|
_slicer(0.0,0), _new(FALSE), _imponibile(0.0), _imposta(0.0), 
 | 
						|
_spese(0.0), _cambio(1.0), _code(codtab), _dirty(FALSE), _inited(FALSE),
 | 
						|
_def_tpr(1), _def_ulc(""), _round(0), _int_rate(30)
 | 
						|
{               
 | 
						|
  _fixd[0] = _fixd[1] = _fixd[2] = 0;
 | 
						|
  if (data != NULL)     
 | 
						|
    _inizio = data;
 | 
						|
  if (_code.blank() || !read()) 
 | 
						|
    _new = TRUE; 
 | 
						|
}  
 |