Gestione saldaconto

git-svn-id: svn://10.65.10.50/trunk@1910 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1995-09-29 16:21:08 +00:00
parent 15ab33f04b
commit 3203d1369f
6 changed files with 561 additions and 461 deletions

View File

@ -279,7 +279,7 @@ bool TPrimanota_application::read_caus(const char* cod, int year)
if (nriga < 1) continue; // Considera solo righe reali (non riempimenti)
TBill tc; causale().bill(nriga, tc);
if (tc.gruppo() < 1) continue; // Considera solo gruppi validi
if (tc.gruppo() <= 0) continue; // Considera solo gruppi validi
if (tc.tipo() > ' ' && tc.ok())
{
@ -289,8 +289,8 @@ bool TPrimanota_application::read_caus(const char* cod, int year)
}
int err = 0;
if (tc.descrizione() == "Sconosciuto") err = 1; else
if (tc.sospeso()) err = 2;
if (tc.descrizione() == "Sconosciuto") err = 1;
else if (tc.sospeso()) err = 2;
if (err)
{
@ -310,8 +310,8 @@ bool TPrimanota_application::read_caus(const char* cod, int year)
char tipr = ' ';
if (_is_saldaconto)
{
if (nriga < 13 && nriga != 10 && nriga != 2) continue; // Si considerano solo le spese
tipr = (nriga == 2) ? 'L' : 'G';
if (nriga < 13 && nriga != 10) continue; // Si considerano solo le spese
tipr = 'G';
}
const int pos = set_cgs_row(-1, zero, tc, desc, tipr);
if (sezione > ' ')
@ -543,7 +543,15 @@ void TPrimanota_application::init_insert_mode(TMask& m)
void TPrimanota_application::init_modify_mode(TMask& m)
{
init_mask(m);
init_mask(m);
partite().destroy();
if (is_pagamento())
{
const long numreg = m.get_long(F_NUMREG);
partite().add_numreg(numreg);
}
calcola_saldo(); // Verifica eventuali sbilanci contabili
}
@ -611,10 +619,6 @@ int TPrimanota_application::read(TMask& m)
disable_cgs_cells(i, tipo);
}
partite().destroy();
if (is_pagamento())
partite().add_numreg(numreg);
if (_iva == nessuna_iva)
return _rel->status();

View File

