Separato saldacon da pagament

git-svn-id: svn://10.65.10.50/trunk@1733 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1995-08-24 07:39:29 +00:00
parent 79ff0b8518
commit f4b8fb1e12
5 changed files with 949 additions and 13 deletions

View File

@ -131,14 +131,9 @@ bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k)
if (importo != speso)
{
ok = yesno_box("L'importo dei pagamenti %c %s\ne' diverso dall'importo sulla riga %d.\n"
"Si desidera correggerlo?", speso.sezione(), speso.valore().string("."), currig);
if (ok)
{
const bool dare = speso.sezione() == 'D';
m.set(101, dare ? speso.valore().string() : "");
m.set(102, dare ? "" : speso.valore().string());
}
ok = yesno_box("L'importo della riga %d dovrebbe essere %c %s\n"
"Si desidera correggerlo?", currig, speso.sezione(), speso.valore().string("."));
if (ok) app().set_cgs_imp(riga, speso);
}
}
}
@ -301,6 +296,13 @@ void TPrimanota_application::set_cgs_imp(int n, const TImporto& imp)
TSheet_field& s = cgs();
imp.add_to(s.row(n), 0);
s.force_update(n);
TMask& m = s.sheet_mask();
if (m.is_running() && s.selected() == n)
{
m.set(101, imp.sezione() == 'D' ? imp.valore().string() : "");
m.set(102, imp.sezione() == 'A' ? imp.valore().string() : "");
}
}
// Legge l'importo della riga n e lo ritorna col segno dovuto
@ -575,8 +577,8 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k)
const TImporto speso = app().partite().importo_speso(numreg, currig);
if (importo != speso)
{
bool ok = yesno_box("L'importo dei pagamenti %c %s\ne' diverso dall'importo sulla riga %d.\n"
"Si desidera correggerlo?", speso.sezione(), speso.valore().string("."), currig);
bool ok = yesno_box("L'importo della riga %d dovrebbe essere %c %s\n"
"Si desidera correggerlo?", currig, speso.sezione(), speso.valore().string("."));
if (ok) app().set_cgs_imp(i, speso);
else return FALSE;
}

View File

@ -9,6 +9,10 @@
#include "pagament.h"
#endif
#ifndef __SALDACON_H
#include "saldacon.h"
#endif
#ifndef __CGLIB_H
#include "cglib.h"
#endif

View File

@ -533,13 +533,14 @@ bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pa
char old_ap, new_ap;
TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam;
const bool empty = p.modifica_pagamento(new_pag,
old_ap, old_abbuono, new_abbuono,
old_ap, old_abbuono, old_diffcam,
new_ap, new_abbuono, new_diffcam);
const int riga_contabile = app().cgs().selected();
// Se c'e' differenza negli abbuoni
if (old_abbuono != new_abbuono || old_ap != new_ap)
{
const int riga_contabile = app().cgs().selected();
if (old_ap != ' ') // Se c'era un abbuono ...
{
const int riga_abb = type2pos(old_ap);
@ -561,7 +562,8 @@ bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pa
}
else
add_cgs_imp(riga_abb, new_abbuono);
sub_cgs_imp(riga_contabile, new_abbuono); // Aggiunge l'abbuono con la sezione invertita
sub_cgs_imp(riga_contabile, new_abbuono); // Aggiunge l'abbuono con la sezione invertita
}
}
@ -581,6 +583,7 @@ bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pa
const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam);
if (empty) reset_cgs_row(riga_diffcam);
}
sub_cgs_imp(riga_contabile, grow_diffcam); // Aggiunge la differenza con la sezione invertita
}
return empty;

729
cg/saldacon.cpp Executable file
View File

