1663 lines
43 KiB
C++
1663 lines
43 KiB
C++
#include <automask.h>
|
|
#include <colors.h>
|
|
#include <controls.h>
|
|
#include <dongle.h>
|
|
#include <execp.h>
|
|
#include <printer.h>
|
|
#include <relapp.h>
|
|
#include <utility.h>
|
|
|
|
#include "../ca/calib01.h"
|
|
#include "../mg/mglib.h"
|
|
#include "../ve/velib.h"
|
|
|
|
#include "pe1400.h"
|
|
#include "pe1401.h"
|
|
#include "pe1500.h"
|
|
|
|
#include "../db/rdist.h"
|
|
#include "../mg/anamag.h"
|
|
#include "../ca/commesse.h"
|
|
|
|
static real ricarico2perc(const TString& exp)
|
|
{
|
|
real val_perc = UNO;
|
|
|
|
if (exp.full())
|
|
{
|
|
TString80 num;
|
|
bool dec = false; // Flag che indica se si attende l'inizio di un numero
|
|
bool startnum = true; // Flag che indica se siamo all'inizio di un numero
|
|
int errorchar = ' ';
|
|
bool valid = true;
|
|
// Flag che indica se sono nella parte decimale di un numero
|
|
for (const char* s = exp; *s && errorchar == ' '; s++)
|
|
{
|
|
const char c = *s;
|
|
switch(c)
|
|
{
|
|
case '+':
|
|
case '-':
|
|
// Se ero in in numero ...
|
|
if( !startnum )
|
|
{
|
|
// Aggiunge il numero alla sequenza
|
|
const real val = num;
|
|
val_perc *= ( CENTO + val ) / CENTO;
|
|
}
|
|
// Inizia il nuovo numero
|
|
num = (c == '-') ? "-" : "+";
|
|
startnum = true;
|
|
dec = false;
|
|
break;
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
num << c;
|
|
startnum = false;
|
|
break;
|
|
case '.':
|
|
case ',':
|
|
if(!dec)
|
|
{
|
|
if( startnum )
|
|
num << '0'; // Se occorreva un numero ci metto lo 0
|
|
num << '.'; // Interpreto la virgola come punto
|
|
dec = true;
|
|
startnum = true;
|
|
}
|
|
else
|
|
errorchar = c; // Se siamo già nella parte decimale segnala un errore
|
|
break;
|
|
case ' ':
|
|
break;
|
|
default:
|
|
errorchar = c;
|
|
break;
|
|
}
|
|
}
|
|
// Controlla la validità
|
|
valid = errorchar == ' ';
|
|
|
|
if (valid)
|
|
{
|
|
// Aggiunge l'ultimo numero preso
|
|
const real val = num;
|
|
val_perc *= ( CENTO + val ) / CENTO;
|
|
}
|
|
}
|
|
|
|
return val_perc;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_app
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPreventivo_app : public TRelation_application
|
|
{
|
|
TMask* _qmsk;
|
|
TMask* _emsk;
|
|
TRelation* _rel;
|
|
bool _revisioning;
|
|
TString8 _codelab;
|
|
|
|
protected:
|
|
int save_rows(const TMask& m);
|
|
virtual const char* extra_modules() const { return "ci"; }
|
|
bool save_and_print(TPrtype mode);
|
|
|
|
|
|
public:
|
|
virtual bool user_create();
|
|
virtual bool user_destroy();
|
|
virtual bool changing_mask(int mode) { return !(_revisioning && mode == MODE_INS); }
|
|
virtual TMask* get_mask(int mode) { return mode == MODE_QUERY ? _qmsk : _emsk; }
|
|
virtual TRelation* get_relation() const { return _rel; }
|
|
virtual bool get_next_key(TToken_string& key);
|
|
virtual bool has_filtered_cursor() const { return true; }
|
|
virtual TCursor& get_filtered_cursor() const;
|
|
|
|
virtual void init_insert_mode(TMask& m);
|
|
virtual void init_modify_mode(TMask& m);
|
|
virtual const char* record_description(const TRelation& rel) const;
|
|
|
|
virtual int read(TMask& m);
|
|
virtual int write(const TMask& m);
|
|
virtual int rewrite(const TMask& m);
|
|
virtual bool remove();
|
|
|
|
virtual void print();
|
|
virtual void preview();
|
|
|
|
void update_tools(TMask& m);
|
|
bool set_elab_code(const TString& cod) { _codelab = cod; return cod.full(); }
|
|
};
|
|
|
|
inline TPreventivo_app& app() { return (TPreventivo_app&)main_app(); }
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_nmsk
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPreventivo_nmsk : public TAutomask
|
|
{
|
|
TString4 _codnum;
|
|
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
public:
|
|
TPreventivo_nmsk(const TString& codnum);
|
|
};
|
|
|
|
bool TPreventivo_nmsk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch(o.dlg())
|
|
{
|
|
case F_ANNO:
|
|
if (e == fe_modify && !o.empty())
|
|
on_field_event(efield(F_NDOC), fe_init, 0L);
|
|
break;
|
|
case F_NDOC:
|
|
if (e == fe_init)
|
|
{
|
|
long n = 1;
|
|
TString query;
|
|
query << "USE DOC"
|
|
<< "\nFROM PROVV=D ANNO=#ANNO CODNUM=#CODNUM"
|
|
<< "\nTO PROVV=D ANNO=#ANNO CODNUM=#CODNUM";
|
|
TISAM_recordset recset(query);
|
|
recset.set_var("#ANNO", get(F_ANNO));
|
|
recset.set_var("#CODNUM", _codnum);
|
|
if (recset.move_last())
|
|
{
|
|
const TCodice_numerazione& num = cached_numerazione(_codnum);
|
|
const int revlen = num.revision_len();
|
|
TString8 ndoc = recset.get(DOC_NDOC).as_string();
|
|
if (revlen > 0) ndoc.rtrim(revlen);
|
|
n += atol(ndoc);
|
|
}
|
|
o.set(n);
|
|
} else
|
|
if (e == fe_modify || e == fe_close)
|
|
{
|
|
TString8 ndoc;
|
|
const TCodice_numerazione& num = cached_numerazione(_codnum);
|
|
const int revlen = num.revision_len();
|
|
if (revlen > 0)
|
|
ndoc.format("%d%0*d", atoi(o.get()), revlen, 1);
|
|
else
|
|
ndoc = o.get();
|
|
|
|
TLocalisamfile doc(LF_DOC);
|
|
doc.put(DOC_PROVV, "D");
|
|
doc.put(DOC_ANNO, get(F_ANNO));
|
|
doc.put(DOC_CODNUM, _codnum);
|
|
doc.put(DOC_NDOC, ndoc);
|
|
if (doc.read() == NOERR)
|
|
return error_box("Preventivo già esistente");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
TPreventivo_nmsk::TPreventivo_nmsk(const TString& codnum) : TAutomask(TR("Nuovo preventivo"), 1, 30, 6), _codnum(codnum)
|
|
{
|
|
const TCodice_numerazione& num = cached_numerazione(_codnum);
|
|
const int revlen = num.revision_len();
|
|
add_number(F_NDOC, 0, PR("Codice "), 13, 1, 7-revlen).check_type(CHECK_REQUIRED);
|
|
add_number(F_ANNO, 0, PR("Anno "), 1, 1, 4, "A").check_type(CHECK_REQUIRED);
|
|
add_button(DLG_OK, 0, "", -12, -1, 9, 2);
|
|
add_button(DLG_CANCEL, 0, "", -22, -1, 9, 2);
|
|
set_handlers();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_msk
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Classe di base per maschere preventivi (query ed edit)
|
|
class TPreventivo_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:
|
|
int revision_length() const;
|
|
int split_ndoc(long ndoc, int& nprev, int& nrev) const;
|
|
int join_ndoc(int nprev, int nrev, long& ndoc) const;
|
|
|
|
TPreventivo_msk(const char* name) { read_mask(name, 0, 8); set_handlers(); }
|
|
};
|
|
|
|
TMask_field* TPreventivo_msk::parse_field(TScanner& s)
|
|
{
|
|
if (s.key() == "TL")
|
|
set_full_screen_interface(page_win(1), true);
|
|
return TAutomask::parse_field(s);
|
|
}
|
|
|
|
int TPreventivo_msk::revision_length() const
|
|
{
|
|
int rl = 0;
|
|
const TString& codnum = get(F_CODNUM);
|
|
if (codnum.full())
|
|
{
|
|
const TCodice_numerazione& num = cached_numerazione(codnum);
|
|
rl = num.revision_len();
|
|
}
|
|
return rl;
|
|
}
|
|
|
|
int TPreventivo_msk::split_ndoc(long ndoc, int& nprev, int& nrev) const
|
|
{
|
|
nprev = nrev = 0;
|
|
const int revlen = revision_length();
|
|
if (revlen > 0)
|
|
{
|
|
TString8 sdoc; sdoc << ndoc;
|
|
if (sdoc.len() > revlen)
|
|
{
|
|
nrev = atoi(sdoc.right(revlen));
|
|
nprev = atoi(sdoc.rtrim(revlen));
|
|
}
|
|
}
|
|
else
|
|
nprev = ndoc;
|
|
|
|
return revlen;
|
|
}
|
|
|
|
int TPreventivo_msk::join_ndoc(int nprev, int nrev, long& ndoc) const
|
|
{
|
|
ndoc = 0L;
|
|
const int revlen = revision_length();
|
|
if (revlen > 0)
|
|
{
|
|
ndoc = nprev;
|
|
for (int i = 0; i < revlen; i++)
|
|
ndoc *= 10;
|
|
ndoc += nrev > 0 ? nrev : 1;
|
|
}
|
|
else
|
|
ndoc = nprev;
|
|
|
|
return revlen;
|
|
}
|
|
|
|
|
|
bool TPreventivo_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_CODNUM:
|
|
if (e == fe_init || e == fe_modify)
|
|
{
|
|
if (o.empty())
|
|
{
|
|
TCursor& c = *((TEdit_field&)o).browse()->cursor();
|
|
c = 0L;
|
|
o.set(c.curr().get("CODTAB"));
|
|
o.check();
|
|
}
|
|
|
|
int revlen = 0;
|
|
if (!o.empty())
|
|
{
|
|
const TCodice_numerazione& num = cached_numerazione(o.get());
|
|
revlen = num.revision_len();
|
|
set(F_TIPODOC, num.tipo_doc(0), 0x3);
|
|
}
|
|
if (revlen > 0)
|
|
{
|
|
RCT rct;
|
|
|
|
TEdit_field& prv = efield(F_NPREV);
|
|
prv.set_len(7-revlen);
|
|
prv.get_rect(rct);
|
|
rct.right = rct.left + CHARX * (8-revlen);
|
|
prv.set_rect(rct);
|
|
|
|
TEdit_field& rev = efield(F_NREV);
|
|
rev.set_len(revlen);
|
|
rev.get_rect(rct);
|
|
rct.right = rct.left + CHARX * (revlen+1);
|
|
rev.set_rect(rct);
|
|
|
|
show(F_NREV);
|
|
}
|
|
else
|
|
hide(F_NREV);
|
|
}
|
|
break;
|
|
case F_NDOC:
|
|
if (!o.empty() && (e == fe_init || e == fe_modify))
|
|
{
|
|
const long ndoc = atol(o.get());
|
|
int nprev = 0, nrev = 0;
|
|
const int revlen = split_ndoc(ndoc, nprev, nrev);
|
|
set(F_NPREV, nprev);
|
|
set(F_NREV, nrev);
|
|
if (revlen == 0)
|
|
reset(F_NPREV);
|
|
}
|
|
break;
|
|
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)
|
|
{
|
|
TRelation rel(LF_RIGHEDOC);
|
|
o.mask().autosave(rel);
|
|
const TString& cms = rel.curr().get(RDOC_CODCMS);
|
|
const TRectype& rec = cache().get(LF_COMMESSE, cms);
|
|
if (rec.get_bool(COMMESSE_CHIUSA))
|
|
return error_box(FR("Impossibile utilizzare la commesa chiusa %s"), (const char*)cms);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_qmsk
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPreventivo_qmsk : public TPreventivo_msk
|
|
{
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
public:
|
|
TPreventivo_qmsk() : TPreventivo_msk("pe1400a") {}
|
|
};
|
|
|
|
bool TPreventivo_qmsk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
return TPreventivo_msk::on_field_event(o, e, jolly);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_emsk
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPreventivo_emsk : public TPreventivo_msk
|
|
{
|
|
TPreventivo_tree* _tree;
|
|
TString _idfase, _iddist;
|
|
int _edit_dist, _edit_dett, _edit_misu;
|
|
int _curr_dist, _curr_dett, _curr_misu;
|
|
bool _locked, _has_db;
|
|
|
|
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, int column);
|
|
void update_dist_qta();
|
|
void update_dist_costo();
|
|
|
|
bool on_dett_event(TOperable_field& o, TField_event e, long jolly);
|
|
bool on_misu_event(TOperable_field& o, TField_event e, long jolly);
|
|
bool on_dist_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
real get_costo(const TString& codart, TString& um, TString& iva) const;
|
|
|
|
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_tree();
|
|
bool msk2rec(const TMask& msk, TRectype& rec) const;
|
|
|
|
public:
|
|
TPreventivo_tree& tree(bool reset = false);
|
|
|
|
TPreventivo_emsk();
|
|
};
|
|
|
|
TPreventivo_tree& TPreventivo_emsk::tree(bool reset)
|
|
{
|
|
if (_tree == NULL)
|
|
{
|
|
_tree = new TPreventivo_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 set_and_check(TMask_field& f, const TRectype& rec)
|
|
{
|
|
const TFieldref* fr = f.field();
|
|
if (fr == NULL)
|
|
{
|
|
if (f.ghost())
|
|
return f.on_hit();
|
|
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
|
|
{
|
|
f.set(fr->read(rec));
|
|
if (!f.empty() && f.is_edit() && f.shown())
|
|
{
|
|
const TBrowse* b = ((TEdit_field&)f).browse();
|
|
if (b != NULL)
|
|
{
|
|
const TFixed_string of = b->get_output_fields();
|
|
if (of.find('|') > 0) // C'è un pipe nell'output, per cui ci sono almeno due campi di output
|
|
f.check(STARTING_CHECK);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
// Riempie gli sheet di articoli e misure della distinta selezionata
|
|
bool TPreventivo_emsk::set_dist(const TString& idd)
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
|
|
bool ok = idd.full();
|
|
if (_iddist != idd)
|
|
{
|
|
_iddist = idd;
|
|
|
|
// Svuota sheet articoli
|
|
TSheet_field& a = sfield(F_ARTICOLI);
|
|
a.hide();
|
|
a.destroy();
|
|
|
|
// Svuota sheet misure
|
|
TSheet_field& m = sfield(F_MISURE);
|
|
m.hide();
|
|
m.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();
|
|
TSheet_field& s = rec.get(RDOC_TIPORIGA) == t.tipo_dett() ? a : m;
|
|
TMask& m = s.sheet_row_mask(n);
|
|
FOR_EACH_MASK_FIELD(m, i, f)
|
|
set_and_check(*f, rec);
|
|
s.update_row(n++);
|
|
}
|
|
_locked = false;
|
|
}
|
|
|
|
// Visualizza nuovamente i due sheet eventualemente riempiti
|
|
a.force_update(); a.show();
|
|
m.force_update(); m.show();
|
|
}
|
|
|
|
_curr_dist = -1;
|
|
if (ok && t.goto_node(idd))
|
|
{
|
|
_curr_dist = 0;
|
|
while(t.goto_lbrother())
|
|
_curr_dist++;
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TPreventivo_emsk::set_dist(int row)
|
|
{
|
|
TPreventivo_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 TPreventivo_emsk::set_fase(const TString& idfase)
|
|
{
|
|
_idfase = idfase;
|
|
|
|
// Svuota lo sheet delle distinte
|
|
TSheet_field& d = sfield(F_DISTINTE);
|
|
d.destroy();
|
|
|
|
TString idd;
|
|
TPreventivo_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)
|
|
set_and_check(*f, rec);
|
|
d.update_row(n++);
|
|
} while (t.goto_rbrother());
|
|
}
|
|
}
|
|
d.force_update();
|
|
set_dist(idd);
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TPreventivo_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 TPreventivo_emsk::on_key(KEY k)
|
|
{
|
|
if (k == K_SHIFT + K_F12)
|
|
{
|
|
enable(F_STATO);
|
|
return true;
|
|
}
|
|
return TAutomask::on_key(k);
|
|
}
|
|
|
|
bool TPreventivo_emsk::on_fasi_button(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
TTree_field& fasi = t.owner();
|
|
|
|
TPreventivo_level pl = pl_documento;
|
|
if (fasi.goto_selected())
|
|
pl = t.level();
|
|
else
|
|
return false;
|
|
|
|
if (pl == pl_documento && o.dlg() == F_FASENEW)
|
|
pl = pl_fase1;
|
|
|
|
if (pl < pl_fase1 || pl > pl_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;
|
|
case F_FASEUP:
|
|
t.swap_left();
|
|
if (pl == pl_distinta)
|
|
{
|
|
TString16 id; t.curr_id(id);
|
|
set_fase(_idfase);
|
|
t.goto_node(id);
|
|
}
|
|
break;
|
|
case F_FASEDN:
|
|
t.swap_right();
|
|
if (pl == pl_distinta)
|
|
{
|
|
TString16 id; t.curr_id(id);
|
|
set_fase(_idfase);
|
|
t.goto_node(id);
|
|
}
|
|
break;
|
|
case F_FASELT:
|
|
if (pl > pl_fase1 && pl < pl_distinta && t.push_up())
|
|
t.curr_row()->put(RPRV_LEVEL, t.curr_depth()-1);
|
|
break;
|
|
case F_FASERT:
|
|
if (pl >= pl_fase1 && pl < t.last_fase_level() && t.push_down())
|
|
t.curr_row()->put(RPRV_LEVEL, t.curr_depth()-1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
o.enable();
|
|
fasi.select_current();
|
|
fasi.force_update();
|
|
return true;
|
|
}
|
|
|
|
bool TPreventivo_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;
|
|
bool can_golt = false;
|
|
bool can_gort = false;
|
|
|
|
switch (e)
|
|
{
|
|
case fe_modify:
|
|
if (fasi.goto_selected())
|
|
{
|
|
modified = true;
|
|
TPreventivo_tree& t = tree();
|
|
TPreventivo_level td = t.level();
|
|
if (td > pl_documento)
|
|
{
|
|
can_edit = true;
|
|
can_goup = t.has_lbrother();
|
|
can_godn = t.has_rbrother();
|
|
if (td >= pl_fase1 && td < pl_distinta) // Cambio fase
|
|
{
|
|
can_golt = td > pl_fase1;
|
|
can_gort = td < t.last_fase_level();
|
|
TString16 id;
|
|
t.curr_id(id);
|
|
set_fase(id);
|
|
}
|
|
else
|
|
{
|
|
while (td > pl_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);
|
|
enable(F_FASEUP, can_goup);
|
|
enable(F_FASEDN, can_godn);
|
|
enable(F_FASELT, can_golt);
|
|
enable(F_FASERT, can_gort);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TPreventivo_emsk::on_dist_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case D_CODDIS:
|
|
case D_CODART:
|
|
if (e == fe_modify && !o.empty())
|
|
{
|
|
const TString& codart = o.get();
|
|
TRecord_array rdist(codart, LF_RDIST);
|
|
if (rdist.rows() > 0 && sfield(F_ARTICOLI).empty())
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
while (t.dett(_iddist, 0))
|
|
t.kill_node();
|
|
const int last = rdist.last_row();
|
|
int n = 0;
|
|
for (int r = rdist.first_row(); r > 0 && r <= last; r = rdist.succ_row(r))
|
|
{
|
|
const TRectype& rd = rdist.row(r);
|
|
const TCodice_articolo codart = rd.get(RDIST_CODCOMP);
|
|
TString80 desc = rd.get(RDIST_DESCR);
|
|
if (desc.empty())
|
|
desc = cache().get(LF_ANAMAG, codart, ANAMAG_DESCR);
|
|
|
|
TRectype* rec = t.dett(_iddist, n++, true);
|
|
rec->put(RDOC_CODART, codart);
|
|
rec->put(RDOC_DESCR, desc);
|
|
rec->put(RDOC_UMQTA, rd.get(RDIST_UM));
|
|
rec->put(RDOC_QTA, rd.get(RDIST_EXPR));
|
|
}
|
|
t.goto_node(_iddist);
|
|
sync_tree();
|
|
// Forza aggiornamento dello sheet
|
|
const TString16 id = _iddist;
|
|
_iddist.cut(0);
|
|
set_dist(id);
|
|
}
|
|
|
|
TString4 um, iva;
|
|
const real costo = get_costo(codart, um, iva);
|
|
TMask& m = o.mask();
|
|
m.set(D_UM, um);
|
|
m.set(D_COSTO, costo, 0x3);
|
|
}
|
|
break;
|
|
case D_COSTO:
|
|
if (e == fe_modify && !o.empty())
|
|
{
|
|
const TString& ric = get(F_RICARICO);
|
|
if (ric.full())
|
|
{
|
|
TMask& m = o.mask();
|
|
const real k = ricarico2perc(ric);
|
|
const real prezzo = real(o.get()) * k;
|
|
m.set(o.dlg()+1, prezzo);
|
|
}
|
|
}
|
|
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:
|
|
{
|
|
TPreventivo_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_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(_idfase, r, true);
|
|
if (rec != NULL)
|
|
{
|
|
const TMask& m = ((TSheet_field&)o).sheet_row_mask(r);
|
|
msk2rec(m, *rec);
|
|
sync_tree();
|
|
}
|
|
}
|
|
break;
|
|
case se_notify_del:
|
|
if (_curr_dist >= 0)
|
|
{
|
|
TPreventivo_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;
|
|
}
|
|
|
|
real TPreventivo_emsk::get_costo(const TString& codart, TString& um, TString& iva) const
|
|
{
|
|
real costo = ZERO;
|
|
const int tc = get_int(F_TIPOCOSTO);
|
|
const TArticolo_giacenza& art = cached_article_balances(codart);
|
|
TEsercizi_contabili esc;
|
|
const int annoes = esc.date2esc(get_date(F_DATADOC));
|
|
switch (tc)
|
|
{
|
|
case 1 : costo = art.ultimo_costo(annoes); break;
|
|
case 2 : costo = art.media_costi(annoes); break;
|
|
case 4 : costo = art.costo_standard(annoes); break;
|
|
case 5 : costo = art.costo_medio(annoes, "", ""); break;
|
|
case 6 : costo = art.costo_mediopond(annoes, "", ""); break;
|
|
default: break;
|
|
}
|
|
if (costo.is_zero())
|
|
costo = art.get_real(ANAMAG_COSTSTD);
|
|
|
|
um = art.um().row(1).get(UMART_UM);
|
|
iva = art.get(ANAMAG_CODIVA);
|
|
|
|
return costo;
|
|
}
|
|
|
|
bool TPreventivo_emsk::on_dett_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case S_CODART:
|
|
if (e == fe_modify && !o.empty() && !_locked)
|
|
{
|
|
const TString& codart = o.get();
|
|
TString4 um, iva;
|
|
const real costo = get_costo(codart, um, iva);
|
|
TMask& m = o.mask();
|
|
if (um.full())
|
|
m.set(S_UMART, um, 0x3);
|
|
if (iva.full() && m.get(S_CODIVA).blank())
|
|
m.set(S_CODIVA, iva, 0x3);
|
|
if (!costo.is_zero())
|
|
m.set(S_COSTO, costo, 0x3);
|
|
}
|
|
break;
|
|
case F_ARTICOLI:
|
|
switch (e)
|
|
{
|
|
case se_query_add:
|
|
return _iddist.full();
|
|
case se_notify_add:
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
TRectype* rec = t.dett(_iddist, _curr_dett = jolly, true);
|
|
if (rec != NULL)
|
|
sync_tree();
|
|
}
|
|
break;
|
|
case se_enter:
|
|
_edit_dett = -1;
|
|
_curr_dett = jolly;
|
|
break;
|
|
case se_query_modify:
|
|
_edit_dett = _curr_dett = jolly;
|
|
break;
|
|
case se_leave:
|
|
case se_notify_modify:
|
|
if (_edit_dett >= 0)
|
|
{
|
|
const int r = _edit_dett;
|
|
_edit_dett = -1;
|
|
TPreventivo_tree& t = tree();
|
|
TRectype* rec = t.dett(_iddist, r, true);
|
|
if (rec != NULL)
|
|
{
|
|
const TMask& m = ((TSheet_field&)o).sheet_row_mask(r);
|
|
msk2rec(m, *rec);
|
|
sync_tree();
|
|
update_dist_costo();
|
|
}
|
|
}
|
|
break;
|
|
case se_notify_del:
|
|
if (_curr_dett >= 0)
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
TRectype* rec = t.dett(_iddist, _curr_dett);
|
|
if (rec != NULL)
|
|
{
|
|
t.kill_node();
|
|
update_dist_costo();
|
|
sync_tree();
|
|
}
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TPreventivo_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 = *o.mask().get_sheet();
|
|
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_misu = _curr_misu = jolly;
|
|
break;
|
|
case se_leave:
|
|
case se_notify_modify:
|
|
if (_iddist.full() && _edit_misu >= 0)
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
TRectype* rec = t.misu(_iddist, _edit_misu, true);
|
|
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)
|
|
{
|
|
TPreventivo_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 TPreventivo_emsk::update_dist(const real& val, int column)
|
|
{
|
|
TSheet_field& dist = sfield(F_DISTINTE);
|
|
dist.row(_curr_dist).add(val.string(), column);
|
|
dist.update_mask(_curr_dist);
|
|
TOperable_field& o = dist.sheet_row_mask(_curr_dist).efield(105);
|
|
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 TPreventivo_emsk::update_dist_costo()
|
|
{
|
|
if (_curr_dist >= 0)
|
|
{
|
|
TSheet_field& sheet = sfield(F_ARTICOLI);
|
|
real costo, prezzo;
|
|
FOR_EACH_SHEET_ROW(sheet, i, row)
|
|
{
|
|
const real q = row->get(3);
|
|
const real c = row->get();
|
|
const real p = row->get();
|
|
costo += q*c;
|
|
prezzo += q*p;
|
|
}
|
|
if (!costo.is_zero())
|
|
update_dist(costo, 4);
|
|
if (!prezzo.is_zero())
|
|
update_dist(prezzo, 5);
|
|
}
|
|
}
|
|
|
|
void TPreventivo_emsk::update_dist_qta()
|
|
{
|
|
if (_curr_dist >= 0)
|
|
{
|
|
TSheet_field& sheet = sfield(F_MISURE);
|
|
real tot;
|
|
FOR_EACH_SHEET_ROW(sheet, i, row)
|
|
tot += real(row->get(5));
|
|
update_dist(tot, 3);
|
|
}
|
|
}
|
|
|
|
bool TPreventivo_emsk::sync_tree()
|
|
{
|
|
TPreventivo_tree& t = tree();
|
|
TTree_field& tf = t.owner();
|
|
tf.force_update();
|
|
return true;
|
|
}
|
|
|
|
static bool ricarica(TTree& tree, void* jolly, word)
|
|
{
|
|
const TPreventivo_tree& t = (const TPreventivo_tree&)tree;
|
|
if (t.level() == pl_distinta)
|
|
{
|
|
TRectype* rec = t.curr_row();
|
|
const real cos = rec->get(RPRV_COSTO);
|
|
const real k = *(real*)jolly;
|
|
rec->put(RDOC_PREZZO, cos * k);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TPreventivo_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:
|
|
case F_FASEDEL:
|
|
case F_FASEUP:
|
|
case F_FASEDN:
|
|
case F_FASERT:
|
|
case F_FASELT:
|
|
if (e == fe_button)
|
|
return on_fasi_button(o, e, jolly);
|
|
break;
|
|
case F_DISTINTE:
|
|
return on_dist_event(o, e, jolly);
|
|
case F_ARTICOLI:
|
|
return on_dett_event(o, e, jolly);
|
|
case F_MISURE:
|
|
return on_misu_event(o, e, jolly);
|
|
case DLG_COPY:
|
|
if (e == fe_button && edit_mode())
|
|
{
|
|
TPreventivo_nmsk m(get(F_CODNUM));
|
|
if (m.run() == K_ENTER)
|
|
{
|
|
const TDate datadoc(TODAY);
|
|
const int nprev = m.get_int(F_NDOC);
|
|
const int nrev = 1;
|
|
long ndoc = 0; join_ndoc(nprev, nrev, ndoc);
|
|
set(F_NPREV, nprev);
|
|
set(F_NREV, nrev);
|
|
set(F_NDOC, ndoc);
|
|
set(F_STATO, 1);
|
|
set(F_DATADOC, datadoc);
|
|
set(F_ANNO, m.get_int(F_ANNO));
|
|
set_mode(MODE_INS);
|
|
stop_run(K_SAVE);
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case DLG_PRINT:
|
|
if (e == fe_button)
|
|
main_app().print();
|
|
break;
|
|
case DLG_PREVIEW:
|
|
if (e == fe_button)
|
|
main_app().preview();
|
|
break;
|
|
case DLG_ELABORA:
|
|
if (e == fe_button)
|
|
{
|
|
const TString& cod = pe_trova_elaborazione(*this, 'O');
|
|
if (cod.full())
|
|
{
|
|
TPreventivo_app& relapp = (TPreventivo_app&)main_app();
|
|
if (relapp.set_elab_code(cod))
|
|
stop_run(K_SAVE);
|
|
}
|
|
}
|
|
break;
|
|
case DLG_ARCHIVE:
|
|
if (e == fe_button)
|
|
{
|
|
const TString& cod = pe_trova_elaborazione(*this, 'F');
|
|
if (cod.full())
|
|
{
|
|
TPreventivo_app& relapp = (TPreventivo_app&)main_app();
|
|
if (relapp.set_elab_code(cod))
|
|
stop_run(K_SAVE);
|
|
}
|
|
}
|
|
break;
|
|
case F_RICARICO:
|
|
if (e == fe_modify && !o.empty())
|
|
{
|
|
// Controllo che ci sia almeno una fase prima di ricalcolare tutto
|
|
TPreventivo_tree& t = tree();
|
|
if (t.goto_root() && t.has_son() && yesno_box(TR("Si desidera applicare il nuovo ricarico a tutte fasi?")))
|
|
{
|
|
if (t.goto_root())
|
|
{
|
|
const real perc = ricarico2perc(o.get());
|
|
t.scan_depth_first(ricarica, (void*)&perc);
|
|
sync_tree();
|
|
set_fase("");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
if (jolly > 0 && o.dlg() >= 101 && o.dlg() < 300) // Sheet mask events
|
|
{
|
|
if (e == fe_modify)
|
|
{
|
|
switch (jolly)
|
|
{
|
|
case 1: return on_dist_event(o, e, jolly);
|
|
case 2: return on_dett_event(o, e, jolly);
|
|
case 3: return on_misu_event(o, e, jolly);
|
|
default: CHECK(false, "Unknown sheet field event"); break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return TPreventivo_msk::on_field_event(o, e, jolly);
|
|
}
|
|
|
|
void TPreventivo_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);
|
|
}
|
|
|
|
TPreventivo_emsk::TPreventivo_emsk() : TPreventivo_msk("pe1400b"), _tree(NULL), _locked(false), _has_db(false)
|
|
{
|
|
int yca = 21; // Riga del primo campo di analitica
|
|
TMask_field* grp = find_by_id(F_CDC0);
|
|
if (grp)
|
|
{
|
|
RCT rct0; grp->get_rect(rct0);
|
|
yca = rct0.top / ROWY + 1;
|
|
}
|
|
|
|
short idcdc = 0, idcms = 0, idfase = 0, idconto = 0;
|
|
ca_create_fields_ext(*this, 0, 2, yca, F_CDC0+1, idcdc, idcms, idfase, idconto,
|
|
DOC_CODCOSTO, DOC_CODCMS, NULL); // Niente fasi qui!
|
|
|
|
set_sheet_color(F_DISTINTE, COLOR_YELLOW);
|
|
set_sheet_color(F_ARTICOLI, COLOR_GREEN);
|
|
set_sheet_color(F_MISURE, COLOR_GRAY);
|
|
|
|
_has_db = dongle().active(DBAUT);
|
|
if (_has_db)
|
|
{
|
|
TISAM_recordset dist("USE DIST");
|
|
_has_db = dist.items() >= 4;
|
|
}
|
|
TMask& dist = sfield(F_DISTINTE).sheet_mask();
|
|
TList_field& tipoa = dist.lfield(D_TIPOA);
|
|
const TToken_string cod = tipoa.get_codes();
|
|
if (!_has_db && cod.items() >= 2)
|
|
{
|
|
TToken_string* m1 = tipoa.message(1);
|
|
tipoa.replace_items("A", TR("Articolo"));
|
|
if (m1 != NULL)
|
|
{
|
|
TToken_string* m0 = tipoa.message(0);
|
|
if (m0 != NULL)
|
|
*m0 = *m1;
|
|
}
|
|
tipoa.disable();
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPreventivo_app
|
|
///////////////////////////////////////////////////////////
|
|
|
|
bool TPreventivo_app::user_create()
|
|
{
|
|
if (ca_config().get_int("Authorizations") < 2)
|
|
return error_box("E' necessario configurare la contabilità analitica o industriale");
|
|
|
|
open_files(LF_TAB, LF_TABCOM, LF_CLIFO,
|
|
LF_DOC, LF_RIGHEDOC, LF_COMMESSE, LF_FASI, 0);
|
|
_rel = new TRelation(LF_DOC);
|
|
_qmsk = new TPreventivo_qmsk;
|
|
_emsk = new TPreventivo_emsk;
|
|
return true;
|
|
}
|
|
|
|
bool TPreventivo_app::user_destroy()
|
|
{
|
|
delete _emsk;
|
|
delete _qmsk;
|
|
delete _rel;
|
|
return true;
|
|
}
|
|
|
|
TCursor& TPreventivo_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;
|
|
}
|
|
|
|
bool TPreventivo_app::get_next_key(TToken_string& key)
|
|
{
|
|
TPreventivo_msk& m = (TPreventivo_msk&)curr_mask();
|
|
|
|
const TEdit_field& codnum = m.efield(F_CODNUM);
|
|
if (codnum.empty())
|
|
return codnum.error_box(TR("Inserire un codice numerazione"));
|
|
|
|
const int revlen = m.revision_length();
|
|
|
|
long ndoc = 0;
|
|
int nprev = 0, nrev = 0;
|
|
|
|
if (m.query_mode() || revlen == 0)
|
|
{
|
|
TCursor& cur = get_filtered_cursor();
|
|
const TRecnotype i = cur.items();
|
|
if (i > 0)
|
|
{
|
|
cur = i-1;
|
|
ndoc = cur.curr().get_long(DOC_NDOC);
|
|
m.split_ndoc(ndoc, nprev, nrev);
|
|
}
|
|
nprev++;
|
|
nrev = 1;
|
|
m.join_ndoc(nprev, nrev, ndoc);
|
|
}
|
|
else
|
|
{
|
|
// Trucchi per evitare l'azzeramento della maschera
|
|
_revisioning = true;
|
|
m.set_mode(MODE_QUERY);
|
|
|
|
ndoc = m.get_long(F_NDOC);
|
|
m.split_ndoc(ndoc, nprev, nrev);
|
|
nrev++;
|
|
m.join_ndoc(nprev, nrev, ndoc);
|
|
m.set(F_NDOC, ndoc, 0x3);
|
|
}
|
|
key.format("%d|%ld", F_NDOC, ndoc);
|
|
return true;
|
|
}
|
|
|
|
int TPreventivo_app::read(TMask& m)
|
|
{
|
|
int err = TRelation_application::read(m);
|
|
if (err == NOERR)
|
|
{
|
|
const TRectype& doc = get_relation()->curr();
|
|
TToken_string keytok;
|
|
keytok.add(doc.get(DOC_CODNUM));
|
|
keytok.add(doc.get(DOC_ANNO));
|
|
keytok.add(doc.get(DOC_PROVV));
|
|
keytok.add(doc.get(DOC_NDOC));
|
|
const TRecord_array rdoc(keytok, LF_RIGHEDOC);
|
|
|
|
TPreventivo_tree& t = ((TPreventivo_emsk&)m).tree();
|
|
t.append_row(doc);
|
|
const int last_row = rdoc.last_row();
|
|
for (int r = rdoc.first_row(); r > 0 && r <= last_row; r = rdoc.succ_row(r))
|
|
t.append_row(rdoc[r]);
|
|
|
|
t.shrink_all();
|
|
t.goto_root();
|
|
t.expand();
|
|
t.owner().force_update();
|
|
|
|
m.set(F_FASEMAX, pe_numero_fasi(rdoc));
|
|
}
|
|
_codelab.cut(0); // Azzera in ogni caso l'elaborazione
|
|
return err;
|
|
}
|
|
|
|
static bool tree_save_row(TTree& tree, void* jolly, word /*flags*/)
|
|
{
|
|
TPreventivo_tree& t = (TPreventivo_tree&)tree;
|
|
const TRectype* rec = t.curr_row();
|
|
if (rec && !rec->empty() && rec->num() == LF_RIGHEDOC)
|
|
{
|
|
const real costo = rec->get(RPRV_COSTO);
|
|
const real price = rec->get(RDOC_PREZZO);
|
|
const TString& descr = rec->get(RDOC_DESCR);
|
|
if (descr.full() || !costo.is_zero() || !price.is_zero())
|
|
{
|
|
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_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));
|
|
|
|
// Make sure of coherent level on final record
|
|
const TPreventivo_level pl = t.level(*rec);
|
|
if (pl > pl_fase1 && pl < pl_distinta)
|
|
row.put(RPRV_LEVEL, int(t.curr_depth() - 1)); // Don't assume RPRV_LEVEL = pl-pl_fase1
|
|
else
|
|
row.zero(RPRV_LEVEL);
|
|
}
|
|
}
|
|
return false; // Don't stop scan
|
|
}
|
|
|
|
int TPreventivo_app::save_rows(const TMask& m)
|
|
{
|
|
TPreventivo_tree& tree = ((TPreventivo_emsk&)m).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
|
|
TString cms, cos;
|
|
FOR_EACH_MASK_FIELD(m, i, f) if (f->active() && f->is_edit() && f->dlg() >= F_CDC0)
|
|
{
|
|
const TFieldref* fref = f->field();
|
|
if (fref != NULL)
|
|
{
|
|
if (fref->name() == DOC_CODCMS)
|
|
cms << f->get();
|
|
if (fref->name() == DOC_CODCOSTO)
|
|
cos << f->get();
|
|
}
|
|
}
|
|
|
|
TRecord_array& rdoc = doc.body();
|
|
rdoc.renum_key(RDOC_CODCMS, cms);
|
|
rdoc.renum_key(RDOC_CODCOSTO, cos);
|
|
|
|
const int err = doc.rewrite(get_relation()->file());
|
|
if (err == NOERR && _codelab.full())
|
|
pe_genera_documento(doc, _codelab, 'O');
|
|
_codelab.cut(0); // Azzera in ogni caso l'elaborazione
|
|
|
|
return err;
|
|
}
|
|
|
|
int TPreventivo_app::write(const TMask& m)
|
|
{
|
|
int err = TRelation_application::write(m);
|
|
if (err == NOERR)
|
|
err = save_rows(m);
|
|
return err;
|
|
}
|
|
|
|
int TPreventivo_app::rewrite(const TMask& m)
|
|
{
|
|
int err = TRelation_application::rewrite(m);
|
|
if (err == NOERR)
|
|
err = save_rows(m);
|
|
return err;
|
|
}
|
|
|
|
bool TPreventivo_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 TPreventivo_app::update_tools(TMask& m)
|
|
{
|
|
const bool is_edit = m.edit_mode();
|
|
const bool can_ord = is_edit && pe_trova_elaborazione(m, 'O').full();
|
|
const bool can_fab = is_edit && pe_trova_elaborazione(m, 'F').full();
|
|
bool can_print = is_edit;
|
|
if (can_print)
|
|
{
|
|
const TTipo_documento& tip = cached_tipodoc(m.get(DOC_TIPODOC));
|
|
TFilename rep;
|
|
can_print = tip.main_print_profile(rep, 0x2);
|
|
}
|
|
|
|
m.enable(DLG_COPY, is_edit);
|
|
m.enable(DLG_NEWREC, is_edit);
|
|
m.enable(DLG_ELABORA, can_ord);
|
|
m.enable(DLG_ARCHIVE, can_fab);
|
|
m.enable(DLG_PRINT, can_print);
|
|
m.enable(DLG_PREVIEW, can_print);
|
|
m.disable(F_STATO); // Enable with F12
|
|
}
|
|
|
|
void TPreventivo_app::init_insert_mode(TMask& m)
|
|
{
|
|
_revisioning = false;
|
|
TRelation_application::init_insert_mode(m);
|
|
m.set(F_DATADOC, TDate(TODAY));
|
|
update_tools(m);
|
|
|
|
const TMultilevel_code_info& fi = ca_multilevel_code_info(LF_FASI);
|
|
const int fasemax = fi.levels() - fi.parent_levels();
|
|
m.set(F_FASEMAX, fasemax);
|
|
}
|
|
|
|
void TPreventivo_app::init_modify_mode(TMask& m)
|
|
{
|
|
_revisioning = false;
|
|
TRelation_application::init_modify_mode(m);
|
|
update_tools(m);
|
|
}
|
|
|
|
bool TPreventivo_app::save_and_print(TPrtype mode)
|
|
{
|
|
static bool already_printing = false;
|
|
if (already_printing)
|
|
return false;
|
|
already_printing = true;
|
|
|
|
if (rewrite(*_emsk) != NOERR)
|
|
return already_printing = false;
|
|
|
|
TString commandline;
|
|
commandline << "ve1 -2" << ' ' << _emsk->get(F_CODNUM) << ' '
|
|
<< _emsk->get(F_ANNO) << " D " << _emsk->get(F_NDOC);
|
|
switch (mode)
|
|
{
|
|
case exportprinter: commandline << " E P"; break;
|
|
case fileprinter : commandline << " P P"; break;
|
|
case screenvis : commandline << " A P"; break;
|
|
default : commandline << " S D"; break;
|
|
}
|
|
|
|
TExternal_app interattivo( commandline );
|
|
if (interattivo.run() == NOERR)
|
|
{
|
|
TLocalisamfile& f = _rel->file();
|
|
f.zero();
|
|
f.put(DOC_PROVV, 'D');
|
|
f.put(DOC_ANNO, _emsk->get(F_ANNO));
|
|
f.put(DOC_CODNUM, _emsk->get(F_CODNUM));
|
|
f.put(DOC_NDOC, _emsk->get(F_NDOC));
|
|
f.read();
|
|
curr_mask().set(F_STATO, f.get(DOC_STATO));
|
|
}
|
|
already_printing = false;
|
|
return true;
|
|
}
|
|
|
|
void TPreventivo_app::print()
|
|
{
|
|
save_and_print(winprinter);
|
|
}
|
|
|
|
void TPreventivo_app::preview()
|
|
{
|
|
save_and_print(screenvis);
|
|
}
|
|
|
|
const char* TPreventivo_app::record_description(const TRelation& rel) const
|
|
{
|
|
const TString4 tipodoc = rel.curr().get(DOC_TIPODOC);
|
|
const TString& desc = cache().get("%TIP", tipodoc, "S0");
|
|
return desc.empty() ? title() : desc;
|
|
}
|
|
|
|
int pe1400(int argc, char* argv[])
|
|
{
|
|
TPreventivo_app a;
|
|
a.run(argc, argv, TR("Preventivi"));
|
|
return 0;
|
|
}
|
|
|
|
|