campo-sirio/pe/pe1401.cpp
guy 80f65c95ef Preventivazione cantieri
git-svn-id: svn://10.65.10.50/branches/R_10_00@22929 c028cbd2-c16b-5b4b-a496-9718f37d4682
2014-03-07 14:42:30 +00:00

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");
}