@ -0,0 +1,729 @@
#include "saldacon.h"
#include <mov.h>
#include <partite.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::copy_key_to_row(TRectype& row) const
{
const int numkey = 0; // Memento! Gli indici delle chiavi partono da zero!
RecDes* recd = rec_des(); // Descrizione del record della testata
row.zero();
for (int i = 0; i < recd->Ky[numkey].NkFields; i++)
{
const KeyDes& kd = recd->Ky[numkey];
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = recd->Fd[nf];
const char* name = rf.Name;
const TString& val = get(name);
row.put(name, val);
}
}
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)
{
int err = TRectype::remove(f);
if (err == NOERR)
err = _recarr.remove();
return err;
}
///////////////////////////////////////////////////////////
// TRiga_scadenze
///////////////////////////////////////////////////////////
TRiga_scadenze::TRiga_scadenze(TRiga_partite* r)
: TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP"), _riga(r)
{
CHECK(_riga, "Riga nulla");
}
TRiga_scadenze::TRiga_scadenze(const TRiga_scadenze& s)
: TTree_rectype(s), _riga(s._riga)
{
CHECK(_riga, "Riga nulla");
}
TPartita& TRiga_scadenze::partita() const
{
return riga().partita();
}
// Controlla se la rata e' in valuta
bool TRiga_scadenze::in_valuta() const
{
return get(SCAD_CODVAL).not_empty();
}
// Controlla se la rata e' stata completamente pagata
int TRiga_scadenze::pagata() const
{
const TRecord_array& a = rows_array();
for (int p = a.last_row(); p > 0; p = a.pred_row(p))
{
const TRectype& pag = a.row(p);
if (pag.get_char("ACCSAL") == 'S')
return p;
}
return 0;
}
// Calcola il totale dei pagamenti (eventualmente in valuta)
TImporto TRiga_scadenze::importo_pagato(bool val) const
{
const TPartita& game = partita();
const char* imp_field = in_valuta() && val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
TImporto totale;
const TRecord_array& a = rows_array();
for (int p = a.last_row(); p > 0; p = a.pred_row(p))
{
const TRectype& pag = a.row(p); // Riga pagamento
const TRiga_partite& sum = game.riga(p); // Riga partite
const TImporto imp(sum.get_char(PART_SEZ), pag.get_real(imp_field));
totale += imp;
}
return totale;
}
// Calcola l'importo da pagare (eventualmente in valuta)
TImporto TRiga_scadenze::importo_da_pagare(bool val) const
{
const char* imp_field = in_valuta() && val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
const TRiga_partite& r = riga(); // Riga fattura
const TImporto totale(r.get_char(PART_SEZ), get_real(imp_field));
return totale;
}
// Calcola l'abbuono 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(TImporto& abbuono, bool val) const
{
bool ap = ' ';
if (pagata())
{
abbuono = importo_da_pagare(TRUE);
abbuono += importo_pagato(TRUE);
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';
}
if (val && in_valuta())
{
abbuono.valore() *= get_real(SCAD_CAMBIO);
abbuono.valore().round();
}
}
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(bool update)
{
TImporto diffcam;
if (in_valuta())
{
const int riga_saldo = pagata();
if (riga_saldo > 0)
{
TRectype& pag = row(riga_saldo, FALSE);
const TRiga_partite& sum = partita().riga(riga_saldo);
const char sez = sum.sezione();
if (update)
{
diffcam = importo_da_pagare(FALSE);
diffcam += importo_pagato(FALSE);
real a = pag.get_real(PAGSCA_ABBUONI);
if (in_valuta())
{
a *= get_real(SCAD_CAMBIO);
a.round();
}
const TImporto abb_lit(sez, a);
diffcam += abb_lit;
diffcam.normalize(sez);
pag.put(PAGSCA_DIFFCAM, diffcam.valore());
}
else
{
diffcam.set(sez, pag.get_real(PAGSCA_DIFFCAM));
}
}
else
if (update)
{
for (int p = last(); p > 0; p = pred(p))
{
TRectype& pag = row(p, FALSE);
pag.zero(PAGSCA_DIFFCAM);
}
}
}
return diffcam;
}
real TRiga_scadenze::residuo() const
{
const char* imp_field = get(SCAD_CODVAL).not_empty() ? SCAD_IMPORTOVAL : SCAD_IMPORTO;
const real da_pagare(get(imp_field));
const real pagato(get(SCAD_IMPORTOPAG));
const real residuo = da_pagare - pagato;
return residuo;
}
bool TRiga_scadenze::modifica_pagamento(const TRectype& new_pag,
char& old_ap, TImporto& old_abb, TImporto& old_diffcam,
char& new_ap, TImporto& new_abb, TImporto& new_diffcam)
{
const int nrigp = new_pag.get_int(PAGSCA_NRIGP);
const TRectype old_pag(row(nrigp));
TRiga_partite& sum = partita().riga(nrigp);
old_ap = calcola_abbuono(old_abb, FALSE);
old_diffcam = calcola_differenza_cambio(FALSE);
const char* imp_field = get(SCAD_CODVAL).not_empty() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
const real importo(new_pag.get(imp_field));
const bool empty = importo.is_zero();
if (empty)
rows_array().destroy_row(nrigp);
else
row(nrigp, FALSE) = new_pag;
TImporto abbuono;
new_ap = calcola_abbuono(abbuono, TRUE); // Calcolo abbuono in valuta
TImporto imp(abbuono); imp.swap_section();
imp.normalize(sum.sezione());
if (new_ap != ' ')
{
CHECK(nrigp == pagata(), "Aggiornamento abbuoni inconsistente");
TRectype& pag = row(nrigp, FALSE);
pag.put(PAGSCA_ABBUONI, imp.valore());
new_abb = abbuono;
if (in_valuta())
{
new_abb.valore() *= get_real(SCAD_CAMBIO);
new_abb.valore().round();
}
}
else
new_abb.valore() = ZERO;
sum.update(old_abb, new_abb, PART_SEZABB, PART_ABBUONI);
new_diffcam = calcola_differenza_cambio(TRUE);
sum.update(old_diffcam, new_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);
return empty;
}
///////////////////////////////////////////////////////////
// TRiga_partite
///////////////////////////////////////////////////////////
TRiga_partite::TRiga_partite(TPartita* game)
: TTree_rectype(LF_PARTITE, LF_SCADENZE, "NRATA"), _partita(game)
{
CHECK(_partita, "Partita nulla");
}
TRiga_partite::TRiga_partite(const TRiga_partite& r)
: TTree_rectype(r), _partita(r._partita)
{
CHECK(_partita, "Partita nulla");
}
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);
copy_key_to_row(*s);
err = _recarr.read(s); // Deve esistere almento una scadenza
#ifdef DBG
if (_recarr.rows() == 0)
yesnofatal_box("Riga di fattura senza nessuna scadenza");
#endif
}
else
_recarr.destroy_rows();
return err;
}
int TRiga_partite::ultimo_pagamento(int r) const
{
const TRiga_scadenze& s = rata(r);
return s.rows_array().last_row();
}
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 grow(nuo); grow -= vec; // Variazione al totale
if (!grow.is_zero())
{
const char sezione = get_char(sez); // Sezione del totale
TImporto totale;
if (sezione > ' ') // Se c'era una sezione (e quindi un importo) ...
totale.set(sezione, get_real(val)); // ... inizializza il totale
else
CHECKS(vec.is_zero(), "Sezione errata per l'importo ", val);
totale += grow; // 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);
}
TPartita::TPartita()
: _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP")
{}
// Costruisce le righe della partita
bool TPartita::read(const TBill& clifo, int anno, const char* num)
{
TRiga_partite* partita = new TRiga_partite(this); // Record campione della partita
partita->put(PART_TIPOCF, clifo.tipo()); // Tipo clifo
if (clifo.tipo() <= ' ')
{
partita->put(PART_GRUPPO, clifo.gruppo()); // Scrivi gruppo e conto solamente
partita->put(PART_CONTO, clifo.conto()); // nei conti normali (no clifo)
}
partita->put(PART_SOTTOCONTO, clifo.sottoconto()); // Sottoconto o codice clifo
partita->put(PART_ANNO, anno); // Anno partita
partita->put(PART_NUMPART, num); // Numero partita
_part.read(partita);
#ifdef DBG
for (int p = last(); p > 0; p = pred(p))
CHECKD(riga(p)._partita == this, "Riga partite inconsistente", p);
#endif
TRectype unas(LF_PAGSCA); // Record campione pagamenti non assegnati
unas.zero();
unas.put(PART_TIPOCF, partita->get(PART_TIPOCF)); // Copia chiave partite
unas.put(PART_GRUPPO, partita->get(PART_GRUPPO));
unas.put(PART_CONTO, partita->get(PART_CONTO));
unas.put(PART_SOTTOCONTO, partita->get(PART_SOTTOCONTO));
unas.put(PART_ANNO, partita->get(PART_ANNO));
unas.put(PART_NUMPART, partita->get(PART_NUMPART));
unas.put(PART_NRIGA, 0); // Numeri magici di non assegamento
unas.put(SCAD_NRATA, 0);
_unassigned.read(unas);
return ok();
}
bool TPartita::reread()
{
TBill zio;
conto(zio);
const int year = anno();
const TString16 num = numero();
return read(zio, year, num);
}
bool TPartita::write(bool re)
{
const bool ok = _part.write(re);
return ok;
}
TImporto TPartita::importo_speso(long nreg, int numrig) const
{
TImporto imp;
for (int r = _part.last_row(); r > 0; r = pred(r))
{
const TRectype& part = riga(r);
const long reg = part.get_long(PART_NREG);
if (reg == nreg)
{
const int num = part.get_int(PART_NUMRIG);
if (num == numrig)
{
const char sez = part.get_char(PART_SEZ); // Deve essere valido per forza!
imp.set(sez, part.get_real(PART_IMPORTO));
const char sezabb = part.get_char(PART_SEZABB); // Puo' essere nullo
if (sezabb > ' ')
imp += TImporto(sezabb, part.get_real(PART_ABBUONI));
const char sezdifcam = part.get_char(PART_SEZDIFCAM); // Puo' essere nullo
if (sezdifcam > ' ')
imp += TImporto(sezdifcam, part.get_real(PART_DIFFCAM));
break;
}
}
}
return imp;
}
void TPartita::update_reg_num(long nreg, const TRectype& mov)
{
for (int r = _part.last_row(); r > 0; r = pred(r))
{
TRectype& pag = _part.row(r, FALSE);
const long reg = pag.get_long(PART_NREG);
if (reg == nreg)
{
pag.put(PART_NREG, mov.get(MOV_NUMREG));
pag.put(PART_DATAREG, mov.get(MOV_DATAREG));
pag.put(PART_NUMDOC, mov.get(MOV_NUMDOC));
pag.put(PART_DATADOC, mov.get(MOV_DATADOC));
}
}
}
// 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 = _part.last_row(); r > 0; r = pred(r))
{
const TRiga_partite& row = riga(r);
if (row.get_long(PART_NREG) == numreg && row.get_int(PART_NUMRIG) == rm)
return r;
}
return -1;
}
// Trova la prima riga della partita contenente una fattura
int TPartita::prima_fattura() 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)
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 = _part.last_row(); 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;
}
i.set(row.get_char(PART_SEZ), row.get_real(PART_ABBUONI));
imp += i;
i.set(row.get_char(PART_SEZ), row.get_real(PART_DIFFCAM));
imp += i;
}
saldo = doc;
saldo += pag;
saldo += imp;
}
bool TPartita::utilizzata(int nrigp) const
{
for (int p = _part.last_row(); p > 0; p = pred(p))
{
const TRiga_partite& fatt = riga(p);
const int tipomov = fatt.get_int(PART_TIPOMOV);
if (tipomov == 1)
{
for (int r = fatt.rate(); r > 0; r--)
{
const TRiga_scadenze& scad = fatt.rata(r);
if (scad.rows_array().exist(nrigp))
return TRUE;
}
}
}
return FALSE;
}
bool TPartita::modifica_pagamento(const TRectype& new_pag,
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 TRiga_partite& fattura = riga(nriga);
const int nrata = new_pag.get_int(PAGSCA_NRATA);
TRiga_scadenze& scaden = fattura.rata(nrata);
const int nrigp = new_pag.get_int(PAGSCA_NRIGP);
const TRectype& old_pag = scaden.row(nrigp);
const bool empty = scaden.modifica_pagamento(new_pag,
old_ap, old_abb, old_diffcam,
new_ap, new_abb, new_diffcam);
if (empty && !utilizzata(nrigp))
_part.destroy_row(nrigp);
return empty;
}
///////////////////////////////////////////////////////////
// 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);
if (p->ok())
add(k, p);
else
{
delete p;
p = NULL;
}
}
return p;
}
TPartita* TPartite_array::find(const TRectype& r, bool create)
{
TBill zio; zio.get(r);
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);
CHECKS(game, "Partita errata ", num);
return *game;
}
TPartita& TPartite_array::partita(const TRectype& r)
{
TPartita* game = find(r, TRUE);
CHECK(game, "Partita errata");
return *game;
}
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;
}
// Aggiunge all'array tutte le partite che si riferiscono alla registrazione nreg
int TPartite_array::add_reg_num(long nreg, int numrig)
{
TRelation rel(LF_PARTITE);
TRectype& part = rel.lfile().curr();
// Costruzione filtro del cursore
part.zero();
part.put(PART_NREG, nreg);
if (numrig > 0)
part.put(PART_NUMRIG, numrig);
const TRectype filter(part);
TCursor cur(&rel, "", 2, &filter, &filter);
for (cur = 0; cur.ok(); ++cur)
partita(part); // Aggiungi partita se non esiste gia'
return (int)cur.items();
}
TImporto TPartite_array::importo_speso(long nreg, int numrig)
{
TImporto imp;
add_reg_num(nreg, numrig);
for (TPartita* game = first(); game; game = next())
imp += game->importo_speso(nreg, numrig);
return imp;
}
void TPartite_array::update_reg_num(long nreg, const TRectype& mov)
{
add_reg_num(nreg, 0);
for (TPartita* game = first(); game; game = next())
game->update_reg_num(nreg, mov);
}

