#include "velib.h" #include #ifndef __EXECP_H #include #endif #ifndef __TABUTIL_H #include #endif /////////////////////////////////////////////////////////// // Lista di documenti /////////////////////////////////////////////////////////// TDate TLista_documenti::num2date(char provv, int anno, const char* codnum, long num) const { TLocalisamfile doc(LF_DOC); CHECK(num > 0, "Numero documento nullo."); TDocumento::set_key(doc.curr(), provv, anno, codnum, num); if (doc.read(_isgteq) != NOERR) // In caso d'errore ... doc.last(); // prendi l'ultimo return doc.get("DATADOC"); } int TLista_documenti::read(char provv, char tipocf, long clifo, int anno, TToken_string& tipidoc, TToken_string& statidoc, const TDate& dd, const TDate& ad, const char* codnum, long dn, long an) { CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?"); CHECK(tipocf == 'C' || tipocf == 'F', "Il tipo deve essere Cliente o Fornitore"); CHECKD(clifo > 0L, "Codice cliente non valido", clifo); CHECKD(anno > 1900, "Anno non valido: ", anno); CHECK(!tipidoc.empty_items(), "Lista dei tipi documento vuota"); CHECK(!statidoc.empty_items(), "Lista degli stati documento vuota"); TRelation doc(LF_DOC); TRectype start(LF_DOC), stop(LF_DOC); int anno_start, anno_stop; start.put("TIPOCF", tipocf); stop.put("TIPOCF", tipocf); start.put("CODCF", clifo); stop.put("CODCF", clifo); start.put("PROVV", provv); stop.put("PROVV", provv); anno_start = anno_stop = anno; if (dd.ok()) { anno_start = dd.year(); start.put("ANNO", anno_start); } if (ad.ok()) { anno_stop = ad.year(); stop.put("ANNO", anno_stop); } if (dn > 0) { const TDate d(num2date(provv, anno_start, codnum, dn)); start.put("DATADOC", d); start.put("ANNO", d.year()); start.put("NDOC", dn); } else { if (dd.ok() && dd > botime) start.put("DATADOC", dd); if (anno_start <= anno_stop) start.put("ANNO", anno_start); } if (an > 0) { const TDate d(num2date(provv, anno_stop, codnum, an)); stop.put("DATADOC", d); stop.put("ANNO", d.year()); stop.put("NDOC", an); } else { if (ad.ok() && ad < eotime) stop.put("DATADOC", ad); stop.put("ANNO", anno_stop); } TString filter(16); if (codnum && *codnum) { bool numfilter = FALSE; if (start.get("DATADOC").empty()) numfilter = TRUE; else start.put("CODNUM", codnum); if (stop.get("DATADOC").empty()) numfilter = TRUE; else stop.put("CODNUM", codnum); if (numfilter) filter << "CODNUM=\"" << codnum << '"'; } TCursor cur(&doc, filter, 2, &start, &stop); const TRectype& head = cur.curr(); _documenti.destroy(); for (cur = 0; cur.ok(); ++cur) { const TString16 tipodoc = head.get("TIPODOC"); const TString16 statodoc = head.get("STATO"); bool match = FALSE; for (int i = tipidoc.items()-1; i>=0; i--) { if (tipodoc == tipidoc.get(i)) if (statodoc == statidoc.get(i)) { match = TRUE; break; } } if (match) { TDocumento* d = new TDocumento(head); _documenti.add(d); } } return _documenti.items(); } int TLista_documenti::write(bool re) const { int err = NOERR; for (int i = 0; i < _documenti.items() && err == NOERR; i++) { err = doc(i).write(re); ((TDocumento&)doc(i)).flush_rows(); } return err; } /////////////////////////////////////////////////////////// // Cliente/Fornitore per vendite /////////////////////////////////////////////////////////// void TLista_clifo::TClifo::init(const TRectype& rec, const TRectype& ven) { _codice = rec.get_long(CLI_CODCF); CHECK(_codice > 0, "Codice cliente nullo"); if (!ven.empty()) { _agente = ven.get_long(CLI_CODAG); _zona = ven.get_long(CLI_CODZONA); } else _agente = _zona = 0; } bool TLista_clifo::TClifo::read(char tipo, long cod) { TRelation clifo(LF_CLIFO); clifo.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); TRectype& curr = clifo.curr(); curr.put(CLI_TIPOCF, tipo); curr.put(CLI_CODCF, cod); if (clifo.read() == NOERR) init(curr, clifo.curr(LF_CFVEN)); else zero(); return ok(); } TLista_clifo::TClifo::TClifo(const TRectype& rec) { CHECK(rec.num() == LF_CLIFO, "Record non clienti"); const char tipo = rec.get_char(CLI_TIPOCF); const long codice = rec.get_long(CLI_CODCF); read(tipo, codice); } int TLista_clifo::leggi(long dc, long ac, long da, long aa, long dz, long az) { TRelation clifo(LF_CLIFO); clifo.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); TRectype start(LF_CLIFO), stop(LF_CLIFO); start.put(CLI_TIPOCF, tipo()); if (dc > 0) start.put(CLI_CODCF, dc); stop.put(CLI_TIPOCF, tipo()); if (ac > 0) stop.put(CLI_CODCF, ac); TString filter(32); if (da > 0) filter << '(' << LF_CFVEN << "->" << CLI_CODAG << ">=" << da << ')'; if (aa > 0) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODAG << "<=" << aa << ')'; } if (dz > 0) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=" << dz << ')'; } if (az > 0) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=" << az << ')'; } TCursor cur(&clifo, filter, 1, &start, &stop); const TRectype& cli = cur.curr(); const TRectype& ven = cur.curr(LF_CFVEN); for (cur = 0; cur.ok(); ++cur) { TClifo* c = new TClifo(cli, ven); _clifo.add(c); } if (dc > 0 || ac > 0) ordina_per_codice(); else if (da > 0 || aa > 0) ordina_per_agente(); else if (dz > 0 || az > 0) ordina_per_zona(); return _clifo.items(); } int TLista_clifo::sort_by_code(const TObject** o1, const TObject** o2) { TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1; TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2; const long d = c1->codice() - c2->codice(); return d == 0L ? 0 : (d > 0 ? +1 : -1); } int TLista_clifo::sort_by_agent(const TObject** o1, const TObject** o2) { TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1; TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2; const long d = c1->agente() - c2->agente(); return d == 0L ? 0 : (d > 0 ? +1 : -1); } int TLista_clifo::sort_by_zone(const TObject** o1, const TObject** o2) { TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1; TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2; const long d = c1->zona() - c2->zona(); return d == 0L ? 0 : (d > 0 ? +1 : -1); } int TLista_clifo::ordina_per_codice() { _clifo.sort(sort_by_code); return _clifo.items(); } int TLista_clifo::ordina_per_agente() { _clifo.sort(sort_by_agent); return _clifo.items(); } int TLista_clifo::ordina_per_zona() { _clifo.sort(sort_by_zone); return _clifo.items(); } int TLista_clifo::find(long cod) const { for (int i = items()-1; i >= 0; i--) if (clifo(i).codice() == cod) break; return i; } int TLista_clifo::add(long cod) { int pos = find(cod); if (pos < 0) { TClifo* c = new TClifo(tipo(), cod); pos = _clifo.add(c); } return pos; } /////////////////////////////////////////////////////////// // TParametri_elaborazione /////////////////////////////////////////////////////////// void TParametri_elaborazione::set(const char * name, const char * val) { _par.add(name, new TString(val), TRUE); } const TString & TParametri_elaborazione::get(const char * name) const { TObject *val = _par.objptr(name); if (val == NULL) return EMPTY_STRING; else return (const TString &) *val; } /////////////////////////////////////////////////////////// // TElaborazione /////////////////////////////////////////////////////////// TElaborazione::TElaborazione(const char* cod) : TRectype(LF_TABCOM) { settab("ELD"); if (cod && *cod) read(cod); } int TElaborazione::read(const char* cod) { CHECK(cod && *cod, "Codice elaborazione nullo"); TTable eld("%ELD"); put("CODTAB", cod); const int err = TRectype::read(eld); if (err != NOERR) yesnofatal_box("Codice elaborazione non valido: %s", cod); return err; } /////////////////////////////////////////////////////////// // TElaborazione_esterna /////////////////////////////////////////////////////////// TElaborazione_esterna::TElaborazione_esterna(const char* cod) : TElaborazione(cod) { } bool TElaborazione_esterna::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) { if (applicazione_esterna().blank()) error_box("Non e' stato specificato il nome del'applicazione esterna"); CHECK(doc_in.items() == 1, "Si deve specificare uno e un solo documento in entrata"); CHECK(doc_out.items() == 1, "Si deve specificare uno e un solo documento in uscita"); TFilename name; name.temp("ext"); TDocumento& d = doc_in[0]; const int doc_fields = d.items(); TString16 par; { TConfig c(name, "Transaction"); c.set("Action", codice()); par.format("%d", LF_DOC); for (int i = 0; i < doc_fields; i++) { const TString16 fname(d.fieldname(i)); TFieldref f(fname, LF_DOC); f.write(c, par, d.get(fname)); } for (TVariable_field * v = d.first_variable_field(); v ; v = d.succ_variable_field()) c.set(v->name(), v->get(), par); const int rows = d.physical_rows(); if (rows > 0) { const row_fields = d[1].items(); for (int r = 1; r <= rows; r++) { TRiga_documento row = d[r]; par.format("%d,%d", LF_RIGHEDOC, r); for (int i = 0; i < row_fields; i++) { const TString16 fname(row.fieldname(i)); TFieldref f(fname, LF_RIGHEDOC); f.write(c, par, row.get(fname)); } } } } TString command_line(applicazione_esterna()); command_line << " /i" << name; TExternal_app app(command_line); if (app.run() == 0) { TConfig c(name, "Main"); if (c.get("Result") == "SUCCESS") { par.format("%d", LF_DOC); for (int i = 0; i < doc_fields; i++) { const TString16 fname(d.fieldname(i)); TFieldref f(fname, LF_DOC); d.put(fname, f.read(c, par)); } for (TVariable_field * v = d.first_variable_field(); v ; v = d.succ_variable_field()) v->put(c.get(v->name(), par)); TString_array p; c.list_paragraphs(p); d.destroy_rows(); int r = 1 ; par.format("%d,%d", LF_RIGHEDOC, r); while (p.find(par) >= 0) { const TString& tiporiga = c.get(RDOC_TIPORIGA, par); TRiga_documento& row = d.new_row(tiporiga); for (int i = row.items()-1; i >= 0; i--) { const TString16 fname(row.fieldname(i)); TFieldref f(fname, LF_RIGHEDOC); const TString& val = f.read(c, par); if (val.not_empty()) row.put(fname, val); } r++; par.format("%d,%d", LF_RIGHEDOC, r); } return TRUE; } } return FALSE; } /////////////////////////////////////////////////////////// // TCopia_documento /////////////////////////////////////////////////////////// TCopia_documento::TCopia_documento(const char* cod) : TElaborazione(cod) { } bool TCopia_documento::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) { CHECK(doc_in.items() == doc_out.items(), "Si deve specificare un numero uguale di documenti in entrata ed in uscita"); for (int d = 0; d < doc_in.items(); d++) { TDocumento& doc_src = doc_in[d]; TDocumento& doc_dest = doc_out[d]; doc_dest.copy_contents(doc_src); doc_dest.put(DOC_DATADOC, data_elab); } return TRUE; } /////////////////////////////////////////////////////////// // TLista_elaborazioni /////////////////////////////////////////////////////////// void TLista_elaborazioni::read() { if (_elab == NULL) { _elab = new TAssoc_array(); TTable eld("%ELD"); for (int err = eld.first(); err == NOERR; err = eld.next()) { TElaborazione * el = NULL; switch (eld.curr().get_int("I0")) { case _esterna : el = new TElaborazione_esterna(eld.curr()); break; case _consegna_ordini: el = new TConsegna_ordini(eld.curr()); break; case _fatturazione_bolle : el = new TFatturazione_bolle(eld.curr()); break; case _contabilizzazione : el = new TContabilizzazione(eld.curr()); break; case _copia_documento : el = new TCopia_documento(eld.curr()); break; case _generazione_effetti : el = new TGenerazione_effetti(eld.curr()); break; default : break; } _elab->add(el->codice(), el); } } } int TLista_elaborazioni::select(TString_array & result, const char * tipo_iniziale, const char * stato_iniziale, const char * tipo_finale, const char * stato_finale) { read(); _elab->restart(); result.destroy(); for (TElaborazione * el = (TElaborazione *)_elab->get(); el ; el = (TElaborazione *) _elab->get()) { bool ok = FALSE; TString ti; if ((tipo_iniziale && *tipo_iniziale) && (stato_iniziale && *stato_iniziale)) for (int i = 0; !ok && i < TElaborazione::_max_tipi_doc_elab; i++) { ti = el->tipo_iniziale(i); const char si = el->stato_iniziale(i); ok |= ti == tipo_iniziale && si == *stato_iniziale; } else ok = TRUE; if ((tipo_finale && *tipo_finale) && (stato_finale && *stato_finale)) ok &= el->tipo_finale() == tipo_finale && el->stato_finale() == stato_finale; if (ok) result.add(el->codice()); } return result.items(); } TElaborazione & TLista_elaborazioni::operator [](const char * key) const { ((TLista_elaborazioni *)this)->read(); return (TElaborazione &) (*_elab)[key]; } void TLista_elaborazioni::update() { delete _elab; _elab = NULL; read(); } TLista_elaborazioni::~TLista_elaborazioni() { if (_elab) delete _elab; }