| | | 1 | | namespace Buergerportal.Gebuehren; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Art der beantragten Amtshandlung. Jede Art hat eine Grundgebuehr |
| | | 5 | | /// gemaess (fiktiver) kommunaler Gebuehrenordnung. |
| | | 6 | | /// </summary> |
| | | 7 | | public enum Amtshandlung |
| | | 8 | | { |
| | | 9 | | Meldebescheinigung, |
| | | 10 | | Fuehrungszeugnis, |
| | | 11 | | Bauvoranfrage, |
| | | 12 | | Gewerbeanmeldung |
| | | 13 | | } |
| | | 14 | | |
| | | 15 | | /// <summary> |
| | | 16 | | /// Personenbezogene Ermaessigungsgruende. Wirken sich prozentual |
| | | 17 | | /// auf die Grundgebuehr aus. |
| | | 18 | | /// </summary> |
| | | 19 | | public enum Ermaessigung |
| | | 20 | | { |
| | | 21 | | Keine, |
| | | 22 | | Sozialleistungsbezug, |
| | | 23 | | Schwerbehinderung, |
| | | 24 | | Student |
| | | 25 | | } |
| | | 26 | | |
| | | 27 | | /// <summary> |
| | | 28 | | /// Berechnet Verwaltungsgebuehren fuer Amtshandlungen eines Buergerportals. |
| | | 29 | | /// Bewusst testbar geschnitten: reine Funktionen, klar abgegrenzte Regeln, |
| | | 30 | | /// definierte Fehlerfaelle. |
| | | 31 | | /// </summary> |
| | | 32 | | public class Gebuehrenrechner |
| | | 33 | | { |
| | | 34 | | // Grundgebuehren in Euro gemaess Gebuehrenordnung (fiktiv). |
| | 1 | 35 | | private static readonly Dictionary<Amtshandlung, decimal> Grundgebuehren = new() |
| | 1 | 36 | | { |
| | 1 | 37 | | [Amtshandlung.Meldebescheinigung] = 9.00m, |
| | 1 | 38 | | [Amtshandlung.Fuehrungszeugnis] = 13.00m, |
| | 1 | 39 | | [Amtshandlung.Bauvoranfrage] = 75.00m, |
| | 1 | 40 | | [Amtshandlung.Gewerbeanmeldung] = 26.00m |
| | 1 | 41 | | }; |
| | | 42 | | |
| | | 43 | | /// <summary> |
| | | 44 | | /// Liefert die Grundgebuehr einer Amtshandlung ohne jede Ermaessigung. |
| | | 45 | | /// </summary> |
| | | 46 | | public decimal Grundgebuehr(Amtshandlung handlung) |
| | 12 | 47 | | { |
| | 12 | 48 | | if (!Grundgebuehren.TryGetValue(handlung, out var betrag)) |
| | 0 | 49 | | { |
| | 0 | 50 | | throw new ArgumentOutOfRangeException( |
| | 0 | 51 | | nameof(handlung), |
| | 0 | 52 | | $"Keine Grundgebuehr fuer '{handlung}' hinterlegt."); |
| | | 53 | | } |
| | | 54 | | |
| | 12 | 55 | | return betrag; |
| | 12 | 56 | | } |
| | | 57 | | |
| | | 58 | | /// <summary> |
| | | 59 | | /// Prozentsatz der Ermaessigung. Ausgelagert, damit die Regel |
| | | 60 | | /// einzeln testbar ist. |
| | | 61 | | /// </summary> |
| | 8 | 62 | | public decimal ErmaessigungsProzent(Ermaessigung ermaessigung) => ermaessigung switch |
| | 8 | 63 | | { |
| | 3 | 64 | | Ermaessigung.Keine => 0.00m, |
| | 2 | 65 | | Ermaessigung.Sozialleistungsbezug => 1.00m, // vollstaendige Befreiung |
| | 2 | 66 | | Ermaessigung.Schwerbehinderung => 0.50m, |
| | 1 | 67 | | Ermaessigung.Student => 0.30m, |
| | 0 | 68 | | _ => throw new ArgumentOutOfRangeException(nameof(ermaessigung)) |
| | 8 | 69 | | }; |
| | | 70 | | |
| | | 71 | | /// <summary> |
| | | 72 | | /// Berechnet die zu zahlende Gebuehr fuer eine Amtshandlung unter |
| | | 73 | | /// Beruecksichtigung einer Ermaessigung. Ergebnis wird kaufmaennisch |
| | | 74 | | /// auf zwei Nachkommastellen gerundet. |
| | | 75 | | /// </summary> |
| | | 76 | | /// <param name="handlung">Die beantragte Amtshandlung.</param> |
| | | 77 | | /// <param name="ermaessigung">Der Ermaessigungsgrund.</param> |
| | | 78 | | /// <param name="anzahl">Anzahl gleicher Amtshandlungen (Standard 1).</param> |
| | | 79 | | /// <exception cref="ArgumentException">Wenn anzahl kleiner als 1 ist.</exception> |
| | | 80 | | public decimal BerechneGebuehr( |
| | | 81 | | Amtshandlung handlung, |
| | | 82 | | Ermaessigung ermaessigung = Ermaessigung.Keine, |
| | | 83 | | int anzahl = 1) |
| | 10 | 84 | | { |
| | 10 | 85 | | if (anzahl < 1) |
| | 3 | 86 | | { |
| | 3 | 87 | | throw new ArgumentException( |
| | 3 | 88 | | "Die Anzahl muss mindestens 1 betragen.", nameof(anzahl)); |
| | | 89 | | } |
| | | 90 | | |
| | 7 | 91 | | var grund = Grundgebuehr(handlung) * anzahl; |
| | 7 | 92 | | var prozent = ErmaessigungsProzent(ermaessigung); |
| | 7 | 93 | | var betrag = grund * (1.00m - prozent); |
| | | 94 | | |
| | 7 | 95 | | return Math.Round(betrag, 2, MidpointRounding.ToEven); |
| | 7 | 96 | | } |
| | | 97 | | } |