campo-sirio/sl/sl0101.cpp
guy e1b494f330 Rimosse righe commentate
git-svn-id: svn://10.65.10.50/branches/R_10_00@23048 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-02-24 08:45:54 +00:00

591 lines
15 KiB
C++
Raw Blame History

#include "sl0100a.h"
#include "sl0101.h"
#include <diction.h>
#include <mask.h>
#include <reputils.h>
#include <urldefid.h>
#include "../ca/calib01.h"
#include "../ca/fasi.h"
#include "../ve/velib.h"
static bool cmscpy(TRectype& dst, const TRectype& src)
{
const TString& cms_in = src.get(RDOC_CODCMS);
if (cms_in.blank())
{
NFCHECK("Commessa nulla");
return false;
}
const TString& cms_out = dst.get(RDOC_CODCMS);
if (cms_in == cms_out)
return true;
if (!cms_out.blank())
NFCHECK("Commessa incoerente");
dst.put(RDOC_CODCMS, cms_in);
return true;
}
bool TSAL_tree::add_lastson(TObject* obj)
{
CHECK(obj != NULL && obj->is_kind_of(CLASS_RECTYPE), "Record non valido per SAL");
TRectype& rec = *(TRectype*)obj;
CHECK(rec.get(RDOC_TIPORIGA).full(), "TIPORIGA vuoto");
cmscpy(rec, *curr_row());
bool done = false;
if (goto_firstson()) // Se ha almeno un figlio ...
{
while (goto_rbrother()); // ... allora vai all'ultimo fratello
done = add_rbrother(obj); // ed aggiungi ultimo fratello
}
else
done = add_son(obj); // Aggiungi primogenito
return done;
}
TSAL_level TSAL_tree::last_fase_level() const
{
return (TSAL_level)_picture_fasi.items();
}
bool TSAL_tree::goto_last_fase(TSAL_level sublevel)
{
bool ok = goto_root() && goto_firstson();
if (ok)
{
while (goto_rbrother()); // goto last son
if (sublevel > sl_fase1)
{
//TSAL_level max_lev = last_fase_level();
//if (sublevel < max_lev)
// max_lev = sublevel;
while (level() < sublevel)
{
if (goto_firstson())
while (goto_rbrother());
else
break;
}
ok = level() == sublevel;
}
}
return ok;
}
bool TSAL_tree::goto_last_dist()
{
bool ok = goto_last_fase(sl_distinta); // sl_distinta = dummy value for maximum depth
if (ok)
while (goto_rbrother());
return ok;
}
TRectype* TSAL_tree::new_row(TSAL_level level) const
{
const TMask& m = owner().mask();
TRectype* rec = new TRectype(level == sl_documento ? LF_DOC : LF_RIGHEDOC);
rec->put(RDOC_PROVV, 'D');
rec->put(RDOC_ANNO, m.get(F_ANNO));
rec->put(RDOC_CODNUM, m.get(F_CODNUM));
rec->put(RDOC_NDOC, m.get(F_NDOC));
TString cantiere;
for (short id = F_CDC0+1; m.id2pos(id) > 0; id++)
cantiere << m.get(id);
rec->put(RDOC_CODCMS, cantiere);
switch (level)
{
case sl_documento:
rec->put(DOC_NUMANT, m.get(F_NSAL));
break;
case sl_distinta:
rec->put(RDOC_TIPORIGA, tipo_dist());
rec->put(RDOC_DESCR, TR("Nuova distinta"));
cmscpy(*rec, *curr_row());
break;
case sl_misura:
rec->put(RDOC_TIPORIGA, tipo_misu());
rec->put(RDOC_DESCR, TR("Nuova misura"));
cmscpy(*rec, *curr_row());
break;
default:
rec->put(RDOC_TIPORIGA, tipo_fasi());
rec->put(RDOC_DESCR, TR("Nuova fase"));
rec->put(RSAL_LEVEL, level-sl_fase1);
break;
}
return rec;
}
static bool find_fase_cb(TTree& node, void* jolly, word /*when*/)
{
const TSAL_tree& tree = (TSAL_tree&)node;
const TSAL_level lev = tree.level();
if (lev < sl_fase1 || lev >= sl_distinta)
return false;
const TString& fascms = *((TString*)jolly);
const TRectype& rec = *tree.curr_row();
const TString& fase = rec.get(RDOC_FASCMS);
return fase == fascms;
}
TRectype* TSAL_tree::fase(const TString& fase, bool create)
{
TRectype* rec = NULL;
if (goto_root() && scan_breadth_first(find_fase_cb, (void*)&fase))
rec = curr_row();
else if (create)
{
if (goto_root())
{
rec = new_row(sl_fase1);
rec->put(RDOC_FASCMS, fase);
TToken_string key; key = rec->get(RDOC_CODCMS); key.add(fase);
TString80 descr = cache().get(LF_FASI, key, FASI_DESCRIZ);
if (descr.empty())
{
key.add(" ", 0);
descr = cache().get(LF_FASI, key, FASI_DESCRIZ);
}
if (descr.full())
rec->put(RDOC_DESCR, descr);
add_lastson(rec);
}
}
return rec;
}
TRectype* TSAL_tree::dist(const TString& fase, int n, bool create)
{
TRectype* rec = NULL;
if (goto_node(fase))
{
if (goto_firstson())
{
int i = 0;
for (; i < n && goto_rbrother(); i++);
if (i < n)
{
if (create)
add_rbrother(rec = new_row(sl_distinta));
}
else
rec = curr_row();
}
else
{
if (create)
add_son(rec = new_row(sl_distinta));
}
}
return rec;
}
TRectype* TSAL_tree::misu(const TString& dist, int n, bool create)
{
TRectype* rec = NULL;
if (goto_node(dist))
{
CHECKS(level() == sl_distinta, "Distinta non valida", (const char*)dist);
if (goto_firstson())
{
int i = level() == sl_misura ? 0 : -1;
while (i < n && goto_rbrother())
if (level() == sl_misura) i++;
if (i < n)
{
if (create)
add_rbrother(rec = new_row(sl_misura));
}
else
rec = curr_row();
}
else
{
if (create && n == 0)
add_son(rec = new_row(sl_misura));
}
}
return rec;
}
TSAL_level TSAL_tree::level(const TRectype& rec) const
{
TSAL_level lev = sl_documento;
if (rec.num() == LF_RIGHEDOC)
{
const TString& t = rec.get(RDOC_TIPORIGA);
if (t.full())
{
lev = sl_fase1;
if (t == _strFasi)
lev = TSAL_level(lev + rec.get_int(RSAL_LEVEL)); else
if (t == _strDist)
lev = sl_distinta; else
if (t == _strMisu)
lev = sl_misura;
}
}
return lev;
}
TSAL_level TSAL_tree::level() const
{
TSAL_level lev = sl_documento;
TRectype* rec = curr_row();
if (rec != NULL)
lev = level(*rec);
return lev;
}
bool TSAL_tree::could_have_son() const
{ return level() < sl_distinta; }
bool TSAL_tree::get_description(TString& str) const
{
const TRectype* rec = curr_row();
bool ok = rec != NULL && !rec->empty();
if (ok)
{
if (rec->num() == LF_DOC)
{
const TMask& m = owner().mask();
str.cut(0) << TR("SAL ") << m.get(F_NSAL) << TR(" del ") << m.get(F_DATADOC);
} else
if (rec->num() == LF_RIGHEDOC)
{
str = rec->get(RDOC_DESCR);
if (str.blank())
str = rec->get(RDOC_CODCMS);
}
else
NFCHECK("Bad tree record");
}
else
NFCHECK("NULL tree record");
return ok;
}
TFieldtypes TSAL_tree::get_var(const TString& name, TVariant& var) const
{
TFieldtypes ft = _nullfld;
const TRectype* rec = curr_row();
if (rec != NULL && !rec->empty())
{
if (rec->num() == LF_DOC)
{
const TMask& m = owner().mask();
if (name == RDOC_CODART)
{
var = m.get(F_NDOC);
ft = _alfafld;
} else
if (name == RDOC_DESCR)
{
TString str; get_description(str);
const int spc = str.find('\n');
if (spc > 0) str.cut(spc);
var = str;
ft = _alfafld;
} else
if (name == RDOC_PREZZO || name == RSAL_COSTO)
{
real c, p; ((TSAL_tree*)this)->ricalcola(c, p);
if (name == RDOC_PREZZO )
var = p.stringa(0,2);
else
var = c.stringa(0,2);
ft = _realfld;
}
}
else
{
ft = rec->type(name);
if (ft > _nullfld)
{
const TSAL_level livello = level(*rec);
if (ft == _realfld)
{
if ((name == RDOC_PREZZO || name == RSAL_COSTO) && livello == sl_distinta)
{
real c, p; ((TSAL_tree*)this)->ricalcola(c, p);
if (name == RDOC_PREZZO )
var = p.stringa(0,2);
else
var = c.stringa(0,2);
}
else
var = rec->get_real(name).stringa(0, 2);
}
else
{
if (name == RDOC_CODART && livello < sl_distinta)
{
TString16 fase = rec->get(RDOC_FASCMS);
if (fase.blank())
{
fase = rec->get(RDOC_CODART);
if (livello < _picture_fasi.items())
{
const TString& pic = _picture_fasi.row(livello-1);
const int len = pic.len();
if (pic[0] == '0')
fase.right_just(len, '0');
else
fase.left_just(len, ' ');
}
((TRectype*)rec)->put(RDOC_FASCMS, fase);
}
var = fase;
}
else
var = rec->get(name);
}
}
}
}
return ft;
}
TImage* TSAL_tree::image(bool sel) const
{
const TSAL_level pl = level();
if (pl <= sl_distinta)
{
const bool ex = expanded();
if (has_son())
return get_res_image(ex ? BMP_DIRDNSEL : BMP_DIRSEL);
else
return get_res_image(ex ? BMP_DIRDN : BMP_DIR);
}
return TObject_tree::image(sel);
}
// Aggiunge un record alla fine dell'albero in base al tipo della riga (usato solo in lettura iniziale)
bool TSAL_tree::append_row(const TRectype& rec)
{
const TSAL_level pl = level(rec);
if (pl == sl_documento)
{
// Se aggiungo un documento allora svuoto albero e ricreo radice
if (goto_root())
kill_node();
return add_son(rec);
} else
if (pl == sl_distinta)
{
const TString16 fascms = rec.get(RDOC_FASCMS);
bool ok = false;
if (fascms.full())
ok = fase(fascms, true) != NULL;
else
ok = goto_last_dist();
return ok && add_lastson(rec);
} else
if (pl == sl_misura)
{
if (goto_last_dist())
return add_lastson(rec);
}
else
{
goto_root();
while (level() < pl)
{
if (goto_firstson())
while (goto_rbrother());
else
break;
}
if (level() < pl)
return add_lastson(rec);
else
return add_rbrother(rec);
}
return false;
}
bool TSAL_tree::ricalcola(real& costo, real& prezzo)
{
bool ok = false;
const TSAL_level lev = level();
costo = prezzo = ZERO;
if (lev < sl_distinta && has_son())
{
TString16 id; curr_id(id);
for (bool go = goto_firstson(); go; go = goto_rbrother())
{
real c, p;
if (ricalcola(c, p))
{
costo += c;
prezzo += p;
}
}
ok = goto_node(id);
if (lev >= sl_fase1)
{
TRectype& rec = *curr_row();
rec.put(RDOC_QTA, 1);
rec.put(RSAL_COSTO, costo);
rec.put(RDOC_PREZZO, prezzo);
}
}
else
{
ok = lev == sl_distinta;
if (ok)
{
const TRectype& rec = *curr_row();
const real qta = rec.get_real(RDOC_QTA);
if (!qta.is_zero())
{
costo = qta * rec.get_real(RSAL_COSTO);
prezzo = qta * rec.get_real(RDOC_PREZZO);
}
}
}
return ok;
}
bool TSAL_tree::load(const TRectype& doc, int nsal)
{
TLog_report log;
// Lettura righe documento
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));
TRecord_array rdoc(keytok, LF_RIGHEDOC);
// Svuota automaticamente albero e crea documento radice
bool done = append_row(doc);
if (done)
{
// Caricamento righe nell'albero
const int last_row = rdoc.last_row();
TString16 curr_fase;
for (int r = rdoc.first_row(); r > 0 && r <= last_row; r = rdoc.succ_row(r))
{
TRectype& rr = rdoc[r];
const TSAL_level sl = level(rr);
const TString& fase = rr.get(RDOC_FASCMS);
if (fase.blank())
{
if (sl < sl_distinta)
curr_fase = rr.get(RDOC_CODART);
rr.put(RDOC_FASCMS, curr_fase);
}
else
curr_fase = fase;
// Gestione copia da ordine o SAL precedente
if (nsal > 0 && sl >= sl_distinta)
{
if (sl >= sl_misura)
continue; // Non copiare le misure!
const real qta = rr.get(RDOC_QTA);
if (nsal == 1) // nsal=1 -> copia da ordine
{
rr.put(RDOC_DAIDRIGA, rr.get(RDOC_IDRIGA));
rr.put(RDOC_QTAGG1, qta); // Inizializza totale riga ordine
rr.put(RDOC_QTAGG2, ZERO); // Totale SAL precedenti (nessuno nel primo SAL)
rr.put(RDOC_QTAGG3, qta); // Residuo (nel primo SAL <20> uguale alla qta)
const TString& sconto = rr.get(RDOC_SCONTO);
if (sconto.full())
{
const real impns = prezzo_scontato(rr.get_real(RDOC_PREZZO), sconto);
if (!impns.is_zero())
rr.put(RDOC_PREZZO, impns);
}
}
else
{
rr.add(RDOC_QTAGG2, qta); // Aggiorna totale precedente quando copi da SAL
rr.add(RDOC_QTAGG3,-qta); // Aggiorna residuo quando copi da SAL
}
rr.zero(RDOC_QTA); // Azzera quantit<69> sempre
}
if (!append_row(rr))
{
TString msg;
msg.format("Impossibile caricare la riga %d di tipo %s:\n%s",
rr.get_int(RDOC_NRIGA), (const char*)rr.get(RDOC_TIPORIGA),
(const char*)rr.get(RDOC_DESCR));
log.log(2, msg);
done = false;
}
} // fine caricamento riga
TMask& m = owner().mask();
if (nsal > 1) // A partire dal secondo sal aggiorno i progressivi di testata P_SAL_*
{
const TDocumento prec(doc);
FOR_EACH_MASK_FIELD(m, i, f)
{
const TFieldref* ref = f->field();
if (ref != NULL && ref->name().starts_with("G1:P_SAL_"))
{
const real p_val = ref->read(prec);
TString16 name = ref->name(); name.ltrim(5);
const real val = prec.get(name);
const real progr = p_val + val;
f->set(progr.string());
}
}
}
const real p_sic2 = m.get_real(F_P_SAL_SIC) + m.get_real(F_P_SAL_ESC);
m.set(F_P_SAL_SIC2, p_sic2);
}
else
{
TString msg; msg.format("Impossibile caricare il documento %s", (const char*)keytok);
log.log(2, msg);
}
// Espansione della sola radice
shrink_all(); goto_root(); expand();
owner().force_update();
if (!done)
log.preview();
return done;
}
TSAL_tree::TSAL_tree(TTree_field& owner) : _owner(owner)
{
// Legge i tipi riga standard per determinare i nodi dell'albero
_strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
_strDist = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDist", "P1");
_strMisu = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaMisu", "P2");
TConfig& cfg = ca_config();
for (int i = 1; i <= 4; i++)
{
const TString& pic = cfg.get("Fsc", "ca", i);
if (pic.full())
_picture_fasi.add(pic);
else
break;
}
}