/// <summary>
        /// Loads the data from database.
        /// </summary>
        private void LoadDataFromDb()
        {
            // Event-Id aus den Einstellungen holen
            var eventId = Properties.Settings.Default.EventId;

            using (var db = new AquariusDataContext(Properties.Settings.Default.ConnectionString))
            {
                // Test-Zugriff auf DB
                try
                {
                    var test = db.Events.ToList();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Fehler beim Datenbank-Zugriff! Verbindung zur Datenbank und Connection String in den Einstellungen prüfen.\r\n\r\nDetails:\r\n\r\n" + ex.ToString());
                    return;
                }

                var dbData = GlobalData.Instance;

                // Veranstaltungen laden
                var dbEvents = db.Events;
                dbData.EventsData = dbEvents.Select(e => new EventData()
                {
                    Id = e.Event_ID, Title = e.Event_Title
                }).ToList();
                if (dbData.EventsData.SingleOrDefault(ed => ed.Id == eventId) == null)
                {
                    MessageBox.Show("Veranstaltung nicht gefunden! Veranstaltung in den Einstellungen auswählen und Programm neu starten!");
                    return;
                }

                // Altersklassen einlesen
                var dbAgeClasses = db.AgeClasses.ToDictionary(ac => ac.AgeClass_ID, ac => ac);

                // Bootsklassen einlesen
                var dbBoatClasses = db.BoatClasses.ToDictionary(bc => bc.BoatClass_ID, bc => bc);

                // Ausschreibung einlesen
                var dbOffers = db.Offers.Where(o => o.Offer_Event_ID_FK == eventId).ToDictionary(o => o.Offer_ID, o => o);

                // Wettkämpfe einlesen
                var dbCompetions = db.Comps.Where(c => (c.Comp_Event_ID_FK == eventId) && c.Comp_DateTime != null).OrderBy(c => c.Comp_DateTime);

                // Boote einlesen (Entries sind Boote, in jedem Boot sitzt eine Mannschaft)
                // (gruppiert nach Meldung)
                var dbEntries = db.Entries.Where(e => e.Entry_Event_ID_FK == eventId).GroupBy(ee => ee.Entry_Race_ID_FK).ToDictionary(ee => ee.Key, ee => ee.Select(x => x).ToList());

                // Mannschaften einlesen
                // (gruppiert nach dem Boot, in dem sie sitzt)
                var dbCrews = db.Crews.GroupBy(c => c.Crew_Entry_ID_FK).ToDictionary(c => c.Key, c => c.Select(x => x).ToList());

                // Ruderer einlesen
                var dbAthlets = db.Athlets.ToDictionary(a => a.Athlet_ID, a => a);

                // Vereine einlesen
                var dbClubs = db.Clubs.ToDictionary(c => c.Club_ID, c => c);

                // Mappings Boot (!) <-> Verein
                var dbEntryLabels = db.EntryLabels.ToDictionary(el => el.EL_ID, el => el);

                // Labels für Boote (!)
                var dbLabels = db.Labels.ToDictionary(l => l.Label_ID, l => l);

                // Rennen tauchen mehrfach auf, falls es z. B. mehrere Leistungsgruppen gibt.
                // Da die Läufe aber ggf. noch nicht eingeteilt sind, lassen sich die Personen nicht
                // den einzelnen Rennen/Läufen zuweisen.
                // Derartig mehrfach vorkommende Rennen werden daher zu einem Rennen zusammengefasst:
                var competitionGroups = dbCompetions.GroupBy(c => c.Comp_Race_ID_FK).ToList();

                #region Wettkämpfe durchgehen

                dbData.RacesData = new List <RaceData>();
                foreach (var competionGroup in competitionGroups)
                {
                    _ = dbOffers.TryGetValue((int)competionGroup.Key, out var offer);
                    _ = dbAgeClasses.TryGetValue(offer.Offer_AgeClass_ID_FK, out var ageClass);
                    _ = dbBoatClasses.TryGetValue(offer.Offer_BoatClass_ID_FK, out var boatClass);

                    var  isChildrenRace    = (ageClass.AgeClass_MaxAge <= 14);
                    bool isLightweightRace = (offer.Offer_IsLightweight);
                    var  isCoxedRace       = (boatClass.BoatClass_Coxed == 1);

                    // Entscheiden, ob man das Rennen übernehmen muss
                    var raceOk = false;
                    if (isLightweightRace)
                    {
                        raceOk = true;                    // alle Leichtgewichtsrennen müssen zur Waage
                    }
                    if (isCoxedRace && !isChildrenRace)
                    {
                        raceOk = true;                                 // gesteuerte Rennen, die keine Kinderrennen sind, müssen zur Waage
                    }
                    if (raceOk)
                    {
                        // Rennzeit ist die Zeit des ersten Rennens dieser Gruppe
                        var raceTime = (DateTime)competionGroup.Select(x => x).OrderBy(c => c.Comp_DateTime).First().Comp_DateTime;

                        #region Gewichte bestimmen

                        var maxSingleWeight        = new Weight(ageClass.AgeClass_LW_UpperLimit, true);
                        var maxAverageWeight       = new Weight(ageClass.AgeClass_LW_AvgLimit, true);
                        var minCoxWeight           = new Weight(ageClass.AgeClass_LW_CoxLowerLimit, true);
                        var maxAdditionalCoxWeight = new Weight(ageClass.AgeClass_LW_CoxTolerance, true);

                        // wenn es kein gesteuertes Rennen ist, dann interessiert das Gewicht des Steuermanns nicht
                        if (!isCoxedRace)
                        {
                            minCoxWeight.Value = null;
                        }

                        // bei Kinderrennen interessiert das Gewicht des Steuermanns ebenfalls nicht
                        if (isChildrenRace)
                        {
                            minCoxWeight.Value = null;
                        }

                        // bei Einer-Rennen kein Mannschaftsdurchschnittsgewicht
                        if (boatClass.BoatClass_NumRowers == 1)
                        {
                            maxAverageWeight.Value = null;
                        }

                        // Wenn es kein Leichgewichtsrennen ist, dann interessieren auch die Gewichte der Ruderer nicht
                        if (!isLightweightRace)
                        {
                            maxSingleWeight.Value  = null;
                            maxAverageWeight.Value = null;
                        }

                        #endregion

                        // Rennen definieren und hinzufügen
                        var newRace = new RaceData()
                        {
                            Id                     = offer.Offer_ID,
                            RaceNumber             = offer.Offer_RaceNumber,
                            ShortTitle             = offer.Offer_ShortLabel,
                            LongTitle              = offer.Offer_LongLabel,
                            DateTime               = raceTime,
                            IsChildrenRace         = isChildrenRace,
                            IsCoxedRace            = isCoxedRace,
                            NumberOfRowers         = boatClass.BoatClass_NumRowers,
                            IsLightweightRace      = isLightweightRace,
                            MaxSingleWeight        = maxSingleWeight,
                            MaxAverageWeight       = maxAverageWeight,
                            MinCoxWeight           = minCoxWeight,
                            MaxAdditionalCoxWeight = maxAdditionalCoxWeight
                        };

                        dbData.RacesData.Add(newRace);

                        // zum aktuellen Rennen die Boote hinzufügen
                        newRace.BoatsData = new List <BoatData>();
                        _ = dbEntries.TryGetValue(offer.Offer_ID, out var entries);

                        if (entries != null)
                        {
                            foreach (var entry in entries)
                            {
                                // das Label für das Boot (!) (z. B. "Renngemeinschaft ...") bestimmen

                                var titleShort = "?";
                                var titleLong  = "?";

                                var entryLabel = dbEntryLabels.Values.FirstOrDefault(el => el.EL_Entry_ID_FK == entry.Entry_ID);
                                if (entryLabel != null)
                                {
                                    dbLabels.TryGetValue(entryLabel.EL_Label_ID_FK, out var label);
                                    titleShort = label?.Label_Short;
                                    titleLong  = label?.Label_Long;
                                }

                                var newBoat = new BoatData()
                                {
                                    TitleShort = titleShort,
                                    TitleLong  = titleLong,
                                    BibNumber  = (byte)entry.Entry_Bib,
                                    Canceled   = (entry.Entry_CancelValue > 0)
                                };

                                newRace.BoatsData.Add(newBoat);

                                // Zum aktuellen Boot die Mannschaft hinzufügen
                                newBoat.Rowers = new List <RowerData>();
                                _ = dbCrews.TryGetValue(entry.Entry_ID, out var crew);

                                #region Sonderbehandlung der Crew für den Fall, dass es Ummeldungen gibt

                                // TODO: Es ist nicht ganz klar, woran man Ummeldungen erkennt, bzw. woran
                                //       man erkennt, welches das alte, und welches das neue Crewmitglied
                                //       ist. Auf jeden Falls stehen beiden in der DB drin.

                                if (crew != null)
                                {
                                    // Gruppieren nach dem Sitzplatz
                                    var crewByPos = crew.GroupBy(c => c.Crew_Pos).ToList();

                                    // Crew-Liste löschen und neu füllen
                                    crew = new List <Crew>();
                                    foreach (var item in crewByPos)
                                    {
                                        // die Ruderer für die aktuelle Sitzposition sortiert nach DB-ID                       // TODO: Ist DB-ID wirklich das richtige ???
                                        var rowersOnCurrentPos = item.Select(x => x).OrderBy(x => x.Crew_ID);
                                        crew.Add(rowersOnCurrentPos.Last());
                                    }
                                }

                                #endregion

                                if (crew != null)
                                {
                                    // Crew durchgehen und ins Boot platzieren
                                    foreach (var crewMember in crew)
                                    {
                                        dbAthlets.TryGetValue(crewMember.Crew_Athlete_ID_FK, out var athlet);
                                        dbClubs.TryGetValue((int)athlet.Athlet_Club_ID_FK, out var club);

                                        if ((athlet != null) && (club != null))
                                        {
                                            var newRower = new RowerData()
                                            {
                                                Id             = athlet.Athlet_ID,
                                                ClubTitleLong  = club.Club_Name,
                                                ClubTitleShort = club.Club_Abbr,
                                                LastName       = athlet.Athlet_LastName,
                                                FirstName      = athlet.Athlet_FirstName,
                                                DateOfBirth    = athlet.Athlet_DOB,
                                                Gender         = (athlet.Athlet_Gender == 'M') ? Gender.Male : Gender.Female
                                            };

                                            if (crewMember.Crew_IsCox)
                                            {
                                                // es handelt sich um den Steuermann
                                                newBoat.Cox = newRower;
                                            }
                                            else
                                            {
                                                // normaler Ruderer
                                                newBoat.Rowers.Add(newRower);
                                            }
                                        }
                                        else
                                        {
                                            // Fehler: Ruderer oder Verein nicht gefunden
                                            Tools.LogErrorNoMessageBox("Warnung: Ruderer oder kein Verein zu Crew nicht gefunden. Rennen ", offer.Offer_RaceNumber, offer.Offer_ShortLabel);
                                        }
                                    }
                                }
                                else
                                {
                                    // Fehler: keine Mannschaft für das Boot gefunden
                                    Tools.LogErrorNoMessageBox("Warnung: Mannschaft zu Rennen nicht gefunden. Rennen ", offer.Offer_RaceNumber, offer.Offer_ShortLabel);
                                }
                            }
                        }

                        // Boote sortieren nach Startnummer
                        newRace.BoatsData = newRace.BoatsData.OrderBy(b => b.BibNumber).ToList();
                    }
                }

                #endregion

                #region Ruderer anhand der ermittelten Rennen bestimmen

                var newRowers = new List <RowerData>();
                foreach (var raceData in dbData.RacesData)
                {
                    foreach (var boatData in raceData.BoatsData)
                    {
                        // Ruderer hinzufügen
                        foreach (var rowerData in boatData.Rowers)
                        {
                            if (!newRowers.Any(r => r.Id == rowerData.Id))
                            {
                                newRowers.Add(rowerData);
                            }
                        }

                        // Steuermann hinzufügen
                        if (boatData.Cox != null)
                        {
                            if (!newRowers.Any(r => r.Id == boatData.Cox.Id))
                            {
                                newRowers.Add(boatData.Cox);
                            }
                        }
                    }
                }

                dbData.RowersData = newRowers.OrderBy(r => r.LastName).ThenBy(r => r.FirstName).ToList();

                #endregion

                // Rennen sortieren nach Startzeit
                dbData.RacesData = dbData.RacesData.OrderBy(r => r.DateTime).ToList();
            }
        }
