683 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			683 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using System.Windows.Controls;
 | |
| using Elwig.Models.Entities;
 | |
| 
 | |
| namespace Elwig.Helpers {
 | |
|     public static class Validator {
 | |
| 
 | |
|         private static readonly Dictionary<string, string[][]> PHONE_NRS = new() {
 | |
|             { "43", [
 | |
|                 [],
 | |
|                 ["57", "59"],
 | |
|                 [
 | |
|                     "50", "517", "718", "804", "720", "780", "800", "802", "810",
 | |
|                     "820", "821", "828", "900", "901", "930", "931", "939",
 | |
|                     "650", "651", "652", "653", "655", "657", "659", "660", "661",
 | |
|                     "663", "664", "665", "666", "667", "668", "669", "67", "68", "69"
 | |
|                 ]
 | |
|             ] },
 | |
|             { "49", [] },
 | |
|             { "48", [] },
 | |
|             { "420", [] },
 | |
|             { "421", [] },
 | |
|             { "36", [] },
 | |
|             { "386", [] },
 | |
|             { "39", [] },
 | |
|             { "33", [] },
 | |
|             { "41", [] },
 | |
|             { "423", [] },
 | |
|         };
 | |
| 
 | |
|         public static ValidationResult CheckInteger(TextBox input, bool required) {
 | |
|             return CheckInteger(input, required, -1);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckInteger(TextBox input, bool required, int maxLen) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (char.IsAsciiDigit(ch))
 | |
|                     text += ch;
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0) {
 | |
|                 return required ? new(false, "Wert ist nicht optional") : new(true, null);
 | |
|             }
 | |
| 
 | |
|             if (maxLen >= 0 && input.Text.Length > maxLen) {
 | |
|                 input.Text = input.Text[..maxLen];
 | |
|                 input.CaretIndex = Math.Min(pos, maxLen);
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckDecimal(TextBox input, bool required) {
 | |
|             return CheckDecimal(input, required, -1, -1);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckDecimal(TextBox input, bool required, int maxLen, int maxDecimal, bool allowMinus = false) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             int v1 = 0, v2 = -1;
 | |
|             for (int i = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (ch == '-' && i == 0 && allowMinus) {
 | |
|                     text += ch;
 | |
|                 } else if (char.IsAsciiDigit(ch)) {
 | |
|                     if (v2 == -1 && (maxLen == -1 || v1 < maxLen)) {
 | |
|                         text += ch; v1++;
 | |
|                     } else if (v2 != -1 && (maxDecimal == -1 || v2 < maxDecimal)) {
 | |
|                         text += ch; v2++;
 | |
|                     }
 | |
|                 } else if (v2 == 0-1 && ch == ',' || ch == '.') {
 | |
|                     if (v1 == 0) { text += '0'; v1++; }
 | |
|                     text += ',';
 | |
|                     v2 = 0;
 | |
|                 }
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text == "-") {
 | |
|                 return new(false, "Ungültige Kommazahl");
 | |
|             } else if (text.Length == 0) {
 | |
|                 return required ? new(false, "Wert ist nicht optional") : new(true, null);
 | |
|             } else if (v2 == 0) {
 | |
|                 return new(false, "Ungültige Kommazahl");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckUpperCase(TextBox input, bool required) {
 | |
|             return CheckUpperCase(input, required, -1);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckUpperCase(TextBox input, bool required, int maxLen) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (char.IsAsciiLetter(ch))
 | |
|                     text += char.ToUpper(ch);
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0) {
 | |
|                 return required ? new(false, "Wert ist nicht optional") : new(true, null);
 | |
|             }
 | |
| 
 | |
|             if (maxLen >= 0 && input.Text.Length > maxLen) {
 | |
|                 input.Text = input.Text[..maxLen];
 | |
|                 input.CaretIndex = Math.Min(pos, maxLen);
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckPlz(TextBox input, bool required) {
 | |
|             CheckInteger(input, false, 4);
 | |
|             if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             } else if (input.Text.Length != 4) {
 | |
|                 return new(false, "PLZ zu kurz");
 | |
|             }
 | |
|             using var ctx = new AppDbContext();
 | |
|             int plz = int.Parse(input.Text);
 | |
|             if (ctx.Postleitzahlen.Find(plz) == null) {
 | |
|                 return new(false, "Ungültige PLZ");
 | |
|             }
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckPhoneNumber(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0, v = 0; i < input.Text.Length && v <= 15; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (v == 0 && input.Text.Length - i >= 2 && ch == '0' && input.Text[i + 1] == '0') {
 | |
|                     v++; i++;
 | |
|                     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') {
 | |
|                     v += 3;
 | |
|                     text += "+43";
 | |
|                 } else if (v == 0 && ch == '+') {
 | |
|                     v++;
 | |
|                     text += ch;
 | |
|                 } else if (v > 0 && (char.IsAsciiDigit(ch) || ch == ' ' || ch == '-')) {
 | |
|                     if (PHONE_NRS.Any(kv => text == "+" + kv.Key))
 | |
|                         text += ' ';
 | |
|                     if (text.StartsWith("+43 ")) {
 | |
|                         var nr = text[4..];
 | |
|                         var vws = PHONE_NRS["43"];
 | |
|                         if (!text.EndsWith(' ') && v >= 4 && v - 4 < vws.Length && vws[v - 4].Any(vw => nr.StartsWith(vw))) {
 | |
|                             text += ' ';
 | |
|                         } else if (nr == "1") {
 | |
|                             text += ' ';
 | |
|                         } else if (v == 7 && nr.Length == 4) {
 | |
|                             text += ' ';
 | |
|                         }
 | |
|                         var vw = text.Split(" ");
 | |
|                         if (char.IsAsciiDigit(ch)) {
 | |
|                             v++;
 | |
|                             text += ch;
 | |
|                         } else if (char.IsAsciiDigit(text[^1]) && vw.Length > 2 && v >= 10 && (vw[1].Length - 1 >= vws.Length || !vws[vw[1].Length - 1].Any(v => vw[1].StartsWith(v)))) {
 | |
|                             text += ch;
 | |
|                         }
 | |
|                     } else {
 | |
|                         v++;
 | |
|                         text += ch;
 | |
|                     }
 | |
|                 }
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (!required && text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             } else if (text.Length < 10) {
 | |
|                 return new(false, "Telefonnummer zu kurz");
 | |
|             }
 | |
| 
 | |
|             return new(char.IsAsciiDigit(text[^1]), null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckEmailAddress(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             bool domain = false;
 | |
|             for (int i = 0; i < input.Text.Length && text.Length < 256; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (domain) {
 | |
|                     if ((char.IsAsciiLetterOrDigit(ch)) || ".-_öäüßÖÄÜẞ".Any(c => c == ch)) {
 | |
|                         if (!(text.Last() == '.' && ch == '.'))
 | |
|                             text += char.ToLower(ch);
 | |
|                     }
 | |
|                 } else {
 | |
|                     if (ch == '@')
 | |
|                         domain = true;
 | |
|                     if (!char.IsControl(ch) && !char.IsWhiteSpace(ch))
 | |
|                         text += ch;
 | |
|                 }
 | |
| 
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0) {
 | |
|                 return required ? new(false, "E-Mail-Adresse ist nicht optional") : new(true, null);
 | |
|             } 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.IsAsciiLetterLower(ch)))
 | |
|                 return new(false, "E-Mail-Adresse ungültig");
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckIban(TextBox input, bool required) {
 | |
|             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.IsAsciiLetterOrDigit(ch)) {
 | |
|                     if (((v < 2 && char.IsAsciiLetter(ch)) || (v >= 2 && v < 4 && char.IsAsciiDigit(ch)) || v >= 4) &&
 | |
|                         ((!text.StartsWith("AT") && !text.StartsWith("DE")) || char.IsAsciiDigit(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 (!required && 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.IsAsciiDigit(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 CheckBic(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0, v = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if ((v < 4 || v >= 6) && char.IsAsciiLetterOrDigit(ch)) {
 | |
|                     v++;
 | |
|                     text += char.ToUpper(ch);
 | |
|                 } else if (v >= 4 && v < 6 && char.IsAsciiLetter(ch)) {
 | |
|                     v++;
 | |
|                     text += char.ToUpper(ch);
 | |
|                 }
 | |
| 
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
| 
 | |
|             if (text.Length == 0) {
 | |
|                 return required ? new(false, "BIC ist nicht optional") : new(true, null);
 | |
|             }
 | |
| 
 | |
|             if (text.Length > 11) {
 | |
|                 text = text[..11];
 | |
|                 pos = Math.Min(pos, 11);
 | |
|             }
 | |
| 
 | |
|             if (text.Length == 11 && text.EndsWith("XXX"))
 | |
|                 text = text[..8];
 | |
| 
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length != 11 && text.Length != 8)
 | |
|                 return new(false, "BIC ist ungültig");
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckLfbisNr(TextBox input, bool required) {
 | |
|             var res = CheckInteger(input, false, 7);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             } else if (input.Text.Length != 7) {
 | |
|                 return new(false, "Betriebsnummer zu kurz");
 | |
|             } else if (!CheckLfbisNr(input.Text)) {
 | |
|                 return new(false, "Prüfsumme der Betriebsnummer ist falsch");
 | |
|             } else {
 | |
|                 return new(true, null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static bool CheckLfbisNr(string nr) {
 | |
|             if (nr.Length != 7 || !nr.All(char.IsAsciiDigit))
 | |
|                 return false;
 | |
| 
 | |
|             // https://statistik.at/fileadmin/shared/QM/Standarddokumentationen/RW/std_r_land-forstw_register.pdf#page=41
 | |
|             int s = 0, v;
 | |
|             for (int i = 0; i < 6; i++)
 | |
|                 s += (nr[i] - '0') * (7 - i);
 | |
|             v = (11 - (s % 11)) % 10;
 | |
| 
 | |
|             return v == (nr[6] - '0');
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckUstIdNr(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0, v = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (v < 2 && char.IsAsciiLetter(ch)) {
 | |
|                     v++;
 | |
|                     text += char.ToUpper(ch);
 | |
|                 } else if (v >= 2 && char.IsAsciiLetterOrDigit(ch)) {
 | |
|                     if (text.StartsWith("AT")) {
 | |
|                         if (v == 2 && (ch == 'u' || ch == 'U')) {
 | |
|                             v++;
 | |
|                             text += 'U';
 | |
|                         } else if (v > 2 && char.IsAsciiDigit(ch)) {
 | |
|                             v++;
 | |
|                             text += ch;
 | |
|                         }
 | |
|                     } else {
 | |
|                         v++;
 | |
|                         text += char.ToUpper(ch);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (i == input.CaretIndex - 1) {
 | |
|                     pos = text.Length;
 | |
|                 } else if (v >= 14) {
 | |
|                     break;
 | |
|                 } else if (text.StartsWith("AT") && v >= 11) {
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0)
 | |
|                 return required ? new(false, "UID ist nicht optional") : new(true, null);
 | |
| 
 | |
|             if (text.StartsWith("AT")) {
 | |
|                 if (text.Length != 11 || text[2] != 'U') {
 | |
|                     return new(false, "UID ist ungültig");
 | |
|                 } else if (!CheckUstIdNr(text)) {
 | |
|                     return new(false, "Prüfsumme der UID ist falsch");
 | |
|                 }
 | |
|             } else {
 | |
|                 return new(false, "Not implemented yet");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static bool CheckUstIdNr(string nr) {
 | |
|             if (nr.Length < 4 || nr.Length > 14 || !nr.All(char.IsAsciiLetterOrDigit))
 | |
|                 return false;
 | |
| 
 | |
|             if (nr.StartsWith("AT")) {
 | |
|                 if (nr.Length != 11 || nr[2] != 'U')
 | |
|                     return false;
 | |
| 
 | |
|                 // http://www.pruefziffernberechnung.de/U/USt-IdNr.shtml
 | |
|                 int s = 0, v = 0;
 | |
|                 for (int i = 0; i < 7; i++)
 | |
|                     s += ((nr[i + 3] - '0') * (i % 2 + 1)).ToString().Select(ch => ch - '0').Sum();
 | |
|                 v = (96 - s) % 10;
 | |
| 
 | |
|                 return v == (nr[10] - '0');
 | |
|             } else {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckMgNr(TextBox input, bool required) {
 | |
|             var res = CheckInteger(input, required);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             using var ctx = new AppDbContext();
 | |
|             int nr = int.Parse(input.Text);
 | |
|             if (!ctx.MgNrExists(nr).GetAwaiter().GetResult()) {
 | |
|                 return new(false, "Ungültige Mitgliedsnummer");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckNewMgNr(TextBox input, bool required, Member? m) {
 | |
|             var res = CheckInteger(input, required);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             using var ctx = new AppDbContext();
 | |
|             int nr = int.Parse(input.Text);
 | |
|             if (nr != m?.MgNr && ctx.MgNrExists(nr).GetAwaiter().GetResult()) {
 | |
|                 return new(false, "Mitgliedsnummer wird bereits verwendet");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckSortId(TextBox input, bool required) {
 | |
|             var res = CheckUpperCase(input, required, 3);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             using var ctx = new AppDbContext();
 | |
|             if (input.Text.Length < 2 || !ctx.SortIdExists(input.Text[0..2]).GetAwaiter().GetResult()) {
 | |
|                 return new(false, "Ungültige Sorte");
 | |
|             } else if (input.Text.Length >= 3) {
 | |
|                 var disc = input.Text[2..];
 | |
|                 if (!ctx.AttrIdExists(disc).GetAwaiter().GetResult() && !ctx.CultIdExists(disc).GetAwaiter().GetResult()) {
 | |
|                     return new(false, "Ungültiges Attribut/Bewirt.");
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckPredecessorMgNr(TextBox input, bool required) {
 | |
|             var res = CheckInteger(input, required);
 | |
|             using var ctx = new AppDbContext();
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             } else if (!ctx.MgNrExists(int.Parse(input.Text)).GetAwaiter().GetResult()) {
 | |
|                 return new(false, "Ein Mitglied mit dieser Mitgliedsnummer existiert nicht");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckDate(TextBox input, bool required) {
 | |
|             return CheckDate(input, required, false);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckPartialDate(TextBox input, bool required) {
 | |
|             return CheckDate(input, required, true);
 | |
|         }
 | |
| 
 | |
|         private static ValidationResult CheckDate(TextBox input, bool required, bool partial) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             int p = 0;
 | |
|             var parts = new string?[3];
 | |
|             parts[0] = "";
 | |
|             for (int i = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (ch == '.') {
 | |
|                     if (p < 2 && (parts[p]?.Length > 0 || pos == text.Length)) {
 | |
|                         if (parts[p]?.Length == 1 && ((pos != text.Length && pos != text.Length - 1) || !input.IsFocused)) {
 | |
|                             parts[p] = "0" + parts[p];
 | |
|                             text = text[..(text.Length - 1)] + "0" + text[^1];
 | |
|                         }
 | |
|                         parts[++p] = "";
 | |
|                         text += '.';
 | |
|                     }
 | |
|                 } else if (char.IsAsciiDigit(ch)) {
 | |
|                     if ((partial && parts[p]?.Length < 4) || (!partial && ((p < 2 && parts[p]?.Length < 2) || (p == 2 && parts[2]?.Length < 4)))) {
 | |
|                         parts[p] += ch;
 | |
|                         text += ch;
 | |
|                     }
 | |
|                     if (p == 0 && pos == 1 && input.Text.Length >= 4 && input.Text.Length <= 9) {
 | |
|                         parts[++p] = "";
 | |
|                         text += '.';
 | |
|                         continue;  // skip caret update
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (i == input.CaretIndex - 1) {
 | |
|                     pos = text.Length;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0)
 | |
|                 return required ? new(false, "Datum ist nicht optional") : new(true, null);
 | |
| 
 | |
|             if (partial) {
 | |
|                 if (p == 0) {
 | |
|                     // only year provided
 | |
|                     return (parts[0]?.Length == 4) ? new(true, null) : new(false, "Datum ist ungültig");
 | |
|                 } else if (p == 1) {
 | |
|                     // only month and year provided
 | |
|                     int m = parts[0] != null && parts[0] != "" ? int.Parse(parts[0] ?? "0") : 0;
 | |
|                     if (parts[1]?.Length != 4 || parts[0]?.Length != 2 || m < 1 || m > 12)
 | |
|                         return new(false, "Datum ist ungültig");
 | |
|                     return new(true, null);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (!DateOnly.TryParseExact(text, "dd.MM.yyyy", out _))
 | |
|                 return new(false, "Datum ist ungültig");
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckTime(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             int v = 0;
 | |
|             for (int i = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = input.Text[i];
 | |
|                 if (v >= 0 && v < 5 && v != 2 && char.IsAsciiDigit(ch)) {
 | |
|                     if ((v == 0 && ch <= '2') || (v == 1 && (text[0] < '2' || ch <= '3')) || (v == 3 && ch <= '5') || v == 4) {
 | |
|                         text += ch;
 | |
|                         v++;
 | |
|                     }
 | |
|                 } else if (v == 2 && ch == ':') {
 | |
|                     text += ch;
 | |
|                     v++;
 | |
|                 }
 | |
|                 if (i == input.CaretIndex - 1)
 | |
|                     pos = text.Length;
 | |
|             }
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0) {
 | |
|                 return required ? new(false, "Wert ist nicht optional") : new(true, null);
 | |
|             } else if (v != 5) {
 | |
|                 return new(false, "Zeit ist ungültig");
 | |
|             } else {
 | |
|                 return new(true, null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckFbNr(TextBox input, bool required, AreaCom? c) {
 | |
|             var res = CheckInteger(input, required);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             using var ctx = new AppDbContext();
 | |
|             int nr = int.Parse(input.Text);
 | |
|             if (nr != c?.FbNr && ctx.FbNrExists(nr).GetAwaiter().GetResult()) {
 | |
|                 return new(false, "Flächenbindungsnummer wird bereits verwendet");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckGradatoinOe(TextBox input, bool required) {
 | |
|             var res = CheckInteger(input, required, 3);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             var oe = double.Parse(input.Text);
 | |
|             if (oe < 10 || oe >= 300) {
 | |
|                 return new(false, "Ungültiger Oechsle-Wert");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckGradationKmw(TextBox input, bool required) {
 | |
|             var res = CheckDecimal(input, required, 2, 1);
 | |
|             if (!res.IsValid) {
 | |
|                 return res;
 | |
|             } else if (!required && input.Text.Length == 0) {
 | |
|                 return new(true, null);
 | |
|             }
 | |
| 
 | |
|             var kmw = double.Parse(input.Text);
 | |
|             if (kmw < 5 || kmw >= 50) {
 | |
|                 return new(false, "Ungültiger KMW-Wert");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
| 
 | |
|         public static ValidationResult CheckOrganicAuthorityCode(TextBox input, bool required) {
 | |
|             string text = "";
 | |
|             int pos = input.CaretIndex;
 | |
|             for (int i = 0, v = 0; i < input.Text.Length; i++) {
 | |
|                 char ch = char.ToUpper(input.Text[i]);
 | |
|                 if (v < 2 && char.IsAsciiLetter(ch)) {
 | |
|                     v++;
 | |
|                     text += ch;
 | |
|                 } else if ((v == 2 || v == 6) && ch == '-') {
 | |
|                     v++;
 | |
|                     text += ch;
 | |
|                 } else if (v >= 2 && char.IsLetterOrDigit(ch)) {
 | |
|                     if (text.StartsWith("AT")) {
 | |
|                         if (v == 3 && ch == 'B' || v == 4 && ch == 'I' || v == 5 && ch == 'O') {
 | |
|                             v++;
 | |
|                             text += ch;
 | |
|                         } else if (v > 6 && char.IsAsciiDigit(ch)) {
 | |
|                             v++;
 | |
|                             text += ch;
 | |
|                         }
 | |
|                     } else {
 | |
|                         v++;
 | |
|                         text += ch;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (i == input.CaretIndex - 1) {
 | |
|                     pos = text.Length;
 | |
|                 } else if (text.StartsWith("AT") && v >= 10) {
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             input.Text = text;
 | |
|             input.CaretIndex = pos;
 | |
| 
 | |
|             if (text.Length == 0)
 | |
|                 return required ? new(false, "Bio-Kontrollstellen-Code ist nicht optional") : new(true, null);
 | |
| 
 | |
|             if (text.StartsWith("AT")) {
 | |
|                 if (text.Length != 10) {
 | |
|                     return new(false, "Bio-Kontrollstellen-Code ist ungültig");
 | |
|                 }
 | |
|             } else {
 | |
|                 return new(false, "Not implemented yet");
 | |
|             }
 | |
| 
 | |
|             return new(true, null);
 | |
|         }
 | |
|     }
 | |
| }
 |