Ristrutturazione pagameeeento (in corso)
git-svn-id: svn://10.65.10.50/trunk@2401 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
6d8b72549a
commit
0e1fc90ebb
761
cg/pagament.cpp
761
cg/pagament.cpp
@ -7,6 +7,11 @@
|
||||
#include <scadenze.h>
|
||||
#include <pagsca.h>
|
||||
|
||||
// se settato, si usa per rate nuove l'intervallo rate default (letto da
|
||||
// tab. pagamenti)
|
||||
#define USE_DEFAULT_INT_RATE
|
||||
|
||||
|
||||
inline void swap(int& x, int& y) {int tmp = x; x = y; y = tmp; }
|
||||
|
||||
int TPagamento::_rata_ifield(int n, int f) const
|
||||
@ -386,7 +391,6 @@ void TPagamento::set_cambio(const real& cambio)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TPagamento::next_scad(TDate& d, int scad, bool mcomm, int rata)
|
||||
{
|
||||
if (mcomm)
|
||||
@ -458,6 +462,24 @@ void TPagamento::remove_rata(int i)
|
||||
_dirty = TRUE;
|
||||
}
|
||||
|
||||
void TPagamento::remove_rate_from(int i)
|
||||
{
|
||||
// elimina dall'ultima a quella indicata (compresa)
|
||||
for (int j = n_rate() - 1; j >= i; j--)
|
||||
_rate.destroy(j);
|
||||
_dirty = TRUE;
|
||||
}
|
||||
|
||||
|
||||
TToken_string& TPagamento::add_rata()
|
||||
{
|
||||
// rata vuota, con -1 sulla scadenza per segnalare
|
||||
TToken_string* tt = new TToken_string("-1| | | | | | ");
|
||||
_rate.add(tt);
|
||||
_dirty = TRUE;
|
||||
return *tt;
|
||||
}
|
||||
|
||||
TToken_string& TPagamento::add_rata(real perc, int day, int type, const char* ulc)
|
||||
{
|
||||
TToken_string* tt = new TToken_string(64);
|
||||
@ -754,7 +776,7 @@ word TPagamento::recalc_rate(int row, bool is_perc_modified,
|
||||
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;
|
||||
if (_rate.items() == 0) return P_OK;
|
||||
|
||||
real rsum(0.0), newv(0.0), rmax(0.0);
|
||||
const int last_rata = _rate.items() - 1;
|
||||
@ -765,37 +787,12 @@ word TPagamento::recalc_rate(int row, bool is_perc_modified,
|
||||
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(srate.items() - 1);
|
||||
// if (_mcomm)
|
||||
// {
|
||||
// int mesi = oldscad / 30;
|
||||
// if (mesi == 0) mesi = 1;
|
||||
// oldscad = 30 * mesi;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
if (oldscad <= 0) oldscad = _int_rate;
|
||||
if (oldtype <= 0) oldtype = _def_tpr;
|
||||
|
||||
if (new_value != NULL)
|
||||
{
|
||||
newv = new_value;
|
||||
rmax = is_perc_modified ? real(100.0) : (_tpr < 4 ? _firstr : _secndr);
|
||||
real test_value(newv);
|
||||
if (_tpr > 0 && _tpr < 4 && row == 0)
|
||||
test_value -= _secndr;
|
||||
if (test_value < ZERO) return P_NEG;
|
||||
if (test_value > rmax) return P_TROP;
|
||||
}
|
||||
|
||||
bool exhausted = FALSE;
|
||||
|
||||
for (int i = 0 /* first */; i < srate.items(); i++)
|
||||
for (int i = 0; i < srate.items(); i++)
|
||||
{
|
||||
if (i == row)
|
||||
{
|
||||
@ -861,7 +858,7 @@ word TPagamento::recalc_rate(int row, bool is_perc_modified,
|
||||
{
|
||||
TToken_string& tt = rata(j);
|
||||
TToken_string& ss = (TToken_string&)srate[j];
|
||||
next_scad(ddd,scad_rata(j),mcomm,j);
|
||||
next_scad(ddd,scad_rata(j), mcomm,j);
|
||||
tt.add(ddd.string(),3);
|
||||
ss.add(ddd.string(),3);
|
||||
need_recalc = TRUE;
|
||||
@ -884,395 +881,314 @@ word TPagamento::recalc_rate(int row, bool is_perc_modified,
|
||||
}
|
||||
}
|
||||
|
||||
// here's the bell
|
||||
if (new_value != NULL)
|
||||
{
|
||||
real totogl((row == first && _inited && _tpr > 0 && _tpr < 4) ? _secndr : 0.0);
|
||||
if (newv == ZERO || (rsum+newv-totogl) > rmax)
|
||||
return P_RSUM;
|
||||
// did not sforate
|
||||
rsum += newv-totogl;
|
||||
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
|
||||
// -------------------------------- vedi se rimettere -----------------------------------
|
||||
// if (rdiff == 3 && (remainder % newv) != 0.0)
|
||||
// {
|
||||
// warning_box("Il resto non e' divisibile - uso 'Uguali finche' possibile'");
|
||||
// rdiff = 4;
|
||||
// }
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// *** 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
|
||||
real imp(remainder);
|
||||
|
||||
if (_inited && _tpr >= 4 )
|
||||
imp += _firstr;
|
||||
if (row < (srate.items()-1))
|
||||
{
|
||||
TToken_string& trt = rata(row+1);
|
||||
trt.add(imp.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 ? imp : (real) 0.0,
|
||||
oldscad, oldtype, oldulc);
|
||||
if (!is_perc_modified) trt.add(imp.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;
|
||||
TString nulc = oldulc;
|
||||
int nscd = oldscad;
|
||||
int frstd = scad_rata(0);
|
||||
|
||||
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 /*28/12/95 +first */)
|
||||
{
|
||||
// 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 == 0 /* 28/12/95 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 - first);
|
||||
div.round(is_perc_modified ? 2 : _round);
|
||||
nimp = tot - (div * real(n-1-first));
|
||||
|
||||
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 ? frstd : 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, nulc, 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[0 /* 28/12/95 first */];
|
||||
real rfirst(is_perc_modified ? trt.get(1) : trt.get(4));
|
||||
if (!delta.is_zero()) rfirst -= delta;
|
||||
if (_tpr >= 4) rfirst = ZERO;
|
||||
real rest = tot - rfirst;
|
||||
real div = rest / nimp;
|
||||
if (div < real(1.0)) { _rate = srate; return P_TROP; }
|
||||
|
||||
int nr = (int)div.integer() + 1 /* 28/12/95 (_tpr > 3 ? 2 : 1) */;
|
||||
real reminder = rest - (nimp * real(nr - 1 /*28/12/95 - first */));
|
||||
rfirst += reminder;
|
||||
if (_tpr >= 4) rfirst += nimp;
|
||||
for (int k = first; k < nr; k++)
|
||||
{
|
||||
nscd = oldscad;
|
||||
type = oldtype;
|
||||
TString16 ulc(oldulc);
|
||||
|
||||
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, NULL, dd.string());
|
||||
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
|
||||
TString16 ulc(oldulc);
|
||||
if (j < srate.items())
|
||||
{
|
||||
TToken_string& trt = (TToken_string&)srate[j];
|
||||
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 (j > 0 && nscd == 0) nscd = oldscad;
|
||||
if (_inited && dd == lastdate && j > frs)
|
||||
next_scad(dd,nscd,mcomm,j);
|
||||
}
|
||||
else if (_inited)
|
||||
{
|
||||
if (dd <= botime) dd = lastdate;
|
||||
if (j > 0 && nscd == 0) nscd = oldscad;
|
||||
next_scad(dd,nscd,mcomm,j);
|
||||
}
|
||||
else nscd = _int_rate;
|
||||
|
||||
real imp(newv);
|
||||
TToken_string& ttr = set_rata(j, is_perc_modified ? imp : ZERO,
|
||||
nscd, type, ulc);
|
||||
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
|
||||
imp += (mx - sum);
|
||||
if (rdiff == 3)
|
||||
{
|
||||
imp = is_perc_modified ? perc_rata(first) : tpay_rata(first);
|
||||
imp += (mx - sum);
|
||||
}
|
||||
if (_inited && _tpr >0 && _tpr < 4)
|
||||
imp += _secndr;
|
||||
if (!is_perc_modified)
|
||||
set_imprata(first, imp);
|
||||
else {
|
||||
TToken_string& t = rata(first);
|
||||
t.add(imp.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
|
||||
TString16 ulc(oldulc);
|
||||
if (j < srate.items())
|
||||
{
|
||||
TToken_string& trt = (TToken_string&)srate[j];
|
||||
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 (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, ulc);
|
||||
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); // * cento???
|
||||
}
|
||||
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.is_zero() ? real(0.0) :
|
||||
(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);
|
||||
// }
|
||||
}
|
||||
|
||||
// sistema scadenze fisse
|
||||
adjust_fixed_scad();
|
||||
|
||||
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 (new_value != NULL)
|
||||
{
|
||||
need_recalc = TRUE;
|
||||
// questa la subappaltiamo, per evitare l'inferno
|
||||
return change_value(row, real(new_value), rdiff, is_perc_modified);
|
||||
}
|
||||
}
|
||||
else // i != row modified
|
||||
{
|
||||
if (rdiff == 2)
|
||||
rdiff = 1;
|
||||
_rdiff = TRUE;
|
||||
}
|
||||
if (is_perc_modified)
|
||||
rsum += perc_rata(i);
|
||||
else
|
||||
{
|
||||
rsum += tpay_rata(i);
|
||||
if (i == 0 && _tpr > 0 && _tpr < 4)
|
||||
rsum -= _secndr;
|
||||
}
|
||||
lastdate = data_rata(i);
|
||||
// oldtype = tipo_rata(i);
|
||||
// if (scad_rata(i) > 0) oldscad = scad_rata(i);
|
||||
if (_inited && i > 0)
|
||||
{
|
||||
if (data_rata(i) <= data_rata(i-1))
|
||||
return P_SCAD;
|
||||
}
|
||||
else if (_inited && lastdate < _inizio)
|
||||
return P_INIZIO;
|
||||
}
|
||||
continue;
|
||||
|
||||
if (scad != NULL)
|
||||
{
|
||||
// check sulle scadenze solo se si sono modificate
|
||||
lastdate = data_rata(i);
|
||||
|
||||
if (_inited && i > 0)
|
||||
{
|
||||
if (data_rata(i) <= data_rata(i-1))
|
||||
return P_SCAD;
|
||||
}
|
||||
else if (_inited && lastdate < _inizio)
|
||||
return P_INIZIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
adjust_fixed_scad();
|
||||
return P_OK;
|
||||
}
|
||||
|
||||
word TPagamento::change_value(int rata, real user_val, int rdiff, bool is_perc)
|
||||
{
|
||||
word err = 0;
|
||||
|
||||
switch (rdiff)
|
||||
{
|
||||
case 1:
|
||||
err = change_value_differenziate(rata, user_val, is_perc);
|
||||
break;
|
||||
case 2:
|
||||
err = change_value_uguali(rata, user_val, is_perc);
|
||||
break;
|
||||
case 3:
|
||||
err = change_value_uguali_prossima(rata, user_val, is_perc);
|
||||
break;
|
||||
case 4:
|
||||
err = change_value_uguali_possible(rata, user_val, is_perc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!err)
|
||||
{
|
||||
// riaggiusta gli altri parametri se si sono create rate nuove
|
||||
adjust_parameters();
|
||||
// risistema scadenze fisse se necessario
|
||||
adjust_fixed_scad();
|
||||
// riaggiusta le percentuali o gli importi rispetto al dato modificato
|
||||
if (_inited) adjust_perc_imp(is_perc, rdiff);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// le quattro che seguono modificano le rate (solo importi o percentuali), e
|
||||
// lasciano in last_old l'indice dell'ultima rata rimasta dalle vecchie che
|
||||
// hanno adoperato
|
||||
|
||||
word TPagamento::change_value_differenziate(int row, real user_val, bool is_perc)
|
||||
{
|
||||
// importi totali, da non suddividere, da suddividere
|
||||
real to_share = is_perc ? real(100.0) : (_tpr < 4 ? _firstr : _secndr);
|
||||
real to_subtract = ZERO;
|
||||
if (row == 0 && _tpr > 0 && _tpr < 4 && !is_perc)
|
||||
to_subtract = _secndr;
|
||||
real user_div = user_val - to_subtract;
|
||||
int first = _tpr > 3 ? 1 : 0;
|
||||
_rdiff = TRUE;
|
||||
|
||||
// togli rate gia' presenti
|
||||
for (int i = first; i < row; i++)
|
||||
{
|
||||
to_share -= (is_perc ? perc_rata(i): tpay_rata(i));
|
||||
if (i == 0 && !is_perc && _tpr > 0 && _tpr < 4)
|
||||
to_share += _secndr;
|
||||
}
|
||||
|
||||
real remainder = to_share - user_div;
|
||||
|
||||
int tok_ind = is_perc ? 1 : 4;
|
||||
rata(row).add(user_div.string(), tok_ind);
|
||||
|
||||
if (!remainder.is_zero())
|
||||
{
|
||||
if (n_rate() <= row + 1) add_rata();
|
||||
rata(row+1).add(remainder.string(), tok_ind);
|
||||
}
|
||||
|
||||
// elimina rate successive
|
||||
remove_rate_from(row+2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
word TPagamento::change_value_uguali(int row, real user_val, bool is_perc)
|
||||
{
|
||||
// importi totali, da non suddividere, da suddividere
|
||||
real to_share = is_perc ? real(100.0) : (_tpr < 4 ? _firstr : _secndr);
|
||||
real to_subtract = ZERO;
|
||||
if (row == 0 && _tpr > 0 && _tpr < 4 && !is_perc)
|
||||
to_subtract = _secndr;
|
||||
real user_div = user_val - to_subtract;
|
||||
real remainder = to_share - user_div;
|
||||
int tok_ind = is_perc ? 1 : 4;
|
||||
int first = _tpr > 3 ? 1 : 0;
|
||||
_rdiff = FALSE;
|
||||
|
||||
if (user_div.is_zero() || user_div.sign() == -1)
|
||||
return P_NEG;
|
||||
|
||||
// la prima viene mantenuta uguale (vale solo per la 0 anche se _tpr > 4)
|
||||
|
||||
// se si modifica la prima, si suddivide l'importo rimanente tra tutte le
|
||||
// altre e si aggiunge il residuo alla prima; il n. rate viene mantenuto
|
||||
if (row == 0)
|
||||
{
|
||||
if (n_rate() == 1)
|
||||
{
|
||||
// se il numero rate e' 1 si aggiungono rate uguali a coprire l'importo
|
||||
if ((to_share - user_div) < user_div) return 0;
|
||||
real div = to_share / user_div;
|
||||
real delta = to_share - (user_div * div.integer());
|
||||
for (int i = 0; i < div.integer(); i++)
|
||||
{
|
||||
if (n_rate() <= i) add_rata();
|
||||
rata(i).add(i == 0 ? user_val.string() : user_div.string(), tok_ind);
|
||||
}
|
||||
|
||||
// add residuo
|
||||
if (!delta.is_zero())
|
||||
{
|
||||
real tp = is_perc ? perc_rata(first) : tpay_rata(first);
|
||||
tp += delta;
|
||||
rata(first).add(tp.string(), tok_ind);
|
||||
}
|
||||
}
|
||||
else // n. rate > 1, modificata la rata 0: _tpr e' per forza < 4
|
||||
{
|
||||
real div = remainder / real(n_rate() - 1);
|
||||
div.round(is_perc ? 3 : _round);
|
||||
real delta = remainder - (div * real(n_rate() - 1));
|
||||
|
||||
rata(0).add(user_val.string(), tok_ind);
|
||||
if (remainder.is_zero())
|
||||
{
|
||||
remove_rate_from(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ripartisci il resto
|
||||
for (int i = 1; i < n_rate(); i++)
|
||||
rata(i).add(div.string(), tok_ind);
|
||||
|
||||
if (!delta.is_zero())
|
||||
{
|
||||
user_val += delta;
|
||||
rata(0).add(div.string(), tok_ind);
|
||||
}
|
||||
}
|
||||
}
|
||||
// dalla seconda in poi, tutte le rate devono essere uguali a quella indicata
|
||||
// (a meno dell'importo non suddivisibile se c'e' (to_subtract); il numero rate
|
||||
// puo' cambiare. Si rispetta il valore della rata 0
|
||||
// se c'e' un residuo lo metto sulla prima calcolabile (dipende da _tpr)
|
||||
else
|
||||
{
|
||||
real first_imp;
|
||||
if (_tpr < 4)
|
||||
{
|
||||
first_imp = is_perc ? perc_rata(0) : tpay_rata(0);
|
||||
if (_tpr > 0) first_imp -= _secndr;
|
||||
}
|
||||
real div = (to_share - first_imp)/user_val;
|
||||
if (div < real(1.0)) return P_TROP;
|
||||
real delta = (to_share - first_imp) - user_val * real(div.integer());
|
||||
for (int i = 1; i < div.integer()+1l; i++)
|
||||
{
|
||||
if (n_rate() <= i) add_rata();
|
||||
rata(i).add(user_val.string(), tok_ind);
|
||||
}
|
||||
|
||||
remove_rate_from(i);
|
||||
|
||||
if (!delta.is_zero())
|
||||
{
|
||||
real tp = is_perc ? perc_rata(first) : tpay_rata(first);
|
||||
tp += delta;
|
||||
rata(first).add(tp.string(), tok_ind);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
word TPagamento::change_value_uguali_prossima(int rata, real user_val, bool is_perc)
|
||||
{
|
||||
_rdiff = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
word TPagamento::change_value_uguali_possible(int rata, real user_val, bool is_perc)
|
||||
{
|
||||
_rdiff = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TPagamento::adjust_parameters()
|
||||
{
|
||||
TDate last_date;
|
||||
int last_type;
|
||||
TString16 last_ulc;
|
||||
int last_scad;
|
||||
|
||||
for (int i = 0; i < n_rate(); i++)
|
||||
{
|
||||
if (scad_rata(i) != -1)
|
||||
{
|
||||
last_date = data_rata(i);
|
||||
last_type = tipo_rata(i);
|
||||
last_ulc = ulc_rata(i);
|
||||
last_scad = scad_rata(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
TToken_string& r = rata(i);
|
||||
r.add(last_scad, 0);
|
||||
r.add(last_type, 2);
|
||||
r.add(last_ulc, 5);
|
||||
if (_inited)
|
||||
{
|
||||
#ifdef USE_DEFAULT_INT_RATE
|
||||
next_scad(last_date, last_scad == 0 ? _int_rate : last_scad, _mcomm, i);
|
||||
#else
|
||||
next_scad(last_date, last_scad, _mcomm, i);
|
||||
#endif
|
||||
r.add(last_date, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TPagamento::adjust_perc_imp(bool is_perc, int rdiff)
|
||||
{
|
||||
real toshare(100.0); real other(100.0);
|
||||
if (is_perc)
|
||||
toshare = (_tpr < 4 ? _firstr : _secndr);
|
||||
else
|
||||
other = (_tpr < 4 ? _firstr : _secndr);
|
||||
|
||||
TDistrib dt(toshare, is_perc ? _round : 3);
|
||||
const int first = _tpr > 3 ? 1 : 0;
|
||||
|
||||
for (int j = first; j < _rate.items(); j++)
|
||||
{
|
||||
real rvl = is_perc ? perc_rata(j) : tpay_rata(j);
|
||||
// togli pezxo di troppo
|
||||
if (!is_perc && j == first && _tpr > 0 && _tpr < 4)
|
||||
rvl -= _secndr;
|
||||
real zpx = rvl/other; // percentuale
|
||||
dt.add(zpx); // * cento???
|
||||
}
|
||||
|
||||
for (j = first; j < n_rate(); 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.is_zero() ? real(0.0) :
|
||||
(reminder / real(_rate.items() - (1+first)));
|
||||
rdiv.round( is_perc ? _round : 2);
|
||||
rfirst += reminder - (rdiv * real(_rate.items() - (1+first)));
|
||||
rvl = rdiv;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_perc && j == first && _tpr > 0 && _tpr < 4)
|
||||
rfirst += _secndr;
|
||||
|
||||
tr.add((j == first ? rfirst.string() : rvl.string()), is_perc ? 4 : 1);
|
||||
|
||||
if (_cambio != 1.0)
|
||||
{
|
||||
real implit(tpay_rata(j));
|
||||
implit *= _cambio;
|
||||
implit.round();
|
||||
tr.add(implit.string(), 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TPagamento::read(TTable* t, TTable* r)
|
||||
{
|
||||
@ -1290,15 +1206,16 @@ bool TPagamento::read(TTable* t, TTable* r)
|
||||
_rate.destroy();
|
||||
|
||||
// set everything
|
||||
_rdiff = t->get_bool("B1");
|
||||
_mcomm = t->get_bool("B0");
|
||||
_tpr = t->get_int("S3");
|
||||
_inscad = t->get_char("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");
|
||||
_rdiff = t->get_bool("B1");
|
||||
_mcomm = t->get_bool("B0");
|
||||
_tpr = t->get_int("S3");
|
||||
_inscad = t->get_char("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");
|
||||
_int_rate = t->get_int("I3");
|
||||
|
||||
// aggiusta _inizio secondo INSCAD; vedi mese commerciale etc.
|
||||
if (_inscad == 'M')
|
||||
@ -1384,7 +1301,7 @@ int TPagamento::rewrite(TTable& r)
|
||||
err = (was ? r.rewrite() : r.write());
|
||||
}
|
||||
|
||||
// erase possible rates > current n. rates
|
||||
// erase possible rate > current n. rate
|
||||
for (;err == NOERR;i++)
|
||||
{
|
||||
r.zero(); s.format("%s%3d",(const char*)_code, i);
|
||||
|
@ -59,6 +59,19 @@ class TPagamento : public TObject
|
||||
int _def_tpr; // tipo rata default
|
||||
TString16 _def_ulc; // ulteriore classificazione default
|
||||
|
||||
// gestione casino se si modificano importi o percentuali rate
|
||||
word change_value(int rata, real new_val, int rdiff, bool is_perc);
|
||||
word change_value_differenziate(int rata, real value, bool is_perc);
|
||||
word change_value_uguali(int rata, real value, bool is_perc);
|
||||
word change_value_uguali_prossima(int rata, real value, bool is_perc);
|
||||
word change_value_uguali_possible(int rata, real value, bool is_perc);
|
||||
|
||||
// aggiusta parametri diversi da importo se si sono aggiunte rate
|
||||
void adjust_parameters();
|
||||
// riaggiusta le percentuali o gli importi rispetto al dato modificato
|
||||
void adjust_perc_imp(bool is_perc, int rdiff);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// pregasi notare la straordinaria dovizia di const
|
||||
@ -93,8 +106,6 @@ public:
|
||||
|
||||
// giorni scadenza fissi, aggiunti poi
|
||||
void set_fixed_scad(int a, int ind) { _fixd[ind] = a; }
|
||||
// aggiusta scadenze fisse (tutte in un colpo)
|
||||
void adjust_fixed_scad();
|
||||
|
||||
// queste vengono usate solo per movimenti editabili nella struttura
|
||||
// (da tabella pagamenti) e riaggiustano tutte le rate in accordo
|
||||
@ -132,6 +143,7 @@ public:
|
||||
// modifica rate manualmente o non
|
||||
TToken_string& rata(int r) { return (TToken_string&)_rate[r]; }
|
||||
TToken_string& add_rata (real perc, int day, int type, const char* ulc = "");
|
||||
TToken_string& add_rata ();
|
||||
TToken_string& set_rata (int index, real perc, int day, int type,
|
||||
const char* ulc = NULL, const char* imp = NULL,
|
||||
const char* data = NULL);
|
||||
@ -146,6 +158,7 @@ public:
|
||||
void set_default_ulc(const char* ulc, bool change_existing = TRUE);
|
||||
|
||||
void remove_rata(int r);
|
||||
void remove_rate_from(int r);
|
||||
void zap_rate () { _rate.destroy(); }
|
||||
// calcola le rate automaticamente secondo quanto specificato
|
||||
void set_rate_auto();
|
||||
@ -166,9 +179,12 @@ public:
|
||||
const char* scad, const char* typ, const char* ulc, int rdiff,
|
||||
bool mcomm, bool& need_recalc);
|
||||
|
||||
// aggiusta scadenze fisse (tutte in un colpo)
|
||||
void adjust_fixed_scad();
|
||||
// determina la prossima scadenza
|
||||
void next_scad(TDate& d, int scad, bool mcomm, int rata);
|
||||
|
||||
|
||||
// se codtab non e' NULL legge da file (e da' errore se non c'e')
|
||||
// se si vuole fare un pagamento nuovo si da' il codice con set_code
|
||||
TPagamento(const char* codtab = NULL, const char* data = NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user