@ -102,7 +102,6 @@ bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
CHECKD(f.is_edit(), "Can't check suspension of a non edit-field ", f.dlg());
const TEdit_field& c = (const TEdit_field&)f;
const TBrowse* b = c.browse();
CHECKD(b, "Can't check suspension of a edit-field without a USE ", f.dlg());
@ -418,15 +417,22 @@ void TPrimanota_application::cgs_pack()
{
TString_array& rows = cgs().rows_array();
const bool pagamento = is_pagamento();
const long numreg = curr_mask().get_long(F_NUMREG);
for (int i = rows.items()-1; i >= 0; i--)
{
TToken_string& r = rows.row(i);
if (can_remove(r))
{
{
bool ok = TRUE;
if (pagamento && row_type(r) == 'K')
cg_notify(cgs(), i, K_DEL);
rows.destroy(i, TRUE);
{
ok = !partite().utilizzata(numreg, i+1);
if (ok)
cg_notify(cgs(), i, K_DEL);
}
if (ok)
rows.destroy(i, TRUE);
}
}
if (!pagamento) // Il pagamento e' gia' ordinato

View File

@ -15,6 +15,7 @@
#include <clifo.h>
#include <partite.h>
#include <scadenze.h>
#include <pagsca.h>
bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k)
{
@ -539,3 +540,236 @@ void TPrimanota_application::write_scadenze(const TMask& m)
}
///////////////////////////////////////////////////////////
// Gestione pagamenti
///////////////////////////////////////////////////////////
bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k)
{
bool ok = TRUE;
TMask& m = f.mask();
const char tipo = m.get(116)[0];
if (tipo == 'K' || (tipo == 'T' && app().causale().tipomov() == 2))
{
TSheet_field& s = *m.get_sheet();
const int riga = s.selected();
if (k == K_SPACE)
{
const bool ok = app().edit_partite(riga);
if (ok)
k = K_ENTER;
}
if (k == K_ENTER)
{
const long curreg = app().curr_mask().get_long(F_NUMREG);
const TImporto importo(app().get_cgs_imp(riga));
const TImporto speso(app().partite().importo_speso(curreg, riga+1));
if (importo != speso)
{
const char* ss = speso.valore().string(".");
return f.error_box("L'importo deve essere %s %c", ss, speso.sezione());
}
if (tipo == 'K' && !speso.is_zero())
app().disable_cgs_cells(riga, 'K');
}
}
return ok;
}
// deleting significato
// -1 non sto cancellando nulla
// 0 sto cancellando tutto
// 1 sto cancellando la prima riga contabile
// n sto cancellando la ennesima riga contabile
bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pag,
const TValuta& valuta, int deleting)
{
const int nriga = new_pag.get_int(PAGSCA_NRIGA); // Riga fattura
const int nrata = new_pag.get_int(PAGSCA_NRATA); // Numero rata
const int nrigp = new_pag.get_int(PAGSCA_NRIGP); // Riga pagamento
const TRectype& old_pag = p.pagamento(nriga, nrata, nrigp);
const TRiga_partite& somma = p.riga(nrigp);
const int riga_contabile = somma.get_int(PART_NUMRIG); // Riga movimento
if (deleting != 0)
{
const char sez = somma.sezione(); // Sezione importo e ritenute
const char controsez = sez == 'A' ? 'D' : 'A'; // Sezione contropartita
// Aggiornamento contopartita
const TImporto old_importo(controsez, old_pag.get_real(PAGSCA_IMPORTO));
TBill old_conto; old_conto.get(old_pag, TRUE);
const TImporto new_importo(controsez, new_pag.get_real(PAGSCA_IMPORTO));
TBill new_conto; new_conto.get(new_pag, TRUE);
if (old_importo != new_importo || old_conto != new_conto)
{
const int old_riga = bill2pos(old_conto, 'I');
if (old_riga >= 0)
{
const bool empty = sub_cgs_imp(old_riga, old_importo);
if (empty && (new_importo.is_zero() || new_conto != old_conto))
reset_cgs_row(old_riga);
}
// Importo della contropartita
if (!new_importo.is_zero() && new_conto.ok())
{
const int new_riga = bill2pos(new_conto, 'I');
if (new_riga < 0)
set_cgs_row(new_riga, new_importo, new_conto, "", 'I');
else
add_cgs_imp(new_riga, new_importo);
}
}
// Aggiornamento ritenute
const real old_ritenute(old_pag.get(PAGSCA_RITENUTE));
const real new_ritenute(new_pag.get(PAGSCA_RITENUTE));
if (old_ritenute != new_ritenute)
{
const TImporto grow_ritenute(controsez, new_ritenute-old_ritenute);
const riga = type2pos('F');
if (riga < 0)
{
TBill conto_rit; causale().bill(11, conto_rit);
set_cgs_row(riga, grow_ritenute, conto_rit, causale().desc_agg(11), 'F');
}
else
{
const bool empty = add_cgs_imp(riga, grow_ritenute);
if (empty) reset_cgs_row(riga);
}
}
} // if (deleting != 0)
char old_ap, new_ap;
TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam;
const bool empty = p.modifica_pagamento(new_pag, valuta,
old_ap, old_abbuono, old_diffcam,
new_ap, new_abbuono, new_diffcam);
if (deleting != 0)
{
// Se c'e' differenza negli abbuoni
if (old_abbuono != new_abbuono || old_ap != new_ap)
{
if (old_ap != ' ') // Se c'era un abbuono ...
{
const int riga_abb = type2pos(old_ap);
CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?");
const bool empty = sub_cgs_imp(riga_abb, old_abbuono);
if (empty && new_ap != old_ap)
reset_cgs_row(riga_abb);
if (deleting != riga_contabile)
{
// Sottrae l'abbuono con la sezione invertita dalla riga contabile
add_cgs_imp(riga_contabile-1, old_abbuono);
}
}
if (new_ap != ' ') // Se ci sono abbuoni
{
const riga_abb = type2pos(new_ap);
if (riga_abb < 0)
{
const int rc = new_ap == 'A' ? 9 : 8;
TBill conto_abb; causale().bill(rc, conto_abb);
app().set_cgs_row(riga_abb, new_abbuono, conto_abb, causale().desc_agg(rc), new_ap);
}
else
add_cgs_imp(riga_abb, new_abbuono);
if (deleting != riga_contabile)
{
// Aggiunge l'abbuono con la sezione invertita
sub_cgs_imp(riga_contabile-1, new_abbuono);
}
}
}
// Se c'e' variazione nella differenza cambi
if (old_diffcam != new_diffcam)
{
const int riga_diffcam = type2pos('C');
TImporto grow_diffcam(new_diffcam);
grow_diffcam -= old_diffcam;
grow_diffcam.normalize();
if (riga_diffcam < 0)
{
TBill conto_diffcam; causale().bill(12, conto_diffcam);
set_cgs_row(riga_diffcam, grow_diffcam, conto_diffcam, causale().desc_agg(12), 'C');
}
else
{
const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam);
if (empty) reset_cgs_row(riga_diffcam);
}
if (deleting != riga_contabile)
{
// Aggiunge la differenza con la sezione invertita
sub_cgs_imp(riga_contabile-1, grow_diffcam);
}
}
} // if (deleting != 0)
return empty;
}
// Scorre tutte le righe della partita ed azzera i pagamenti relativi a alla riga contabile
// cancellata e decrementa i numeri riga superiori a numrig
bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig)
{
bool found = FALSE;
for (int p = partita.last(); p > 0; p = partita.pred(p))
{
TRiga_partite& part = partita.riga(p);
if (part.get_int(PART_TIPOMOV) == 1)
{
for (int r = part.rate(); r > 0; r--)
{
const TRiga_scadenze& scad = part.rata(r);
for (int s = scad.last(); s > 0; s = scad.pred(s))
{
const TRiga_partite& sum = partita.riga(s);
if (sum.get_long(PART_NREG) == nreg &&
(numrig <= 0 || sum.get_int(PART_NUMRIG) == numrig))
{
TRectype nul_pag(scad.row(s));
nul_pag.zero(PAGSCA_IMPORTO);
nul_pag.zero(PAGSCA_IMPORTOVAL);
nul_pag.zero(PAGSCA_RITENUTE);
nul_pag.put(PAGSCA_ACCSAL, 'A');
const TValuta val; // Non cambiare valuta
notify_edit_pagamento(partita, nul_pag, val, numrig);
found = TRUE;
}
}
}
}
else
{
if (numrig > 0 && part.get_long(PART_NREG) == nreg && part.get_int(PART_NUMRIG) > numrig)
part.put(PART_NUMRIG, numrig-1);
}
}
return found;
}
bool TPrimanota_application::notify_cgline_deletion(int numrig)
{
bool found = FALSE;
const long nreg = curr_mask().get_long(F_NUMREG);
for (TPartita* game = _partite.first(); game; game = _partite.next())
found |= notify_cgline_deletion(*game, nreg, numrig);
return found;
}

