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 })); }