diff --git a/WGneu/Utils.cs b/WGneu/Utils.cs index d9ae7b2..66982de 100644 --- a/WGneu/Utils.cs +++ b/WGneu/Utils.cs @@ -21,5 +21,11 @@ namespace WGneu { 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); + } } } diff --git a/WGneu/Validator.cs b/WGneu/Validator.cs index 3a017cf..25acf20 100644 --- a/WGneu/Validator.cs +++ b/WGneu/Validator.cs @@ -32,12 +32,19 @@ namespace WGneu { { "423", Array.Empty() }, }; - - public static ValidationResult CheckNumericInput(TextBox input) { - return CheckNumericInput(input, -1); + public static void SetInputInvalid(TextBox input) { + input.BorderBrush = System.Windows.Media.Brushes.Red; } - 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 = ""; int pos = input.CaretIndex; for (int i = 0; i < input.Text.Length; i++) { @@ -50,6 +57,11 @@ namespace WGneu { input.Text = text; 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) { input.Text = input.Text.Substring(0, maxLen); input.CaretIndex = Math.Min(pos, maxLen); @@ -58,14 +70,14 @@ namespace WGneu { return new(true, null); } - public static ValidationResult CheckPhoneNumber(TextBox input) { + public static ValidationResult CheckPhoneNumber(TextBox input, bool optional) { string text = ""; 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]; if (v == 0 && input.Text.Length - i >= 2 && ch == '0' && input.Text[i + 1] == '0') { v++; i++; - text += "+"; + text += '+'; } else if (ch == '(' && input.Text.Length - i >= 3 && input.Text[i + 1] == '0' && input.Text[i + 2] == ')') { i += 2; } else if (v == 0 && ch == '0') { @@ -76,16 +88,16 @@ namespace WGneu { text += ch; } else if (v > 0 && char.IsDigit(ch)) { if (PHONE_NRS.Any(kv => text == "+" + kv.Key)) - text += " "; + text += ' '; if (text.StartsWith("+43 ")) { var nr = text[4..]; var vws = PHONE_NRS["43"]; if (v >= 4 && v - 4 < vws.Length && vws[v - 4].Any(vw => nr.StartsWith(vw))) - text += " "; + text += ' '; else if (nr == "1") - text += " "; + text += ' '; else if (v == 7 && nr.Length == 4) - text += " "; + text += ' '; } v++; text += ch; @@ -96,7 +108,7 @@ namespace WGneu { input.Text = text; input.CaretIndex = pos; - if (text.Length == 0) + if (optional && text.Length == 0) return new(true, null); if (text.Length < 10) return new(false, "Telefonnummer zu kurz"); @@ -104,11 +116,11 @@ namespace WGneu { return new(true, null); } - public static ValidationResult CheckEmailAddress(TextBox input) { + public static ValidationResult CheckEmailAddress(TextBox input, bool optional) { string text = ""; int pos = input.CaretIndex; 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]; if (domain) { if ((char.IsAscii(ch) && char.IsLetterOrDigit(ch)) || ".-_öäüßÖÄÜẞ".Any(c => c == ch)) { @@ -116,7 +128,8 @@ namespace WGneu { text += char.ToLower(ch); } } else { - if (ch == '@') domain = true; + if (ch == '@') + domain = true; if (!char.IsControl(ch) && !char.IsWhiteSpace(ch)) text += ch; } @@ -127,10 +140,13 @@ namespace WGneu { input.Text = text; input.CaretIndex = pos; - if (text.Length == 0) - return new(true, null); - else if (text[0] == '@' || !domain) + if (text.Length == 0) { + if (optional) return new(true, null); + return new(false, "E-Mail-Adresse ist nicht optional"); + } else if (text[0] == '@' || !domain) { return new(false, "E-Mail-Adresse ungültig"); + } + var last = text.Split(".").Last(); if (last.Length < 2 || !last.All(ch => char.IsAscii(ch) && char.IsLower(ch))) return new(false, "E-Mail-Adresse ungültig"); @@ -138,8 +154,49 @@ namespace WGneu { return new(true, null); } - public static ValidationResult CheckLfbisNr(TextBox input) { - var res = CheckNumericInput(input, 7); + public static ValidationResult CheckIban(TextBox input, bool optional) { + 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) return res; if (input.Text.Length == 0) @@ -152,16 +209,8 @@ namespace WGneu { 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"); } - - public static void SetInputInvalid(TextBox input) { - input.BorderBrush = System.Windows.Media.Brushes.Red; - } - - public static void SetInputValid(TextBox input) { - input.ClearValue(TextBox.BorderBrushProperty); - } } } diff --git a/WGneu/Windows/MemberListWindow.xaml b/WGneu/Windows/MemberListWindow.xaml index fd39913..1efeb36 100644 --- a/WGneu/Windows/MemberListWindow.xaml +++ b/WGneu/Windows/MemberListWindow.xaml @@ -155,6 +155,7 @@