Exemplo n.º 1
0
        public ActionResult CalculateResult(int id)
        {
            RaceDetails details = _raceRepository.GetRaceDetails(UserContext.User.Id, UserContext.User.OrganizationId, id);

            if (details.Detail == null)
            {
                return(NotFoundResult());
            }

            if (details.Detail.EntityStateId != Dom.EntityType.Race.State.Open ||
                details.Detail.StartRaceTime == null ||
                details.Detail.DarknessBeginTime == null ||
                details.Detail.DarknessEndTime == null ||
                details.StatementPigeonIds == null ||
                (details.StatementPigeonIds != null && details.Detail.ReturnPigeonCount * 1.0 / details.StatementPigeonIds.Count <= 0.2))
            {
                return(NotFoundResult());
            }

            Race race = _raceRepository.Get <Race>(id);

            race.RaceResults.ToList().ForEach(
                x =>
            {
                x.RaceResultCategories.ToList().ForEach(c => _raceRepository.Delete(c));
                _raceRepository.Delete(x);
            });

            var members     = race.RacePigeons.Select(m => m.Pigeon.Member).Distinct().ToList();
            int memberCount = members.Count;
            int pigeonCount = race.RacePigeons.Count;
            ICollection <RaceResult> raceResults = new List <RaceResult>();

            foreach (var pigeonReturnTime in race.PigeonReturnTimes)
            {
                double?distance = race.RaceDistances.First(m => m.MemberId == pigeonReturnTime.Pigeon.MemberId)?.Distance;
                if (distance > 0)
                {
                    var totalTime = FlyTime(race.StartRaceTime.Value, pigeonReturnTime.ReturnTime);
                    var speed     = distance.Value / totalTime;
                    raceResults.Add(new RaceResult
                    {
                        Pigeon   = pigeonReturnTime.Pigeon,
                        RaceId   = id,
                        Distance = distance.Value,
                        FlyTime  = totalTime,
                        Speed    = speed * 60
                    });
                }
            }

            List <RaceResult> raceResultSortered = raceResults
                                                   .OrderByDescending(m => m.Speed)   //
                                                   .ThenByDescending(m => m.Distance) // якщо швидкість однакова, вище стоїть голуб із більшою дистанцією
                                                   .ThenBy(m => m.Pigeon.Number)      // якщо швидкість і дистанція однакові, вище стоїть голуб із меншим порядковим номером кільця
                                                   .ToList();
            //todo
            //Якщо середня швидкість першого голуба становить менше 600 м / хв.,
            //місця у гонці повинні визначатися за фактичним часом констатування голубів
            //у гонці без врахування швидкості та відстані від точки випуску до учасника.
            //Якщо зафіксований час співпадає для двох і більше голубів, розстановка місць здійснюється від більшої подоланої дистанції до меншої.

            int numberOfPrizes = pigeonCount / 5;

            // заокруглення в більшу сторону
            if (numberOfPrizes * 5 < pigeonCount)
            {
                numberOfPrizes++;
            }
            for (int i = 0; i < raceResultSortered.Count; i++)
            {
                raceResultSortered[i].Position = i + 1;
                if (i < numberOfPrizes)
                {
                    raceResultSortered[i].Ac = true;
                    var raceResultCategories = RaceManager.GetCategory(raceResultSortered[i].Pigeon.Year, raceResultSortered[i].Distance, memberCount, pigeonCount);
                    raceResultSortered[i].RaceResultCategories = new List <RaceResultCategory>();
                    foreach (var raceResultCategory in raceResultCategories)
                    {
                        raceResultSortered[i].RaceResultCategories.Add(
                            new RaceResultCategory
                        {
                            RaceResult  = raceResultSortered[i],
                            CategoryId  = raceResultCategory.Key,
                            IsOlymp     = raceResultCategory.Value,
                            Coefficient = RaceManager.CalculateCoefficient(pigeonCount, i + 1),
                            Mark        = RaceManager.CalculateMark(numberOfPrizes, i + 1)
                        });
                    }
                }
                race.RaceResults.Add(raceResultSortered[i]);
            }

            race.RaceStatistics.ToList().ForEach(x => _raceRepository.Delete(x));

            foreach (var member in members)
            {
                int    memberId          = member.Id;
                int    statedPigeonCount = race.RacePigeons.Count(m => m.Pigeon.MemberId == memberId);
                int    prizePigeonCount  = race.RaceResults.Count(m => m.Pigeon.MemberId == memberId && m.Ac);
                double mark = race.RaceResults.Where(m => m.Pigeon.MemberId == memberId && m.Ac).OrderBy(m => m.Position).Take(5).Sum(m => m.RaceResultCategories.First().Mark);
                race.RaceStatistics.Add(new RaceStatistic
                {
                    MemberId          = member.Id,
                    StatedPigeonCount = statedPigeonCount,
                    PrizePigeonCount  = prizePigeonCount,
                    Mark    = mark,
                    Success = prizePigeonCount * 100.0 / statedPigeonCount
                });
            }

            var firstPigeon = raceResultSortered.FirstOrDefault(m => m.Position == 1);
            var lastPigeon  = raceResultSortered.FirstOrDefault(m => m.Position == numberOfPrizes);

            race.PigeonCount     = race.RacePigeons.Count;
            race.MemberCount     = memberCount;
            race.AverageDistance = race.RaceDistances.Where(m => m.Distance > 0).Average(m => m.Distance);
            race.TimeOfFirst     = race.StartRaceTime.Value.AddSeconds(firstPigeon.FlyTime);
            race.TimeOfLast      = race.StartRaceTime.Value.AddSeconds(lastPigeon.FlyTime);
            race.SpeedOfFirst    = firstPigeon.Speed;
            race.SpeedOfLast     = lastPigeon.Speed;
            race.TwentyPercent   = race.PigeonCount / 5;
            race.CockCount       = race.RacePigeons.Count(m => m.Pigeon.SexId == Dom.Sex.C**k);
            race.HenCount        = race.RacePigeons.Count(m => m.Pigeon.SexId == Dom.Sex.Hen);
            int currentYear = DateTime.UtcNow.Year;

            race.YoungCount           = race.RacePigeons.Count(m => currentYear - m.Pigeon.Year == 0);
            race.YearlyCount          = race.RacePigeons.Count(m => currentYear - m.Pigeon.Year == 1);
            race.AdultsCount          = race.RacePigeons.Count(m => currentYear - m.Pigeon.Year > 1);
            race.StartСompetitionTime = race.PigeonReturnTimes.Min(m => m.ReturnTime);

            //todo
            race.EndСompetitionTime = race.StartRaceTime.Value.AddSeconds(lastPigeon.FlyTime);

            race.DurationOfCompetition    = race.EndСompetitionTime.Value.Subtract(race.StartСompetitionTime.Value).TotalSeconds;
            race.PigeonTwentyPercentAFact = race.RaceResults.Count(m => m.FlyTime < race.DurationOfCompetition.Value);
            race.MemberTwentyPercentAFact = race.RaceResults.Where(m => m.FlyTime < race.DurationOfCompetition.Value).Select(m => m.Pigeon.MemberId).Distinct().Count();
            race.InFactAbidedPercent      = race.PigeonTwentyPercentAFact * 100.0 / race.PigeonCount;
            _raceRepository.UnitOfWork.SaveChanges();

            return(RedirectToAction(Mvc.Controller.Race.Details, Mvc.Controller.Race.Name, new { id }));
        }