Beispiel #1
0
        /// <summary>
        /// Validates the flight matrix.
        /// </summary>
        /// <param name="flightMatrix">The flight matrix.</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private bool ValidateFlightMatrix(FlightMatrix flightMatrix)
        {
            if (flightMatrix == null)
            {
                return(false);
            }

            if (flightMatrix.Matrix == null ||
                flightMatrix.Matrix.Count < 1)
            {
                return(false);
            }

            if (string.IsNullOrEmpty(flightMatrix.ContestId))
            {
                return(false);
            }

            foreach (var flightMatrixRounds in flightMatrix.Matrix)
            {
                if (flightMatrixRounds.PilotSlots.Count < 1)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #2
0
        public async Task FlightMatrixQueryInteractor_GetFlightMatrixForContest_HappyPath()
        {
            var contestId = "dfklewrowidf";

            var flightMatrix = new FlightMatrix
            {
                ContestId = contestId,
                Matrix    = new List <FlightMatrixRound>
                {
                    new FlightMatrixRound
                    {
                        RoundOrdinal = 0,
                        PilotSlots   = new List <FlightMatrixPilotSlot>
                        {
                            new FlightMatrixPilotSlot
                            {
                                PilotId     = "sdfsf",
                                FlightGroup = FlightGroup.A
                            }
                        }
                    }
                }
            };

            mockFlightMatrixRepository.Setup(fmqr => fmqr.ReadAsync(contestId)).Returns(Task.FromResult(new Result <FlightMatrix>(flightMatrix)));
            var fmqInteractor = new FlightMatrixQueryInteractor(mockFlightMatrixRepository.Object, mockLogger.Object);
            var result        = await fmqInteractor.GetFlightMatrixForContest(contestId);

            Assert.IsFalse(result.IsFaulted);
            Assert.AreEqual(contestId, result.Value.ContestId);
            Assert.IsNotNull(result.Value.Matrix);
            Assert.AreEqual(1, result.Value.Matrix.Count);
        }
        /// <summary>
        /// Stores a new flight matrix in the file.
        /// </summary>
        /// <param name="flightMatrixToCreate">The flight matrix to create.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > CreateAsync(FlightMatrix flightMatrixToCreate)
        {
            if (flightMatrixToCreate == null)
            {
                return(Error <FlightMatrix>(null, "The Pilot cannot be null"));
            }

            if (!string.IsNullOrEmpty(flightMatrixToCreate.Id))
            {
                this.logger.LogTrace("The Id already has a value, and that's ok for this repository");
            }

            var allFlightMatricies = new List <FlightMatrix>
            {
                flightMatrixToCreate
            };

            try
            {
                var success = await WriteAll(allFlightMatricies);

                this.cache.Put(FLIGHT_MATRIX_CACHE_KEY, allFlightMatricies);
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }

            return(Success((allFlightMatricies.Where(p => p.Id == flightMatrixToCreate.Id)).First(), nameof(CreateAsync)));
        }
Beispiel #4
0
        public async Task FlightMatrixCommandInteractor_SaveFlightMatrixForContestAsync_HappyPath()
        {
            var flightMatrix = new FlightMatrix
            {
                ContestId = "sdfasdf"
            };

            flightMatrix.Matrix.Add(new FlightMatrixRound
            {
                RoundOrdinal = 0,
                PilotSlots   = new List <FlightMatrixPilotSlot>
                {
                    new FlightMatrixPilotSlot
                    {
                        PilotId     = "sadfxcvcxasdf",
                        FlightGroup = FlightGroup.A
                    }
                }
            });

            mockFlightMatrixRepository.Setup(f => f.CreateAsync(It.IsAny <FlightMatrix>())).Returns <FlightMatrix>(x => Task.FromResult(new Result <FlightMatrix>(flightMatrix)));

            var flightMatrixCmdInteractor = new FlightMatrixStorageCmdInteractor(mockFlightMatrixRepository.Object, mockLogger.Object);
            var result = await flightMatrixCmdInteractor.SaveFlightMatrixForContestAsync(flightMatrix);

            Assert.IsFalse(result.IsFaulted);
            Assert.IsNotNull(result.Value);
        }
        /// <summary>
        /// Creates the asynchronous.
        /// </summary>
        /// <param name="flightMatrixToCreate">The flight matrix to create.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > CreateAsync(FlightMatrix flightMatrixToCreate)
        {
            if (flightMatrixToCreate == null)
            {
                return(Error <FlightMatrix>(null, "The Pilot cannot be null"));
            }

            if (!string.IsNullOrEmpty(flightMatrixToCreate.Id))
            {
                return(Error <FlightMatrix>(null, "The Id already has a value"));
            }

            var allFlightMatricies = (await GetAll <FlightMatrix>()) ?? new List <FlightMatrix>();

            if (allFlightMatricies == null)
            {
                allFlightMatricies = new List <FlightMatrix>();
            }

            // Assign a new GUID for the ID
            flightMatrixToCreate.Id = base.GenerateId();

            allFlightMatricies.Add(flightMatrixToCreate);

            try
            {
                var success = await WriteAll <FlightMatrix>(allFlightMatricies);
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }

            return(Success((allFlightMatricies.Where(p => p.Id == flightMatrixToCreate.Id)).First(), nameof(CreateAsync)));
        }
        public void FlightMatrixGenerationInteractor_CreateSortedFlightMatrix_SortingAlgo_HappyPath()
        {
            var pilotRegistrations = GenerateValidPilotRegistration(10);

            var flightMatrix = new FlightMatrix
            {
                ContestId = "sdfasdf"
            };

            flightMatrix.Matrix.Add(new FlightMatrixRound
            {
                RoundOrdinal = 0,
                PilotSlots   = new List <FlightMatrixPilotSlot>
                {
                    new FlightMatrixPilotSlot
                    {
                        PilotId     = "sadfxcvcxasdf",
                        FlightGroup = FlightGroup.A
                    }
                }
            });

            this.mockSortingAlgo.Setup(sa => sa.GenerateInitialMatrix(It.IsAny <IEnumerable <PilotRegistration> >(), It.IsAny <int>(), It.IsAny <int>())).Returns(flightMatrix);

            var fmgi   = new FlightMatrixGenInteractor(mockSortingAlgo.Object, mockLogger.Object);
            var result = fmgi.CreateSortedFlightMatrix(pilotRegistrations, 1, 7);

            Assert.IsFalse(result.IsFaulted);
            Assert.IsNull(result.Error);
            Assert.IsNotNull(result.Value);
        }
Beispiel #7
0
        /// <summary>
        /// Updates the specified flight matrix.
        /// </summary>
        /// <param name="flightMatrix">The flight matrix.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > UpdateAsync(FlightMatrix flightMatrix)
        {
            if (flightMatrix == null)
            {
                return(Error <FlightMatrix>(null, new ArgumentNullException(nameof(flightMatrix), "Pilot cannot be null.")));
            }

            if (string.IsNullOrEmpty(flightMatrix.Id))
            {
                return(Error <FlightMatrix>(null, new ArgumentOutOfRangeException(nameof(flightMatrix), "The Pilot passed in does not have a valid id.")));
            }

            // Check cache
            var allMatricies = this.cache.Get <List <FlightMatrix> >(FLIGHT_MATRIX_CACHE_KEY);

            if (allMatricies == null)
            {
                allMatricies = (await GetAll <FlightMatrix>()) ?? new List <FlightMatrix>();
            }

            if (allMatricies == null ||
                allMatricies.Count < 1 ||
                allMatricies.Where(matrix => matrix.Id != flightMatrix.Id).FirstOrDefault() == null)
            {
                return(Error <FlightMatrix>(null, new Exception("A flight matrix with that name and id could not be found.")));
            }

            // Clear out any existing matrices with the same id or contest id.
            var newFlightMatrixList = allMatricies.Where(
                matrix => matrix.Id != flightMatrix.Id &&
                matrix.ContestId != flightMatrix.ContestId).ToList();

            newFlightMatrixList.Add(flightMatrix);

            var result = false;

            try
            {
                // Write the new pilot list.
                result = await WriteAll <FlightMatrix>(newFlightMatrixList);

                this.cache.Put(FLIGHT_MATRIX_CACHE_KEY, newFlightMatrixList);
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }

            if (!result)
            {
                return(Error <FlightMatrix>(null, $"An error occured with updating the flight matrix with id {flightMatrix.Id}."));
            }
            else
            {
                return(Success(flightMatrix, nameof(UpdateAsync)));
            }
        }
        public async Task <IActionResult> AddFlightMatrix([FromBody] FlightMatrix flightMatrix)
        {
            var result = await this.flightMatrixStorageCmdInteractor.SaveFlightMatrixForContestAsync(flightMatrix);

            if (result.IsFaulted)
            {
                return(BadRequest(result.Error.ErrorMessage));
            }

            return(Ok());
        }
Beispiel #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FileFormat" /> class.
 /// </summary>
 /// <param name="contest">The contest.</param>
 /// <param name="pilots">The pilots.</param>
 /// <param name="flightMatrix">The flight matrix.</param>
 /// <param name="registrations">The registrations.</param>
 /// <param name="timeSheets">The time sheets.</param>
 public FileFormat(Contest contest,
                   IEnumerable <Pilot> pilots,
                   FlightMatrix flightMatrix,
                   IEnumerable <PilotRegistration> registrations,
                   IEnumerable <TimeSheet> timeSheets)
 {
     this.Contest       = contest;
     this.FlightMatrix  = flightMatrix;
     this.Pilots        = pilots == null ? new List <Pilot>(pilots) : new List <Pilot>();
     this.Registrations = registrations == null ? new List <PilotRegistration>(registrations) : new List <PilotRegistration>();
     this.TimeSheets    = timeSheets == null ? new List <TimeSheet>(timeSheets) : new List <TimeSheet>();
 }
Beispiel #10
0
        public async Task FlightMatrixCommandInteractor_SaveFlightMatrixForContestAsync_NoPilotsInMatrix()
        {
            var flightMatrix = new FlightMatrix
            {
                ContestId = "234234"
            };

            var flightMatrixCmdInteractor = new FlightMatrixStorageCmdInteractor(mockFlightMatrixRepository.Object, mockLogger.Object);
            var result = await flightMatrixCmdInteractor.SaveFlightMatrixForContestAsync(flightMatrix);

            Assert.IsTrue(result.IsFaulted);
            Assert.IsNull(result.Value);
        }
Beispiel #11
0
        public async Task FlightMatrixCommandInteractor_SaveFlightMatrixForContestAsync_BadFlightMatrixParameter()
        {
            var flightMatrix = new FlightMatrix
            {
                Matrix = null
            };

            var flightMatrixCmdInteractor = new FlightMatrixStorageCmdInteractor(mockFlightMatrixRepository.Object, mockLogger.Object);
            var result = await flightMatrixCmdInteractor.SaveFlightMatrixForContestAsync(flightMatrix);

            Assert.IsTrue(result.IsFaulted);
            Assert.IsNull(result.Value);
        }
        /// <summary>
        /// Inflates the matrix.
        /// </summary>
        /// <param name="pilotMatrix">The pilot matrix.</param>
        private async Task InflateMatrix(FlightMatrix pilotMatrix)
        {
            var flightMatrixGenerationIntr = new FlightMatrixGenInteractor(App.SortingAlgos.Where(algo => algo.GetUniqueId() == this.contest.SortingAlgoId).Single(), App.Logger);

            // Sort by pilot
            var pilotSortedMatrixResult = await this.flightMatrixQueryIntr.Value.GetPilotSortedFlightMatrix(this.contest.Id);

            if (pilotSortedMatrixResult.IsFaulted)
            {
                base.Alert($"{nameof(FlightMatrixPageViewModel)}:{nameof(InflateMatrix)} - Failed to pilot sort the matrix.");
                return;
            }

            // Get all of the pilots
            var allPilotsResult = await this.pilotQueryIntr.Value.GetAllPilotsAsync();

            if (allPilotsResult.IsFaulted)
            {
                base.Alert($"{nameof(FlightMatrixPageViewModel)}:{nameof(InflateMatrix)} - Failed to get all pilots.");
                return;
            }

            // Clear the Pilots collection on the UI thread...
            await this.Dispatcher.DispatchAsync(new Action(() => this.Pilots.Clear()));

            // Populate the View models
            foreach (var pilotSchedule in pilotSortedMatrixResult.Value)
            {
                var fullPilotObj = allPilotsResult.Value.Where(p => p.Id == pilotSchedule.PilotId).FirstOrDefault();
                if (fullPilotObj == null)
                {
                    base.Throw(new Exception($"Could not find pilotId:{pilotSchedule.PilotId} in the system."));
                }

                // Update the pilots collection on the UI thread.
                await this.Dispatcher.DispatchAsync(new Action(() =>
                {
                    // Create a view model for each pilot schedule
                    this.Pilots.Add(new PilotRoundMatrixListItemViewModel
                    {
                        PilotName = $"{fullPilotObj.FirstName} {fullPilotObj.LastName}",
                        FlightGroups = new ObservableCollection <string>(pilotSchedule.FlightGroupDraw.Select(flightGroup => flightGroup.ToString()))
                    });
                }));
            }

            this.matrix = pilotMatrix;
        }
        /// <summary>
        /// Updates the specified flight matrix.
        /// </summary>
        /// <param name="flightMatrix">The flight matrix.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > UpdateAsync(FlightMatrix flightMatrix)
        {
            if (flightMatrix == null)
            {
                return(Error <FlightMatrix>(null, new ArgumentNullException(nameof(flightMatrix), "Pilot cannot be null.")));
            }

            if (!string.IsNullOrEmpty(flightMatrix.Id))
            {
                return(Error <FlightMatrix>(null, new ArgumentOutOfRangeException(nameof(flightMatrix), "The Pilot passed in does not have a valid id.")));
            }

            var allMatricies = (await GetAll <FlightMatrix>()) ?? new List <FlightMatrix>();

            if (allMatricies == null ||
                allMatricies.Count < 1 ||
                allMatricies.Where(c => c.Id != flightMatrix.Id).FirstOrDefault() == null)
            {
                return(Error <FlightMatrix>(null, new Exception("A flight matrix with that name and id could not be found.")));
            }

            // Grab all of the pilots w/o the id passed in and save.
            var newFlightMatrixList = allMatricies.Where(c => c.Id != flightMatrix.Id).ToList();

            newFlightMatrixList.Add(flightMatrix);

            var result = false;

            try
            {
                // Write the new pilot list.
                result = await WriteAll <FlightMatrix>(newFlightMatrixList);
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }

            if (!result)
            {
                return(Error <FlightMatrix>(null, $"An error occured with updating the flight matrix with id {flightMatrix.Id}."));
            }
            else
            {
                return(Success(flightMatrix, nameof(UpdateAsync)));
            }
        }
        /// <summary>
        /// Handles a click on the Generate matrix button.
        /// </summary>
        /// <returns></returns>
        public async Task GenerateMatrix()
        {
            var contestRegistrationsResult = await this.registrationQueryIntr.Value.GetPilotRegistrationsForContest(this.contest.Id);

            if (contestRegistrationsResult.IsFaulted || contestRegistrationsResult.Value == null)
            {
                return;
            }

            try
            {
                var flightMatrixGenerationIntr = new FlightMatrixGenInteractor(
                    App.SortingAlgos.Where(algo => algo.GetUniqueId() == this.contest.SortingAlgoId).Single(),
                    App.Logger);

                var sortedMatrixResult = flightMatrixGenerationIntr.CreateSortedFlightMatrix(
                    contestRegistrationsResult.Value,
                    // Don't include the fly-off rounds
                    this.contest.Rounds.Where(r => !r.Value.IsFlyOffRound).Count(),
                    this.contest.SuggestedNumberOfPilotsPerGroup);

                if (sortedMatrixResult.IsFaulted || sortedMatrixResult.Value == null)
                {
                    return;
                }

                this.matrix = sortedMatrixResult.Value;

                // Assign it to the current contest.
                this.matrix.ContestId = this.contest.Id;

                // Save it
                var flightMatrixSaveResult = await this.flightMatrixCmdIntr.Value.SaveFlightMatrixForContestAsync(this.matrix);

                if (flightMatrixSaveResult.IsFaulted)
                {
                    base.Alert($"{nameof(FlightMatrixPageViewModel)}:{nameof(GenerateMatrix)} - Failed to save the flight matrix.");
                    return;
                }

                await InflateMatrix(sortedMatrixResult.Value);
            }
            catch (Exception ex)
            {
                App.Logger.LogException(ex);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Creates the asynchronous.
        /// </summary>
        /// <param name="flightMatrixToCreate">The flight matrix to create.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > CreateAsync(FlightMatrix flightMatrixToCreate)
        {
            if (flightMatrixToCreate == null)
            {
                return(Error <FlightMatrix>(null, "The Pilot cannot be null"));
            }

            if (!string.IsNullOrEmpty(flightMatrixToCreate.Id))
            {
                return(Error <FlightMatrix>(null, "The Id already has a value"));
            }

            // Check cache
            var allFlightMatricies = this.cache.Get <List <FlightMatrix> >(FLIGHT_MATRIX_CACHE_KEY);

            if (allFlightMatricies == null)
            {
                allFlightMatricies = (await GetAll <FlightMatrix>()) ?? new List <FlightMatrix>();
            }

            if (allFlightMatricies == null)
            {
                allFlightMatricies = new List <FlightMatrix>();
            }

            // Assign a new GUID for the ID
            flightMatrixToCreate.Id = base.GenerateId();

            // Remove any that exist for the contest this is intended for
            allFlightMatricies = allFlightMatricies.Where(matrix => matrix.ContestId != flightMatrixToCreate.ContestId).ToList();

            allFlightMatricies.Add(flightMatrixToCreate);

            try
            {
                var success = await WriteAll(allFlightMatricies);

                this.cache.Put(FLIGHT_MATRIX_CACHE_KEY, allFlightMatricies);
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }

            return(Success((allFlightMatricies.Where(p => p.Id == flightMatrixToCreate.Id)).First(), nameof(CreateAsync)));
        }
Beispiel #16
0
        /// <summary>
        /// Deletes the flight matrix for contest asynchronous.
        /// </summary>
        /// <param name="flightMatrix">The flight matrix.</param>
        /// <returns></returns>
        public async Task <Result <bool> > DeleteFlightMatrixForContestAsync(FlightMatrix flightMatrix)
        {
            if (!ValidateFlightMatrix(flightMatrix))
            {
                return(Error <bool>(false, $"The {nameof(flightMatrix)} is not a valid flight matrix."));
            }

            try
            {
                var result = await this.flightMatrixRepository.DeleteAsync(flightMatrix.ContestId);

                if (result.IsFaulted || result.Value)
                {
                    return(Error(false, "An error occured while deleting the flight matrix."));
                }

                return(Success(true, nameof(DeleteFlightMatrixForContestAsync)));
            }
            catch (Exception ex)
            {
                return(Error(false, ex));
            }
        }
Beispiel #17
0
        /// <summary>
        /// Saves the flight matrix for contest asynchronous.
        /// </summary>
        /// <param name="flightMatrix">The flight matrix.</param>
        /// <returns></returns>
        public async Task <Result <FlightMatrix> > SaveFlightMatrixForContestAsync(FlightMatrix flightMatrix)
        {
            if (!ValidateFlightMatrix(flightMatrix))
            {
                return(Error <FlightMatrix>(null, $"The {nameof(flightMatrix)} is not a valid flight matrix."));
            }

            try
            {
                var result = await this.flightMatrixRepository.CreateAsync(flightMatrix);

                if (result.IsFaulted || result.Value == null)
                {
                    return(Error <FlightMatrix>(null, "An error occured while creating the flight matrix."));
                }

                return(Success(result.Value, nameof(SaveFlightMatrixForContestAsync)));
            }
            catch (Exception ex)
            {
                return(Error <FlightMatrix>(null, ex));
            }
        }
        /// <summary>
        /// Sorts the specified pilots.
        /// </summary>
        /// <param name="pilots">The pilots.</param>
        /// <param name="numberOfRounds">The number of rounds.</param>
        /// <param name="suggestedNumberofPilotsInFlightGroup">The suggested numberof pilots in flight group.</param>
        /// <returns>
        /// Flight Matrix for Complete Contest.
        /// </returns>
        public virtual FlightMatrix GenerateInitialMatrix(IEnumerable <PilotRegistration> pilots,
                                                          int numberOfRounds,
                                                          int suggestedNumberofPilotsInFlightGroup)
        {
            Validate.IsEnumerableSizeInRange(pilots, nameof(pilots), 1, int.MaxValue);
            Validate.IsInRange(numberOfRounds, nameof(numberOfRounds), 1, 100);
            Validate.IsInRange(suggestedNumberofPilotsInFlightGroup, nameof(suggestedNumberofPilotsInFlightGroup), 1, 100);

            var pilotsList           = new List <PilotRegistration>(pilots);
            var flightMatrixToReturn = new FlightMatrix();
            var remainder            = pilotsList.Count % suggestedNumberofPilotsInFlightGroup;
            var numberOfGroups       = pilotsList.Count / suggestedNumberofPilotsInFlightGroup;

            // If we have a remainder and that number is less than half of the size of the flight group
            // size, just add the remainder to the last group.  Otherwise, create a new group for the remainder.
            // Also, if there is only 1 left over, don't create an extra group. (Ex: suggested ppg is 2)
            if (remainder > 1 &&
                (((double)suggestedNumberofPilotsInFlightGroup / 2) <= remainder))
            {
                ++numberOfGroups;
            }

            // Loop through each round and build the flight groups
            for (var i = 0; i < numberOfRounds; ++i)
            {
                var group         = FlightGroup.A;
                var numberInGroup = 0;

                // Shuffle the pilots each round
                pilotsList = Shuffle(pilotsList).ToList();

                // Create the groups
                foreach (var p in pilotsList)
                {
                    // Increment the groups, but if there are leftover pilots that do not divide
                    // evently, add them to the last group..
                    if (numberInGroup != 0 &&
                        (numberInGroup % suggestedNumberofPilotsInFlightGroup == 0 &&
                         (int)group < numberOfGroups))
                    {
                        group++;
                    }

                    if (!flightMatrixToReturn.Matrix.Any(round => round.RoundOrdinal == i))
                    {
                        flightMatrixToReturn.Matrix.Add(
                            new FlightMatrixRound
                        {
                            RoundOrdinal = i,
                            PilotSlots   = new List <FlightMatrixPilotSlot>()
                        });
                    }
                    flightMatrixToReturn.Matrix[i].PilotSlots.Add(
                        new FlightMatrixPilotSlot {
                        PilotId = p.PilotId, FlightGroup = group
                    });
                    ++numberInGroup;
                }
            }

            return(flightMatrixToReturn);
        }