#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; }