Add IBAN validation
This commit is contained in:
@ -21,5 +21,11 @@ namespace WGneu {
|
|||||||
yield return childOfChild;
|
yield return childOfChild;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int Modulo(string a, int b) {
|
||||||
|
if (!a.All(char.IsDigit))
|
||||||
|
throw new ArgumentException("First argument has to be a decimal string");
|
||||||
|
return a.Select(ch => ch - '0').Aggregate((sum, n) => (sum * 10 + n) % b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,19 @@ namespace WGneu {
|
|||||||
{ "423", Array.Empty<string[]>() },
|
{ "423", Array.Empty<string[]>() },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static void SetInputInvalid(TextBox input) {
|
||||||
public static ValidationResult CheckNumericInput(TextBox input) {
|
input.BorderBrush = System.Windows.Media.Brushes.Red;
|
||||||
return CheckNumericInput(input, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValidationResult CheckNumericInput(TextBox input, int maxLen) {
|
public static void SetInputValid(TextBox input) {
|
||||||
|
input.ClearValue(TextBox.BorderBrushProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationResult CheckNumericInput(TextBox input, bool optional) {
|
||||||
|
return CheckNumericInput(input, optional, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValidationResult CheckNumericInput(TextBox input, bool optional, int maxLen) {
|
||||||
string text = "";
|
string text = "";
|
||||||
int pos = input.CaretIndex;
|
int pos = input.CaretIndex;
|
||||||
for (int i = 0; i < input.Text.Length; i++) {
|
for (int i = 0; i < input.Text.Length; i++) {
|
||||||
@ -50,6 +57,11 @@ namespace WGneu {
|
|||||||
input.Text = text;
|
input.Text = text;
|
||||||
input.CaretIndex = pos;
|
input.CaretIndex = pos;
|
||||||
|
|
||||||
|
if (text.Length == 0) {
|
||||||
|
if (optional) return new(true, null);
|
||||||
|
return new(false, "Wert ist nicht optional");
|
||||||
|
}
|
||||||
|
|
||||||
if (maxLen >= 0 && input.Text.Length > maxLen) {
|
if (maxLen >= 0 && input.Text.Length > maxLen) {
|
||||||
input.Text = input.Text.Substring(0, maxLen);
|
input.Text = input.Text.Substring(0, maxLen);
|
||||||
input.CaretIndex = Math.Min(pos, maxLen);
|
input.CaretIndex = Math.Min(pos, maxLen);
|
||||||
@ -58,14 +70,14 @@ namespace WGneu {
|
|||||||
return new(true, null);
|
return new(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckPhoneNumber(TextBox input) {
|
public static ValidationResult CheckPhoneNumber(TextBox input, bool optional) {
|
||||||
string text = "";
|
string text = "";
|
||||||
int pos = input.CaretIndex;
|
int pos = input.CaretIndex;
|
||||||
for (int i = 0, v = 0; i < input.Text.Length; i++) {
|
for (int i = 0, v = 0; i < input.Text.Length && v < 30; i++) {
|
||||||
char ch = input.Text[i];
|
char ch = input.Text[i];
|
||||||
if (v == 0 && input.Text.Length - i >= 2 && ch == '0' && input.Text[i + 1] == '0') {
|
if (v == 0 && input.Text.Length - i >= 2 && ch == '0' && input.Text[i + 1] == '0') {
|
||||||
v++; i++;
|
v++; i++;
|
||||||
text += "+";
|
text += '+';
|
||||||
} else if (ch == '(' && input.Text.Length - i >= 3 && input.Text[i + 1] == '0' && input.Text[i + 2] == ')') {
|
} else if (ch == '(' && input.Text.Length - i >= 3 && input.Text[i + 1] == '0' && input.Text[i + 2] == ')') {
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if (v == 0 && ch == '0') {
|
} else if (v == 0 && ch == '0') {
|
||||||
@ -76,16 +88,16 @@ namespace WGneu {
|
|||||||
text += ch;
|
text += ch;
|
||||||
} else if (v > 0 && char.IsDigit(ch)) {
|
} else if (v > 0 && char.IsDigit(ch)) {
|
||||||
if (PHONE_NRS.Any(kv => text == "+" + kv.Key))
|
if (PHONE_NRS.Any(kv => text == "+" + kv.Key))
|
||||||
text += " ";
|
text += ' ';
|
||||||
if (text.StartsWith("+43 ")) {
|
if (text.StartsWith("+43 ")) {
|
||||||
var nr = text[4..];
|
var nr = text[4..];
|
||||||
var vws = PHONE_NRS["43"];
|
var vws = PHONE_NRS["43"];
|
||||||
if (v >= 4 && v - 4 < vws.Length && vws[v - 4].Any(vw => nr.StartsWith(vw)))
|
if (v >= 4 && v - 4 < vws.Length && vws[v - 4].Any(vw => nr.StartsWith(vw)))
|
||||||
text += " ";
|
text += ' ';
|
||||||
else if (nr == "1")
|
else if (nr == "1")
|
||||||
text += " ";
|
text += ' ';
|
||||||
else if (v == 7 && nr.Length == 4)
|
else if (v == 7 && nr.Length == 4)
|
||||||
text += " ";
|
text += ' ';
|
||||||
}
|
}
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
@ -96,7 +108,7 @@ namespace WGneu {
|
|||||||
input.Text = text;
|
input.Text = text;
|
||||||
input.CaretIndex = pos;
|
input.CaretIndex = pos;
|
||||||
|
|
||||||
if (text.Length == 0)
|
if (optional && text.Length == 0)
|
||||||
return new(true, null);
|
return new(true, null);
|
||||||
if (text.Length < 10)
|
if (text.Length < 10)
|
||||||
return new(false, "Telefonnummer zu kurz");
|
return new(false, "Telefonnummer zu kurz");
|
||||||
@ -104,11 +116,11 @@ namespace WGneu {
|
|||||||
return new(true, null);
|
return new(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckEmailAddress(TextBox input) {
|
public static ValidationResult CheckEmailAddress(TextBox input, bool optional) {
|
||||||
string text = "";
|
string text = "";
|
||||||
int pos = input.CaretIndex;
|
int pos = input.CaretIndex;
|
||||||
bool domain = false;
|
bool domain = false;
|
||||||
for (int i = 0; i < input.Text.Length; i++) {
|
for (int i = 0; i < input.Text.Length && text.Length < 256; i++) {
|
||||||
char ch = input.Text[i];
|
char ch = input.Text[i];
|
||||||
if (domain) {
|
if (domain) {
|
||||||
if ((char.IsAscii(ch) && char.IsLetterOrDigit(ch)) || ".-_öäüßÖÄÜẞ".Any(c => c == ch)) {
|
if ((char.IsAscii(ch) && char.IsLetterOrDigit(ch)) || ".-_öäüßÖÄÜẞ".Any(c => c == ch)) {
|
||||||
@ -116,7 +128,8 @@ namespace WGneu {
|
|||||||
text += char.ToLower(ch);
|
text += char.ToLower(ch);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ch == '@') domain = true;
|
if (ch == '@')
|
||||||
|
domain = true;
|
||||||
if (!char.IsControl(ch) && !char.IsWhiteSpace(ch))
|
if (!char.IsControl(ch) && !char.IsWhiteSpace(ch))
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
}
|
||||||
@ -127,10 +140,13 @@ namespace WGneu {
|
|||||||
input.Text = text;
|
input.Text = text;
|
||||||
input.CaretIndex = pos;
|
input.CaretIndex = pos;
|
||||||
|
|
||||||
if (text.Length == 0)
|
if (text.Length == 0) {
|
||||||
return new(true, null);
|
if (optional) return new(true, null);
|
||||||
else if (text[0] == '@' || !domain)
|
return new(false, "E-Mail-Adresse ist nicht optional");
|
||||||
|
} else if (text[0] == '@' || !domain) {
|
||||||
return new(false, "E-Mail-Adresse ungültig");
|
return new(false, "E-Mail-Adresse ungültig");
|
||||||
|
}
|
||||||
|
|
||||||
var last = text.Split(".").Last();
|
var last = text.Split(".").Last();
|
||||||
if (last.Length < 2 || !last.All(ch => char.IsAscii(ch) && char.IsLower(ch)))
|
if (last.Length < 2 || !last.All(ch => char.IsAscii(ch) && char.IsLower(ch)))
|
||||||
return new(false, "E-Mail-Adresse ungültig");
|
return new(false, "E-Mail-Adresse ungültig");
|
||||||
@ -138,8 +154,49 @@ namespace WGneu {
|
|||||||
return new(true, null);
|
return new(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckLfbisNr(TextBox input) {
|
public static ValidationResult CheckIban(TextBox input, bool optional) {
|
||||||
var res = CheckNumericInput(input, 7);
|
string text = "";
|
||||||
|
int pos = input.CaretIndex;
|
||||||
|
int v = 0;
|
||||||
|
for (int i = 0; i < input.Text.Length && v < 34; i++) {
|
||||||
|
char ch = input.Text[i];
|
||||||
|
if (char.IsLetterOrDigit(ch) && char.IsAscii(ch)) {
|
||||||
|
if (((v < 2 && char.IsLetter(ch)) || (v >= 2 && v < 4 && char.IsDigit(ch)) || v >= 4) &&
|
||||||
|
((!text.StartsWith("AT") && !text.StartsWith("DE")) || char.IsDigit(ch)))
|
||||||
|
{
|
||||||
|
if (v != 0 && v % 4 == 0)
|
||||||
|
text += ' ';
|
||||||
|
v++;
|
||||||
|
text += char.ToUpper(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == input.CaretIndex - 1)
|
||||||
|
pos = text.Length;
|
||||||
|
if (text.StartsWith("AT") && v >= 20)
|
||||||
|
break;
|
||||||
|
else if (text.StartsWith("DE") && v >= 22)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input.Text = text;
|
||||||
|
input.CaretIndex = pos;
|
||||||
|
|
||||||
|
if (optional && text.Length == 0) {
|
||||||
|
return new(true, null);
|
||||||
|
} else if (v < 5 || (text.StartsWith("AT") && v != 20) || (text.StartsWith("DE") && v != 22)) {
|
||||||
|
return new(false, "IBAN hat falsche Länge");
|
||||||
|
}
|
||||||
|
|
||||||
|
var validation = (text[4..] + text[..4]).Replace(" ", "")
|
||||||
|
.Select(ch => char.IsDigit(ch) ? ch.ToString() : (ch - 'A' + 10).ToString())
|
||||||
|
.Aggregate((a, b) => a + b);
|
||||||
|
if (Utils.Modulo(validation, 97) != 1)
|
||||||
|
return new(false, "Prüfsumme der IBAN ist falsch");
|
||||||
|
|
||||||
|
return new(true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValidationResult CheckLfbisNr(TextBox input, bool optional) {
|
||||||
|
var res = CheckNumericInput(input, optional, 7);
|
||||||
if (!res.IsValid)
|
if (!res.IsValid)
|
||||||
return res;
|
return res;
|
||||||
if (input.Text.Length == 0)
|
if (input.Text.Length == 0)
|
||||||
@ -152,16 +209,8 @@ namespace WGneu {
|
|||||||
return new(true, "Not implemented yet");
|
return new(true, "Not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckUstIdInput(TextBox input) {
|
public static ValidationResult CheckUstIdInput(TextBox input, bool optional) {
|
||||||
return new(false, "Not implemented yet");
|
return new(false, "Not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetInputInvalid(TextBox input) {
|
|
||||||
input.BorderBrush = System.Windows.Media.Brushes.Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetInputValid(TextBox input) {
|
|
||||||
input.ClearValue(TextBox.BorderBrushProperty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,7 @@
|
|||||||
|
|
||||||
<Label Content="IBAN:" HorizontalAlignment="Left" Margin="10,12,0,0" VerticalAlignment="Top" Padding="2"/>
|
<Label Content="IBAN:" HorizontalAlignment="Left" Margin="10,12,0,0" VerticalAlignment="Top" Padding="2"/>
|
||||||
<TextBox x:Name="IbanInput" IsReadOnly="True"
|
<TextBox x:Name="IbanInput" IsReadOnly="True"
|
||||||
|
TextChanged="IbanInput_TextChanged" LostFocus="IbanInput_LostFocus"
|
||||||
Margin="0,10,10,0" VerticalAlignment="Top" FontSize="14" Padding="2" Grid.Column="1" Height="25"/>
|
Margin="0,10,10,0" VerticalAlignment="Top" FontSize="14" Padding="2" Grid.Column="1" Height="25"/>
|
||||||
|
|
||||||
<Label Content="BIC:" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" Padding="2"/>
|
<Label Content="BIC:" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" Padding="2"/>
|
||||||
|
@ -385,8 +385,8 @@ namespace WGneu.Windows {
|
|||||||
return true; // TODO
|
return true; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InputTextChanged(TextBox input, Func<TextBox, ValidationResult> checker) {
|
private void InputTextChanged(TextBox input, bool optional, Func<TextBox, bool, ValidationResult> checker) {
|
||||||
var res = checker(input);
|
var res = checker(input, optional);
|
||||||
Valid[input] = res.IsValid;
|
Valid[input] = res.IsValid;
|
||||||
if (res.IsValid)
|
if (res.IsValid)
|
||||||
Validator.SetInputValid(input);
|
Validator.SetInputValid(input);
|
||||||
@ -395,8 +395,8 @@ namespace WGneu.Windows {
|
|||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InputLostFocus(TextBox input, Func<TextBox, ValidationResult> checker, string? msg) {
|
private void InputLostFocus(TextBox input, bool optional, Func<TextBox, bool, ValidationResult> checker, string? msg) {
|
||||||
var res = checker(input);
|
var res = checker(input, optional);
|
||||||
if (!res.IsValid)
|
if (!res.IsValid)
|
||||||
MessageBox.Show(res.ErrorContent.ToString(), msg ?? res.ErrorContent.ToString(), MessageBoxButton.OK, MessageBoxImage.Warning);
|
MessageBox.Show(res.ErrorContent.ToString(), msg ?? res.ErrorContent.ToString(), MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
}
|
}
|
||||||
@ -406,27 +406,35 @@ namespace WGneu.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void PhoneNrInput_TextChanged(object sender, RoutedEventArgs e) {
|
private void PhoneNrInput_TextChanged(object sender, RoutedEventArgs e) {
|
||||||
InputTextChanged((TextBox)sender, Validator.CheckPhoneNumber);
|
InputTextChanged((TextBox)sender, true, Validator.CheckPhoneNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PhoneNrInput_LostFocus(object sender, RoutedEventArgs e) {
|
private void PhoneNrInput_LostFocus(object sender, RoutedEventArgs e) {
|
||||||
InputLostFocus((TextBox)sender, Validator.CheckPhoneNumber, null);
|
InputLostFocus((TextBox)sender, true, Validator.CheckPhoneNumber, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmailInput_TextChanged(object sender, RoutedEventArgs e) {
|
private void EmailInput_TextChanged(object sender, RoutedEventArgs e) {
|
||||||
InputTextChanged((TextBox)sender, Validator.CheckEmailAddress);
|
InputTextChanged((TextBox)sender, true, Validator.CheckEmailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmailInput_LostFocus(object sender, RoutedEventArgs e) {
|
private void EmailInput_LostFocus(object sender, RoutedEventArgs e) {
|
||||||
InputLostFocus((TextBox)sender, Validator.CheckEmailAddress, null);
|
InputLostFocus((TextBox)sender, true, Validator.CheckEmailAddress, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IbanInput_TextChanged(object sender, RoutedEventArgs e) {
|
||||||
|
InputTextChanged((TextBox)sender, true, Validator.CheckIban);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IbanInput_LostFocus(object sender, RoutedEventArgs e) {
|
||||||
|
InputLostFocus((TextBox)sender, true, Validator.CheckIban, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LfbisNrInput_TextChanged(object sender, RoutedEventArgs e) {
|
private void LfbisNrInput_TextChanged(object sender, RoutedEventArgs e) {
|
||||||
InputTextChanged((TextBox)sender, Validator.CheckLfbisNr);
|
InputTextChanged((TextBox)sender, true, Validator.CheckLfbisNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LfbisNrInput_LostFocus(object sender, RoutedEventArgs e) {
|
private void LfbisNrInput_LostFocus(object sender, RoutedEventArgs e) {
|
||||||
InputLostFocus((TextBox)sender, Validator.CheckLfbisNr, "Betriebsnummer ungültig");
|
InputLostFocus((TextBox)sender, true, Validator.CheckLfbisNr, "Betriebsnummer ungültig");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user