#ifndef __VELIB04_H
#define __VELIB04_H

#ifndef __VELIB_H
#include "velib.h"
#endif

#ifndef __CALIB01_H
#include "../ca/calib01.h"
#endif

class TLista_documenti : public TObject  // velib04
{ 
  TArray _documenti;
  
protected:  
  const TDocumento& doc(int n) const { return (const TDocumento&)_documenti[n]; }
  TDate num2date(char provv, int anno, const char* codnum, long num) const;

public:
	bool find(char provv, int anno, const char * codnum, long ndoc) const;
  int read(char provv, char tipo, long clifo, int anno, 
           TToken_string& tipidoc, TToken_string& statidoc,
           const TDate& dd, const TDate& ad, 
           const char* codnum = "", long dn = 0L, long an = 0L);
  int write(bool re = false) const;
  int rewrite() const { return write(true); }
  
  int add(TDocumento* doc) { return _documenti.add(doc); }
  int add(const TDocumento& doc) { return _documenti.add(doc); }
  int destroy(int i, bool pack = true) { return _documenti.destroy(i, pack); }
  
  const TDocumento& operator[] (int n) const { return doc(n); }
  TDocumento& operator[] (int n) { return (TDocumento&)_documenti[n]; }
  int items() const { return _documenti.items(); }

  TLista_documenti() { }
  virtual ~TLista_documenti() {};
};
     
///////////////////////////////////////////////////////////
// Lista Cliente/Fornitore per vendite
///////////////////////////////////////////////////////////

class TLista_clifo : public TObject  // velib04
{                
  class TClifo : public TObject
  { 
    long _codice;
    long _agente;
    long _zona;
    
  protected:
    void zero() { _codice = _agente = _zona = 0L; }  
    void init(const TRectype& rec, const TRectype& ven); 
    bool read(char tipo, long cod);
  
  public: // TObject
    virtual bool ok() const { return _codice > 0; }
  
  public:     
    long codice() const { return _codice; }
    long agente() const { return _agente; }
    long zona() const { return _zona; }
  
    TClifo() { zero(); }
    TClifo(char tipo, long cod) { read(tipo, cod); }
    TClifo(const TRectype& rec, const TRectype& ven) { init(rec, ven); }
    TClifo(const TRectype& rec);
    virtual ~TClifo() { }
  };

  TArray _clifo;
  
protected:  
  virtual char tipo() const pure;
  const TClifo& clifo(int n) const { return (TClifo&)_clifo[n]; }
  
  static int sort_by_code(const TObject** o1, const TObject** o2);
  static int sort_by_agent(const TObject** o1, const TObject** o2);
  static int sort_by_zone(const TObject** o1, const TObject** o2);

public:
  int ordina_per_codice();
  int ordina_per_agente();
  int ordina_per_zona();
  
  int leggi(long dc, long ac, long da = 0, long aa = 0, const char * dz = "", const char * az = "");
  int leggi_ragsoc(const char *dr, const char * ar, long da = 0, long aa = 0, const char * dz = "", const char * az = "");
 
  long operator[] (int n) const { return clifo(n).codice(); }
  int items() const { return _clifo.items(); }
  int find(long cod) const;
  int add(long cod);

  TLista_clifo() { }
  virtual ~TLista_clifo() { }
};

class TLista_clienti : public TLista_clifo 
{
protected:
  virtual char tipo() const { return 'C'; }
};

class TLista_fornitori : public TLista_clifo 
{
protected:
  virtual char tipo() const { return 'F'; }
};

class TLista_cf : public TLista_clifo 
{
  char _tipo;

protected:
  virtual char tipo() const { return _tipo; }

public:
  TLista_cf(char tipo) : _tipo(tipo) {}
};

enum TTipo_elaborazione { _esterna, _consegna_ordini, _fatturazione_bolle, 
                          _contabilizzazione, _copia_documento, 
                          _generazione_effetti, _consuntivazione_produzione,
                          _contabilizzazione_analitica };

class TParametri_elaborazione : public TObject // velib04
{      
  TAssoc_array _par;

public:  
  void set(const char * name, const char * val);
  void set(const char * name, const real & val) { set(name, val.string());}
  
  const TString & get(const char * name) const ;
  const real get_real(const char * name) const { return (real) get(name);}
  