예제 #2
0
        /// <summary>
        /// Adds the rower.
        /// </summary>
        /// <param name="rowers">The rowers.</param>
        /// <param name="raceData">The race data.</param>
        /// <param name="rowerData">The rower data.</param>
        /// <param name="rowerIsCox">if set to <c>true</c> [steuermann].</param>
        /// <param name="delay">The delay.</param>
        public void AddRower(ref List <UserControls.Rower> rowers, RaceData raceData, RowerData rowerData, bool rowerIsCox, TimeSpan delay)
        {
            var coronaSonderregeln = DateTime.Now.Year <= 2021;


            UserControls.RowerStatus rowerStatus = UserControls.RowerStatus.None;
            string weightRower = "-";
            float? weightInfo  = null;

            var weightings = GlobalData.Instance.Weightings.Where(w => w.Id == rowerData.Id).ToList();
            var raceDt     = raceData.DateTime + delay;

            var weightRowerRequired = raceData.MaxSingleWeight.IsSpecified();
            var weightCoxRequired   = raceData.MaxAdditionalCoxWeight.IsSpecified();

            if (raceData.IsChildrenRace)
            {
                #region Kinderennen

                #region Zeitfenster für's Wiegen im Kinderrennen

                DateTime existingWeightingAcceptedFromDt;
                DateTime newWeightingAcceptedFromDt;
                DateTime weightingToDt;

                if (coronaSonderregeln)
                {
                    // ACHTUNG: Aktuell gibt es nur ein Zeitfenster, egal ob für Ruderer oder Steuermann. Das kann man nur machen, weil für beide das gleiche Zeitfenster gilt!

                    // Es gibt kein "frühestens", das Kind darf so früh kommen wie es möchte
                    // Daher ist "frühestens" der 01.01.2000 und das ist auf jeden Fall vor jedem beliebigen Zeitpunkt, zu dem das Kind kommt.
                    // Könnte man eigentlich zusammen mit der Abfrage rauswerfen, aber vielleicht gibt es ja doch mal ein "frühestens"

                    // EINSTELLUNG: ab wann wird eine bereits existierende Wiegung für das aktuelle Rennen berücksichtigt?
                    // frühestens 01.01.2000 04:00 Uhr
                    existingWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0);

                    // EINSTELLUNG (2 Werte): Zeitfenster, in dem eine weitere/neue Wiegung für das aktuelle Rennen zugelassen ist

                    // neue Wiegung (wenn es keine andere gibt) frühestens ??? h ??? min vorher
                    // gleicher Fall wie oben, daher auch 01.01.2000 04:00 Uhr
                    newWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0); // ansonsten so was hier:    raceDt.Add(new TimeSpan(-2, -5, 0));

                    // spätestens 1 Stunde vorher
                    weightingToDt = raceDt.Add(new TimeSpan(-1, 0, 0));
                }
                else
                {
                    // ACHTUNG: Aktuell gibt es nur ein Zeitfenster, egal ob für Ruderer oder Steuermann. Das kann man nur machen, weil für beide das gleiche Zeitfenster gilt!

                    // Es gibt kein "frühestens", das Kind darf so früh kommen wie es möchte
                    // Daher ist "frühestens" der 01.01.2000 und das ist auf jeden Fall vor jedem beliebigen Zeitpunkt, zu dem das Kind kommt.
                    // Könnte man eigentlich zusammen mit der Abfrage rauswerfen, aber vielleicht gibt es ja doch mal ein "frühestens"

                    // EINSTELLUNG: ab wann wird eine bereits existierende Wiegung für das aktuelle Rennen berücksichtigt?
                    // frühestens 01.01.2000 04:00 Uhr
                    existingWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0);

                    // EINSTELLUNG (2 Werte): Zeitfenster, in dem eine weitere/neue Wiegung für das aktuelle Rennen zugelassen ist

                    // neue Wiegung (wenn es keine andere gibt) frühestens ??? h ??? min vorher
                    // gleicher Fall wie oben, daher auch 01.01.2000 04:00 Uhr
                    newWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0); // ansonsten so was hier:    raceDt.Add(new TimeSpan(-2, -5, 0));

                    // spätestens 1 Stunde vorher
                    weightingToDt = raceDt.Add(new TimeSpan(-1, 0, 0));
                }

                #endregion

                // Ruderer muss im Zeitfenster zum Wiegen gekommen sein
                // => letzte Wiegung im Zeitfenster bestimmen
                var weighting = weightings.Where(w => (w.Zeitstempel >= existingWeightingAcceptedFromDt) && (w.Zeitstempel <= weightingToDt)).OrderByDescending(x => x.Zeitstempel).FirstOrDefault();

                if (!rowerIsCox)
                {
                    // normaler Ruderer im Kinderrennen (nicht der Steuermann)

                    if (weightRowerRequired)
                    {
                        // Ruderer muss gewogen werden

                        if (weighting != null)
                        {
                            // Es gibt eine Wiegung im Zeitfenster, die entscheidet, ob der Ruderer starten darf.
                            // (Wenn es hingegen keine gültige Wiegung gibt, kann der Status auch nicht OK sein.)

                            rowerStatus = (weighting.Gewicht <= raceData.MaxSingleWeight.Value) ? UserControls.RowerStatus.WeightOk : UserControls.RowerStatus.WeightNotOk;
                            weightInfo  = weighting.Gewicht;
                            weightRower = $"{weighting.Gewicht} kg";
                        }
                        else
                        {
                            // keine Wiegung im Zeitfenster vorhanden
                            // entweder es ist noch zu früh zum Wiegen oder es ist schon zu spät dazu

                            rowerStatus = GetStatusNoWeight(newWeightingAcceptedFromDt, weightingToDt);
                        }
                    }
                    else
                    {
                        // Ruderer muss nicht gewogen werden (kein Leichtgewichtrennen)
                        rowerStatus = UserControls.RowerStatus.WeightOk;
                    }
                }
                else
                {
                    // Es handelt sich um einen Steuerman im Kinderrennen

                    // Steuermann im Kinderrennen muss grundsätzlich nicht gewogen werden!

                    rowerStatus = UserControls.RowerStatus.WeightOk;
                }

                #endregion Kinderennen
            }
            else
            {
                #region Kein Kinderennen

                #region Zeitfenster für's Wiegen

                DateTime existingWeightingAcceptedFromDt;
                DateTime newWeightingAcceptedFromDt;
                DateTime weightingToDt;

                if (coronaSonderregeln)
                {
                    // ACHTUNG: Aktuell gibt es nur ein Zeitfenster, egal ob für Ruderer oder Steuermann. Das kann man nur machen, weil für beide das gleiche Zeitfenster gilt!

                    // frühestens 2 Stunden vor dem ersten Rennen an diesem Tag.
                    // Das wird hier aber nicht abgefragt, weil man dann hier abfragen müsste, ob dieses Rennen hier das erste an diesem Tag ist oder nicht.
                    // Stattdessen verlassen wir uns hier darauf, niemand außerhalb des zugelassenen Zeitfensters zum Wiegen zugelassen wurde,
                    // in dem Fall muss die letzte/jüngste Wiegung auch eine gültige Wiegung sein, Hauptsache, sie hat am gleichen Tag stattgefunden.

                    // EINSTELLUNG: ab wann wird eine bereits existierende Wiegung für das aktuelle Rennen berücksichtigt?
                    // frühestens 01.01.2000 04:00 Uhr                                   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    existingWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                    // EINSTELLUNG (2 Werte): Zeitfenster, in dem eine weitere/neue Wiegung für das aktuelle Rennen zugelassen ist
                    // gleicher Fall wie oben, daher auch 01.01.2000 04:00 Uhr                                                                        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    newWeightingAcceptedFromDt = new DateTime(2000, 1, 1, 4, 0, 0); // ansonsten so was hier:    raceDt.Add(new TimeSpan(-2, -5, 0)); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                    // spätestens 1 Stunde vorher
                    weightingToDt = raceDt.Add(new TimeSpan(-1, 0, 0));
                }
                else
                {
                    // ACHTUNG: Aktuell gibt es nur ein Zeitfenster, egal ob für Ruderer oder Steuermann. Das kann man nur machen, weil für beide das gleiche Zeitfenster gilt!

                    // frühestens 2 Stunden vor dem ersten Rennen an diesem Tag.
                    // Das wird hier aber nicht abgefragt, weil man dann hier abfragen müsste, ob dieses Rennen hier das erste an diesem Tag ist oder nicht.
                    // Stattdessen verlassen wir uns hier darauf, niemand außerhalb des zugelassenen Zeitfensters zum Wiegen zugelassen wurde,
                    // in dem Fall muss die letzte/jüngste Wiegung auch eine gültige Wiegung sein, Hauptsache, sie hat am gleichen Tag stattgefunden.

                    // EINSTELLUNG: ab wann wird eine bereits existierende Wiegung für das aktuelle Rennen berücksichtigt?
                    // frühestens 4 Uhr morgens am Tag des Rennens (und damit sicher nicht mehr am Vortrag)
                    existingWeightingAcceptedFromDt = new DateTime(raceDt.Year, raceDt.Month, raceDt.Day, 4, 0, 0);

                    // EINSTELLUNG (2 Werte): Zeitfenster, in dem eine weitere/neue Wiegung für das aktuelle Rennen zugelassen ist
                    // neue Wiegung (wenn es keine andere gibt) frühestens 2 h vorher
                    newWeightingAcceptedFromDt = raceDt.Add(new TimeSpan(-2, 0, 0));

                    // spätestens 1 Stunde vorher
                    weightingToDt = raceDt.Add(new TimeSpan(-1, 0, 0));
                }

                #endregion

                // Ruderer muss im Zeitfenster zum Wiegen gekommen sein
                // => letzte Wiegung im Zeitfenster bestimmen
                var weighting = weightings.Where(w => (w.Zeitstempel >= existingWeightingAcceptedFromDt) && (w.Zeitstempel <= weightingToDt)).OrderByDescending(x => x.Zeitstempel).FirstOrDefault();

                if (!rowerIsCox)
                {
                    // normaler Ruderer (nicht der Steuermann)

                    if (weightRowerRequired)
                    {
                        // Ruderer muss gewogen werden

                        if (weighting != null)
                        {
                            // Es gibt eine Wiegung im Zeitfenster, die entscheidet, ob der Ruderer starten darf.
                            // (Wenn es hingegen keine gültige Wiegung gibt, kann der Status auch nicht OK sein.)

                            rowerStatus = (weighting.Gewicht <= raceData.MaxSingleWeight.Value) ? UserControls.RowerStatus.WeightOk : UserControls.RowerStatus.WeightNotOk;
                            weightInfo  = weighting.Gewicht;
                            weightRower = $"{weighting.Gewicht} kg";
                        }
                        else
                        {
                            // keine Wiegung im Zeitfenster vorhanden
                            // entweder es ist noch zu früh zum Wiegen oder es ist schon zu spät dazu

                            rowerStatus = GetStatusNoWeight(newWeightingAcceptedFromDt, weightingToDt);
                        }
                    }
                    else
                    {
                        // Ruderer muss nicht gewogen werden (kein Leichtgewichtrennen)
                        rowerStatus = UserControls.RowerStatus.WeightOk;
                    }
                }
                else
                {
                    // Es handelt sich um einen Steuerman

                    if (weightCoxRequired)
                    {
                        // Steuermann muss gewogen werden

                        if (weighting != null)
                        {
                            // Es gibt eine Wiegung im Zeitfenster, die entscheidet, ob der Ruderer starten darf.
                            // (Wenn es hingegen keine gültige Wiegung gibt, kann der Status auch nicht OK sein.)
                            // (Steuermann darf leichter sein als das Mindestgewicht, sofern er damit nicht das maximale Zusatzgewicht überschreitet.)

                            rowerStatus = (weighting.Gewicht >= raceData.MinCoxWeight.Value - raceData.MaxAdditionalCoxWeight.Value) ? UserControls.RowerStatus.WeightOk : UserControls.RowerStatus.WeightNotOk;
                            weightInfo  = weighting.Gewicht;
                            weightRower = $"{weighting.Gewicht} kg";
                        }
                        else
                        {
                            // keine Wiegung im Zeitfenster vorhanden
                            // entweder es ist noch zu früh zum Wiegen oder es ist schon zu spät dazu

                            rowerStatus = GetStatusNoWeight(newWeightingAcceptedFromDt, weightingToDt);
                        }
                    }
                    else
                    {
                        // Steuermann muss nicht gewogen werden (kein Leichtgewichtrennen)
                        rowerStatus = UserControls.RowerStatus.WeightOk;
                    }
                }

                #endregion Kein Kinderennen
            }

            var newRower = new UserControls.Rower()
            {
                Id         = rowerData.Id,
                Name       = $"{rowerData.LastName}, {rowerData.FirstName} ({weightRower})",
                Type       = rowerIsCox ? UserControls.RowerType.Cox : UserControls.RowerType.Rower,
                Status     = rowerStatus,
                WeightInfo = weightInfo
            };

            rowers.Add(newRower);
        }