campo-sirio/include/validate.cpp
guy ffccf3bbea Patch level : 2.0 nopatch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

colors.*     Aggiunta funzione per calcolo distanza tra colori per
             gestione trasparenze in menu principale
dongle.cpp   Corretta gestione chiave Eutron normale (non SV)
image.cpp    Migliorata gestion etrasparenze
progind.cpp  Corretta gestione messaggi su piu' righe
relapp.cpp   Corretta traduzione messaggi di richiesta salvataggio
validate.cpp Sostituita TFixed_string errata con la corretta const TString&


git-svn-id: svn://10.65.10.50/trunk@11123 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-13 15:12:54 +00:00

868 lines
21 KiB
C++
Executable File

#include <stdlib.h>
#include <ctype.h>
#include <expr.h>
#include <isam.h>
#include <mask.h>
#include <prefix.h>
#include <validate.h>
#include <defmask.h>
#include <nditte.h>
typedef bool (*VAL_FUNC)(TMask_field&, KEY k);
HIDDEN const TArray* _parms;
HIDDEN int get_val_param_num() { return _parms->items(); }
HIDDEN const char* get_val_param(int i)
{ return i < _parms->items() ? (const char*)((const TString&) (*_parms)[i]):"" ; }
HIDDEN bool _expr_val(TMask_field& f, KEY)
{
TTypeexp type = atoi(get_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 << "Non esiste la variabile " << s << " in " << e;
return f.error_box((const char*)err);
}
s++;
const int fldid = atoi(s);
if (type == _numexpr)
{
const real r(fldid == 0 ? f.get() : f.mask().get(fldid));
e.setvar(i, r);
}
else
{
const char* v = fldid == 0 ? f.get() : f.mask().get(fldid);
e.setvar(i, v);
}
}
return bool(e);
}
HIDDEN bool _emptycopy_val(TMask_field& f, KEY)
{
if (f.empty())
{
const short id = atoi(get_val_param(0));
const TString& val = f.mask().get(id);
if (val.not_empty())
{
f.set(val);
f.on_hit();
}
}
return TRUE;
}
bool check_pi_estera(const TString& st, const TString& paiva)
{
const char* stpi[] = { "AT09", "BE09", "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 (st=="AT") // Controllo speciale per l'Austria che comincia per U
lenok &= (paiva[0] == 'U');
}
else
lenok = TRUE; // Gli stati ignoti hanno sempre lunghezza corretta!
return lenok;
}
// @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.empty())
return TRUE;
bool ok = TRUE; // Assumiamo ottimisticamente che tutto va be'
if (stato.blank() || stato == "IT")
{
// Testa partita iva italiana
ok = pi.len() == 11;
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(atoi(get_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;
const char* msg = len_error ? "Lunghezza p" : "P";
ok = f.yesno_box("%sartita IVA errata, la accetto ugualmente?", 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 TString16 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
{
TString16 cf (codcf);
if (cf.empty())
return TRUE;
const bool 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 TString16 cf(f.get());
bool ok = TRUE;
if (cf.empty()) return TRUE;
if (cf.len() == 11 && isdigit(cf[0]))
{
TString16 stato(f.mask().get(atoi(get_val_param(0))));
if (stato.not_empty() && stato != "IT") return TRUE;
ok = pi_check (stato, cf);
}
else
ok = __cf_check(cf);
if (!ok)
{
if(f.dirty())
{
ok = f.yesno_box("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("Partita IVA obbligatoria");
if (!_pi_val(f, key))
return FALSE;
const TString& stato = m.get(atoi(get_val_param(0)));
if (stato.empty() || stato == "IT")
{
TLocalisamfile c(LF_COMUNI);
const int pi = atoi(value.mid(7,3));
for (int i = 1 ; i < 3; i++)
{
const int comune = atoi(get_val_param(i));
if (comune > 0 && !m.field(comune).empty())
{
const TString16 com(m.get(comune)); // Comune residenza fiscale e residenza
c.zero();
c.put("COM", com);
if (c.read() == NOERR)
{
const int s1 = c.get_int("UFFIVA1");
const int s2 = c.get_int("UFFIVA2");
const int s3 = c.get_int("UFFIVA3");
if (pi != s1 && pi != s2 && pi != s3)
{
TString16 ui; ui.format("%03d", s1);
if (f.yesno_box("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)
{
if (f.empty() || f.mask().query_mode())
return TRUE;
return _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.empty()) return f.error_box("Codice fiscale obbligatorio");
if (!_cf_val(f, key)) return FALSE;
if (cf.len() == 11 && isdigit(cf[0]))
{
// 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(atoi(get_val_param(1)));
TMask_field& fld_dat = m.field(atoi(get_val_param(2)));
TMask_field& fld_com = m.field(atoi(get_val_param(3)));
const char sesso = fld_sex.get()[0];
TString16 data(fld_dat.get());
TString16 com(fld_com.get());
TString16 wm("LMNPQRSTUV");
int p;
if ((p = wm.find(cf[6])) != -1) cf[6] = '0' + p;
if ((p = wm.find(cf[7])) != -1) cf[7] = '0' + p;
if ((p = wm.find(cf[9])) != -1) cf[9] = '0' + p;
if ((p = wm.find(cf[10])) != -1) cf[10] = '0' + p;
if ((p = wm.find(cf[12])) != -1) cf[12] = '0' + p;
if ((p = wm.find(cf[13])) != -1) cf[13] = '0' + p;
if ((p = wm.find(cf[14])) != -1) cf[14] = '0' + p;
int gn = atoi(cf.mid(9,2));
if ((sesso == 'F' && gn < 40) || (sesso == 'M' && gn > 40))
{
passed = fld_sex.yesno_box("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 ? "Anno" : (err==2 ? "Mese" : "Giorno");
passed = fld_dat.yesno_box("%s di nascita non congruente al codice fiscale: correzione automatica?", what);
if (passed) data = "";
else return TRUE;
}
}
if (data.empty())
{
const int mn = wm.find(cf[8]) + 1;
if (mn > 0)
{
const TDate d(gn, mn, 1900 + atoi(cf.mid(6, 2)));
fld_dat.set(d.string());
}
}
// Controllo del comune di nascita
const char* const codcom = cf.mid(11, 4);
if (com.not_empty() && com != codcom)
{
passed = fld_com.yesno_box("Comune non congruente al codice fiscale: correzione automatica?");
if (passed) com = "";
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)
{
if (f.mask().query_mode()) return TRUE;
const char* cf = f.get();
return (*cf == '\0') ? TRUE : _xt_cf_val(f, key);
}
HIDDEN bool _notempty_val(TMask_field& f, KEY)
{
return f.mask().query_mode() || f.get().not_empty();
}
HIDDEN bool _date_cmp(TMask_field& f, KEY)
{
TFixed_string s(f.get());
if (s.empty()) return TRUE;
TDate d0(s), d1(f.mask().get(atoi(get_val_param(1))));
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)
{
const TFixed_string s(f.get());
if (s.empty()) return TRUE;
const int length = atoi(get_val_param(0));
const bool ok = s.len() == length;
if (!ok) f.error_box("Lunghezza errata: 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.zero();
d.put(NDT_CODDITTA, prefix().get_codditta());
d.read();
if (d.bad()) 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)
{
if (f.get().not_empty()) return TRUE;
const int nparms = get_val_param_num();
for (int i = 0 ; i < nparms; i++)
{
const short id = atoi(get_val_param(i));
if (id > 0 && f.mask().get(id).not_empty())
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 next = m.next_fld();
if (next != DLG_NULL && next != f.dlg() && m.field(next).in_key(0))
{
const byte last = m.num_keys();
for (byte k = 1; k <= last; k++)
if (f.in_key(k) && m.field(next).in_key(k))
return TRUE;
}
*/
const int nparms = get_val_param_num();
bool one_not_empty = FALSE;
for (int i = nparms; i-- > 0;)
{
const short id = f.atodlg(get_val_param(i));
const TMask_field& c = f.mask().field(id);
const bool empty = c.get().empty();
if (empty)
{
if (c.check_type() != CHECK_NONE || one_not_empty)
return TRUE;
}
else
one_not_empty = TRUE;
}
if (one_not_empty)
f.mask().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] != '#')
{
TString80 err; err << "Cannot load variable " << s << " in " << e;
return f.error_box((const char*)err);
}
s++;
const int fldid = atoi(s);
e.setvar(i, fldid == 0 ? f.get() : f.mask().get(fldid));
}
const TFixed_string 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] != '#')
{
TString80 err; err << "Cannot load variable " << s << " in " << e;
return f.error_box((const char*)err);
}
s++;
const int fldid = atoi(s);
e.setvar(i, fldid == 0 ? f.get() : f.mask().get(fldid));
}
TFixed_string s( e.as_string());
f.set(s);
return TRUE;
}
HIDDEN bool _onereq_val(TMask_field& f, KEY k)
{
if (k != K_ENTER) return TRUE;
const TMask& m = f.mask();
if (m.mode() == MODE_QUERY) return TRUE;
const int nparms = get_val_param_num();
for (int i = 0; i < nparms ; i++)
{
const char* s = m.get(atoi(get_val_param(i)));
if (*s) return TRUE;
}
return FALSE;
}
HIDDEN bool _chkfld_val(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const int fldid = atoi(get_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 = atoi(get_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("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( "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 ) )
{
TFixed_string ora( f.get( ), 6 );
if ( ora.not_empty( ) || f.required( ) )
{
if ( isdigit( ora[ 0 ] ) )
{
if ( ora[ 2 ] != ':' )
{
if ( ora.len( ) > 4 )
ora.overwrite( ":", 2 );
else
ora.insert( ":", 2 );
}
}
bool ok;
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.error_box("Ora errata o formato non valido");
return FALSE;
}
else
{
f.set( ora );
return TRUE;
}
}
}
return TRUE;
}
#define MAX_FUNC 24
HIDDEN VAL_FUNC _global_val_func[MAX_FUNC] =
{
_expr_val,
_emptycopy_val,
_pi_val,
_cf_val,
_notempty_val,
_date_cmp,
_xt_pi_val,
_xt_cf_val,
_xtz_pi_val,
_xtz_cf_val,
_fixlen_val,
_mtcheck_val,
_reqif_val,
_autoexit_val,
_numcalc_val,
_strcalc_val,
_onereq_val,
_chkfld_val,
_filename_val,
_zerofill_val,
_alpha_val,
_not_empty_chkfld_val,
_ora_val,
_sconto_val,
};
// @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 TArray& parms) // @parm Array di paramtri per effettuare il controllo
{
_parms = &parms;
return (fn >= 0 && fn < MAX_FUNC) ? _global_val_func[fn](f, k) : TRUE;
}