git-svn-id: svn://10.65.10.50/branches/R_10_00@23140 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2601 lines
		
	
	
		
			92 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2601 lines
		
	
	
		
			92 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <dongle.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <reputils.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "lvlib.h"
 | 
						||
#include "lv2500a.h"
 | 
						||
 | 
						||
#include "../pr/agenti.h"
 | 
						||
#include "../pr/percprov.h"
 | 
						||
#include "../cg/cfban.h"
 | 
						||
#include "../cg/cglib03.h"
 | 
						||
 | 
						||
#include "comuni.h"
 | 
						||
#include "lvcondv.h"
 | 
						||
#include "lvrcondv.h"
 | 
						||
 | 
						||
#include "../ve/ve6200.h"
 | 
						||
#include "../ve/ve6200a.h"
 | 
						||
 | 
						||
#define DOC_DEST  "DEST"  //c campo virtuale per la destinazone
 | 
						||
 | 
						||
class TFatturazione_lavanderie;
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
                                      //// classe TFatturazione_msk       ////
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
 | 
						||
class TFatturazione_msk: public TAutomask
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly){return true;}
 | 
						||
public:
 | 
						||
  TFatturazione_msk();
 | 
						||
};
 | 
						||
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
                                      //// TFatturazione_lavanderie app   ////
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
 | 
						||
//Classe TFatturazione_lavanderie_app
 | 
						||
class TFatturazione_lav_app: public TSkeleton_application
 | 
						||
{ 
 | 
						||
  TFatturazione_msk*  _msk;
 | 
						||
	TLog_report * _log;
 | 
						||
	bool _solototali;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual void main_loop();
 | 
						||
  virtual bool create();
 | 
						||
 | 
						||
public:
 | 
						||
  void genera_bolle_nolo(TAssoc_array& cliela, TFatturazione_lavanderie& elab, int& numdocgen, real& totimp, real& imposta, real& totdoc, real& spese);
 | 
						||
  bool controlli_preliminari();
 | 
						||
  bool copy_file(const TFilename& src, const TFilename& dst) const;
 | 
						||
  bool copy_tree(const char* src_study, const char* dst_study) const;
 | 
						||
  void log(const char* msg, int sev = 0);
 | 
						||
};
 | 
						||
 | 
						||
TFatturazione_lav_app & app() { return (TFatturazione_lav_app &) main_app();}
 | 
						||
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
                                      ////    TCalc_02_data               ////
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
 | 
						||
//Classe TCalc_02_data
 | 
						||
class TCalc_02_data : public TObject
 | 
						||
{
 | 
						||
	TString _key;
 | 
						||
	TGeneric_distrib _distr;
 | 
						||
	TGeneric_distrib _distr_rit;
 | 
						||
	TAssoc_array _bol_rows;
 | 
						||
 | 
						||
  virtual TObject* dup() const;
 | 
						||
	void copy(const TCalc_02_data & d);
 | 
						||
 | 
						||
public:
 | 
						||
	TCalc_02_data & operator = (const TCalc_02_data & d) { copy(d); return *this; }
 | 
						||
	const TString & key() const { return _key; }
 | 
						||
	TGeneric_distrib & distr() { return _distr; }
 | 
						||
	TGeneric_distrib & distr_rit() { return _distr_rit; }
 | 
						||
	TAssoc_array & bol_rows() { return _bol_rows; }
 | 
						||
 | 
						||
	TCalc_02_data(const char * key) : _key(key) {}
 | 
						||
	TCalc_02_data(const TCalc_02_data & d) {copy(d);}
 | 
						||
};
 | 
						||
 | 
						||
void TCalc_02_data::copy(const TCalc_02_data & d)
 | 
						||
{
 | 
						||
	_key = d._key;
 | 
						||
	_distr = d._distr;
 | 
						||
	_bol_rows = d._bol_rows;
 | 
						||
}
 | 
						||
 | 
						||
TObject* TCalc_02_data::dup() const
 | 
						||
{
 | 
						||
  TCalc_02_data* o = new TCalc_02_data(*this);
 | 
						||
  return o;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
                                      ////    TFatturazione_lavanderie    ////
 | 
						||
                                      ////////////////////////////////////////
 | 
						||
 | 
						||
//Classe TFatturazione_lavanderie
 | 
						||
class TFatturazione_lavanderie : public TFatturazione_bolle
 | 
						||
{
 | 
						||
  TDate _data_elab;
 | 
						||
	TToken_string _campi_raggruppamento;
 | 
						||
	TAssoc_array _output_rows_02;
 | 
						||
	TAssoc_array _doc_grouped;
 | 
						||
	bool _prova;
 | 
						||
	long _last_cli_damn;
 | 
						||
	int _art_damn;
 | 
						||
	int _cli_damn;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual void add_rows(TRiga_documento & rout, TRiga_documento & rin);
 | 
						||
  virtual void create_row(TDocumento& doc_out, const TRiga_documento & rin);
 | 
						||
  virtual void pre_process_input(TLista_documenti& doc_in);
 | 
						||
	virtual void post_process_input(TLista_documenti& doc_in) {}
 | 
						||
  virtual void post_process(TLista_documenti& doc_out, TLista_documenti& doc_in);
 | 
						||
	virtual bool da_raggruppare(const TRiga_documento & rin);
 | 
						||
	virtual bool doc_raggruppabili(const TDocumento& doc_in, const TDocumento& doc_out, TToken_string& campi) const ;
 | 
						||
	virtual bool doc_raggruppabile(const TDocumento & doc) const { return true; }
 | 
						||
  virtual void campi_raggruppamento_righe(TToken_string& campi_riga) const;
 | 
						||
  virtual bool gestione_riferimenti() const { return true; }
 | 
						||
  virtual bool riferimenti_in_testa() const { return true; }
 | 
						||
  virtual TRiga_documento& find_or_create_row(TDocumento& doc_out, const TRiga_documento & rin,const char lavtype);
 | 
						||
  virtual bool get_num_tip_out(const TDocumento& doc_out, TString& codnum, TString& tipodoc) const;
 | 
						||
 | 
						||
	void aggiorna_fattura(TDocumento & doc, int codcont);
 | 
						||
	bool fatt_02() const { return !_prova && lv_is_02_active(); }
 | 
						||
	void add_doc_to_list(const TString & key, const TDocumento & doc);
 | 
						||
  real get_percprovv(const TRiga_documento & row, char tipoprovv, const TString & codpr, bool first, const TRectype & age) const;
 | 
						||
 | 
						||
public:
 | 
						||
	bool is_document_compatible(const TRectype & doc) const;
 | 
						||
  int write_fatt_ragg(const bool solotot);
 | 
						||
	void set_perc_provv(TRiga_documento & row, bool prima = true);
 | 
						||
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
 | 
						||
                       const TDate& data_elab, bool interattivo = false);
 | 
						||
	long & last_cli_damn() {return _last_cli_damn;}
 | 
						||
	int & cli_damn() {return _cli_damn;}
 | 
						||
	int & art_damn() {return _art_damn;}
 | 
						||
 | 
						||
	TFatturazione_lavanderie(const char* cod, bool prova = false);
 | 
						||
	~TFatturazione_lavanderie() {}
 | 
						||
};
 | 
						||
 | 
						||
TFatturazione_lavanderie::TFatturazione_lavanderie(const char* cod, bool prova)
 | 
						||
                        : TFatturazione_bolle(cod), _prova(prova)
 | 
						||
{
 | 
						||
}
 | 
						||
 | 
						||
