Files correlati : Ricompilazione Demo : [ ] Commento : Corretta abilitazione bottone email in base all'indirizzo di posta del cliente correntemente selezionato git-svn-id: svn://10.65.10.50/branches/R_10_00@21922 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1496 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1496 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "velib05.h"
 | 
						||
#include "ve1300a.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 <spotlite.h>
 | 
						||
#include <statbar.h>
 | 
						||
#include <textset.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include <clifo.h>
 | 
						||
#include <cfven.h>
 | 
						||
#include <comuni.h>
 | 
						||
#include <nditte.h>
 | 
						||
#include <multirel.h>
 | 
						||
 | 
						||
#include "../lv/lvlib.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("05").get_int(RDOC_NRIGA); // 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 TToken_string _sortexpr;
 | 
						||
 | 
						||
static int compare_rdocs(const TObject** p1, const TObject** p2)
 | 
						||
{
 | 
						||
	const TRectype& r1 = *(const TRectype*)(*p1);
 | 
						||
	const TRectype& r2 = *(const TRectype*)(*p2);
 | 
						||
 | 
						||
  int cmp = 0;
 | 
						||
  FOR_EACH_TOKEN(_sortexpr, fld)
 | 
						||
  {
 | 
						||
	  const TString& c1 = r1.get(fld);
 | 
						||
	  const TString& c2 = r2.get(fld);
 | 
						||
    if (real::is_real(c1) && real::is_real(c2))
 | 
						||
    {
 | 
						||
      const real r1(c1);
 | 
						||
      const real r2(c2);
 | 
						||
      cmp = r1 == r2 ? 0 : (r1 < r2 ? -1 : +1);
 | 
						||
    }
 | 
						||
    else
 | 
						||
	    cmp = c1.compare(c2);
 | 
						||
    if (cmp != 0)
 | 
						||
      break;
 | 
						||
  }
 | 
						||
	return cmp;
 | 
						||
}
 | 
						||
 | 
						||
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)
 | 
						||
			{
 | 
						||
        TToken_string by(line.mid(pos + 3), ' '); 
 | 
						||
        by.strip_double_spaces(); by.trim();
 | 
						||
        FOR_EACH_TOKEN(by, tok)
 | 
						||
        {
 | 
						||
          TString16 fld = tok;
 | 
						||
				  if (fld.starts_with("34."))
 | 
						||
					  fld.ltrim(3);
 | 
						||
				  if (fld.starts_with("RDOC."))
 | 
						||
  				  fld.ltrim(5);
 | 
						||
          _sortexpr.add(fld);
 | 
						||
        }
 | 
						||
			}
 | 
						||
			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[4] = { 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);
 | 
						||
	}
 | 
						||
	_doc->set_riga_conai();
 | 
						||
 | 
						||
  // Posiziona correttamente anche il cursore principale
 | 
						||
  *cursor() = 0L;
 | 
						||
}
 | 
						||
 | 
						||
TDoc_recordset::~TDoc_recordset()
 | 
						||
{
 | 
						||
  if (_doc != NULL)
 | 
						||
    delete _doc;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TTrans_recordset
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TTrans_recordset : public TAS400_recordset
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool parse_query(const TString& query, TFilename& n);
 | 
						||
  virtual bool load_file(const TFilename& n);
 | 
						||
 | 
						||
public:
 | 
						||
  TTrans_recordset(const char* ininame);
 | 
						||
};
 | 
						||
 | 
						||
bool TTrans_recordset::parse_query(const TString& query, TFilename& n)
 | 
						||
{
 | 
						||
  n = query;
 | 
						||
  return n.exist() ? _qt_select : _qt_none;
 | 
						||
}
 | 
						||
 | 
						||