  TParametri_elaborazione & copy(const TParametri_elaborazione & p) { _par = p._par; return *this;}
  virtual TObject* dup() const { return new TParametri_elaborazione(*this); }
  TParametri_elaborazione & operator =(const TParametri_elaborazione & p) {return copy(p);}
  TParametri_elaborazione() { }
  TParametri_elaborazione(const TParametri_elaborazione & p) {copy(p);}
  virtual ~TParametri_elaborazione() { }
};

class TElaborazione : public TRectype // velib04
{ 
  TParametri_elaborazione _parms;
  
protected:
  int read(const char* cod);
  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) {}

public:
  enum  { _max_tipi_doc_elab = 10 };
  const TString& codice() const { return get("CODTAB"); }
  const TString& descrizione() const { return get("S0"); }
  const TTipo_elaborazione tipo() const { return (TTipo_elaborazione) get_int("I0"); } 

  virtual void tipi_stati_iniziali(TToken_string& tipi, TToken_string& stati) const;                     


  bool doc_uguale(int u) const  { return get("S1").mid(u, 1) == "X"; }
  bool riga_uguale(int u) const { return get("S1").mid(40+u, 1) == "X"; }
  
  bool raggruppa_righe() const      { return get_bool("B0"); }
  virtual bool gestione_riferimenti() const { return get_bool("B1"); }
  virtual bool riferimenti_in_testa() const { return get_bool("B2"); }
  bool ignora_descrizioni() const   { return get_bool("B3"); }
  char tipo_numerazione() const     { return get_bool("B4") ? 'P' : 'D'; }
	bool protocollo_da_registro() const { return get_bool("B4"); }
  bool prezzo_da_ordine() const     { return get_bool("B5"); }
  bool aggiorna_testata_se_vuoto() const { return get_bool("B6"); }
  bool ordina_per_codice() const     { return get_bool("B7"); }
  bool usa_doc_rif() const     { return get_bool("B8"); }
  bool usa_data_consegna() const     { return get_bool("B9"); }
  bool kill_descrizione_estesa() const { return get_bool("B10"); }
  bool pack_rif() const { return get_bool("B15"); }
	bool calcola_scarti() const { return get_bool("B11"); }
 	bool reload_prices() const { return get_bool("B13"); }
	const TString & num_riferimenti_in() const { return get("S11"); }

  int intestazioni_sheet() const { return get_int("I1"); }

  const TString& codice_numerazione_iniziale() const { return get("S5"); }
  const TString tipo_iniziale(int i) const { return get("S2").smid(i*4, 4).rtrim(); }
  const char stato_iniziale(int i) const { return i < 5 ? get("S7")[i] : get("S10")[i - 5]; }
  const TString& tipo_finale() const { return get("S8"); }
  const TString& stato_finale_doc_iniziale() const { return get("S4"); }
  const TString& stato_finale() const { return get("S9"); }
  
  const TString& codice_numerazione_finale() const { return get("S6"); }
  const TString& applicazione_esterna() const { return get("S3"); }
  void set_params(const TParametri_elaborazione & parms) { _parms = parms;}
	bool is_document_ok(const TRectype & doc) const ;
  TParametri_elaborazione & params() { return _parms;}
  
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false) pure;

  TElaborazione(const char* cod);
  TElaborazione(const TRectype& rec) : TRectype(rec) { }
  virtual ~TElaborazione() { }
};

class TElaborazione_esterna : public TElaborazione  // velib04
{ 
public:
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);

  TElaborazione_esterna(const char* cod);
  TElaborazione_esterna(const TRectype& rec) : TElaborazione(rec) { }
  virtual ~TElaborazione_esterna() { }
};

class TConsegna_ordini : public TElaborazione  // velib04d
{ 
protected:
  bool calcola_ncolli_tara_pnetto(const TString& codart, const real& qta,
                                  real& nolli, real& tara, real& pnetto) const;
  bool aggiorna_ncolli_tara_pnetto(TRiga_documento& r) const;
  bool genera_righe_riferimento(const TDocumento& indoc, TDocumento& outdoc, TSheet_field& s) const;

public:
	bool nettifica() const { return get_bool("B12"); }
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);

  TConsegna_ordini(const char* cod) : TElaborazione(cod) { }
  TConsegna_ordini(const TRectype& rec) : TElaborazione(rec) { }
  virtual ~TConsegna_ordini() { }
};

