1562 lines
40 KiB
C++
1562 lines
40 KiB
C++
#include <automask.h>
|
||
#include <colors.h>
|
||
#include <controls.h>
|
||
#include <execp.h>
|
||
#include <printer.h>
|
||
#include <relapp.h>
|
||
#include <utility.h>
|
||
|
||
#include "sl0100a.h"
|
||
#include "sl0101.h"
|
||
#include "sl0200.h"
|
||
|
||
#include "../ca/calib01.h"
|
||
#include "../ve/velib.h"
|
||
|
||
#include "../db/rdist.h"
|
||
#include "../mg/anamag.h"
|
||
#include "../ca/commesse.h"
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TSAL_app
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TSAL_app : public TRelation_application
|
||
{
|
||
TMask* _qmsk;
|
||
TMask* _emsk;
|
||
TRelation* _rel;
|
||
|
||
protected:
|
||
int save_rows(const TMask& m);
|
||
virtual const char* extra_modules() const { return "ci"; }
|
||
const char* record_description(const TRelation& r) const;
|
||
bool save_and_print(TPrtype mode);
|
||
|
||
public:
|
||
virtual bool user_create();
|
||
virtual bool user_destroy();
|
||
virtual bool changing_mask(int mode) { return true; }
|
||
virtual TMask* get_mask(int mode) { return mode == MODE_QUERY ? _qmsk : _emsk; }
|
||
virtual TRelation* get_relation() const { return _rel; }
|
||
virtual bool has_filtered_cursor() const { return true; }
|
||
virtual TCursor& get_filtered_cursor() const;
|
||
|
||
virtual bool get_next_key(TToken_string& key);
|
||
virtual void init_insert_mode(TMask& m);
|
||
virtual void init_modify_mode(TMask& m);
|
||
|
||
virtual int read(TMask& m);
|
||
virtual int write(const TMask& m);
|
||
virtual int rewrite(const TMask& m);
|
||
virtual bool remove();
|
||
|
||
virtual void print();
|
||
bool report(const char* name);
|
||
|
||
void update_tools(TMask& m);
|
||
};
|
||
|
||
inline TSAL_app& app() { return (TSAL_app&)main_app(); }
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TSAL_msk
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Classe di base per maschere preventivi (query ed edit)
|
||
class TSAL_msk : public TAutomask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
virtual TMask_field* parse_field(TScanner& s);
|
||
|
||
public:
|
||
const TString& fget(const char* fld) const;
|
||
void fset(const char* fld, const TString& val, int hit=0x0);
|
||
|
||
TSAL_msk(const char* name) { read_mask(name, 0, 8); set_handlers(); }
|
||
};
|
||
|
||
TMask_field* TSAL_msk::parse_field(TScanner& s)
|
||
{
|
||
if (s.key() == "TL")
|
||
set_full_screen_interface(page_win(1), true);
|
||
return TAutomask::parse_field(s);
|
||
}
|
||
|
||
// Legge il valore di un campo multiplo (commessa, fase, ...) da maschera e lo restituisce come unico valore
|
||
const TString& TSAL_msk::fget(const char* fld) const
|
||
{
|
||
TString& val = get_tmp_string();
|
||
FOR_EACH_MASK_FIELD(*this, i, f)
|
||
{
|
||
const TFieldref* fr = f->field();
|
||
if (fr != NULL && fr->name() == fld)
|
||
{
|
||
if (fr->from() > 0 || fr->to() > 0)
|
||
val.overwrite(f->get(), fr->from());
|
||
else
|
||
{
|
||
val = f->get();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return val;
|
||
}
|
||
|
||
// Spezza un valore unico su pi<70> sottocampi (commessa, fase, ...)
|
||
void TSAL_msk::fset(const char* fld, const TString& val, int hit)
|
||
{
|
||
FOR_EACH_MASK_FIELD(*this, i, f)
|
||
{
|
||
const TFieldref* fr = f->field();
|
||
if (fr != NULL && fr->name() == fld)
|
||
{
|
||
if (fr->from() > 0 || fr->to() > 0)
|
||
{
|
||
const TString& str = val.sub(fr->from(), fr->to());
|
||
f->set(str);
|
||
}
|
||
else
|
||
f->set(val);
|
||
if ((f->active() || f->ghost()))
|
||
{
|
||
f->set_dirty();
|
||
if (hit & 0x2)
|
||
f->check();
|
||
if (hit & 0x1)
|
||
f->on_hit();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
bool TSAL_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
// switch (o.dlg())
|
||
// {
|
||
// default:
|
||
if ((e == fe_modify || e == fe_close) && (!o.empty() && o.is_edit()))
|
||
{
|
||
const TFieldref* fr = o.field();
|
||
if (fr != NULL && fr->name() == RDOC_CODCMS)
|
||
{
|
||
const TString& cms = fget(RDOC_CODCMS);
|
||
const TRectype& rec = cache().get(LF_COMMESSE, cms);
|
||
if (rec.get_bool(COMMESSE_CHIUSA))
|
||
return error_box(FR("Impossibile utilizzare la commessa chiusa %s"), (const char*)cms);
|
||
}
|
||
}
|
||
// break;
|
||
// }
|
||
return true;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TSAL_qmsk
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TSAL_qmsk : public TSAL_msk
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
bool choose_best(TCursor& cur, const char* codtab);
|
||
|
||
public:
|
||
TSAL_qmsk();
|
||
};
|
||
|
||
// Inizialmente seleziona solo i documenti cliente
|
||
static const char* m_tipocf = "C";
|
||
|
||
static bool tipoc_filter(const TRelation* rel)
|
||
{
|
||
const TCodice_numerazione& codnum = cached_numerazione(rel->curr().get("CODTAB"));
|
||
for (int i = 0; ; i++)
|
||
{
|
||
const TString& td = codnum.tipo_doc(i);
|
||
if (td.blank())
|
||
break;
|
||
const TTipo_documento& tipodoc = cached_tipodoc(td);
|
||
TFilename ini; tipodoc.profile_name(ini);
|
||
if (ini.custom_path())
|
||
{
|
||
const TString& tipocf = ini_get_string(ini, "MAIN", "TIPOCF");
|
||
if (tipocf == m_tipocf)
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// Seleziona solo gli ordini
|
||
static bool ord_filter(const TRelation* rel)
|
||
{ return rel->curr().get_int("I1") == 3 && tipoc_filter(rel); }
|
||
|
||
// Seleziona solo le bolle
|
||
static bool sal_filter(const TRelation* rel)
|
||
{ return rel->curr().get_int("I1") == 1 && tipoc_filter(rel); }
|
||
|
||
bool TSAL_qmsk::choose_best(TCursor& cur, const char* codtab)
|
||
{
|
||
const TRecnotype recs = cur.items();
|
||
if (recs > 0)
|
||
{
|
||
cur.freeze();
|
||
TRecnotype best = 0;
|
||
double score = 0;
|
||
for (cur = 0L; cur.pos() < recs; ++cur)
|
||
{
|
||
const TString& cod = cur.curr().get("CODTAB");
|
||
const double s = xvt_str_fuzzy_compare(cod, codtab);
|
||
if (s > score)
|
||
{
|
||
score = s;
|
||
best = cur.pos();
|
||
}
|
||
}
|
||
cur = best;
|
||
cur.freeze(false);
|
||
}
|
||
return recs > 0;
|
||
}
|
||
|
||
bool TSAL_qmsk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case F_TIPOCF:
|
||
if (e == fe_modify)
|
||
{
|
||
m_tipocf = get(F_TIPOCF); // Seleziona Clienti o Fornitori
|
||
on_field_event(efield(F_CODNUM_ORD), fe_init, 0);
|
||
on_field_event(efield(F_CODNUM), fe_init, 0);
|
||
}
|
||
break;
|
||
case F_CODNUM_ORD:
|
||
if (e == fe_init)
|
||
{
|
||
TEdit_field& codnum_ord = (TEdit_field&)o;
|
||
TCursor& cur_ord = *codnum_ord.browse()->cursor();
|
||
cur_ord.set_filterfunction(ord_filter);
|
||
if (choose_best(cur_ord, "ORC"))
|
||
codnum_ord.browse()->do_output(STARTING_CHECK);
|
||
}
|
||
break;
|
||
case F_CODNUM:
|
||
if (e == fe_init)
|
||
{
|
||
TEdit_field& codnum_sal = (TEdit_field&)o;
|
||
TCursor& cur_sal = *codnum_sal.browse()->cursor();
|
||
cur_sal.set_filterfunction(sal_filter);
|
||
if (choose_best(cur_sal, "SAL"))
|
||
{
|
||
codnum_sal.browse()->do_output(RUNNING_CHECK);
|
||
e = fe_modify;
|
||
}
|
||
}
|
||
if (e == fe_modify && !o.empty())
|
||
{
|
||
const TString& sal = o.get();
|
||
const TCodice_numerazione& codnum = cached_numerazione(sal);
|
||
int best = 0;
|
||
double score = 0;
|
||
for (int i = 0; ; i++)
|
||
{
|
||
const TString& td = codnum.tipo_doc(i);
|
||
if (td.blank())
|
||
break;
|
||
const double s = xvt_str_fuzzy_compare(td, sal);
|
||
if (s > score)
|
||
{
|
||
score = s;
|
||
best = i;
|
||
}
|
||
}
|
||
set(F_TIPODOC, codnum.tipo_doc(best), 0x2);
|
||
}
|
||
break;
|
||
case F_NSAL:
|
||
if (e == fe_modify && !o.empty())
|
||
{
|
||
static bool blocked = false;
|
||
if (!blocked)
|
||
{
|
||
blocked = true;
|
||
const int nsal = atoi(o.get());
|
||
TEdit_field& fld_nsal = efield(F_NDOC);
|
||
TCursor& cur_nsal = *fld_nsal.browse()->cursor();
|
||
int n = 0;
|
||
for (cur_nsal = 0L; cur_nsal.ok(); ++cur_nsal)
|
||
{
|
||
n = cur_nsal.curr().get_int(DOC_NUMANT);
|
||
if (n == nsal)
|
||
break;
|
||
}
|
||
|
||
if (nsal > n)
|
||
{
|
||
o.reset();
|
||
send_key(K_SPACE, DLG_NEWREC, &o);
|
||
}
|
||
else
|
||
{
|
||
fld_nsal.browse()->do_output();
|
||
stop_run(K_AUTO_ENTER);
|
||
}
|
||
blocked = false;
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
if (e == fe_modify && o.is_edit() && o.dlg() > F_CDC0) // Probabile commessa?
|
||
{
|
||
const TFieldref* fr = o.field();
|
||
if (fr != NULL && fr->name() == DOC_CODCMS) // Campo commessa
|
||
{
|
||
const TRectype& cur = ((TEdit_field&)o).browse()->cursor()->curr();
|
||
const long codcf = cur.get_long(COMMESSE_CODCF);
|
||
if (codcf > 0) set(F_CLIFO, codcf);
|
||
const int anno = cur.get_int(COMMESSE_ANNO);
|
||
if (anno > 0) set(F_ANNO_ORD, anno);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return TSAL_msk::on_field_event(o, e, jolly);
|
||
}
|
||
|
||
TSAL_qmsk::TSAL_qmsk() : TSAL_msk("sl0100a")
|
||
{
|
||
TMask_field& cdc0 = field(F_CDC0);
|
||
RCT rct0; cdc0.get_rect(rct0);
|
||
const int yca = rct0.top / ROWY + 1; // Riga del primo campo di analitica
|
||
short idcdc, idcms, idfase, idconto;
|
||
ca_create_fields_ext(*this, 0, 2, yca, F_CDC0+1, idcdc, idcms, idfase, idconto,
|
||
DOC_CODCOSTO, DOC_CODCMS /*, DOC_FASCMS */); // Niente fasi qui!
|
||
set_handlers();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TSAL_emsk
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TSAL_emsk : public TSAL_msk
|
||
{
|
||
TSAL_tree* _tree;
|
||
TString80 _idfase, _iddist, _edit_fase;
|
||
int _edit_dist, _edit_misu;
|
||
int _curr_dist, _curr_misu;
|
||
bool _locked;
|
||
|
||
private:
|
||
// bool on_fasi_button(TOperable_field& btn, TField_event e, long jolly);
|
||
bool on_fasi_event(TTree_field& s, TField_event e, long jolly);
|
||
bool set_fase(const TString& idf);
|
||
bool set_dist(const TString& idd);
|
||
bool set_dist(int row);
|
||
|
||
void update_dist(const real& val, const TDate& dt);
|
||
void update_dist_qta();
|
||
|
||
bool on_misu_event(TOperable_field& o, TField_event e, long jolly);
|
||
bool on_dist_event(TOperable_field& o, TField_event e, long jolly);
|
||
|
||
protected:
|
||
virtual bool on_key(KEY k);
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
void set_sheet_color(short id, COLOR col);
|
||
bool sync_totdoc();
|
||
bool sync_tree();
|
||
bool msk2rec(const TMask& msk, TRectype& rec) const;
|
||
|
||
public:
|
||
TSAL_tree& tree(bool reset = false);
|
||
|
||
TSAL_emsk();
|
||
};
|
||
|
||
TSAL_tree& TSAL_emsk::tree(bool reset)
|
||
{
|
||
if (_tree == NULL)
|
||
{
|
||
_tree = new TSAL_tree(tfield(F_FASI));
|
||
reset = true;
|
||
}
|
||
if (reset)
|
||
{
|
||
TRectype doc(LF_DOC);
|
||
doc.put(DOC_PROVV, 'D');
|
||
doc.put(DOC_ANNO, get(F_ANNO));
|
||
doc.put(DOC_CODNUM, get(F_CODNUM));
|
||
doc.put(DOC_NDOC, get(F_NDOC));
|
||
_tree->append_row(doc);
|
||
TTree_field& tf = tfield(F_FASI);
|
||
tf.set_tree(_tree);
|
||
tf.hide_leaves();
|
||
}
|
||
return *_tree;
|
||
}
|
||
|
||
static bool rec2field(TMask_field& f, const TRectype& rec)
|
||
{
|
||
const TFieldref* fr = f.field();
|
||
if (fr == NULL)
|
||
return false;
|
||
|
||
if (fr->name() == RDOC_DESCR)
|
||
{
|
||
TString descr(255);
|
||
descr = rec.get(RDOC_DESCR);
|
||
if (rec.get_bool(RDOC_DESCLUNGA))
|
||
descr << rec.get(RDOC_DESCEST);
|
||
f.set(descr);
|
||
}
|
||
else
|
||
{
|
||
const TString& val = fr->read(rec);
|
||
f.set(val);
|
||
if (!f.empty() && f.is_edit() && f.shown())
|
||
{
|
||
const TBrowse* b = ((TEdit_field&)f).browse();
|
||
if (b != NULL)
|
||
{
|
||
const TFixed_string inf = b->get_input_fields();
|
||
const TFixed_string outf = b->get_output_fields();
|
||
if (outf.find('|') > 0) // C'<27> un pipe nell'output, per cui ci sono almeno due campi di output
|
||
{
|
||
f.check(STARTING_CHECK);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
static bool chk_field(TMask_field& f)
|
||
{
|
||
const TFieldref* fr = f.field();
|
||
if (fr == NULL)
|
||
{
|
||
if (f.ghost())
|
||
return f.on_hit();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Riempie gli sheet di articoli e misure della distinta selezionata
|
||
bool TSAL_emsk::set_dist(const TString& idd)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
|
||
bool ok = idd.full();
|
||
if (_iddist != idd)
|
||
{
|
||
_iddist = idd;
|
||
|
||
// Svuota sheet misure
|
||
TSheet_field& s = sfield(F_MISURE);
|
||
s.hide();
|
||
s.destroy();
|
||
|
||
// Scandisce i figli della distinta e li smista tra i due sheet
|
||
ok = idd.full() && t.goto_node(idd);
|
||
if (ok)
|
||
{
|
||
_locked = true; // Diabilita ricalcolo prezzi
|
||
int n = 0;
|
||
for (bool ok = t.goto_firstson(); ok; ok = t.goto_rbrother())
|
||
{
|
||
const TRectype& rec = *t.curr_row();
|
||
TMask& m = s.sheet_row_mask(n);
|
||
FOR_EACH_MASK_FIELD(m, i, f) if (f->field())
|
||
rec2field(*f, rec);
|
||
FOR_EACH_MASK_FIELD(m, i, c) if (c->is_edit())
|
||
chk_field(*c);
|
||
s.update_row(n++);
|
||
}
|
||
_locked = false;
|
||
}
|
||
|
||
// Visualizza nuovamente lo sheet eventualemente riempito
|
||
s.force_update(); s.show();
|
||
}
|
||
|
||
_curr_dist = -1;
|
||
if (ok && t.goto_node(idd))
|
||
{
|
||
_curr_dist = 0;
|
||
while(t.goto_lbrother())
|
||
_curr_dist++;
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TSAL_emsk::set_dist(int row)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
bool ok = _idfase.full() && t.dist(_idfase, row) != NULL;
|
||
if (ok)
|
||
{
|
||
TString16 idd; t.curr_id(idd);
|
||
ok = set_dist(idd);
|
||
CHECK(ok && row == _curr_dist, "Distinta sospetta");
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
// Riempie lo sheet delle distinte della fase selezionata
|
||
bool TSAL_emsk::set_fase(const TString& idfase)
|
||
{
|
||
_idfase = idfase;
|
||
|
||
// Svuota lo sheet delle distinte
|
||
TSheet_field& d = sfield(F_DISTINTE);
|
||
d.destroy();
|
||
|
||
TString idd;
|
||
TSAL_tree& t = tree();
|
||
bool ok = idfase.full() && t.goto_node(idfase);
|
||
if (ok)
|
||
{
|
||
// Scandisce le distinte della fase corrente
|
||
if (t.goto_firstson())
|
||
{
|
||
t.curr_id(idd); // Memorizza la prima distinta per dopo...
|
||
int n = 0;
|
||
do
|
||
{
|
||
const TRectype& rec = *t.curr_row();
|
||
TMask& m = d.sheet_row_mask(n);
|
||
FOR_EACH_MASK_FIELD(m, i, f) if (f->field())
|
||
rec2field(*f, rec);
|
||
FOR_EACH_MASK_FIELD(m, i, c) if (c->is_edit())
|
||
chk_field(*c);
|
||
d.update_row(n++);
|
||
} while (t.goto_rbrother());
|
||
}
|
||
}
|
||
d.force_update();
|
||
set_dist(idd);
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TSAL_emsk::msk2rec(const TMask& msk, TRectype& rec) const
|
||
{
|
||
TRelation rel(rec.num());
|
||
rel.curr() = rec;
|
||
msk.autosave(rel);
|
||
rec = rel.curr();
|
||
const TString& desc = msk.get(RDOC_DESCR);
|
||
const int maxlen = rec.length(RDOC_DESCR);
|
||
int spc = desc.find('\n');
|
||
if (spc >= 0 || desc.len() > maxlen)
|
||
{
|
||
if (spc < 0 || spc > maxlen)
|
||
{
|
||
spc = desc.left(maxlen).rfind(' ');
|
||
if (spc < maxlen/2)
|
||
spc = maxlen;
|
||
}
|
||
rec.put(RDOC_DESCR, desc.left(spc));
|
||
rec.put(RDOC_DESCLUNGA, "X");
|
||
rec.put(RDOC_DESCEST, desc.mid(spc));
|
||
}
|
||
else
|
||
{
|
||
rec.put(RDOC_DESCR, desc);
|
||
rec.zero(RDOC_DESCLUNGA);
|
||
rec.put(RDOC_DESCEST, "");
|
||
}
|
||
return !rec.empty();
|
||
}
|
||
|
||
bool TSAL_emsk::on_key(KEY k)
|
||
{
|
||
if (k == K_SHIFT + K_F12)
|
||
{
|
||
enable(F_STATO);
|
||
return true;
|
||
}
|
||
return TAutomask::on_key(k);
|
||
}
|
||
|
||
/*
|
||
bool TSAL_emsk::on_fasi_button(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
TTree_field& fasi = t.owner();
|
||
|
||
TSAL_level pl = sl_documento;
|
||
if (fasi.goto_selected())
|
||
pl = t.level();
|
||
else
|
||
return false;
|
||
|
||
if (pl == sl_documento && o.dlg() == F_FASENEW)
|
||
pl = sl_fase1;
|
||
|
||
if (pl < sl_fase1 || pl > sl_distinta)
|
||
return false;
|
||
|
||
o.disable();
|
||
switch (o.dlg())
|
||
{
|
||
case F_FASENEW:
|
||
{
|
||
TMask m("Nuovo", 1, 46, 7);
|
||
m.add_string(S_CODART, 0, "Codice ", 1, 1, 20).check_type(CHECK_REQUIRED);
|
||
m.add_string(S_DESCR, 0, "Descrizione ", 1, 2, 50, "", 30).check_type(CHECK_REQUIRED);
|
||
m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
|
||
m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
|
||
if (m.run() == K_ENTER)
|
||
{
|
||
TRectype* rec = t.new_row(pl);
|
||
rec->put(RDOC_CODART, m.get(S_CODART));
|
||
rec->put(RDOC_DESCR, m.get(S_DESCR));
|
||
if (tree().level() == pl)
|
||
t.add_rbrother(rec);
|
||
else
|
||
{
|
||
t.append_row(*rec);
|
||
delete rec;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case F_FASEDIT:
|
||
{
|
||
TRectype& rec = *t.curr_row();
|
||
TMask m("Modifica", 1, 46, 7);
|
||
m.add_string(S_CODART, 0, "Codice ", 1, 1, 20).check_type(CHECK_REQUIRED);
|
||
m.add_string(S_DESCR, 0, "Descrizione ", 1, 2, 50, "", 30).check_type(CHECK_REQUIRED);
|
||
m.add_button(DLG_OK, 0, "", -13, -1, 10, 2);
|
||
m.add_button(DLG_DELREC, 0, "", -23, -1, 10, 2);
|
||
m.add_button(DLG_CANCEL, 0, "", -33, -1, 10, 2);
|
||
m.set(S_CODART, rec.get(RDOC_CODART));
|
||
m.set(S_DESCR, rec.get(RDOC_DESCR));
|
||
switch (m.run())
|
||
{
|
||
case K_ENTER:
|
||
rec.put(RDOC_CODART, m.get(S_CODART));
|
||
rec.put(RDOC_DESCR, m.get(S_DESCR));
|
||
break;
|
||
case K_DEL:
|
||
t.kill_node();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
o.enable();
|
||
fasi.select_current();
|
||
fasi.force_update();
|
||
return true;
|
||
}
|
||
*/
|
||
|
||
bool TSAL_emsk::on_fasi_event(TTree_field& fasi, TField_event e, long jolly)
|
||
{
|
||
bool modified = false;
|
||
bool can_edit = false;
|
||
bool can_goup = false;
|
||
bool can_godn = false;
|
||
|
||
switch (e)
|
||
{
|
||
case fe_modify:
|
||
if (fasi.goto_selected())
|
||
{
|
||
modified = true;
|
||
TSAL_tree& t = tree();
|
||
TSAL_level td = t.level();
|
||
if (td > sl_documento)
|
||
{
|
||
can_edit = true;
|
||
can_goup = t.has_lbrother();
|
||
can_godn = t.has_rbrother();
|
||
if (td < sl_distinta) // Cambio fase
|
||
{
|
||
TString16 id;
|
||
t.curr_id(id);
|
||
set_fase(id);
|
||
}
|
||
else
|
||
{
|
||
while (td > sl_distinta)
|
||
{
|
||
t.goto_father();
|
||
td = t.level();
|
||
}
|
||
TString idd; t.curr_id(idd);
|
||
if (t.goto_father())
|
||
{
|
||
TString idf; t.curr_id(idf);
|
||
if (idf != _idfase)
|
||
set_fase(idf);
|
||
}
|
||
set_dist(idd);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// if (modified) enable(F_FASEDIT, can_edit);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TSAL_emsk::on_dist_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case S_CODART:
|
||
if (e == fe_modify && !o.empty())
|
||
{
|
||
const TString& codart = o.get();
|
||
TMask& m = o.mask();
|
||
|
||
TToken_string tok; tok << codart << "|1";
|
||
const TString& um = cache().get(LF_UMART, tok, "UM");
|
||
if (um.full())
|
||
m.set(S_UMART, um);
|
||
|
||
TEdit_field& iva = m.efield(S_CODIVA);
|
||
if (iva.empty())
|
||
on_dist_event(iva, fe_init, jolly);
|
||
}
|
||
break;
|
||
case S_CODIVA:
|
||
if ((e == fe_init || e == fe_close) && o.empty())
|
||
{
|
||
const TString& codcms = fget(DOC_CODCMS);
|
||
TString4 codiva = cache().get(LF_COMMESSE, codcms, COMMESSE_CODIVA);
|
||
if (codiva.blank())
|
||
{
|
||
const TString& codart = o.mask().get(S_CODART);
|
||
codiva = cache().get(LF_ANAMAG, codart, ANAMAG_CODIVA);
|
||
}
|
||
o.set(codiva);
|
||
}
|
||
break;
|
||
case F_DISTINTE:
|
||
switch (e)
|
||
{
|
||
case se_enter:
|
||
_edit_dist = -1;
|
||
set_dist(_curr_dist = jolly);
|
||
break;
|
||
case se_query_add:
|
||
return _idfase.full();
|
||
case se_notify_add:
|
||
{
|
||
TSAL_tree& t = tree();
|
||
TRectype* rec = t.dist(_idfase, _curr_dist = jolly, true);
|
||
if (rec != NULL)
|
||
sync_tree();
|
||
}
|
||
break;
|
||
case se_query_modify:
|
||
if (jolly != _curr_dist)
|
||
set_dist(jolly);
|
||
_edit_fase = _idfase;
|
||
_edit_dist = _curr_dist = jolly;
|
||
break;
|
||
case se_leave:
|
||
case se_notify_modify:
|
||
if (_edit_dist >= 0)
|
||
{
|
||
const int r = _edit_dist; // Memorizza numero riga corrente
|
||
_edit_dist = -1; // Annulla numero riga corrente
|
||
TRectype* rec = tree().dist(_edit_fase, r, false);
|
||
if (rec != NULL)
|
||
{
|
||
const TSheet_field& sheet = (TSheet_field&)o;
|
||
const TMask& m = sheet.sheet_row_mask(r);
|
||
msk2rec(m, *rec);
|
||
sync_tree();
|
||
}
|
||
}
|
||
break;
|
||
case se_notify_del:
|
||
if (_curr_dist >= 0)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
TRectype* rec = t.dist(_idfase, _curr_dist);
|
||
if (rec != NULL)
|
||
{
|
||
t.kill_node();
|
||
sync_tree();
|
||
}
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TSAL_emsk::on_misu_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case 102:
|
||
case 103:
|
||
case 104:
|
||
case 105:
|
||
if (e == fe_modify && _curr_misu >= 0 && _curr_dist >= 0)
|
||
{
|
||
TSheet_field& misure = sfield(F_MISURE);
|
||
TEdit_field& tot = o.mask().efield(106);
|
||
tot.validate(K_TAB);
|
||
misure.row(_curr_misu).add(tot.get(), 5);
|
||
update_dist_qta();
|
||
}
|
||
break;
|
||
case F_MISURE:
|
||
switch (e)
|
||
{
|
||
case se_query_add:
|
||
return _iddist.full();
|
||
case se_notify_add:
|
||
tree().misu(_iddist, _edit_misu = jolly, true);
|
||
break;
|
||
case se_enter:
|
||
_edit_misu = -1;
|
||
_curr_misu = jolly;
|
||
break;
|
||
case se_query_modify:
|
||
_edit_fase = _idfase;
|
||
_edit_dist = _curr_dist;
|
||
_edit_misu = _curr_misu = jolly;
|
||
break;
|
||
case se_leave:
|
||
case se_notify_modify:
|
||
if (_edit_dist >= 0 && _edit_misu >= 0)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
t.dist(_edit_fase, _edit_dist, false);
|
||
TString idd; t.curr_id(idd);
|
||
TRectype* rec = t.misu(idd, _edit_misu, false);
|
||
if (rec != NULL)
|
||
{
|
||
TSheet_field& sheet = (TSheet_field&)o;
|
||
const TMask& m = sheet.sheet_row_mask(_edit_misu);
|
||
msk2rec(m, *rec);
|
||
update_dist_qta();
|
||
}
|
||
_edit_misu = -1;
|
||
}
|
||
break;
|
||
case se_notify_del:
|
||
if (_curr_misu >= 0)
|
||
{
|
||
TSAL_tree& t = tree();
|
||
TRectype* rec = t.misu(_iddist, _curr_misu);
|
||
if (rec != NULL)
|
||
{
|
||
t.kill_node();
|
||
update_dist_qta();
|
||
}
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TSAL_emsk::update_dist(const real& val, const TDate& dt_new)
|
||
{
|
||
TSheet_field& dist = sfield(F_DISTINTE);
|
||
TToken_string& row = dist.row(_curr_dist);
|
||
row.add(val.string(), dist.cid2index(S_QTA));
|
||
if (dt_new.ok())
|
||
{
|
||
TDate dt_old; row.get(dist.cid2index(S_DATALAV), dt_old);
|
||
if (dt_new > dt_old)
|
||
row.add(dt_new.string(), dist.cid2index(S_DATALAV));
|
||
}
|
||
dist.update_mask(_curr_dist);
|
||
TOperable_field& o = dist.sheet_row_mask(_curr_dist).efield(S_QTA);
|
||
on_dist_event(o, fe_modify, 1);
|
||
dist.force_update(_curr_dist);
|
||
TRectype* rec = tree().dist(_idfase, _curr_dist);
|
||
if (rec)
|
||
msk2rec(dist.sheet_row_mask(_curr_dist), *rec);
|
||
}
|
||
|
||
void TSAL_emsk::update_dist_qta()
|
||
{
|
||
if (_curr_dist >= 0)
|
||
{
|
||
TSheet_field& sheet = sfield(F_MISURE);
|
||
real tot;
|
||
TDate data_lavori;
|
||
FOR_EACH_SHEET_ROW(sheet, i, row)
|
||
{
|
||
tot += real(row->get(sheet.cid2index(106))); // 106 = totale
|
||
const TDate data = row->get();
|
||
if (data > data_lavori)
|
||
data_lavori = data;
|
||
}
|
||
update_dist(tot, data_lavori);
|
||
sync_tree();
|
||
}
|
||
}
|
||
|
||
struct SAL_tot : public TObject
|
||
{
|
||
real _totdoc;
|
||
real _sicurezza;
|
||
real _esclusi;
|
||
|
||
real _t_totdoc;
|
||
real _t_sicurezza;
|
||
real _t_esclusi;
|
||
|
||
};
|
||
|
||
static bool calc_totdoc(TTree& tree, void* jolly, word)
|
||
{
|
||
const TSAL_tree& t = (const TSAL_tree&)tree;
|
||
const TRectype& rec = *t.curr_row();
|
||
if (t.level(rec) == sl_distinta)
|
||
{
|
||
const real qta = rec.get(RDOC_QTA); // da 3 a 5 decimali
|
||
const real prz = rec.get(RDOC_PREZZO); // da 0 a 3 decimali
|
||
if (!qta.is_zero() && !prz.is_zero())
|
||
{
|
||
const int tipo = rec.get_int(RDOC_TIPODET); // 0=lavori, ..., 3=Sicurezza, 4=esclusi
|
||
|
||
const TCurrency parziale(real(qta * prz)); // arrotonda all'euro
|
||
const real& imp = parziale.get_num();
|
||
SAL_tot& tot = *(SAL_tot*)jolly;
|
||
tot._totdoc += imp;
|
||
|
||
switch (tipo)
|
||
{
|
||
case 3: tot._sicurezza += imp; break;
|
||
case 4: tot._esclusi += imp; break;
|
||
default: break;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool TSAL_emsk::sync_totdoc()
|
||
{
|
||
TSAL_tree& t = tree();
|
||
|
||
if (!t.goto_root())
|
||
return false;
|
||
|
||
const bool attivo = get(F_TIPOCF)[0] != 'F';
|
||
const TRectype& doc = *t.curr_row();
|
||
|
||
real importo_base, sicurezza_cantiere;
|
||
TString4 codiva;
|
||
|
||
SAL_tot tot;
|
||
t.scan_depth_first(calc_totdoc, &tot);
|
||
|
||
if (t.goto_firstson())
|
||
{
|
||
const TRiga_documento* row = (TRiga_documento*)t.curr_row();
|
||
const TRectype* ord = row->find_original_doc();
|
||
if (ord != NULL)
|
||
{
|
||
const TVariable_rectype ordine(*ord);
|
||
importo_base = ordine.get_real("TOTDOC");
|
||
|
||
if (!attivo)
|
||
{
|
||
TDocumento orig(*ord);
|
||
FOR_EACH_PHYSICAL_RDOC(orig, r, rdoc)
|
||
{
|
||
codiva = rdoc->get(RDOC_CODIVA);
|
||
if (codiva.full())
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
const TRectype& cantiere = cache().get(LF_COMMESSE, doc.get(DOC_CODCMS));
|
||
|
||
const real& lor = tot._totdoc;
|
||
const real& esc = tot._esclusi;
|
||
real sic = tot._sicurezza;
|
||
real prib;
|
||
|
||
if (attivo)
|
||
{
|
||
if (importo_base.is_zero())
|
||
importo_base = cantiere.get_real(COMMESSE_IMPORTOB);
|
||
sicurezza_cantiere = cantiere.get_real(COMMESSE_SICUREZZA);
|
||
prib = cantiere.get_real(COMMESSE_RIBASSO);
|
||
if (codiva.blank())
|
||
codiva = cantiere.get(COMMESSE_CODIVA);
|
||
}
|
||
|
||
set(F_SAL_LOR, lor);
|
||
|
||
if (sic.is_zero() && !importo_base.is_zero())
|
||
{
|
||
sic = lor * sicurezza_cantiere / importo_base;
|
||
sic.round(2);
|
||
}
|
||
set(F_SAL_SIC, sic);
|
||
set(F_SAL_ESC, esc);
|
||
const real sicesc = sic + esc;
|
||
set(F_SAL_SIC2, sicesc);
|
||
|
||
const real idr = lor - sicesc;
|
||
set(F_SAL_IDR, idr);
|
||
|
||
set(F_SAL_PRIB, prib);
|
||
real rib = idr * prib / CENTO; rib.round(2);
|
||
set(F_SAL_RIB, rib);
|
||
|
||
const real irb = idr - rib;
|
||
set(F_SAL_IRB, irb);
|
||
|
||
const real sal = irb + sicesc;
|
||
set(F_SAL_SAL, sal);
|
||
|
||
real pgar = ZERO;
|
||
const TString& exp_gar = get(F_PGARANZIA);
|
||
if (exp_gar.full())
|
||
{
|
||
TString80 dummy;
|
||
if (scontoexpr2perc(exp_gar, false, dummy, pgar))
|
||
pgar = (UNO-pgar)*CENTO;
|
||
}
|
||
set(F_SAL_PGAR, pgar);
|
||
real gar = sal * pgar / CENTO; gar.round(2);
|
||
set(F_SAL_GAR, gar);
|
||
|
||
real ant = ZERO;
|
||
real pant = ZERO;
|
||
const TString& exp_ant = get(F_PANTICIPO);
|
||
if (exp_ant.full())
|
||
{
|
||
TString80 dummy;
|
||
real eant = ZERO;
|
||
if (scontoexpr2perc(exp_ant, false, dummy, eant))
|
||
{
|
||
pant = (UNO-eant)*CENTO;
|
||
ant = sal * pant / CENTO;
|
||
ant.round(2);
|
||
}
|
||
}
|
||
set(F_SAL_PANT, pant);
|
||
set(F_SAL_ANT, ant);
|
||
|
||
const real net = sal - ant - gar;
|
||
set(F_SAL_NET, net);
|
||
|
||
real piva = ZERO;
|
||
if (codiva.full())
|
||
piva = real(cache().get("%IVA", codiva, "R0"));
|
||
real iva = net * piva / CENTO; iva.round(2);
|
||
set(F_SAL_PIVA, piva);
|
||
set(F_SAL_IVA, iva);
|
||
set(F_SAL_TOT, real(net + iva));
|
||
|
||
return !sal.is_zero();
|
||
}
|
||
|
||
bool TSAL_emsk::sync_tree()
|
||
{
|
||
TSAL_tree& t = tree();
|
||
TTree_field& tf = t.owner();
|
||
tf.force_update();
|
||
return sync_totdoc();
|
||
}
|
||
|
||
bool TSAL_emsk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case F_STATO:
|
||
if ((e == fe_init || e == fe_close) && o.empty())
|
||
o.set("1");
|
||
if (e == fe_modify && !o.empty())
|
||
app().update_tools(*this);
|
||
break;
|
||
case F_FASI:
|
||
return on_fasi_event((TTree_field&)o, e, jolly);
|
||
/*
|
||
case F_FASENEW:
|
||
case F_FASEDIT:
|
||
if (e == fe_button)
|
||
return on_fasi_button(o, e, jolly);
|
||
break;
|
||
*/
|
||
case F_DISTINTE:
|
||
return on_dist_event(o, e, jolly);
|
||
case F_MISURE:
|
||
return on_misu_event(o, e, jolly);
|
||
case DLG_PRINT:
|
||
if (e == fe_button)
|
||
app().report("sl1600");
|
||
break;
|
||
case B_PRINT_LIB:
|
||
if (e == fe_button)
|
||
app().report("sl1400");
|
||
break;
|
||
case B_PRINT_REG:
|
||
if (e == fe_button)
|
||
app().report("sl1500");
|
||
break;
|
||
case DLG_ELABORA:
|
||
if (e == fe_button)
|
||
{
|
||
const TString16 cod = sl_trova_elaborazione(*this);
|
||
if (cod.full())
|
||
{
|
||
app().rewrite(*this);
|
||
sl_genera_documento(app().get_relation()->curr(), cod);
|
||
}
|
||
}
|
||
break;
|
||
case DLG_ARCHIVE:
|
||
if (e == fe_button)
|
||
{
|
||
}
|
||
break;
|
||
case F_SAL_TOT:
|
||
if (e == fe_init && o.empty())
|
||
sync_totdoc();
|
||
break;
|
||
default:
|
||
if (jolly > 0 && o.dlg() >= DLG_USER && o.dlg() < 2*DLG_USER) // Sheet mask events
|
||
{
|
||
if (e == fe_modify)
|
||
{
|
||
switch (jolly)
|
||
{
|
||
case 1: return on_dist_event(o, e, jolly);
|
||
case 2: return on_misu_event(o, e, jolly);
|
||
default: CHECK(false, "Unknown sheet field event"); break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return TSAL_msk::on_field_event(o, e, jolly);
|
||
}
|
||
|
||
void TSAL_emsk::set_sheet_color(short id, COLOR col)
|
||
{
|
||
const COLOR rgb = blend_colors(NORMAL_BACK_COLOR, col, 0.75);
|
||
TSheet_field& s = sfield(id);
|
||
s.set_back_and_fore_color(rgb, NORMAL_COLOR, -1);
|
||
}
|
||
|
||
TSAL_emsk::TSAL_emsk() : TSAL_msk("sl0100b"), _tree(NULL), _locked(false)
|
||
{
|
||
TMask_field& cdc0 = field(F_CDC0);
|
||
RCT rct0; cdc0.get_rect(rct0);
|
||
const int yca = rct0.top / ROWY + 1; // Riga del primo campo di analitica
|
||
short idcdc, idcms, idfase, idconto;
|
||
ca_create_fields_ext(*this, 0, 2, yca, F_CDC0+1, idcdc, idcms, idfase, idconto,
|
||
DOC_CODCOSTO, DOC_CODCMS /*, DOC_FASCMS */); // Niente fasi qui!
|
||
|
||
set_sheet_color(F_DISTINTE, COLOR_YELLOW);
|
||
set_sheet_color(F_MISURE, COLOR_GRAY);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TSAL_app
|
||
///////////////////////////////////////////////////////////
|
||
|
||
bool TSAL_app::user_create()
|
||
{
|
||
open_files(LF_TAB, LF_TABCOM, LF_CLIFO, LF_ANAMAG, LF_UMART,
|
||
LF_DOC, LF_RIGHEDOC, LF_COMMESSE, LF_FASI, 0);
|
||
_rel = new TRelation(LF_DOC);
|
||
_qmsk = new TSAL_qmsk;
|
||
_emsk = new TSAL_emsk;
|
||
return true;
|
||
}
|
||
|
||
bool TSAL_app::user_destroy()
|
||
{
|
||
delete _emsk;
|
||
delete _qmsk;
|
||
delete _rel;
|
||
return true;
|
||
}
|
||
|
||
const char* TSAL_app::record_description(const TRelation& r) const
|
||
{
|
||
TString& tmp = get_tmp_string();
|
||
tmp << title() << " n." << r.curr().get(DOC_NUMANT);
|
||
return tmp;
|
||
}
|
||
|
||
TCursor& TSAL_app::get_filtered_cursor() const
|
||
{
|
||
TEdit_field& f = _qmsk->efield(F_NDOC);
|
||
TCursor& cur = *f.browse()->cursor();
|
||
if (cur.items() == 0) // A volte deve scantarsi ...
|
||
f.check(); // ... forzo ricalcolo elementi
|
||
return cur;
|
||
}
|
||
|
||
int TSAL_app::read(TMask& m)
|
||
{
|
||
int err = TRelation_application::read(m);
|
||
if (err == NOERR)
|
||
{
|
||
const TRectype& doc = get_relation()->curr();
|
||
TSAL_tree& t = ((TSAL_emsk&)m).tree();
|
||
t.load(doc);
|
||
}
|
||
return err;
|
||
}
|
||
|
||
static bool tree_save_row(TTree& tree, void* jolly, word /*flags*/)
|
||
{
|
||
TSAL_tree& t = (TSAL_tree&)tree;
|
||
const TRectype* rec = t.curr_row();
|
||
if (rec && !rec->empty() && rec->num() == LF_RIGHEDOC)
|
||
{
|
||
const char* full_field[] = { RDOC_DESCR, RDOC_QTA, RDOC_PREZZO,
|
||
RDOC_QTAGG1, RDOC_QTAGG2, RDOC_QTAGG3,
|
||
RDOC_QTAGG4, RDOC_QTAGG5, RDOC_DATACONS,
|
||
NULL } ;
|
||
bool one_full = false;
|
||
for (int f = 0; full_field[f] && !one_full; f++)
|
||
{
|
||
if (f == 0)
|
||
one_full = rec->get(full_field[f]).full();
|
||
else
|
||
one_full = !rec->get_real(full_field[f]).is_zero();
|
||
}
|
||
if (one_full)
|
||
{
|
||
TDocumento& doc = *(TDocumento*)jolly;
|
||
const TString4 tiporiga = rec->get(RDOC_TIPORIGA);
|
||
TRectype& row = doc.new_row(tiporiga);
|
||
|
||
const TString80 codart = rec->get(RDOC_CODART);
|
||
TString80 codartmag;
|
||
if (codart.full())
|
||
codartmag = cache().get(LF_ANAMAG, codart, ANAMAG_CODART);
|
||
|
||
for (int f = rec->items()-1; f > 5; f--)
|
||
{
|
||
const char* fld = rec->fieldname(f);
|
||
if (rec->type(fld) == _memofld)
|
||
break;
|
||
const TString& src = rec->get(fld);
|
||
if (src.full())
|
||
{
|
||
const TString& dst = row.get(fld);
|
||
if (dst.blank())
|
||
row.put(fld, src);
|
||
}
|
||
}
|
||
|
||
row.put(RDOC_IDRIGA, row.get(RDOC_NRIGA));
|
||
row.put(RDOC_TIPORIGA, rec->get(RDOC_TIPORIGA));
|
||
row.put(RDOC_QTA, rec->get(RDOC_QTA));
|
||
row.put(RDOC_QTAEVASA, rec->get(RDOC_QTAEVASA));
|
||
row.put(RDOC_DESCR, rec->get(RDOC_DESCR));
|
||
row.put(RDOC_DESCLUNGA, rec->get(RDOC_DESCLUNGA));
|
||
row.put(RDOC_DESCEST, rec->get(RDOC_DESCEST));
|
||
row.put(RDOC_CODART, codart);
|
||
row.put(RDOC_CODARTMAG, codartmag);
|
||
row.put(RDOC_CHECKED, codartmag.full());
|
||
row.put(RDOC_UMQTA, rec->get(RDOC_UMQTA));
|
||
row.put(RDOC_QTAGG1, rec->get(RDOC_QTAGG1));
|
||
row.put(RDOC_QTAGG2, rec->get(RDOC_QTAGG2));
|
||
row.put(RDOC_QTAGG3, rec->get(RDOC_QTAGG3));
|
||
row.put(RDOC_QTAGG4, rec->get(RDOC_QTAGG4));
|
||
row.put(RDOC_QTAGG5, rec->get(RDOC_QTAGG5));
|
||
row.put(RDOC_PREZZO, rec->get(RDOC_PREZZO));
|
||
row.put(RDOC_DATACONS, rec->get(RDOC_DATACONS));
|
||
row.put(RDOC_TIPOCOLL, rec->get(RDOC_TIPOCOLL));
|
||
row.put(RDOC_IDRIGACOLL,rec->get(RDOC_IDRIGACOLL));
|
||
row.put(RDOC_TIPODET, rec->get(RDOC_TIPODET));
|
||
row.put(RDOC_CODCMS, doc.get(RDOC_CODCMS)); // Commessa/cantiere da DOC
|
||
row.put(RDOC_FASCMS, rec->get(RDOC_FASCMS)); // Fase specifica da riga
|
||
}
|
||
}
|
||
return false; // Don't stop scan
|
||
}
|
||
|
||
int TSAL_app::save_rows(const TMask& m)
|
||
{
|
||
TSAL_emsk& sm = (TSAL_emsk&)m;
|
||
TSAL_tree& tree = sm.tree();
|
||
|
||
TDocumento doc(get_relation()->curr());
|
||
|
||
doc.destroy_rows();
|
||
if (tree.goto_root() && tree.goto_firstson())
|
||
tree.scan_depth_first(tree_save_row, &doc);
|
||
|
||
// Estrae campi analitica da maschera principale e li riporta sulle righe
|
||
const TString80 cdc = sm.fget(DOC_CODCOSTO);
|
||
const TString80 cms = sm.fget(DOC_CODCMS);
|
||
TRecord_array& rdoc = doc.body();
|
||
rdoc.renum_key(RDOC_CODCOSTO, cdc);
|
||
rdoc.renum_key(RDOC_CODCMS, cms);
|
||
rdoc.renum_key(RDOC_DAPROVV, "D");
|
||
rdoc.renum_key(RDOC_DAANNO, _qmsk->get(F_ANNO_ORD));
|
||
rdoc.renum_key(RDOC_DACODNUM, _qmsk->get(F_CODNUM_ORD));
|
||
rdoc.renum_key(RDOC_DANDOC, _qmsk->get(F_NDOC_ORD));
|
||
|
||
FOR_EACH_MASK_FIELD(sm, i, f)
|
||
{
|
||
const TFieldref* fr = f->field();
|
||
if (fr != NULL)
|
||
{
|
||
const TString& value = f->get();
|
||
if (fr->name().starts_with("G1:"))
|
||
{
|
||
const TString& fname = fr->name().mid(3);
|
||
doc.put(fname, value);
|
||
}
|
||
else
|
||
fr->write(value, doc.head());
|
||
}
|
||
}
|
||
|
||
const int err = doc.rewrite(get_relation()->file());
|
||
|
||
return err;
|
||
}
|
||
|
||
int TSAL_app::write(const TMask& m)
|
||
{
|
||
get_relation()->curr().zero("G1");
|
||
int err = TRelation_application::write(m);
|
||
if (err == NOERR)
|
||
err = save_rows(m);
|
||
return err;
|
||
}
|
||
|
||
int TSAL_app::rewrite(const TMask& m)
|
||
{
|
||
get_relation()->curr().zero("G1");
|
||
int err = TRelation_application::rewrite(m);
|
||
if (err == NOERR)
|
||
err = save_rows(m);
|
||
return err;
|
||
}
|
||
|
||
bool TSAL_app::remove()
|
||
{
|
||
bool done = TRelation_application::remove();
|
||
if (done)
|
||
{
|
||
const TRectype& rec = get_relation()->curr();
|
||
TToken_string keytok;
|
||
keytok.add(rec.get(DOC_CODNUM));
|
||
keytok.add(rec.get(DOC_ANNO));
|
||
keytok.add(rec.get(DOC_PROVV));
|
||
keytok.add(rec.get(DOC_NDOC));
|
||
TRecord_array rdoc(keytok, LF_RIGHEDOC);
|
||
rdoc.remove();
|
||
}
|
||
return done;
|
||
}
|
||
|
||
void TSAL_app::update_tools(TMask& m)
|
||
{
|
||
const bool is_edit = m.edit_mode();
|
||
bool can_print = is_edit;
|
||
if (can_print)
|
||
{
|
||
TFilename rep = "sl1400.rep"; // Libretto delle misure
|
||
can_print = rep.custom_path();
|
||
}
|
||
|
||
m.enable(DLG_NEWREC, is_edit);
|
||
m.enable(DLG_PRINT, can_print);
|
||
m.enable(DLG_ELABORA, sl_trova_elaborazione(m).full());
|
||
m.enable(B_PRINT_LIB, can_print);
|
||
m.enable(B_PRINT_REG, can_print);
|
||
|
||
m.disable(F_STATO); // Enable with F12
|
||
}
|
||
|
||
bool TSAL_app::get_next_key(TToken_string& key)
|
||
{
|
||
const char provv = _qmsk->get(F_PROVV)[0];
|
||
const int anno = _qmsk->get_int(F_ANNO);
|
||
const TString& codnum = _qmsk->get(F_CODNUM);
|
||
if (anno < 2000 || codnum.blank())
|
||
return false; // Rinumera con anno e numerazione validi
|
||
|
||
long newdoc = 1L;
|
||
TLocalisamfile doc(LF_DOC);
|
||
doc.put(DOC_PROVV, provv);
|
||
doc.put(DOC_ANNO, anno);
|
||
doc.put(DOC_CODNUM, codnum);
|
||
doc.put(DOC_NDOC, 9999999);
|
||
int err = doc.read(_isgreat);
|
||
if (err == NOERR)
|
||
err = doc.prev();
|
||
else
|
||
err = doc.last();
|
||
if (err == NOERR && doc.get(DOC_CODNUM) == codnum)
|
||
newdoc += doc.get_long(DOC_NDOC);
|
||
|
||
key.cut(0);
|
||
key.add(F_PROVV); key.add(provv);
|
||
key.add(F_ANNO); key.add(anno);
|
||
key.add(F_CODNUM); key.add(codnum);
|
||
key.add(F_NDOC); key.add(newdoc);
|
||
|
||
return true;
|
||
}
|
||
|
||
void TSAL_app::init_insert_mode(TMask& m)
|
||
{
|
||
TRelation_application::init_insert_mode(m);
|
||
m.set(F_DATADOC, TDate(TODAY));
|
||
|
||
long nsal = 1;
|
||
|
||
const char ord_provv = _qmsk->get(F_PROVV)[0];
|
||
const int ord_anno = _qmsk->get_int(F_ANNO_ORD);
|
||
const TString& ord_codnum = _qmsk->get(F_CODNUM_ORD);
|
||
const long ord_ndoc = _qmsk->get_long(F_NDOC_ORD);
|
||
TString filter;
|
||
filter.format("DAPROVV=%c DAANNO=%d DACODNUM=%s DANDOC=%ld",
|
||
ord_provv, ord_anno, (const char*)ord_codnum, ord_ndoc);
|
||
TString query;
|
||
query << "USE 34 KEY 4\nJOIN 33 INTO PROVV=PROVV ANNO=ANNO CODNUM==CODNUM NDOC==NDOC\n"
|
||
<< "FROM " << filter << "\nTO " << filter;
|
||
TISAM_recordset rsal(query);
|
||
if (rsal.move_last())
|
||
nsal += rsal.cursor()->curr(LF_DOC).get_int(DOC_NUMANT);
|
||
m.set(F_NSAL, nsal);
|
||
|
||
TSAL_tree& t = ((TSAL_emsk&)m).tree();
|
||
const TRectype* model = &rsal.cursor()->curr(LF_DOC); // Usa come modello l'ultimo SAL
|
||
if (nsal <= 1) // Primo SAL
|
||
{
|
||
const TEdit_field& fld_ord = _qmsk->efield(F_NDOC_ORD);
|
||
model = &fld_ord.browse()->cursor()->curr(LF_DOC); // Usa come modello l'ordine
|
||
// Copia anticipo e granzia cliente
|
||
if (model->get_char(DOC_TIPOCF) != 'F')
|
||
{
|
||
const TRectype& cms = cache().get(LF_COMMESSE, model->get(DOC_CODCMS));
|
||
m.set(F_PANTICIPO, cms.get(COMMESSE_ANTICIPO));
|
||
m.set(F_PGARANZIA, cms.get(COMMESSE_GARANZIA));
|
||
}
|
||
}
|
||
|
||
TSAL_msk& sm = (TSAL_msk&)m;
|
||
FOR_EACH_MASK_FIELD(sm, i, f)
|
||
{
|
||
if (f->empty() && f->active() && f->field() != NULL)
|
||
{
|
||
const TString& name = f->field()->name();
|
||
sm.fset(name, model->get(name), 0x2);
|
||
}
|
||
}
|
||
t.load(*model, nsal);
|
||
|
||
update_tools(m);
|
||
}
|
||
|
||
void TSAL_app::init_modify_mode(TMask& m)
|
||
{
|
||
TRelation_application::init_modify_mode(m);
|
||
update_tools(m);
|
||
}
|
||
|
||
void TSAL_app::print()
|
||
{
|
||
app().report("sl1400");
|
||
}
|
||
|
||
bool TSAL_app::report(const char* name)
|
||
{
|
||
static bool already_printing = false;
|
||
if (already_printing)
|
||
return false;
|
||
already_printing = true;
|
||
|
||
TFilename rep = name; rep.ext("rep");
|
||
if (!rep.custom_path())
|
||
return cantread_box(rep.name());
|
||
|
||
if (rewrite(*_emsk) != NOERR)
|
||
return cantwrite_box("SAL");
|
||
|
||
TFilename ini; ini.tempdir(); ini.add(name); ini.ext("ini");
|
||
if (ini.full())
|
||
{
|
||
TConfig cfg(ini, "Transaction");
|
||
cfg.set("Action", printer().printtype() == screenvis ? "Preview" : "Print");
|
||
cfg.set_paragraph("Vars");
|
||
cfg.remove_all();
|
||
|
||
TSAL_msk& sm = *(TSAL_msk*)_emsk;
|
||
FOR_EACH_MASK_FIELD(sm, i, f) if (f->is_edit() && !f->empty())
|
||
{
|
||
const TFieldref* field = f->field();
|
||
if (field != NULL && field->from() == 0)
|
||
{
|
||
const TString& name = field->name();
|
||
cfg.set(name, sm.fget(name));
|
||
}
|
||
}
|
||
|
||
cfg.set(RDOC_DAPROVV, _qmsk->get(F_PROVV));
|
||
cfg.set(RDOC_DAANNO, _qmsk->get(F_ANNO_ORD));
|
||
cfg.set(RDOC_DACODNUM, _qmsk->get(F_CODNUM_ORD));
|
||
cfg.set(RDOC_DANDOC, _qmsk->get(F_NDOC_ORD));
|
||
}
|
||
|
||
TString cmd;
|
||
cmd << "ba8 -4 " << rep;
|
||
if (ini.exist())
|
||
cmd << " -i" << ini;
|
||
TExternal_app a(cmd);
|
||
a.run();
|
||
|
||
already_printing = false;
|
||
return true;
|
||
}
|
||
|
||
int sl0100(int argc, char* argv[])
|
||
{
|
||
TSAL_app a;
|
||
a.run(argc, argv, TR("S.A.L."));
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|