campo-sirio/include/validate.cpp
alex b3cd9c64a9 Patch level : xx.888
Files correlati     : no patch
Ricompilazione Demo : [ ]
Commento            : Riportata la versione 01.05 patch 888 sul main trunk


git-svn-id: svn://10.65.10.50/trunk@9217 c028cbd2-c16b-5b4b-a496-9718f37d4682
2000-10-03 13:45:12 +00:00

848 lines
20 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] != '#')
{
TString80 err; err << "Non trovo 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.get().empty())
{
const short id = atoi(get_val_param(0));
const TFixed_string val(f.mask().get(id));
if (val.not_empty())
{
f.set(val);
f.on_hit();
}
}
return TRUE;
}
// @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
{
const char* stpi[] = { "BE09", "DE09", "DK08", "EL08", "ES09",
"FR11", "GB09", "GB12", "IE08", "IT11",
"LU08", "NL12", "PT09", NULL };
TString16 test;
test.format("%s%02d", (const char*)stato, pi.len());
ok = FALSE;
for (int g = 0; stpi[g]; g++)
{
ok = (test == stpi[g]);
if (ok)
break;
}
}
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;
}