class TFatturazione_bolle : public TElaborazione  // velib04a
{ 
	TToken_string _cod_desc, _lista_campi, _rowsort;
	bool _cambia_codice;
	real _impminfat;

protected:
	virtual void campi_raggruppamento_righe(TToken_string& campi_riga) const;
	virtual void campi_raggruppamento(TToken_string& campi) const;
	virtual bool doc_raggruppabile(const TDocumento & doc) const { return doc.raggruppabile(); }
	virtual bool doc_raggruppabili(const TDocumento & doc_in, const TDocumento & doc_out, TToken_string & campi) const;

	virtual void add_rows(TRiga_documento & rout, TRiga_documento & rin) { rout += rin; }
  virtual void create_row(TDocumento& doc_out, const TRiga_documento & rin);
	virtual const TString & get_tipo_out(const TDocumento & doc_out) { return get("S8"); }
  virtual bool da_raggruppare(const TRiga_documento & rin) { return true; }
	virtual void elabora_riga(TRiga_documento& r, TDocumento& doc_out, bool usa_dcons, bool ragg_rig, bool ignora_desc,
      											TToken_string & campi_riga, const TDate & dcons, const TDate & ddoc);

public:
  virtual bool raggruppa(TDocumento& din, TDocumento& dout);
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);
                       
	bool change_clifo() { return get_bool("B14"); }
  
  TFatturazione_bolle(const char* cod);
  TFatturazione_bolle(const TRectype& rec);
  virtual ~TFatturazione_bolle() { }
};

// Tipi di errore validi solo per TContabilizzazione e TGenerazione_effetti

enum error_type {
  no_error,
  nr_es_error,
  nr_reg_error,
  nr_doc_error,
  chg_stat_error,
  clifo_error,
  ultprot_error,
  datadoc_error,
  caus_error,
  causre_error,
  cauval_error,
  ivasto_error,
  register_error,
  change_error,
  val_error,
  codpag_error,
  row_type_error,
  no_rows_error,
  contocf_error,
  conto_error,
  sconto_error,
  spinbo_error,
  movement_error,
  write_error,
  scadenze_error,
  bank_error,
  caus_ant_error,
  counter_p_ant_error,
  cau_abb_error,
  cau_spe_error,
  write_part_error,
  intra_mov_error,
  intra_rett_error,
  cont_seq_error,
  cau_ritintra_error,
	m770_write_error,
  generic_error
};

class TBill;
class TSaldo_agg;


///////////////////////////////////////////////////////////
// TContabilizzazione
///////////////////////////////////////////////////////////

// TMovimentoPN_VE
// Classe derivata da TMovimentoPN per calcolare automaticamente le righe conabili
// una volta settate le righe iva e la riga di totale documento
// Sostanzialmente di tratta di aggiungere un metodo in piu' :
// recalc_cg_rows(), liberamente ispirato alla notify_iva() in cg2102.cpp

class TMovimentoPN_VE : public TMovimentoPN
{
  bool     _valuta;
  TCausale * _caus;
  
protected:
  // simula il K_ENTER di iva_notify
  void enter_row(int i, const TString & descr_cr);
  // cerca la prima tra quelle di contabilita' che corrisponde al tipo indicato 
  int type2pos(char tipo);
  // Trova nelle righe contabili un conto nelle righe di tipo prescelto
  int bill2pos(const TBill& conto, char tipo);
  // trasforma un real in TImporto, in base al tipo riga
  TImporto real2imp(const real& r, char row_type);
  // setta il record delle righe di contabilita'
  int insert_cg_rec(int n, const TImporto& imp, TBill& conto, const char* desc, char tipo);
  // setta il record delle righe di contabilita'
  int set_cg_rec(int n, const TImporto& imp, const TBill& conto, const char* desc, char tipo);
  // aggiunge l'importo indicato alla n-esima riga di contabilita'
  bool add_cg_rec(int n, const TImporto& imp);
  // Legge l'importo della riga n e lo ritorna col segno dovuto
  TImporto get_cg_imp(int n);
  // Setta l'importo della riga n 
  void set_cg_imp(int n, const TImporto& imp);

public:
  void set_caus(TCausale * c) { _caus = c;}
  bool movement_ok() ;
  void add_row_re(int i);
  void add_row_tot_re(TDocumento& doc);
	bool add_row_cp_re(int i);
  void map_conto_re(TBill & c);
  void destroy_iva_row(int i = -1);
  int recalc_cg_rows(const TString & descr_cr, TCausale & caus);
  TMovimentoPN_VE(bool valuta) : _valuta(valuta), _caus(NULL) {};
  virtual ~TMovimentoPN_VE() {}
};

