1995-08-25 07:39:49 +00:00
|
|
|
#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)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TRectype(testa), _recarr(riga, num)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TTree_rectype::TTree_rectype(int testa, int riga, const char* num)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TRectype(testa), _recarr(riga, num)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TTree_rectype::TTree_rectype(const TTree_rectype& t)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TRectype(t), _recarr(t._recarr)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
row.zero();
|
1995-08-28 07:50:28 +00:00
|
|
|
const KeyDes& kd = recd->Ky[numkey];
|
|
|
|
for (int i = recd->Ky[numkey].NkFields-1; i >= 0; i--)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
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)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP"), _riga(r)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
CHECK(_riga, "Riga nulla");
|
|
|
|
}
|
|
|
|
|
|
|
|
TRiga_scadenze::TRiga_scadenze(const TRiga_scadenze& s)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TTree_rectype(s), _riga(s._riga)
|
1995-08-25 07:39:49 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
CHECK(_riga, "Riga nulla");
|
|
|
|
}
|
|
|
|
|
|
|
|
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().get(PART_CODVAL).not_empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Controlla se la rata e' stata completamente pagata
|
|
|
|
int TRiga_scadenze::pagata() const
|
|
|
|
{
|
|
|
|
for (int p = last(); p > 0; p = pred(p))
|
|
|
|
{
|
|
|
|
const TRectype& pag = row(p);
|
|
|
|
if (pag.get_char("ACCSAL") == 'S')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calcola il totale dei pagamenti (eventualmente in valuta)
|
|
|
|
TImporto TRiga_scadenze::importo_pagato(bool val) const
|
|
|
|
{
|
|
|
|
const char* imp_field = val && in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
|
|
|
|
const TPartita& game = partita();
|
|
|
|
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 TImporto imp(sum.sezione(), 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 = val && in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
|
|
|
|
const TRiga_partite& r = riga(); // Riga fattura
|
|
|
|
const TImporto totale(r.sezione(), 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() *= riga().get_real(PART_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);
|
|
|
|
const TRiga_partite& sum = partita().riga(riga_saldo);
|
|
|
|
const char sez = sum.sezione();
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
if (update)
|
|
|
|
{
|
|
|
|
diffcam = importo_da_pagare(FALSE);
|
|
|
|
diffcam += importo_pagato(FALSE);
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
real a = pag.get_real(PAGSCA_ABBUONI);
|
|
|
|
if (in_valuta())
|
|
|
|
{
|
|
|
|
a *= riga().get_real(PART_CAMBIO);
|
|
|
|
a.round();
|
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
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);
|
|
|
|
pag.zero(PAGSCA_DIFFCAM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return diffcam;
|
|
|
|
}
|
|
|
|
|
|
|
|
real TRiga_scadenze::residuo(bool val) const
|
|
|
|
{
|
|
|
|
TImporto residuo(importo_da_pagare(val));
|
1995-08-28 07:50:28 +00:00
|
|
|
residuo += importo_pagato(val); // Somma con sezione opposta
|
1995-08-25 07:39:49 +00:00
|
|
|
return residuo.valore();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
TImporto old_abbuono;
|
|
|
|
old_ap = calcola_abbuono(old_abbuono, TRUE); // Vecchio abbuono in valuta
|
|
|
|
old_abb = old_abbuono; // Vecchio abbuono in lire
|
|
|
|
if (in_valuta())
|
|
|
|
{
|
|
|
|
old_abb.valore() *= riga().get_real(PART_CAMBIO);
|
|
|
|
old_abb.valore().round();
|
|
|
|
}
|
|
|
|
|
|
|
|
old_diffcam = calcola_differenza_cambio(FALSE);
|
|
|
|
|
|
|
|
const char* imp_field = in_valuta() ? 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) = new_pag;
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
TImporto new_abbuono;
|
|
|
|
new_ap = calcola_abbuono(new_abbuono, TRUE); // Calcolo abbuono in valuta
|
|
|
|
|
|
|
|
new_abb = new_abbuono; // Calcola nuovo abbuono in lire
|
|
|
|
if (in_valuta())
|
|
|
|
{
|
|
|
|
new_abb.valore() *= riga().get_real(PART_CAMBIO);
|
|
|
|
new_abb.valore().round();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scambia sezione per registrazione contabile
|
|
|
|
old_abbuono.swap_section();
|
|
|
|
new_abbuono.swap_section();
|
|
|
|
new_abbuono.normalize(sum.sezione());
|
|
|
|
if (new_ap != ' ')
|
|
|
|
{
|
|
|
|
CHECK(nrigp == pagata(), "Aggiornamento abbuoni inconsistente");
|
|
|
|
TRectype& pag = row(nrigp);
|
|
|
|
pag.put(PAGSCA_ABBUONI, new_abbuono.valore());
|
|
|
|
}
|
|
|
|
sum.update(old_abbuono, new_abbuono, PART_SEZABB, PART_ABBUONI);
|
|
|
|
|
|
|
|
new_diffcam = calcola_differenza_cambio(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);
|
|
|
|
|
|
|
|
partita().chiusa(TRUE); // Aggiorna flag di chiusura
|
|
|
|
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
1995-08-29 13:11:15 +00:00
|
|
|
bool TPartita::modifica_pagamento(const TRectype& new_pag)
|
|
|
|
{
|
|
|
|
char old_ap, new_ap;
|
|
|
|
TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam;
|
|
|
|
return modifica_pagamento(new_pag,
|
|
|
|
old_ap, old_abbuono, old_diffcam,
|
|
|
|
new_ap, new_abbuono, new_diffcam);
|
|
|
|
}
|
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TRiga_partite
|
|
|
|
///////////////////////////////////////////////////////////
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
TRiga_partite::TRiga_partite(TPartita* game)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TTree_rectype(LF_PARTITE, LF_SCADENZE, SCAD_NRATA), _partita(game)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
CHECK(_partita, "Partita nulla");
|
|
|
|
}
|
|
|
|
|
|
|
|
TRiga_partite::TRiga_partite(const TRiga_partite& r)
|
1995-08-29 13:11:15 +00:00
|
|
|
: TTree_rectype(r), _partita(r._partita)
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
CHECK(_partita, "Partita nulla");
|
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-28 07:50:28 +00:00
|
|
|
TRiga_scadenze& TRiga_partite::new_row(int r)
|
|
|
|
{
|
|
|
|
if (r <= 0) r = last()+1;
|
|
|
|
|
|
|
|
if (_recarr.rows() == 0)
|
|
|
|
{
|
|
|
|
TRiga_scadenze* scad = new TRiga_scadenze(this);
|
|
|
|
copy_key_to_row(*scad);
|
|
|
|
_recarr.set_key(scad); // Altrimenti le righe sarebbero dei TRectype!
|
|
|
|
}
|
|
|
|
|
|
|
|
return (TRiga_scadenze&)_recarr.row(r, TRUE);
|
|
|
|
}
|
1995-08-25 07:39:49 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_recarr.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;
|
1995-08-29 13:11:15 +00:00
|
|
|
TImporto growth(nuo); growth -= vec; // Variazione al totale
|
1995-08-25 07:39:49 +00:00
|
|
|
|
1995-08-29 13:11:15 +00:00
|
|
|
if (!growth.is_zero())
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
1995-08-29 13:11:15 +00:00
|
|
|
TImporto totale(get_char(sez), get_real(val));
|
|
|
|
totale += growth; // incrementa il totale
|
1995-08-25 07:39:49 +00:00
|
|
|
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)
|
1995-08-29 13:11:15 +00:00
|
|
|
: _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP")
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
read(clifo, anno, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
TPartita::TPartita()
|
1995-08-29 13:11:15 +00:00
|
|
|
: _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP")
|
1995-08-25 07:39:49 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
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));
|
1995-08-28 07:50:28 +00:00
|
|
|
unas.put(PART_NRIGA, (int)UNASSIGNED);
|
|
|
|
unas.put(SCAD_NRATA, (int)UNASSIGNED);
|
1995-08-25 07:39:49 +00:00
|
|
|
_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;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TPartita::remove()
|
|
|
|
{
|
|
|
|
_part.destroy_rows();
|
|
|
|
return rewrite();
|
1995-08-28 07:50:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Crea un nuova riga partite e gli copia la chiave principale e il conto cliente/fornitore
|
|
|
|
TRiga_partite& TPartita::nuova_riga()
|
|
|
|
{
|
|
|
|
TRiga_partite& nuova = (TRiga_partite&)_part.row(last()+1, TRUE);
|
|
|
|
const TRiga_partite& prima = riga(first());
|
|
|
|
nuova.put(PART_GRUPPOCL, prima.get(PART_GRUPPOCL));
|
|
|
|
nuova.put(PART_CONTOCL, prima.get(PART_CONTOCL));
|
|
|
|
return nuova;
|
1995-08-25 07:39:49 +00:00
|
|
|
}
|
|
|
|
|
1995-08-29 13:11:15 +00:00
|
|
|
TRiga_scadenze& TPartita::rata(int nriga, int nrata) const
|
|
|
|
{
|
|
|
|
if (nriga < 1) nriga = prima_fattura();
|
|
|
|
const TRiga_partite& r = riga(nriga);
|
|
|
|
return r.rata(nrata);
|
|
|
|
}
|
1995-08-28 07:50:28 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
TImporto TPartita::importo_speso(long nreg, int numrig, bool extra) const
|
|
|
|
{
|
|
|
|
TImporto imp;
|
|
|
|
|
|
|
|
for (int r = last(); r > 0; r = pred(r))
|
|
|
|
{
|
1995-08-29 13:11:15 +00:00
|
|
|
const TRiga_partite& part = riga(r);
|
1995-08-25 07:39:49 +00:00
|
|
|
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 valida per forza!
|
|
|
|
imp += TImporto(sez, part.get_real(PART_IMPORTO));
|
|
|
|
|
|
|
|
if (extra)
|
|
|
|
{
|
|
|
|
TImporto abbuoni(part.get_char(PART_SEZABB), part.get_real(PART_ABBUONI));
|
1995-08-29 13:11:15 +00:00
|
|
|
if (part.in_valuta()) // Se e' in valuta
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
abbuoni.valore() *= part.get_real(PART_CAMBIO);
|
|
|
|
abbuoni.valore().round();
|
|
|
|
}
|
|
|
|
imp += abbuoni;
|
|
|
|
imp += TImporto(part.get_char(PART_SEZDIFCAM), part.get_real(PART_DIFFCAM));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return imp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TPartita::update_reg_num(long nreg, const TRectype& mov)
|
|
|
|
{
|
|
|
|
for (int r = last(); 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 = last(); r > 0; r = pred(r))
|
|
|
|
{
|
|
|
|
const TRiga_partite& row = riga(r);
|
1995-08-28 07:50:28 +00:00
|
|
|
if (row.get_long(PART_NREG) == numreg)
|
|
|
|
{
|
|
|
|
if (rm <= 0 || row.get_int(PART_NUMRIG) == rm)
|
|
|
|
return r;
|
|
|
|
}
|
1995-08-25 07:39:49 +00:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trova la prima riga della partita contenente una fattura
|
1995-08-25 08:00:18 +00:00
|
|
|
int TPartita::prima_fattura(long nreg) const
|
1995-08-25 07:39:49 +00:00
|
|
|
{
|
|
|
|
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)
|
1995-08-25 08:00:18 +00:00
|
|
|
if (nreg == -1 || nreg == row.get_long(PART_NREG))
|
1995-08-29 13:11:15 +00:00
|
|
|
return r;
|
1995-08-25 08:00:18 +00:00
|
|
|
}
|
|
|
|
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 == 3) // TBI controllare per insoluti (tipomov == 6)
|
|
|
|
if (nreg == -1 || nreg == row.get_long(PART_NREG))
|
1995-08-29 13:11:15 +00:00
|
|
|
return r;
|
1995-08-25 07:39:49 +00:00
|
|
|
}
|
|
|
|
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))
|
|
|
|
{
|
1995-08-29 13:11:15 +00:00
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
doc += i; // documenti
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
pag += i; // pagamenti
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
imp += i; // altri importi
|
|
|
|
break;
|
1995-08-25 07:39:49 +00:00
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TPartita::utilizzata(int nrigp) const
|
|
|
|
{
|
|
|
|
for (int p = last(); 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;
|
|
|
|
}
|
|
|
|
}
|
1995-08-28 07:50:28 +00:00
|
|
|
}
|
|
|
|
return _unassigned.exist(nrigp);
|
1995-08-25 07:39:49 +00:00
|
|
|
}
|
|
|
|
|
1995-08-28 07:50:28 +00:00
|
|
|
|
|
|
|
bool TPartita::remove_unassigned(long nreg)
|
|
|
|
{
|
|
|
|
bool found = FALSE;
|
|
|
|
|
|
|
|
for (int u = _unassigned.last_row(); u > 0; u = _unassigned.pred_row(u))
|
|
|
|
{
|
|
|
|
const TRectype& pag = _unassigned.row(u);
|
|
|
|
const int nrigp = pag.get_int(PAGSCA_NRIGP);
|
|
|
|
TRiga_partite& sum = riga(nrigp);
|
|
|
|
if (sum.get_long(PART_NREG) == nreg)
|
|
|
|
{
|
|
|
|
TRectype zero(pag); zero.zero();
|
|
|
|
sum.update(pag, zero, PART_IMPORTO);
|
|
|
|
sum.update(pag, zero, PART_IMPORTOVAL);
|
|
|
|
sum.update(pag, zero, PART_RITENUTE);
|
|
|
|
_unassigned.destroy_row(u);
|
|
|
|
found = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
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);
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TPartita::chiusa(bool update)
|
|
|
|
{
|
|
|
|
const TRiga_partite& row = riga(first());
|
|
|
|
bool chiusa = row.get_bool(PART_CHIUSA);
|
|
|
|
|
|
|
|
if (update)
|
|
|
|
{
|
|
|
|
bool forse_chiusa = TRUE;
|
|
|
|
for (int p = last(); p > 0 && forse_chiusa; p = pred(p))
|
|
|
|
{
|
|
|
|
const TRiga_partite& part = riga(first());
|
|
|
|
if (part.get_int(PART_TIPOMOV) == 1)
|
|
|
|
{
|
|
|
|
for (int r = part.last(); r > 0; r--)
|
|
|
|
{
|
|
|
|
const TRiga_scadenze& scad = part.rata(r);
|
|
|
|
if (!scad.pagata())
|
|
|
|
{
|
|
|
|
forse_chiusa = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
if (chiusa != forse_chiusa)
|
|
|
|
{
|
|
|
|
chiusa = forse_chiusa;
|
|
|
|
for (p = last(); p > 0; p = pred(p))
|
|
|
|
{
|
|
|
|
TRiga_partite& part = riga(first());
|
|
|
|
part.put(PART_CHIUSA, chiusa);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return chiusa;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// 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;
|
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
// 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);
|
1995-08-29 13:11:15 +00:00
|
|
|
|
1995-08-25 07:39:49 +00:00
|
|
|
for (cur = 0; cur.ok(); ++cur)
|
1995-08-28 07:50:28 +00:00
|
|
|
{
|
|
|
|
TPartita& p = partita(part); // Aggiungi partita se non esiste gia'
|
|
|
|
p.remove_unassigned(nreg); // Togli righe non assegnate
|
|
|
|
}
|
1995-08-25 07:39:49 +00:00
|
|
|
|
|
|
|
return (int)cur.items();
|
|
|
|
}
|
|
|
|
|
|
|
|
TImporto TPartite_array::importo_speso(long nreg, int numrig, bool extra)
|
|
|
|
{
|
|
|
|
TImporto imp;
|
|
|
|
add_reg_num(nreg, numrig);
|
|
|
|
for (TPartita* game = first(); game; game = next())
|
|
|
|
imp += game->importo_speso(nreg, numrig, extra);
|
|
|
|
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);
|
|
|
|
}
|
1995-08-29 13:11:15 +00:00
|
|
|
|