198
cg/saldacon.h Executable file
View File

@ -0,0 +1,198 @@
#ifndef __SALDACON_H
#define __SALDACON_H
#ifndef __ASSOC_H
#include <assoc.h>
#endif
#ifndef __RELATION_H
#include <relation.h>
#endif
#ifndef __CONTO_H
#include "conto.h"
#endif
#ifndef __PARTITE_H
#include <partite.h>
#endif
class TTree_rectype : public TRectype
{
protected:
TRecord_array _recarr;
void copy_key_to_row(TRectype& row) const;
int fill_array();
protected: // TRectype
virtual TObject* dup() const;
virtual int read(TBaseisamfile& f, word op = _isequal);
virtual int next(TBaseisamfile& f);
virtual int write(TBaseisamfile& f) const;
virtual int rewrite(TBaseisamfile& f) const;
virtual int remove(TBaseisamfile& f);
public:
const TRecord_array& rows_array() const { return _recarr; }
TRecord_array& rows_array() { return _recarr; }
const TRectype& row(int r) const { return ((TRecord_array&)_recarr).row(r, FALSE); }
TRectype& row(int r, bool create) { return _recarr.row(r, create); }
int last() const { return _recarr.last_row(); }
int pred(int r) const { return _recarr.pred_row(r); }
TTree_rectype(const TRectype& testata, const TRectype& riga, const char* num);
TTree_rectype(int testata, int riga, const char* num);
TTree_rectype(const TTree_rectype& t);
virtual ~TTree_rectype() {}
};
class TRiga_scadenze : public TTree_rectype
{
friend class TPartita;
friend class TRiga_partite;
TRiga_partite* _riga;
protected:
char calcola_abbuono(TImporto& abbuono, bool val) const;
TImporto calcola_differenza_cambio(bool update);
bool modifica_pagamento(const TRectype& new_pag,
char& old_ap, TImporto& old_abb, TImporto& old_diffcam,
char& new_ap, TImporto& new_abb, TImporto& new_diffcam);
protected: // TRecord_tree
virtual TObject* dup() const { return new TRiga_scadenze(*this); }
public:
int pagata() const; // Riga che chiude la rata o 0 se non pagata completamente
real residuo() const;
bool in_valuta() const;
TPartita& partita() const;
TRiga_partite& riga() const { CHECK(_riga, "Riga nulla"); return *_riga; } // Riga partite
TImporto importo_pagato(bool val) const;
TImporto importo_da_pagare(bool val) const;
TRiga_scadenze(TRiga_partite* riga);
TRiga_scadenze(const TRiga_scadenze& s);
virtual ~TRiga_scadenze() {}
};
class TRiga_partite : public TTree_rectype
{
friend class TPartita;
friend class TRiga_scadenze;
TPartita* _partita;
protected:
bool update(const TRectype& vec, const TRectype& nuo, const char* field);
bool update(const TImporto& vec, const TImporto& nuo, const char* sez, const char* val);
public: // TTree_rectype
virtual TObject* dup() const { return new TRiga_partite(*this); }
virtual int read(TBaseisamfile& f, word op);
public:
int rate() const { return _recarr.rows(); }
TRiga_scadenze& rata(int r) const { return (TRiga_scadenze&)_recarr.row(r); }
int ultimo_pagamento(int rata) const;
char sezione() const { return get_char("SEZ"); }
TPartita& partita() const { CHECK(_partita, "Partita nulla"); return *_partita; }
TRiga_partite(TPartita* game);
TRiga_partite(const TRiga_partite& r);
virtual ~TRiga_partite() {}
};
class TPartita : public TObject
{
TRecord_array _part;
TRecord_array _unassigned;
public: // TObject
virtual bool ok() const { return _part.rows() > 0; }
public:
TRiga_partite& riga(int r) const { return (TRiga_partite&)_part.row(r); }
TRiga_partite& nuova_riga() { return (TRiga_partite&)_part.row(last()+1, TRUE); }
int succ(int r) const { return _part.succ_row(r); }
int pred(int r) const { return _part.pred_row(r); }
int first() const { return _part.first_row(); }
int last() const { return _part.last_row(); }
bool reread();
bool read(const TBill& clifo, int anno, const char* num);
bool write(bool re = FALSE);
bool rewrite() { return write(TRUE); }
int mov2rig(long nreg, int rmov) const;
int rig2mov(int rmov) const;
int prima_fattura() const;
bool utilizzata(int r) const; // Controlla se esistono pagamenti sommati alla riga r
void conto(TBill& c) const { c.get(_part.key()); }
int anno() const { return _part.key().get_int(PART_ANNO); }
const TString& numero() const { return _part.key().get(PART_NUMPART); }
const TString& descrizione() const { return _part.key().get(PART_DESCR); }
TImporto importo_speso(long numreg, int numrig) const;
void update_reg_num(long nreg, const TRectype& mov);
void calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImporto& imp) const;
bool modifica_pagamento(const TRectype& new_pag,
char& old_ap, TImporto& old_abb, TImporto& old_diffcam,
char& new_ap, TImporto& new_abb, TImporto& new_diffcam);
TPartita(const TBill& clifo, int anno, const char* num);
TPartita();
};
class TPartite_array : private TAssoc_array
{
TString80 _key; // Work string
protected:
const TString& key(const TBill& clifo, int anno, const char* num); // Build key for TAssoc_array
TPartita* find(const TBill& clifo, int anno, const char* numero, bool create);
TPartita* find(const TRectype& part, bool create);
public: // TAssoc_array
virtual void destroy() { TAssoc_array::destroy(); }
public:
TPartita& partita(const TBill& clifo, int anno, const char* numero);
TPartita& partita(const TRectype& r);
TPartita* exist(const TBill& clifo, int anno, const char* numero) const
{ return ((TPartite_array*)this)->find(clifo, anno, numero, FALSE); }
TPartita* exist(const TRectype& part) const
{ return ((TPartite_array*)this)->find(part, FALSE); }
bool write(bool re = FALSE);
bool rewrite() { return write(TRUE); }
int add_reg_num(long numreg, int numrig);
TImporto importo_speso(long numreg, int numrig);
void update_reg_num(long nreg, const TRectype& mov);
TPartita* first() { restart(); return next(); }
TPartita* next() { return (TPartita*)get(); }
TPartite_array() {}
virtual ~TPartite_array() {}
};
#endif