public async Task <PersonLicense> AddNewLicenseAsync(string issuerId, string discipline, string key, Person person, int?season, DateTime?validFrom, DateTime?validTo,
                                                             PersonLicenseFlags flags, string category = null, int?number = null, string sponsor = null, Club club = null, string venueCode = null,
                                                             string transponder1 = null, string transponder2 = null)
        {
            var expert = calculatorManager.Find(discipline);

            if (expert == null)
            {
                throw new InvalidDisciplineException();
            }

            season    = season ?? expert.CurrentSeason;
            validFrom = validFrom ?? expert.SeasonStarts(season.Value);
            validTo   = validTo ?? expert.SeasonEnds(season.Value);

            if (category == null)
            {
                var age            = expert.SeasonAge(season.Value, person.BirthDate);
                var personCategory = await GetDefaultCategoryAsync(issuerId, discipline, person.Gender, age);

                category = personCategory?.Code;
            }

            if (venueCode == null && club != null)
            {
                await context.LoadAsync(club, c => c.Venues, c => c.VenueDiscipline == discipline);

                venueCode = club.Venues?.FirstOrDefault(v => v.VenueDiscipline == discipline)?.VenueCode;
            }

            var license = new PersonLicense
            {
                IssuerId     = issuerId,
                Discipline   = discipline,
                Key          = key,
                Season       = season.Value,
                ValidFrom    = validFrom.Value,
                ValidTo      = validTo.Value,
                Sponsor      = sponsor,
                Club         = club,
                Person       = person,
                Category     = category,
                Number       = number,
                Flags        = flags,
                VenueCode    = venueCode,
                Transponder1 = transponder1,
                Transponder2 = transponder2
            };

            context.PersonLicenses.Add(license);
            await context.SaveChangesAsync();

            recorder.RecordEvent(new PersonLicenseChangedEvent(license));
            return(license);
        }
        public async Task AddCompetitionAsync(Competition competition)
        {
            await EnsureValidSerieAsync(competition);

            if (competition.VenueCode != null)
            {
                var venue = await context.Venues.FirstOrDefaultAsync(v => v.Code == competition.VenueCode && competition.Discipline.StartsWith(v.Discipline));

                competition.Venue = venue ?? throw new VenueNotFoundException();
            }

            competition.Id = Guid.NewGuid();
            context.Competitions.Add(competition);
            await context.SaveChangesAsync();

            recorder.RecordEvent(new CompetitionAddedEvent(competition));
        }
        public async Task <DistanceCombinationCompetitor> AddNewCompetitorAsync(Guid competitorId, Guid distanceCombinationId, int?reserve,
                                                                                DistanceCombinationCompetitorStatus status)
        {
            using (var transaction = context.UseOrBeginTransaction(IsolationLevel.RepeatableRead))
                try
                {
                    var competitor = await context.Competitors.FirstOrDefaultAsync(c => c.Id == competitorId);

                    if (competitor == null)
                    {
                        throw new CompetitorNotFoundException();
                    }

                    var combination = await context.DistanceCombinations.FirstOrDefaultAsync(c => c.Id == distanceCombinationId);

                    if (combination == null)
                    {
                        throw new DistanceCombinationNotFoundException();
                    }

                    CategoryFilter.EnsureMatch(combination.CategoryFilter, competitor.Category);
                    ClassFilter.EnsureMatch(combination.ClassFilter, competitor.Class);

                    var combinationCompetitor = new DistanceCombinationCompetitor
                    {
                        DistanceCombination = combination,
                        Competitor          = competitor,
                        Reserve             = reserve,
                        Status = status
                    };

                    context.DistanceCombinationCompetitors.Add(combinationCompetitor);
                    await context.SaveChangesAsync();

                    recorder.RecordEvent(new DistanceCombinationClassificationChangedEvent(combination));

                    transaction.Commit();
                    return(combinationCompetitor);
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
        }
Example #4
0
        public async Task PresentInstanceResultAsync(Race race, string instanceName)
        {
            Debug.Assert(race.Distance != null, "race.Distance != null");

            using (var transaction = context.BeginTransaction(IsolationLevel.RepeatableRead))
                try
                {
                    race.PresentedInstanceName = instanceName;
                    await context.SaveChangesAsync();

                    foreach (var combination in await DistanceCombinations(race.Distance.CompetitionId, race.DistanceId).ToListAsync())
                    {
                        recorder.RecordEvent(new DistanceCombinationClassificationChangedEvent(combination));
                    }

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
        }
        public async Task AddRacesToHeatAsync(Distance distance, int round, int heat, bool shiftHeats = true, params Race[] races)
        {
            var expert = distanceExpertManager.Find(distance.Discipline);

            if (expert == null)
            {
                throw new InvalidDisciplineException();
            }

            using (var transaction = context.UseOrBeginTransaction(IsolationLevel.RepeatableRead))
                try
                {
                    if (heat < distance.FirstHeat)
                    {
                        throw new ValidationException(string.Format(Resources.InvalidHeat, heat));
                    }

                    // TODO: Continuous numbering may become optional here
                    if (await Races(distance.CompetitionId, distance.Id, round).AnyAsync(r => r.Heat == heat))
                    {
                        await RenumberHeatsAsync(distance, round, false, distance.FirstHeat, heat, 1);
                    }

                    var lane = 1;
                    if (!expert.FixedLanes)
                    {
                        lane = await(from r in context.Races
                                     where r.DistanceId == distance.Id && r.Round == round && r.Heat == heat
                                     select r.Lane).DefaultIfEmpty(0).MaxAsync() + 1;
                    }

                    foreach (var race in races)
                    {
                        race.Id       = Guid.NewGuid();
                        race.Distance = distance;
                        race.Round    = round;
                        race.Heat     = heat;
                        race.Lane     = expert.FixedLanes ? race.Lane : lane;
                        await OnAddingRaceAsync(distance, race);

                        context.Races.Add(race);
                        await context.SaveChangesAsync();

                        lane++;
                    }

                    IList <Distance> shiftedDistances = null;
                    if (shiftHeats)
                    {
                        shiftedDistances = await ShiftHeatsAsync(distance, round, heat);
                    }

                    transaction.Commit();

                    recorder.RecordEvent(new DistanceRacesAddedEvent(distance, races));
                    if (shiftHeats)
                    {
                        foreach (var shiftedDistance in shiftedDistances)
                        {
                            recorder.RecordEvent(new DistanceRacesChangedEvent(shiftedDistance, shiftedDistance.Races));
                        }
                    }
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
        }