af76bbf855
Files correlati : Ricompilazione Demo : [ ] Commento :sistemati casini da riporto 3.2 git-svn-id: svn://10.65.10.50/trunk@17124 c028cbd2-c16b-5b4b-a496-9718f37d4682
605 lines
15 KiB
C++
Executable File
605 lines
15 KiB
C++
Executable File
#include "velib07.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TMateriali_base_recordset
|
|
///////////////////////////////////////////////////////////
|
|
|
|
const TVariant& TMateriali_base_recordset::get(const char* column_name) const
|
|
{
|
|
const TString name(column_name);
|
|
|
|
if (name[0] != '#')
|
|
{
|
|
TVariant& var = get_tmp_var();
|
|
int rownum = current_row();
|
|
|
|
if (_reverse)
|
|
rownum = items() - 1 - rownum;
|
|
|
|
const TRiga_esplosione * row = (const TRiga_esplosione *)boom().objptr(rownum);
|
|
|
|
if (row != NULL)
|
|
{
|
|
if (name == "LASTQTA")
|
|
var = row->last_qta();
|
|
else
|
|
if (name == "TOTQTA")
|
|
var = row->val();
|
|
else
|
|
{
|
|
if (rownum != _lastrow)
|
|
{
|
|
((TMateriali_base_recordset *) this)->_lastrow = rownum;
|
|
const TCodice_articolo & comp = row->componente();
|
|
const TCodice_articolo & dist = row->distinta();
|
|
TLocalisamfile rd(LF_RDIST);
|
|
|
|
rd.setkey(2);
|
|
rd.put("CODCOMP", comp);
|
|
rd.put("CODDIST", dist);
|
|
if (rd.read() == NOERR)
|
|
*_rdist = rd.curr();
|
|
}
|
|
|
|
|
|
if (_rdist != NULL)
|
|
{
|
|
const TString & v = _rdist->get(column_name);
|
|
|
|
var = v;
|
|
}
|
|
}
|
|
}
|
|
return var;
|
|
}
|
|
return TRecordset::get(column_name);
|
|
}
|
|
|
|
const TVariant& TMateriali_base_recordset::get(unsigned int column) const
|
|
{
|
|
const TRecordset_column_info & ci = column_info(column);
|
|
|
|
return get(ci._name);
|
|
}
|
|
|
|
void TMateriali_base_recordset::requery()
|
|
{
|
|
TDistinta_tree distinta;
|
|
|
|
_boom.destroy();
|
|
int pos1 = query_text().find("MATBASE");
|
|
if (pos1 > 0)
|
|
{
|
|
pos1 += 7;
|
|
_reverse = query_text()[pos1] == '-';
|
|
if (_reverse)
|
|
pos1++;
|
|
int pos = query_text().find("==", pos1);
|
|
int pos2 = -1;
|
|
if (pos > 0)
|
|
{
|
|
TString val(query_text().mid(pos + 2));
|
|
pos2 = val.find("FILTER");
|
|
|
|
if (pos2 > 0)
|
|
val.cut(pos2 - 1);
|
|
|
|
if (val.starts_with("\"") || val.starts_with("'"))
|
|
{
|
|
val.ltrim(1);
|
|
val.rtrim(1);
|
|
}
|
|
else
|
|
{
|
|
TVariant var = get(val);
|
|
val = var.as_string();
|
|
}
|
|
|
|
TCodice_articolo art(val);
|
|
|
|
if (distinta.set_root(art))
|
|
{
|
|
while (isspace(query_text()[pos1]))
|
|
pos1++;
|
|
const int level = atoi(query_text().mid(pos1));
|
|
if (level > 0 || query_text()[pos1] =='0')
|
|
while (isdigit(query_text()[pos1]))
|
|
pos1++;
|
|
while (isspace(query_text()[pos1]))
|
|
pos1++;
|
|
TString8 filter;
|
|
if (query_text()[pos1] != 'S')
|
|
while (isalpha(query_text()[pos1]))
|
|
filter << query_text()[pos1++];
|
|
distinta.explode(_boom, true, RAGGR_EXP_NONE, level, filter);
|
|
}
|
|
pos = query_text().find("FILTER", pos);
|
|
if (pos > 0)
|
|
{
|
|
pos = query_text().find("==", pos);
|
|
if (pos > 0)
|
|
{
|
|
TString val(query_text().mid(pos + 2));
|
|
|
|
if (val.starts_with("\"") || val.starts_with("'"))
|
|
{
|
|
val.ltrim(1);
|
|
val.rtrim(1);
|
|
}
|
|
else
|
|
{
|
|
TVariant var = get(val);
|
|
val = var.as_string();
|
|
}
|
|
const int items = _boom.items();
|
|
for (int i = 0; i < items; i++)
|
|
{
|
|
const TRiga_esplosione * row = (const TRiga_esplosione *)_boom.objptr(i);
|
|
if ( row != NULL && row->componente() != val)
|
|
_boom.destroy(i);
|
|
}
|
|
_boom.pack();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TMateriali_base_recordset::TMateriali_base_recordset(const char* use) : _query(use)
|
|
{
|
|
_lastrow = -1;
|
|
_rdist = new TRectype(LF_RDIST);
|
|
const int nfields = _rdist->items();
|
|
|
|
int pos = 1;
|
|
for ( int i = 0 ; i < nfields; i++)
|
|
{
|
|
TRecordset_column_info * ci = new TRecordset_column_info;
|
|
|
|
ci->_name = _rdist->fieldname(i);
|
|
ci->_pos = pos;
|
|
ci->_type = _rdist->type(ci->_name);
|
|
|
|
const int len = _rdist->length(ci->_name);
|
|
|
|
pos += len;
|
|
ci->_width = len;
|
|
_column.add(ci);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TScalare_recordset
|
|
///////////////////////////////////////////////////////////
|
|
|
|
void TScalare_recordset::requery()
|
|
{
|
|
TDistinta_tree distinta;
|
|
|
|
boom().destroy();
|
|
int pos1 = query_text().find("SCALARE");
|
|
if (pos1 > 0)
|
|
{
|
|
pos1 += 7;
|
|
reverse() = query_text()[pos1] == '-';
|
|
if (reverse())
|
|
pos1++;
|
|
int pos = query_text().find("==", pos1);
|
|
if (pos > 0)
|
|
{
|
|
TString val(query_text().mid(pos + 2));
|
|
|
|
if (val.starts_with("\"") || val.starts_with("'"))
|
|
{
|
|
val.ltrim(1);
|
|
val.rtrim(1);
|
|
}
|
|
else
|
|
{
|
|
TVariant var = get(val);
|
|
val = var.as_string();
|
|
}
|
|
|
|
TCodice_articolo art(val);
|
|
|
|
if (distinta.set_root(art))
|
|
{
|
|
while (isspace(query_text()[pos1]))
|
|
pos1++;
|
|
const int level = atoi(query_text().mid(pos1));
|
|
if (level > 0 || query_text()[pos1] =='0')
|
|
while (isdigit(query_text()[pos1]))
|
|
pos1++;
|
|
while (isspace(query_text()[pos1]))
|
|
pos1++;
|
|
TString8 filter;
|
|
if (query_text()[pos1] != 'S')
|
|
while (isalpha(query_text()[pos1]))
|
|
filter << query_text()[pos1++];
|
|
distinta.explode(boom(), false, RAGGR_EXP_NONE, level, filter);
|
|
}
|
|
pos = query_text().find("FILTER", pos);
|
|
if (pos > 0)
|
|
{
|
|
pos = query_text().find("==", pos);
|
|
if (pos > 0)
|
|
{
|
|
TString val(query_text().mid(pos + 2));
|
|
|
|
if (val.starts_with("\"") || val.starts_with("'"))
|
|
{
|
|
val.ltrim(1);
|
|
val.rtrim(1);
|
|
}
|
|
else
|
|
{
|
|
TVariant var = get(val);
|
|
val = var.as_string();
|
|
}
|
|
const int items = boom().items();
|
|
for (int i = 0; i < items; i++)
|
|
{
|
|
const TRiga_esplosione * row = (const TRiga_esplosione *)boom().objptr(i);
|
|
if ( row != NULL && row->componente() != val)
|
|
boom().destroy(i);
|
|
}
|
|
boom().pack();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TDocument_cache
|
|
///////////////////////////////////////////////////////////
|
|
TObject* TDocument_cache::key2obj(const char* key)
|
|
{
|
|
TToken_string k(key);
|
|
const char provv = *k.get(0);
|
|
const int anno = k.get_int();
|
|
const TString4 codnum= k.get();
|
|
const long ndoc = k.get_long();
|
|
TDocumento* doc = new TDocumento(provv, anno, codnum, ndoc);
|
|
doc->get("IMPONIBILI"); // Bastardata per far funzionare la successiva dirty_fields
|
|
doc->dirty_fields();
|
|
return doc;
|
|
}
|
|
|
|
TDocumento& TDocument_cache::doc(const TRectype& rec)
|
|
{
|
|
TToken_string key;
|
|
key = rec.get(DOC_PROVV);
|
|
key.add(rec.get(DOC_ANNO));
|
|
key.add(rec.get(DOC_CODNUM));
|
|
key.add(rec.get(DOC_NDOC));
|
|
TDocumento& d = *(TDocumento*)objptr(key);
|
|
return d;
|
|
}
|
|
|
|
|
|
TDocument_cache:: TDocument_cache() : TCache(3)
|
|
{
|
|
}
|
|
|
|
TDocument_cache:: ~TDocument_cache()
|
|
{
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TDocument_recordset
|
|
///////////////////////////////////////////////////////////
|
|
|
|
const TVariant& TDocument_recordset::get(int num, const char* field) const
|
|
{
|
|
if (*field != '#')
|
|
{
|
|
const int idx = relation()->log2ind(num);
|
|
if (idx < 0)
|
|
return NULL_VARIANT;
|
|
const int logic = num > 0 ? num : relation()->file(idx).num();
|
|
if (logic == LF_DOC || logic == LF_RIGHEDOC)
|
|
{
|
|
const TRectype& rec = relation()->file(idx).curr();
|
|
// Se non e' un campo standard, ma e' calcolato da una formula...
|
|
if (rec.type(field) == _nullfld && strncmp(field, "G1:", 3) != 0)
|
|
{
|
|
const TDocumento& doc = ((TDocument_cache&)_cache).doc(rec);
|
|
TVariant& var = get_tmp_var();
|
|
|
|
if (xvt_str_compare_ignoring_case(field, "SEGNO") == 0)
|
|
{
|
|
var = doc.is_nota_credito() ? -UNO : UNO;
|
|
} else
|
|
if (xvt_str_compare_ignoring_case(field, "IS_COSTO") == 0)
|
|
{
|
|
bool costo = (doc.tipo().is_costo()) || (!doc.tipo().is_ricavo() && doc.get_char(DOC_TIPOCF)=='F');
|
|
var = costo ? UNO : ZERO;
|
|
} else
|
|
if (xvt_str_compare_ignoring_case(field, "IS_RICAVO") == 0)
|
|
{
|
|
bool ricavo = (doc.tipo().is_ricavo()) || (!doc.tipo().is_costo() && doc.get_char(DOC_TIPOCF)=='C');
|
|
var = ricavo ? UNO : ZERO;
|
|
}
|
|
else
|
|
{
|
|
const TFieldref ref(field, logic);
|
|
if (logic == LF_DOC)
|
|
{
|
|
var = ref.read(doc);
|
|
}
|
|
else
|
|
{
|
|
const int nriga = rec.get_int(RDOC_NRIGA);
|
|
if (nriga > 0 && nriga <= doc.rows())
|
|
{
|
|
const TRiga_documento& rdoc = doc[nriga];
|
|
var = ref.read(rdoc);
|
|
}
|
|
else
|
|
var = NULL_VARIANT;
|
|
}
|
|
}
|
|
return var;
|
|
}
|
|
}
|
|
}
|
|
return TISAM_recordset::get_field(num, field);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TDocument_report
|
|
///////////////////////////////////////////////////////////
|
|
|
|
bool TDocument_report::set_recordset(const TString& query)
|
|
{
|
|
if (query.find("MATBASE") > 0)
|
|
return TReport::set_recordset(new TMateriali_base_recordset(query));
|
|
if (query.find("SCALARE") > 0)
|
|
return TReport::set_recordset(new TScalare_recordset(query));
|
|
|
|
return TReport::set_recordset(new TDocument_recordset(query));
|
|
}
|
|
|
|
bool TDocument_report::load(const char* name)
|
|
{
|
|
const bool ok = TReport::load(name);
|
|
if (ok)
|
|
{
|
|
// Purtroppo il recordset delle sottosezioni deve essere reimpostato a mano
|
|
for (int i = 11; i <= 999; i++)
|
|
{
|
|
TReport_section* sec = find_section('B', i);
|
|
if (sec != NULL)
|
|
{
|
|
TRecordset* recset = sec->recordset();
|
|
if (recset != NULL)
|
|
{
|
|
const TString use = recset->query_text();
|
|
if (use.find("MATBASE") > 0)
|
|
recset = new TMateriali_base_recordset(use);
|
|
else
|
|
if (use.find("SCALARE") > 0)
|
|
recset = new TScalare_recordset(use);
|
|
else
|
|
recset = new TDocument_recordset(use);
|
|
sec->set_recordset(recset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void TDocument_report::output_values(const TRectype& rec, const TString& output)
|
|
{
|
|
TToken_string out(output, '!');
|
|
TString curr;
|
|
for (const char * str = out.get(0); str; str = out.get())
|
|
{ // scansione sugli elementi dell'output
|
|
curr = str;
|
|
int poseq = curr.find('='); // divide la stringa corrente in lvalue e rvalue
|
|
if (poseq < 0)
|
|
{
|
|
curr_field()->set(rec.get(curr));
|
|
}
|
|
else
|
|
{
|
|
int posrv = poseq+1;
|
|
if (poseq >= 0 && curr[posrv] == '=')
|
|
posrv++;
|
|
TString16 fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale
|
|
const TString& dat = rec.get(curr.mid(posrv)); // preleva il nome del campo del file alla destra dell'uguale e lo legge dal record
|
|
TReport_field* campo = field(fld);
|
|
if (campo != NULL)
|
|
campo->set(dat);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TDocument_report::reset_values(const TString& output)
|
|
{
|
|
TToken_string out(output, '!');
|
|
TString curr;
|
|
for (const char * str = out.get(0); str; str = out.get())
|
|
{ // scansione sugli elementi dell'output
|
|
curr = str;
|
|
int poseq = curr.find('='); // divide la stringa corrente in lvalue e rvalue
|
|
if (poseq < 0)
|
|
{
|
|
curr_field()->set("");
|
|
}
|
|
else
|
|
{
|
|
TString16 fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale
|
|
TReport_field* campo = field(fld);
|
|
if (campo != NULL)
|
|
campo->set("");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TDocument_report::msg_parent_doc(TVariant_stack& stack)
|
|
{
|
|
TReport_field& cf = *curr_field();
|
|
|
|
int idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC);
|
|
|
|
if (idx < 0)
|
|
return false;
|
|
|
|
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
|
TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec);
|
|
const TRiga_documento * rdoc = NULL;
|
|
|
|
// Se il campo corrente non appartiene al body allora cerco la prima riga documento buona!
|
|
if (cf.section().type() == 'B')
|
|
{
|
|
idx = ((TISAM_recordset*)recordset())->cursor()->relation()->log2ind(LF_RIGHEDOC);
|
|
if (idx < 0)
|
|
return false;
|
|
|
|
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
|
const int n = rec.get_long("NRIGA");
|
|
|
|
rdoc = &(doc[n]);
|
|
}
|
|
else
|
|
{
|
|
const TRiga_documento * first_desc = NULL;
|
|
|
|
for (int r = 1; r <= doc.physical_rows(); r++)
|
|
{
|
|
const TRiga_documento& row = doc[r];
|
|
if (row.get(RDOC_DANDOC).not_empty())
|
|
{
|
|
if (row.is_descrizione())
|
|
{
|
|
if (first_desc == NULL)
|
|
first_desc = &row; // Non e' una riga buona, ma nemmeno da buttare!
|
|
}
|
|
else
|
|
{
|
|
rdoc = &row;
|
|
break; // Ho trovato la riga buona!
|
|
}
|
|
}
|
|
}
|
|
if (rdoc == NULL && first_desc != NULL)
|
|
rdoc = first_desc;
|
|
}
|
|
|
|
int level = stack.pop().as_int();
|
|
for (; rdoc != NULL && level > 0; level--)
|
|
rdoc = (const TRiga_documento *)(rdoc->find_original_rdoc());
|
|
|
|
const TString& values = stack.pop().as_string();
|
|
const bool is_full = stack.peek().as_bool();
|
|
|
|
if (rdoc != NULL && rdoc->get(RDOC_PROVV).not_empty())
|
|
{
|
|
const char provv = rdoc->get_char(RDOC_PROVV);
|
|
const int anno = rdoc->get_int(RDOC_ANNO);
|
|
const TString4 codnum = rdoc->get(RDOC_CODNUM);
|
|
const long ndoc = rdoc->get_long(RDOC_NDOC);
|
|
|
|
if (is_full)
|
|
{
|
|
TDocumento doc(provv, anno, codnum, ndoc);
|
|
output_values(doc, values);
|
|
}
|
|
else
|
|
{
|
|
TToken_string key;
|
|
key.add(provv); key.add(anno); key.add(codnum); key.add(ndoc);
|
|
const TRectype& doc = cache().get(LF_DOC, key);
|
|
output_values(doc, values);
|
|
}
|
|
}
|
|
else
|
|
reset_values(values);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TDocument_report::msg_parent_row(TVariant_stack& stack)
|
|
{
|
|
int idx = ((TISAM_recordset*)recordset())->cursor()->relation()->log2ind(LF_RIGHEDOC);
|
|
if (idx < 0)
|
|
return false;
|
|
|
|
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
|
const int n = rec.get_long("NRIGA");
|
|
idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC);
|
|
|
|
if (idx < 0)
|
|
return false;
|
|
|
|
TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec);
|
|
|
|
const TRiga_documento * rdoc = &(doc[n]);
|
|
|
|
// Se il campo corrente non appartiene al body allora cerco la prima riga documento buona!
|
|
|
|
int level = stack.pop().as_int();
|
|
for (; rdoc != NULL && level > 0; level--)
|
|
rdoc = (const TRiga_documento *)(rdoc->find_original_rdoc());
|
|
|
|
const TString& values = stack.pop().as_string();
|
|
const bool is_full = stack.peek().as_bool();
|
|
|
|
if (rdoc != NULL && rdoc->get(RDOC_PROVV).not_empty())
|
|
{
|
|
if (is_full)
|
|
{
|
|
const char provv = rdoc->get_char(RDOC_PROVV);
|
|
const int anno = rdoc->get_int(RDOC_ANNO);
|
|
const TString4 codnum = rdoc->get(RDOC_CODNUM);
|
|
const long ndoc = rdoc->get_long(RDOC_NDOC);
|
|
TDocumento doc(provv, anno, codnum, ndoc);
|
|
output_values(doc[rdoc->get_int(RDOC_NRIGA)], values);
|
|
}
|
|
else
|
|
output_values(*rdoc, values);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
size_t TDocument_report::get_usr_words(TString_array& words) const
|
|
{
|
|
TReport::get_usr_words(words);
|
|
|
|
const char* const name[] =
|
|
{
|
|
"DOC_PARENT_DOC", "DOC_PARENT_ROW",
|
|
NULL
|
|
};
|
|
|
|
((TDocument_report*)this)->_first_msg = words.items(); // Calcola il primo numero disponibile
|
|
size_t i;
|
|
for (i = 0; name[i] != NULL; i++)
|
|
words.add(name[i]);
|
|
|
|
return words.items();
|
|
}
|
|
|
|
bool TDocument_report::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
|
|
{
|
|
if (opcode < _first_msg)
|
|
return TReport::execute_usr_word(opcode, stack);
|
|
opcode -= _first_msg;
|
|
switch (opcode)
|
|
{
|
|
case 0 : msg_parent_doc(stack); break;
|
|
case 1 : msg_parent_row(stack); break;
|
|
default: break;
|
|
}
|
|
|
|
while (!stack.pop().is_null()); // Svuota eventuali parametri variabili inutilizzati
|
|
|
|
return true;
|
|
}
|
|
|