pagament   cgpagame
                                 classpim   cgpim
git-svn-id: svn://10.65.10.50/trunk@4725 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
	
			
		
			
				
	
	
		
			1875 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1875 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <defmask.h>          // Serve per DLG_NEWREC
 | |
| #include <msksheet.h>
 | |
| #include <colors.h>           // COlori righe
 | |
| 
 | |
| #include "cg2100p.h"          // Campi maschere partite e pagamenti
 | |
| 
 | |
| #ifdef __EXTRA__
 | |
| #include "cgsaldac.h"
 | |
| #include "sc0100p.h"
 | |
| #else
 | |
| #include "cg2100.h"           // Campi maschere prima nota
 | |
| #include "cg2102.h"           // Applicazione di prima nota
 | |
| #endif
 | |
| 
 | |
| #include <causali.h>          // Archivio causali
 | |
| #include <clifo.h>            // Archivio clienti/fornitori
 | |
| #include <mov.h>              // Archivio movimenti di prima nota
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Definizione Maschera partite
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TGame_mask : public TMask
 | |
| {                       
 | |
|   const TBill _conto;          // Conto fisso del cliente/fornitore
 | |
|   long _numreg;                // Numero movimento contabile
 | |
|   int  _numrig;                // Riga contabile corrente (prima = 1!)
 | |
|   TImporto _importo;           // Importo su riga contabile
 | |
|   TImporto _residuo, _resval;  // Residuo della riga contabile
 | |
|   int _riga_partite;           // Riga corrente delle partite
 | |
|   bool _changed;               // Flag di modifica partite
 | |
|   bool _valfirst;              // La colonna della valuta precede le lire
 | |
|   
 | |
|   TDecoder _causali;           // Decodificatore delle causali
 | |
|   
 | |
| protected:
 | |
|   static bool annopart_handler(TMask_field& f, KEY k);
 | |
|   static bool numpart_handler(TMask_field& f, KEY k);
 | |
|   static bool partite_notify(TSheet_field& partite, int r, KEY k);
 | |
|   static bool scadenze_notify(TSheet_field& partite, int r, KEY k);
 | |
|   static bool show_all_handler(TMask_field& f, KEY k);
 | |
|   static bool edit_scadenza_handler(TMask_field& f, KEY k);
 | |
|   static bool nuovo_handler(TMask_field& f, KEY k);
 | |
|   static bool cambio_handler(TMask_field& f, KEY k);
 | |
| 
 | |
|   void add_importo(TToken_string& s, const TImporto& i, bool val = FALSE, int pos = -1);
 | |
|   void add_descrizione(TToken_string& s, const TRiga_partite& riga, int pos = -1);
 | |
|   TImporto get_importo(TToken_string& s, int pos) const;
 | |
|                       
 | |
|   TToken_string& add_colored_row(TSheet_field& sheet, char type) const;
 | |
| 
 | |
|   void fill_partite();
 | |
|   
 | |
|   void aggiorna_residuo();
 | |
| 
 | |
|   int update_partita(const TRectype& game, const TImporto& s, const TImporto& d,
 | |
|                      const TImporto& p, const TImporto& i, int prow);
 | |
|   int update_partita(const TPartita& game, int prow);
 | |
|   int update_partita(const TRectype& game, int prow);
 | |
| 
 | |
|   void update_saldo_clifo();
 | |
|   int nuova_riga(TPartita& partita, tipo_movimento tm) const;
 | |
|   int nuovo_pagamento(TPartita& partita, int nriga, int rata, tipo_movimento tm) const;
 | |
|   bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const;
 | |
| 
 | |
|   char calcola_sezione(tipo_movimento tm = tm_pagamento) const;
 | |
|   long number_distance(const char* key, const char* num) const;
 | |
|   bool same_number(const char* key, const char* num) const;
 | |
|   void append_conto(TString& s) const;
 | |
|   
 | |
| #ifdef __EXTRA__  
 | |
|   bool edit_fattura(TPartita& p, int nriga);
 | |
|   bool prima_nota(const long nreg);
 | |
| #endif
 | |
| 
 | |
|   const TRiga_partite* cerca_prima_riga() const;
 | |
|   void aggiorna_valuta(const TValuta& val);
 | |
| //  void aggiorna_sorelle(const TRiga_partite& part) const;
 | |
|   
 | |
| public:
 | |
|   TSheet_field& partite() const { return (TSheet_field&)field(P_PARTITE); }
 | |
|   TSheet_field& scadenze() const { return (TSheet_field&)field(P_SCADENZE); }
 | |
|   const TBill& conto() const { return _conto; }
 | |
|   
 | |
|   const TImporto& residuo(bool val) const { return val ? _resval : _residuo; }
 | |
|   bool changed() const { return _changed; }
 | |
| 
 | |
|   TGame_mask(const TBill& bill, long numreg, int riga);
 | |
|   virtual ~TGame_mask() {}
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Maschera pagamenti
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TPay_mask : public TMask
 | |
| { 
 | |
|   TDate _datadoc;                         
 | |
|   real _da_pagare, _pagabile;
 | |
|   const TGame_mask& _parent;
 | |
|   
 | |
|   tipo_movimento _tipomov;
 | |
|   
 | |
|   TDecoder _causale;   
 | |
|   bool _assigned;
 | |
|   bool _can_solder;
 | |
|   
 | |
| protected:
 | |
|   static bool importo_handler(TMask_field& f, KEY k);
 | |
|   static bool importolire_handler(TMask_field& f, KEY k);
 | |
|   static bool saldo_handler(TMask_field& f, KEY k);
 | |
|   static bool datapag_handler(TMask_field& f, KEY k);
 | |
|   static bool conto_handler(TMask_field& f, KEY k);
 | |
|   static bool descr_handler(TMask_field& f, KEY k);
 | |
|   void gioca_cambi(int force = 0x0);
 | |
|   
 | |
|   static bool sottoconto_handler(TMask_field& f, KEY k);
 | |
| #ifdef __EXTRA__  
 | |
|   static bool datareg_handler(TMask_field& f, KEY k);
 | |
|   static bool datadoc_handler(TMask_field& f, KEY k);
 | |
|   static bool numdoc_handler(TMask_field& f, KEY k);
 | |
|   static bool sezione_handler(TMask_field& f, KEY k);
 | |
| #endif  
 | |
| 
 | |
| public:
 | |
|   void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad, const TImporto& importo);
 | |
|   void get_pag(TRectype& oldpag, TRectype& somma) const;
 | |
|   
 | |
|   bool assigned() const { return _assigned; }
 | |
|   bool unassigned() const { return !_assigned; }
 | |
|   tipo_movimento tipo() const { return _tipomov; }
 | |
|   
 | |
|   void attiva_valuta(bool on);
 | |
| 
 | |
|   TPay_mask(const TGame_mask& parent, int mode);
 | |
|   virtual ~TPay_mask();
 | |
| };
 | |
| 
 | |
| #ifdef __EXTRA__         
 | |
| const char* const PAYMASK = "sc0100b";
 | |
| #else
 | |
| const char* const PAYMASK = "cg2100s";
 | |
| #endif           
 | |
| 
 | |
| TPay_mask::TPay_mask(const TGame_mask& parent, int mod) 
 | |
|          : TMask(PAYMASK), _parent(parent), 
 | |
|            _causale(LF_CAUSALI, CAU_DESCR)
 | |
| { 
 | |
|   set_mode(mod);
 | |
|   enable(DLG_DELREC, edit_mode());
 | |
|   set_handler(S_SOTTOCONTO, sottoconto_handler);
 | |
|   
 | |
| #ifdef __EXTRA__
 | |
|   xvt_statbar_set(mod == MODE_MOD ? "Modifica" : "Inserimento", TRUE);
 | |
| 
 | |
|   hide(E_CODPAG); hide(E_DESPAG);  
 | |
|   set_handler(E_DATAREG, datareg_handler);
 | |
|   set_handler(E_DATADOC, datadoc_handler);
 | |
|   set_handler(E_NUMDOC, numdoc_handler);
 | |
|   set_handler(E_SEZIONE, sezione_handler);
 | |
| 
 | |
|   set_handler(E_TOTALE, TSaldaconto_app::totale_handler);
 | |
|   if (app().gestione_valuta())
 | |
|   {            
 | |
|     show(-3);  
 | |
|     set_handler(E_TOTDOCVAL,  TSaldaconto_app::totval_handler);
 | |
|     set_handler(E_VALUTA,     TSaldaconto_app::valuta_handler);
 | |
|     set_handler(E_DATACAMBIO, TSaldaconto_app::datacambio_handler);
 | |
|     set_handler(E_CAMBIO,     TSaldaconto_app::cambio_handler);
 | |
|   }
 | |
|   else
 | |
|     hide(-3);  
 | |
| 
 | |
|   hide(S_RESIDUOPAG);
 | |
|   hide(-2); // I campi relativi alla contropartita non vengono gestiti
 | |
|   hide(E_IMPOSTE);
 | |
|                                                                       
 | |
|   set_handler(E_DESCR, descr_handler);
 | |
|   set_handler(S_DESCAGG, descr_handler);
 | |
|                                                                       
 | |
|   const char a = TPartita::allineamento_richiesto(parent.conto().tipo());
 | |
|   field(E_NUMRIF).set_justify(a == 'R');
 | |
| 
 | |
|   disable(E_ANNORIF);
 | |
|   disable(E_NUMRIF);
 | |
| #endif
 | |
| } 
 | |
| 
 | |
| TPay_mask::~TPay_mask() 
 | |
| {
 | |
| #ifdef __EXTRA__
 | |
|   xvt_statbar_set("Estratto conto", TRUE);
 | |
| #endif  
 | |
| }
 | |
| 
 | |
| void TPay_mask::attiva_valuta(bool in_valuta)
 | |
| {
 | |
|   if (in_valuta)
 | |
|   {
 | |
|     set_handler(S_IMPORTOVAL, importo_handler); 
 | |
|     set_handler(S_IMPORTO, importolire_handler); 
 | |
|   }
 | |
|   else  
 | |
|     set_handler(S_IMPORTO, importo_handler); 
 | |
|     
 | |
|   enable(S_RITENUTE, !in_valuta);       // dis/abilita ritenute
 | |
|   enable(S_IMPORTOVAL, in_valuta);
 | |
|   
 | |
|   if (in_valuta) 
 | |
|   {
 | |
|     reset(S_RITENUTE);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     reset(S_IMPORTOVAL_SCAD);
 | |
|     reset(S_IMPORTOVAL);
 | |
|   }  
 | |
| }
 | |
