Patch level :
Files correlati : db0.exe Ricompilazione Demo : [ ] Commento : Gestione interattiva distinta base git-svn-id: svn://10.65.10.50/trunk@6849 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
719ef4a1fb
commit
41d3f8ab37
757
db/db0100.cpp
757
db/db0100.cpp
@ -1,13 +1,12 @@
|
||||
#include <automask.h>
|
||||
#include <expr.h>
|
||||
#include <recarray.h>
|
||||
#include <relapp.h>
|
||||
#include <tabutil.h>
|
||||
#include <tree.h>
|
||||
#include <urldefid.h>
|
||||
#include "dblib.h"
|
||||
|
||||
#include <automask.h>
|
||||
#include <relapp.h>
|
||||
#include <sheet.h>
|
||||
#include <tabutil.h>
|
||||
|
||||
#include "../mg/mglib.h"
|
||||
#include "../mg/anamag.h"
|
||||
#include "../mg/umart.h"
|
||||
|
||||
#include "db0100a.h"
|
||||
|
||||
@ -15,12 +14,18 @@
|
||||
// Funzione di richiesta stringa che andra' in libreria
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
#include <defmask.h>
|
||||
|
||||
bool query_string(const char* prompt, TString& str, int width = 50, const char* flags= "")
|
||||
{
|
||||
int maskwidth = width+2;
|
||||
if (maskwidth < 26) maskwidth = 26;
|
||||
if (maskwidth < 26)
|
||||
maskwidth = 26;
|
||||
if (maskwidth > 78)
|
||||
maskwidth = 78;
|
||||
|
||||
TMask m(prompt, 1, maskwidth, 5);
|
||||
m.add_string(DLG_USER, 0, "", 1, 1, width, flags);
|
||||
m.add_string(DLG_USER, 0, "", 1, 1, width, flags, width > 76 ? 76 : width);
|
||||
m.add_button(DLG_CANCEL, 0, "", -12, -1, 10, 2);
|
||||
m.add_button(DLG_OK, 0, "", -22, -1, 10, 2);
|
||||
m.set(DLG_USER, str);
|
||||
@ -31,304 +36,41 @@ bool query_string(const char* prompt, TString& str, int width = 50, const char*
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_expr
|
||||
// TDistinta_sheet
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TDistinta_expr : public TExpression
|
||||
class TDistinta_sheet : public TSheet
|
||||
{
|
||||
TArray _data;
|
||||
|
||||
protected:
|
||||
virtual bool print_error(const char* msg) const;
|
||||
virtual void get_row(long n, TToken_string& row);
|
||||
virtual long get_items() const { return _data.items(); }
|
||||
|
||||
public:
|
||||
TDistinta_expr();
|
||||
virtual ~TDistinta_expr() { }
|
||||
TArray& rows_array() { return _data; }
|
||||
TDistinta_sheet();
|
||||
virtual ~TDistinta_sheet() { }
|
||||
};
|
||||
|
||||
bool TDistinta_expr::print_error(const char* msg) const
|
||||
void TDistinta_sheet::get_row(long n, TToken_string& row)
|
||||
{
|
||||
return error_box(msg);
|
||||
const TRiga_esplosione& re = (const TRiga_esplosione&)_data[int(n)];
|
||||
row.cut(0);
|
||||
row.add(re.tipo());
|
||||
row.add(re.articolo());
|
||||
row.add(re.giacenza());
|
||||
row.add(re.um());
|
||||
row.add(re.val().string(0, 5));
|
||||
row.add(re.livello());
|
||||
row.add(re.ordinamento());
|
||||
}
|
||||
|
||||
TDistinta_expr::TDistinta_expr()
|
||||
: TExpression(_numexpr, FALSE)
|
||||
TDistinta_sheet::TDistinta_sheet()
|
||||
: TSheet(-1, -1, 0, 20, "Esplosione", "Tipo|Codice@20|Giacenza@15|UM|Quantita'@18R|Liv.@R|Sort@8R")
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_tree
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TDistinta_tree : public TBidirectional_tree
|
||||
{
|
||||
TLocalisamfile* _rdist;
|
||||
TString _root;
|
||||
TToken_string _path;
|
||||
|
||||
protected:
|
||||
|
||||
TLocalisamfile& file() const;
|
||||
void add_child();
|
||||
void kill_child();
|
||||
bool is_cyclic() const;
|
||||
|
||||
virtual void node2id(const TObject* node, TString& id) const;
|
||||
|
||||
public:
|
||||
virtual bool goto_root();
|
||||
virtual bool goto_firstson();
|
||||
virtual bool goto_rbrother();
|
||||
virtual bool goto_node(const TString &id);
|
||||
virtual bool has_son() const;
|
||||
virtual bool has_rbrother() const;
|
||||
virtual bool has_root() const;
|
||||
virtual bool has_father() const;
|
||||
virtual bool has_lbrother() const;
|
||||
virtual bool goto_father();
|
||||
virtual bool goto_lbrother();
|
||||
virtual bool get_description(TString& desc) const;
|
||||
virtual TImage* image(bool selected) const;
|
||||
virtual TObject* curr_node() const;
|
||||
|
||||
bool set_root(const char* str);
|
||||
long find_node(const char* str, word flags = SCAN_PRE_ORDER);
|
||||
|
||||
TDistinta_tree();
|
||||
virtual ~TDistinta_tree();
|
||||
};
|
||||
|
||||
TLocalisamfile& TDistinta_tree::file() const
|
||||
{
|
||||
if (_rdist == NULL)
|
||||
((TDistinta_tree*)this)->_rdist = new TLocalisamfile(LF_RDIST);
|
||||
return *_rdist;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_node(const TString &id)
|
||||
{
|
||||
_path = id;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct TFind_node_data
|
||||
{
|
||||
TString _id;
|
||||
long _count;
|
||||
};
|
||||
|
||||
HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags)
|
||||
{
|
||||
if (flags == SCAN_PRE_ORDER)
|
||||
{
|
||||
TFind_node_data& data = *(TFind_node_data*)jolly;
|
||||
data._count++;
|
||||
TToken_string id; tree.curr_id(id);
|
||||
if (data._id == id.get(-2))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
long TDistinta_tree::find_node(const char* str, word flags)
|
||||
{
|
||||
if (goto_root())
|
||||
{
|
||||
TFind_node_data fnd;
|
||||
fnd._id = str;
|
||||
fnd._count = 0;
|
||||
if (scan_breadth_first(find_node_callback, &fnd, flags))
|
||||
return fnd._count;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
void TDistinta_tree::node2id(const TObject* node, TString& id) const
|
||||
{
|
||||
id = *(TToken_string*)node;
|
||||
}
|
||||
|
||||
TObject* TDistinta_tree::curr_node() const
|
||||
{
|
||||
return &((TDistinta_tree*)this)->_path;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::get_description(TString& desc) const
|
||||
{
|
||||
_path.get(-2, desc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TImage* TDistinta_tree::image(bool selected) const
|
||||
{
|
||||
TImage* img;
|
||||
if (is_cyclic())
|
||||
img = get_res_image(BMP_STOP);
|
||||
else
|
||||
img = TBidirectional_tree::image(selected);
|
||||
return img;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::set_root(const char* str)
|
||||
{
|
||||
TLocalisamfile dist(LF_DIST);
|
||||
dist.put("CODDIST", str);
|
||||
const bool ok = dist.read() == NOERR;
|
||||
if (ok)
|
||||
{
|
||||
_root = str;
|
||||
shrink_all();
|
||||
goto_root();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_root() const
|
||||
{
|
||||
return _root.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_root()
|
||||
{
|
||||
const bool ok = has_root();
|
||||
if (ok)
|
||||
_path = _root;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_cyclic() const
|
||||
{
|
||||
bool cyclic = FALSE;
|
||||
const int last = _path.items()-1;
|
||||
if (last >= 2)
|
||||
{
|
||||
TString80 mycod; _path.get(last, mycod);
|
||||
TString80 cod;
|
||||
for (int i = last-2; i >= 0; i -= 2)
|
||||
{
|
||||
_path.get(i, cod);
|
||||
if (cod == mycod)
|
||||
{
|
||||
cyclic = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cyclic;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_son() const
|
||||
{
|
||||
if (is_cyclic())
|
||||
return FALSE;
|
||||
TString80 cod; _path.get(-2, cod);
|
||||
file().put("CODDIST", cod);
|
||||
file().put("NRIG", 1);
|
||||
return file().read() == NOERR;
|
||||
}
|
||||
|
||||
|
||||
void TDistinta_tree::add_child()
|
||||
{
|
||||
_path.add(file().get("NRIG"));
|
||||
_path.add(file().get("CODCOMP"));
|
||||
}
|
||||
|
||||
void TDistinta_tree::kill_child()
|
||||
{
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
const int pipe = _path.rfind('|');
|
||||
_path.cut(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_firstson()
|
||||
{
|
||||
const bool ok = has_son();
|
||||
if (ok)
|
||||
add_child();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_rbrother() const
|
||||
{
|
||||
const int items = _path.items();
|
||||
if (items < 3)
|
||||
return FALSE;
|
||||
|
||||
TString80 str;
|
||||
_path.get(items-2, str);
|
||||
const int brother = atoi(str)+1;
|
||||
_path.get(items-3, str);
|
||||
file().put("CODDIST", str);
|
||||
file().put("NRIG", brother);
|
||||
return file().read() == NOERR;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_rbrother()
|
||||
{
|
||||
const bool ok = has_rbrother();
|
||||
if (ok)
|
||||
{
|
||||
kill_child();
|
||||
add_child();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_lbrother() const
|
||||
{
|
||||
const int items = _path.items();
|
||||
if (items < 3)
|
||||
return FALSE;
|
||||
TString80 str;
|
||||
_path.get(items-2, str);
|
||||
const int brother = atoi(str)-1;
|
||||
if (brother <= 0)
|
||||
return FALSE;
|
||||
|
||||
_path.get(items-3, str);
|
||||
file().put("CODDIST", str);
|
||||
file().put("NRIG", brother);
|
||||
return file().read() == NOERR;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_lbrother()
|
||||
{
|
||||
const bool ok = has_lbrother();
|
||||
if (ok)
|
||||
{
|
||||
kill_child();
|
||||
add_child();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_father() const
|
||||
{
|
||||
const int items = _path.items();
|
||||
return items >= 3;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_father()
|
||||
{
|
||||
const bool ok = has_father();
|
||||
if (ok)
|
||||
{
|
||||
kill_child();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
TDistinta_tree::TDistinta_tree() : _rdist(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
TDistinta_tree::~TDistinta_tree()
|
||||
{
|
||||
if (_rdist)
|
||||
delete _rdist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TQuery_mask
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -343,11 +85,28 @@ protected:
|
||||
|
||||
public:
|
||||
const TToken_string& curr() const { return _curr; }
|
||||
void restart_tree();
|
||||
|
||||
TQuery_mask(TDistinta_tree& tree);
|
||||
virtual ~TQuery_mask() { }
|
||||
};
|
||||
|
||||
void TQuery_mask::restart_tree()
|
||||
{
|
||||
_tree.restart();
|
||||
while (!_tree.is_leaf())
|
||||
{
|
||||
_tree.expand();
|
||||
_tree.goto_firstson();
|
||||
if (_tree.has_rbrother())
|
||||
break;
|
||||
}
|
||||
|
||||
TTree_field& tf = tfield(F_TREE);
|
||||
tf.win().update_thumb(0, 0);
|
||||
tf.win().force_update();
|
||||
}
|
||||
|
||||
bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
{
|
||||
switch (o.dlg())
|
||||
@ -355,8 +114,8 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
case F_CODICE:
|
||||
if (e == fe_modify)
|
||||
{
|
||||
TTree_field& tf = (TTree_field&)field(F_TREE);
|
||||
const TString& val = o.get();
|
||||
TTree_field& tf = tfield(F_TREE);
|
||||
const TCodice_articolo val = o.get();
|
||||
if (val.not_empty() && _tree.has_root())
|
||||
{
|
||||
long pos = _tree.find_node(val);
|
||||
@ -387,11 +146,21 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
}
|
||||
tf.win().force_update();
|
||||
}
|
||||
case F_SORT:
|
||||
if (e == fe_init || e == fe_modify)
|
||||
{
|
||||
int sk = atoi(o.get());
|
||||
_tree.set_sort_key(sk);
|
||||
if (e == fe_modify)
|
||||
restart_tree();
|
||||
}
|
||||
break;
|
||||
case F_TREE:
|
||||
if (e == fe_modify)
|
||||
{
|
||||
_tree.curr_id(_curr);
|
||||
set(F_CODICE, _curr.get(-2));
|
||||
TCodice_articolo code; _tree.curr_code(code);
|
||||
set(F_CODICE, code);
|
||||
}
|
||||
break;
|
||||
case DLG_SELECT:
|
||||
@ -443,6 +212,49 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
error_box("Il codice '%s' non corrisponde ad una distinta valida", (const char*)oldcode);
|
||||
}
|
||||
break;
|
||||
case F_EXPLODE:
|
||||
if (e == fe_button)
|
||||
{
|
||||
TCodice_articolo art = get(F_CODICE);
|
||||
if (art.not_empty())
|
||||
{
|
||||
_tree.set_root(art);
|
||||
restart_tree();
|
||||
}
|
||||
if (_tree.goto_root())
|
||||
{
|
||||
_tree.curr_code(art);
|
||||
TString80 caption;
|
||||
caption << "Esplosione " << art;
|
||||
|
||||
TMask m("db0100c");
|
||||
m.set_caption(caption);
|
||||
m.set(F_SORT, get(F_SORT));
|
||||
m.set(F_ARTICOLI, "X");
|
||||
m.set(F_LAVORAZIONI, "X");
|
||||
m.set(F_VIRTUALI, "X");
|
||||
if (m.run() == K_ENTER)
|
||||
{
|
||||
TDistinta_sheet a;
|
||||
a.set_caption(caption);
|
||||
int sk = m.get_int(F_SORT);
|
||||
int md = m.get_int(F_MAXDEPTH);
|
||||
int gr = m.get_int(F_GROUPMODE);
|
||||
bool mb = m.get_bool(F_MATBASE);
|
||||
bool lq = m.get_bool(F_LASTQTA);
|
||||
|
||||
TString16 fi;
|
||||
if (m.get_bool(F_ARTICOLI)) fi << 'A';
|
||||
if (m.get_bool(F_LAVORAZIONI)) fi << 'L';
|
||||
if (m.get_bool(F_VIRTUALI)) fi << 'V';
|
||||
if (fi.len() == 3) fi.cut(0);
|
||||
|
||||
_tree.explode(a.rows_array(), mb, gr, md, fi, sk, lq);
|
||||
a.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -452,7 +264,7 @@ bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
TQuery_mask::TQuery_mask(TDistinta_tree& dt)
|
||||
: TAutomask("db0100a"), _tree(dt)
|
||||
{
|
||||
TTree_field& tree = (TTree_field&)field(F_TREE);
|
||||
TTree_field& tree = tfield(F_TREE);
|
||||
tree.set_tree(&_tree);
|
||||
}
|
||||
|
||||
@ -463,50 +275,32 @@ TQuery_mask::TQuery_mask(TDistinta_tree& dt)
|
||||
class TDistinta_mask : public TAutomask
|
||||
{
|
||||
TDistinta_tree& _tree;
|
||||
TRecord_cache _mag, _lav;
|
||||
|
||||
TRecord_cache _ord;
|
||||
|
||||
bool on_distsheet_event(TOperable_field& o, TField_event e, long jolly);
|
||||
bool on_parmsheet_event(TOperable_field& o, TField_event e, long jolly);
|
||||
|
||||
protected:
|
||||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||||
bool test_row(const TToken_string& row);
|
||||
|
||||
public:
|
||||
bool is_lav(const TString& str);
|
||||
bool is_mag(const TString& str);
|
||||
|
||||
TDistinta_mask(TDistinta_tree& dt);
|
||||
virtual ~TDistinta_mask() { }
|
||||
};
|
||||
|
||||
bool TDistinta_mask::is_lav(const TString& str)
|
||||
{
|
||||
if (_lav.items() > 1000)
|
||||
_lav.destroy();
|
||||
const TString& val = _lav.get(str, "S0");
|
||||
return val.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_mask::is_mag(const TString& str)
|
||||
{
|
||||
if (_mag.items() > 1000)
|
||||
_mag.destroy();
|
||||
const TString& val = _mag.get(str, "DESCR");
|
||||
return val.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_mask::test_row(const TToken_string& row)
|
||||
{
|
||||
const TString& father = get(F_CODICE);
|
||||
const TCodice_articolo father = get(F_CODICE);
|
||||
|
||||
TString code; row.get(1, code);
|
||||
TCodice_articolo code; row.get(1, code);
|
||||
bool ok = code != father;
|
||||
if (ok && _tree.find_node(father) > 0)
|
||||
{
|
||||
TToken_string path; _tree.curr_id(path);
|
||||
for (const char* c = path.get(0); c != NULL && ok; c = path.get())
|
||||
{
|
||||
ok = code != c;
|
||||
c = path.get();
|
||||
}
|
||||
path.add(code);
|
||||
ok = !_tree.is_cyclic(path);
|
||||
}
|
||||
if (!ok)
|
||||
error_box("Il codice '%s' non puo' essere utilizzato\n"
|
||||
@ -515,7 +309,7 @@ bool TDistinta_mask::test_row(const TToken_string& row)
|
||||
// Se e' una lavorazione
|
||||
if (get(F_TIPO)[0] == 'L')
|
||||
{
|
||||
ok = row[0] == 'L' && is_lav(code);
|
||||
ok = row[0] == 'L' && _tree.is_lav(code);
|
||||
if (!ok)
|
||||
error_box("Il codice '%s' non e' una lavorazione", (const char*)code);
|
||||
}
|
||||
@ -523,42 +317,11 @@ bool TDistinta_mask::test_row(const TToken_string& row)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
bool TDistinta_mask::on_distsheet_event(TOperable_field& o, TField_event e, long jolly)
|
||||
{
|
||||
switch (o.dlg())
|
||||
const short id = o.dlg();
|
||||
switch (id)
|
||||
{
|
||||
case F_CODICE:
|
||||
if (e == fe_init)
|
||||
{
|
||||
bool virtuale = TRUE;
|
||||
const TString& code = o.get();
|
||||
if (virtuale && is_mag(code)) // E' un articolo di magazzino?
|
||||
{
|
||||
set(F_TIPO, "A", TRUE);
|
||||
const TRectype& rec = _mag.get(code);
|
||||
set(F_DESCR, rec.get("DESCR"));
|
||||
|
||||
TLocalisamfile umart(LF_UMART);
|
||||
umart.put(UMART_CODART, code);
|
||||
umart.put(UMART_NRIGA, "1");
|
||||
if (umart.read() == NOERR)
|
||||
set(F_UM, umart.get(UMART_UM));
|
||||
|
||||
virtuale = FALSE;
|
||||
}
|
||||
if (virtuale && is_lav(code)) // E' una lavorazione?
|
||||
{
|
||||
set(F_TIPO, "L", TRUE);
|
||||
const TRectype& rec = _lav.get(code);
|
||||
set(F_DESCR, rec.get("S0"));
|
||||
set(F_UM, rec.get("S6"));
|
||||
set(F_PREZZO, rec.get("R0"));
|
||||
virtuale = FALSE;
|
||||
}
|
||||
if (virtuale)
|
||||
set(F_TIPO, "V", TRUE);
|
||||
}
|
||||
break;
|
||||
case F_SHEET:
|
||||
if (e == se_notify_add || e == se_notify_modify || e == fe_close)
|
||||
{
|
||||
@ -568,17 +331,18 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
switch(e)
|
||||
{
|
||||
case se_notify_add:
|
||||
row = "A| | |1"; // Forza il listbox ad articolo
|
||||
row.add("A", F_TIPOCOMP-FIRST_FIELD); // Forza il listbox ad articolo
|
||||
row.add("1", F_EXPR-FIRST_FIELD);
|
||||
break;
|
||||
case se_notify_modify:
|
||||
return test_row(row);
|
||||
case fe_close:
|
||||
{
|
||||
TString code;
|
||||
TString80 code;
|
||||
for (int n = sheet.items()-1; n >= 0; n--)
|
||||
{
|
||||
const TToken_string& row = sheet.row(n);
|
||||
row.get(1, code);
|
||||
row.get(F_CODART-FIRST_FIELD, code);
|
||||
if (!code.blank())
|
||||
{
|
||||
if (!test_row(row))
|
||||
@ -588,6 +352,8 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
sheet.destroy(n);
|
||||
}
|
||||
}
|
||||
if (sheet.items() == 0)
|
||||
error_box("E' necessario inserire almeno una riga nella distinta");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -600,7 +366,7 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
if (e == fe_modify || e == fe_init)
|
||||
{
|
||||
TMask& m = o.mask();
|
||||
TEdit_field& ef = (TEdit_field&)o;
|
||||
const TEdit_field& ef = (const TEdit_field&)o;
|
||||
const TRectype& rec = ef.browse()->cursor()->curr();
|
||||
switch(rec.num())
|
||||
{
|
||||
@ -609,11 +375,9 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
m.enable(F_UMEXPR);
|
||||
if (m.get(F_UMEXPR).empty())
|
||||
{
|
||||
TLocalisamfile umart(LF_UMART);
|
||||
umart.put(UMART_CODART, o.get());
|
||||
umart.put(UMART_NRIGA, "1");
|
||||
if (umart.read() == NOERR)
|
||||
m.set(F_UMEXPR, umart.get(UMART_UM));
|
||||
const TCodice_articolo art = o.get();
|
||||
const TQuantita qta(art);
|
||||
m.set(F_UMEXPR, qta.um());
|
||||
}
|
||||
break;
|
||||
case LF_DIST :
|
||||
@ -623,7 +387,7 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
break;
|
||||
default :
|
||||
m.set(F_DESCOMP, rec.get("S0"));
|
||||
m.set(F_UMEXPR, rec.get("S7"));
|
||||
m.set(F_UMEXPR, rec.get("S6"));
|
||||
m.disable(F_UMEXPR);
|
||||
break;
|
||||
}
|
||||
@ -640,12 +404,11 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
{
|
||||
if (expr.numvar() > 0)
|
||||
{
|
||||
TTable var("VAR");
|
||||
TDecoder var("VAR");
|
||||
for (int v = expr.numvar()-1; v >= 0; v--)
|
||||
{
|
||||
const char* name = expr.varname(v);
|
||||
var.put("CODTAB", name);
|
||||
if (var.read() != NOERR)
|
||||
if (var.decode(name).empty())
|
||||
return error_box("La variabile %s non e' definita in tabella", name);
|
||||
}
|
||||
}
|
||||
@ -653,22 +416,191 @@ bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jol
|
||||
o.set(expr.as_string());
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
return error_box("Errore di sintassi: %s", expr.last_token());
|
||||
}
|
||||
else
|
||||
return error_box("L'espressione deve essere specificata");
|
||||
}
|
||||
break;
|
||||
case F_SORT1:
|
||||
case F_SORT2:
|
||||
case F_SORT3:
|
||||
case F_SORT4:
|
||||
case F_SORT5:
|
||||
if (e == fe_modify && o.empty())
|
||||
{
|
||||
TString16 key; key << (o.dlg() - F_SORT1 + 1);
|
||||
bool completo = _ord.get(key).get_bool("B0");
|
||||
if (completo)
|
||||
return error_box("Il criterio di ordinamento %s deve essere specificato",
|
||||
(const char*)key);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TDistinta_mask::on_parmsheet_event(TOperable_field& o, TField_event e, long jolly)
|
||||
{
|
||||
const short id = o.dlg();
|
||||
switch (id)
|
||||
{
|
||||
case F_PARAM:
|
||||
if (e == fe_modify || e == fe_close)
|
||||
{
|
||||
const TString& str = o.get();
|
||||
if (!isalpha(str[0]) && str[0] != '_')
|
||||
return error_box("Il nome del parametro deve iniziare con un carattere alfabetico o con _");
|
||||
for (const char* s = str; *s; s++)
|
||||
{
|
||||
if (!isalnum(*s) && *s != '_')
|
||||
return error_box("Il nome del parametro puo' contenere solo caratteri alfanumerici o _");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static _sort_key = 0;
|
||||
|
||||
static int compare_sheet_rows(const TObject** o1, const TObject** o2)
|
||||
{
|
||||
TToken_string* s1 = (TToken_string*)*o1;
|
||||
TToken_string* s2 = (TToken_string*)*o2;
|
||||
|
||||
const int key_pos = F_SORT1 - FIRST_FIELD + _sort_key - 1;
|
||||
long k1 = s1->get_long(key_pos);
|
||||
long k2 = s2->get_long(key_pos);
|
||||
|
||||
if (k1 == 0) k1 = 100000000L;
|
||||
if (k2 == 0) k2 = 100000000L;
|
||||
|
||||
return k1 == k2 ? 0 : (k1 > k2 ? +1 : -1);
|
||||
}
|
||||
|
||||
bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
{
|
||||
const short id = o.dlg();
|
||||
switch (id)
|
||||
{
|
||||
case F_CODICE:
|
||||
if (e == fe_init)
|
||||
{
|
||||
bool virtuale = TRUE;
|
||||
const TString& code = o.get();
|
||||
const char type = _tree.get_type(code);
|
||||
switch(type)
|
||||
{
|
||||
case 'A':
|
||||
{
|
||||
set(F_TIPO, "A", TRUE);
|
||||
|
||||
TDecoder mag(LF_ANAMAG, ANAMAG_DESCR);
|
||||
set(F_DESCR, mag.decode(code));
|
||||
|
||||
const TQuantita qta(code);
|
||||
set(F_UM, qta.um());
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
set(F_TIPO, "L", TRUE);
|
||||
TTable lav("LAV");
|
||||
lav.put("CODTAB", code);
|
||||
if (lav.read() == NOERR)
|
||||
{
|
||||
set(F_DESCR, lav.get("S0"));
|
||||
set(F_UM, lav.get("S6"));
|
||||
set(F_PREZZO, lav.get("R0"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
set(F_TIPO, "V", TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_SORT:
|
||||
if (e == fe_modify)
|
||||
{
|
||||
TSheet_field& sf = sfield(F_SHEET);
|
||||
_sort_key = atoi(o.get());
|
||||
if (_sort_key > 0)
|
||||
{
|
||||
TString_array& a = sf.rows_array();
|
||||
a.TArray::sort(compare_sheet_rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRelation rel(LF_DIST);
|
||||
sf.autoload(rel);
|
||||
}
|
||||
sf.force_update();
|
||||
}
|
||||
break;
|
||||
case F_SHEET:
|
||||
return on_distsheet_event(o, e, jolly);
|
||||
default:
|
||||
if (id >= 101 && id < 500) // E' in uno sheet?
|
||||
{
|
||||
switch (jolly)
|
||||
{
|
||||
case 1 : return on_distsheet_event(o, e, jolly);
|
||||
case 2 : return on_parmsheet_event(o, e, jolly);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TDistinta_mask::TDistinta_mask(TDistinta_tree& dt)
|
||||
: TAutomask("db0100b"), _tree(dt),
|
||||
_mag(LF_ANAMAG), _lav("LAV")
|
||||
{ }
|
||||
: TAutomask("db0100b"), _tree(dt), _ord("ORD")
|
||||
{
|
||||
TSheet_field& sf = sfield(F_SHEET);
|
||||
TMask& sm = sf.sheet_mask();
|
||||
TString16 key;
|
||||
int i;
|
||||
for (i = 4; i >= 0; i--)
|
||||
{
|
||||
key.format("%d", i+1);
|
||||
const bool kill = _ord.get(key).empty();
|
||||
if (kill)
|
||||
{
|
||||
const short id = F_SORT1+i;
|
||||
sm.hide(id);
|
||||
sf.delete_column(id);
|
||||
}
|
||||
}
|
||||
|
||||
TCodgiac_livelli cgl;
|
||||
for (i = 4; i > 0; i--)
|
||||
{
|
||||
const short id = F_LIV1+i;
|
||||
const bool kill = !cgl.enabled(i);
|
||||
if (kill)
|
||||
{
|
||||
sm.hide(id);
|
||||
sf.delete_column(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
const TString & header = cgl.name(i);
|
||||
const int len = header.len() + 1;
|
||||
const int f_len = cgl.code_length(i);
|
||||
sf.set_column_header(id, header);
|
||||
sf.set_column_width(id, (len > f_len ? len : f_len) * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -683,13 +615,17 @@ class TDistinta_app : public TRelation_application
|
||||
TDistinta_mask* _themask;
|
||||
int _mode;
|
||||
|
||||
void parms2rel(const TMask& m);
|
||||
|
||||
protected:
|
||||
virtual bool user_create();
|
||||
virtual bool user_destroy();
|
||||
virtual TRelation* get_relation() const { return _therel; }
|
||||
virtual bool changing_mask(int mode);
|
||||
virtual void init_modify_mode(TMask& m);
|
||||
virtual TMask* get_mask(int mode);
|
||||
virtual int read(TMask& m);
|
||||
virtual int write(const TMask& m);
|
||||
virtual int rewrite(const TMask& m);
|
||||
|
||||
public:
|
||||
};
|
||||
@ -705,6 +641,7 @@ bool TDistinta_app::user_create()
|
||||
bool TDistinta_app::user_destroy()
|
||||
{
|
||||
delete _themask;
|
||||
delete _querymask;
|
||||
delete _therel;
|
||||
return TRUE;
|
||||
}
|
||||
@ -718,16 +655,70 @@ bool TDistinta_app::changing_mask(int mode)
|
||||
|
||||
TMask* TDistinta_app::get_mask(int mode)
|
||||
{
|
||||
const bool is_query = mode == MODE_QUERY || mode == MODE_QUERYINS;
|
||||
_mode = mode;
|
||||
bool is_query = mode == MODE_QUERY || mode == MODE_QUERYINS;
|
||||
return is_query ? (TMask*)_querymask : (TMask*)_themask;
|
||||
}
|
||||
|
||||
void TDistinta_app::init_modify_mode(TMask& m)
|
||||
int TDistinta_app::read(TMask& m)
|
||||
{
|
||||
TSheet_field& sheet = m.sfield(F_SHEET);
|
||||
FOR_EACH_SHEET_ROW(sheet, nrig, row)
|
||||
sheet.check_row(nrig);
|
||||
const int err = TRelation_application::read(m);
|
||||
|
||||
if (err == NOERR)
|
||||
{
|
||||
TSheet_field& sheet = m.sfield(F_SHEET);
|
||||
FOR_EACH_SHEET_ROW(sheet, nrig, row)
|
||||
sheet.check_row(nrig);
|
||||
|
||||
TToken_string memo(1024, '\n');
|
||||
memo = _therel->curr().get("PARAMETRI");
|
||||
const int righe = memo.items();
|
||||
TSheet_field& params = m.sfield(F_PARAMS);
|
||||
params.destroy();
|
||||
for (int i = 0; i < righe; i++)
|
||||
{
|
||||
TToken_string& row = params.row(i);
|
||||
memo.get(i, row);
|
||||
int equal = row.find('=');
|
||||
if (equal > 0)
|
||||
row[equal] = '|';
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void TDistinta_app::parms2rel(const TMask& m)
|
||||
{
|
||||
TToken_string memo(1024, '\n');
|
||||
TSheet_field& parms = m.sfield(F_PARAMS);
|
||||
TString var;
|
||||
FOR_EACH_SHEET_ROW(parms, r, row)
|
||||
{
|
||||
var = row->get(0);
|
||||
if (!var.blank())
|
||||
{
|
||||
memo.add(var);
|
||||
memo << '=';
|
||||
memo << row->get();
|
||||
}
|
||||
}
|
||||
_therel->curr().put("PARAMETRI", memo);
|
||||
|
||||
// Azzera albero per rispecchiare eventuali modifiche
|
||||
_querymask->restart_tree();
|
||||
}
|
||||
|
||||
int TDistinta_app::write(const TMask& m)
|
||||
{
|
||||
parms2rel(m);
|
||||
return TRelation_application::write(m);
|
||||
}
|
||||
|
||||
int TDistinta_app::rewrite(const TMask& m)
|
||||
{
|
||||
parms2rel(m);
|
||||
return TRelation_application::rewrite(m);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
41
db/db0100a.h
41
db/db0100a.h
@ -4,9 +4,12 @@
|
||||
#define F_TREE 500
|
||||
#define F_CODICE 501
|
||||
#define F_CODICEQ 502
|
||||
#define F_TIPO 503
|
||||
#define F_VIRTUALE 504
|
||||
#define F_COPY 505
|
||||
#define F_SORT 503
|
||||
#define F_SORTDESC 504
|
||||
#define F_TIPO 505
|
||||
#define F_VIRTUALE 506
|
||||
#define F_COPY 507
|
||||
#define F_EXPLODE 508
|
||||
|
||||
#define F_DESCR 510
|
||||
#define F_PREZZO 511
|
||||
@ -15,19 +18,35 @@
|
||||
#define F_UMP 514
|
||||
|
||||
#define F_SHEET 520
|
||||
#define F_PARAMS 521
|
||||
|
||||
#define F_TIPOCOMP 101
|
||||
#define F_CODART 102
|
||||
#define F_CODLAV 202
|
||||
#define F_CODDIS 302
|
||||
#define F_CODVAR 402
|
||||
#define F_UMEXPR 103
|
||||
#define F_EXPR 104
|
||||
#define F_DESCOMP 105
|
||||
#define F_SORT1 106
|
||||
#define F_SORT2 107
|
||||
#define F_SORT3 108
|
||||
#define F_SORT4 109
|
||||
#define F_SORT5 110
|
||||
#define F_LIV1 103
|
||||
#define F_LIV2 104
|
||||
#define F_LIV3 105
|
||||
#define F_LIV4 106
|
||||
#define F_UMEXPR 107
|
||||
#define F_EXPR 108
|
||||
#define F_DESCOMP 109
|
||||
#define F_SORT1 110
|
||||
#define F_SORT2 111
|
||||
#define F_SORT3 112
|
||||
#define F_SORT4 113
|
||||
#define F_SORT5 114
|
||||
|
||||
#define F_PARAM 101
|
||||
#define F_VALUE 102
|
||||
|
||||
#define F_MATBASE 101
|
||||
#define F_MAXDEPTH 102
|
||||
#define F_ARTICOLI 103
|
||||
#define F_LAVORAZIONI 104
|
||||
#define F_VIRTUALI 105
|
||||
#define F_GROUPMODE 106
|
||||
#define F_LASTQTA 107
|
||||
|
||||
#endif
|
||||
|
@ -1,17 +1,17 @@
|
||||
#include "db0100a.h"
|
||||
|
||||
TOOLBAR "" 0 20 0 0
|
||||
TOOLBAR "" 0 19 0 0
|
||||
|
||||
BUTTON DLG_SELECT 10 2
|
||||
BEGIN
|
||||
PROMPT -16 -1 "~Selezione"
|
||||
PROMPT -16 -11 "~Selezione"
|
||||
MESSAGE EXIT,K_ENTER
|
||||
PICTURE BMP_SELECT
|
||||
END
|
||||
|
||||
BUTTON DLG_NEWREC 10 2
|
||||
BEGIN
|
||||
PROMPT -26 -1 "~Nuovo"
|
||||
PROMPT -26 -11 "~Nuovo"
|
||||
MESSAGE EXIT,K_INS
|
||||
PICTURE BMP_NEWREC
|
||||
PICTURE BMP_NEWRECDN
|
||||
@ -19,7 +19,7 @@ END
|
||||
|
||||
BUTTON DLG_DELREC 10 2
|
||||
BEGIN
|
||||
PROMPT -36 -1 "~Elimina"
|
||||
PROMPT -36 -11 "~Elimina"
|
||||
MESSAGE EXIT,K_DEL
|
||||
PICTURE BMP_DELREC
|
||||
PICTURE BMP_DELRECDN
|
||||
@ -27,19 +27,17 @@ END
|
||||
|
||||
BUTTON F_COPY 10 2
|
||||
BEGIN
|
||||
PROMPT -46 -1 "~Copia"
|
||||
PROMPT -46 -11 "~Copia"
|
||||
END
|
||||
|
||||
BUTTON DLG_CANCEL 10 2
|
||||
BUTTON F_EXPLODE 10 2
|
||||
BEGIN
|
||||
PROMPT -56 -1 "~Annulla"
|
||||
MESSAGE EXIT,K_ESC
|
||||
PICTURE 102
|
||||
PROMPT -56 -11 "E~splodi"
|
||||
END
|
||||
|
||||
BUTTON DLG_QUIT 10 2
|
||||
BEGIN
|
||||
PROMPT -66 -1 "~Fine"
|
||||
PROMPT -66 -11 "~Fine"
|
||||
MESSAGE EXIT,K_QUIT
|
||||
PICTURE BMP_QUIT
|
||||
PICTURE BMP_QUITDN
|
||||
@ -49,14 +47,14 @@ ENDPAGE
|
||||
|
||||
PAGE "Distinta base" -1 -1 80 20
|
||||
|
||||
GROUPBOX DLG_NULL 78 3
|
||||
GROUPBOX DLG_NULL 78 4
|
||||
BEGIN
|
||||
PROMPT 1 1 "Distinta"
|
||||
END
|
||||
|
||||
STRING F_CODICE 20
|
||||
BEGIN
|
||||
PROMPT 2 2 "Cerca "
|
||||
PROMPT 2 2 "Cerca "
|
||||
FLAGS "GU"
|
||||
USE LF_DIST
|
||||
JOIN LF_ANAMAG INTO CODART==CODDIST
|
||||
@ -64,14 +62,13 @@ BEGIN
|
||||
DISPLAY "Codice@20" CODDIST
|
||||
DISPLAY "Descrizione@50" LF_ANAMAG->DESCR
|
||||
OUTPUT F_CODICE CODDIST
|
||||
ADD RUN ve2 -3
|
||||
CHECKTYPE REQUIRED
|
||||
FIELD CODDIST
|
||||
END
|
||||
|
||||
STRING F_CODICEQ 20
|
||||
BEGIN
|
||||
PROMPT 42 2 "Codice "
|
||||
PROMPT 47 2 "Codice "
|
||||
FIELD CODDIST
|
||||
KEY 1
|
||||
USE LF_ANAMAG
|
||||
@ -81,16 +78,35 @@ BEGIN
|
||||
DISPLAY "Descrizione@50" DESCR
|
||||
OUTPUT F_CODICEQ CODART
|
||||
CHECKTYPE REQUIRED
|
||||
ADD RUN ve2 -3
|
||||
MESSAGE COPY,F_CODICE
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
TREE F_TREE -3 -1
|
||||
NUMBER F_SORT 1
|
||||
BEGIN
|
||||
PROMPT 0 4 ""
|
||||
PROMPT 2 3 "Ordinamento "
|
||||
USE ORD
|
||||
INPUT CODTAB F_SORT
|
||||
DISPLAY "Codice ordinamento" CODTAB
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_SORT CODTAB
|
||||
OUTPUT F_SORTDESC S0
|
||||
CHECKTYPE NORMAL
|
||||
FLAGS "U"
|
||||
MESSAGE EMPTY "Immissione",F_SORTDESC
|
||||
END
|
||||
|
||||
STRING F_SORTDESC 50
|
||||
BEGIN
|
||||
PROMPT 24 3 ""
|
||||
FLAGS "D"
|
||||
END
|
||||
|
||||
TREE F_TREE -3 -1
|
||||
BEGIN
|
||||
PROMPT 0 5 ""
|
||||
END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
|
257
db/db0100b.uml
257
db/db0100b.uml
@ -1,10 +1,56 @@
|
||||
#include "db0100a.h"
|
||||
|
||||
TOOLBAR "" 0 20 0 0
|
||||
#include <toolbar.h>
|
||||
TOOLBAR "" 0 19 0 0
|
||||
|
||||
BUTTON DLG_SAVEREC 10 2
|
||||
BEGIN
|
||||
PROMPT -16 -11 "~Registra"
|
||||
MESSAGE EXIT,K_SAVE
|
||||
PICTURE BMP_SAVEREC
|
||||
PICTURE BMP_SAVERECDN
|
||||
END
|
||||
|
||||
BUTTON DLG_NEWREC 10 2
|
||||
BEGIN
|
||||
PROMPT -26 -11 "~Nuovo"
|
||||
MESSAGE EXIT,K_INS
|
||||
PICTURE BMP_NEWREC
|
||||
PICTURE BMP_NEWRECDN
|
||||
END
|
||||
|
||||
BUTTON DLG_DELREC 10 2
|
||||
BEGIN
|
||||
PROMPT -36 -11 "~Elimina"
|
||||
MESSAGE EXIT,K_DEL
|
||||
PICTURE BMP_DELREC
|
||||
PICTURE BMP_DELRECDN
|
||||
END
|
||||
|
||||
BUTTON DLG_FINDREC 10 2
|
||||
BEGIN
|
||||
PROMPT -46 -11 "Ri~cerca"
|
||||
MESSAGE EXIT,K_F9
|
||||
PICTURE 126
|
||||
END
|
||||
|
||||
BUTTON DLG_CANCEL 10 2
|
||||
BEGIN
|
||||
PROMPT -56 -11 "~Annulla"
|
||||
MESSAGE EXIT,K_ESC
|
||||
PICTURE 102
|
||||
END
|
||||
|
||||
BUTTON DLG_QUIT 10 2
|
||||
BEGIN
|
||||
PROMPT -66 -11 "~Fine"
|
||||
MESSAGE EXIT,K_QUIT
|
||||
PICTURE BMP_QUIT
|
||||
PICTURE BMP_QUITDN
|
||||
END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
PAGE "Distinta base" -1 -1 80 20
|
||||
PAGE "Distinta" -1 -1 80 20
|
||||
|
||||
GROUPBOX DLG_NULL 78 3
|
||||
BEGIN
|
||||
@ -21,7 +67,7 @@ END
|
||||
|
||||
LIST F_TIPO 1 12
|
||||
BEGIN
|
||||
PROMPT 42 2 "Tipo "
|
||||
PROMPT 54 2 "Tipo "
|
||||
ITEM "A|Articolo"
|
||||
MESSAGE "",F_VIRTUALE
|
||||
ITEM "L|Lavorazione"
|
||||
@ -33,7 +79,7 @@ END
|
||||
|
||||
BOOLEAN F_VIRTUALE
|
||||
BEGIN
|
||||
PROMPT 42 42 "Virtuale"
|
||||
PROMPT 50 50 "Virtuale"
|
||||
MESSAGE FALSE DISABLE,1@
|
||||
MESSAGE TRUE ENABLE,1@
|
||||
FLAGS "DG"
|
||||
@ -95,13 +141,37 @@ BEGIN
|
||||
FLAGS "D"
|
||||
END
|
||||
|
||||
NUMBER F_SORT 1
|
||||
BEGIN
|
||||
PROMPT 2 9 "Ordinamento "
|
||||
USE ORD
|
||||
INPUT CODTAB F_SORT
|
||||
DISPLAY "Codice ordinamento" CODTAB
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_SORT CODTAB
|
||||
OUTPUT F_SORTDESC S0
|
||||
CHECKTYPE NORMAL
|
||||
FLAGS "U"
|
||||
MESSAGE EMPTY "Immissione",F_SORTDESC
|
||||
END
|
||||
|
||||
STRING F_SORTDESC 50
|
||||
BEGIN
|
||||
PROMPT 21 9 ""
|
||||
FLAGS "D"
|
||||
END
|
||||
|
||||
SPREADSHEET F_SHEET
|
||||
BEGIN
|
||||
PROMPT 0 9 ""
|
||||
PROMPT 0 10 ""
|
||||
ITEM "Tipo@4"
|
||||
ITEM "Codice@20"
|
||||
ITEM "Liv1"
|
||||
ITEM "Liv2"
|
||||
ITEM "Liv3"
|
||||
ITEM "Liv4"
|
||||
ITEM "UM@3"
|
||||
ITEM "Espressione@20"
|
||||
ITEM "Espressione@30"
|
||||
ITEM "Descrizione@50"
|
||||
ITEM "Ord1"
|
||||
ITEM "Ord2"
|
||||
@ -115,11 +185,34 @@ END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
PAGE "Parametri" -1 -1 80 20
|
||||
|
||||
GROUPBOX DLG_NULL 78 3
|
||||
BEGIN
|
||||
PROMPT 1 1 "Distinta"
|
||||
END
|
||||
|
||||
STRING F_CODICEQ 20
|
||||
BEGIN
|
||||
PROMPT 2 2 "Codice "
|
||||
FLAGS "D"
|
||||
FIELD CODDIST
|
||||
END
|
||||
|
||||
SPREADSHEET F_PARAMS
|
||||
BEGIN
|
||||
PROMPT 0 4 ""
|
||||
ITEM "Variabile@20"
|
||||
ITEM "Valore@70"
|
||||
END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
ENDMASK
|
||||
|
||||
PAGE "Riga 1" -1 -1 68 12
|
||||
PAGE "Distinta" -1 -1 68 14
|
||||
|
||||
GROUPBOX DLG_NULL 66 4
|
||||
GROUPBOX DLG_NULL 66 5
|
||||
BEGIN
|
||||
PROMPT 1 0 "Componente"
|
||||
END
|
||||
@ -140,7 +233,7 @@ END
|
||||
|
||||
STRING F_CODART 20
|
||||
BEGIN
|
||||
PROMPT 37 1 "Codice "
|
||||
PROMPT 35 1 "Codice "
|
||||
USE LF_ANAMAG
|
||||
INPUT CODART F_CODART
|
||||
DISPLAY "Codice@20" CODART
|
||||
@ -154,10 +247,10 @@ END
|
||||
|
||||
STRING F_CODLAV 20
|
||||
BEGIN
|
||||
PROMPT 37 1 "Codice "
|
||||
PROMPT 35 1 "Codice "
|
||||
USE LAV
|
||||
INPUT CODTAB F_CODLAV
|
||||
DISPLAY "Codice@8" CODTAB
|
||||
DISPLAY "Codice@20" CODTAB
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_CODLAV CODTAB
|
||||
CHECKTYPE REQUIRED
|
||||
@ -167,7 +260,7 @@ END
|
||||
|
||||
STRING F_CODDIS 20
|
||||
BEGIN
|
||||
PROMPT 37 1 "Codice "
|
||||
PROMPT 35 1 "Codice "
|
||||
USE LF_DIST SELECT VIRTUALE=="X"
|
||||
INPUT CODDIST F_CODDIS
|
||||
DISPLAY "Codice@20" CODDIST
|
||||
@ -180,7 +273,7 @@ END
|
||||
|
||||
STRING F_CODVAR 20
|
||||
BEGIN
|
||||
PROMPT 37 1 "Codice "
|
||||
PROMPT 35 1 "Codice "
|
||||
USE VAR
|
||||
INPUT CODTAB F_CODDIS
|
||||
DISPLAY "Codice@20" CODTAB
|
||||
@ -191,73 +284,136 @@ BEGIN
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
STRING F_LIV1 10
|
||||
BEGIN
|
||||
PROMPT 2 2 "Livello "
|
||||
FLAGS "U"
|
||||
USE GCG
|
||||
JOIN FCG ALIAS 500 INTO CODTAB==CODTAB[1,1]
|
||||
INPUT CODTAB[1,1] "1"
|
||||
INPUT CODTAB[2,11] F_LIV1
|
||||
DISPLAY "Livello@20" 500@->S0
|
||||
DISPLAY "Gruppo@10" CODTAB[2,20]
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_LIV1 CODTAB[2,12]
|
||||
CHECKTYPE NORMAL
|
||||
MESSAGE EMPTY RESET,F_LIV2|RESET,F_LIV3|RESET,F_LIV4
|
||||
END
|
||||
|
||||
STRING F_LIV2 6
|
||||
BEGIN
|
||||
FLAGS "U"
|
||||
PROMPT 26 2 ""
|
||||
USE GCG
|
||||
JOIN FCG ALIAS 500 INTO CODTAB==CODTAB[1,1]
|
||||
INPUT CODTAB[1,1] "2"
|
||||
INPUT CODTAB[2,12] F_LIV2
|
||||
COPY DISPLAY F_LIV1
|
||||
OUTPUT F_LIV2 CODTAB[2,12]
|
||||
CHECKTYPE NORMAL
|
||||
MESSAGE EMPTY RESET,F_LIV3|RESET,F_LIV4
|
||||
END
|
||||
|
||||
STRING F_LIV3 6
|
||||
BEGIN
|
||||
FLAGS "U"
|
||||
PROMPT 34 2 ""
|
||||
USE GCG
|
||||
JOIN FCG ALIAS 500 INTO CODTAB==CODTAB[1,1]
|
||||
INPUT CODTAB[1,1] "3"
|
||||
INPUT CODTAB[2,12] F_LIV3
|
||||
COPY DISPLAY F_LIV1
|
||||
OUTPUT F_LIV3 CODTAB[2,12]
|
||||
CHECKTYPE NORMAL
|
||||
MESSAGE EMPTY RESET,F_LIV4
|
||||
END
|
||||
|
||||
STRING F_LIV4 6
|
||||
BEGIN
|
||||
FLAGS "U"
|
||||
PROMPT 42 2 ""
|
||||
USE GCG
|
||||
JOIN FCG ALIAS 500 INTO CODTAB==CODTAB[1,1]
|
||||
INPUT CODTAB[1,1] "4"
|
||||
INPUT CODTAB[2,12] F_LIV4
|
||||
COPY DISPLAY F_LIV1
|
||||
OUTPUT F_LIV4 CODTAB[2,12]
|
||||
CHECKTYPE NORMAL
|
||||
END
|
||||
|
||||
STRING F_DESCOMP 50
|
||||
BEGIN
|
||||
PROMPT 2 2 "Descrizione "
|
||||
PROMPT 2 3 "Descrizione "
|
||||
FLAGS "D"
|
||||
END
|
||||
|
||||
GROUPBOX DLG_NULL 66 4
|
||||
BEGIN
|
||||
PROMPT 1 4 "Formula"
|
||||
PROMPT 1 5 "Formula"
|
||||
END
|
||||
|
||||
STRING F_UMEXPR 3
|
||||
STRING F_UMEXPR 2
|
||||
BEGIN
|
||||
PROMPT 2 5 "Unita' di misura "
|
||||
PROMPT 2 6 "Unita' di misura "
|
||||
USE LF_UMART KEY 2
|
||||
JOIN LF_ANAMAG INTO CODART==CODART
|
||||
INPUT CODART F_CODART SELECT
|
||||
INPUT UM F_UMEXPR
|
||||
DISPLAY "Unita'" UM
|
||||
DISPLAY "Articolo@20" CODART
|
||||
DISPLAY "Descrizione@50" LF_ANAMAG->DESCR
|
||||
DISPLAY "Descrizione Articolo@50" LF_ANAMAG->DESCR
|
||||
OUTPUT F_UMEXPR UM
|
||||
CHECKTYPE NORMAL
|
||||
ADD RUN ve2 -3
|
||||
FIELD UM
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
STRING F_EXPR 50 62
|
||||
BEGIN
|
||||
PROMPT 2 6 ""
|
||||
PROMPT 2 7 ""
|
||||
FIELD EXPR
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
GROUPBOX DLG_NULL 66 3
|
||||
BEGIN
|
||||
PROMPT 1 8 "Criteri d'ordinamento"
|
||||
PROMPT 1 9 "Criteri d'ordinamento"
|
||||
END
|
||||
|
||||
NUMBER F_SORT1 4
|
||||
NUMBER F_SORT1 8
|
||||
BEGIN
|
||||
PROMPT 2 9 "1 "
|
||||
PROMPT 2 10 "1 "
|
||||
FIELD SORT1
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
NUMBER F_SORT2 4
|
||||
NUMBER F_SORT2 8
|
||||
BEGIN
|
||||
PROMPT 16 9 "2 "
|
||||
PROMPT 15 10 "2 "
|
||||
FIELD SORT2
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
NUMBER F_SORT3 4
|
||||
NUMBER F_SORT3 8
|
||||
BEGIN
|
||||
PROMPT 30 9 "3 "
|
||||
PROMPT 28 10 "3 "
|
||||
FIELD SORT3
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
NUMBER F_SORT4 4
|
||||
NUMBER F_SORT4 8
|
||||
BEGIN
|
||||
PROMPT 44 9 "4 "
|
||||
PROMPT 41 10 "4 "
|
||||
FIELD SORT4
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
NUMBER F_SORT5 4
|
||||
NUMBER F_SORT5 8
|
||||
BEGIN
|
||||
PROMPT 58 9 "5 "
|
||||
PROMPT 54 10 "5 "
|
||||
FIELD SORT5
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
BUTTON DLG_OK 10 2
|
||||
@ -275,6 +431,45 @@ BEGIN
|
||||
PROMPT -33 -1 ""
|
||||
END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
ENDMASK
|
||||
|
||||
PAGE "Variabili" -1 -1 64 5
|
||||
|
||||
STRING F_PARAM 20
|
||||
BEGIN
|
||||
PROMPT 1 1 "Variabile "
|
||||
USE VAR
|
||||
INPUT CODTAB F_PARAM
|
||||
DISPLAY "Codice@20" CODTAB
|
||||
DISPLAY "Numerico@B" B0
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_PARAM CODTAB
|
||||
CHECKTYPE REQUIRED
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
STRING F_VALUE 70 50
|
||||
BEGIN
|
||||
PROMPT 1 2 "Valore "
|
||||
END
|
||||
|
||||
BUTTON DLG_OK 10 2
|
||||
BEGIN
|
||||
PROMPT -13 -1 ""
|
||||
END
|
||||
|
||||
BUTTON DLG_DELREC 10 2
|
||||
BEGIN
|
||||
PROMPT -23 -1 ""
|
||||
END
|
||||
|
||||
BUTTON DLG_CANCEL 10 2
|
||||
BEGIN
|
||||
PROMPT -33 -1 ""
|
||||
END
|
||||
|
||||
ENDPAGE
|
||||
|
||||
ENDMASK
|
||||
|
85
db/db0100c.uml
Executable file
85
db/db0100c.uml
Executable file
@ -0,0 +1,85 @@
|
||||
#include "db0100a.h"
|
||||
|
||||
PAGE "Esplosione" -1 -1 66 11
|
||||
|
||||
RADIOBUTTON F_MATBASE 1 31
|
||||
BEGIN
|
||||
PROMPT 1 1 "Tipo"
|
||||
ITEM " |Scalare"
|
||||
MESSAGE ENABLE,F_MAXDEPTH|ENABLE,F_LASTQTA
|
||||
ITEM "X|Materiali di base"
|
||||
MESSAGE CLEAR,F_MAXDEPTH|CLEAR,F_LASTQTA
|
||||
END
|
||||
|
||||
GROUPBOX DLG_NULL 32 5
|
||||
BEGIN
|
||||
PROMPT 33 1 "Visualizza"
|
||||
END
|
||||
|
||||
BOOLEAN F_ARTICOLI
|
||||
BEGIN
|
||||
PROMPT 34 2 "Articoli"
|
||||
END
|
||||
|
||||
BOOLEAN F_LAVORAZIONI
|
||||
BEGIN
|
||||
PROMPT 34 3 "Lavorazioni"
|
||||
END
|
||||
|
||||
BOOLEAN F_VIRTUALI
|
||||
BEGIN
|
||||
PROMPT 34 4 "Distinte virtuali"
|
||||
END
|
||||
|
||||
NUMBER F_MAXDEPTH 3
|
||||
BEGIN
|
||||
PROMPT 2 5 "Profondita' "
|
||||
FLAGS "U"
|
||||
END
|
||||
|
||||
BOOLEAN F_LASTQTA
|
||||
BEGIN
|
||||
PROMPT 2 6 "Disabilita ricalcolo quantita'"
|
||||
END
|
||||
|
||||
NUMBER F_SORT 1
|
||||
BEGIN
|
||||
PROMPT 2 7 "Ordina "
|
||||
USE ORD
|
||||
INPUT CODTAB F_SORT
|
||||
DISPLAY "Codice ordinamento" CODTAB
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT F_SORT CODTAB
|
||||
OUTPUT F_SORTDESC S0
|
||||
CHECKTYPE NORMAL
|
||||
FLAGS "U"
|
||||
MESSAGE EMPTY "Immissione",F_SORTDESC
|
||||
END
|
||||
|
||||
STRING F_SORTDESC 50
|
||||
BEGIN
|
||||
PROMPT 14 7 ""
|
||||
FLAGS "D"
|
||||
END
|
||||
|
||||
LIST F_GROUPMODE 1 50
|
||||
BEGIN
|
||||
PROMPT 2 8 "Raggruppa "
|
||||
ITEM "0|Nessun raggruppamento"
|
||||
ITEM "1|Alla prima unita' di misura"
|
||||
ITEM "2|All'unita' di misura di riferimento"
|
||||
ITEM "3|Per unita' di misura"
|
||||
END
|
||||
|
||||
BUTTON DLG_CANCEL 10 2
|
||||
BEGIN
|
||||
PROMPT -12 -1 ""
|
||||
END
|
||||
|
||||
BUTTON DLG_OK 10 2
|
||||
BEGIN
|
||||
PROMPT -22 -1 ""
|
||||
END
|
||||
|
||||
|
||||
ENDMASK
|
957
db/dblib.cpp
Executable file
957
db/dblib.cpp
Executable file
@ -0,0 +1,957 @@
|
||||
#include <urldefid.h>
|
||||
|
||||
#include "dblib.h"
|
||||
|
||||
#include "../mg/anamag.h"
|
||||
#include "../mg/umart.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TQuantita'
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TDecoder* TQuantita::_umart1 = NULL;
|
||||
TDecoder* TQuantita::_umart2 = NULL;
|
||||
|
||||
real TQuantita::get_factor(const TCodice_um& um) const
|
||||
{
|
||||
real fc = 1.0;
|
||||
if (_articolo.blank())
|
||||
{
|
||||
NFCHECK("Unita' di misura generica non supportata");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_umart2 == NULL)
|
||||
_umart2 = new TDecoder(LF_UMART, UMART_FC, 2);
|
||||
|
||||
TString80 code;
|
||||
code << _articolo << '|' << (um.empty() ? _um : um);
|
||||
const TString& val = _umart2->decode(code);
|
||||
if (val.not_empty())
|
||||
fc = real(val);
|
||||
}
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
void TQuantita::set_articolo(const TCodice_articolo& art,
|
||||
const TCodice_um& um)
|
||||
{
|
||||
_articolo = art;
|
||||
|
||||
if (um.blank())
|
||||
{
|
||||
if (_umart1 == NULL)
|
||||
_umart1 = new TDecoder(LF_UMART, UMART_UM, 1);
|
||||
|
||||
TString80 code;
|
||||
code << _articolo << "|1";
|
||||
const TString& new_um = _umart1->decode(code);
|
||||
if (!new_um.blank())
|
||||
_um = new_um;
|
||||
_conv = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_um = um;
|
||||
_conv = get_factor(_um);
|
||||
}
|
||||
|
||||
CHECK(!_um.blank(), "Unita' di misura nulla");
|
||||
CHECK(_conv > ZERO, "Invalid conversion factor");
|
||||
}
|
||||
|
||||
void TQuantita::copy(const TQuantita& q)
|
||||
{
|
||||
_articolo = q._articolo;
|
||||
_um = q._um;
|
||||
_conv = q._conv;
|
||||
_val = q._val;
|
||||
}
|
||||
|
||||
|
||||
void TQuantita::convert(real& val, const TCodice_um& from_um,
|
||||
const TCodice_um& to_um) const
|
||||
{
|
||||
CHECK(!from_um.blank() && !to_um.blank(), "Unita' di misura nulla");
|
||||
if (from_um != to_um)
|
||||
{
|
||||
if (!_val.is_zero())
|
||||
{
|
||||
const real mul = get_factor(from_um);
|
||||
const real div = get_factor(to_um);
|
||||
val *= mul;
|
||||
val /= div;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TQuantita::convert_to_base()
|
||||
{
|
||||
CHECK(_conv > ZERO, "Invalid conversion factor");
|
||||
_val *= _conv;
|
||||
TCodice_um dummy;
|
||||
set_articolo(_articolo, dummy);
|
||||
}
|
||||
|
||||
int TQuantita::compare(const TSortable& s) const
|
||||
{
|
||||
const TQuantita& q = (const TQuantita&)s;
|
||||
real qta = q._val;
|
||||
if (_um != q._um)
|
||||
convert(qta, q._um, _um);
|
||||
qta -= _val;
|
||||
return -qta.sign();
|
||||
}
|
||||
|
||||
const TQuantita& TQuantita::operator +=(const TQuantita& q)
|
||||
{
|
||||
real qta = q._val;
|
||||
if (_um != q._um)
|
||||
convert(qta, q._um, _um);
|
||||
_val += qta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TQuantita& TQuantita::operator -=(const TQuantita& q)
|
||||
{
|
||||
real qta = q._val;
|
||||
if (_um != q._um)
|
||||
convert(qta, q._um, _um);
|
||||
_val -= qta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TQuantita& TQuantita::operator =(const real& q)
|
||||
{
|
||||
CHECK(!_um.blank(), "Unita' di misura nulla");
|
||||
_val = q;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TQuantita& TQuantita::operator *=(const real& q)
|
||||
{
|
||||
CHECK(!_um.blank(), "Unita' di misura nulla");
|
||||
_val *= q;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TQuantita& TQuantita::operator /=(const real& q)
|
||||
{
|
||||
CHECK(!_um.blank(), "Unita' di misura nulla");
|
||||
_val /= q;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TQuantita::TQuantita()
|
||||
: _conv(1.0)
|
||||
{ }
|
||||
|
||||
TQuantita::TQuantita(const TCodice_articolo& art)
|
||||
{
|
||||
TCodice_um dummy;
|
||||
set(art, dummy, ZERO);
|
||||
}
|
||||
|
||||
TQuantita::TQuantita(const TCodice_articolo& art, const TCodice_um& um, const real& val)
|
||||
{
|
||||
set(art, um, val);
|
||||
}
|
||||
|
||||
TQuantita::TQuantita(const TQuantita& q)
|
||||
{ copy(q); }
|
||||
|
||||
TQuantita::~TQuantita()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_expr
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
bool TDistinta_expr::print_error(const char* msg) const
|
||||
{
|
||||
return error_box(msg);
|
||||
}
|
||||
|
||||
TDistinta_expr::TDistinta_expr()
|
||||
: TExpression(_numexpr, FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_tree
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
const TRectype* TDistinta_tree::_curr = NULL;
|
||||
TToken_string TDistinta_tree::_tmp(80, ',');
|
||||
|
||||
bool TDistinta_tree::isola_codice(TString& code) const
|
||||
{
|
||||
int comma = code.find(',');
|
||||
if (comma > 0)
|
||||
code.cut(comma);
|
||||
return code.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::curr_code(TCodice_articolo& code) const
|
||||
{
|
||||
_path.get(-2, _tmp);
|
||||
isola_codice(_tmp);
|
||||
code = _tmp;
|
||||
return code.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::curr_giac(TString& code) const
|
||||
{
|
||||
_path.get(-2, _tmp);
|
||||
_tmp.get(1, code);
|
||||
return code.not_empty();
|
||||
}
|
||||
|
||||
int TDistinta_tree::curr_comp(TString& code) const
|
||||
{
|
||||
_path.get(-2, _tmp);
|
||||
_tmp.get(2, code);
|
||||
return atoi(code);
|
||||
}
|
||||
|
||||
long TDistinta_tree::curr_sort() const
|
||||
{
|
||||
_path.get(-2, _tmp);
|
||||
return _tmp.get_long(3);
|
||||
}
|
||||
|
||||
const char* TDistinta_tree::curr_um(TCodice_um& code) const
|
||||
{
|
||||
_path.get(-2, _tmp);
|
||||
_tmp.get(4, code);
|
||||
return code;
|
||||
}
|
||||
|
||||
real TDistinta_tree::curr_qta(bool last_only) const
|
||||
{
|
||||
real qta = 1.0;
|
||||
const int last = _path.items()-1;
|
||||
if (last > 0)
|
||||
{
|
||||
for (int i = last; i > 0; i--)
|
||||
{
|
||||
_path.get(i, _tmp);
|
||||
real val; _tmp.get(5, val);
|
||||
qta *= val;
|
||||
if (last_only || qta.is_zero())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return qta;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_node(const TString &id)
|
||||
{
|
||||
if (id != _path)
|
||||
{
|
||||
_stack.destroy();
|
||||
TToken_string str = id;
|
||||
_path = str.get(0);
|
||||
push_vars();
|
||||
for (const char* t = str.get(); t; t = str.get())
|
||||
{
|
||||
_path.add(t);
|
||||
push_vars();
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct TFind_node_data
|
||||
{
|
||||
TCodice_articolo _id;
|
||||
long _count;
|
||||
};
|
||||
|
||||
HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags)
|
||||
{
|
||||
if (flags == SCAN_PRE_ORDER)
|
||||
{
|
||||
TFind_node_data& data = *(TFind_node_data*)jolly;
|
||||
data._count++;
|
||||
TDistinta_tree& dt = (TDistinta_tree&)tree;
|
||||
TCodice_articolo id; dt.curr_code(id);
|
||||
if (data._id == id)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
long TDistinta_tree::find_node(const TCodice_articolo& str, word flags)
|
||||
{
|
||||
if (goto_root())
|
||||
{
|
||||
TFind_node_data fnd;
|
||||
fnd._id = str;
|
||||
fnd._count = 0;
|
||||
if (scan_breadth_first(find_node_callback, &fnd, flags))
|
||||
return fnd._count;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
void TDistinta_tree::node2id(const TObject* node, TString& id) const
|
||||
{
|
||||
id = *(TToken_string*)node;
|
||||
}
|
||||
|
||||
TObject* TDistinta_tree::curr_node() const
|
||||
{
|
||||
return (TObject*)&_path;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::get_description(TString& desc) const
|
||||
{
|
||||
_path.get(-2, desc);
|
||||
isola_codice(desc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TImage* TDistinta_tree::image(bool selected) const
|
||||
{
|
||||
TImage* img;
|
||||
if (is_cyclic())
|
||||
img = get_res_image(BMP_STOP);
|
||||
else
|
||||
{
|
||||
if (is_leaf())
|
||||
img = get_res_image(BMP_FILE);
|
||||
else
|
||||
img = TBidirectional_tree::image(selected);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
void TDistinta_tree::restart()
|
||||
{
|
||||
_dist.destroy();
|
||||
_rdist.destroy();
|
||||
_vars.destroy();
|
||||
_mag.destroy();
|
||||
_lav.destroy();
|
||||
shrink_all();
|
||||
goto_root();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::set_root(const TCodice_articolo& str)
|
||||
{
|
||||
const bool ok = find(str, 1) != NULL;
|
||||
if (ok)
|
||||
{
|
||||
_root = str;
|
||||
restart();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_root() const
|
||||
{
|
||||
return _root.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_root()
|
||||
{
|
||||
const bool ok = has_root();
|
||||
if (ok)
|
||||
{
|
||||
_path = _root;
|
||||
_stack.destroy();
|
||||
push_vars();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_cyclic(const TToken_string& path) const
|
||||
{
|
||||
bool cyclic = FALSE;
|
||||
const int last = path.items()-1;
|
||||
if (last > 0)
|
||||
{
|
||||
path.get(-2, _tmp);
|
||||
TCodice_articolo mycod; _tmp.get(0, mycod);
|
||||
for (int i = last-1; i >= 0; i--)
|
||||
{
|
||||
path.get(i, _tmp);
|
||||
isola_codice(_tmp);
|
||||
if (_tmp == mycod)
|
||||
{
|
||||
cyclic = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cyclic;
|
||||
}
|
||||
|
||||
static int _sort_key;
|
||||
static int compare_rdist(const TObject** o1, const TObject** o2)
|
||||
{
|
||||
const TRectype* r1 = (const TRectype*)(*o1);
|
||||
const TRectype* r2 = (const TRectype*)(*o2);
|
||||
TString16 field;
|
||||
field << "SORT" << _sort_key;
|
||||
long k1 = r1->get_long(field);
|
||||
long k2 = r2->get_long(field);
|
||||
if (k1 == 0 && k2 == 0)
|
||||
{
|
||||
k1 = r1->get_long("NRIG");
|
||||
k2 = r2->get_long("NRIG");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k1 == 0) k1 = 100000000L;
|
||||
if (k2 == 0) k2 = 100000000L;
|
||||
}
|
||||
return k1 == k2 ? 0 : (k1 > k2 ? +1 : -1);
|
||||
}
|
||||
|
||||
const TRectype* TDistinta_tree::find(const TCodice_articolo& father, int child) const
|
||||
{
|
||||
TString80 key = father;
|
||||
key << '|' << child;
|
||||
const TRectype& rec = ((TDistinta_tree*)this)->_rdist.get(key);
|
||||
return rec.empty() ? NULL : &rec;
|
||||
}
|
||||
|
||||
int TDistinta_tree::build_children_list(const TCodice_articolo& father, TPointer_array& children) const
|
||||
{
|
||||
for (int nrig = 1; ; nrig++)
|
||||
{
|
||||
const TRectype* rec = find(father, nrig);
|
||||
if (rec == NULL)
|
||||
break;
|
||||
children.add((TRectype*)rec);
|
||||
}
|
||||
const int total = children.items();
|
||||
if (total > 1)
|
||||
{
|
||||
_sort_key = _sort;
|
||||
children.sort(compare_rdist);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_son() const
|
||||
{
|
||||
if (_max_depth > 0)
|
||||
{
|
||||
const int depth = _path.items()-1;
|
||||
if (depth >= _max_depth)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (is_cyclic())
|
||||
return FALSE;
|
||||
|
||||
TCodice_articolo key; curr_code(key);
|
||||
_curr = find(key, 1);
|
||||
// Se c'e' almeno un figlio ed e' necessario ordinare
|
||||
if (_curr != NULL && _sort > 0)
|
||||
{
|
||||
TPointer_array children;
|
||||
const int total = build_children_list(key, children);
|
||||
if (total > 1)
|
||||
_curr = (TRectype*)children.objptr(0);
|
||||
}
|
||||
return _curr != NULL;
|
||||
}
|
||||
|
||||
|
||||
void TDistinta_tree::add_child()
|
||||
{
|
||||
const char tipo = _curr->get_char("TIPO");
|
||||
const TString& comp = _curr->get("CODCOMP");
|
||||
|
||||
if (tipo == 'V')
|
||||
_path.add(get_string(comp));
|
||||
else
|
||||
_path.add(comp); // Codice articolo
|
||||
|
||||
_path << ',' << _curr->get("LIVELLO");// Livello giacenza
|
||||
|
||||
long num = _curr->get_long("NRIG");
|
||||
_path << ',' << num; // Numero componente
|
||||
if (_sort > 0)
|
||||
{
|
||||
TString16 field; field << "SORT" << _sort;
|
||||
num = _curr->get_long(field);
|
||||
}
|
||||
_path << ',' << num; // Numero ordinamento
|
||||
|
||||
_path << ',' << _curr->get("UM"); // Unita' di misura
|
||||
|
||||
const TString& expr = _curr->get("EXPR");
|
||||
const real qta = evaluate_numexpr(expr);
|
||||
_path << ',' << qta; // Quantita'
|
||||
|
||||
push_vars();
|
||||
}
|
||||
|
||||
void TDistinta_tree::kill_child()
|
||||
{
|
||||
// Distrugge l'ultimo stack delle variabili
|
||||
pop_vars();
|
||||
|
||||
// Toglie l'ultimo elemento dal path
|
||||
const int pipe = _path.rfind('|');
|
||||
_path.cut(pipe);
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_firstson()
|
||||
{
|
||||
const bool ok = has_son();
|
||||
if (ok)
|
||||
add_child();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_rbrother() const
|
||||
{
|
||||
const int last = _path.items()-1;
|
||||
if (last < 1)
|
||||
return FALSE;
|
||||
|
||||
TString80 key; _path.get(last-1, key);
|
||||
isola_codice(key);
|
||||
const TCodice_articolo father(key);
|
||||
curr_comp(key);
|
||||
|
||||
if (_sort > 0)
|
||||
{
|
||||
TPointer_array children;
|
||||
const int last = build_children_list(father, children)-1;
|
||||
if (last > 0)
|
||||
{
|
||||
for (int c = last; c >= 0; c--)
|
||||
{
|
||||
const TRectype& rec = (const TRectype&)children[c];
|
||||
if (rec.get("NRIG") == key)
|
||||
break;
|
||||
}
|
||||
if (c >= 0 && c < last)
|
||||
_curr = &(TRectype&)children[c+1];
|
||||
else
|
||||
_curr = NULL;
|
||||
}
|
||||
else
|
||||
_curr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int brother = atoi(key) + 1;
|
||||
_curr = find(father, brother);
|
||||
}
|
||||
|
||||
return _curr != NULL;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_rbrother()
|
||||
{
|
||||
const bool ok = has_rbrother();
|
||||
if (ok)
|
||||
{
|
||||
kill_child();
|
||||
add_child();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_lbrother() const
|
||||
{
|
||||
const int last = _path.items()-1;
|
||||
if (last < 1)
|
||||
return FALSE;
|
||||
|
||||
TString80 key; _path.get(last-1, key);
|
||||
isola_codice(key);
|
||||
const TCodice_articolo father(key);
|
||||
curr_comp(key);
|
||||
|
||||
if (_sort > 0)
|
||||
{
|
||||
TPointer_array children;
|
||||
const int last = build_children_list(father, children)-1;
|
||||
if (last > 0)
|
||||
{
|
||||
for (int c = last; c > 0; c--)
|
||||
{
|
||||
const TRectype& rec = (const TRectype&)children[c];
|
||||
if (rec.get("NRIG") == key)
|
||||
break;
|
||||
}
|
||||
if (c > 0)
|
||||
_curr = &(TRectype&)children[c-1];
|
||||
else
|
||||
_curr = NULL;
|
||||
}
|
||||
else
|
||||
_curr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int brother = atoi(key) - 1;
|
||||
if (brother > 0)
|
||||
_curr = find(father, brother);
|
||||
else
|
||||
_curr = NULL;
|
||||
}
|
||||
|
||||
return _curr != NULL;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_lbrother()
|
||||
{
|
||||
const bool ok = has_lbrother();
|
||||
if (ok)
|
||||
{
|
||||
kill_child();
|
||||
add_child();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::has_father() const
|
||||
{
|
||||
const int items = _path.items();
|
||||
return items > 1;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::goto_father()
|
||||
{
|
||||
const bool ok = has_father();
|
||||
if (ok)
|
||||
kill_child();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_root() const
|
||||
{
|
||||
const int items = _path.items();
|
||||
return items <= 1;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_leaf() const
|
||||
{
|
||||
TCodice_articolo key; curr_code(key);
|
||||
const TRectype* first_son = find(key, 1);
|
||||
return first_son == NULL;
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_mag(const char* c) const
|
||||
{
|
||||
TCodice_articolo code = c;
|
||||
if (code.blank())
|
||||
curr_code(code);
|
||||
const TString& desc = ((TDistinta_tree*)this)->_mag.decode(code);
|
||||
return desc.not_empty();
|
||||
}
|
||||
|
||||
bool TDistinta_tree::is_lav(const char* c) const
|
||||
{
|
||||
TCodice_articolo code = c;
|
||||
if (code.blank())
|
||||
curr_code(code);
|
||||
const TString& desc = ((TDistinta_tree*)this)->_lav.decode(code);
|
||||
return desc.not_empty();
|
||||
}
|
||||
|
||||
char TDistinta_tree::get_type(const char* c) const
|
||||
{
|
||||
char type = 'V';
|
||||
if (is_mag(c))
|
||||
type = 'A';
|
||||
else
|
||||
{
|
||||
if (is_lav(c))
|
||||
type = 'L';
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
void TDistinta_tree::set_sort_key(int k)
|
||||
{
|
||||
CHECK(k >= 0 && k <= 5, "Chiave distinta errata");
|
||||
_sort = k;
|
||||
}
|
||||
|
||||
TTypeexp TDistinta_tree::get_var_type(const char* var)
|
||||
{
|
||||
const TString& vt = _vars.decode(var);
|
||||
return vt.blank() ? _strexpr : _numexpr;
|
||||
}
|
||||
|
||||
void TDistinta_tree::pop_vars()
|
||||
{
|
||||
_stack.pop();
|
||||
}
|
||||
|
||||
void TDistinta_tree::clear_globals()
|
||||
{
|
||||
_globals.destroy();
|
||||
}
|
||||
|
||||
void TDistinta_tree::set_global(const char* name, const char* val)
|
||||
{
|
||||
TString* str = new TString(val);
|
||||
_globals.add(name, str, TRUE);
|
||||
}
|
||||
|
||||
void TDistinta_tree::set_global(const char* name, const real& val)
|
||||
{
|
||||
_globals.add(name, val, TRUE);
|
||||
}
|
||||
|
||||
const TString& TDistinta_tree::get_string(const char* var)
|
||||
{
|
||||
for (int s = 0; s < _stack.count(); s++)
|
||||
{
|
||||
TAssoc_array& a = (TAssoc_array&)_stack.peek(s);
|
||||
TObject* val = a.objptr(var);
|
||||
if (val)
|
||||
{
|
||||
if (val->class_id() == CLASS_STRING)
|
||||
return (TString&)*val;
|
||||
}
|
||||
}
|
||||
TObject* val = _globals.objptr(var);
|
||||
if (val && val->class_id() == CLASS_STRING)
|
||||
return (TString&)*val;
|
||||
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
const real& TDistinta_tree::get_real(const char* var)
|
||||
{
|
||||
for (int s = 0; s < _stack.count(); s++)
|
||||
{
|
||||
TAssoc_array& a = (TAssoc_array&)_stack.peek(s);
|
||||
TObject* val = a.objptr(var);
|
||||
if (val)
|
||||
{
|
||||
if (val->class_id() != CLASS_STRING)
|
||||
return (real&)*val;
|
||||
}
|
||||
}
|
||||
|
||||
TObject* val = _globals.objptr(var);
|
||||
if (val && val->class_id() != CLASS_STRING)
|
||||
return (real&)*val;
|
||||
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
void TDistinta_tree::evaluate(TDistinta_expr& e)
|
||||
{
|
||||
for (int v = e.numvar()-1; v >= 0; v--)
|
||||
{
|
||||
const char* name = e.varname(v);
|
||||
const TTypeexp vartype = get_var_type(name);
|
||||
if (vartype == _numexpr)
|
||||
e.setvar(v, get_real(name));
|
||||
else
|
||||
e.setvar(v, get_string(name));
|
||||
}
|
||||
}
|
||||
|
||||
real TDistinta_tree::evaluate_numexpr(const char* str)
|
||||
{
|
||||
TDistinta_expr e;
|
||||
e.set(str, _numexpr);
|
||||
evaluate(e);
|
||||
return e.as_real();
|
||||
}
|
||||
|
||||
void TDistinta_tree::evaluate_strexpr(const char* str, TString& res)
|
||||
{
|
||||
TDistinta_expr e;
|
||||
e.set(str, _strexpr);
|
||||
evaluate(e);
|
||||
res = e.as_string();
|
||||
}
|
||||
|
||||
|
||||
void TDistinta_tree::push_vars()
|
||||
{
|
||||
TAssoc_array* vars = new TAssoc_array;
|
||||
_stack.push(vars);
|
||||
|
||||
TCodice_articolo var; curr_code(var);
|
||||
const TString& memo_field = _dist.decode(var);
|
||||
|
||||
if (!memo_field.blank())
|
||||
{
|
||||
TString80 expr;
|
||||
TDistinta_expr e;
|
||||
|
||||
TToken_string memo(memo_field, '\n');
|
||||
|
||||
for (const char* str = memo.get(0); str; str = memo.get())
|
||||
{
|
||||
char* equal = strchr(str, '=');
|
||||
if (equal)
|
||||
{
|
||||
*equal = '\0';
|
||||
var = str;
|
||||
expr = equal + 1;
|
||||
const TTypeexp exprtype = get_var_type(var);
|
||||
e.set(expr, exprtype);
|
||||
evaluate(e);
|
||||
|
||||
if (exprtype == _numexpr)
|
||||
vars->add(var, e.as_real());
|
||||
else
|
||||
vars->add(var, e.as_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TExplosion_params
|
||||
{
|
||||
TArray* _array;
|
||||
TString16 _filter;
|
||||
int _raggruppa;
|
||||
int _max_depth;
|
||||
int _sort_key;
|
||||
bool _materiali_base;
|
||||
bool _last_qta;
|
||||
};
|
||||
|
||||
static bool explode_callback(TTree& node, void* jolly, word when)
|
||||
{
|
||||
if (when == SCAN_PRE_ORDER)
|
||||
{
|
||||
TDistinta_tree& tree = (TDistinta_tree&)node;
|
||||
if (tree.is_root())
|
||||
return FALSE; // Don't explode roots
|
||||
|
||||
const TExplosion_params& ep = *(const TExplosion_params*)jolly;
|
||||
if (ep._materiali_base && !tree.is_leaf())
|
||||
return FALSE; // Please, leaves only
|
||||
|
||||
TRiga_esplosione er(tree, ep);
|
||||
|
||||
const char type = er.tipo();
|
||||
if (ep._filter.not_empty())
|
||||
{
|
||||
if (ep._filter.find(type) < 0)
|
||||
return FALSE;
|
||||
}
|
||||
if (ep._sort_key > 0)
|
||||
{
|
||||
if (er.ordinamento() <= 0)
|
||||
return FALSE; // Non fa parte dell'ordinamento
|
||||
}
|
||||
|
||||
ep._array->add(er);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int TDistinta_tree::raggruppa(TArray& boom, int mode) const
|
||||
{
|
||||
for (int i = 0; i < boom.items(); i++)
|
||||
{
|
||||
TRiga_esplosione& qta1 = (TRiga_esplosione&)boom[i];
|
||||
|
||||
if (mode == 2)
|
||||
qta1.convert_to_base();
|
||||
|
||||
for (int j = boom.items()-1; j > i; j--)
|
||||
{
|
||||
TRiga_esplosione& qta2 = (TRiga_esplosione&)boom[j];
|
||||
if (qta1.articolo() != qta2.articolo())
|
||||
continue;
|
||||
|
||||
if (mode == 3 && qta1.um() != qta2.um())
|
||||
continue;
|
||||
|
||||
qta1 += qta2;
|
||||
boom.destroy(j, TRUE);
|
||||
}
|
||||
}
|
||||
return boom.items();
|
||||
}
|
||||
|
||||
int TDistinta_tree::explode(TArray& boom,
|
||||
bool mb, int gr, int md,
|
||||
const char* filter, int sk,
|
||||
bool lq)
|
||||
{
|
||||
const int old_sk = get_sort_key();
|
||||
const int old_md = get_max_depth();
|
||||
if (mb) md = 0;
|
||||
|
||||
set_sort_key(sk);
|
||||
set_max_depth(md);
|
||||
|
||||
TExplosion_params ep;
|
||||
ep._array = &boom;
|
||||
ep._materiali_base = mb;
|
||||
ep._raggruppa = gr;
|
||||
ep._max_depth = md;
|
||||
ep._filter = filter;
|
||||
ep._sort_key = sk;
|
||||
ep._last_qta = lq;
|
||||
|
||||
scan_depth_first(explode_callback, &ep);
|
||||
|
||||
set_sort_key(old_sk);
|
||||
set_max_depth(old_md);
|
||||
|
||||
if (gr)
|
||||
raggruppa(boom, gr);
|
||||
|
||||
return boom.items();
|
||||
}
|
||||
|
||||
TDistinta_tree::TDistinta_tree()
|
||||
: _rdist(LF_RDIST), _sort(0), _max_depth(0),
|
||||
_dist(LF_DIST, "PARAMETRI"), _vars("VAR", "B0"),
|
||||
_mag(LF_ANAMAG, "DESCR"), _lav("LAV")
|
||||
{
|
||||
}
|
||||
|
||||
TDistinta_tree::~TDistinta_tree()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TRiga_esplosione
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void TRiga_esplosione::init(const TDistinta_tree& tree,
|
||||
const TExplosion_params& ep)
|
||||
{
|
||||
TCodice_articolo art; tree.curr_code(art);
|
||||
TCodice_um um; tree.curr_um(um);
|
||||
real val = tree.curr_qta(ep._last_qta);
|
||||
set(art, um, val);
|
||||
tree.curr_giac(_giac);
|
||||
_tipo = tree.get_type(art);
|
||||
_sort = tree.curr_sort();
|
||||
_livello = tree.curr_depth();
|
||||
}
|
||||
|
||||
TRiga_esplosione::TRiga_esplosione(const TDistinta_tree& tree,
|
||||
const TExplosion_params& ep)
|
||||
{
|
||||
init(tree, ep);
|
||||
}
|
||||
|
||||
TRiga_esplosione::TRiga_esplosione(const TRiga_esplosione& re)
|
||||
: TQuantita(re)
|
||||
{
|
||||
_giac = re._giac;
|
||||
_tipo = re._tipo;
|
||||
_livello = re._livello;
|
||||
_sort = re._sort;
|
||||
}
|
258
db/dblib.h
Executable file
258
db/dblib.h
Executable file
@ -0,0 +1,258 @@
|
||||
#ifndef __DBLIB_H
|
||||
#define __DBLIB_H
|
||||
|
||||
#ifndef __EXPR_H
|
||||
#include <expr.h>
|
||||
#endif
|
||||
|
||||
#ifndef __RECARRAY_H
|
||||
#include <recarray.h>
|
||||
#endif
|
||||
|
||||
#ifndef __TREE_H
|
||||
#include <tree.h>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TCodice_articolo
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Codice articolo di magazzino (equivale ad una TString20 )
|
||||
class TCodice_articolo : public TFixed_string
|
||||
{
|
||||
char _str20[21];
|
||||
|
||||
public:
|
||||
TCodice_articolo(const char* s = "") : TFixed_string(_str20, 21)
|
||||
{ set(s); }
|
||||
TCodice_articolo(const TString& s) : TFixed_string(_str20, 21)
|
||||
{ set(s); }
|
||||
TCodice_articolo(const TCodice_articolo& s) : TFixed_string(_str20, 21)
|
||||
{ set(s); }
|
||||
const TString& operator =(const char* s)
|
||||
{ return set(s); }
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set((const char*)s); }
|
||||
const TString& operator =(const TCodice_articolo& s)
|
||||
{ return set((const char*)s); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TCodice_um
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Codice articolo di magazzino (equivale ad una TString2 )
|
||||
class TCodice_um : public TFixed_string
|
||||
{
|
||||
char _str2[3];
|
||||
|
||||
public:
|
||||
TCodice_um(const char* s = "") : TFixed_string(_str2, 3)
|
||||
{ set(s); }
|
||||
TCodice_um(const TString& s) : TFixed_string(_str2, 3)
|
||||
{ set(s); }
|
||||
TCodice_um(const TCodice_um& s) : TFixed_string(_str2, 3)
|
||||
{ set(s); }
|
||||
const TString& operator =(const char* s)
|
||||
{ return set(s); }
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set((const char*)s); }
|
||||
const TString& operator =(const TCodice_um& s)
|
||||
{ return set((const char*)s); }
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TQuantita'
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Quantita' di un articolo in una certa unita' di misura
|
||||
|
||||
class TQuantita : public TSortable
|
||||
{
|
||||
TCodice_articolo _articolo; // Articolo di riferimento
|
||||
TCodice_um _um; // Unita' di misura
|
||||
real _conv; // Fattore di conversione alla base
|
||||
real _val; // Valore attuale
|
||||
|
||||
static TDecoder* _umart1; // Decoder per trovare unita' base
|
||||
static TDecoder* _umart2; // Decoder per trovare conversione
|
||||
|
||||
protected:
|
||||
virtual int compare(const TSortable& s) const;
|
||||
virtual TObject* dup() const { return new TQuantita(*this); }
|
||||
|
||||
void copy(const TQuantita& q);
|
||||
real get_factor(const TCodice_um& um) const;
|
||||
void convert(real& val, const TCodice_um& from_um, const TCodice_um& to_um) const;
|
||||
|
||||
public:
|
||||
virtual bool ok() const { return !_um.blank(); }
|
||||
|
||||
const TQuantita& operator =(const TQuantita& q)
|
||||
{ copy(q); return q; }
|
||||
|
||||
const TQuantita& operator +=(const TQuantita& q);
|
||||
const TQuantita& operator -=(const TQuantita& q);
|
||||
const TQuantita& operator =(const real& q);
|
||||
const TQuantita& operator *=(const real& q);
|
||||
const TQuantita& operator /=(const real& q);
|
||||
|
||||
const TCodice_articolo& articolo() const { return _articolo; }
|
||||
const TCodice_um& um() const { return _um; }
|
||||
const real& val() const { return _val; }
|
||||
|
||||
void set_articolo(const TCodice_articolo& art, const TCodice_um& um);
|
||||
void set(const TCodice_articolo& art, const TCodice_um& um, const real& val)
|
||||
{ set_articolo(art, um); _val = val; }
|
||||
|
||||
void convert_to_base();
|
||||
|
||||
TQuantita();
|
||||
TQuantita(const TCodice_articolo& art);
|
||||
TQuantita(const TCodice_articolo& art, const TCodice_um& um, const real& val);
|
||||
TQuantita(const TQuantita& q);
|
||||
virtual ~TQuantita();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_expr
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TDistinta_expr : public TExpression
|
||||
{
|
||||
protected:
|
||||
virtual bool print_error(const char* msg) const;
|
||||
|
||||
public:
|
||||
TDistinta_expr();
|
||||
virtual ~TDistinta_expr() { }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TDistinta_tree
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TDistinta_tree : public TBidirectional_tree
|
||||
{
|
||||
TCodice_articolo _root;
|
||||
TToken_string _path;
|
||||
int _sort, _max_depth;
|
||||
|
||||
TDecoder _dist, _vars, _mag, _lav;
|
||||
TRecord_cache _rdist;
|
||||
|
||||
static const TRectype* _curr;
|
||||
static TToken_string _tmp;
|
||||
|
||||
TStack _stack;
|
||||
TAssoc_array _globals;
|
||||
|
||||
protected:
|
||||
bool isola_codice(TString& code) const;
|
||||
|
||||
void add_child();
|
||||
void kill_child();
|
||||
const TRectype* find(const TCodice_articolo& father, int child) const;
|
||||
int build_children_list(const TCodice_articolo& father, TPointer_array& child) const;
|
||||
|
||||
TTypeexp get_var_type(const char* var);
|
||||
const TString& get_string(const char* var);
|
||||
const real& get_real(const char* var);
|
||||
|
||||
void evaluate(TDistinta_expr& e);
|
||||
real evaluate_numexpr(const char* str);
|
||||
void evaluate_strexpr(const char* str, TString& res);
|
||||
|
||||
void push_vars();
|
||||
void pop_vars();
|
||||
int raggruppa(TArray& boom, int mode) const;
|
||||
|
||||
protected: // TTree
|
||||
virtual void node2id(const TObject* node, TString& id) const;
|
||||
|
||||
public:
|
||||
virtual bool goto_root();
|
||||
virtual bool goto_firstson();
|
||||
virtual bool goto_rbrother();
|
||||
virtual bool goto_node(const TString &id);
|
||||
virtual bool has_son() const;
|
||||
virtual bool has_rbrother() const;
|
||||
virtual bool has_root() const;
|
||||
virtual bool has_father() const;
|
||||
virtual bool has_lbrother() const;
|
||||
virtual bool goto_father();
|
||||
virtual bool goto_lbrother();
|
||||
virtual bool get_description(TString& desc) const;
|
||||
virtual TImage* image(bool selected) const;
|
||||
virtual TObject* curr_node() const;
|
||||
|
||||
bool set_root(const TCodice_articolo& str);
|
||||
long find_node(const TCodice_articolo& str, word flags = SCAN_PRE_ORDER);
|
||||
|
||||
void set_sort_key(int k);
|
||||
int get_sort_key() const { return _sort; }
|
||||
|
||||
void set_max_depth(int m) { _max_depth = m; }
|
||||
int get_max_depth() const { return _max_depth; }
|
||||
|
||||
void restart(); // reset all and go to root
|
||||
int explode(TArray& boom, bool mb = FALSE, int gr = 0, int md = 0,
|
||||
const char* filter = NULL, int sk = 0, bool lq = FALSE);
|
||||
|
||||
bool curr_code(TCodice_articolo& code) const;
|
||||
bool curr_giac(TString& code) const;
|
||||
int curr_comp(TString& code) const;
|
||||
long curr_sort() const;
|
||||
const char* curr_um(TCodice_um& code) const;
|
||||
real curr_qta(bool last = FALSE) const;
|
||||
int curr_depth() const { return _path.items()-1; }
|
||||
|
||||
bool is_cyclic(const TToken_string& path) const;
|
||||
bool is_cyclic() const { return is_cyclic(_path); }
|
||||
bool is_root() const;
|
||||
bool is_leaf() const;
|
||||
|
||||
bool is_mag(const char* c = NULL) const;
|
||||
bool is_lav(const char* c = NULL) const;
|
||||
char get_type(const char* c = NULL) const;
|
||||
|
||||
void clear_globals();
|
||||
void set_global(const char* var, const char* val);
|
||||
void set_global(const char* var, const real& val);
|
||||
|
||||
TDistinta_tree();
|
||||
virtual ~TDistinta_tree();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TRiga_esplosione
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
struct TExplosion_params;
|
||||
|
||||
class TRiga_esplosione : public TQuantita
|
||||
{
|
||||
TString16 _giac;
|
||||
long _sort;
|
||||
int _livello;
|
||||
char _tipo;
|
||||
|
||||
protected:
|
||||
virtual TObject* dup() const { return new TRiga_esplosione(*this); }
|
||||
void init(const TDistinta_tree& tree, const TExplosion_params& ep);
|
||||
|
||||
public:
|
||||
const TString& giacenza() const { return _giac; }
|
||||
long ordinamento() const { return _sort; }
|
||||
int livello() const { return _livello; }
|
||||
char tipo() const { return _tipo; }
|
||||
|
||||
TRiga_esplosione();
|
||||
TRiga_esplosione(const TDistinta_tree& tree,
|
||||
const TExplosion_params& ep);
|
||||
TRiga_esplosione(const TRiga_esplosione& re);
|
||||
virtual ~TRiga_esplosione() { }
|
||||
};
|
||||
|
||||
#endif
|
@ -1,3 +1,3 @@
|
||||
113
|
||||
0
|
||||
$rdist|0|0|119|0|Righe distinta|||
|
||||
$rdist|0|0|154|0|Righe distinta|||
|
||||
|
13
db/f113.trr
13
db/f113.trr
@ -1,16 +1,17 @@
|
||||
113
|
||||
11
|
||||
12
|
||||
CODDIST|1|20|0|Codice distinta
|
||||
NRIG|2|4|0|Numero di riga
|
||||
TIPO|1|1|0|Tipo componente <A>rticolo, <L>avorazione, <D>istinta
|
||||
CODCOMP|1|20|0|Codice componente
|
||||
LIVELLO|1|15|0|Livello di giacenza
|
||||
UM|1|3|0|Unita' di misura
|
||||
EXPR|1|50|0|Espressione quantita'
|
||||
SORT1|2|4|0|Ordinamento 1
|
||||
SORT2|2|4|0|Ordinamento 2
|
||||
SORT3|2|4|0|Ordinamento 3
|
||||
SORT4|2|4|0|Ordinamento 4
|
||||
SORT5|2|4|0|Ordinamento 5
|
||||
SORT1|3|8|0|Ordinamento 1
|
||||
SORT2|3|8|0|Ordinamento 2
|
||||
SORT3|3|8|0|Ordinamento 3
|
||||
SORT4|3|8|0|Ordinamento 4
|
||||
SORT5|3|8|0|Ordinamento 5
|
||||
2
|
||||
CODDIST+NRIG|
|
||||
CODCOMP+CODDIST|X
|
||||
|
Loading…
x
Reference in New Issue
Block a user