#include #include "velib04.h" /////////////////////////////////////////////////////////// // 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_date(DOC_DATADOC); } bool TLista_documenti::find(char provv, int anno, const char * codnum, long ndoc) const { bool found = false; if (ndoc > 0) { const int it = items(); for (int i = 0; !found && i < it; i++) { const TDocumento & d = doc(i); found = ((d.head().get_long(DOC_NDOC) == ndoc) && (d.head().get_char(DOC_PROVV) == provv) && (d.head().get_int(DOC_ANNO) == anno) && (d.head().get(DOC_CODNUM) == codnum)); } } return found; } 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(DOC_TIPOCF, tipocf); stop.put(DOC_TIPOCF, tipocf); start.put(DOC_CODCF, clifo); stop.put(DOC_CODCF, clifo); start.put(DOC_PROVV, provv); stop.put(DOC_PROVV, provv); anno_start = anno_stop = anno; if (dd.ok()) { anno_start = dd.year(); start.put(DOC_ANNO, anno_start); } if (ad.ok()) { anno_stop = ad.year(); stop.put(DOC_ANNO, anno_stop); } if (dn > 0) { const TDate d(num2date(provv, anno_start, codnum, dn)); start.put(DOC_DATADOC, d); start.put(DOC_ANNO, d.year()); start.put(DOC_NDOC, dn); } else { if (dd.ok() && dd > botime) start.put(DOC_DATADOC, dd); if (anno_start <= anno_stop) start.put(DOC_ANNO, anno_start); } if (an > 0) { const TDate d(num2date(provv, anno_stop, codnum, an)); stop.put(DOC_DATADOC, d); stop.put(DOC_ANNO, d.year()); stop.put(DOC_NDOC, an); } else { if (ad.ok() && ad < eotime) stop.put(DOC_DATADOC, ad); stop.put(DOC_ANNO, anno_stop); } TString filter(16); if (codnum && *codnum) { bool numfilter = FALSE; if (start.get(DOC_DATADOC).empty()) numfilter = TRUE; else start.put(DOC_CODNUM, codnum); if (stop.get(DOC_DATADOC).empty()) numfilter = TRUE; else stop.put(DOC_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 TString4 tipodoc = head.get(DOC_TIPODOC); const TString4 statodoc = head.get(DOC_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; } /////////////////////////////////////////////////////////// // 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) { int err = NOERR; *this = cache().get("%ELD", cod); if (empty()) { yesnofatal_box("Codice elaborazione non valido: %s", cod); err = _iskeynotfound; } 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()); c.set("ProvvOut", doc_out[0].get(DOC_PROVV)); c.set("AnnoOut", doc_out[0].get(DOC_ANNO)); c.set("CodNumOut", doc_out[0].get(DOC_CODNUM)); c.set("NDocOut", doc_out[0].get(DOC_NDOC)); 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 int 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"); const TString & res = c.get("Result"); if (res == "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; } else if (res == "OUTDOC") { doc_out[0].read(); 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, false); doc_dest.put(DOC_DATADOC, data_elab); } return TRUE; }