public List <Zahlung> Buche()
        {
            if (Gebucht)
            {
                throw new InvalidOperationException("Diese Abrechnung ist bereits gebucht.");
            }

            Verifiziere();

            var verlustumlage = BerechneVerlustumlage();

            var getränkekosten = BerechneKostenProBenutzer();

            Zahlungen.Clear();
            // Wir fügen selbst dann eine Zahlung hinzu wenn der Benutzer in dieser Abrechnung nichts bezahlen muss
            // Das erlaubt den Schluss abrechnung.Gebucht => es gibt eine Zahlung für jeden Benutzer in abrechnung.Benutzer
            Zahlungen.AddRange(Benutzer.Select(benutzer => new Zahlung()
            {
                Benutzer          = benutzer, // Untypisch, erleichtert aber die Zuweisung
                Betrag            = -verlustumlage[benutzer] - getränkekosten[benutzer],
                Buchungszeitpunkt = Endzeitpunkt,
                Beschreibung      = "Abrechnung: " + Name,
                Abrechnung        = this,
                Löschbar          = false
            }));

            Zahlungen.ForEach(z => z.Benutzer.Buche(z));

            Gebucht = true;

            return(Zahlungen);
        }
        public void Verifiziere()
        {
            var produkte = Verkaufsprodukte.ToDictionary(vk => vk.Produkt);

            if (produkte.Count != Verkaufsprodukte.Count)
            {
                throw new InvalidOperationException("In dieser Abrechung kommen doppelte Produkte vor.");
            }

            if (!Einkäufe.SelectMany(e => e.Positionen).Select(p => p.Kastengröße.Produkt).Distinct().All(p => produkte.ContainsKey(p)))
            {
                throw new InvalidOperationException("In den Einkäufen dieser Abrechnung kommt ein Produkt vor, das nicht Teil der Abrechnung ist.");
            }

            var paare = Verbrauche.Select(v => new { v.Benutzer, v.Verkaufsprodukt }).ToHashSet();

            if (!Benutzer.SelectMany(b => Verkaufsprodukte.Select(p => new { Benutzer = b, Verkaufsprodukt = p })).All(p => paare.Contains(p)))
            {
                throw new InvalidOperationException("Diese Abrechnung hat keinen Verbrauch für jeden Benutzer und jedes Produkt");
            }

            if (!Zahlungen.Select(z => z.Benutzer).ToHashSet().SetEquals(Benutzer))
            {
                throw new InvalidOperationException("Diese Abrechnung enthält nicht eine Zahlung für jeden Benutzer");
            }
        }
Beispiel #3
0
 public void Buche(Zahlung zahlung)
 {
     zahlung.AltesGuthaben = Guthaben;
     zahlung.NeuesGuthaben = Guthaben + zahlung.Betrag;
     Guthaben         = Guthaben + zahlung.Betrag;
     zahlung.Benutzer = this;
     Zahlungen.Add(zahlung);
 }
Beispiel #4
0
        public Zahlung SetzeKaution(double neueKaution, Konto konto)
        {
            double diff = Kaution - neueKaution;

            var zahlung = new Zahlung()
            {
                Buchungszeitpunkt = DateTime.Now,
                Betrag            = diff,
                Beschreibung      = "Kaution " + Vorname,
                Löschbar          = false
            };

            if (diff < 0)
            {
                // Zahlt der Benutzer Kaution ein, erhält das Konto Geld, der Benutzer aber kein Guthaben.
                var überweisung = new Überweisung()
                {
                    Buchungszeitpunkt = zahlung.Buchungszeitpunkt,
                    Betrag            = -zahlung.Betrag,
                    Beschreibung      = zahlung.Beschreibung,
                    Löschbar          = false
                };
                konto.Buche(überweisung);

                zahlung.Überweisung   = überweisung;
                zahlung.AltesGuthaben = Guthaben;
                zahlung.NeuesGuthaben = Guthaben;
                zahlung.Benutzer      = this;
                Zahlungen.Add(zahlung);
            }
            else
            {
                // Wird eine Kaution ausbezahlt, erhöht sich das Guthaben des Benutzers normal.
                Buche(zahlung);
            }

            Kaution = neueKaution;
            return(zahlung);
        }