campo-sirio/include/validate.cpp
guy 3e25e35ae6 Patch level : 10.0
Files correlati     : ba8
Ricompilazione Demo : [ ]
Commento            :

Riassunto	 0001600: Dopo la stampa di un report in orizz ritorna in visual con il foglio in vert.
Faccio l'anteprima di un report creato con orientamento foglio orrizzontale fisso, dopo aver stampato ritorna in visualizzazione con l'orientamento del foglio impostato sulla stampante (normalmente in verticale)


git-svn-id: svn://10.65.10.50/trunk@20331 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-04-13 14:30:29 +00:00

1180 lines
28 KiB
C++
Executable File

#include <diction.h>
#include <expr.h>
#include <isam.h>
#include <mask.h>
#include <validate.h>
#include <defmask.h>
#include <comuni.h>
#include <nditte.h>
typedef bool (*VAL_FUNC)(TMask_field&, KEY k);
HIDDEN const TString_array* _parms;
HIDDEN int get_val_param_count()
{ return _parms->items(); }
HIDDEN const TString& get_val_param(int i)
{
const TString* str = (const TString*)_parms->objptr(i);
if (str && *str)
return *str;
return EMPTY_STRING;
}
HIDDEN int get_int_val_param(int i)
{ return atoi(get_val_param(i)); }
HIDDEN const TString& get_fld_val_param(const TMask_field& f, int i)
{
const TString & id = get_val_param(i);
return f.evaluate_field(id);
}
HIDDEN bool _expr_val(TMask_field& f, KEY)
{
const TMask& m = f.mask();
const TTypeexp type = get_int_val_param(0) == 0 ? _numexpr : _strexpr;
TExpression e(get_val_param(1), type);
for (int i = 0; i < e.numvar(); i++)
{
const char* s = e.varname(i);
if (s[0] != '#')
{
TString err; err << TR("Le variabili devono cominciare con #") << ": " << s << '\n' << e;
return f.error_box((const char*)err);
}
if (type == _numexpr)
{
const real r = f.evaluate_field(s);
e.setvar(i, r);
}
else
e.setvar(i, f.evaluate_field(s));
}
return bool(e);
}
HIDDEN bool _emptycopy_val(TMask_field& f, KEY)
{
if (f.empty())
{
const TString& val = get_fld_val_param(f, 0);
if (val.not_empty())
{
f.set(val);
f.on_hit();
}
}
return true;
}
HIDDEN bool check_pi_estera(const TString& st, const TString& paiva)
{
/*
const char* stpi[] = { "AT09", "BE10", "DE09", "DK08", "EL08", "ES09",
"FI08", "FR11", "GB05", "GB09", "GB12", "IE08",
"LU08", "NL12", "PT09", "SE12", "SM05", NULL };
bool lenok = false;
bool known = false;
for (int g = 0; stpi[g] && !lenok; g++)
{
if (st.compare(stpi[g], 2, true) == 0) // Se lo stato corrisponde
{
known = true;
lenok = paiva.len() == atoi(stpi[g]+2); // Confronto lunghezza
}
else
{
if (known) // Inutile cercare ancora
break;
}
}
if (known)
{
if (lenok)
{
if (st=="AT") // Controllo speciale per l'Austria che comincia per U
lenok = paiva[0] == 'U' && real::is_natural(paiva.mid(1)); else
if (st=="BE") // Controllo speciale per il Belgio che comincia per 0
lenok = paiva[0] == '0' && real::is_natural(paiva); else
if (st=="NL") // Controllo speciale per l'Olanda che ha una B in posizione 10
lenok = paiva[9] == 'B' && real::is_natural(paiva.left(9));
}
}
else
lenok = true; // Gli stati ignoti hanno sempre lunghezza corretta!
return lenok;
*/
const int len = paiva.len();
const char* p = paiva;
const bool nat = real::is_natural(p);
if (st == "AT")
return len == 9 && p[0] =='U' && real::is_natural(p+1);
if (st == "BE")
return len == 10 && p[0] =='0' && nat;
if (st == "DE")
return len == 9 && nat;
if (st == "DK")
return len == 8 && nat;
if (st == "EL")
return len == 9 && nat;
if (st == "ES")
return len == 9 && !(isdigit(p[0] && isdigit(p[8])) && real::is_natural(paiva.mid(1,7)));
if (st == "IT")
return len == 11 && nat; // Ridondante ma documentante
if (st == "HU")
return len == 8 && nat;
if (st == "FI")
return len == 8 && nat;
if (st == "FR")
return len == 11 && real::is_natural(p+2);
if (st == "GB")
return (len == 5 && real::is_natural(p+2)) || ((len == 9 || len == 12) && nat);
if (st == "IE")
return len == 8;
if (st == "LU")
return len == 8 && nat;
if (st == "NL")
return len == 12 && paiva[9] == 'B' && real::is_natural(paiva.left(9));
if (st == "PL")
return len == 10 && nat;
if (st == "PT")
return len == 9 && nat;
if (st == "RO")
return len >= 2 && len <= 10 && nat;
if (st == "SE")
return len == 12 && nat;
if (st == "SM")
return len == 5;
return paiva.full(); // Gli stati ignoti hanno sempre lunghezza corretta!
}
// @doc EXTERNAL
// @func Controlla se la Partita IVA assume un valore valido
//
// @rdesc Ritorna i seguenti valori:
//
// @flag true | Se il valore della Partita IVA assume un valore corretto
// @flag false | Se il valore della Partita IVA non puo' essere valido
bool pi_check(
const char* st, // @parm Stato di assegnazione della Partita IVA
const char* paiva) // @parm Codice della Partita IVA da controllare
{
const TFixed_string stato(st);
const TFixed_string pi(paiva);
if (pi.blank())
return true;
bool ok = true; // Assumiamo ottimisticamente che tutto va be'
if (stato.blank() || stato == "IT")
{
// Testa partita iva italiana
ok = pi.len() == 11 && real::is_natural(pi);
if (ok)
{
int tot = 0, y;
for (int i = 0; i <= 9; i++)
{
if ((i + 1) & 0x0001)
tot += (pi[i] - '0');
else
{
y = (pi[i] - '0') * 2;
if (y >= 10)
{
tot += (y / 10);
y = y % 10;
}
tot += y;
}
}
y = 10 - (tot % 10);
if (y == 10) y = 0;
ok = (pi[10] == (y + '0'));
}
}
else
{
ok = check_pi_estera(stato, pi);
}
return ok;
}
// Controlla la partita iva se e' non vuota ed italiana
HIDDEN bool _pi_val(TMask_field& f, KEY)
{
const TMask& m = f.mask();
if (m.query_mode())
return true;
const TString& stato = m.get(get_int_val_param(0));
const TString& pi = f.get();
bool ok = pi_check (stato, pi);
if (!ok)
{
if (f.dirty())
{
bool len_error = true;
if (stato.blank() || stato == "IT")
len_error = pi.len() != 11;
TString msg = len_error ? TR("Lunghezza partita IVA errata") : TR("Partita IVA errata");
msg << ": " << TR("proseguire ugualmente?");
ok = f.yesno_box(msg);
if (ok) f.set_dirty(false);
}
else ok = true; // Era gia' errata e la ho accettata
}
return ok;
}
HIDDEN bool __cf_check (const char* codcf)
{
const TFixed_string cf(codcf);
if (cf.len() != 16)
return false;
const TFixed_string tab("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
int tot = 0, y;
byte val[36][2];
val[0][0] = 0; val[0][1] = 1;
val[1][0] = 1; val[1][1] = 0;
val[2][0] = 2; val[2][1] = 5;
val[3][0] = 3; val[3][1] = 7;
val[4][0] = 4; val[4][1] = 9;
val[5][0] = 5; val[5][1] = 13;
val[6][0] = 6; val[6][1] = 15;
val[7][0] = 7; val[7][1] = 17;
val[8][0] = 8; val[8][1] = 19;
val[9][0] = 9; val[9][1] = 21;
val[10][0] = 10; val[10][1] = 2;
val[11][0] = 11; val[11][1] = 4;
val[12][0] = 12; val[12][1] = 18;
val[13][0] = 13; val[13][1] = 20;
val[14][0] = 14; val[14][1] = 11;
val[15][0] = 15; val[15][1] = 3;
val[16][0] = 16; val[16][1] = 6;
val[17][0] = 17; val[17][1] = 8;
val[18][0] = 18; val[18][1] = 12;
val[19][0] = 19; val[19][1] = 14;
val[20][0] = 20; val[20][1] = 16;
val[21][0] = 21; val[21][1] = 10;
val[22][0] = 22; val[22][1] = 22;
val[23][0] = 23; val[23][1] = 25;
val[24][0] = 24; val[24][1] = 24;
val[25][0] = 25; val[25][1] = 23;
val[26][0] = 0; val[26][1] = 1;
val[27][0] = 1; val[27][1] = 0;
val[28][0] = 2; val[28][1] = 5;
val[29][0] = 3; val[29][1] = 7;
val[30][0] = 4; val[30][1] = 9;
val[31][0] = 5; val[31][1] = 13;
val[32][0] = 6; val[32][1] = 15;
val[33][0] = 7; val[33][1] = 17;
val[34][0] = 8; val[34][1] = 19;
val[35][0] = 9; val[35][1] = 21;
for (int i = 0; i <= 14; i++)
{
y = tab.find(cf[i]);
if (y >= 0) tot += val[y][(i + 1) & 0x1];
}
const bool ok = (cf[15] == (tot % 26) + 'A');
return ok;
}
// @doc EXTERNAL
// @func Controlla se il Codice Fiscale assume un valore valido
//
// @rdesc Ritorna i seguenti valori:
//
// @flag true | Se il valore del Codice Fiscale assume un valore corretto
// @flag false | Se il valore del Codice Fiscale non puo' essere valido
bool cf_check (
const char* stato, // @parm Stato di assegnazione del Codice Fiscale
const char* codcf) // @parm Codice Fiscale da controllare
{
bool ok = true;
if (codcf && *codcf)
{
const TFixed_string cf = codcf;
ok = (cf.len() == 11 && isdigit(cf[0])) ? pi_check(stato, cf) : __cf_check(cf);
}
return ok;
}
HIDDEN bool _cf_val(TMask_field& f, KEY key)
{
if (f.mask().query_mode())
return true;
const TString& cf = f.get();
bool ok = true;
if (cf.empty()) return true;
if (cf.len() == 11 && isdigit(cf[0]))
{
const TString& stato = f.mask().get(atoi(get_val_param(0)));
if (stato.full() && stato != "IT")
return true;
ok = pi_check (stato, cf);
}
else
ok = __cf_check(cf);
if (!ok)
{
if(f.dirty())
{
ok = f.yesno_box(TR("Codice fiscale errato: lo accetto ugualmente?"));
if (ok) f.set_dirty(false);
}
else
ok = true; // Era gia' errato al caricamento quindi lo accetto
}
return ok;
}
HIDDEN bool _xt_pi_val(TMask_field& f, KEY key)
{
TMask& m = f.mask();
if (m.query_mode())
return true;
TString16 value = f.get();
if (value.empty())
return f.error_box(TR("Partita IVA obbligatoria"));
if (!_pi_val(f, key))
return true;
const TString& stato = get_fld_val_param(f, 0);
if (stato.blank() || stato == "IT")
{
TLocalisamfile c(LF_COMUNI);
const int pi = atoi(value.mid(7,3));
for (int i = 1 ; i < 3; i++)
{
const TString& com = get_fld_val_param(f, i); // Comune residenza fiscale e residenza
if (com.full())
{
c.zero();
c.put("COM", com);
if (c.read() == NOERR)
{
const int s1 = c.get_int(COM_UFFIVA1);
const int s2 = c.get_int(COM_UFFIVA2);
const int s3 = c.get_int(COM_UFFIVA3);
if (pi != s1 && pi != s2 && pi != s3)
{
TString16 ui; ui.format("%03d", s1);
if (f.yesno_box(FR("Ufficio IVA della partita IVA non congruente: correggere in %s?"),
(const char*)ui))
{
value.overwrite(ui, 7);
f.set(value);
}
}
break;
}
}
}
}
return true;
}
HIDDEN bool _xtz_pi_val(TMask_field& f, KEY key)
{
return f.empty() || _xt_pi_val(f, key);
}
HIDDEN bool _xt_cf_val(TMask_field& f, KEY key)
{
if (f.mask().query_mode())
return true;
TString16 cf = f.get();
if (cf.blank())
return true;
if (!_cf_val(f, key))
return false;
if (cf.len() == 11 && real::is_natural(cf))
{
// if (!_xt_pi_val(f, key)) return false;
// TString16 stato(f.mask().get(atoi(get_val_param(0))));
// if ((stato.not_empty()) && (stato != "IT")) return true;
return true;
}
bool passed = __cf_check(cf);
if (!passed) return true;
TMask& m = f.mask();
TMask_field& fld_sex = m.field(get_int_val_param(1));
TMask_field& fld_dat = m.field(get_int_val_param(2));
TMask_field& fld_com = m.field(get_int_val_param(3));
const char sesso = fld_sex.get()[0];
TString16 data = fld_dat.get();
TString4 com = fld_com.get();
TString16 wm("LMNPQRSTUV");
int p;
if ((p = wm.find(cf[ 6])) >= 0) cf[ 6] = '0' + p;
if ((p = wm.find(cf[ 7])) >= 0) cf[ 7] = '0' + p;
if ((p = wm.find(cf[ 9])) >= 0) cf[ 9] = '0' + p;
if ((p = wm.find(cf[10])) >= 0) cf[10] = '0' + p;
if ((p = wm.find(cf[12])) >= 0) cf[12] = '0' + p;
if ((p = wm.find(cf[13])) >= 0) cf[13] = '0' + p;
if ((p = wm.find(cf[14])) >= 0) cf[14] = '0' + p;
int gn = atoi(cf.mid(9,2));
if ((sesso == 'F' && gn < 40) || (sesso == 'M' && gn > 40))
{
passed = passed = fld_sex.yesno_box(TR("Sesso non congruente al codice fiscale:\n"
"correzione automatica?"));
if (passed) fld_sex.set(sesso == 'M' ? "F" : "M");
else return true;
}
if (gn > 40) gn -= 40; // Aggiusta giorno di nascita delle donne
// Controllo data di nascita
wm = "ABCDEHLMPRST";
if (data.not_empty())
{
const TDate d(data);
int err = 0;
if ((d.year() % 100) != atoi(cf.mid(6, 2)))
err = 1;
if (wm[d.month() - 1] != cf[8])
err = 2;
if (d.day() != gn)
err = 3;
if (err != 0)
{
const char* const what = err==1 ? TR("Anno") : (err==2 ? TR("Mese") : TR("Giorno"));
passed = fld_dat.yesno_box(FR("%s di nascita non congruente al codice fiscale: correzione automatica?"), what);
if (passed) data.cut(0);
else return true;
}
}
if (data.blank())
{
const int mn = wm.find(cf[8]) + 1;
if (mn > 0)
{
int anno = atoi(cf.mid(6, 2));
anno += anno < 5 ? 2000 : 1900;
const TDate d(gn, mn, anno);
fld_dat.set(d.string());
}
}
// Controllo del comune di nascita
const char* const codcom = cf.mid(11, 4);
if (com.full() && com != codcom)
{
passed = fld_com.yesno_box(TR("Comune non congruente al codice fiscale: correzione automatica?"));
if (passed) com.cut(0);
else return true;
}
if (com.empty())
{
fld_com.set(codcom);
fld_com.on_key(K_TAB);
}
return true;
}
HIDDEN bool _xtz_cf_val(TMask_field& f, KEY key)
{
return f.empty() || _xt_cf_val(f, key);
}
HIDDEN bool _notempty_val(TMask_field& f, KEY)
{
return f.mask().query_mode() || !f.empty();
}
HIDDEN bool _date_cmp(TMask_field& f, KEY)
{
const TString& s = f.get();
if (s.empty())
return true;
const TDate d0(s), d1(get_fld_val_param(f, 1));
const TFixed_string op(get_val_param(0));
if (op == "==") return d0 == d1;
if (op == "!=") return d0 != d1;
if (op == ">") return d0 > d1;
if (op == "<") return d0 < d1;
if (op == ">=") return d0 >= d1;
if (op == "<=") return d0 <= d1;
#ifdef DBG
f.error_box("Bad date operator '%s' in field %d", (const char*) op, f.dlg());
#endif
return false;
}
HIDDEN bool _fixlen_val(TMask_field& f, KEY)
{
if (f.empty())
return true;
const TString& s = f.get();
const int length = get_int_val_param(0);
const bool ok = s.len() == length;
if (!ok)
f.error_box(FR("La lunghezza del campo deve essere %d"), length);
return ok;
}
HIDDEN bool _mtcheck_val(TMask_field& f, KEY)
{
const int month = atoi(f.get());
if (month < 1 || month > 13)
return false;
TLocalisamfile d(LF_NDITTE);
d.put(NDT_CODDITTA, prefix().get_codditta());
if (d.read() != NOERR)
return true;
if (d.get_char(NDT_FREQVIVA) == 'M')
return true;
return month == 13 || (month % 3) == 0;
}
HIDDEN bool _reqif_val(TMask_field& f, KEY k)
{
if (k == K_ENTER && f.empty())
{
const int nparms = get_val_param_count();
for (int i = 0; i < nparms; i++)
{
const TString& fld = get_fld_val_param(f, i);
if (fld.full())
return false;
}
}
return true;
}
HIDDEN bool _autoexit_val(TMask_field& f, KEY key)
{
TMask& m = f.mask();
if (!m.query_mode() || key == K_ENTER)
return true;
const int nparms = get_val_param_count();
bool one_not_empty = false;
for (int i = nparms-1; i >= 0; i--)
{
const short id = get_int_val_param(i);
const int pos = m.id2pos(id);
if (pos >= 0)
{
const TMask_field& c = m.fld(pos);
if (c.empty())
{
if (c.check_type() != CHECK_NONE || one_not_empty)
return true;
}
else
one_not_empty = true;
}
}
if (one_not_empty)
m.stop_run(K_AUTO_ENTER);
return true;
}
HIDDEN bool _numcalc_val(TMask_field& f, KEY k)
{
if (k != K_TAB) return true;
TExpression e(get_val_param(0), _numexpr);
for (int i = 0; i < e.numvar(); i++)
{
const char* s = e.varname(i);
if (s[0] != '#')
{
TString err; err << "Cannot load variable " << s << " in " << e;
return f.error_box((const char*)err);
}
e.setvar(i, f.evaluate_field(s));
}
const TString& s = e.as_string();
f.set(s);
return true;
}
HIDDEN bool _strcalc_val(TMask_field& f, KEY k)
{
if (k != K_TAB) return true;
TExpression e(get_val_param(0), _strexpr);
for (int i = 0 ; i < e.numvar(); i++)
{
const char* s = e.varname(i);
if (s[0] != '#')
{
TString err; err << "Cannot load variable " << s << " in " << e;
return f.error_box((const char*)err);
}
e.setvar(i, f.evaluate_field(s));
}
const TString& s = e.as_string();
f.set(s);
return true;
}
HIDDEN bool _onereq_val(TMask_field& f, KEY k)
{
if (k != K_ENTER|| f.mask().mode() == MODE_QUERY)
return true;
const int nparms = get_val_param_count();
for (int i = 0; i < nparms ; i++)
{
const TString& s = get_fld_val_param(f, i);
if (s.full())
return true;
}
return false;
}
HIDDEN bool _chkfld_val(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const int fldid = get_int_val_param(0);
if (fldid == THIS_FIELD)
{
if (!f.required() && f.get().empty())
return true;
else
return f.check();
}
TMask_field & chkfld = f.mask().field(fldid);
chkfld.set(f.get());
return chkfld.check();
}
return true;
}
HIDDEN bool _filename_val(TMask_field& f, KEY)
{
const TFilename fn(f.get());
return fn.blank() || fn.ok();
}
HIDDEN bool _zerofill_val(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const int columns = get_int_val_param(0);
const TString& val = f.get();
if (val.len() < columns && real::is_natural(val))
{
TString z(val);
z.right_just(columns, '0');
f.set(z);
}
}
return true;
}
HIDDEN bool _alpha_val(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const TString& s = f.get();
for (int i = 0; s[i]; i++)
if (!isalpha(s[i]))
return f.error_box(TR("Sono ammessi solo caratteri alfabetici"));
}
return true;
}
HIDDEN bool _not_empty_chkfld_val(TMask_field& f, KEY k)
{
bool ok = true;
if (f.to_check(k,true) && f.get().not_empty())
{
TBrowse * b = ((TEdit_field&)f).browse();
if (b != NULL) ok = b->check(k == K_TAB ? RUNNING_CHECK : FINAL_CHECK);
}
return ok;
}
HIDDEN bool _sconto_val(TMask_field& f, KEY key)
{
bool ok = true;
if ( f.to_check( key ) )
{
const TString80 work(f.get());
TString80 goodexp;
// Elimina gli spazi molesti
// work.strip_spaces( );
if (work.not_empty())
{
TString80 num;
bool dec = false; // Flag che indica se si attende l'inizio di un numero
bool startnum = true; // Flag che indica se siamo all'inizio di un numero
int errorchar = ' ';
// Flag che indica se sono nella parte decimale di un numero
for (const char * s = (const char *)work; *s && errorchar == ' '; s++)
{
const char c = *s;
switch(c)
{
case '+':
case '-':
// Se ero in in numero ...
if( !startnum )
goodexp << num;
// Inizia il nuovo numero
num = (c == '-') ? "-" : "+";
startnum = true;
dec = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
num << c;
startnum = false;
break;
case '.':
case ',':
if(!dec)
{
if( startnum )
num << '0'; // Se occorreva un numero ci metto lo 0
num << '.'; // Interpreto la virgola come punto
dec = true;
startnum = true;
}
else
errorchar = c; // Se siamo gi` nella parte decimale segnala un errore
break;
case ' ':
break;
default:
errorchar = c;
break;
}
}
// Controlla la validita`
ok = errorchar == ' ';
if (ok)
{
goodexp << num; // Assegna la nuova espressione formattata bene
f.set(goodexp);
}
else
f.error_box(FR("Espressione di sconto non valida. Errore sul carattere %c"), errorchar);
}
}
return ok;
}
HIDDEN bool _ora_val(TMask_field& f, KEY key)
{
if ( f.to_check( key ) )
{
TString8 ora = f.get();
if ( ora.full( ) || f.required( ) )
{
if ( isdigit( ora[ 0 ] ) )
{
if ( ora[ 2 ] != ':' )
{
if ( ora.len( ) > 4 )
ora.overwrite( ":", 2 );
else
ora.insert( ":", 2 );
}
}
bool ok = ((isdigit(ora[0]))&&(isdigit(ora[1]))&&(isdigit(ora[3]))&&(isdigit(ora[4])));
ok &= ((atoi(&(ora[0]))<24)&&(atoi(&(ora[3]))<60));
if ( ok )
f.set( ora );
else
return f.error_box(TR("Ora errata o formato non valido"));
}
}
return true;
}
int iban_check(const TString& b, TString& msg)
{
if (b.len() < 5)
{
msg = TR("Lunghezza inferiore a 5 caratteri");
return 2;
}
if (!isalpha(b[0]) || !isalpha(b[1]))
{
msg.format(FR("I primi due caratteri (%s) devono essere alfabetici"), (const char*)b.left(2));
return 3;
}
if (!isdigit(b[2]) || !isdigit(b[3]))
{
msg.format(FR("I caratteri 3 e 4 (%s) devono essere numerici"), (const char*)b.mid(2,2));
return 4;
}
TString80 s;
s << b.mid(4) << b.left(4);
int r = 0;
for (int i = 0; s[i]; i++)
{
const char c = s[i];
if (c >= '0' && c <= '9')
{
const int k = c - '0';
r = (10 * r + k) % 97;
} else
if (c >= 'A' && c <= 'Z')
{
const int k = c - 'A' + 10;
r = (100 * r + k) % 97;
}
else
{
msg.format(FR("Carattere non ammesso: '%c'"), c);
return 5;
}
}
if (r != 1)
{
msg = TR("Codice di controllo errato");
return 1;
}
return 0;
}
int bban_check(const TString& b, TString& msg)
{
const unsigned char dispari[26] = { 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18,
20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23 };
if (b.len() != 23)
{
msg = TR("Lunghezza diversa da 23 caratteri");
return 2;
}
if (b[0] < 'A' || b[0] > 'Z')
{
msg.format(FR("Il CIN deve essere una lettera maiuscola: '%c'"), b[0]);
return 2;
}
for (int a = 1; a <= 10; a++)
{
if (!isdigit(b[a]))
{
msg = TR("ABI e CAB devono essere numerici");
return 3;
}
}
int s = 0, kcin = 0;
for (int i = 0; b[i]; i++)
{
const char c = b[i];
int k = 0;
if (isdigit(c))
{
k = c - '0';
} else
if (c >= 'A' && c <= 'Z')
{
k = c - 'A';
}
else
{
msg.format(FR("Carattere non ammesso: '%c'"), c);
return 4;
}
if (i == 0)
kcin = k;
else
{
if (i & 1) // dispari
s += dispari[k];
else
s += k;
}
}
if (s % 26 != kcin)
{
msg.format(TR("Codice di controlo (CIN) errato"));
return 1;
}
return 0;
}
HIDDEN bool _iban_val(TMask_field& f, KEY key)
{
bool ok = true;
if (key == K_TAB || key == K_ENTER)
{
TMask& m = f.mask();
const int nparms = get_val_param_count();
CHECKD(nparms == 8, "IBAN_CHECK deve avere 8 parametri: ", nparms);
int id[8];
for (int i = 0; i < 8; i++)
id[i] = get_int_val_param(i);
if (f.dlg() == id[1]) // Campo Stato IBAN
{
if (key == K_TAB && !m.is_running())
{
const TString& iban = m.get(id[0]);
m.set(id[1], iban.left(2));
m.set(id[2], iban.mid(2,2));
m.set(id[3], iban.mid(4));
m.set(id[4], iban.mid(4,1));
m.set(id[5], iban.mid(5,5));
m.set(id[6], iban.mid(10,5));
m.set(id[7], iban.mid(15));
}
const bool italy = f.empty() || f.get() == "IT";
m.show(id[3], !italy);
m.show(id[4], italy);
m.show(id[5], italy);
m.show(id[6], italy);
m.show(id[7], italy);
}
if (f.dlg() == id[2])
{
TString4 stato = m.get(id[1]);
if (stato.empty())
stato = "IT";
const bool italy = stato=="IT";
const bool do_test = !m.field(id[italy ? 7 : 3]).empty(); // Faccio il test solo in presenza di conto corrente
TString80 iban;
if (do_test)
{
if (f.empty()) // Cifra di controllo vuota
{
TString msg;
TString80 iban;
iban << stato << "@@";
if (italy)
iban << m.get(id[4]) << m.get(id[5]) << m.get(id[6]) << m.get(id[7]);
else
iban << m.get(id[3]);
int err = 1;
for (int pp = 0; pp <= 99 && err == 1; pp++)
{
msg.format("%02d", pp);
iban.overwrite(msg, 2);
err = iban_check(iban, msg);
if (err == 0)
{
m.set(id[1], stato);
m.set(id[2], pp);
break;
}
}
}
iban << m.get(id[1]) << m.get(id[2]);
if (italy)
iban << m.get(id[4]) << m.get(id[5]) << m.get(id[6]) << m.get(id[7]);
else
iban << m.get(id[3]);
TString msg;
const int err = iban_check(iban, msg);
if (err != 0)
{
msg.insert(TR("Codice IBAN errato:\n"));
if (err > 1) // Errore grave
ok = error_box(msg);
else
{
msg << '\n' << TR("Si desidera continuare ugualmente?");
ok = yesno_box(msg);
}
}
}
if (key == K_ENTER)
{
if (!ok) iban.cut(0);
m.set(id[0], iban);
}
}
}
return ok;
}
HIDDEN bool _bban_val(TMask_field& f, KEY key)
{
bool ok = true;
if (!f.empty() && f.to_check(key))
{
TMask& m = f.mask();
const int nparms = get_val_param_count();
CHECKD(nparms == 5, "BBAN_CHECK deve avere 5 parametri: ", nparms);
int id[5];
for (int i = 0; i < 5; i++)
id[i] = get_int_val_param(i);
if (m.field(id[1]).empty()) // CIN vuoto
{
TString msg;
TString80 bban;
bban << "#" << m.get(id[2]) << m.get(id[3]) << m.get(id[4]);
int err = 1;
for (char cin = 'A'; cin <= 'Z' && err == 1; cin++)
{
bban[0] = cin;
err = bban_check(bban, msg);
if (err == 0)
{
m.set(id[1], bban.left(1));
break;
}
}
}
if (f.dlg() == id[1] && key == K_ENTER)
{
TString80 bban;
for (int i = 1; i < 5; i++)
bban << m.get(id[i]);
if (bban.len() > 11)
{
TString msg;
const int err = bban_check(bban, msg);
if (err != 0)
{
msg.insert(TR("Codice BBAN errato:\n"));
if (err > 1) // Errore grave
ok = error_box(msg);
else
{
msg << '\n' << TR("Si desidera continuare ugualmente?");
ok = yesno_box(msg);
}
}
}
}
}
return ok;
}
#define MAX_FUNC 26
HIDDEN VAL_FUNC _global_val_func[MAX_FUNC] =
{
_expr_val, // 0
_emptycopy_val,
_pi_val,
_cf_val,
_notempty_val,
_date_cmp, // 5
_xt_pi_val,
_xt_cf_val,
_xtz_pi_val,
_xtz_cf_val,
_fixlen_val, // 10
_mtcheck_val,
_reqif_val,
_autoexit_val,
_numcalc_val,
_strcalc_val, // 15
_onereq_val,
_chkfld_val,
_filename_val,
_zerofill_val,
_alpha_val, // 20
_not_empty_chkfld_val,
_ora_val,
_sconto_val,
_iban_val,
_bban_val, // 25
};
// @doc INTERNAL
// @func Effettua i controlli sui campi di una maschera
//
// @rdesc Ritorna se il controllo ha avuto successo:
//
// @flag true | Il campo e' positivo al controllo
// @flag false | Il campo non ha i requisiti necessari per passare il controllo
bool validate(
int fn, // @parm Numero della funzione da effettuare
TMask_field& f, // @parm Identificatore del campo da controllare
KEY k, // @parm Codice del tasto premuto sul campo
const TString_array& parms) // @parm Array di parametri per effettuare il controllo
{
_parms = &parms;
return (fn >= 0 && fn < MAX_FUNC) ? _global_val_func[fn](f, k) : true;
}