1241 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1241 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <mask.h>
 | 
						|
 | 
						|
#include "saldacon.h"
 | 
						|
 | 
						|
#include <mov.h>
 | 
						|
#include <scadenze.h>
 | 
						|
#include <pagsca.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TTree_rectype
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TTree_rectype::TTree_rectype(const TRectype& testa, const TRectype& riga, const char* num)
 | 
						|
: TRectype(testa), _recarr(riga, num)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TTree_rectype::TTree_rectype(int testa, int riga, const char* num)
 | 
						|
: TRectype(testa), _recarr(riga, num)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TTree_rectype::TTree_rectype(const TTree_rectype& t)
 | 
						|
: TRectype(t), _recarr(t._recarr)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TObject* TTree_rectype::dup() const
 | 
						|
{
 | 
						|
  TTree_rectype* r = new TTree_rectype(*this);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
void TTree_rectype::renum_key(const char* field, const char* val)
 | 
						|
{                   
 | 
						|
  TRectype::renum_key(field, val);
 | 
						|
  _recarr.renum_key(field, val);
 | 
						|
}
 | 
						|
 | 
						|
void TTree_rectype::copy_key_to_row(TRectype& row) const
 | 
						|
{   
 | 
						|
  RecDes* recd = rec_des();  // Descrizione del record della testata
 | 
						|
  row.zero();                              
 | 
						|
  const KeyDes& kd = recd->Ky[0];   // Memento! Gli indici delle chiavi partono da zero!  
 | 
						|
  for (int i = kd.NkFields-1; i >= 0; i--)
 | 
						|
  {                        
 | 
						|
    const int nf = kd.FieldSeq[i] % MaxFields;
 | 
						|
    const RecFieldDes& rf = recd->Fd[nf];  
 | 
						|
    const char* name = rf.Name;
 | 
						|
    const TString& val = get(name);
 | 
						|
    row.renum_key(name, val);
 | 
						|
  }
 | 
						|
}  
 | 
						|
 | 
						|
 | 
						|
TRectype& TTree_rectype::new_row(int r) 
 | 
						|
{ 
 | 
						|
  if (r <= 0) 
 | 
						|
    r = last()+1;                     
 | 
						|
  CHECKD(!exist(r), "Ue' pirla!, esiste gia' la riga ", r);
 | 
						|
  TRectype& row = rows_array().row(r, TRUE); 
 | 
						|
  return row;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TTree_rectype::fill_array()
 | 
						|
{
 | 
						|
  TRectype* row = (TRectype*)_recarr.key().dup();
 | 
						|
  copy_key_to_row(*row);
 | 
						|
  const int err = _recarr.read(row);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TTree_rectype::read(TBaseisamfile& f, word op)
 | 
						|
{
 | 
						|
  int err = TRectype::read(f, op);
 | 
						|
  if (err == NOERR)
 | 
						|
    fill_array();
 | 
						|
  else 
 | 
						|
    _recarr.destroy_rows();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
int TTree_rectype::next(TBaseisamfile& f)
 | 
						|
{
 | 
						|
  int err = TRectype::next(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    fill_array();
 | 
						|
  else 
 | 
						|
    _recarr.destroy_rows();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
int TTree_rectype::write(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  int err = TRectype::write(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    err = _recarr.write();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
int TTree_rectype::rewrite(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  int err = TRectype::rewrite(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    err = _recarr.rewrite();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
int TTree_rectype::remove(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  int err = TRectype::remove(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    err = _recarr.remove();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Valuta
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TValuta::TValuta(const char* cod, const TDate& dat, const real& cam)
 | 
						|
: _cod(cod), _dat(dat), _cam(cam)
 | 
						|
{
 | 
						|
  adjust();
 | 
						|
}
 | 
						|
 | 
						|
TValuta::TValuta() : _cod(""), _dat(TODAY), _cam(1.0)
 | 
						|
{}
 | 
						|
 | 
						|
void TValuta::adjust()
 | 
						|
{ 
 | 
						|
  _cod.upper();
 | 
						|
  if (_cod.empty() || _cod == "LIT" || _cam.is_zero()) 
 | 
						|
    _cam = 1.0; 
 | 
						|
}
 | 
						|
 | 
						|
int TValuta::compare(const TSortable& s) const
 | 
						|
{
 | 
						|
  const TValuta& v = (const TValuta&)s;
 | 
						|
  real c(_cam); c -= v._cam;
 | 
						|
  return c.sign();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TValuta::get(const TRectype& rec)
 | 
						|
{
 | 
						|
  _cod = rec.get("CODVAL");
 | 
						|
  _dat = rec.get("DATACAM");
 | 
						|
  _cam = rec.get_real("CAMBIO");
 | 
						|
  adjust();
 | 
						|
}
 | 
						|
 | 
						|
void TValuta::put(TRectype& rec) const
 | 
						|
{
 | 
						|
  if (in_lire())            
 | 
						|
  {  
 | 
						|
    rec.zero("CODVAL");
 | 
						|
    rec.zero("DATACAM");
 | 
						|
    rec.zero("CAMBIO");
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    rec.put("CODVAL", _cod);
 | 
						|
    rec.put("DATACAM", _dat);
 | 
						|
    rec.put("CAMBIO", _cam);
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
void TValuta::set(TMask& m, short v, short d, short c) const
 | 
						|
{
 | 
						|
  if (in_lire())            
 | 
						|
  {
 | 
						|
    m.reset(v);
 | 
						|
    m.reset(d);
 | 
						|
    m.reset(c);
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
    m.set(v, _cod);
 | 
						|
    m.set(d, _dat.string());
 | 
						|
    m.set(c, _cam.string());
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
void TValuta::get(const TMask& m, short v, short d, short c)
 | 
						|
{
 | 
						|
  _cod = m.get(v);
 | 
						|
  _dat = m.get(d);
 | 
						|
  _cam = real(m.get(c));
 | 
						|
  adjust();
 | 
						|
}
 | 
						|
 | 
						|
real TValuta::lit2val(const real& lit) const
 | 
						|
{
 | 
						|
  real val(lit);
 | 
						|
  val /= _cam;
 | 
						|
  val.round(2);
 | 
						|
  return val;
 | 
						|
}
 | 
						|
 | 
						|
real TValuta::val2lit(const real& val) const
 | 
						|
{   
 | 
						|
  real lit(val);
 | 
						|
  lit *= _cam;
 | 
						|
  lit.round();
 | 
						|
  return lit;
 | 
						|
}
 | 
						|
 | 
						|
void TValuta::val2lit(real& val) const
 | 
						|
{   
 | 
						|
  val *= _cam;
 | 
						|
  val.round();
 | 
						|
}
 | 
						|
 | 
						|
void TValuta::val2lit(TImporto& imp) const
 | 
						|
{           
 | 
						|
  val2lit(imp.valore());
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRiga_scadenze
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TRiga_scadenze::TRiga_scadenze(TRiga_partite* r)
 | 
						|
: TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP"), _riga(r)
 | 
						|
{
 | 
						|
  CHECK(_riga, "Riga nulla");
 | 
						|
  r->copy_key_to_row(*this);
 | 
						|
}  
 | 
						|
 | 
						|
TRiga_scadenze::TRiga_scadenze(const TRiga_scadenze& s)
 | 
						|
: TTree_rectype(s), _riga(s._riga)
 | 
						|
{} 
 | 
						|
 | 
						|
TObject* TRiga_scadenze::dup() const
 | 
						|
{
 | 
						|
  TRiga_scadenze* r = new TRiga_scadenze(*this);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
TPartita& TRiga_scadenze::partita() const
 | 
						|
{
 | 
						|
  return riga().partita();
 | 
						|
}
 | 
						|
 | 
						|
// Controlla se la fattura della rata e' in valuta
 | 
						|
bool TRiga_scadenze::in_valuta() const
 | 
						|
{
 | 
						|
  return riga().in_valuta();
 | 
						|
}
 | 
						|
 | 
						|
// Controlla se la rata e' stata completamente pagata
 | 
						|
bool TRiga_scadenze::chiusa(bool update) const
 | 
						|
{                                      
 | 
						|
  bool chiusa;
 | 
						|
  if (update)
 | 
						|
  {          
 | 
						|
    TImporto imp(importo_da_pagare(TRUE));
 | 
						|
    imp += importo_pagato(TRUE, 0x3);
 | 
						|
    chiusa = imp.is_zero();
 | 
						|
    ((TRectype*)this)->put(SCAD_PAGATA, chiusa ? "X" : "");
 | 
						|
  }
 | 
						|
  else
 | 
						|
    chiusa = get_bool(SCAD_PAGATA);
 | 
						|
  
 | 
						|
  return chiusa;  
 | 
						|
}
 | 
						|
 | 
						|
// Calcola il totale dei pagamenti (eventualmente in valuta)
 | 
						|
TImporto TRiga_scadenze::importo_pagato(bool val, int mode) const
 | 
						|
{                                
 | 
						|
  CHECKD(mode > 0 && mode < 8, "Bad importo_pagato mode ", mode);
 | 
						|
  const TPartita& game = partita();
 | 
						|
  const bool in_val = in_valuta();   
 | 
						|
  const char* imp_field = (val && in_val) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
 | 
						|
  
 | 
						|
  TImporto totale;
 | 
						|
  for (int p = last(); p > 0; p = pred(p))
 | 
						|
  {
 | 
						|
    const TRectype& pag = row(p);                         // Riga pagamento
 | 
						|
    const TRiga_partite& sum = game.riga(p);              // Riga partite
 | 
						|
    const char sez = sum.sezione();
 | 
						|
    
 | 
						|
    if (mode & 0x1)
 | 
						|
      totale += TImporto(sez, pag.get_real(imp_field));
 | 
						|
    
 | 
						|
    if (mode & 0x2)   // Voglio anche gli abbuoni
 | 
						|
    {
 | 
						|
      real abb(pag.get_real(PAGSCA_ABBUONI));
 | 
						|
      if (!val && in_val)
 | 
						|
      {
 | 
						|
        abb *= sum.get_real(PART_CAMBIO);
 | 
						|
        abb.round();
 | 
						|
      }
 | 
						|
      totale += TImporto(sez, abb);
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (!val && (mode & 0x4))   // Voglio anche le differenze cambi
 | 
						|
    {
 | 
						|
      const TImporto diffcam(sez, pag.get_real(PAGSCA_DIFFCAM));
 | 
						|
      totale += diffcam;
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  
 | 
						|
  return totale.normalize();
 | 
						|
}
 | 
						|
 | 
						|
// Calcola l'importo da pagare (eventualmente in valuta)
 | 
						|
TImporto TRiga_scadenze::importo_da_pagare(bool val) const
 | 
						|
{            
 | 
						|
  const char* imp_field = (val && in_valuta()) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
 | 
						|
  const TRiga_partite& fatt = riga();              // Riga fattura
 | 
						|
  const TImporto totale(fatt.sezione(), get_real(imp_field));
 | 
						|
  return totale;
 | 
						|
}
 | 
						|
 | 
						|
// Calcola l'abbuono in valuta della rata e ritorna il suo tipo:
 | 
						|
// 'A' abbuono attivo; 'P' abbuono passivo
 | 
						|
// La sezione dell'abbuono calcolato e' quella della riga contabile in cui finira'
 | 
						|
char TRiga_scadenze::calcola_abbuono(int p, TImporto& abbuono) const
 | 
						|
{
 | 
						|
  bool ap = ' ';
 | 
						|
  
 | 
						|
  const TRectype& pag = row(p);
 | 
						|
  if (pag.get_char(PAGSCA_ACCSAL) == 'S')
 | 
						|
  {
 | 
						|
    abbuono = importo_da_pagare(TRUE);
 | 
						|
    abbuono += importo_pagato(TRUE);
 | 
						|
    
 | 
						|
    for (int r = last(); r > 0; r = pred(r)) if (r != p)
 | 
						|
    {
 | 
						|
      const TRiga_partite& sum = partita().riga(r);         // Riga partite
 | 
						|
      const TImporto imp(sum.sezione(), row(r).get_real(PAGSCA_ABBUONI));
 | 
						|
      abbuono += imp;
 | 
						|
    }  
 | 
						|
 | 
						|
    const int sign = abbuono.valore().sign();
 | 
						|
    if (sign != 0)
 | 
						|
    {
 | 
						|
      if (sign > 0)
 | 
						|
        ap = abbuono.sezione() == 'D' ? 'P' : 'A';
 | 
						|
      else  
 | 
						|
        ap = abbuono.sezione() == 'D' ? 'A' : 'P';
 | 
						|
    }    
 | 
						|
  }
 | 
						|
  else 
 | 
						|
    abbuono.valore() = ZERO;
 | 
						|
  
 | 
						|
  return ap;
 | 
						|
}
 | 
						|
 | 
						|
// Calcola la differenza cambi con la sezione da mettere nella riga contabile corrispondente
 | 
						|
TImporto TRiga_scadenze::calcola_differenza_cambio(int p, bool update)
 | 
						|
{ 
 | 
						|
  TImporto diffcam;      
 | 
						|
 | 
						|
  TRectype& pag = row(p);
 | 
						|
  if (pag.get_char(PAGSCA_ACCSAL) == 'S' && in_valuta())
 | 
						|
  {
 | 
						|
    const char sez = partita().riga(p).sezione();
 | 
						|
    
 | 
						|
    if (update)
 | 
						|
    {
 | 
						|
      diffcam = importo_da_pagare(FALSE);
 | 
						|
      diffcam += importo_pagato(FALSE, 0x3);      // Conta anche gli abbuoni
 | 
						|
      diffcam.normalize(sez);
 | 
						|
      
 | 
						|
      const TImporto gir(sez, -diffcam.valore());
 | 
						|
      pag.put(PAGSCA_DIFFCAM, gir.valore());
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {                                            
 | 
						|
      diffcam.set(sez, -pag.get_real(PAGSCA_DIFFCAM));
 | 
						|
    }  
 | 
						|
  } 
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (update)
 | 
						|
      pag.zero(PAGSCA_DIFFCAM);
 | 
						|
  }
 | 
						|
 | 
						|
  return diffcam.normalize();
 | 
						|
}
 | 
						|
 | 
						|
TImporto TRiga_scadenze::residuo(bool val, int mode) const
 | 
						|
{                         
 | 
						|
  TImporto residuo(importo_da_pagare(val));
 | 
						|
  residuo += importo_pagato(val, mode);            // Somma con sezione opposta 
 | 
						|
  return residuo;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TRiga_scadenze::modifica_pagamento(const TRectype& new_pag, const TValuta& valuta,
 | 
						|
                                        char& old_ap, TImporto& old_abb, TImporto& old_diffcam,  
 | 
						|
                                        char& new_ap, TImporto& new_abb, TImporto& new_diffcam)
 | 
						|
{       
 | 
						|
  const bool in_val = in_valuta();
 | 
						|
  const int nrigp = new_pag.get_int(PAGSCA_NRIGP);
 | 
						|
  const TRectype old_pag(row(nrigp));
 | 
						|
  TRiga_partite& sum = partita().riga(nrigp);
 | 
						|
  
 | 
						|
  TImporto old_abbuono;
 | 
						|
  old_ap = calcola_abbuono(nrigp, old_abbuono);          // Vecchio abbuono in valuta
 | 
						|
  old_abb = old_abbuono;                                 // Vecchio abbuono in lire
 | 
						|
  if (in_val)
 | 
						|
  {
 | 
						|
    old_abb.valore() *= sum.get_real(PART_CAMBIO);
 | 
						|
    old_abb.valore().round();
 | 
						|
  }
 | 
						|
  old_diffcam = calcola_differenza_cambio(nrigp, FALSE);
 | 
						|
  
 | 
						|
  if (in_val && !valuta.in_lire())
 | 
						|
    valuta.put(sum);
 | 
						|
  
 | 
						|
  row(nrigp) = new_pag;
 | 
						|
  row(nrigp).zero(PAGSCA_ABBUONI);              // Azzera abbuoni per ricalcolo
 | 
						|
  row(nrigp).zero(PAGSCA_DIFFCAM);              // Azzera differenza cambio per ricalcolo
 | 
						|
  
 | 
						|
  TImporto new_abbuono;
 | 
						|
  new_ap = calcola_abbuono(nrigp, new_abbuono); // Calcolo abbuono in valuta
 | 
						|
 | 
						|
  new_abb = new_abbuono;                        // Calcola nuovo abbuono in lire
 | 
						|
  if (in_valuta())
 | 
						|
  {
 | 
						|
    new_abb.valore() *= sum.get_real(PART_CAMBIO);
 | 
						|
    new_abb.valore().round();
 | 
						|
  }  
 | 
						|
  new_abb.normalize();
 | 
						|
  
 | 
						|
  // Scambia sezione per registrazione contabile
 | 
						|
  old_abbuono.swap_section();          
 | 
						|
  new_abbuono.swap_section();          
 | 
						|
  new_abbuono.normalize(sum.sezione());
 | 
						|
  if (new_ap != ' ')
 | 
						|
    row(nrigp).put(PAGSCA_ABBUONI, new_abbuono.valore());
 | 
						|
  else
 | 
						|
    row(nrigp).zero(PAGSCA_ABBUONI);
 | 
						|
  
 | 
						|
  sum.update(old_abbuono, new_abbuono, PART_SEZABB, PART_ABBUONI);
 | 
						|
  
 | 
						|
  new_diffcam = calcola_differenza_cambio(nrigp, TRUE);
 | 
						|
  // Memorizza differenza cambi invertita, mettendo new_diffcam prima di old_diffcam!
 | 
						|
  sum.update(new_diffcam, old_diffcam, PART_SEZDIFCAM, PART_DIFFCAM);
 | 
						|
  
 | 
						|
  sum.update(old_pag, new_pag, PART_IMPORTO);
 | 
						|
  sum.update(old_pag, new_pag, PART_IMPORTOVAL);
 | 
						|
  sum.update(old_pag, new_pag, PART_RITENUTE);
 | 
						|
  
 | 
						|
  // Aggiorna flags di chiusura          
 | 
						|
  chiusa(TRUE);          
 | 
						|
  partita().chiusa(TRUE);             
 | 
						|
  
 | 
						|
  const bool empty = new_pag.get_char(PAGSCA_ACCSAL) != 'S' &&
 | 
						|
    new_pag.get_real(PAGSCA_IMPORTO).is_zero();
 | 
						|
  if (empty)
 | 
						|
    rows_array().destroy_row(nrigp);
 | 
						|
  
 | 
						|
  return empty;
 | 
						|
}
 | 
						|
 | 
						|
bool TRiga_scadenze::elimina_pagamento(int p)
 | 
						|
{
 | 
						|
  TRectype old_pag(row(p));
 | 
						|
  old_pag.put(PAGSCA_ACCSAL, "A");
 | 
						|
  old_pag.zero(PAGSCA_IMPORTO); 
 | 
						|
  old_pag.zero(PAGSCA_IMPORTOVAL);
 | 
						|
  return partita().modifica_pagamento(old_pag);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRiga_partite
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TRiga_partite::TRiga_partite(TPartita* game)
 | 
						|
: TTree_rectype(LF_PARTITE, LF_SCADENZE, SCAD_NRATA), _partita(game)
 | 
						|
{
 | 
						|
  CHECK(_partita, "Partita nulla");
 | 
						|
  TRiga_scadenze* scad = new TRiga_scadenze(this);
 | 
						|
  copy_key_to_row(*this);
 | 
						|
  rows_array().set_key(scad);               // Altrimenti le righe sarebbero dei TRectype!
 | 
						|
}  
 | 
						|
 | 
						|
TRiga_partite::TRiga_partite(const TRiga_partite& r)
 | 
						|
: TTree_rectype(r), _partita(r._partita)
 | 
						|
{
 | 
						|
  update_rigaptr();
 | 
						|
}  
 | 
						|
 | 
						|
void TRiga_partite::update_rigaptr()
 | 
						|
{
 | 
						|
  for (int i = rate(); i >= 0; i--)
 | 
						|
  {
 | 
						|
    TRiga_scadenze& scad = i == 0 ? (TRiga_scadenze&)rows_array().key() : rata(i);
 | 
						|
    scad._riga = this;
 | 
						|
  }  
 | 
						|
}
 | 
						|
 | 
						|
TRiga_scadenze& TRiga_partite::new_row(int r)
 | 
						|
{               
 | 
						|
  TRiga_scadenze& scad = (TRiga_scadenze&)TTree_rectype::new_row(r); 
 | 
						|
  scad._riga = this;
 | 
						|
  return scad;
 | 
						|
}   
 | 
						|
 | 
						|
void TRiga_partite::elimina_rate()
 | 
						|
{
 | 
						|
  for (int r = rate(); r > 0; r--)
 | 
						|
  {
 | 
						|
    TRiga_scadenze& scad = rata(r);
 | 
						|
    for (int p = scad.last(); p > 0; p = scad.pred(p))
 | 
						|
      scad.elimina_pagamento(p);
 | 
						|
    rows_array().destroy_row(r);  
 | 
						|
  }           
 | 
						|
}
 | 
						|
 | 
						|
int TRiga_partite::ultima_ratapagata() const
 | 
						|
{
 | 
						|
  for (int r = rate(); r > 0; r--)
 | 
						|
    if (rata(r).chiusa()) break;
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
int TRiga_partite::read(TBaseisamfile& f, word op)
 | 
						|
{                  
 | 
						|
  int err = TRectype::read(f, op);
 | 
						|
  if (err == NOERR && get_int(PART_TIPOMOV) == 1)
 | 
						|
  {
 | 
						|
    TRiga_scadenze* s = new TRiga_scadenze(this);             
 | 
						|
    err = rows_array().read(s);                // Deve esistere almento una scadenza
 | 
						|
    update_rigaptr();
 | 
						|
  }  
 | 
						|
  else 
 | 
						|
    rows_array().destroy_rows();
 | 
						|
  return err; 
 | 
						|
}
 | 
						|
 | 
						|
int TRiga_partite::ultimo_pagamento(int r) const
 | 
						|
{
 | 
						|
  const TRiga_scadenze& s = rata(r);
 | 
						|
  return s.last();
 | 
						|
}
 | 
						|
 | 
						|
bool TRiga_partite::update(const TRectype& vec, const TRectype& nuo, const char* field)
 | 
						|
{
 | 
						|
  real totale(get(field));
 | 
						|
  totale -= vec.get_real(field);
 | 
						|
  totale += nuo.get_real(field);
 | 
						|
  put(field, totale);
 | 
						|
  return totale.is_zero();
 | 
						|
}
 | 
						|
 | 
						|
bool TRiga_partite::update(const TImporto& vec, const TImporto& nuo, 
 | 
						|
                           const char* sez, const char* val)
 | 
						|
{  
 | 
						|
  bool zero = FALSE;                  
 | 
						|
  TImporto growth(nuo); growth -= vec;     // Variazione al totale
 | 
						|
 | 
						|
  if (!growth.is_zero())
 | 
						|
  {
 | 
						|
    TImporto totale(get_char(sez), get_real(val));
 | 
						|
    totale += growth;                      // incrementa il totale
 | 
						|
    totale.normalize();
 | 
						|
    put(sez, totale.sezione());            // Aggiorna il totale sul record
 | 
						|
    put(val, totale.valore());
 | 
						|
    zero = totale.is_zero();
 | 
						|
  }
 | 
						|
  else
 | 
						|
    zero = get_real(val).is_zero();
 | 
						|
  
 | 
						|
  return zero;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPartita
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TPartita::TPartita(const TBill& clifo, int anno, const char* num) 
 | 
						|
: _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP")
 | 
						|
{ 
 | 
						|
  read(clifo, anno, num); 
 | 
						|
}                    
 | 
						|
 | 
						|
const char* TPartita::build_key(TString& key) const
 | 
						|
{
 | 
						|
  if (_conto.tipo() > ' ')
 | 
						|
    key.format("%c%3d%3d%6ld%4d%s", _conto.tipo(), 0, 0, _conto.sottoconto(), 
 | 
						|
               _anno, (const char*)_num);
 | 
						|
  else
 | 
						|
    key.format("%c%3d%3d%6ld%4d%s", 
 | 
						|
               _conto.tipo(), _conto.gruppo(), _conto.conto(), _conto.sottoconto(), 
 | 
						|
               _anno, (const char*)_num);
 | 
						|
  return key;               
 | 
						|
}
 | 
						|
 | 
						|
int TPartita::compare(const TSortable& s) const
 | 
						|
{
 | 
						|
  TString80 key; build_key(key);
 | 
						|
  const TPartita& p = (const TPartita&)s;             
 | 
						|
  TString80 par; p.build_key(par);
 | 
						|
  return strcmp(key, par);
 | 
						|
}
 | 
						|
 | 
						|
// Costruisce le righe della partita
 | 
						|
bool TPartita::read(const TBill& clifo, int year, const char* num)
 | 
						|
{
 | 
						|
  _conto = clifo;
 | 
						|
  _anno  = year;
 | 
						|
  _num   = num;
 | 
						|
  TRiga_partite* partita = new TRiga_partite(this);        // Record campione della partita
 | 
						|
  TString16 str;
 | 
						|
  str << clifo.tipo();
 | 
						|
  partita->renum_key(PART_TIPOCF, str);                    // Tipo clifo
 | 
						|
  if (clifo.tipo() <= ' ')
 | 
						|
  {                                                        
 | 
						|
    str.cut(0); str << clifo.gruppo();
 | 
						|
    partita->renum_key(PART_GRUPPO, str);                  // Scrivi gruppo e conto solamente
 | 
						|
    str.cut(0); str << clifo.conto();                      // nei conti normali (no clifo)
 | 
						|
    partita->renum_key(PART_CONTO, str);                   
 | 
						|
  }                                   
 | 
						|
  str.cut(0); str << clifo.sottoconto();
 | 
						|
  partita->renum_key(PART_SOTTOCONTO, str);                // Sottoconto o codice clifo
 | 
						|
  str.cut(0); str << anno();
 | 
						|
  partita->renum_key(PART_ANNO, str);                      // Anno partita
 | 
						|
  partita->renum_key(PART_NUMPART, num);                   // Numero partita
 | 
						|
  _part.read(partita);
 | 
						|
 | 
						|
  TRectype* unas = new TRectype(LF_PAGSCA);                // Record pagamenti non assegnati
 | 
						|
  partita->copy_key_to_row(*unas);
 | 
						|
  unas->put(PART_NRIGA, (int)UNASSIGNED);                           
 | 
						|
  unas->put(SCAD_NRATA, (int)UNASSIGNED);
 | 
						|
  _unassigned.read(unas);
 | 
						|
  
 | 
						|
  return ok();
 | 
						|
}
 | 
						|
 | 
						|
bool TPartita::reread()
 | 
						|
{       
 | 
						|
  return read(conto(), anno(), numero());
 | 
						|
}
 | 
						|
 | 
						|
bool TPartita::write(bool re) const
 | 
						|
{                   
 | 
						|
  if (conto().tipo() > ' ')
 | 
						|
  {
 | 
						|
    for (int r = last(); r > 0; r = pred(r))
 | 
						|
    {
 | 
						|
      TRiga_partite& row = riga(r);
 | 
						|
      row.put(PART_GRUPPOCL, conto().gruppo());
 | 
						|
      row.put(PART_CONTOCL, conto().conto());
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  int err = _part.write(re);
 | 
						|
  if (err == NOERR)
 | 
						|
    err = _unassigned.write(re);
 | 
						|
  return err == NOERR;
 | 
						|
} 
 | 
						|
 | 
						|
bool TPartita::remove()
 | 
						|
{
 | 
						|
  _part.destroy_rows();
 | 
						|
  _unassigned.destroy_rows();
 | 
						|
  return rewrite();
 | 
						|
} 
 | 
						|
 | 
						|
 | 
						|
// Crea un  nuova riga partite
 | 
						|
TRiga_partite& TPartita::new_row(int r) 
 | 
						|
{                        
 | 
						|
  if (r <= 0)                   
 | 
						|
    for (r = 1; esiste(r); r++);
 | 
						|
  CHECKD(!esiste(r), "Ue' pirla!, esiste gia' la riga ", r);
 | 
						|
  TRiga_partite& nuova = (TRiga_partite&)_part.row(r, TRUE); 
 | 
						|
  return nuova;
 | 
						|
}
 | 
						|
 | 
						|
TRiga_scadenze& TPartita::rata(int nriga, int nrata) const
 | 
						|
{
 | 
						|
  if (nriga <= 0) nriga = prima_fattura();
 | 
						|
  const TRiga_partite& r = riga(nriga);
 | 
						|
  return r.rata(nrata);
 | 
						|
}
 | 
						|
 | 
						|
bool TPartita::rata_chiusa(int nriga, int nrata) const
 | 
						|
{        
 | 
						|
  bool pag = FALSE;
 | 
						|
  if (nriga != UNASSIGNED)
 | 
						|
  {
 | 
						|
    const TRiga_scadenze& r = rata(nriga, nrata);
 | 
						|
    pag = r.chiusa();
 | 
						|
  }
 | 
						|
  return pag;
 | 
						|
}
 | 
						|
 | 
						|
TRectype& TPartita::pagamento(int nriga, int nrata, int nrigp)
 | 
						|
{
 | 
						|
  if (nriga == UNASSIGNED)
 | 
						|
    return _unassigned.row(nrigp, TRUE);
 | 
						|
  TRiga_scadenze& r = rata(nriga, nrata);
 | 
						|
  return r.row(nrigp);
 | 
						|
}
 | 
						|
 | 
						|
bool TPartita::esiste(int nriga, int nrata, int nrigp) const
 | 
						|
{
 | 
						|
  if (nriga == UNASSIGNED)
 | 
						|
    return _unassigned.exist(nrigp);
 | 
						|
  
 | 
						|
  if (nrata <= 0)
 | 
						|
    return _part.exist(nriga);
 | 
						|
  
 | 
						|
  if (nrigp <= 0)
 | 
						|
  {
 | 
						|
    const TRiga_partite& r = riga(nriga);
 | 
						|
    return r.exist(nrata);
 | 
						|
  }  
 | 
						|
  
 | 
						|
  const TRiga_scadenze& r = rata(nriga, nrata);
 | 
						|
  return r.exist(nrigp);
 | 
						|
}
 | 
						|
 | 
						|
// Ritorna l'importo in lire speso su di una riga contabile
 | 
						|
TImporto TPartita::importo_speso(long nreg, int numrig) const
 | 
						|
{           
 | 
						|
  TImporto imp;
 | 
						|
  
 | 
						|
  for (int r = last(); r > 0; r = pred(r))
 | 
						|
  {
 | 
						|
    const TRiga_partite& part = riga(r);
 | 
						|
    if (nreg == part.get_long(PART_NREG) && numrig == part.get_int(PART_NUMRIG))
 | 
						|
    {
 | 
						|
      imp += TImporto(part.sezione(), part.get_real(PART_IMPORTO));
 | 
						|
 | 
						|
      TImporto abbuoni(part.get_char(PART_SEZABB), part.get_real(PART_ABBUONI));
 | 
						|
      const TValuta valuta(part);
 | 
						|
      if (!valuta.in_lire())            
 | 
						|
      {
 | 
						|
        valuta.val2lit(abbuoni);
 | 
						|
        imp += TImporto(part.get_char(PART_SEZDIFCAM), part.get_real(PART_DIFFCAM));
 | 
						|
      }  
 | 
						|
      imp += abbuoni;
 | 
						|
    }    
 | 
						|
  }
 | 
						|
  
 | 
						|
  return imp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPartita::update_reg(long nreg, const TRectype& mov)
 | 
						|
{                         
 | 
						|
  for (int r = last(); r > 0; r = pred(r))
 | 
						|
  {
 | 
						|
    TRiga_partite& rig = riga(r);
 | 
						|
    if (rig.get_long(PART_NREG) == nreg)
 | 
						|
    {
 | 
						|
      rig.put(PART_NREG,    mov.get(MOV_NUMREG));
 | 
						|
      rig.put(PART_DATAREG, mov.get(MOV_DATAREG));
 | 
						|
      rig.put(PART_DATADOC, mov.get(MOV_DATADOC));
 | 
						|
      rig.put(PART_NUMDOC,  mov.get(MOV_NUMDOC));
 | 
						|
      rig.put(PART_REG,     mov.get(MOV_REG));
 | 
						|
      rig.put(PART_PROTIVA, mov.get(MOV_PROTIVA));
 | 
						|
      rig.put(PART_CODCAUS, mov.get(MOV_CODCAUS));
 | 
						|
    }    
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// Calcola la riga di movimento relativa a una riga partita
 | 
						|
int TPartita::rig2mov(int rp) const
 | 
						|
{
 | 
						|
  const TRiga_partite& r = riga(rp);
 | 
						|
  return r.get_int(PART_NUMRIG);
 | 
						|
}
 | 
						|
 | 
						|
// Calcola la riga di partita relativa a una riga movimento
 | 
						|
int TPartita::mov2rig(long numreg, int rm) const
 | 
						|
{ 
 | 
						|
  for (int r = last(); r > 0; r = pred(r))
 | 
						|
  {
 | 
						|
    const TRiga_partite& row = riga(r);
 | 
						|
    if (row.get_long(PART_NREG) == numreg)
 | 
						|
    {
 | 
						|
      if (rm <= 0 || row.get_int(PART_NUMRIG) == rm)
 | 
						|
        return r;
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
} 
 | 
						|
 | 
						|
// Trova la prima riga della partita contenente una fattura
 | 
						|
int TPartita::prima_fattura(long nreg) const
 | 
						|
{  
 | 
						|
  const int lastrow = last();
 | 
						|
  for (int r = first(); r <= lastrow; r = succ(r))
 | 
						|
  {
 | 
						|
    const TRiga_partite& row = riga(r);
 | 
						|
    const int tipomov = row.get_int(PART_TIPOMOV);
 | 
						|
    if (tipomov == 1 || tipomov == 2)
 | 
						|
      if (nreg <= 0 || nreg == row.get_long(PART_NREG))
 | 
						|
        return r;
 | 
						|
  }
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
// Trova la prima riga della partita contenente una fattura
 | 
						|
int TPartita::primo_pagamento(long nreg) const
 | 
						|
{  
 | 
						|
  const int lastrow = last();
 | 
						|
  for (int r = first(); r <= lastrow; r = succ(r))
 | 
						|
  {
 | 
						|
    const TRiga_partite& row = riga(r);
 | 
						|
    const int tipomov = row.get_int(PART_TIPOMOV);
 | 
						|
    if (tipomov != 1)   
 | 
						|
      if (nreg <= 0 || nreg == row.get_long(PART_NREG))
 | 
						|
        return r;
 | 
						|
  }
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
void TPartita::calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImporto& imp) const
 | 
						|
{   
 | 
						|
  doc = pag = imp = TImporto('D', ZERO);
 | 
						|
 | 
						|
  for (int r = last(); r > 0; r = pred(r))
 | 
						|
  {
 | 
						|
    const TRiga_partite& row = riga(r);
 | 
						|
    TImporto i(row.get_char(PART_SEZ), row.get_real(PART_IMPORTO));
 | 
						|
    switch (row.get_int(PART_TIPOMOV))
 | 
						|
    {
 | 
						|
    case 1:
 | 
						|
    case 2:
 | 
						|
      doc += i;              // documenti
 | 
						|
      break;
 | 
						|
    case 3: 
 | 
						|
      pag += i;              // pagamenti
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      imp += i;              // altri importi
 | 
						|
      break;
 | 
						|
    }    
 | 
						|
    
 | 
						|
    TImporto abbuoni(row.get_char(PART_SEZABB), row.get_real(PART_ABBUONI));
 | 
						|
    if (row.get(PART_CODVAL).not_empty())
 | 
						|
    {
 | 
						|
      abbuoni.valore() *= row.get_real(PART_CAMBIO);
 | 
						|
      abbuoni.valore().round();
 | 
						|
    }
 | 
						|
 | 
						|
    imp += abbuoni;
 | 
						|
    imp += TImporto(row.get_char(PART_SEZDIFCAM), row.get_real(PART_DIFFCAM));
 | 
						|
  }
 | 
						|
 | 
						|
  saldo = doc;
 | 
						|
  saldo += pag;
 | 
						|
  saldo += imp;
 | 
						|
  
 | 
						|
  saldo.normalize();
 | 
						|
  doc.normalize();
 | 
						|
  pag.normalize();
 | 
						|
  imp.normalize();
 | 
						|
}
 | 
						|
 | 
						|
// Controlla se esistono pagamenti riferiti alla riga nrigp
 | 
						|
bool TPartita::utilizzata(int nrigp) const
 | 
						|
{           
 | 
						|
  for (int p = last(); p > 0; p = pred(p))
 | 
						|
  {
 | 
						|
    const TRiga_partite& fatt = riga(p);
 | 
						|
    for (int r = fatt.rate(); r > 0; r--)
 | 
						|
    {
 | 
						|
      const TRiga_scadenze& scad = fatt.rata(r);
 | 
						|
      if (scad.rows_array().exist(nrigp))
 | 
						|
        return TRUE;
 | 
						|
    }    
 | 
						|
  }           
 | 
						|
  return _unassigned.exist(nrigp);
 | 
						|
} 
 | 
						|
 | 
						|
bool TPartita::modifica_pagamento(const TRectype& new_pag, const TValuta& valuta, 
 | 
						|
                                  char& old_ap, TImporto& old_abb, TImporto& old_diffcam,  
 | 
						|
                                  char& new_ap, TImporto& new_abb, TImporto& new_diffcam)
 | 
						|
{                    
 | 
						|
  const int nriga = new_pag.get_int(PAGSCA_NRIGA);
 | 
						|
  const int nrata = new_pag.get_int(PAGSCA_NRATA);
 | 
						|
  const int nrigp = new_pag.get_int(PAGSCA_NRIGP);
 | 
						|
 | 
						|
  bool empty = FALSE;
 | 
						|
  
 | 
						|
  if (nriga != UNASSIGNED)    
 | 
						|
  {                       
 | 
						|
    TRiga_scadenze& scaden = rata(nriga, nrata);
 | 
						|
    empty = scaden.modifica_pagamento(new_pag, valuta,
 | 
						|
                                      old_ap, old_abb, old_diffcam,  
 | 
						|
                                      new_ap, new_abb, new_diffcam);
 | 
						|
  }                            
 | 
						|
  else
 | 
						|
  {                                    
 | 
						|
    const TRectype& old_pag = pagamento(nriga, nrata, nrigp);
 | 
						|
    
 | 
						|
    TRiga_partite& sum = riga(nrigp);
 | 
						|
    empty = sum.update(old_pag, new_pag, PART_IMPORTO);
 | 
						|
    sum.update(old_pag, new_pag, PART_IMPORTOVAL);
 | 
						|
    sum.update(old_pag, new_pag, PART_RITENUTE);
 | 
						|
    
 | 
						|
    if (new_pag.get_real(PAGSCA_IMPORTO).is_zero())        
 | 
						|
      _unassigned.destroy_row(nrigp);
 | 
						|
    else    
 | 
						|
      _unassigned.row(nrigp, FALSE) = new_pag;
 | 
						|
    
 | 
						|
    // Non ci possono essere abbuoni o differenze cambio di sorta!
 | 
						|
    old_ap = new_ap = ' ';       
 | 
						|
    old_abb = new_abb = old_diffcam = new_diffcam = TImporto('D', ZERO);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (empty && !utilizzata(nrigp))
 | 
						|
    rimuovi_riga(nrigp);
 | 
						|
 | 
						|
  return empty;    
 | 
						|
} 
 | 
						|
 | 
						|
 | 
						|
bool TPartita::modifica_pagamento(const TRectype& new_pag)
 | 
						|
{
 | 
						|
  char old_ap, new_ap;
 | 
						|
  TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam;
 | 
						|
  TValuta valuta;
 | 
						|
  return modifica_pagamento(new_pag, valuta,
 | 
						|
                            old_ap, old_abbuono, old_diffcam, 
 | 
						|
                            new_ap, new_abbuono, new_diffcam);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TPartita::chiusa(bool update)
 | 
						|
{ 
 | 
						|
  bool chiusa = FALSE;          
 | 
						|
  
 | 
						|
  if (update)
 | 
						|
  {
 | 
						|
    bool forse_chiusa = TRUE;
 | 
						|
    for (int p = last(); p > 0 && forse_chiusa; p = pred(p))
 | 
						|
    {
 | 
						|
      const TRiga_partite& part = riga(p);
 | 
						|
      if (part.get_int(PART_TIPOMOV) == 1)
 | 
						|
      {
 | 
						|
        for (int r = part.last(); r > 0; r--)
 | 
						|
        {
 | 
						|
          const TRiga_scadenze& scad = part.rata(r);
 | 
						|
          if (!scad.chiusa())
 | 
						|
          {
 | 
						|
            forse_chiusa = FALSE;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }  
 | 
						|
    
 | 
						|
    if (chiusa != forse_chiusa)
 | 
						|
    {
 | 
						|
      chiusa = forse_chiusa;
 | 
						|
      for (p = last(); p > 0; p = pred(p))
 | 
						|
      {
 | 
						|
        TRiga_partite& part = riga(p);
 | 
						|
        part.put(PART_CHIUSA, chiusa);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const int ultima = last();
 | 
						|
    if (ultima > 0)
 | 
						|
    {
 | 
						|
      const TRiga_partite& row = riga(ultima);
 | 
						|
      chiusa = row.get_bool(PART_CHIUSA);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return chiusa;
 | 
						|
}
 | 
						|
 | 
						|
void TPartita::rimuovi_riga(int r) 
 | 
						|
{                
 | 
						|
  TRiga_partite& row = riga(r);
 | 
						|
  if (row.rate() > 0)
 | 
						|
    row.elimina_rate();
 | 
						|
  else
 | 
						|
    CHECKD(!utilizzata(r), "Can't remove still referenced row ", r);
 | 
						|
  _part.destroy_row(r); 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void somma(const TRectype& vec, TRectype& nuo, const char* field)
 | 
						|
{
 | 
						|
  real totale(vec.get(field));
 | 
						|
  totale += nuo.get_real(field);
 | 
						|
  nuo.put(field, totale);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TPartita::sposta_riga(int r, TPartita& part)
 | 
						|
{
 | 
						|
  const TRiga_partite& row = riga(r);
 | 
						|
  const long nreg = row.get_long(PART_NREG);
 | 
						|
  const int prima = part.prima_fattura(nreg);
 | 
						|
  TRiga_partite& nrw = part.riga(prima);
 | 
						|
  
 | 
						|
  const int address_size = last()+1;
 | 
						|
  int* address = new int[address_size];
 | 
						|
  memset(address, 0, address_size*sizeof(int));
 | 
						|
 | 
						|
  TToken_string knames(256);
 | 
						|
  knames.add(PART_TIPOCF);
 | 
						|
  knames.add(PART_GRUPPO);
 | 
						|
  knames.add(PART_CONTO);
 | 
						|
  knames.add(PART_SOTTOCONTO);
 | 
						|
  knames.add(PART_ANNO);
 | 
						|
  knames.add(PART_NUMPART);
 | 
						|
  knames.add(PART_NRIGA);
 | 
						|
  knames.add(SCAD_NRATA);
 | 
						|
  knames.add(PAGSCA_NRIGP);
 | 
						|
  
 | 
						|
  for (int i = 1; i <= row.rate(); i++)
 | 
						|
  {                         
 | 
						|
    TRiga_scadenze& scd = row.rata(i);
 | 
						|
    for (int j = scd.last(); j > 0; j = scd.pred(j))
 | 
						|
    { 
 | 
						|
      const TRectype& pag = scd.row(j);
 | 
						|
      
 | 
						|
      CHECK(j < address_size, "Bad nrigp address");
 | 
						|
      if (address[j] == 0)
 | 
						|
      {                                       
 | 
						|
        const TRiga_partite& vecchia = riga(j);
 | 
						|
        TRiga_partite& nuova = part.new_row(part.esiste(j) ? 0 :j);
 | 
						|
        for (int f = 0; f < vecchia.items(); f++)
 | 
						|
        {
 | 
						|
          const char* fnam = vecchia.fieldname(f);
 | 
						|
          if (knames.get_pos(fnam) < 0)
 | 
						|
            nuova.put(fnam, vecchia.get(fnam));
 | 
						|
        }
 | 
						|
        nuova.zero(PART_IMPORTO);
 | 
						|
        nuova.zero(PART_IMPORTOVAL);
 | 
						|
        nuova.zero(PART_ABBUONI);
 | 
						|
        nuova.zero(PART_DIFFCAM);
 | 
						|
        address[j] = nuova.get_int(PART_NRIGA);
 | 
						|
      }        
 | 
						|
      
 | 
						|
      const int nrigp = address[j];
 | 
						|
      TRectype npg(LF_PAGSCA);
 | 
						|
      if (part.esiste(r, i, nrigp))
 | 
						|
      {  
 | 
						|
        npg = part.pagamento(r, i, nrigp);
 | 
						|
        somma(pag, npg, PART_IMPORTO);
 | 
						|
        somma(pag, npg, PART_IMPORTOVAL);
 | 
						|
        somma(pag, npg, PART_ABBUONI);
 | 
						|
        somma(pag, npg, PART_DIFFCAM);
 | 
						|
        npg.put(PAGSCA_ACCSAL, 'A');
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (nrw.exist(i))
 | 
						|
          npg = nrw.rata(i).new_row(nrigp);
 | 
						|
        else
 | 
						|
          npg = part.unassigned().row(nrigp, TRUE);
 | 
						|
        for (int f = 0; f < pag.items(); f++)
 | 
						|
        {
 | 
						|
          const char* fnam = pag.fieldname(f);
 | 
						|
          if (knames.get_pos(fnam) < 0)
 | 
						|
            npg.put(fnam, pag.get(fnam));
 | 
						|
        }    
 | 
						|
      }
 | 
						|
      part.modifica_pagamento(npg);
 | 
						|
      scd.elimina_pagamento(j);
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  
 | 
						|
  delete address;
 | 
						|
  rimuovi_riga(r);        
 | 
						|
}
 | 
						|
 | 
						|
// Sposta i pagamenti della riga r, dalla rata s compresa in poi, sui non assegnati
 | 
						|
void TPartita::scollega_pagamenti(int r, int s)
 | 
						|
{                          
 | 
						|
  CHECKD(s > 0, "Impossibile scollegare la rata ", s);
 | 
						|
  
 | 
						|
  const TRiga_partite& row = riga(r);
 | 
						|
  for (int i = row.rate(); i >= s; i--)
 | 
						|
  {                         
 | 
						|
    TRiga_scadenze& sc = row.rata(i);
 | 
						|
    for (int j = sc.last(); j > 0; j = sc.pred(j))
 | 
						|
    { 
 | 
						|
      TRectype& pag = sc.row(j);                              
 | 
						|
      CHECK(pag.get_real(PAGSCA_ABBUONI).is_zero(), "Can't remove payment with ABBUONI");
 | 
						|
      CHECK(pag.get_real(PAGSCA_DIFFCAM).is_zero(), "Can't remove payment with DIFFCAM");
 | 
						|
      pag.put(PAGSCA_ACCSAL, 'A');
 | 
						|
      pag.put(PAGSCA_NRIGA, (int)TPartita::UNASSIGNED);
 | 
						|
      pag.put(PAGSCA_NRATA, (int)TPartita::UNASSIGNED);  
 | 
						|
      _unassigned.add_row(pag);
 | 
						|
      sc.rows_array().destroy_row(j);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPartite_array
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 99%              
 | 
						|
const TString& TPartite_array::key(const TBill& clifo, int anno, const char* num)
 | 
						|
{                  
 | 
						|
  if (clifo.tipo() > ' ')
 | 
						|
    _key.format("%c%3d%3d%6ld%4d%s", clifo.tipo(), 0, 0, clifo.sottoconto(), anno, num);
 | 
						|
  else
 | 
						|
    _key.format("%c%3d%3d%6ld%4d%s", 
 | 
						|
                clifo.tipo(), clifo.gruppo(), clifo.conto(), clifo.sottoconto(), anno, num);
 | 
						|
  return _key;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 99%              
 | 
						|
TPartita* TPartite_array::find(const TBill& clifo, int anno, const char* num, bool create)
 | 
						|
{
 | 
						|
  const TString& k = key(clifo, anno, num);
 | 
						|
  TPartita* p = (TPartita*)objptr(k);
 | 
						|
  if (p == NULL && create)
 | 
						|
  {
 | 
						|
    p = new TPartita(clifo, anno, num);
 | 
						|
    add(k, p);
 | 
						|
  }
 | 
						|
  return p;
 | 
						|
}
 | 
						|
 | 
						|
TPartita* TPartite_array::find(const TRectype& r, bool create)
 | 
						|
{                           
 | 
						|
  TBill zio; zio.get(r);
 | 
						|
  if (zio.gruppo() == 0)
 | 
						|
  {
 | 
						|
    zio.set(r.get_int(PART_GRUPPOCL), r.get_int(PART_CONTOCL), 
 | 
						|
            zio.sottoconto(), zio.tipo());
 | 
						|
  }
 | 
						|
  const int anno = r.get_int(PART_ANNO);
 | 
						|
  const char* num = r.get_str(PART_NUMPART);
 | 
						|
  return find(zio, anno, num, create);
 | 
						|
}
 | 
						|
 | 
						|
TPartita& TPartite_array::partita(const TBill& clifo, int anno, const char* num)
 | 
						|
{                           
 | 
						|
  TPartita* game = find(clifo, anno, num, TRUE);
 | 
						|
  CHECK(game, "Partita errata");
 | 
						|
  return *game;
 | 
						|
}
 | 
						|
 | 
						|
TPartita& TPartite_array::partita(const TRectype& r)
 | 
						|
{                           
 | 
						|
  TPartita* game = find(r, TRUE);
 | 
						|
  CHECK(game, "Partita errata");
 | 
						|
  return *game;
 | 
						|
}
 | 
						|
 | 
						|
bool TPartite_array::destroy(const TBill& clifo, int anno, const char* num)
 | 
						|
{
 | 
						|
  const TString& k = key(clifo, anno, num);
 | 
						|
  return remove(k);
 | 
						|
}
 | 
						|
 | 
						|
bool TPartite_array::write(bool re)
 | 
						|
{       
 | 
						|
  int err = NOERR;
 | 
						|
  
 | 
						|
  TPartita* game;
 | 
						|
  restart();
 | 
						|
  while ((game = (TPartita*)get()) != NULL)
 | 
						|
  {
 | 
						|
    err = game->write(re);
 | 
						|
    if (err != NOERR)    // L'errore viene gia' segnalato dalla partita
 | 
						|
      break;
 | 
						|
  }  
 | 
						|
  
 | 
						|
  return err == NOERR;
 | 
						|
}
 | 
						|
 | 
						|
void TPartite_array::destroy() 
 | 
						|
{ 
 | 
						|
  TAssoc_array::destroy(); 
 | 
						|
  _numreg = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Aggiunge all'array tutte le partite che si riferiscono alla registrazione nreg
 | 
						|
int TPartite_array::add_numreg(long nreg)
 | 
						|
{                                       
 | 
						|
  if (nreg != _numreg)
 | 
						|
  {
 | 
						|
    TRelation rel(LF_PARTITE);
 | 
						|
    TRectype& part = rel.curr(); 
 | 
						|
    
 | 
						|
    // Costruzione cursore filtrato
 | 
						|
    part.zero();
 | 
						|
    part.put(PART_NREG, nreg);
 | 
						|
    const TRectype filter(part);    
 | 
						|
    TCursor cur(&rel, "", 2, &filter, &filter);
 | 
						|
    
 | 
						|
    for (cur = 0; cur.ok(); ++cur)
 | 
						|
      partita(part);                // Aggiungi partita se non esiste gia'
 | 
						|
 | 
						|
    _numreg = nreg;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return items();
 | 
						|
}
 | 
						|
 | 
						|
bool TPartite_array::utilizzata(long numreg, int numrig)
 | 
						|
{
 | 
						|
  bool ok = FALSE;
 | 
						|
  for (TPartita* game = first(); game; game = next())
 | 
						|
  {
 | 
						|
    ok = game->mov2rig(numreg, numrig) > 0;
 | 
						|
    if (ok) break;
 | 
						|
  }  
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TImporto TPartite_array::importo_speso(long nreg, int numrig)
 | 
						|
{
 | 
						|
  TImporto imp;
 | 
						|
  add_numreg(nreg);
 | 
						|
  for (TPartita* game = first(); game; game = next())
 | 
						|
    imp += game->importo_speso(nreg, numrig);
 | 
						|
  imp.normalize();
 | 
						|
  return imp;
 | 
						|
}
 | 
						|
 | 
						|
void TPartite_array::update_reg(const TRectype& mov, long old_nreg)
 | 
						|
{
 | 
						|
  if (old_nreg <= 0)
 | 
						|
    old_nreg = mov.get_long(MOV_NUMREG);
 | 
						|
  add_numreg(old_nreg);      
 | 
						|
  for (TPartita* game = first(); game; game = next())
 | 
						|
    game->update_reg(old_nreg, mov);
 | 
						|
}
 | 
						|
 |