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