#include "velib05.h" #include "ve1100.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TDoc_recordset /////////////////////////////////////////////////////////// class TDoc_recordset : public TISAM_recordset { TDocumentoEsteso* _doc; TRecnotype _mypos; protected: virtual const TVariant& get_field(int logic, const char* field) const; public: virtual TRecnotype items() const; virtual TRecnotype current_row() const { return _mypos; } virtual bool move_to(TRecnotype pos); TDocumentoEsteso& doc() { return *_doc; } TRiga_documento& riga_doc(int r = 0) const; TDoc_recordset(const TRecordset& doc, const TString& old_query); virtual ~TDoc_recordset(); }; TRecnotype TDoc_recordset::items() const { return _doc->rows(); } TRiga_documento& TDoc_recordset::riga_doc(int n) const { if (n <= 0) n = _mypos+1; if (n > _doc->rows()) // Non dovrebbe succedere mai { n = _doc->new_row().get_int(RDOC_NRIGA); (*_doc)[n].put(RDOC_TIPORIGA, "05"); // Crea ua riga descrizione fittizia } if (n <= 0) n = 1; return (*_doc)[n]; } bool TDoc_recordset::move_to(TRecnotype pos) { const bool ok = pos >= 0 && pos < items(); if (ok) { if (pos != _mypos) { _mypos = pos; TRelation& rel = *relation(); rel.curr(LF_RIGHEDOC) = riga_doc(); // Copia riga corrente nella relazione rel.update(1); // Aggiorna solo i file della relazione dipendenti da LF_RIGHEDOC if (_mypos == 0) { doc().scadenze_reset(); doc().summary_reset(true); } } } else { if (pos == items()) _mypos = pos; } return ok; } const TVariant& TDoc_recordset::get_field(int logic, const char* field) const { if (logic == 0 || logic == LF_DOC) { const TFieldref ref(field, LF_DOC); return get_tmp_var() = ref.read(*_doc); } else if (logic == LF_RIGHEDOC) { const TFieldref ref(field, LF_RIGHEDOC); return get_tmp_var() = ref.read(riga_doc()); } return TISAM_recordset::get_field(logic, field); } static TString _sortexpr; static int compare_rdocs(const TObject** p1, const TObject** p2) { const TRectype& r1 = *(const TRectype*)(*p1); const TRectype& r2 = *(const TRectype*)(*p2); const TString& c1 = r1.get(_sortexpr); const TString& c2 = r2.get(_sortexpr); return c1.compare(c2); } TDoc_recordset::TDoc_recordset(const TRecordset& doc, const TString& old_query) : TISAM_recordset(old_query), _doc(NULL), _mypos(-1) { TRectype curr(LF_DOC); TToken_string query(old_query, '\n'); TToken_string new_query("", '\n'); TString line; _sortexpr.cut(0); FOR_EACH_TOKEN(query, tok) { line = tok; line.trim(); if (line.starts_with("SORT ")) { const int pos = line.find("BY "); if (pos > 0) { _sortexpr = line.mid(pos + 3); _sortexpr.trim(); if (_sortexpr.starts_with("34.")) _sortexpr.ltrim(3); if (_sortexpr.starts_with("RDOC.")) _sortexpr.ltrim(5); } line = query.get(); line.trim(); if (line.starts_with("JOIN TO")) line.insert("34 ", 5); new_query.add(line); continue; } if (line.starts_with("USE ")) { new_query.add(line); for (int i = 0; i < 2; i++) { const char* key[] = { DOC_PROVV, DOC_ANNO, DOC_CODNUM, DOC_NDOC }; line = (i == 0) ? "FROM " : "TO "; for (int k = 0; k < 4; k++) { const TString& val = doc.get(key[k]).as_string(); line << key[k] << "='" << val << "' "; if (i == 0) curr.put(key[k], val); } new_query.add(line); } continue; } new_query.add(line); } set(new_query); _doc = new TDocumentoEsteso(curr); if (_sortexpr.full()) { TRecord_array& rows = _doc->body(); rows.sort(compare_rdocs); } const bool has_conai = (_doc->tipo().add_conai() && _doc->clifor().vendite().get_bool(CFV_CONAIASS)); if (has_conai || _doc->rows() == 0) { const int n = _doc->new_row().get_int(RDOC_NRIGA); TRiga_documento& r = (*_doc)[n]; r.put(RDOC_TIPORIGA, "05"); // Crea ua riga descrizione fittizia if (has_conai) { TConfig c(CONFIG_DITTA, "ve"); TString conai = c.get("DESCCONAIASS"); if (conai.empty()) conai = TR("Contributo CONAI assolto"); r.put(RDOC_DESCR, conai); } } // Posiziona correttamente anche il cursore principale *cursor() = 0L; } TDoc_recordset::~TDoc_recordset() { if (_doc != NULL) delete _doc; } /////////////////////////////////////////////////////////// // TReport_doc /////////////////////////////////////////////////////////// class TReport_doc : public TReport { size_t _first_msg; protected: virtual void include_libraries(bool reload); virtual size_t get_usr_words(TString_array& words) const; virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); TDocumentoEsteso& doc(); TRiga_documento& riga_doc(int n = 0); void output_values(const TRectype& rec, const TString& output); void reset_values(const TString& output); bool msg_cliente(TVariant_stack& stack); bool msg_parent_doc(TVariant_stack& stack); bool msg_parent_row(TVariant_stack& stack); bool msg_riepilogo_iva(TVariant_stack& stack); bool msg_scadenze(TVariant_stack& stack); bool msg_tot_imponibili(TVariant_stack& stack); int set_printed_status(TDocumento& doc) const; public: bool print(const TRecordset& doc, TReport_book& book, bool def, word copies, bool alleg, bool arc); TReport_doc(const char* name); virtual ~TReport_doc(); }; int TReport_doc::set_printed_status(TDocumento& doc) const { int err = NOERR; if (doc.get_char(DOC_PROVV) == 'D') // Se e' una numerazione definitiva { if (doc.stampabile()) // Controlla se non e' gia' nello stato si stampato in definitiva { doc.stato(doc.tipo().stato_finale_stampa()); // Se e' gia' in definitiva aggiorna solo lo stato err = doc.rewrite(); // Invia la transazione di cambio stato se necessario if (::can_dispatch_transaction(doc)) { TFilename tmpname; tmpname.temp(); { // Parentesi strategiche TConfig ini(tmpname, "Transaction"); ini.set("Action", "MODIFY"); ini.set("Firm", prefix().get_codditta()); ini.set("Mode", "A"); TString8 paradoc; paradoc.format("%d", LF_DOC); ini.set_paragraph(paradoc); ini.set(DOC_PROVV, doc.get(DOC_PROVV)); ini.set(DOC_ANNO, doc.get(DOC_ANNO)); ini.set(DOC_CODNUM, doc.get(DOC_CODNUM)); ini.set(DOC_NDOC, doc.get(DOC_NDOC)); ini.set(DOC_STATO, doc.stato()); } ::dispatch_transaction(doc, tmpname); ::remove(tmpname); } } } else // Se e' una numerazione provvisoria { // Scrive il nuovo documento con lo stato, numero e flag di definitiva TDocumento bak_doc; bak_doc = doc; // Setta il flag di nuovo documento bak_doc.put(DOC_STATO,doc.tipo().stato_finale_stampa()); bak_doc.put(DOC_PROVV,"D"); bak_doc.put(DOC_NDOC,-1L); const int pr = bak_doc.physical_rows(); for (int i=1;i<=pr;i++) bak_doc[i].put(DOC_PROVV,"D"); err = bak_doc.write(); // Esegue automagicamente rinumerazione di testata e righe nel caso di reinsert if (err == NOERR) // Cancella il vecchio documento doc.remove(); } return err; } bool TReport_doc::print(const TRecordset& doc, TReport_book& book, bool definitive, word copie, bool can_allegate, bool arc) { const TString old_query = recordset()->query_text(); TDoc_recordset* rs = new TDoc_recordset(doc, old_query); set_recordset(rs); bool printed = false; for (int c = 1; c <= copie; c++) { set_copy(c, copie); // Tenta di stampare gli allegati solo sull'ultima copia definitiva if (c == copie && can_allegate) { const TDocumento& d = rs->doc(); const TTipo_documento& tipodoc = d.tipo(); if (tipodoc.allega_documenti()) { const long codcf = d.get_long(CLI_CODCF); TString_array allegati; for (bool ok = rs->move_first(); ok; ok = rs->move_next()) { const TString& codart = rs->get("RDOC.CODARTMAG").as_string(); const TRectype& anamag = cache().get(LF_ANAMAG, codart); TToken_string golem(anamag.get(ANAMAG_GOLEM), '\n'); if (!golem.empty_items()) { TToken_string key; key.add(d.get(DOC_PROVV)); key.add(d.get(DOC_ANNO)); key.add(d.get(DOC_CODNUM)); key.add(d.get(DOC_NDOC)); TLocalisamfile alleg(LF_MULTIREL); alleg.put(MULTI_COD, "ALLEG"); alleg.put(MULTI_FIRST, codcf); alleg.put(MULTI_SECOND, codart); alleg.put(MULTI_DATA, key); bool print_alleg = alleg.write() == NOERR; // Se riesco a scrivere vuol dire che non esisteva if (!print_alleg) { alleg.put(MULTI_COD, "ALLEG"); alleg.put(MULTI_FIRST, codcf); alleg.put(MULTI_SECOND, codart); if (alleg.read() == NOERR) print_alleg = alleg.get(MULTI_DATA) == key; } if (print_alleg) { FOR_EACH_TOKEN(golem, allegato) { TToken_string a(allegato); TFilename name = a.get(); const bool link = a.get_char(2) > ' '; if (!link) { TFilename golem_path = firm2dir(prefix().get_codditta()); golem_path.add("golem"); golem_path.add(name.name()); name = golem_path; } if (name.exist()) allegati.add(name); } } } } set_allegates(allegati); } } printed = book.add(*this, false); if (!printed) break; } if (printed && definitive) set_printed_status(rs->doc()); if (printed && arc) archive(); set_recordset(old_query); return printed; } TDocumentoEsteso& TReport_doc::doc() { TDoc_recordset* rs = (TDoc_recordset*)recordset(); return rs->doc(); } TRiga_documento& TReport_doc::riga_doc(int n) { TDoc_recordset* rs = (TDoc_recordset*)recordset(); return rs->riga_doc(n); } bool TReport_doc::msg_cliente(TVariant_stack& stack) { TReport_field& cf = *curr_field(); const TCli_for& cli_for = doc().clifor(); const TOccasionale& cli_occ = doc().occas(); const bool occasionale = cli_for.occasionale(); TString in = stack.pop().as_string(); // prende la macro o il fieldref TString valore; if (in[0] != '!') { // Controlla l'esistenza dei campi... if (occasionale && cli_occ.exist(in)) valore = cli_occ.get(in); if (!occasionale && cli_for.exist(in)) valore = cli_for.get(in); cf.set(valore); return true; } in.ltrim(1); if (in=="INDNUM") { valore = occasionale ? cli_occ.get(OCC_INDIR) : cli_for.get(CLI_INDCF); valore << ' '; valore << (occasionale ? cli_occ.get(OCC_CIV) : cli_for.get(CLI_CIVCF)); cf.set(valore); return true; } if (in.find("COM") == 0) { const bool nascita = in[3] == 'N'; const int p = in.find("->"); if (p > 0) in.ltrim(p + 2); TString8 key; if (nascita) { key = occasionale ? cli_occ.get(OCC_STATONASC) : cli_for.get(CLI_STATONASC); key << '|' << (occasionale ? cli_occ.get(OCC_COMNASC) : cli_for.get(CLI_COMNASC)); } else { key = occasionale ? cli_occ.get(OCC_STATO): cli_for.get(CLI_STATOCF); key << '|' << (occasionale ? cli_occ.get(OCC_COM): cli_for.get(CLI_COMCF)); } valore = cache().get(LF_COMUNI, key, in); cf.set(valore); return true; } if (in.find("CAP") == 0) { valore = occasionale ? cli_occ.get(OCC_CAP) : cli_for.get(CLI_CAPCF); cf.set(valore); return true; } if (in.find("TEL") == 0) { if (!occasionale) { if (in.len() == 3) in << "1"; const TString num(cli_for.get(in)); in.insert("P"); valore = cli_for.get(in); valore << "/" << num; } cf.set(valore); return true; } if (in=="FAX") { if (!occasionale) { valore = cli_for.get("PFAX"); valore << "/" << cli_for.get("FAX"); } cf.set(valore); return true; } if (in=="RAGSOC") { valore = occasionale ? cli_occ.get(in) : cli_for.get(in); valore.strip_double_spaces(); cf.set(valore); return true; } return false; } void TReport_doc::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 TReport_doc::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 TReport_doc::msg_parent_doc(TVariant_stack& stack) { TReport_field& cf = *curr_field(); const TRectype* rdoc = &riga_doc(); // Se il campo corrente non appartiene al body allora cerco la prima riga documento buona! if (cf.section().type() != 'B') { const TRiga_documento* first_merc = NULL; const TRiga_documento* first_desc = NULL; for (int r = 1; r <= doc().physical_rows(); r++) { const TRiga_documento& row = riga_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 { first_merc = &row; break; // Ho trovato la riga buona! } } } if (first_merc != NULL) rdoc = first_merc; else { if (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 TReport_doc::msg_parent_row(TVariant_stack& stack) { const TRectype* rdoc = &riga_doc(); 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; } bool TReport_doc::msg_riepilogo_iva(TVariant_stack& stack) { // tabella riepilogo aliquote iva e relative imposte // sintassi: _RIEPILOGOIVA,,, // dove: è uno dei seguenti: // 1 = codici IVA a regime normale // 2 = codici IVA da ventilare // 4 = codici IVA esenti // 8 = codici IVA non imponibili // 16 = codici IVA non soggetti // oppure la combinazione di uno o piu' di essi: // 12 = 4+8, 19 = 1+2+16, 29 = 1+4+8+16 ecc... // dove: è uno dei seguenti: // COD colonna dei codici // IMP colonna degli imponibili // IVA colonna delle imposte // ALI colonna delle aliquote // DES colonna delle descrizioni (stampata solo se il regime IVA non e' normale) // dove: è uno dei seguenti: // 0 indica di non leggere il successivo codice IVA nella tabella riepilogativa // 1 indica di leggere il successivo codice IVA nella tabella riepilogativa const int selector = stack.pop().as_int(); if (selector != 0) { TDocumentoEsteso& d = doc(); d.summary_filter(selector); const TString& what = stack.pop().as_string(); // cosa deve stampare ? const TVariant value = d.summary_get(what); // Piglia il valore dalla riga selezionata sulla tabellina curr_field()->set(value); const bool next = stack.pop().as_bool(); // deve cambiare elemento ? if (next) d.summary_set_next(); } return true; } bool TReport_doc::msg_scadenze(TVariant_stack& stack) { const TString& what = stack.pop().as_string(); const TVariant value = doc().scadenze_get(what); curr_field()->set(value); const bool next = stack.pop().as_bool(); if (next) doc().scadenze_set_next(); return true; } bool TReport_doc::msg_tot_imponibili(TVariant_stack& stack) { TReport_field& cf = *curr_field(); // sintassi: _TOTIMPONIBILI, // dove: funge da filtro per la somma degli imponibili // se selettore vale 0 restituisce il tot. imponibili con le spese // vedi _RIEPILOGOIVA per la spiegazione dei filtri selettivi const int sel = stack.pop().as_int(); const TVariant x = (sel == 0) ? doc().imponibile(true) : doc().tot_imponibili(sel); cf.set(x); return true; } size_t TReport_doc::get_usr_words(TString_array& words) const { TReport::get_usr_words(words); const char* const name[] = { "DOC_CLIENTE", "DOC_PARENT_DOC", "DOC_PARENT_ROW", "DOC_RIEPILOGO_IVA", "DOC_SCADENZE", "DOC_TOT_IMPONIBILI", NULL }; ((TReport_doc*)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 TReport_doc::execute_usr_word(unsigned int opcode, TVariant_stack& stack) { bool ok = true; if (opcode >= _first_msg) { switch (opcode - _first_msg) { case 0: msg_cliente(stack); break; case 1: msg_parent_doc(stack); break; case 2: msg_parent_row(stack); break; case 3: msg_riepilogo_iva(stack); break; case 4: msg_scadenze(stack); break; case 5: msg_tot_imponibili(stack); break; default: ok = false; break; } stack.reset(); // Svuota eventuali parametri variabili inutilizzati } else ok = TReport::execute_usr_word(opcode, stack); return ok; } void TReport_doc::include_libraries(bool reload) { TReport::include_libraries(reload); if (reload || !defined("MESSAGE_DESCRIGA")) include("ve1300.alx"); } TReport_doc::TReport_doc(const char* name) { // istanziamento e impostazione della relazione di gestione della ditta corrente load(name); // Faccio la load altrimenti non include la libreria 1300.alx } TReport_doc::~TReport_doc() { } /////////////////////////////////////////////////////////// // TDoc_book /////////////////////////////////////////////////////////// class TDoc_book : public TReport_book { protected: virtual void draw_link(const TRectangle& rect, const char* text, const char* link); }; void TDoc_book::draw_link(const TRectangle& rect, const char* text, const char* link) { if (main_app().argc() < 6) // Vieta i link quando sono in batch TReport_book::draw_link(rect, text, link); } /////////////////////////////////////////////////////////// // TReport_doc_mask /////////////////////////////////////////////////////////// class TReport_doc_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TReport_doc_mask(); }; bool TReport_doc_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DA_NDOC: if (e == fe_modify) { const long dal = get_long(F_DA_NDOC); const long al = get_long(F_A_NDOC); if (al < dal) set(F_A_NDOC, dal); } break; default: break; } return true; } TReport_doc_mask::TReport_doc_mask() : TAutomask("ve1100a") { hide(F_PROVV); enable(DLG_EMAIL); } /////////////////////////////////////////////////////////// // TReports_cache /////////////////////////////////////////////////////////// class TReports_cache : TCache { protected: virtual TObject* key2obj(const char* key); public: TReport_doc& get(const TString& key) { return *(TReport_doc*)objptr(key); } TReports_cache() : TCache(7) { } }; TObject* TReports_cache::key2obj(const char* key) { TReport_doc* rep = new TReport_doc(key); return rep; } /////////////////////////////////////////////////////////// // TReport_doc_app /////////////////////////////////////////////////////////// class TReport_doc_app : public TSkeleton_application { TReport_doc_mask* _msk; int _anno; TString16 _codnum; // codice numerazione / profilo long _ndoc, _codcf; char _tipocf; protected: void add_data_filter(TString& query, bool from) const; void add_ndoc_filter(TString& query, bool from) const; void add_filter(TString& str, bool from) const; bool print_loop(const TString& query, bool send_by_mail); void print_selection(bool send_by_mail = false); void set_next_pdf(int an, const char* cn, long nd, char tcf, long cf); virtual bool get_next_pdf(int anno, long ditta, const char* codnum, long numdoc, long codcf, TFilename& pdf) const; const TString & get_mail_address() const; virtual bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, TString& subj, TString& text, TToken_string& attach, bool& ui) const ; public: virtual bool create(); virtual void main_loop(); virtual bool destroy(); }; void TReport_doc_app::set_next_pdf(int an, const char* cn, long nd, char tcf, long cf) { _anno = an; _codnum = cn; _ndoc = nd; _tipocf = tcf; _codcf = cf; } bool TReport_doc_app::get_next_pdf(int anno, long ditta, const char* codnum, long ndoc, long codcf, TFilename& pdf) const { bool ok = false; if (_anno > 0 && _codnum.full() && _ndoc > 0 && _codcf > 0) ok = TSkeleton_application::get_next_pdf(_anno, ditta, _codnum, _ndoc, _codcf, pdf); return ok; } const TString & TReport_doc_app::get_mail_address() const { TString key; key << _tipocf << '|' << _codcf; return cache().get(LF_CLIFO, key, CLI_DOCMAIL); } bool TReport_doc_app::get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, TString& subj, TString& text, TToken_string& attach, bool& ui) const { bool ok = TApplication::get_next_mail(to, cc, ccn, subj, text, attach, ui); if (_ndoc > 0L) { to = get_mail_address(); ok = to.full(); if (ok) { TDocumento doc('D', _anno, _codnum, _ndoc); doc.riferimento(subj); if (subj.blank()) subj = doc.tipo().descrizione(); text << "Invio documento " << subj; } } return ok; } void TReport_doc_app::add_data_filter(TString& query, bool from) const { if (from) { query << " KEY 3 SELECT " << "(PROVV='D')&&(ANNO=" << _msk->get(F_ANNO) << ")&&(CODNUM='" << _msk->get(F_CODNUM) << "')"; } query << '\n'; const TDate d = _msk->get(from ? F_DA_DATADOC : F_A_DATADOC); if (d.ok()) query << (from ? "FROM" : "TO") << " DATADOC=" << d.date2ansi(); } void TReport_doc_app::add_ndoc_filter(TString& query, bool from) const { query << '\n' << (from ? "FROM" : "TO") << " PROVV='D' ANNO=" << _msk->get(F_ANNO) << " CODNUM='" << _msk->get(F_CODNUM) << '\''; const long ndoc = _msk->get_long(from ? F_DA_NDOC : F_A_NDOC); if (ndoc > 0) query << " NDOC=" << ndoc; } void TReport_doc_app::add_filter(TString& query, bool from) const { const bool per_data = _msk->get(F_DATA_O_NUM) == "D"; if (per_data) add_data_filter(query, from); else add_ndoc_filter(query, from); } bool TReport_doc_app::create() { if (!has_module(RSAUT)) return error_box(TR("Modulo non autorizzato")); _msk = new TReport_doc_mask; return TSkeleton_application::create(); } bool TReport_doc_app::destroy() { delete _msk; return TSkeleton_application::destroy(); } bool TReport_doc_app::print_loop(const TString& query, bool send_by_mail) { TISAM_recordset doc(query); const int docs = doc.items(); if (docs <= 0) return false; bool is_definitive = false; if (argc() > 7) // Batch is_definitive = *argv(7) == 'D'; else { const KEY k = yesnocancel_box(FR("Stampare in definitiva %d documenti?"), docs); if (k == K_ESC) return false; is_definitive = k == K_YES; } TReports_cache reports; // Cache degli ultimi reports usati TDoc_book book; // Destinazione dell'intera stampa TDoc_book* mail_book = NULL; // Destinazione dell'intera stampa TLog_report log(TR("Invio documenti per email")); TProgind pi(docs, TR("Elaborazione documenti..."), true, true); for (int i = 0; i < docs; i++) { if (!pi.addstatus(1)) break; doc.move_to(i); bool arc = false; if (is_definitive) { const TString& codnum = doc.get(DOC_CODNUM).as_string(); const TCodice_numerazione& cn = cached_numerazione(codnum); arc = cn.auto_archive(); } set_next_pdf(doc.get(DOC_ANNO).as_int(), doc.get(DOC_CODNUM).as_string(), doc.get(DOC_NDOC).as_int(), doc.get(DOC_TIPOCF).as_string()[0], doc.get(DOC_CODCF).as_int()); const TString& tipodoc = doc.get(DOC_TIPODOC).as_string(); const TTipo_documento& tipo = cached_tipodoc(tipodoc); const bool send_mail = send_by_mail && get_mail_address().full(); TFilename profilo; // Tenta di costruirsi il nome del report bool ok = false; if (send_mail) ok = tipo.mail_print_profile(profilo); else ok = tipo.main_print_profile(profilo, 2); if (ok) { int copies = _msk->get_int(F_NCOPIE); if (copies <= 0 && is_definitive) copies = tipo.ncopie(); if (copies <= 0) copies = 1; TReport_doc& report = reports.get(profilo); if (send_mail) { mail_book = new TDoc_book; if (!report.print(doc, *mail_book, is_definitive, 1, true, arc)) break; TString mesg; mesg << tipo.descrizione() << TR(" n. ") << doc.get(DOC_NDOC).as_int() << TR(" a ") << get_mail_address(); log.log(0, mesg); } else { if (!report.print(doc, book, is_definitive, copies, true, arc)) break; } } //if(profilo.custom_path()... else { TString msg; msg << TR("Report inesistente") << " : " << profilo; statbar_set_title(TASK_WIN, msg); beep(2); continue; } // Stampa eventuali allegati if (tipo.additional_print_profile(profilo, 2)) { int copies = tipo.additional_ncopie(); if (copies <= 0) copies = 1; TReport_doc& allegato = reports.get(profilo); // Cambio _codnum per non sovrascrivere il pdf precedente if (arc) { _codnum = profilo.name(); _codnum = _codnum.before("."); } // Il flag di definitvo deve essere false altrimenti riaggiorna lo stato e ristampa i documenti allegati if (send_mail) allegato.print(doc, *mail_book, false, 1, false, arc); else allegato.print(doc, book, false, copies, false, arc); } if (mail_book != NULL) { if (mail_book->pages() > 0) { TFilename attachment; attachment.tempdir(); attachment << SLASH << _anno <<'_' << _codnum << '_' << _ndoc; attachment.ext("pdf"); mail_book->send_mail(attachment); remove(attachment); } delete mail_book; mail_book = NULL; } } if (book.pages() > 0) { if (docs > 1) set_next_pdf(0, "", 0L, ' ', 0L); // Disabilita archiviazione PDF book.add(log); book.print_or_preview(); } return true; } void TReport_doc_app::print_selection(bool send_by_mail) { TString query; query << "USE " << LF_DOC; add_filter(query, true); add_filter(query, false); print_loop(query, send_by_mail); } void TReport_doc_app::main_loop() { if (argc() > 6) // Stampa da riga di comando { _msk->set(F_DATA_O_NUM, "N"); // Stampa per numero documento _msk->set(F_PROVV, argv(4)); _msk->set(F_ANNO, argv(3)); _msk->set(F_CODNUM, argv(2)); _msk->set(F_DA_NDOC, argv(5)); _msk->set(F_A_NDOC, argv(6)); // argv(7) = stampa Definitiva o Provvisoria if (argc() > 8) _msk->set(F_NCOPIE, argv(8)); // Numero copie print_selection(); } else { KEY k; while ((k = _msk->run()) != K_QUIT) // Stampa interattiva print_selection(k != K_ENTER); } } int ve1300(int argc, char* argv[]) { TReport_doc_app a; a.run(argc, argv, TR("Stampa documenti")); return (0); }