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