Files correlati : Ricompilazione Demo : [ ] Commento :riporto gestione ripartizioni interattive per conversione git-svn-id: svn://10.65.10.50/trunk@17147 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1977 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1977 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <dongle.h>
 | 
						|
#include <modaut.h>
 | 
						|
#include <tree.h>
 | 
						|
#include <treectrl.h>
 | 
						|
 | 
						|
#include <mov.h>
 | 
						|
#include <pconti.h>
 | 
						|
#include <treectrl.h>
 | 
						|
 | 
						|
#include "calib01.h"
 | 
						|
#include "calib02.h"
 | 
						|
#include "calibmsk.h"
 | 
						|
#include "../cg/cg2103.h"
 | 
						|
 | 
						|
#include "fasi.h"
 | 
						|
#include "movana.h"
 | 
						|
#include "rmovana.h"
 | 
						|
#include "rip.h"
 | 
						|
#include "rrip.h"
 | 
						|
#include "saldana.h"
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//  TConfig_anal
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TConfig_anal : public TConfig
 | 
						|
{
 | 
						|
  bool _has_ca;
 | 
						|
public:
 | 
						|
  virtual const TString& get(const char* var, const char* section = NULL, int index = -1, const char* def = "");
 | 
						|
  TConfig_anal();
 | 
						|
};
 | 
						|
 | 
						|
TConfig_anal::TConfig_anal() : TConfig(CONFIG_DITTA, "ca"), _has_ca(dongle().active(CAAUT))
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
const TString& TConfig_anal::get(const char* var, const char* section, int index, const char* def)
 | 
						|
{
 | 
						|
  if (_has_ca)
 | 
						|
    return  TConfig::get(var, section, index, def);
 | 
						|
  
 | 
						|
  //se il valore della variabile sul .ini e' vuoto controlla se e' possibile assegnarlo di default
 | 
						|
  TString& tmp = get_tmp_string();
 | 
						|
  if (var == "AttFasi")
 | 
						|
    tmp = "X"; else
 | 
						|
  if (var == "FathFasi")
 | 
						|
    tmp = "CMS"; else
 | 
						|
  if (var == "Level(1)")
 | 
						|
    tmp = "CMS"; else
 | 
						|
  if (var == "Cms(1)")
 | 
						|
    tmp = "LLLLLLLLLLLLLLLLLLLL"; else
 | 
						|
  if (var == "CmsDes(1)")
 | 
						|
    tmp = "Commessa"; else
 | 
						|
  if (var == "Fsc(1)")
 | 
						|
    tmp = "LLLLLLLLLL"; else
 | 
						|
  if (var == "FscDes(1)")
 | 
						|
    tmp == "Fase"; else
 | 
						|
  if (var == "EdMask")
 | 
						|
    tmp = "ca0300a"; else
 | 
						|
  if (var == "UsePdcc")
 | 
						|
    tmp = "X";
 | 
						|
 | 
						|
  return tmp;
 | 
						|
}
 | 
						|
 | 
						|
