Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.2 patch 1353 git-svn-id: svn://10.65.10.50/trunk@18581 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1217 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1217 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "velib05.h"
 | ||
| #include "ve1100.h"
 | ||
| 
 | ||
| #include <applicat.h>
 | ||
| #include <automask.h>
 | ||
| #include <defmask.h>
 | ||
| #include <modaut.h>
 | ||
| #include <postman.h>
 | ||
| #include <progind.h>
 | ||
| #include <reprint.h>
 | ||
| #include <reputils.h>
 | ||
| #include <statbar.h>
 | ||
| 
 | ||
| #include <clifo.h>
 | ||
| #include <cfven.h>
 | ||
| #include <comuni.h>
 | ||
| #include <nditte.h>
 | ||
| #include <multirel.h>
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // 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, bool signature);
 | ||
| 
 | ||
|   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, bool signature)
 | ||
| {
 | ||
|   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(signature);
 | ||
| 
 | ||
|   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,<selettore>,<macro>,<cambio codice>
 | ||
|   // dove: <selettore> <20> 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: <macro> <20> 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: <cambio codice> <20> 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,<selettore>
 | ||
|   // dove: <selettore> 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);
 | ||
| 
 | ||
|   //abilita i bottoni della toolbar in base ai moduli presenti sulla chiave
 | ||
|   TApplication& a = main_app();
 | ||
|   const bool can_pdf = a.has_module(RSAUT);
 | ||
|   const bool can_sign = can_pdf && a.has_module(FDAUT);
 | ||
|   enable(DLG_EMAIL, can_pdf);
 | ||
|   enable(DLG_SIGNMAIL, can_sign);
 | ||
|   enable(DLG_PDF, can_pdf);
 | ||
|   enable(DLG_SIGNPDF, can_sign);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // 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;
 | ||
| 
 | ||
|   enum TOutput_mode {out_preview, out_print, out_mail, out_signed_mail, out_pdf, out_signed_pdf};
 | ||
| 
 | ||
|   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, TOutput_mode mode);
 | ||
|   void print_selection(TOutput_mode mode);
 | ||
|   TOutput_mode key2mode(KEY k) const;
 | ||
| 
 | ||
|   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;
 | ||
|       ui = false;
 | ||
| 		}
 | ||
| 	}
 | ||
| 	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, TOutput_mode mode)
 | ||
| {
 | ||
|   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;
 | ||
|   }
 | ||
| 
 | ||
|   if (mode == out_signed_mail && !xvt_sign_start())
 | ||
|   {
 | ||
|     if (yesno_box(TR("Si desidera generare comunque documenti non firmati?")))
 | ||
|       mode = out_mail;
 | ||
|     else
 | ||
|       return false;
 | ||
|   }
 | ||
|   const bool signature = mode==out_signed_mail || mode==out_signed_pdf;
 | ||
|   
 | ||
|   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 = ( mode == out_mail || mode == out_signed_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 || send_mail)
 | ||
| 				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, signature))
 | ||
| 					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, signature))
 | ||
| 					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 definitivo deve essere false altrimenti riaggiorna lo stato e ristampa i documenti allegati
 | ||
| 			if (send_mail)
 | ||
|         allegato.print(doc, *mail_book, false, 1, false, false, false); // Non archivio gli allegati alla mail
 | ||
| 			else
 | ||
|         allegato.print(doc, book, false, copies, false, arc, signature);
 | ||
|     }
 | ||
| 
 | ||
| 		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, mode == out_signed_mail);
 | ||
| 				remove(attachment);
 | ||
| 			}
 | ||
| 			delete mail_book;
 | ||
| 			mail_book = NULL;
 | ||
| 		}
 | ||
|   }
 | ||
| 
 | ||
|   if (book.pages() > 0)
 | ||
