Files correlati : ef0.exe Ricompilazione Demo : [ ] Commento : Importazione effetti da ini (CHIMA) git-svn-id: svn://10.65.10.50/branches/R_10_00@21489 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1522 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1522 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|    ef0800.cpp: programma di contabilizzazione effetti
 | |
|  Ho visto ombre di sconforto riemergere dal passato...
 | |
|       al largo dei bastioni di Orione
 | |
| 
 | |
|                              _|_|_  
 | |
|                            ^/ . ..\^
 | |
|                        ___[=========]___
 | |
|             ___-==++""" .  /. . .  \ .  """++==-___
 | |
|       __-+"" __\   .. . .  | ..  . |  . .  .   /__ ""+-__
 | |
|      /\__+-""   `-----=====\_ <O> _/=====-----'   ""-+__/\
 | |
|    _/_/                      ""=""                      \_\_
 | |
|  
 | |
|          _________ .-~~~-..---..-~~~-. __________
 | |
|       -~.--<<<<<<<`-...--'.---.`--...-'>>>>>>>--.~-
 | |
|   =~~.-~         ````\\_`(`._.')'_//''''         ~-.~~=
 | |
| [(o)/                   ``.._..''                   \(o)
 | |
|  
 | |
|   .___________________          _-_
 | |
|   .\==============_=_/ ____.---'---`---.____
 | |
|   .           \_ \    \----._________.----/
 | |
|   .             \ \   /  /    `-_-'
 | |
|   .         __,--`.`-'..'-_
 | |
|   .        /____          ||
 | |
|   .             `--.____,-'
 | |
|  
 | |
| 
 | |
|  Did you see my apogee ?
 | |
| */
 | |
| 
 | |
| #include <applicat.h>
 | |
| #include <automask.h>
 | |
| #include <modaut.h>
 | |
| #include <progind.h>
 | |
| #include <sheet.h>
 | |
| 
 | |
| #include "../cg/cg2101.h"
 | |
| #include "../cg/cg2103.h"
 | |
| #include "../cg/cgsaldac.h"
 | |
| #include "../cg/cglib02.h"
 | |
| #include "../ve/velib04.h"
 | |
| #include "ef0301.h"
 | |
| #include "ef0800a.h"
 | |
| 
 | |
| #include <mov.h>
 | |
| #include <rmov.h>
 | |
| #include <rmoviva.h>
 | |
| #include <clifo.h>
 | |
| #include <effetti.h>
 | |
| #include <pagsca.h>
 | |
| #include <doc.h>
 | |
| 
 | |
| #define CGROWS_LIMIT 96 // Limite imposto da invii/ricezioni
 | |
| 
 | |
| #define DIST_INCASSO 'I'
 | |
| #define DIST_SBF     'B'
 | |
| #define DIST_SCONTO  'S'
 | |
| 
 | |
| // TContabilizzazione_mask
 | |
| 
 | |
| class TContabilizzazione_mask : public TAutomask
 | |
| {   
 | |
| protected:
 | |
|   virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
 | |
| 
 | |
| public:
 | |
|   TContabilizzazione_mask();
 | |
| };
 | |
| 
 | |
| // TContabilizzazione_effetti_app
 | |
| // Applicazione di contabilizzazione effetti
 | |
| class TContabilizzazione_effetti_app : public TSkeleton_application
 | |
| {
 | |
|   TDate         _data_op;      // Data operazione
 | |
|   TString16     _cod_caus;     // Codice causale
 | |
|   TString16     _cod_caus_pag; // Codice causale pagamenti
 | |
|   int           _cod_es;       // Codice/anno esercizio
 | |
|   bool          _sc_enabled;   // se TRUE il saldaconto di ditta e' abilitato
 | |
|   bool          _can_write;    // se TRUE e' abilitata la scrittura. Non appena rileva un errore rimane a FALSE for this instance  
 | |
|   real          _total_mov,    // Totale del movimento corrente
 | |
|                 _total_mov_val;// Same as above but in valuta
 | |
|   TString       _desc_inc, _desc_pag;  // Descrizioni movimento generato              
 | |
|   TMask         *_msk;         // maschera di selezione dati
 | |
| //  TLocalisamfile *_attiv,      // file delle attivita' (per far funzionare TRegistro)
 | |
| //                 *_fcaus,      // file delle causale (per far funzionare TCausale)
 | |
| //                *_frcaus,     // file delle righe causali (per far funzionare TCausale)
 | |
| //                *_effetti,    // file degli  effetti (per TDistinta)
 | |
| //                 *_reffetti,   // file delle righe effetti (per TDistinta)
 | |
| //                 *_cessionari, // file dei cessionari      (per TDistinta)
 | |
| //                 *_part,       // file delle partite (per far funzionare TPartita)
 | |
| //                 *_scad,       // file delle scadenze (per far funzionare TPartita)
 | |
| //                 *_pags,       // file dei pagamenti (per far funzionare TPartita)
 | |
| //                 *_clifo,      // file dei clienti
 | |
| //                 *_doc,        // file dei documenti 
 | |
| //                 *_pcon;       // file piano dei conti
 | |
|   TBill          _banca,       // conto di contropartita della banca
 | |
|                  _cliente,     // conto di contropartita del cliente
 | |
|                  _trandiffcam; // conto di transizione per differenze cambi
 | |
|   TArray_sheet   *_dist_sheet; // array_sheet di distinte selezionabili per la conatabilizzazione
 | |
|   TDistinta      *_distinta;   // Distinta per le elaborazioni
 | |
|   TPartite_array *_part_array; // Array di partite da scrivere
 | |
|   TMovimentoPN   *_movimento;  // Movimento di prima nota
 | |
|   TSaldo_agg      _saldo;      // Saldo da aggiornare
 | |
|   TCausale       *_caus;       // Causale contabile per le elaborazioni
 | |
|   error_type     _error;       // Errore rilevato durante l'elaborazione
 | |
|   long           _total_bills; // Totale distinte contabilizzate.
 | |
|   int            _cur_dist_row;// Numero di riga distinta corrente  (per visualizzazione errore)
 | |
|   bool           _dett_rate_att;// Dettaglia le rate su effetti attivi
 | |
|   bool           _dett_rate_pas;// Dettaglia le rate su effetti passivi
 | |
|   
 | |
| protected: // TApplication
 | |
|   // Compila la testata del movimento
 | |
|   void compile_head_mov();
 | |
|   // Compila la riga di partita
 | |
|   void compile_riga_partita(TRiga_partite& riga, const TEffetto& effetto, const TRectype& riga_effetto, int numrig);
 | |
|   // Compila la riga di pagamento
 | |
|   void  compile_riga_pagamento(TRectype& riga_pagamento, const TEffetto& effetto, const TRectype& riga_effetto, char acc_sal);
 | |
|   // Funzione di aggiornamento saldi una volta generato il movimento
 | |
|   void aggiorna_saldi();
 | |
|   // scrive il movimento e le scadenze
 | |
|   error_type write_all(bool chage_status = TRUE);
 | |
|   // cerca il conto di contropartita per la distinta corrente (setta _banca)
 | |
|   error_type search_bank_counter_bill(int tipopag=0);
 | |
|   // cerca il conto clienti
 | |
|   error_type search_clifo_bill(char tipo, const long codcf);
 | |
|   // ritorna la sezione corretta per la riga di partita
 | |
|   char sezione() const;
 | |
|   // Ordina le righe di un effetto
 | |
|   int sort_eff(TRecord_array& sorted);
 | |
|   // aggiunge una riga all'array dei clienti da una riga effetto
 | |
|   bool add_cg_row(const TEffetto& eff, const TRectype& reff, TArray& customers, TAssoc_array& banks, bool add_desc);
 | |
|   // somma ad una riga all'array dei clienti una riga effetto
 | |
|   void sum_cg_row(const TRectype& reff, TArray& customers, TAssoc_array& banks);
 | |
|   // aggiunge le righe spese al movimento
 | |
|   bool add_spese_rows(const real& spese);
 | |
|   // aggiunge riga pagamento da riga effetto
 | |
|   void compile_saldac(const TEffetto& eff, const TRectype& reff, 
 | |
|       TImporto& abbuoni_att, TImporto& abbuoni_pas, TArray& differenze_cam,
 | |
|       TArray& customers);
 | |
|   // Controlla se il pagamento dell'effetto avra' differenze cambio
 | |
|   bool has_diffcam(const TEffetto& eff) const;
 | |
| 
 | |
|   // Aggiunge una riga contabile al movimento
 | |
|   void join_row(const TRectype& row);
 | |
| 
 | |
|   // unisce gli array clienti/banche nel record array delle righe contabili
 | |
|   void join_rows(TArray& customers, TAssoc_array& banks, 
 | |
|                  const TImporto& abbuoni_att, const TImporto& abbuoni_pas, 
 | |
|                  const TArray& differenze_cam, const real& spese);
 | |
|   // Visualizza l'ultimo errore rilevato
 | |
|   void display_error();
 | |
|   // Contabilizza l'effetto corrente
 | |
|   void contabilize_bill(const char tipo, const long numero);
 | |
|   // Contabilizza gli effetti
 | |
|   void contabilize();
 | |
|   // costruisce lo sheet delle distinte
 | |
|   void build_dist_sheet();
 | |
|   // Handler della selezione distinte
 | |
|   static bool handle_select(TMask_field& f, KEY k);
 | |
|   // Handler del pulsante di reset
 | |
|   static bool handle_reset(TMask_field& f, KEY k);
 | |
|   // Le 4 seguenti non hanno bisogno di commenti
 | |
|   virtual void main_loop();
 | |
|   virtual bool create();
 | |
|   virtual bool destroy();
 | |
|   virtual void on_config_change();
 | |
| public:
 | |
|   // Verifica se non ci sono stati errori
 | |
|   bool good() const { return _error == no_error;}
 | |
|   error_type status() { return _error; }
 | |
|   void set_status(error_type e) { _error = e; }
 | |
|   
 | |
|   TArray_sheet& dist_sheet() { return *_dist_sheet; }
 | |
|   
 | |
|   TContabilizzazione_effetti_app() : _msk(NULL) {} 
 | |
|   virtual ~TContabilizzazione_effetti_app() { }
 | |
| };
 | |
| 
 | |
| inline TContabilizzazione_effetti_app& app() { return (TContabilizzazione_effetti_app&) main_app(); }
 | |
| 
 | |
| // TContabilizzazione_mask
 | |
| 
 | |
| bool TContabilizzazione_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
 | |
| {             
 | |
|   switch (f.dlg())
 | |
|   {
 | |
|   case F_DATA_OP:
 | |
|     if (e == fe_modify || e == fe_close)
 | |
|     {              
 | |
|       const TDate data = f.get();
 | |
|       TEsercizi_contabili esc;
 | |
|       if (esc.date2esc(data) <= 0)
 | |
|         return error_box(TR("La data deve appartenere ad un esercizio valido"));
 | |
|     }
 | |
|     break;
 | |
|   case F_RESET:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       app().dist_sheet().check(-1, FALSE);
 | |
|       reset(F_DISTINTE);
 | |
|     }
 | |
|     break;
 | |
|   case F_SELECT:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       TArray_sheet& sh = app().dist_sheet();
 | |
|       if (sh.run() == K_ENTER)
 | |
|         set(F_DISTINTE,sh.checked());
 | |
|     }
 | |
|     break;
 | |
|   default: 
 | |
|     break;
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| TContabilizzazione_mask::TContabilizzazione_mask()
 | |
|                        : TAutomask("ef0800a")
 | |
| {
 | |
| }
 | |
|  
 | |
| // TContabilizzazione_effetti_app
 | |
| 
 | |
| void TContabilizzazione_effetti_app::build_dist_sheet()
 | |
| {
 | |
|   TRelation eff_rel(LF_EFFETTI);
 | |
|   TCursor cur_dist(&eff_rel,"TIPODIST!=\"\"",4);
 | |
|   TRectype& rec = cur_dist.curr();
 | |
|   const long items = cur_dist.items();
 | |
|   
 | |
|   _dist_sheet->destroy(); // resetta lo sheet delle distinte
 | |
|   if (items > 0)                                   
 | |
|   {
 | |
|     cur_dist.freeze();
 | |
| 
 | |
|     cur_dist = 0;
 | |
|     long ndist_prec = rec.get_long(EFF_NDIST);
 | |
|     char tipo_prec = rec.get_char(EFF_TIPODIST);
 | |
|     TDate data_prec(rec.get(EFF_DATADIST));
 | |
| 
 | |
|     TString8 codabi, codcab, codprg, codval;
 | |
|     char tipocf;
 | |
|     bool enabled = true;
 | |
|     int num_eff = 0;
 | |
| 
 | |
|     for (long i = 0; i < items; i++)
 | |
|     {
 | |
|       cur_dist = i;
 | |
|       const long ndist = rec.get_long(EFF_NDIST);
 | |
|       const char tipo  = rec.get_char(EFF_TIPODIST);
 | |
|       TDate data_dist(rec.get(EFF_DATADIST));
 | |
| 
 | |
|       if (ndist != ndist_prec || tipo != tipo_prec)
 | |
|       {
 | |
|         TToken_string * t = new TToken_string;
 | |
|         t->add(" ");t->add(tipo_prec);
 | |
|         t->add(ndist_prec);
 | |
|         t->add(num_eff);
 | |
|         t->add(codabi);
 | |
|         t->add(codcab);
 | |
|         t->add(codprg);
 | |
|         t->add(codval);
 | |
|         t->add(tipocf);
 | |
|         t->add(data_prec);
 | |
|         const long pos = _dist_sheet->add(t); //aggiunge una riga allo sheet delle distinte
 | |
|         _dist_sheet->enable_row(pos, enabled);
 | |
|         ndist_prec = ndist;
 | |
|         tipo_prec = tipo;
 | |
| 				data_prec = data_dist;
 | |
|         enabled = true;
 | |
|         num_eff = 0;
 | |
|       }
 | |
|       if (num_eff == 0)
 | |
|       {
 | |
|         codabi = rec.get(EFF_CODABIP);   // Memorizza dati della prima riga
 | |
|         codcab = rec.get(EFF_CODCABP);
 | |
|         codprg = rec.get(EFF_PROGBNP);
 | |
|         if (real::is_null(codprg))
 | |
|           codprg.cut(0);
 | |
|         else
 | |
|           codprg.right_just(2, '0');
 | |
|         codval = rec.get(EFF_CODVAL);
 | |
|         tipocf = rec.get_char(EFF_TIPOCF);
 | |
|       }
 | |
|       num_eff++; // numero di effetti che compongono la distinta
 | |
|       if (rec.get_bool(EFF_EFFCONT)) // Disabilito le distinte contabilizzate
 | |
|         enabled = false;
 | |
|     }
 | |
|     
 | |
|     TToken_string * t = new TToken_string;
 | |
|     
 | |
|     t->add(" "); t->add(tipo_prec);
 | |
|     t->add(ndist_prec);
 | |
|     t->add(num_eff);
 | |
|     t->add(codabi);
 | |
|     t->add(codcab);
 | |
|     t->add(codprg);
 | |
|     t->add(rec.get(EFF_CODVAL));
 | |
|     t->add(rec.get(EFF_TIPOCF));
 | |
|     t->add(rec.get(EFF_DATADIST));
 | |
| 
 | |
|     const long pos = _dist_sheet->add(t); //aggiunge una riga allo sheet delle distinte
 | |
|     _dist_sheet->enable_row(pos, enabled);
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::handle_reset(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_SPACE)
 | |
|   {
 | |
|     app()._dist_sheet->check(-1, FALSE);
 | |
|     f.mask().reset(F_DISTINTE);
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::handle_select(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k==K_SPACE) // ricerca
 | |
|   {
 | |
|     TArray_sheet* sh = app()._dist_sheet;
 | |
|       
 | |
|     if (sh->run() == K_ENTER)
 | |
|       f.mask().set(F_DISTINTE,sh->checked());
 | |
|   }
 | |
|     
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::on_config_change()
 | |
| {
 | |
|   TPartita::carica_allineamento();
 | |
| 
 | |
|   TConfig conf(CONFIG_DITTA, "ef");
 | |
|   _cod_caus = conf.get("CODCAUS"); // implementare programma di gestione parametri effetti
 | |
|   _cod_caus_pag = conf.get("CODCAUSPAG"); // implementare programma di gestione parametri effetti
 | |
|   _desc_inc = conf.get("DESCINC", NULL, -1, "Distinta d'incasso");
 | |
|   _desc_pag = conf.get("DESCPAG", NULL, -1, "Ordine di pagamento");
 | |
|   _dett_rate_att = conf.get_bool("DETRATATT"); // Dettaglio rate su effetti attivi
 | |
|   _dett_rate_pas = conf.get_bool("DETRATPAS"); // Dettaglio rate su effetti passivi
 | |
|   
 | |
|   const long trans = conf.get_long("DIFFCAMS");
 | |
|   if (trans > 0)
 | |
|     _trandiffcam.set(conf.get_int("DIFFCAMG"), conf.get_int("DIFFCAMC"), trans);
 | |
|   
 | |
|   _sc_enabled = conf.get_bool("GesSal","cg");
 | |
|   if (!has_module(CGAUT) && _sc_enabled)
 | |
|   {
 | |
|     error_box(TR("Impossibile contabilizzare gli effetti se il modulo Contabilita' Generale non e' abilitato"));
 | |
|     stop_run();
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::create()
 | |
| {
 | |
|   open_files(LF_TAB, LF_TABCOM, LF_CAUSALI, LF_RCAUSALI, 
 | |
|              LF_EFFETTI, LF_REFFETTI, LF_CESS, 
 | |
|              LF_MOV, LF_RMOV, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, 
 | |
|              LF_DOC, LF_CLIFO, LF_ATTIV, LF_PCON, LF_SALDI, 0);
 | |
| 
 | |
|   _caus = NULL;
 | |
|   _error = no_error;
 | |
|   _can_write = TRUE;
 | |
|   _msk = new TContabilizzazione_mask();
 | |
|   _distinta = new TDistinta;
 | |
|   _movimento = new TMovimentoPN;
 | |
|   _dist_sheet = new TArray_sheet(-1, -1, -4, -6, TR("Selezione distinte"),
 | |
|                                  HR("@1|Tipo|Numero distinta@R|Numero effetti@R|ABI@5|CAB@5|Prg.|Valuta|C/F|Data Dist."));
 | |
|   _part_array = new TPartite_array;
 | |
|   return TSkeleton_application::create();
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::destroy()
 | |
| {
 | |
|   if (_msk) delete _msk;
 | |
|   if (_caus) delete _caus;
 | |
|   if (_distinta) delete _distinta;
 | |
|   if (_movimento) delete _movimento;
 | |
|   if (_dist_sheet) delete _dist_sheet;
 | |
|   if (_part_array) delete _part_array;
 | |
|   return TApplication::destroy();
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::main_loop()
 | |
| {
 | |
|   build_dist_sheet();
 | |
|   
 | |
|   // Preselezione della distinta specificata sulla riga di comando
 | |
|   if (argc() >= 4)
 | |
|   {
 | |
|     const char tip = *argv(2);
 | |
|     const long num = atol(argv(3));
 | |
|     for (int r = 0; r < _dist_sheet->items(); r++)
 | |
|     {
 | |
|       TToken_string& row = _dist_sheet->row(r);
 | |
|       if (row.get_char(1) == tip && row.get_long(2) == num)
 | |
|       {
 | |
|         _dist_sheet->check(r);
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|     _msk->set(F_DISTINTE, _dist_sheet->checked());
 | |
|   }
 | |
|   
 | |
|   _msk->set(F_DETT_RATE_ATT, _dett_rate_att ? "X" : "");
 | |
|   _msk->set(F_DETT_RATE_PAS, _dett_rate_pas ? "X" : "");
 | |
| 
 | |
|   while (_msk->run() == K_ENTER)
 | |
|   {
 | |
|     if (!_dist_sheet->one_checked()) 
 | |
|     {
 | |
|       error_box(TR("Nessuna distinta selezionata"));
 | |
|       continue;
 | |
|     }
 | |
|     _data_op   = _msk->get_date(F_DATA_OP);
 | |
| 
 | |
|     TEsercizi_contabili esc;
 | |
|     _cod_es = esc.date2esc(_data_op);
 | |
|     _dett_rate_att = _msk->get_bool(F_DETT_RATE_ATT);
 | |
|     _dett_rate_pas = _msk->get_bool(F_DETT_RATE_PAS);
 | |
|     
 | |
|     // Salva parametri per la prossima volta
 | |
|     {
 | |
|       TConfig conf(CONFIG_DITTA, "ef");
 | |
|       conf.set("DETRATATT", _dett_rate_att ? "X" : ""); 
 | |
|       conf.set("DETRATPAS", _dett_rate_pas ? "X" : ""); 
 | |
|     }
 | |
|     
 | |
|     contabilize();
 | |
|     _msk->reset(F_DISTINTE);
 | |
|     build_dist_sheet();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::display_error()
 | |
| {
 | |
|   TString msg;
 | |
| 
 | |
|   switch (_error)
 | |
|   {
 | |
|     case clifo_error:
 | |
|       msg.format(FR("Non e' possibile reperire il cliente/fornitore relativamente alla distinta %c %ld. "
 | |
|                  "Controllare la riga %d"),_distinta->tipodist(), _distinta->ndist(),_cur_dist_row+1);
 | |
|       break;
 | |
|     case bank_error:
 | |
|       msg.format(FR("Non e' possibile reperire i conti di contropartita per la banca di presentazione "
 | |
|                  "relativamente alla distinta %c %ld. Controllare la tabella e la causale."),_distinta->tipodist(), _distinta->ndist());
 | |
|       break;
 | |
|     case cau_abb_error:
 | |
|       msg.format(FR("Non e' possibile reperire i conti per gli abbuoni\n"
 | |
|                  "o le differenze cambi dalla causale '%s'"), _caus->codice());
 | |
|       break;
 | |
|     case cau_spe_error:
 | |
|       msg.format(FR("Non e' possibile reperire il conto per le spese\n"
 | |
|                  "dalla causale '%s'"), _caus->codice());
 | |
|       break;           
 | |
|     case datadoc_error:
 | |
|       msg.format(FR("La data distinta %s non appartiene ad un esercizio valido"), 
 | |
|                  (const char*)_distinta->data_dist().string());
 | |
| 
 | |
|       break;
 | |
|     default: // Errori generici o non indicati vengono visualizzati nel punto dell'errore
 | |
|       break;
 | |
|   }
 | |
|   if (!msg.blank())
 | |
|     warning_box(msg);
 | |
|   _error = no_error;  // reset error, as any other one would do, so you can show me the other ones.
 | |
|   _can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred.
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::add_cg_row(const TEffetto& eff, const TRectype& reff, TArray& customers, TAssoc_array& banks, bool add_desc)
 | |
| {
 | |
|   const long numreg = _movimento->curr().get_long(MOV_NUMREG);
 | |
|   real imp = reff.get_real(REFF_IMPORTO);
 | |
|   TRectype* c_rec = new TRectype(LF_RMOV);
 | |
|   // setta i valori per la riga cliente
 | |
|   c_rec->put(RMV_ANNOES,_cod_es);
 | |
|   c_rec->put(RMV_DATAREG,_data_op);
 | |
|   c_rec->put(RMV_NUMREG,numreg);
 | |
|   c_rec->put(RMV_SEZIONE,_caus->sezione_clifo());
 | |
|   _cliente.put(*c_rec);
 | |
| 
 | |
|   if (_sc_enabled)
 | |
|     c_rec->put(RMV_ROWTYPE,"K");
 | |
| 
 | |
|   
 | |
|   TString80 desc;
 | |
|   if (_cliente.tipo() == 'F')
 | |
|   {
 | |
|     if (imp >= ZERO)
 | |
|       desc = TR("Pag. ft.");
 | |
|     else  
 | |
|       desc = TR("Nota cr.");
 | |
|   }  
 | |
|   else
 | |
|   { 
 | |
|     if (imp >= ZERO)
 | |
|       desc = TR("Inc. ft.");
 | |
|     else
 | |
|       desc = TR("Nota cr.");
 | |
|   }
 | |
|   desc << ' ' << reff.get(REFF_NFATT);
 | |
|   if (_cliente.tipo() == 'C')
 | |
|     desc << TR(" sc. ") << eff.get(EFF_DATASCAD);
 | |
|   c_rec->put(RMV_DESCR, desc);
 | |
|   if (add_desc)
 | |
|   {
 | |
|     TString80 head_desc = _movimento->curr().get(MOV_DESCR);
 | |
|     head_desc << ' ' << desc;                              
 | |
|     _movimento->curr().put(MOV_DESCR, head_desc);
 | |
|   }
 | |
| 
 | |
|   // setta i valori per la riga banca
 | |
|   TRectype b_r(*c_rec);
 | |
|   TString16 key;
 | |
|   key.format("%3d%3d%6ld",_banca.gruppo(),_banca.conto(),_banca.sottoconto()); 
 | |
|   const bool is_present = banks.is_key(key);
 | |
|   TRectype& b_rec = is_present ? (TRectype&)banks.find(key) : b_r;
 | |
|   // setta i valori
 | |
|   if (!is_present) // nuova banca? allora setta la sezione ed il conto
 | |
|   {
 | |
|     const int tipopag = eff.get_int(EFF_TIPOPAG);
 | |
|     int nriga = 2;
 | |
|     if (_sc_enabled && tipopag>1 && tipopag<8) 
 | |
|       nriga = tipopag+1;
 | |
|     b_rec.put(RMV_SEZIONE,_caus->sezione(nriga));
 | |
|     b_rec.put(RMV_TIPOC,_banca.tipo());
 | |
|     b_rec.put(RMV_GRUPPO,_banca.gruppo());
 | |
|     b_rec.put(RMV_CONTO,_banca.conto());
 | |
|     b_rec.put(RMV_SOTTOCONTO,_banca.sottoconto());
 | |
|     if (_sc_enabled)
 | |
|       b_rec.put(RMV_ROWTYPE,"I"); 
 | |
|     b_rec.zero(RMV_DESCR);
 | |
|   }
 | |
|   real b_imp = b_rec.get_real(RMV_IMPORTO) + imp; // aggiorna l'importo per questa banca
 | |
|   b_rec.put(RMV_IMPORTO,b_imp);
 | |
|   banks.add(key,b_rec,is_present);
 | |
| 
 | |
|   c_rec->put(RMV_IMPORTO,imp);
 | |
| 	c_rec->put(RMV_CUP, eff.get(EFF_CUP));
 | |
| 	c_rec->put(RMV_CIG, eff.get(EFF_CIG));
 | |
| 
 | |
|   customers.add(c_rec);
 | |
|   
 | |
|   return !is_present;  
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::sum_cg_row(const TRectype& reff, TArray& customers, TAssoc_array& banks)
 | |
| {
 | |
|   const real imp = reff.get_real(REFF_IMPORTO);
 | |
| 
 | |
|   // setta i valori per la riga cliente
 | |
|   TRectype& c_rec = (TRectype&)customers[customers.last()];
 | |
|   c_rec.add(RMV_IMPORTO, imp);
 | |
| 
 | |
|   // setta i valori per la riga banca
 | |
|   TString16 key;
 | |
|   key.format("%3d%3d%6ld",_banca.gruppo(),_banca.conto(),_banca.sottoconto()); 
 | |
|   TRectype& b_rec = (TRectype&)banks.find(key);
 | |
|   b_rec.add(RMV_IMPORTO, imp); // aggiorna l'importo per questa banca
 | |
| }
 | |
| 
 | |
| 
 | |
| void TContabilizzazione_effetti_app::join_row(const TRectype& row)
 | |
| {
 | |
|   const int n = _movimento->cg_items();
 | |
|   TRectype& riga = _movimento->cg(n);
 | |
|   riga = row;                                 
 | |
|   riga.put(RMV_NUMRIG, n+1);            
 | |
|   riga.put(RMV_ANNOES,_cod_es);
 | |
|   riga.put(MOV_DATAREG,_data_op);
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::add_spese_rows(const real& spese)
 | |
| {
 | |
|   if (spese.is_zero())
 | |
|     return false;
 | |
| 
 | |
|   TRectype& row_spese = _movimento->cg(-1);
 | |
|   TRectype& row_banca = _movimento->cg(-1);
 | |
|   
 | |
|   TBill conto_spese; _caus->bill(11, conto_spese);
 | |
|   const char sez_spese = _caus->sezione(11);
 | |
|   const char sez_banca = sez_spese == 'D' ? 'A' : 'D';
 | |
|   
 | |
|   row_spese.put(RMV_ANNOES,_cod_es);
 | |
|   row_spese.put(RMV_DATAREG,_data_op);
 | |
|   row_spese.put(RMV_SEZIONE, sez_spese);
 | |
|   row_spese.put(RMV_IMPORTO, spese);
 | |
|   conto_spese.put(row_spese);
 | |
|   _banca.put(row_spese, true);
 | |
|   row_spese.put(RMV_DESCR, _caus->desc_agg(11));
 | |
|   if (_sc_enabled)
 | |
|     row_spese.put(RMV_ROWTYPE, 'G');
 | |
| 
 | |
|   row_banca.put(RMV_ANNOES,_cod_es);
 | |
|   row_banca.put(RMV_DATAREG,_data_op);
 | |
|   row_banca.put(RMV_SEZIONE, sez_banca);
 | |
|   row_banca.put(RMV_IMPORTO, spese);
 | |
|   _banca.put(row_banca);
 | |
|   conto_spese.put(row_banca, true);
 | |
|   if (_sc_enabled)
 | |
|     row_banca.put(RMV_ROWTYPE, 'L');
 | |
|   
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::join_rows(TArray& customers, TAssoc_array& banks,
 | |
|                                                const TImporto& abbuoni_att, 
 | |
|                                                const TImporto& abbuoni_pas, 
 | |
|                                                const TArray& differenze_cam,
 | |
|                                                const real& spese)
 | |
| {
 | |
|   // aggiunge prima i record delle righe relative ai clienti
 | |
|   const int customer_items = customers.items();
 | |
|   int j;
 | |
|   for (j = 0; j < customer_items; j++)
 | |
|     join_row((const TRectype&) customers[j]);
 | |
|   
 | |
|   // e poi i record delle righe relative alle banche
 | |
|   const int bank_items = banks.items();
 | |
|   TRectype* row;
 | |
|   for (j = 0, row = (TRectype*)banks.first_item(); row != NULL && j < bank_items; j++, row = (TRectype *)banks.succ_item())
 | |
|     join_row(*row);
 | |
| 
 | |
|   // infine abbuoni e differenze cambio
 | |
|   if (_sc_enabled)
 | |
|   {
 | |
|     TBill zio;
 | |
|     TRectype riga(_movimento->cg(0));
 | |
|     if (!abbuoni_pas.is_zero())
 | |
|     {
 | |
|       _caus->bill(9, zio); zio.put(riga);
 | |
|       if (!zio.ok()) _error = cau_abb_error;
 | |
|       riga.put(RMV_SEZIONE, abbuoni_pas.sezione());
 | |
|       riga.put(RMV_IMPORTO, abbuoni_pas.valore());
 | |
|       riga.put(RMV_ROWTYPE, "P");
 | |
|       join_row(riga);
 | |
|     }
 | |
|     if (!abbuoni_att.is_zero())
 | |
|     {
 | |
|       _caus->bill(10, zio); zio.put(riga);
 | |
|       if (!zio.ok()) _error = cau_abb_error;
 | |
|       riga.put(RMV_SEZIONE, abbuoni_att.sezione());
 | |
|       riga.put(RMV_IMPORTO, abbuoni_att.valore());
 | |
|       riga.put(RMV_ROWTYPE, "A");
 | |
|       join_row(riga);
 | |
|     }
 | |
|     if (differenze_cam.items() > 0)
 | |
|     {                             
 | |
|       TImporto diffcam;
 | |
|       for (int i = differenze_cam.items()-1; i >= 0; i--)
 | |
|       {            
 | |
|         const TRectype& rec = (const TRectype&)differenze_cam[i];  
 | |
|         TImporto dc(rec.get_char(RMV_SEZIONE), rec.get_real(RMV_IMPORTO));
 | |
|         diffcam += dc;
 | |
|       }  
 | |
|       
 | |
|       _caus->bill(13, zio); 
 | |
|       if (!zio.ok()) 
 | |
|         _error = cau_abb_error;
 | |
| 
 | |
|       zio.put(riga);
 | |
|       riga.put(RMV_SEZIONE, diffcam.sezione());
 | |
|       riga.put(RMV_IMPORTO, diffcam.valore());
 | |
|       riga.put(RMV_ROWTYPE, "C");
 | |
|       join_row(riga);
 | |
|       
 | |
|       if (_trandiffcam.ok() && (customers.items() > 1 || differenze_cam.items() > 1))
 | |
|       {
 | |
|         TRectype& rec = _movimento->cg(_movimento->cg_items()-1);
 | |
|         _trandiffcam.put(rec); _trandiffcam.put(rec, TRUE);
 | |
|       
 | |
|         riga.put(RMV_SEZIONE, diffcam.sezione() == 'D' ? 'A' : 'D');
 | |
|         _trandiffcam.put(riga); _trandiffcam.put(riga, true); 
 | |
|         riga.zero(RMV_ROWTYPE);
 | |
|         join_row(riga);
 | |
|       
 | |
|         for (int i = 0; i < differenze_cam.items(); i++)
 | |
|         {            
 | |
|           const TRectype& rec = (const TRectype&)differenze_cam[i];  
 | |
|           join_row(rec);
 | |
|         }
 | |
|       }  
 | |
|     }
 | |
|   }
 | |
|   if (add_spese_rows(spese))
 | |
|   {
 | |
|     const char tipocf = ((const TRectype&)customers[0]).get_char(RMV_TIPOC);
 | |
|     if (tipocf == 'C')  
 | |
|       _total_mov -= spese;
 | |
|     else  
 | |
|       _total_mov += spese;
 | |
|   }  
 | |
| }
 | |
| 
 | |
| error_type TContabilizzazione_effetti_app::search_clifo_bill(char tipo, const long codcf)
 | |
| {
 | |
|   _error = no_error;
 | |
| 	
 | |
|   TString8 key; key.format("%c|%ld", tipo, codcf);	
 | |
| 	const TRectype & clifo = cache().get(LF_CLIFO, key);
 | |
| 
 | |
| 	if (clifo.empty())
 | |
| 	  _cliente.set(0,0,0);
 | |
| 	else
 | |
| 		_cliente.set(clifo.get_int(CLI_GRUPPO), clifo.get_int(CLI_CONTO), codcf, tipo);
 | |
|   if (!_cliente.ok()) // se non e' valido, reperiscilo dalla riga #1 della causale
 | |
|   {
 | |
|     _caus->bill(1,_cliente); // conto della riga 1
 | |
|     _cliente.codclifo() = codcf;
 | |
|     if (!_cliente.ok())
 | |
|       _error = clifo_error;
 | |
|   }
 | |
|   return _error;
 | |
| }
 | |
| 
 | |
| error_type TContabilizzazione_effetti_app::search_bank_counter_bill(int tipopag)
 | |
| {
 | |
|   // reperisce i codici ABI e CAB della banca presentazione effetti dalla
 | |
|   // distinta e va a cercarli sulla tabella BNP di ditta.
 | |
|   // La banca di presentazione effetti e' una unica per tutta la distinta
 | |
|   // e non puo' essere vuota
 | |
|   _error = no_error;
 | |
|   if (tipopag <= 0) // cerca sulla tabella e poi sulla 2a riga di causale
 | |
|   {
 | |
|     _banca.set(0,0,0); // resetta il conto...
 | |
|     
 | |
|     TString16 codtab(_distinta->abip());
 | |
|     codtab << _distinta->cabp();
 | |
|     TString4 prog = _distinta->progbnp();
 | |
|     if (!real::is_null(prog))
 | |
|     {
 | |
|       prog.right_just(2, '0');
 | |
|       codtab << prog;
 | |
|     }
 | |
|     const TRectype& bnp = cache().get("BNP", codtab);
 | |
|     if (!bnp.empty())
 | |
|     {                        
 | |
|       const char* fg = NULL;
 | |
|       const char* fc = NULL;
 | |
|       const char* fs = NULL; 
 | |
|       const char tipodist = _distinta->tipodist();
 | |
|       switch (tipodist)
 | |
|       {
 | |
|       case DIST_SBF: 
 | |
|         fg = "I3"; fc = "I4"; fs = "I5"; 
 | |
|         break;
 | |
|       case DIST_SCONTO: 
 | |
|         fg = "I6"; fc = "I7"; fs = "I8"; 
 | |
|         break;
 | |
|       case DIST_INCASSO: // Default
 | |
|       default: 
 | |
|         if (_distinta->tipocf() == 'F')
 | |
|         { 
 | |
|           fg = "I9"; fc = "I10"; fs = "I11"; 
 | |
|         }
 | |
|         else  
 | |
|         { 
 | |
|           fg = "I0"; fc = "I1"; fs = "I2"; 
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|       const int  g = bnp.get_int(fg);
 | |
|       const int  c = bnp.get_int(fc);
 | |
|       const long s = bnp.get_long(fs);
 | |
|       _banca.set(g,c,s);
 | |
|     }
 | |
|     // se non ha trovato la banca oppure il conto, verifica che vi sia 
 | |
|     // il conto sulla riga 2 della causale (solo se SC non abilitato)
 | |
|     
 | |
|     if (!_banca.ok())
 | |
|       _caus->bill(2,_banca); // conto della riga 2
 | |
|     // se il saldaconto non e' abilitato, il conto di contropartita sulla causale
 | |
|     // va verificato per ogni riga di distinta, a seconda del tipo di pagamento.  
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     // cerca il conto relativo alla riga di causale:
 | |
|     // 1 Rimessa diretta o contanti (banca)   riga 2
 | |
|     // 2 Tratta                               riga 3
 | |
|     // 3 Ricevuta bancaria                    riga 4
 | |
|     // 4 Cessione                             riga 5
 | |
|     // 5 Paghero'                             riga 6
 | |
|     // 6 Lettera di credito                   riga 7
 | |
|     // 7 Tratta accettata                     riga 8
 | |
|     // 8 Rapporti interban. diretti           riga 2 
 | |
|     // 9 Bonifici                             riga 2
 | |
|     _caus->bill(tipopag>0 && tipopag<8 ? tipopag+1:2,_banca);
 | |
|   }
 | |
|   if (!_banca.ok())
 | |
|     _error =  bank_error;
 | |
|   return _error;
 | |
| }
 | |
| 
 | |
| char TContabilizzazione_effetti_app::sezione() const
 | |
| { 
 | |
|   char sezione = ' ';
 | |
|   const char tipoc = _cliente.tipo();
 | |
| 
 | |
|   tipo_movimento tm = (tipo_movimento)_caus->tipomov();
 | |
|   sezione = _caus->sezione(1);                     // Usa la sezione della causale
 | |
|   
 | |
|   if (sezione <= ' ')                               // Se non c'e' la sezione bell'e' ch'e' pronta
 | |
|   {
 | |
|     if (tm == tm_fattura || tm == tm_insoluto)      // calcola in base al tipo movimento e
 | |
|       sezione = (tipoc == 'C') ? 'D' : 'A';         // al tipo cliente/fornitore
 | |
|     else  
 | |
|       sezione = (tipoc == 'C') ? 'A' : 'D';
 | |
|   }
 | |
|   return sezione;
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::compile_head_mov()
 | |
| {
 | |
|   CHECK(_caus,"Causale non allocata");
 | |
|   
 | |
|   TLocalisamfile& mov = _movimento->lfile();
 | |
|   mov.last();
 | |
|   const long numreg = mov.get_long(MOV_NUMREG)+1; // Calcola il numero di registrazione
 | |
|   const TDate datadist(_distinta->data_dist());
 | |
|   const TDate datacam(_distinta->data_cam());
 | |
|   const TString4 codval(_distinta->codval());
 | |
|   const real cambio(_distinta->cambio());
 | |
|   const long ndist = _distinta->ndist();
 | |
|   
 | |
|   TEsercizi_contabili esc;
 | |
|   if (esc.date2esc(datadist) <= 0)
 | |
|   {
 | |
|     if (!yesno_box(FR("Attenzione: la data distinta %s non appartiene ad un esercizio valido:\n"
 | |
|                    "Si desidera proseguire ugualmente?"), (const char*)datadist.string()))
 | |
|     {
 | |
|       _can_write = FALSE;
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   TString des;
 | |
|   des = (_distinta->tipocf() == 'F') ? _desc_pag : _desc_inc;
 | |
|   des << ' ';
 | |
|   switch (_distinta->tipopag())
 | |
|   {
 | |
|   case  1: des << TR("rimessa diretta"); break;
 | |
|   case  2: des << TR("tratta"); break;
 | |
|   case  3: des << TR("ricevuta bancaria"); break;
 | |
|   case  4: des << TR("cessione"); break;
 | |
|   case  5: des << TR("paghero'"); break;
 | |
|   case  6: des << TR("lettera di credito"); break;
 | |
|   case  7: des << TR("tratta accettata"); break;
 | |
|   case  8: des << TR("rapp. interb. dir."); break;
 | |
|   case  9: des << TR("bonifico"); break;
 | |
|   default: des.rtrim(); break;
 | |
|   }
 | |
|   des << TR(" n.") << ndist;  
 | |
|   
 | |
|   mov.zero();
 | |
|   mov.put(MOV_DESCR,des);
 | |
|   mov.put(MOV_NUMREG,numreg);
 | |
|   mov.put(MOV_ANNOES,_cod_es);
 | |
|   mov.put(MOV_DATAREG,_data_op);
 | |
|   mov.put(MOV_DATACOMP,_data_op);
 | |
|   mov.put(MOV_DATADOC,datadist);
 | |
|   mov.put(MOV_NUMDOC,ndist);
 | |
|   mov.put(MOV_TIPODOC,_caus->tipo_doc());
 | |
|   mov.put(MOV_CODCAUS,_caus->codice());
 | |
|   mov.put(MOV_TIPOMOV,_caus->tipomov());
 | |
|   
 | |
|   if (is_true_value(codval))
 | |
|   {
 | |
|     mov.put(MOV_CODVAL, codval);
 | |
|     mov.put(MOV_DATACAM, _distinta->data_cam());
 | |
|     
 | |
|     real cambio = _distinta->cambio();
 | |
|     const bool eurocambio = _distinta->contro_euro();
 | |
|     const TExchange chg(codval, cambio, eurocambio ? _exchange_contro : _exchange_base);
 | |
|     if (eurocambio && mov.curr().exist(MOV_CONTROEURO))
 | |
|     {
 | |
|       mov.put(MOV_CONTROEURO, eurocambio);
 | |
|       cambio = chg.get_contro_change();
 | |
|     }
 | |
|     else                                             
 | |
|     {
 | |
|       cambio = chg.get_base_change();
 | |
|     }    
 | |
|     mov.put(MOV_CAMBIO, cambio);
 | |
|   }
 | |
|   // MOV_TOTDOC e MOV_TOTDOCVAL vengono completati prima della scrittura del movimento
 | |
|   // e solo nel caso di saldaconto abilitato
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::compile_riga_partita(TRiga_partite& riga, const TEffetto& effetto, const TRectype& riga_effetto, int numrig)
 | |
| {
 | |
|   const TRectype& head_mov = _movimento->curr();  
 | |
|   riga.put(PART_TIPOMOV,_caus->tipomov());
 | |
|   riga.put(PART_TIPOPAG,effetto.get(EFF_TIPOPAG));
 | |
|   riga.put(PART_NREG,head_mov.get(MOV_NUMREG));
 | |
|   riga.put(PART_NUMRIG,numrig); 
 | |
|   riga.put(PART_DATAREG,head_mov.get(MOV_DATAREG));
 | |
|   riga.put(PART_DATADOC,head_mov.get(MOV_DATADOC));
 | |
|   riga.put(PART_DATAPAG,effetto.get(EFF_DATASCAD));
 | |
|   riga.put(PART_CODCAUS,head_mov.get(MOV_CODCAUS));
 | |
|   riga.put(PART_NUMDOC,head_mov.get(MOV_NUMDOC)); // Sarebbe il numero della distinta...
 | |
|   riga.put(PART_DESCR, head_mov.get(MOV_DESCR));
 | |
|   riga.put(PART_SEZ,sezione());
 | |
|   const real imp = riga_effetto.get(REFF_IMPORTO);
 | |
|   const real imp_val = riga_effetto.get(REFF_IMPORTOVAL);
 | |
|   riga.put(PART_CODVAL,effetto.get(EFF_CODVAL));
 | |
|   riga.put(PART_DATACAM,effetto.get_date(EFF_DATACAMBIO));
 | |
|   real cambio = effetto.get(EFF_CAMBIO);
 | |
|   riga.put(PART_CAMBIO, cambio);
 | |
|   if (effetto.get_bool(EFF_CONTROEURO))
 | |
|   {
 | |
|     if (!((TRectype&)riga).exist(PART_CONTROEURO))
 | |
|     {                                 
 | |
|       const TExchange chg(effetto.get(EFF_CODVAL), cambio, _exchange_contro);
 | |
|       const real cc = chg.get_base_change();
 | |
|       riga.put(PART_CAMBIO, cc);
 | |
|     }
 | |
|     else
 | |
|       riga.put(PART_CONTROEURO, TRUE);
 | |
|   }
 | |
|   riga.put(PART_TIPOCF,_cliente.tipo());
 | |
|   riga.put(PART_SOTTOCONTO,_cliente.sottoconto());
 | |
|   riga.put(PART_IMPTOTDOC,effetto.get(EFF_IMPORTO));
 | |
|   riga.put(PART_IMPTOTVAL,effetto.get(EFF_IMPORTOVAL));
 | |
|   // PART_GRUPPOCL e PART_CONTOCL sono gia' compilati dalla TPartita::new_row()
 | |
|   // Aggiorna il totale movimento in lire e totale movimento in valuta (solo con saldaconto abilitato)
 | |
|   if (_sc_enabled)
 | |
|   {
 | |
|     _total_mov += imp;
 | |
|     _total_mov_val += imp_val;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::compile_riga_pagamento(TRectype& riga_pagamento, const TEffetto& effetto, const TRectype& riga_effetto, char acc_sal)
 | |
| {
 | |
|   // ANNO, NUMPART, NRIGA, NRATA, NRIGP dovrebbero essere gia' compilati
 | |
|   riga_pagamento.put(PAGSCA_TIPOC,_cliente.tipo());
 | |
|   riga_pagamento.put(PAGSCA_SOTTOCONTO,_cliente.sottoconto());
 | |
|   riga_pagamento.put(PAGSCA_ACCSAL,acc_sal); 
 | |
|   riga_pagamento.put(PAGSCA_IMPORTO,riga_effetto.get_real(REFF_IMPORTO));
 | |
|   riga_pagamento.put(PAGSCA_IMPORTOVAL,riga_effetto.get_real(REFF_IMPORTOVAL));
 | |
|   riga_pagamento.put(PAGSCA_TIPOCC,_banca.tipo());
 | |
|   riga_pagamento.put(PAGSCA_GRUPPOC,_banca.gruppo());
 | |
|   riga_pagamento.put(PAGSCA_CONTOC,_banca.conto());
 | |
|   riga_pagamento.put(PAGSCA_SOTTOCONTC,_banca.sottoconto());
 | |
|   riga_pagamento.put(PAGSCA_CODABI, effetto.get(EFF_CODABI));
 | |
|   riga_pagamento.put(PAGSCA_CODCAB, effetto.get(EFF_CODCAB));
 | |
|   riga_pagamento.put(PAGSCA_CODABIPR, effetto.get(EFF_CODABIP));
 | |
|   riga_pagamento.put(PAGSCA_CODCABPR, effetto.get(EFF_CODCABP));
 | |
|   // Cerca l'eventuale codice agente sul documento
 | |
| 
 | |
| 	TString key(30);
 | |
| 
 | |
| 	key << riga_effetto.get(REFF_PROVV) << "|";
 | |
|   key << riga_effetto.get(REFF_ANNODOC) << "|";
 | |
|   key << riga_effetto.get(REFF_CODNUM) << "|";
 | |
|   key << riga_effetto.get(REFF_NFATT);
 | |
| 
 | |
|   const TRectype & doc = cache().get(LF_DOC, key);
 | |
| 		
 | |
|   if (!doc.empty())
 | |
|     riga_pagamento.put(PAGSCA_CODAG, doc.get(DOC_CODAG));
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::compile_saldac(const TEffetto& eff, 
 | |
|      const TRectype& reff, TImporto& abbuoni_att, TImporto& abbuoni_pas, 
 | |
|      TArray& differenze_cam, TArray& customers)
 | |
| {
 | |
|   int anno = reff.get_int(REFF_ANNO);
 | |
|   TString16 numpart = reff.get(REFF_NUMPART);
 | |
|   // Ricava il numero della fattura.
 | |
|   TString16 numdoc_to_search = reff.get(REFF_CODNUM);
 | |
|   TString16 nfatt = reff.get(REFF_NFATT);
 | |
|   TCodice_numerazione cn;
 | |
| 
 | |
|   if (numdoc_to_search.not_empty() && nfatt.not_empty() && real::is_natural(nfatt))
 | |
|   {
 | |
|     cn.read(numdoc_to_search);
 | |
|     const long nf = atol(nfatt);
 | |
|     cn.complete_num(nf, numdoc_to_search);
 | |
|   }
 | |
|   else // se gli estremi della fattura non sono compilati si piglia il numero della partita
 | |
| 		if (nfatt.full())
 | |
| 	    numdoc_to_search = nfatt;
 | |
| 		else
 | |
| 			numdoc_to_search = numpart;
 | |
|   if (anno == 0 || numpart.empty()) // Se non sono gia' settati sulla riga effetto...
 | |
|   {
 | |
|     anno = reff.get_int(REFF_ANNODOC);// ... li va a prendere dagli estremi fattura...
 | |
|     if (numdoc_to_search.not_empty())
 | |
|     {
 | |
|       numpart = numdoc_to_search;
 | |
|     }  
 | |
|     else // ...oppure dalla testata movimento.
 | |
|     {    // Appunto: da verificare se facciamo cosi' o generiamo un errore...
 | |
|       anno = eff.get_date(EFF_DATADIST).year();
 | |
|       const char all = TPartita::allineamento_richiesto(eff.get_char(EFF_TIPOCF));
 | |
|       if (all == 'R')
 | |
|         numpart.format("%7ld", eff.get_long(EFF_NDIST));
 | |
|       else  
 | |
|         numpart.format("%ld", eff.get_long(EFF_NDIST));
 | |
|       numdoc_to_search = numpart;      // A mali estremi... estremi rimedi
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   TPartita * partita = _part_array->exist(_cliente,anno,numpart);
 | |
|   if (partita == NULL)  // Se la partita non esiste nell'array la aggiunge
 | |
|   {
 | |
|     partita = new TPartita(_cliente,anno,numpart);
 | |
|     _part_array->insert(partita);
 | |
|   }
 | |
|   TRiga_partite& riga_part = partita->new_row();
 | |
|   // Compila la riga di partita
 | |
|   const int numrig = customers.items();
 | |
|   compile_riga_partita(riga_part,eff,reff, numrig);
 | |
|   // Compila la riga di pagamento:
 | |
|   // reperire il numero della riga partita (nrigp) appena aggiunta
 | |
|   const int nrigp = riga_part.get_int(PART_NRIGA);
 | |
|   ((TRectype&)reff).put(REFF_NRIGP, nrigp);
 | |
|         
 | |
|   // scorrere le righe della partita (nriga) per trovare il riferimento alla fattura di cui si sta effettuando il pagamento
 | |
|   //    se non la si trova allora... nriga = UNASSIGNED
 | |
|   const int uns = (int)TPartita::UNASSIGNED;
 | |
|   int nriga = reff.get_int(REFF_NRIGA);
 | |
|   if (nriga == 0 || nriga == uns)
 | |
|   {
 | |
|     nriga = uns;
 | |
|     for (int r = partita->last(); r > 0; r = partita->pred(r))
 | |
|     {
 | |
|       const TRiga_partite& rpart = partita->riga(r); 
 | |
|       const TString16 numdoc = rpart.get(PART_NUMDOC);
 | |
|       if (numdoc == numdoc_to_search && rpart.is_fattura())
 | |
|       {
 | |
|         nriga = r;
 | |
|         break;
 | |
|       }  
 | |
|     }
 | |
|   }  
 | |
|   // reperire il numero di rata (nrata) dalla riga effetto
 | |
|   const int nrata = reff.get_int(REFF_NRATA);
 | |
|   char acc_sal = 'A';
 | |
|   if (partita->esiste(nriga,nrata)) // calcola se e' a saldo o in acconto della rata
 | |
|   {
 | |
|     acc_sal = reff.get_char(REFF_ACCSAL);
 | |
|     if (acc_sal != 'S' && acc_sal != 'A')
 | |
| 			acc_sal = 'A';  // Potrebbe succedere che il ACCSAL sia vuoto
 | |
|   }
 | |
|   else 
 | |
|   {
 | |
|     if (nriga != uns) 
 | |
|       nriga = uns; // E' praticamente impossibile che si trovi la fattura
 | |
|                    // senza le proprie scadenze. Al limite settiamo il numero di riga per non assegnati.
 | |
|   }                 
 | |
|   // Creo una nuova riga di pagamento
 | |
|   TRectype& old_riga_pagamento = partita->pagamento(nriga,nrata,nrigp); 
 | |
|   // compilo i campi di riga_pagamento
 | |
|   TRectype riga_pagamento(old_riga_pagamento);
 | |
|   compile_riga_pagamento(riga_pagamento,eff,reff, acc_sal);
 | |
|   // Aggiorno il pagamento generando eventuali abbuoni
 | |
|   char old_ap, new_ap;
 | |
|   TImporto old_abb, new_abb, old_diffcam, new_diffcam;  
 | |
|   
 | |
|   const TString4 codval = eff.get(EFF_CODVAL);
 | |
|   const TDate datacam = eff.get(EFF_DATACAMBIO);
 | |
|   real cambio = eff.get(EFF_CAMBIO);
 | |
|   exchange_type et = eff.get_bool(EFF_CONTROEURO) ? _exchange_contro : _exchange_base;
 | |
|   if (et == _exchange_contro)
 | |
|   {
 | |
|     if (!((TRectype&)riga_part).exist(PART_CONTROEURO))
 | |
|     {
 | |
|       const TExchange chg(codval, cambio, et);
 | |
|       cambio = chg.get_base_change();
 | |
|       et = _exchange_base;
 | |
|       riga_part.put(PART_CAMBIO, cambio);
 | |
|     }
 | |
|   }
 | |
|   const TValuta valuta_eff(codval, datacam, cambio, et);
 | |
| 
 | |
|   partita->modifica_pagamento(riga_pagamento, valuta_eff,
 | |
|                               old_ap, old_abb, old_diffcam,  
 | |
|                               new_ap, new_abb, new_diffcam, TRUE);
 | |
| 
 | |
|   // Se ci sono abbuoni o differenze cambio...
 | |
|   if (!new_abb.is_zero() || !new_diffcam.is_zero())
 | |
|   {
 | |
|     if (new_ap == 'A') 
 | |
|     {
 | |
|       abbuoni_att -= new_abb;  // Sottraggo perche' va in sezione opposta
 | |
|       abbuoni_att.normalize();
 | |
|     }
 | |
|     if (new_ap == 'P') 
 | |
|     {
 | |
|       abbuoni_pas -= new_abb; // Sottraggo perche' va in sezione opposta
 | |
|       abbuoni_pas.normalize();
 | |
|     }
 | |
|     if (!new_diffcam.is_zero())
 | |
|     {
 | |
|       // Sottraggo perche' va in sezione opposta
 | |
|       TImporto dc = new_diffcam; 
 | |
|       dc.normalize(); dc.swap_section();
 | |
|       
 | |
|       TRectype* row = new TRectype(LF_RMOV);
 | |
|       differenze_cam.add(row);
 | |
|       row->put(RMV_SEZIONE, dc.sezione());
 | |
|       row->put(RMV_IMPORTO, dc.valore());
 | |
|       TBill zio; _caus->bill(13, zio);
 | |
|       zio.put(*row);
 | |
|       
 | |
|       TString80 str; str << TR("ft. ") << nfatt;
 | |
|       row->put(RMV_DESCR, str);
 | |
|     }
 | |
| 
 | |
|     TRectype& last = (TRectype&)customers[customers.last()];
 | |
|     TImporto imp(last.get_char(RMV_SEZIONE), last.get_real(RMV_IMPORTO));
 | |
|     imp += new_abb;      // Incremento con abbuoni
 | |
|     imp += new_diffcam;  // Incremento con differenze cambi
 | |
|     last.put(RMV_SEZIONE, imp.sezione());
 | |
|     last.put(RMV_IMPORTO, imp.valore());
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::aggiorna_saldi()
 | |
| {
 | |
|   CHECK(_movimento, "Movimento non valido passato ad aggiorna_saldi()");
 | |
|   
 | |
|   TLocalisamfile& mov = _movimento->lfile();
 | |
|   
 | |
|   const TDate datareg(mov.get_date(MOV_DATAREG));
 | |
| 
 | |
|   tiposal tsal = _caus->apertura() ? apertura : 
 | |
|            (_caus->chiusura() ? chiusura : normale);
 | |
| 
 | |
| 
 | |
|   _saldo.reset();  // Inizializza saldi
 | |
|   _saldo.set_movprovv(FALSE);
 | |
|   _saldo.set_tipo_saldo(tsal);
 | |
|   _saldo.set_anno_es(mov.get_int(MOV_ANNOES));
 | |
|   _saldo.set_num_ulmov(mov.get_long(MOV_NUMREG));
 | |
|   _saldo.set_data_ulmov(datareg);
 | |
|   _saldo.set_movimentato(TRUE);
 | |
| 
 | |
|   const int cgitems = _movimento->cg_items();
 | |
|   for (int i = 0; i < cgitems; i++)
 | |
|   {
 | |
|     const TRectype& r = _movimento->cg(i);
 | |
|     TImporto import(r.get_char("SEZIONE"), r.get_real("IMPORTO"));
 | |
| 
 | |
|     TBill conto; conto.get(r);
 | |
|     _saldo.aggiorna(conto, import, TRUE);
 | |
|   }
 | |
|   
 | |
|   _saldo.registra();
 | |
| }
 | |
| 
 | |
| error_type TContabilizzazione_effetti_app::write_all(bool change_status)
 | |
| { 
 | |
| 	TRectype& head = _movimento->lfile().curr();
 | |
| 	long numreg = head.get_long(MOV_NUMREG);
 | |
| 
 | |
|   if (_movimento->cg_items() > 0) // puo' succedere nell'ultima write
 | |
| 	{
 | |
| 		if (_movimento->cg_items() >= 2)  // Non ha senso un movimento di una riga sola
 | |
| 		{
 | |
| 			TRectype& head = _movimento->lfile().curr();
 | |
| 			head.put(MOV_TOTDOC,_total_mov); 
 | |
| 			head.put(MOV_TOTDOCVAL,_total_mov_val);
 | |
|     
 | |
| 			const long orig_numreg = numreg;
 | |
| 			while (_movimento->write() == _isreinsert)
 | |
| 				head.put(MOV_NUMREG,++numreg);
 | |
| 			if (_movimento->status() != NOERR)
 | |
| 			{
 | |
| 				error_box(FR("E' stato rilevato l'errore %d scrivendo il movimento %ld."),_movimento->status(),numreg);
 | |
| 				_error = generic_error;
 | |
| 			}
 | |
|     
 | |
| 			if (good()) // nessun errore ?
 | |
| 			{
 | |
| 				aggiorna_saldi();
 | |
|       
 | |
| 				if (_sc_enabled) // Debbo scrivere anche le partite ?
 | |
| 				{
 | |
| 					if (numreg > orig_numreg) // Ha effettuato una rinumerazione ?
 | |
| 					{
 | |
| 						// Allora scorre le partite in _part_array e aggiorna il campo NREG delle righe di ognuna
 | |
| 						for (TPartita * p = _part_array->first(); p != NULL; p = _part_array->next()) 
 | |
| 							// Scorre le righe della partita corrente
 | |
| 							for (int n = p->last(); n > 0; n = p->pred(n))
 | |
| 							{
 | |
| 								TRiga_partite& riga = p->riga(n);
 | |
| 								if (riga.get_long(PART_NREG) == orig_numreg) // sostituisce il numero registrazione con quello nuovo
 | |
| 									riga.put(PART_NREG, numreg);
 | |
| 							}
 | |
| 					}
 | |
| 					if (!_part_array->write()) // L'errore viene gia' segnalato dalla partita
 | |
| 						_error = generic_error; 
 | |
| 				}
 | |
| 			}
 | |
| 		}    
 | |
| 		else
 | |
| 		{
 | |
| 			error_box(FR("Il movimento deve contenere almeno 2 righe contabili e non %d"), _movimento->cg_items());
 | |
| 			_error = generic_error; 
 | |
| 		}
 | |
| 	}
 | |
|   
 | |
|   if (good() && change_status) // deve anche cambiare lo stato alla distinta ?
 | |
|   {
 | |
|     TDistinta& distinta = *_distinta;
 | |
|     const int items = distinta.items();
 | |
|     for (int n = 0; n < items; n++)
 | |
|     {
 | |
|       TRectype& eff = distinta[n];
 | |
|       eff.put(EFF_EFFCONT, TRUE);
 | |
|       eff.put(EFF_NUMREG, numreg);
 | |
|     }
 | |
|     int err = distinta.rewrite();
 | |
|     if (err != NOERR)
 | |
|     {
 | |
|       error_box(FR("E' stato rilevato l'errore %d aggiornando lo stato della distinta %c %ld."),err,distinta.tipodist(),distinta.ndist());
 | |
|       _error = generic_error; 
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return _error;
 | |
| }
 | |
| 
 | |
| bool TContabilizzazione_effetti_app::has_diffcam(const TEffetto& eff) const
 | |
| {
 | |
|   bool yes = FALSE;
 | |
|   if (eff.in_valuta()) // Considera solo effetti in valuta
 | |
|   {
 | |
|     const TExchange cambio(eff);
 | |
| 
 | |
|     TLocalisamfile partite(LF_PARTITE);  
 | |
|     for (int n = 1; yes == FALSE && n <= eff.rows_r(); n++)
 | |
|     {
 | |
|       const TRectype& riga = eff.row_r(n);
 | |
|       if (riga.get_char(REFF_ACCSAL) != 'S')  // Ignora righe non saldanti
 | |
|         continue;
 | |
|       
 | |
|       partite.put(PART_TIPOCF, eff.get(EFF_TIPOCF));
 | |
|       partite.put(PART_GRUPPO, 0);
 | |
|       partite.put(PART_CONTO, 0);
 | |
|       partite.put(PART_SOTTOCONTO, eff.get(EFF_CODCF));
 | |
|       partite.put(PART_ANNO, riga.get(REFF_ANNO));
 | |
|       partite.put(PART_NUMPART, riga.get(REFF_NUMPART));
 | |
|       partite.put(PART_NRIGA, riga.get(REFF_NRIGA));
 | |
|       int err = partite.read();
 | |
|       if (err == NOERR)
 | |
|       {
 | |
|         const TExchange cambiofatt(partite.curr());
 | |
|         yes = cambiofatt != cambio;
 | |
|       }
 | |
|       else
 | |
|         NFCHECK("Effetto pagante fattura fantasma");
 | |
|     }
 | |
|   }  
 | |
|   return yes;    
 | |
| }
 | |
| 
 | |
| static void build_eff_key(const TRectype& row, TString& str, int level)
 | |
| {                   
 | |
|   int anno = row.get_int(REFF_ANNO);
 | |
|   if (anno <= 0)
 | |
|     anno = row.get_int(REFF_ANNODOC);
 | |
|   
 | |
|   TString16 part = row.get(REFF_NUMPART);
 | |
|   if (part.blank() || part == "0")
 | |
|     part = row.get(REFF_NFATT);
 | |
|   
 | |
|   int riga = row.get_int(REFF_NRIGA);
 | |
|   if (riga <= 0)
 | |
|     riga = 1;
 | |
|   
 | |
|   if (level > 0)
 | |
|   {
 | |
|     const int rata = row.get_int(REFF_NRATA);
 | |
|     str.format("%04d|%s|%04d|%04d", anno, (const char*)part, riga, rata);
 | |
| 
 | |
|     if (level > 1)
 | |
|     { // Devo fare in modo che le fatture precedano le note doi credito nell'array delle righe effetto 
 | |
|       int tipo = 2;
 | |
|       if (row.get_real(REFF_IMPORTO) <= ZERO)
 | |
|         tipo = 1; // Nota di credito
 | |
|       str << '|'  << tipo;
 | |
|     }    
 | |
|   }
 | |
|   else  
 | |
|     str.format("%04d|%s|%04d", anno, (const char*)part, riga);
 | |
| }
 | |
| 
 | |
| static int sort_eff_func(const TObject** o1, const TObject** o2)
 | |
| {
 | |
|   const TRectype& r1 = *((TRectype*)*o1);
 | |
|   const TRectype& r2 = *((TRectype*)*o2);
 | |
|   TString80 s1, s2;
 | |
|   build_eff_key(r1, s1, 2);
 | |
|   build_eff_key(r2, s2, 2);
 | |
|   return s2.compare(s1);
 | |
| }
 | |
| 
 | |
| int TContabilizzazione_effetti_app::sort_eff(TRecord_array& rows)
 | |
| {
 | |
|   rows.sort(sort_eff_func);   // Ordina per anno/partita/fattura/rata
 | |
| 
 | |
|   // Raggruppa le righe riferite alla stessa rata
 | |
|   TString last_key, curr_key;
 | |
|   for (int i = rows.last_row(); i > 0; i--)
 | |
|   {
 | |
|     TRectype& row = rows[i];
 | |
|     build_eff_key(row, curr_key, 1);
 | |
|     if (curr_key == last_key) // Hanno la stessa rata per cui sommo e cancello l'ultima riga
 | |
|     {
 | |
|       real importo = rows[i+1].get(REFF_IMPORTO);
 | |
|       importo += row.get_real(REFF_IMPORTO);
 | |
|       row.put(REFF_IMPORTO, importo);
 | |
|       rows.destroy_row(i+1, TRUE);
 | |
|     }
 | |
|     else
 | |
|       last_key = curr_key;
 | |
|   }
 | |
|   
 | |
|   return rows.rows();
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::contabilize_bill(const char tipo, const long numero)
 | |
| {
 | |
|   TDistinta& distinta = *_distinta;
 | |
|   TLocalisamfile& mov = _movimento->lfile();
 | |
|   // tiene 2 array di record separati: uno per i clienti ed uno per le banche,
 | |
|   // alla fine, prima di scrivere il movimento, li riunisce nel record array di 
 | |
|   // _movimento, per metterli in ordine, prima le righe clienti e poi le righe delle banche
 | |
|   // L'array delle banche e' un assoc_array, con indice sul gruppo/conto/sottoconto
 | |
|   // per effettuare il raggruppamento
 | |
|   TArray customers;
 | |
|   TAssoc_array banks;
 | |
|   TArray differenze_cam;
 | |
|   TImporto abbuoni_att, abbuoni_pas;
 | |
| 
 | |
|   bool reset_bank = FALSE;
 | |
|   _total_mov = 0.0;
 | |
|   _total_mov_val = 0.0;
 | |
|   distinta.read(tipo,numero,_lock); // Sblocca da solo quella precedente
 | |
|   if (_caus != NULL)
 | |
|     delete _caus;
 | |
| 
 | |
|   const TString& cc = distinta.tipocf() == 'F' ? _cod_caus_pag : _cod_caus;
 | |
|   _caus = new TCausale(cc, _data_op.year());
 | |
|   if (!_caus->ok())                                                                
 | |
|   {                          
 | |
|      _error = generic_error;
 | |
|      error_box(FR("Causale '%s' non valida o non presente in parametri effetti"), cc);
 | |
|      return;
 | |
|   }
 | |
|   
 | |
|   //Cerca il conto della contropartita della banca di presentazione.
 | |
|   //Nel caso in cui sia presente sulla tabella BNP (selezione anche per
 | |
|   //tipo distinta) il conto sara' unico per tutti; se invece non e' presente sul file oppure il conto
 | |
|   //di contropartita e' vuoto, andra' reperito per ogni effetto, a seconda della causale
 | |
|   //impostata e del tipo di pagamento (quest'ultimo solo nel caso di saldaconto abilitato); altrimenti si
 | |
|   //terra' per buono sempre quello della seconda riga della casuale .
 | |
|   //E' chiaro che nella maggioranza dei casi si avra' sempre un unico conto di contropartita, definito
 | |
|   //nella tabella BNP.
 | |
|   //Non meno importante: nel caso avessimo piu' conti di contropartita per le banche
 | |
|   //si dovra' procedere ad un raggruppamento, sommando gli importi (mentre invece le righe 
 | |
|   //clienti non dovranno subire tale procedimento.
 | |
|   //Infine: a causa del cazzutissimo limite di 99 righe contabili settato in invii/ricezioni
 | |
|   //si dovranno generare piu' movimenti per un stessa distinta se le righe eccedono tale
 | |
|   //valore (come avere le palle sopra un'incudine ed una mazza ferrata che sta per piombare a tutta forza...)
 | |
|   search_bank_counter_bill();
 | |
|   if (!good()) 
 | |
|     return; // _error's already set
 | |
|     
 | |
|   real spese = distinta[0].get(EFF_SPESE);
 | |
|   TBill conto_cassa, conto_spese; 
 | |
|   if (!spese.is_zero())
 | |
|   {                     
 | |
|     _caus->bill(11, conto_spese);
 | |
|     if (!conto_spese.ok())
 | |
|     {
 | |
|       _error = cau_spe_error;
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
|  
 | |
|   bool dettaglio_rate = FALSE;
 | |
|   if (distinta.tipocf() == 'F')
 | |
|     dettaglio_rate = _dett_rate_pas;
 | |
|   else                                       
 | |
|     dettaglio_rate = _dett_rate_att;
 | |
|   
 | |
|   const int items = distinta.items();  // Perche' sul file effetti il numero riga distinta e' un long ??
 | |
|   
 | |
|   // compila la testata
 | |
|   compile_head_mov();
 | |
|    
 | |
|   // _cur_dist_row e' un int sebbene su file sia un long: TArray::items() ritorna un int!!
 | |
|   for (_cur_dist_row = 0; _cur_dist_row<items; _cur_dist_row++) // scorre le righe della distinta (effetti)
 | |
|   {
 | |
|     const TEffetto& eff = distinta[_cur_dist_row];
 | |
|     const long codcf = eff.get_long(EFF_CODCF);
 | |
|     const char tipo  = eff.get_tipo();
 | |
|     search_clifo_bill(tipo, codcf);
 | |
| 
 | |
|     if (!good()) break;
 | |
|     
 | |
|     // se la banca non e' stata settata cerca il conto sulla causale a seconda del tipo di pagamento di questo effetto
 | |
|     if (!_banca.ok() || reset_bank) 
 | |
|     {
 | |
|       search_bank_counter_bill(eff.get_int(EFF_TIPOPAG));
 | |
|       if (!good()) break;
 | |
|       reset_bank = TRUE;  // forza la ricerca del conto della banca ad ogni riga distinta
 | |
|     }
 | |
|     const bool force_break = !_trandiffcam.ok() && has_diffcam(eff);
 | |
|     
 | |
|     TRecord_array sorted = ((TEffetto&)eff).righe();
 | |
|     sort_eff(sorted);
 | |
|     
 | |
|     TString last_key, curr_key;
 | |
|     
 | |
|     for (int n = 1; n <= sorted.rows(); n++)
 | |
|     {
 | |
|       const TRectype& riga = sorted[n];
 | |
|       build_eff_key(riga, curr_key, 0);
 | |
|       
 | |
|       if (n == 1 || (dettaglio_rate && curr_key != last_key) || customers.items() == 0)
 | |
|       {
 | |
|         add_cg_row(eff, riga, customers, banks, FALSE);
 | |
|         last_key = curr_key;
 | |
|       }
 | |
|       else
 | |
|         sum_cg_row(riga, customers, banks);
 | |
|       
 | |
|       if (_sc_enabled)
 | |
|         compile_saldac(eff, riga, abbuoni_att, abbuoni_pas, differenze_cam, customers);
 | |
|       
 | |
|       // Calcola il numero di righe contabili generate fino ad ora.
 | |
|       // per i clienti e' sempre vero, mentre per le banche dipende 
 | |
|       // se e' stato fatto un raggruppamento
 | |
|       int nrows = customers.items() + banks.items();
 | |
|       if (_sc_enabled)
 | |
|       {
 | |
|         if (!abbuoni_att.is_zero()) nrows++;
 | |
|         if (!abbuoni_pas.is_zero()) nrows++;
 | |
|         nrows+=differenze_cam.items();
 | |
|       }   
 | |
|       if (!spese.is_zero())
 | |
|         nrows += 2;
 | |
| 
 | |
|       if (nrows > 0 && force_break)  // Se ci sono differenze cambio ...
 | |
|         nrows = CGROWS_LIMIT;        // ... allora forza cambio movimento
 | |
|     
 | |
|       if (nrows >= CGROWS_LIMIT) // se sono arrivato al limite massimo, scrivo questo movimento
 | |
|       {
 | |
|         // Unisce le righe banche e clienti nel record_array delle righe contabili
 | |
|         if (good() && _can_write)
 | |
|         {
 | |
|           join_rows(customers, banks, abbuoni_att, abbuoni_pas, differenze_cam, spese); 
 | |
|           if (good())
 | |
|             write_all(FALSE); // non cambiare lo stato della distinta, cambialo solo alla fine
 | |
|         }
 | |
|         if (good())
 | |
|         {
 | |
|           _movimento->destroy_rows(mov.get_long(MOV_NUMREG)); // azzera le righe..
 | |
|           _part_array->destroy(); // e l'array delle partite
 | |
|           customers.destroy();
 | |
|           banks.destroy();            
 | |
|           differenze_cam.destroy(); 
 | |
|           abbuoni_att = abbuoni_pas = TImporto('A', ZERO);
 | |
|           _total_mov = ZERO;
 | |
|           _total_mov_val = ZERO;
 | |
|           spese = ZERO;
 | |
|           // compila la testata del nuovo movimento
 | |
|           compile_head_mov();
 | |
|         }
 | |
|       }
 | |
|       if (!good()) break;
 | |
|     }
 | |
|   } // Ciclo su effetti
 | |
|   
 | |
|   if (good() && _can_write) // scrive il movimento residuo ...
 | |
|   {                       
 | |
|     if (customers.items() > 0)
 | |
|       join_rows(customers, banks, abbuoni_att, abbuoni_pas, differenze_cam, spese); 
 | |
|     if (good() && write_all() == no_error)  // Se la scrittura e' andata ok...
 | |
|       _total_bills++; // incrementa il numero di distinte contabilizzate
 | |
|   }
 | |
|   _movimento->destroy_rows(mov.get_long(MOV_NUMREG)); // azzera le righe..
 | |
|   _part_array->destroy(); // e l'array delle partite
 | |
| }
 | |
| 
 | |
| void TContabilizzazione_effetti_app::contabilize()
 | |
| {
 | |
|   _total_bills = 0;
 | |
| 
 | |
|   const long cur_items = _dist_sheet->items(); // Quante distinte in totale ?
 | |
|   TProgind p(cur_items, TR("Contabilizzazione effetti"), FALSE, TRUE);
 | |
|   for (long j = 0; j < cur_items; j++)
 | |
|   {                    
 | |
|     p.setstatus(j+1);
 | |
|     if (_dist_sheet->checked(j))
 | |
|     {
 | |
|       TToken_string& t = _dist_sheet->row(j);
 | |
|       const char tipo = t.get_char(1);
 | |
|       const long numero = t.get_long(2);
 | |
|       contabilize_bill(tipo,numero);
 | |
|       if (!good())    
 | |
|         display_error();
 | |
|     }
 | |
|   }
 | |
|   if (_total_bills > 0)
 | |
|     message_box(FR("Totale distinte contabilizzate: %ld"),_total_bills);
 | |
| }
 | |
| 
 | |
| int ef0800 (int argc, char* argv[])
 | |
| {
 | |
|   TContabilizzazione_effetti_app a;
 | |
|   a.run(argc,argv,TR("Contabilizzazione effetti"));
 | |
|   return TRUE;
 | |
| } |