TConfig& ca_config()
 | 
						|
{
 | 
						|
  static TConfig_anal* cfg = NULL;
 | 
						|
  if (cfg == NULL)
 | 
						|
    cfg = new TConfig_anal;
 | 
						|
  return *cfg;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMultilevel_code_info
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int TMultilevel_code_info::levels() const
 | 
						|
{
 | 
						|
  return _picture.items();
 | 
						|
}
 | 
						|
 | 
						|
const TString& TMultilevel_code_info::picture(int level) const
 | 
						|
{
 | 
						|
  if (level < 0 || level >= levels())
 | 
						|
    return EMPTY_STRING;
 | 
						|
  return _picture.row(level);
 | 
						|
}
 | 
						|
 | 
						|
bool TMultilevel_code_info::is_required(int level) const
 | 
						|
{
 | 
						|
  bool yes = level <= 0;
 | 
						|
  return yes;
 | 
						|
}
 | 
						|
 | 
						|
bool TMultilevel_code_info::is_numeric_picture(int level) const
 | 
						|
{
 | 
						|
  const TString& pic = picture(level);
 | 
						|
  if (pic.blank())
 | 
						|
    return false;
 | 
						|
 | 
						|
  for (int i = 0; pic[i]; i++)
 | 
						|
    if (pic[i] != '0' && pic[i] != '9')
 | 
						|
      return false;
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
int TMultilevel_code_info::len(int level) const
 | 
						|
{
 | 
						|
  return picture(level).len();
 | 
						|
}
 | 
						|
 | 
						|
int TMultilevel_code_info::total_len(int level) const
 | 
						|
{
 | 
						|
  const int max_lev = levels();
 | 
						|
  if (level < 0)    // -1 = fino al penultimo
 | 
						|
    level = max_lev+level-1;
 | 
						|
  int l = 0;
 | 
						|
  for (int i = 0; i <= level && i < max_lev; i++)
 | 
						|
    l += picture(i).len();
 | 
						|
  return l;
 | 
						|
}
 | 
						|
 
 | 
						|
const TString& TMultilevel_code_info::prompt(int level) const
 | 
						|
{
 | 
						|
  if (level < 0 || level >= _prompt.items())
 | 
						|
    return EMPTY_STRING;
 | 
						|
  return _prompt.row(level);
 | 
						|
}
 | 
						|
 
 | 
						|
const TFieldref& TMultilevel_code_info::fieldref(int level, int key) const
 | 
						|
{
 | 
						|
  const TArray& a = key <= 1 ? _key1_fields : _key2_fields;
 | 
						|
  const TFieldref& fr = (const TFieldref&)a[level];
 | 
						|
  return fr;
 | 
						|
}
 | 
						|
 | 
						|
const char* TMultilevel_code_info::get_key_fieldname(int k) const
 | 
						|
{
 | 
						|
  const RecDes& rd = prefix().get_recdes(_logicnum);
 | 
						|
  CHECKD(k > 0 && k <= rd.NKeys, "Invalid key ", k);
 | 
						|
  const KeyDes& ky = rd.Ky[k-1];
 | 
						|
  int idx = 0;
 | 
						|
  if (k == 1 && (_logicnum == LF_TAB || _logicnum == LF_TABCOM || _logicnum == LF_FASI))
 | 
						|
    idx = 1;
 | 
						|
  const int pos = ky.FieldSeq[idx] % MaxFields;
 | 
						|
  return rd.Fd[pos].Name;
 | 
						|
}
 | 
						|
 | 
						|
bool TMultilevel_code_info::get_cfg_vars(TString& key, TString& des) const
 | 
						|
{
 | 
						|
  switch (_logicnum)
 | 
						|
  {
 | 
						|
  case LF_PCONANA : key = "Pdci"; des = "PdciDes"; break;
 | 
						|
  case LF_CDC     : key = "CdC";  des = "CdCDes";  break;
 | 
						|
  case LF_COMMESSE: key = "Cms";  des = "CmsDes";  break;
 | 
						|
  case LF_FASI    : key = "Fsc";  des = "FscDes";  break;
 | 
						|
  default: break;
 | 
						|
  }
 | 
						|
  return key.not_empty();
 | 
						|
}
 | 
						|
 | 
						|
void TMultilevel_code_info::add_fieldref(int k, int from, int to)
 | 
						|
{
 | 
						|
  TArray& a = k == 1 ? _key1_fields : _key2_fields;
 | 
						|
  TString80 str = get_key_fieldname(k);
 | 
						|
  if (from > 0)
 | 
						|
    str << '[' << from << ',' << to << ']';
 | 
						|
 | 
						|
  TFieldref* fr = new TFieldref(str, _logicnum);
 | 
						|
  a.add(fr);
 | 
						|
}
 | 
						|
 | 
						|
int TMultilevel_code_info::pack(TString& code) const
 | 
						|
{
 | 
						|
  code.strip("|");
 | 
						|
  return levels();
 | 
						|
}
 | 
						|
 | 
						|
int TMultilevel_code_info::unpack(TString& code) const
 | 
						|
{
 | 
						|
  const int lev = levels();
 | 
						|
  if (lev > 1)
 | 
						|
  {
 | 
						|
    for (int i = lev-2; i >= 0; i--)
 | 
						|
      code.insert("|", total_len(i));
 | 
						|
  }
 | 
						|
  return lev;
 | 
						|
}
 | 
						|
 | 
						|
TMultilevel_code_info::TMultilevel_code_info(int logicnum) : _logicnum(logicnum), _parentnum(0)
 | 
						|
{
 | 
						|
  if (_logicnum == LF_PCON)
 | 
						|
  {
 | 
						|
    _key1_fields.add(new TFieldref(PCN_GRUPPO,     LF_PCON));
 | 
						|
    _picture.add("999");
 | 
						|
    _prompt.add(TR("Gruppo"));
 | 
						|
 | 
						|
    _key1_fields.add(new TFieldref(PCN_CONTO,      LF_PCON));
 | 
						|
    _picture.add("999");
 | 
						|
    _prompt.add(TR("Conto"));
 | 
						|
    
 | 
						|
    _key1_fields.add(new TFieldref(PCN_SOTTOCONTO, LF_PCON));
 | 
						|
    _picture.add("999999");
 | 
						|
    _prompt.add(TR("Sottoconto"));
 | 
						|
    
 | 
						|
    _key2_fields.add(new TFieldref(PCN_DESCR, LF_PCON));
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    TConfig& cfg = ca_config();
 | 
						|
 | 
						|
    if (logicnum == LF_FASI)
 | 
						|
    {
 | 
						|
      const TString& father = cfg.get("FathFasi");
 | 
						|
      if (father == "CMS")
 | 
						|
        _parentnum = LF_COMMESSE; else
 | 
						|
      if (father == "CDC")
 | 
						|
        _parentnum = LF_CDC;
 | 
						|
      if (_parentnum != 0)
 | 
						|
      {
 | 
						|
        const TMultilevel_code_info& info = ca_multilevel_code_info(_parentnum);
 | 
						|
        for (int i = 0; i < info.levels(); i++)
 | 
						|
        {
 | 
						|
          _prompt.add(info.prompt(i));
 | 
						|
          _picture.add(info.picture(i));
 | 
						|
          TFieldref fr = info.fieldref(i);
 | 
						|
          fr.set_name("CODCMSFAS");
 | 
						|
          _key1_fields.add(fr);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    TString16 keyvar, desvar;
 | 
						|
    get_cfg_vars(keyvar, desvar);
 | 
						|
 | 
						|
    int from = 1, to = 1;
 | 
						|
    for (int level = 1; ; level++)
 | 
						|
    {
 | 
						|
      const TString& prompt = cfg.get(desvar, NULL, level);
 | 
						|
      if (prompt.blank())
 | 
						|
        break;
 | 
						|
      _prompt.add(prompt);
 | 
						|
 | 
						|
      const TString& picture = cfg.get(keyvar, NULL, level);
 | 
						|
      _picture.add(picture);
 | 
						|
 | 
						|
      const int keylen = picture.len();
 | 
						|
      to = from+keylen-1;
 | 
						|
      add_fieldref(1, from, to);
 | 
						|
      from = to+1;
 | 
						|
    }
 | 
						|
    add_fieldref(2, 0, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  const TRectype rec(logicnum);
 | 
						|
  rec.get_relapp(_editor);
 | 
						|
}
 | 
						|
 | 
						|
const TMultilevel_code_info& ca_multilevel_code_info(int logicnum)
 | 
						|
{
 | 
						|
  static TArray* cache = NULL;
 | 
						|
  if (cache == NULL)
 | 
						|
    cache = new TArray;
 | 
						|
  TMultilevel_code_info* info = (TMultilevel_code_info*)cache->objptr(logicnum);
 | 
						|
  if (info == NULL)
 | 
						|
  {
 | 
						|
    info = new TMultilevel_code_info(logicnum);
 | 
						|
    cache->add(info, logicnum);
 | 
						|
  }
 | 
						|
  return *info;
 | 
						|
}
 | 
						|
 | 
						|
const TMultilevel_code_info* ca_multilevel_code_info_by_index(int level)
 | 
						|
{
 | 
						|
  static int _logicnum[3] =  { -1, -1, -1 };
 | 
						|
 | 
						|
  int logic = 0;
 | 
						|
  if (level >= 0 && level < 3)
 | 
						|
  {
 | 
						|
    // Riempie lista dei livelli, ad esempio:
 | 
						|
    // LF_COMMESSE, LF_FASI, LF_CDC oppure LF_COMMESSE, LF_CDC, ecc...
 | 
						|
    if (_logicnum[0] < 0)
 | 
						|
    {
 | 
						|
	    TConfig& cfg = ca_config();
 | 
						|
      const TString& lev1 = cfg.get("Level", NULL, 1);
 | 
						|
      if (lev1.full())
 | 
						|
      {
 | 
						|
        const TMultilevel_code_info& fasi = ca_multilevel_code_info(LF_FASI);
 | 
						|
        int k = 0;
 | 
						|
        _logicnum[k] = lev1 == "CDC" ? LF_CDC : LF_COMMESSE;
 | 
						|
        if (fasi.parent() == _logicnum[k])
 | 
						|
          _logicnum[++k] = LF_FASI;
 | 
						|
 | 
						|
        const TString& lev2 = cfg.get("Level", NULL, 2);
 | 
						|
        if (lev2.full())
 | 
						|
        {
 | 
						|
          _logicnum[++k] = _logicnum[0] == LF_COMMESSE ? LF_CDC : LF_COMMESSE;
 | 
						|
          if (fasi.parent() == _logicnum[k])
 | 
						|
            _logicnum[++k] = LF_FASI;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
        memset(_logicnum, 0, sizeof(_logicnum));
 | 
						|
    }
 | 
						|
	  logic = _logicnum[level];
 | 
						|
  }
 | 
						|
 | 
						|
  return logic > 0 ? &ca_multilevel_code_info(logic) : NULL;
 | 
						|
}
 | 
						|
 | 
						|
bool ca_test_multilevel_field(TEdit_field& fld, int level)
 | 
						|
{
 | 
						|
  const int logic = fld.browse()->cursor()->curr().num();
 | 
						|
  const TMultilevel_code_info& info = ca_multilevel_code_info(logic);
 | 
						|
  const TString& pic = info.picture(level);
 | 
						|
  const TString& val = fld.get();
 | 
						|
 | 
						|
  bool ok = val.len() <= pic.len();
 | 
						|
  for (int i = 0; val[i] && ok; i++)
 | 
						|
  {
 | 
						|
    const char v = val[i];
 | 
						|
    const char p = pic[i];
 | 
						|
    switch (p)
 | 
						|
    {
 | 
						|
    case 'A': ok = (v >= '0' && v <= '9') || (v >= 'A' && v <= 'Z'); break;
 | 
						|
    case '0': ok = (v >= '0' && v <= '9'); break;
 | 
						|
    case '9': ok = (v == ' ') || (v >= '0' && v <= '9'); break;
 | 
						|
    default : break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (!ok)
 | 
						|
  {
 | 
						|
    TString msg;
 | 
						|
    msg << TR("Il codice non rispetta il formato impostato nella configurazione")
 | 
						|
        << '\n' << val << " <> " << pic;
 | 
						|
    return fld.error_box(msg);
 | 
						|
  }
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
static void ca_append_select_clause(ostream& out, int level, int logic, bool upper_limit)
 | 
						|
{
 | 
						|
  TString str;
 | 
						|
  if (logic == LF_PCON)
 | 
						|
  {
 | 
						|
    switch (level)
 | 
						|
    {
 | 
						|
    case 0: str = "CONTO==\"\""; break;
 | 
						|
    case 1: str = "SOTTOCONTO==\"\""; break;
 | 
						|
    default: break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TMultilevel_code_info& mci = ca_multilevel_code_info(logic);
 | 
						|
    const TFieldref& key = mci.fieldref(level);
 | 
						|
 | 
						|
    str << "STR(";
 | 
						|
    if (level > 1 && !upper_limit)
 | 
						|
      str << "(NUM(LEN(" << key.name() << "))>" << key.from() << ')'; // SE LEN(CODCONTO)>=4
 | 
						|
    if (level < mci.levels())
 | 
						|
    {
 | 
						|
      if (level > 1 && !upper_limit) str << "&&";
 | 
						|
      str << "(NUM(LEN(" << key.name() << "))<=" << key.to() << ')';  // SE LEN(CODCONTO)<=7
 | 
						|
    }
 | 
						|
    str << ')';
 | 
						|
  }
 | 
						|
	TString16 fieldname;
 | 
						|
 | 
						|
	switch (logic)
 | 
						|
	{
 | 
						|
		case LF_COMMESSE:
 | 
						|
			fieldname = "S0";
 | 
						|
			break;
 | 
						|
		case LF_CDC:
 | 
						|
			fieldname = "S1";
 | 
						|
			break;
 | 
						|
		case LF_FASI:
 | 
						|
			fieldname = "S2";
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			break;
 | 
						|
	}
 | 
						|
	if (fieldname.full())
 | 
						|
	{
 | 
						|
		const TString utente(user());
 | 
						|
		const TString gruppo(cache().get(LF_USER, utente,"GROUPNAME"));
 | 
						|
		TString condition;
 | 
						|
 | 
						|
		if (gruppo.full())
 | 
						|
			condition = cache().get("%AUC", gruppo, fieldname);
 | 
						|
		if (utente.full())
 | 
						|
			condition = cache().get("%AUC", utente, fieldname);
 | 
						|
		if (condition.full())
 | 
						|
		{
 | 
						|
			if (str.full())
 | 
						|
			{
 | 
						|
				str.insert("(");
 | 
						|
				str << ")&&";
 | 
						|
			}
 | 
						|
			str << '(' << condition << ')';
 | 
						|
		}
 | 
						|
	}
 | 
						|
  if (str.full())
 | 
						|
    out << " SE " << str << '\n';
 | 
						|
}
 | 
						|
 | 
						|
static void ca_append_run_clause(ostream& out, int logicnum)
 | 
						|
{
 | 
						|
  const TString& app = ca_multilevel_code_info(logicnum).editor();
 | 
						|
  if (app.not_empty())
 | 
						|
    out << "AD RU " << app << '\n';
 | 
						|
}
 | 
						|
 | 
						|
static void init_tmp_filename(TFilename& name)
 | 
						|
{
 | 
						|
  name.tempdir(); 
 | 
						|
  name.add("tmp.msk");
 | 
						|
}
 | 
						|
 | 
						|
void ca_create_browse1(TEdit_field& kfld, int level, int logic, short key_id, short des_id)
 | 
						|
{
 | 
						|
  const TMultilevel_code_info& main_info = ca_multilevel_code_info(logic);
 | 
						|
	bool add_select = false;
 | 
						|
  if (logic == LF_FASI)
 | 
						|
  {
 | 
						|
    const int par = main_info.parent();
 | 
						|
    if (par > 0)
 | 
						|
    {
 | 
						|
      const TMultilevel_code_info& parinfo = ca_multilevel_code_info(par);
 | 
						|
      if (level < parinfo.levels())
 | 
						|
        logic = par;
 | 
						|
			else
 | 
						|
				add_select = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(logic);
 | 
						|
 | 
						|
  TFilename tmp; init_tmp_filename(tmp);
 | 
						|
  ofstream out(tmp);
 | 
						|
 | 
						|
  out << "US " << logic << '\n';
 | 
						|
	ca_append_select_clause(out, level, logic, add_select);
 | 
						|
  ca_append_run_clause(out, logic);
 | 
						|
 | 
						|
  for (int i = 0; i <= level; i++)
 | 
						|
  {
 | 
						|
    const TString& picture = mci.picture(i);
 | 
						|
    const TString& prompt = mci.prompt(i);
 | 
						|
    const TFieldref& field = mci.fieldref(i);
 | 
						|
    const int length = field.to() - field.from();
 | 
						|
    out << "IN " << field << ' ' << (key_id+i);
 | 
						|
		if (add_select &&  field.name() == FASI_CODCMSFAS)
 | 
						|
			out << " SE";
 | 
						|
 | 
						|
		out << '\n';
 | 
						|
    out << "DI \"" << prompt;
 | 
						|
    if (length > prompt.len())
 | 
						|
      out << '@' << length;
 | 
						|
    out << "\" " << field << '\n';
 | 
						|
    out << "OU " << (key_id+i) << ' ' << field << '\n';
 | 
						|
  }
 | 
						|
  const TFieldref& field = mci.fieldref(0, 2);
 | 
						|
  out << "DI \"" << TR("Descrizione") << "@50\" " << field << '\n';
 | 
						|
	if (logic == LF_COMMESSE)
 | 
						|
	{
 | 
						|
		out << "DI \"" << TR("Proroga") << "\" PROROGA" << '\n';
 | 
						|
		out << "DI \"" << TR("Data") << "@10" << "\" DATAPROR" << '\n';
 | 
						|
		out << "DI \"" << TR("Chiusa") << "\" CHIUSA" << '\n';
 | 
						|
	}
 | 
						|
  out << "OU " << (des_id+level) << ' ' << field << '\n';
 | 
						|
  out << "CH NO" << '\n';
 | 
						|
  out << "FI " << main_info.fieldref(level) << '\n';
 | 
						|
  out << "EN" << '\n';
 | 
						|
  out.close();
 | 
						|
 | 
						|
  TScanner scan(tmp);
 | 
						|
  while (scan.pop() != "EN")
 | 
						|
    kfld.parse_item(scan);
 | 
						|
 | 
						|
  xvt_fsys_remove_file(tmp);
 | 
						|
}
 | 
						|
 | 
						|
void ca_create_browse2(TEdit_field& kfld, int level, int logic, short key_id)
 | 
						|
{
 | 
						|
  const TMultilevel_code_info& main_info = ca_multilevel_code_info(logic);
 | 
						|
	bool add_select = false;
 | 
						|
  if (logic == LF_FASI)
 | 
						|
  {
 | 
						|
    const int par = main_info.parent();
 | 
						|
    if (par > 0)
 | 
						|
    {
 | 
						|
      const TMultilevel_code_info& parinfo = ca_multilevel_code_info(par);
 | 
						|
      if (level < parinfo.levels())
 | 
						|
        logic = par;
 | 
						|
			else
 | 
						|
				add_select = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(logic);
 | 
						|
 | 
						|
  const TFieldref& field = mci.fieldref(0, 2);
 | 
						|
  TString str2; str2 << field;
 | 
						|
 | 
						|
  TFilename tmp; init_tmp_filename(tmp);
 | 
						|
  ofstream out(tmp);
 | 
						|
  
 | 
						|
  out << "US " << logic << " KE 2" << '\n';
 | 
						|
	ca_append_select_clause(out, level, logic, add_select);
 | 
						|
  ca_append_run_clause(out, logic);
 | 
						|
 | 
						|
  out << "IN " << str2 << ' ' << kfld.dlg() << '\n';
 | 
						|
  out << "DI \"" << TR("Descrizione") << "@50\" " << str2 << '\n';
 | 
						|
 | 
						|
  out << "OU " << kfld.dlg() << ' ' << str2 << '\n';
 | 
						|
 | 
						|
  for (int i = 0; i <= level; i++)
 | 
						|
  {
 | 
						|
    const TString& picture = mci.picture(i);
 | 
						|
    const TString& prompt = mci.prompt(i);
 | 
						|
    const TFieldref& field = mci.fieldref(i);
 | 
						|
    const int length = field.to() - field.from();
 | 
						|
    out << "DI \"" << prompt;
 | 
						|
    if (length > prompt.len()) 
 | 
						|
    {
 | 
						|
      out << '@' << length;
 | 
						|
      if (mci.is_numeric_picture(i))
 | 
						|
        out << 'R';
 | 
						|
    }
 | 
						|
    out << "\" " << field << '\n';
 | 
						|
    out << "OU " << (key_id+i) << ' ' << field << '\n';
 | 
						|
  }
 | 
						|
	if (logic == LF_COMMESSE)
 | 
						|
	{
 | 
						|
		out << "DI \"" << TR("Proroga") << "\" PROROGA" << '\n';
 | 
						|
		out << "DI \"" << TR("Data") << "@10" << "\" DATAPROR" << '\n';
 | 
						|
		out << "DI \"" << TR("Chiusa") << "\" CHIUSA" << '\n';
 | 
						|
	}
 | 
						|
 | 
						|
  out << "CH NO" << '\n';
 | 
						|
  if (level == main_info.levels()-1)
 | 
						|
    out << "FI " << main_info.fieldref(0, 2) << '\n';
 | 
						|
  out << "EN" << '\n';
 | 
						|
  out.close();
 | 
						|
 | 
						|
  TScanner scan(tmp);
 | 
						|
  while (scan.pop() != "EN")
 | 
						|
    kfld.parse_item(scan);
 | 
						|
 | 
						|
  xvt_fsys_remove_file(tmp);
 | 
						|
}
 | 
						|
 | 
						|
int ca_create_fields(TMask& msk, int page, int logicnum, int x, int y, 
 | 
						|
                  short key_id, short des_id, unsigned int mode, const char* fieldname, int from )
 | 
						|
{
 | 
						|
  TWait_cursor hourglass;
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum);
 | 
						|
 | 
						|
  int maxkeylen = 0, maxdeslen = 0;
 | 
						|
  for (int level = 0; level < mci.levels(); level++)
 | 
						|
  {
 | 
						|
    const TString& prompt = mci.prompt(level);
 | 
						|
    const TString& picture = mci.picture(level);
 | 
						|
    const int keylen = picture.len();
 | 
						|
    const int deslen = prompt.len();
 | 
						|
    if (keylen > maxkeylen) maxkeylen = keylen;
 | 
						|
    if (deslen > maxdeslen) maxdeslen = deslen;
 | 
						|
  }
 | 
						|
 | 
						|
  maxdeslen++;
 | 
						|
  const int tab0 = x;
 | 
						|
  const int tab1 = tab0 + maxdeslen + maxkeylen + 4;
 | 
						|
 | 
						|
  if (key_id > 0 && (mode == 0 || (mode & 0x1) != 0))
 | 
						|
  {
 | 
						|
    for (int i = 0; i < mci.levels(); i++)
 | 
						|
    {
 | 
						|
      const short kid = key_id+i;
 | 
						|
 | 
						|
      const TString& picture = mci.picture(i);
 | 
						|
      TString80 prompt = mci.prompt(i);
 | 
						|
      prompt.left_just(maxdeslen);
 | 
						|
 | 
						|
      const char* flags = picture[0] == '0' || picture[0] == '9' ? "BUZ" : "BU";
 | 
						|
      TEdit_field* kfld = NULL;
 | 
						|
      if (mci.is_numeric_picture(i))  // Numeric
 | 
						|
        kfld = &msk.add_number(kid, page, prompt, tab0, y+i, picture.len(), flags);
 | 
						|
      else
 | 
						|
        kfld = &msk.add_string(kid, page, prompt, tab0, y+i, picture.len(), flags);
 | 
						|
      ca_create_browse1(*kfld, i, logicnum, key_id, des_id);
 | 
						|
      if ((mode & 0x1) != 0 && fieldname == NULL)
 | 
						|
        kfld->set_key(1);
 | 
						|
 | 
						|
      // Ho specificato un nome di campo speciale
 | 
						|
      if (fieldname && *fieldname)
 | 
						|
      {
 | 
						|
        const TFieldref& fr = *kfld->field();
 | 
						|
        TString80 str; str.format("%s[%d,%d]", fieldname, fr.from()+from+1, fr.to()+from);
 | 
						|
        kfld->set_field(str);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (des_id > 0 && (mode == 0 || (mode & 0x2) != 0))
 | 
						|
  {
 | 
						|
    for (int i = 0; i < mci.levels(); i++)
 | 
						|
    {
 | 
						|
      const short did = des_id+i;
 | 
						|
      TEdit_field& dfld = msk.add_string(did, page, "", tab1, y+i, 50, "B", 72+tab0-tab1);
 | 
						|
      ca_create_browse2(dfld, i, logicnum, key_id);
 | 
						|
      if ((mode & 0x2) != 0 && fieldname == NULL)
 | 
						|
        dfld.set_key(2);
 | 
						|
      else
 | 
						|
        dfld.set_field("");
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  return mci.levels();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAnal_tree
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct TAnal_tree_pos : public TObject
 | 
						|
{
 | 
						|
  TRecnotype _recno;
 | 
						|
  TToken_string _key;
 | 
						|
 | 
						|
  void as_string(TString& id) const;
 | 
						|
  int level() const { return _key.items(); }
 | 
						|
  void reset();
 | 
						|
};
 | 
						|
 | 
						|
void TAnal_tree_pos::as_string(TString& id) const
 | 
						|
{
 | 
						|
  id.format("%ld|%s", _recno, (const char*)_key);
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_tree_pos::reset()
 | 
						|
{
 | 
						|
  _recno = 0;
 | 
						|
  _key.cut(0);
 | 
						|
}
 | 
						|
 | 
						|
class TAnal_tree : public TBidirectional_tree
 | 
						|
{
 | 
						|
  TLocalisamfile* _file;
 | 
						|
  TAnal_tree_pos  _curr;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual void node2id(const TObject* node, TString& id) const;
 | 
						|
 | 
						|
  virtual bool goto_firstson();
 | 
						|
  virtual bool goto_rbrother(); 
 | 
						|
  virtual bool goto_node(const TString &id);
 | 
						|
  virtual TObject* curr_node() const;
 | 
						|
  virtual bool goto_father();
 | 
						|
  virtual bool goto_lbrother();
 | 
						|
  virtual bool get_description(TString& desc) const;
 | 
						|
 | 
						|
protected:
 | 
						|
  void update_curr();
 | 
						|
  int level_of(const TToken_string& key) const;
 | 
						|
  int level_of_file() const;
 | 
						|
  const TToken_string& curr_of_file() const;
 | 
						|
  int curr_level() const;
 | 
						|
  int max_level() const;
 | 
						|
  const TToken_string& father_of(const TToken_string& key) const;
 | 
						|
  const TToken_string& father_of_file() const;
 | 
						|
  bool repos() const;
 | 
						|
 | 
						|
public:
 | 
						|
  virtual bool goto_root();
 | 
						|
 | 
						|
  TAnal_tree(int logicnum);
 | 
						|
  virtual ~TAnal_tree();
 | 
						|
};
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAnal_msk
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#define F_TREE 99
 | 
						|
 | 
						|
short TSimple_anal_msk::get_field_id(int n, int k) const
 | 
						|
{
 | 
						|
  short id = 0;
 | 
						|
  if (n >= 0 && n < fieldrefs(1))
 | 
						|
  {
 | 
						|
    if (k == 1)
 | 
						|
      id = F_KEY1+n;
 | 
						|
    else
 | 
						|
      id = F_DES1+n;
 | 
						|
  }
 | 
						|
  return id;
 | 
						|
}
 | 
						|
 | 
						|
bool TSimple_anal_msk::test_key_field(short id)
 | 
						|
{
 | 
						|
  TEdit_field& fld = efield(id);
 | 
						|
  const int level = id - F_KEY1;
 | 
						|
  return ca_test_multilevel_field(fld, level);
 | 
						|
}
 | 
						|
 | 
						|
bool TSimple_anal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case F_TREE:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      if (edit_mode() && !dirty())
 | 
						|
        set_mode(MODE_QUERY);
 | 
						|
      if (query_mode())
 | 
						|
      {
 | 
						|
        const TTree_field& fld = (const TTree_field&)o;
 | 
						|
        const TTree& tree = *fld.tree();
 | 
						|
        TToken_string curr; tree.curr_id(curr);
 | 
						|
        for (int i = 0; ; i++)
 | 
						|
        {
 | 
						|
          const short id = get_field_id(i);
 | 
						|
          if (id <= 0)
 | 
						|
            break;
 | 
						|
          const char* tok = curr.get(i+1);
 | 
						|
          TEdit_field& e = efield(id);
 | 
						|
          e.set(tok);
 | 
						|
          e.show();
 | 
						|
        }
 | 
						|
        stop_run(K_AUTO_ENTER);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        beep(0);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_KEY1:
 | 
						|
  case F_KEY2:
 | 
						|
  case F_KEY3:
 | 
						|
  case F_KEY4:
 | 
						|
    if ((jolly == 0) &&(e == fe_modify || e == fe_close))
 | 
						|
			return test_key_field(o.dlg());
 | 
						|
    break;
 | 
						|
  default: 
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
int TSimple_anal_msk::compute_offset() const
 | 
						|
{
 | 
						|
  int delta = 0;
 | 
						|
  RCT rct; xvt_vobj_get_client_rect(TASK_WIN, &rct);
 | 
						|
  if (rct.right > 720)
 | 
						|
    delta = (rct.right - 720) / 2 / CHARX;
 | 
						|
  return delta;
 | 
						|
}
 | 
						|
 | 
						|
void TSimple_anal_msk::read(const char* name)
 | 
						|
{
 | 
						|
  const int delta = compute_offset();
 | 
						|
 | 
						|
  if (delta > 0)
 | 
						|
  {
 | 
						|
    TFilename outname; init_tmp_filename(outname);
 | 
						|
    TFilename inpname = name; inpname.ext("msk");
 | 
						|
    inpname.custom_path();
 | 
						|
 | 
						|
    ofstream out(outname);
 | 
						|
 | 
						|
    TString line;
 | 
						|
    int status = 0;
 | 
						|
    TScanner inp(inpname);
 | 
						|
    while (!inp.eof())
 | 
						|
    {
 | 
						|
      line = inp.line();
 | 
						|
      switch (status)
 | 
						|
      {
 | 
						|
      case 0:
 | 
						|
        if (line.starts_with("PA"))
 | 
						|
          status = 1;                         // Ho trovato la prima pagina
 | 
						|
        break;
 | 
						|
      case 1:
 | 
						|
        if (line.starts_with("PR"))          // Ho trovato un prompt sulla prima pagina
 | 
						|
        {
 | 
						|
          TToken_string l(line, ' ');
 | 
						|
          int x = l.get_int(1);
 | 
						|
          if (x >= 0)
 | 
						|
          {
 | 
						|
            x += delta;
 | 
						|
            l.add(x, 1);
 | 
						|
            line = l;
 | 
						|
          }
 | 
						|
        } else
 | 
						|
        if (line.starts_with("PA"))          // Ho finito la prima pagina
 | 
						|
        {
 | 
						|
          status = 2;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      out << line << endl;
 | 
						|
    }
 | 
						|
    out.close();
 | 
						|
 | 
						|
    read_mask(outname, 0, 0);
 | 
						|
    xvt_fsys_remove_file(outname);
 | 
						|
    set_source_file(name);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    read_mask(name, 0, 0);
 | 
						|
 | 
						|
  create_key_fields();
 | 
						|
  create_tree_field();
 | 
						|
}
 | 
						|
 | 
						|
short TSimple_anal_msk::create_tree_field()
 | 
						|
{
 | 
						|
  short id = 0;
 | 
						|
  const int delta = compute_offset();
 | 
						|
  if (delta > 0)
 | 
						|
  {
 | 
						|
    id = F_TREE;
 | 
						|
    add_tree(id, 0, 0, 1, (delta-1)*2, -1);
 | 
						|
 | 
						|
    TAnal_tree* t = new TAnal_tree(get_logicnum());
 | 
						|
    tfield(id).set_tree(t);
 | 
						|
    t->goto_root();
 | 
						|
    t->expand();
 | 
						|
  }
 | 
						|
  set_handlers();
 | 
						|
  return id;
 | 
						|
}
 | 
						|
 | 
						|
void TSimple_anal_msk::update_tree_field()
 | 
						|
{
 | 
						|
  const int pos = id2pos(F_TREE);
 | 
						|
  if (pos >= 0)
 | 
						|
  {
 | 
						|
    TTree_field& t = tfield(F_TREE);
 | 
						|
    t.win().force_update();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
int TSimple_anal_msk::fieldrefs(int k) const
 | 
						|
{
 | 
						|
  int n = 1;
 | 
						|
  if (k == 1)
 | 
						|
  {
 | 
						|
    const TMultilevel_code_info& mci = ca_multilevel_code_info(get_logicnum());
 | 
						|
    n = mci.levels();
 | 
						|
  }
 | 
						|
  return n;
 | 
						|
}
 | 
						|
 | 
						|
const TFieldref& TSimple_anal_msk::fieldref(int n, int k) const
 | 
						|
{
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(get_logicnum());
 | 
						|
  return mci.fieldref(n, k);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
const TToken_string& TSimple_anal_msk::get_key_value(const TRectype& rec, int c) const
 | 
						|
{
 | 
						|
  TToken_string& val = get_tmp_string();
 | 
						|
  const int tot = fieldrefs(c);
 | 
						|
  for (int i = 0; i < tot; i++)
 | 
						|
  {
 | 
						|
    const TFieldref& field = fieldref(i, c);
 | 
						|
    val.add(field.read(rec));
 | 
						|
  }
 | 
						|
  return val;
 | 
						|
}
 | 
						|
 | 
						|
const TToken_string& TSimple_anal_msk::get_key_value(int c) const
 | 
						|
{
 | 
						|
  TToken_string& val = get_tmp_string();
 | 
						|
  for (TEditable_field* f = get_key_field(c, true); f != NULL; f = get_key_field(c, false))
 | 
						|
  {
 | 
						|
    val.add(f->get());
 | 
						|
  }
 | 
						|
  return val;
 | 
						|
}
 | 
						|
 | 
						|
int TSimple_anal_msk::create_key_fields()
 | 
						|
{
 | 
						|
  const int logic = get_logicnum();
 | 
						|
  const short kid = get_field_id(0, 1);
 | 
						|
  const short did = get_field_id(0, 2);
 | 
						|
  const int x = compute_offset()+3;
 | 
						|
  const int y = 1;
 | 
						|
  const int n = ca_create_fields(*this, 0, logic, x, y, kid, did, 0x1);
 | 
						|
  const int m = ca_create_fields(*this, 0, logic, x, y, kid, did, 0x2);
 | 
						|
	first_focus(kid);
 | 
						|
  return n;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAnal_tree
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const TToken_string& TAnal_tree::curr_of_file() const
 | 
						|
{
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num());
 | 
						|
  const TRectype& rec = _file->curr();
 | 
						|
 | 
						|
  TToken_string& k = get_tmp_string();
 | 
						|
  
 | 
						|
  for (int i = 0; i < mci.levels(); i++)
 | 
						|
  {
 | 
						|
    const TFieldref& fld = mci.fieldref(i);
 | 
						|
    k.add(fld.read(rec));
 | 
						|
  }
 | 
						|
 | 
						|
  for (int j = k.len()-1; j >= 0; j--)
 | 
						|
  {
 | 
						|
    if (k[j] == ' ' || k[j] == k.separator())
 | 
						|
      k.cut(j);
 | 
						|
    else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_tree::level_of(const TToken_string& k) const
 | 
						|
{
 | 
						|
  return k.items();
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_tree::level_of_file() const
 | 
						|
{
 | 
						|
  const TToken_string& str = curr_of_file();
 | 
						|
  return level_of(str);
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_tree::curr_level() const
 | 
						|
{
 | 
						|
  return level_of(_curr._key);
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_tree::max_level() const
 | 
						|
{
 | 
						|
  const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num());
 | 
						|
  return mci.levels();
 | 
						|
}
 | 
						|
 | 
						|
const TToken_string& TAnal_tree::father_of(const TToken_string& key) const
 | 
						|
{
 | 
						|
  const int pos = key.rfind(key.separator());
 | 
						|
  if (pos <= 0)
 | 
						|
    return EMPTY_STRING;
 | 
						|
 | 
						|
  TToken_string& k = get_tmp_string();
 | 
						|
  k = key.left(pos);
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
const TToken_string& TAnal_tree::father_of_file() const
 | 
						|
{
 | 
						|
  const TToken_string& k = curr_of_file();
 | 
						|
  return father_of(k);
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_tree::update_curr()
 | 
						|
{
 | 
						|
  _curr._key = curr_of_file();
 | 
						|
  if (_curr._key.not_empty())
 | 
						|
    _curr._recno = _file->recno();
 | 
						|
  else
 | 
						|
    _curr.reset();
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::repos() const
 | 
						|
{
 | 
						|
  bool ok = false;
 | 
						|
  if (_curr.level() > 0)
 | 
						|
  {
 | 
						|
    if (_file->recno() != _curr._recno)
 | 
						|
      ok = ((TLocalisamfile*)_file)->readat(_curr._recno) == NOERR;
 | 
						|
    else
 | 
						|
      ok = true;
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_tree::node2id(const TObject* node, TString& id) const
 | 
						|
{
 | 
						|
  const TAnal_tree_pos* pos = (const TAnal_tree_pos*)node;
 | 
						|
  pos->as_string(id);
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_root()
 | 
						|
{
 | 
						|
  const bool ok = _file->first() == NOERR;
 | 
						|
  if (ok)
 | 
						|
    update_curr();
 | 
						|
  else
 | 
						|
    _curr.reset();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_firstson()
 | 
						|
{
 | 
						|
  bool ok = _curr.level() < max_level() && repos();
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    ok = _file->next() == NOERR;
 | 
						|
    if (ok)
 | 
						|
    {
 | 
						|
      ok = father_of_file() == _curr._key; 
 | 
						|
      if (ok)
 | 
						|
        update_curr();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_rbrother()
 | 
						|
{
 | 
						|
  bool ok = false;
 | 
						|
  if (repos())
 | 
						|
  {
 | 
						|
    const TToken_string curr_father = father_of(_curr._key);
 | 
						|
    while (_file->next() == NOERR)
 | 
						|
    {
 | 
						|
      const int lev = level_of_file();
 | 
						|
      if (lev > _curr.level())
 | 
						|
        continue;
 | 
						|
 | 
						|
      const TToken_string& next_father = father_of_file();
 | 
						|
      ok = next_father == curr_father;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if (ok)
 | 
						|
      update_curr();
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_node(const TString &id)
 | 
						|
{
 | 
						|
  const TRecnotype rec = atol(id); 
 | 
						|
  const int err = _file->readat(rec);
 | 
						|
  
 | 
						|
  if (err == NOERR)
 | 
						|
    update_curr();
 | 
						|
  
 | 
						|
  return err == NOERR;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_father()
 | 
						|
{
 | 
						|
  const int lev = _curr.level();
 | 
						|
  bool ok = lev > 1;
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    TRectype& rec = _file->curr();
 | 
						|
    rec.zero();
 | 
						|
    
 | 
						|
    const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num());
 | 
						|
    for (int i = 0; i < lev-1; i++)
 | 
						|
    {
 | 
						|
      const char* val = _curr._key.get(i);
 | 
						|
      const TFieldref& fld = mci.fieldref(i);
 | 
						|
      fld.write(val, rec);
 | 
						|
    }
 | 
						|
    ok = _file->read() == NOERR;
 | 
						|
    if (ok)
 | 
						|
      update_curr();
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::goto_lbrother()
 | 
						|
{
 | 
						|
  bool ok = false;
 | 
						|
  if (repos())
 | 
						|
  {
 | 
						|
    const TString curr_father = father_of(_curr._key);
 | 
						|
    while (_file->prev() == NOERR)
 | 
						|
    {
 | 
						|
      const int lev = level_of_file();
 | 
						|
      if (lev > _curr.level())
 | 
						|
        continue;
 | 
						|
 | 
						|
      const TString& next_father = father_of_file();
 | 
						|
      ok = next_father == curr_father;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if (ok)
 | 
						|
      update_curr();
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TObject* TAnal_tree::curr_node() const
 | 
						|
{
 | 
						|
  return (TObject*)&_curr;
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_tree::get_description(TString& desc) const
 | 
						|
{
 | 
						|
  const bool ok = repos();
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    const int lev = _curr.level();
 | 
						|
    if (lev > 0)
 | 
						|
    {
 | 
						|
      const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num());
 | 
						|
      const TFieldref& fld1 = mci.fieldref(lev-1, 1);
 | 
						|
      const TFieldref& fld2 = mci.fieldref(0, 2);
 | 
						|
      const TRectype& rec = _file->curr();
 | 
						|
      desc = fld1.read(rec);
 | 
						|
      desc << ' ' << fld2.read(rec);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TAnal_tree::TAnal_tree(int logicnum) 
 | 
						|
{
 | 
						|
  _file = new TLocalisamfile(logicnum);
 | 
						|
}
 | 
						|
 | 
						|
TAnal_tree::~TAnal_tree()
 | 
						|
{
 | 
						|
  delete _file;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAnal_app
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TAnal_app::init_key_fields(TSimple_anal_msk & m) const
 | 
						|
{
 | 
						|
  int maxlev = 0;
 | 
						|
  for (maxlev = 0; maxlev < 4; maxlev++)
 | 
						|
  {
 | 
						|
    const short id = m.get_field_id(maxlev, 1);
 | 
						|
    if (id <= 0 || m.id2pos(id) < 0)
 | 
						|
      break;
 | 
						|
    m.disable(id);
 | 
						|
 | 
						|
    const short did = m.get_field_id(maxlev, 2);
 | 
						|
    m.disable(did);
 | 
						|
  }
 | 
						|
 | 
						|
  for (int i = maxlev-1; i >= 0; i--)
 | 
						|
  {
 | 
						|
    const short id = m.get_field_id(i, 1);
 | 
						|
    TEdit_field& e = m.efield(id);
 | 
						|
    const short did = m.get_field_id(i, 2);
 | 
						|
    TEdit_field& d = m.efield(did);
 | 
						|
 | 
						|
    if (e.empty())
 | 
						|
    {
 | 
						|
      e.hide();
 | 
						|
      d.hide();
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      e.show();
 | 
						|
      e.check(STARTING_CHECK);
 | 
						|
 | 
						|
      TString80 key2; 
 | 
						|
			key2 << m.fieldref(0, 2);
 | 
						|
      d.set_field(key2);
 | 
						|
      d.show();
 | 
						|
      d.enable();
 | 
						|
		  m.first_focus(d.dlg());
 | 
						|
      d.enable_check(false);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TRelation* TAnal_app::create_relation() const 
 | 
						|
{ 
 | 
						|
  return new TRelation(_msk->get_logicnum()); 
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_app::user_create()
 | 
						|
{
 | 
						|
  _msk = create_mask();
 | 
						|
  _rel = create_relation();
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_app::init_query_mode(TMask& mask)
 | 
						|
{
 | 
						|
  TSimple_anal_msk& m = (TSimple_anal_msk&)mask;
 | 
						|
  for (int i = 0; ; i++)
 | 
						|
  {
 | 
						|
    const short id = m.get_field_id(i, 1);
 | 
						|
    if (id <= 0 || m.id2pos(id) < 0)
 | 
						|
      break;
 | 
						|
 | 
						|
    TEdit_field& e = m.efield(id);
 | 
						|
    e.show(); e.enable();
 | 
						|
 | 
						|
    const short did = m.get_field_id(i, 2);
 | 
						|
    TEdit_field& d = m.efield(did);
 | 
						|
    d.show(); d.enable();
 | 
						|
    d.enable_check();
 | 
						|
		d.set_field("");
 | 
						|
  }
 | 
						|
  m.first_focus(m.get_field_id(0, 1));
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_app::init_modify_mode(TMask& mask)
 | 
						|
{
 | 
						|
  init_key_fields((TSimple_anal_msk &)mask);
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_app::init_insert_mode(TMask& mask)
 | 
						|
{
 | 
						|
  init_key_fields((TSimple_anal_msk &)mask);
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_app::write(const TMask& m)
 | 
						|
{
 | 
						|
  _msk->update_tree_field();
 | 
						|
  return TRelation_application::write(m);
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_app::rewrite(const TMask& m)
 | 
						|
{
 | 
						|
  _msk->update_tree_field();
 | 
						|
  return TRelation_application::rewrite(m);
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_app::user_destroy()
 | 
						|
{
 | 
						|
  if (_msk != NULL)
 | 
						|
    delete _msk;
 | 
						|
  if (_rel != NULL)
 | 
						|
    delete _rel;
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAnal_mov
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TAnal_mov::saldo_set_reset(const TRectype& row, bool reset)
 | 
						|
{
 | 
						|
  const int dec = TCurrency::get_firm_dec();
 | 
						|
  const TImporto imp_row(row.get_char(RMOVANA_SEZIONE), row.get_real(RMOVANA_IMPORTO));
 | 
						|
  const int esc_iniziale = get_int(MOVANA_ANNOES);
 | 
						|
  int esc_finale = esc_iniziale;
 | 
						|
 | 
						|
  //che movimento e'?
 | 
						|
  TToken_string annies;
 | 
						|
  annies.add(esc_iniziale);
 | 
						|
  
 | 
						|
  const char tipomov = get_char(MOVANA_TIPOMOV);
 | 
						|
  //se e' un movimento di tipo preventivo potrebbe avere una data di scadenza come la mozzarella
 | 
						|
  if (tipomov == 'P' || tipomov == 'V')
 | 
						|
  {
 | 
						|
    const TDate datacomp = get_date(MOVANA_DATACOMP);
 | 
						|
    const TDate datafcomp = get_date(MOVANA_DATAFCOMP);
 | 
						|
    if (datafcomp.ok() && datafcomp > datacomp)
 | 
						|
    {
 | 
						|
      TEsercizi_contabili esc;
 | 
						|
      esc_finale = esc.date2esc(datafcomp);
 | 
						|
      if (esc_finale < esc_iniziale)  //se l'esercizio di scadenza non esiste ancora perche' troppo futuro...
 | 
						|
        esc_finale = esc_iniziale + datafcomp.year() - datacomp.year(); //...se lo genera
 | 
						|
      if (esc_finale > esc_iniziale)
 | 
						|
      {
 | 
						|
        for (int a = esc_iniziale + 1; a <= esc_finale; a++)
 | 
						|
          annies.add(a);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TToken_string key;
 | 
						|
  key.add(tipomov);
 | 
						|
  key.add(esc_iniziale);
 | 
						|
  key.add(row.get(RMOVANA_CODCCOSTO));
 | 
						|
  key.add(row.get(RMOVANA_CODCMS));
 | 
						|
  key.add(row.get(RMOVANA_CODFASE));
 | 
						|
  key.add(row.get(RMOVANA_CODCONTO));
 | 
						|
  
 | 
						|
  if (annies.items() > 1) //saldi spammati su piu' anni
 | 
						|
  {
 | 
						|
    TToken_string giorni_annies;  //lista dei giorni di saldo per annoes
 | 
						|
    TEsercizi_contabili esc;
 | 
						|
 | 
						|
    const TDate datacomp = get_date(MOVANA_DATACOMP);
 | 
						|
    const TDate datafcomp = get_date(MOVANA_DATAFCOMP);
 | 
						|
 | 
						|
    TDate inizio_esc_iniziale, fine_esc_iniziale;
 | 
						|
    esc.code2range(esc_iniziale, inizio_esc_iniziale, fine_esc_iniziale);
 | 
						|
    giorni_annies.add(fine_esc_iniziale - datacomp + 1); //primo esercizio
 | 
						|
 | 
						|
    TDate inizio_esc_finale, fine_esc_finale;
 | 
						|
    for (int a = 1; a < annies.items() - 1; a++)
 | 
						|
    {
 | 
						|
      const int curr_esc = annies.get_int(a);
 | 
						|
      esc.code2range(curr_esc, inizio_esc_finale, fine_esc_finale);
 | 
						|
      giorni_annies.add(fine_esc_finale - inizio_esc_finale + 1); //esercizi intermedi
 | 
						|
    }
 | 
						|
 | 
						|
    esc.code2range(esc_finale, inizio_esc_finale, fine_esc_finale);
 | 
						|
    giorni_annies.add(datafcomp - inizio_esc_finale + 1);  //ultimo esercizio
 | 
						|
 | 
						|
    //Adesso che ha l'elenco dei giorni impegnati per esercizio, scatta il casino del distributore..
 | 
						|
    TGeneric_distrib texaco(imp_row.valore(), dec);
 | 
						|
    FOR_EACH_TOKEN(giorni_annies, gg)
 | 
						|
      texaco.add(real(gg));
 | 
						|
 | 
						|
    FOR_EACH_TOKEN(annies, es)
 | 
						|
    {
 | 
						|
      TImporto curr_imp(imp_row.sezione(), texaco.get());
 | 
						|
      key.add(es, 1);   //sistema l'anno di esercizio nella chiave
 | 
						|
      TImporto* imp = (TImporto*)_saldi.objptr(key);
 | 
						|
      if (imp == NULL)
 | 
						|
      {
 | 
						|
        imp = new TImporto;
 | 
						|
        _saldi.add(key, imp);
 | 
						|
      }
 | 
						|
      if (reset)
 | 
						|
        *imp -= curr_imp;
 | 
						|
      else
 | 
						|
        *imp += curr_imp;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else  //saldo in un solo anno (caso standard)
 | 
						|
  {
 | 
						|
    TImporto* imp = (TImporto*)_saldi.objptr(key);
 | 
						|
    if (imp == NULL)
 | 
						|
    {
 | 
						|
      imp = new TImporto;
 | 
						|
      _saldi.add(key, imp);
 | 
						|
    }
 | 
						|
    if (reset)
 | 
						|
      *imp -= imp_row;
 | 
						|
    else
 | 
						|
      *imp += imp_row;
 | 
						|
 | 
						|
    imp->valore().round(dec);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_mov::load_saldi(bool reset)
 | 
						|
{
 | 
						|
  if (reset)
 | 
						|
    _saldi.destroy();
 | 
						|
  
 | 
						|
  const TRecord_array& a = body(LF_RMOVANA);
 | 
						|
  for (int i = a.last_row(); i > 0; i--)
 | 
						|
  {
 | 
						|
    const TRectype& row = a[i];
 | 
						|
    saldo_set_reset(row, reset);  //aggiunge o toglie la riga corrente ai saldi in memoria  
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_mov::update_saldi(bool kill)
 | 
						|
{
 | 
						|
  if (!kill)
 | 
						|
    load_saldi(false);
 | 
						|
  
 | 
						|
  save_saldi();
 | 
						|
  
 | 
						|
  if (kill)
 | 
						|
    _saldi.destroy();
 | 
						|
  else
 | 
						|
    load_saldi(true);
 | 
						|
}
 | 
						|
 | 
						|
bool TAnal_mov::save_saldi(const int annoes)
 | 
						|
{
 | 
						|
  TLocalisamfile saldi(LF_SALDANA);
 | 
						|
  FOR_EACH_ASSOC_OBJECT(_saldi, h, k, o)
 | 
						|
  {
 | 
						|
    const TImporto& imp = *(const TImporto*)o;
 | 
						|
    if (!imp.is_zero())
 | 
						|
    {
 | 
						|
      TToken_string key = k;
 | 
						|
      const char tipo = key.get_char(0);
 | 
						|
      const int anno = key.get_int(1);
 | 
						|
      
 | 
						|
      //Controlla se deve veramente salvre i saldi che ha calcolato
 | 
						|
      bool save_for_true = true;
 | 
						|
      //se annoes = 0 -> registrazione movimento analitico -> save_for_true = true -> salva!
 | 
						|
      //se invece trova un anno e' in fase ricostruzione saldi! Deve fare delle considerazioni..
 | 
						|
      if (annoes != 0)
 | 
						|
      {
 | 
						|
        if (annoes > 0)   //se annoes e' positivo -> sono saldi normali -> salva!
 | 
						|
          save_for_true = anno == annoes;
 | 
						|
        else              //se annoes e' negativo -> sono preventivi futuri -> salva solo se abs(anno)>annoes (senno' non sei nel futuro!) 
 | 
						|
          save_for_true = anno > -annoes;
 | 
						|
      }
 | 
						|
      if (!save_for_true)   //se non deve salvare davvero il saldo -> continua
 | 
						|
        continue;
 | 
						|
      
 | 
						|
      saldi.put(SALDANA_ANNO,     anno);
 | 
						|
      saldi.put(SALDANA_COSTO,    key.get(2));
 | 
						|
      saldi.put(SALDANA_COMMESSA, key.get(3));
 | 
						|
      saldi.put(SALDANA_FASE,     key.get(4));
 | 
						|
      saldi.put(SALDANA_CONTO,    key.get(5));
 | 
						|
 | 
						|
      int err = saldi.read(_isequal, _testandlock);
 | 
						|
      if (err != NOERR)
 | 
						|
      {
 | 
						|
//Richiesta specifica del nostro Fuhrer! I saldi appartenenti ad esercizi futuri NON ancora aperti vanno..
 | 
						|
//..comunque registrati!!!
 | 
						|
//        TEsercizi_contabili esc;
 | 
						|
//        if (esc.exist(anno))
 | 
						|
        {
 | 
						|
				  saldi.zero();
 | 
						|
          saldi.put(SALDANA_ANNO,     anno);
 | 
						|
          saldi.put(SALDANA_COSTO,    key.get(2));
 | 
						|
          saldi.put(SALDANA_COMMESSA, key.get(3));
 | 
						|
          saldi.put(SALDANA_FASE,     key.get(4));
 | 
						|
          saldi.put(SALDANA_CONTO,    key.get(5));
 | 
						|
          err = saldi.write();
 | 
						|
        }
 | 
						|
//        else
 | 
						|
//          continue;  // NON devo dare errori fuorvianti causa saldi nel futuro che ci saranno ma non vanno scritti
 | 
						|
      }
 | 
						|
 | 
						|
      if (err == NOERR)
 | 
						|
      {
 | 
						|
        const char* fld_sez = NULL;
 | 
						|
        const char* fld_val = NULL;
 | 
						|
        switch (tipo)
 | 
						|
        {
 | 
						|
	        case 'P': fld_sez = SALDANA_SEZIONEP; fld_val = SALDANA_SALDOP; break;
 | 
						|
	        case 'V': fld_sez = SALDANA_SEZIONEV; fld_val = SALDANA_SALDOV; break;
 | 
						|
					default : fld_sez = SALDANA_SEZIONE;  fld_val = SALDANA_SALDO;  break;
 | 
						|
        }
 | 
						|
        TImporto saldo(saldi.get_char(fld_sez), saldi.get_real(fld_val));
 | 
						|
        saldo += imp;
 | 
						|
        saldo.normalize();
 | 
						|
 | 
						|
        saldi.put(fld_sez, saldo.sezione());
 | 
						|
        saldi.put(fld_val, saldo.valore());
 | 
						|
        err = saldi.rewrite();
 | 
						|
      }
 | 
						|
    
 | 
						|
      if (err != NOERR)
 | 
						|
        return error_box(FR("Impossibile aggiornare i saldi: errore %d"), err);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_mov::readat(TBaseisamfile& f, TRecnotype nrec, word lockop)
 | 
						|
{
 | 
						|
  const int err = TMultiple_rectype::readat(f, nrec, lockop);
 | 
						|
  
 | 
						|
	load_saldi(true);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_mov::read(TBaseisamfile& f, word op, word lockop)
 | 
						|
{
 | 
						|
  const int err = TMultiple_rectype::read(f, op, lockop);
 | 
						|
 | 
						|
	load_saldi(true);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
// Riporta su tutte le righe la data di competenza e l'esercizio dellla testata
 | 
						|
void TAnal_mov::update_datacomp() const
 | 
						|
{
 | 
						|
  body().renum_key(RMOVANA_ANNOES, get(MOVANA_ANNOES));
 | 
						|
  body().renum_key(RMOVANA_DATACOMP, get(MOVANA_DATACOMP));
 | 
						|
} 
 | 
						|
 | 
						|
int TAnal_mov::write(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  update_datacomp();
 | 
						|
  const int err = TMultiple_rectype::write(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    ((TAnal_mov*)this)->update_saldi(false);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_mov::rewrite(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  update_datacomp();
 | 
						|
  const int err = TMultiple_rectype::rewrite(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    ((TAnal_mov*)this)->update_saldi(false);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_mov::remove(TBaseisamfile& f) const
 | 
						|
{
 | 
						|
  const int err = TMultiple_rectype::remove(f);
 | 
						|
  if (err == NOERR)
 | 
						|
    ((TAnal_mov*)this)->update_saldi(true);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_mov::read(long numreg, word lock)
 | 
						|
{
 | 
						|
  put(MOVANA_NUMREG, numreg);
 | 
						|
  const int err = TMultiple_rectype::read(_isequal, lock);
 | 
						|
  
 | 
						|
	load_saldi(true);
 | 
						|
	return err;
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_mov::zero(char c)
 | 
						|
{
 | 
						|
	TMultiple_rectype::zero(c);
 | 
						|
	kill_saldi();
 | 
						|
}
 | 
						|
 | 
						|
void TAnal_mov::update_totdoc()
 | 
						|
{
 | 
						|
  TImporto totdoc;
 | 
						|
  for (int i = rows(); i > 0; i--)
 | 
						|
  {
 | 
						|
    const TRectype& riga = body().row(i); 
 | 
						|
    TImporto imp_riga(riga.get_char(RMOVANA_SEZIONE), riga.get_real(RMOVANA_IMPORTO));
 | 
						|
    totdoc += imp_riga;
 | 
						|
  }
 | 
						|
  totdoc.normalize();
 | 
						|
 | 
						|
  put(MOVANA_TOTDOC, totdoc.valore());
 | 
						|
  put(MOVANA_SEZIONE, totdoc.sezione());
 | 
						|
}
 | 
						|
 | 
						|
TAnal_mov::TAnal_mov(long numreg) : TMultiple_rectype(LF_MOVANA)
 | 
						|
{
 | 
						|
  add_file(LF_RMOVANA, RMOVANA_NUMRIG);
 | 
						|
  if (numreg > 0)
 | 
						|
    read(numreg);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TAnal_mov::TAnal_mov(const TRectype& rec) : TMultiple_rectype(LF_MOVANA)
 | 
						|
{
 | 
						|
	add_file(LF_RMOVANA, RMOVANA_NUMRIG);
 | 
						|
 | 
						|
	long numreg = 0;
 | 
						|
	switch(rec.num())
 | 
						|
	{
 | 
						|
	case LF_MOV:
 | 
						|
	case LF_RMOV:
 | 
						|
	case LF_RMOVIVA:
 | 
						|
		{
 | 
						|
			TLocalisamfile movana(LF_MOVANA);
 | 
						|
			movana.setkey(3);
 | 
						|
			movana.put(MOVANA_NUMREGCG, rec.get(MOV_NUMREG));
 | 
						|
			if (movana.read() == NOERR)
 | 
						|
				numreg = movana.get_long(MOVANA_NUMREG);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	default: 
 | 
						|
		numreg = rec.get_long(MOVANA_NUMREG);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	if (numreg > 0)
 | 
						|
    read(numreg);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//  TAnal_ripartizioni_batch
 | 
						|
//////////////////////////////////////////////////////////
 | 
						|
int TAnal_ripartizioni_batch::indbil() const
 | 
						|
{ 
 | 
						|
  return head().get_int(RIP_INDBIL); 
 | 
						|
}
 | 
						|
 | 
						|
char TAnal_ripartizioni_batch::tiporip() const
 | 
						|
{
 | 
						|
  return head().get_char(RIP_TIPO);
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_ripartizioni_batch::read (const char tiporip, const char* codice)
 | 
						|
{
 | 
						|
  TLocalisamfile rip(LF_RIP);
 | 
						|
  _rip.put(RIP_TIPO, tiporip); //solo tipi batch!
 | 
						|
  _rip.put(RIP_CODICE, codice);
 | 
						|
  int err = _rip.read(rip);   //leggi il record dal file
 | 
						|
  if (err == NOERR)
 | 
						|
  {
 | 
						|
    TRectype rrip(LF_RRIP);
 | 
						|
    rrip.put(RRIP_TIPO, tiporip);
 | 
						|
    rrip.put(RRIP_CODICE, codice);
 | 
						|
    TRecord_array::read(rrip);
 | 
						|
  }
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_ripartizioni_batch::read_rip_4(TLocalisamfile& rip, const char* codcosto, const char* commessa, 
 | 
						|
                                         const char* fase, const int annoes, const int indbil, const int classe_mov) const
 | 
						|
{
 | 
						|
  rip.put(RIP_TIPO, "B"); //solo tipi batch, unici per chiave cdc/cms/fase
 | 
						|
  rip.put(RIP_CODCOSTO, codcosto);
 | 
						|
  rip.put(RIP_CODCMS, commessa);
 | 
						|
  rip.put(RIP_CODFASE, fase);
 | 
						|
  rip.put(RIP_ANNOES, annoes);
 | 
						|
  rip.put(RIP_INDBIL, indbil);
 | 
						|
  rip.put(RIP_CLASSEMOV, classe_mov);
 | 
						|
  return rip.read();
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_ripartizioni_batch::read (const char* codcosto, const char* commessa, const char* fase,
 | 
						|
                                    const int annoes, const int indbil, const int classe_mov)
 | 
						|
{
 | 
						|
  CHECKD(classe_mov > 0, "Classe movimento non valida ", classe_mov);
 | 
						|
  TLocalisamfile rip(LF_RIP);
 | 
						|
  rip.setkey(4);
 | 
						|
 | 
						|
  int err = read_rip_4(rip, codcosto, commessa, fase, annoes, indbil, classe_mov);
 | 
						|
  if (err != NOERR)
 | 
						|
   err = read_rip_4(rip, codcosto, commessa, fase, annoes, indbil, 0);
 | 
						|
  //la put va rifatta perche' potrebbe essersi spostato al record successivo!!!
 | 
						|
  //se fallisce il primo tentativo prova con lo stesso anno e indbil=0
 | 
						|
  if (err != NOERR && indbil != 0)
 | 
						|
  {
 | 
						|
    err = read_rip_4(rip, codcosto, commessa, fase, annoes, 0, classe_mov);
 | 
						|
    if (err != NOERR)
 | 
						|
     err = read_rip_4(rip, codcosto, commessa, fase, annoes, 0, 0);
 | 
						|
  }
 | 
						|
  //se fallisce ancora riprova con anno=0 e lo stesso indbil
 | 
						|
  if (err != NOERR && annoes != 0)
 | 
						|
  {
 | 
						|
    err = read_rip_4(rip, codcosto, commessa, fase, 0, indbil, classe_mov);
 | 
						|
    if (err != NOERR)
 | 
						|
     err = read_rip_4(rip, codcosto, commessa, fase, 0, indbil, 0);
 | 
						|
 | 
						|
    //estremo tentativo con annoes e indbil = 0
 | 
						|
    if (err != NOERR && indbil != 0)
 | 
						|
    {
 | 
						|
      err = read_rip_4(rip, codcosto, commessa, fase, 0, 0, classe_mov);
 | 
						|
      if (err != NOERR)
 | 
						|
       err = read_rip_4(rip, codcosto, commessa, fase, 0, 0, 0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (err == NOERR)
 | 
						|
    err = read('B', rip.get(RIP_CODICE)); //per chiave 4 solo tipo B (batch)
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_ripartizioni_batch::read_rip_3(TLocalisamfile& rip, const char tiporip, const int gr, const int co, const long sot, 
 | 
						|
                                    const int annoes, const int indbil, const int classe_mov) const
 | 
						|
{
 | 
						|
  rip.put(RIP_TIPO, tiporip); //tipo 'P' oppure tipo 'I', che sono quelli che vanno per conto
 | 
						|
  rip.put(RIP_GRUPPO, gr);
 | 
						|
  rip.put(RIP_CONTO, co);
 | 
						|
  rip.put(RIP_SOTTOCONTO, sot);
 | 
						|
  rip.put(RIP_ANNOES, annoes);
 | 
						|
  rip.put(RIP_INDBIL, indbil);
 | 
						|
  rip.put(RIP_CLASSEMOV, classe_mov);
 | 
						|
	return rip.read();
 | 
						|
}
 | 
						|
 | 
						|
int TAnal_ripartizioni_batch::read (const char tiporip, const int gr, const int co, const long sot, 
 | 
						|
                                    const int annoes, const int indbil, const int classe_mov)
 | 
						|
{
 | 
						|
  CHECKD(classe_mov > 0, "Classe movimento non valida ", classe_mov);
 | 
						|
  TLocalisamfile rip(LF_RIP);
 | 
						|
  rip.setkey(3);
 | 
						|
 | 
						|
  int err = read_rip_3(rip, tiporip, gr, co, sot, annoes, indbil, classe_mov);
 | 
						|
  if (err != NOERR)
 | 
						|
     err = read_rip_3(rip, tiporip, gr, co, sot, annoes, indbil, 0);
 | 
						|
 | 
						|
  //la put va rifatta perche' potrebbe essersi spostato al record successivo!!!
 | 
						|
  //se fallisce il primo tentativo prova con lo stesso anno e indbil=0
 | 
						|
  if (err != NOERR && indbil != 0)
 | 
						|
  {
 | 
						|
    err = read_rip_3(rip, tiporip, gr, co, sot, annoes, 0, classe_mov);
 | 
						|
    if (err != NOERR)
 | 
						|
      err = read_rip_3(rip, tiporip, gr, co, sot, annoes, 0, 0);
 | 
						|
  }
 | 
						|
  //se fallisce ancora riprova con anno=0 e lo stesso indbil
 | 
						|
  if (err != NOERR && annoes != 0)
 | 
						|
  {
 | 
						|
    err = read_rip_3(rip, tiporip, gr, co, sot, 0, indbil, classe_mov);
 | 
						|
    if (err != NOERR)
 | 
						|
      err = read_rip_3(rip, tiporip, gr, co, sot, 0, indbil, 0);
 | 
						|
 
 | 
						|
    //estremo tentativo con annoes e indbil = 0
 | 
						|
    if (err != NOERR && indbil != 0)
 | 
						|
    {
 | 
						|
      err = read_rip_3(rip, tiporip, gr, co, sot, 0, 0, classe_mov);
 | 
						|
      if (err != NOERR)
 | 
						|
        err = read_rip_3(rip, tiporip, gr, co, sot, 0, 0, 0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (err == NOERR)
 | 
						|
    err = read(tiporip, rip.get(RIP_CODICE)); //per chiave 3 sia tiporip=P che tiporip=B
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
TAnal_ripartizioni_batch::TAnal_ripartizioni_batch() : TRecord_array (LF_RRIP, RRIP_NRIGA), _rip(LF_RIP)
 | 
						|
{
 | 
						|
  
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//  TCache_ripartizioni
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
TObject* TCache_ripartizioni::key2obj(const char* key)
 | 
						|
{
 | 
						|
  TToken_string parametro(key);
 | 
						|
  const int nkey = parametro.get_int(0);
 | 
						|
 | 
						|
  TAnal_ripartizioni_batch* rip = new TAnal_ripartizioni_batch;
 | 
						|
 
 | 
						|
  switch (nkey)
 | 
						|
  {
 | 
						|
  case 3:
 | 
						|
    {
 | 
						|
      const int gruppo = parametro.get_int(1);
 | 
						|
      const int conto = parametro.get_int(2);
 | 
						|
      const long sottoconto = parametro.get_long(3);
 | 
						|
      const int anno = parametro.get_int(4);
 | 
						|
      const int indbil = parametro.get_int(5);
 | 
						|
      const int classe_mov = parametro.get_int(6);
 | 
						|
 | 
						|
      //solo i movimenti a pareggio hanno chiave 3
 | 
						|
      rip->read('P', gruppo, conto, sottoconto, anno, indbil, classe_mov);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case 5:
 | 
						|
    {
 | 
						|
      const int gruppo = parametro.get_int(1);
 | 
						|
      const int conto = parametro.get_int(2);
 | 
						|
      const long sottoconto = parametro.get_long(3);
 | 
						|
      const int anno = parametro.get_int(4);
 | 
						|
      const int indbil = parametro.get_int(5);
 | 
						|
      const int classe_mov = parametro.get_int(6);
 | 
						|
 | 
						|
      //solo i movimenti interattivi e di conversione hanno chiave 5
 | 
						|
      rip->read('I', gruppo, conto, sottoconto, anno, indbil, 1);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:  //chiave 4: normali ripartizioni batch
 | 
						|
    {
 | 
						|
      const TString80 codcosto = parametro.get(1);
 | 
						|
      const TString80 commessa = parametro.get(2);
 | 
						|
      const TString16 fase = parametro.get(3);
 | 
						|
      const int anno = parametro.get_int(4);
 | 
						|
      const int indbil = parametro.get_int(5);
 | 
						|
      const int classe_mov = parametro.get_int(6);
 | 
						|
 | 
						|
      rip->read(codcosto, commessa, fase, anno, indbil, classe_mov);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
	if (rip->head().get_int(RIP_TIPORIP) == 1)
 | 
						|
	{
 | 
						|
		bool some_value = false;
 | 
						|
		const int items = rip->rows();
 | 
						|
 | 
						|
		for (int i = 1; i <= items; i++)
 | 
						|
		{
 | 
						|
			TRectype & rec = (*rip)[i];
 | 
						|
			TAnal_bill bill;
 | 
						|
 | 
						|
			bill.set_conto(rec.get(RRIP_CODCONTO));
 | 
						|
			bill.set_costo(rec.get(RRIP_CODCOSTO));
 | 
						|
			bill.set_commessa(rec.get(RRIP_CODCMS));
 | 
						|
			bill.set_fase(rec.get(RRIP_CODFASE));
 | 
						|
 | 
						|
			const TSaldanal& s = ca_saldo(bill, _dal, _al, _saldanal_consuntivo);
 | 
						|
			TImporto val = s._ini;
 | 
						|
			
 | 
						|
			val.normalize('D');
 | 
						|
			some_value |= !val.valore().is_zero();
 | 
						|
			rec.put(RRIP_RIPARTO, val.valore());
 | 
						|
		}
 | 
						|
		if (!some_value)
 | 
						|
		{
 | 
						|
			for (int i = 1; i <= items; i++)
 | 
						|
			{
 | 
						|
				TRectype& rec = (*rip)[i];
 | 
						|
				rec.put(RRIP_RIPARTO, 1);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
  return (TObject*)rip;
 | 
						|
}
 | 
						|
 | 
						|
void TCache_ripartizioni::set_esercizio(const int codes)
 | 
						|
{
 | 
						|
  if (codes != _codes)
 | 
						|
  {
 | 
						|
	  TEsercizi_contabili e;
 | 
						|
	  const TEsercizio& esc = e.esercizio(codes);
 | 
						|
    _codes = codes;
 | 
						|
    _dal = esc.inizio();		
 | 
						|
    _al = esc.fine();		
 | 
						|
	  destroy();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const TAnal_ripartizioni_batch& TCache_ripartizioni::righe(const char* costo, const char* commessa, const char* fase,
 | 
						|
                                                           const int annoes, const int indbil, const char tipomov)
 | 
						|
{
 | 
						|
  //classi di movimento: se preventivi 2, se normali 1
 | 
						|
  int classe_movimento;
 | 
						|
  if (tipomov == 'P' || tipomov == 'V')
 | 
						|
    classe_movimento = 2;
 | 
						|
  else
 | 
						|
    classe_movimento = 1;
 | 
						|
 | 
						|
  TToken_string parametro;
 | 
						|
  parametro << "4|" << costo << '|' << commessa << '|' << fase << '|' << annoes << '|' << indbil << '|' << classe_movimento; //per chiave 4
 | 
						|
  return *(const TAnal_ripartizioni_batch*)objptr(parametro);
 | 
						|
}
 | 
						|
 | 
						|
const TAnal_ripartizioni_batch& TCache_ripartizioni::righe(const TBill& bill, const int annoes, const char tipomov)
 | 
						|
{
 | 
						|
  //classi di movimento: se preventivi 2, se normali 1
 | 
						|
  int classe_movimento;
 | 
						|
  if (tipomov == 'P' || tipomov == 'V')
 | 
						|
    classe_movimento = 2;
 | 
						|
  else
 | 
						|
    classe_movimento = 1;
 | 
						|
 | 
						|
  TToken_string parametro;
 | 
						|
  parametro << "3|" << bill.gruppo() << '|' << bill.conto() << '|' << bill.sottoconto() << '|' 
 | 
						|
            << annoes << '|' << bill.indicatore_bilancio() << '|' << classe_movimento;  //per chiave 3
 | 
						|
  return *(const TAnal_ripartizioni_batch*)objptr(parametro);
 | 
						|
}
 | 
						|
 | 
						|
const TAnal_ripartizioni_batch& TCache_ripartizioni::righe(const TAnal_bill& bill, const int annoes, const int indbil, 
 | 
						|
                                                           const char tipomov)
 | 
						|
{
 | 
						|
  TConfig& config = ca_config();
 | 
						|
  const bool use_pdcc = config.get_bool("UsePdcc");    //usa il piano dei conti contabile
 | 
						|
  if (use_pdcc)
 | 
						|
  {
 | 
						|
    const TString& contone = bill.conto();
 | 
						|
    const int gr = atoi(contone.mid(0,3));
 | 
						|
    const int co = atoi(contone.mid(3,3));
 | 
						|
    const long so = atol(contone.mid(6,6));
 | 
						|
    const TBill zio(gr, co, so);
 | 
						|
    const TAnal_ripartizioni_batch& rb = righe(zio, annoes, tipomov);
 | 
						|
    //ha trovato una ripartizione?
 | 
						|
    if (rb.rows() > 0)
 | 
						|
      return rb;
 | 
						|
 | 
						|
  }
 | 
						|
  //se non riesce a trovare una ripartizione per conto (chiave 3, tipo 'P') prova con la chiave 4 (cdc/cms/fase, tipo 'B')
 | 
						|
  return righe(bill.costo(), bill.commessa(), bill.fase(), annoes, indbil, tipomov);
 | 
						|
}
 | 
						|
 | 
						|
const TAnal_ripartizioni_batch& TCache_ripartizioni::righe_interattive(const TBill& bill, const int annoes, const char tipomov)
 | 
						|
{
 | 
						|
    //classi di movimento: se preventivi 2, se normali 1
 | 
						|
  int classe_movimento;
 | 
						|
  if (tipomov == 'P' || tipomov == 'V')
 | 
						|
    classe_movimento = 2;
 | 
						|
  else
 | 
						|
    classe_movimento = 1; //sempre questo per cacnv
 | 
						|
 | 
						|
  TToken_string parametro;
 | 
						|
  parametro << "5|" << bill.gruppo() << '|' << bill.conto() << '|' << bill.sottoconto() << '|' 
 | 
						|
            << annoes << '|' << bill.indicatore_bilancio() << '|' << classe_movimento;  //per chiave 5
 | 
						|
  return *(const TAnal_ripartizioni_batch*)objptr(parametro);
 | 
						|
}
 | 
						|
 | 
						|
TCache_ripartizioni::TCache_ripartizioni()
 | 
						|
{
 | 
						|
  _codes = 0;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//  Metodi per la ricompattazione delle righe ripartite
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
bool ca_can_merge_rows(const TRectype& compact_rec, const TRectype& rec)
 | 
						|
{
 | 
						|
  return compact_rec.get(RMOVANA_CODCCORI)   == rec.get(RMOVANA_CODCCORI)   &&
 | 
						|
         compact_rec.get(RMOVANA_CODCMSORI)  == rec.get(RMOVANA_CODCMSORI)  &&
 | 
						|
         compact_rec.get(RMOVANA_CODFASEORI) == rec.get(RMOVANA_CODFASEORI) &&
 | 
						|
         compact_rec.get(RMOVANA_CODCONTORI) == rec.get(RMOVANA_CODCONTORI);
 | 
						|
}
 | 
						|
 | 
						|
bool ca_ori_present(const TRectype& rec)
 | 
						|
{
 | 
						|
  return (rec.get(RMOVANA_CODCCORI).not_empty() || rec.get(RMOVANA_CODCMSORI).not_empty() ||
 | 
						|
    rec.get(RMOVANA_CODFASEORI).not_empty() || rec.get(RMOVANA_CODCONTORI).not_empty());
 | 
						|
}
 | 
						|
 | 
						|
void ca_taglia_campo(TRectype& src, const char* campo_src, TRectype& dst, const char* campo_dst)
 | 
						|
{
 | 
						|
  ca_copia_campo(src, campo_src, dst, campo_dst);
 | 
						|
  src.zero(campo_src);
 | 
						|
}
 | 
						|
 | 
						|
void ca_copia_campo(const TRectype& src, const char* campo_src, TRectype& dst, const char* campo_dst)
 | 
						|
{
 | 
						|
  const TString& valore = src.get(campo_src);
 | 
						|
  if (!valore.blank())
 | 
						|
    dst.put(campo_dst, valore);
 | 
						|
}
 | 
						|
 | 
						|
bool ca_implode_rows(const TRecord_array& input_rows, TRecord_array& compact_rows)
 | 
						|
{
 | 
						|
  bool implosion_done = false;
 | 
						|
  const int last_row = input_rows.last_row();
 | 
						|
  for (int r = input_rows.first_row(); r > 0 && r <= last_row; r = input_rows.succ_row(r))
 | 
						|
  {
 | 
						|
    const TRectype& rec = input_rows.row(r);  //record originale
 | 
						|
    //se esiste almeno un campo origine compilato puo' implodere, senno' lascia perdere
 | 
						|
    if (ca_ori_present(rec))
 | 
						|
    {
 | 
						|
      //controlla se e' un pareggio e non una ripartizione
 | 
						|
      if (rec.get(RMOVANA_CODCONTORI).blank())
 | 
						|
        continue;
 | 
						|
 | 
						|
      int i = 0;
 | 
						|
      for (i = compact_rows.rows(); i > 0; i--) //giro sulle righe gia' compattate per scoprire se
 | 
						|
      {                                         //il nostro record esiste gia' o e' da aggiungere
 | 
						|
        const TRectype& nuovo_rec = compact_rows.row(i);  //
 | 
						|
        if (ca_can_merge_rows(nuovo_rec, rec)) //se esiste gia'...
 | 
						|
          break;
 | 
						|
      }
 | 
						|
      if (i > 0)  //...aggiunge solo importo e sezione...
 | 
						|
      {
 | 
						|
        const TImporto imp_rec(rec.get_char(RMOVANA_SEZIONE), rec.get_real(RMOVANA_IMPORTO));
 | 
						|
        TRectype& compact_rec = compact_rows.row(i, false);  //record originale
 | 
						|
      
 | 
						|
        TImporto imp_orig(compact_rec.get_char(RMOVANA_SEZIONE), compact_rec.get_real(RMOVANA_IMPORTO));
 | 
						|
        imp_orig += imp_rec;
 | 
						|
        imp_orig.normalize();
 | 
						|
        compact_rec.put(RMOVANA_SEZIONE, imp_orig.sezione());
 | 
						|
        compact_rec.put(RMOVANA_IMPORTO, imp_orig.valore());
 | 
						|
      }
 | 
						|
      else  //...senno' aggiunge direttamente tutta la riga
 | 
						|
      {
 | 
						|
        TRectype* newrec = new TRectype(rec); //record destinazione
 | 
						|
        newrec->put(RMOVANA_NUMRIG, compact_rows.rows() + 1);
 | 
						|
        compact_rows.add_row(newrec);
 | 
						|
      }
 | 
						|
      implosion_done = true;  //ha imploso almeno 1 riga!!!
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      TRectype* newrec = new TRectype(rec);
 | 
						|
      newrec->put(RMOVANA_NUMRIG, compact_rows.rows() + 1);
 | 
						|
      compact_rows.add_row(newrec);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //ripristina i campi originali sul record di destinazione
 | 
						|
  for (int k = 1; k <= compact_rows.rows(); k++)
 | 
						|
  {
 | 
						|
    TRectype& compact_rec = compact_rows.row(k, false);
 | 
						|
    if (ca_ori_present(compact_rec))
 | 
						|
    {
 | 
						|
      ca_taglia_campo(compact_rec, RMOVANA_CODCCORI,   compact_rec, RMOVANA_CODCCOSTO);
 | 
						|
      ca_taglia_campo(compact_rec, RMOVANA_CODCMSORI,  compact_rec, RMOVANA_CODCMS);
 | 
						|
      ca_taglia_campo(compact_rec, RMOVANA_CODFASEORI, compact_rec, RMOVANA_CODFASE);
 | 
						|
      ca_taglia_campo(compact_rec, RMOVANA_CODCONTORI, compact_rec, RMOVANA_CODCONTO);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return implosion_done;
 | 
						|
}
 |