class TContabilizzazione : public TElaborazione  // velib04b
{ 
  bool                _auto_data; // Flag per data di registrazione automatica
  bool                _nump_iva;  // se true prende il numero protocollo da registro iva, se no prende il numero protocollo dal numero doc.
  TDate               _data_reg;  // Data di registrazione documenti
  long                _total_docs;// Numero di documenti contabilizzati
  error_type          _error;     // Errore rilevato durante l'elaborazione
	int									_nrow;			// numero di riga documento errata
  bool                _can_write; // se true e' abilitata la scrittura. Non appena rileva un errore rimane a false for this instance
  TString16           _spin_cod,  // codice iva spese d'incasso
                      _spbo_cod;  // codice iva spese bolli
  TAssoc_array        _totali_lordi;// array per totalizzare i lordi per aliquota, al fine di aggiustare gli imponibili
                                    // nel caso di calcolo lordo sul documento
  TIVA_array          *_righe_iva; // array per la memorizzazione delle righe iva raggruppate in codesto modo:
                                   // CODICE_IVA+TIPOCF+GRUPPO+CONTO+SOTTOCONTO+COMMESSA+FASE+DETRAIBILITA
                                   // una volta completo, tale array viene scorso per comporre le righe IVA
                                   // del movimento
  
  // Files, tabelle, oggetti contabili ed altre amenita'...
  TLocalisamfile      *_anamag,   // file delle anagrafiche di magazzino
                      *_fcaus,
                      *_frcaus,
                      *_attiv,
                      *_part,
                      *_scad,
                      *_pags,
                      *_intra,
                      *_rintra,
                      *_occas,
                      *_saldi,
                      *_docfile,
                      *_rdocfile;

  TTable              *_cpg,      // tabella condizioni di pagamento
                      *_gmc,      // tabella gruppi/sottogruppi merceologici
                      *_rfa,      // tabella raggruppamenti fiscali
                      *_cve,      // tabella categorie di vendita
                      *_val,      // tabella valute estere
                      *_prs,      // tabella prestazioni
                      *_spp,      // tabella spese
                      *_caa,      // tabella categorie acquisto articoli
                      *_cra,      // tabella categorie ricavo articoli
                      *_cco;      // tabella categorie contabili
  TRelation           *_clifo;    // relazione dei clienti e fornitori + cfven
  TViswin*  _viswin;              // Visualizzazione log di elaborazione
  TBill _conto_errato;            // Conto da visualizzare in messaggio d'errore
  bool _check_prev_cont;          // Controllare se il documento precedente e' stato contabilizzato
	TString16 _fld_cms_cont;        // Campo delle commesse per reperire la causale
                                                                                                   
protected:
  // Carica i parametri dalla configurazione
  bool load_parameters();        
  // Testa il fatto che il documento sia una nota di credito/debito
  bool test_swap();
	// Istanzia la causale contabile
	TCausale * get_caus(const TDocumento& doc, const int year);