| 
 | |
| void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad, 
 | |
|                         const TImporto& residuo)
 | |
| {                   
 | |
|   const TPartita& p = scad.partita();
 | |
|   const int nrigp = oldpag.get_int(PAGSCA_NRIGP);
 | |
|   const TRiga_partite& sum = p.riga(nrigp);
 | |
|   _assigned = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED;
 | |
|   _tipomov = (tipo_movimento)sum.get_int(PART_TIPOMOV);
 | |
|   
 | |
|   const TRiga_partite& fatt = _assigned ? scad.riga() : sum;
 | |
| 
 | |
|   TRelation rel(LF_PAGSCA);                // Working relation
 | |
|   rel.add(LF_PARTITE, "ANNO=ANNO|NUMPART=NUMPART");
 | |
|   rel.curr() = oldpag;
 | |
|   rel.curr(LF_PARTITE) = sum;
 | |
|   autoload(rel);                          // Load current record on mask
 | |
|   
 | |
|   TMask_field& group = field(S_RATA);
 | |
|   TString prompt(80);
 | |
|   
 | |
|   const TBill& k = p.conto();
 | |
|   switch (k.tipo())
 | |
|   {
 | |
|   case 'C': prompt << "Cliente"; break;
 | |
|   case 'F': prompt << "Fornitore"; break;
 | |
|   default : prompt << "Conto " << k.gruppo() << ' ' << k.conto(); break;
 | |
|   }
 | |
|   prompt << ' ' << k.sottoconto() << ' ';
 | |
|   prompt << "Partita:" << p.anno() << ' ' << p.numero()
 | |
|          << " Riga:" << oldpag.get_int(PAGSCA_NRIGA) 
 | |
|          << " Rata:" << oldpag.get_int(PAGSCA_NRATA);
 | |
|   if (assigned())       
 | |
|     prompt << " del " << scad.get_date(SCAD_DATASCAD).string();
 | |
| #ifndef __EXTRA__    
 | |
|   else
 | |
|     prompt << " del " << sum.get_date(PART_DATAPAG).string();
 | |
| #endif    
 | |
|   group.set_prompt(prompt);
 | |
| 
 | |
|   set(S_NUMDOC,  fatt.get(PART_NUMDOC));             // Numero documento
 | |
|   set(S_DATADOC, fatt.get(PART_DATADOC));            // Data documento
 | |
|   set(S_NUMPROT, fatt.get(PART_PROTIVA));            // Protocollo IVA
 | |
| 
 | |
|   TString desfat = fatt.get(PART_DESCR);             // Descrizione fattura
 | |
|   if (desfat.empty())                                // Se e' vuota ...
 | |
|   {
 | |
|     desfat = fatt.get(PART_CODCAUS);
 | |
|     desfat = _causale.decode(desfat);                // ... usa descrizione causale
 | |
|   }
 | |
|   set(S_DESCR, desfat);                              
 | |
| 
 | |
|   bool in_valuta = fatt.in_valuta();
 | |
| #ifdef __EXTRA__
 | |
|   const bool prima_riga = p.first() == p.last();
 | |
|   if (!in_valuta && prima_riga)
 | |
|     in_valuta = app().gestione_valuta();
 | |
|   enable(E_VALUTA, prima_riga); // La valuta puo' essere cambiata solo sulle partite nuove
 | |
| #endif  
 | |
|   show(-3, in_valuta);          // Visualizza campi relativi alla valuta
 | |
|   attiva_valuta(in_valuta);     // Attiva campi e handlers relativi alla valuta
 | |
|   
 | |
|   const char sez_fat = fatt.sezione();
 | |
|   set(S_SEZIONE_SCAD, sez_fat == 'A' ? "A" : "D"); // Sezione della riga
 | |
|   if (assigned())
 | |
|   {
 | |
|     set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO));         // Importo della rata
 | |
|     if (in_valuta)
 | |
|       set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta 
 | |
|     TImporto res_rat = scad.residuo(in_valuta);  
 | |
|     res_rat.normalize(sez_fat);  
 | |
|     _da_pagare = res_rat.valore();       // Calcola residuo in valuta
 | |
| 
 | |
|     TReal_field& res = (TReal_field&)field(S_RESIDUORATA);
 | |
|     res.set_decimals(in_valuta ? 3 : 0);
 | |
|     if (get(S_SALDOACC)[0] != 'S')
 | |
|       res.set(_da_pagare.string());
 | |
|   }
 | |
|   else                
 | |
|   {
 | |
|     hide(S_RESIDUORATA);        // Se non assegnato nascondi residuo rata
 | |
|     _da_pagare = ZERO;
 | |
|   }
 | |
|   
 | |
|   set_handler(S_SALDOACC, saldo_handler);
 | |
|   
 | |
|   real oldimp = oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO);   
 | |
|   if (!in_valuta)
 | |
|     oldimp += oldpag.get_real(PAGSCA_RITENUTE);   
 | |
|   
 | |
|   // Ricorda l'importo da pagare
 | |
|   _da_pagare += oldimp;
 | |
|   
 | |
| #ifndef __EXTRA__
 | |
|   _pagabile = _parent.residuo(in_valuta).valore();
 | |
| 
 | |
|   TReal_field& resp = (TReal_field&)field(S_RESIDUOPAG);
 | |
|   resp.set_decimals(in_valuta ? 3 : 0);
 | |
|   resp.set(_pagabile.string());
 | |
|   
 | |
|   _pagabile += oldimp;
 | |
| #endif
 | |
|   
 | |
|   // Il flag di saldo/acconto e' attivo solo se non ci sono acconti, cioe':
 | |
|   // pagamento non assegnato o con data documento antecedente quella della fattura
 | |
|   _can_solder = _assigned;
 | |
|   if (_can_solder)
 | |
|   {                            
 | |
|     const tipo_movimento tm = sum.tipo();
 | |
|     _can_solder = !(tm == tm_nota_credito || tm == tm_insoluto);
 | |
|     if (_can_solder)
 | |
|     {
 | |
|       const TDate datasca(fatt.get(PART_DATADOC)); 
 | |
|       const TDate datapag(sum.get(PART_DATADOC));
 | |
|       _can_solder = datapag >= datasca;
 | |
|     }  
 | |
|   }
 | |
| 
 | |
|   // Mostra saldo solo se non e' ne' un acconto, ne' una nota di credito
 | |
|   enable(S_SALDOACC, _can_solder);  
 | |
| 
 | |
| #ifdef __EXTRA__                          
 | |
|   enable(E_SEZIONE, oldpag.get_char(PAGSCA_ACCSAL) != 'S');
 | |
| #else
 | |
|   set_handler(S_GRUPPO, conto_handler);
 | |
|   set_handler(S_CONTO, conto_handler);
 | |
|   const bool mostra_conto = !sum.is_nota_credito();          
 | |
|   show(-2, mostra_conto);       // mostra/nasconde conto contropartita
 | |
| #endif  
 | |
| 
 | |
| // Gestione data-pagamento: non puo' precedere la data del documento
 | |
|   _datadoc = sum.get_date(PART_DATADOC);
 | |
|   set_handler(S_DATAPAG, datapag_handler); 
 | |
| 
 | |
|   const bool mostra_ritenute = !sum.is_nota_credito();
 | |
|   show(S_RITENUTE, mostra_ritenute);
 | |
| } 
 | |
| 
 | |
| void TPay_mask::get_pag(TRectype& newpag, TRectype& sum) const
 | |
| {
 | |
|   TRelation rel(LF_PAGSCA);                // Working relation
 | |
|   rel.add(LF_PARTITE, "ANNO=ANNO|NUMPART=NUMPART");
 | |
|   rel.curr() = newpag;       
 | |
|   rel.curr(LF_PARTITE) = sum;
 | |
|   autosave(rel);                          // Load current record from mask
 | |
|   newpag = rel.curr();
 | |
|   sum = rel.curr(LF_PARTITE);
 | |
| }     
 | |
| 
 | |
| // Riempie i campi valuta a zero in base agli altri
 | |
| void TPay_mask::gioca_cambi(int force)
 | |
