Files correlati : batbsta.msk batbiva.msk Ricompilazione Demo : [ ] Commento : Aggiunti alla tabella stata i codici ISTAT e UNICO Tolta da tabella IVA la distinzione tra beni e servizi git-svn-id: svn://10.65.10.50/branches/R_10_00@22531 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			717 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			717 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <applicat.h>
 | 
						|
#include <assoc.h>
 | 
						|
#include <automask.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <config.h>
 | 
						|
#include <dongle.h>
 | 
						|
#include <netsock.h>
 | 
						|
#include <odbcrset.h>
 | 
						|
#include <progind.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <xml.h>
 | 
						|
 | 
						|
#include "ba2800a.h"
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const TString& smart_trim(const TString& str, int len)
 | 
						|
{
 | 
						|
  TString& tmp = get_tmp_string();
 | 
						|
  tmp = str;
 | 
						|
  tmp.trim();
 | 
						|
  if (tmp.len() > len)
 | 
						|
  {
 | 
						|
    TParagraph_string p(tmp, len);
 | 
						|
    tmp = p.get();
 | 
						|
  }
 | 
						|
  return tmp;
 | 
						|
}
 | 
						|
 | 
						|
int smart_cmp(const char* s1, const char* s2)
 | 
						|
{
 | 
						|
  if (s1 == NULL || *s1 <= ' ') s1 = "";
 | 
						|
  if (s2 == NULL || *s2 <= ' ') s2 = "";
 | 
						|
  if (isdigit(*s1) && isdigit(*s2))
 | 
						|
    return atoi(s1) - atoi(s2);
 | 
						|
 | 
						|
  return xvt_str_compare_ignoring_case(s1, s2);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////a
 | 
						|
// TOEM_cache
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TOEM_cache
 | 
						|
{
 | 
						|
public:
 | 
						|
  int Agente2OEM(int agente) const;
 | 
						|
  TOEM_cache();
 | 
						|
};
 | 
						|
 | 
						|
// Trasforma un codice OEM del DB in quello di oem.ini
 | 
						|
int TOEM_cache::Agente2OEM(int agente) const
 | 
						|
{
 | 
						|
  int oem = -1;
 | 
						|
  switch (agente)
 | 
						|
  {
 | 
						|
  case 1: // Administrator
 | 
						|
  case 2: oem = 0; break;
 | 
						|
  case 3: oem = 1; break;
 | 
						|
  case 4: oem = 3; break;
 | 
						|
  case 5: oem = 6; break;
 | 
						|
  case 6: oem = 5; break;
 | 
						|
  case 7: oem = 7; break;
 | 
						|
  case 8: oem = 8; break;
 | 
						|
  default: break;
 | 
						|
  }
 | 
						|
  return oem;
 | 
						|
}
 | 
						|
 | 
						|
// Carica la lista di tutti gli OEM dal file setup/oem.ini
 | 
						|
TOEM_cache::TOEM_cache()
 | 
						|
{ }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Tdnist_full
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class Tdnist_full
 | 
						|
{
 | 
						|
  TArray _chiavi;
 | 
						|
 | 
						|
public:
 | 
						|
  void set(int key, const char* var, const TString& value);
 | 
						|
  const TString& get(int key, const char* var) const;
 | 
						|
  int last() const { return _chiavi.last(); }
 | 
						|
  bool exists(int key) const { return _chiavi.objptr(key) != NULL; }
 | 
						|
 | 
						|
  bool load();
 | 
						|
  bool save() const;
 | 
						|
};
 | 
						|
 | 
						|
const char* const DNINST_ZIP = "setup/dninst.zip";
 | 
						|
const char* const DNINST_TXT = "setup/dninst.txt";
 | 
						|
 | 
						|
void Tdnist_full::set(int key, const char* var, const TString& value)
 | 
						|
{
 | 
						|
  CHECKD(key > 0, "Invalid key ", key);
 | 
						|
  TAssoc_array* info = (TAssoc_array*)_chiavi.objptr(key);
 | 
						|
  if (info == NULL)
 | 
						|
  {
 | 
						|
    info = new TAssoc_array;
 | 
						|
    _chiavi.add(info, key);
 | 
						|
  }
 | 
						|
  if (value.full())
 | 
						|
    info->add(var, value, true);
 | 
						|
  else
 | 
						|
    info->remove(var);
 | 
						|
}
 | 
						|
 | 
						|
const TString& Tdnist_full::get(int key, const char* var) const
 | 
						|
{
 | 
						|
  TAssoc_array* info = (TAssoc_array*)_chiavi.objptr(key);
 | 
						|
  if (info == NULL)
 | 
						|
    return EMPTY_STRING;
 | 
						|
  const TString* val = (const TString*)info->objptr(var);
 | 
						|
  return val ? *val : EMPTY_STRING;
 | 
						|
}
 | 
						|
 | 
						|
// Decodifica l'intero dninst.zip in memoria
 | 
						|
bool Tdnist_full::load()
 | 
						|
{
 | 
						|
  _chiavi.destroy();
 | 
						|
 | 
						|
  TFilename txt = DNINST_TXT;
 | 
						|
  Tdninst dninst;
 | 
						|
  if (dninst.decode(txt)) 
 | 
						|
  {
 | 
						|
    TScanner s(txt);
 | 
						|
    const int anno = atoi(s.line());
 | 
						|
    int key = 0;
 | 
						|
    TString16 var;
 | 
						|
    TString256 val;
 | 
						|
    while (s.good())
 | 
						|
    {
 | 
						|
      TString& line = s.line();
 | 
						|
      if (line[0] == '[')
 | 
						|
      {
 | 
						|
        line.strip("[]");
 | 
						|
        key = atoi(line);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (key > 0)
 | 
						|
        {
 | 
						|
          const int equal = line.find('=');
 | 
						|
          if (equal > 0)
 | 
						|
          {
 | 
						|
            var = line.left(equal); var.trim();
 | 
						|
            val = line.mid(equal+1); val.strip("\""); val.trim();
 | 
						|
            set(key, var, val);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    cantread_box(DNINST_ZIP);
 | 
						|
  
 | 
						|
  return !_chiavi.empty();
 | 
						|
}
 | 
						|
 | 
						|
bool Tdnist_full::save() const
 | 
						|
{
 | 
						|
  Tdninst dninst;
 | 
						|
  bool done = dninst.ok();
 | 
						|
 | 
						|
  if (done)
 | 
						|
  {
 | 
						|
    ofstream out(DNINST_TXT);
 | 
						|
    out << dninst.assist_year() << endl;
 | 
						|
    FOR_EACH_ARRAY_ITEM(_chiavi, key, obj)
 | 
						|
    {
 | 
						|
      out << '[' << key << ']' << endl;
 | 
						|
      TAssoc_array& info = (TAssoc_array&)*obj;
 | 
						|
      FOR_EACH_ASSOC_OBJECT(info, o, k, i)
 | 
						|
        out << k << '=' << *i << endl;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (done)
 | 
						|
  {
 | 
						|
    done = dninst.encode(DNINST_TXT);
 | 
						|
#ifdef DBG
 | 
						|
    fcopy(DNINST_TXT, "../setup/dninst.txt");
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  return done;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Tdnist_mask
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
static int _c_key, _c_oem, _c_owner, _c_suspend, _c_killed;
 | 
						|
static int _c_dboem, _c_dbowner, _c_dbsuspend, _c_dbkilled;
 | 
						|
static int _c_xmloem, _c_xmlowner, _c_xmlaccess;
 | 
						|
 | 
						|
class Tdnist_mask : public TAutomask
 | 
						|
{
 | 
						|
  TOEM_cache _oem;
 | 
						|
  Tdnist_full _dninst;
 | 
						|
 | 
						|
private:
 | 
						|
  static int dongle_compare(const TSortable& o1, const TSortable& o2, void* jolly);
 | 
						|
 | 
						|
  const TString& remote_dninst() const;
 | 
						|
 | 
						|
  void load_dninst(TString_array& a);
 | 
						|
  bool load_odbc(TString_array& a) const;
 | 
						|
  bool load_xml(TString_array& a) const;
 | 
						|
  TToken_string& find_or_create_line(TString_array& a, int key) const;
 | 
						|
 | 
						|
protected:
 | 
						|
  void fill_sheet();
 | 
						|
  void merge_sheet();
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
 | 
						|
public:
 | 
						|
  Tdnist_mask();
 | 
						|
};
 | 
						|
 | 
						|
int Tdnist_mask::dongle_compare(const TSortable& o1, const TSortable& o2, void* jolly)
 | 
						|
{
 | 
						|
  TToken_string& d1 = (TToken_string&)o1;
 | 
						|
  TToken_string& d2 = (TToken_string&)o2;
 | 
						|
  const int sort = *(int*)jolly;
 | 
						|
 | 
						|
  if (sort == 1)
 | 
						|
  {
 | 
						|
    const char* o1 = d1.get(_c_oem); 
 | 
						|
    if (o1 == NULL || *o1 <= ' ')
 | 
						|
      o1 = d1.get(_c_dboem); 
 | 
						|
    const char* o2 = d2.get(_c_oem); 
 | 
						|
    if (o2 == NULL || *o2 <= ' ')
 | 
						|
      o2 = d2.get(_c_dboem); 
 | 
						|
    const int cmp = smart_cmp(o1, o2);
 | 
						|
    if (cmp != 0)
 | 
						|
      return cmp;
 | 
						|
  }
 | 
						|
  if (sort >= 1)
 | 
						|
  {
 | 
						|
    const char* o1 = d1.get(_c_owner); 
 | 
						|
    if (o1 == NULL || *o1 <= ' ')
 | 
						|
      o1 = d1.get(_c_dbowner); 
 | 
						|
    const char* o2 = d2.get(_c_owner); 
 | 
						|
    if (o2 == NULL || *o2 <= ' ')
 | 
						|
      o2 = d2.get(_c_dbowner); 
 | 
						|
    const int cmp = smart_cmp(o1, o2);
 | 
						|
    if (cmp != 0)
 | 
						|
      return cmp;
 | 
						|
  }
 | 
						|
 | 
						|
  return atoi(d1) - atoi(d2);
 | 
						|
}
 | 
						|
 | 
						|
const TString& Tdnist_mask::remote_dninst() const
 | 
						|
{
 | 
						|
  TString& path = get_tmp_string();
 | 
						|
  if (get_bool(F_DNINST_ON))
 | 
						|
  {
 | 
						|
    path = get(F_DNINST); path.lower();
 | 
						|
    if (!path.ends_with(DNINST_ZIP))
 | 
						|
      path << "/" << DNINST_ZIP;
 | 
						|
  }
 | 
						|
  return path;
 | 
						|
}
 | 
						|
 | 
						|
void Tdnist_mask::load_dninst(TString_array& a)
 | 
						|
{
 | 
						|
  _dninst.load();
 | 
						|
 | 
						|
  const int last_key = _dninst.last();
 | 
						|
  TToken_string str;
 | 
						|
  for (int key = 1; key <= last_key; key++) if (_dninst.exists(key))
 | 
						|
  {
 | 
						|
    str.cut(0) << key;
 | 
						|
    str.add(_dninst.get(key, "OEM"), _c_oem);
 | 
						|
    str.add(smart_trim(_dninst.get(key, "Owner"), 50), _c_owner);
 | 
						|
    str.add(_dninst.get(key, "MustCall"), _c_suspend);
 | 
						|
    str.add(_dninst.get(key, "*"), _c_killed);
 | 
						|
    a.add(str);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TToken_string& Tdnist_mask::find_or_create_line(TString_array& a, int key) const
 | 
						|
{
 | 
						|
  int mi = 0, ma = a.last();
 | 
						|
  int k = 0;
 | 
						|
  while (mi <= ma)
 | 
						|
  {
 | 
						|
    const int me = (mi+ma)/2;
 | 
						|
    k = a.row(me).get_int(0);
 | 
						|
    if (k == key) 
 | 
						|
      return a.row(me);
 | 
						|
    if (k < key)
 | 
						|
      mi = me+1;
 | 
						|
    else
 | 
						|
      ma = me-1;
 | 
						|
  }
 | 
						|
  while (mi < a.items() && key > a.row(mi).get_int(0))
 | 
						|
    mi++;
 | 
						|
  TToken_string* str = new TToken_string;
 | 
						|
  str->add(key);
 | 
						|
  a.insert(str, mi);
 | 
						|
  return *str;
 | 
						|
}
 | 
						|
 | 
						|
bool Tdnist_mask::load_odbc(TString_array& a) const
 | 
						|
{
 | 
						|
  if (!get_bool(F_DSN_ON))
 | 
						|
    return false;
 | 
						|
 | 
						|
  TString query;
 | 
						|
  query << "ODBC(" << get(F_DSN) << ")\n"
 | 
						|
        << "SELECT chiavette.codice AS Chiave, Agente, RagioneSociale, DataDisattivazione\n"
 | 
						|
        << "FROM chiavette,clienti WHERE chiavette.cliente=clienti.codice\n" 
 | 
						|
        << "ORDER BY Chiave";
 | 
						|
 | 
						|
  TODBC_recordset att(query);
 | 
						|
  TProgind pi(att.items(), get(F_DSN));
 | 
						|
  for (bool ok = att.move_first(); ok; ok = att.move_next())
 | 
						|
  {
 | 
						|
    if (!pi.addstatus(1)) break;
 | 
						|
    const int key = att.get("Chiave").as_int();
 | 
						|
 | 
						|
    if (key > 0)
 | 
						|
    {
 | 
						|
      TToken_string& r = find_or_create_line(a, key);
 | 
						|
      const int agente = att.get("Agente").as_int();
 | 
						|
      r.add(_oem.Agente2OEM(agente), _c_dboem);
 | 
						|
      r.add(smart_trim(att.get("RagioneSociale").as_string(), 50), _c_dbowner);
 | 
						|
 | 
						|
      const TString& kill = att.get("DataDisattivazione").as_string();
 | 
						|
      if (kill.full() && kill.len() == 10)
 | 
						|
      {
 | 
						|
        const TString& stato = att.get("Stato").as_string();
 | 
						|
        switch (stato[0])
 | 
						|
        {
 | 
						|
        case 'D': r.add(kill, _c_dbkilled); break; // Disdetto
 | 
						|
        case 'S': r.add(kill, _c_dbsuspend); break; // Sospeso
 | 
						|
        default: break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return !att.empty();
 | 
						|
}
 | 
						|
 | 
						|
static bool XmlScanner(TXmlItem& item, long jolly)
 | 
						|
{
 | 
						|
  TToken_string& row = *(TToken_string*)jolly;
 | 
						|
  if (item.GetTag() == "firm")
 | 
						|
  {
 | 
						|
    if (item.GetBoolAttr("Current"))
 | 
						|
      row.add(item.GetAttr("RAGSOC"), _c_xmlowner);
 | 
						|
  } else
 | 
						|
  if (item.GetTag() == "dongle")
 | 
						|
  {
 | 
						|
    row.add(item.GetAttr("OEM"), _c_xmloem);
 | 
						|
  } else
 | 
						|
  if (item.GetTag() == "module")
 | 
						|
  {
 | 
						|
    const TDate date_new = item.GetAttr("Date");
 | 
						|
    const TDate date_old = row.get(_c_xmlaccess);
 | 
						|
    if (date_new > date_old)
 | 
						|
      row.add(date_new, _c_xmlaccess);
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Tdnist_mask::load_xml(TString_array& a) const
 | 
						|
{
 | 
						|
  if (!get_bool(F_FTP_ON))
 | 
						|
    return false;
 | 
						|
 | 
						|
  TFilename path = get(F_FTP);
 | 
						|
  if (!path.ends_with(".xml"))
 | 
						|
  {
 | 
						|
    if (!path.ends_with("/"))
 | 
						|
      path << '/';
 | 
						|
    path << "?????.xml";
 | 
						|
  }
 | 
						|
 | 
						|
  TString_array xml;
 | 
						|
  list_files(path, xml);
 | 
						|
 | 
						|
  TString msg; msg.format(FR("Scansione cartella %s: %d files"), (const char*)path, xml.items());
 | 
						|
  TProgind pi(xml.items(), msg);
 | 
						|
  TFilename fname;
 | 
						|
  FOR_EACH_ARRAY_ROW(xml, r, row)
 | 
						|
  {
 | 
						|
    if (!pi.addstatus(1)) break;
 | 
						|
    fname = *row;
 | 
						|
    const TString& n = fname.name_only();
 | 
						|
    const int sn = atoi(n);
 | 
						|
    if (sn > 0)
 | 
						|
    {
 | 
						|
      TToken_string& r = find_or_create_line(a, sn);
 | 
						|
      TXmlItem i; i.Load(fname);
 | 
						|
      i.ForEach(XmlScanner, (long)&r);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return !xml.empty();
 | 
						|
}
 | 
						|
 | 
						|
void Tdnist_mask::fill_sheet()
 | 
						|
{
 | 
						|
  TSheet_field& s = sfield(F_DNSHEET);
 | 
						|
  s.destroy();
 | 
						|
 | 
						|
  TString_array& a = s.rows_array();
 | 
						|
  load_dninst(a);
 | 
						|
  load_odbc(a);
 | 
						|
  load_xml(a);
 | 
						|
 | 
						|
  const int sort = get_int(F_SORT);
 | 
						|
  a.TArray::sort(dongle_compare, (void*)&sort);
 | 
						|
 | 
						|
  FOR_EACH_ARRAY_ROW(a, r, row)
 | 
						|
  {
 | 
						|
    const char* o1 = row->get(_c_owner);
 | 
						|
    const char* o2 = row->get(_c_dbowner);
 | 
						|
    const char* o3 = row->get(_c_xmlowner);
 | 
						|
 | 
						|
    if (o2 && *o2 > ' ')
 | 
						|
    {
 | 
						|
      const double cmp = xvt_str_fuzzy_compare_ignoring_case(o1, o2);
 | 
						|
      if (cmp < 0.7)
 | 
						|
      {
 | 
						|
        if (cmp == 0)
 | 
						|
          s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_dbowner);
 | 
						|
        else
 | 
						|
          s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, r, _c_dbowner);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (o3 && *o3 > ' ')
 | 
						|
    {
 | 
						|
      const char* o1 = row->get(2);
 | 
						|
      const double cmp = xvt_str_fuzzy_compare_ignoring_case(o1, o3);
 | 
						|
      if (cmp < 0.7)
 | 
						|
      {
 | 
						|
        if (cmp == 0)
 | 
						|
          s.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, r, _c_xmlowner);
 | 
						|
        else
 | 
						|
          s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, r, _c_xmlowner);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  s.force_update();
 | 
						|
 | 
						|
  enable(DLG_ELABORA, !s.empty());
 | 
						|
}
 | 
						|
 | 
						|
void Tdnist_mask::merge_sheet()
 | 
						|
{
 | 
						|
  TSheet_field& sheet = sfield(F_DNSHEET);
 | 
						|
 | 
						|
  TString16 killed;
 | 
						|
  TString o1, o2, o3;
 | 
						|
  TString c1, c2, c3;
 | 
						|
 | 
						|
  int changed = 0;
 | 
						|
  FOR_EACH_SHEET_ROW(sheet, r, row)
 | 
						|
  {
 | 
						|
    const int key = row->get_int(_c_key);
 | 
						|
    c1 = row->get(_c_owner);
 | 
						|
    c2 = row->get(_c_dbowner);
 | 
						|
    c3 = row->get(_c_xmlowner);
 | 
						|
    if (c1.blank())
 | 
						|
    {
 | 
						|
      if (c2.full())
 | 
						|
      {
 | 
						|
        c1 = c2; 
 | 
						|
        o1 = row->get(_c_dboem);
 | 
						|
      } else
 | 
						|
      if (c3.full())
 | 
						|
      {
 | 
						|
        c1 = c3;
 | 
						|
        o1 = row->get(_c_xmloem);
 | 
						|
      }
 | 
						|
      if (c1.full())
 | 
						|
      {
 | 
						|
        row->add(o1, _c_oem);
 | 
						|
        row->add(c1, _c_owner);
 | 
						|
        changed++;
 | 
						|
      }
 | 
						|
    } 
 | 
						|
    else
 | 
						|
    {
 | 
						|
      o1 = row->get(_c_oem);
 | 
						|
      if (o1.blank())
 | 
						|
      {
 | 
						|
        o2 = row->get(_c_dboem);
 | 
						|
        if (o2.full())
 | 
						|
        {
 | 
						|
          row->add(o2, _c_oem);
 | 
						|
          changed++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    killed = row->get(_c_killed);
 | 
						|
    if (killed.blank())
 | 
						|
    {
 | 
						|
      killed = row->get(_c_dbkilled);
 | 
						|
      if (killed.full())
 | 
						|
        row->add(killed, _c_killed);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  sheet.force_update();
 | 
						|
  TString msg; msg.format(FR("Sono state aggiornate %d chiavi"), changed);
 | 
						|
  xvt_dm_popup_message(msg);
 | 
						|
}
 | 
						|
 | 
						|
bool Tdnist_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{ 
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case DLG_RECALC:
 | 
						|
    if (e == fe_button && check_fields())
 | 
						|
    {
 | 
						|
      save_profile();
 | 
						|
 | 
						|
      const TString& n = remote_dninst();
 | 
						|
      if (n.full())
 | 
						|
      {
 | 
						|
        TFilename tmp; tmp.tempdir(); tmp.add("dninst.zip");
 | 
						|
        if (fcopy(n, tmp, false, true) && fsize(tmp) > 0)
 | 
						|
        {
 | 
						|
          fcopy(tmp, DNINST_ZIP);
 | 
						|
          tmp.fremove();
 | 
						|
        }
 | 
						|
        else
 | 
						|
          cantread_box(n);
 | 
						|
      }
 | 
						|
      fill_sheet();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_ELABORA:
 | 
						|
    if (e == fe_button && yesno_box(TR("Riporare sul DNINST tutte le chiavi presenti solo su DB?")))
 | 
						|
    {
 | 
						|
      merge_sheet();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_SAVEREC:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TSheet_field& sheet = sfield(F_DNSHEET);
 | 
						|
      TString str;
 | 
						|
      FOR_EACH_SHEET_ROW(sheet, r, row)
 | 
						|
      {
 | 
						|
        const int key = row->get_int(0);
 | 
						|
        str = row->get(_c_oem);
 | 
						|
        _dninst.set(key, "OEM", str.trim());
 | 
						|
        str = row->get(_c_owner);
 | 
						|
        _dninst.set(key, "Owner", str.trim());
 | 
						|
        str = row->get(_c_suspend);
 | 
						|
        _dninst.set(key, "MustCall", str.trim());
 | 
						|
        str = row->get(_c_killed);
 | 
						|
        _dninst.set(key, "*", str.trim());
 | 
						|
      }
 | 
						|
      if (_dninst.save())
 | 
						|
      {
 | 
						|
        fill_sheet();
 | 
						|
        const TString& ftp = remote_dninst();
 | 
						|
        if (ftp != DNINST_ZIP && ftp.starts_with("ftp://") 
 | 
						|
                              && yesno_box(FR("Copiare il DNINST locale in %s?"), (const char*)ftp))
 | 
						|
        {
 | 
						|
          int at = ftp.find('@', 6); if (at < 0) at = 5;
 | 
						|
          int slash = ftp.find('/', at+1);
 | 
						|
          const TString& server = ftp.sub(at+1, slash);
 | 
						|
 | 
						|
          bool sent = false;
 | 
						|
          TSocketClient aga;
 | 
						|
          CONNID id = aga.QueryConnection("21", server);
 | 
						|
          if (id > 0)
 | 
						|
          {
 | 
						|
            TString16 user = "guastalla", password = "tk0nmo4q3";
 | 
						|
            const int colon = ftp.find(':', 6);
 | 
						|
            if (colon > 6 && colon < at)
 | 
						|
            {
 | 
						|
              user = ftp.sub(6, colon);
 | 
						|
              password = ftp.sub(colon+1, at);
 | 
						|
            }
 | 
						|
            sent = aga.FtpSendFile(id, ftp.mid(slash), DNINST_ZIP, user, password);
 | 
						|
            aga.RemoveConnection(id);
 | 
						|
          }
 | 
						|
          if (!sent)
 | 
						|
            cantwrite_box(ftp);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_DNINST_ON:
 | 
						|
    if (e == fe_init)
 | 
						|
    {
 | 
						|
      if (field(F_DNINST).empty())
 | 
						|
        set(F_DNINST, "ftp://guastalla:tk0nmo4q3@www.aga.it/release/v_10.0/program");
 | 
						|
      if (field(F_FTP).empty())
 | 
						|
        set(F_FTP, "ftp://attivazioni:viagra@www.aga.it");
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_DSN:
 | 
						|
    if (e == fe_button && !o.empty())
 | 
						|
    {
 | 
						|
      TString query;
 | 
						|
      query << "ODBC(" << o.get() << ")\n"
 | 
						|
            << "SELECT * FROM chiavette,clienti WHERE chiavette.cliente=clienti.codice\n" 
 | 
						|
            << "ORDER BY ";
 | 
						|
      switch(get_int(F_SORT))
 | 
						|
      {
 | 
						|
      case  1: query << "agente,RagioneSociale,chiavette.codice"; break;
 | 
						|
      case  2: query << "RagioneSociale,chiavette.codice"; break;
 | 
						|
      default: query << "chiavette.codice"; break;
 | 
						|
      }
 | 
						|
 | 
						|
      TODBC_recordset att(query);
 | 
						|
      if (att.move_first())
 | 
						|
      {
 | 
						|
        TRecordset_sheet sheet(att, TR("Chiavi"),0x10);
 | 
						|
        sheet.run();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_SORT:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      TSheet_field& s = sfield(F_DNSHEET);
 | 
						|
      const int sort = get_int(F_SORT);
 | 
						|
      s.rows_array().TArray::sort(dongle_compare, (void*)&sort);
 | 
						|
      s.force_update();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_DNSHEET:
 | 
						|
    if (e == se_query_add || e == se_query_del)
 | 
						|
      return false;
 | 
						|
    break;
 | 
						|
  case F_SUSPEND:
 | 
						|
  case F_KILLED:
 | 
						|
    if (e == fe_magic)
 | 
						|
    {
 | 
						|
      const TDate oggi(TODAY);
 | 
						|
      o.set(oggi.string());
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default: break;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
Tdnist_mask::Tdnist_mask() : TAutomask("ba2800a") 
 | 
						|
{ 
 | 
						|
  const TSheet_field& s = sfield(F_DNSHEET);
 | 
						|
  TMask& m = s.sheet_mask();
 | 
						|
 | 
						|
  _c_key      = s.cid2index(F_NUMBER);
 | 
						|
  _c_oem      = s.cid2index(F_OEM);
 | 
						|
  _c_owner    = s.cid2index(F_OWNER);
 | 
						|
  _c_suspend  = s.cid2index(F_SUSPEND);
 | 
						|
  _c_killed   = s.cid2index(F_KILLED);
 | 
						|
  _c_dboem    = s.cid2index(F_DBOEM);
 | 
						|
  _c_dbowner  = s.cid2index(F_DBOWNER);
 | 
						|
  _c_dbsuspend= s.cid2index(F_DBSUSPEND);
 | 
						|
  _c_dbkilled = s.cid2index(F_DBKILLED);
 | 
						|
  _c_xmloem   = s.cid2index(F_ATOEM);
 | 
						|
  _c_xmlowner = s.cid2index(F_ATOWNER);
 | 
						|
  _c_xmlaccess= s.cid2index(F_ATACCESS);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Tdninst_manager
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class Tdninst_manager : public TSkeleton_application
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual bool use_files() const { return false; }
 | 
						|
  virtual bool create();
 | 
						|
  virtual void main_loop();
 | 
						|
};
 | 
						|
 | 
						|
bool Tdninst_manager::create()
 | 
						|
{
 | 
						|
  const word n = dongle().number();
 | 
						|
  // 8453 = Ilaria; 8517 = Sara; 8578 = Monica
 | 
						|
  if (n != 8453 && n != 8517 && !is_power_station())
 | 
						|
    return error_box(TR("Postazione non abilitata"));
 | 
						|
 | 
						|
  if (user() != dongle().administrator())
 | 
						|
    return error_box(TR("Utente non abilitato"));
 | 
						|
 | 
						|
  TSheet_field::set_line_number_width(4); // Numero di chiavette ~ 1000
 | 
						|
 | 
						|
  return TSkeleton_application::create();
 | 
						|
}
 | 
						|
 | 
						|
void Tdninst_manager::main_loop()
 | 
						|
{
 | 
						|
  Tdnist_mask m;
 | 
						|
  m.run();
 | 
						|
}
 | 
						|
 | 
						|
int ba2800(int argc, char* argv[])
 | 
						|
{                                             
 | 
						|
  Tdninst_manager a;
 | 
						|
  a.run(argc, argv, TR("Gestione attivazioni"));
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 |