  // Ritorna l'ultimo numero di registrazione disponibile dei movimenti di prima nota
  error_type   get_next_reg_num(long &);
  // Compila la testata del movimento
  error_type   compile_head_mov(TDocumento&);
  // Compila la testata del movimento per le fatture da emettere / ricevere;
  error_type   compile_head_mov_re(TDocumento&);
	bool spalma_spese() const { return get("I2") == "X"; }
	// Funzione per distribuire le spese
	void split_sp_amount(const real & amount, int decimals);
	// Funzione per ricercare il conto di costo/ricavo
  error_type   search_costo_ricavo(TBill& conto, const TRiga_documento& r, real & amount_to_split, const real & valore);
  // Funzione per ricercare il conto di costo/ricavo materiali
  error_type   search_costo_ricavo_mat(TBill&, const TRiga_documento&);
  // Funzione per aggiungere la riga iva al TAssoc_array _righe_iva
  //  error_type   add_iva_row(const TBill&, const TRiga_documento&, const int ndec, const real p = 1.0);
  // Funzione atomica per aggiungere le righe di spese d'incasso e bolli al TAssoc_array _righe_iva
  void calculate_spese(real&, real&, int, bool, bool, const TString &, const TDocumento & );
  // Funzione per aggiungere le righe di spese d'incasso e bolli al TAssoc_array _righe_iva (chiama calculate_spese())
  error_type   add_spese_inbo(TDocumento&, const int);
  // Aggiorna le righe di sconto importo o percentuale
  error_type   adjust_sconto_rows(TDocumento&);
  // Controlla la corrispondenza tra limposta del documento e quelle generate
  error_type   adjust_iva_rows(TDocumento&);
  // Crea le righe iva sul movimento
  error_type   create_iva_rows(TDocumento&);
  // Crea la riga di totale documento
  error_type   create_total_doc_row(TDocumento&);
  // Compila le righe del movimento
  error_type   compile_rows_mov(TDocumento&);
  // Compila le righe del movimento  per le fatture  da emettere / ricevere
  error_type   compile_rows_mov_re(TDocumento&);
  // scrive le scadenze
  error_type write_scadenze(TDocumento&);
  // scrive il movimento e le scadenze
  virtual error_type write_all(TDocumento& doc, TMovimentoPN_VE & movimento);
  // scrive il movimento e le scadenze per le fatture da emettere / ricevere
  virtual error_type write_all_re(TDocumento& doc, TMovimentoPN_VE & movimento);
  // restituisce la sezione per sto cliente
  char sezione() const;
  // Cerca il conto cliente per il movimento d'anticipo
  error_type search_clifo_bill(const TString& catven);
  // Cerca il conto di contropartita per il movimento d'anticipo
  error_type search_counter_bill(TDocumento& doc, const TDate& datareg);
  // compila la testata del movimento di anticipo
  error_type compile_head_anticipo(TDocumento&);
  // compila le righe del movimento di anticipo
  error_type compile_rows_anticipo(TDocumento&);
  // compila e scrive il pagamento del movimento di anticipo
  error_type write_pagamento_anticipo(TDocumento&);
  // scrive il movimento di anticipo pagamento
  error_type write_anticipo(TDocumento&);
  // scrive il movimento INTRA
  error_type write_intra(TDocumento&);
  error_type write_anal(TDocumento& doc, const TMovimentoPN& mv);
	error_type write_percip(TDocumento& doc, const TMovimentoPN& movimento);
  TRecnotype kill_righe_percip(TIsam_handle logic, char tipopercip, long codpercip, long nprog) const;
  
  // Aggiorna i saldi
  void aggiorna_saldi(TSaldo_agg& saldo, TMovimentoPN& mv, bool save);
  // Visualizza l'ultimo errore rilevato
  void display_error(TDocumento&);
  // Verifica se non ci sono stati errori
  bool good() const { return _error == no_error;}
  // Ritorna true se il saldaconto e' abilitato (verifica anche la causale del documento corrente)
  bool   sc_enabled(const TDate& data) const ; 
  // Ritorna true se il modulo INTRA  e' abilitato (verifica anche la causale del documento corrente)
  bool   in_enabled() const ; 
  // Controlla se il tipo riga esiste
  bool valid_row_type(const char* rt) const;
	virtual void export_movimento(TMovimentoPN_VE & mov, TViswin & v) {};
	virtual bool exporting() { return false; }

public:
  // Cambia lo stato del documento
  error_type   change_doc_status(TDocumento&);
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);
  void set_auto(const bool a) { _auto_data = a; }
  void set_writeable(const bool b) { _can_write = b; }
  const long processed_docs() const { return _total_docs; }                        
  void inc_processed_docs() { _total_docs++; }
  
  // Ritorna il numero dell'eventuale movimento con cui il documento stato contabilizzato                                                    
  long doc_contabilized(const TDocumento& doc, bool anticipo) const;

   // Personalizzazioni
  bool call_exe(const TDocumento& doc, const TMovimentoPN& movimento) const;
                                                     
  // Ritorna true se il documento precedente a doc e' gia' stato contabilizzato                                                    
  bool prev_contabilized(const TDocumento& doc) const;

  TContabilizzazione(const char* cod);
  TContabilizzazione(const TRectype& rec);
  virtual ~TContabilizzazione();
};


class TCopia_documento : public TElaborazione  // velib04
{ 
	bool _preserve_original_rif;

public:
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);
	void preserve_original_rif(bool on = true) { _preserve_original_rif = on;}

  TCopia_documento(const char* cod);
  TCopia_documento(const TRectype& rec) : TElaborazione(rec), _preserve_original_rif(false) { }
  virtual ~TCopia_documento() { }
};


class TGenerazione_effetti : public TElaborazione  // velib04c
{ 
  error_type     _error;       // Errore rilevato durante l'elaborazione
  long           _total_bills; // Totale effetti generati
  bool           _can_write;   // se true e' abilitata la scrittura. Non appena rileva un errore rimane a false for this instance
  TBit_array     _valid_array; // array dei tipi di pagamento validi per la generazione di effetti
	real					 _impmin;