View File

@ -1,8 +1,14 @@
#include <defmask.h> // Serve per DLG_NEWREC
#include "cg2102.h" // Applicazione di prima nota
#ifdef __EXTRA__
#else
#include "cg2102.h" // Applicazione di prima nota
#include "cg2100.h" // Campi maschere prima nota
#endif
#include "cg2100p.h" // Campi maschere partite e pagamenti
#include <clifo.h> // Archivio clienti/fornitori
@ -11,6 +17,138 @@
#include <partite.h> // Archivio partite
#include <scadenze.h> // Archivio scadenze
///////////////////////////////////////////////////////////
// Maschera pagamenti
///////////////////////////////////////////////////////////
class TPay_mask : public TMask
{
real _da_pagare;
TValuta _valuta;
protected:
static bool importo_handler(TMask_field& f, KEY k);
public:
void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad);
void get_pag(TRectype& oldpag) const;
const TValuta& valuta() const { return _valuta; }
TPay_mask();
virtual ~TPay_mask() {}
};
TPay_mask::TPay_mask() : TMask("cg2100s")
{
}
void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad)
{
TRelation rel(LF_PAGSCA); // Working relation
rel.curr() = oldpag;
autoload(&rel); // Load current record on mask
const TRiga_partite& fatt = scad.riga();
set(S_NUMDOC, fatt.get(PART_NUMDOC)); // Numero documento
set(S_DATADOC, fatt.get(PART_DATADOC)); // Data documento
set(S_NUMPROT, fatt.get(PART_PROTIVA)); // Protocollo IVA
set(S_DESCR, fatt.get(PART_DESCR)); // Descrizione documento
set(S_DATA_SCAD, scad.get(SCAD_DATASCAD)); // Data della scadenza
set(S_SEZIONE_SCAD, scad.riga().sezione()); // Sezione della rata
set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO)); // Importo della rata
set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta
const bool in_valuta = scad.in_valuta();
_da_pagare = scad.residuo(in_valuta).valore(); // Calcola residuo in valuta
TReal_field& res = (TReal_field&)field(S_RESIDUORATA);
res.set_decimals(in_valuta ? 2 : 0);
res.set(_da_pagare.string());
if (!_da_pagare.is_zero())
set_handler(in_valuta ? S_IMPORTOVAL : S_IMPORTO, importo_handler);
// Ricorda l'importo da pagare
_da_pagare += oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO);
// Attiva campi relativi alla valuta
show(-3, in_valuta);
const TPartita& p = scad.partita();
const int nrigp = oldpag.get_int(PAGSCA_NRIGP);
const TRiga_partite& sum = p.riga(nrigp);
_valuta.get(sum);
const long numreg = sum.get_long(PART_NREG);
const int numrig = sum.get_int(PART_NUMRIG);
#ifdef __EXTRA__
TImporto residuo(app().curr_mask().get(F_TOTALE));
#else
TImporto residuo(app().get_cgs_imp(numrig-1));
#endif
residuo -= app().partite().importo_speso(numreg, numrig);
set(S_RESIDUOPAG, residuo.valore().string());
// Il flag di saldo/acconto e' attivo solo se non ci sono acconti
bool sa = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED;
if (sa)
{
const TDate datasca(fatt.get(PART_DATADOC));
const TDate datapag(sum.get(PART_DATADOC));
sa = datapag >= datasca;
}
else
{
hide(S_RESIDUORATA);
}
enable(S_SALDOACC, sa);
#ifdef __EXTRA__
const bool disabilita = TRUE;
#else
const bool disabilita = app().causale().tipomov() == 2;
#endif
if (disabilita)
send_key(K_CTRL + K_SHIFT + 'c', -2); // Disabilita contropartita e ritenute
}
void TPay_mask::get_pag(TRectype& newpag) const
{
TRelation rel(LF_PAGSCA); // Working relation
rel.curr() = newpag;
autosave(&rel); // Load current record from mask
newpag = rel.curr();
}
bool TPay_mask::importo_handler(TMask_field& f, KEY k)
{
TPay_mask& m = (TPay_mask&)f.mask();
if (k == K_F8)
{
f.set(m._da_pagare.string());
k = K_TAB;
}
if (k == K_TAB && f.focusdirty())
{
const real i(f.get());
if (i >= m._da_pagare && m.field(S_SALDOACC).active())
m.set(S_SALDOACC, "S");
const real residuo(m._da_pagare - i);
m.set(S_RESIDUORATA, residuo.string());
if (f.dlg() == S_IMPORTOVAL)
{
const real lit = m.valuta().val2lit(i);
m.set(S_IMPORTO, lit.string());
}
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Maschera partite
///////////////////////////////////////////////////////////
@ -40,7 +178,8 @@ protected:
int update_partita(const TPartita& game, int prow);
void update_saldo_clifo();
int nuovo_pagamento(TPartita& partita, int nriga, int rata);
int nuovo_pagamento(TPartita& partita, int nriga, int rata) const;
bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const;
bool cerca_valuta(TValuta& val) const;
void aggiorna_valuta(const TValuta& val);
@ -65,19 +204,13 @@ TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga)
set(P_DESCR, ((TBill&)_conto).descrizione());
TValuta val;
if (numreg > 0)
{
TMask& cm = app().curr_mask();
val.get(cm, S_VALUTA, S_DATACAMBIO, S_CAMBIO);
}
if (val.in_valuta())
{
cerca_valuta(val);
val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
enable(-3);
}
else
disable(-3);
#ifndef __EXTRA__
TMask& cm = app().curr_mask();
val.get(cm, S_VALUTA, S_DATACAMBIO, S_CAMBIO);
#endif
cerca_valuta(val);
val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
enable(-3, val.in_valuta());
set_handler(P_ANNO, annopart_handler);
set_handler(P_NUMERO, numpart_handler);
@ -173,8 +306,12 @@ bool TGame_mask::cambio_handler(TMask_field& f, KEY k)
///////////////////////////////////////////////////////////
real TGame_mask::aggiorna_residuo()
{
{
#ifdef __EXTRA__
TImporto residuo(app().curr_mask().get(F_TOTALE));
#else
TImporto residuo(app().get_cgs_imp(_numrig-1));
#endif
residuo -= app().partite().importo_speso(_numreg, _numrig);
set(P_RESIDUO, residuo.valore().string());
return residuo.valore();
@ -227,7 +364,11 @@ void TGame_mask::aggiorna_valuta(const TValuta& val)
real imp(pag.get(PAGSCA_IMPORTOVAL));
val.val2lit(imp);
pag.put(PAGSCA_IMPORTO, imp); // Converte in lire l'importo in valuta
#ifdef __EXTRA__
game->modifica_pagamento(pag, val);
#else
app().notify_edit_pagamento(*game, pag, val);
#endif
}
}
}
@ -235,9 +376,14 @@ void TGame_mask::aggiorna_valuta(const TValuta& val)
}
if (annorif != 0)
{
const bool nota_credito = app().causale().tipomov() == 2;
if (nota_credito)
{
const bool proponi =
#ifdef __EXTRA__
TRUE;
#else
app().causale().tipomov() == 2;
#endif
if (proponi)
{
const TMask& cm = app().curr_mask();
const int anno = cm.get_int(F_ANNORIF);
@ -336,7 +482,7 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
if (in_valuta)
{
add_importo(rabb, scad.importo_pagato(FALSE, 0x2));
add_importo(rabb, abb.normalize());
add_importo(rabb, abb);
}
else
{
@ -364,13 +510,15 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
rsal.add("", 5);
TImporto sl(scad.residuo(FALSE, 0x7));
sl.normalize();
add_importo(rsal, sl);
tot_lit += sl.normalize();
tot_lit += sl;
if (in_valuta)
{
sl = scad.residuo(TRUE, 0x3);
tot_val += sl.normalize();
sl.normalize();
tot_val += sl;
add_importo(rsal, sl, 2);
}
}
@ -394,12 +542,14 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
row.add("");
TImporto i(sum.sezione(), pag.get_real(PAGSCA_IMPORTO));
i.normalize();
tot_lit += i;
add_importo(row, i);
if (in_valuta)
{
i = TImporto(sum.sezione(), pag.get_real(PAGSCA_IMPORTOVAL));
tot_val += i;
i.normalize();
add_importo(row, i, 2);
}
else
@ -425,13 +575,16 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
return TRUE;
}
int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata)
int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) const
{
const TBill& conto = partita.conto(); // Legge conto principale
int nrigp = partita.mov2rig(_numreg, _numrig); // Cerca riga partita relativa alla riga rmov
TMask& cm = app().curr_mask();
#ifndef __EXTRA__
const TCausale& causale = app().causale();
#endif
if (nrigp <= 0) // Devo creare una nuova riga di partita
{
TRiga_partite& part = partita.new_row(); // Creazione nuova riga vuota
@ -440,14 +593,21 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata)
// Copia dati movimento corrente
part.put(PART_NREG, _numreg); // Numero operazione
part.put(PART_NUMRIG, _numrig); // Riga su cui ho cliccato
part.put(PART_DATAREG, cm.get(F_DATAREG));
part.put(PART_DATADOC, cm.get(F_DATADOC));
part.put(PART_NUMDOC, cm.get(F_NUMDOC));
part.put(PART_DESCR, cm.get(F_DESCR));
part.put(PART_CODVAL, cm.get(S_VALUTA));
part.put(PART_CAMBIO, cm.get(S_CAMBIO));
part.put(PART_DATACAM, cm.get(S_DATACAMBIO));
part.put(PART_CODVAL, get(P_VALUTA));
part.put(PART_CAMBIO, get(P_CAMBIO));
part.put(PART_DATACAM, get(P_DATACAMBIO));
#ifdef __EXTRA__
part.zero(PART_DATAREG);
part.zero(PART_NUMDOC);
// Complesso algoritmo per calcolare la sezione di una nuova riga partita
const char sezione = (conto.tipo() == 'C') ? 'A' : 'D';
#else
part.put(PART_DATAREG, cm.get(F_DATAREG));
part.put(PART_NUMDOC, cm.get(F_NUMDOC));
// Copia dati causale corrente
const int tipomov = causale.tipomov();
part.put(PART_TIPOMOV, tipomov);
@ -457,7 +617,7 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata)
part.put(PART_REG, cm.get(F_CODREG));
part.put(PART_PROTIVA, cm.get(F_PROTIVA));
}
// Complesso algoritmo per calcolare la sezione di una nuova riga partita
char sezione = causale.sezione(1); // Usa la sezione della causale
if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta
@ -474,6 +634,7 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata)
if (bill.tipo() != conto.tipo())
sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno
}
#endif
part.put(PART_SEZ, sezione); // Memorizza solo la sezione (importi nulli)
part.put(PART_SEZABB, sezione);
@ -515,11 +676,13 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata)
pagamento.put(PAGSCA_CODAG, scad.get(SCAD_CODAG));
pagamento.put(PAGSCA_DATAPAG, cm.get(F_DATADOC));
}
#ifndef __EXTRA__
TBill contro; causale.bill(caus, contro); // Legge conto contropartita
if (contro.empty()) // Se non specificato ...
causale.bill(caus = 1, contro); // ... prende il primo
if (caus != 2 && contro.empty()) // Se non specificato ...
causale.bill(caus = 2, contro); // ... prende il primo
contro.put(pagamento, TRUE); // Scrive conto contropartita
#endif
return nrigp;
}
@ -557,8 +720,7 @@ bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k)
return f.error_box("Modificare il movimento %ld", nreg);
}
const bool dirty = app().edit_pagamento(game, nriga, nrata, nrigp);
const bool dirty = gm.edit_pagamento(game, nriga, nrata, nrigp);
if (dirty)
{
gm.update_partita(game, gm._riga_partite);
@ -580,7 +742,12 @@ bool TGame_mask::nuovo_handler(TMask_field& f, KEY k)
new_game.add_button(DLG_CANCEL, 0, "" , -22, 3, 8, 2);
new_game.first_focus(P_NUMERO);
if (app().causale().tipomov() == 2)
#ifdef __EXTRA__
const bool proponi = TRUE;
#else
const bool proponi = app().causale().tipomov() == 2;
#endif
if (proponi)
{
const TMask& cm = app().curr_mask();
new_game.set(P_ANNO, cm.get(F_ANNORIF));
@ -599,7 +766,7 @@ bool TGame_mask::nuovo_handler(TMask_field& f, KEY k)
const int nriga = TPartita::UNASSIGNED;
const int nrata = TPartita::UNASSIGNED;
const int nrigp = gm.nuovo_pagamento(game, nriga, nrata);
app().edit_pagamento(game, nriga, nrata, nrigp);
gm.edit_pagamento(game, nriga, nrata, nrigp);
if (game.ok())
{
game.write();
@ -787,340 +954,8 @@ void TGame_mask::fill_partite(int annorif, const char* numrif)
app().end_wait();
}
///////////////////////////////////////////////////////////
// Paymask
///////////////////////////////////////////////////////////
class TPay_mask : public TMask
{
bool _in_valuta;
real _da_pagare;
TValuta _valuta;
protected:
static bool importo_handler(TMask_field& f, KEY k);
public:
void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad);
void get_pag(TRectype& oldpag) const;
const TValuta& valuta() const { return _valuta; }
TPay_mask();
virtual ~TPay_mask() {}
};
TPay_mask::TPay_mask() : TMask("cg2100s")
{
}
void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad)
{
TRelation rel(LF_PAGSCA); // Working relation
rel.curr() = oldpag;
autoload(&rel); // Load current record on mask
const TRiga_partite& fatt = scad.riga();
set(S_NUMDOC, fatt.get(PART_NUMDOC)); // Numero documento
set(S_DATADOC, fatt.get(PART_DATADOC)); // Data documento
set(S_NUMPROT, fatt.get(PART_PROTIVA)); // Protocollo IVA
set(S_DESCR, fatt.get(PART_DESCR)); // Descrizione documento
set(S_DATA_SCAD, scad.get(SCAD_DATASCAD)); // Data della scadenza
set(S_SEZIONE_SCAD, scad.riga().sezione()); // Sezione della rata
set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO)); // Importo della rata
set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta
_in_valuta = scad.in_valuta();
_da_pagare = scad.residuo(_in_valuta).valore(); // Calcola residuo in valuta
TReal_field& res = (TReal_field&)field(S_RESIDUORATA);
res.set_decimals(_in_valuta ? 2 : 0);
res.set(_da_pagare.string());
if (!_da_pagare.is_zero())
set_handler(_in_valuta ? S_IMPORTOVAL : S_IMPORTO, importo_handler);
// Ricorda l'importo da pagare
_da_pagare += oldpag.get_real(_in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO);
// Attiva campi relativi alla valuta
show(-3, _in_valuta);
const TPartita& p = scad.partita();
const int nrigp = oldpag.get_int(PAGSCA_NRIGP);
const TRiga_partite& sum = p.riga(nrigp);
_valuta.get(sum);
const long numreg = sum.get_long(PART_NREG);
const int numrig = sum.get_int(PART_NUMRIG);
TImporto residuo(app().get_cgs_imp(numrig-1));
residuo -= app().partite().importo_speso(numreg, numrig);
set(S_RESIDUOPAG, residuo.valore().string());
// Il flag di saldo/acconto e' attivo solo se non ci sono acconti
bool sa = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED;
if (sa)
{
const TDate datasca(fatt.get(PART_DATADOC));
const TDate datapag(sum.get(PART_DATADOC));
sa = datapag >= datasca;
}
else
{
hide(S_RESIDUORATA);
}
enable(S_SALDOACC, sa);
const bool nota_credito = app().causale().tipomov() == 2;
if (nota_credito)
send_key(K_CTRL + K_SHIFT + 'c', -2); // Disabilita contropartita e ritenute
}
void TPay_mask::get_pag(TRectype& newpag) const
{
TRelation rel(LF_PAGSCA); // Working relation
rel.curr() = newpag;
autosave(&rel); // Load current record from mask
newpag = rel.curr();
}
bool TPay_mask::importo_handler(TMask_field& f, KEY k)
{
TPay_mask& m = (TPay_mask&)f.mask();
if (k == K_F8)
{
f.set(m._da_pagare.string());
k = K_TAB;
}
if (k == K_TAB && f.focusdirty())
{
const real i(f.get());
if (i >= m._da_pagare && m.field(S_SALDOACC).active())
m.set(S_SALDOACC, "S");
const real residuo(m._da_pagare - i);
m.set(S_RESIDUORATA, residuo.string());
if (f.dlg() == S_IMPORTOVAL)
{
const real lit = m.valuta().val2lit(i);
m.set(S_IMPORTO, lit.string());
}
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Metodi di prima nota
///////////////////////////////////////////////////////////
bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k)
{
bool ok = TRUE;
TMask& m = f.mask();
const char tipo = m.get(116)[0];
if (tipo == 'K' || (tipo == 'T' && app().causale().tipomov() == 2))
{
TSheet_field& s = *m.get_sheet();
const int riga = s.selected();
if (k == K_SPACE)
{
const bool ok = app().edit_partite(riga);
if (ok)
k = K_ENTER;
}
if (k == K_ENTER)
{
const long curreg = app().curr_mask().get_long(F_NUMREG);
const TImporto importo(app().get_cgs_imp(riga));
const TImporto speso(app().partite().importo_speso(curreg, riga+1));
if (importo != speso)
{
const char* ss = speso.valore().string(".");
return f.error_box("L'importo deve essere %s %c", ss, speso.sezione());
}
if (tipo == 'K' && !speso.is_zero())
app().disable_cgs_cells(riga, 'K');
}
}
return ok;
}
bool TPrimanota_application::edit_partite(int riga)
{
TToken_string& cgr = cgs().row(riga);
TImporto imp; imp = cgr;
if (imp.is_zero()) // Esci se 'importo e' nullo
return FALSE;
const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata
if (!b.ok())
return FALSE; // Esci se il conto della riga cliente non e' valido
curr_mask().autosave(get_relation()); // Aggiorna i dati della testata sulle partite
const TRectype& mov = get_relation()->curr();
partite().update_reg(mov);
// Esecuzione maschera di selezione partite
TGame_mask mask(b, mov.get_long(MOV_NUMREG), riga+1);
mask.run();
cgs().force_update(); // Aggiornamento righe contabili
return TRUE;
}
// deleting significato
// -1 non sto cancellando nulla
// 0 sto cancellando tutto
// 1 sto cancellando la prima riga contabile
// n sto cancellando la ennesima riga contabile
bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pag,
const TValuta& valuta, int deleting)
{
const int nriga = new_pag.get_int(PAGSCA_NRIGA); // Riga fattura
const int nrata = new_pag.get_int(PAGSCA_NRATA); // Numero rata
const int nrigp = new_pag.get_int(PAGSCA_NRIGP); // Riga pagamento
const TRectype& old_pag = p.pagamento(nriga, nrata, nrigp);
const TRiga_partite& somma = p.riga(nrigp);
const int riga_contabile = somma.get_int(PART_NUMRIG); // Riga movimento
if (deleting != 0)
{
const char sez = somma.sezione(); // Sezione importo e ritenute
const char controsez = sez == 'A' ? 'D' : 'A'; // Sezione contropartita
// Aggiornamento contopartita
const TImporto old_importo(controsez, old_pag.get_real(PAGSCA_IMPORTO));
TBill old_conto; old_conto.get(old_pag, TRUE);
const TImporto new_importo(controsez, new_pag.get_real(PAGSCA_IMPORTO));
TBill new_conto; new_conto.get(new_pag, TRUE);
if (old_importo != new_importo || old_conto != new_conto)
{
const int old_riga = bill2pos(old_conto, 'I');
if (old_riga >= 0)
{
const bool empty = sub_cgs_imp(old_riga, old_importo);
if (empty && (new_importo.is_zero() || new_conto != old_conto))
reset_cgs_row(old_riga);
}
// Importo della contropartita
if (!new_importo.is_zero() && new_conto.ok())
{
const int new_riga = bill2pos(new_conto, 'I');
if (new_riga < 0)
set_cgs_row(new_riga, new_importo, new_conto, "", 'I');
else
add_cgs_imp(new_riga, new_importo);
}
}
// Aggiornamento ritenute
const real old_ritenute(old_pag.get(PAGSCA_RITENUTE));
const real new_ritenute(new_pag.get(PAGSCA_RITENUTE));
if (old_ritenute != new_ritenute)
{
const TImporto grow_ritenute(controsez, new_ritenute-old_ritenute);
const riga = type2pos('F');
if (riga < 0)
{
TBill conto_rit; causale().bill(11, conto_rit);
set_cgs_row(riga, grow_ritenute, conto_rit, causale().desc_agg(11), 'F');
}
else
{
const bool empty = add_cgs_imp(riga, grow_ritenute);
if (empty) reset_cgs_row(riga);
}
}
} // if (deleting != 0)
char old_ap, new_ap;
TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam;
const bool empty = p.modifica_pagamento(new_pag, valuta,
old_ap, old_abbuono, old_diffcam,
new_ap, new_abbuono, new_diffcam);
if (deleting != 0)
{
// Se c'e' differenza negli abbuoni
if (old_abbuono != new_abbuono || old_ap != new_ap)
{
if (old_ap != ' ') // Se c'era un abbuono ...
{
const int riga_abb = type2pos(old_ap);
CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?");
const bool empty = sub_cgs_imp(riga_abb, old_abbuono);
if (empty && new_ap != old_ap)
reset_cgs_row(riga_abb);
if (deleting != riga_contabile)
{
// Sottrae l'abbuono con la sezione invertita dalla riga contabile
add_cgs_imp(riga_contabile-1, old_abbuono);
}
}
if (new_ap != ' ') // Se ci sono abbuoni
{
const riga_abb = type2pos(new_ap);
if (riga_abb < 0)
{
const int rc = new_ap == 'A' ? 9 : 8;
TBill conto_abb; causale().bill(rc, conto_abb);
app().set_cgs_row(riga_abb, new_abbuono, conto_abb, causale().desc_agg(rc), new_ap);
}
else
add_cgs_imp(riga_abb, new_abbuono);
if (deleting != riga_contabile)
{
// Aggiunge l'abbuono con la sezione invertita
sub_cgs_imp(riga_contabile-1, new_abbuono);
}
}
}
// Se c'e' variazione nella differenza cambi
if (old_diffcam != new_diffcam)
{
const int riga_diffcam = type2pos('C');
TImporto grow_diffcam(new_diffcam);
grow_diffcam -= old_diffcam;
grow_diffcam.normalize();
if (riga_diffcam < 0)
{
TBill conto_diffcam; causale().bill(12, conto_diffcam);
set_cgs_row(riga_diffcam, grow_diffcam, conto_diffcam, causale().desc_agg(12), 'C');
}
else
{
const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam);
if (empty) reset_cgs_row(riga_diffcam);
}
if (deleting != riga_contabile)
{
// Aggiunge la differenza con la sezione invertita
sub_cgs_imp(riga_contabile-1, grow_diffcam);
}
}
} // if (deleting != 0)
return empty;
}
bool TPrimanota_application::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp)
bool TGame_mask::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const
{
const TRectype& oldpag = p.pagamento(nriga, nrata, nrigp);
TRiga_partite& somma = p.riga(nrigp);
@ -1154,66 +989,48 @@ bool TPrimanota_application::edit_pagamento(TPartita& p, int nriga, int nrata, i
m.reset(S_RITENUTE); // Azzera ritenute
}
else
{
somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti)
}
TRectype new_pag(oldpag);
m.get_pag(new_pag);
const TValuta val; // Non cambiare valuta!
notify_edit_pagamento(p, new_pag, val);
}
return key != K_ESC;
}
TRectype new_pag(oldpag);
m.get_pag(new_pag);
// Scorre tutte le righe della partita ed azzera i pagamenti relativi a alla riga contabile
// cancellata e decrementa i numeri riga superiori a numrig
bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig)
{
bool found = FALSE;
for (int p = partita.last(); p > 0; p = partita.pred(p))
{
TRiga_partite& part = partita.riga(p);
if (part.get_int(PART_TIPOMOV) == 1)
{
for (int r = part.rate(); r > 0; r--)
{
const TRiga_scadenze& scad = part.rata(r);
for (int s = scad.last(); s > 0; s = scad.pred(s))
{
const TRiga_partite& sum = partita.riga(s);
if (sum.get_long(PART_NREG) == nreg &&
(numrig <= 0 || sum.get_int(PART_NUMRIG) == numrig))
{
TRectype nul_pag(scad.row(s));
nul_pag.zero(PAGSCA_IMPORTO);
nul_pag.zero(PAGSCA_IMPORTOVAL);
nul_pag.zero(PAGSCA_RITENUTE);
nul_pag.put(PAGSCA_ACCSAL, 'A');
const TValuta val; // Non cambiare valuta
notify_edit_pagamento(partita, nul_pag, val, numrig);
found = TRUE;
}
}
}
}
else
{
if (numrig > 0 && part.get_long(PART_NREG) == nreg && part.get_int(PART_NUMRIG) > numrig)
part.put(PART_NUMRIG, numrig-1);
}
const TValuta val; // Non cambiare valuta!
#ifdef __EXTRA__
p.modifica_pagamento(new_pag, val);
#else
app().notify_edit_pagamento(p, new_pag, val);
#endif
}
return found;
return key != K_ESC;
}
bool TPrimanota_application::notify_cgline_deletion(int numrig)
{
bool found = FALSE;
const long nreg = curr_mask().get_long(F_NUMREG);
for (TPartita* game = _partite.first(); game; game = _partite.next())
found |= notify_cgline_deletion(*game, nreg, numrig);
return found;
///////////////////////////////////////////////////////////
// Edit delle partite
///////////////////////////////////////////////////////////
bool TPrimanota_application::edit_partite(int riga)
{
TToken_string& cgr = cgs().row(riga);
TImporto imp; imp = cgr;
if (imp.is_zero()) // Esci se 'importo e' nullo
return FALSE;
const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata
if (!b.ok())
return FALSE; // Esci se il conto della riga cliente non e' valido
curr_mask().autosave(get_relation()); // Aggiorna i dati della testata sulle partite
const TRectype& mov = get_relation()->curr();
partite().update_reg(mov);
// Esecuzione maschera di selezione partite
TGame_mask mask(b, mov.get_long(MOV_NUMREG), riga+1);
mask.run();
cgs().force_update(); // Aggiornamento righe contabili
return TRUE;
}

View File

@ -132,7 +132,7 @@ TValuta::TValuta() : _cod(""), _dat(TODAY), _cam(1.0)
void TValuta::adjust()
{
_cod.upper();
if (_cod.empty() || _cod == "LIT")
if (_cod.empty() || _cod == "LIT" || _cam.is_zero())
_cam = 1.0;
}
@ -154,16 +154,34 @@ void TValuta::get(const TRectype& rec)
void TValuta::put(TRectype& rec) const
{
rec.put("CODVAL", _cod);
rec.put("DATACAM", _dat);
rec.put("CAMBIO", _cam);
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
{
m.set(v, _cod);
m.set(d, _dat.string());
m.set(c, _cam.string());
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)
@ -286,7 +304,7 @@ TImporto TRiga_scadenze::importo_pagato(bool val, int mode) const
}
}
return totale;
return totale.normalize();
}
// Calcola l'importo da pagare (eventualmente in valuta)
@ -362,7 +380,8 @@ TImporto TRiga_scadenze::calcola_differenza_cambio(int p, bool update)
if (update)
pag.zero(PAGSCA_DIFFCAM);
}
return diffcam;
return diffcam.normalize();
}
TImporto TRiga_scadenze::residuo(bool val, int mode) const
@ -408,6 +427,7 @@ bool TRiga_scadenze::modifica_pagamento(const TRectype& new_pag, const TValuta&
new_abb.valore() *= sum.get_real(PART_CAMBIO);
new_abb.valore().round();
}
new_abb.normalize();
// Scambia sezione per registrazione contabile
old_abbuono.swap_section();
@ -720,17 +740,16 @@ void TPartita::update_reg(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)
TRiga_partite& rig = riga(r);
if (rig.get_long(PART_NREG) == nreg)
{
pag.put(PART_NREG, mov.get(MOV_NUMREG));
pag.put(PART_DATAREG, mov.get(MOV_DATAREG));
pag.put(PART_DATADOC, mov.get(MOV_DATADOC));
pag.put(PART_NUMDOC, mov.get(MOV_NUMDOC));
pag.put(PART_REG, mov.get(MOV_REG));
pag.put(PART_PROTIVA, mov.get(MOV_PROTIVA));
pag.put(PART_CODCAUS, mov.get(MOV_CODCAUS));
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));
}
}
}
@ -754,7 +773,7 @@ int TPartita::mov2rig(long numreg, int rm) const
return r;
}
}
return -1;
return 0;
}
// Trova la prima riga della partita contenente una fattura
@ -815,14 +834,19 @@ void TPartita::calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImp
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
@ -1150,7 +1174,7 @@ int TPartite_array::add_numreg(long nreg)
if (nreg != _numreg)
{
TRelation rel(LF_PARTITE);
TRectype& part = rel.lfile().curr();
TRectype& part = rel.curr();
// Costruzione cursore filtrato
part.zero();
@ -1167,12 +1191,24 @@ int TPartite_array::add_numreg(long 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;
}

View File

@ -276,6 +276,9 @@ public:
TImporto importo_speso(long numreg, int numrig);
void update_reg(const TRectype& mov, long old_reg = 0);
// Controlla se esistono righe di pagamento relative alla riga numrig
bool utilizzata(long numreg, int numrig);
TPartita* first() { restart(); return next(); }
TPartita* next() { return (TPartita*)get(); }