#include "pe1401.h" #include #include #include #include #include #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) { TString80 str = m.get(F_NOTE); if (str.blank()) get_description(str); 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.stringa(0,2); else var = c.stringa(0,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.stringa(0,2); else var = c.stringa(0,2); } else var = rec->get_real(name).stringa(0, 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", "01"); _strDett = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDett", "04"); _strMisu = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaMisu", "09"); }