Files correlati : cg2.exe Ricompilazione Demo : [ ] Commento Bug: 0001649: Ordinamento e Descrizione righe prima nota Dopo aver creato una registrazione di prima nota pura, se metto una descrizione di riga per ogni riga inserita e registro, se richiamo la registrazione inserita l'ordinamento delle righe è cambiato e sparisce la descrizione di riga solitamente la prima git-svn-id: svn://10.65.10.50/trunk@20534 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			3297 lines
		
	
	
		
			94 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			3297 lines
		
	
	
		
			94 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <colors.h> 
 | 
						||
#include <execp.h> 
 | 
						||
#include <msksheet.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <tabutil.h>
 | 
						||
#include <urldefid.h>
 | 
						||
#include <utility.h>
 | 
						||
#include <validate.h>
 | 
						||
 | 
						||
#include "cg2100.h"
 | 
						||
#include "cg2102.h"
 | 
						||
#include "cg21sld.h"
 | 
						||
 | 
						||
#include <clifo.h>
 | 
						||
#include <cfven.h>
 | 
						||
#include <pconti.h>
 | 
						||
#include <doc.h>
 | 
						||
#include <occas.h>
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Funzioni di decodifica/calcolo
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// Determina il tipo di una riga contabile in formato TToken_string
 | 
						||
char TPrimanota_application::row_type(const TToken_string& s)
 | 
						||
{
 | 
						||
  char t = ' ';
 | 
						||
  if (s.full() && s.items() >= CG_ROWTYPE - 100)
 | 
						||
  {
 | 
						||
    t = s[s.len()-1]; 
 | 
						||
    if (t < 'A' || t > 'Z')
 | 
						||
      t = ' '; 
 | 
						||
  }
 | 
						||
  return t;
 | 
						||
}
 | 
						||
 | 
						||
// Determina il tipo IVA da causale+anno
 | 
						||
// Certified 100%
 | 
						||
TipoIVA TPrimanota_application::cau2IVA(const char* cod, int annoiva)
 | 
						||
{
 | 
						||
  if (!read_caus(cod, annoiva))
 | 
						||
    error_box(FR("Causale errata: '%s'"), cod);
 | 
						||
  return causale().iva();
 | 
						||
}
 | 
						||
 | 
						||
// Calcolo della percentuale di un dato codice IVA
 | 
						||
// Certified 99%         
 | 
						||