  TLocalisamfile *_efffile,    // file effetti
                 *_refffile,   // file righe di effetti
                 *_cessfile,
                 *_docfile,
                 *_rdocfile,
                 *_clifo,
                 *_cfven,
                 *_tab,
                 *_occas;
  TArray         _effetti_array;//Array di effetti (TEffetto) da scrivere
protected:
  // Visualizza l'ultimo errore rilevato
  void display_error(TDocumento& doc);
  // Restituisce true se il tipo di pagamento passato e' valido per generare l'effetto
  bool   valid_type(int) const ;
  // Genera l'effetto
  void   generate_bill(TDocumento& doc, bool interattivo);
  // Istanzia il pagamento corrente
  void   calc_pagamento(TDocumento&);
  // Scrive i record array degli effetti raggruppati
  error_type write_groups(bool interattivo);
  // Cambia lo stato dei gruppi di documenti raggruppati in effetti
  error_type change_group_status(TDocumento&, TAssoc_array&);
  // Cambia lo stato del documento
  error_type change_doc_status(TDocumento&);
  // Verifica se non ci sono stati errori
  bool good() const { return _error == no_error;}
public:
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);
                           
  // Effettua il raggruppamento vero e proprio degli effetti (solo se ci sono elementi nell'assoc_array passato)
  long   group_bills(TAssoc_array& group_array, bool interattivo);
  long bills() const { return _total_bills; }
//  void set_group(TAssoc_array& a) { _group_array = a; }
  void set_writeable(const bool b) { _can_write = b; }
  
  TGenerazione_effetti(const char* cod);
  TGenerazione_effetti(const TRectype& rec);
  virtual ~TGenerazione_effetti();
};

class TConsuntivazione_produzione : public TElaborazione  // velib04e
{ 
protected:
	bool ref2doc(char & provv, int & anno, TString8 & codnum, long & ndoc, int & nriga, const TString & codart);

public:
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);

  TConsuntivazione_produzione(const char* cod) : TElaborazione(cod) { }
  TConsuntivazione_produzione(const TRectype& rec) : TElaborazione(rec) { }
  virtual ~TConsuntivazione_produzione() { }
};


class TCache_causali;  // Internal use only

class TContabilizzazione_analitica : public TElaborazione  // velib04f
{ 
  TCache_ripartizioni _rip;
  
  TToken_string _search_seq;
  TBill _sco_perc_bill_an, _sco_imp_bill_an, _spin_billa, _spin_billv, _spbo_billa, _spbo_billv;
	TString _spin_cod, _spbo_cod;
  TCache_causali* _caus;
	TString16 _fld_cms_cont;
  long _total_docs;// Numero di documenti contabilizzati

  error_type _error;       // Errore rilevato durante l'elaborazione
	bool _usepdcc;

protected:
  bool find_conti_iva_indetraibile(const TRiga_documento& riga, const TBill & bill, TString_array& conti, int annoes, const char tipomov, bool & pareggio);
	bool spalma_spese() const { return get("I2") == "X"; }
	void split_sp_amount(TAnal_mov & mov, bool pareggio,  const TImporto & totdoc, const TBit_array & spese, const real & amount, const real & no_ca_amount, int decimals);
  bool find_conti(const TRiga_documento& riga, TString_array& conti, int annoes, bool riclassifica_fdr_fde, const char tipomov, real & amount_to_split, real & no_ca_amount,  const real & valore, bool & pareggio);
	void init();

  virtual const TCausale& doc2caus(const TDocumento& doc);
  const TCausale& rdoc2caus(const TRiga_documento& rdoc);

  void init_distrib(TString_array& conti, TGeneric_distrib& distrib, bool pareggio);
  void calcola_date_comp(const TDocumento& doc, TDate& datacomp, TDate& datafcomp, int annoes);

public:
	bool search_costo_ricavo(const TRiga_documento& riga, TBill& conto, bool riclassifica_fdr_fde);
  const long processed_docs() const { return _total_docs; }
  virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                       const TDate& data_elab, bool interattivo = false);
  virtual bool elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, TAnal_mov& mov, 
               bool riclassifica_fdr_fde = true);

  TContabilizzazione_analitica(const char* cod = NULL);
  TContabilizzazione_analitica(const TRectype& rec);
  TContabilizzazione_analitica(const TContabilizzazione & el);
  virtual ~TContabilizzazione_analitica();
};

#endif