bool TTrans_recordset::load_file(const TFilename& n)
 | 
						||
{
 | 
						||
  TConfig ini(n, "33");
 | 
						||
 | 
						||
  TToken_string dokey;
 | 
						||
  for (int idx = 0; ; idx++)
 | 
						||
  {
 | 
						||
    dokey = ini.get("Doc", NULL, idx);
 | 
						||
    if (dokey.blank())
 | 
						||
      break;
 | 
						||
    const TRectype& doc = cache().get(LF_DOC, dokey);
 | 
						||
    if (!doc.empty())
 | 
						||
    {
 | 
						||
      new_rec();
 | 
						||
      for (unsigned int c = 0; c < columns(); c++)
 | 
						||
      {
 | 
						||
        const TRecordset_column_info& ci = column_info(c);
 | 
						||
        const char* fldname = ci._name;
 | 
						||
        set(fldname, doc.get(fldname));
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return items() > 0;
 | 
						||
}
 | 
						||
 | 
						||
TTrans_recordset::TTrans_recordset(const char* ininame) : TAS400_recordset(ininame)
 | 
						||
{
 | 
						||
	_info._width = 32;
 | 
						||
  create_field(DOC_PROVV,   -1, 1, _alfafld, true);
 | 
						||
  create_field(DOC_ANNO,    -1, 4,  _intfld, true);
 | 
						||
  create_field(DOC_CODNUM,  -1, 4, _alfafld, true);
 | 
						||
  create_field(DOC_NDOC,    -1, 7, _longfld, true);
 | 
						||
  create_field(DOC_TIPODOC, -1, 4, _alfafld);
 | 
						||
  create_field(DOC_TIPOCF,  -1, 1, _alfafld);
 | 
						||
  create_field(DOC_CODCF,   -1, 6, _longfld);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TReport_doc
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TReport_doc : public TReport
 | 
						||
{
 | 
						||
  size_t _first_msg;
 | 
						||
  int _extra_copies;
 | 
						||
 | 
						||
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);
 | 
						||
  virtual bool get_usr_val(const TString& name, TVariant& var) const;
 | 
						||
  virtual bool set_usr_val(const TString& name, const TVariant& var);
 | 
						||
 | 
						||
  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);
 | 
						||
  bool msg_lv_dot(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, word printed_copies = 0);
 | 
						||
  int extra_copies() const { return _extra_copies; }
 | 
						||
 | 
						||
  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");            
 | 
						||
          TString4 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, word printed_copies)
 | 
						||
{
 | 
						||
  bool printed = true;
 | 
						||
 | 
						||
  const TString old_query = recordset()->query_text();
 | 
						||
  TDoc_recordset* rs = new TDoc_recordset(doc, old_query);
 | 
						||
	set_recordset(rs);
 | 
						||
 | 
						||
  TDocumento& d = rs->doc();
 | 
						||
  if (!definitive || d.stampabile())
 | 
						||
  {
 | 
						||
    for (int c = 1; c <= copie; c++)
 | 
						||
    {
 | 
						||
  		set_copy(c + printed_copies, copie + printed_copies);
 | 
						||
      // Tenta di stampare gli allegati solo sull'ultima copia definitiva
 | 
						||
      if (c == copie && can_allegate) 
 | 
						||
      {
 | 
						||
        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)
 | 
						||
    {
 | 
						||
      if (definitive)
 | 
						||
        set_printed_status(d);
 | 
						||
      if (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;
 | 
						||
}
 | 
						||
 | 
						||
bool TReport_doc::msg_lv_dot(TVariant_stack& stack)
 | 
						||
{
 | 
						||
  TReport_field& cf = *curr_field();
 | 
						||
 | 
						||
  const TString& field = stack.pop().as_string();
 | 
						||
  if(field == "DOTOD" || field == "DOTMP" || field == "DOTIN")
 | 
						||
  {
 | 
						||
    const TRectype& rdoc = riga_doc();
 | 
						||
    const TDocumento& h = doc();
 | 
						||
    //instanzio un TArticolo_lavanderie per poter recuperare i dati di interesse
 | 
						||
    TArticolo_lavanderie& artrec = cached_article_laundry(rdoc.get(RDOC_CODARTMAG), h.get(DOC_TIPOCF)[0], h.get_long(DOC_CODCF), h.get_int(DOC_CODINDSP));
 | 
						||
	
 | 
						||
    //setto datasc a oggi e fisso l'anno esercizio
 | 
						||
    TEsercizi_contabili& esc = esercizi();
 | 
						||
    const int last_esc = esc.last();
 | 
						||
 | 
						||
    //estraggo il record corrispondente su LF_CLIFOGIAC	
 | 
						||
    const TRecmag_lavanderie& reclav = artrec.find_rec(last_esc);
 | 
						||
    TVariant x = reclav.get(field);
 | 
						||
 | 
						||
    if(reclav.empty())
 | 
						||
    {
 | 
						||
      TArticolo_lavanderie& artrec1 = cached_article_laundry(rdoc.get(RDOC_CODARTMAG), h.get(DOC_TIPOCF)[0], h.get_long(DOC_CODCF), 0);
 | 
						||
      const TRecmag_lavanderie& reclav1 = artrec1.find_rec(last_esc);
 | 
						||
      x = reclav1.get(field);
 | 
						||
    }
 | 
						||
    cf.set(x);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    cf.set("");
 | 
						||
  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",
 | 
						||
    "DOC_LV_DOT",
 | 
						||
    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;
 | 
						||
    case  6: msg_lv_dot(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");
 | 
						||
}
 | 
						||
 | 
						||
bool TReport_doc::get_usr_val(const TString& name, TVariant& var) const
 | 
						||
{
 | 
						||
  if (name == "#PRINT_EXTRA_COPIES")
 | 
						||
  {
 | 
						||
    var = long(_extra_copies);
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
  return TReport::get_usr_val(name, var);
 | 
						||
}
 | 
						||
 | 
						||
bool TReport_doc::set_usr_val(const TString& name, const TVariant& var)
 | 
						||
{
 | 
						||
  if (name == "#PRINT_EXTRA_COPIES")
 | 
						||
  {
 | 
						||
    _extra_copies = var.as_int();
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
  return TReport::set_usr_val(name, var);
 | 
						||
}
 | 
						||
 | 
						||
TReport_doc::TReport_doc(const char* name) : _extra_copies(0)
 | 
						||
{ 
 | 
						||
  // 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 TReport_rct& rect, const char* text, const char* link);
 | 
						||
};
 | 
						||
 | 
						||
void TDoc_book::draw_link(const TReport_rct& 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("ve1300a") 
 | 
						||
{ 
 | 
						||
  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) { return new TReport_doc(key); }
 | 
						||
public:
 | 
						||
  TReport_doc& get(const TString& key) { return *(TReport_doc*)objptr(key); }
 | 
						||
  TReports_cache() : TCache(13) { }
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TReport_doc_app
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TReport_doc_app : public TSkeleton_application
 | 
						||
{
 | 
						||
  enum TOutput_mode { out_preview, out_print, out_mail, out_signed_mail, out_pdf, out_signed_pdf };
 | 
						||
 | 
						||
  TReport_doc_mask* _msk;
 | 
						||
 | 
						||
  int _anno;
 | 
						||
  TString16 _codnum; // codice numerazione / profilo
 | 
						||
  long _ndoc, _codcf;
 | 
						||
	char _tipocf;
 | 
						||
  bool _no_print_dlg;
 | 
						||
 | 
						||
protected:
 | 
						||
	void add_cli_filter(TString& query, bool from) const;
 | 
						||
  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(TRecordset& doc, TOutput_mode mode, bool is_definitive);
 | 
						||
  void print_selection(TOutput_mode mode);
 | 
						||
  void print_trans(const char* ininame);
 | 
						||
  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, short& ui) const ;
 | 
						||
  void print_extra_copies(TReport_doc& report, const TRecordset& doc, TReport_book& book, word printed_copies) const;
 | 
						||
  bool nome_report(const TRecordset& doc, int quale, TFilename& profilo) 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
 | 
						||
{
 | 
						||
	TString8 key;	key << _tipocf << '|' << _codcf;
 | 
						||
  const TString& maddr = cache().get(LF_CLIFO, key, CLI_DOCMAIL);
 | 
						||
	return maddr;
 | 
						||
}
 | 
						||
 | 
						||
bool TReport_doc_app::get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, 
 | 
						||
											              TString& subj, TString& text, TToken_string& attach, short& 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();
 | 
						||
        subj << ' ' << _ndoc << TR(" del ") << doc.get(DOC_DATADOC) 
 | 
						||
             << ' ' << prefix().firm().ragione_sociale();
 | 
						||
      }
 | 
						||
			text << TR("Invio documento ") << subj;
 | 
						||
      if (to.full())
 | 
						||
        ui &= ~0x1; // No user interface
 | 
						||
      ui |= 0x2; // Query receipt
 | 
						||
		}
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TReport_doc_app::add_cli_filter(TString& query, bool from) const
 | 
						||
{
 | 
						||
  if (from)
 | 
						||
  {
 | 
						||
    query << " KEY 4 SELECT "
 | 
						||
          << "(PROVV='" << _msk->get(F_PROVV)
 | 
						||
					<< "')&&(ANNO=" << _msk->get(F_ANNO) 
 | 
						||
          << ")&&(CODNUM='" << _msk->get(F_CODNUM) << "')";
 | 
						||
  }
 | 
						||
  query << '\n';
 | 
						||
	const TString4 tipocf = _msk->get(F_TIPOCFD);
 | 
						||
  const long cod = _msk->get_long(from ? F_DA_CLIFO : F_A_CLIFO);
 | 
						||
  if (cod > 0L)
 | 
						||
     query << (from ? "FROM" : "TO") << " TIPOCF=" << tipocf << " CODCF=" << cod;
 | 
						||
}
 | 
						||
 | 
						||
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 char tipost = _msk->get(F_ORDERING)[0];
 | 
						||
	switch (tipost)
 | 
						||
	{
 | 
						||
	case 'D': add_data_filter(query, from); break;
 | 
						||
	case 'C':	add_cli_filter(query, from);	break;
 | 
						||
	default : add_ndoc_filter(query, from);	break;
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
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();
 | 
						||
}
 | 
						||
 | 
						||
void TReport_doc_app::print_extra_copies(TReport_doc& report, const TRecordset& doc, 
 | 
						||
                                         TReport_book& book, word printed_copies) const
 | 
						||
{
 | 
						||
  const int extra_copies = report.extra_copies();
 | 
						||
  if (extra_copies > 0)
 | 
						||
    report.print(doc, book, false, extra_copies, false, false, false, printed_copies);
 | 
						||
}
 | 
						||
 | 
						||
// Quale 0=standard,1=aggiuntivo,2=mail
 | 
						||
bool TReport_doc_app::nome_report(const TRecordset& doc, int quale, TFilename& profilo) const
 | 
						||
{
 | 
						||
  const TString4 tipodoc = doc.get(DOC_TIPODOC).as_string();
 | 
						||
  const TTipo_documento& tipo = cached_tipodoc(tipodoc);
 | 
						||
  bool ok = false;
 | 
						||
  switch (quale)
 | 
						||
  {
 | 
						||
  case  1:  ok = tipo.additional_print_profile(profilo, 2); break;
 | 
						||
  case  2:  ok = tipo.mail_print_profile(profilo); break;
 | 
						||
  default:  ok = tipo.main_print_profile(profilo, 2); break;
 | 
						||
  }
 | 
						||
 | 
						||
  if (ok) // Cerca eventuale personalizzazione per il singolo cliente
 | 
						||
  {
 | 
						||
    TString8 codcf = doc.get(DOC_CODCF).as_string(); codcf.right_just(6, '0');
 | 
						||
    TFilename path = profilo.name_only();
 | 
						||
    path << '_' << doc.get(DOC_TIPOCF) << codcf << ".rep";
 | 
						||
    if (path.custom_path())
 | 
						||
      profilo = path;
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TReport_doc_app::print_loop(TRecordset& doc, TOutput_mode mode, bool is_definitive)
 | 
						||
{
 | 
						||
  const int docs = doc.items();
 | 
						||
  if (docs <= 0)
 | 
						||
    return false;
 | 
						||
 | 
						||
  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 della singola mail
 | 
						||
	TLog_report mail_log(TR("Invio documenti per email"));
 | 
						||
  TProgind pi(docs, TR("Elaborazione documenti..."), true, true);
 | 
						||
 | 
						||
  bool attach_mail = mode==out_mail || mode==out_signed_mail;
 | 
						||
  if (attach_mail && is_power_station())
 | 
						||
    attach_mail = yesno_box(TR("Si desidera spedire veramente i documenti via mail?\n"
 | 
						||
                               "Rispondendo NO verranno solo salvati gli allegati."));
 | 
						||
 | 
						||
  for (int i = 0; i < docs; i++)
 | 
						||
  {
 | 
						||
    if (!pi.addstatus(1))
 | 
						||
      break;
 | 
						||
 | 
						||
    doc.move_to(i);
 | 
						||
 | 
						||
    const TString4 tipodoc = doc.get(DOC_TIPODOC).as_string();
 | 
						||
		const TTipo_documento& tipo = cached_tipodoc(tipodoc);
 | 
						||
 | 
						||
    bool arc = false;
 | 
						||
    if (is_definitive)
 | 
						||
    {
 | 
						||
      if (doc.get(DOC_STATO).as_string()[0] == tipo.stato_finale_stampa())
 | 
						||
        continue; // Evita lavoro inutile!
 | 
						||
 | 
						||
      const TString4 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 bool send_mail = ( mode == out_mail || mode == out_signed_mail) && get_mail_address().full();
 | 
						||
    const bool paperless = send_mail || mode == out_pdf || mode == out_signed_pdf;
 | 
						||
	
 | 
						||
    // Tenta di costruirsi il nome del report: se non stampo su carta cerco di usare un profilo con sfondo
 | 
						||
    TFilename profilo; 
 | 
						||
    const bool ok = nome_report(doc, paperless ? 2 : 0, profilo); 
 | 
						||
    
 | 
						||
		if (ok) 
 | 
						||
		{
 | 
						||
			int copies = 1;
 | 
						||
      if (!paperless)
 | 
						||
      {
 | 
						||
        copies = _msk->get_int(F_NCOPIE);
 | 
						||
			  if (copies <= 0 && is_definitive)
 | 
						||
				  copies = tipo.ncopie();
 | 
						||
			  if (copies <= 0)
 | 
						||
				  copies = 1;
 | 
						||
      }
 | 
						||
 | 
						||
			TReport_doc& report = reports.get(profilo);
 | 
						||
  		if (send_mail)
 | 
						||
			{
 | 
						||
				mail_book = new TDoc_book;
 | 
						||
				if (!report.print(doc, *mail_book, is_definitive, 1, true, false, false)) // Non archiviare per ora...
 | 
						||
					break;
 | 
						||
        if (arc) // ... eventualemte archivia direttamente il book senza passare per uno temporaneo
 | 
						||
          mail_book->archive(NULL, signature);
 | 
						||
 | 
						||
				TString mesg;
 | 
						||
        mesg << tipo.descrizione() << TR(" n. ") << doc.get(DOC_NDOC)
 | 
						||
             << TR(" del ") << doc.get(DOC_DATADOC) << TR(" a ") << get_mail_address();
 | 
						||
				mail_log.log(0, mesg);
 | 
						||
			}
 | 
						||
			else
 | 
						||
			{
 | 
						||
				if (!report.print(doc, book, is_definitive, copies, true, arc, signature))
 | 
						||
					break;
 | 
						||
        if (!paperless)
 | 
						||
          print_extra_copies(report, doc, book, copies);
 | 
						||
			}
 | 
						||
		}	//if(profilo.custom_path()...
 | 
						||
		else
 | 
						||
		{
 | 
						||
      TString msg; msg << TR("Report inesistente: ") << profilo;
 | 
						||
      xvtil_popup_error(msg);
 | 
						||
			continue;
 | 
						||
		}
 | 
						||
 | 
						||
    // Stampa eventuali allegati
 | 
						||
    if (nome_report(doc, 1, profilo))
 | 
						||
    {
 | 
						||
      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 (!paperless)
 | 
						||
          print_extra_copies(allegato, doc, book, copies);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
		if (mail_book != NULL)
 | 
						||
		{
 | 
						||
			if (mail_book->pages() > 0)
 | 
						||
			{
 | 
						||
				TFilename attachment;
 | 
						||
        bool is_tmp = false;
 | 
						||
 | 
						||
        // Se ho archiviato (arc==true) allora il file di attachment e' gia' pronto!
 | 
						||
        bool ok = arc && get_next_pdf(_anno, -1, _codnum, _ndoc, _codcf, attachment);
 | 
						||
        if (!ok || !attachment.exist()) // Altrimenti ne creo uno temporaneo
 | 
						||
        {
 | 
						||
  				attachment.tempdir();
 | 
						||
	  			attachment << SLASH << _anno <<'_' << _codnum << '_' << _ndoc;
 | 
						||
		  		attachment.ext("pdf");
 | 
						||
          ok = mail_book->export_pdf(attachment, mode == out_signed_mail);
 | 
						||
          is_tmp = ok;
 | 
						||
        }
 | 
						||
        if (ok && attach_mail) // Ho chiesto la spedizione vera e propria
 | 
						||
        {
 | 
						||
          ok = spotlite_send_mail(attachment);
 | 
						||
          if (is_tmp)
 | 
						||
            attachment.fremove();
 | 
						||
        }
 | 
						||
			}
 | 
						||
			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!!!
 | 
						||
 | 
						||
    if (mail_log.recordset()->items() > 0)
 | 
						||
		  book.add(mail_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:
 | 
						||
      if (_no_print_dlg)
 | 
						||
        book.print(1, book.pages()); // Evita di chiedere da pag. a pag.
 | 
						||
      else
 | 
						||
        book.print(); 
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (mail_log.recordset()->items() > 0)
 | 
						||
      mail_log.preview();
 | 
						||
  }
 | 
						||
 | 
						||
  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);
 | 
						||
 | 
						||
  TISAM_recordset doc(query);
 | 
						||
  const TRecnotype docs = doc.items();
 | 
						||
  if (docs > 0)
 | 
						||
  {
 | 
						||
    bool is_definitive = false;
 | 
						||
    if (argc() > 7) // Batch
 | 
						||
      is_definitive = *argv(7) == 'D';
 | 
						||
    else
 | 
						||
    {
 | 
						||
  		if (argc() < 6)   // Vieta i link quando sono in batch
 | 
						||
  			is_definitive = _msk->get(F_TIPOST) == "D";
 | 
						||
  		else
 | 
						||
  		{
 | 
						||
  	    const KEY k = yesnocancel_box(FR("Stampare in definitiva %ld documenti?"), docs);
 | 
						||
  		  if (k == K_ESC)
 | 
						||
  			  return;
 | 
						||
  			is_definitive = k == K_YES;
 | 
						||
  		}
 | 
						||
    }
 | 
						||
    print_loop(doc, mode, is_definitive);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// Elabora una transazione del tipo
 | 
						||
// [Transaction]
 | 
						||
// Action = Stampa
 | 
						||
// Mode = D
 | 
						||
// NoPrintDlg = X
 | 
						||
// [33]
 | 
						||
// Doc(0)=D|2009|F01|1
 | 
						||
// Doc(1)=D|2009|A02|2
 | 
						||
void TReport_doc_app::print_trans(const char* ininame)
 | 
						||
{
 | 
						||
  TTrans_recordset doc(ininame);
 | 
						||
  if (doc.items() > 0)
 | 
						||
  {
 | 
						||
    char a='S', m='P';
 | 
						||
    if (ininame && *ininame) // Dummy test
 | 
						||
    {
 | 
						||
      TConfig ini(ininame, "Transaction");
 | 
						||
      a = ini.get("Action")[0]; // Stampa, Anteprima, Pdf, ...
 | 
						||
      m = ini.get("Mode")[0];   // Definitivo o Provvisori
 | 
						||
      _no_print_dlg = ini.get_bool("NoPrintDlg");
 | 
						||
    }
 | 
						||
    const TOutput_mode mode = key2mode(a);
 | 
						||
    const bool is_definitive = m == 'D';
 | 
						||
    print_loop(doc, mode, is_definitive);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    cantread_box(ininame);
 | 
						||
}
 | 
						||
 | 
						||
// Traduce un carattere ASCII nella corrispondente modalita' di stampa
 | 
						||
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()
 | 
						||
{
 | 
						||
  _no_print_dlg = false;
 | 
						||
  const int a = argc();
 | 
						||
  if (a > 2)
 | 
						||
  {
 | 
						||
    const TFixed_string arg = argv(2);
 | 
						||
    
 | 
						||
    // Gestione transazioni di stampa
 | 
						||
    if (arg.starts_with("-i"))
 | 
						||
    {
 | 
						||
      const TFilename ini = arg.mid(2);
 | 
						||
      if (ini.exist())
 | 
						||
        print_trans(ini);
 | 
						||
      return;
 | 
						||
    }
 | 
						||
 | 
						||
    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_ORDERING, "N");  // Stampa per numero documento
 | 
						||
    _msk->set(F_ANNO,  argv(3));
 | 
						||
		_msk->set(F_PROVV, argv(4));
 | 
						||
    
 | 
						||
    // "883" = Stampa solo 883; "882-884" = stampa dal 882 al 884
 | 
						||
		const TToken_string strndoc(argv(5), '-'); 
 | 
						||
    long dandoc = 0, andoc = 0;
 | 
						||
    if (strndoc.get(0, dandoc))
 | 
						||
    {
 | 
						||
      if (!strndoc.get(1, andoc))
 | 
						||
        andoc = dandoc;
 | 
						||
      _msk->set(F_DA_NDOC, dandoc);
 | 
						||
      _msk->set(F_A_NDOC,  andoc);
 | 
						||
    }
 | 
						||
 | 
						||
   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);
 | 
						||
}
 |