const real& TPrimanota_application::cod2IVA(const TMask& m)
 | 
						||
{
 | 
						||
  static TString4 _codiva;            // Ultimo codice iva decodificato
 | 
						||
  static real _percent;               // Percentuale dell'ultimo codice iva
 | 
						||
                                      // Tipo Costo Ricavo
 | 
						||
  if (app().iva() == iva_acquisti && m.get_int(103) == 3)
 | 
						||
    return ZERO;
 | 
						||
  
 | 
						||
  const TString& codiva = m.get(102);
 | 
						||
  if (_codiva != codiva)
 | 
						||
  {
 | 
						||
    _codiva = codiva;
 | 
						||
    const TCodiceIVA c(_codiva);
 | 
						||
    _percent = c.percentuale();
 | 
						||
  }
 | 
						||
  
 | 
						||
  return _percent;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Scorpora dall'imponibile la percentuale d'imposta(0.0%-100.0%) e ritorna l'imposta stessa
 | 
						||
// Certified 99%  Non sono sicurissimo degli imponibili negativi
 | 
						||
real TPrimanota_application::scorpora(real& imponibile, const real& percent)
 | 
						||
{
 | 
						||
  real imposta;
 | 
						||
  const int dec = TCurrency::get_firm_dec();
 | 
						||
  if (dec == 0)  // Gestione Lire
 | 
						||
  {
 | 
						||
    imposta = abs(imponibile) * percent / (percent + CENTO);
 | 
						||
    imposta.ceil();
 | 
						||
    if (imponibile.sign() < 0) imposta = -imposta;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {              // Gestione Euro
 | 
						||
    imposta = imponibile * percent / (percent + CENTO);
 | 
						||
    imposta.round(dec);
 | 
						||
  }
 | 
						||
  imponibile -= imposta;
 | 
						||
  return imposta;
 | 
						||
}  
 | 
						||
 | 
						||
 | 
						||
// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle
 | 
						||
// ritenute sociali sulla causale                        
 | 
						||
real TPrimanota_application::totale_documento()
 | 
						||
{
 | 
						||
  const TMask& m = curr_mask();
 | 
						||
 | 
						||
  real tot(m.get(F_TOTALE));              // Legge totale
 | 
						||
  const real ritfis(m.get(F_RITFIS));
 | 
						||
  tot += ritfis;                          // Somma ritenute fiscali
 | 
						||
  
 | 
						||
  const real ritsoc(m.get(F_RITSOC));           
 | 
						||
 | 
						||
  const bool swapt = test_swap(false);    // Totale invertito ?
 | 
						||
  const bool swaps = test_swap(true);     // Ritenute sociali invertite ?
 | 
						||
  if (swapt ^ swaps)                      // Somma ritenute sociali con segno
 | 
						||
    tot -= ritsoc;
 | 
						||
  else
 | 
						||
    tot += ritsoc;                        
 | 
						||
 | 
						||
  return tot;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Determina se un codice sospeso o no
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k)
 | 
						||
{                   
 | 
						||
  if (f.to_check(k) && !f.empty())
 | 
						||
  {
 | 
						||
    const TEdit_field& c = (const TEdit_field&)f;
 | 
						||
    const TBrowse* b = c.browse();
 | 
						||
    CHECKD(b, "Can't check suspension of an edit-field without a USE ", f.dlg());
 | 
						||
    const TLocalisamfile& i = b->cursor()->file();
 | 
						||
    //                        Tabella    File
 | 
						||
    const char* sf = i.tab() ? "B2" : "SOSPESO";  
 | 
						||
    const bool suspended = i.get_bool(sf);
 | 
						||
    if (suspended)
 | 
						||
    {                                                                    
 | 
						||
      sf = f.get();
 | 
						||
      return f.error_box(TR("Il codice '%s' e' sospeso e non puo' essere utilizzato"), sf);  
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Funzioni di ricerca
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
int TPrimanota_application::type2pos(char tipo)
 | 
						||
{
 | 
						||
  TString_array& cg = app().cgs().rows_array();
 | 
						||
  for (int i = 0; i < cg.items(); i++)
 | 
						||
  {
 | 
						||
    const TToken_string& s = cg.row(i);
 | 
						||
    const char t = row_type(s);
 | 
						||
    if (t == tipo)
 | 
						||
      return i;
 | 
						||
  }
 | 
						||
  return -1;
 | 
						||
}
 | 
						||
 | 
						||
// Trova nelle righe contabili un conto nelle righe di tipo prescelto
 | 
						||
int TPrimanota_application::bill2pos(const TBill& conto, char tipo)
 | 
						||
{
 | 
						||
  TString_array& cg = app().cgs().rows_array();
 | 
						||
  const int num_rows = cg.items();
 | 
						||
  for (int i = 0; i < num_rows; i++)
 | 
						||
  {
 | 
						||
    TToken_string& s = cg.row(i);
 | 
						||
    const char t = row_type(s);
 | 
						||
    if (t == tipo)
 | 
						||
    {
 | 
						||
      const TBill c(s, 3, 0x0);
 | 
						||
      if (c == conto)
 | 
						||
        return i;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return -1;
 | 
						||
}
 | 
						||
 | 
						||
// Trova nelle righe contabili un conto di contropartita per il conto dato
 | 
						||
int TPrimanota_application::bill2contr(const TBill& conto, char sezione) const
 | 
						||
{
 | 
						||
  TString_array& rows = cgs().rows_array();
 | 
						||
  const int num_rows = rows.items();
 | 
						||
  TBill c;                                // Conto corrente (Buona questa!)
 | 
						||
  for (int i = 0; i < num_rows; i++)
 | 
						||
  {
 | 
						||
    TToken_string& r = rows.row(i);
 | 
						||
    const real dare(r.get(0));
 | 
						||
    const char sez = dare.is_zero() ? 'A' : 'D';
 | 
						||
    if (sez == sezione)                   // Devo cercare sezione contraria
 | 
						||
      continue;
 | 
						||
    c.get(r, 3, 0x0);
 | 
						||
    if (conto == c)
 | 
						||
      return i;
 | 
						||
  }
 | 
						||
  return -1;
 | 
						||
}
 | 
						||
 | 
						||
// Controlla se un conto e' usato nelle righe IVA                              
 | 
						||
int TPrimanota_application::bill_used(const TBill& conto) const
 | 
						||
{
 | 
						||
  TString_array& rows = ivas().rows_array();
 | 
						||
  TBill c;               // Conto corrente
 | 
						||
  int users = 0;
 | 
						||
  for (int i = rows.items(); i >= 0 ; i--)
 | 
						||
  {
 | 
						||
    TToken_string& row = rows.row(i);
 | 
						||
    if (!row.empty_items())
 | 
						||
    {                       
 | 
						||
      c.get(row, 6, 0x0);
 | 
						||
      if (conto == c) 
 | 
						||
        users++;
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return users;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Gestione sheet CG
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TSheet_field& TPrimanota_application::cgs() const
 | 
						||
{                                  
 | 
						||
  const TMask* m = _msk[_iva == nessuna_iva ? 1 : 2];
 | 
						||
  CHECK(m, "Null cgs() mask");
 | 
						||
  return m->sfield(F_SHEETCG);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Certified 100%
 | 
						||
// Scrive l'importo imp nella opportuna colonna della riga n
 | 
						||
void TPrimanota_application::set_cgs_imp(int n, const TImporto& imp)
 | 
						||
{ 
 | 
						||
  TSheet_field& s = cgs();
 | 
						||
  imp.add_to(s.row(n), 0);
 | 
						||
  s.force_update(n);
 | 
						||
}
 | 
						||
 | 
						||
// Legge l'importo della riga n e lo ritorna col segno dovuto
 | 
						||
// Certified 100%
 | 
						||
TImporto TPrimanota_application::get_cgs_imp(int n) const
 | 
						||
{     
 | 
						||
  TSheet_field& s = cgs();
 | 
						||
  
 | 
						||
  TImporto importo;
 | 
						||
  
 | 
						||
  const TMask& m = s.sheet_mask();
 | 
						||
  if (m.is_running() && s.selected() == n)
 | 
						||
  {
 | 
						||
    const TString& imp = m.get(CG_DARE);
 | 
						||
    if (imp.not_empty())
 | 
						||
      importo.set('D', real(imp));
 | 
						||
    else  
 | 
						||
      importo.set('A', real(m.get(CG_AVERE)));
 | 
						||
  }
 | 
						||
  else
 | 
						||
    importo = s.row(n);
 | 
						||
  
 | 
						||
  return importo;
 | 
						||
}
 | 
						||
 | 
						||
// Certified 100%
 | 
						||
bool TPrimanota_application::add_cgs_imp(int n, const TImporto& imp)
 | 
						||
{
 | 
						||
  TImporto tot(get_cgs_imp(n));
 | 
						||
  tot += imp;       
 | 
						||
  tot.normalize();
 | 
						||
  set_cgs_imp(n, tot);
 | 
						||
  return tot.is_zero();
 | 
						||
}
 | 
						||
 | 
						||
// Certified 100%
 | 
						||
bool TPrimanota_application::sub_cgs_imp(int n, const TImporto& imp)
 | 
						||
{
 | 
						||
  TImporto tot(get_cgs_imp(n));
 | 
						||
  tot -= imp; 
 | 
						||
  tot.normalize();
 | 
						||
  set_cgs_imp(n, tot);
 | 
						||
  return tot.is_zero();
 | 
						||
}
 | 
						||
 | 
						||
TImporto TPrimanota_application::real2imp(const real& r, char row_type)
 | 
						||
{   
 | 
						||
  bool dare;
 | 
						||
  if (row_type == 'S')
 | 
						||
  {
 | 
						||
    dare = causale().sezione_ritsoc() == 'D';
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    dare = causale().sezione_clifo() == 'D';
 | 
						||
    if (row_type != 'T' && row_type != 'F') 
 | 
						||
      dare = !dare;
 | 
						||
  }  
 | 
						||
  
 | 
						||
  TImporto importo(dare ? 'D' : 'A', r);
 | 
						||
  return importo;
 | 
						||
}
 | 
						||
 | 
						||
// Disabilita le celle della riga contabile n in base al suo tipo
 | 
						||
void TPrimanota_application::disable_cgs_cells(int n, char tipo)
 | 
						||
{
 | 
						||
  TSheet_field& cg = cgs();
 | 
						||
 | 
						||
  int first = 0, last = 0;    // Range di righe da disabilitare
 | 
						||
  switch(tipo)
 | 
						||
  {
 | 
						||
  case 'T':                   // Totale documento
 | 
						||
    if (causale().corrispettivi())
 | 
						||
    {
 | 
						||
      last = 2;
 | 
						||
    }    
 | 
						||
    else
 | 
						||
    {
 | 
						||
      last = 3;
 | 
						||
      cg.disable_cell(n, 5);
 | 
						||
      cg.disable_cell(n, 6);
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case 'A':                   // Abbuoni attivi
 | 
						||
  case 'C':                   // Differenza cambio
 | 
						||
  case 'D':                   // IVA Detraibile
 | 
						||
  case 'F':                   // Ritenute Fiscali
 | 
						||
  case 'L':                   // Contropartita delle spese
 | 
						||
  case 'N':                   // IVA Non detraibile
 | 
						||
  case 'P':                   // Abbuoni passivi
 | 
						||
  case 'R':                   // Ritenute professionali
 | 
						||
  case 'S':                   // Ritenute Sociali
 | 
						||
    last = 3;                 
 | 
						||
    break;          
 | 
						||
  case 'K':                   // Riga cliente/fornitore per saldaconto
 | 
						||
    if (curr_mask().is_running() && n == cg.items()-1) // Sono in inserimento di una riga nuova
 | 
						||
      break;
 | 
						||
    first = 2;  
 | 
						||
  case 'I':
 | 
						||
    last = 7;                 // Imponibile
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    last = 0;                 // Solo contabile
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  
 | 
						||
  bool needs_update = false;  
 | 
						||
 | 
						||
  if (last)
 | 
						||
  {
 | 
						||
    for (int i = first; i < last; i++)
 | 
						||
      cg.disable_cell(n, i);
 | 
						||
    needs_update = true;  
 | 
						||
  }  
 | 
						||
  
 | 
						||
  COLOR back_color, fore_color;
 | 
						||
  type2colors(tipo, back_color, fore_color);
 | 
						||
  if (back_color != NORMAL_BACK_COLOR || fore_color != NORMAL_COLOR)
 | 
						||
  {
 | 
						||
    cg.set_back_and_fore_color(back_color, fore_color, n);
 | 
						||
    needs_update = true;  
 | 
						||
  }
 | 
						||
    
 | 
						||
  if (needs_update)  
 | 
						||
    cg.force_update(n);
 | 
						||
}
 | 
						||
 | 
						||
void TPrimanota_application::reset_sheet_row(TSheet_field& s, int n)
 | 
						||
{
 | 
						||
  s.row(s.items());           // Append a new line
 | 
						||
  s.destroy(n);               // Remove line n
 | 
						||
}
 | 
						||
 | 
						||
int TPrimanota_application::set_cgs_row(int n, const TImporto& imp,
 | 
						||
                                        TBill& conto, const char* desc,
 | 
						||
                                        char tipo, const char* cms, const char* fas)
 | 
						||
{
 | 
						||
  TSheet_field& cg = cgs();
 | 
						||
  if (n < 0) n = cg.first_empty();
 | 
						||
  TToken_string& row = cg.row(n);
 | 
						||
  row.cut(0);
 | 
						||
  imp.add_to(row, 0);
 | 
						||
  row.add(conto.string(0x3));
 | 
						||
  row.add("");                          // Codice decrizione
 | 
						||
  row.add(desc);                        // Descrizione aggiuntiva
 | 
						||
  
 | 
						||
  if (tipo == 'T')                      // Calcolo contropartita
 | 
						||
  {
 | 
						||
    TToken_string& irow = ivas().row(0);
 | 
						||
    TBill contro(irow, 5, 0x3);
 | 
						||
    if (contro.ok())                    // Errore MI3599
 | 
						||
      row.add(contro.string(0x3));
 | 
						||
    else  
 | 
						||
      row.add(" | | | | ");  
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    const int pos = type2pos('T');
 | 
						||
    if (pos >= 0)
 | 
						||
    {                         
 | 
						||
      TBill contro(cg.row(pos), 2, 0x3);
 | 
						||
      if (contro.ok())
 | 
						||
        row.add(contro.string(0x3));
 | 
						||
    }
 | 
						||
    else 
 | 
						||
      row.add(" | | | | ");  
 | 
						||
  }
 | 
						||
   
 | 
						||
	row.add(tipo, CG_ROWTYPE-FIRST_FIELD);
 | 
						||
 | 
						||
  disable_cgs_cells(n, tipo);
 | 
						||
 | 
						||
  return n;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
HIDDEN int compare_rows(const TObject** o1, const TObject** o2)
 | 
						||
{
 | 
						||
  // Totale, Rit.Fisc., Rit.Soc., da riga IVA, riga contabile, IVA detr., IVA non detr.
 | 
						||
  const char* const sort_order = "TFSI DNAPRC"; 
 | 
						||
 | 
						||
  const TToken_string* r1 = (const TToken_string*)*o1;
 | 
						||
  const TToken_string* r2 = (const TToken_string*)*o2;
 | 
						||
  const char c1 = app().row_type(*r1);
 | 
						||
  const char c2 = app().row_type(*r2);
 | 
						||
  return int(strchr(sort_order, c1) - strchr(sort_order, c2));
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN bool can_remove(TToken_string& s)
 | 
						||
{     
 | 
						||
  const char* dare = s.get(0);
 | 
						||
  bool yes = dare == NULL ;
 | 
						||
  if (!yes)
 | 
						||
  {
 | 
						||
    if (*dare == '\0' || *dare == ' ' || strcmp(dare,"0") == 0)
 | 
						||
    {
 | 
						||
      const char* avere = s.get();
 | 
						||
      yes = (avere == NULL || *avere == '\0' || *avere == ' ' || strcmp(avere,"0") == 0);
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return yes;
 | 
						||
}
 | 
						||
 | 
						||
void TPrimanota_application::cgs_pack()
 | 
						||
{ 
 | 
						||
  const bool pagamento = is_pagamento();
 | 
						||
  const long numreg = curr_mask().get_long(F_NUMREG);
 | 
						||
  bool rowtypes_present = false;
 | 
						||
 | 
						||
  TSheet_field& s = cgs();
 | 
						||
  TString_array& rows = s.rows_array();
 | 
						||
  for (int i = rows.items()-1; i >= 0; i--)
 | 
						||
  {
 | 
						||
    TToken_string& r = rows.row(i);
 | 
						||
    const char rt = row_type(r);
 | 
						||
 | 
						||
    rowtypes_present |= (rt > ' ');
 | 
						||
 | 
						||
    if (can_remove(r))
 | 
						||
    {                                    
 | 
						||
      bool ok = true;
 | 
						||
      if (pagamento && rt == 'K')
 | 
						||
      {
 | 
						||
        ok = !partite().utilizzata(numreg, i+1);
 | 
						||
        if (ok)
 | 
						||
          cg_notify(s, i, K_DEL);
 | 
						||
      }  
 | 
						||
      if (ok) 
 | 
						||
        rows.destroy(i, true);
 | 
						||
    }  
 | 
						||
  }  
 | 
						||
  if (!pagamento && rowtypes_present)  // Il pagamento e' gia' ordinato
 | 
						||
    rows.TArray::sort(compare_rows);   // Pack and sort array
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TPrimanota_application::ci_sono_importi(const TSheet_field& s) const
 | 
						||
{
 | 
						||
  TImporto imp;
 | 
						||
  FOR_EACH_SHEET_ROW(s, r, riga) if (riga && !riga->empty_items())
 | 
						||
  {
 | 
						||
    imp = *riga;
 | 
						||
    if (!imp.is_zero())
 | 
						||
      return true;
 | 
						||
  } 
 | 
						||
  return false;
 | 
						||
}
 | 
						||
 | 
						||
real TPrimanota_application::calcola_saldo() const
 | 
						||
{
 | 
						||
  const bool pag = is_pagamento() && !_as400;
 | 
						||
  TImporto importo, bilancio, saldaconto;
 | 
						||
  
 | 
						||
  TSheet_field& cgrows = cgs();
 | 
						||
  FOR_EACH_SHEET_ROW_BACK(cgrows, i, r)
 | 
						||
  {
 | 
						||
    importo = *r;
 | 
						||
    bilancio += importo;
 | 
						||
    if (pag)
 | 
						||
    {                                      
 | 
						||
      const char tipo = row_type(*r);     
 | 
						||
      if (strchr("ACGKP", tipo) != NULL) // Abbuoni attivi, differenze cambio, spese, ...
 | 
						||
        saldaconto += importo;  
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  TMask& m = curr_mask();
 | 
						||
  bilancio.normalize();
 | 
						||
  const real& sbil = bilancio.valore();
 | 
						||
  
 | 
						||
  const char sez = bilancio.is_zero() ? 'Z' : bilancio.sezione();
 | 
						||
  switch (sez) 
 | 
						||
  {                   
 | 
						||
  case 'D':
 | 
						||
    m.set(F_DARE, sbil);
 | 
						||
    m.reset(F_AVERE);
 | 
						||
    break;
 | 
						||
  case 'A':
 | 
						||
    m.reset(F_DARE);
 | 
						||
    m.set(F_AVERE, sbil);
 | 
						||
    break;
 | 
						||
  default: // Sbilancio nullo
 | 
						||
    m.reset(F_DARE);
 | 
						||
    m.reset(F_AVERE);
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (pag)
 | 
						||
  { 
 | 
						||
    const char s(causale().sezione(2));    // Conto della cassa
 | 
						||
    const real t(m.get(F_TOTALE));
 | 
						||
    TImporto totdoc(s, t);
 | 
						||
    totdoc += saldaconto;
 | 
						||
    totdoc.normalize(s);
 | 
						||
    m.set(K_RESIDUO, totdoc.valore().string());
 | 
						||
  }
 | 
						||
  
 | 
						||
  return sbil;
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN bool imptot_error(const TImporto& imptot, const TImporto& impsal, bool val)
 | 
						||
{   
 | 
						||
  TImporto cassa(impsal); cassa.swap_section();
 | 
						||
  TImporto residuo(imptot); residuo -= cassa; residuo.normalize(imptot.sezione());
 | 
						||
	bool ok = true;
 | 
						||
  
 | 
						||
//  if (!residuo.is_zero())
 | 
						||
  if (abs(residuo.valore()) >= 0.001)
 | 
						||
  {                    
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    const TMask& m = a.curr_mask();
 | 
						||
    TString4 codval; 
 | 
						||
    if (val) 
 | 
						||
      codval = m.get(SK_VALUTA);
 | 
						||
    TCurrency euro(imptot.valore(), codval);
 | 
						||
 | 
						||
    TString msg(255);
 | 
						||
    if (is_true_value(codval)) 
 | 
						||
      msg << TR("Il totale documento in valuta") << ' ' << codval;
 | 
						||
    else
 | 
						||
      msg << TR("Il totale documento inserito");  
 | 
						||
    msg << TR(" e' ") << euro.string(true) << ' ' << imptot.sezione() << ",\n";
 | 
						||
 | 
						||
    euro.set_num(cassa.valore());
 | 
						||
    msg << TR("i pagamenti e le spese ammontano a ") 
 | 
						||
        << euro.string(true) << ' ' << cassa.sezione() << ",\n";
 | 
						||
 | 
						||
    euro.set_num(residuo.valore());
 | 
						||
    msg << TR("per cui il residuo e' ") << euro.string(true);              
 | 
						||
    
 | 
						||
    if (m.edit_mode() && impsal.is_zero())
 | 
						||
    {
 | 
						||
      msg << TR("\nSi desidera registrare ugualmente?");
 | 
						||
      ok = a.cgs().yesno_box(msg);
 | 
						||
    }    
 | 
						||
    else
 | 
						||
      ok = a.cgs().error_box(msg);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Handler dello sheet di contabilita'
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::cg_handler(TMask_field& f, KEY k)
 | 
						||
{          
 | 
						||
  if (k == K_ENTER)
 | 
						||
  {             
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    const TCurrency saldo(a.calcola_saldo());
 | 
						||
    
 | 
						||
    if (!saldo.get_num().is_zero())
 | 
						||
    {
 | 
						||
      const char* ss = saldo.string(true); 
 | 
						||
      if (*ss == '-') ss++;        
 | 
						||
 | 
						||
      const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val());
 | 
						||
      const char* name = rec.get("S0");
 | 
						||
      return f.error_box(FR("Il movimento e' sbilanciato di %s %s."), ss, name);
 | 
						||
    } 
 | 
						||
    
 | 
						||
    TMask& m = f.mask();
 | 
						||
    const bool paga = a.is_pagamento(); 
 | 
						||
    const bool nota = a.is_nota_credito() && m.field(F_NUMRIF).active(); 
 | 
						||
    const bool fatt = a.is_fattura() && m.page_enabled(2);
 | 
						||
    
 | 
						||
    const long numreg = m.insert_mode() ? NUMREG_PROVVISORIO : m.get_long(F_NUMREG);
 | 
						||
    
 | 
						||
    const bool in_valuta = is_true_value(m.get(SK_VALUTA));
 | 
						||
    TImporto saldaconto, saldaconto_val;
 | 
						||
    
 | 
						||
    TSheet_field& cg = a.cgs();
 | 
						||
    bool empty = true;
 | 
						||
    for (int i = 0; i < cg.items(); i++)
 | 
						||
    {                        
 | 
						||
      TToken_string& r = cg.row(i);
 | 
						||
      TImporto importo; importo = r;
 | 
						||
      
 | 
						||
      if (!importo.is_zero())
 | 
						||
      {
 | 
						||
        TBill c(r, 2, 0x1);
 | 
						||
        if (!c.ok()) 
 | 
						||
          return f.error_box(FR("Il conto della riga %d non e' completo"), i+1);
 | 
						||
        if (m.insert_mode() && c.sospeso()) 
 | 
						||
          return f.error_box(FR("Il conto della riga %d e' sospeso"), i+1);
 | 
						||
        TBill co(r, 10, 0x0);
 | 
						||
        if (!co.empty() && !co.ok()) 
 | 
						||
        {
 | 
						||
          const bool ok = f.yesno_box(FR("La contropartita della riga %d non e' completa:\n"
 | 
						||
                                      "Si desidera continuare ugualmente?"), i+1);
 | 
						||
          if (!ok) return false;
 | 
						||
        }
 | 
						||
 | 
						||
        if (app().is_transaction())  
 | 
						||
        {   
 | 
						||
          // Controlla esistenza conti nelle transazioni (visto che non c'e' controllo in inserimento)
 | 
						||
          if (!c.find())
 | 
						||
            return f.error_box("Il conto della riga %d non esiste", i+1);
 | 
						||
          if (!co.empty() && !co.find())
 | 
						||
            return f.error_box("Il conto di contropartita della riga %d non esiste", i+1);
 | 
						||
        }
 | 
						||
     
 | 
						||
        empty = false;       
 | 
						||
        if (paga || nota)
 | 
						||
        {
 | 
						||
          const char tipo = row_type(r);
 | 
						||
          if (tipo == 'K' || tipo == 'T' || a._as400)
 | 
						||
          {                                               
 | 
						||
            const int currig = i+1;
 | 
						||
            const TImporto speso = a.partite().importo_speso(numreg, currig);
 | 
						||
            
 | 
						||
            bool errato = importo != speso;
 | 
						||
            if (errato && a._as400 && speso.is_zero())
 | 
						||
              errato = false;
 | 
						||
 | 
						||
            if (nota && errato && speso.is_zero())
 | 
						||
            {
 | 
						||
              const int annorif = m.get_int(F_ANNORIF);
 | 
						||
              const TString& numrif = m.get(F_NUMRIF);
 | 
						||
              if (annorif > 0 && !numrif.blank() && 
 | 
						||
                  yesno_box(FR("Si desidera generare automaticamente la partita %d %s?"), 
 | 
						||
                            annorif, (const char*)numrif))
 | 
						||
              {    
 | 
						||
                const TBill bill(r, 2, 0x1);
 | 
						||
                errato = !a.crea_partita(bill, annorif, numrif, currig, importo);
 | 
						||
              } 
 | 
						||
            }
 | 
						||
              
 | 
						||
            if (errato)
 | 
						||
            {
 | 
						||
              TString msg(128);
 | 
						||
              const TCurrency euro(speso.valore());
 | 
						||
              msg.format("L'importo sul saldaconto della riga %d e' %s", currig, (const char*)euro.string(true)); 
 | 
						||
              if (!speso.is_zero())    
 | 
						||
                msg << (speso.sezione() == 'A' ? TR(" Avere") : TR(" Dare"));
 | 
						||
              
 | 
						||
              bool ok = false;    
 | 
						||
              if (m.edit_mode() && speso.is_zero())    
 | 
						||
              {
 | 
						||
                msg << TR("\nSi desidera registrare ugualmente?");
 | 
						||
                ok = f.yesno_box(msg);
 | 
						||
              }
 | 
						||
              else
 | 
						||
                ok = f.error_box(msg);
 | 
						||
              if (!ok)  
 | 
						||
                return false;  
 | 
						||
            }
 | 
						||
          }
 | 
						||
          if (strchr("ACGKPT", tipo) != NULL)
 | 
						||
          {
 | 
						||
            saldaconto += importo;  
 | 
						||
            if (in_valuta)
 | 
						||
            {
 | 
						||
              if (tipo == 'G')  // Le spese non si trovano sul saldaconto
 | 
						||
              {
 | 
						||
                const TExchange cam(m.get(SK_VALUTA), m.get_real(SK_CAMBIO));
 | 
						||
                TCurrency spe(importo.valore()); spe.change_value(cam);
 | 
						||
                const TImporto imp_spe(importo.sezione(), spe.get_num());
 | 
						||
                saldaconto_val += imp_spe;
 | 
						||
              }  else
 | 
						||
              if (tipo == 'K' || tipo == 'T')
 | 
						||
                saldaconto_val += a.partite().importo_speso(numreg, i+1, true, 0x1);
 | 
						||
            }
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
 | 
						||
      }
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (empty)
 | 
						||
      return f.error_box(TR("Il movimento non ha nessuna riga contabile con un importo"));
 | 
						||
    
 | 
						||
    if ((paga || nota) && !a._as400)
 | 
						||
    {              
 | 
						||
      const char sez(a.causale().sezione(2));
 | 
						||
      const TImporto totdoc(sez, m.get_real(F_TOTALE));
 | 
						||
      bool ok = imptot_error(totdoc, saldaconto, false);
 | 
						||
      
 | 
						||
      if (ok && in_valuta && !saldaconto.is_zero())                                                   
 | 
						||
      {
 | 
						||
        const TImporto totdoc_val(sez, m.get_real(SK_TOTDOCVAL));
 | 
						||
        ok = imptot_error(totdoc_val, saldaconto_val, true);
 | 
						||
      }  
 | 
						||
      
 | 
						||
      if (!ok) 
 | 
						||
        return false;
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (fatt || nota)
 | 
						||
    {
 | 
						||
      TBill contocf; 
 | 
						||
      const int riga_cf = a.cerca_conto_cf(contocf);
 | 
						||
      if (riga_cf < 0)
 | 
						||
      {
 | 
						||
        TString msg(80); msg = TR("Non esiste una riga contabile riferita al ");
 | 
						||
        msg << (contocf.tipo() == 'C' ? TR("cliente") : TR("fornitore")) << ' ';
 | 
						||
        msg << contocf.codclifo() << ":\n";
 | 
						||
        if (m.edit_mode())
 | 
						||
        {         
 | 
						||
          msg << TR("Si desidera eliminare il saldaconto?");
 | 
						||
          const bool kill = f.yesno_box(msg);
 | 
						||
          if (kill)
 | 
						||
          { 
 | 
						||
            if (fatt)                   // Se e' una fattura elimina il numero partita
 | 
						||
            {
 | 
						||
              m.reset(F_ANNORIF);
 | 
						||
              m.reset(F_NUMRIF);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {                           // Se e' una nota credito elimina il saldaconto
 | 
						||
              a.notify_cgline_deletion(-1);
 | 
						||
            }  
 | 
						||
          }
 | 
						||
          else
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
        else         
 | 
						||
        {
 | 
						||
          msg << TR("Impossibile registrare il saldaconto!");
 | 
						||
          return f.error_box(msg);
 | 
						||
        }  
 | 
						||
      }  
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPrimanota_application::generazione_righe_cg(int r)
 | 
						||
{   
 | 
						||
  TSheet_field& cg = cgs();
 | 
						||
  TToken_string& row = cg.row(r);
 | 
						||
  
 | 
						||
  if (can_remove(row))                      // Ignora righe senza importo
 | 
						||
    return;
 | 
						||
 | 
						||
  TWait_cursor hourglass;
 | 
						||
 | 
						||
  TImporto importo; importo = row; 
 | 
						||
  const bool causale_ok = causale().codice()[0] > ' ';  
 | 
						||
 | 
						||
  // Se la seconda riga e' vuota la genero completamente dalla prima
 | 
						||
  if (r == 0 && cg.row(1).empty_items())
 | 
						||
  {
 | 
						||
    TBill contro(row, 9, 0x3);              // Contropartita della prima riga
 | 
						||
    if (causale_ok && !contro.ok())
 | 
						||
    {
 | 
						||
      causale().bill(2, contro);            // Prendi contropartita dalla causale
 | 
						||
      if (contro.ok())
 | 
						||
      {
 | 
						||
        contro.add_to(row, 9, 0x3);
 | 
						||
        cg.force_update(0);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
    if (contro.ok())
 | 
						||
    {
 | 
						||
      importo.swap_section();                // Inverto la sezione  D/A
 | 
						||
      set_cgs_row(1, importo, contro, "", ' ');
 | 
						||
      TBill conto(row, 2, 0x3);
 | 
						||
      conto.add_to(cg.row(1), 9, 0x3);
 | 
						||
      cg.force_update(1);  
 | 
						||
    }  
 | 
						||
  }                        
 | 
						||
 | 
						||
  if (causale_ok)
 | 
						||
  {
 | 
						||
    int first_not_empty = 0;
 | 
						||
    int i;
 | 
						||
     
 | 
						||
    for (i = 0; i < r; i++)
 | 
						||
    {   
 | 
						||
      TToken_string& row = cg.row(i);
 | 
						||
      if (!can_remove(row))
 | 
						||
      {
 | 
						||
        first_not_empty = i;
 | 
						||
        break;
 | 
						||
      }  
 | 
						||
    }
 | 
						||
    
 | 
						||
    TBill conto(row, 2, 0x3);
 | 
						||
    if (first_not_empty == r)              // Sono la prima riga con importo ?
 | 
						||
    {            
 | 
						||
      int last = -1;
 | 
						||
      for (i = r+1; i < cg.items(); i++)   // Aggiorna tutte le altre contropartite
 | 
						||
      {                                    
 | 
						||
        TToken_string& rowi = cg.row(i);
 | 
						||
        int gruppo =  rowi.get_int(3);
 | 
						||
        if (gruppo != 0)                   // Considera righe con conto ...
 | 
						||
        {     
 | 
						||
          long sotto = rowi.get_long(12);
 | 
						||
          if (sotto == 0)                  // ... e senza contropartita
 | 
						||
          { 
 | 
						||
            char sez = ' ';                // Calcola sezione D/A della riga i
 | 
						||
            if (cg.cell_disabled(i,0)) sez = 'A'; else
 | 
						||
              if (cg.cell_disabled(i,1)) sez = 'D';
 | 
						||
            
 | 
						||
            if (sez != ' ' && importo.sezione() != sez)  // Considera solo le sezioni opposte 
 | 
						||
            {   
 | 
						||
              conto.add_to(rowi, 9, 0x3);
 | 
						||
              cg.force_update(i);
 | 
						||
              if (last < 0) last = i;
 | 
						||
              else last = 0;
 | 
						||
            }  
 | 
						||
          }  
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (last > r)
 | 
						||
      {
 | 
						||
        importo.swap_section();
 | 
						||
        set_cgs_imp(last, importo);
 | 
						||
        
 | 
						||
        const long sotto = row.get_long(12);             
 | 
						||
        if (sotto == 0)                       // Se non ho contropartita ...
 | 
						||
        {
 | 
						||
          TBill contro(cg.row(last), 2, 0x3); // ... copiala dalla riga corrispondente
 | 
						||
          contro.add_to(row, 9, 0x3); 
 | 
						||
          cg.force_update(r);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {                  
 | 
						||
      TToken_string& first = cg.row(first_not_empty);
 | 
						||
      long sotto = first.get_long(12);
 | 
						||
      if (sotto == 0)                       // Se la prima riga non ha contropartita ...
 | 
						||
      {
 | 
						||
        conto.add_to(first, 9, 0x3);        // ... copiaci la mia partita
 | 
						||
        cg.force_update(first_not_empty);
 | 
						||
      }              
 | 
						||
      sotto = row.get_long(12);             
 | 
						||
      if (sotto == 0)                       // Se non ho contropartita ...
 | 
						||
      {
 | 
						||
        TBill contro(first, 2, 0x3);        // ... copiala dalla prima riga
 | 
						||
        contro.add_to(row, 9, 0x3); 
 | 
						||
        cg.force_update(r);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
int TPrimanota_application::crea_somma_spese(TImporto& imp)
 | 
						||
{
 | 
						||
  TBill cassa; causale().bill(2, cassa);
 | 
						||
  const TString desc(causale().desc_agg(2));
 | 
						||
  imp.swap_section(); imp.normalize();
 | 
						||
  const int r = set_cgs_row(-1, imp, cassa, desc, 'L');
 | 
						||
  cgs().force_update();
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
void TPrimanota_application::update_saldo_riga(int r)
 | 
						||
{
 | 
						||
  TMask& m = curr_mask();
 | 
						||
	
 | 
						||
	if (m.id2pos(F_SHEETCG) < 0)
 | 
						||
		return;
 | 
						||
 | 
						||
  TSheet_field& sheet = m.sfield(F_SHEETCG);
 | 
						||
  TToken_string row = sheet.row(r);
 | 
						||
  TBill bill; bill.get(row, 2, 0x1);
 | 
						||
 | 
						||
  if (bill.ok())
 | 
						||
  {
 | 
						||
    const int annoes = m.get_int(F_ANNOES);
 | 
						||
 | 
						||
    // Legge il saldo finale del conto
 | 
						||
    TBalance bilancio;
 | 
						||
    bilancio.read(bill, annoes, false, false);
 | 
						||
    TImporto saldo = bilancio.saldo_finale();
 | 
						||
 | 
						||
    // Sottrae (somma algebricamente) il valore iniziale del conto
 | 
						||
    const TConto* conto = _saldi.find(bill, annoes);
 | 
						||
    if (conto != NULL)
 | 
						||
    {
 | 
						||
      saldo += TImporto('D', conto->dare());
 | 
						||
      saldo += TImporto('A', conto->avere());
 | 
						||
    }
 | 
						||
 | 
						||
    // Somma l'importo delle singole righe con quel conto
 | 
						||
    for (int i = sheet.items()-1; i >= 0; i--)
 | 
						||
    {
 | 
						||
      row = sheet.row(i);
 | 
						||
      if (!row.empty_items())
 | 
						||
      {
 | 
						||
        TBill zio; zio.get(row, 2, 0x1);
 | 
						||
        if (zio == bill)
 | 
						||
        {
 | 
						||
          TImporto da; da = row;
 | 
						||
          saldo += da;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    
 | 
						||
    TString80 s;  // Stringa di lavoro
 | 
						||
 | 
						||
    // Trasforma il saldo in stringa
 | 
						||
    saldo.normalize();
 | 
						||
    if (!saldo.is_zero())
 | 
						||
    {
 | 
						||
      const TCurrency imp = saldo.valore();  
 | 
						||
      s = imp.string(true);
 | 
						||
      s << ' ' << saldo.sezione();
 | 
						||
    }
 | 
						||
 | 
						||
    bill.set(m, F_GRUPPO, F_CONTO, F_SOTTOCONTO);  // Stampa conto
 | 
						||
    m.set(F_SALDOCONTO, s);                        // Stampa saldo 
 | 
						||
 | 
						||
    // Controlla se il conto ha attivato il controllo del segno
 | 
						||
    s = bill.string();     // Chiave del sottoconto da controllare
 | 
						||
    if (bill.tipo() > ' ') // Per i clienti/fornitori devo controllare il solo gruppo/conto
 | 
						||
    {
 | 
						||
      const int pipe = s.rfind('|');
 | 
						||
      s.cut(pipe);
 | 
						||
    }
 | 
						||
    const TRectype& pcon = cache().get(LF_PCON, s);
 | 
						||
    const char sez = pcon.get_char(PCN_SEZSALDI);
 | 
						||
    bool red = false;
 | 
						||
    if (sez > ' ' && !saldo.is_zero()) // Il conto ha impostato il controllo della sezione!
 | 
						||
      red = sez != saldo.sezione();
 | 
						||
 | 
						||
    // Scrive in nero o rosso la parola Saldo
 | 
						||
    s = TR("Saldo");
 | 
						||
    if (red)
 | 
						||
    {
 | 
						||
      s.upper();
 | 
						||
      s.insert("@b$[r]");
 | 
						||
    }
 | 
						||
    m.field(F_SALDOCONTO).set_prompt(s);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::cg_notify(TSheet_field& cg, int r, KEY k)
 | 
						||
{                            
 | 
						||
  static TImporto old_spesa;
 | 
						||
  static bool delete_l = false;
 | 
						||
  static bool selecting = false;
 | 
						||
  
 | 
						||
  CHECKD(r >= 0, "Chi e' quel ca$$one che notifica la riga ", r);
 | 
						||
  
 | 
						||
  TPrimanota_application& a = app();
 | 
						||
 | 
						||
  if (k == K_CTRL + K_DEL)
 | 
						||
  {
 | 
						||
    if (delete_l)
 | 
						||
    {
 | 
						||
      const int l = type2pos('L');
 | 
						||
      CHECK(l >= 0, "Impossibile cancellare riga di tipo L");
 | 
						||
      cg.destroy(l);
 | 
						||
      delete_l = false;
 | 
						||
    }
 | 
						||
    a.calcola_saldo();                      // Ricalcola saldo dopo cancellazione
 | 
						||
    return true;                            // Ritorna subito, altrimenti crea riga vuota
 | 
						||
  }  
 | 
						||
  
 | 
						||
  if (k == K_INS)                           // La riga non esiste ancora
 | 
						||
    return true;
 | 
						||
  
 | 
						||
  TToken_string& row = cg.row(r);
 | 
						||
  const char tipo = row_type(row);          // Tipo della riga in esame
 | 
						||
 | 
						||
  switch(k)
 | 
						||
  {                             
 | 
						||
  case K_SPACE:
 | 
						||
    if (tipo == 'G')
 | 
						||
      old_spesa = row;
 | 
						||
    else  
 | 
						||
      old_spesa.valore() = ZERO;
 | 
						||
    break;  
 | 
						||
  case K_TAB:
 | 
						||
    if (!selecting)
 | 
						||
    {
 | 
						||
      cg.sheet_mask().enable(DLG_DELREC, tipo <= ' ' || tipo == 'K' || tipo == 'G');
 | 
						||
      if (row.empty_items())
 | 
						||
      {
 | 
						||
        selecting = true;
 | 
						||
        cg.select(r, 1);  // Vado alla prima colonna delle righe vuote 
 | 
						||
        selecting = false;
 | 
						||
      }
 | 
						||
      a.update_saldo_riga(r);
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case K_DEL:                  
 | 
						||
    if (tipo == 'G')
 | 
						||
    {
 | 
						||
      if (old_spesa.is_zero())
 | 
						||
        old_spesa = row;
 | 
						||
      row.add("", 0); 
 | 
						||
      row.add("", 1);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (tipo == 'K')
 | 
						||
        a.notify_cgline_deletion(r+1);
 | 
						||
      break;  
 | 
						||
    }  
 | 
						||
  case K_ENTER:   
 | 
						||
    if (tipo == 'G')
 | 
						||
    {       
 | 
						||
      TImporto growth; growth = row; growth -= old_spesa;
 | 
						||
      if (!growth.is_zero())
 | 
						||
      {
 | 
						||
        const int s = type2pos('L');
 | 
						||
        if (s < 0)
 | 
						||
          a.crea_somma_spese(growth);
 | 
						||
        else
 | 
						||
          delete_l = a.sub_cgs_imp(s, growth);
 | 
						||
      }    
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (a.iva() == nessuna_iva && !a.is_saldaconto())        
 | 
						||
        a.generazione_righe_cg(r);
 | 
						||
    }  
 | 
						||
    if (k == K_ENTER)
 | 
						||
    {
 | 
						||
      a.calcola_saldo();             // Altrimenti ci pensa CTRL-DEL
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case K_CTRL+K_INS:                 // Post inserimento
 | 
						||
    if (a.is_pagamento())
 | 
						||
    {  
 | 
						||
      const char tipo = cg.mask().get(SK_TIPORIGA)[0];
 | 
						||
      if (tipo == 'K' || tipo == 'G') 
 | 
						||
      {                             
 | 
						||
        const int k = tipo == 'K' ? 1 : RIGA_SPESE;      
 | 
						||
        TBill conto; a.causale().bill(k, conto);
 | 
						||
        const TString desc(a.causale().desc_agg(k));
 | 
						||
        const char sez = a.causale().sezione(k);
 | 
						||
        const real imp = cg.mask().get_real(K_RESIDUO);
 | 
						||
        TImporto importo(sez, imp); importo.normalize();
 | 
						||
        
 | 
						||
        if (tipo == 'G')
 | 
						||
        {
 | 
						||
          const char sezbanca = a.causale().sezione(2);
 | 
						||
          if (sezbanca == sez)
 | 
						||
            importo.swap_section();
 | 
						||
        }
 | 
						||
        
 | 
						||
        a.set_cgs_row(r, importo, conto, desc, tipo);
 | 
						||
        
 | 
						||
        if (tipo == 'K')
 | 
						||
        {     
 | 
						||
          for (int i = 0; i < r; i++)
 | 
						||
          {
 | 
						||
            const TToken_string& row = cg.row(i);
 | 
						||
            if (row_type(row) != 'K') 
 | 
						||
            {
 | 
						||
              cg.swap_rows(r, i);
 | 
						||
              cg.post_select(i);
 | 
						||
              break;
 | 
						||
            }  
 | 
						||
          }  
 | 
						||
        }   
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (!importo.is_zero())
 | 
						||
          {
 | 
						||
            const int s = type2pos('L');
 | 
						||
            if (s < 0)           
 | 
						||
              a.crea_somma_spese(importo);
 | 
						||
            else
 | 
						||
              a.sub_cgs_imp(s, importo);
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
        a.calcola_saldo();
 | 
						||
      }
 | 
						||
    }    
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::descr_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_TAB && f.focusdirty())
 | 
						||
  {
 | 
						||
    if (app().iva() != nessuna_iva)
 | 
						||
    { 
 | 
						||
      const int first = type2pos('T'); 
 | 
						||
      if (first >= 0)
 | 
						||
      {
 | 
						||
        TSheet_field& cg = app().cgs();
 | 
						||
        const TString80 old = cg.row(first).get(8);
 | 
						||
        if (old.blank() || f.get().find(old) >= 0)
 | 
						||
        {
 | 
						||
          cg.row(first).add(f.get(), 8);
 | 
						||
          cg.force_update(first);
 | 
						||
        }  
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  if (k == K_ENTER && f.get().empty())
 | 
						||
  {
 | 
						||
    if (f.mask().get(F_CODCAUS).empty())
 | 
						||
      return f.error_box(TR("La descrizione del documento e' necessaria in assenza della causale"));
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Handler per le colonne 'Dare' e 'Avere' dello sheet contabile.  
 | 
						||
// Scrivendo qualcosa in dare (101) cancella l'importo in avere (102) e viceversa
 | 
						||
bool TPrimanota_application::dareavere_handler(TMask_field& f, KEY k)
 | 
						||
{          
 | 
						||
  TPrimanota_application& a = app();
 | 
						||
  TSheet_field& cgs = a.cgs();
 | 
						||
  const int currig = cgs.selected();
 | 
						||
  TMask& m = f.mask();
 | 
						||
  
 | 
						||
  if (k == K_F8 && a.is_pagamento())
 | 
						||
  { 
 | 
						||
    const TMask& cm = a.curr_mask();
 | 
						||
    const long numreg = cm.insert_mode() ? NUMREG_PROVVISORIO : cm.get_long(F_NUMREG);
 | 
						||
    const TImporto speso = a.partite().importo_speso(numreg, currig+1);
 | 
						||
    
 | 
						||
    const char* ss = speso.valore().string();
 | 
						||
    m.set(CG_DARE,  speso.sezione() == 'D' ? ss : ""); 
 | 
						||
    m.set(CG_AVERE, speso.sezione() == 'A' ? ss : "");
 | 
						||
    
 | 
						||
    if (!m.is_running())
 | 
						||
    {
 | 
						||
      speso.add_to(cgs.row(currig), 0);             // Aggiorna riga sheet
 | 
						||
      a.calcola_saldo();                            // Aggiorna saldo e residuo
 | 
						||
      a.update_saldo_riga(currig);
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (k == K_TAB && f.focusdirty())
 | 
						||
  {                               
 | 
						||
    const TString& val = f.get();
 | 
						||
    TToken_string& row = cgs.row(currig);
 | 
						||
    row.add(val, f.dlg() - CG_DARE);               // Aggiorno stringa sheet
 | 
						||
 | 
						||
    if (val.not_empty())
 | 
						||
    {
 | 
						||
      // Calcola id del campo da resettare
 | 
						||
      const int id = f.dlg() == CG_DARE ? CG_AVERE : CG_DARE;  
 | 
						||
      m.reset(id);                         // Aggiorna maschera e ...
 | 
						||
      row.add("", id - CG_DARE);                  // ... riga dello sheet
 | 
						||
    }  
 | 
						||
    
 | 
						||
    if (!m.is_running())
 | 
						||
    {
 | 
						||
      a.calcola_saldo();                          // Aggiorna saldo e residuo
 | 
						||
      a.update_saldo_riga(currig);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (k == K_ENTER && f.dirty() && m.is_running())
 | 
						||
  {
 | 
						||
    a.calcola_saldo();                          // Aggiorna saldo e residuo
 | 
						||
    a.update_saldo_riga(currig);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
TSheet_field& TPrimanota_application::pags() const
 | 
						||
{                                         
 | 
						||
  CHECK(is_fattura(), "Can't use rate sheet without a fattura");
 | 
						||
  TMask& m = *_msk[iva() == nessuna_iva ? 1 : 2];
 | 
						||
  return m.sfield(FS_RATESHEET);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Gestione sheet IVA
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// Ritorna lo sheet delle righe IVA
 | 
						||
// Certified 100%
 | 
						||
TSheet_field& TPrimanota_application::ivas() const
 | 
						||
{
 | 
						||
  TSheet_field& s = _msk[2]->sfield(F_SHEETIVA);
 | 
						||
  return s;
 | 
						||
}
 | 
						||
 | 
						||
// Gestione del campo imponibile sullo sheet iva
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::imponibile_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.dirty())
 | 
						||
  { 
 | 
						||
    TMask& m = f.mask();
 | 
						||
    TString4 iva(m.get(102));        
 | 
						||
    if (iva.blank())
 | 
						||
    {
 | 
						||
      iva = app().curr_mask().get(F_CODIVA);
 | 
						||
      if (iva.not_empty())
 | 
						||
        m.set(102, iva, true);
 | 
						||
    }  
 | 
						||
    if (iva.not_empty() && !app().causale().corrispettivi())
 | 
						||
    {
 | 
						||
      const real& percent = cod2IVA(m);
 | 
						||
      const real imponibile(f.get());
 | 
						||
      const int dec = TCurrency::get_firm_dec();
 | 
						||
      real imposta;
 | 
						||
      if (dec == 0) // Siamo in ancora in LIRE!
 | 
						||
      {
 | 
						||
        imposta = abs(imponibile) * percent / CENTO; 
 | 
						||
        imposta.ceil();
 | 
						||
        if (imponibile.sign() < 0) imposta = -imposta;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        imposta = imponibile * percent / CENTO;
 | 
						||
        imposta.round(dec);
 | 
						||
      }
 | 
						||
      m.set(104, imposta);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Gestione del codice IVA sullo sheet iva
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::codiva_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (!suspended_handler(f, key))
 | 
						||
    return false;
 | 
						||
 | 
						||
  if (key == K_TAB && f.dirty())
 | 
						||
  {
 | 
						||
    TMask& m = f.mask();
 | 
						||
    const TCodiceIVA iva(f.get());
 | 
						||
 | 
						||
    if (m.get_int(107) == 0)
 | 
						||
    { 
 | 
						||
      TBill b; app().IVA2bill(iva, b);
 | 
						||
      
 | 
						||
      char cr[2] = { b.tipo_cr() + '0', '\0' };
 | 
						||
      m.set(105, *cr > '0' ? cr : "");
 | 
						||
      
 | 
						||
      const char tipo[2] = { b.tipo(), '\0' };
 | 
						||
      m.set(106, tipo);
 | 
						||
      m.set(107, b.gruppo());
 | 
						||
      m.set(108, b.conto());
 | 
						||
      const short id = b.tipo() == 'C' ? 209 : (b.tipo() == 'F' ? 309 : 109);
 | 
						||
      m.set(id, b.sottoconto());
 | 
						||
      m.set(id+1, b.descrizione());
 | 
						||
      
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (app().iva() == iva_acquisti)
 | 
						||
    {
 | 
						||
      const int det = iva.detraibilita();
 | 
						||
      if (det > 0)
 | 
						||
        m.set(103, det);
 | 
						||
    }
 | 
						||
    
 | 
						||
    TMask_field& im = m.field(101);
 | 
						||
    im.set_dirty();
 | 
						||
    im.on_hit();
 | 
						||
  } 
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (key == K_ENTER)
 | 
						||
    { 
 | 
						||
      if (f.get().empty() && f.mask().get(101).not_empty())
 | 
						||
        return f.error_box(TR("Codice IVA obbligatorio"));
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Gestione del codice detrazione sullo sheet iva
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::detrazione_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.dirty() && app().iva() == iva_acquisti)
 | 
						||
  {                            
 | 
						||
    TMask& m = f.mask();
 | 
						||
    TMask_field& ci = m.field(101);
 | 
						||
    ci.set_dirty();
 | 
						||
    ci.on_hit();
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Gestione del campo imposta sullo sheet iva
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::imposta_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  TMask& m = f.mask();
 | 
						||
  if ((key == K_ENTER || key == K_TAB) && f.dirty())
 | 
						||
  {
 | 
						||
    const real imponibile(m.get(101));
 | 
						||
    const real percent = app().causale().corrispettivi() ? ZERO : cod2IVA(m);
 | 
						||
    const int dec = TCurrency::get_firm_dec();
 | 
						||
    real imposta;
 | 
						||
    if (dec == 0)
 | 
						||
    {
 | 
						||
      imposta = abs(imponibile) * percent / CENTO; 
 | 
						||
      imposta.ceil();
 | 
						||
      if (imponibile.sign() < 0) imposta = -imposta;
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      imposta = imponibile * percent / CENTO; 
 | 
						||
      imposta.round(dec);
 | 
						||
    }
 | 
						||
    
 | 
						||
    const real val(f.get());
 | 
						||
    if (val != imposta)
 | 
						||
    {    
 | 
						||
      const TCurrency euro(imposta);
 | 
						||
      f.warning_box(FR("L'imposta dovrebbe essere %s"), euro.string(true));
 | 
						||
    }
 | 
						||
  } else
 | 
						||
    if (key == K_F8)
 | 
						||
    {
 | 
						||
      real imposta(f.get());
 | 
						||
      if (imposta.is_zero())
 | 
						||
      {
 | 
						||
        real imponibile(m.get(101));
 | 
						||
        const real& percent = cod2IVA(m);
 | 
						||
        imposta = scorpora(imponibile, percent);
 | 
						||
        m.set(101, imponibile);
 | 
						||
        f.set(imposta.string());
 | 
						||
      }
 | 
						||
      else 
 | 
						||
        f.warning_box(TR("Cancellare l'imposta (tasto F2) prima di effettuare lo scorporo"));  
 | 
						||
    }
 | 
						||
 | 
						||
  return true;
 | 
						||
}                   
 | 
						||
 | 
						||
 | 
						||
// Calcola il totale degli imponibili e delle imposte e aggiorna
 | 
						||
// i corrispondenti campi della maschera
 | 
						||
// Certified 99%
 | 
						||
real TPrimanota_application::calcola_imp() const
 | 
						||
{                   
 | 
						||
  TArray& rows = ivas().rows_array();
 | 
						||
 | 
						||
  real imponibili, imposte;
 | 
						||
  for (int r = rows.items()-1; r >= 0; r--)
 | 
						||
  {
 | 
						||
    TToken_string& row = (TToken_string&)rows[r];
 | 
						||
    imponibili += real(row.get(0));  
 | 
						||
    imposte += real(row.get(3));
 | 
						||
  }
 | 
						||
  
 | 
						||
  TMask& m = curr_mask();
 | 
						||
  m.set(F_IMPONIBILI, imponibili);
 | 
						||
  m.set(F_IMPOSTE, imposte);
 | 
						||
  
 | 
						||
  // Se e' attiva la terza pagina allora riporta i totali in testata
 | 
						||
  if (is_fattura())
 | 
						||
  {                              
 | 
						||
    real tot(m.get(F_TOTALE)); tot -= imposte;
 | 
						||
    m.set(FS_IMPONIBILI, tot);
 | 
						||
    m.set(FS_IMPOSTE, imposte);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return imponibili+imposte;
 | 
						||
}
 | 
						||
                 
 | 
						||
// Elimina dallo sheet le righe iva senza importi (imponibile e imposta)
 | 
						||
// Certified 99%
 | 
						||
void TPrimanota_application::ivas_pack()
 | 
						||
{
 | 
						||
  TString_array& rows = ivas().rows_array();
 | 
						||
  
 | 
						||
  const int max = rows.items();
 | 
						||
  for (int i = 0; i < max; i++)
 | 
						||
  {
 | 
						||
    TToken_string& r = rows.row(i);
 | 
						||
    const real imponibile(r.get(0));
 | 
						||
    if (imponibile != ZERO) continue;
 | 
						||
    const real imposta(r.get(3));
 | 
						||
    if (imposta != ZERO) continue;
 | 
						||
    rows.destroy(i, false);
 | 
						||
  }
 | 
						||
 | 
						||
  rows.pack();           // Pack array
 | 
						||
}
 | 
						||
 | 
						||
int TPrimanota_application::get_importi_iva(const TToken_string& row, 
 | 
						||
                                             real& imp_det, real& iva_det,
 | 
						||
                                             real& imp_ind, real& iva_ind)
 | 
						||
{
 | 
						||
  real imptot;       row.get(0, imptot);   // Importo scritto nella riga iva
 | 
						||
  TString4 zanicchi; row.get(1, zanicchi); // Codice IVA
 | 
						||
  TString4 codind;   row.get(2, codind);   // Codice indetraibilita'
 | 
						||
  real ivatot;       row.get(3, ivatot);   // Imposta scritta nella riga iva
 | 
						||
 | 
						||
  int annodoc = app()._msk[2]->get_date(F_DATADOC).year();
 | 
						||
  if (annodoc <= 0)
 | 
						||
  {
 | 
						||
    annodoc = app()._msk[2]->get_date(F_DATAREG).year();
 | 
						||
    if (annodoc <= 0)
 | 
						||
      annodoc = TDate(TODAY).year();
 | 
						||
  }
 | 
						||
 | 
						||
  const TCausale& caus = app().causale();
 | 
						||
  const TMovimentoPN& mov = (const TMovimentoPN&)*app().get_relation();
 | 
						||
  return mov.analizza_riga_IVA(imptot, ivatot, caus, annodoc, zanicchi, codind,
 | 
						||
                               imp_det, iva_det, imp_ind, iva_ind);
 | 
						||
}
 | 
						||
 | 
						||
// Certified 50%
 | 
						||
bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k)
 | 
						||
{
 | 
						||
  static int oldpos[2],oldposiva[2];
 | 
						||
  static TImporto oldimp[2], oldiva[2];
 | 
						||
  static bool selecting = false;
 | 
						||
 | 
						||
  TPrimanota_application& a = app();
 | 
						||
  if (a._as400) 
 | 
						||
    return true;
 | 
						||
                
 | 
						||
  if (k == K_INS || k == K_CTRL+K_DEL)              
 | 
						||
    return true;
 | 
						||
                
 | 
						||
  TToken_string& row = iva.row(r);
 | 
						||
  const TCausale& cau = a.causale();
 | 
						||
 | 
						||
  if (k == K_TAB)
 | 
						||
  {
 | 
						||
    if (!selecting && row.empty_items())
 | 
						||
    {
 | 
						||
      selecting = true;
 | 
						||
      iva.select(r, 1);      // Vado alla prima colonna delle righe vuote
 | 
						||
      selecting = false;
 | 
						||
 | 
						||
    }
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {                     
 | 
						||
    real imp_det, iva_det, imp_ind, iva_ind;
 | 
						||
    get_importi_iva(row, imp_det, iva_det, imp_ind, iva_ind);
 | 
						||
    for (int d = 0; d < 2; d++)
 | 
						||
    {
 | 
						||
      const char tipod = d ? 'D' : 'N';
 | 
						||
      oldimp[d] = a.real2imp(d ? imp_det : imp_ind, 'I');   // Imponibile
 | 
						||
      oldiva[d] = a.real2imp(d ? iva_det : iva_ind, tipod); // Imposta
 | 
						||
      oldposiva[d] = type2pos(tipod);                                      
 | 
						||
      if (oldposiva[d] < 0 && !oldiva[d].is_zero())
 | 
						||
      {
 | 
						||
        TBill c; 
 | 
						||
				int ri;
 | 
						||
 | 
						||
				if (d)
 | 
						||
				{	
 | 
						||
					if (iva.mask().get_bool(F_LIQDIFF))
 | 
						||
						cau.bill(ri = RIGA_IVA_DIFFERITA, c); 
 | 
						||
					if (!c.ok())
 | 
						||
						cau.bill(ri = RIGA_IVA_DETRAIBILE, c); 
 | 
						||
				}
 | 
						||
				else
 | 
						||
					cau.bill(ri = RIGA_IVA_NON_DETRAIBILE, c); 
 | 
						||
        if (c.ok())
 | 
						||
        {
 | 
						||
          const TString80 desc(cau.desc_agg(ri));
 | 
						||
          oldposiva[d] = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), c, desc, tipod);     
 | 
						||
        }  
 | 
						||
      }
 | 
						||
    
 | 
						||
      TBill oldconto(row, 6);
 | 
						||
      if (oldconto.ok())
 | 
						||
      {
 | 
						||
        oldpos[d] = bill2pos(oldconto, 'I');
 | 
						||
        if (oldpos[d] < 0)
 | 
						||
        {                      
 | 
						||
          const TString desc(cau.desc_agg(2));
 | 
						||
          oldpos[d] = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), oldconto, desc, 'I');
 | 
						||
        }  
 | 
						||
      } 
 | 
						||
      else 
 | 
						||
        oldpos[d] = -1;                             // Se il conto e' incompleto ignoralo
 | 
						||
    }  
 | 
						||
    
 | 
						||
  }
 | 
						||
  if (k == K_DEL)                              // Cancellazione di una riga
 | 
						||
  {
 | 
						||
    row.add("0", 0);                           // Azzera imponibile
 | 
						||
    row.add("0", 3);                           // Azzera imposta
 | 
						||
    k = K_ENTER;                               // Elegante o Sporco trucco (dipende dai gusti!)
 | 
						||
  }
 | 
						||
  if (k == K_ENTER)
 | 
						||
  {  
 | 
						||
    real imp_det, iva_det, imp_ind, iva_ind;
 | 
						||
    get_importi_iva(row, imp_det, iva_det, imp_ind, iva_ind);
 | 
						||
    for (int d = 0; d < 2; d++)
 | 
						||
    {
 | 
						||
      const real imponibile = d ? imp_det : imp_ind;
 | 
						||
      const real imposta    = d ? iva_det : iva_ind;
 | 
						||
 | 
						||
      int delimp = -1, deliva = -1;              // Eventuali righe contabili da cancellare
 | 
						||
      if (oldpos[d] >= 0)                        // Se il conto esisteva anche prima ...
 | 
						||
      {                                          // sottrai il vecchio imponibile
 | 
						||
        TImporto i(a.get_cgs_imp(oldpos[d]));
 | 
						||
        i -= oldimp[d]; 
 | 
						||
        i.normalize();
 | 
						||
        a.set_cgs_imp(oldpos[d], i);
 | 
						||
        if (i.is_zero()) 
 | 
						||
          delimp = oldpos[d];
 | 
						||
      } 
 | 
						||
      if (oldposiva[d] >= 0)                     // Se conto IVA esisteva anche prima ...
 | 
						||
      {                                          // sottrai la vecchia imposta
 | 
						||
        TImporto i(a.get_cgs_imp(oldposiva[d]));
 | 
						||
        i -= oldiva[d];
 | 
						||
        i.normalize();
 | 
						||
        a.set_cgs_imp(oldposiva[d], i);
 | 
						||
        if (i.is_zero()) 
 | 
						||
          deliva = oldposiva[d];
 | 
						||
      }
 | 
						||
 | 
						||
   
 | 
						||
      TBill conto(row, 6);
 | 
						||
      int newpos = bill2pos(conto, 'I');  // Riga in cui andra' l'imponibile
 | 
						||
       
 | 
						||
      TImporto newimp = a.real2imp(imponibile, 'I');
 | 
						||
      newimp.normalize();
 | 
						||
    
 | 
						||
    // Aggiorna conto sulla riga contabile
 | 
						||
      if (newpos < 0)
 | 
						||
      {
 | 
						||
        TString saved_descr;
 | 
						||
        if (delimp >= 0)       
 | 
						||
        {
 | 
						||
          TSheet_field& s = a.cgs();
 | 
						||
          saved_descr = s.row(delimp).get(8);      // Memorizza vecchia descrizione
 | 
						||
          a.reset_cgs_row(delimp);                 // Cancella vecchia riga
 | 
						||
          if (deliva > delimp) deliva--;
 | 
						||
        }  
 | 
						||
 | 
						||
        if (conto.ok() && !newimp.is_zero())        // Se c'e' imponibile ...
 | 
						||
        {                                           // crea una nuova riga contabile
 | 
						||
          if (saved_descr.blank())
 | 
						||
            saved_descr = cau.desc_agg(2);
 | 
						||
          newpos = a.set_cgs_row(-1, newimp, conto, saved_descr, 'I');
 | 
						||
        }  
 | 
						||
      }  
 | 
						||
      else
 | 
						||
 | 
						||
      {
 | 
						||
        const bool empty = a.add_cgs_imp(newpos, newimp);
 | 
						||
        if (empty)                               // Se la riga si e' azzerata ...
 | 
						||
        {                                        // ... cancellala
 | 
						||
          a.reset_cgs_row(newpos);
 | 
						||
          newpos = -1;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (delimp >= 0 && delimp != newpos)       
 | 
						||
          {
 | 
						||
            a.reset_cgs_row(delimp);           // Cancella vecchia riga
 | 
						||
            if (deliva > delimp) deliva--;
 | 
						||
          }  
 | 
						||
        }
 | 
						||
      }  
 | 
						||
      oldimp[d] = newimp; 
 | 
						||
      oldpos[d] = newpos;
 | 
						||
    
 | 
						||
      // Aggiorna conto IVA sulla riga contabile
 | 
						||
 | 
						||
      const char tipod = d ? 'D' : 'N';
 | 
						||
      int newposiva = type2pos(tipod);
 | 
						||
      if (deliva >= 0 && newposiva != deliva)                 // E' cambiato il tipo d'imposta
 | 
						||
        a.reset_cgs_row(deliva);                              // Azzera il vecchio tipo se necessario
 | 
						||
    
 | 
						||
      TImporto newiva = a.real2imp(imposta, 'I');
 | 
						||
    
 | 
						||
      newiva.normalize();
 | 
						||
      if (newposiva < 0)
 | 
						||
      {                                          
 | 
						||
        if (!imposta.is_zero())                               // Se  c'e' imposta ...
 | 
						||
        {                                                     // ... crea nuova riga per l'IVA
 | 
						||
					TBill contoiva; 
 | 
						||
					int ri;
 | 
						||
 | 
						||
					if (d)
 | 
						||
					{	
 | 
						||
						if (iva.mask().get_bool(F_LIQDIFF))
 | 
						||
							cau.bill(ri = RIGA_IVA_DIFFERITA, contoiva); 
 | 
						||
						if (!contoiva.ok())
 | 
						||
							cau.bill(ri = RIGA_IVA_DETRAIBILE, contoiva); 
 | 
						||
					}
 | 
						||
					else
 | 
						||
						cau.bill(ri = RIGA_IVA_NON_DETRAIBILE, contoiva); 
 | 
						||
	        
 | 
						||
						const TString desc(cau.desc_agg(ri));     
 | 
						||
						cau.bill(ri, contoiva);
 | 
						||
						newposiva = a.set_cgs_row(-1, newiva, contoiva, desc, tipod);
 | 
						||
				}  
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        const bool empty = a.add_cgs_imp(newposiva, newiva);
 | 
						||
        if (empty)                                    // Se l'imposta si e' azzerata ...
 | 
						||
        {
 | 
						||
          a.reset_cgs_row(newposiva);                 // ... cancellala
 | 
						||
          newposiva = -1;
 | 
						||
        }  
 | 
						||
      }
 | 
						||
 | 
						||
      oldiva[d]    = newiva;         
 | 
						||
      oldposiva[d] = newposiva;   
 | 
						||
  
 | 
						||
    }  // for (int d = 0; d < 2; d++)
 | 
						||
    
 | 
						||
    TMask& m = a.curr_mask();                                   
 | 
						||
    if (r == 0)                             // Se cambio la prima riga ...
 | 
						||
    {
 | 
						||
      a.add_cgs_tot(m);                     // ... ricalcola conti e imponibili
 | 
						||
    }  
 | 
						||
    else
 | 
						||
    {                                                                 
 | 
						||
      a.calcola_saldo();                    // Calcola sbilancio
 | 
						||
      a.calcola_imp();                      // Calcola imponibili
 | 
						||
    }
 | 
						||
  
 | 
						||
    if (m.insert_mode() && a.is_fattura())
 | 
						||
    {          
 | 
						||
      TPagamento& pag = a.pagamento();                         
 | 
						||
      const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
 | 
						||
      const bool inv = cambio.in_valuta();
 | 
						||
      real imposta, imponibile;              
 | 
						||
      if (inv)
 | 
						||
      {         
 | 
						||
        const real il(m.get(F_IMPOSTE));
 | 
						||
        imposta = cambio.lit2val(il);
 | 
						||
        imponibile = m.get_real(SK_TOTDOCVAL) - imposta;   
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        imposta = m.get_real(F_IMPOSTE);   
 | 
						||
        imponibile = m.get_real(F_TOTALE) - imposta;   
 | 
						||
      }
 | 
						||
      imposta.round(pag.round(inv)); imponibile.round(pag.round(inv));
 | 
						||
      real pimposta(pag.imposta(inv)); real pimponibile(pag.imponibile(inv));
 | 
						||
      pimposta.round(pag.round(inv)); pimponibile.round(pag.round(inv));
 | 
						||
    
 | 
						||
      if (pimposta != imposta || pimponibile != imponibile) 
 | 
						||
        a.set_scadenze(m);                // Ricalcola rate 
 | 
						||
    }
 | 
						||
 | 
						||
  }                                                         
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler dello sheet
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::iva_handler(TMask_field& f, KEY k)
 | 
						||
{  
 | 
						||
  if ((k == K_TAB && !f.mask().is_running()) || k == K_ENTER)
 | 
						||
  {
 | 
						||
    const TCurrency imp(app().calcola_imp());
 | 
						||
    if (k == K_ENTER)
 | 
						||
    {
 | 
						||
      const TCurrency tot(app().totale_documento());
 | 
						||
      if (imp != tot)
 | 
						||
      {
 | 
						||
        const TString t(tot.string(true));
 | 
						||
        const TString i(imp.string(true));
 | 
						||
        return error_box(FR("La somma del totale documento e delle ritenute (%s) e' diverso dalla " 
 | 
						||
                         "somma degli imponibili e delle imposte (%s)"), 
 | 
						||
                         (const char*)t, (const char*)i);
 | 
						||
      }  
 | 
						||
 | 
						||
      TSheet_field& iva = app().ivas();
 | 
						||
      for (int i = 0; i < iva.items(); i++)
 | 
						||
      {
 | 
						||
        TToken_string& row = iva.row(i);
 | 
						||
        const real im(row.get(0)); 
 | 
						||
        if (!im.is_zero())
 | 
						||
        {                            
 | 
						||
          const TFixed_string codiva = row.get(1);
 | 
						||
          if (codiva.blank())
 | 
						||
            return error_box(FR("Il codice IVA della riga %d e' obbligatorio"), i+1);
 | 
						||
        
 | 
						||
          TBill c(row, 5, 0x1);
 | 
						||
          if (!c.ok() || !c.find()) 
 | 
						||
            return error_box(FR("Il conto della riga iva %d e' errato o incompleto"), i+1);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Il gruppo non possiede una ricerca propria per cui se viene variato richiama
 | 
						||
// quella del conto.
 | 
						||
bool TPrimanota_application::cg_gruppo_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
  {
 | 
						||
    TEdit_field& conto = f.mask().efield(f.dlg()+1);
 | 
						||
    const TRectype& curr = conto.browse()->cursor()->curr();
 | 
						||
    if (curr.get(RMV_GRUPPO) != f.get()) // Se non e' gia' posizionato ...
 | 
						||
      conto.check(RUNNING_CHECK);        // ... forza ricerca sul conto
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::cg_conto_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  
 | 
						||
  if (key == K_ENTER)
 | 
						||
  {                          
 | 
						||
    TMask& m = f.mask();
 | 
						||
    if (m.get(CG_ROWTYPE)[0] == 'T' && !app().causale().corrispettivi())  
 | 
						||
    {
 | 
						||
      const char tipo = app().clifo();        // Tipo conto richiesto dal movimento
 | 
						||
      char cf = m.get(f.dlg()-2)[0]; 
 | 
						||
      if (cf < ' ') cf = ' ';                 // Tipo conto della riga
 | 
						||
      if (cf != tipo)                         // Incongruenza!
 | 
						||
      {
 | 
						||
        const char* d = tipo == 'C' ? TR("clienti") : TR("fornitori");
 | 
						||
        ok = f.error_box(FR("La riga totale richiede un conto %s."), d);
 | 
						||
      }                   
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Gestore del sottoconto dello sheet IVA
 | 
						||
// Attenzione questo handler e' agganciato anche alla descrizione del sottoconto
 | 
						||
bool TPrimanota_application::iva_sottoconto_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (!suspended_handler(f, key))
 | 
						||
    return false;
 | 
						||
 | 
						||
  TMask& m = f.mask();
 | 
						||
 | 
						||
  if (key == K_TAB && f.dirty())
 | 
						||
  {                                          
 | 
						||
    const TEdit_field& e = (const TEdit_field&)f;        
 | 
						||
    const TRectype& piano = e.browse()->cursor()->curr();
 | 
						||
    int spric = piano.get_int(PCN_TIPOSPRIC);
 | 
						||
    
 | 
						||
    if (app().iva() == iva_vendite)
 | 
						||
    {
 | 
						||
      if (spric == 2 || spric == 3)
 | 
						||
      {
 | 
						||
        const TCausale& caus = app().causale();
 | 
						||
        const TString& td = caus.tipo_doc();
 | 
						||
        if (td == "FV" || td == "NC" || td == "ND") 
 | 
						||
          spric = 4;
 | 
						||
      }                         
 | 
						||
    }
 | 
						||
    TString16 s; if (spric > 0) s << spric;
 | 
						||
    m.set(105, s, true);       // Setta il campo spesa-ricavo della riga IVA
 | 
						||
  }
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::cg_sottoconto_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (!suspended_handler(f, k))
 | 
						||
    return false;
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::sheet_clifo_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (!suspended_handler(f, k))
 | 
						||
    return false;
 | 
						||
  
 | 
						||
  if (k == K_TAB || k == K_ENTER)
 | 
						||
  {
 | 
						||
    const long codice = atol(f.get());
 | 
						||
    if (codice > 0L)
 | 
						||
    {
 | 
						||
      TMask& m = f.mask();
 | 
						||
      const short cid  = 100 + (f.dlg() % 100) -1;
 | 
						||
      const short gid  = cid-1;
 | 
						||
      const int conto  = m.get_int(cid);
 | 
						||
      const int gruppo = m.get_int(gid);
 | 
						||
      if ((k == K_TAB && f.focusdirty()) || (gruppo == 0 && conto == 0))
 | 
						||
      {
 | 
						||
        TBill c(0, 0, codice, f.dlg() > 300 ? 'F' : 'C');
 | 
						||
        c.find(); // Carica gruppo e conto
 | 
						||
        if (c.ok()) 
 | 
						||
        {
 | 
						||
          m.set(gid-1, c.tipo() == 'C' ? "C" : "F");
 | 
						||
          m.set(gid, c.gruppo());
 | 
						||
          m.set(cid, c.conto());
 | 
						||
        }           
 | 
						||
      } 
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
void TPrimanota_application::link_mastrino(const TBill& bill) const
 | 
						||
{
 | 
						||
  if (bill.ok())
 | 
						||
  {
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    const TMask& cm = a.curr_mask();
 | 
						||
 | 
						||
    int anno = cm.get_int(F_ANNOES);
 | 
						||
    if (anno <= 0)
 | 
						||
    {
 | 
						||
      TDate date = cm.get(F_DATACOMP);
 | 
						||
      if (!date.ok())
 | 
						||
      {
 | 
						||
        date = cm.get_date(F_DATAREG);
 | 
						||
        if (!date.ok())
 | 
						||
          date = TDate(TODAY);
 | 
						||
      }
 | 
						||
      anno = a._esercizi.date2esc(date);
 | 
						||
    }
 | 
						||
 | 
						||
    TFilename ininame; ininame.tempdir(); ininame.add("mastrino.ini");
 | 
						||
    if (anno > 0)
 | 
						||
    {
 | 
						||
      TConfig ini(ininame, "Transaction");
 | 
						||
      ini.set("Action", "Modify");
 | 
						||
      ini.set_paragraph("24");
 | 
						||
      ini.set(RMV_ANNOES, anno);
 | 
						||
      const char tipo[2] = { bill.tipo(), '\0' };
 | 
						||
      ini.set(RMV_TIPOC,  tipo); // Non esiste la TConfig::set(const char* name, char value);
 | 
						||
      ini.set(RMV_GRUPPO, bill.gruppo());
 | 
						||
      ini.set(RMV_CONTO,  bill.conto());
 | 
						||
      ini.set(RMV_SOTTOCONTO, bill.sottoconto());
 | 
						||
    }
 | 
						||
    if (ininame.exist())
 | 
						||
    {
 | 
						||
      TString cmd;
 | 
						||
      cmd << "cg3 -5 -i" << ininame;
 | 
						||
      TExternal_app app(cmd);
 | 
						||
      app.run();
 | 
						||
      ininame.fremove();
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::mastrino_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    const TMask& m = f.mask();
 | 
						||
    TBill bill; bill.get(m, F_GRUPPO, F_CONTO, F_SOTTOCONTO);
 | 
						||
    app().link_mastrino(bill);
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::sheet_mastrino_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    const TMask& m = f.mask();
 | 
						||
    const char tipo = m.get(CG_TIPO)[0];
 | 
						||
    const short id_sotto = CG_SOTTOCONTO + (tipo <= ' ' ? 0 : (tipo == 'C' ? 100 : 200));
 | 
						||
    TBill bill; bill.get(m, CG_GRUPPO, CG_CONTO, id_sotto, CG_TIPO);
 | 
						||
    app().link_mastrino(bill);
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Handlers dei campi della testata
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
// Handler of the F_NUMREG field on the query mask
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::num_handler(TMask_field& f, KEY key)
 | 
						||
{                       
 | 
						||
  if (key == K_TAB && f.to_check(key, true))
 | 
						||
  {                    
 | 
						||
    TMask& m = f.mask();
 | 
						||
    TPrimanota_application& a = app();    
 | 
						||
 | 
						||
    if (a.autodeleting() == 0x3)
 | 
						||
      return true; // Non effettuare controlli inutili in cancellazione
 | 
						||
    
 | 
						||
    a._skip_giornale_check = false;
 | 
						||
    a._skip_bollato_check  = false;
 | 
						||
                 
 | 
						||
    const TRectype& mov = cache().get(LF_MOV, f.get());             
 | 
						||
    if (!mov.empty())
 | 
						||
    {
 | 
						||
      bool ok = true;
 | 
						||
        
 | 
						||
      if (mov.get_bool(MOV_STAMPATO))
 | 
						||
      {
 | 
						||
        ok = f.yesno_box(TR("Il movimento e' gia' stato stampato sul libro giornale:\n"
 | 
						||
                         "si desidera continuare ugualmente?"));
 | 
						||
        a._skip_giornale_check = ok;              
 | 
						||
      }                
 | 
						||
        
 | 
						||
      if (ok && mov.get_bool(MOV_REGST))
 | 
						||
      {
 | 
						||
        ok = f.yesno_box(TR("Il movimento e' gia' stato stampato sul bollato:\n"
 | 
						||
                         "si desidera continuare ugualmente?"));
 | 
						||
        a._skip_bollato_check = ok;                            
 | 
						||
      }
 | 
						||
        
 | 
						||
      if (ok && mov.get_bool(MOV_INVIATO))
 | 
						||
      {                  
 | 
						||
        ok = f.yesno_box(TR("Il movimento e' stato inviato ad un'altra contabilita':\n"
 | 
						||
                         "si desidera continuare ugualmente?"));
 | 
						||
      }
 | 
						||
        
 | 
						||
      if (ok)    
 | 
						||
      {          
 | 
						||
        // Riempie a mano i campi necessari nel caso non sia stato usata la ricerca F9
 | 
						||
        m.set(F_DATAREG,  mov.get(MOV_DATAREG), true);     
 | 
						||
        m.set(F_CODCAUS,  mov.get(MOV_CODCAUS));
 | 
						||
 | 
						||
        f.set_focusdirty(false);
 | 
						||
        ok = m.stop_run(K_AUTO_ENTER);
 | 
						||
      }  
 | 
						||
      else
 | 
						||
      {
 | 
						||
        m.reset(F_NUMREG);
 | 
						||
        if (a.lnflag())
 | 
						||
          m.stop_run(K_FORCE_CLOSE);
 | 
						||
      }
 | 
						||
      return ok;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of the F_CODCAUS field on the query mask
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::caus_query_handler(TMask_field& f, KEY key)
 | 
						||
{                  
 | 
						||
  const TMask& m = f.mask();
 | 
						||
  if (!m.is_running()) 
 | 
						||
    return true;
 | 
						||
 | 
						||
  if (f.to_check(key))
 | 
						||
  {
 | 
						||
    const TString& cau = f.get();
 | 
						||
    const int ann = m.get_int(F_ANNOIVA);
 | 
						||
    
 | 
						||
    const TipoIVA i = app().cau2IVA(cau, ann);    // Cerca causale e suo tipo
 | 
						||
    if (i != iva_errata)
 | 
						||
      return suspended_handler(f, key);  // Controlla sospensione
 | 
						||
    else 
 | 
						||
      return error_box(TR("Causale non presente in archivio"));
 | 
						||
  } 
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_CODCAUS field on the modify mask
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::caus_modify_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (f.to_check(key))
 | 
						||
  {
 | 
						||
    if (!suspended_handler(f, key)) 
 | 
						||
      return false;
 | 
						||
 | 
						||
 | 
						||
    TMask& m = f.mask();
 | 
						||
 | 
						||
    const int ann = m.get_int(F_ANNOIVA);
 | 
						||
    const TString& cau = f.get();
 | 
						||
 | 
						||
    const TCausale c(cau, ann);
 | 
						||
    if (!c.ok())
 | 
						||
        return false;
 | 
						||
 
 | 
						||
		const TCausale& k = app().causale();
 | 
						||
    const TString& msg = c.compatible(k);
 | 
						||
    if (msg.not_empty())  // La causale non e' compatibile
 | 
						||
    {
 | 
						||
      if (m.insert_mode() && !app()._sal_dirty)
 | 
						||
      {
 | 
						||
        // Cambio la maschera al volo
 | 
						||
        if (app().force_mask_swap(k, c))
 | 
						||
				{
 | 
						||
					TString4 provv;
 | 
						||
 | 
						||
					provv << c.provvisorio();
 | 
						||
					m.set(F_PROVVISORIO, provv);
 | 
						||
					if (c.iva() != nessuna_iva && m.id2pos(F_SOLAIVA) > 0)
 | 
						||
					m.set(F_SOLAIVA, c.soloiva() ? "X" : " ");
 | 
						||
          return true;
 | 
						||
				}
 | 
						||
      }
 | 
						||
      return error_box(msg);
 | 
						||
    }
 | 
						||
 | 
						||
    if (key == K_TAB)
 | 
						||
    {
 | 
						||
      app().read_caus(cau, ann);
 | 
						||
      app().cgs().force_update();
 | 
						||
			
 | 
						||
			TString4 provv;
 | 
						||
 | 
						||
			provv << c.provvisorio();
 | 
						||
			m.set(F_PROVVISORIO, provv);
 | 
						||
			if (c.iva() != nessuna_iva)
 | 
						||
				m.set(F_SOLAIVA, c.soloiva() ? "X" : " ");
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of the F_DATAREG field
 | 
						||
// Certified 70%
 | 
						||
bool TPrimanota_application::datareg_handler(TMask_field& f, KEY key)
 | 
						||
{                           
 | 
						||
  bool ok = true;
 | 
						||
  TMask& m = f.mask();  
 | 
						||
  
 | 
						||
  //if ((key == K_TAB && m.is_running() ) || key == K_ENTER)
 | 
						||
  if (key == K_TAB && f.focusdirty() || key == K_ENTER)
 | 
						||
  {            
 | 
						||
    const TDate dr(f.get());                         // Data dell'operazione
 | 
						||
    if (dr > TDate(TODAY))
 | 
						||
      return f.error_box(TR("La data dell'operazione e' superiore quella di sistema"));
 | 
						||
    
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    
 | 
						||
    const int ae = a._esercizi.date2esc(dr);     // Codice esercizio
 | 
						||
    if (ae <= 0) 
 | 
						||
      return f.error_box(TR("La data dell'operazione non appartiene a nessun esercizio"));
 | 
						||
 | 
						||
    TLibro_giornale& gio = a.giornale();                                                 
 | 
						||
    const int ar = dr.year();                    // Anno per registri
 | 
						||
    if (m.query_mode() || gio.year() != ar)
 | 
						||
    {
 | 
						||
      ok = gio.read(ar);
 | 
						||
      if (!ok) 
 | 
						||
        return f.error_box(FR("Non esiste il libro giornale del %d"), ar);
 | 
						||
    }  
 | 
						||
    else
 | 
						||
      ok = true;
 | 
						||
    
 | 
						||
    if (key == K_ENTER || f.focusdirty())
 | 
						||
    {               
 | 
						||
      const long numreg = m.get_long(F_NUMREG);
 | 
						||
      const bool error = numreg == 0 || numreg > a._lastreg; 
 | 
						||
      
 | 
						||
      if (key != K_ENTER && !a._skip_giornale_check)
 | 
						||
      {    
 | 
						||
        if (dr < gio.last_print())
 | 
						||
        {
 | 
						||
          f.error_box(FR("La data dell'operazione e' antecedente al %s,\n"
 | 
						||
                      "ultima stampa del libro giornale del %d"), 
 | 
						||
                      gio.last_print().string(), ar);
 | 
						||
          if (error) return false;           
 | 
						||
        }              
 | 
						||
        if (key == K_TAB && dr < gio.last_reg())                
 | 
						||
          f.warning_box(FR("La data dell'operazione e' antecedente al %s,\n"
 | 
						||
                        "ultima registrazione sul libro giornale del %d"), 
 | 
						||
                        gio.last_reg().string(), ar);
 | 
						||
      }
 | 
						||
      
 | 
						||
      if (m.query_mode())
 | 
						||
        a.read_caus(m.get(F_CODCAUS), ar);
 | 
						||
      
 | 
						||
      TRegistro& reg = a.causale().reg();                       
 | 
						||
      const TString codreg(reg.name());
 | 
						||
      if (codreg.not_empty())
 | 
						||
      {
 | 
						||
        if (reg.year() != ar)
 | 
						||
        {
 | 
						||
          const bool ok = reg.read(codreg, ar);
 | 
						||
          if (!ok) return false;
 | 
						||
          a.read_caus(NULL, 0);
 | 
						||
          if (a.iva() != nessuna_iva)
 | 
						||
            m.field(F_CODREG).on_hit();
 | 
						||
        }  
 | 
						||
        
 | 
						||
        if (!a._skip_bollato_check)
 | 
						||
        {  
 | 
						||
          if (dr < reg.last_print()) 
 | 
						||
          {
 | 
						||
            f.error_box(FR("La data dell'operazione e' antecedente al %s,\n"
 | 
						||
                        "ultima stampa del registro '%s' del %d"), 
 | 
						||
                        reg.last_print().string(), (const char*)codreg, ar);
 | 
						||
            if (error) return false;           
 | 
						||
          }              
 | 
						||
          if (f.dirty() && dr < reg.last_reg()) 
 | 
						||
            f.warning_box(FR("La data dell'operazione e' antecedente al %s,\n"
 | 
						||
                          "ultima registrazione sul registro '%s' del %d"),
 | 
						||
                          reg.last_reg().string(), (const char*)codreg, ar);
 | 
						||
        }
 | 
						||
        
 | 
						||
        if (reg.iva() != nessuna_iva && a._rel->controlla_liquidazione(dr, reg) == true)
 | 
						||
        {
 | 
						||
          const char* const mese = itom(dr.month());
 | 
						||
          f.warning_box(FR("La liquidazione IVA relativa al mese di %s e' gia' stata calcolata"), mese);
 | 
						||
        }
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_DATACOMP field on the modify mask
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::datacomp_handler(TMask_field& f, KEY key)
 | 
						||
{                          
 | 
						||
  TMask& m = f.mask();      
 | 
						||
 | 
						||
  if (key == K_TAB || key == K_ENTER)
 | 
						||
  {
 | 
						||
    const TDate dr(m.get(F_DATAREG));      // Data operazione
 | 
						||
    
 | 
						||
    TString16 datacomp = f.get();
 | 
						||
    if (datacomp.empty())
 | 
						||
    {
 | 
						||
      datacomp = dr.string();
 | 
						||
      // DATACOMP new way
 | 
						||
      if (key == K_ENTER)
 | 
						||
        f.set(datacomp);
 | 
						||
    }
 | 
						||
    const TDate dc(datacomp);                          // Data di competenza
 | 
						||
    TEsercizi_contabili& esc = app()._esercizi;
 | 
						||
    const int ae = esc.date2esc(dc);                   // Esercizio corrispondente
 | 
						||
    
 | 
						||
    const char* data = TR("La data del 74/ter");
 | 
						||
    if (f.dlg() == F_DATACOMP)
 | 
						||
    {
 | 
						||
      m.set(F_ANNOES, ae, true);                       // Aggiorna anno esercizio in entrambe le pagine
 | 
						||
      data = TR("La data di competenza");
 | 
						||
 | 
						||
      if (dc > dr)
 | 
						||
      {  
 | 
						||
        bool ok = false;
 | 
						||
        const TString& ca = m.get(F_CODCAUS);
 | 
						||
        if (ca.not_empty())  // Controlla ratei e risconti
 | 
						||
        {
 | 
						||
          TConfig ini(CONFIG_DITTA, "cg");
 | 
						||
          const TString& ra = ini.get("RrCcRa");
 | 
						||
          const TString& ri = ini.get("RrCcRi");
 | 
						||
          ok = (ca == ra) || (ca == ri);
 | 
						||
        }
 | 
						||
        if (!ok)
 | 
						||
          return f.error_box(TR("La data di competenza non puo' superare la data di registrazione"));
 | 
						||
      }
 | 
						||
    }  
 | 
						||
    
 | 
						||
    if (ae)
 | 
						||
    {                     
 | 
						||
      const int ar = esc.date2esc(dr);        // Esercizio in corso
 | 
						||
      const int pr = esc.pred(ar);            // Esercizio precedente
 | 
						||
      if (ae != ar && ae != pr)
 | 
						||
      {
 | 
						||
        TString e(80); 
 | 
						||
        e.format(FR("%s deve appartenere all'esercizio %d"), data, ar); 
 | 
						||
        if (pr > 0) e << TR(" o all'esercizio ") << pr;
 | 
						||
        return f.error_box(e);
 | 
						||
      }
 | 
						||
    }  
 | 
						||
    else  
 | 
						||
    {
 | 
						||
      if (m.is_running())
 | 
						||
        return f.error_box(FR("%s non appartiene a nessun esercizio"), data);
 | 
						||
    }  
 | 
						||
  }    
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_DATA74TER field on the modify mask
 | 
						||
// Certified 90%
 | 
						||
bool TPrimanota_application::data74ter_handler(TMask_field& f, KEY key)
 | 
						||
{                          
 | 
						||
  if (!f.to_check(key)) 
 | 
						||
    return true;
 | 
						||
 | 
						||
  const TDate dr(f.mask().get(F_DATAREG)); // Data operazione
 | 
						||
  const TDate d74(f.get());                // Data 74/ter
 | 
						||
  if (d74 > dr)
 | 
						||
    return true;
 | 
						||
 | 
						||
  if (d74.year() < dr.year()-1) 
 | 
						||
    return error_box(FR("La data 74/ter non puo' essere antecedente all'anno %d"), dr.year()-1);
 | 
						||
    
 | 
						||
  const TLibro_giornale g(d74.year());
 | 
						||
  if (!g.ok())
 | 
						||
    return error_box(TR("La data 74/ter non appartiene ad un esercizio valido"));
 | 
						||
    
 | 
						||
  if (d74 < g.last_print())
 | 
						||
  {
 | 
						||
    const char* lp = g.last_print().string();
 | 
						||
    return f.error_box(FR("La data 74/ter e' antecedente al %s,\n"
 | 
						||
                       "data di stampa del libro giornale del %d"), lp, g.year());
 | 
						||
  }
 | 
						||
  return true; 
 | 
						||
}   
 | 
						||
 | 
						||
bool TPrimanota_application::numdoc_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (f.to_check(key, true))
 | 
						||
  {
 | 
						||
    TMask& m = f.mask();
 | 
						||
    if (key == K_TAB && m.insert_mode() && app().is_saldaconto())
 | 
						||
    {
 | 
						||
      if (!f.empty() && !app().npart_is_prot()) // Copiare numero documento nel numero partita?
 | 
						||
      { 
 | 
						||
        if (m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank())
 | 
						||
          m.set(F_NUMRIF, f.get(), true);             
 | 
						||
      }  
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  // Controllo documenti duplicati 
 | 
						||
  if (key == K_ENTER  && !f.empty() && app().iva() == iva_acquisti)
 | 
						||
  {
 | 
						||
    TMask& m = f.mask();
 | 
						||
 | 
						||
    const int annodoc = m.get_date(F_DATADOC).year();
 | 
						||
    const long fornitore = m.get_long(F_FORNITORE);
 | 
						||
    if (annodoc > 0 && fornitore > 0)
 | 
						||
    {
 | 
						||
      // SELECT NUMREG,DATAREG,DATADOC,NUMDOC FROM MOV 
 | 
						||
      // WHERE TIPO='F' AND CODCF=F_FORNITORE AND 
 | 
						||
      // NUMDOC=F_NUMDOC AND DATAREG>=F_DATADOC AND NUMREG<>F_NUMREG
 | 
						||
      
 | 
						||
      TString filter;
 | 
						||
      filter << MOV_NUMDOC << "=\"" << f.get() << '"';
 | 
						||
      if (m.edit_mode())              
 | 
						||
      {
 | 
						||
        filter.insert("(");
 | 
						||
        filter << ")&&(" << MOV_NUMREG << "!=\"" << m.get(F_NUMREG) << "\")";
 | 
						||
      }
 | 
						||
          
 | 
						||
      TRelation rel(LF_MOV);
 | 
						||
      TRectype& rec = rel.curr();
 | 
						||
        
 | 
						||
      TRectype recfrom(rec);
 | 
						||
      recfrom.put(MOV_TIPO, "F");
 | 
						||
      recfrom.put(MOV_CODCF, fornitore);
 | 
						||
      recfrom.put(MOV_DATAREG, TDate(1, 1, annodoc));
 | 
						||
  
 | 
						||
      TRectype recto(recfrom);
 | 
						||
      recto.put(MOV_DATAREG, TDate(31, 12, annodoc+1));
 | 
						||
        
 | 
						||
      TCursor cur(&rel, filter, 3, &recfrom, &recto);
 | 
						||
      const TRecnotype items = cur.items();
 | 
						||
      cur.freeze();
 | 
						||
      for (cur = 0; cur.pos() < items; ++cur)
 | 
						||
      {
 | 
						||
        const int ad = rec.get_date(MOV_DATADOC).year();
 | 
						||
        if (ad == annodoc)
 | 
						||
          return yesno_box("Il documento %d / %s e' gia' stato inserito con la registrazione %ld\nSi desidera continuare ugualmente?",
 | 
						||
                           annodoc, (const char*)f.get(), rec.get_long(MOV_NUMREG));
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::datadoc_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  TMask& m = f.mask();
 | 
						||
 | 
						||
  if (key == K_TAB && f.to_check(key, true) && app().is_saldaconto())
 | 
						||
  {
 | 
						||
    const TDate dd(f.get());                            // Fattura o nota credito
 | 
						||
    if (dd.ok())
 | 
						||
    {     
 | 
						||
      if (m.insert_mode() && m.field(F_ANNORIF).active() && m.get(F_ANNORIF).empty())
 | 
						||
        m.set(F_ANNORIF, dd.year());                    // copia anno documento
 | 
						||
      
 | 
						||
      TPrimanota_application& a = app();  
 | 
						||
      if (a.is_fattura())     
 | 
						||
      {   
 | 
						||
        if (m.insert_mode())
 | 
						||
        {   
 | 
						||
          if (m.get_bool(FS_RECALC))   // Evita scancellamenti indesiderati
 | 
						||
            a.recalc_scadenze(dd);
 | 
						||
        }  
 | 
						||
        else 
 | 
						||
        {
 | 
						||
          if (a._pag) 
 | 
						||
            a._pag->set_datadoc(dd);
 | 
						||
        }  
 | 
						||
      }
 | 
						||
    }  
 | 
						||
  }
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::occas_code_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  TMask& m = f.mask();
 | 
						||
  if (key == K_TAB && (f.dirty() || !m.is_running()))
 | 
						||
  {
 | 
						||
    const TString& code = f.get();
 | 
						||
    if (code.full())
 | 
						||
    {
 | 
						||
      TRelation occas(LF_OCCAS);
 | 
						||
      occas.curr().put(OCC_CFPI, code);
 | 
						||
      if (occas.read(_isequal) == NOERR)
 | 
						||
      {                     
 | 
						||
        m.autoload(occas);      
 | 
						||
 | 
						||
        if (m.field(O_COFI).empty() && !isdigit(code[0]) && cf_check(m.get(O_STATONAS), code))
 | 
						||
          m.set(O_COFI, code, 1);
 | 
						||
        if (m.field(O_PAIV).empty() && isdigit(code[0]) && pi_check(m.get(O_STATONAS), code))
 | 
						||
          m.set(O_PAIV, code, 1);
 | 
						||
 | 
						||
        m.send_key(K_TAB, O_COMUNE);         // Forza decodifica comuni
 | 
						||
        m.send_key(K_TAB, O_COMUNENAS);
 | 
						||
      } 
 | 
						||
    }
 | 
						||
  } 
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::occas_cfpi_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  TMask& om = f.mask();
 | 
						||
  if (key == K_TAB && (f.focusdirty() || !om.is_running()))
 | 
						||
  {
 | 
						||
    TString16 cofi = om.get(O_COFI);
 | 
						||
    if (cofi.empty())
 | 
						||
      cofi = om.get(O_CODICE);
 | 
						||
 | 
						||
    if (cf_check(om.get(O_STATONAS), cofi))
 | 
						||
    {
 | 
						||
      int giorno = atoi(cofi.mid(9,2));
 | 
						||
      om.set(O_SESSO, giorno > 40 ? "F" : "M");
 | 
						||
 | 
						||
      if (om.field(O_COMUNENAS).empty())
 | 
						||
        om.set(O_COMUNENAS, cofi.mid(11,4), 0x2);
 | 
						||
 | 
						||
      if (om.field(O_DATANAS).empty())
 | 
						||
      {
 | 
						||
        const TFixed_string mesi("ABCDEHLMPRST");
 | 
						||
        const int mese = mesi.find(cofi[8])+1;
 | 
						||
        int anno = atoi(cofi.mid(6,2));
 | 
						||
        if (giorno > 0 && mese > 0 && anno > 0)
 | 
						||
        {
 | 
						||
          giorno %= 40;
 | 
						||
          anno += anno < 5 ? 2000 : 1900;
 | 
						||
          om.set(O_DATANAS, TDate(giorno, mese, anno));
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  } 
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::occas_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_SPACE && f.mask().is_running())
 | 
						||
  {
 | 
						||
    TMask& om = app().occas_mask();
 | 
						||
    om.run();     
 | 
						||
    f.set_focus();
 | 
						||
  }  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Crea o aggiorna la riga contabile col totale documento
 | 
						||
// Certified 99%
 | 
						||
void TPrimanota_application::add_cgs_tot(TMask& m)
 | 
						||
{                           
 | 
						||
  const bool corri = causale().corrispettivi();
 | 
						||
  const char tipo = corri ? ' ' : app().clifo();
 | 
						||
  int gruppo = 0, conto = 0;
 | 
						||
  long codice = corri ? 0L : m.get_long(tipo == 'C' ? F_CLIENTE : F_FORNITORE);
 | 
						||
 | 
						||
  TSheet_field& ss = cgs();
 | 
						||
  const int riga_totale = type2pos('T');   
 | 
						||
  
 | 
						||
  // Cerca di preservare il gruppo-conto-sottoconto sulla riga totale
 | 
						||
  if (riga_totale >= 0)
 | 
						||
  {          
 | 
						||
    TToken_string& rowt = ss.row(riga_totale);
 | 
						||
 | 
						||
    gruppo = rowt.get_int(3); 
 | 
						||
    conto = rowt.get_int();
 | 
						||
    const long oldcode = rowt.get_long();
 | 
						||
 | 
						||
    if (corri)
 | 
						||
      codice = oldcode;          // I corrispettivi non hanno un cliente in testata
 | 
						||
    else
 | 
						||
    {     
 | 
						||
      if (m.insert_mode())       // Errore MI3567: se cambio cliente ripesca conto
 | 
						||
      {
 | 
						||
        if (codice != oldcode)   // Se cambia il codice cliente ...
 | 
						||
          gruppo = conto = 0;    // ... forza il ricalcolo del gruppo-conto
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  TBill nuovo(gruppo, conto, codice, tipo);
 | 
						||
  if (!corri && (gruppo == 0 || conto == 0))
 | 
						||
    nuovo.find(); // Compila anche gruppo e conto in base al codice clifo
 | 
						||
  
 | 
						||
  if (nuovo.gruppo() == 0 || nuovo.conto() == 0)
 | 
						||
  {    
 | 
						||
    // Se l'utente non ha ancora specificato un conto lo prendo dalla prima riga della causale
 | 
						||
    causale().bill(1, nuovo);  
 | 
						||
    
 | 
						||
    // Nelle fatture si deve sempre aggiungere il codice clifo (in causale normalmente non c'e')
 | 
						||
    if (!corri)
 | 
						||
      nuovo.codclifo() = codice;
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (riga_totale >= 0) 
 | 
						||
  {       
 | 
						||
    TToken_string& row = ss.row(riga_totale);
 | 
						||
    const TBill vecchio(row, 2, 0x1);
 | 
						||
    if (!vecchio.empty() && nuovo != vecchio)                  // Se cambio cliente/fornitore
 | 
						||
    {
 | 
						||
      for (int i = 0; i < ss.items(); i++) if (i != riga_totale)
 | 
						||
      {
 | 
						||
        TToken_string& r = ss.row(i);
 | 
						||
        const TBill tacchia(r, 9, 0x1);
 | 
						||
        if (tacchia == vecchio) 
 | 
						||
        {
 | 
						||
          nuovo.add_to(r, 9, 0x3);   // Aggiorna contropartite
 | 
						||
          ss.force_update(i);
 | 
						||
        }  
 | 
						||
      }
 | 
						||
    }  
 | 
						||
  }
 | 
						||
 | 
						||
  if (!_as400)
 | 
						||
  {
 | 
						||
    // Creazione/Aggiornamento riga totale 
 | 
						||
    const real tot(m.get(F_TOTALE));
 | 
						||
    TString descr;
 | 
						||
    if (riga_totale >= 0)
 | 
						||
      descr = cgs().row(riga_totale).get(8);
 | 
						||
    if (descr.blank())
 | 
						||
      descr = m.get(F_DESCR);
 | 
						||
		TImporto imp = real2imp(tot, 'T');
 | 
						||
		imp.normalize();
 | 
						||
    set_cgs_row(riga_totale, imp, nuovo, descr, 'T');
 | 
						||
  }
 | 
						||
 | 
						||
  calcola_imp();                                    // Ricalcola totale IVA
 | 
						||
  calcola_saldo();                                  // Ricalcola sbilanci
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_CLIENTE & F_FORNITORE field on the modify mask
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (!suspended_handler(f, key))
 | 
						||
    return false;
 | 
						||
    
 | 
						||
  if (key == K_TAB && f.active())
 | 
						||
  {                                  
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    TMask& m = f.mask();
 | 
						||
    
 | 
						||
    if (f.focusdirty() && a.is_nota_credito())
 | 
						||
    {   
 | 
						||
      TPartite_array& p = a.partite();
 | 
						||
 | 
						||
      const TPartita* game = p.first();
 | 
						||
      if (game != NULL && atol(f.get()) != game->conto().codclifo())  
 | 
						||
      { 
 | 
						||
        const bool del = f.yesno_box(TR("Si desidera cancellare i pagamenti effettuati?"));
 | 
						||
        if (!del)     // Ripristina codice copiandolo dalla prima partita
 | 
						||
        {
 | 
						||
          TString cod; cod << game->conto().codclifo();
 | 
						||
          f.set(cod);
 | 
						||
          return true;
 | 
						||
        }
 | 
						||
        f.set_dirty();     // yesno_box cleared the dirty flag
 | 
						||
        a.notify_cgline_deletion(-1);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    const char cf = a.clifo();
 | 
						||
    const long codice = atol(f.get());
 | 
						||
 | 
						||
    if (codice == 0) 
 | 
						||
    {
 | 
						||
      m.hide(F_OCCASEDIT);                                 // Spegni bottone occasionali
 | 
						||
      m.show(F_STATOPAIV);                                 // Stato partita IVA
 | 
						||
      m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE); // Partita IVA
 | 
						||
      m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE); // Codice Fiscale
 | 
						||
      a.activate_numrif(m, true);
 | 
						||
      return true;
 | 
						||
    }  
 | 
						||
    
 | 
						||
    TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF");
 | 
						||
    TRectype& clifo = cliforel.curr();
 | 
						||
    clifo.put(CLI_TIPOCF, cf);
 | 
						||
    clifo.put(CLI_CODCF, codice);   
 | 
						||
    cliforel.read();
 | 
						||
 | 
						||
    if (!m.is_running() || f.dirty())
 | 
						||
    {
 | 
						||
      a._conto_ricavo.set(clifo.get_int(CLI_GRUPPORIC), 
 | 
						||
                          clifo.get_int(CLI_CONTORIC), 
 | 
						||
                          clifo.get_long(CLI_SOTTOCRIC));
 | 
						||
      if (a._conto_ricavo.find() && a._conto_ricavo.sospeso())
 | 
						||
      {
 | 
						||
        f.error_box(TR("Il conto di ricavo e' sospeso"));
 | 
						||
        a._conto_ricavo.set(0,0,0);
 | 
						||
      }
 | 
						||
      
 | 
						||
      const int alleg = clifo.get_int(CLI_ALLEG);
 | 
						||
      TEdit_field& upi = m.efield(F_RIEPILOGO);
 | 
						||
      upi.check_type(alleg == 3 ? CHECK_REQUIRED : CHECK_NORMAL);
 | 
						||
    
 | 
						||
      TEdit_field& cp = m.efield(F_CODPAG);
 | 
						||
      if ((f.focusdirty() && m.is_running()) || (cp.empty() && !m.is_running())) 
 | 
						||
      {
 | 
						||
        const TString& oldpag = cp.get();
 | 
						||
        const TString& s = clifo.get(CLI_CODPAG);
 | 
						||
        if (s != oldpag)
 | 
						||
        {
 | 
						||
          if (cp.active())              // Se il campo F_CODPAG e' attivo
 | 
						||
          {
 | 
						||
            cp.set(s);                  // Setta il codice di pagamento sulla maschera
 | 
						||
            cp.check(RUNNING_CHECK);    // lo decodifica
 | 
						||
            cp.on_hit();                // lo ricopia eventualmente a pag.3
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
        if (cf == 'F' && app().causale().valintra())
 | 
						||
        {                                 
 | 
						||
          const TString& valintra = clifo.get(CLI_VALINTRA);
 | 
						||
          if  (valintra.full())
 | 
						||
            m.set(F_VALUTAINTRA, valintra, true);
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      if (f.focusdirty() && a.is_saldaconto())
 | 
						||
      {                         
 | 
						||
        if (m.field(SK_VALUTA).active() && m.get(SK_VALUTA).empty())
 | 
						||
        {
 | 
						||
          const TString& valuta = clifo.get(CLI_CODVAL);
 | 
						||
          if (valuta.not_empty())
 | 
						||
            m.set(SK_VALUTA, valuta, true);
 | 
						||
        }                   
 | 
						||
        
 | 
						||
        if (a.is_fattura())
 | 
						||
        {                         
 | 
						||
          const TRectype& clifov = cliforel.curr(LF_CFVEN);
 | 
						||
          
 | 
						||
          if (clifo.get(CLI_CODCAB).not_empty())
 | 
						||
          {
 | 
						||
            m.set(FS_VSABI, clifo.get(CLI_CODABI));
 | 
						||
            m.set(FS_VSCAB, clifo.get(CLI_CODCAB));
 | 
						||
            m.send_key(K_TAB, FS_VSCAB);
 | 
						||
          }
 | 
						||
          if (clifov.get(CFV_CODCABPR).not_empty())
 | 
						||
          {
 | 
						||
            m.set(FS_NSABI, clifov.get(CFV_CODABIPR));
 | 
						||
            m.set(FS_NSCAB, clifov.get(CFV_CODCABPR));
 | 
						||
            m.send_key(K_TAB, FS_NSCAB);
 | 
						||
          }
 | 
						||
          
 | 
						||
          const TString& agente = clifov.get(CLI_CODAG);
 | 
						||
          if (agente.full())
 | 
						||
          {
 | 
						||
            m.set(FS_AGENTE, agente, true);
 | 
						||
            m.send_key(K_TAB, FS_AGENTE);
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
      }
 | 
						||
    }  
 | 
						||
 | 
						||
    const bool occas = clifo.get_bool(CLI_OCCAS);
 | 
						||
    m.show(F_OCCASEDIT, occas);                                  // Bottone Dati anagrafici
 | 
						||
    m.show(F_STATOPAIV, !occas);                                 // Stato partita IVA
 | 
						||
    if (!occas)                                   
 | 
						||
      m.set(F_STATOPAIV, clifo.get(CLI_STATOPAIV));
 | 
						||
    m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE, !occas); // Partita IVA
 | 
						||
    m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE, !occas); // Codice Fiscale
 | 
						||
    
 | 
						||
    if (occas && a.is_fattura() && a.partite().first() != NULL)
 | 
						||
    {
 | 
						||
      f.warning_box(TR("Attenzione, il saldaconto verra' eliminato!"));
 | 
						||
      f.set_dirty();    // warning_box cleans the field!
 | 
						||
    }  
 | 
						||
    a.activate_numrif(m, true);
 | 
						||
    
 | 
						||
    if (f.focusdirty())
 | 
						||
    {
 | 
						||
      a.add_cgs_tot(m);
 | 
						||
      if (occas && a.occas_mask().get(O_CODICE).blank())
 | 
						||
        m.send_key(K_SPACE, F_OCCASEDIT);   // Lancia maschera occasionali
 | 
						||
    }
 | 
						||
    
 | 
						||
  }  
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TPrimanota_application::IVA2bill(const TCodiceIVA& iva, TBill& bill)
 | 
						||
{
 | 
						||
  const TCausale& cau = causale();
 | 
						||
  if (!cau.corrispettivi())   
 | 
						||
    bill = _conto_ricavo;
 | 
						||
  return cau.IVA2bill(iva, bill);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of the F_CODIVA
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
	static bool __in_handler = false;
 | 
						||
 | 
						||
	if (key == K_TAB && !f.empty() && !__in_handler)
 | 
						||
  {
 | 
						||
    if (!suspended_handler(f, key))
 | 
						||
      return false;
 | 
						||
 | 
						||
    __in_handler = true;
 | 
						||
    
 | 
						||
		TPrimanota_application& a = app();
 | 
						||
    const real imp(a.ivas().row(1).get(0));   
 | 
						||
 | 
						||
		if (a.iva() == iva_acquisti && a.causale().intra())
 | 
						||
		{
 | 
						||
	    const real iva(f.mask().get_real(F_RITFIS));   
 | 
						||
			if (iva.is_zero())
 | 
						||
			{
 | 
						||
				TCodiceIVA codiva(f.get());
 | 
						||
				const real totale = f.mask().get_real(F_TOTALE);
 | 
						||
				const real imposta = codiva.imposta(totale);
 | 
						||
				f.mask().set(F_RITFIS, imposta, true);
 | 
						||
			}
 | 
						||
		}
 | 
						||
		if (imp.is_zero()) // Se il totale documento non e' stato spezzato
 | 
						||
    {                     
 | 
						||
      TToken_string& row = a.ivas().row(0);
 | 
						||
 | 
						||
 //     TMask& m = f.mask();
 | 
						||
      iva_notify(a.ivas(), 0, K_SPACE);
 | 
						||
      
 | 
						||
      const TCodiceIVA iva(f.get());   
 | 
						||
      const bool corr = a.causale().corrispettivi();
 | 
						||
      const bool acq3 = (a.iva() == iva_acquisti) && (row.get_int(2) == 3);
 | 
						||
      
 | 
						||
      real tot = a.totale_documento();            // Calcola totale documento
 | 
						||
      real imposta;                               // Calcola imposta
 | 
						||
      if (!corr && !acq3)
 | 
						||
        imposta = iva.scorpora(tot);
 | 
						||
      
 | 
						||
      row.add(tot.string(), 0);                   // imponibile
 | 
						||
      row.add(imposta.string(), 3);               // imposta
 | 
						||
      
 | 
						||
      if (iva.codice() != row.get(1))
 | 
						||
      {
 | 
						||
        row.add(iva.codice(), 1);       // Aggiorna codice IVA
 | 
						||
        
 | 
						||
        const int det = iva.detraibilita();
 | 
						||
        if (det > 0) row.add(det, 2);
 | 
						||
 | 
						||
        TBill bill;                     // Aggiorna conto della prima riga IVA
 | 
						||
        a.IVA2bill(iva, bill);
 | 
						||
        bill.add_to(row, 4, 0x7); 
 | 
						||
      }
 | 
						||
      a.ivas().force_update(0);
 | 
						||
 | 
						||
      iva_notify(a.ivas(), 0, K_ENTER);
 | 
						||
    }   
 | 
						||
    __in_handler = false;
 | 
						||
  }  
 | 
						||
  return true;  
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_LIQDIFF
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::liqdiff_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
 | 
						||
	if (key == K_SPACE && f.mask().is_running())
 | 
						||
	{
 | 
						||
		TSheet_field & cgs = app().cgs();
 | 
						||
		const bool liqdiff = f.get().full();
 | 
						||
	  const TCausale& cau = app().causale();
 | 
						||
    TBill contoiva; 
 | 
						||
		int ri;
 | 
						||
 | 
						||
		if (f.mask().get_bool(F_LIQDIFF))
 | 
						||
			cau.bill(ri = RIGA_IVA_DIFFERITA, contoiva); 
 | 
						||
		if (!contoiva.ok())
 | 
						||
			cau.bill(ri = RIGA_IVA_DETRAIBILE, contoiva); 
 | 
						||
		TToken_string conto(contoiva.string(0x3));
 | 
						||
    const TString80 descragg(cau.desc_agg(ri));
 | 
						||
		int rowtype = cgs.cid2index(CG_ROWTYPE);
 | 
						||
		int tp = cgs.cid2index(CG_TIPO);
 | 
						||
		int gr = cgs.cid2index(CG_GRUPPO);
 | 
						||
		int co = cgs.cid2index(CG_CONTO);
 | 
						||
		int sc = cgs.cid2index(CG_SOTTOCONTO);
 | 
						||
		int des = cgs.cid2index(CG_DESCR);
 | 
						||
 | 
						||
		FOR_EACH_SHEET_ROW(cgs, r, row)
 | 
						||
		{
 | 
						||
			const TString4 type(row->get(rowtype));
 | 
						||
 | 
						||
			if (type == "D")
 | 
						||
			{
 | 
						||
				row->add(conto.get(0), tp);
 | 
						||
				row->add(conto.get(), gr);
 | 
						||
				row->add(conto.get(), co);
 | 
						||
				row->add(conto.get(), sc);
 | 
						||
				row->add(conto.get(), sc + 1);
 | 
						||
				row->add(descragg, des);
 | 
						||
			}
 | 
						||
		}
 | 
						||
		cgs.force_update();
 | 
						||
	}
 | 
						||
  return true;  
 | 
						||
}
 | 
						||
 | 
						||
// Riempie i campi valuta a zero in base agli altri
 | 
						||
void TPrimanota_application::gioca_cambi(int force)
 | 
						||
{               
 | 
						||
  TMask& m = curr_mask();    
 | 
						||
  if (m.get(SK_VALUTA).empty())
 | 
						||
    return;
 | 
						||
  
 | 
						||
  const real totale = m.get_real(F_TOTALE);
 | 
						||
  const real totval = m.get_real(SK_TOTDOCVAL);
 | 
						||
  const real cambio = m.get_real(SK_CAMBIO);  
 | 
						||
 | 
						||
  if ( (force == 0x1 || totale.is_zero()) && !(totval.is_zero() || cambio.is_zero()) )
 | 
						||
  {
 | 
						||
    const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
 | 
						||
    const real new_totale = cam.val2lit(totval);
 | 
						||
    if (new_totale != totale)
 | 
						||
      m.set(F_TOTALE, new_totale, true);
 | 
						||
  } 
 | 
						||
  
 | 
						||
  if ( (force == 0x2 || totval.is_zero()) && !(totale.is_zero() || cambio.is_zero()) )
 | 
						||
  {
 | 
						||
    const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
 | 
						||
    const real new_totval = cam.lit2val(totale);
 | 
						||
    if (new_totval != totval)
 | 
						||
      m.set(SK_TOTDOCVAL, new_totval, true);
 | 
						||
  } 
 | 
						||
  
 | 
						||
  if ( (force == 0x4 || cambio.is_zero()) && !(totale.is_zero() || totval.is_zero()) )
 | 
						||
  {
 | 
						||
    real new_cambio = totale / totval;
 | 
						||
    if (m.id2pos(SK_CONTROEURO) >= 0)
 | 
						||
      m.reset(SK_CONTROEURO);
 | 
						||
    
 | 
						||
    exchange_type dummy_contro_euro;  
 | 
						||
    const real& fc = TCurrency::get_firm_change(dummy_contro_euro);
 | 
						||
    if (fc > ZERO)
 | 
						||
      new_cambio *= fc;
 | 
						||
    
 | 
						||
    new_cambio.round(6);
 | 
						||
    if (new_cambio != cambio)
 | 
						||
      m.set(SK_CAMBIO, new_cambio, true);
 | 
						||
  } 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of the F_TOTALE
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::totdoc_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  TMask& m = f.mask();
 | 
						||
  TPrimanota_application& a = app();
 | 
						||
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
  {       
 | 
						||
    a.gioca_cambi();
 | 
						||
 | 
						||
    if (a.iva() != nessuna_iva)
 | 
						||
    {
 | 
						||
      a.add_cgs_tot(m);
 | 
						||
      if (m.insert_mode())               // Se si e' in inserimento provoca ricalcolo
 | 
						||
        m.field(F_CODIVA).on_hit();      // dello sheet iva e delle scadenze
 | 
						||
    }  
 | 
						||
    else   
 | 
						||
    {
 | 
						||
      if (a.is_pagamento())
 | 
						||
        a.calcola_saldo();
 | 
						||
    }                         
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (key == K_ENTER)
 | 
						||
  {
 | 
						||
    const TCurrency totale(real(f.get()));
 | 
						||
    if (totale.get_num().is_zero())
 | 
						||
      ok = yesno_box(TR("Totale documento nullo: continuare ugualmente?"));
 | 
						||
    
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
 | 
						||
      if (cambio.in_valuta())
 | 
						||
      {
 | 
						||
        const real totval(m.get(SK_TOTDOCVAL));
 | 
						||
        const TCurrency totlit(cambio.val2lit(totval));
 | 
						||
        if (totale != totlit)
 | 
						||
          ok = f.yesno_box(FR("Il totale documento dovrebbe essere %s: continuare ugualmente?"),
 | 
						||
                         totlit.string(true));
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
 | 
						||
    if (a.iva() == nessuna_iva && a.is_fattura())
 | 
						||
    {
 | 
						||
      TBill bill;
 | 
						||
      const int riga_cf = a.cerca_conto_cf(bill);
 | 
						||
      if (riga_cf >= 0)
 | 
						||
      {
 | 
						||
        TImporto imp = a.get_cgs_imp(riga_cf);
 | 
						||
        if (imp.valore() != m.get_real(F_TOTALE))
 | 
						||
          ok = f.error_box(FR("Il totale documento non corrisponde alla riga %d:\ndovrebbe essere %s"),
 | 
						||
                           riga_cf+1, imp.valore().string());
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }    
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::totdocval_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
  {  
 | 
						||
    TPrimanota_application& a = app();
 | 
						||
    a.gioca_cambi();
 | 
						||
    
 | 
						||
    TMask& m = f.mask();
 | 
						||
    if (a.is_fattura() && m.insert_mode())    
 | 
						||
      a.set_scadenze(m);  
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Aggiunge o aggiorna la riga delle ritenute fiscali o sociali   
 | 
						||
// Certified 99%
 | 
						||
void TPrimanota_application::add_cgs_rit(bool fiscali)
 | 
						||
{                            
 | 
						||
  if (_as400)
 | 
						||
    return;
 | 
						||
 | 
						||
  TMask& m = curr_mask();
 | 
						||
  const real imp(m.get(fiscali ? F_RITFIS : F_RITSOC)); // Determina importo
 | 
						||
 | 
						||
  const char tipo = fiscali ? 'F' : 'S';
 | 
						||
  const int pos = type2pos(tipo);          // Cerca la riga contabile
 | 
						||
  if (pos < 0)                             // Se non c'e' ...
 | 
						||
  {  
 | 
						||
    if (!imp.is_zero())                      // ... e l'importo e' valido
 | 
						||
    {                                        // crea una nuova riga di ritenute
 | 
						||
      const int riga = fiscali ? RIGA_RITENUTE_FISCALI : RIGA_RITENUTE_SOCIALI;
 | 
						||
      TBill conto; causale().bill(riga, conto);
 | 
						||
      const TString desc(causale().desc_agg(riga));
 | 
						||
      set_cgs_row(-1, real2imp(imp, tipo), conto, desc, tipo);
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (imp.is_zero())                       // se l'importo e' nullo ...
 | 
						||
      reset_cgs_row(pos);                    // ... azzera la riga contabile
 | 
						||
    else                                     // altrimenti ...
 | 
						||
      set_cgs_imp(pos, real2imp(imp, tipo)); // ... aggiorna importo
 | 
						||
  }  
 | 
						||
  
 | 
						||
  if (m.insert_mode())
 | 
						||
    m.field(F_CODIVA).on_hit();              // Ricalcola sheet iva e contabile
 | 
						||
  else
 | 
						||
    app().calcola_saldo();                   // Ricalcola solo lo sbilancio
 | 
						||
}
 | 
						||
 | 
						||
// Handler of the F_PROTIVA
 | 
						||
bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key)
 | 
						||
{          
 | 
						||
  bool ok = true;            
 | 
						||
  TMask& m = f.mask();
 | 
						||
  
 | 
						||
  if (m.insert_mode())
 | 
						||
  {
 | 
						||
    if (key == K_ENTER && f.dirty())
 | 
						||
    {
 | 
						||
      const long protiva = atol(f.get());
 | 
						||
      const long protocol = app().causale().reg().protocol() + 1;
 | 
						||
      if (protiva != protocol)
 | 
						||
        ok = f.yesno_box(FR("Accettare il protocollo IVA fuori sequenza: %ld invece di %ld"), 
 | 
						||
                         protiva, protocol);    
 | 
						||
    }
 | 
						||
    else 
 | 
						||
    if (key == K_TAB && m.insert_mode() && app().npart_is_prot() &&
 | 
						||
        m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank())
 | 
						||
    {
 | 
						||
      const TString& piva = f.get();
 | 
						||
      if (piva.not_empty())    
 | 
						||
        m.set(F_NUMRIF, piva, true); 
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of the F_RITFIS
 | 
						||
// Certified 100%
 | 
						||
bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
    app().add_cgs_rit(true);
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of F_RITSOC
 | 
						||
// Certified 100%
 | 
						||
bool TPrimanota_application::ritsoc_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
    app().add_cgs_rit(false);
 | 
						||
  return true;
 | 
						||
}                                  
 | 
						||
 | 
						||
HIDDEN void inventa_cambio_intra(TMask& m)
 | 
						||
{
 | 
						||
  const TString& codval = m.get(F_VALUTAINTRA);
 | 
						||
  if (codval.not_empty() && TCurrency::get_firm_val() != codval)
 | 
						||
  {
 | 
						||
    TTable cam("CAM");
 | 
						||
    cam.put("CODTAB", codval);
 | 
						||
    const int err = cam.read(_isgteq);
 | 
						||
    bool yes = err != NOERR;
 | 
						||
    if (!yes)
 | 
						||
    {
 | 
						||
      TString16 v = cam.get("CODTAB");
 | 
						||
      v.cut(3).rtrim();
 | 
						||
      yes = v != codval;
 | 
						||
    }
 | 
						||
    if (yes)
 | 
						||
      m.set(F_CAMBIOINTRA, cache().get("%VAL", codval, "S4"));
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// Handler of F_DATAINTRA
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::dataintra_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  // Se la data INTRA e' vuota allora copiala dalla data di competenza normale
 | 
						||
  if (key == K_ENTER && f.empty())
 | 
						||
  {
 | 
						||
    f.set(f.mask().get(F_DATAREG));
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Handler of F_CORRLIRE
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::corrlire_handler(TMask_field& f, KEY key)
 | 
						||
{   
 | 
						||
  TMask& m = f.mask();
 | 
						||
  TMask_field& cv = m.field(F_CORRVALUTA);
 | 
						||
 | 
						||
  if (key == K_ENTER && f.get().empty())
 | 
						||
  {
 | 
						||
    if (!cv.empty()) 
 | 
						||
    {
 | 
						||
      cv.set_focusdirty();
 | 
						||
      cv.on_hit();
 | 
						||
    }  
 | 
						||
    else
 | 
						||
      key = K_F8;  
 | 
						||
  }
 | 
						||
 | 
						||
  if (key == K_F8)
 | 
						||
  {
 | 
						||
    f.set(m.get(F_IMPONIBILI));
 | 
						||
    f.set_dirty();
 | 
						||
    cv.set("");
 | 
						||
    key = K_TAB;
 | 
						||
  }
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
  {                     
 | 
						||
    if (cv.empty())
 | 
						||
    {           
 | 
						||
      if (m.field(F_CAMBIOINTRA).empty())
 | 
						||
        inventa_cambio_intra(m);
 | 
						||
      const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA));
 | 
						||
      TCurrency imp(real(f.get()));
 | 
						||
      imp.change_value(cambio);
 | 
						||
      cv.set(imp.get_num().string());
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (key == K_ENTER)
 | 
						||
  {
 | 
						||
    const real im(m.get(F_IMPONIBILI));
 | 
						||
    const real cl(f.get());
 | 
						||
    if (im != cl)                          
 | 
						||
    { 
 | 
						||
      const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val());
 | 
						||
      const char* name = (const char*)rec.get("S0");
 | 
						||
      warning_box(FR("Il corrispettivo in %s e' diverso dal totale degli imponibili"), name);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Handler of F_CORRVALUTA
 | 
						||
// Certified 99%
 | 
						||
bool TPrimanota_application::corrvaluta_handler(TMask_field& f, KEY key)
 | 
						||
{               
 | 
						||
  TMask& m = f.mask();
 | 
						||
  TMask_field& cl = m.field(F_CORRISPETTIVO);
 | 
						||
 | 
						||
  if (key == K_TAB && f.focusdirty())
 | 
						||
  {                     
 | 
						||
    if (cl.empty())
 | 
						||
    {
 | 
						||
      if (m.field(F_CAMBIOINTRA).empty())
 | 
						||
        inventa_cambio_intra(m);
 | 
						||
      const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA));
 | 
						||
      TCurrency imp(real(f.get()), cambio);
 | 
						||
      imp.change_to_firm_val();
 | 
						||
      cl.set(imp.get_num().string());
 | 
						||
    }  
 | 
						||
  } 
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (key == K_ENTER && f.get().empty())
 | 
						||
    {
 | 
						||
      cl.set_dirty();
 | 
						||
      cl.on_hit();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TPrimanota_application::activate_numrif(TMask& m, bool init_pag)
 | 
						||
{
 | 
						||
  // Il numero riferimento esiste 
 | 
						||
  bool shown = is_saldaconto() && (is_fattura() || is_nota_credito());         
 | 
						||
  
 | 
						||
  if (shown)
 | 
						||
  {
 | 
						||
    if (m.id2pos(F_SOLAIVA) >= 0) // Maschera moviventi IVA
 | 
						||
    {
 | 
						||
      const bool hide = m.get_bool(F_SOLAIVA) || m.field(F_OCCASEDIT).shown();
 | 
						||
      if (hide) 
 | 
						||
        shown = false;
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  
 | 
						||
  if (shown != m.field(F_NUMRIF).shown())
 | 
						||
  {
 | 
						||
    m.show(F_ANNORIF, shown);
 | 
						||
    m.show(F_NUMRIF,  shown); 
 | 
						||
    if (shown)
 | 
						||
    {  
 | 
						||
      if (m.field(F_ANNORIF).empty())
 | 
						||
      {
 | 
						||
        m.set(F_ANNORIF, m.get_date(F_DATADOC).year());
 | 
						||
        const bool use_protiva = _npart_is_prot && m.id2pos(F_PROTIVA) > 0;
 | 
						||
        m.set(F_NUMRIF, m.get(use_protiva ? F_PROTIVA : F_NUMDOC));
 | 
						||
      }  
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      m.reset(F_ANNORIF);
 | 
						||
      m.reset(F_NUMRIF);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  // Gestione pagina 3
 | 
						||
  const bool page = shown && is_fattura() && !m.get(F_NUMRIF).blank();
 | 
						||
  if (page != m.page_enabled(2))
 | 
						||
  {
 | 
						||
    m.enable_page(2, page);                 
 | 
						||
    if (page && init_pag && m.is_running())
 | 
						||
    {
 | 
						||
      if (m.edit_mode())
 | 
						||
      {
 | 
						||
        const TString& dt = m.get(F_DATADOC);
 | 
						||
        set_pagamento(NULL, dt);          // Reset pagamento
 | 
						||
        set_totale_pagamento(true);
 | 
						||
      }
 | 
						||
      else
 | 
						||
        set_scadenze(m);                  // Inizializza pagamento
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  return shown;
 | 
						||
}
 | 
						||
 | 
						||
// Handler del checkbox di movimento di sola IVA
 | 
						||
bool TPrimanota_application::solaiva_handler(TMask_field& f, KEY key)
 | 
						||
{                                         
 | 
						||
  TMask& m = f.mask();
 | 
						||
  const bool run = m.is_running();
 | 
						||
 | 
						||
  if ((key == K_TAB && f.focusdirty()) || !run)
 | 
						||
  {     
 | 
						||
    TPrimanota_application& a = app();                                  
 | 
						||
    
 | 
						||
    bool anchecg = f.get()[0] != 'X'; 
 | 
						||
    bool recalcg = anchecg;
 | 
						||
    
 | 
						||
    if (run && a.is_fattura())
 | 
						||
    {
 | 
						||
      const TPartita* game = a.partite().first();
 | 
						||
 | 
						||
      if (anchecg)
 | 
						||
      {                          
 | 
						||
        if (game != NULL)
 | 
						||
        {
 | 
						||
          m.set(F_ANNORIF, game->anno());
 | 
						||
          m.set(F_NUMRIF, game->numero());
 | 
						||
        }
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {                 
 | 
						||
        bool del = true;
 | 
						||
        if (game != NULL)
 | 
						||
          del = f.yesno_box(TR("Si desidera cancellare il saldaconto?"));
 | 
						||
        if (!del)  
 | 
						||
        {
 | 
						||
          f.reset();
 | 
						||
          anchecg = true;
 | 
						||
          recalcg = false;
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      a.activate_numrif(m, true);
 | 
						||
    }
 | 
						||
    
 | 
						||
    m.show(F_SHEETCG, anchecg);
 | 
						||
    m.show(F_DARE,    anchecg);
 | 
						||
    m.show(F_AVERE,   anchecg);
 | 
						||
    
 | 
						||
    if (run && recalcg)
 | 
						||
    {                      
 | 
						||
      TSheet_field& iva = a.ivas();
 | 
						||
      const int righe = iva.items();
 | 
						||
      TProgind pi(righe, TR("Generazione righe contabilita'"), false, true);
 | 
						||
      
 | 
						||
      TSheet_field& cg = a.cgs();
 | 
						||
      cg.reset();
 | 
						||
      
 | 
						||
      a.add_cgs_tot(m);                                        // Genera totale documento
 | 
						||
      if (m.get(F_RITFIS).not_empty()) a.add_cgs_rit(true);    // Genera ritenute fiscali
 | 
						||
      if (m.get(F_RITSOC).not_empty()) a.add_cgs_rit(false);   // Genera ritenute sociali
 | 
						||
      
 | 
						||
      TToken_string oldrow(128);
 | 
						||
      for (int i = 0; i < righe; i++)
 | 
						||
      {             
 | 
						||
        TToken_string& r = iva.row(i);
 | 
						||
        if (!r.empty_items())
 | 
						||
        {
 | 
						||
          oldrow = r;
 | 
						||
          r = "";
 | 
						||
          iva_notify(iva, i, K_SPACE);   // Simula la creazione di una nuova riga iva
 | 
						||
          r = oldrow;
 | 
						||
          iva_notify(iva, i, K_ENTER);
 | 
						||
        }
 | 
						||
        pi.setstatus(i+1);
 | 
						||
      }
 | 
						||
      a.fill_sheet(m);                   // Aggiunge righe vuote
 | 
						||
      cg.force_update();
 | 
						||
      m.set_focus();                     // Ripristina il focus al campo (a causa della progind)
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  return true;  
 | 
						||
}
 | 
						||
 | 
						||
// Handler del bottone di collegamento ai documenti
 | 
						||
bool TPrimanota_application::linkdoc_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_SPACE)
 | 
						||
  {
 | 
						||
    const TRectype& mov = app().get_relation()->curr();
 | 
						||
    TRectype doc(LF_DOC);
 | 
						||
    doc.put(DOC_PROVV, mov.get(MOV_DPROVV));
 | 
						||
    doc.put(DOC_ANNO,  mov.get(MOV_DANNO));
 | 
						||
    doc.put(DOC_CODNUM,mov.get(MOV_DCODNUM));
 | 
						||
    doc.put(DOC_NDOC,  mov.get(MOV_DNDOC));
 | 
						||
    doc.edit();
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
  
 | 
						||
  
 | 
						||
bool TPrimanota_application::quadratura_handler(TMask_field& f, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_SPACE)
 | 
						||
  {
 | 
						||
    TMask& m = f.mask();
 | 
						||
    TSheet_field& shiva = m.sfield(F_SHEETIVA);
 | 
						||
 | 
						||
    const real totdoc = app().totale_documento();
 | 
						||
    TGeneric_distrib distrib(totdoc, TCurrency::get_firm_dec());
 | 
						||
		real totdist;
 | 
						||
    if (!shiva.empty())
 | 
						||
    {
 | 
						||
      FOR_EACH_SHEET_ROW(shiva, o, orow)
 | 
						||
      {
 | 
						||
        const real o_imponibile = orow->get(0);
 | 
						||
        const real o_imposta    = orow->get(3);
 | 
						||
 | 
						||
        if (!o_imponibile.is_zero() || !o_imposta.is_zero())
 | 
						||
          distrib.add(o_imponibile + o_imposta);
 | 
						||
	      totdist += o_imponibile + o_imposta;
 | 
						||
      }
 | 
						||
    }
 | 
						||
		if (app()._perc_attesa_fld.full())
 | 
						||
		{
 | 
						||
			TFieldref f(app()._perc_attesa_fld, LF_CLIFO);
 | 
						||
			TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF");
 | 
						||
			TRectype& clifo = cliforel.curr();
 | 
						||
			real perc;
 | 
						||
 | 
						||
			if (m.field(F_CLIENTE).shown())
 | 
						||
			{
 | 
						||
				clifo.put(CLI_TIPOCF, "C");   
 | 
						||
				clifo.put(CLI_CODCF, m.get(F_CLIENTE));;
 | 
						||
			}                                 
 | 
						||
			else
 | 
						||
			{
 | 
						||
				clifo.put(CLI_TIPOCF, "F");   
 | 
						||
				clifo.put(CLI_CODCF, m.get(F_FORNITORE));;
 | 
						||
			}       
 | 
						||
 | 
						||
			if (cliforel.read() == NOERR)
 | 
						||
				perc = f.read(cliforel);
 | 
						||
			real perc_reale = ((totdoc - totdist) * CENTO) / totdist;
 | 
						||
 | 
						||
			perc_reale.round(2);
 | 
						||
 | 
						||
			if (perc != perc_reale)
 | 
						||
			{
 | 
						||
			  if (!yesno_box("La percentuale su questo documento <20> %s\nmentre dovrebbe essere %s:\nContinuare ugualmente ?", perc_reale.stringa(), perc.stringa()))
 | 
						||
				return false;
 | 
						||
			}
 | 
						||
		}
 | 
						||
    FOR_EACH_SHEET_ROW(shiva, n, nrow)
 | 
						||
    {
 | 
						||
      const real o_imponibile = nrow->get(0);
 | 
						||
      const real o_imposta    = nrow->get(3);
 | 
						||
      if (!o_imponibile.is_zero() || !o_imposta.is_zero())
 | 
						||
      {
 | 
						||
        const TString4 zanicchi(nrow->get(1));    // Codice IVA
 | 
						||
        const TCodiceIVA i(zanicchi);          
 | 
						||
        real n_imponibile = distrib.get();
 | 
						||
        real n_imposta = i.scorpora(n_imponibile);   
 | 
						||
        if (n_imponibile != o_imponibile || n_imposta != o_imposta)
 | 
						||
        {
 | 
						||
          app().iva_notify(shiva, n, K_SPACE);
 | 
						||
          nrow->add(n_imponibile.string(), 0);      
 | 
						||
          nrow->add(n_imposta.string(), 3);
 | 
						||
          app().iva_notify(shiva, n, K_ENTER);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    shiva.force_update();
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 |