bool TFatturazione_lavanderie::is_document_compatible(const TRectype & doc) const
 | 
						||
{
 | 
						||
	bool ok = false;
 | 
						||
	const TString4 codnum(doc.get(DOC_CODNUM));
 | 
						||
	const TString4 tipodoc(doc.get(DOC_TIPODOC));
 | 
						||
	const char stato = doc.get_char(DOC_STATO);
 | 
						||
	const TString& codnumel = codice_numerazione_iniziale();
 | 
						||
 | 
						||
	if (codnumel.blank() || codnum == codnumel)
 | 
						||
	{
 | 
						||
		for (int i = 0; !ok && i < TElaborazione::_max_tipi_doc_elab; i++)
 | 
						||
		{                
 | 
						||
			const TString & tipel = tipo_iniziale(i);
 | 
						||
			if (tipel.blank())
 | 
						||
				break;
 | 
						||
			if (tipodoc == tipel)
 | 
						||
				ok = true;
 | 
						||
		} 
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
//DOC_RAGGRUPPABILI: metodo che restituisce true se i documenti sono raggruppabili sulla base dei campi
 | 
						||
//contenuti nella stringa campi
 | 
						||
bool TFatturazione_lavanderie::doc_raggruppabili(const TDocumento& doc_in, const TDocumento& doc_out, TToken_string& campi) const
 | 
						||
{ 
 | 
						||
  if (doc_in.ha_riga_esenzione() != doc_out.ha_riga_esenzione())
 | 
						||
    return false;
 | 
						||
	bool ok = true;
 | 
						||
 | 
						||
	//scorro tutti i campi contenuti nella TToken_string
 | 
						||
  //se sto controllando i campi CODABI e CODCAB, allora il controllo
 | 
						||
  //deve essere numerico e non tra stringhe
 | 
						||
  for (const char* c = campi.get(0); c && ok; c = campi.get())
 | 
						||
  {
 | 
						||
    if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0)
 | 
						||
		{
 | 
						||
			long cod = doc_in.get_long(c);
 | 
						||
			ok &= (cod == doc_out.get_long(c));
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			const TString& campo = doc_in.get(c);
 | 
						||
			ok &= campo == doc_out.get(c);
 | 
						||
		}
 | 
						||
  }
 | 
						||
  return ok; 
 | 
						||
}
 | 
						||
 | 
						||
//DA_RAGGRUPPARE: per adesso segnaposto: resituisce sempre false
 | 
						||
bool TFatturazione_lavanderie::da_raggruppare(const TRiga_documento & rin)
 | 
						||
{
 | 
						||
	/*	const long clifo = rin.doc().get_long(DOC_CODCF);
 | 
						||
		const int indsped = rin.doc().get_int(DOC_CODINDSP);
 | 
						||
		TLaundry_contract contr(clifo, indsped, _data_elab);
 | 
						||
		const TString80 codart = rin.get(RDOC_CODART);
 | 
						||
		const TRectype & rcont = contr.row(codart);
 | 
						||
		const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
 | 
						||
 | 
						||
		// return tipoforf > 1;   // Test originale
 | 
						||
    if (tipoforf > 1)
 | 
						||
      return true;
 | 
						||
 | 
						||
    // Da qui in poi e' sottinteso tipoforf == 1
 | 
						||
    if (ini_get_int(CONFIG_DITTA, "lv", "TipoPr") == 1) 
 | 
						||
      return false;
 | 
						||
 | 
						||
    // Test GUY
 | 
						||
    const TString8 causale = rin.get(RDOC_CODAGG1);
 | 
						||
    const TCausale_lavand cau = cache().get("&CAU", causale);
 | 
						||
    if (cau.get_bool("B1")) 
 | 
						||
    {
 | 
						||
      const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2"));
 | 
						||
	    if (con.sgn(s_dottm))  // Causale di incremento sotazione temporanea
 | 
						||
        return true; 
 | 
						||
    }
 | 
						||
 | 
						||
    if (cau.get_bool("B4")) // Causale di rotto
 | 
						||
      return true; */
 | 
						||
 | 
						||
    return false;
 | 
						||
}
 | 
						||
 | 
						||
void TFatturazione_lavanderie::pre_process_input(TLista_documenti& doc_in)
 | 
						||
{
 | 
						||
  for (int id = 0; id < doc_in.items(); id++)
 | 
						||
  {                                             
 | 
						||
    TDocumento& doc = doc_in[id];
 | 
						||
		const int rows = doc.physical_rows();
 | 
						||
 | 
						||
    TString str_real;
 | 
						||
		for (int i = 1; i <= rows; i++)
 | 
						||
		{
 | 
						||
			TRiga_documento& row = doc[i];
 | 
						||
			str_real = row.get(RDOC_QTAREALE);
 | 
						||
			if (str_real.full())
 | 
						||
			{
 | 
						||
				const real qta_real(decode(str_real));
 | 
						||
				row.put(RDOC_QTA, qta_real);
 | 
						||
				row.zero(RDOC_QTAREALE);
 | 
						||
			}
 | 
						||
			str_real = row.get(RDOC_QTARITREALE);
 | 
						||
			if (str_real.full())
 | 
						||
			{
 | 
						||
				const real qta_real(decode(str_real));
 | 
						||
				row.put(RDOC_QTAGG1, qta_real);
 | 
						||
				row.zero(RDOC_QTARITREALE);
 | 
						||
			}
 | 
						||
		}
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
//aggiunge una riga fittizia al documento con qta a zero per gli articoli per cui <20> previsto il forfait
 | 
						||
//e che non sono stati consegnati
 | 
						||
void TFatturazione_lavanderie::aggiorna_fattura(TDocumento& doc, int codcont)
 | 
						||
{
 | 
						||
	const int nrows = doc.physical_rows();
 | 
						||
	const long codcf = doc.get_long(DOC_CODCF);
 | 
						||
 | 
						||
  TString str;
 | 
						||
  str << "USE LVRCONDV\n"
 | 
						||
      << "FROM CODCF=" << codcf << " CODCONT=" << codcont << "\n"
 | 
						||
      << "TO CODCF=" << codcf << " CODCONT=" << codcont;
 | 
						||
  
 | 
						||
  TISAM_recordset rcont(str);
 | 
						||
 | 
						||
  for(bool ok = rcont.move_first(); ok; ok = rcont.move_next())
 | 
						||
  {
 | 
						||
    TRectype& riga = rcont.cursor()->curr();
 | 
						||
		int forfait = riga.get_int(LVRCONDV_TIPOFORF);
 | 
						||
		const TString & codart = riga.get(LVRCONDV_CODART);
 | 
						||
		bool to_add = forfait != 0;
 | 
						||
 | 
						||
 | 
						||
    for (int i = 1; to_add && i <= nrows ; i++)
 | 
						||
    {
 | 
						||
	    TRiga_documento& rout = doc[i];
 | 
						||
      const TCodice_articolo codart_contr = rout.get(RDOC_CODART);
 | 
						||
 | 
						||
			if (codart == codart_contr)
 | 
						||
				to_add = false;
 | 
						||
		}
 | 
						||
    if (to_add)
 | 
						||
    {
 | 
						||
      TRiga_documento& rdoc = doc.new_row("21");
 | 
						||
 | 
						||
      rdoc.put(RDOC_CODART, codart);
 | 
						||
      rdoc.put(RDOC_CODARTMAG, codart);
 | 
						||
			rdoc.put(RDOC_DESCR, cached_article(codart).get(ANAMAG_DESCR));
 | 
						||
      rdoc.put(RDOC_CHECKED, true);
 | 
						||
      rdoc.put(RDOC_QTA, 0);
 | 
						||
      rdoc.put(RDOC_QTAGG1, 0);
 | 
						||
      rdoc.put(RDOC_UMQTA, cached_article(codart).first_um());
 | 
						||
 | 
						||
      TToken_string key;
 | 
						||
      key.add('C');
 | 
						||
      key.add(codcf);
 | 
						||
      TString8 codiva = cache().get(LF_CFVEN, key, CFV_ASSFIS);
 | 
						||
      if (codiva.blank())
 | 
						||
        codiva = cache().get(LF_ANAMAG, riga.get(LVRCONDV_CODART), ANAMAG_CODIVA);
 | 
						||
 | 
						||
      rdoc.put(RDOC_CODIVA, codiva);
 | 
						||
      rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"));
 | 
						||
			set_perc_provv(rdoc);
 | 
						||
			set_perc_provv(rdoc, false);
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TFatturazione_lavanderie::add_doc_to_list(const TString& key, const TDocumento& doc)
 | 
						||
{
 | 
						||
	TDocumento * doc_cli = (TDocumento *) _doc_grouped.objptr(key);
 | 
						||
 | 
						||
	if (doc_cli == NULL)
 | 
						||
		_doc_grouped.add(key, doc);
 | 
						||
	else
 | 
						||
	{
 | 
						||
		const int nrows = doc.physical_rows();
 | 
						||
 | 
						||
		for (int r = 1; r <=nrows; r++)
 | 
						||
		{
 | 
						||
			const TRiga_documento & row = doc[r];
 | 
						||
			TRiga_documento & new_row = doc_cli->new_row(row.get(RDOC_TIPORIGA));
 | 
						||
 | 
						||
			doc_cli->copy_data(new_row, row);
 | 
						||
		}
 | 
						||
	}
 | 
						||
}
 | 
						||
real TFatturazione_lavanderie::get_percprovv(const TRiga_documento & row, char tipoprovv, const TString & codpr, bool first, const TRectype & age) const
 | 
						||
{
 | 
						||
  real val = ZERO;
 | 
						||
	const TDocumento & doc = row.doc();
 | 
						||
	const TRectype& anamag = cache().get(LF_ANAMAG, row.get(RDOC_CODARTMAG));
 | 
						||
  
 | 
						||
  switch (tipoprovv)
 | 
						||
  {
 | 
						||
    case 'A':
 | 
						||
      val = age.get_real(AGE_PERCPROVV);
 | 
						||
      break;
 | 
						||
    case 'M':
 | 
						||
      val = anamag.get_real(ANAMAG_PERCPROVV);
 | 
						||
      break;
 | 
						||
    case 'C':
 | 
						||
			val = doc.clifor().vendite().get_real(first ? CFV_PERCPROVV : CFV_PERCPROVV1);
 | 
						||
      break;                                              
 | 
						||
    case 'V':
 | 
						||
      {
 | 
						||
        const TString16 catven = doc.get(DOC_CATVEN);
 | 
						||
        if (catven.not_empty())
 | 
						||
          val = real(cache().get("CVE", catven, "R0"));
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case 'O':
 | 
						||
//      val = _rcondv.get_real("PERCPROVV");
 | 
						||
      break;
 | 
						||
    case '1':                    
 | 
						||
    case '2':                    
 | 
						||
    case '3':                    
 | 
						||
    case '4':                    
 | 
						||
      {
 | 
						||
        const TString16 ord = cache().get("APR", codpr, "S3");
 | 
						||
        
 | 
						||
        int len = ord.len();
 | 
						||
        TString key;
 | 
						||
        TString80 campo;
 | 
						||
        
 | 
						||
        for (int i = 0; i < len; i++)
 | 
						||
        {  
 | 
						||
          switch (ord[i])
 | 
						||
          {
 | 
						||
            case 'C':
 | 
						||
              campo = doc.clifor().get(CLI_CODCF);
 | 
						||
              campo.lpad(doc.clifor().length(CLI_CODCF));
 | 
						||
            break;
 | 
						||
            case 'V':
 | 
						||
              campo = doc.get(DOC_CATVEN);
 | 
						||
              campo.rpad(doc.length(DOC_CATVEN));
 | 
						||
            break;
 | 
						||
            case 'A':
 | 
						||
              campo = doc.get(DOC_CODAG);
 | 
						||
              campo.rpad(doc.length(DOC_CODAG));
 | 
						||
            break;
 | 
						||
            case 'P':
 | 
						||
              campo = doc.get(DOC_CODPAG);
 | 
						||
              campo.rpad(doc.length(DOC_CODPAG));
 | 
						||
            break;
 | 
						||
            case 'S':
 | 
						||
              campo = doc.clifor().vendite().get(CFV_CODSCC);
 | 
						||
              campo.rpad(doc.clifor().length(CFV_CODSCC));
 | 
						||
            break;
 | 
						||
            case 'Z':
 | 
						||
              campo = doc.get(DOC_ZONA);
 | 
						||
              campo.rpad(doc.length(DOC_ZONA)); 
 | 
						||
              break;
 | 
						||
            case 'M':
 | 
						||
              campo = row.get(RDOC_CODARTMAG);
 | 
						||
              campo.rpad(row.length(RDOC_CODARTMAG));
 | 
						||
            break;
 | 
						||
            case 'E':
 | 
						||
              campo = anamag.get(ANAMAG_GRMERC);
 | 
						||
              campo.rpad(anamag.length(ANAMAG_GRMERC)); 
 | 
						||
              campo.cut(3);
 | 
						||
            break;
 | 
						||
            case 'R':
 | 
						||
              campo = anamag.get(ANAMAG_GRMERC);
 | 
						||
              campo.rpad(anamag.length(ANAMAG_GRMERC)); 
 | 
						||
            break;
 | 
						||
            case 'F':
 | 
						||
              campo = anamag.get(ANAMAG_RAGGFIS);
 | 
						||
              campo.rpad(anamag.length(ANAMAG_RAGGFIS)); 
 | 
						||
            break;
 | 
						||
            default:
 | 
						||
              campo.cut(0);
 | 
						||
            break;
 | 
						||
 | 
						||
          }
 | 
						||
          key << campo;
 | 
						||
        }
 | 
						||
        
 | 
						||
        TLocalisamfile perc(LF_PERCPROV);
 | 
						||
                               
 | 
						||
        perc.put(PER_CODPR, codpr);                       
 | 
						||
        perc.put(PER_KEYORD, key);                   
 | 
						||
        if (perc.read() == NOERR)
 | 
						||
          val= perc.get_real(PER_PERCPROVV);           
 | 
						||
        
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    default:
 | 
						||
      break;
 | 
						||
  }
 | 
						||
  return val;
 | 
						||
}
 | 
						||
 | 
						||
void TFatturazione_lavanderie::set_perc_provv(TRiga_documento & row, bool prima)
 | 
						||
{
 | 
						||
	const TString & codage = row.doc().get(prima ? DOC_CODAG : DOC_CODAGVIS);                 
 | 
						||
    
 | 
						||
  if (codage.full())
 | 
						||
  {                                                             
 | 
						||
    const TRectype & age = cache().get(LF_AGENTI, codage);
 | 
						||
                  
 | 
						||
    if (!age.empty())
 | 
						||
    {                           
 | 
						||
      TString16 seqric(age.get(AGE_SEQRIC));
 | 
						||
      real percprovv;
 | 
						||
      
 | 
						||
      if (seqric[0] == '-')
 | 
						||
        seqric = ini_get_string(CONFIG_DITTA, "ve", "AGETIPOPERC");
 | 
						||
      
 | 
						||
      int len = seqric.len();
 | 
						||
      int i;
 | 
						||
        
 | 
						||
      for (i = 0; percprovv.is_zero() && seqric[i] != '\0' && seqric[i] != '-'; i++)
 | 
						||
			{
 | 
						||
        TString16 codric;
 | 
						||
        if (isdigit(seqric[i]))
 | 
						||
					codric = age.get(format("CODRICPR%d", i+1));
 | 
						||
				percprovv = get_percprovv(row, seqric[i], codric, prima, age);
 | 
						||
			}
 | 
						||
      real percalt;
 | 
						||
      seqric = age.get(AGE_SEQALT);
 | 
						||
      for (i = 0; percalt.is_zero() && seqric[i] != '\0' && seqric[i] != '-'; i++)
 | 
						||
			{
 | 
						||
        TString16 codric;
 | 
						||
        if (isdigit(seqric[i]))
 | 
						||
          codric = age.get(format("CODALTPR%d", i+1));
 | 
						||
        percalt = get_percprovv(row, seqric[i], codric, prima, age);
 | 
						||
			}
 | 
						||
      percprovv += percalt;
 | 
						||
			row.put(prima ? RDOC_PERCPROV : RDOC_PERCPROV1, percprovv);
 | 
						||
    }                     
 | 
						||
  }
 | 
						||
}       
 | 
						||
 | 
						||
int TFatturazione_lavanderie::write_fatt_ragg(const bool solotot)
 | 
						||
{
 | 
						||
	int items = _doc_grouped.items();
 | 
						||
	TString_array kl;
 | 
						||
	
 | 
						||
  _doc_grouped.get_keys(kl);
 | 
						||
	kl.sort();
 | 
						||
	FOR_EACH_ARRAY_ROW(kl, r, key)
 | 
						||
	{
 | 
						||
		TDocumento* d = (TDocumento*)_doc_grouped.objptr(*key);
 | 
						||
		if (d != NULL && !solotot)
 | 
						||
			d->write();
 | 
						||
	}
 | 
						||
	_doc_grouped.destroy();
 | 
						||
	return items;
 | 
						||
}
 | 
						||
 | 
						||
//POST_PROCESS: metodo che elabora i documenti di output dopo che si sono svolte
 | 
						||
//le operazioni di base sugli stessi, in modo da raggruppare le righe raggruppabili
 | 
						||
//e/o eliminare quelle inutili e/o aggiungere quelle per il ciclaggio su 2 linee
 | 
						||
void TFatturazione_lavanderie::post_process(TLista_documenti& doc_out, TLista_documenti& doc_in)
 | 
						||
{
 | 
						||
	const bool use_indsp = ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED");
 | 
						||
  const bool riftest   = ini_get_bool(CONFIG_DITTA, "lv", "RifTest");
 | 
						||
  const bool zero_note = ini_get_bool(CONFIG_DITTA, "lv", "ZeroNote");
 | 
						||
	
 | 
						||
  //scorro tutti i documenti di output generati precedentemente
 | 
						||
  for (int id = 0; id < doc_out.items(); id++)
 | 
						||
  {                                             
 | 
						||
    //instanzio il documento e recupero le variabili di interesse per recuperare
 | 
						||
    //il contratto del cliente in questione
 | 
						||
    TDocumento& doc = doc_out[id];
 | 
						||
		const long clifo = doc.get_long(DOC_CODCF);
 | 
						||
 | 
						||
		const int indsped = doc.get_int(DOC_CODINDSP);
 | 
						||
		TLaundry_contract contr(clifo,indsped,_data_elab);
 | 
						||
    //flag per il calcolo sul valore convenzionale e sul fisso per dotazione iniziale
 | 
						||
    bool valconvcli = false;
 | 
						||
    bool fixdotin = false;
 | 
						||
    bool elcons = contr.get_bool(LVCONDV_ELCONS);
 | 
						||
    bool rifbol = contr.get_bool(LVCONDV_RIFBOL);
 | 
						||
 | 
						||
    const bool splitpay = doc.anno() > 2015 && doc.clifor().get_bool(CLI_SPLITPAY);
 | 
						||
		real consvconv;
 | 
						||
		real impvconv;
 | 
						||
		TAssoc_array nolo_computed;
 | 
						||
    
 | 
						||
  	doc.zero(DOC_LIQDIFF);
 | 
						||
    doc.zero(DOC_IVAXCASSA);
 | 
						||
    if (!splitpay)
 | 
						||
    {
 | 
						||
      const bool liqdiff = doc.clifor().vendite().get_bool(CFV_FATTSOSP);
 | 
						||
		  if (liqdiff)
 | 
						||
      {
 | 
						||
			  doc.put(DOC_LIQDIFF, "X");
 | 
						||
      }
 | 
						||
		  else 
 | 
						||
      {
 | 
						||
        if (doc.clifor().get(CLI_PAIV).full() && 
 | 
						||
            gestione_IVAxCassa(doc.get_date(DOC_DATADOC)))
 | 
						||
        {
 | 
						||
			    doc.put(DOC_IVAXCASSA, "X");
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    if (doc.physical_rows() > 0 && doc[1].is_descrizione())
 | 
						||
		{
 | 
						||
			if (elcons)
 | 
						||
			{
 | 
						||
				TRiga_documento& rout = doc[1];
 | 
						||
				rout.put(RDOC_DESCR, TR("COME DA ELENCO CONSEGNE"));
 | 
						||
				rout.put(RDOC_DESCLUNGA, false);
 | 
						||
				rout.put(RDOC_DESCEST, "");
 | 
						||
			}
 | 
						||
			else
 | 
						||
				if (!rifbol)
 | 
						||
					doc.destroy_row(1, true);
 | 
						||
		}
 | 
						||
 | 
						||
    if (zero_note)
 | 
						||
      doc.zero(DOC_NOTE);
 | 
						||
 | 
						||
    //se devo mettere i riferimenti della bolla in testata, prendo la descrizione della prima riga
 | 
						||
    //e la metto sulla testata del documento, poi cancello la prima riga del documento
 | 
						||
    if (rifbol && riftest)
 | 
						||
    {
 | 
						||
      TRiga_documento& rout = doc[1];
 | 
						||
      TString descr = rout.get(RDOC_DESCR);
 | 
						||
      descr << ' ' << rout.get(RDOC_DESCEST);
 | 
						||
      descr.ltrim(21);
 | 
						||
      //sostituisco la stringa " -  n. " e la sostituisco con la stringa " - " su tutta la stringa descrizione
 | 
						||
      int pos = descr.find(" -  n. ");
 | 
						||
      while (pos > 0)
 | 
						||
      {
 | 
						||
        descr.overwrite(" - ", pos, 7);
 | 
						||
        pos = descr.find(" -  n. ", pos + 1);        
 | 
						||
      }
 | 
						||
      descr.strip_double_spaces();
 | 
						||
 | 
						||
			const TString original_notes = doc.get(DOC_NOTE);
 | 
						||
 | 
						||
			if (original_notes.full())
 | 
						||
				descr << '\n' << original_notes;
 | 
						||
      doc.put(DOC_NOTE, descr);
 | 
						||
      doc.destroy_row(1, true);
 | 
						||
    }
 | 
						||
		aggiorna_fattura(doc, contr.get_int(LVCONDV_CODCONT));
 | 
						||
    if (doc.physical_rows() > 0)
 | 
						||
			doc.sort_rows(RDOC_CODART "|LVTYPE");
 | 
						||
 | 
						||
    const bool ragart = contr.get_bool(LVCONDV_RAGART); // leggo il flag di testata raggruppa su unico articolo
 | 
						||
    const int tipocan = contr.get_int(LVCONDV_TIPOCAN); // leggo il tipo canone
 | 
						||
		const real redditivita = contr.get_real(LVCONDV_REDDI);
 | 
						||
    if (ragart)
 | 
						||
    {
 | 
						||
      real totmerc;
 | 
						||
      const int rows = doc.physical_rows();
 | 
						||
      
 | 
						||
      for (int i=1; i <= rows; i++)  //calcolo totale merce
 | 
						||
      {
 | 
						||
        const TRiga_documento& riga = doc[i];
 | 
						||
        if (riga.is_merce())
 | 
						||
          totmerc += riga.importo(true,false);
 | 
						||
      }
 | 
						||
 | 
						||
      const int rigamerce = doc[1].is_descrizione() ? 2 : 1;
 | 
						||
 | 
						||
      for (int i=rigamerce; i <= rows; i++) 
 | 
						||
        doc.destroy_row(i);
 | 
						||
        
 | 
						||
      TRiga_documento& riga = doc.new_row("01");
 | 
						||
 | 
						||
      const TCodice_articolo codartcfg = ini_get_string(CONFIG_DITTA, "lv", "Codartcafix");
 | 
						||
      const TString80 descart = cache().get(LF_ANAMAG, codartcfg, ANAMAG_DESCR);
 | 
						||
			const TString descragg =  cache().get(LF_ANAMAG, codartcfg, ANAMAG_DESCRAGG);
 | 
						||
 | 
						||
      // istanzio una token string e poi una cache per estrarre l'unit<69> di misura dell articolo in configurazione da UMART
 | 
						||
      TToken_string key;
 | 
						||
      key.add(codartcfg);
 | 
						||
      key.add(1);
 | 
						||
      const TRectype& umart = cache().get(LF_UMART,key);
 | 
						||
      const TString4 umcodart = umart.get(UMART_UM);
 | 
						||
 | 
						||
      /* estraggo il codice IVA istanziando in primis una cache su CFVEN per analizzare il codice esenzione iva 
 | 
						||
         del cliente in questione. Se <20> >0 imposto il codiva a tale valore, altrimenti se <20> uguale a 0 istanzio
 | 
						||
         un altra cache su ANAMAG e imposto il codiva uguale al codice iva dell articolo in questione */
 | 
						||
      key = doc.get(DOC_TIPOCF);
 | 
						||
      key.add(clifo);
 | 
						||
      const TRectype& cfven = cache().get(LF_CFVEN,key);
 | 
						||
      TString8 codiva = cfven.get(CFV_ASSFIS);
 | 
						||
 | 
						||
      if (codiva.blank())
 | 
						||
      {
 | 
						||
        const TRectype& anamag = cache().get(LF_ANAMAG,codartcfg);
 | 
						||
        codiva = anamag.get(ANAMAG_CODIVA);
 | 
						||
      }
 | 
						||
 | 
						||
      riga.put(RDOC_QTA,UNO);
 | 
						||
      riga.put(RDOC_UMQTA,umcodart);
 | 
						||
      riga.put(RDOC_PREZZO,totmerc);
 | 
						||
      riga.put(RDOC_CODART,codartcfg);
 | 
						||
      riga.put(RDOC_DESCR,descart);
 | 
						||
			if (descragg.full())
 | 
						||
			{
 | 
						||
        riga.put(RDOC_DESCLUNGA, "X");
 | 
						||
        riga.put(RDOC_DESCEST, descragg);
 | 
						||
			}
 | 
						||
      riga.put(RDOC_CODIVA,codiva);
 | 
						||
			set_perc_provv(riga);
 | 
						||
			set_perc_provv(riga, false);
 | 
						||
 | 
						||
      break;
 | 
						||
    }
 | 
						||
    else // se non <20> selezionato raggrupa su unico articolo controllo il tipo canone se <20> impostato a importo fisso
 | 
						||
      if (tipocan == 1) //se <20> selezionato tipo canone = importo fisso
 | 
						||
	    {
 | 
						||
        // estraggo il canone fisso e l'articolo in configurazione
 | 
						||
        const real canfis=contr.get_real(LVCONDV_IMPFIX);
 | 
						||
        const TCodice_articolo codartcfg = ini_get_string(CONFIG_DITTA, "lv", "Codartfix");
 | 
						||
        const TString80 descart = cached_article(codartcfg).get(ANAMAG_DESCR);
 | 
						||
				const TString descragg = cached_article(codartcfg).get(ANAMAG_DESCRAGG);
 | 
						||
 | 
						||
        // istanzio una token string e poi una cache per estrarre l'unit<69> di misura dell articolo in configurazione da UMART
 | 
						||
        TToken_string key;
 | 
						||
        key.add(codartcfg);
 | 
						||
        key.add(1);
 | 
						||
        const TRectype& umart = cache().get(LF_UMART,key);
 | 
						||
        const TString4 umcodart = umart.get(UMART_UM);
 | 
						||
 | 
						||
        /* estraggo il codice IVA istanziando in primis una cache su CFVEN per analizzare il codice esenzione iva 
 | 
						||
           del cliente in questione. Se <20> >0 imposto il codiva a tale valore, altrimenti se <20> uguale a 0 istanzio
 | 
						||
           un altra cache su ANAMAG e imposto il codiva uguale al codice iva dell articolo in questione */
 | 
						||
        key = doc.get(DOC_TIPOCF);
 | 
						||
        key.add(clifo);
 | 
						||
        const TRectype& cfven = cache().get(LF_CFVEN,key);
 | 
						||
        TString8 codiva = cfven.get(CFV_ASSFIS);
 | 
						||
 | 
						||
        if (codiva.blank())
 | 
						||
        {
 | 
						||
          const TRectype& anamag = cache().get(LF_ANAMAG,codartcfg);
 | 
						||
          codiva = anamag.get(ANAMAG_CODIVA);
 | 
						||
        }
 | 
						||
 | 
						||
        const int rigamerce = doc.physical_rows() > 0 && doc[1].is_descrizione()?2:1;
 | 
						||
        TRiga_documento& fixrow=doc.insert_row(rigamerce, "01"); // creo una nuova riga in cima al documento e imposto i valori appena estratti
 | 
						||
       
 | 
						||
        fixrow.put(RDOC_QTA,UNO);
 | 
						||
        fixrow.put(RDOC_UMQTA,umcodart);
 | 
						||
        fixrow.put(RDOC_PREZZO,canfis);
 | 
						||
        fixrow.put(RDOC_CODART,codartcfg);
 | 
						||
        fixrow.put(RDOC_DESCR,descart);
 | 
						||
				if (descragg.full())
 | 
						||
				{
 | 
						||
	        fixrow.put(RDOC_DESCLUNGA, "X");
 | 
						||
	        fixrow.put(RDOC_DESCEST, descragg);
 | 
						||
				}
 | 
						||
        fixrow.put(RDOC_CODIVA,codiva);
 | 
						||
 | 
						||
        int tipocanfix = contr.get_int(LVCONDV_CANFIX);
 | 
						||
 | 
						||
        const int rows = doc.physical_rows();
 | 
						||
 | 
						||
        switch (tipocanfix)
 | 
						||
        {
 | 
						||
        case 0:
 | 
						||
          for (int k = rigamerce+1; k <= rows; k++)
 | 
						||
            doc.destroy_row(k);
 | 
						||
          break;
 | 
						||
        case 1:
 | 
						||
          for (int k = rigamerce+1; k <= rows; k++)
 | 
						||
          {
 | 
						||
            TRiga_documento& rout = doc[k]; 
 | 
						||
            rout.zero(RDOC_PREZZO);
 | 
						||
          }
 | 
						||
          break;
 | 
						||
        case 2:
 | 
						||
          for (int k = rigamerce+1; k <= rows; k++)
 | 
						||
          {
 | 
						||
            TRiga_documento& rout = doc[k]; 
 | 
						||
            rout.zero(RDOC_PREZZO);
 | 
						||
            rout.zero(RDOC_QTA);
 | 
						||
          }
 | 
						||
          break;
 | 
						||
        default: break;
 | 
						||
        }
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      else // se il tipo canone <20> impostato a nessuno o % sul valore convenzionale per cliente vado in ambedue i casi ad eseguire il ciclo che analizza i tipi forfait
 | 
						||
      {
 | 
						||
        //per ogni documento, scorro tutte le sue righe
 | 
						||
		    for (int i = 1; i <= doc.physical_rows() ; i++)
 | 
						||
		    {
 | 
						||
			    TRiga_documento& rout = doc[i];
 | 
						||
       
 | 
						||
			    const TCodice_articolo codart = rout.get(RDOC_CODART);
 | 
						||
          //leggo dalla riga del contratto di questo articolo il tipo dotazione e
 | 
						||
          //la scelta per la % sul val.conv su articolo <A> o cliente <C>
 | 
						||
			    const TRectype& rcont = contr.row(codart);
 | 
						||
			    const TString4 tipodot = rcont.get(LVRCONDV_NOLCIC);
 | 
						||
			    const TString4 artcli = rcont.get(LVRCONDV_VCARTCLI);
 | 
						||
			    const int annoes = _data_elab.year();
 | 
						||
 			    real dot;
 | 
						||
 | 
						||
          //instanzio il TArticolo_lavanderia
 | 
						||
          //cerco la giacenza per articolo dell'articolo esaminato
 | 
						||
				  TArticolo_lavanderie& artlav = cached_article_laundry(codart, 'C', clifo, use_indsp ? indsped : 0);
 | 
						||
				  //estraggo il record corrispondente su LF_CLIFOGIAC	
 | 
						||
					const TRecmag_lavanderie& reclav = artlav.find_rec(annoes);
 | 
						||
          //se il tipo dotazione <20> iniziale 'I', allora leggo la dotazione iniziale
 | 
						||
          //dalle giacenze articolo per cliente, altrimenti leggo la dotazione odierna
 | 
						||
			    if (tipodot == "I")
 | 
						||
				    dot = reclav.get_real("DOTIN");
 | 
						||
			    else
 | 
						||
				    dot = reclav.get_real("DOTOD");
 | 
						||
    	    
 | 
						||
          //leggo dalla riga contratto il tipo forfait
 | 
						||
			    const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
 | 
						||
 | 
						||
          switch (tipoforf)
 | 
						||
			    {
 | 
						||
				  case 0:  //forfait = NESSUNO
 | 
						||
            {
 | 
						||
              //gestione fatturazione a kg
 | 
						||
              const bool fatkg = rcont.get_bool(LVRCONDV_FATTKG);
 | 
						||
              //se devo fatturare a kg
 | 
						||
              if(fatkg)
 | 
						||
              {
 | 
						||
                const TString4 umkg = ini_get_string(CONFIG_DITTA, "lv", "UmKg");
 | 
						||
                const TString4 umri = rout.get(RDOC_UMQTA);
 | 
						||
 | 
						||
                //se la riga <20> gi<67> espressa in kg non devo fare niente, altrimenti:
 | 
						||
                if(umri != umkg)
 | 
						||
                {
 | 
						||
                  //leggo e controllo l'unit<69> di misura del peso
 | 
						||
                  const TString4 ump = artlav.get(ANAMAG_UMP);
 | 
						||
                  if(ump.empty())
 | 
						||
                  {
 | 
						||
                    warning_box(TR("Manca l'unit<69> di misura del peso"));
 | 
						||
                    break;
 | 
						||
                  }
 | 
						||
 | 
						||
                  //leggo e controllo il peso dell'articolo
 | 
						||
                  const real peso = artlav.get_real(ANAMAG_PESO);
 | 
						||
                  if(peso == ZERO)
 | 
						||
                  {
 | 
						||
                    warning_box(TR("Manca il peso"));
 | 
						||
                    break;
 | 
						||
                  }
 | 
						||
 | 
						||
                  //leggo l'unit<69> di misura dell'articolo e la quantit<69> convertita all'unit<69> di misura dell'articolo
 | 
						||
                  const TString4 umart = artlav.um()[1].get(UMART_UM);
 | 
						||
                  const real qta = artlav.convert_to_um(rout.get_real(RDOC_QTA), umart, umri, false);
 | 
						||
 | 
						||
                  //se l'articolo non <20> espresso in kg, allora:
 | 
						||
                  if(umart != umkg)
 | 
						||
                  {
 | 
						||
                    //preparo una cache sulla tabella delle unit<69> di misura
 | 
						||
                    const TRectype& unita = cache().get("%UMS", ump);
 | 
						||
										real fatconv = UNO;
 | 
						||
                    
 | 
						||
                    if (ump != umkg)
 | 
						||
										{
 | 
						||
											//leggo e controllo se esiste l'unit<69> di misura di riferimento
 | 
						||
											const TString4 umrif = unita.get("S7");
 | 
						||
											if(umrif.empty())
 | 
						||
											{
 | 
						||
												warning_box(TR("Manca l'unit<69> di misura di riferimento"));
 | 
						||
												break;
 | 
						||
											}
 | 
						||
											if (umrif != umkg)
 | 
						||
											{
 | 
						||
												warning_box(TR("L'unit<69> di misura di riferimento non <20> quella dei Kg"));
 | 
						||
												break;
 | 
						||
											}
 | 
						||
 | 
						||
											//leggo e controllo il fattore di conversione
 | 
						||
											fatconv = unita.get_real("R10");
 | 
						||
											if (fatconv.is_zero())
 | 
						||
											{
 | 
						||
												warning_box(TR("Manca il fattore di conversione"));
 | 
						||
												break;
 | 
						||
											}
 | 
						||
										}
 | 
						||
 | 
						||
                    //se tutti i controlli sono andati a buon fine, converto la quantit<69> e la scrivo sulla riga documento
 | 
						||
                    const real qtaconv = qta * fatconv * peso;
 | 
						||
                    rout.put(RDOC_UMQTA, umkg);
 | 
						||
                    rout.put(RDOC_QTA, qtaconv);
 | 
						||
                  }
 | 
						||
                }
 | 
						||
              }
 | 
						||
            }
 | 
						||
            break;
 | 
						||
          case 1:  //forfait = A VALORE FISSO
 | 
						||
					  {
 | 
						||
					    rout.put(RDOC_QTA, UNO);  //qta fissa a UNO
 | 
						||
					    rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_IMPFISART));  //prezzo letto dalla riga contratto
 | 
						||
					    // gestione in base codice per valore fisso ??? tolta la scelta dell'articolo o del cliente
 | 
						||
				    }
 | 
						||
				    break;
 | 
						||
				  case 2:  //forfait = NOLO
 | 
						||
				    {
 | 
						||
			        //aggiungo una riga tipo merce, che contiene tutti i dati della riga del documento
 | 
						||
              //di partenza, poi costruisco la descrizione in base alla periodicit<69> di fatturazione,
 | 
						||
              //metto la qta uguale alla dotazione che ho appena letto
 | 
						||
              //e prendo il prezzo nolo dalla riga contratto
 | 
						||
							if (dot != ZERO && nolo_computed.objptr(codart) == NULL)
 | 
						||
							{
 | 
						||
								TRiga_documento& nolorow = doc.insert_row(++i, "01");
 | 
						||
								nolo_computed.add(codart, codart);
 | 
						||
								doc.copy_data(nolorow, rout);
 | 
						||
								const TString descrart = rout.get(RDOC_DESCR);
 | 
						||
 | 
						||
								TString80 descr("Nolo");
 | 
						||
								const int contrper = contr.get_int(LVCONDV_PERFAT);
 | 
						||
 | 
						||
								switch (contrper)
 | 
						||
								{
 | 
						||
								case 0:  descr << " per il giorno ";      break;
 | 
						||
								case 1:  descr << " per la settimana ";   break;
 | 
						||
								case 2:  descr << " per la quindicina ";  break;
 | 
						||
								case 3:  descr << " per il mese ";        break;
 | 
						||
								default: break;
 | 
						||
								}
 | 
						||
								descr << descrart;
 | 
						||
 | 
						||
						    int split_pos = descr.find('\n');                                  
 | 
						||
								const int descr_len = nolorow.length(RDOC_DESCR);
 | 
						||
								if (split_pos < 0 && descr.len() > descr_len)
 | 
						||
									split_pos = descr_len;
 | 
						||
								if (split_pos > descr_len)
 | 
						||
									split_pos = descr_len;
 | 
						||
						    if (split_pos > 0)
 | 
						||
								{
 | 
						||
									nolorow.put(RDOC_DESCR, descr.left(split_pos));
 | 
						||
									const TString& dest = descr.mid(split_pos);
 | 
						||
									nolorow.put(RDOC_DESCLUNGA, "X");  
 | 
						||
									nolorow.put(RDOC_DESCEST, dest);
 | 
						||
								}
 | 
						||
								else
 | 
						||
								{
 | 
						||
									nolorow.put(RDOC_DESCR, descr);
 | 
						||
									nolorow.zero(RDOC_DESCLUNGA);
 | 
						||
									nolorow.zero(RDOC_DESCEST);
 | 
						||
								}
 | 
						||
 | 
						||
								nolorow.put(RDOC_QTA, dot); 
 | 
						||
								nolorow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZNOL));
 | 
						||
							}
 | 
						||
				    }
 | 
						||
				    break;
 | 
						||
				  case 3:  //forfait = CICLAGGIO
 | 
						||
				    {
 | 
						||
              //leggo la quantit<69> consegnata e calcolo consumo e ciclaggio secondo le formule
 | 
						||
              //CONSUMO   = QTA * PREZZO(dalla riga documento)
 | 
						||
              //CLICLAGGIO = DOT * PREZZO(dalla riga contratto) * MINIMO CICLAGGIO
 | 
						||
              const real qta = rout.get_real(RDOC_QTA);
 | 
						||
              const real consumo = qta * rout.get_real(RDOC_PREZZO);
 | 
						||
              const real ciclaggio = dot * rcont.get_real(LVRCONDV_PREZZO) * rcont.get_real(LVRCONDV_MINCIC);              
 | 
						||
					    //se il consumo <20> minore del ciclaggio, allora
 | 
						||
              if (consumo < ciclaggio)
 | 
						||
              {
 | 
						||
                //leggo il flag del tipo ciclaggio
 | 
						||
                const bool cicl2rig = contr.get_bool(LVCONDV_CICLAGGIO);
 | 
						||
                //calcolo il valore cicl secondo la formula  CICL = MINIMO CICLAGGIO * DOT
 | 
						||
                const real cicl = rcont.get_real(LVRCONDV_MINCIC) * dot;
 | 
						||
                //se il ciclaggio <20> su due linee, allora aggiungo una riga merce, per pareggiare il minimo ciclaggio
 | 
						||
                //che ha come quantit<69> la differenza tra la quantit<69> di minimo cilcaggio
 | 
						||
                //e la quantit<69> effettivamente consegnata e come prezzo il prezzo preso dalla riga contratto;
 | 
						||
                //altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
 | 
						||
                if (cicl2rig)
 | 
						||
                {
 | 
						||
                  TRiga_documento& congrow = doc.insert_row(++i, "01");
 | 
						||
                  doc.copy_data(congrow,rout);
 | 
						||
                  congrow.put(RDOC_DESCR,"Pareggio minimo ciclaggio");
 | 
						||
							    congrow.put(RDOC_QTA, cicl - qta); 
 | 
						||
                  congrow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO));
 | 
						||
                }
 | 
						||
                else
 | 
						||
                {
 | 
						||
					        rout.put(RDOC_QTA, cicl); 
 | 
						||
                  rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO));
 | 
						||
                }
 | 
						||
              }
 | 
						||
					  }
 | 
						||
					  break;
 | 
						||
				  case 4: //forfait = % SUL VALORE CONVENZIONALE
 | 
						||
				    {
 | 
						||
              //leggo dalla riga contratto la % sul val.conv su articolo <A> o cliente <C>
 | 
						||
              const char tipovalconv = rcont.get_char(LVRCONDV_VCARTCLI);
 | 
						||
              //se la percentuale sul valore convenzionale <20> sull'articolo, allora:
 | 
						||
              if (tipovalconv == 'A')
 | 
						||
              {
 | 
						||
                //leggo la quantit<69> consegnata e calcolo consumo e importo convenzionale secondo le formule
 | 
						||
                //CONSUMO = QTA * PREZZO(dalla riga documento)
 | 
						||
                //IMPCONV = DOT * PREZZO(dalla riga contratto) * PERCENTUALE DI FORFAIT CLIENTE
 | 
						||
                const real qta = rout.get_real(RDOC_QTA);
 | 
						||
                const real consumo = qta * rout.get_real(RDOC_PREZZO);
 | 
						||
                const real impconv = dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL) / CENTO;
 | 
						||
 | 
						||
								impvconv  += impconv;
 | 
						||
								consvconv += consumo;
 | 
						||
              }
 | 
						||
              else
 | 
						||
              {
 | 
						||
                //se la percentuale sul valore convenzionale <20> sul cliente, allora se il flag valconvcli <20> false
 | 
						||
                if (!valconvcli)
 | 
						||
                {
 | 
						||
                  //pongo valconvcli a true in modo da non tornare pi<70> in questo if
 | 
						||
                  valconvcli = true;
 | 
						||
                  //instanzio i due real che andranno a contenere l'importo covenzionale totale e il consumo totale
 | 
						||
                  real impconvtot;
 | 
						||
                  real consumotot;
 | 
						||
									TAssoc_array arts;
 | 
						||
 | 
						||
 | 
						||
                  //scorro tutte le righe documento dalla riga in esame fino alla fine
 | 
						||
                  for (int j = i; j < doc.physical_rows(); j++)
 | 
						||
                  {
 | 
						||
                    //instanzio la riga documento e sommo ai totali gli importi solo se
 | 
						||
                    //la percentuale sul valore convenzionale <20> sul cliente
 | 
						||
                    TRiga_documento& riga = doc[j];
 | 
						||
                    const TCodice_articolo codart = riga.get(RDOC_CODART);
 | 
						||
                    const TRectype & rcont = contr.row(codart);
 | 
						||
                    const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
 | 
						||
										const char lavtype = riga.get_char("LVTYPE");
 | 
						||
                    if (tipvalconvcli == 'C' && lavtype != 'D')
 | 
						||
                    {
 | 
						||
											if (arts.objptr(codart) == NULL)
 | 
						||
											{
 | 
						||
	           						const TString4 tipodot = rcont.get(LVRCONDV_NOLCIC);
 | 
						||
												TArticolo_lavanderie& art = cached_article_laundry(codart, 'C', clifo, use_indsp ? indsped : 0);
 | 
						||
												//estraggo il record corrispondente su LF_CLIFOGIAC	
 | 
						||
												const TRecmag_lavanderie& rec = art.find_rec(annoes);
 | 
						||
												//se il tipo dotazione <20> iniziale 'I', allora leggo la dotazione iniziale
 | 
						||
												//dalle giacenze articolo per cliente, altrimenti leggo la dotazione odierna
 | 
						||
												if (tipodot == "I")
 | 
						||
													dot = rec.get_real("DOTIN");
 | 
						||
												else
 | 
						||
													dot = rec.get_real("DOTOD");
 | 
						||
												const real impconv = dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL) / CENTO;
 | 
						||
												impconvtot += impconv;
 | 
						||
												arts.add(codart, codart);
 | 
						||
											}
 | 
						||
                      consumotot += riga.get_real(RDOC_QTA) * riga.get_real(RDOC_PREZZO);
 | 
						||
                    }
 | 
						||
                  }
 | 
						||
                  //se il consumo <20> minore dell'importo convenzionale, allora
 | 
						||
                  if (consumotot < impconvtot)
 | 
						||
                  {
 | 
						||
                    const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO);
 | 
						||
							      const TCodice_articolo codartcon = ini_get_string(CONFIG_DITTA, "lv", "Codartcofix");
 | 
						||
  
 | 
						||
										//se il ciclaggio <20> su due linee, allora aggiungo una riga merce, che contiene
 | 
						||
                    //il conguaglio al valore convenzionale, che ha come quantit<69> la costante UNO
 | 
						||
                    //e come prezzo la differenza tra l'importo convenzionale totale e il consumo totale;
 | 
						||
                    //altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
 | 
						||
                    //e elimino tutte le righe che vanno a comporre il totale in modo che rimanga una riga sola
 | 
						||
                    //per mostrare l'importo del conguaglio al valore convenzionale
 | 
						||
                    if (cicl2rig)
 | 
						||
                    {
 | 
						||
											i++;
 | 
						||
                      TRiga_documento& congrow=doc.new_row("01");
 | 
						||
                      doc.copy_data(congrow, rout);
 | 
						||
											congrow.put(RDOC_CODART, codartcon);
 | 
						||
											congrow.put(RDOC_CHECKED, "X");
 | 
						||
											congrow.put(RDOC_CODARTMAG, codartcon);
 | 
						||
                      congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
 | 
						||
                      congrow.put(RDOC_QTA, UNO);
 | 
						||
							        congrow.put(RDOC_PREZZO, impconvtot - consumotot);
 | 
						||
											set_perc_provv(congrow);
 | 
						||
											set_perc_provv(congrow, false);
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
											rout.put(RDOC_CODART, codartcon);
 | 
						||
											rout.put(RDOC_CHECKED, "X");
 | 
						||
											rout.put(RDOC_CODARTMAG, codartcon);
 | 
						||
                      rout.put(RDOC_DESCR, "Valore convenzionale");
 | 
						||
                      rout.put(RDOC_QTA, UNO); 
 | 
						||
                      rout.put(RDOC_PREZZO, impconvtot);
 | 
						||
									
 | 
						||
                      for (int k = doc.physical_rows(); k > i; k--)
 | 
						||
                      {
 | 
						||
                        TRiga_documento& delrow = doc[k];
 | 
						||
                        const TCodice_articolo codart = delrow.get(RDOC_CODART);
 | 
						||
                        const TRectype& rcont = contr.row(codart);
 | 
						||
                        const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
 | 
						||
												char lavtype = delrow.get_char("LVTYPE");
 | 
						||
                        if (tipvalconvcli == 'C' && lavtype != 'D')
 | 
						||
                          doc.destroy_row(k, true);
 | 
						||
                      }
 | 
						||
                    }
 | 
						||
                  }
 | 
						||
                }
 | 
						||
              }
 | 
						||
				    }
 | 
						||
				    break;
 | 
						||
			    case 5:  //forfait = FISSO SU DOTAZIONE INIZIALE 
 | 
						||
				    {
 | 
						||
              rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_IMPFISART));
 | 
						||
							const real dotin = reclav.get_real("DOTIN");
 | 
						||
 | 
						||
					    rout.put(RDOC_QTA, dotin);
 | 
						||
               
 | 
						||
							if (rout.get(RDOC_DESCR).blank())
 | 
						||
							{
 | 
						||
								const TString & descr = cached_article(codart).get(RDOC_DESCR);
 | 
						||
								const TString descragg =  cached_article(codart).get(ANAMAG_DESCRAGG);
 | 
						||
 | 
						||
								rout.put(RDOC_DESCR, descr);
 | 
						||
								if (descragg.full())
 | 
						||
								{
 | 
						||
									rout.put(RDOC_DESCLUNGA, "X");
 | 
						||
									rout.put(RDOC_DESCEST, descragg);
 | 
						||
								}
 | 
						||
							}
 | 
						||
 | 
						||
							const TCodice_articolo codartorig=rout.get(RDOC_CODART);
 | 
						||
              for (int h = doc.physical_rows(); h > i; h--)
 | 
						||
              {
 | 
						||
                TRiga_documento& delrow = doc[h];
 | 
						||
                const TCodice_articolo codart=delrow.get(RDOC_CODART);  
 | 
						||
                if ( codartorig == codart)
 | 
						||
                  doc.destroy_row(h, true);
 | 
						||
              } 
 | 
						||
            }
 | 
						||
				    break;
 | 
						||
				  default:  break;
 | 
						||
			    }
 | 
						||
				}
 | 
						||
 | 
						||
        if (tipocan == 3)
 | 
						||
        {
 | 
						||
          const real canfis = contr.get_real(LVCONDV_IMPFIX);
 | 
						||
          const real imponibile = doc.imponibile();
 | 
						||
          if (canfis > imponibile)
 | 
						||
          {
 | 
						||
            TRiga_documento& congrow = doc.new_row("01");
 | 
						||
		        const TCodice_articolo codartcon = ini_get_string(CONFIG_DITTA, "lv", "Codartcofix");
 | 
						||
 | 
						||
					  congrow.put(RDOC_CODART, codartcon);
 | 
						||
					  congrow.put(RDOC_CHECKED, "X");
 | 
						||
					  congrow.put(RDOC_CODARTMAG, codartcon);
 | 
						||
            congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
 | 
						||
            congrow.put(RDOC_QTA, UNO);
 | 
						||
 | 
						||
					  TString4 codiva = doc.clifor().vendite().get(CFV_ASSFIS);
 | 
						||
					  if (codiva.blank())
 | 
						||
	            codiva = cache().get(LF_ANAMAG, codartcon, ANAMAG_CODIVA);
 | 
						||
 | 
						||
					  congrow.put(RDOC_CODIVA, codiva);
 | 
						||
 | 
						||
		        congrow.put(RDOC_PREZZO, canfis - imponibile);
 | 
						||
          }
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          //se il consumo <20> minore del ciclaggio, allora
 | 
						||
				  if (impvconv > consvconv)
 | 
						||
          {
 | 
						||
            const bool cicl2rig = contr.get_bool(LVCONDV_CICLAGGIO);
 | 
						||
					  const int rows = doc.physical_rows();
 | 
						||
 | 
						||
					  //se il ciclaggio <20> su due linee, allora aggiungo una riga merce, che contiene
 | 
						||
            //il conguaglio al valore convenzionale, che ha come quantit<69> la costante UNO
 | 
						||
            //e come prezzo la differenza tra l'importo convenzionale e il consumo;
 | 
						||
            //altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
 | 
						||
            TRiga_documento& congrow = doc.new_row("01");
 | 
						||
		        const TCodice_articolo codartcon = ini_get_string(CONFIG_DITTA, "lv", "Codartcofix");
 | 
						||
 | 
						||
					  congrow.put(RDOC_CODART, codartcon);
 | 
						||
					  congrow.put(RDOC_CHECKED, "X");
 | 
						||
					  congrow.put(RDOC_CODARTMAG, codartcon);
 | 
						||
            congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
 | 
						||
            congrow.put(RDOC_QTA, UNO);
 | 
						||
 | 
						||
					  TString8 codiva = doc.clifor().vendite().get(CFV_ASSFIS);
 | 
						||
					
 | 
						||
					  if (codiva.blank())
 | 
						||
	            codiva = cache().get(LF_ANAMAG, codartcon, ANAMAG_CODIVA);
 | 
						||
 | 
						||
					  congrow.put(RDOC_CODIVA, codiva);
 | 
						||
 | 
						||
            if (cicl2rig)
 | 
						||
		          congrow.put(RDOC_PREZZO, impvconv - consvconv);
 | 
						||
            else
 | 
						||
            {
 | 
						||
		          congrow.put(RDOC_PREZZO, impvconv);
 | 
						||
              for (int k = rows - 1; k >= 1; k--)
 | 
						||
              {
 | 
						||
                TRiga_documento& delrow = doc[k];
 | 
						||
                const TCodice_articolo codart = delrow.get(RDOC_CODART);
 | 
						||
                const TRectype& rcont = contr.row(codart);
 | 
						||
							  const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
 | 
						||
							  char lavtype = delrow.get_char("LVTYPE");
 | 
						||
                if (tipoforf == 4 && lavtype != 'D')
 | 
						||
                  doc.destroy_row(k, true);
 | 
						||
						  }
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
			
 | 
						||
      if (redditivita > ZERO && fatt_02() && !ragart && tipocan != 1)
 | 
						||
			{
 | 
						||
				const real totdoc = doc.totale_doc();
 | 
						||
				const real provvigione1 = doc.provvigione();
 | 
						||
				const real provvigione2 = doc.provvigione(false);
 | 
						||
 | 
						||
				doc.put(RDOC_TOTREALE, encode(totdoc.string()));
 | 
						||
				doc.put(RDOC_PROVV1REALE, encode(provvigione1.string()));
 | 
						||
				doc.put(RDOC_PROVV2REALE, encode(provvigione2.string()));
 | 
						||
 | 
						||
				for(int j = doc.physical_rows(); j > 0; j--)
 | 
						||
				{
 | 
						||
					TRiga_documento& rdoc = doc[j];
 | 
						||
			    const TCodice_articolo codart = rdoc.get(RDOC_CODARTMAG);
 | 
						||
			    const TRectype& rcont = contr.row(codart);
 | 
						||
			    const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
 | 
						||
					long ppconf = cached_article(codart).get_long(ANAMAG_PPCONF);
 | 
						||
					const real real_qta = rdoc.get(RDOC_QTA); 
 | 
						||
 | 
						||
					if (rcont.get_int(LVRCONDV_CALCCONS) != 1 || ppconf == 0)
 | 
						||
						ppconf = 1;
 | 
						||
 | 
						||
					const char lvtype = rdoc.get_char("LVTYPE");
 | 
						||
					bool row_has_02 = (tipoforf == 0) && (real_qta / ppconf > UNO || redditivita >= CENTO) && (lvtype == 'C');
 | 
						||
 | 
						||
          // 0 forfait = NESSUN FORFAIT SI
 | 
						||
          // 1 forfait = A VALORE FISSO NO
 | 
						||
				  // 2 forfait = NOLO NO
 | 
						||
				  // 3 forfait = CICLAGGIO NO
 | 
						||
				  // 4 forfait = % SUL VALORE CONVENZIONALE NO
 | 
						||
				  // 5 forfait = FISSO SU DOTAZIONE INIZIALE NO
 | 
						||
											
 | 
						||
					if (row_has_02)
 | 
						||
					{
 | 
						||
						const TString key = format("%04d%04d", doc.get_int("FATID"), rdoc.get_int(RDOC_IDRIGA));
 | 
						||
						real new_qta = real_qta;
 | 
						||
						TCalc_02_data * data = (TCalc_02_data *) _output_rows_02.objptr(key);
 | 
						||
 | 
						||
						rdoc.put(RDOC_QTAREALE, encode(real_qta.string()));
 | 
						||
 | 
						||
						if (data != NULL)
 | 
						||
						{
 | 
						||
							new_qta /= ppconf;
 | 
						||
 | 
						||
							real test = new_qta;
 | 
						||
 | 
						||
							test.ceil();
 | 
						||
 | 
						||
							if (test * ppconf != real_qta)
 | 
						||
							{
 | 
						||
								warning_box(FR("L'articolo %s per il cliente %ld ha una quantit<69> %s\nnon coincidente coi pacchi. Controllare le bolle"),
 | 
						||
															 (const char *)codart, doc.get_long(DOC_CODCF), real_qta.string());
 | 
						||
								ppconf = 1;
 | 
						||
							}
 | 
						||
							new_qta *= (CENTO - redditivita) / CENTO;
 | 
						||
							new_qta.round();
 | 
						||
							data->distr() = new_qta;
 | 
						||
							new_qta *= ppconf;
 | 
						||
							rdoc.put(RDOC_QTA, new_qta);
 | 
						||
 | 
						||
							real new_qta_rit = rdoc.get_real("TOTRIT");
 | 
						||
							new_qta_rit *= (CENTO - redditivita) / CENTO;
 | 
						||
							new_qta_rit.round();
 | 
						||
							data->distr_rit() = new_qta_rit;
 | 
						||
							
 | 
						||
							TAssoc_array & bol_rows = data->bol_rows();
 | 
						||
 | 
						||
							FOR_EACH_ASSOC_OBJECT(bol_rows, obj, wkey, item)              
 | 
						||
							{
 | 
						||
								TToken_string bolkey(wkey);
 | 
						||
								const long ndoc = bolkey.get_long(3);
 | 
						||
								const long id = bolkey.get_long(4);
 | 
						||
 | 
						||
								for (int i = 0; i < doc_in.items(); i++)
 | 
						||
								{                                             
 | 
						||
									TDocumento& doc = doc_in[i];
 | 
						||
									
 | 
						||
									if (doc.get_long(DOC_NDOC) == ndoc)
 | 
						||
									{
 | 
						||
										TRiga_documento * bolrow = (TRiga_documento *) doc.get_row_id(id);
 | 
						||
 | 
						||
										if (bolrow != NULL)
 | 
						||
										{
 | 
						||
										  const TString8 causale = bolrow->get(RDOC_CODAGG1);
 | 
						||
											const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
 | 
						||
											if (cau.is_rotto())
 | 
						||
												break;
 | 
						||
											bool fatturo_ritirato = cau.is_ritiro();
 | 
						||
											bool fatturo_consegnato = cau.is_consegna();
 | 
						||
 | 
						||
											if (fatturo_ritirato)
 | 
						||
											{
 | 
						||
											  const TCausale_magazzino& rit = cau.causale_ritiro();
 | 
						||
												
 | 
						||
												fatturo_ritirato = rit.sgn(s_consmese) != 0;
 | 
						||
											}
 | 
						||
											if (fatturo_consegnato)
 | 
						||
											{
 | 
						||
											  const TCausale_magazzino& con = cau.causale_consegna();
 | 
						||
												
 | 
						||
												fatturo_consegnato = con.sgn(s_consmese) != 0;
 | 
						||
											}
 | 
						||
 | 
						||
											TString str_real = bolrow->get(RDOC_QTA);
 | 
						||
											real qta =  real(str_real) / ppconf; 
 | 
						||
 | 
						||
											qta.round();
 | 
						||
											if (str_real.full())
 | 
						||
												bolrow->put(RDOC_QTAREALE, encode(str_real));
 | 
						||
											str_real = bolrow->get(RDOC_QTAGG1);
 | 
						||
 | 
						||
											real qtarit = real(str_real); 
 | 
						||
 | 
						||
											data->distr_rit().add(qtarit);
 | 
						||
											if (str_real.full())
 | 
						||
												bolrow->put(RDOC_QTARITREALE, encode(str_real));
 | 
						||
											if (fatturo_ritirato && !fatturo_consegnato) // ! fatturo il ritirato o fatturo il consegnato
 | 
						||
											{
 | 
						||
												qtarit = real(str_real) / ppconf; 
 | 
						||
												qtarit.round();
 | 
						||
												data->distr().add(qtarit);
 | 
						||
											}
 | 
						||
											else
 | 
						||
												data->distr().add(qta);
 | 
						||
										}
 | 
						||
										else
 | 
						||
											message_box("Riga_bolla smarrita %d - %s - %ld - id = %ld", bolkey.get_int(1), bolkey.get(0), bolkey.get(3), bolkey.get(4));
 | 
						||
										break;
 | 
						||
									}
 | 
						||
								}
 | 
						||
							}
 | 
						||
 | 
						||
							FOR_EACH_ASSOC_OBJECT(bol_rows, obj1, wkey1, item1)              
 | 
						||
							{
 | 
						||
								TToken_string bolkey(wkey1);
 | 
						||
								const long ndoc = bolkey.get_long(3);
 | 
						||
								const long id = bolkey.get_long(4);
 | 
						||
 | 
						||
								for (int i = 0; i < doc_in.items(); i++)
 | 
						||
								{                                             
 | 
						||
									TDocumento& docb = doc_in[i];
 | 
						||
									
 | 
						||
									if (docb.get_long(DOC_NDOC) == ndoc)
 | 
						||
									{
 | 
						||
										TRiga_documento * bolrow = (TRiga_documento *) docb.get_row_id(id);
 | 
						||
 | 
						||
										if (bolrow != NULL)
 | 
						||
										{
 | 
						||
										  const TString8 causale = bolrow->get(RDOC_CODAGG1);
 | 
						||
											const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
 | 
						||
											if (cau.is_rotto())
 | 
						||
												break;
 | 
						||
											bool fatturo_ritirato = cau.is_ritiro();
 | 
						||
											bool fatturo_consegnato = cau.is_consegna();
 | 
						||
 | 
						||
											if (fatturo_ritirato)
 | 
						||
											{
 | 
						||
											  const TCausale_magazzino& rit = cau.causale_ritiro();
 | 
						||
												
 | 
						||
												fatturo_ritirato = rit.sgn(s_consmese) != 0;
 | 
						||
											}
 | 
						||
											if (fatturo_consegnato)
 | 
						||
											{
 | 
						||
											  const TCausale_magazzino& con = cau.causale_consegna();
 | 
						||
												
 | 
						||
												fatturo_consegnato = con.sgn(s_consmese) != 0;
 | 
						||
											}
 | 
						||
 | 
						||
											const real qta = data->distr().get() * ppconf;
 | 
						||
											const real qtarit = data->distr_rit().get();
 | 
						||
 | 
						||
											bolrow->put(RDOC_QTAGG1, qtarit); 
 | 
						||
											if ((!fatturo_ritirato) || (fatturo_consegnato)) // ! fatturo il ritirato o fatturo il consegnato
 | 
						||
												bolrow->put(RDOC_QTA, qta);
 | 
						||
											else
 | 
						||
												int	c = 1; // placeholder
 | 
						||
										}
 | 
						||
										else
 | 
						||
											message_box("Riga_bolla smarrita %d - %s - %ld - id = %ld", bolkey.get_int(1), bolkey.get(0), bolkey.get(3), bolkey.get(4));
 | 
						||
										break;
 | 
						||
									}
 | 
						||
								}
 | 
						||
							}
 | 
						||
						}
 | 
						||
					}
 | 
						||
				}
 | 
						||
			}
 | 
						||
      for(int h = doc.physical_rows(); h > 0; h--)
 | 
						||
      {
 | 
						||
        TRiga_documento& rdoc = doc[h];
 | 
						||
        if (rdoc.get(RDOC_DESCR).empty() || ((rdoc.imponibile().is_zero() && rdoc.get_real(RDOC_QTA).is_zero())))
 | 
						||
          doc.destroy_row(h, true);
 | 
						||
      }
 | 
						||
  }
 | 
						||
  for (int id = doc_out.items() - 1; id >= 0 ; id--)
 | 
						||
  {                                             
 | 
						||
    TDocumento& doc = doc_out[id];
 | 
						||
		const int rows = doc.physical_rows();
 | 
						||
		bool to_delete = true;
 | 
						||
 | 
						||
		for (int i = rows; to_delete && i > 0; i--)
 | 
						||
		{
 | 
						||
	    const TRiga_documento& riga = doc[i];
 | 
						||
 | 
						||
			if (!riga.is_descrizione())
 | 
						||
				to_delete = (riga.imponibile() == ZERO && riga.get_real(RDOC_QTA) == ZERO);
 | 
						||
		}
 | 
						||
		if (to_delete || doc.totale_doc() == ZERO)
 | 
						||
			doc_out.destroy(id);
 | 
						||
	}
 | 
						||
  for (int id = doc_out.items() - 1; id >= 0 ; id--)
 | 
						||
  {             
 | 
						||
    TDocumento& doc = doc_out[id];
 | 
						||
		const TString4 tipocf = doc.get(DOC_TIPOCF);
 | 
						||
		const int act_cli = doc.get_long(DOC_CODCF);
 | 
						||
		TToken_string key(tipocf);
 | 
						||
		
 | 
						||
		key.add(act_cli);
 | 
						||
		
 | 
						||
		const TRectype & reccli = cache().get(LF_CLIFO, key);
 | 
						||
		const long new_cli = reccli.get_long(CLI_CODCFFATT);
 | 
						||
 | 
						||
		if (new_cli > 0L)
 | 
						||
		{
 | 
						||
			doc.put(DOC_CODCF, new_cli);
 | 
						||
			key = tipocf;
 | 
						||
			key.add(new_cli);
 | 
						||
			const TRectype & new_reccli = cache().get(LF_CLIFO, key);
 | 
						||
			const TRectype & new_reccliven = cache().get(LF_CFVEN, key);
 | 
						||
			TLaundry_contract contr(new_cli, doc.get_long(DOC_CODINDSP), _data_elab);
 | 
						||
 | 
						||
			if (new_reccli.get_int(CLI_ALLEG) == 7 && new_reccliven.get_bool(CFV_FATTSOSP))
 | 
						||
				doc.put(DOC_LIQDIFF, "X");
 | 
						||
			doc.put(DOC_CODINDSP, new_reccliven.get(CFV_CODINDDOC));
 | 
						||
 | 
						||
			TString descr;
 | 
						||
 | 
						||
	    if (ini_get_bool(CONFIG_DITTA, "lv", "DestHead"))
 | 
						||
			{
 | 
						||
				descr << reccli.get(CLI_RAGSOC) << ", ";
 | 
						||
				descr << reccli.get(CLI_INDCF) << ' ' <<  reccli.get(CLI_CIVCF) << ", ";
 | 
						||
				descr << reccli.get(CLI_LOCCF) << ", ";
 | 
						||
				TToken_string keyc = reccli.get(CLI_STATOCF);
 | 
						||
 | 
						||
				keyc.add(reccli.get(CLI_COMCF));
 | 
						||
				const TRectype & com = cache().get(LF_COMUNI, keyc);
 | 
						||
				descr << reccli.get(CLI_CAPCF) << ' ' <<  com.get(COM_DENCOM);
 | 
						||
				doc.put(DOC_DEST, descr);
 | 
						||
			}
 | 
						||
			else
 | 
						||
			{
 | 
						||
				TRiga_documento & r = doc.insert_row(1, "05");
 | 
						||
 | 
						||
				r.put(RDOC_DESCR, "Consegne effettuate presso\n");
 | 
						||
				descr << act_cli << " " << reccli.get(CLI_RAGSOC);
 | 
						||
				r.put(RDOC_DESCLUNGA, "X");
 | 
						||
				r.put(RDOC_DESCEST, descr);
 | 
						||
			}
 | 
						||
			if (contr.get_bool(LVCONDV_RAGGCGRUP))
 | 
						||
			{
 | 
						||
				add_doc_to_list(key, doc);
 | 
						||
				doc_out.destroy(id);
 | 
						||
			}
 | 
						||
 | 
						||
		}
 | 
						||
	}
 | 
						||
	if (fatt_02())
 | 
						||
	{
 | 
						||
		for (int id = doc_in.items() - 1; id >= 0 ; id--)
 | 
						||
		{                   
 | 
						||
			TDocumento & doc = doc_in[id];
 | 
						||
			const long clifo = doc.get_long(DOC_CODCF);
 | 
						||
			const int indsped = doc.get_int(DOC_CODINDSP);
 | 
						||
			TLaundry_contract contr(clifo,indsped,_data_elab);
 | 
						||
			const real redditivita = contr.get_real(LVCONDV_REDDI);
 | 
						||
 | 
						||
			if (redditivita >= CENTO)
 | 
						||
			{
 | 
						||
				doc_in[id].remove();
 | 
						||
				doc_in.destroy(id);
 | 
						||
			}
 | 
						||
		}
 | 
						||
	}
 | 
						||
}         
 | 
						||
 | 
						||
 | 
						||
//ADD_ROWS: per adesso un segnaposto
 | 
						||
void TFatturazione_lavanderie::add_rows(TRiga_documento & rout, TRiga_documento & rin)
 | 
						||
{
 | 
						||
  /*const TString8 causale = rin.get(RDOC_CODAGG1);
 | 
						||
  const TRectype& cau = cache().get("&CAU", causale);
 | 
						||
  const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1"));
 | 
						||
  const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2")); //movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale
 | 
						||
  
 | 
						||
  const long clifo = rin.doc().get_long(DOC_CODCF);
 | 
						||
	const int indsped = rin.doc().get_int(DOC_CODINDSP);
 | 
						||
	TLaundry_contract contr(clifo, indsped, _data_elab);
 | 
						||
  
 | 
						||
  if (cau.get_bool("B4") && contr.get_int(LVCONDV_ADDCAPROT)) // Guardo se <20> una causale di rotto e se <20> abilitato nella testata del contratto la fatturazione dei rotti
 | 
						||
  {
 | 
						||
    const real qta = rit.sgn(s_consmese) * rin.get_real(RDOC_QTA);
 | 
						||
    rout.put(RDOC_PREZZO,contr.get_int(LVCONDV_PREZROT));
 | 
						||
    rout.add(RDOC_QTA, qta);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
	  if (cau.get_bool("B0"))
 | 
						||
    {
 | 
						||
      const real qta = rit.sgn(s_consmese) * rin.get_real(RDOC_QTA);
 | 
						||
	    rout.add(RDOC_QTA, qta);
 | 
						||
 | 
						||
    } 
 | 
						||
    if (cau.get_bool("B1"))
 | 
						||
    {
 | 
						||
     const real qta = con.sgn(s_consmese) * rin.get_real(RDOC_QTA);
 | 
						||
     rout.add(RDOC_QTA, qta);
 | 
						||
    }
 | 
						||
  } */
 | 
						||
}
 | 
						||
 | 
						||
//CAMPI_RAGGRUPPAMENTO_RIGHE: ridefinisco il metodo campi_raggruppamento_righe della TFatturazione_bolle
 | 
						||
void TFatturazione_lavanderie::campi_raggruppamento_righe(TToken_string& campi_riga) const
 | 
						||
{
 | 
						||
  campi_riga = RDOC_CODART"|"RDOC_UMQTA;  // Uguali sempre
 | 
						||
  const bool ragg_rig = raggruppa_righe();
 | 
						||
	if (ragg_rig)
 | 
						||
  {
 | 
						||
    // Uguali se commesse attive
 | 
						||
    if (dongle().active(CAAUT) || dongle().active(CMAUT))
 | 
						||
    {
 | 
						||
      campi_riga.add(RDOC_CODCMS);
 | 
						||
      campi_riga.add(RDOC_FASCMS);
 | 
						||
      campi_riga.add(RDOC_CODCOSTO);
 | 
						||
    }
 | 
						||
    // Uguali opzionalmente
 | 
						||
    if (riga_uguale(0)) campi_riga.add(RDOC_CODMAG);
 | 
						||
    if (riga_uguale(1)) campi_riga.add(RDOC_CODIVA);
 | 
						||
    if (riga_uguale(2))
 | 
						||
	  {
 | 
						||
		  const int tipoprezzo = ini_get_int(CONFIG_DITTA, "lv", "TipoPr");
 | 
						||
		  if (tipoprezzo == 0)
 | 
						||
		    campi_riga.add(RDOC_SCONTO);
 | 
						||
		  else
 | 
						||
		    campi_riga.add(RDOC_PREZZO"|"RDOC_SCONTO);
 | 
						||
	  }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
//FIND_OR_CREATE_ROW: questo metodo cerca tra tutte le righe documento della fattura prodotta
 | 
						||
//una eventuale riga lavanderia raggruppabile; se la trova restituiace quella riga, altrimenti
 | 
						||
//ne crea una nuova
 | 
						||
TRiga_documento& TFatturazione_lavanderie::find_or_create_row(TDocumento& doc_out, const TRiga_documento& rin, const char lavtype) 
 | 
						||
{  
 | 
						||
  int r;
 | 
						||
 | 
						||
  //scorro le righe documetno
 | 
						||
	for (r = doc_out.physical_rows(); r > 0; r--)
 | 
						||
	{
 | 
						||
    //se trovo una riga raggruppabile e di lavanderia, allora interrompo il ciclo
 | 
						||
		if (doc_out[r].raggruppabile(rin, _campi_raggruppamento) && (doc_out[r].get_char("LVTYPE") == lavtype))
 | 
						||
      break;
 | 
						||
	}
 | 
						||
 | 
						||
  //se non ho trovato la riga, ne creo una nuova
 | 
						||
  if (r <= 0)
 | 
						||
  {
 | 
						||
    TRiga_documento& row = doc_out.new_row("01");
 | 
						||
    doc_out.copy_data(row, rin);
 | 
						||
		row.put(RDOC_TIPORIGA, "01");
 | 
						||
		set_perc_provv(row);
 | 
						||
		set_perc_provv(row, false);
 | 
						||
    
 | 
						||
    const TRectype& anamag = cache().get(LF_ANAMAG, rin.get(RDOC_CODART));
 | 
						||
    row.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA));
 | 
						||
 | 
						||
    row.zero(RDOC_CODAGG1);
 | 
						||
    row.zero(RDOC_QTA);
 | 
						||
    row.zero(RDOC_QTAGG1);
 | 
						||
    row.zero(RDOC_CODMAGC);
 | 
						||
    row.put("LVTYPE", lavtype);
 | 
						||
    r = row.get_int(RDOC_NRIGA);
 | 
						||
 | 
						||
    TString msg; msg.format(FR("Creazione riga %d in fattura %d/%s/%ld"), 
 | 
						||
      r, doc_out.anno(), (const char*)row.get(RDOC_CODNUM), row.get_long(RDOC_NDOC));
 | 
						||
    app().log(msg, -1);
 | 
						||
  }
 | 
						||
	if (fatt_02())
 | 
						||
	{
 | 
						||
		doc_out.set_row_ids();
 | 
						||
		const TString key = format("%04d%04d", doc_out.get_int("FATID"), doc_out[r].get_int(RDOC_IDRIGA));
 | 
						||
		TCalc_02_data * data = (TCalc_02_data *) _output_rows_02.objptr(key);
 | 
						||
 | 
						||
		if (data == NULL)
 | 
						||
		{
 | 
						||
			data = new TCalc_02_data(key);
 | 
						||
			_output_rows_02.add(key, data);
 | 
						||
		}
 | 
						||
		TString16 bolkey = rin.get_rdoc_key();
 | 
						||
		data->bol_rows().add(bolkey, bolkey);
 | 
						||
	}
 | 
						||
  return doc_out[r];  
 | 
						||
}
 | 
						||
 | 
						||
//CREATE_ROW: metodo che crea fisicamente la riga sul documento di uscita partendo dal documento di ingresso (bolla)
 | 
						||
void TFatturazione_lavanderie::create_row(TDocumento& doc_out, const TRiga_documento & rin)
 | 
						||
{
 | 
						||
  //leggo la causale della riga del documento di ingresso
 | 
						||
  const TString8 causale = rin.get(RDOC_CODAGG1);
 | 
						||
  const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
 | 
						||
  
 | 
						||
  //recupero i dati cliente dalla testata del documento e instanzio il contratto
 | 
						||
  const long clifo = rin.doc().get_long(DOC_CODCF);
 | 
						||
	const int indsped = rin.doc().get_int(DOC_CODINDSP);
 | 
						||
	TLaundry_contract contr(clifo, indsped, _data_elab);
 | 
						||
  
 | 
						||
  //leggo dal documento i valori che vanno riportati sulla fattura e recupero la riga contratto
 | 
						||
  //di quell'articolo
 | 
						||
  const TCodice_articolo codart = rin.get(RDOC_CODARTMAG); // non <20> gestito il caso di un articolo fuori contratto
 | 
						||
  const real qta = rin.get_real(RDOC_QTA);
 | 
						||
  const real qta1 = rin.get_real(RDOC_QTAGG1);
 | 
						||
  const TRectype& rcont = contr.row(codart);
 | 
						||
 | 
						||
  //leggo dalla configurazione da dove va preso il prezzo
 | 
						||
  const int tipoprezzo = ini_get_int(CONFIG_DITTA, "lv", "TipoPr");
 | 
						||
  real prezzo;
 | 
						||
  //se tipoprezzo == 0 (prezzo da contratto), allora cerco il prezzo sul contratto; se l'articolo
 | 
						||
  //non esiste sul contratto, allora cerco il suo prezzo sull'anagrafica di magazzino.
 | 
						||
  //Se tipoprezzo == 1 (prezzo da bolla), allora leggo il prezzo sulla riga della bolla
 | 
						||
  if (tipoprezzo == 0)
 | 
						||
  {
 | 
						||
    if (!rcont.empty())
 | 
						||
      prezzo = rcont.get_real(LVRCONDV_PREZZO);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    prezzo = rin.get_real(RDOC_PREZZO);
 | 
						||
      
 | 
						||
  //se <20> una causale di rotto e se <20> abilitato nella testata del contratto la fatturazione dei rotti
 | 
						||
  //e se sto ritirando una quantit<69> di merce diversa da zero, allora:
 | 
						||
  
 | 
						||
  if (cau.is_rotto() && contr.get_bool(LVCONDV_ADDCAPROT) && !qta1.is_zero()) 
 | 
						||
  {
 | 
						||
    //se passo le condizioni iniziali cerco eventualmente una riga che possa essere raggruppata con quella
 | 
						||
    //che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> da ritirare
 | 
						||
    //al prezzo segnato in contratto
 | 
						||
    TRiga_documento& rd = find_or_create_row(doc_out, rin ,'D');    
 | 
						||
 | 
						||
		rd.put(RDOC_DESCLUNGA, "X");
 | 
						||
		rd.put(RDOC_DESCEST, "\nper addebito biancheria");
 | 
						||
    rd.add(RDOC_QTA, qta1);    
 | 
						||
    rd.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZDAN));
 | 
						||
		if (cau.get_int("I2") > 0)
 | 
						||
		{
 | 
						||
			rd.put(RDOC_QTAGG1, cau.get("I0"));
 | 
						||
			rd.put(RDOC_QTAGG2, cau.get("I1"));
 | 
						||
			rd.put(RDOC_QTAGG3, cau.get("I2"));
 | 
						||
		}
 | 
						||
		if (clifo != _last_cli_damn)
 | 
						||
			_cli_damn++;
 | 
						||
		_last_cli_damn = clifo;
 | 
						||
		_art_damn++;
 | 
						||
  }
 | 
						||
 | 
						||
  //se <20> una causale di ritirato e se sto ritirando una quantit<69> di merce diversa da zero, allora:
 | 
						||
  if (!qta1.is_zero() && cau.is_ritiro())
 | 
						||
  {
 | 
						||
    //leggo la casuale di magazzino associata al ritiro e il suo segno sul consegnato mese
 | 
						||
    const TCausale_magazzino& rit = cau.causale_ritiro();
 | 
						||
    const real sgnrit = rit.sgn(s_consmese);
 | 
						||
 | 
						||
    //se movimenta il consegnato mese, cerco eventualmente una riga che possa essere raggruppata con quella
 | 
						||
    //che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto ritirando moltiplicata
 | 
						||
    //per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
 | 
						||
    if (!sgnrit.is_zero())
 | 
						||
    {
 | 
						||
      TRiga_documento& rr = find_or_create_row(doc_out, rin, 'C');
 | 
						||
	    rr.add(RDOC_QTA, sgnrit * qta1);
 | 
						||
      rr.put(RDOC_PREZZO, prezzo);
 | 
						||
			rr.add("TOTRIT", qta1);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  //se <20> una causale di consegnato e se sto consegnando una quantit<69> di merce diversa da zero, allora:
 | 
						||
  if (!qta.is_zero() && cau.is_consegna())
 | 
						||
  {
 | 
						||
    //leggo la casuale di magazzino associata al ritiro e i suoi segni sul consegnato mese,
 | 
						||
    //sulla dotazione temporanea e sulla dotazione iniziale
 | 
						||
    const TCausale_magazzino& con = cau.causale_consegna();    
 | 
						||
    const real sgntmp=con.sgn(s_dottm);
 | 
						||
    const real sgndotin=con.sgn(s_dotin);
 | 
						||
    const real sgncons=con.sgn(s_consmese);
 | 
						||
 | 
						||
    //se movimenta la dotazione temporanea e <20> previsto l'addebito dotazione temporanea con prezzo diverso,
 | 
						||
    //cerco eventualmente una riga che possa essere raggruppata con quella che sto guardando adesso,
 | 
						||
    //altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
 | 
						||
    //per il suo segno al prezzo scritto sul contratto per la dotazine temporanea
 | 
						||
    if (!sgntmp.is_zero() && contr.get_bool(LVCONDV_DOTTMPPRZD))
 | 
						||
    {
 | 
						||
      TRiga_documento& rt = find_or_create_row(doc_out, rin, 'T');
 | 
						||
  	  rt.add(RDOC_QTA, sgntmp * qta);
 | 
						||
      rt.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PRZDTTMP));
 | 
						||
    }
 | 
						||
 | 
						||
    //se movimenta la dotazione iniziale, cerco eventualmente una riga che possa essere raggruppata con quella
 | 
						||
    //che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
 | 
						||
    //per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
 | 
						||
    if (!sgndotin.is_zero() && !sgncons.is_zero())
 | 
						||
    {
 | 
						||
      TRiga_documento& rc = find_or_create_row(doc_out, rin, 'C');
 | 
						||
  	  rc.add(RDOC_QTA, sgndotin * qta);
 | 
						||
      rc.put(RDOC_PREZZO, prezzo);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      //se movimenta il consegnato mese, cerco eventualmente una riga che possa essere raggruppata con quella
 | 
						||
      //che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
 | 
						||
      //per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
 | 
						||
      if (!sgncons.is_zero())
 | 
						||
      {
 | 
						||
        TRiga_documento& rc = find_or_create_row(doc_out, rin, 'C');
 | 
						||
  	    rc.add(RDOC_QTA, sgncons * qta);
 | 
						||
        rc.put(RDOC_PREZZO, prezzo);
 | 
						||
				rc.add("TOTRIT", qta1);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TFatturazione_lavanderie::get_num_tip_out(const TDocumento& doc_out, TString& codnum, TString& tipodoc) const
 | 
						||
{
 | 
						||
  // Nel caso di fatturazione di prova NON deve scattare il meccanismo di riattribuzione del tipo documento in base a CFV_TIPODOCFAT.
 | 
						||
  // Deve accontentarsi del tipo documento specificato normalmente sul record dell'elaborazione
 | 
						||
  if (_prova)
 | 
						||
  {
 | 
						||
    codnum = codice_numerazione_finale();
 | 
						||
    tipodoc = get_tipo_out(doc_out);
 | 
						||
    const TCodice_numerazione& cn = cached_numerazione(codnum);
 | 
						||
    return cn.find_tipo_doc(tipodoc) >= 0;
 | 
						||
  }
 | 
						||
  return TFatturazione_bolle::get_num_tip_out(doc_out, codnum, tipodoc);
 | 
						||
}
 | 
						||
 | 
						||
//ELABORA: metodo che esegue alcune operazioni prliminari, quali settare la data elaborazione e trovare i campi
 | 
						||
//in base ai quali <20> possibile raggruppare le righe documetno, e poi chiama l'elaborazione standard per la fatturazione
 | 
						||
bool TFatturazione_lavanderie::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
 | 
						||
                                       const TDate& data_elab, bool interattivo)
 | 
						||
{
 | 
						||
  _data_elab = data_elab;
 | 
						||
  campi_raggruppamento_righe(_campi_raggruppamento);
 | 
						||
	_output_rows_02.destroy();
 | 
						||
  return TFatturazione_bolle::elabora(doc_in, doc_out, data_elab, interattivo);
 | 
						||
}
 | 
						||
 | 
						||
                                      /////////////////////////////////
 | 
						||
                                      ////    TFatturazione_msk    ////
 | 
						||
                                      /////////////////////////////////
 | 
						||
 | 
						||
TFatturazione_msk::TFatturazione_msk():TAutomask("lv2500a") 
 | 
						||
{
 | 
						||
  //imposto il periodo di fatturazione dal primo del mese precedente all'ultimo del mese precedente 
 | 
						||
  //se la data odierna <20> inferiore al 10 del mese corrente
 | 
						||
  //altrimenti la imposto dal primo del mese corrente alla data odierna    
 | 
						||
  TDate data(TODAY);
 | 
						||
  if (data.day() <= 10)     
 | 
						||
  {
 | 
						||
    data.addmonth(-1);
 | 
						||
    data.set_day(1);
 | 
						||
    set(F_DADATA, data);
 | 
						||
    data.set_end_month();
 | 
						||
    set(F_ADATA, data);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    set(F_ADATA, data);
 | 
						||
    data.set_day(1);
 | 
						||
    set(F_DADATA, data);
 | 
						||
  }
 | 
						||
 | 
						||
  if (main_app().argc() > 2)
 | 
						||
  {
 | 
						||
    TString16 tpela = main_app().argv(2);
 | 
						||
    tpela = tpela.mid(4);
 | 
						||
    TString8 codela = ini_get_string(CONFIG_DITTA, "lv", tpela);
 | 
						||
    set(F_COD_ELAB, codela);
 | 
						||
    field(F_COD_ELAB).check();
 | 
						||
		disable(F_COD_ELAB);
 | 
						||
		disable(F_DESC_ELAB);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
                                      /////////////////////////////////////
 | 
						||
                                      ////    TFatturazione_lav_app    ////
 | 
						||
                                      /////////////////////////////////////
 | 
						||
 | 
						||
void TFatturazione_lav_app::log(const char* msg, int sev)
 | 
						||
{ 
 | 
						||
  #ifdef NDEBUG
 | 
						||
    if (sev >= 0)  // No debug messages in release build
 | 
						||
  #endif
 | 
						||
  if (_log) _log->log(sev, msg); 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//GENERA_BOLLE_NOLO: metodo che genera le fatture di solo nolo per quei clienti a cui non <20> stato consegnato niente
 | 
						||
void TFatturazione_lav_app::genera_bolle_nolo(TAssoc_array& cliela, TFatturazione_lavanderie& elab, int& numdocgen, real& totimp, real& imposta, real& totdoc, real& spese)
 | 
						||
{
 | 
						||
  const TString4 codnum  = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
 | 
						||
  const TString4 tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
 | 
						||
  const char     stato   = cache().get("%TIP", tipodoc, "S2").mid(1,1)[0];
 | 
						||
  
 | 
						||
  //preparo la query sui contratti
 | 
						||
  TString str;
 | 
						||
  str << "USE LVCONDV";
 | 
						||
 | 
						||
  if (_msk->get_long(F_DACODCF) > 0)
 | 
						||
    str << "\nFROM CODCF=" << _msk->get_long(F_DACODCF);
 | 
						||
 | 
						||
  if (_msk->get_long(F_ACODCF) > 0)
 | 
						||
    str << "\nTO CODCF=" << _msk->get_long(F_ACODCF);
 | 
						||
 | 
						||
  TISAM_recordset contr(str);
 | 
						||
 | 
						||
  TLista_documenti doc_in;
 | 
						||
  TLista_documenti doc_out;
 | 
						||
 | 
						||
  TProgress_monitor pi(contr.items(), TR("Elaborazione Nolo"), true);
 | 
						||
  for(bool ok = contr.move_first(); ok; ok = contr.move_next())
 | 
						||
  {
 | 
						||
    if (!pi.add_status())
 | 
						||
			break;
 | 
						||
    
 | 
						||
    //scarto i contratti scaduti
 | 
						||
    const TDate data_scad_contr = contr.get(LVCONDV_DATASC).as_date();
 | 
						||
    if (data_scad_contr.ok())
 | 
						||
      if (_msk->get_date(F_DADATA) < contr.get(LVCONDV_DATAIN).as_date() || _msk->get_date(F_ADATA) > data_scad_contr)
 | 
						||
        continue;
 | 
						||
 | 
						||
    //scarto tutti quelli che non sono in periodo di fatturazione corretto
 | 
						||
    if (contr.get(LVCONDV_PERFAT).as_int() > _msk->get_int(F_PERFAT))
 | 
						||
      continue;
 | 
						||
 | 
						||
    // scarto i clienti sospesi
 | 
						||
	  if (contr.get(LVCONDV_FATTSOSP).as_bool())
 | 
						||
			continue;
 | 
						||
 | 
						||
    if (cliela.is_key(contr.get(LVCONDV_CODCF).as_string()))
 | 
						||
      continue;
 | 
						||
 | 
						||
    TDocumento *pdoc= new TDocumento('D', _msk->get_date(F_DATAFAT).year(), codnum, 0);
 | 
						||
 | 
						||
    doc_in.add(pdoc);
 | 
						||
    TDocumento& doc = *pdoc;
 | 
						||
 | 
						||
    doc.put(DOC_TIPODOC, tipodoc);
 | 
						||
    doc.put(DOC_STATO, stato);
 | 
						||
    doc.put(DOC_TIPOCF, 'C');
 | 
						||
 | 
						||
    TLaundry_contract contratto(contr.cursor()->curr());
 | 
						||
 | 
						||
    const long codcf  = contratto.get_long(LVCONDV_CODCF);
 | 
						||
    const int codcont = contratto.get_int(LVCONDV_CODCONT);
 | 
						||
		const bool fattnocons = !contratto.get_bool(LVCONDV_FORFNOCONS);
 | 
						||
 | 
						||
		doc.put(DOC_CODCF, codcf);
 | 
						||
		TToken_string key("C");
 | 
						||
		key.add(codcf);
 | 
						||
 | 
						||
    const TRectype& clifo = cache().get(LF_CLIFO, key);
 | 
						||
    const TString4 codpag  = clifo.get(CLI_CODPAG);
 | 
						||
    const long codabi      = clifo.get_long(CLI_CODABI);
 | 
						||
    const long codcab      = clifo.get_long(CLI_CODCAB);
 | 
						||
    const TString80 iban   = clifo.get(CLI_IBAN);
 | 
						||
 | 
						||
    //recupero i dati di interesse dal file CFVEN  
 | 
						||
    const TRectype& cfven = cache().get(LF_CFVEN, key);
 | 
						||
    const long codabipr      = cfven.get_long(CFV_CODABIPR);
 | 
						||
    const long codcabpr      = cfven.get_long(CFV_CODCABPR);
 | 
						||
    const bool ragdoc        = cfven.get_bool(CFV_RAGGDOC);
 | 
						||
    const TString8 codag1    = cfven.get(CFV_CODAG1);
 | 
						||
    const TString4 codmez    = cfven.get(CFV_CODSPMEZZO);
 | 
						||
    const TString4 codporto  = cfven.get(CFV_CODPORTO);
 | 
						||
    const TString4 codnote1  = cfven.get(CFV_CODNOTESP1);
 | 
						||
    const TString4 codnote2  = cfven.get(CFV_CODNOTESP2);
 | 
						||
    const TString4 codnote   = cfven.get(CFV_CODNOTE);
 | 
						||
    const TString8 codvet1   = cfven.get(CFV_CODVETT1);
 | 
						||
    const TString8 codvet2   = cfven.get(CFV_CODVETT2);
 | 
						||
    const TString8 codvet3   = cfven.get(CFV_CODVETT3);
 | 
						||
    const real speseinc      = cfven.get_real(CFV_PERCSPINC);
 | 
						||
    const TString4 catven    = cfven.get(CFV_CATVEN);
 | 
						||
    const bool addbolli      = cfven.get_bool(CFV_ADDBOLLI);
 | 
						||
    const TString8 codlist   = cfven.get(CFV_CODLIST);
 | 
						||
    const TString4 codzona   = cfven.get(CFV_CODZONA);
 | 
						||
 | 
						||
    //gestione sconto
 | 
						||
    TString sconto;
 | 
						||
 | 
						||
    const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0];
 | 
						||
    switch(tpgest)
 | 
						||
    {
 | 
						||
    case 'P':  sconto = cfven.get(CFV_SCONTO);  break;                             //Percentuale su anagrafica cliente
 | 
						||
    case 'T':  sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1");  break;  //Gestione tabella sconti
 | 
						||
    case 'A':                                                                      //Gestione archivio sconti
 | 
						||
      {
 | 
						||
        TConfig ditta(CONFIG_DITTA, "ve");      
 | 
						||
 | 
						||
        TLocalisamfile sconti(LF_SCONTI);
 | 
						||
        sconti.put("TIPO", "I");
 | 
						||
 | 
						||
        if(ditta.get_bool("SCOKEY", "ve", 1))
 | 
						||
          sconti.put("CODCAT", cfven.get(CFV_CATVEN));
 | 
						||
 | 
						||
        TString16 cod;
 | 
						||
        if(ditta.get_bool("SCOKEY", "ve", 2))
 | 
						||
          cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC));
 | 
						||
        else
 | 
						||
          cod = " ";
 | 
						||
 | 
						||
        if(ditta.get_bool("SCOKEY", "ve", 3))
 | 
						||
        {
 | 
						||
          TString8 tmp; 
 | 
						||
          tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA));
 | 
						||
          cod << tmp;
 | 
						||
        }
 | 
						||
        else
 | 
						||
          cod << " ";
 | 
						||
 | 
						||
        if(ditta.get_bool("SCOKEY", "ve", 4))
 | 
						||
          cod << clifo.get(CLI_CODPAG);
 | 
						||
 | 
						||
        sconti.put("CODART", cod);
 | 
						||
 | 
						||
        if (sconti.read() == NOERR)
 | 
						||
          sconto = sconti.get("SCONTO");
 | 
						||
      }
 | 
						||
    case 'N':  //sconto non gestito
 | 
						||
    default: break;
 | 
						||
    }
 | 
						||
 | 
						||
    doc.put(DOC_CODPAG, codpag);
 | 
						||
    doc.put(DOC_CODABIA, codabi);
 | 
						||
    doc.put(DOC_CODCABA, codcab);
 | 
						||
    doc.put(DOC_IBAN, iban);
 | 
						||
    doc.put(DOC_CODABIP, codabipr);
 | 
						||
    doc.put(DOC_CODCABP, codcabpr);
 | 
						||
    doc.put(DOC_CODAGVIS, codag1);
 | 
						||
    doc.put(DOC_CODSPMEZZO, codmez);
 | 
						||
    doc.put(DOC_ZONA, codzona);
 | 
						||
    doc.put(DOC_CODPORTO, codporto);
 | 
						||
    doc.put(DOC_CODNOTESP1, codnote1);
 | 
						||
    doc.put(DOC_CODNOTESP2, codnote2);
 | 
						||
    doc.put(DOC_CODNOTE, codnote);
 | 
						||
    doc.put(DOC_CODVETT1, codvet1);
 | 
						||
    doc.put(DOC_CODVETT2, codvet2);
 | 
						||
    doc.put(DOC_CODVETT3, codvet3);
 | 
						||
    doc.put(DOC_CATVEN, catven);
 | 
						||
    doc.put(DOC_CODLIST, codlist);
 | 
						||
    doc.put(DOC_PERCSPINC, speseinc);
 | 
						||
    doc.put(DOC_ADDBOLLI, addbolli);
 | 
						||
    doc.put(DOC_SCONTOPERC, sconto);
 | 
						||
 | 
						||
    TString str;
 | 
						||
    str << "USE LVRCONDV\n"
 | 
						||
        << "FROM CODCF=" << codcf << " CODCONT=" << codcont << "\n"
 | 
						||
        << "TO CODCF=" << codcf << " CODCONT=" << codcont;
 | 
						||
    
 | 
						||
    TISAM_recordset rcont(str);
 | 
						||
 | 
						||
    for(bool ok = rcont.move_first(); ok; ok = rcont.move_next())
 | 
						||
    {
 | 
						||
      TRectype& riga = rcont.cursor()->curr();
 | 
						||
			const int tipoforf = riga.get_int(LVRCONDV_TIPOFORF);
 | 
						||
 | 
						||
      //il nolo deve esserci sempre, il ciclaggio solo se fattnocons -> per me l'if diventa:
 | 
						||
      //if (tipoforf > 0 &&	(tipoforf != 2 && fattnocons))
 | 
						||
      if (tipoforf > 0 &&	((tipoforf == 2) || (tipoforf != 2 && fattnocons)))
 | 
						||
      {
 | 
						||
        TRiga_documento& rdoc = doc.new_row("21");
 | 
						||
 | 
						||
        rdoc.put(RDOC_CODART, riga.get(LVRCONDV_CODART));
 | 
						||
        rdoc.put(RDOC_CODARTMAG, riga.get(LVRCONDV_CODART));
 | 
						||
        real r = UNO;
 | 
						||
        if (tipoforf == 3 || tipoforf == 4)
 | 
						||
          r = ZERO;
 | 
						||
        rdoc.put(RDOC_QTA, r);
 | 
						||
        rdoc.put(RDOC_QTAGG1, r);
 | 
						||
        rdoc.put(RDOC_PREZZO, riga.get_real(LVRCONDV_PREZNOL));
 | 
						||
        rdoc.put(RDOC_CHECKED, true);
 | 
						||
        rdoc.put(RDOC_UMQTA, riga.get(LVRCONDV_UM));
 | 
						||
 | 
						||
        TToken_string key;
 | 
						||
        key.add('C');
 | 
						||
        key.add(codcf);
 | 
						||
        TString8 codiva = cache().get(LF_CFVEN, key, CFV_ASSFIS);
 | 
						||
        if (codiva.blank())
 | 
						||
          codiva = cache().get(LF_ANAMAG, riga.get(LVRCONDV_CODART), ANAMAG_CODIVA);
 | 
						||
 | 
						||
        rdoc.put(RDOC_CODIVA, codiva);
 | 
						||
 | 
						||
        rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"));
 | 
						||
				elab.set_perc_provv(rdoc);
 | 
						||
				elab.set_perc_provv(rdoc, false);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    if (ini_get_bool(CONFIG_DITTA, "lv", "RifTest"))
 | 
						||
      elab.put("B15", true);  //forzo la descrizione abbreviata
 | 
						||
 | 
						||
    if (doc.physical_rows() > 0)
 | 
						||
    {
 | 
						||
      elab.elabora(doc_in, doc_out, _msk->get_date(F_DATAFAT));
 | 
						||
			if (!_solototali)
 | 
						||
				int err = doc_out.write();
 | 
						||
      numdocgen += doc_out.items();
 | 
						||
 | 
						||
			if (doc_out.items() > 0)
 | 
						||
			{
 | 
						||
				totimp += doc_out[0].imponibile();
 | 
						||
				imposta += doc_out[0].imposta();
 | 
						||
				totdoc += doc_out[0].totale_doc();
 | 
						||
				spese += doc_out[0].spese();
 | 
						||
			}
 | 
						||
    }
 | 
						||
 | 
						||
    doc_out.destroy(-1);
 | 
						||
 
 | 
						||
    doc_in.destroy(-1);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
//CONTROLLI PRELIMINARI: metodo che si preoccupa di ferivicare la presenza in configurazione di tutti
 | 
						||
//i dati necessari alla fatturazione
 | 
						||
bool TFatturazione_lav_app::controlli_preliminari()
 | 
						||
{
 | 
						||
  bool corretto = true;
 | 
						||
 | 
						||
  //controllo se il tipo documento <20> configurato
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "NUM_FAT").empty() || ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_FAT").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("Il Tipo documento fattura non <20> configurato correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  //controllo se le causali di dafault sono configurate
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("La causale di default non <20> configurata correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "CAULVRITDT").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("La causale di default non <20> configurata correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  //controllo se l'articolo per il canone fisso <20> configurato
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "Codartfix").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("L'articolo per canone fisso non <20> configurato correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  //controllo se l'articolo per il raggruppamento <20> configurato
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "Codartcafix").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("L'articolo per il raggruppamento non <20> configurato correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  //controllo se l'articolo per il raggruppamento <20> configurato
 | 
						||
  if (ini_get_string(CONFIG_DITTA, "lv", "Codartcofix").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("L'articolo per il valore convenzionale non <20> configurato correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  //controllo se l'unit<69> di misura per la fatturazioni a Kg <20> settata
 | 
						||
  if(ini_get_string(CONFIG_DITTA, "lv", "UmKg").empty())
 | 
						||
  {
 | 
						||
    warning_box(TR("L'unit<69> di misura per la fatturazione a Kg non <20> configurata correttamente"));
 | 
						||
    corretto = false;
 | 
						||
  }
 | 
						||
 | 
						||
  return corretto;
 | 
						||
}
 | 
						||
 | 
						||
bool TFatturazione_lav_app::copy_file(const TFilename& src, const TFilename& dst) const
 | 
						||
{
 | 
						||
  // Crea la cartella di destinazione se necessario
 | 
						||
  const char* dstdir = dst.path();
 | 
						||
  if (*dstdir && !xvt_fsys_dir_exists(dstdir) && !xvt_fsys_mkdir(dstdir))
 | 
						||
    return cantwrite_box(dstdir);
 | 
						||
 | 
						||
  // Copia veramente il file
 | 
						||
  return ::fcopy(src, dst);
 | 
						||
}
 | 
						||
 | 
						||
bool TFatturazione_lav_app::copy_tree(const char* src_study, const char* dst_study) const
 | 
						||
{
 | 
						||
  xvt_fsys_save_dir();
 | 
						||
  TFilename mask(src_study); mask.add("*.");
 | 
						||
  SLIST dlist = xvt_fsys_list_files(DIR_TYPE, mask, TRUE);
 | 
						||
  xvt_fsys_restore_dir();
 | 
						||
  TProgress_monitor pd(xvt_slist_count(dlist), TR("Copia cartelle"), true);
 | 
						||
 | 
						||
  TString msg; // Messaggio di progresso
 | 
						||
 | 
						||
  bool go_on = true;
 | 
						||
  for (SLIST_ELT d = xvt_slist_get_first(dlist); d && go_on; d = xvt_slist_get_next(dlist, d))
 | 
						||
  { 
 | 
						||
    if (!pd.add_status())
 | 
						||
    {
 | 
						||
      go_on = false;
 | 
						||
      break;
 | 
						||
    }
 | 
						||
 | 
						||
    const TFilename dir = xvt_slist_get(dlist, d, NULL);
 | 
						||
    
 | 
						||
    TString name = dir.name(); name.lower();
 | 
						||
    if (name.compare("cesp", -1, true) == 0) // Ignora la vetusta cartella Cespiti in FoxPro
 | 
						||
      continue;
 | 
						||
 | 
						||
    msg.cut(0) << TR("Copia di ") << name;
 | 
						||
    pd.set_text(msg);
 | 
						||
 
 | 
						||
    mask = dir; mask.add("*.*");
 | 
						||
    TString_array files; list_files(mask, files);
 | 
						||
 | 
						||
    TProgress_monitor pi(files.items(), "Copia file", true);
 | 
						||
 | 
						||
    TFilename dst;
 | 
						||
    FOR_EACH_ARRAY_ROW(files, i, f)
 | 
						||
    {
 | 
						||
      if (!pi.add_status())
 | 
						||
      {
 | 
						||
        go_on = false;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      TFilename src(*f);
 | 
						||
      TString16 ext(src.ext()); ext.lower();
 | 
						||
      if (ext != "zip" && ext != "rar" && ext != "mdb" && ext != "inf") 
 | 
						||
      {
 | 
						||
        msg.cut(0) << TR("Copia di ") << src;
 | 
						||
        pi.set_text(msg);
 | 
						||
 | 
						||
        dst = dst_study;
 | 
						||
        dst.add(name);
 | 
						||
        dst.add(src.name());
 | 
						||
        copy_file(src, dst);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  xvt_slist_destroy(dlist);
 | 
						||
 | 
						||
  return go_on;
 | 
						||
}
 | 
						||
 | 
						||
bool TFatturazione_lav_app::create()
 | 
						||
{
 | 
						||
  //instanzio i localisamfile che mi servono
 | 
						||
	open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_DOC, LF_RIGHEDOC, LF_LVCONDV, LF_LVRCONDV, 0);
 | 
						||
  return TSkeleton_application::create();
 | 
						||
}
 | 
						||
	
 | 
						||
void TFatturazione_lav_app::main_loop()
 | 
						||
{
 | 
						||
	bool prova = false;
 | 
						||
	const bool use_indsp = ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED");
 | 
						||
	const bool prezzo_da_contratto = ini_get_int(CONFIG_DITTA, "lv", "Tipopr") == 0;
 | 
						||
	const bool agghead = prezzo_da_contratto || ini_get_bool(CONFIG_DITTA, "lv", "AggHead");
 | 
						||
	const TString4 num_buoni = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
 | 
						||
	const TString4 tipo_buoni = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
 | 
						||
 | 
						||
	if (main_app().argc() > 2)
 | 
						||
  {
 | 
						||
    TString16 tpela = main_app().argv(2);
 | 
						||
    tpela = tpela.mid(4);
 | 
						||
		prova  = (tpela == "FatPro");
 | 
						||
	}
 | 
						||
 | 
						||
  //instanzio la maschera
 | 
						||
  _msk = new TFatturazione_msk();
 | 
						||
	_msk->show(F_SAVEDATA, lv_is_02_active());
 | 
						||
 | 
						||
  while (_msk->run()!= K_QUIT)
 | 
						||
  {
 | 
						||
		_solototali = _msk->get_bool(F_SOLOTOTALI);
 | 
						||
	  const int annoes = _msk->get_date(F_DATAFAT).year();
 | 
						||
 | 
						||
    if (!controlli_preliminari())
 | 
						||
    {
 | 
						||
      TString str;
 | 
						||
      str << "Prima di poter eseguire la fatturazione <20> necessario correggere tutti gli errori segnalati.\n"
 | 
						||
          << "Si prega di controllare i dati di configurazione.";
 | 
						||
      warning_box(str);
 | 
						||
      return;
 | 
						||
    }
 | 
						||
		_log = new TLog_report(TR("Fatturazione"));
 | 
						||
    
 | 
						||
		if (_msk->get_bool(F_SAVEDATA))
 | 
						||
		{
 | 
						||
		  TFilename src = firm2dir(-1);
 | 
						||
		  TFilename dst =	ini_get_string(CONFIG_DITTA, "lv", "Backup");
 | 
						||
			copy_tree(src, dst);
 | 
						||
		}
 | 
						||
    //leggo i dati di primo interesse
 | 
						||
    const TString4 mskzona = _msk->get(F_CODZONA);
 | 
						||
    const TString4 mskcat = _msk->get(F_CODCATC);
 | 
						||
    //preparo le date estremi (dal - al) della query e l'anno dell'esercizio
 | 
						||
    TDate al = _msk->get_date(F_ADATA);    
 | 
						||
    //se la data "al" non <20> corretta, la pongo uguale alla data fattura
 | 
						||
		if (!al.ok())
 | 
						||
			al = _msk->get_date(F_DATAFAT);
 | 
						||
 | 
						||
    const long year = al.year();
 | 
						||
 | 
						||
    TDate dal = _msk->get_date(F_DADATA);
 | 
						||
    //se la data "dal" non <20> corretta, la pongo uguale a 1/1/annoes
 | 
						||
    if (!dal.ok())
 | 
						||
		{
 | 
						||
			dal.set_day(1);
 | 
						||
			dal.set_month(1);
 | 
						||
			dal.set_year(year);
 | 
						||
		}
 | 
						||
 | 
						||
    //instanzio una TFatturaziome_lavanderie
 | 
						||
    TFatturazione_lavanderie elab(_msk->get(F_COD_ELAB), prova);
 | 
						||
    //preparo le variabili di interesse
 | 
						||
    TLista_documenti docsin;
 | 
						||
    TLista_documenti docsout;
 | 
						||
    long lastcli = 0;
 | 
						||
    const int period = _msk->get_int(F_PERFAT);
 | 
						||
    const TDate datafat = _msk->get_date(F_DATAFAT);
 | 
						||
    long indsped;
 | 
						||
		TToken_string tipi;
 | 
						||
		TToken_string stati;
 | 
						||
		TString stato_min("Z");
 | 
						||
		
 | 
						||
		elab.last_cli_damn() = -1L;
 | 
						||
		elab.cli_damn() = 0;
 | 
						||
		elab.art_damn() = 0;
 | 
						||
		elab.tipi_stati_iniziali(tipi, stati);
 | 
						||
 | 
						||
		for (const char * s = stati.get(); s > " "; s = stati.get())
 | 
						||
			if (stato_min > s)
 | 
						||
				stato_min = s;
 | 
						||
    
 | 
						||
    //preparo la query
 | 
						||
    TString query;
 | 
						||
		const TString& fromcod = _msk->get(F_DACODCF);
 | 
						||
		const TString& tocod = _msk->get(F_ACODCF);
 | 
						||
	
 | 
						||
    //&&(BETWEEN(DATADOC,#DADATA,#ADATA))&&(STATO==\"2\")&&(TIPODOC==\"B01\")
 | 
						||
    query << "USE DOC KEY 3 SELECT (TIPOCF==\"C\")&&"  
 | 
						||
          << "STR(BETWEEN(CODCF,\"" << fromcod << "\",\"" << tocod << "\"))\n"
 | 
						||
     			<< "BY TIPOCF CODCF DATADOC\n"
 | 
						||
          << "FROM DATADOC=#DAL PROVV=D ANNO=" << year << "\n"
 | 
						||
          << "TO DATADOC=#AL PROVV=D ANNO=" << year << "\n";
 | 
						||
//    query << "USE DOC KEY 2 SELECT BETWEEN(DATADOC,#DADATA,#ADATA)&&STATO==\"2\")&&(TIPODOC==\"B01\")\n"
 | 
						||
//          << "FROM " << "TIPOCF=C PROVV=D ANNO=#ANNO DATADOC=#DADATA \n"
 | 
						||
//          << "TO "  << "TIPOCF=C PROVV=D ANNO=#ANNO DATADOC=#ADATA \n";
 | 
						||
     
 | 
						||
    //instanzio il recordset011
 | 
						||
 | 
						||
    TISAM_recordset recset(query);
 | 
						||
    recset.set_var("#DAL", dal);
 | 
						||
    recset.set_var("#AL", al);
 | 
						||
    TProgress_monitor pi(recset.items(), TR("Fatturazione"), true);
 | 
						||
    long last_clifo = 0;
 | 
						||
    int numdocgen = 0;
 | 
						||
    int numdocscart = 0;
 | 
						||
		
 | 
						||
		real totimp;
 | 
						||
		real imposta;
 | 
						||
		real totdoc;
 | 
						||
		real spese;
 | 
						||
    TToken_string key;
 | 
						||
 | 
						||
    //TAssoc_array dei clienti per cui ho generato dei documenti
 | 
						||
    TAssoc_array cliela;
 | 
						||
    //scorro tutti documenti che la query mi restiuisce
 | 
						||
    for (bool ok = recset.move_first(); ok; ok = recset.move_next())
 | 
						||
    {
 | 
						||
      //leggo il codcf
 | 
						||
      const long clifo = recset.get(DOC_CODCF).as_int();
 | 
						||
      if (clifo != last_clifo)
 | 
						||
      {
 | 
						||
        key.format("C|%ld", clifo);
 | 
						||
        TString str; 
 | 
						||
        str << TR("Cliente") << ' ' << clifo << ' ' << cache().get(LF_CLIFO, key, CLI_RAGSOC);
 | 
						||
        pi.set_text(str);
 | 
						||
        last_clifo=clifo;
 | 
						||
      }
 | 
						||
      
 | 
						||
      if (!pi.add_status())
 | 
						||
        break;
 | 
						||
      
 | 
						||
      //se non <20> l'ultimo cliente, allora:
 | 
						||
      if (clifo != lastcli)
 | 
						||
      {
 | 
						||
       //se effettivamente devo elaborare delle bolle per questo cliente, allora:
 | 
						||
       if (docsin.items() > 0)
 | 
						||
       {
 | 
						||
         //elaboro tutti i documenti, li salvo nei file di Campo e svuoto le TList_file
 | 
						||
         elab.put("B15", 'X');
 | 
						||
         elab.elabora(docsin, docsout, datafat);
 | 
						||
				 const int items = docsout.items();
 | 
						||
				 if (items > 0)
 | 
						||
				 {
 | 
						||
					 if (!_solototali)
 | 
						||
						 docsout.write();
 | 
						||
					 numdocgen += items;
 | 
						||
					 TString8 tmp;
 | 
						||
					 tmp << lastcli;
 | 
						||
					 cliela.add(tmp, tmp);
 | 
						||
				 }
 | 
						||
	  		 else if (!_solototali) //il messaggio deve comparire solo se non ho generato fatture
 | 
						||
				 {
 | 
						||
					 key.format("C|%ld", lastcli);
 | 
						||
           TString str;
 | 
						||
					 str << "Cli. " << lastcli << ' ' << cache().get(LF_CLIFO, key, CLI_RICALT) << TR(" non ha generato la fattura pur avendo bolle");
 | 
						||
					 log(str);
 | 
						||
					 numdocscart++;
 | 
						||
				 }
 | 
						||
 | 
						||
         //solo totali
 | 
						||
         if(_solototali)
 | 
						||
         {
 | 
						||
           for (int i = 0; i < items; i++)
 | 
						||
				   {
 | 
						||
					   const TDocumento & doc = docsout[i];
 | 
						||
 | 
						||
             totimp += doc.imponibile();
 | 
						||
				     imposta += doc.imposta();
 | 
						||
					   totdoc += doc.totale_doc();
 | 
						||
					   spese += doc.spese();
 | 
						||
				   }
 | 
						||
         }
 | 
						||
 | 
						||
         docsout.destroy(-1);
 | 
						||
				 if (!_solototali)
 | 
						||
	         docsin.rewrite();
 | 
						||
         docsin.destroy(-1);
 | 
						||
       }
 | 
						||
       lastcli = clifo;
 | 
						||
      }
 | 
						||
 | 
						||
      //preparo la chiave e recupero da CFVEN i dati di quel cliente
 | 
						||
      key.format("C|%ld", clifo);
 | 
						||
      const TRectype& clienti = cache().get(LF_CFVEN,key);
 | 
						||
			const TRectype& docrec = recset.cursor()->curr();
 | 
						||
      const TRectype& clirec = cache().get(LF_CLIFO,key);
 | 
						||
 | 
						||
      //se il documento che sto analizzando <20> corretto, allora:
 | 
						||
      bool cliok = elab.is_document_ok(docrec);      
 | 
						||
      if (cliok)
 | 
						||
      {
 | 
						||
        //se il codice di zona <20> pieno, allora:
 | 
						||
        if (mskzona.full())
 | 
						||
        {
 | 
						||
          //leggo il codice di zona standard di quel cliente e lo confronto con quello della maschera (V o F)
 | 
						||
          const TString& codzona = clienti.get(CFV_CODZONA);
 | 
						||
          cliok = (codzona == mskzona);
 | 
						||
        }
 | 
						||
 | 
						||
        //se il codice categoria economica <20> pieno e ho passato il test sul codice di zona, allora:
 | 
						||
        if (cliok && mskcat.full())
 | 
						||
        {
 | 
						||
          //leggo il codice categoria economica standard di quel cliente e lo confronto con quello della maschera (V o F)
 | 
						||
          const TString& codcat = clienti.get(CFV_CODCATC);
 | 
						||
          cliok = (codcat == mskcat);
 | 
						||
        }
 | 
						||
      }
 | 
						||
			else
 | 
						||
				if (!_solototali && elab.is_document_compatible(docrec) && docrec.get(DOC_STATO) < stato_min)
 | 
						||
				{
 | 
						||
					TString msg;
 | 
						||
					msg << "Cli. " << clifo << ' ' << clirec.get(CLI_RICALT) << " Bolla n. " << docrec.get(DOC_NDOC) << " del " << docrec.get(DOC_DATADOC)  << " in stato " << docrec.get(DOC_STATO);
 | 
						||
					log(msg);
 | 
						||
				}
 | 
						||
      
 | 
						||
      //se ho passato tutti e due i test, allora:
 | 
						||
      if (cliok)
 | 
						||
      {
 | 
						||
        //cerco sul contratto qual'<27> il periodo di fatturazione di quel cliente
 | 
						||
        indsped = recset.get(DOC_CODINDSP).as_int();
 | 
						||
        TLaundry_contract contr(clifo, indsped, datafat);
 | 
						||
        if(!contr.ok())
 | 
						||
        {
 | 
						||
          TString msg;
 | 
						||
          msg << TR("Non ci sono contratti in essere per il cliente ") << clifo << " " << clirec.get(CLI_RICALT) << TR(" in data ") << datafat.string();
 | 
						||
          log(msg);
 | 
						||
          continue;
 | 
						||
        }
 | 
						||
        const int contrper = contr.get_int(LVCONDV_PERFAT);
 | 
						||
        
 | 
						||
        //se il cliente non <20> sospeso e se si <20> nel periodo di fatturazione giusto, aggiungo il documento alla
 | 
						||
        //lista dei documenti da elaborare
 | 
						||
			  if (!contr.get_bool(LVCONDV_FATTSOSP) && contrper <= period)
 | 
						||
				{
 | 
						||
					TDocumento * doc = new TDocumento(recset.cursor()->curr());
 | 
						||
	
 | 
						||
					if (agghead && !_solototali && doc->get(DOC_CODNUM) == num_buoni && doc->tipo().codice() == tipo_buoni)
 | 
						||
					{
 | 
						||
 | 
						||
						bool doc_updated = false;
 | 
						||
						// banche
 | 
						||
 | 
						||
						key.cut(0);
 | 
						||
						key.add(clirec.get(CLI_TIPOCF));
 | 
						||
						key.add(clirec.get(CLI_CODCF));
 | 
						||
						key.add("V");
 | 
						||
						key.add("1");
 | 
						||
 | 
						||
						const TRectype & cfban = cache().get(LF_CFBAN, key);
 | 
						||
						TString8 abi;
 | 
						||
						TString8 cab;
 | 
						||
						TString iban;
 | 
						||
 | 
						||
						if (cfban.empty())
 | 
						||
						{
 | 
						||
							abi = clirec.get(CLI_CODABI);
 | 
						||
							cab = clirec.get(CLI_CODCAB);
 | 
						||
							iban = clirec.get(CLI_IBAN);
 | 
						||
						}
 | 
						||
						else
 | 
						||
						{
 | 
						||
							abi = cfban.get(CFBAN_ABI);
 | 
						||
							cab = cfban.get(CFBAN_CAB);
 | 
						||
							iban = cfban.get(CFBAN_IBAN);
 | 
						||
						}
 | 
						||
						if (cab.full() && cab != "00000")
 | 
						||
						{
 | 
						||
							doc_updated |= (doc->get(DOC_CODABIA) != abi) || (doc->get(DOC_CODCABA) != cab);
 | 
						||
							doc->put(DOC_CODABIA, abi);
 | 
						||
							doc->put(DOC_CODCABA, cab);
 | 
						||
							doc->put(DOC_IBAN, iban);
 | 
						||
						}
 | 
						||
						key.cut(0);
 | 
						||
						key.add(clirec.get(CLI_TIPOCF));
 | 
						||
						key.add(clirec.get(CLI_CODCF));
 | 
						||
						key.add("N");
 | 
						||
						key.add("1");
 | 
						||
 | 
						||
						const TRectype & cfbanpr = cache().get(LF_CFBAN, key);
 | 
						||
						int progbnp = 0;
 | 
						||
 | 
						||
						if (cfbanpr.empty())
 | 
						||
						{
 | 
						||
							abi = clienti.get(CFV_CODABIPR);
 | 
						||
							cab = clienti.get(CFV_CODCABPR);
 | 
						||
						}
 | 
						||
						else
 | 
						||
						{
 | 
						||
							abi = cfbanpr.get(CFBAN_ABI);
 | 
						||
							cab = cfbanpr.get(CFBAN_CAB);
 | 
						||
							progbnp = cfbanpr.get_int(CFBAN_PROGPR);
 | 
						||
						}
 | 
						||
 | 
						||
						if (cab.full() && cab != "00000")
 | 
						||
						{
 | 
						||
							doc_updated |= (doc->get(DOC_CODABIP) != abi) || (doc->get(DOC_CODCABP) != cab);
 | 
						||
							doc->put(DOC_CODABIP, abi);
 | 
						||
							doc->put(DOC_CODCABP, cab);
 | 
						||
							doc->put(DOC_PROGBNP, progbnp);
 | 
						||
						}
 | 
						||
						const TString8 codpag = clirec.get(CLI_CODPAG);
 | 
						||
						if (codpag.full())
 | 
						||
						{
 | 
						||
							doc_updated |= (doc->get(DOC_CODPAG) != codpag);
 | 
						||
							doc->put(DOC_CODPAG, codpag);
 | 
						||
						}
 | 
						||
						const TString8 spinc = clienti.get(CFV_PERCSPINC);
 | 
						||
						if (spinc.full())
 | 
						||
						{
 | 
						||
							doc_updated |= (doc->get(DOC_PERCSPINC) != spinc);
 | 
						||
							doc->put(DOC_PERCSPINC, spinc);
 | 
						||
						}
 | 
						||
						const bool addbolli = clienti.get_bool(CFV_ADDBOLLI);
 | 
						||
						doc_updated |= (doc->get_bool(DOC_ADDBOLLI) != addbolli);
 | 
						||
						doc->put(DOC_ADDBOLLI, addbolli);
 | 
						||
						const TString agente1 = clienti.get(CFV_CODAG1);
 | 
						||
						if (agente1.full())
 | 
						||
						{
 | 
						||
							doc_updated |= (doc->get(DOC_CODAGVIS) != agente1);
 | 
						||
							doc->put(DOC_CODAGVIS, agente1);
 | 
						||
						}
 | 
						||
						if (doc_updated)
 | 
						||
						{
 | 
						||
							TString msg(" Cli.");
 | 
						||
							msg << clifo << " " << clirec.get(CLI_RICALT) << "Bolla " << docrec.get(DOC_CODNUM) << ' ' << docrec.get(DOC_TIPODOC) 
 | 
						||
                  << ' ' << docrec.get(DOC_NDOC) << " del " << docrec.get(DOC_DATADOC)  << " aggiornata la testata ";
 | 
						||
							log(msg);
 | 
						||
						}
 | 
						||
					}
 | 
						||
					for (int r = 1; !_solototali && r <= doc->physical_rows(); r++)
 | 
						||
					{
 | 
						||
            const TRiga_documento& rdoc = (*doc)[r];
 | 
						||
						const TCodice_articolo codart = rdoc.get(RDOC_CODARTMAG);
 | 
						||
 | 
						||
						if (codart.full())
 | 
						||
						{
 | 
						||
							const TRectype & rcont = contr.row(codart);
 | 
						||
							const TArticolo_lavanderie& art = cached_article_laundry(codart, 'C', clifo, use_indsp ? indsped : 0);
 | 
						||
							//estraggo il record corrispondente su LF_CLIFOGIAC	
 | 
						||
							const TRecmag_lavanderie& rec = art.find_rec(annoes);
 | 
						||
 | 
						||
              TString str;
 | 
						||
              str << "Cli." << clifo << ' ' << clirec.get(CLI_RICALT) << " Bolla " << docrec.get(DOC_CODNUM) << ' ' << docrec.get(DOC_TIPODOC)
 | 
						||
								  << ' ' << docrec.get(DOC_NDOC) << " del " << docrec.get(DOC_DATADOC) << " art." << codart << " - ";
 | 
						||
 | 
						||
							if (rec.get_real("DOTOD") < ZERO)
 | 
						||
							{
 | 
						||
								TString msg;
 | 
						||
								msg << str << " Dot.odier.negativa";
 | 
						||
								log(msg);
 | 
						||
							}
 | 
						||
							if (rec.get_real("DOTIN") < ZERO)
 | 
						||
							{
 | 
						||
								TString msg;
 | 
						||
								msg << str << " Dot.iniz.negativa";
 | 
						||
								log(msg);
 | 
						||
							}
 | 
						||
 | 
						||
              bool prezzo_nullo = false;
 | 
						||
							if (prezzo_da_contratto)
 | 
						||
							{
 | 
						||
                // Segnalo prezzo nullo solo se il contratto non <20> ad importo fisso (07/11/2011)
 | 
						||
                prezzo_nullo = rcont.get_real(LVRCONDV_PREZZO).is_zero() && contr.get_real(LVCONDV_IMPFIX).is_zero();
 | 
						||
							}
 | 
						||
							else
 | 
						||
							{
 | 
						||
                prezzo_nullo = rdoc.get_real(RDOC_PREZZO).is_zero(); // Prezzo sulla bolla
 | 
						||
							}
 | 
						||
							if (prezzo_nullo)
 | 
						||
							{
 | 
						||
                const TString8 causale = rdoc.get(RDOC_CODAGG1);
 | 
						||
								const TCausale_lavanderie& cau = cached_causale_lavanderie(causale);
 | 
						||
                if (!cau.ignora_prezzo_zero())          // Segnalo anomalia solo se la causale lo prevede (07/11/2011)
 | 
						||
                {
 | 
						||
									TString msg;
 | 
						||
									msg << str << " Prezzo zero ";
 | 
						||
                  if (prezzo_da_contratto)
 | 
						||
                    msg << "sul contratto";
 | 
						||
                  else
 | 
						||
                    msg << "sulla bolla";
 | 
						||
									log(msg);
 | 
						||
                }
 | 
						||
							}
 | 
						||
						}
 | 
						||
					}
 | 
						||
 | 
						||
          docsin.add(doc);
 | 
						||
				}
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    //se ho dei documenti in lista li elaboro e poi svuoto le TList_file
 | 
						||
    if (docsin.items() != 0)
 | 
						||
    {
 | 
						||
      if (ini_get_bool(CONFIG_DITTA, "lv", "RifTest"))
 | 
						||
        elab.put("B15", true);  //forzo la descrizione abbreviata
 | 
						||
      elab.elabora(docsin, docsout, datafat);
 | 
						||
 | 
						||
			const int items = docsout.items();
 | 
						||
			
 | 
						||
			if (items > 0)
 | 
						||
			{
 | 
						||
				if (!_solototali)
 | 
						||
					docsout.write();
 | 
						||
				numdocgen += items;
 | 
						||
				TString tmp;
 | 
						||
				tmp << lastcli;
 | 
						||
				cliela.add(tmp, tmp);
 | 
						||
				for (int i = 0; i < items; i++)
 | 
						||
				{
 | 
						||
					const TDocumento & doc = docsout[i];
 | 
						||
 | 
						||
					totimp += doc.imponibile();
 | 
						||
					imposta += doc.imposta();
 | 
						||
					totdoc += doc.totale_doc();
 | 
						||
					spese += doc.spese();
 | 
						||
				}
 | 
						||
			}
 | 
						||
 		  else
 | 
						||
				if (!_solototali)
 | 
						||
				{
 | 
						||
					TString str;
 | 
						||
					TToken_string key;
 | 
						||
 | 
						||
					key.add('C');
 | 
						||
					key.add(lastcli); 
 | 
						||
					str << "Cli." << lastcli << ' ' << cache().get(LF_CLIFO, key, CLI_RICALT) << " non ha generato la fattura pur avendo bolle";
 | 
						||
					_log->log(0, str);
 | 
						||
					numdocscart++;
 | 
						||
				}
 | 
						||
      docsout.destroy(-1);
 | 
						||
			if (!_solototali)
 | 
						||
				docsin.rewrite();
 | 
						||
      docsin.destroy(-1);
 | 
						||
    }
 | 
						||
 | 
						||
    genera_bolle_nolo(cliela, elab, numdocgen, totimp, imposta, totdoc, spese);
 | 
						||
    numdocgen += elab.write_fatt_ragg(_solototali);
 | 
						||
		
 | 
						||
		TString str;
 | 
						||
    const char* const parolapl = _solototali ? TR("generate") : TR("elaborate");
 | 
						||
    const char* const parolasi = _solototali ? TR("generata") : TR("elaborata");
 | 
						||
 | 
						||
    switch (numdocgen)
 | 
						||
    {
 | 
						||
    case  0: str << TR("Non <20> stata ") << parolasi << TR(" alcuna fattura"); break;
 | 
						||
    case  1: str << TR("E' stata ") << parolasi << TR(" una fattura"); break;
 | 
						||
    default: str << TR("Sono state ") << parolapl << ' ' << numdocgen << TR(" fatture"); break;
 | 
						||
    }
 | 
						||
    if (numdocgen <= 0)
 | 
						||
      warning_box(str);
 | 
						||
    else
 | 
						||
      message_box(str);
 | 
						||
 | 
						||
    message_box(TR("Elaborazione terminata"));
 | 
						||
		str = TR("Clienti Danneggati Articoli danneggiati");
 | 
						||
		_log->log(0, str);
 | 
						||
		str.format("                    %5d                       %5d", elab.cli_damn(), elab.art_damn());
 | 
						||
		_log->log(0, str);
 | 
						||
		str = "Numero fatture    Imponibile        Imposta          Totale         Spese";
 | 
						||
		_log->log(0, str);
 | 
						||
		str.format("               %5d", numdocgen);
 | 
						||
		str << totimp.stringa(17) << imposta.stringa(16) << totdoc.stringa(15) << spese.stringa(17);
 | 
						||
		_log->log(0, str);
 | 
						||
		str = TR("Numero fatture scartate");
 | 
						||
		_log->log(0, str);
 | 
						||
		str.format("                            %5d", numdocscart);
 | 
						||
		_log->log(0, str);
 | 
						||
		_log->print_or_preview();
 | 
						||
		
 | 
						||
    delete _log; _log = NULL;
 | 
						||
  }
 | 
						||
}
 | 
						||
 
 | 
						||
int lv2500(int argc, char *argv[])
 | 
						||
{
 | 
						||
  TFatturazione_lav_app a;
 | 
						||
  a.run (argc, argv, TR("Fatturazione lavanderie"));
 | 
						||
  return TRUE;
 | 
						||
}
 |