campo-sirio/cg/cg2105.cpp
guy 919e99206f Corretta gestione modifica rata in prima nota
git-svn-id: svn://10.65.10.50/trunk@1942 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-10-12 15:02:46 +00:00

1029 lines
32 KiB
C++
Executable File

#include <defmask.h> // Serve per DLG_NEWREC
#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
#include <mov.h> // Archivio movimenti di prima nota
#include <pagsca.h> // Archivio pagamenti
#include <partite.h> // Archivio partite
#include <scadenze.h> // Archivio scadenze
///////////////////////////////////////////////////////////
// Maschera pagamenti
///////////////////////////////////////////////////////////
class TPay_mask : public TMask
{
real _da_pagare, _pagabile;
TValuta _valuta;
protected:
static bool importo_handler(TMask_field& f, KEY k);
public:
void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad, const TImporto& importo);
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,
const TImporto& importo)
{
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());
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);
const long numreg = sum.get_long(PART_NREG);
const int numrig = sum.get_int(PART_NUMRIG);
_valuta.get(sum);
TReal_field& resp = (TReal_field&)field(S_RESIDUOPAG);
resp.set_decimals(in_valuta ? 2 : 0);
TImporto r(importo);
r -= app().partite().importo_speso(numreg, numrig);
if (in_valuta)
_pagabile = _valuta.lit2val(r.valore());
else
_pagabile = r.valore();
resp.set(_pagabile.string());
_pagabile += oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO);
// 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)
{
const real& imp = fnc_min(m._da_pagare, m._pagabile);
f.set(imp.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());
const real residuopag(m._pagabile - i);
m.set(S_RESIDUOPAG, residuopag.string());
if (f.dlg() == S_IMPORTOVAL)
{
const real lit = m.valuta().val2lit(i);
m.set(S_IMPORTO, lit.string());
}
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Maschera partite
///////////////////////////////////////////////////////////
class TGame_mask : public TMask
{
const TBill _conto; // Conto fisso del cliente/fornitore
long _numreg; // Numero movimento contabile
int _numrig; // Riga contabile corrente (prima = 1!)
TImporto _importo; // Importo riga contabile
int _riga_partite; // Riga corrente delle partite
protected:
static bool annopart_handler(TMask_field& f, KEY k);
static bool numpart_handler(TMask_field& f, KEY k);
static bool partite_notify(TSheet_field& partite, int r, KEY k);
static bool show_all_handler(TMask_field& f, KEY k);
static bool edit_scadenza_handler(TMask_field& f, KEY k);
static bool nuovo_handler(TMask_field& f, KEY k);
static bool cambio_handler(TMask_field& f, KEY k);
static void add_importo(TToken_string& s, const TImporto& i, int dec = 0);
TImporto get_importo(TToken_string& s, int pos) const;
void fill_partite(int anno = 0, const char* numero = "");
real aggiorna_residuo();
int update_partita(const TPartita& game, int prow);
void update_saldo_clifo();
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);
public:
TSheet_field& partite() const { return (TSheet_field&)field(P_PARTITE); }
TSheet_field& scadenze() const { return (TSheet_field&)field(P_SCADENZE); }
const TBill& conto() const { return _conto; }
TGame_mask(const TBill& bill, long numreg, int riga);
virtual ~TGame_mask() {}
};
TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga)
: TMask("cg2100p"), _conto(bill), _numreg(numreg), _numrig(riga)
{
const char tipocf[2] = { _conto.tipo(), '\0' };
set(P_TIPOC, tipocf);
set(P_GRUPPO, _conto.gruppo());
set(P_CONTO, _conto.conto());
set(P_SOTTOCONTO, _conto.sottoconto());
set(P_DESCR, ((TBill&)_conto).descrizione());
TValuta val;
#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);
set_handler(P_SHOWALL, show_all_handler);
set_handler(P_NUOVO, nuovo_handler);
set_handler(P_CAMBIO, cambio_handler);
partite().set_notify(partite_notify);
scadenze().sheet_mask().set_handler(100, edit_scadenza_handler);
}
///////////////////////////////////////////////////////////
// Handlers dei campi e della maschera principale
///////////////////////////////////////////////////////////
bool TGame_mask::annopart_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.focusdirty() && f.get().not_empty())
{
TMask_field& n = f.mask().field(P_NUMERO);
n.set_dirty();
numpart_handler(n, k);
}
return TRUE;
}
bool TGame_mask::numpart_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.dirty())
{
const TGame_mask& m = (const TGame_mask&)f.mask();
const int anno = m.get_int(P_ANNO);
const TString16 num = f.get();
if (anno > 0 && num.not_empty())
{
TSheet_field& sheet = m.partite();
for (int i = 0; i < sheet.items(); i++)
{
TToken_string& row = sheet.row(i);
if (anno == row.get_int(0)) // Se corrisponde l'anno e ...
if (num == row.get()) // corrisponde il numero partita ...
{
sheet.select(i); // ... seleziona la partita
partite_notify(sheet, i, K_TAB); // ed esplodi le sue righe
break;
}
}
if (i >= sheet.items())
f.warning_box("Partita inesistente");
}
}
return TRUE;
}
bool TGame_mask::show_all_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TGame_mask& gm = (TGame_mask&)f.mask();
gm.fill_partite();
}
return TRUE;
}
bool TGame_mask::cambio_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.focusdirty() &&
yesno_box("Aggiornare gli importi dei pagamenti?"))
{
TGame_mask& gm = (TGame_mask&)f.mask();
TValuta val; val.get(gm, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
gm.aggiorna_valuta(val);
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Metodi dei campi e della maschera principale
///////////////////////////////////////////////////////////
real TGame_mask::aggiorna_residuo()
{
#ifdef EXTRA
return ZERO;
#else
_importo = app().get_cgs_imp(_numrig-1);
TImporto residuo(_importo);
residuo -= app().partite().importo_speso(_numreg, _numrig);
set(P_RESIDUO, residuo.valore().string());
return residuo.valore();
#endif
}
bool TGame_mask::cerca_valuta(TValuta& val) const
{
bool found = FALSE;
TPartite_array& pa = app().partite();
for (const TPartita* game = pa.first(); game; game = pa.next())
{
const int r = game->mov2rig(_numreg, _numrig);
if (r > 0)
{
const TRiga_partite& row = game->riga(r);
val.get(row);
found = TRUE;
break;
}
}
return found;
}
void TGame_mask::aggiorna_valuta(const TValuta& val)
{
int annorif = 0;
TString16 numrif;
TPartite_array& pa = app().partite();
for (TPartita* game = pa.first(); game; game = pa.next())
{
for (int r = game->last(); r > 0; r = game->pred(r))
{
const TRiga_partite& riga = game->riga(r);
for (int s = riga.rate(); s > 0; s--)
{
const TRiga_scadenze& scad = riga.rata(s);
for (int p = scad.last(); p > 0; p = scad.pred(p))
{
TRiga_partite& sum = game->riga(p);
if (sum.get_long(PART_NREG) == _numreg &&
sum.get_int(PART_NUMRIG) == _numrig)
{
if (annorif == 0)
{
annorif = sum.get_int(PART_ANNO);
numrif = sum.get(PART_NUMPART);
}
TRectype pag(scad.row(p));
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
}
}
}
}
}
if (annorif != 0)
{
#ifdef __EXTRA__
const bool proponi = RUE;
#else
const bool proponi = app().causale().tipomov() == 2;
#endif
if (proponi)
{
const TMask& cm = app().curr_mask();
const int anno = cm.get_int(F_ANNORIF);
if (anno != 0)
{
annorif = anno;
numrif = cm.get(F_NUMRIF);
}
}
}
fill_partite(annorif, numrif);
}
bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
{
if (k == K_TAB)
{
TGame_mask& gm = (TGame_mask&)partite.mask();
gm._riga_partite = r;
TString_array& scadenze = gm.scadenze().rows_array();
scadenze.destroy();
const TBill& zio = gm.conto(); // Conto cliente/fornitore
TToken_string& row = partite.row(r);
const int anno = row.get_int(0); // Anno partita
const TString16 num = row.get(); // Numero partita
gm.set(P_ANNO, anno); // Aggiorna campi di ricerca
gm.set(P_NUMERO, num);
TPartita* game = app().partite().exist(zio, anno, num); // Cerca la partita tra quelle editate
const bool should_delete_game = (game == NULL); // Ricorda di fare delete
if (should_delete_game) // Se non c'era ...
game = new TPartita(zio, anno, num); // ... creane una temporanea
TImporto tot_lit, tot_val;
const int lastrow = game->last();
for (int ri = game->first(); ri <= lastrow; ri = game->succ(ri))
{
const TRiga_partite& riga = game->riga(ri);
const bool in_valuta = riga.in_valuta();
for (int ra = 1; ra <= riga.rate(); ra++)
{
const TRiga_scadenze& scad = riga.rata(ra);
TToken_string& row = scadenze.row(scadenze.add(""));
row.add(ri);
row.add(ra);
row.add(scad.get(SCAD_DATASCAD));
row.add(riga.get(PART_DATADOC));
row.add(riga.get(PART_DESCR));
add_importo(row, TImporto(riga.sezione(), scad.get_real(SCAD_IMPORTO)));
if (in_valuta)
add_importo(row, TImporto(riga.sezione(), scad.get_real(SCAD_IMPORTOVAL)), 2);
else
row.add("");
row.add(riga.get(PART_NREG));
row.add(riga.get(PART_DATAREG));
row.add(riga.get(PART_NUMDOC));
row.add(riga.get(PART_PROTIVA));
const int lastp = scad.last();
for (int pa = scad.first(); pa <= lastp; pa = scad.succ(pa))
{
const TRectype& pag = scad.row(pa);
const TRiga_partite& sum = game->riga(pa);
const char sez = sum.sezione();
TToken_string& row = scadenze.row(scadenze.add(""));
row.add(ri);
row.add(ra);
row.add(scad.get(SCAD_DATASCAD));
row.add(sum.get(PART_DATADOC));
row.add(sum.get(PART_DESCR));
add_importo(row, TImporto(sez, pag.get_real(PAGSCA_IMPORTO)));
if (in_valuta)
add_importo(row, TImporto(sez, pag.get_real(PAGSCA_IMPORTOVAL)), 2);
else
row.add("");
row.add(sum.get(PART_NREG));
row.add(sum.get(PART_DATAREG));
row.add(sum.get(PART_NUMDOC));
row.add("");
row.add(pa);
}
TImporto abb(scad.importo_pagato(TRUE, 0x2));
if (!abb.is_zero())
{
TToken_string& rabb = scadenze.row(scadenze.add(""));
rabb.add("Abbuoni rata ", 4); rabb << ra;
if (in_valuta)
{
add_importo(rabb, scad.importo_pagato(FALSE, 0x2));
add_importo(rabb, abb);
}
else
{
add_importo(rabb, abb, 2);
rabb.add("");
}
}
if (in_valuta)
{
TImporto diff(scad.importo_pagato(FALSE, 0x4));
if (!diff.is_zero())
{
TToken_string& rdiff = scadenze.row(scadenze.add(""));
rdiff.add("Differ. cambio rata ", 4); rdiff << ra;
add_importo(rdiff, diff.normalize());
}
}
TToken_string& rsal = scadenze.row(scadenze.add(""));
rsal.add("Saldo rata ", 4); rsal << ra;
if (!scad.chiusa())
{
TImporto sl(scad.residuo(FALSE, 0x7));
sl.normalize();
add_importo(rsal, sl);
tot_lit += sl;
if (in_valuta)
{
sl = scad.residuo(TRUE, 0x3);
sl.normalize();
add_importo(rsal, sl, 2);
tot_val += sl;
}
}
}
TRecord_array& unas = game->unassigned();
const int lastp = unas.last_row();
for (int pa = unas.first_row(); pa <= lastp; pa = unas.succ_row(pa))
{
const TRectype& pag = unas.row(pa);
const TRiga_partite& sum = game->riga(pa);
TImporto imp(sum.sezione(), ZERO);
TToken_string& row = scadenze.row(scadenze.add(""));
row.add("9999|9999| ");
row.add(sum.get(PART_DATADOC));
row.add(sum.get(PART_DESCR));
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
row.add("");
row.add(sum.get(PART_NREG));
row.add(sum.get(PART_DATAREG));
row.add(sum.get(PART_NUMDOC));
row.add("");
row.add(pa);
}
}
if (lastrow > 0)
{
TToken_string& sp = scadenze.row(scadenze.add(""));
sp.add("Saldo ", 4); sp << anno << ' ' << num;
add_importo(sp, tot_lit.normalize());
add_importo(sp, tot_val.normalize(), 2);
}
gm.scadenze().force_update();
if (should_delete_game)
delete game;
}
return TRUE;
}
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
nrigp = part.get_int(PART_NRIGA);
// Copia dati movimento corrente
part.put(PART_NREG, _numreg); // Numero operazione
part.put(PART_NUMRIG, _numrig); // Riga su cui ho cliccato
part.put(PART_DATADOC, cm.get(F_DATADOC));
part.put(PART_DESCR, cm.get(F_DESCR));
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);
part.put(PART_CODCAUS, causale.codice());
if (causale.iva() != nessuna_iva)
{
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
{
if (tipomov == 1 || tipomov == 5) // calcola in base al tipo movimento e
sezione = (conto.tipo() == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore
else
sezione = (conto.tipo() == 'C') ? 'A' : 'D';
}
if (conto.tipo() > ' ') // Se il tipo e' C o F
{
TBill bill; causale.bill(1, bill); // Legge primo conto causale
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);
part.put(PART_SEZDIFCAM, sezione);
}
TRectype& pagamento = partita.pagamento(nriga, rata, nrigp); // Crea nuovo pagamento
int caus = 2; // Calcola riga causale per la contropartita in base al tipo pagamento
if (rata != TPartita::UNASSIGNED)
{
const TRiga_scadenze& scad = partita.rata(nriga, rata);
const int tp = scad.get_int(SCAD_TIPOPAG);
switch (tp)
{
case 2: // Tratta
case 7: // Tratta accettata
caus = 3; break;
case 3: // Ricevuta bancaria
caus = 4; break;
case 4: // Cessione
caus = 5; break;
case 5: // Paghero'
caus = 6; break;
case 6: // Fattura di credito
caus = 7; break;
case 1: // Rimessa
case 8: // Rapporti interbancari diretti
case 9: // Bonifico
default:
caus = 2; break;
}
pagamento.put(PAGSCA_TIPOPAG, tp);
pagamento.put(PAGSCA_CODABIPR, scad.get(SCAD_CODABIPR));
pagamento.put(PAGSCA_CODCABPR, scad.get(SCAD_CODCABPR));
pagamento.put(PAGSCA_CODABI, scad.get(SCAD_CODABI));
pagamento.put(PAGSCA_CODCAB, scad.get(SCAD_CODCAB));
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 (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;
}
bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
const int nriga = m.get_int(101);
const int nrata = m.get_int(102);
if (nriga == 0 || nrata == 0)
return FALSE; // Ho cliccato su di un saldo (per sbaglio!)
TGame_mask& gm = (TGame_mask&)(m.get_sheet()->mask());
TMask_field& cambio = gm.field(P_CAMBIO);
if (cambio.active() && cambio.get().empty())
return f.error_box("E' necessario specificare un cambio");
const TBill& bill = gm.conto();
const int anno = gm.get_int(P_ANNO);
const TString16 numero = gm.get(P_NUMERO);
TPartita& game = app().partite().partita(bill, anno, numero);
int nrigp = m.get_int(112);
if (nrigp == 0)
{
nrigp = gm.nuovo_pagamento(game, nriga, nrata);
}
else
{
const long nreg = m.get_long(108);
if (nreg != gm._numreg)
return f.error_box("Modificare il movimento %ld", nreg);
}
const bool dirty = gm.edit_pagamento(game, nriga, nrata, nrigp);
if (dirty)
{
gm.update_partita(game, gm._riga_partite);
partite_notify(gm.partite(), gm._riga_partite, K_TAB);
}
}
return TRUE;
}
bool TGame_mask::nuovo_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
int anno;
TString16 numero;
// Graffa tattica per distruggere la maschera new_game alla fine del blocco
{
TMask new_game("Nuova partita", 1, 24, 5);
new_game.add_number(P_ANNO, 0, "Anno ", 1, 1, 4, "A");
new_game.add_string(P_NUMERO, 0, "Partita ", 1, 2, 7, "U");
new_game.add_button(DLG_OK, 0, "" , -12, 3, 8, 2);
new_game.add_button(DLG_CANCEL, 0, "" , -22, 3, 8, 2);
new_game.first_focus(P_NUMERO);
#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));
new_game.set(P_NUMERO, cm.get(F_NUMRIF));
}
k = new_game.run();
anno = new_game.get_int(P_ANNO);
numero = new_game.get(P_NUMERO);
}
if (k == K_ENTER)
{
TGame_mask& gm = (TGame_mask&)f.mask();
TPartita& game = app().partite().partita(gm.conto(), anno, numero);
if (game.ok())
return error_box("La partita %d %s esiste gia'.", anno, (const char*)numero);
const int nriga = TPartita::UNASSIGNED;
const int nrata = TPartita::UNASSIGNED;
const int nrigp = gm.nuovo_pagamento(game, nriga, nrata);
gm.edit_pagamento(game, nriga, nrata, nrigp);
if (game.ok())
gm.fill_partite(anno, numero); // Aggiorna sheet partite
else
app().partite().destroy(gm.conto(), anno, numero);
}
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Metodi della maschera delle partite
///////////////////////////////////////////////////////////
void TGame_mask::add_importo(TToken_string& s, const TImporto& i, int dec)
{
if (i.is_zero())
s.add("");
else
{
s.add(i.valore().string(dec));
s << ' ' << i.sezione();
}
}
TImporto TGame_mask::get_importo(TToken_string& s, int pos) const
{
const TFixed_string imp(s.get(pos));
const real i(imp);
const char sez = imp.right(1)[0];
return TImporto(sez, i);
}
int TGame_mask::update_partita(const TPartita& game, int prow)
{
TImporto saldo, doc, pag, imp;
game.calcola_saldo(saldo, doc, pag, imp);
TSheet_field& games = partite();
int riga_fatt = game.prima_fattura();
if (riga_fatt <= 0) riga_fatt = game.first(); // E' un anticipo
TToken_string &r = games.row(prow); // Stringa di lavoro per lo sheet
if (game.esiste(riga_fatt)) // Esiste veramente
{
const TRiga_partite& riga = game.riga(riga_fatt);
r.cut(0);
r.add(riga.get(PART_ANNO));
r.add(riga.get(PART_NUMPART));
r.add(riga.get(PART_DATADOC));
r.add(riga.get(PART_NUMDOC));
add_importo(r, saldo);
add_importo(r, doc);
add_importo(r, pag);
add_importo(r, imp);
r.add(riga.get(PART_DESCR));
}
else
{
r.add("", 4);
r.add("", 5);
r.add("", 6);
r.add("", 7);
}
if (prow >= 0)
{
games.force_update(prow);
update_saldo_clifo();
games.force_update(games.items()-1);
aggiorna_residuo();
}
else
prow = partite().items()-1;
return prow;
}
void TGame_mask::update_saldo_clifo()
{
TString_array& s = partite().rows_array();
TImporto sal, doc, pag, imp;
for (int i = 0; i < s.items(); i++)
{
TToken_string& r = s.row(i);
if (r.get_int(0) > 0)
{
sal += get_importo(r, 4);
doc += get_importo(r, -1);
pag += get_importo(r, -1);
imp += get_importo(r, -1);
}
else
break;
}
TToken_string& r = s.row(s.add("", i));
r.add("");
r.add("");
r.add(TDate(TODAY).string());
r.add("");
add_importo(r, sal);
add_importo(r, doc);
add_importo(r, pag);
add_importo(r, imp);
r.add("Saldo ");
if (get(P_TIPOC)[0] == 'C')
r << "cliente";
else
r << "fornitore";
}
void TGame_mask::fill_partite(int annorif, const char* numrif)
{
const bool all = get(P_SHOWALL).not_empty();
int first_game = -1;
TString_array& a = partite().rows_array();
a.destroy();
app().begin_wait();
for (TPartita* gioco = app().partite().first(); gioco != NULL; gioco = app().partite().next())
{
const int added = update_partita(*gioco, -1);
if (first_game < 0 && gioco->anno() == annorif && gioco->numero() == numrif)
first_game = added;
}
TLocalisamfile partita(LF_PARTITE);
partita.zero();
if (conto().tipo() > ' ') // Ignora gruppo e conto dei clifo
{
partita.put(PART_TIPOCF, conto().tipo());
partita.put(PART_SOTTOCONTO, conto().sottoconto());
}
else conto().put(partita.curr()); // Scrive completamente i conti normali
const TRectype filter(partita.curr()); // Record campione
for (int err = partita.read(_isgteq);
err == NOERR && partita.curr() == filter;
err = partita.read(_isgreat))
{
const int anno = partita.get_int(PART_ANNO);
const TString16 num(partita.get(PART_NUMPART));
if (!app().partite().exist(conto(), anno, num))
{
TPartita game(conto(), anno, num);
int added = -1;
if (all || !game.chiusa())
added = update_partita(game, -1);
if (first_game < 0 && added >= 0 && anno == annorif && num == numrif)
first_game = added;
}
partita.put(PART_NRIGA, 9999); // Forza lettura partita successiva nella prossima read
}
update_saldo_clifo();
partite().force_update();
aggiorna_residuo();
if (a.items() > 0)
{
if (first_game < 0) first_game = 0;
partite_notify(partite(), first_game, K_TAB);
}
else
{
scadenze().destroy();
scadenze().force_update();
}
app().end_wait();
}
bool TGame_mask::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const
{
TRectype oldpag = p.pagamento(nriga, nrata, nrigp);
TRiga_partite& somma = p.riga(nrigp);
TPay_mask m;
// Dati della scadenza che ha generato la partita
if (nriga != TPartita::UNASSIGNED)
{
const TRiga_scadenze& scaden = p.rata(nriga, nrata);
m.set_pag(oldpag, scaden, _importo);
}
else
{
nriga = p.primo_pagamento();
TRiga_partite& riga = p.riga(nriga);
TRiga_scadenze& scaden = riga.new_row();
m.set_pag(oldpag, scaden, _importo);
riga.destroy_rows();
}
m.set(S_DESCAGG, somma.get(PART_DESCR));
const KEY key = m.run();
if (key == K_ENTER || key == K_DEL)
{
if (key == K_DEL)
{
m.reset(S_SALDOACC); // Non puo' essere un saldo
m.reset(S_IMPORTO); // Azzera importo ...
m.reset(S_IMPORTOVAL); // .. anche in valuta
m.reset(S_RITENUTE); // Azzera ritenute
}
else
somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti)
TRectype newpag(oldpag);
m.get_pag(newpag);
const TValuta val; // Non cambiare valuta!
#ifdef __EXTRA__
p.modifica_pagamento(newpag, val);
#else
app().notify_edit_pagamento(p, newpag, val);
#endif
}
return key != K_ESC;
}
///////////////////////////////////////////////////////////
// Edit delle partite
///////////////////////////////////////////////////////////
bool TPrimanota_application::edit_partite(const TMask& m, int riga)
{
const TImporto imp = get_cgs_imp(riga);
if (imp.is_zero()) // Esci se 'importo e' nullo
return FALSE;
TBill b; // Legge il conto della riga selezionata
b.set(m.get_int(104), m.get_int(105), m.get_long(106), m.get(103)[0]);
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
calcola_saldo();
return TRUE;
}