| {               
 | |
|   const real totale = get(S_IMPORTO);
 | |
|   const real totval = get(S_IMPORTOVAL);
 | |
| 
 | |
| #ifdef __EXTRA__
 | |
|   const TValuta cambio(*this, E_VALUTA, E_DATACAMBIO, E_CAMBIO);
 | |
| #else  
 | |
|   const TValuta cambio(_parent, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
| #endif  
 | |
| 
 | |
|   if ( (force == 0x1 || totale.is_zero()) && !(totval.is_zero() || cambio.in_lire()) )
 | |
|   {
 | |
|     const real new_totale = cambio.val2lit(totval);
 | |
|     if (new_totale != totale)
 | |
|       set(S_IMPORTO, new_totale, TRUE);
 | |
|   } 
 | |
|   
 | |
|   if ( (force == 0x2 || totval.is_zero()) && !(totale.is_zero() || cambio.in_lire()))
 | |
|   {
 | |
|     const real new_totval = cambio.lit2val(totale);
 | |
|     if (new_totval != totval)
 | |
|       set(S_IMPORTOVAL, new_totval, TRUE);
 | |
|   } 
 | |
| 
 | |
| #ifdef __EXTRA__  
 | |
|   if ( (force == 0x4 || cambio.in_lire()) && !(totale.is_zero() || totval.is_zero()))
 | |
|   {
 | |
|     real new_cambio = totale / totval; new_cambio.round(5);
 | |
|     if (new_cambio != cambio.cambio())
 | |
|       set(E_CAMBIO, new_cambio, TRUE);
 | |
|   } 
 | |
| #endif  
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TPay_mask::importo_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   TPay_mask& m = (TPay_mask&)f.mask();         
 | |
| 
 | |
|   if (k == K_F8)
 | |
|   {        
 | |
|     real imp;
 | |
| #ifdef __EXTRA__
 | |
|     const bool in_valuta = m.field(S_IMPORTOVAL).active();
 | |
|     m._pagabile = m.get_real(in_valuta ? E_TOTDOCVAL : E_TOTALE);
 | |
|     if (m._assigned)
 | |
|       imp = fnc_min(m._da_pagare, m._pagabile);
 | |
|     else
 | |
|       imp = m._pagabile;
 | |
| #else
 | |
|     if (m.field(S_RESIDUORATA).shown() && m.field(S_RESIDUOPAG).shown())
 | |
|       imp = fnc_min(m._da_pagare, m._pagabile);
 | |
|     else
 | |
|       imp = m.field(S_RESIDUORATA).shown() ? m._da_pagare : m._pagabile;
 | |
| #endif
 | |
|       
 | |
|     if (m.field(S_RITENUTE).active())
 | |
|       imp -= real(m.get(S_RITENUTE));
 | |
|     
 | |
|     f.set(imp.string());           
 | |
|     k = K_TAB;
 | |
|   }           
 | |
|   
 | |
|   if (k == K_TAB && (f.focusdirty() || !m.is_running()))
 | |
|   {            
 | |
|     const bool in_valuta = m.field(S_IMPORTOVAL).active();
 | |
|     if (in_valuta)
 | |
|       m.gioca_cambi();
 | |
|   
 | |
|     real i(f.get());
 | |
|     if (m.field(S_RITENUTE).active())
 | |
|       i += real(m.get(S_RITENUTE));
 | |
|     
 | |
|     TMask_field& sa = m.field(S_SALDOACC);
 | |
|     TMaskmode mod = (TMaskmode)m.mode();
 | |
|     if (m._can_solder && (mod == NO_MODE || mod == MODE_INS))
 | |
|     {                      
 | |
|       if (i >= m._da_pagare)
 | |
|         sa.set("S");
 | |
| /*
 | |
|       Eliminato perche' rende ingestibili due pagamenti in valuta a saldo  
 | |
|       if (in_valuta) sa.enable(i != m._da_pagare);
 | |
| */      
 | |
|     }  
 | |
|     
 | |
|     if (sa.get()[0] != 'S')
 | |
|     {
 | |
|       real residuo = m._da_pagare;
 | |
|       if (m.tipo() == tm_insoluto)
 | |
|         residuo += i;
 | |
|       else  
 | |
|         residuo -= i;
 | |
|       m.set(S_RESIDUORATA, residuo);
 | |
|     }
 | |
|     else
 | |
|       m.reset(S_RESIDUORATA);
 | |
|       
 | |
|     const real residuopag(m._pagabile - i);
 | |
|     m.set(S_RESIDUOPAG, residuopag);
 | |
|   } 
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TPay_mask::importolire_handler(TMask_field& f, KEY k)
 | |
| {               
 | |
|   TPay_mask& m = (TPay_mask&)f.mask();         
 | |
| 
 | |
|   if (k == K_F8)
 | |
|   {
 | |
| #ifdef __EXTRA__
 | |
|     if (m.unassigned())
 | |
|       f.set(m.get(E_TOTALE));
 | |
|     else  
 | |
| #endif  
 | |
|     m.send_key(k, S_IMPORTOVAL);
 | |
|   }
 | |
|     
 | |
|   if (f.to_check(k))
 | |
|     m.gioca_cambi();
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TPay_mask::saldo_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_SPACE)
 | |
|   {           
 | |
|     TMask& m = f.mask();
 | |
|     m.set_mode(MODE_QUERY);
 | |
|     TMask_field& imp =  m.field(m.field(S_IMPORTOVAL).active() ? S_IMPORTOVAL : S_IMPORTO);
 | |
|     imp.set_dirty();
 | |
|     imp.on_hit();
 | |
|     m.set_mode(NO_MODE);
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TPay_mask::sottoconto_handler(TMask_field& f, KEY k)
 | |
| {           
 | |
|   bool ok = TRUE;
 | |
|   if (k == K_ENTER && f.mask().insert_mode() && f.get().empty())
 | |
|     ok = f.error_box("Contropartita obbligatoria");
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TPay_mask::datapag_handler(TMask_field& f, KEY k)
 | |
| {   
 | |
|   if (f.to_check(k))           
 | |
|   {
 | |
|     const TDate datapag(f.get());
 | |
|     TPay_mask& m = (TPay_mask&)f.mask();         
 | |
|     if (datapag < m._datadoc)
 | |
|       return f.error_box("La data del pagamento e' inferiore alla data del documento %s", 
 | |
|                          m._datadoc.string());
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TPay_mask::conto_handler(TMask_field& f, KEY k)
 | |
| {   
 | |
|   if (k == K_TAB && f.focusdirty())
 | |
|   {                        
 | |
|     TMask& m = f.mask();
 | |
|     TBill conto; conto.get(m, S_GRUPPO, S_CONTO, S_SOTTOCONTO);
 | |
|     const TString& desc = conto.descrizione();
 | |
|     if (desc.empty()) 
 | |
|       m.reset(S_SOTTOCONTO);
 | |
|     m.set(S_DESCRCONTO, desc);
 | |
|   }           
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Maschera gestione nuovo pagamento / fattura
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TNew_mask : public TMask
 | |
| {        
 | |
|   bool _allow_fatt;
 | |
| 
 | |
| protected:
 | |
|   static bool tipomov_handler(TMask_field& f, KEY k);
 | |
|               
 | |
| public:
 | |
|   TNew_mask(char tipocf, bool fatt, bool edit);
 | |
|   virtual ~TNew_mask() {}
 | |
| };                                                         
 | |
| 
 | |
| bool TNew_mask::tipomov_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_ENTER)
 | |
|   {
 | |
|     TNew_mask& m = (TNew_mask&)f.mask();
 | |
|     if (!m._allow_fatt && f.get() == "1")
 | |
|       return f.error_box("Non e' possibile utilizzare una fattura come pagamento");
 | |
|   }
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| TNew_mask::TNew_mask(char tipocf, bool fatt, bool edit)
 | |
|          : TMask("cg2100n"), _allow_fatt(fatt)
 | |
| {   
 | |
|   TMask_field& tipomov = field(P_NUOVO);
 | |
| #ifdef __EXTRA__
 | |
|   tipomov.set_handler(tipomov_handler);
 | |
|   tipomov.enable();
 | |
|   tipomov.set(_allow_fatt ? "1" : "3");
 | |
|   if (!_allow_fatt)
 | |
|     set_caption("Nuovo pagamento");
 | |
| #else  
 | |
|   tipomov.disable();
 | |
| #endif  
 | |
| 
 | |
|   enable(P_ANNO,   edit);
 | |
|   enable(P_NUMERO, edit);
 | |
|   if (edit) first_focus(P_NUMERO);
 | |
|   
 | |
|   const char a = TPartita::allineamento_richiesto(tipocf);
 | |
|   field(P_NUMERO).set_justify(a == 'R');
 | |
| }         
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Maschera partite
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void TGame_mask::append_conto(TString& s) const
 | |
| {
 | |
|   switch (conto().tipo()) 
 | |
|   {
 | |
|   case 'C':
 | |
|     s << "Cliente"; break;
 | |
|   case 'F':
 | |
|     s << "Fornitore"; break;
 | |
|   default:
 | |
|     s << "Conto " << conto().gruppo() << ' ' << conto().conto(); break;
 | |
|   }    
 | |
|   s << ' ' << conto().sottoconto();  
 | |
| }
 | |
| 
 | |
| TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga) 
 | |
| : TMask("cg2100p"), _conto(bill), _numreg(numreg), _numrig(riga),
 | |
|   _changed(FALSE), _valfirst(FALSE), _causali(LF_CAUSALI, CAU_DESCR)
 | |
| {     
 | |
|   TString descr(80);
 | |
|   append_conto(descr);
 | |
|   descr << ' ' << ((TBill&)_conto).descrizione();
 | |
|   set(P_DESCR, descr);
 | |
|               
 | |
| #ifdef __EXTRA__  
 | |
|   xvt_statbar_set("Estratto conto", TRUE);
 | |
| 
 | |
|   disable(-3);     // Disabilita gestione valuta
 | |
|   hide(P_RESIDUO);
 | |
|   hide(P_RESIDUOVAL);
 | |
| #else
 | |
|   TValuta val;
 | |
|   const TRiga_partite* row = cerca_prima_riga();
 | |
|   if (row != NULL)
 | |
|   {                                   
 | |
|     val.get(*row);                               // Legge valuta standard dalla partita
 | |
|     set(P_ANNO, row->get(PART_ANNO));            // Propone anno e partita
 | |
|     set(P_NUMERO, row->get(PART_NUMPART));
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     TMask& cm = app().curr_mask();               // Legge valuta dal movimento      
 | |
|     val.get(cm, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO);
 | |
|     
 | |
|     if (cm.id2pos(F_ANNORIF) > 0)                // Se in testata c'e' l'anno di riferimento
 | |
|     {
 | |
|       set(P_ANNO, cm.get(F_ANNORIF));            // Propone anno e partita
 | |
|       set(P_NUMERO, cm.get(F_NUMRIF));             
 | |
|     }  
 | |
|   }
 | |
|   val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
|   enable(-3, val.in_valuta());
 | |
| #endif  
 | |
|   
 | |
|   set_handler(P_ANNO,    annopart_handler);
 | |
|   set_handler(P_NUMERO,  numpart_handler);
 | |
|   set_handler(P_SHOWALL, show_all_handler);
 | |
|   set_handler(P_NUOVO,   nuovo_handler);
 | |
|   set_handler(P_CAMBIO,  cambio_handler);
 | |
|   
 | |
|   TSheet_field& games = partite();
 | |
|   games.set_notify(partite_notify);
 | |
|     
 | |
|   scadenze().set_notify(scadenze_notify);
 | |
|   scadenze().sheet_mask().set_handler(100, edit_scadenza_handler);
 | |
|   
 | |
|   fill_partite();                                     // Riempie sheet partite
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| // Handlers dei campi e della maschera principale
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| 
 | |
| bool TGame_mask::annopart_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_TAB && f.focusdirty() && f.get().not_empty())
 | |
|   {
 | |
|     TMask_field& n = f.mask().field(P_NUMERO);
 | |
|     n.set_dirty();
 | |
|     numpart_handler(n, k);
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::numpart_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_TAB && f.focusdirty())
 | |
|   {                  
 | |
|     const TGame_mask& m = (const TGame_mask&)f.mask();
 | |
|     const int anno = m.get_int(P_ANNO);        // Anno partita da cercare
 | |
|     if (anno > 0)
 | |
|     {
 | |
|       const TString key = f.get();             // Numero partita da cercare
 | |
|       int best_match = 0;                      // Partita piu' somigliante
 | |
|       long min_dist = 10000000L;               // Livello di somiglianza migliore
 | |
|       
 | |
|       TSheet_field& sheet = m.partite();
 | |
|       for (int i = 0; i < sheet.items(); i++)
 | |
|       {
 | |
|         TToken_string& row = sheet.row(i);
 | |
|         if (anno == row.get_int(0))               // Se corrisponde l'anno e ...
 | |
|         {        
 | |
|           const long dist = m.number_distance(key, row.get());
 | |
|           if (i == 0 || dist < min_dist)
 | |
|           {
 | |
|             min_dist = dist;
 | |
|             best_match = i;
 | |
|             if (dist == 0L)
 | |
|               break;
 | |
|           }
 | |
|         }  
 | |
|       }
 | |
|       sheet.select(best_match);                   // seleziona la partita
 | |
|     }
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::show_all_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   TGame_mask& gm = (TGame_mask&)f.mask();
 | |
|   if (k == K_SPACE && gm.is_running())
 | |
|   {
 | |
|     gm.fill_partite();
 | |
|   } 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::cambio_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_TAB && f.focusdirty())
 | |
|   {
 | |
|     TGame_mask& gm = (TGame_mask&)f.mask();
 | |
|     const bool needed = app().partite().mov2rig(gm._numreg, gm._numrig) > 0;
 | |
|     if (needed && yesno_box("Aggiornare gli importi dei pagamenti?"))
 | |
|     {
 | |
|       const TValuta val(gm, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
|       gm.aggiorna_valuta(val);
 | |
|     }  
 | |
|     gm.aggiorna_residuo();
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| // Metodi dei campi e della maschera principale
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| 
 | |
| // Aggiorna il campo con il residuo da spendere sui pagamenti
 | |
| void TGame_mask::aggiorna_residuo()
 | |
| {                            
 | |
| #ifndef __EXTRA__
 | |
|   _importo = app().get_cgs_imp(_numrig-1);                     // Importo sulla riga contabile
 | |
|   _residuo = _importo;
 | |
|   
 | |
|   TPartite_array& giochi = app().partite();
 | |
|   const TImporto speso = giochi.importo_speso(_numreg, _numrig); 
 | |
|   _residuo -= speso;                                           // Residuo della riga
 | |
| 
 | |
|   const char sez = calcola_sezione();                          // Sezione di riferimento
 | |
|   _residuo.normalize(sez);
 | |
|   set(P_RESIDUO, _residuo.valore());
 | |
|   
 | |
|   const TValuta cambio(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
|   if (cambio.in_valuta())
 | |
|   {                                                                         
 | |
|     // Importo della riga contabile senza differenza cambi
 | |
|     _resval = _importo;
 | |
|     const TImporto abb_diff = giochi.importo_speso(_numreg, _numrig, FALSE, 0x6);
 | |
|     _resval -= abb_diff;
 | |
|     cambio.lit2val(_resval);
 | |
|     const TImporto spesoval = giochi.importo_speso(_numreg, _numrig, TRUE, 0x1);
 | |
|     _resval -= spesoval;                                       // Residuo della riga
 | |
|     _resval.normalize(sez);
 | |
|     set(P_RESIDUOVAL, _resval.valore());
 | |
|   }
 | |
| #endif  
 | |
| }
 | |
| 
 | |
| // Scandisce tutte le partite per cercare la prima del movimento corrente
 | |
| const TRiga_partite* TGame_mask::cerca_prima_riga() const
 | |
| {   
 | |
|   const TRiga_partite* riga = app().partite().mov2rig(_numreg, _numrig);
 | |
|   return riga;
 | |
| }
 | |
| 
 | |
| 
 | |
| void TGame_mask::aggiorna_valuta(const TValuta& val)
 | |
| {          
 | |
|   TPartite_array& pa = app().partite();
 | |
|   for (TPartita* game = pa.first(); game; game = pa.next())
 | |
|   {
 | |
|     for (int r = game->last(); r > 0; r = game->pred(r))
 | |
|     {
 | |
|       const TRiga_partite& riga = game->riga(r);
 | |
|       for (int s = riga.rate(); s > 0; s--)
 | |
|       {
 | |
|         const TRiga_scadenze& scad = riga.rata(s);
 | |
|         for (int p = scad.last(); p > 0; p = scad.pred(p))
 | |
|         {
 | |
|           TRiga_partite& sum = game->riga(p);
 | |
|           if (sum.get_long(PART_NREG) == _numreg && 
 | |
|               sum.get_int(PART_NUMRIG) == _numrig)
 | |
|           {     
 | |
|             TRectype pag(scad.row(p));
 | |
|             real imp(pag.get(PAGSCA_IMPORTOVAL));
 | |
|             val.val2lit(imp);
 | |
|             pag.put(PAGSCA_IMPORTO, imp);          // Converte in lire l'importo in valuta
 | |
| #ifdef __EXTRA__
 | |
|             game->modifica_pagamento(pag, val, TRUE);
 | |
| #else                           
 | |
|             app().notify_edit_pagamento(*game, pag, val);
 | |
| #endif            
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }  
 | |
|   fill_partite(); 
 | |
| }
 | |
| 
 | |
| /*
 | |
| void TGame_mask::aggiorna_sorelle(const TRiga_partite& part) const
 | |
| {     
 | |
|   TPartite_array& pa = app().partite();
 | |
|   for (TPartita* game = pa.first(); game; game = pa.next())
 | |
|   {
 | |
|     for (int r = game->last(); r > 0; r = game->pred(r))
 | |
|     {
 | |
|       TRiga_partite& row = game->riga(r);
 | |
|       if (row.get_long(PART_NREG) == _numreg && row.get_int(PART_NUMRIG) == _numrig)
 | |
|       {
 | |
|         row.put(PART_DESCR,   part.get(PART_DESCR));
 | |
|         row.put(PART_DATAPAG, part.get(PART_DATAPAG));
 | |
|         row.put(PART_TIPOPAG, part.get(PART_TIPOPAG));
 | |
|       }
 | |
|     }
 | |
|   }  
 | |
| } 
 | |
| */      
 | |
| 
 | |
| TToken_string& TGame_mask::add_colored_row(TSheet_field& sheet, char type) const
 | |
| {    
 | |
|   int r = sheet.insert(-1, FALSE, FALSE);
 | |
|   COLOR back, fore;
 | |
|   app().type2colors(type, back, fore);
 | |
|   sheet.set_back_and_fore_color(back, fore, r);
 | |
|   return sheet.row(r);
 | |
| }
 | |
| 
 | |
| bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k)
 | |
| {
 | |
|   TGame_mask& gm = (TGame_mask&)partite.mask();
 | |
| 
 | |
|   if (k == K_TAB)
 | |
|   {           
 | |
|     const bool changing_row = gm._riga_partite != r;
 | |
|     if (!changing_row)
 | |
|       return TRUE;
 | |
|       
 | |
|     main_app().begin_wait();  
 | |
|     
 | |
|     gm._riga_partite = r;
 | |
|     
 | |
|     TSheet_field& sheet = gm.scadenze();
 | |
|     sheet.destroy(-1, FALSE);                               // Azzera righe
 | |
| 
 | |
|     TToken_string& row = partite.row(r);
 | |
|     const int anno = row.get_int(0);                        // Anno partita
 | |
|     const TString16 num = row.get();                        // Numero partita
 | |
|     gm.set(P_ANNO, anno);                                   // Aggiorna campi di ricerca
 | |
|     gm.set(P_NUMERO, num);
 | |
|     
 | |
|     TValuta prima_valuta;                                   // Codice prima valuta
 | |
|       
 | |
|     if (anno > 0)
 | |
|     {
 | |
|       const TBill& zio = gm.conto();                          // Conto cliente/fornitore
 | |
|       
 | |
|       TPartita* game = app().partite().exist(zio, anno, num); // Cerca la partita tra quelle editate
 | |
|       const bool should_delete_game = (game == NULL);         // Ricorda di fare delete
 | |
|       if (should_delete_game)                                 // Se non c'era ...
 | |
|         game = new TPartita(zio, anno, num);                  // ... creane una temporanea
 | |
|       
 | |
|       TImporto tot_lit, tot_val;
 | |
|       
 | |
|       const int lastrow = game->last();
 | |
|       
 | |
|       if (lastrow > 0)
 | |
|         prima_valuta.get(game->riga(lastrow));
 | |
|       const bool in_valuta = prima_valuta.in_valuta();
 | |
|       
 | |
|       for (int ri = game->first(); ri <= lastrow; ri = game->succ(ri))
 | |
|       {
 | |
|         const TRiga_partite& riga = game->riga(ri);
 | |
|         if (!riga.is_fattura())
 | |
|           continue;
 | |
| 
 | |
|         TToken_string& riga_fattura = gm.add_colored_row(sheet, 'K');
 | |
|         riga_fattura.add(ri);
 | |
|         riga_fattura.add("");
 | |
|         riga_fattura.add(riga.get(PART_DATADOC)); 
 | |
|         riga_fattura.add("");     // Data scad
 | |
|         gm.add_descrizione(riga_fattura, riga);
 | |
|         gm.add_importo(riga_fattura, riga.importo(FALSE, 0x1));
 | |
|         if (in_valuta)
 | |
|           gm.add_importo(riga_fattura, riga.importo(TRUE, 0x1), TRUE);
 | |
|         else
 | |
|           riga_fattura.add("");  
 | |
|         riga_fattura.add(riga.get(PART_NREG));
 | |
|         riga_fattura.add(riga.get(PART_DATAREG));
 | |
|         riga_fattura.add(riga.get(PART_NUMDOC)); 
 | |
|         riga_fattura.add(riga.get(PART_PROTIVA)); 
 | |
|         riga_fattura.add(riga.get(PART_TIPOMOV)); 
 | |
|         
 | |
|         for (int ra = 1; ra <= riga.rate(); ra++)
 | |
|         {
 | |
|           const TRiga_scadenze& scad = riga.rata(ra);
 | |
|             
 | |
|           TToken_string& row = gm.add_colored_row(sheet, 'I');
 | |
|           row = riga_fattura;
 | |
|           row.add(ra, 1);                            
 | |
|           row.add(scad.get(SCAD_DATASCAD), 3); 
 | |
|           gm.add_importo(row, scad.importo(FALSE), FALSE, 5);
 | |
|           if (in_valuta)
 | |
|             gm.add_importo(row, scad.importo(TRUE), TRUE, 6);
 | |
|           
 | |
|           const TString& descr = scad.get(SCAD_DESCR);   
 | |
|           if (descr.not_empty())
 | |
|             row.add(descr, 4);
 | |
|           
 | |
|           const bool blocked = scad.get_bool(SCAD_BLOCCATA);
 | |
|           row.add(blocked ? "X" : " ", 13);
 | |
|             
 | |
|           const int lastp = scad.last();
 | |
|           for (int pa = scad.first(); pa <= lastp; pa = scad.succ(pa))
 | |
|           {
 | |
|             const TRectype& pag = scad.row(pa);
 | |
|             const TRiga_partite& sum = game->riga(pa);
 | |
|             const char sez = sum.sezione();
 | |
|               
 | |
|             TToken_string& row = gm.add_colored_row(sheet, ' ');
 | |
|             row.add(ri);
 | |
|             row.add(ra);
 | |
|             row.add(sum.get(PART_DATADOC)); 
 | |
|             row.add(sum.get(PART_DATAPAG)); 
 | |
|             gm.add_descrizione(row, sum);
 | |
|             const TImporto imp(sez, pag.get_real(PAGSCA_IMPORTO));
 | |
|             if (in_valuta)
 | |
|             {
 | |
|               gm.add_importo(row, imp);
 | |
|               gm.add_importo(row, TImporto(sez, pag.get_real(PAGSCA_IMPORTOVAL)), TRUE);
 | |
|             }  
 | |
|             else
 | |
|             {
 | |
|               gm.add_importo(row, imp);
 | |
|               row.add("");
 | |
|             }  
 | |
|             row.add(sum.get(PART_NREG));
 | |
|             row.add(sum.get(PART_DATAREG));
 | |
|             row.add(sum.get(PART_NUMDOC)); 
 | |
|             row.add(""); 
 | |
|             row.add(sum.get(PART_TIPOMOV)); 
 | |
|             row.add(pa);
 | |
|             
 | |
|             // Le ritenute non possono esistere in valuta
 | |
|             if (!in_valuta)
 | |
|             {
 | |
|               const TImporto rit(sez, pag.get_real(PAGSCA_RITENUTE)); 
 | |
|               if (!rit.is_zero())   
 | |
|               {
 | |
|                 TToken_string& rrit = gm.add_colored_row(sheet, 'R');
 | |
|                 rrit.add("Ritenute professionali", 4); 
 | |
|                 gm.add_importo(rrit, rit, FALSE);
 | |
|                 rrit.add(sum.get(PART_TIPOMOV), 11);
 | |
|               }
 | |
|             }  
 | |
| 
 | |
|             // Gli abbuoni e le differenze cambio esistono solo se e' a saldo
 | |
|             if (pag.get_char(PAGSCA_ACCSAL) == 'S')
 | |
|             {
 | |
|               const TImporto abb(sez, pag.get_real(PAGSCA_ABBUONI));
 | |
|               if (!abb.is_zero())
 | |
|               {
 | |
|                 const char tipo_abb = pag.get_char(PAGSCA_PASSATT);
 | |
|                 TToken_string& rabb = gm.add_colored_row(sheet, tipo_abb);
 | |
|                 rabb.add("Abbuoni ", 4); 
 | |
|                 rabb << (tipo_abb == 'A' ? "attivi" : "passivi");
 | |
|                 if (in_valuta)
 | |
|                 {                   
 | |
|                   TImporto abb_lit = abb;
 | |
|                   prima_valuta.val2lit(abb_lit);
 | |
|                   gm.add_importo(rabb, abb_lit, FALSE);
 | |
|                   gm.add_importo(rabb, abb, TRUE);
 | |
|                 }  
 | |
|                 else  
 | |
|                 {
 | |
|                   gm.add_importo(rabb, abb, FALSE);
 | |
|                   rabb.add("");
 | |
|                 }
 | |
|                 rabb.add(sum.get(PART_TIPOMOV), 11);
 | |
|               }
 | |
|               
 | |
|               // Le differenze cambio possono esistere solo in valuta
 | |
|               if (in_valuta)  
 | |
|               {
 | |
|                 const TImporto diff(sez, pag.get_real(PAGSCA_DIFFCAM));
 | |
|                 if (!diff.is_zero())
 | |
|                 {
 | |
|                   TToken_string& rdiff = gm.add_colored_row(sheet, 'C');
 | |
|                   rdiff.add("Differenza cambio", 4);
 | |
|                   gm.add_importo(rdiff, diff);
 | |
|                   rdiff.add(sum.get(PART_TIPOMOV), 11);
 | |
|                 }
 | |
|               }  
 | |
|             
 | |
|             }      // Il pagamento era a saldo
 | |
|           }        // Fine ciclo sui pagamenti della rata
 | |
|     
 | |
|           TToken_string& rsal = gm.add_colored_row(sheet, 'S');
 | |
|           rsal.add("Saldo rata ", 4); rsal << ra;
 | |
|           if (!scad.chiusa())
 | |
|           {           
 | |
|             TImporto sl = scad.residuo(FALSE);
 | |
|             gm.add_importo(rsal, sl);
 | |
|             tot_lit += sl;
 | |
|               
 | |
|             if (in_valuta)
 | |
|             { 
 | |
|               sl = scad.residuo(TRUE, 0xB);
 | |
|               gm.add_importo(rsal, sl, TRUE);
 | |
|               tot_val += sl;
 | |
|             }  
 | |
|           }  
 | |
|         }
 | |
|       }
 | |
|       
 | |
|       TRecord_array& unas = game->unassigned();
 | |
|       const int lastp = unas.last_row();
 | |
|       for (int pa = unas.first_row(); pa <= lastp; pa = unas.succ_row(pa))
 | |
|       {
 | |
|         const TRectype& pag = unas.row(pa);
 | |
|         const TRiga_partite& sum = game->riga(pa);
 | |
|         const char sez = sum.sezione();
 | |
|           
 | |
|         TToken_string& row = gm.add_colored_row(sheet, ' ');
 | |
|         row.add(pag.get(PAGSCA_NRIGA));
 | |
|         row.add(pag.get(PAGSCA_NRATA));
 | |
|         row.add(sum.get(PART_DATADOC)); 
 | |
|         row.add(sum.get(PART_DATAPAG));
 | |
|         gm.add_descrizione(row, sum);
 | |
|         
 | |
|         TImporto imp(sez, pag.get_real(PAGSCA_IMPORTO));
 | |
|         gm.add_importo(row, imp);
 | |
|         tot_lit += imp;
 | |
|         
 | |
|         const real& impval = pag.get_real(PAGSCA_IMPORTOVAL);
 | |
|         if (!impval.is_zero())     
 | |
|         { 
 | |
|           imp.set(sum.sezione(), impval);
 | |
|           imp.normalize();
 | |
|           gm.add_importo(row, imp, TRUE);
 | |
|           tot_val += imp;
 | |
|         }  
 | |
|         else
 | |
|           row.add("");  
 | |
|         row.add(sum.get(PART_NREG));
 | |
|         row.add(sum.get(PART_DATAREG));
 | |
|         row.add(sum.get(PART_NUMDOC)); 
 | |
|         row.add(""); 
 | |
|         row.add(sum.get(PART_TIPOMOV)); 
 | |
|         row.add(pa);
 | |
|         
 | |
|         const TImporto rit(sez, pag.get_real(PAGSCA_RITENUTE));
 | |
|         if (!rit.is_zero())
 | |
|         {
 | |
|           TToken_string& row = gm.add_colored_row(sheet, 'R');
 | |
|           row.add("Ritenute professionali", 4); 
 | |
|           gm.add_importo(row, rit, FALSE);
 | |
|           row.add(sum.get(PART_TIPOMOV), 11);
 | |
|           tot_lit += rit;
 | |
|         }
 | |
|       }
 | |
|       
 | |
|       if (lastrow > 0)
 | |
|       {        
 | |
|         TToken_string& sp = gm.add_colored_row(sheet, 'T');
 | |
|         sp.add("Saldo partita", 4);
 | |
|         if (prima_valuta.in_valuta())
 | |
|           sp << ' ' << prima_valuta.codice();
 | |
| #ifdef __EXTRA__
 | |
|         prima_valuta.set(gm, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
| #endif         
 | |
|         gm.add_importo(sp, tot_lit);
 | |
|         gm.add_importo(sp, tot_val, TRUE);
 | |
|       }
 | |
|     
 | |
|       if (should_delete_game)
 | |
|         delete game;
 | |
|     }
 | |
|     
 | |
|     if (prima_valuta.in_valuta() != gm._valfirst)
 | |
|     { 
 | |
|       sheet.swap_columns(106, 107); // Scambia le colonne dell'importo in lire e in valuta
 | |
|       gm._valfirst = !gm._valfirst;
 | |
|     }
 | |
|     
 | |
|     if (sheet.items() > 0)
 | |
|       sheet.select(0, TRUE);
 | |
|     else  
 | |
|       sheet.force_update(); 
 | |
|       
 | |
|     main_app().end_wait();  
 | |
|   }   
 | |
|   
 | |
|   if (k == K_INS)
 | |
|   {
 | |
|     gm.send_key(K_CTRL + 'N', 0, &partite);  // Simula la pressione del tasto nuovo
 | |
|     return FALSE;                            // Rifiuta l'aggiunta di una riga
 | |
|   }
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::scadenze_notify(TSheet_field& scadenze, int r, KEY k)
 | |
| {
 | |
|   if (k == K_INS)
 | |
|   {
 | |
|     TGame_mask& gm = (TGame_mask&)scadenze.mask();
 | |
|     gm.send_key(K_CTRL + 'N', 0, &scadenze); // Simula la pressione del tasto nuovo
 | |
|     return FALSE;                            // Rifiuta l'aggiunta di una riga
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| // Complesso algoritmo per calcolare la sezione di una nuova riga partita
 | |
| char TGame_mask::calcola_sezione(tipo_movimento tm) const
 | |
| { 
 | |
|   char sezione = ' ';
 | |
|   const char tipoc = conto().tipo();
 | |
| 
 | |
| #ifndef __EXTRA__ 
 | |
|   const TCausale& causale = app().causale();
 | |
|   tm = (tipo_movimento)causale.tipomov();
 | |
|   sezione = causale.sezione(1);                     // Usa la sezione della causale
 | |
| #endif
 | |
|   
 | |
|   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';
 | |
|   }
 | |
| 
 | |
| #ifndef __EXTRA__ 
 | |
|   // Gestione compensazioni
 | |
|   if (tipoc > ' ')                                  // Se il tipo e' C o F
 | |
|   {
 | |
|     TBill bill; causale.bill(1, bill);              // Legge primo conto causale
 | |
|     const char tc = bill.tipo();
 | |
|     if (tc > ' ' && tc != tipoc)
 | |
|       sezione = (sezione == 'D') ? 'A' : 'D';       // scambia segno
 | |
|   }
 | |
| #endif
 | |
| 
 | |
|   return sezione;
 | |
| }
 | |
| 
 | |
| int TGame_mask::nuova_riga(TPartita& partita, tipo_movimento tm) const
 | |
| { 
 | |
|   const int una_riga = partita.last();              // Memorizza una riga valida
 | |
| 
 | |
|   TRiga_partite& part = partita.new_row();          // Creazione nuova riga vuota
 | |
|   const int nriga = part.get_int(PART_NRIGA);       // Nuova riga
 | |
|   
 | |
|   // Copia dati movimento corrente
 | |
|   part.put(PART_NREG,   _numreg);                   // Numero operazione
 | |
|   part.put(PART_NUMRIG, _numrig);                   // Riga su cui ho cliccato
 | |
|   
 | |
|   // Forza il gruppo/conto cliente corretto 
 | |
|   part.put(PART_GRUPPOCL, conto().gruppo());
 | |
|   part.put(PART_CONTOCL,  conto().conto());
 | |
|   
 | |
|   part.put(PART_TIPOMOV, (int)tm);       
 | |
|   
 | |
|   if (una_riga > 0)
 | |
|   {
 | |
|     const char* valuta = partita.riga(una_riga).get(PART_CODVAL);
 | |
|     part.put(PART_CODVAL, valuta);
 | |
|   }
 | |
| 
 | |
| #ifdef __EXTRA__    
 | |
|   const TDate oggi(TODAY);
 | |
|   const char* s = oggi.string();
 | |
|   part.put(PART_DATADOC, s);
 | |
|   part.put(PART_DATAREG, s);
 | |
| #else
 | |
|   // Setta il cambio corrente
 | |
|   const TValuta valuta(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
|   valuta.put(part);
 | |
| 
 | |
|   TMask& cm = app().curr_mask();
 | |
|   const TCausale& causale = app().causale();
 | |
|   part.put(PART_NUMDOC,  cm.get(F_NUMDOC));
 | |
|   part.put(PART_DATADOC, cm.get(F_DATADOC));
 | |
|   part.put(PART_DATAREG, cm.get(F_DATAREG));
 | |
|   part.put(PART_DESCR,   cm.get(F_DESCR));
 | |
|   part.put(PART_DATAPAG, cm.get(F_DATAREG));
 | |
|   part.put(PART_TIPOPAG, 1);
 | |
|   
 | |
|   const TRiga_partite* prima = (tm != tm_fattura) ? cerca_prima_riga() : NULL;
 | |
|   if (prima != NULL && prima != &part)
 | |
|   {
 | |
|     part.put(PART_DESCR,   prima->get(PART_DESCR));
 | |
|     part.put(PART_DATAPAG, prima->get(PART_DATAPAG));
 | |
|     part.put(PART_TIPOPAG, prima->get(PART_TIPOPAG));
 | |
|   }
 | |
|   
 | |
|   // Copia dati causale corrente
 | |
|   part.put(PART_CODCAUS, causale.codice());
 | |
|   if (causale.iva() != nessuna_iva)
 | |
|   {
 | |
|     part.put(PART_REG,     cm.get(F_CODREG));
 | |
|     part.put(PART_PROTIVA, cm.get(F_PROTIVA));
 | |
|   }   
 | |
| #endif    
 | |
| 
 | |
|   const char sezione = calcola_sezione(tm);
 | |
|   
 | |
|   // Memorizza solo la sezione (importi nulli)  
 | |
|   part.put(PART_SEZ,       sezione);
 | |
|   part.put(PART_SEZABB,    sezione); 
 | |
|   part.put(PART_SEZDIFCAM, sezione);
 | |
|   
 | |
|   return nriga;
 | |
| }
 | |
| 
 | |
| int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata, tipo_movimento tm) const
 | |
| {              
 | |
| #ifdef __EXTRA__                
 | |
|   const int nrigp = nuova_riga(partita, tm);
 | |
| #else
 | |
|   int nrigp = partita.mov2rig(_numreg, _numrig);       // Cerca riga partita relativa alla riga rmov
 | |
|   if (nrigp <= 0)                                      // Devo creare una nuova riga di partita
 | |
|     nrigp = nuova_riga(partita, tm);
 | |
| #endif
 | |
|   TRectype& pagamento = partita.pagamento(nriga, rata, nrigp);      // Crea nuovo pagamento
 | |
|   
 | |
|   // Calcola riga causale per la contropartita in base al tipo pagamento
 | |
|   int caus = 2;          
 | |
|   
 | |
|   if (nriga != TPartita::UNASSIGNED)
 | |
|   {       
 | |
|     const TRiga_partite& fatt = partita.riga(nriga);
 | |
|     const TRiga_scadenze& scad = fatt.rata(rata);
 | |
|     const int tp = scad.get_int(SCAD_TIPOPAG);
 | |
|     caus = partita.tipopag2causale(tp);
 | |
|     
 | |
|     TRiga_partite& somma = partita.riga(nrigp);
 | |
|     somma.put(PART_TIPOPAG, tp);
 | |
|     somma.put(PART_CODVAL, fatt.get(PART_CODVAL));
 | |
|     
 | |
|     pagamento.put(PAGSCA_CODABIPR, scad.get(SCAD_CODABIPR));
 | |
|     pagamento.put(PAGSCA_CODCABPR, scad.get(SCAD_CODCABPR));
 | |
|     pagamento.put(PAGSCA_CODABI,   scad.get(SCAD_CODABI));
 | |
|     pagamento.put(PAGSCA_CODCAB,   scad.get(SCAD_CODCAB));
 | |
|     pagamento.put(PAGSCA_CODAG,    scad.get(SCAD_CODAG));
 | |
|   }
 | |
| 
 | |
| #ifndef __EXTRA__  
 | |
|   const TCausale& causale = app().causale();
 | |
|   TBill contro; causale.bill(caus, contro);    // Legge conto contropartita
 | |
|   if (caus != 2 && contro.empty())             // Se non specificato ...
 | |
|     causale.bill(caus = 2, contro);            // ... prende il primo
 | |
|   contro.put(pagamento, TRUE);                 // Scrive conto contropartita
 | |
| #endif  
 | |
|   
 | |
|   return nrigp;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k)
 | |
| {             
 | |
|   if (k == K_SPACE)
 | |
|   {
 | |
|     TMask& m = f.mask();
 | |
|     const int nriga = m.get_int(101);  // Numero riga fattura
 | |
| 
 | |
|     if (nriga == 0)
 | |
|       return FALSE;                    // Ho cliccato su di un saldo (per sbaglio!)
 | |
|     
 | |
|     TGame_mask& gm = (TGame_mask&)(m.get_sheet()->mask());
 | |
|     const TBill&  bill   = gm.conto();             // Clifo 
 | |
|     
 | |
|     TSheet_field& sp = gm.partite();
 | |
|     TToken_string& spr = sp.row(sp.selected());
 | |
|     const int anno = spr.get_int(0);               // Anno
 | |
|     const TString numero = spr.get();              // Numero
 | |
|     
 | |
|     TPartite_array& giochi = app().partite();
 | |
|     TPartita* was = giochi.exist(bill, anno, numero);      // Controlla esistenza nell'array
 | |
|     TPartita& game = was ? *was : giochi.partita(bill, anno, numero);
 | |
|     
 | |
|     long nreg = m.get_long(108);       // Numero registrazione
 | |
|     const int nrata = m.get_int(102);  // Rata selezionata (puo' essere 0)
 | |
|     int nrigp = m.get_int(113);        // Pagamento selezionato (puo' essere 0)
 | |
|     
 | |
|     if (nrata != 0 && nrigp == 0)
 | |
|     {          
 | |
|       if (m.get_bool(114))
 | |
|       {
 | |
|         if (was == NULL) giochi.destroy(game);
 | |
|         return f.error_box("La rata %d e' bloccata.", nrata);
 | |
|       }  
 | |
| 
 | |
| #ifndef __EXTRA__
 | |
|       const TValuta parval(game.riga(nriga));
 | |
|       const TValuta curval(gm, P_VALUTA, P_DATACAMBIO, P_CAMBIO);
 | |
|       if (parval != curval)
 | |
|       {
 | |
|         TString c = parval.codice();
 | |
|         if (c.empty()) c = "lire";
 | |
| 
 | |
|         if (was == NULL) giochi.destroy(game);
 | |
|         return f.error_box("La fattura deve essere pagata in %s.", (const char*)c);
 | |
|       }                   
 | |
| #endif
 | |
|       
 | |
|       tipo_movimento tm;
 | |
| 
 | |
| #ifdef __EXTRA__
 | |
|       TMask* nm = new TNew_mask(gm.conto().tipo(), FALSE, FALSE);
 | |
|       nm->set(P_ANNO, game.anno());
 | |
|       nm->set(P_NUMERO, game.numero());
 | |
|       const KEY k = nm->run();
 | |
|       
 | |
|       if (k == K_ENTER)
 | |
|         tm = (tipo_movimento)nm->get_int(P_NUOVO);
 | |
|       else  
 | |
|       {
 | |
|         if (was == NULL) giochi.destroy(game);
 | |
|         return FALSE;
 | |
|       }  
 | |
|       delete nm;   
 | |
| #else        
 | |
|       tm = (tipo_movimento)app().causale().tipomov();
 | |
| #endif    
 | |
|       
 | |
|       nrigp = gm.nuovo_pagamento(game, nriga, nrata, tm);
 | |
|       nreg = gm._numreg;
 | |
|     }
 | |
|     
 | |
|     bool cambiato  = FALSE;
 | |
|     
 | |
|     if (nrigp > 0)            // Si vuole editare un pagamento
 | |
|     {                       
 | |
|       if (nreg == gm._numreg)
 | |
|       {
 | |
|         cambiato = gm.edit_pagamento(game, nriga, nrata, nrigp);
 | |
|         if (cambiato)
 | |
|         {                              
 | |
| #ifdef __EXTRA__
 | |
|           game.rewrite();   // In extra-contabile salvo subito!
 | |
| #endif            
 | |
|         }  
 | |
|       }
 | |
|       else
 | |
|       {
 | |
| #ifdef __EXTRA__
 | |
|         gm.prima_nota(nreg);
 | |
|         if (m.is_running()) m.set_focus();
 | |
| #else      
 | |
|         if (was == NULL) giochi.destroy(game);
 | |
|         return f.error_box("Modificare il movimento %ld", nreg);  
 | |
| #endif        
 | |
|       }  
 | |
|     }
 | |
|     else
 | |
|     {                        // Si vogliono editare le rate
 | |
| #ifdef __EXTRA__
 | |
|       if (nreg > 0)
 | |
|       {
 | |
|         gm.prima_nota(nreg);
 | |
|         if (m.is_running()) m.set_focus();
 | |
|       }
 | |
|       else  
 | |
|         cambiato = gm.edit_fattura(game, nriga);
 | |
| #else      
 | |
|       if (nreg != gm._numreg || nrata == 0)
 | |
|       {              
 | |
|         if (nreg == 0)
 | |
|           f.error_box("Utilizzare la gestione extra-contabile");
 | |
|         else
 | |
|           f.error_box("Modificare il movimento %ld", nreg);
 | |
|         if (was == NULL) giochi.destroy(game);
 | |
|         return FALSE;
 | |
|       }  
 | |
| #endif        
 | |
|     }  
 | |
|     
 | |
|     if (cambiato)
 | |
|     {                 
 | |
|       if (m.is_running())               // Se la maschera e' aperta la chiudo
 | |
|         m.stop_run(K_FORCE_CLOSE);
 | |
|     
 | |
|       TSheet_field& ss = gm.scadenze();
 | |
|       const int rs = ss.selected();     // Memorizza la riga corrente
 | |
|       const int rt = ss.items();        // Memorizza numero righe correnti
 | |
|       
 | |
|       gm.fill_partite();                // Aggiorna elenco partite
 | |
|       
 | |
|       const int rn = ss.items();        // Memorizza nuovo numero righe
 | |
|       if (rs < rn)                      // Se esiste ancora ...
 | |
|       {
 | |
|         const bool scroll =  rn > rt;   // Scrolla solo se aggiungo righe
 | |
|         ss.select(rs, scroll);          // ... riporta la selezione sulla riga corrente
 | |
|       }
 | |
|       gm._changed = TRUE;
 | |
|     }  
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::nuovo_handler(TMask_field& f, KEY k)
 | |
| {
 | |
|   if (k == K_SPACE)
 | |
|   { 
 | |
|     TGame_mask& gm = (TGame_mask&)f.mask();
 | |
|     int anno;
 | |
|     TString numero;
 | |
| 
 | |
| #ifdef __EXTRA__
 | |
|     const bool allow_fatt = TRUE;
 | |
| #else
 | |
|     const bool allow_fatt = FALSE;
 | |
| #endif    
 | |
|     TMask* new_game = new TNew_mask(gm.conto().tipo(), allow_fatt, TRUE);     
 | |
|     
 | |
|     tipo_movimento tm;
 | |
| 
 | |
| #ifndef __EXTRA__                     
 | |
|     const TMask& cm = app().curr_mask();
 | |
|     tm = (tipo_movimento)app().causale().tipomov();
 | |
|     new_game->set(P_NUOVO, tm);
 | |
|     if (tm == tm_nota_credito)
 | |
|     {                    
 | |
|       new_game->set(P_ANNO, cm.get(F_ANNORIF)); 
 | |
|       new_game->set(P_NUMERO, cm.get(F_NUMRIF));
 | |
|     }
 | |
| #endif             
 | |
| 
 | |
|     k = new_game->run();
 | |
|     tm = (tipo_movimento)new_game->get_int(P_NUOVO);
 | |
|     anno   = new_game->get_int(P_ANNO);
 | |
|     numero = new_game->get(P_NUMERO);
 | |
|     
 | |
|     // Distruzione maschera di richiesta
 | |
|     delete new_game; new_game = NULL;
 | |
|     
 | |
|     if (k == K_ENTER)
 | |
|     {             
 | |
|       // Creazione nuova partita         
 | |
|       TPartita& game = app().partite().partita(gm.conto(), anno, numero);
 | |
|       
 | |
|       bool edit = FALSE;
 | |
|       // N.B. Le fatture non possone essere editate in modo contabile
 | |
|       if (tm != tm_fattura)     
 | |
|       {                              
 | |
|         const int nriga = TPartita::UNASSIGNED;
 | |
|         const int nrata = TPartita::UNASSIGNED;
 | |
|         const int nrigp = gm.nuovo_pagamento(game, nriga, nrata, tm);
 | |
|         edit = gm.edit_pagamento(game, nriga, nrata, nrigp);
 | |
| #ifdef __EXTRA__      
 | |
|         if (edit) game.rewrite();
 | |
| #endif        
 | |
|       }   
 | |
| #ifdef __EXTRA__      
 | |
|       else
 | |
|         edit = gm.edit_fattura(game, 0);
 | |
| #endif    
 | |
|       
 | |
|       if (edit)         
 | |
|       {
 | |
|         gm.set(P_ANNO, anno);
 | |
|         gm.set(P_NUMERO, numero);
 | |
|         gm._changed = TRUE;
 | |
|         
 | |
|         // Aggiorna sheet partite: aggiunge la nuova partita e lo riordina
 | |
|         gm.fill_partite();                    
 | |
|       } // Sono state apportate modifiche 
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| // Metodi della maschera delle partite
 | |
| ///////////////////////////////////////////////////////////                          
 | |
| 
 | |
| void TGame_mask::add_importo(TToken_string& s, const TImporto& i, bool valuta, int pos)
 | |
| {
 | |
|   if (i.is_zero())
 | |
|     s.add("", pos);  
 | |
|   else  
 | |
|   {              
 | |
|     TString80 v;
 | |
|     TImporto n(i); n.normalize();
 | |
|     if (valuta)
 | |
|     {
 | |
|       v = n.valore().string(0, 3);
 | |
|       const int sep = v.find('.');
 | |
|       v[sep] = ',';
 | |
|     }
 | |
|     else
 | |
|       v = n.valore().string(0, 0);
 | |
|     v << ' ' << n.sezione();
 | |
|     s.add(v, pos);
 | |
|   }
 | |
| } 
 | |
| 
 | |
| void TGame_mask::add_descrizione(TToken_string& s, const TRiga_partite& riga, int pos)
 | |
| {
 | |
|   const TString& desc = riga.get(PART_DESCR);
 | |
|   if (desc.empty())
 | |
|   {
 | |
|     const TString& caus = riga.get(PART_CODCAUS);
 | |
|     if (caus.not_empty())
 | |
|       s.add(_causali.decode(caus), pos);
 | |
|     else
 | |
|       s.add("", pos);
 | |
|   }
 | |
|   else
 | |
|     s.add(desc, pos);
 | |
| }
 | |
| 
 | |
| TImporto TGame_mask::get_importo(TToken_string& s, int pos) const
 | |
| {
 | |
|   const TFixed_string imp(s.get(pos));
 | |
|   const real i(imp);
 | |
|   const char sez = imp.right(1)[0];
 | |
|   return TImporto(sez, i);
 | |
| } 
 | |
| 
 | |
| int TGame_mask::update_partita(const TRectype& riga, 
 | |
|                                const TImporto& saldo, const TImporto& doc, 
 | |
|                                const TImporto& pag, const TImporto& imp, int prow)
 | |
| {              
 | |
|   TSheet_field& games = partite();
 | |
|   TToken_string &r = games.row(prow);                    // Stringa di lavoro per lo sheet
 | |
|   if (!riga.empty())                                     // Esiste veramente 
 | |
|   {
 | |
|     r.cut(0);
 | |
|     r.add(riga.get(PART_ANNO)); r.right_just(4);          // Mette gli spazi se ce n'e' bisogno
 | |
|     r.add(riga.get(PART_NUMPART));
 | |
|     r.add(riga.get(PART_DATADOC));
 | |
|     r.add(riga.get(PART_NUMDOC));
 | |
|     add_importo(r, saldo);
 | |
|     add_importo(r, doc);
 | |
|     add_importo(r, pag);
 | |
|     add_importo(r, imp);
 | |
|     r.add(riga.get(PART_DESCR)); 
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     r.add("", 4);
 | |
|     r.add("", 5);
 | |
|     r.add("", 6);
 | |
|     r.add("", 7);
 | |
|   }  
 | |
|   
 | |
|   if (prow >= 0)
 | |
|   {                            
 | |
|     games.force_update(prow);
 | |
|     update_saldo_clifo();
 | |
|     games.force_update(games.items()-1);
 | |
|     aggiorna_residuo();
 | |
|   }
 | |
|   else
 | |
|     prow = partite().items()-1;
 | |
|     
 | |
|   if (prow == 0)
 | |
|   {
 | |
|     const char all = TPartita::allineamento_richiesto(conto().tipo());
 | |
|     field(P_NUMERO).set_justify(all == 'R');
 | |
|   }  
 | |
|   
 | |
|   return prow;    
 | |
| }
 | |
| 
 | |
| int TGame_mask::update_partita(const TPartita& part, int prow)
 | |
| {                                            
 | |
|   int r = part.prima_fattura();
 | |
|   if (r <= 0) r = part.first();
 | |
| 
 | |
|   TImporto saldo, doc, pag, imp;                       
 | |
|   part.calcola_saldo(saldo, doc, pag, imp);
 | |
|   return update_partita(part.riga(r), saldo, doc, pag, imp, prow);
 | |
| }
 | |
| 
 | |
| int TGame_mask::update_partita(const TRectype& riga, int prow)
 | |
| {                                            
 | |
|   TImporto saldo, doc, pag, imp;
 | |
|   
 | |
|   TRectype rec = riga;
 | |
|   const int err = TPartita::read_saldo(rec, saldo, doc, pag, imp);
 | |
|   return update_partita(rec, saldo, doc, pag, imp, prow);
 | |
| }
 | |
| 
 | |
| void TGame_mask::update_saldo_clifo()
 | |
| {                    
 | |
|   TString_array& s = partite().rows_array();
 | |
|   
 | |
|   TImporto sal, doc, pag, imp;
 | |
|   for (int i = 0; i < s.items(); i++)
 | |
|   {                  
 | |
|     TToken_string& r = s.row(i);
 | |
|     if (r.get_int(0) > 0)
 | |
|     {
 | |
|       sal += get_importo(r, 4);
 | |
|       doc += get_importo(r, -1);
 | |
|       pag += get_importo(r, -1);
 | |
|       imp += get_importo(r, -1);
 | |
|     }  
 | |
|     else
 | |
|       break;
 | |
|   }
 | |
|   
 | |
|   TToken_string& r = s.row(s.add("", i));
 | |
|   r.add(""); 
 | |
|   r.add("");
 | |
|   r.add(TDate(TODAY).string());
 | |
|   r.add("");
 | |
|   add_importo(r, sal);
 | |
|   add_importo(r, doc);
 | |
|   add_importo(r, pag);
 | |
|   add_importo(r, imp);
 | |
|   r.add("Saldo "); 
 | |
|   append_conto(r);
 | |
|   
 | |
|   COLOR back, fore;
 | |
|   app().type2colors('T', back, fore);
 | |
|   partite().set_back_and_fore_color(back, fore, i);
 | |
|   if (i > 0)  // Se ho aggiunto una riga devo decolorare la precedente
 | |
|     partite().set_back_and_fore_color(NORMAL_BACK_COLOR, NORMAL_COLOR, i-1);
 | |
| }
 | |
| 
 | |
| long TGame_mask::number_distance(const char* k, const char* n) const
 | |
| {
 | |
|   TString16 key(k); key.upper(); key.trim(); 
 | |
|   const int kl = key.len();
 | |
|   TString16 num(n); num.upper(); num.trim();
 | |
|   const int nl = num.len();
 | |
|   long dist = 0;
 | |
|   for (int i = kl-1; i >= 0; i--)
 | |
|   {
 | |
|     const char kc = i < kl ? key[i] : 0;
 | |
|     const char nc = i < nl ? num[i] : 0;
 | |
|     const long d = abs(kc - nc) * (kl - i) * 32;
 | |
|     dist += d;
 | |
|   }
 | |
|   return dist;
 | |
| }
 | |
| 
 | |
| bool TGame_mask::same_number(const char* key, const char* num) const
 | |
| {
 | |
|   TString16 k(key); k.upper(); k.trim();
 | |
|   TString16 n(num); n.upper(); n.trim();
 | |
|   return k == n;
 | |
| }
 | |
| 
 | |
| void TGame_mask::fill_partite()
 | |
| {                                                 
 | |
|   const int annorif = get_int(P_ANNO);           // Anno corrente    
 | |
|   const TString numrif = get(P_NUMERO);          // Partita corrente
 | |
|   const bool all = get(P_SHOWALL).not_empty();   // Visualizza anche partite chiuse
 | |
|                               
 | |
|   TString_array& a = partite().rows_array();
 | |
|   a.destroy();
 | |
| 
 | |
|   app().begin_wait();
 | |
|   
 | |
|   TPartite_array& giochi = app().partite();
 | |
|   for (TPartita* gioco = giochi.first(); gioco != NULL; gioco = giochi.next())
 | |
|   {     
 | |
|     // Visualizza solo le partite con almeno una riga!  Non posso scaricarle a priori in quanto
 | |
|     // potrebbero essere state cancellate proprio ora e quindi devo tenerle cosi' per aggiornare
 | |
|     // correttamente gli archivi.
 | |
|     if (gioco->ok())     
 | |
|     {        
 | |
|       const TBill& k = gioco->conto();       
 | |
|       bool u = (k.tipo() > ' ' && k.sottoconto() == conto().sottoconto()) || k == conto();
 | |
| 
 | |
|       if (u && !all && gioco->chiusa() && gioco->mov2rig(_numreg, _numrig) <= 0)                     
 | |
|         u = FALSE;
 | |
|       
 | |
|       if (u)
 | |
|         update_partita(*gioco, -1);             
 | |
|     }  
 | |
|     else
 | |
|     {                               // Se la partita e' vuota ...
 | |
|       if (!gioco->is_on_file())     // ... e non esiste su file
 | |
|         giochi.destroy(*gioco);     // posso eliminarla tranquillamente
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   TLocalisamfile partita(LF_PARTITE);
 | |
|   TRectype& curpar = partita.curr();
 | |
|   curpar.zero();
 | |
|   if (conto().tipo() > ' ')                   // Ignora gruppo e conto dei clifo
 | |
|   {
 | |
|     curpar.put(PART_TIPOCF, conto().tipo());             
 | |
|     curpar.put(PART_SOTTOCONTO, conto().codclifo()); 
 | |
|   }
 | |
|   else 
 | |
|     conto().put(curpar);                      // Scrive completamente i conti normali
 | |
|   
 | |
|   const TRectype filter(curpar);              // Record campione
 | |
| 
 | |
|   for (int err = partita.read(_isgreat); 
 | |
|        err == NOERR && curpar == filter; 
 | |
|        err = partita.read(_isgreat))
 | |
|   {
 | |
|     if (!giochi.exist(curpar))
 | |
|     {
 | |
|       if (all || curpar.get_bool(PART_CHIUSA) == FALSE)
 | |
|         update_partita(curpar, -1);
 | |
|     }
 | |
|     // Forza lettura partita successiva nella prossima read
 | |
|     curpar.put(PART_NRIGA, (int)TPartita::UNASSIGNED); 
 | |
|   }
 | |
|   
 | |
|   a.sort();
 | |
|   for (int r = a.items()-1; r > 0; r--)
 | |
|   {
 | |
|     TToken_string& row = a.row(r);
 | |
|     if (annorif == row.get_int(0) && same_number(numrif, row.get(1)))
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   update_saldo_clifo();
 | |
|   partite().force_update();
 | |
|   aggiorna_residuo();
 | |
|   
 | |
|   if (a.items() > 1)
 | |
|   {
 | |
|     _riga_partite = -1;
 | |
|     partite().select(r, TRUE); 
 | |
|   }  
 | |
|   else
 | |
|   {
 | |
|     scadenze().destroy();
 | |
|   }  
 | |
|   app().end_wait();
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TGame_mask::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const
 | |
| { 
 | |
|   TRectype oldpag = p.pagamento(nriga, nrata, nrigp);
 | |
|   TRiga_partite& somma  = p.riga(nrigp);
 | |
| 
 | |
|   const bool nuovo = oldpag.get(PAGSCA_ACCSAL) != "S" && 
 | |
|                      oldpag.get_real(PAGSCA_IMPORTO).is_zero() &&
 | |
|                      oldpag.get_real(PAGSCA_RITENUTE).is_zero();
 | |
|   
 | |
|   // We must create masks on the heap
 | |
|   TPay_mask* pm = new TPay_mask(*this, nuovo ? MODE_INS : MODE_MOD);              
 | |
|   TPay_mask& m = *pm;
 | |
| 
 | |
|   if (nriga == TPartita::UNASSIGNED)
 | |
|   {              
 | |
|     TRiga_scadenze& scaden = somma.new_row();        // Crea una rata falsa
 | |
|     scaden.put(SCAD_DATASCAD, somma.get(PART_DATADOC));
 | |
|     m.set_pag(oldpag, scaden, _residuo);
 | |
|     somma.destroy_rows();                            // Distrugge la rata falsa
 | |
|   }  
 | |
|   else
 | |
|   {
 | |
|     const TRiga_scadenze& scaden = p.rata(nriga, nrata);
 | |
|     m.set_pag(oldpag, scaden, _residuo);
 | |
|   }
 | |
|   if (nuovo)   // Inizializza automaticamente l'importo
 | |
|   {
 | |
|     TMask_field& imp = m.field(S_IMPORTO);
 | |
|     imp.set_dirty();
 | |
|     imp.on_key(K_F8);
 | |
|   }
 | |
|   
 | |
|   KEY key = m.run();
 | |
|   
 | |
|   if (key == K_DEL)
 | |
|   {
 | |
|     const bool truly = yesno_box("Confermare l'eliminazione");
 | |
|     if (!truly) key = K_ESC;
 | |
|   }
 | |
|   
 | |
|   if (key == K_ESC && nuovo)
 | |
|     key = K_DEL;
 | |
|   
 | |
|   if (key != K_ESC)
 | |
|   {
 | |
|     TRectype newpag(oldpag);
 | |
| 
 | |
|     if (key == K_DEL)
 | |
|     {
 | |
|       newpag.zero(PAGSCA_ACCSAL);                  // Non puo' essere un saldo
 | |
|       newpag.zero(PAGSCA_IMPORTO);                 // Azzera importo ...
 | |
|       newpag.zero(PAGSCA_IMPORTOVAL);              // .. anche in valuta
 | |
|       newpag.zero(PAGSCA_RITENUTE);                // Azzera ritenute
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       m.get_pag(newpag, somma);   
 | |
|     }
 | |
|     
 | |
|     const TValuta val(somma);                              
 | |
| #ifdef __EXTRA__
 | |
|     p.modifica_pagamento(newpag, val, TRUE);
 | |
| #else  
 | |
|     if (somma.is_nota_credito())      
 | |
|       p.modifica_pagamento(newpag, val, TRUE);
 | |
|     else
 | |
|       app().notify_edit_pagamento(p, newpag, val);
 | |
| #endif          
 | |
|   }       
 | |
|   
 | |
|   delete pm;
 | |
|   
 | |
|   return key != K_ESC;
 | |
| }
 | |
| 
 | |
| #ifndef __EXTRA__
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Edit delle partite
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| bool TPrimanota_application::edit_partite(const TMask& m, int riga)
 | |
| {                           
 | |
|   const char tipo = m.get(CG_TIPO)[0];
 | |
|   const char rt = m.get(CG_ROWTYPE)[0];
 | |
|   if (rt == 'T' && tipo <= ' ')           // Nelle note di credito DEVE essere un clifo
 | |
|     return FALSE;
 | |
| 
 | |
|   const int gruppo = m.get_int(CG_GRUPPO);
 | |
|   const int conto = m.get_int(CG_CONTO);
 | |
|   const long sottoconto = m.get_long(CG_SOTTOCONTO);
 | |
|   TBill b(gruppo, conto, sottoconto, tipo);  // Legge il conto della riga selezionata
 | |
|   
 | |
|   // Esci se il conto della riga cliente non e' valido
 | |
|   if (!b.ok() || !b.find()) 
 | |
|     return m.field(CG_SOTTOCONTO).error_box("Conto assente");
 | |
|   
 | |
|   // Aggiorna conto sulla riga contabile  
 | |
|   b.add_to(cgs().row(riga), 3, 0x0);
 | |
|     
 | |
|   TMovimentoPN* pn = (TMovimentoPN*)get_relation();
 | |
|   curr_mask().autosave(*pn);   // Aggiorna i dati della testata sulle partite
 | |
|   partite().update_reg(pn->curr());
 | |
|   
 | |
|   // Esecuzione maschera di selezione partite
 | |
|   TGame_mask* mask = new TGame_mask(b, pn->curr().get_long(MOV_NUMREG), riga+1); 
 | |
|   mask->run();        
 | |
|   const bool changed = mask->changed();
 | |
|   delete mask;
 | |
|   
 | |
|   if (changed)
 | |
|   {
 | |
|     cgs().force_update();      // Aggiornamento righe contabili
 | |
|     calcola_saldo();
 | |
|   }
 | |
|   return changed;
 | |
| }
 | |
| 
 | |
| #endif
 |