git-svn-id: svn://10.65.10.50/branches/R_10_00@23120 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1172 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1172 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "cg2100.h"
 | 
						|
#include "cg2102.h"
 | 
						|
#include "cg2107.h"
 | 
						|
 | 
						|
#include "cg2100e.h"
 | 
						|
#include "cgsalda3.h"
 | 
						|
 | 
						|
#include <urldefid.h>
 | 
						|
#include <toolfld.h>
 | 
						|
#include <treectrl.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TNew_game_mask
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TNew_game_mask : public TAutomask
 | 
						|
{
 | 
						|
  const TBill& _conto;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
 | 
						|
public:
 | 
						|
  TNew_game_mask(const TBill& conto);
 | 
						|
};
 | 
						|
 | 
						|
bool TNew_game_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  bool ok = true;
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case 102: // Numero partita
 | 
						|
    if (e == fe_close)
 | 
						|
    {
 | 
						|
      const int anno = get_int(101); // ANNO
 | 
						|
      const TString& part = o.get(); // NUMPART
 | 
						|
      // Controlla partita in memoria
 | 
						|
      ok = !app().partite().exist(_conto, anno, part) ||              // Non esiste
 | 
						|
            app().partite().partita(_conto, anno, part).last()<=0;    // Esiste ma non ha righe
 | 
						|
      if (ok)
 | 
						|
      {
 | 
						|
        const TPartita p(_conto, anno, part);          // Controlla partita su disco  
 | 
						|
        ok = p.last() <= 0;
 | 
						|
      }
 | 
						|
      if (!ok)
 | 
						|
        error_box(FR("La partita %d/%s esiste già"), anno, (const char*)part);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TNew_game_mask::TNew_game_mask(const TBill& conto) 
 | 
						|
              : TAutomask(TR("Nuova partita"), 1, 24, 4), _conto(conto)
 | 
						|
{
 | 
						|
  add_button_tool(DLG_OK, "", TOOL_OK);
 | 
						|
  add_button_tool(DLG_CANCEL, "", TOOL_CANCEL);
 | 
						|
 | 
						|
  const char* flags = TPartita::allineamento_richiesto(_conto.tipo()) == 'R' ? "UR" : "U";
 | 
						|
  TEdit_field& partita = add_string(102, 0, PR("Partita "), 1, 2, 6, flags);
 | 
						|
  partita.set_field(TFixed_string(PART_NUMPART));
 | 
						|
  partita.check_type(CHECK_REQUIRED);
 | 
						|
  
 | 
						|
  TReal_field& anno = add_number(101, 0, PR("Anno    "), 1, 1, 4, "AU");
 | 
						|
  anno.set_field(TFixed_string(PART_ANNO));
 | 
						|
  anno.check_type(CHECK_REQUIRED);
 | 
						|
  
 | 
						|
  set_handlers();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TEasySolder_mask
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Forse andrebbe in libreria!
 | 
						|
void TEasySolder_mask::set_imp(short id, const TImporto& imp)
 | 
						|
{
 | 
						|
  TEdit_field& e = efield(id);
 | 
						|
  CHECK(e.size() >= 15, "Campo troppo piccolo per contenere un importo");
 | 
						|
  if (!imp.is_zero())
 | 
						|
  {
 | 
						|
    const TCurrency c(imp.valore());
 | 
						|
    TString80 str;
 | 
						|
    str << c.string(true) << ' ' << imp.sezione();
 | 
						|
    e.set(str);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    e.reset();
 | 
						|
}
 | 
						|
 | 
						|
#define get_row_bool(sheet, row, id)    (row).get_char(sheet.cid2index(id))=='X'
 | 
						|
#define get_row_int(sheet, row, id)     (row).get_int(sheet.cid2index(id))
 | 
						|
#define get_row_str(sheet, row, id)     (row).get(sheet.cid2index(id))
 | 
						|
#define get_row_real(sheet, row, id)    real((row).get(sheet.cid2index(id)))
 | 
						|
 | 
						|
#define set_row_bool(sheet, row, id, n) (row).add(n ? "X" : "", sheet.cid2index(id))
 | 
						|
#define set_row_int(sheet, row, id, n)  (row).add(n, sheet.cid2index(id))
 | 
						|
#define set_row_str(sheet, row, id, n)  (row).add(n, sheet.cid2index(id))
 | 
						|
 | 
						|
static bool set_row_currency(const TSheet_field& sheet, TToken_string& row, short id, const real& n)
 | 
						|
{
 | 
						|
  const TMask& m = sheet.sheet_mask();
 | 
						|
  const TCurrency_field& cf = (const TCurrency_field&)m.field(id);
 | 
						|
  TOperable_field* vf = cf.driver(0);
 | 
						|
  if (vf != NULL && !vf->empty()) // E' un importo in valuta?
 | 
						|
  {
 | 
						|
    const TString& codval = vf->get();
 | 
						|
    if (is_true_value(codval)) // La valuta e' diversa dall'euro?
 | 
						|
    {
 | 
						|
      if (n.is_zero())
 | 
						|
        set_row_str(sheet, row, id, "");
 | 
						|
      else
 | 
						|
      {
 | 
						|
        const TCurrency cur(n, codval);
 | 
						|
        set_row_str(sheet, row, id, cur.get_num().string());
 | 
						|
      }
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (n.is_zero())
 | 
						|
    set_row_str(sheet, row, id, "");
 | 
						|
  else
 | 
						|
    set_row_str(sheet, row, id, n.string(-1, 2));
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
void TEasySolder_mask::save_sheet()
 | 
						|
{
 | 
						|
  // Memorizza i dati del cambio da salvare sulle righe di partita
 | 
						|
  TValuta valuta; valuta.get(*this, G_VALUTA, G_DATACAMBIO, G_CAMBIO); 
 | 
						|
 | 
						|
  const TCausale& causale = app().causale();
 | 
						|
      
 | 
						|
  TSheet_field& s = sfield(G_SHEET);
 | 
						|
  FOR_EACH_SHEET_ROW(s, r, row_ptr)
 | 
						|
  {
 | 
						|
    TToken_string& row = *row_ptr;
 | 
						|
    const int      anno    = get_row_int(s, row, S_ANNO);
 | 
						|
    const TString8 numpart = get_row_str(s, row, S_PARTITA);
 | 
						|
    const int      rigaf   = get_row_int(s, row, S_RIGAF);
 | 
						|
    const int      nrata   = get_row_int(s, row, S_RATA);
 | 
						|
    const bool     goodrat = nrata > 0 && nrata < TPartita::UNASSIGNED;
 | 
						|
          int      nrigp   = get_row_int(s, row, S_RIGAP);
 | 
						|
    const real     importo = get_row_real(s, row, S_IMPORTO);
 | 
						|
    const real     ritfis  = valuta.in_valuta() ? ZERO : get_row_real(s, row, S_RITFIS);
 | 
						|
    const real     ritsoc  = valuta.in_valuta() ? ZERO : get_row_real(s, row, S_RITSOC);
 | 
						|
    const bool     a_saldo = goodrat && get_row_bool(s, row, S_SALDO);
 | 
						|
    const TTipo_pag tipopag = (TTipo_pag)get_row_int(s, row, S_MODOPAG);
 | 
						|
    const TDate    datapag = get_row_str(s, row, S_DATAPAG);
 | 
						|
 | 
						|
    if (a_saldo || !importo.is_zero() || !ritfis.is_zero() || !ritsoc.is_zero() || nrigp > 0)
 | 
						|
    {
 | 
						|
      TPartita& partita = app().partite().partita(_conto, anno, numpart);
 | 
						|
      if (nrigp <= 0)
 | 
						|
      {
 | 
						|
        TRiga_partite& part = partita.new_row();  // Creazione nuova riga vuota
 | 
						|
        nrigp = part.get_int(PART_NRIGA);         // Nuova riga
 | 
						|
        set_row_int(s, row, S_RIGAP, nrigp);
 | 
						|
        part.put(PART_SEZ, calcola_sezione());  
 | 
						|
      }
 | 
						|
 | 
						|
      TRiga_partite& part = partita.riga(nrigp);  // Riga pagamento 
 | 
						|
 | 
						|
      // Setta il cambio corrente
 | 
						|
      valuta.put(part);
 | 
						|
 | 
						|
      // Copia dati di testata movimento
 | 
						|
      TMask& cm = app().curr_mask();
 | 
						|
      part.put(PART_NREG,   _numreg);             // Numero operazione
 | 
						|
      part.put(PART_NUMRIG, _numrig);             // Riga su cui ho cliccato
 | 
						|
      part.put(PART_NUMDOC,  cm.get(F_NUMDOC));
 | 
						|
      part.put(PART_DATADOC, cm.get(F_DATADOC));
 | 
						|
      part.put(PART_DATAREG, cm.get(F_DATAREG));
 | 
						|
      part.put(PART_DESCR,   cm.get(F_DESCR));
 | 
						|
      part.put(PART_DATAPAG, datapag);
 | 
						|
      part.put(PART_TIPOPAG, tipopag); 
 | 
						|
  
 | 
						|
      // Copia dati causale corrente
 | 
						|
      part.put(PART_CODCAUS, causale.codice());
 | 
						|
      part.put(PART_TIPOMOV, causale.tipomov());       
 | 
						|
      if (causale.iva() != nessuna_iva)
 | 
						|
      {
 | 
						|
        part.put(PART_REG,     cm.get(F_CODREG));
 | 
						|
        part.put(PART_PROTIVA, cm.get(F_PROTIVA));
 | 
						|
      }   
 | 
						|
 | 
						|
      TRectype newpag = partita.pagamento(rigaf, nrata, nrigp);
 | 
						|
      newpag.put(PAGSCA_ACCSAL, a_saldo ? 'S' : 'A');
 | 
						|
      
 | 
						|
      if (valuta.in_valuta())
 | 
						|
      {
 | 
						|
        newpag.put(PAGSCA_IMPORTOVAL, importo);
 | 
						|
        const real impeur = get_row_str(s, row, S_IMPORTO_EUR);
 | 
						|
        newpag.put(PAGSCA_IMPORTO, impeur);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        newpag.put(PAGSCA_IMPORTO, importo);
 | 
						|
        newpag.zero(PAGSCA_IMPORTOVAL);
 | 
						|
        newpag.put(PAGSCA_RITENUTE, ritfis);
 | 
						|
        newpag.put(PAGSCA_RITSOC,   ritsoc);
 | 
						|
      }
 | 
						|
 | 
						|
      if (part.tipo() == tm_nota_credito)
 | 
						|
      {
 | 
						|
        const TBill conto_nullo; 
 | 
						|
        conto_nullo.put(newpag, true);   // Azzera conto
 | 
						|
        newpag.zero(PAGSCA_CODABIPR);
 | 
						|
        newpag.zero(PAGSCA_CODCABPR);
 | 
						|
        app().notify_edit_pagamento(partita, newpag, valuta, importo.is_zero() ? _numrig : 0);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        TBill conto_banca; 
 | 
						|
        conto_banca.get(*this, G_GRUPPOC, G_CONTOC, G_SOTTOCONTOC);
 | 
						|
        conto_banca.put(newpag, true);   
 | 
						|
        newpag.put(PAGSCA_CODABIPR, get(G_ABI));
 | 
						|
        newpag.put(PAGSCA_CODCABPR, get(G_CAB));
 | 
						|
        app().notify_edit_pagamento(partita, newpag, valuta, importo.is_zero() ? _numrig : 0);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  app().cgs().force_update();
 | 
						|
}
 | 
						|
 | 
						|
long TEasySolder_mask::handler(WINDOW w, EVENT* ep)
 | 
						|
{
 | 
						|
  // Ordinamento col click destro sull'intestazione colonna
 | 
						|
  if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1)
 | 
						|
  {  
 | 
						|
    short id = DLG_NULL;
 | 
						|
    long rec = -1;
 | 
						|
    FOR_EACH_MASK_SHEET(*this, i, s)
 | 
						|
    {
 | 
						|
      if (s->parent() == w && s->point2cell(ep->v.mouse.where, id, rec) && rec < 0)
 | 
						|
      {
 | 
						|
        const char* st = NULL;
 | 
						|
        switch (id)
 | 
						|
        {
 | 
						|
        case S_DATADOC : 
 | 
						|
        case S_NUMDOC  : st = "C"; break; // Data+Numero documento
 | 
						|
        case S_IMPORTO : st = "I"; break; // Importo pagamento (o insoluto)
 | 
						|
        case S_MODOPAG : st = "M"; break; // Modalità di pagamento
 | 
						|
        case S_RESIDUO : st = "R"; break; // Residuo rata
 | 
						|
        case S_TOTALE  : st = "T"; break; // Totale rata
 | 
						|
        case S_DATASCAD: st = "D"; break; // Data scadenza
 | 
						|
        default: if (id >= S_ANNO && id <= S_RIGAP) st = "P"; break; // Anno+Partita+Riga
 | 
						|
        }
 | 
						|
        if (st && *st)
 | 
						|
          set(G_SORT, st, 0x1);
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return TAutomask::handler(w, ep);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_fields(TSheet_field& sheet, int r1, int r2, const short* const ids)
 | 
						|
{
 | 
						|
  const TToken_string& row1 = sheet.row(r1);
 | 
						|
  const TToken_string& row2 = sheet.row(r2);
 | 
						|
 | 
						|
  long diff = 0;
 | 
						|
  for (int i = 0; ids[i]>0 && diff==0; i++)
 | 
						|
  {
 | 
						|
    const int idx = sheet.cid2index(ids[i]);
 | 
						|
    switch (ids[i])
 | 
						|
    {
 | 
						|
    case S_DATASCAD:
 | 
						|
    case S_DATADOC:
 | 
						|
      {
 | 
						|
        TDate d1; row1.get(idx, d1);
 | 
						|
        TDate d2; row2.get(idx, d2);
 | 
						|
        long n1 = d1.date2ansi();
 | 
						|
        long n2 = d2.date2ansi();
 | 
						|
        diff = n1-n2;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case S_PARTITA:
 | 
						|
      {
 | 
						|
        TString8 p1; row1.get(idx, p1);
 | 
						|
        TString8 p2; row2.get(idx, p2);
 | 
						|
        diff = p1.compare(p2, -1, true);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case S_IMPORTO:
 | 
						|
    case S_RESIDUO:
 | 
						|
    case S_TOTALE:
 | 
						|
      {
 | 
						|
        real n1, n2;
 | 
						|
        row1.get(idx, n1);
 | 
						|
        row2.get(idx, n2);
 | 
						|
        diff = real(n1-n2).sign();
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      {
 | 
						|
        long n1, n2;
 | 
						|
        row1.get(idx, n1);
 | 
						|
        row2.get(idx, n2);
 | 
						|
        diff = n1-n2;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return diff;
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_date(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_DATASCAD, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_game(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_doc(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_DATADOC, S_NUMDOC, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_imp(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_IMPORTO, S_DATASCAD, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_tot(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_TOTALE, S_DATASCAD, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_res(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_RESIDUO, S_DATASCAD, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
static int sort_by_moda(TSheet_field& sheet, int r1, int r2)
 | 
						|
{
 | 
						|
  // Elenco dei campi da confrontare in ordine di priorita'
 | 
						|
  const short ids[8] = { S_MODOPAG, S_DATASCAD, S_ANNO, S_PARTITA, S_RIGAF, S_RATA, S_RIGAP, DLG_NULL };
 | 
						|
  return sort_by_fields(sheet, r1, r2, ids);
 | 
						|
}
 | 
						|
 | 
						|
real TEasySolder_mask::val2eur(const real& val) const
 | 
						|
{
 | 
						|
  real eur;
 | 
						|
  const TMask& mm = app().curr_mask();
 | 
						|
  const real toteur = mm.get(F_TOTALE);
 | 
						|
  const real totval = mm.get(SK_TOTDOCVAL);
 | 
						|
  
 | 
						|
  if (toteur.is_zero() || totval.is_zero())
 | 
						|
  {
 | 
						|
    const TValuta valuta(mm, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO);
 | 
						|
    eur = valuta.val2eur(val);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    eur = val * toteur / totval;
 | 
						|
    eur.round(2);
 | 
						|
  }
 | 
						|
  return eur;
 | 
						|
}
 | 
						|
 | 
						|
real TEasySolder_mask::eur2val(const real& eur) const
 | 
						|
{
 | 
						|
  real val;
 | 
						|
  const TMask& mm = app().curr_mask();
 | 
						|
  const real toteur = mm.get(F_TOTALE);
 | 
						|
  const real totval = mm.get(SK_TOTDOCVAL);
 | 
						|
  if (toteur.is_zero() || totval.is_zero())
 | 
						|
  {
 | 
						|
    const TValuta valuta(mm, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO);
 | 
						|
    val = valuta.eur2val(eur);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    val = eur * totval / toteur;
 | 
						|
    val.round(2);
 | 
						|
  }
 | 
						|
  return val;
 | 
						|
}
 | 
						|
 | 
						|
TImporto TEasySolder_mask::eur2val(const TImporto& imp) const
 | 
						|
{
 | 
						|
  TImporto eur = imp;
 | 
						|
  eur.valore() = eur2val(imp.valore());
 | 
						|
  return eur;
 | 
						|
}
 | 
						|
 | 
						|
bool TEasySolder_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case DLG_SAVEREC:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      if (!check_fields())
 | 
						|
        return false;
 | 
						|
      save_sheet();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case G_SORT:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      TSheet_field& s = sfield(G_SHEET);
 | 
						|
      switch (o.get()[0])
 | 
						|
      {
 | 
						|
      case 'C': s.sort(sort_by_doc);  break;
 | 
						|
      case 'I': s.sort(sort_by_imp);  break;
 | 
						|
      case 'M': s.sort(sort_by_moda); break;
 | 
						|
      case 'P': s.sort(sort_by_game); break;
 | 
						|
      case 'R': s.sort(sort_by_res);  break;
 | 
						|
      case 'T': s.sort(sort_by_tot);  break;
 | 
						|
      default : s.sort(sort_by_date); break;
 | 
						|
      }
 | 
						|
      s.force_update();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case G_SHEET:
 | 
						|
    switch (e)
 | 
						|
    {
 | 
						|
    case se_enter:
 | 
						|
      {
 | 
						|
        TSheet_field& s = (TSheet_field&)o;
 | 
						|
        TToken_string& row = s.row(jolly); 
 | 
						|
        _anno    = get_row_int(s, row, S_ANNO);
 | 
						|
        _numpart = get_row_str(s, row, S_PARTITA);
 | 
						|
        const int rigaf = get_row_int(s, row, S_RIGAF);
 | 
						|
        const int nrata = get_row_int(s, row, S_RATA);
 | 
						|
        const int nrigp = get_row_int(s, row, S_RIGAP);
 | 
						|
 | 
						|
        if (_tree->goto_single_game(_anno, _numpart, rigaf, nrata, nrigp))
 | 
						|
        {
 | 
						|
          TTree_field& tf = tfield(G_PARTITE);      
 | 
						|
          tf.select_current();
 | 
						|
          tf.win().force_update();
 | 
						|
          reset(G_TUTTE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case se_query_add:
 | 
						|
      {
 | 
						|
        TNew_game_mask m(_conto);
 | 
						|
        if (m.run() == K_ENTER)
 | 
						|
        {
 | 
						|
          // Memorizzo il codice partita in modo da poterlo mettere nella nuova riga
 | 
						|
          _anno = atoi(m.get(PART_ANNO));
 | 
						|
          _numpart = m.get(PART_NUMPART);
 | 
						|
          return true;
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
   case se_notify_add:
 | 
						|
     {
 | 
						|
       // Metto nella nuova riga il codice partita memorizzato sopra
 | 
						|
       TSheet_field& sheet = (TSheet_field&)o;
 | 
						|
       TToken_string& row = sheet.row(jolly);
 | 
						|
       set_row_int(sheet, row, S_ANNO, _anno);
 | 
						|
       set_row_str(sheet, row, S_PARTITA, _numpart);
 | 
						|
       set_row_int(sheet, row, S_RIGAF, TPartita::UNASSIGNED);
 | 
						|
       set_row_int(sheet, row, S_RATA, TPartita::UNASSIGNED);
 | 
						|
       sheet.disable_cell(jolly, S_SALDO);
 | 
						|
     }
 | 
						|
     break;
 | 
						|
   case se_notify_modify:
 | 
						|
     aggiorna_residuo();
 | 
						|
     break;
 | 
						|
    case se_query_del: 
 | 
						|
      return false;
 | 
						|
    default: 
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case G_CAB:
 | 
						|
    if (e == fe_modify && !o.empty() && is_running())
 | 
						|
    {
 | 
						|
      TString16 codtab; codtab << get(G_ABI) << get(G_CAB);
 | 
						|
      const TRectype& bnp = cache().get("BNP", codtab);
 | 
						|
      if (!bnp.empty())
 | 
						|
      {
 | 
						|
        const int g = bnp.get_int("I9");
 | 
						|
        const int c = bnp.get_int("I10");
 | 
						|
        const long s = bnp.get_long("I11");
 | 
						|
        if (g > 0 && c > 0 && s > 0)
 | 
						|
        {
 | 
						|
          set(G_GRUPPOC, g);
 | 
						|
          set(G_CONTOC, c);
 | 
						|
          set(G_SOTTOCONTOC, s, 0x2); // Decodifica descrizione
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case S_SPUNTA:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      TMask& m = o.mask();
 | 
						|
      TSheet_field& s = sfield(G_SHEET);
 | 
						|
 | 
						|
      if (o.get().full())
 | 
						|
      {
 | 
						|
        const real importo = m.get(S_IMPORTO);
 | 
						|
        if (importo.is_zero())
 | 
						|
        {
 | 
						|
          real residuo = m.get(S_RESIDUO);
 | 
						|
          if (residuo.is_zero())
 | 
						|
          {
 | 
						|
            const int anno = m.get_int(S_ANNO);
 | 
						|
            const TString8 num = m.get(S_PARTITA);
 | 
						|
            const int nriga = m.get_int(S_RIGAF);
 | 
						|
            const int nrata = m.get_int(S_RATA);
 | 
						|
            const TPartita& game = app().partite().partita(_conto, anno, num);
 | 
						|
            if (game.esiste(nriga, nrata))
 | 
						|
              residuo = game.rata(nriga, nrata).residuo(true).valore();
 | 
						|
          }
 | 
						|
          if (!residuo.is_zero())
 | 
						|
          {
 | 
						|
            m.set(S_IMPORTO, residuo);
 | 
						|
            if (_tipomov != tm_insoluto && _tipomov != tm_nota_credito)
 | 
						|
              m.set(S_SALDO, true);
 | 
						|
            if (in_valuta())
 | 
						|
            {
 | 
						|
              const real residuo_eur = val2eur(residuo);
 | 
						|
              m.set(S_IMPORTO_EUR, residuo_eur);
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        m.reset(S_IMPORTO);
 | 
						|
        m.reset(S_IMPORTO_EUR);
 | 
						|
        m.reset(S_SALDO);
 | 
						|
      }
 | 
						|
     
 | 
						|
      if (!m.is_running())
 | 
						|
      {
 | 
						|
        const int r = s.selected();
 | 
						|
        s.update_row(r);
 | 
						|
        aggiorna_residuo();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case S_IMPORTO:
 | 
						|
  case S_IMPORTO_EUR:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      if (in_valuta())
 | 
						|
      {
 | 
						|
        const short buddy_id = S_IMPORTO + S_IMPORTO_EUR - o.dlg(); // :-)
 | 
						|
        TEdit_field& buddy_imp = o.mask().efield(buddy_id);
 | 
						|
        if (buddy_imp.empty())
 | 
						|
        {
 | 
						|
          const real imp = o.get();
 | 
						|
          if (buddy_id == S_IMPORTO_EUR)
 | 
						|
            buddy_imp.set(val2eur(imp).string());
 | 
						|
          else
 | 
						|
            buddy_imp.set(eur2val(imp).string());
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (!o.mask().is_running())
 | 
						|
      {
 | 
						|
        TSheet_field& s = sfield(G_SHEET);
 | 
						|
        const int r = s.selected();
 | 
						|
        s.update_row(r);
 | 
						|
        aggiorna_residuo();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case G_TUTTE:
 | 
						|
  case G_INVALUTA:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      TSolder_tree_flags flags = (TSolder_tree_flags)get_int(G_TUTTE); 
 | 
						|
      const TString& codval = get(G_VALUTA);
 | 
						|
      real cambio;
 | 
						|
      if (is_true_value(codval))
 | 
						|
      {
 | 
						|
        cambio = get_real(G_CAMBIO);
 | 
						|
        if (get_bool(G_INVALUTA))
 | 
						|
          flags = TSolder_tree_flags(flags | sct_show_val);
 | 
						|
      }
 | 
						|
      _tree->set_root(app().partite(), _conto, _numreg, _numrig, codval, cambio, flags);
 | 
						|
 | 
						|
      if ((flags & sct_all_games) == sct_single_game)
 | 
						|
      {
 | 
						|
        TSheet_field& s = sfield(G_SHEET);
 | 
						|
        const int sel = s.selected();
 | 
						|
        if (sel >= 0 && sel < s.items())
 | 
						|
          on_field_event(s, se_enter, sel);
 | 
						|
      }
 | 
						|
      else                                  // Partite aperte, chiuse o tutte
 | 
						|
      {
 | 
						|
        if (_tree->goto_root())
 | 
						|
        {
 | 
						|
          if (_tree->has_rbrother())
 | 
						|
            _tree->shrink_all();
 | 
						|
          else
 | 
						|
            _tree->expand_all();
 | 
						|
        }
 | 
						|
        TTree_field& tfp = tfield(G_PARTITE);
 | 
						|
        tfp.win().force_update();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case G_PARTITE:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      TToken_string curr; _tree->curr_id(curr);
 | 
						|
      const int level = curr.items();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default: break;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
static int nrigp_pagamento_locale(const TSolder_tree& st)
 | 
						|
{
 | 
						|
  const TToken_string& curr = *(TToken_string*)st.curr_node();
 | 
						|
  const int level = curr.items();
 | 
						|
  if (level >= 3)
 | 
						|
  {
 | 
						|
    const long nreg_mov = st.num_reg();
 | 
						|
    const int  nrig_mov = st.num_rig();
 | 
						|
    if (level == 3)
 | 
						|
    {
 | 
						|
      const TRiga_scadenze* scad = st.scadenza();
 | 
						|
      if (scad != NULL) // Vera scadenza
 | 
						|
      {
 | 
						|
        for (int nrigp = scad->last(); nrigp > 0; nrigp = scad->pred(nrigp))
 | 
						|
        {
 | 
						|
          const TRiga_partite& riga = scad->partita().riga(nrigp);
 | 
						|
          const long nreg_riga = riga.get_long(PART_NREG);
 | 
						|
          const int nrig_riga = riga.get_int(PART_NUMRIG);
 | 
						|
          if (nreg_riga == nreg_mov && nrig_riga == nrig_mov)
 | 
						|
            return nrigp;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else
 | 
						|
    if (level == 4)
 | 
						|
    {
 | 
						|
      // const int nrigp = st.pagamento()->get_int(PAGSCA_NRIGP);
 | 
						|
      int nrigp = 0; curr.get(3, nrigp);
 | 
						|
      const TRiga_partite& riga = st.partita()->riga(nrigp);
 | 
						|
      const long nreg_riga = riga.get_long(PART_NREG);
 | 
						|
      const int nrig_riga = riga.get_int(PART_NUMRIG);
 | 
						|
      if (nreg_riga == nreg_mov && nrig_riga == nrig_mov)
 | 
						|
        return nrigp;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int has_lonely_nc(TPartita& game)
 | 
						|
{
 | 
						|
  int ncs = 0;
 | 
						|
  const TRecord_array& u = game.unassigned();
 | 
						|
  for (int i = u.last_row(); i > 0; i = u.pred_row(i))
 | 
						|
  {
 | 
						|
    const TRiga_partite& r = game.riga(i);
 | 
						|
    if (r.tipo() == tm_nota_credito)
 | 
						|
    {
 | 
						|
      ncs = i;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ncs;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Aggiunge una nota di credito non associata a fattura
 | 
						|
static bool add_lonely_nc(TPartita& game, TSheet_field& sheet, int rigasheet)
 | 
						|
{
 | 
						|
  int nrigp = has_lonely_nc(game);
 | 
						|
  if (nrigp <= 0)
 | 
						|
    return false;
 | 
						|
  const TRiga_partite& riga = game.riga(nrigp);
 | 
						|
 | 
						|
  TToken_string& row = sheet.row(rigasheet);
 | 
						|
 | 
						|
  const TCausale& causale = app().causale();
 | 
						|
  const char expected_section = causale.sezione_clifo() == 'D' ? 'A' : 'D';
 | 
						|
  
 | 
						|
  TImporto res = game.calcola_saldo(true);
 | 
						|
  res.normalize(expected_section);
 | 
						|
  set_row_currency(sheet, row, S_RESIDUO, res.valore());
 | 
						|
 | 
						|
  TImporto tot = riga.importo(true);
 | 
						|
  tot.normalize(expected_section);
 | 
						|
  set_row_currency(sheet, row, S_TOTALE, tot.valore());
 | 
						|
  
 | 
						|
  set_row_int(sheet, row, S_ANNO, game.anno());
 | 
						|
  set_row_str(sheet, row, S_PARTITA, game.numero());
 | 
						|
  set_row_int(sheet, row, S_RIGAF, TPartita::UNASSIGNED);
 | 
						|
  set_row_int(sheet, row, S_RATA, TPartita::UNASSIGNED);
 | 
						|
  set_row_int(sheet, row, S_RIGAP, 0);  // Lasciare 0 e NON mettere assultamente nrigp o la scambia per pagamento!
 | 
						|
  set_row_str(sheet, row, S_DATASCAD, riga.get(PART_DATAPAG));
 | 
						|
  if (game.in_valuta())
 | 
						|
  {
 | 
						|
    row.add(game.codice_valuta(), sheet.cid2index(S_VALUTA));
 | 
						|
    TImporto reseur = riga.importo(false);
 | 
						|
    reseur.normalize(expected_section);
 | 
						|
    set_row_currency(sheet, row, S_RESIDUO_EUR, reseur.valore());
 | 
						|
  }
 | 
						|
  set_row_str(sheet, row, S_NUMDOC, riga.get(PART_NUMDOC));
 | 
						|
  set_row_str(sheet, row, S_DATADOC, riga.get(PART_DATADOC));
 | 
						|
  const int nrow = sheet.items()-1;
 | 
						|
  sheet.disable_cell(nrow, S_SALDO);
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
// static callback function
 | 
						|
bool TEasySolder_mask::sheet_rate_filler(TTree& tree, void* jolly, word /* flags */)
 | 
						|
{
 | 
						|
  const TSolder_tree& st = (const TSolder_tree&)tree;
 | 
						|
  const TToken_string& curr = *(TToken_string*)st.curr_node();
 | 
						|
  const int level = curr.items();
 | 
						|
  if (level < 3)
 | 
						|
    return false;
 | 
						|
 | 
						|
  int nriga; curr.get(1, nriga);
 | 
						|
  int nrata; curr.get(2, nrata);
 | 
						|
  if (level == 3 && nrata >= TPartita::UNASSIGNED)
 | 
						|
    return false; // Falso nodo dell'albero padre dei non assegnati
 | 
						|
 | 
						|
  TPartita& game = *st.partita();
 | 
						|
  if (!same_values(st.codval(), game.codice_valuta()))
 | 
						|
    return false; // Scadenza in valuta diversa da quella selezionata
 | 
						|
 | 
						|
  int nrigp = nrigp_pagamento_locale(st);
 | 
						|
  bool good_rat = level >= 3 && nrata > 0 && nrata < TPartita::UNASSIGNED;
 | 
						|
  bool good_pag = level == 4 && nrigp > 0;
 | 
						|
  
 | 
						|
  const TRiga_scadenze* scad = good_rat ? st.scadenza() : NULL;
 | 
						|
  if (good_rat && scad == NULL)
 | 
						|
  {
 | 
						|
    CHECKD(false, "Rata nulla inattesa ", nrata); // Segnalazione 1867
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  TSheet_field& sheet = *(TSheet_field*)jolly;
 | 
						|
 | 
						|
  const TCausale& causale = app().causale();
 | 
						|
  const tipo_movimento tm = causale.tipomov();
 | 
						|
  
 | 
						|
  const char pag_section = ((TEasySolder_mask&)sheet.mask()).calcola_sezione();
 | 
						|
  const char rat_section = pag_section == 'D' ? 'A' : 'D';
 | 
						|
 | 
						|
  switch (tm)
 | 
						|
  {
 | 
						|
  case tm_nota_credito:
 | 
						|
  case tm_pagamento:
 | 
						|
  case tm_pagamento_insoluto:
 | 
						|
    if (level == 3)
 | 
						|
    {
 | 
						|
      if (good_rat)
 | 
						|
        good_rat = nrigp <= 0 && !scad->chiusa();
 | 
						|
    } 
 | 
						|
    else
 | 
						|
      good_rat &= good_pag;
 | 
						|
    break;
 | 
						|
  case tm_insoluto:
 | 
						|
    if (level == 3)
 | 
						|
    {
 | 
						|
      if (good_rat && nrigp <= 0)
 | 
						|
        good_rat = !scad->importo_pagato(true).is_zero();
 | 
						|
      else
 | 
						|
        good_rat = false;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      good_rat &= good_pag;
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    good_rat = good_pag = false;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (good_rat || good_pag) // Creo una nuova riga solo se necessario
 | 
						|
  {
 | 
						|
    TToken_string& row = sheet.row(-1);
 | 
						|
    row.add(game.codice_valuta(), sheet.cid2index(S_VALUTA));
 | 
						|
    if (good_rat)
 | 
						|
    {
 | 
						|
      TImporto res;
 | 
						|
      if (tm == tm_insoluto)
 | 
						|
      {
 | 
						|
        res = scad->importo_pagato(true);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        res = scad->residuo(true);
 | 
						|
        res.normalize(rat_section);
 | 
						|
      }
 | 
						|
      set_row_currency(sheet, row, S_RESIDUO, res.valore());
 | 
						|
      const TImporto tot = scad->importo(true);
 | 
						|
      set_row_currency(sheet, row, S_TOTALE, tot.valore());
 | 
						|
      set_row_int(sheet, row, S_ANNO, game.anno());
 | 
						|
      set_row_str(sheet, row, S_PARTITA, game.numero());
 | 
						|
      set_row_int(sheet, row, S_RIGAF, nriga);
 | 
						|
      set_row_int(sheet, row, S_RATA, nrata);
 | 
						|
      set_row_str(sheet, row, S_DATASCAD, scad->get(SCAD_DATASCAD));
 | 
						|
      set_row_str(sheet, row, S_MODOPAG, scad->get(SCAD_TIPOPAG)); // Solo proposta
 | 
						|
      if (game.in_valuta())
 | 
						|
      {
 | 
						|
        // Calcola il residuo rata utilizzando il cambio della fattura e non quello del pagamento
 | 
						|
        const TImporto reseur = tm == tm_insoluto ? scad->importo_pagato(false) : scad->residuo(false);
 | 
						|
        set_row_currency(sheet, row, S_RESIDUO_EUR, reseur.valore());
 | 
						|
      }
 | 
						|
      if (nriga > 0 && nriga < TPartita::UNASSIGNED) // Dovrebbe sempre essere vero, ma ...
 | 
						|
      {
 | 
						|
        const TRiga_partite& riga = game.riga(nriga);
 | 
						|
        set_row_str(sheet, row, S_NUMDOC, riga.get(PART_NUMDOC));
 | 
						|
        set_row_str(sheet, row, S_DATADOC, riga.get(PART_DATADOC));
 | 
						|
        
 | 
						|
        set_row_str(sheet, row, S_NOTE, scad->get(SCAD_DESCR));
 | 
						|
        if (scad->get_bool(SCAD_BLOCCATA))
 | 
						|
        {
 | 
						|
          set_row_bool(sheet, row, S_BLOCCO, true);
 | 
						|
          sheet.disable_cell(sheet.items()-1, -1);
 | 
						|
          const TString8 cbp = scad->get(SCAD_MOTIVO);
 | 
						|
          if (cbp.full())
 | 
						|
          {
 | 
						|
            set_row_str(sheet, row, S_MOTIVO, cbp);
 | 
						|
            set_row_str(sheet, row, S_NOTE, cache().get("%CBP", cbp, "S0"));
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      // Propone data di pagamento per le RIBA
 | 
						|
      if (!good_pag)
 | 
						|
      {
 | 
						|
        TDate dp(TODAY);
 | 
						|
        if (scad->get_int(SCAD_TIPOPAG) > 1)
 | 
						|
        {
 | 
						|
          const TDate ds = scad->get(SCAD_DATASCAD);
 | 
						|
          if (ds > dp)
 | 
						|
            dp = ds;
 | 
						|
        }
 | 
						|
        set_row_str(sheet, row, S_DATAPAG, dp);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (good_pag)
 | 
						|
    {
 | 
						|
      if (!good_rat && nrigp > 1 && has_lonely_nc(game))
 | 
						|
        add_lonely_nc(game, sheet, sheet.items()-1);
 | 
						|
 | 
						|
      const TRiga_partite& rigp = game.riga(nrigp);
 | 
						|
      set_row_int(sheet, row, S_RIGAP, nrigp);
 | 
						|
      set_row_int(sheet, row, S_NREG, rigp.get_long(PART_NREG));
 | 
						|
      set_row_int(sheet, row, S_NRIG, rigp.get_int(PART_NUMRIG));
 | 
						|
 | 
						|
      const TRectype& pag = *st.pagamento();
 | 
						|
      const real imp = pag.get_real(PAGSCA_IMPORTO);
 | 
						|
      if (!imp.is_zero())
 | 
						|
      {
 | 
						|
        set_row_bool(sheet, row, S_SPUNTA, true);
 | 
						|
        if (rigp.in_valuta())
 | 
						|
        {
 | 
						|
          const real impval = pag.get_real(PAGSCA_IMPORTOVAL);
 | 
						|
          set_row_currency(sheet, row, S_IMPORTO, impval);
 | 
						|
          set_row_currency(sheet, row, S_IMPORTO_EUR, imp);
 | 
						|
        }
 | 
						|
        else
 | 
						|
          set_row_currency(sheet, row, S_IMPORTO, imp);
 | 
						|
      }
 | 
						|
      set_row_str(sheet, row, S_SALDO, (good_rat && pag.get_char(PAGSCA_ACCSAL)=='S') ? "X" : "");
 | 
						|
      set_row_int(sheet, row, S_MODOPAG, rigp.get_int(PART_TIPOPAG));
 | 
						|
      set_row_currency(sheet, row, S_RITFIS, pag.get_real(PAGSCA_RITENUTE));
 | 
						|
      set_row_currency(sheet, row, S_RITSOC, pag.get_real(PAGSCA_RITSOC));
 | 
						|
 | 
						|
      set_row_int(sheet, row, S_ANNO, game.anno());
 | 
						|
      set_row_str(sheet, row, S_PARTITA, game.numero());
 | 
						|
      set_row_int(sheet, row, S_RIGAF, nriga);
 | 
						|
      set_row_int(sheet, row, S_RATA, nrata);
 | 
						|
      set_row_str(sheet, row, S_MODOPAG, rigp.get(PART_TIPOPAG)); 
 | 
						|
      if (good_rat)
 | 
						|
      {
 | 
						|
        set_row_str(sheet, row, S_DATAPAG, rigp.get(PART_DATAPAG));
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        set_row_str(sheet, row, S_DATASCAD, rigp.get(PART_DATAPAG));
 | 
						|
        const int nrow = sheet.items()-1;
 | 
						|
        sheet.disable_cell(nrow, S_SALDO);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    // Nota di credito non assegnata e senza pagamenti in questo movimento
 | 
						|
    if (level == 4 && nriga == TPartita::UNASSIGNED && nrigp == 0 && has_lonely_nc(game))
 | 
						|
    {
 | 
						|
      const TImporto sld = game.calcola_saldo(true);
 | 
						|
      if (!sld.is_zero())
 | 
						|
        add_lonely_nc(game, sheet, -1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
// Complesso algoritmo per calcolare la sezione di una nuova riga partita
 | 
						|
char TEasySolder_mask::calcola_sezione() const
 | 
						|
{ 
 | 
						|
  const char tipoc = _conto.tipo();
 | 
						|
  const TCausale& causale = app().causale();
 | 
						|
  char sezione = causale.sezione_clifo();           // Usa la sezione della causale
 | 
						|
  
 | 
						|
  if (sezione != 'A' && sezione != 'D')             // Se non c'e' la sezione bell'e' ch'e' pronta
 | 
						|
  {
 | 
						|
    const tipo_movimento tm = causale.tipomov();
 | 
						|
    if (tm == tm_fattura || tm == tm_insoluto)      // calcola in base al tipo movimento e
 | 
						|
      sezione = (tipoc == 'C') ? 'D' : 'A';         // al tipo cliente/fornitore
 | 
						|
    else  
 | 
						|
      sezione = (tipoc == 'C') ? 'A' : 'D';
 | 
						|
  }
 | 
						|
 | 
						|
  // Gestione compensazioni
 | 
						|
  if (tipoc > ' ')                                  // Se il tipo e' C o F
 | 
						|
  {
 | 
						|
    TBill bill; causale.bill(1, bill);              // Legge primo conto causale
 | 
						|
    const char tc = bill.tipo();
 | 
						|
    if (tc > ' ' && tc != tipoc)
 | 
						|
      sezione = (sezione == 'D') ? 'A' : 'D';       // inverti sezione
 | 
						|
  }
 | 
						|
 | 
						|
  return sezione;
 | 
						|
}
 | 
						|
 | 
						|
bool TEasySolder_mask::in_valuta() const
 | 
						|
{
 | 
						|
  const TString& codval = get(G_VALUTA);
 | 
						|
  return is_true_value(codval);
 | 
						|
}
 | 
						|
 | 
						|
void TEasySolder_mask::calcola_residuo()
 | 
						|
{
 | 
						|
  TImporto impriga = app().get_cgs_imp(_numrig-1); // Importo sulla riga contabile
 | 
						|
  set(G_TOTALE, impriga.valore());
 | 
						|
 | 
						|
  TImporto residuo = impriga;
 | 
						|
  TPartite_array& giochi = app().partite();
 | 
						|
  const TImporto speso = giochi.importo_speso(_numreg, _numrig); 
 | 
						|
  residuo -= speso;                   // Residuo della riga
 | 
						|
 | 
						|
  const char sez = calcola_sezione(); // Sezione di riferimento
 | 
						|
  residuo.normalize(sez);
 | 
						|
  const real segno_ritsoc = app().causale().sezione_ritsoc() == sez ? UNO : -UNO;
 | 
						|
 | 
						|
  _res_eur = residuo.valore();
 | 
						|
  set(G_RESIDUO_EUR, _res_eur);
 | 
						|
 | 
						|
  const bool in_val = in_valuta();
 | 
						|
  if (in_val)
 | 
						|
  {                                                                         
 | 
						|
    // Importo della riga contabile senza differenza cambi
 | 
						|
    TImporto resval = impriga;
 | 
						|
    const TImporto abb_diff = giochi.importo_speso(_numreg, _numrig, false, 0x6);
 | 
						|
    resval -= abb_diff;
 | 
						|
    resval = eur2val(resval);
 | 
						|
    
 | 
						|
    TImporto spesoval = giochi.importo_speso(_numreg, _numrig, true, 0x1);
 | 
						|
    resval -= spesoval; // Residuo della riga
 | 
						|
    resval.normalize(sez);
 | 
						|
    _res_val = resval.valore();
 | 
						|
    set(G_RESIDUO_VAL, _res_val);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    _res_val = _res_eur;
 | 
						|
    reset(G_RESIDUO_VAL);
 | 
						|
  }
 | 
						|
 | 
						|
  TSheet_field& s = sfield(G_SHEET);
 | 
						|
  _tot_val = _tot_eur = ZERO;
 | 
						|
  FOR_EACH_SHEET_ROW(s, i, row)
 | 
						|
  {
 | 
						|
    if (in_val)
 | 
						|
    {
 | 
						|
      _tot_val += get_row_real(s, *row, S_IMPORTO);
 | 
						|
      _tot_eur += get_row_real(s, *row, S_IMPORTO_EUR);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      _tot_eur += get_row_real(s, *row, S_IMPORTO);
 | 
						|
      _tot_eur += get_row_real(s, *row, S_RITFIS);
 | 
						|
      _tot_eur += get_row_real(s, *row, S_RITSOC) * segno_ritsoc;
 | 
						|
      
 | 
						|
      _tot_val = _tot_eur;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TEasySolder_mask::aggiorna_residuo()
 | 
						|
{
 | 
						|
  const TCausale& caus = app().causale();
 | 
						|
  const real segno_ritsoc = caus.sezione_clifo() == caus.sezione_ritsoc() ? UNO : -UNO;
 | 
						|
  const TSheet_field& s = sfield(G_SHEET);
 | 
						|
  const bool in_val = in_valuta();
 | 
						|
 | 
						|
  real totval, toteur;
 | 
						|
  FOR_EACH_SHEET_ROW(s, i, row)
 | 
						|
  {
 | 
						|
    if (in_val)
 | 
						|
    {
 | 
						|
      totval += get_row_real(s, *row, S_IMPORTO);
 | 
						|
      toteur += get_row_real(s, *row, S_IMPORTO_EUR);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      toteur += get_row_real(s, *row, S_IMPORTO);
 | 
						|
 | 
						|
      // Gestisco le ritenute solo per i movimenti in Euro
 | 
						|
      toteur += get_row_real(s, *row, S_RITFIS);                // Ritfis ha sempre la sezione dell'importo
 | 
						|
      toteur += get_row_real(s, *row, S_RITSOC) * segno_ritsoc; // Ritsoc puo' avere segno contrario
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const real reseur = _res_eur + _tot_eur - toteur;
 | 
						|
  set(G_RESIDUO_EUR, reseur);
 | 
						|
  if (in_val)
 | 
						|
  {
 | 
						|
    const real resval = _res_val + _tot_val - totval;
 | 
						|
    set(G_RESIDUO_VAL, resval);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    reset(G_RESIDUO_VAL);
 | 
						|
}
 | 
						|
 | 
						|
void TEasySolder_mask::fill_sheet()
 | 
						|
{
 | 
						|
  TSheet_field& s = sfield(G_SHEET);
 | 
						|
  s.destroy();
 | 
						|
 | 
						|
  const TString& codval = get(G_VALUTA);
 | 
						|
  const real cambio = get(G_CAMBIO);
 | 
						|
 | 
						|
  s.enable_column(S_SALDO, _tipomov != tm_insoluto && _tipomov != tm_nota_credito);
 | 
						|
 | 
						|
  const bool in_val = in_valuta();
 | 
						|
  s.enable_column(S_IMPORTO_EUR, in_val);
 | 
						|
  s.enable_column(S_RITFIS, !in_val);
 | 
						|
  s.enable_column(S_RITSOC, !in_val);
 | 
						|
 | 
						|
  if (_tipomov == tm_insoluto)
 | 
						|
  {
 | 
						|
    s.set_column_header(S_IMPORTO, HR("Importo\nInsoluto"));
 | 
						|
    s.set_column_header(S_RESIDUO, HR("Importo\nPagato"));
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    s.set_column_header(S_IMPORTO, HR("Importo\nPagamento"));
 | 
						|
    s.set_column_header(S_RESIDUO, HR("Residuo\nScadenza"));
 | 
						|
  }
 | 
						|
  s.set_column_justify(S_PARTITA, TPartita::allineamento_richiesto(_conto.tipo()) == 'R');
 | 
						|
 | 
						|
  TSolder_tree_flags flags = sct_open_games; 
 | 
						|
  if (_tipomov == tm_insoluto || _tipomov == tm_nota_credito)
 | 
						|
    flags = sct_all_games;
 | 
						|
 | 
						|
  _tree->set_root(app().partite(), _conto, _numreg, _numrig, codval, cambio, flags);
 | 
						|
  _tree->scan_depth_first(sheet_rate_filler, &s);
 | 
						|
 | 
						|
  on_field_event(lfield(G_SORT), fe_modify, 0);
 | 
						|
 | 
						|
  FOR_EACH_SHEET_ROW_BACK(s, r, riga)
 | 
						|
  {
 | 
						|
    if (riga->get_char(0) == 'X')
 | 
						|
    {
 | 
						|
      s.post_select(r);
 | 
						|
      first_focus(G_SHEET);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  calcola_residuo();
 | 
						|
}
 | 
						|
 | 
						|
void TEasySolder_mask::init(const TBill& conto, long numreg, int numrig)
 | 
						|
{
 | 
						|
  _conto = conto;
 | 
						|
  _numreg= numreg;
 | 
						|
  _numrig = numrig;
 | 
						|
  _tipomov = app().causale().tipomov();
 | 
						|
  _changed = false;
 | 
						|
 | 
						|
  if (_conto.tipo() > ' ')
 | 
						|
    _conto.set(*this, 0, 0, G_CODCF, G_TIPOCF, G_RAGSOC);
 | 
						|
  else
 | 
						|
    _conto.set(*this, 0, 0, 0, G_TIPOCF, G_RAGSOC);
 | 
						|
 | 
						|
  TMask& cm = app().curr_mask();
 | 
						|
  const TString& codval = cm.get(SK_VALUTA);
 | 
						|
  if (is_true_value(codval))
 | 
						|
  {
 | 
						|
    set(G_VALUTA, codval);
 | 
						|
    set(G_CAMBIO, cm.get(SK_CAMBIO));
 | 
						|
    set(G_DATACAMBIO, cm.get(SK_DATACAMBIO));
 | 
						|
    set(G_INVALUTA, "X");
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    reset(G_VALUTA);
 | 
						|
    reset(G_CAMBIO);
 | 
						|
    reset(G_DATACAMBIO);
 | 
						|
    reset(G_INVALUTA);
 | 
						|
  }    
 | 
						|
  reset(G_TUTTE);
 | 
						|
 | 
						|
  TBill controbill; 
 | 
						|
  const int riga_i = app().type2pos('I');
 | 
						|
  if (riga_i >= 0)
 | 
						|
  {
 | 
						|
    TToken_string& row = app().cgs().row(riga_i);
 | 
						|
    controbill.get(row, 2, 0xF);
 | 
						|
  } 
 | 
						|
  else
 | 
						|
    app().causale().bill(2, controbill);
 | 
						|
  if (controbill.gruppo() > 0) // con controbill.ok() non presentava assolutamente i conti parziali
 | 
						|
  {
 | 
						|
    controbill.set(*this, G_GRUPPOC, G_CONTOC, G_SOTTOCONTOC, 0, G_DESCONTOC);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    for (short id = G_ABI; id <= G_DESCONTOC; id++)
 | 
						|
      reset(id);
 | 
						|
  }
 | 
						|
  
 | 
						|
  // Nel caso di nota di credito devo nascondere il conto (fuorviante)
 | 
						|
  for (short id = G_ABI; id <= G_DESCONTOC; id++)
 | 
						|
    show(id, _tipomov != tm_nota_credito);
 | 
						|
 | 
						|
  if (_tree == NULL)
 | 
						|
  {
 | 
						|
    _tree = new TSolder_tree;
 | 
						|
    tfield(G_PARTITE).set_tree(_tree);
 | 
						|
  }
 | 
						|
 | 
						|
  fill_sheet();
 | 
						|
}
 | 
						|
 | 
						|
TEasySolder_mask::TEasySolder_mask(const TBill& conto, long numreg, int numrig) 
 | 
						|
                : TAutomask("cg2100e"), _tree(NULL)
 | 
						|
{ init(conto, numreg, numrig); }
 | 
						|
 | 
						|
TEasySolder_mask::~TEasySolder_mask()
 | 
						|
{
 | 
						|
  if (_tree != NULL)
 | 
						|
    delete _tree;
 | 
						|
}
 | 
						|
 |