예제 #1
0
 /// <summary>
 /// Checks the not duplicate measured course.
 /// </summary>
 /// <param name="measuredCourse">The measured course.</param>
 /// <exception cref="InvalidOperationException">Unable to add measured course as this has a duplicate Course Id</exception>
 private void CheckNotDuplicateMeasuredCourse(MeasuredCourseDataTransferObject measuredCourse)
 {
     if (this.MeasuredCourses.Any(m => m.MeasuredCourseId == measuredCourse.MeasuredCourseId))
     {
         throw new InvalidOperationException("Unable to add measured course as this has a duplicate Course Id");
     }
 }
예제 #2
0
        /// <summary>
        /// Gets the measured course.
        /// </summary>
        /// <param name="measuredCourseId">The measured course identifier.</param>
        /// <returns></returns>
        /// <exception cref="NotFoundException">No measured course found for Club {this.Name} with Measured Course Id {measuredCourseId}</exception>
        public MeasuredCourseDataTransferObject GetMeasuredCourse(Guid measuredCourseId)
        {
            Boolean measuredCourseFound = this.MeasuredCourses.Any(m => m.MeasuredCourseId == measuredCourseId);

            if (!measuredCourseFound)
            {
                throw new NotFoundException($"No measured course found for Club {this.Name} with Measured Course Id {measuredCourseId}");
            }

            MeasuredCourse measuredCourse = this.MeasuredCourses.Where(m => m.MeasuredCourseId == measuredCourseId).Single();

            MeasuredCourseDataTransferObject result = new MeasuredCourseDataTransferObject
            {
                Name                 = measuredCourse.Name,
                MeasuredCourseId     = measuredCourse.MeasuredCourseId,
                StandardScratchScore = measuredCourse.StandardScratchScore,
                TeeColour            = measuredCourse.TeeColour,
                Holes                = new List <HoleDataTransferObject>()
            };

            foreach (Hole measuredCourseHole in measuredCourse.Holes)
            {
                result.Holes.Add(new HoleDataTransferObject
                {
                    HoleNumber     = measuredCourseHole.HoleNumber,
                    Par            = measuredCourseHole.Par,
                    LengthInYards  = measuredCourseHole.LengthInYards,
                    StrokeIndex    = measuredCourseHole.StrokeIndex,
                    LengthInMeters = measuredCourseHole.LengthInMeters
                });
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Validates the measured course.
        /// </summary>
        /// <param name="measuredCourse">The measured course.</param>
        private void ValidateMeasuredCourse(MeasuredCourseDataTransferObject measuredCourse)
        {
            Guard.ThrowIfInvalidGuid(measuredCourse.MeasuredCourseId, typeof(ArgumentNullException), "A measured course must have a valid Id");
            Guard.ThrowIfNullOrEmpty(measuredCourse.Name, typeof(ArgumentNullException), "A measured course must have a name");
            Guard.ThrowIfNullOrEmpty(measuredCourse.TeeColour, typeof(ArgumentNullException), "A measured course must have a tee colour");
            Guard.ThrowIfNegative(measuredCourse.StandardScratchScore,
                                  typeof(ArgumentNullException),
                                  "A measured course must have a non negative Standard Scratch Score");
            Guard.ThrowIfZero(measuredCourse.StandardScratchScore, typeof(ArgumentNullException), "A measured course must have a non zero Standard Scratch Score");

            // Only validate the holes if the have been populated
            if (measuredCourse.Holes.Count != 18)
            {
                throw new InvalidDataException("A measured course must have 18 holes");
            }

            // Check there are no missing hole numbers
            IEnumerable <Int32> holeNumberList     = measuredCourse.Holes.Select(h => h.HoleNumber);
            List <Int32>        missingHoleNumbers = Enumerable
                                                     .Range(GolfClubAggregate.MinimumHoleNumber, GolfClubAggregate.MaximumHoleNumber - GolfClubAggregate.MinimumHoleNumber + 1)
                                                     .Except(holeNumberList).ToList();

            if (missingHoleNumbers.Count > 0)
            {
                // there are missing hole numbers
                throw new InvalidDataException($"Hole numbers {string.Join(",", missingHoleNumbers)} are missing from the measured course");
            }

            // Check there are no missing stroke indexes
            IEnumerable <Int32> strokeIndexList      = measuredCourse.Holes.Select(h => h.StrokeIndex);
            List <Int32>        missingStrokeIndexes = Enumerable
                                                       .Range(GolfClubAggregate.MinimumStrokeIndex,
                                                              GolfClubAggregate.MaximumStrokeIndex - GolfClubAggregate.MinimumStrokeIndex + 1).Except(strokeIndexList).ToList();

            if (missingStrokeIndexes.Count > 0)
            {
                // there are missing stroke indexes
                throw new InvalidDataException($"Hole with Stroke Indexes {string.Join(",", missingStrokeIndexes)} are missing from the measured course");
            }

            // Check all holes have a valid length in yards
            IEnumerable <Int32> holesWithInvalidLengthInYards = measuredCourse.Holes.Where(h => h.LengthInYards <= 0).Select(h => h.HoleNumber);

            if (holesWithInvalidLengthInYards.Any())
            {
                throw new
                      InvalidDataException($"All holes must have a length in yards, hole numbers {string.Join(",", holesWithInvalidLengthInYards)} are missing a valid length in yards");
            }

            // Check all holes have a valid par
            IEnumerable <Int32> holesWithInvalidPar = measuredCourse.Holes.Where(h => h.Par != 3 && h.Par != 4 && h.Par != 5).Select(h => h.HoleNumber);

            if (holesWithInvalidPar.Any())
            {
                throw new
                      InvalidDataException($"All holes must have a valid Par of 3,4 or 5, hole numbers {string.Join(",", holesWithInvalidPar)} are missing a valid Par");
            }
        }
예제 #4
0
        /// <summary>
        /// Gets the measured courses.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotFoundException">No measured courses found for Club {this.Name}</exception>
        public List <MeasuredCourseDataTransferObject> GetMeasuredCourses()
        {
            if (this.MeasuredCourses.Any() == false)
            {
                throw new NotFoundException($"No measured courses found for Club {this.Name}");
            }

            List <MeasuredCourseDataTransferObject> measuredCourses = new List <MeasuredCourseDataTransferObject>();

            foreach (MeasuredCourse measuredCourse in this.MeasuredCourses)
            {
                MeasuredCourseDataTransferObject result = new MeasuredCourseDataTransferObject
                {
                    Name                 = measuredCourse.Name,
                    MeasuredCourseId     = measuredCourse.MeasuredCourseId,
                    StandardScratchScore = measuredCourse.StandardScratchScore,
                    TeeColour            = measuredCourse.TeeColour,
                    Holes                = new List <HoleDataTransferObject>()
                };

                foreach (Hole measuredCourseHole in measuredCourse.Holes)
                {
                    result.Holes.Add(new HoleDataTransferObject
                    {
                        HoleNumber     = measuredCourseHole.HoleNumber,
                        Par            = measuredCourseHole.Par,
                        LengthInYards  = measuredCourseHole.LengthInYards,
                        StrokeIndex    = measuredCourseHole.StrokeIndex,
                        LengthInMeters = measuredCourseHole.LengthInMeters
                    });
                }

                measuredCourses.Add(result);
            }

            return(measuredCourses);
        }
예제 #5
0
        /// <summary>
        /// Adds the measured course.
        /// </summary>
        /// <param name="measuredCourse">The measured course.</param>
        public void AddMeasuredCourse(MeasuredCourseDataTransferObject measuredCourse)
        {
            // Apply the business rules here
            // Check club has been created
            this.CheckHasGolfClubAlreadyBeenCreated();

            // Check for a duplicate measured course addition
            this.CheckNotDuplicateMeasuredCourse(measuredCourse);

            // Validate the measured course data
            this.ValidateMeasuredCourse(measuredCourse);

            // Now apply and pend the required events

            // First the measured course added event
            MeasuredCourseAddedEvent measuredCourseAddedEvent = MeasuredCourseAddedEvent.Create(this.AggregateId,
                                                                                                measuredCourse.MeasuredCourseId,
                                                                                                measuredCourse.Name,
                                                                                                measuredCourse.TeeColour,
                                                                                                measuredCourse.StandardScratchScore);

            this.ApplyAndPend(measuredCourseAddedEvent);

            // Now add an event for each hole
            foreach (HoleDataTransferObject holeDataTransferObject in measuredCourse.Holes)
            {
                HoleAddedToMeasuredCourseEvent holeAddedToMeasuredCourseEvent =
                    HoleAddedToMeasuredCourseEvent.Create(this.AggregateId,
                                                          measuredCourse.MeasuredCourseId,
                                                          holeDataTransferObject.HoleNumber,
                                                          holeDataTransferObject.LengthInYards,
                                                          holeDataTransferObject.LengthInMeters,
                                                          holeDataTransferObject.Par,
                                                          holeDataTransferObject.StrokeIndex);
                this.ApplyAndPend(holeAddedToMeasuredCourseEvent);
            }
        }