From 8d83316486c8a8b3e2ce2bc29deaa5ee00f758ea Mon Sep 17 00:00:00 2001 From: angelo <angelo@c028cbd2-c16b-5b4b-a496-9718f37d4682> Date: Thu, 2 Jan 1997 09:01:59 +0000 Subject: [PATCH] Nuova versione programma di stampa documenti, utilizzo piu' intensivo di TDocumento e TRiga_documento. Alias: More Cazzuted. git-svn-id: svn://10.65.10.50/trunk@4034 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ve/ve1100.cpp | 1252 +++++++++++++++++++++++++++---------------------- 1 file changed, 702 insertions(+), 550 deletions(-) diff --git a/ve/ve1100.cpp b/ve/ve1100.cpp index 0feb673b3..f5ff403fd 100755 --- a/ve/ve1100.cpp +++ b/ve/ve1100.cpp @@ -10,65 +10,61 @@ #include <urldefid.h> #include <progind.h> -#include "velib02.h" +#include <doc.h> +#include <rdoc.h> #include "ve1100.h" #include "ve0100b.h" +#include "velib02.h" -////////////////////////////////////////////////////////////////////////////////////////////// -// classe TStampa_Doc_Vendita customizzata dalla TApplication per l'applicazione principale -////////////////////////////////////////////////////////////////////////////////////////////// - -enum behaviour { - skip, - go, - cancel -}; +#define Usage "Usage: ve1 -1 [codnum anno {D|P} dalnum alnum {D|P} [ncopie]]" -class TDocVen_Form; +// Queste classi (TDocisamfile e TRDocisamfile) servono nel costruttore di TDocumento_form +// in modo da sostituire i file della relazione, ovvero LF_DOC e LF_RIGHEDOC. +// Facendo in questo modo ogni get() del record, viene reindirizzata alla get() dei +// TVariable_recfield, in modo da utilizzare nel form le istruzioni FIELD anche per i campi +// virtuali. -class TStampa_Doc_Vendita: public TApplication { - TString _codnum; // codice di numerazione - TString _provv; // stampa provvisioria - int _anno; // anno della documentazione - int _ncopie, _base_page_no; // numero di copie per ogni documento, numero della pagina base per stampare il numero di pagina - long _dalnum, _alnum; // estremi di numerazione dei documenti - TDate _dadata, _adata; // estremi di data dei documenti - bool _order_by_num; // flag che indica se e' stato selezionato l'ordine principale per numero documento - bool _interattivo; // flag che indica se il prog. funziona in interattivo o in batch - bool _definitiva; // flag che indica se la stampa � definitiva o no - TRelation *_firmrel; // puntatore alla relazione che gestisce i dati della ditta corrente - TDocVen_Form *_form; // puntatore al form di stampa -protected: - virtual bool create(void); - virtual bool destroy(void); - virtual bool menu(MENU_TAG); - int select(void); - virtual void print(void); - virtual void on_firm_change(void); - virtual behaviour on_module_change(const TString &, TString &); // funzione chiamata ad ogni cambio modulo durante la stampa - virtual bool query_final_print(void); // funzione chiamata all'inizializzazione per sapere se la stampa � definitiva - static bool date2num_handler(TMask_field& f, KEY key); - static bool range_handler(TMask_field& f, KEY key); - static bool filter_rows(const TRelation * r); +class TDocisamfile : public TLocalisamfile +{ + TDocumento *_doc; public: - int base_no() { return _base_page_no;} + virtual TRectype& curr() const { return (TRectype&) *_doc; } + TDocisamfile(TDocumento* doc) : TLocalisamfile(LF_DOC) { _doc = doc;} + virtual ~TDocisamfile() {}; }; - -inline TStampa_Doc_Vendita& app() { return (TStampa_Doc_Vendita&) main_app(); } +class TRDocisamfile : public TLocalisamfile +{ + TDocumento *_doc; + int _row; +protected: + TDocumento& doc() const { return *_doc;} +public: + virtual TRectype& curr() const {return (TRectype&) doc()[_row>0 ? _row : 1];} + void set_row(int r) { _row = r;} + TRDocisamfile(TDocumento* doc) : TLocalisamfile(LF_RIGHEDOC) { _doc = doc; _row = 1;} + virtual ~TRDocisamfile() {}; +}; //////////////////////////////////////////////////////////////////////////// -// classe TDocVen_Form customizzata dalla Form per i documenti di vendita +// classe TDocumento_form customizzata dalla Form per i documenti //////////////////////////////////////////////////////////////////////////// -class TDocVen_Form: public TForm { +class TDocumento_form : public TForm +{ + + static TDocumento_form* _form; + TDocisamfile* _docfile; + TRDocisamfile* _rdocfile; + TLocalisamfile *_tab; + TTable *_tip; TRelation &_firmrel; // relazione di gestione dei dati della ditta corrente TString _module; // codice del modulo di carta associato a questo al form TCliFor *_cliente; // oggetto per le informazioni sul cliente TString_array _exclude_array; // array di coppie tipo/articolo da escludere dalla stampa - TDocumentoEsteso * _doc; // oggetto - bool _cli_loaded; // flag che indica se l'oggetto cliente � gi� stato caricato + TDocumentoEsteso * _doc; // Documento da stampare + bool _valid, _cli_loaded; // flag che indica se il form e' valido | se l'oggetto cliente � gi� stato caricato TString_array _group_decimals; // Array di TToken_string per ogni gruppo definito in GENERAL. // Il primo elelemento della token_string conterra' il numero del gruppo // il secondo il n.ro di decimali per importi in lire ed il terzo il n.ro @@ -89,24 +85,81 @@ class TDocVen_Form: public TForm { protected: virtual void extended_parse_general(TScanner &); // gestione dei parametri estesi nella sezione general virtual bool validate(TForm_item &, TToken_string &); // gestione dei messaggi estesi nei campi - virtual word set_body(word p, bool u); // derivata per la gestione del totalizzatore void edit_picture(TForm_item & f, const int dec); void modify_pictures(); + bool print_on_body(int r); // Trascrive la riga 'r' del documento sul body. Ritorna TRUE se va stampata, FALSE se va saltata + + void print_header(TPrinter& p); // Stampa la testata + void print_footer(TPrinter& p); // Stampa la pedata + + static void doc_header_handler(TPrinter& p); + static void doc_footer_handler(TPrinter& p); + public: + void print_documento(); + bool valid() { return _valid; } + bool doc_arrange(); + int ncopie() { return _doc->tipo().ncopie(); } const TString &get_module_code() { return _module; } // ritorna il codice del modulo di carta TString_array & exclude_list() { return _exclude_array; } - TDocumentoEsteso* doc() { return _doc; } - TDocVen_Form(const char *, TRelation &, TDocumentoEsteso * ); - virtual ~TDocVen_Form(); + TDocumentoEsteso& doc() { return *_doc; } + TDocumento_form(TRectype& cur_doc, TRelation& rel, const bool definitiva, const bool interattivo); + virtual ~TDocumento_form(); }; +TDocumento_form* TDocumento_form::_form = NULL; +TDocumento_form::TDocumento_form(TRectype& cur_doc, TRelation& rel, const bool definitiva, const bool interattivo): TForm(), _firmrel(rel), _valid(FALSE) +{ + _form = this; + + _tip = new TTable("%TIP"); + _tab = new TLocalisamfile(LF_TAB); + TString nomeform; + TFilename profilo; + TString codnum(cur_doc.get(DOC_CODNUM)); + TString numdoc(cur_doc.get(DOC_NDOC)); + + _tip->put("CODTAB", cur_doc.get(DOC_TIPODOC)); // posiziona la tabella dei tipi di documento + int err=_tip->read(); // legge la tabella + if (err==NOERR) + { // se non ci sono errori procede con la stampa + nomeform= _tip->get("S5"); // legge il nome del form di stampa + profilo= _tip->get("S4"); // legge il nome del profilo di configurazione + profilo.ext("ini"); // aggiunge l'estensione al nome del file del profilo + if (profilo.empty() || nomeform.empty()) + { + error_box("Nome profilo o form di stampa non valido nella tabella TIP"); + return; + } + TConfig config(profilo, "STAMPA"); // apre il file di configurazione del profilo + TToken_string stati((const char*)config.get("STATIVALIDI"), ','); // legge gli stati validi di questo tipo di documento + if (definitiva && (stati.get_pos(cur_doc.get(DOC_STATO))== -1)) + // se lo stato del doc. corrente non � valido... + if (interattivo) + { + error_box("Non � possibile stampare il documento %s %s con stato non valido", (const char*) codnum, (const char*) numdoc); // ...viene mostrato un messaggio (solo in modo interattivo)... + return; + } + } + else + { + error_box("Il documento %s %s non � stato trovato nella tabella dei tipi di documento (errore %d)", + (const char*) codnum,(const char*) numdoc,err); + return; + } + _valid = TRUE; -TDocVen_Form::TDocVen_Form(const char* name, TRelation &rel, TDocumentoEsteso * doc): TForm(), _firmrel(rel) { - read(name); + + read(nomeform); _cliente= new TCliFor; _cli_loaded= FALSE; - _doc = doc; + + _doc = new TDocumentoEsteso(cur_doc); // istanzia TDocumentoEsteso + _docfile = new TDocisamfile(_doc); + _rdocfile = new TRDocisamfile(_doc); + relation()->replace(_docfile,0); + relation()->replace(_rdocfile,1); modify_pictures(); dec_parm p; const int items = _group_decimals.items(); @@ -128,14 +181,117 @@ TDocVen_Form::TDocVen_Form(const char* name, TRelation &rel, TDocumentoEsteso * } } _doc->set_decimals(p); + + TPrinter& pr = printer(); + + pr.setheaderhandler(doc_header_handler); + TPrint_section& head = section('H'); + pr.headerlen(head.height()); + + pr.setfooterhandler(doc_footer_handler); + const TPrint_section& foot = section('F'); + pr.footerlen(foot.height()); } -TDocVen_Form::~TDocVen_Form() { +TDocumento_form::~TDocumento_form() +{ delete _cliente; if (_doc) delete _doc; + if (_tip) delete _tip; + if (_tab) delete _tab; + if (_docfile) delete _docfile; + if (_rdocfile) delete _rdocfile; } -void TDocVen_Form::edit_picture(TForm_item & fi, const int dec) +bool TDocumento_form::doc_arrange() +{ + TPrinter& pr = printer(); + + if (char_to_pos() != '\0' || (ipx()+ipy()+fpx()) != 0) + { + if (offset_x() != 0 || offset_y() != 0) + { + error_box("Non e' possibile settare contemporaneamente gli offset" + " e i parametri di posizionamento del modulo %s.", (const char*)name()); + return FALSE; + } + else + if (pr.printtype() == winprinter) + _form->arrange_form(); + } + else + pr.set_offset(_form->offset_x(),_form->offset_y()); + return TRUE; +} + +void TDocumento_form::print_documento() +{ + // stampa tutte le righe + TPrint_section& body = section('B'); + TPrint_section& foot = section('F'); + TPrinter& pr = printer(); + + const int righe = _doc->rows(); + + set_last_page(FALSE); // E' importante settare questo flag, per evitare "Falli di Piede" eheh :-) + for (int r=1; r<=righe; r++) + { + _rdocfile->set_row(r); + if (pr.rows_left() <= (body.height()+1)) // salto pagina + pr.formfeed(); + + if (!print_on_body(r)) continue; + + const word h = body.height(); + for (word j = 0; j < h; j++) + pr.print(body.row(j)); + } + + set_last_page(TRUE); // Cosi' stampera' l'ultima pagina del footer + pr.formfeed(); + // Rimette ad 1 il numero della pagina + pr.setcurrentpage(1); +} + +void TDocumento_form::print_header(TPrinter& pr) +{ + TPrint_section& head = section('H'); + + head.update(); + + const word r = head.height()-1; + + for (word j = 0; j <= r; j++) + pr.setheaderline(j, head.row(j)); +} + + +void TDocumento_form::print_footer(TPrinter& pr) +{ + const bool p = _form->page(pr)>0; + TPrint_section& foot = section('F',p ? odd_page : last_page); + + foot.update(); + const word r = foot.height()-1; + + for (word j = 0; j <= r; j++) + pr.setfooterline(j, foot.row(j)); + +} + +void TDocumento_form::doc_header_handler(TPrinter& pr) +{ + pr.resetheader(); + _form->print_header(pr); +} + +void TDocumento_form::doc_footer_handler(TPrinter& pr) +{ + pr.resetfooter(); + _form->print_footer(pr); +} + +void TDocumento_form::edit_picture(TForm_item & fi, const int dec) { TString old_picture(20); old_picture = fi.picture(); @@ -169,7 +325,7 @@ void TDocVen_Form::edit_picture(TForm_item & fi, const int dec) fi.set_picture(new_picture); // setta la nuova picture } -void TDocVen_Form::modify_pictures() +void TDocumento_form::modify_pictures() { const bool valuta = _doc->in_valuta(); const char sechar[4] = { 'B', 'F', 'G', 'H' }; @@ -199,17 +355,43 @@ void TDocVen_Form::modify_pictures() } } -word TDocVen_Form::set_body(word p, bool u) { - TPrint_section& body = section('B', p); - return TForm::set_body(p, u); +bool TDocumento_form::print_on_body(int r) +{ + TPrint_section& body = section('B'); + + const TRiga_documento& riga = doc()[r]; + + TString tiporiga(riga.get(RDOC_TIPORIGA)); + TString codart(riga.get(RDOC_CODART)); + const int items = _exclude_array.items(); + bool ok = TRUE; + + for (int i = 0; i < items && ok; i++) + { + TToken_string& s=_exclude_array.row(i); + TString tr(s.get(0)); + TString ar(s.get(1)); + tr.trim();ar.trim(); + if (tr.empty() && ar.empty()) continue; + if (tr.empty() && ar == codart) ok = FALSE; + else if (tr == tiporiga) + if (ar.empty() || (ar.not_empty() && ar == codart)) ok = FALSE; + } + + if (ok) + body.update(); // Crea la vera riga di stampa, eventuali allineamenti avverranno nella validate(), come al solito. + + return ok; } -void TDocVen_Form::extended_parse_general(TScanner &scanner) { +void TDocumento_form::extended_parse_general(TScanner &scanner) +{ // se viene riconosciuto il token per l'impostazione del modulo legge il codice... if (scanner.key() == "MO") _module= scanner.string(); // Legge i decimali necessari per gli arrotondamenti (il primo per gli importi in lire, l'altro per quelli in valuta) - if (scanner.key() == "PR") { + if (scanner.key() == "PR") + { TToken_string t; t.add(29);t.add(scanner.integer());t.add(scanner.integer()); _group_decimals.add(t); @@ -224,26 +406,29 @@ void TDocVen_Form::extended_parse_general(TScanner &scanner) { } // Stessa cosa per gli importi in genere - if (scanner.key() == "IM") { + if (scanner.key() == "IM") + { TToken_string t; t.add(31);t.add(scanner.integer());t.add(scanner.integer()); _group_decimals.add(t); } - if (scanner.key() == "NE") { + if (scanner.key() == "NE") + { TToken_string t; t.add(scanner.integer());t.add(scanner.integer());t.add(scanner.integer()); _group_decimals.add(t); } // Esclude certi tipi riga e codici articolo - if (scanner.key() == "EX") { + if (scanner.key() == "EX") + { TToken_string s(scanner.string(),','); _exclude_array.add(s); } } -bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { +bool TDocumento_form::validate(TForm_item &cf, TToken_string &s) { const TString code(s.get(0)); // prende il primo parametro, il codice del messaggio TString valore; @@ -292,9 +477,7 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { } else posrv= poseq+2; if (poseq== -1) { const TString &dat= file->get(curr); // preleva il nome del campo del file e lo legge dal record - cf.set(dat); // setta il campo letto dal file nel campo corrente della form cf.put_paragraph(dat); - cf.set(""); // Resetta il campo per la prossima stampa di questo item } else { TString fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale const TString &dat= file->get(curr.mid(posrv)); // preleva il nome del campo del file alla destra dell'uguale e lo legge dal record @@ -312,15 +495,11 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { } for (j=0; j<itms; j++) { // per ogni campo della sezione specificata (o sottointesa)... TForm_item &fi= section(sec, pt).field(j); - fi.set(dat); // ...il contenuto viene settato al valore del file fi.put_paragraph(dat); - fi.set(""); // Resetta il campo per la prossima stampa di questo item } } else { TForm_item &fi= cf.find_field(fld); - fi.set(dat); fi.put_paragraph(dat); - fi.set(""); // Resetta il campo per la prossima stampa di questo item } } } @@ -347,12 +526,189 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { if (tab.read()== NOERR) { const TString &fld= s.get(); // prende il nome del campo da leggere... valore = tab.get(fld); - cf.set(tab.get(fld)); // ...e lo scrive nel campo del form cf.put_paragraph(valore); - cf.set(""); // Resetta il campo per la prossima stampa di questo item } return (TRUE); } // fine _TABLEREAD + + if (code== "_DITTA") { + // lettura dei dati della ditta + // sintassi: _DITTA,{<campo relazione>|<macro>} + // dove: <campo relazione> � un riferimento alla relazione di gestione dei dati della ditta (es. 113@->DENCOM � la denominazione del comune di residenza della ditta) + // <macro> � uno delle macro seguenti: + // !RAGSOC ragione sociale + // !IND indirizzo (fiscale se c'�, oppure di residenza) + // !NUM numero civico (fiscale se c'�, oppure di residenza) + // !CAP CAP (fiscale se c'�, oppure di residenza) + // !COM comune (fiscale se c'�, oppure di residenza) + // !PROV provincia (fiscale se c'�, oppure di residenza) + // !IVA partita iva + // !CF codice fiscale + // !TEL numero di telefono (con prefisso) + // !FAX numero di fax (con prefisso) + // !REGSOC numero di registrazione presso il Tribunale + // !CCIAA numero di registrazione presso la camera di commercio + // nota: la relazione della ditta � cos� strutturata: + // %NDITTE (9) Dati ditte + // + %ANAGR (6) Anagrafica generale (indirizzo, ecc.) + // + %COMUNI (113@) Comune di residenza + // + %COMUNI (213@) Comune di residenza fiscale + TString in(s.get()); + if (in[0]=='!') { + in.ltrim(1); + bool _fisc= _firmrel.lfile(6).get("INDRF").not_empty(); + if (in=="RAGSOC") + valore = _firmrel.lfile().get("RAGSOC"); + if (in=="IND") { + if (_fisc) + valore = _firmrel.lfile(6).get("INDRF"); + else + valore = _firmrel.lfile(6).get("INDRES"); + } + if (in=="NUM") { + if (_fisc) + valore = _firmrel.lfile(6).get("CIVRF"); + else + valore = _firmrel.lfile(6).get("CIVRES"); + } + if (in=="CAP") { + if (_fisc) + valore = _firmrel.lfile(6).get("CAPRF"); + else + valore = _firmrel.lfile(6).get("CAPRES"); + } + if (in=="COM") { + if (_fisc) + valore = _firmrel.lfile(-213).get("DENCOM"); + else + valore = _firmrel.lfile(-113).get("DENCOM"); + } + if (in=="PROV") { + if (_fisc) + valore = _firmrel.lfile(-213).get("PROVCOM"); + else + valore = _firmrel.lfile(-113).get("PROVCOM"); + } + if (in=="IVA") + valore = _firmrel.lfile(6).get("PAIV"); + if (in=="CF") + _firmrel.lfile(6).get("COFI"); + if (in=="TEL") { + valore = _firmrel.lfile().get("PTEL"); + valore << "/" << _firmrel.lfile().get("TEL"); + } + if (in=="FAX") { + valore = _firmrel.lfile().get("PFAX"); + valore << "/" << _firmrel.lfile().get("FAX"); + } + if (in=="REGSOC") { + valore = _firmrel[LF_UNLOC].get("REGTRIB"); + valore << " Vol. " << _firmrel[LF_UNLOC].get("VOLTRIB"); + valore << " Fasc. " << _firmrel[LF_UNLOC].get("FASCTRIB"); + } + if (in=="CCIAA") { + valore = _firmrel[LF_UNLOC].get("NUMCCIAA"); + valore << " del " << _firmrel[LF_UNLOC].get("DATAICCIAA"); + } + } else { + TFieldref fref(s.get(), 0); + valore = fref.read(_firmrel); + } + cf.put_paragraph(valore); + return (TRUE); + } // fine _DITTA + + if (code== "_CLIENTE") { + // lettura dei dati del cliente + // sintassi: _CLIENTE,{<campo relazione>|<macro>} + // dove: <campo relazione> � un riferimento alla relazione di gestione dei dati del cliente + // <macro> � uno delle macro seguenti: + // !RAGSOC ragione sociale + // !IND indirizzo + // !NUM numero civico + // !INDNUM indirizzo + numero civico + // !LOC localit� + // !CAP CAP + // !COM comune + // !PROV provincia + // !IVA partita iva + // !CF codice fiscale + // !PERS <F> se persona fisica, <G> se giuridica + // !DATANAS data di nascita + // !COMNAS comune di nascita + // !TEL primo numero di telefono (con prefisso) + // !TEL2 secondo numero di telefono (con prefisso) + // !TEL3 terzo numero di telefono (con prefisso) + // !FAX numero di fax (con prefisso) + // nota: la relazione del cliente � cos� strutturata: + // CLIFO (20) Clienti/fornitori + // + CFVEN (17) Clienti/fornitori per vendite + // + %COMUNI (113@) Comune di residenza + // + %COMUNI (213@) Comune di nascita + TLocalisamfile &doc= (cursor())->file(LF_DOC); + TString16 tipocf= doc.get("TIPOCF"), codcf= doc.get("CODCF"), ocfpi= doc.get("OCFPI"); + if (!_cli_loaded ) { // il cliente � sulla testata del documento di vendita, quindi pu� essere caricato una volta sola per tutte + _cliente->load(tipocf[0], atol(codcf), ocfpi); + _cliente->add(LF_COMUNI, "COM=STATOCF+COMCF", 1, LF_CLIFO, 100+LF_COMUNI); + _cliente->add(LF_COMUNI, "COM=STATONASC+COMNASC", 1, LF_CLIFO, 200+LF_COMUNI); + _cli_loaded= TRUE; + } + TString in(s.get()); // prende la macro o il fieldref + if (in[0]=='!') { + in.ltrim(1); + if (in=="RAGSOC") + valore = _cliente->get(LF_CLIFO, "RAGSOC"); + if (in=="IND") + valore = _cliente->get(LF_CLIFO, "INDCF"); + if (in=="NUM") + valore = _cliente->get(LF_CLIFO, "CIVCF"); + if (in=="INDNUM") { + valore = _cliente->get(LF_CLIFO, "INDCF"); + valore << " " << _cliente->get(LF_CLIFO,"CIVCF"); + } + if (in=="LOC") + valore = _cliente->get(LF_CLIFO, "LOCALITACF"); + if (in=="CAP") + valore = _cliente->get(LF_CLIFO, "CAPCF"); + if (in=="COM") + valore = _cliente->get(-(100+LF_COMUNI), "DENCOM"); + if (in=="PROV") + valore = _cliente->get(-(100+LF_COMUNI), "PROVCOM"); + if (in=="IVA") + valore = _cliente->get(LF_CLIFO, "PAIV"); + if (in=="CF") + valore = _cliente->get(LF_CLIFO, "COFI"); + if (in=="PERS") + valore = _cliente->get(LF_CLIFO, "TIPOPERS"); + if (in=="DATANAS") + valore = _cliente->get(LF_CLIFO, "DATANASC"); + if (in=="COMNAS") + valore = _cliente->get(-(200+LF_COMUNI), "DENCOM"); + if (in=="TEL") { + valore = _cliente->get(LF_CLIFO, "PTEL"); + valore << "/" << _cliente->get(LF_CLIFO, "TEL"); + } + if (in=="TEL2") { + valore = _cliente->get(LF_CLIFO, "PTEL2"); + valore << "/" << _cliente->get(LF_CLIFO, "TEL2"); + } + if (in=="TEL3") { + valore = _cliente->get(LF_CLIFO, "PTEL3"); + valore << "/" << _cliente->get(LF_CLIFO, "TEL3"); + } + if (in=="FAX") { + valore = _cliente->get(LF_CLIFO, "PFAX"); + valore << "/" << _cliente->get(LF_CLIFO, "FAX"); + } + } else { + TFieldref fref(s.get(), 0); + // l'oggetto cliente � figlio della TRelation, quindi lo passo al fieldref semplicemente con un typecast + valore = fref.read(*_cliente); + } + cf.put_paragraph(valore); + return (TRUE); + } // fine _CLIENTE + if (code == "_DESCRIGA") { // Messaggio per reperire la descrizione estesa sulle righe del documento TLocalisamfile &rdoc= (cursor())->file(LF_RIGHEDOC); @@ -369,12 +725,11 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { descrizione << " " << linea; } } - cf.set(descrizione); cf.put_paragraph(descrizione); - cf.set(""); // Resetta il contenuto del TForm_item(R) per la prossima riga + // Setta l'altezza effettiva del body, per evitare sprechi di righe cf.section().set_height(cf.effective_height() + 1); } - + if (code== "_ALIGN") { // allineamento della posizione di un campo rispetto ad un altro // sintassi: _ALIGN,<campo form>[,<allineamento>][,<allineamento>...] @@ -426,284 +781,13 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { cf.height() = save_height; return (TRUE); } // fine _ALIGN - - if (code== "_DITTA") { - // lettura dei dati della ditta - // sintassi: _DITTA,{<campo relazione>|<macro>} - // dove: <campo relazione> � un riferimento alla relazione di gestione dei dati della ditta (es. 113@->DENCOM � la denominazione del comune di residenza della ditta) - // <macro> � uno delle macro seguenti: - // !RAGSOC ragione sociale - // !IND indirizzo (fiscale se c'�, oppure di residenza) - // !NUM numero civico (fiscale se c'�, oppure di residenza) - // !CAP CAP (fiscale se c'�, oppure di residenza) - // !COM comune (fiscale se c'�, oppure di residenza) - // !PROV provincia (fiscale se c'�, oppure di residenza) - // !IVA partita iva - // !CF codice fiscale - // !TEL numero di telefono (con prefisso) - // !FAX numero di fax (con prefisso) - // !REGSOC numero di registrazione presso il Tribunale - // !CCIAA numero di registrazione presso la camera di commercio - // nota: la relazione della ditta � cos� strutturata: - // %NDITTE (9) Dati ditte - // + %ANAGR (6) Anagrafica generale (indirizzo, ecc.) - // + %COMUNI (113@) Comune di residenza - // + %COMUNI (213@) Comune di residenza fiscale - TString in(s.get()); - if (in[0]=='!') { - in.ltrim(1); - bool _fisc= _firmrel.lfile(6).get("INDRF").not_empty(); - if (in=="RAGSOC") cf.set(_firmrel.lfile().get("RAGSOC")); - if (in=="IND") { - if (_fisc) cf.set(_firmrel.lfile(6).get("INDRF")); - else cf.set(_firmrel.lfile(6).get("INDRES")); - } - if (in=="NUM") { - if (_fisc) cf.set(_firmrel.lfile(6).get("CIVRF")); - else cf.set(_firmrel.lfile(6).get("CIVRES")); - } - if (in=="CAP") { - if (_fisc) cf.set(_firmrel.lfile(6).get("CAPRF")); - else cf.set(_firmrel.lfile(6).get("CAPRES")); - } - if (in=="COM") { - if (_fisc) cf.set(_firmrel.lfile(-213).get("DENCOM")); - else cf.set(_firmrel.lfile(-113).get("DENCOM")); - } - if (in=="PROV") { - if (_fisc) cf.set(_firmrel.lfile(-213).get("PROVCOM")); - else cf.set(_firmrel.lfile(-113).get("PROVCOM")); - } - if (in=="IVA") cf.set(_firmrel.lfile(6).get("PAIV")); - if (in=="CF") cf.set(_firmrel.lfile(6).get("COFI")); - if (in=="TEL") { - TString tel(_firmrel.lfile().get("PTEL")); - tel << "/" << _firmrel.lfile().get("TEL"); - cf.set(tel); - } - if (in=="FAX") { - TString tel(_firmrel.lfile().get("PFAX")); - tel << "/" << _firmrel.lfile().get("FAX"); - cf.set(tel); - } - if (in=="REGSOC") { - TString reg(_firmrel[LF_UNLOC].get("REGTRIB")); - reg << " Vol. " << _firmrel[LF_UNLOC].get("VOLTRIB"); - reg << " Fasc. " << _firmrel[LF_UNLOC].get("FASCTRIB"); - cf.set(reg); - } - if (in=="CCIAA") { - TString cod(_firmrel[LF_UNLOC].get("NUMCCIAA")); - cod << " del " << _firmrel[LF_UNLOC].get("DATAICCIAA"); - cf.set(cod); - } - } else { - TFieldref fref(s.get(), 0); - cf.set(fref.read(_firmrel)); - } - valore = cf.get(); - cf.put_paragraph(valore); - cf.set(""); // Resetta il campo per la prossima stampa di questo item - return (TRUE); - } // fine _DITTA - if (code== "_CIFRELET") { - // conversione di un reale da cifre a lettere - // sintassi: _CIFRELETTERE[,<campo form>] - // dove: <campo form> � il campo della form (preceduto da '#') da cui prendere il valore, se non � specificato � sottointeso il campo corrente - // nota: prende il valore del campo specificato e scrive la sua conversione in lettere nel campo corrente - TString in; - if (s.items()==2) { - in= s.get(); - if (in[0]== '#') in.ltrim(1); - TForm_item &fi= cf.find_field(in); - in= fi.get(); - } else in= cf.get(); - real n(in); - valore = n.string("LETTERE"); - cf.set(valore); - cf.put_paragraph(valore); - cf.set(""); // Resetta il campo per la prossima stampa di questo item - return (TRUE); - } // fine _CIFRELET - - if (code.left(6) == "_TOTAL") { - // totalizzatori di testata/coda, riga e progressione - // sintassi: _TOTAL_{CODA|RIGA|PROGRES},<totalizzatore>[,<parametri opz>] - // dove: <totalizzatore> � il codice del totalizzatore richiesto - static real zero("0.0"); // 0 sotto forma di real per i casi in cui il totalizzatore non viene trovato - //if (!_doc->summary_compiled() &&_cli_loaded) _doc->set_condv(_cliente); - TString tot= s.get(); // prende il codice del totalizzatore richiesto - TForm_item *fi; // puntatore al campo della form in cui scrivere il valore del totalizzatore - fi= &cf; // prende il puntatore al campo corrente - if (code.mid(6) == "_CODA") { - TString value; - if (tot == "TOTDOC") value = _doc->tot_documento().string(); - else if (tot == "TIMPNETTI") value = _doc->tot_importi_netti().string(); - else if (tot == "TIMPOSTE") value = _doc->tot_imposte().string(); - else if (tot == "TIMPONIBILI") - { - byte sel = atoi(s.get()); - value = _doc->tot_imponibili(sel).string(); - } - else - value = _doc->get_head_info(tot); - if (value.not_empty()) - fi->set(value); // setta il campo della form - else - fi->set(zero.string()); - } - if (code.mid(6) == "_RIGA") { - TLocalisamfile &rdoc= (cursor())->file(LF_RIGHEDOC); - TToken_string totriga(rdoc.get("G1"),'\n'); // prende il campo memo con i totalizzatori sotto forma di token string - TString value; - const int items = totriga.items(); - for (int i = 0; i<items; i++) - { - TToken_string item(totriga.get(),'='); - if (tot == item.get()) - { - value = item.get(); - break; - } - } - if (value.not_empty()) - fi->set(value); // setta il campo della form - else - fi->set(zero.string()); - } -// if (code.mid(6) == "_PROGRES") { -// TString16 tot16(tot); -// fi->set(_total_prog->get(tot16).string()); -// } - - valore = fi->get(); - real x(valore); - TString picture(fi->picture()); - if (x != 0.0) - valore = x.string(picture); // Riformatta il valore - else - valore = ""; - fi->put_paragraph(valore); - fi->set(""); // Resetta il campo per la prossima stampa di questo item - return (TRUE); - } // fine _TOTAL_xxx - - if (code== "_CLIENTE") { - // lettura dei dati del cliente - // sintassi: _CLIENTE,{<campo relazione>|<macro>} - // dove: <campo relazione> � un riferimento alla relazione di gestione dei dati del cliente - // <macro> � uno delle macro seguenti: - // !RAGSOC ragione sociale - // !IND indirizzo - // !NUM numero civico - // !INDNUM indirizzo + numero civico - // !LOC localit� - // !CAP CAP - // !COM comune - // !PROV provincia - // !IVA partita iva - // !CF codice fiscale - // !PERS <F> se persona fisica, <G> se giuridica - // !DATANAS data di nascita - // !COMNAS comune di nascita - // !TEL primo numero di telefono (con prefisso) - // !TEL2 secondo numero di telefono (con prefisso) - // !TEL3 terzo numero di telefono (con prefisso) - // !FAX numero di fax (con prefisso) - // nota: la relazione del cliente � cos� strutturata: - // CLIFO (20) Clienti/fornitori - // + CFVEN (17) Clienti/fornitori per vendite - // + %COMUNI (113@) Comune di residenza - // + %COMUNI (213@) Comune di nascita - TLocalisamfile &doc= (cursor())->file(LF_DOC); - TString16 tipocf= doc.get("TIPOCF"), codcf= doc.get("CODCF"), ocfpi= doc.get("OCFPI"); - if (!_cli_loaded ) { // il cliente � sulla testata del documento di vendita, quindi pu� essere caricato una volta sola per tutte - _cliente->load(tipocf[0], atol(codcf), ocfpi); - _cliente->add(LF_COMUNI, "COM=STATOCF+COMCF", 1, LF_CLIFO, 100+LF_COMUNI); - _cliente->add(LF_COMUNI, "COM=STATONASC+COMNASC", 1, LF_CLIFO, 200+LF_COMUNI); - _cli_loaded= TRUE; - } - TString in(s.get()); // prende la macro o il fieldref - if (in[0]=='!') { - in.ltrim(1); - if (in=="RAGSOC") cf.set(_cliente->get(LF_CLIFO, "RAGSOC")); - if (in=="IND") cf.set(_cliente->get(LF_CLIFO, "INDCF")); - if (in=="NUM") cf.set(_cliente->get(LF_CLIFO, "CIVCF")); - if (in=="INDNUM") { - TString indnum(_cliente->get(LF_CLIFO, "INDCF")); - indnum << " " << _cliente->get(LF_CLIFO,"CIVCF"); - cf.set(indnum); - } - if (in=="LOC") cf.set(_cliente->get(LF_CLIFO, "LOCALITACF")); - if (in=="CAP") cf.set(_cliente->get(LF_CLIFO, "CAPCF")); - if (in=="COM") cf.set(_cliente->get(-(100+LF_COMUNI), "DENCOM")); - if (in=="PROV") cf.set(_cliente->get(-(100+LF_COMUNI), "PROVCOM")); - if (in=="IVA") cf.set(_cliente->get(LF_CLIFO, "PAIV")); - if (in=="CF") cf.set(_cliente->get(LF_CLIFO, "COFI")); - if (in=="PERS") cf.set(_cliente->get(LF_CLIFO, "TIPOPERS")); - if (in=="DATANAS") cf.set(_cliente->get(LF_CLIFO, "DATANASC")); - if (in=="COMNAS") cf.set(_cliente->get(-(200+LF_COMUNI), "DENCOM")); - if (in=="TEL") { - TString tel(_cliente->get(LF_CLIFO, "PTEL")); - tel << "/" << _cliente->get(LF_CLIFO, "TEL"); - cf.set(tel); - } - if (in=="TEL2") { - TString tel2(_cliente->get(LF_CLIFO, "PTEL2")); - tel2 << "/" << _cliente->get(LF_CLIFO, "TEL2"); - cf.set(tel2); - } - if (in=="TEL3") { - TString tel3(_cliente->get(LF_CLIFO, "PTEL3")); - tel3 << "/" << _cliente->get(LF_CLIFO, "TEL3"); - cf.set(tel3); - } - if (in=="FAX") { - TString fax(_cliente->get(LF_CLIFO, "PFAX")); - fax << "/" << _cliente->get(LF_CLIFO, "FAX"); - cf.set(fax); - } - } else { - TFieldref fref(s.get(), 0); - cf.set(fref.read(*_cliente)); // l'oggetto cliente � figlio della TRelation, quindi lo passo al fieldref semplicemente con un typecast - } - valore = cf.get(); - cf.put_paragraph(valore); - cf.set(""); // Resetta il campo per la prossima stampa di questo item - return (TRUE); - } // fine _CLIENTE - - if (code== "_SCADENZE") { - // messaggio per stampare le scadenze - // sintassi: _SCADENZE,<macro>,<cambio codice> - // dove <macro> e' uno dei seguenti: - // DATA : stampa la data di scadenza - // IMPORTO : stampa l'importo in scadenza - // dove <cambio codice> vale 0 o 1 se indica di rendere corrente la prossima scadenza - if (s.items() == 3) - { - TString what(s.get()); - TString value(_doc->scadenze_get(what)); - cf.set(value); - - real x(value); - if (x.is_real(value)) - { - TString picture(cf.picture()); - if (x != 0.0) - value = x.string(picture); // Riformatta il valore - else - value = ""; - } - - what = s.get(); - const bool next = what == "1"; - if (next) _doc->scadenze_set_next(); - cf.put_paragraph(value); - cf.set(""); // Resetta il campo per la prossima stampa di questo item - } - } + // Messaggio per stampare il numero di pagina corrente + if (code== "_PAGENO") + { + TString16 pg; pg << int(printer().getcurrentpage() ); + cf.put_paragraph(pg); + } if (code== "_RIEPILOGOIVA") { // tabella riepilogo aliquote iva e relative imposte @@ -726,7 +810,6 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { // 0 indica di non leggere il successivo codice IVA nella tabella riepilogativa // 1 indica di leggere il successivo codice IVA nella tabella riepilogativa - //if (!_doc->summary_compiled() &&_cli_loaded) _doc->set_condv(_cliente); if (s.items() == 4) { @@ -741,7 +824,6 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { what = s.get(); const bool next = what == "1"; // deve cambiare elemento ? if (next) _doc->summary_set_next(); - cf.set(value); real x(value); if (x.is_real(value)) @@ -753,7 +835,6 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { value = ""; } cf.put_paragraph(value); - cf.set(""); // Resetta il campo per la prossima stampa di questo item } } else @@ -761,20 +842,246 @@ bool TDocVen_Form::validate(TForm_item &cf, TToken_string &s) { return (TRUE); } // fine _RIEPILOGOIVA - // Messaggio per stampare il numero di pagina corrente - if (code== "_PAGENO") { - TString16 pg; pg << int(printer().getcurrentpage() - app().base_no()); - cf.set(pg); cf.put_paragraph(pg); - cf.set(""); + if (code == "_TOTIMPONIBILI") + { + // sintassi: _TOTIMPONIBILI,<selettore> + // dove: <selettore> funge da filtro per la somma degli imponibili + // vedi _RIEPILOGOIVA per la spiegazione dei filtri selettivi + byte sel = atoi(s.get()); + valore = _doc->tot_imponibili(sel).string(); + + real x(valore); + TString picture(cf.picture()); + if (x != 0.0) + valore = x.string(picture); // Riformatta il valore + else + valore = ""; + cf.put_paragraph(valore); + return (TRUE); + } // fine _TOTIMPONIBILI + + if (code== "_SCADENZE") { + // messaggio per stampare le scadenze + // sintassi: _SCADENZE,<macro>,<cambio codice> + // dove <macro> e' uno dei seguenti: + // DATA : stampa la data di scadenza + // IMPORTO : stampa l'importo in scadenza + // dove <cambio codice> vale 0 o 1 se indica di rendere corrente la prossima scadenza + if (s.items() == 3) + { + TString what(s.get()); + TString value(_doc->scadenze_get(what)); + + real x(value); + if (x.is_real(value)) + { + TString picture(cf.picture()); + if (x != 0.0) + value = x.string(picture); // Riformatta il valore + else + value = ""; + } + + what = s.get(); + const bool next = what == "1"; + if (next) _doc->scadenze_set_next(); + cf.put_paragraph(value); + } } + return TForm::validate(cf, s); // se il codice del messaggio non � identificato viene passato alla funzione standard } ////////////////////////////////////////////////////////////////////////////////////////////// -// classe TStampa_Doc_Vendita customizzata dalla TApplication per l'applicazione principale +// classe TStampaDoc_application customizzata dalla TApplication per l'applicazione principale ////////////////////////////////////////////////////////////////////////////////////////////// -bool TStampa_Doc_Vendita::date2num_handler(TMask_field& f, KEY key) + +enum behaviour +{ + skip, + go, + cancel +}; + +// Chiavi di ordinamento LF_DOC: +// Chiave 1: ordinamento per Provvisorio + Anno + Codice numerazione + Numero documento +// Chiave 3: ordinamento per Data documento + Provvisorio + Anno + Codice numerazione + Numero documento + +#define BY_NUM_KEY 1 +#define BY_DATE_KEY 3 + + +class TStampaDoc_application: public TApplication +{ + TString _codnum; // codice di numerazione + char _provv; // stampa documenti provvisiori o definitivi (D o P) + int _anno; // anno della documentazione + int _key; // chiave per scorrere i documenti (1 o 3, vedi sopra) + int _ncopie; // numero di copie per ogni documento + long _dalnum, _alnum; // estremi di numerazione dei documenti + TDate _dadata, _adata; // estremi di data dei documenti + bool _interattivo; // flag che indica se il prog. funziona in interattivo o in batch + bool _definitiva; // flag che indica se la stampa � definitiva o no + TRelation *_firmrel; // puntatore alla relazione che gestisce i dati della ditta corrente + TDocumento_form *_form; // puntatore al form di stampa +protected: + virtual bool create(); + virtual bool destroy(); + virtual bool menu(MENU_TAG); + bool select(void); + virtual void on_firm_change(void); + virtual behaviour on_module_change(const TString &, TString &); // funzione chiamata ad ogni cambio modulo durante la stampa + virtual bool query_final_print(void); // funzione chiamata all'inizializzazione per sapere se la stampa � definitiva + static bool date2num_handler(TMask_field& f, KEY key); + static bool range_handler(TMask_field& f, KEY key); +public: + TDocumento_form& form() { return *_form; } + void print_documento(); + void print_selected(); + TStampaDoc_application() {}; + virtual ~TStampaDoc_application() {}; +}; + + +void TStampaDoc_application::print_selected() +{ + TRelation rel(LF_DOC); + rel.add(LF_RIGHEDOC,"CODNUM==CODNUM|ANNO==ANNO|PROVV==PROVV|NDOC==NDOC"); + TCursor cur(&rel); + TLocalisamfile& doc = cur.file(); + cur.setkey(_key); + TRectype darec(LF_DOC),arec(LF_DOC); // Estremi filtro + TString modulo_prec; + const bool order_by_num = _key == BY_NUM_KEY; + + doc.put(DOC_CODNUM, _codnum); // compone la chiave per il record di inizio cursore + doc.put(DOC_ANNO, _anno); + doc.put(DOC_PROVV, _provv); + doc.put(DOC_NDOC, _dalnum); + if (!order_by_num) doc.put(DOC_DATADOC, _dadata); + doc.setkey(_key); + doc.read(); // trova il record iniziale + darec = doc.curr(); + doc.put(DOC_NDOC, _alnum); + if (!order_by_num) doc.put(DOC_DATADOC, _adata); + int err = doc.read(); // trova il record finale + if (err == _iseof) doc.last(); + else if (err == _iskeynotfound) doc.prev(); + arec = doc.curr(); + + if (arec < darec) + { + error_box("Non vi sono documenti da stampare nell'intervallo indicato"); + return; + } + _definitiva= query_final_print(); // legge il flag di stampa definitiva + + TPrinter& pr = printer(); + pr.open(); + + TProgind* pi = pr.printtype() != screenvis ? + new TProgind(cur.items(),"Stampa documenti in corso...",FALSE,TRUE,10) : + NULL; + + cur.setregion(darec, arec); + const long items = cur.items(); + behaviour whattodo = go; + bool first_inst = TRUE; + for (long i = 0; i < items; i++) + { + cur = i; // Posiziona il documento + _form = new TDocumento_form(cur.curr(), *_firmrel, _definitiva, _interattivo); // Istanzia il form + + if (!_form->valid()) break; // interrompe la stampa se il doc corrente non e' tra i tipi validi + const TString &modulo= _form->get_module_code(); // legge dal form il codice del modulo di carta per la stampa + if (modulo_prec.empty()) modulo_prec = modulo; // se siamo al primo passaggio la variabile di modulo precedente viene riempita + else first_inst = FALSE; + const bool module_changed = modulo != modulo_prec; + if (first_inst || module_changed) + if (!_form->doc_arrange()) // Setta l'offset o posiziona manualmente + break; // Se vi sono errori interrompe la stampa + if (module_changed) whattodo = on_module_change(modulo, modulo_prec); // se il modulo � cambiato dalla stampa precedente interroga la funzione per sapere che comportamento tenere + if (whattodo==cancel) break; // se non si pu� procedere la stampa viene interrotta + if (whattodo==skip) continue; // Salta il documento corrente + // altrimenti prosegue + + // Carica il numero di copie da stampare per questo form + int ncopie = _ncopie == 0 ? _form->ncopie() : _ncopie; // Numero di copie da stampare per questo documento + if (ncopie == 0) ncopie = 1; + + for (int n=0; n < ncopie; n++) + { + print_documento(); + _form->doc().summary_reset(); + _form->doc().scadenze_reset(); + } + delete _form; + + if (_definitiva && (numerazione_definitiva(doc) != NOERR)) + { // se la stampa � definitiva viene lanciata la procedura di rinumerazione + if (_interattivo) error_box("Non � possibile completare la procedura di numerazione definitiva dei documenti"); + break; + } + } + + if (pi != NULL) delete pi; + printer().close(); +} + +void TStampaDoc_application::print_documento() +{ + CHECK(_form,"Nessun form istanziato!"); + TDocumento_form& f = form(); + TLocalisamfile& doc = f.cursor()->file(); + const bool is_vis = printer().printtype() == screenvis; + if (!is_vis) + { + TString status("Documento: "); + status << doc.get(DOC_CODNUM); + status << '\\' << doc.get(DOC_NDOC); + xvt_statbar_set(status); + } + f.print_documento(); + + if (!is_vis) + xvt_statbar_set(NULL); +} + +behaviour TStampaDoc_application::on_module_change(const TString &modulo, TString &modulo_prec) +{ + if (!_interattivo) return skip; // se siamo in interattivo il documento viene saltato... + else + { // ...altrimenti viene chiesto all'utente il da farsi + int risp= yesnocancel_box("Il modulo di carta � cambiato: inserisci il modulo '%s' e premi 'S�' per continuare, 'No' per saltare il documento o 'Cancel' per interrompere la stampa", modulo); + behaviour ret; + switch (risp) + { + case K_YES: + modulo_prec= modulo; // aggiorna l'inseguitore dei moduli + ret= go; // la stampa pu� continuare + break; + case K_NO: + ret= skip; // il documento viene saltato + break; + case K_ESC: + ret= cancel; // la stampa viene interrotta + break; + } + return ret; + } +} + +bool TStampaDoc_application::query_final_print() +{ + if (_interattivo) + { // se siamo in interattivo viene richiesto all'utente se la stampa � definitiva o meno + if (yesno_box("E' una stampa definitiva?")) return TRUE; + else return FALSE; + } else return _definitiva; // altrimenti ritorna il valore letto dalla linea di comando +} + +bool TStampaDoc_application::date2num_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_TAB && f.focusdirty()) @@ -808,7 +1115,7 @@ bool TStampa_Doc_Vendita::date2num_handler(TMask_field& f, KEY key) return TRUE; } -bool TStampa_Doc_Vendita::range_handler(TMask_field& f, KEY key) +bool TStampaDoc_application::range_handler(TMask_field& f, KEY key) { int rt = TRUE; TMask& m = f.mask(); @@ -825,77 +1132,65 @@ bool TStampa_Doc_Vendita::range_handler(TMask_field& f, KEY key) return rt; } -bool TStampa_Doc_Vendita::filter_rows(const TRelation * r) +bool TStampaDoc_application::create() { - TLocalisamfile& righe = r->lfile(LF_RIGHEDOC); - bool rt = TRUE; - TString tiporiga(righe.get("TIPORIGA")); - TString codart(righe.get("CODART")); - TString_array& a = app()._form->exclude_list(); - const int items = a.items(); - - for (int i = 0; i < items && rt; i++) - { - TToken_string& s=a.row(i); - TString tr(s.get(0)); - TString ar(s.get(1)); - tr.trim();ar.trim(); - if (tr.empty() && ar.empty()) continue; - if (tr.empty() && ar == codart) rt = FALSE; - else if (tr == tiporiga) - if (ar.empty() || (ar.not_empty() && ar == codart)) rt = FALSE; - } - - return rt; -} - -bool TStampa_Doc_Vendita::create() { TApplication::create(); - _form = NULL; _firmrel= new TRelation(LF_NDITTE); // istanziamento e impostazione della relazione di gestione della ditta corrente _firmrel->add(LF_ANAG, "TIPOA=TIPOA|CODANAGR=CODANAGR"); _firmrel->add(LF_UNLOC,"CODDITTA=CODDITTA"); // si posiziona sulla prima unita' locale della ditta _firmrel->add(LF_COMUNI, "COM=STATORES+COMRES", 1, LF_ANAG, 100+LF_COMUNI); _firmrel->add(LF_COMUNI, "COM=STATORES+COMRF", 1, LF_ANAG, 200+LF_COMUNI); - if (argc()>2) { // lettura dei parametri iniziali dalla linea di comando + int argc = TApplication::argc(); + if (argc>2 && (argc == 8 || argc == 9)) + { // lettura dei parametri iniziali dalla linea di comando _codnum= argv(2); // il primo parametro � il codice di numerazione _anno= atoi(argv(3)); // il secondo � l'anno - _provv= argv(4); // il terzo � il flag di numerazione provvisoria + _provv= argv(4)[0]; // il terzo � il flag di numerazione provvisoria _dalnum= atol(argv(5)); // il quarto � il numero di documento di partenza _alnum= atol(argv(6)); // il quinto � il numero di documento di fine _definitiva= (strcmp(argv(7), "D")==0); // il sesto � se la stampa � definitiva (rinumerazione dei documenti) - _ncopie = atoi(argv(8)); + _ncopie = argc == 9 ? atoi(argv(8)) : 1; _interattivo= FALSE; - print(); - } else { // oppure lancio della maschera + print_selected(); + } + else if (argc == 2) + { // oppure lancio della maschera _interattivo= TRUE; dispatch_e_menu(BAR_ITEM(1)); } + else + { + error_box(Usage); + return FALSE; + } return TRUE; } -bool TStampa_Doc_Vendita::destroy() { - if (_form) delete _form; +bool TStampaDoc_application::destroy() +{ delete _firmrel; // distruzione della relazione di gestione della ditta corrente return TApplication::destroy(); } -void TStampa_Doc_Vendita::on_firm_change() { +void TStampaDoc_application::on_firm_change() +{ TLocalisamfile &firmfile= _firmrel->lfile(); firmfile.put("CODDITTA", get_firm()); _firmrel->read(); } -int TStampa_Doc_Vendita::select() { +bool TStampaDoc_application::select() +{ TMask m("ve1100a"); TString wdate; m.set_handler(F_DA_DATADOC, date2num_handler); m.set_handler(F_A_DATADOC, date2num_handler); m.set_handler(F_A_NDOC, range_handler); - if (m.run() == K_ENTER) { + if (m.run() == K_ENTER) + { _codnum= m.get(F_CODNUM); // lettura dei dati dalla maschera _anno= m.get_int(F_ANNO); - _provv= m.get(F_PROVV); + _provv= m.get(F_PROVV)[0]; _dalnum= m.get_long(F_DA_NDOC); _alnum= m.get_long(F_A_NDOC); _ncopie = m.get_int(F_NCOPIE); @@ -906,165 +1201,22 @@ int TStampa_Doc_Vendita::select() { wdate = m.get(F_A_DATADOC); if (wdate.not_empty()) _adata = wdate; else _adata = eotime; - _order_by_num = m.get(F_DATA_O_NUM) == "N"; - return 1; - } else return 0; // 0 indica che non si � usciti con "Conferma" dalla maschera + _key = BY_NUM_KEY; + if (m.get(F_DATA_O_NUM) != "N") _key = BY_DATE_KEY; + return TRUE; + } else return FALSE; } -bool TStampa_Doc_Vendita::menu(MENU_TAG) { // procedura di dispatch dei menu - int s; - while ((s= select()) != 0) if (s==1) print(); // se la selezione della maschera ritorna 1 viene lanciata la stampa +bool TStampaDoc_application::menu(MENU_TAG) +{ + while (select()) print_selected(); return FALSE; } -void TStampa_Doc_Vendita::print() { - TFilename nomeform, profilo; // istanzia le stringhe per il nome del form di stampa e del profilo di configurazione - TString modulo_prec; // istanzia la stringa per l'inseguimento del modulo di carta - TTable tip("%TIP"); // istanzia la tabella dei tipi di documento per i profili - TRelation rel(LF_DOC); // istanzia la relazione sul file principale - TLocalisamfile righe(LF_RIGHEDOC); // cosi' i trecord_array non rompono i coglioni - TCursor cur(&rel); // crea il cursore principale dalla relazione - if (!_order_by_num) cur.setkey(3); // setta l'ordine per data. - TLocalisamfile &doc= cur.file(); // prende il riferimento al file principale - doc.zero(); // vuota il record del file - doc.put("CODNUM", _codnum); // compone la chiave per il record di inizio cursore - doc.put("ANNO", _anno); - doc.put("PROVV", _provv); - doc.put("NDOC", _dalnum); - if (!_order_by_num) doc.put("DATADOC", _dadata); - doc.read(); // posiziona il file sul record - TRectype darec= doc.curr(); // copia il record di inizio cursore - doc.zero(); // vuota il record del file - doc.put("CODNUM", _codnum); // compone la chiave per il record di fine cursore - doc.put("ANNO", _anno); - doc.put("PROVV", _provv); - doc.put("NDOC", _alnum); - if (!_order_by_num) doc.put("DATADOC", _adata); - const int err = doc.read(); // posiziona il file sul record - if (err == _iseof) doc.last(); - else if (err == _iskeynotfound) doc.prev(); - const long num_lim_sup = doc.get_int("NDOC"); - const TDate date_lim_sup = doc.get_date("DATADOC"); - if (num_lim_sup > _alnum || (!_order_by_num && date_lim_sup < _adata)) - { - error_box("Non vi sono documenti da stampare nell'intervallo indicato"); - return; - } - _definitiva= query_final_print(); // legge il flag di stampa definitiva - printer().open(); // apre la stampante - TRectype arec= doc.curr(); // copia il record di fine cursore - cur.setregion(darec, arec); // imposta il filtro sul cursore di stampa (nell'ordine giusto :-) - const bool is_vis = printer().printtype() == screenvis; - TProgind* pi; - if (!is_vis) - pi = new TProgind(cur.items(),"Stampa documenti in corso...",FALSE,TRUE,10); - _base_page_no = 0; - for (cur= 0; cur.pos()<cur.items(); ++cur) { // ciclo sugli elementi del cursore di stampa - if (!is_vis) - pi->addstatus(1L); - tip.put("CODTAB", doc.get("TIPODOC")); // posiziona la tabella dei tipi di documento - int err=tip.read(); // legge la tabella - if (err==NOERR) { // se non ci sono errori procede con la stampa - nomeform= tip.get("S5"); // legge il nome del form di stampa - profilo= tip.get("S4"); // legge il nome del profilo di configurazione - profilo.ext("ini"); // aggiunge l'estensione al nome del file del profilo - if (profilo.empty() || nomeform.empty()) { - error_box("Nome profilo o form di stampa non valido nella tabella TIP"); - break; - } - TConfig config(profilo, "STAMPA"); // apre il file di configurazione del profilo - TToken_string stati((const char*)config.get("STATIVALIDI"), ','); // legge gli stati validi di questo tipo di documento - if (_definitiva && (stati.get_pos(doc.get("STATO"))== -1)) { // se lo stato del doc. corrente non � valido... - if (_interattivo) error_box("Non � possibile stampare un documento con stato non valido"); // ...viene mostrato un messaggio (solo in modo interattivo)... - break; // ...e la stampa viene interrotta - } - behaviour whattodo= go; // istanzia la variabile di comportamento - - TDocumentoEsteso * doc_est = new TDocumentoEsteso(cur.curr()); // istanzia TDocumentoEsteso sulla testata attuale - // Da implementare quando verra gestito il numero di copie - int ncopie = _ncopie == 0 ? doc_est->tipo().ncopie() : _ncopie; // Numero di copie da stampare per questo documento - if (ncopie == 0) ncopie = 1; - _form = new TDocVen_Form(nomeform, *_firmrel, doc_est); // istanzia il form, passandogli il documento. (la delete del documento e' nel ditruttore - const TString &modulo= _form->get_module_code(); // legge dal form il codice del modulo di carta per la stampa - if (modulo_prec.empty()) modulo_prec= modulo; // se siamo al primo passaggio la variabile di modulo precedente viene riempita - if (modulo != modulo_prec) whattodo= on_module_change(modulo, modulo_prec); // se il modulo � cambiato dalla stampa precedente interroga la funzione per sapere che comportamento tenere - if (whattodo==cancel) break; // se non si pu� procedere la stampa viene interrotta - else if (whattodo==go) { // altrimenti prosegue - TCursor &fcur= *(_form->cursor()); // ricava il riferimento al cursore originale del form - TLocalisamfile &rdoc= fcur.file(LF_RIGHEDOC); // ricava il riferimento al file principale del cursore del form - TRectype darec_r(rdoc.curr()); // istanzia il record di filtro per il cursore - darec_r.zero(); // vuota il record - darec_r.put("CODNUM", _codnum); // compone la chiave parziale per il filtro sul cursore dal file principale del cursore di selezione dei documenti - darec_r.put("ANNO", _anno); - darec_r.put("PROVV", _provv); - darec_r.put("NDOC", doc.get("NDOC")); - TRectype arec_r(darec_r); // istanzia il secondo record per il filtro sul cursore - fcur.setregion(darec_r, arec_r); // setta il filtro sul cursore del form - fcur.set_filterfunction(filter_rows); // setta il filtro per escludere alcuni tipi riga indicati nel form - // Da implementare quando verra gestito il numero di copie - for (int j=0; j<ncopie; j++) - { - _form->print(); // stampa il form corrente - _base_page_no = printer().getcurrentpage() -1; // Numero base della pagina - _form->doc()->summary_reset(); - _form->doc()->scadenze_reset(); - } - if (_definitiva && (numerazione_definitiva(doc) != NOERR)) { // se la stampa � definitiva viene lanciata la procedura di rinumerazione - if (_interattivo) error_box("Non � possibile completare la procedura di numerazione definitiva dei documenti"); - break; - } - } - if (_form) - { - delete _form; - _form = NULL; - } - } else { - error_box("Il documento corrente non � stato trovato nella tabella dei tipi di documento (errore %d)", err); - break; - } - } - if (!is_vis) delete pi; - if (_form) - { - delete _form; - _form = NULL; - } - printer().close(); // chiude la stampante -} - -behaviour TStampa_Doc_Vendita::on_module_change(const TString &modulo, TString &modulo_prec) { - if (!_interattivo) return skip; // se siamo in interattivo il documento viene saltato... - else { // ...altrimenti viene chiesto all'utente il da farsi - int risp= yesnocancel_box("Il modulo di carta � cambiato: inserisci il modulo '%s' e premi 'S�' per continuare, 'No' per saltare il documento o 'Cancel' per interrompere la stampa", modulo); - behaviour ret; - switch (risp) { - case K_YES: - modulo_prec= modulo; // aggiorna l'inseguitore dei moduli - ret= go; // la stampa pu� continuare - break; - case K_NO: - ret= skip; // il documento viene saltato - break; - case K_ESC: - ret= cancel; // la stampa viene interrotta - break; - } - return ret; - } -} - -bool TStampa_Doc_Vendita::query_final_print() { - if (_interattivo) { // se siamo in interattivo viene richiesto all'utente se la stampa � definitiva o meno - if (yesno_box("E' una stampa definitiva?")) return TRUE; - else return FALSE; - } else return _definitiva; // altrimenti ritorna il valore letto dalla linea di comando -} - - - -int ve1100(int argc, char* argv[]) { - TStampa_Doc_Vendita a; +// Do all the work! +int ve1100(int argc, char* argv[]) +{ + TStampaDoc_application a; a.run(argc, argv, "Stampa documenti di vendita"); return (0); }