campo-sirio/cg/cg2107.cpp
luca 96074eca0f Patch level :4.0 567
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :corretti errori di riporto


git-svn-id: svn://10.65.10.50/trunk@14637 c028cbd2-c16b-5b4b-a496-9718f37d4682
2006-12-14 16:45:14 +00:00

588 lines
14 KiB
C++
Executable File

#include "cg2102.h"
#include "cg2107.h"
#include "cg2100e.h"
#include "cgsaldac.h"
#include <defmask.h>
#include <diction.h>
#include <relation.h>
#include <tree.h>
///////////////////////////////////////////////////////////
// TPartite_cache
///////////////////////////////////////////////////////////
class TPartite_cache : public TString_array
{
TBill _bill;
long _numreg;
public:
const TBill& bill() const { return _bill; }
long num_reg() const { return _numreg; }
void set_bill(const TBill& conto, long numreg, bool all);
bool has_game(int id) const { return id >= 0 && id < items(); }
TPartita* find(int index) const; // Find by index (0 based)
TPartita& game(int index) const { return *find(index); }
};
// Callback per scansione cursore
static bool fill_games(const TRelation& rel, void* pJolly)
{
TString_array& a = *(TString_array*)pJolly;
TString16 key, last_key;
const TRectype& rec = rel.curr();
key.format("%d|%s", rec.get_int(PART_ANNO), (const char*)rec.get(PART_NUMPART));
const int last = a.items()-1;
if (last >= 0)
last_key = a.row(last);
if (key != last_key)
a.add(key);
return true;
}
void TPartite_cache::set_bill(const TBill& conto, long numreg, bool all)
{
_bill = conto;
_numreg = numreg;
destroy();
TRelation partite(LF_PARTITE);
TRectype& rec = partite.curr();
rec.put(PART_TIPOCF, conto.tipo());
rec.put(PART_GRUPPO, conto.tipo() > ' ' ? 0 : conto.gruppo());
rec.put(PART_CONTO, conto.tipo() > ' ' ? 0 : conto.conto());
rec.put(PART_SOTTOCONTO, conto.sottoconto());
TString filter;
filter << '(' << PART_NUMRIG << "<9999)";
if (!all)
filter << "&&((" << PART_CHIUSA << "!='X')||("
<< PART_NREG << "==" << numreg << "))";
TCursor cur(&partite, filter, 1, &rec, &rec);
cur.scan(fill_games, this);
}
TPartita* TPartite_cache::find(int idx) const
{
TPartita* g = NULL;
if (has_game(idx))
{
const TToken_string& str = row(idx);
int anno; str.get(0, anno);
TString8 numero; str.get(1, numero);
TPartite_array& giochi = app().partite();
g = &giochi.partita(_bill, anno, numero);
}
return g;
}
///////////////////////////////////////////////////////////
// TSolder_tree
///////////////////////////////////////////////////////////
class TSolder_tree : public TBidirectional_tree
{
TPartite_cache _cache;
TToken_string _curr;
public:
virtual bool goto_root();
virtual bool goto_firstson();
virtual bool goto_rbrother();
virtual bool goto_node(const TString &id) { _curr = id; return true; }
virtual bool has_son() const;
virtual bool has_rbrother() const;
virtual TObject* curr_node() const { return (TObject*)&_curr; }
virtual void node2id(const TObject* obj, TString& id) const { id = *(TString*)obj; }
virtual bool has_root() const { return _cache.bill().ok(); }
virtual bool has_father() const { return _curr.not_empty(); }
virtual bool has_lbrother() const;
virtual bool goto_father();
virtual bool goto_lbrother();
virtual bool get_description(TString& desc) const;
virtual bool marked() const;
public:
void set_root(const TBill& conto, long numreg, bool all);
TPartita* partita() const;
};
TPartita* TSolder_tree::partita() const
{
int index = -1; _curr.get(0, index);
TPartita* g = _cache.find(index);
return g;
}
bool TSolder_tree::goto_root()
{
_curr.cut(0);
return _cache.bill().ok();
}
bool TSolder_tree::goto_firstson()
{
const int level = _curr.items();
if (level >= 4)
return false;
const TPartita* g = partita(); // Funziona per level <= 1
if (g == NULL)
return false;
if (level == 0)
{
_curr = "0";
return true; // Basta il test precedente g!=NULL
}
if (level == 1)
{
const int riga = g->first();
const bool ok = riga > 0 && riga < 9999;
if (ok)
_curr.add(riga);
return ok;
}
const int riga = _curr.get_int(1);
if (level == 2)
{
const bool ok = g->esiste(riga, 1);
if (ok)
_curr.add(1);
return ok;
}
const int rata = _curr.get_int(2);
if (level == 3)
{
const TRiga_scadenze& scad = g->rata(riga, rata);
const int p = scad.first();
const bool ok = p > 0 && p < 9999;
if (ok)
_curr.add(p);
return ok;
}
return false;
}
bool TSolder_tree::goto_rbrother()
{
const int level = _curr.items();
if (level == 0) // Il prossimo clifo non esiste mai per progetto
return false;
const int index = _curr.get_int(0);
if (level == 1) // Esite la prossima partita?
{
const bool ok = _cache.find(index+1) != NULL;
if (ok)
_curr.add(index+1, 0);
return ok;
}
const TPartita& g = _cache.game(index);
const int riga = _curr.get_int(1);
if (level == 2) // Esite la prossima riga?
{
const int nriga = g.succ(riga);
const bool ok = nriga > riga && nriga < 9999;
if (ok)
_curr.add(nriga, 1);
return ok;
}
const int rata = _curr.get_int(2);
if (level == 3) // Esiste la prossima rata?
{
const int nrata = rata+1;
const bool ok = g.esiste(riga, nrata);
if (ok)
_curr.add(nrata, 2);
return ok;
}
const int pag = _curr.get_int(3);
if (level == 4) // Esiste il prossimo pagamento
{
const TRiga_scadenze& scad = g.rata(riga, rata);
const int npag = scad.succ(pag);
const bool ok = g.esiste(riga, rata, npag);
if (ok)
_curr.add(npag, 3);
return ok;
}
return false;
}
bool TSolder_tree::has_son() const
{
TSolder_tree& me = (TSolder_tree&)*this;
const TString16 old = me._curr;
const bool ok = me.goto_firstson();
me._curr = old;
return ok;
}
bool TSolder_tree::has_rbrother() const
{
TSolder_tree& me = (TSolder_tree&)*this;
const TString16 old = me._curr;
const bool ok = me.goto_rbrother();
me._curr = old;
return ok;
}
bool TSolder_tree::has_lbrother() const
{
TSolder_tree& me = (TSolder_tree&)*this;
const TString16 old = me._curr;
const bool ok = me.goto_lbrother();
me._curr = old;
return ok;
}
bool TSolder_tree::goto_father()
{
const bool ok = has_father();
if (ok)
{
const int pipe = _curr.rfind(_curr.separator());
if (pipe >= 0)
_curr.cut(pipe);
else
_curr.cut(0);
}
return ok;
}
bool TSolder_tree::goto_lbrother()
{
const int level = _curr.items();
if (level == 0) // Il precedente clifo non esiste mai per progetto
return false;
const int index = _curr.get_int(0);
if (level == 1) // Esite la precedente partita?
{
const bool ok = index > 0;
if (ok)
_curr.add(index-1, 0);
return ok;
}
const TPartita& g = _cache.game(index);
const int riga = _curr.get_int(1);
if (level == 2) // Esite la precedente riga?
{
const int nriga = g.pred(riga);
const bool ok = nriga > 0 && nriga < 9999;
if (ok)
_curr.add(nriga, 1);
return ok;
}
const int rata = _curr.get_int(2);
if (level == 3) // Esiste la precedente rata?
{
const int nrata = rata-1;
const bool ok = nrata > 0;
if (ok)
_curr.add(nrata, 2);
return ok;
}
const int pag = _curr.get_int(3);
if (level == 4) // Esiste il precedente pagamento
{
const TRiga_scadenze& scad = g.rata(riga, rata);
const int npag = scad.pred(pag);
const bool ok = npag > 0;
if (ok)
_curr.add(npag, 3);
return ok;
}
return false;
}
bool TSolder_tree::get_description(TString& desc) const
{
const int level = _curr.items();
if (level == 0) // Il prossimo clifo non esiste mai per progetto
{
desc = _cache.bill().descrizione();
desc.strip_double_spaces();
return true;
}
const TPartita& g = *partita();
if (level == 1)
{
desc.cut(0) << g.anno() << '/' << g.numero();
desc.strip(" ");
return true;
}
int nriga = 1; _curr.get(1, nriga);
const TRiga_partite& riga = g.riga(nriga);
if (level == 2)
{
desc = riga.get(PART_DESCR);
return true;
}
int nrata = 1; _curr.get(2, nrata);
const TRiga_scadenze& scad = riga.rata(nrata);
if (level == 3)
{
desc = TR("Rata");
desc << ' ' << nrata << ' ' << scad.get(SCAD_DATASCAD);
return true;
}
int npag = 2; _curr.get(3, npag);
const TRectype& pag = scad.row(npag);
if (level == 4)
{
const TRiga_partite& rpag = g.riga(npag);
const tipo_movimento tipo = rpag.tipo();
switch(tipo)
{
case tm_insoluto: desc = TR("Insoluto"); break;
case tm_pagamento_insoluto: desc = TR("Pagamento insoluto"); break;
default: desc = TR("Pagamento"); break;
}
desc << ' ' << rpag.get(PART_DATAPAG);
return true;
}
desc = _curr;
return true;
}
void TSolder_tree::set_root(const TBill& conto, long numreg, bool all)
{
_cache.set_bill(conto, numreg, all);
}
bool TSolder_tree::marked() const
{
bool yes = false;
const int level = _curr.items();
if (level >= 2)
{
const TPartita& g = *partita();
int nriga = 1; _curr.get(1, nriga);
const TRiga_partite& riga = g.riga(nriga);
yes = riga.get_long(PART_NREG) == _cache.num_reg();
}
return yes;
}
///////////////////////////////////////////////////////////
// TNew_game_mask
///////////////////////////////////////////////////////////
class TNew_game_mask : public TAutomask
{
const TBill& _conto;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TNew_game_mask(const TBill& conto);
};
bool TNew_game_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
bool ok = true;
switch (o.dlg())
{
case 102:
if (e == fe_modify || e == fe_close)
{
const int anno = get_int(101);
const char* part = get(102);
const TPartita p(_conto, anno, part);
if (p.first() > 0)
ok = error_box("La partita %d/%s esiste gia'", anno, part);
}
break;
default:
break;
}
return ok;
}
TNew_game_mask::TNew_game_mask(const TBill& conto)
: TAutomask(TR("Nuova partita"), 1, 24, 5), _conto(conto)
{
TReal_field& anno = add_number(101, 0, PR("Anno "), 1, 1, 4, "A");
anno.check_type(CHECK_REQUIRED);
const char* flags = TPartita::allineamento_richiesto(_conto.tipo()) == 'R' ? "R" : "";
TEdit_field& partita = add_string(102, 0, PR("Partita "), 1, 2, 6, flags);
partita.check_type(CHECK_REQUIRED);
add_button(DLG_OK, 0, "", -12, -1, 10, 2);
add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
set_handlers();
}
///////////////////////////////////////////////////////////
// TEasySolder_mask
///////////////////////////////////////////////////////////
// Forse andrebbe in libreria!
void TEasySolder_mask::set_imp(short id, const TImporto& imp)
{
TEdit_field& e = efield(id);
CHECK(e.size() >= 15, "Campo troppo piccolo per contenere un importo");
TString80 str;
if (!imp.is_zero())
{
const TCurrency c(imp.valore());
str << c.string(true) << ' ' << imp.sezione();
}
e.set(str);
}
bool TEasySolder_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_NEWREC:
if (e == fe_button)
{
TNew_game_mask m(_conto.tipo());
if (m.run() == K_ENTER)
{
}
}
break;
case F_TUTTE:
if (e == fe_modify)
{
TSolder_tree& t = *(TSolder_tree*)_tree;
const bool all = o.get().full();
t.set_root(_conto, _numreg, all);
if (t.goto_root())
t.expand();
tfield(F_PARTITE).win().force_update();
}
break;
case F_PARTITE:
if (e == fe_modify)
{
TSolder_tree& t = *(TSolder_tree*)_tree;
TToken_string curr; t.curr_id(curr);
const int level = curr.items();
if (level > 0)
{
const TPartita& p = *t.partita();
TImporto saldo, doc, pag, imp;
p.calcola_saldo(saldo, doc, pag, imp);
set_imp(F_DOCUMENTI_P, doc);
set_imp(F_PAGAMENTI_P, pag);
set_imp(F_IMPORTI_P, imp);
set_imp(F_SALDO_P, saldo);
}
if (level > 1)
{
const TPartita& p = *t.partita();
const int nriga = curr.get_int(1);
const TRiga_partite& r = p.riga(nriga);
TImporto imp(r.get_char(PART_SEZ), r.get_real(PART_IMPORTO));
set(F_DATA_R, r.get(PART_DATADOC));
set_imp(F_IMPORTO_R, imp);
}
if (level > 2)
{
const int nriga = curr.get_int(1);
const TRiga_partite& r = t.partita()->riga(nriga);
const int nrata = curr.get_int(2);
const TRiga_scadenze& s = r.rata(nrata);
TImporto doc = s.importo(false);
TImporto pag = s.importo_pagato(false);
TImporto saldo = s.residuo(false);
set(F_DATA_S, s.get(SCAD_DATASCAD));
set_imp(F_IMPORTO_S, doc);
set_imp(F_PAGAMENTI_S, pag);
set_imp(F_SALDO_S, saldo);
}
if (level > 3)
{
const int nriga = curr.get_int(1);
const TRiga_partite& rf = t.partita()->riga(nriga);
const int nrata = curr.get_int(2);
const TRiga_scadenze& s = rf.rata(nrata);
const int nrigp = curr.get_int(3);
const TRectype& p = s.row(nrigp);
const TRiga_partite& rp = t.partita()->riga(nrigp);
const TImporto pag(rp.get_char(PART_SEZ), p.get_real(PAGSCA_IMPORTO));
const TImporto abb(rp.get_char(PART_SEZABB), p.get_real(PAGSCA_ABBUONI));
const TImporto dif(rp.get_char(PART_SEZDIFCAM), p.get_real(PAGSCA_DIFFCAM));
set(F_DATA_PAG, rp.get(PART_DATAPAG));
set_imp(F_IMPORTO_PAG, pag);
set_imp(F_ABBUONI_PAG, abb);
set_imp(F_DIFFCAM_PAG, dif);
}
show(-10, level > 0);
show(-20, level > 1);
show(-30, level > 2);
show(-40, level > 3);
}
break;
default: break;
}
return true;
}
void TEasySolder_mask::init(const TBill& conto, long numreg, int numrig)
{
_conto = conto;
_numreg= numreg;
_numrig = numrig;
_changed = false;
if (_tree == NULL)
{
_tree = new TSolder_tree;
tfield(F_PARTITE).set_tree(_tree);
}
TSolder_tree& t = *(TSolder_tree*)_tree;
t.set_root(_conto, _numreg, get_bool(F_TUTTE));
if (t.goto_root())
t.expand();
}
TEasySolder_mask::TEasySolder_mask(const TBill& conto, long numreg, int numrig)
: TAutomask("cg2100e"), _tree(NULL)
{
init(conto, numreg, numrig);
}
TEasySolder_mask::~TEasySolder_mask()
{
if (_tree)
delete _tree;
}