git-svn-id: svn://10.65.10.50/branches/R_10_00@22929 c028cbd2-c16b-5b4b-a496-9718f37d4682
418 lines
10 KiB
C++
418 lines
10 KiB
C++
#include "pe1401.h"
|
|
|
|
#include <diction.h>
|
|
#include <mask.h>
|
|
#include <urldefid.h>
|
|
|
|
#include <doc.h>
|
|
#include <rdoc.h>
|
|
#include "pe1400.h"
|
|
|
|
bool TPreventivo_tree::add_lastson(TObject* obj)
|
|
{
|
|
CHECK(obj != NULL && obj->is_kind_of(CLASS_RECTYPE), "Record non valido per preventivo");
|
|
CHECK(((TRectype*)obj)->get(RDOC_TIPORIGA).full(), "TIPORIGA vuoto");
|
|
bool done = false;
|
|
if (goto_firstson()) // Se ha almeno un figlio ...
|
|
{
|
|
while (goto_rbrother()); // ... allora vai all'ultimo fratello
|
|
done = add_rbrother(obj); // ed aggiungi ultimo fratello
|
|
}
|
|
else
|
|
done = add_son(obj); // Aggiungi primogenito
|
|
return done;
|
|
}
|
|
|
|
TPreventivo_level TPreventivo_tree::last_fase_level() const
|
|
{
|
|
const int mf = owner().mask().get_int(F_FASEMAX);
|
|
return TPreventivo_level(pl_fase1 + mf - 1);
|
|
}
|
|
|
|
bool TPreventivo_tree::goto_last_fase(TPreventivo_level sublevel)
|
|
{
|
|
bool ok = goto_root() && goto_firstson();
|
|
if (ok)
|
|
{
|
|
while (goto_rbrother()); // goto last son
|
|
|
|
if (sublevel > pl_fase1)
|
|
{
|
|
const TPreventivo_level mf = last_fase_level();
|
|
if (sublevel > mf)
|
|
sublevel = mf;
|
|
|
|
while (level() < sublevel)
|
|
{
|
|
if (goto_firstson())
|
|
while (goto_rbrother());
|
|
else
|
|
break;
|
|
}
|
|
|
|
ok = level() == sublevel;
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TPreventivo_tree::goto_last_dist()
|
|
{
|
|
bool ok = goto_last_fase(pl_distinta); // pl_distinta = dummy value for maximum depth
|
|
if (ok)
|
|
{
|
|
ok = goto_firstson();
|
|
if (ok)
|
|
while (goto_rbrother());
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TRectype* TPreventivo_tree::new_row(TPreventivo_level level) const
|
|
{
|
|
const TMask& m = owner().mask();
|
|
TRectype* rec = new TRectype(level == pl_documento ? LF_DOC : LF_RIGHEDOC);
|
|
rec->put(RDOC_PROVV, 'D');
|
|
rec->put(RDOC_ANNO, m.get(F_ANNO));
|
|
rec->put(RDOC_CODNUM, m.get(F_CODNUM));
|
|
rec->put(RDOC_NDOC, m.get(F_NDOC));
|
|
switch (level)
|
|
{
|
|
case pl_distinta : rec->put(RDOC_TIPORIGA, tipo_dist()); rec->put(RDOC_DESCR, TR("Nuova distinta"));break;
|
|
case pl_dettaglio: rec->put(RDOC_TIPORIGA, tipo_dett()); rec->put(RDOC_DESCR, TR("Nuova riga"));break;
|
|
case pl_misura : rec->put(RDOC_TIPORIGA, tipo_misu()); rec->put(RDOC_DESCR, TR("Nuova misura"));break;
|
|
default : rec->put(RDOC_TIPORIGA, tipo_fasi()); rec->put(RDOC_DESCR, TR("Nuova fase")); rec->put(RPRV_LEVEL, level-pl_fase1); break;
|
|
}
|
|
|
|
return rec;
|
|
}
|
|
|
|
TRectype* TPreventivo_tree::dist(const TString& fase, int n, bool create)
|
|
{
|
|
TRectype* rec = NULL;
|
|
if (goto_node(fase))
|
|
{
|
|
if (goto_firstson())
|
|
{
|
|
int i = 0;
|
|
for (; i < n && goto_rbrother(); i++);
|
|
if (i < n)
|
|
{
|
|
if (create)
|
|
add_rbrother(rec = new_row(pl_distinta));
|
|
}
|
|
else
|
|
rec = curr_row();
|
|
}
|
|
else
|
|
{
|
|
if (create)
|
|
add_son(rec = new_row(pl_distinta));
|
|
}
|
|
}
|
|
return rec;
|
|
}
|
|
|
|
TRectype* TPreventivo_tree::dett(const TString& dist, int n, bool create)
|
|
{
|
|
TRectype* rec = NULL;
|
|
if (goto_node(dist))
|
|
{
|
|
if (goto_firstson())
|
|
{
|
|
if (level() == pl_dettaglio)
|
|
{
|
|
int i = 0;
|
|
for (; i < n && goto_rbrother() && level() == pl_dettaglio; i++);
|
|
if (i == n)
|
|
rec = curr_row();
|
|
}
|
|
if (rec == NULL && create)
|
|
{
|
|
if (level() == pl_dettaglio)
|
|
add_rbrother(rec = new_row(pl_dettaglio));
|
|
else
|
|
add_lbrother(rec = new_row(pl_dettaglio));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (create && n == 0)
|
|
add_son(rec = new_row(pl_dettaglio));
|
|
}
|
|
}
|
|
return rec;
|
|
}
|
|
|
|
TRectype* TPreventivo_tree::misu(const TString& dist, int n, bool create)
|
|
{
|
|
TRectype* rec = NULL;
|
|
if (goto_node(dist))
|
|
{
|
|
CHECKS(level() == pl_distinta, "Distinta non valida", (const char*)dist);
|
|
if (goto_firstson())
|
|
{
|
|
int i = level() == pl_misura ? 0 : -1;
|
|
while (i < n && goto_rbrother())
|
|
if (level() == pl_misura) i++;
|
|
if (i < n)
|
|
{
|
|
if (create)
|
|
add_rbrother(rec = new_row(pl_misura));
|
|
}
|
|
else
|
|
rec = curr_row();
|
|
}
|
|
else
|
|
{
|
|
if (create && n == 0)
|
|
add_son(rec = new_row(pl_misura));
|
|
}
|
|
}
|
|
return rec;
|
|
}
|
|
|
|
TPreventivo_level TPreventivo_tree::level(const TRectype& rec) const
|
|
{
|
|
TPreventivo_level lev = pl_documento;
|
|
if (rec.num() == LF_RIGHEDOC)
|
|
{
|
|
const TString& t = rec.get(RDOC_TIPORIGA);
|
|
if (t.full())
|
|
{
|
|
lev = pl_fase1;
|
|
if (t == _strFasi)
|
|
lev = TPreventivo_level(lev + rec.get_int(RPRV_LEVEL)); else
|
|
if (t == _strDist)
|
|
lev = pl_distinta; else
|
|
if (t == _strDett)
|
|
lev = pl_dettaglio; else
|
|
if (t == _strMisu)
|
|
lev = pl_misura;
|
|
}
|
|
}
|
|
return lev;
|
|
}
|
|
|
|
TPreventivo_level TPreventivo_tree::level() const
|
|
{
|
|
TPreventivo_level lev = pl_documento;
|
|
TRectype* rec = curr_row();
|
|
if (rec != NULL)
|
|
lev = level(*rec);
|
|
return lev;
|
|
}
|
|
|
|
bool TPreventivo_tree::could_have_son() const
|
|
{ return level() < pl_distinta; }
|
|
|
|
bool TPreventivo_tree::get_description(TString& str) const
|
|
{
|
|
const TRectype* rec = curr_row();
|
|
bool ok = rec != NULL && !rec->empty();
|
|
if (ok)
|
|
{
|
|
if (rec->num() == LF_DOC)
|
|
{
|
|
const TMask& m = owner().mask();
|
|
str = m.get(F_NPREV);
|
|
if (m.field(F_NREV).shown())
|
|
str << '.' << m.get(F_NREV);
|
|
str << TR(" del ") << m.get(F_DATADOC);
|
|
} else
|
|
if (rec->num() == LF_RIGHEDOC)
|
|
{
|
|
str = rec->get(RDOC_DESCR);
|
|
if (str.blank())
|
|
str = rec->get(RDOC_CODART);
|
|
}
|
|
else
|
|
NFCHECK("Bad tree record");
|
|
}
|
|
else
|
|
NFCHECK("NULL tree record");
|
|
return ok;
|
|
}
|
|
|
|
TFieldtypes TPreventivo_tree::get_var(const TString& name, TVariant& var) const
|
|
{
|
|
TFieldtypes ft = _nullfld;
|
|
const TRectype* rec = curr_row();
|
|
if (rec != NULL && !rec->empty())
|
|
{
|
|
if (rec->num() == LF_DOC)
|
|
{
|
|
const TMask& m =owner().mask();
|
|
if (name == RDOC_CODART)
|
|
{
|
|
TString16 str = m.get(F_NPREV);
|
|
if (m.field(F_NREV).shown())
|
|
str << '.' << m.get(F_NREV);
|
|
var = str;
|
|
ft = _alfafld;
|
|
} else
|
|
if (name == RDOC_DESCR)
|
|
{
|
|
TString str = m.get(F_NOTE);
|
|
if (str.blank())
|
|
get_description(str);
|
|
const int spc = str.find('\n');
|
|
if (spc > 0) str.cut(spc);
|
|
var = str;
|
|
ft = _alfafld;
|
|
} else
|
|
if (name == RDOC_PREZZO || name == RPRV_COSTO)
|
|
{
|
|
real c, p; ((TPreventivo_tree*)this)->ricalcola(c, p);
|
|
if (name == RDOC_PREZZO)
|
|
var = p.string(".2");
|
|
else
|
|
var = c.string(".2");
|
|
ft = _realfld;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ft = rec->type(name);
|
|
if (ft > _nullfld)
|
|
{
|
|
if (ft == _realfld)
|
|
{
|
|
if ((name == RDOC_PREZZO || name == RPRV_COSTO) && level() == pl_distinta)
|
|
{
|
|
real c, p; ((TPreventivo_tree*)this)->ricalcola(c, p);
|
|
if (name == RDOC_PREZZO )
|
|
var = p.string(".2");
|
|
else
|
|
var = c.string(".2");
|
|
}
|
|
else
|
|
var = rec->get_real(name).string(".2");
|
|
}
|
|
else
|
|
var = rec->get(name);
|
|
}
|
|
}
|
|
}
|
|
return ft;
|
|
}
|
|
|
|
|
|
TImage* TPreventivo_tree::image(bool sel) const
|
|
{
|
|
const TPreventivo_level pl = level();
|
|
if (pl <= pl_distinta)
|
|
{
|
|
const bool ex = expanded();
|
|
if (has_son())
|
|
return get_res_image(ex ? BMP_DIRDNSEL : BMP_DIRSEL);
|
|
else
|
|
return get_res_image(ex ? BMP_DIRDN : BMP_DIR);
|
|
}
|
|
return TObject_tree::image(sel);
|
|
}
|
|
|
|
// Aggiunge un record alla fine dell'albero in base al tipo della riga (usato solo in lettura iniziale)
|
|
bool TPreventivo_tree::append_row(const TRectype& rec)
|
|
{
|
|
const TPreventivo_level pl = level(rec);
|
|
if (pl == pl_documento)
|
|
{
|
|
// Se aggiungo un documento allora svuoto albero e ricreo radice
|
|
if (goto_root())
|
|
kill_node();
|
|
return add_son(rec);
|
|
} else
|
|
if (pl == pl_dettaglio)
|
|
{
|
|
// Le righe di dettaglio devono precedere quelle di misura
|
|
if (goto_last_dist())
|
|
{
|
|
if (goto_firstson())
|
|
{
|
|
while (level() == pl_dettaglio && goto_rbrother());
|
|
if (level() == pl_dettaglio)
|
|
return add_rbrother(rec);
|
|
else
|
|
return add_lbrother(rec);
|
|
}
|
|
return add_son(rec);
|
|
}
|
|
} else
|
|
if (pl == pl_misura)
|
|
{
|
|
if (goto_last_dist())
|
|
return add_lastson(rec);
|
|
}
|
|
else
|
|
{
|
|
goto_root();
|
|
while (level() < pl)
|
|
{
|
|
if (goto_firstson())
|
|
while (goto_rbrother());
|
|
else
|
|
break;
|
|
}
|
|
if (level() < pl)
|
|
return add_lastson(rec);
|
|
else
|
|
return add_rbrother(rec);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool TPreventivo_tree::ricalcola(real& costo, real& prezzo)
|
|
{
|
|
bool ok = false;
|
|
const TPreventivo_level lev = level();
|
|
costo = prezzo = ZERO;
|
|
if (lev < pl_distinta && has_son())
|
|
{
|
|
TString16 id; curr_id(id);
|
|
for (bool go = goto_firstson(); go; go = goto_rbrother())
|
|
{
|
|
real c, p;
|
|
if (ricalcola(c, p))
|
|
{
|
|
costo += c;
|
|
prezzo += p;
|
|
}
|
|
}
|
|
ok = goto_node(id);
|
|
if (lev >= pl_fase1)
|
|
{
|
|
TRectype& rec = *curr_row();
|
|
rec.put(RDOC_QTA, 1);
|
|
rec.put(RPRV_COSTO, costo);
|
|
rec.put(RDOC_PREZZO, prezzo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ok = lev == pl_distinta;
|
|
if (ok)
|
|
{
|
|
const TRectype& rec = *curr_row();
|
|
const real qta = rec.get_real(RDOC_QTA);
|
|
if (!qta.is_zero())
|
|
{
|
|
costo = qta * rec.get_real(RPRV_COSTO);
|
|
prezzo = qta * rec.get_real(RDOC_PREZZO);
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TPreventivo_tree::TPreventivo_tree(TTree_field& owner) : _owner(owner)
|
|
{
|
|
// Legge i tipi riga standard per determinare i nodi dell'albero
|
|
_strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
|
|
_strDist = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDist", "P1");
|
|
_strDett = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDett", "01");
|
|
_strMisu = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaMisu", "P2");
|
|
}
|
|
|