|   {
 | ||
|     if (docs > 1) 
 | ||
| 			set_next_pdf(0, "", 0L, ' ', 0L); //spegne l'archiviazione nell'esportazione;non si possono archiviare pi<70> docs in uno!!!
 | ||
| 		book.add(log);
 | ||
|     switch (mode)
 | ||
|     {
 | ||
|     case out_preview: book.preview(); break;
 | ||
|     case out_pdf:     
 | ||
|     case out_signed_pdf:
 | ||
|       {
 | ||
|         TFilename pdf;
 | ||
| 				pdf.tempdir();
 | ||
| 				pdf << SLASH << _anno <<'_' << _codnum << '_' << _ndoc;
 | ||
| 				pdf.ext("pdf");
 | ||
| 
 | ||
|         if (book.export_pdf(pdf, mode == out_signed_pdf))
 | ||
|           xvt_sys_goto_url(pdf, "open");
 | ||
|       }
 | ||
|       break;
 | ||
|     default: book.print(); break;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   if (mode == out_signed_mail || mode == out_signed_pdf)
 | ||
|     xvt_sign_stop();
 | ||
| 
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| void TReport_doc_app::print_selection(TOutput_mode mode)
 | ||
| {
 | ||
|   TString query;
 | ||
|   query << "USE " << LF_DOC;
 | ||
|   add_filter(query, true);
 | ||
|   add_filter(query, false);
 | ||
|   print_loop(query, mode);
 | ||
| }
 | ||
| 
 | ||
| //Allah!!
 | ||
| TReport_doc_app::TOutput_mode TReport_doc_app::key2mode(KEY k) const
 | ||
| {
 | ||
|   TOutput_mode mode = out_print;
 | ||
|   
 | ||
|   if (k >= 'a' && !has_module(FDAUT))
 | ||
|     k -= ' '; // toupper dei poveri
 | ||
|   if (!has_module(RSAUT))
 | ||
|     k = 'A';
 | ||
| 
 | ||
|   switch (k)
 | ||
|   {
 | ||
|     case 'A': mode = out_preview; break;
 | ||
|     case 'E': mode = out_mail; break;
 | ||
|     case 'e': mode = out_signed_mail; break;
 | ||
|     case 'P': mode = out_pdf; break;
 | ||
|     case 'p': mode = out_signed_pdf; break;
 | ||
|     case 'S': 
 | ||
|     default : mode = out_print; break;
 | ||
|   }
 | ||
|   return mode;
 | ||
| }
 | ||
| 
 | ||
| void TReport_doc_app::main_loop()
 | ||
| {
 | ||
|   const int a = argc();
 | ||
| 
 | ||
|   if (a > 2)
 | ||
|   {
 | ||
|     const TFixed_string arg = argv(2);
 | ||
|     TString4 codnum = arg.left(4);
 | ||
|     if (arg.len() > 4 || cache().get("%NUM", arg).empty())
 | ||
| 		{
 | ||
|       const TToken_string tok(arg, ',');
 | ||
|       TString16 paragraph, field;
 | ||
|       tok.get(0, paragraph); tok.get(1, field);
 | ||
|       if (field.blank()) field = DOC_CODNUM;
 | ||
| 			codnum = ini_get_string(CONFIG_DITTA, paragraph, field);
 | ||
| 		}
 | ||
|     _msk->set(F_CODNUM, codnum); // Stampa da menu con numerazione imposta
 | ||
|   }
 | ||
| 
 | ||
|   if (a > 6)                       // Stampa da riga di comando
 | ||
|   {
 | ||
|     _msk->set(F_DATA_O_NUM, "N");  // Stampa per numero documento
 | ||
|     _msk->set(F_ANNO,    argv(3));
 | ||
|     _msk->set(F_PROVV,   argv(4));
 | ||
|     _msk->set(F_DA_NDOC, argv(5));
 | ||
|     _msk->set(F_A_NDOC,  argv(5));
 | ||
|     const TOutput_mode mode = key2mode(*argv(6)); // modo di 'S'tampa, 'A'nteprima, 'P'DF
 | ||
|     // argv(7);                    // Provvisiorio o Definitivo testato altrove!
 | ||
|     if (a > 8) 
 | ||
|       _msk->set(F_NCOPIE, argv(8)); // Numero copie
 | ||
|     
 | ||
|     print_selection(mode);
 | ||
|     return;
 | ||
|   }
 | ||
| 
 | ||
|   while (true)
 | ||
|   {
 | ||
|     const KEY k = _msk->run();
 | ||
|     if (k == K_QUIT)
 | ||
|       break;
 | ||
|     print_selection(key2mode(k));
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| int ve1300(int argc, char* argv[])
 | ||
| { 
 | ||
|   TReport_doc_app a;
 | ||
|   a.run(argc, argv, TR("Stampa documenti"));
 | ||
|   return (0);
 | ||
| }
 |