#include #include #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 > 2000, "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; if (codnum && *codnum > ' ') { if (!start.get(DOC_DATADOC).empty()) start.put(DOC_CODNUM, codnum); if (!stop.get(DOC_DATADOC).empty()) stop.put(DOC_CODNUM, codnum); filter << DOC_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--) { const TString & tipo = tipidoc.get(i); if (tipo.blank() || tipodoc == tipo) { const TString & stato = statidoc.get(i); if (stato.blank() || statodoc == stato) { match = true; break; } } } if (match) { TDocumento* d = new TDocumento(head); _documenti.add(d); } } return _documenti.items(); } int TLista_documenti::write(bool re) const { const int docs = _documenti.items(); TString msg; if (re) msg.format(FR("Aggiornamento di %d documenti"), docs); else msg.format(FR("Creazione di %d documenti"), docs); TProgind pi(docs, msg, true, true); int err = NOERR; for (int i = 0; i < docs && err == NOERR; i++) { TDocumento& d = (TDocumento&)doc(i); err = d.write(re); d.flush_rows(); if (!pi.addstatus(1)) break; } return err; } /////////////////////////////////////////////////////////// // TLista_clifo /////////////////////////////////////////////////////////// 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, const char * dz, const char * 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 && (*dz !='\0')) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=\"" << dz << "\")"; } if (az && (*az !='\0')) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=\"" << az << "\")"; } TCursor cur(&clifo, "", 1, &start, &stop); if (filter.not_empty()) cur.setfilter(filter, TRUE); 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 && (*dz !='\0')) || (az && (*dz !='\0'))) ordina_per_zona(); return _clifo.items(); } int TLista_clifo::leggi_ragsoc(const char *dr, const char * ar, long da, long aa, const char * dz, const char * 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 (dr && *dr) start.put(CLI_RAGSOC, dr); stop.put(CLI_TIPOCF, tipo()); if (ar && *ar) stop.put(CLI_RAGSOC, ar); 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 && (*dz !='\0')) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=\"" << dz << "\")"; } if (az && (*az !='\0')) { if (filter.not_empty()) filter << "&&"; filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=\"" << az << "\")"; } TCursor cur(&clifo, "", 2, &start, &stop); if (filter.not_empty()) cur.setfilter(filter, TRUE); 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); } 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 { int i; for (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 /////////////////////////////////////////////////////////// bool TElaborazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) { SORRY_BOX(); return false; } TElaborazione::TElaborazione(const char* cod) : TRectype(LF_TABCOM) { settab("ELD"); if (cod && *cod) read(cod); } int TElaborazione::read(const char* cod) { int err = NOERR; TRectype::operator=(cache().get("%ELD", cod)); if (empty()) { yesnofatal_box("Codice elaborazione non valido: %s", cod); err = _iskeynotfound; } return err; } bool TElaborazione::is_document_ok(const TRectype & doc) const { bool ok = false; const TString4 codnum(doc.get(DOC_CODNUM)); const TString4 tipodoc(doc.get(DOC_TIPODOC)); const char stato(doc.get_char(DOC_STATO)); const TString& codnumel = codice_numerazione_iniziale(); if (codnumel.blank() || codnum == codnumel) { for (int i = 0; !ok && i < TElaborazione::_max_tipi_doc_elab; i++) { const TString & tipel = tipo_iniziale(i); if (tipel.blank()) break; if (tipodoc == tipel && stato == stato_iniziale(i)) ok = true; } } return ok; } void TElaborazione::tipi_stati_iniziali(TToken_string& tipi, TToken_string& stati) const { TString4 t; tipi.cut(0); stati.cut(0); for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++) { t = tipo_iniziale(i); const char s = stato_iniziale(i); if (t.blank() && s == '\0') break; else if (t.full() || s > ' ') { tipi.add(t); stati.add(s); } } CHECK(!tipi.empty_items(), "Nessun tipo documento valido"); CHECK(!stati.empty_items(), "Nessuno stato documento valido"); } /////////////////////////////////////////////////////////// // 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)); } for (TVariable_field * v = row.first_variable_field(); v ; v = row.succ_variable_field()) c.set(v->name(), v->get(), par); } } } TString command_line(applicazione_esterna()); command_line << " /i" << name; TExternal_app app(command_line); if (app.run() == 0) { TConfig c(name, "Transaction"); 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); } d.stato(stato_finale_doc_iniziale()[0]); 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), _preserve_original_rif(false) { } 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"); pre_process_input(doc_in); for (int d = 0; d < doc_in.items(); d++) { TDocumento& doc_src = doc_in[d]; if (doc_out.items() <= d) { const TString4 codnum = codice_numerazione_finale(); doc_out.add(new TDocumento('D', doc_src.get_int(DOC_ANNO), codnum, 0L)); } TDocumento& doc_dest = doc_out[d]; doc_dest.copy_contents(doc_src); const TString4 tipodoc = tipo_finale(); doc_dest.put(DOC_TIPODOC, tipodoc); const TString4 stato = stato_finale(); doc_dest.put(DOC_STATO, stato); // Scancello tutti gli inutili riferimenti al documento origine if (!_preserve_original_rif) for (int r = doc_dest.physical_rows(); r > 0; r--) doc_dest[r].reset_original_rdoc_key(); if (data_elab.ok()) doc_dest.put(DOC_DATADOC, data_elab); doc_src.put(DOC_STATO, stato_finale_doc_iniziale()); } post_process_input(doc_in); post_process(doc_out, doc_in); return TRUE; }