public void SetUp()
        {
            var idCounter = 0;

            repoList = new List<DriveReport>();
            _emplMock = Substitute.For<IGenericRepository<Employment>>();
            _calculatorMock = Substitute.For<IReimbursementCalculator>();
            _orgUnitMock = Substitute.For<IGenericRepository<OrgUnit>>();
            _routeMock = Substitute.For<IRoute<RouteInformation>>();
            _coordinatesMock = Substitute.For<IAddressCoordinates>();
            _subMock = Substitute.For<IGenericRepository<Core.DomainModel.Substitute>>();
            _mailServiceMock = Substitute.For<IMailService>();
            _reportRepoMock = NSubstitute.Substitute.For<IGenericRepository<DriveReport>>();
            _personMock = Substitute.For<IGenericRepository<Person>>();
            _logger = new Core.ApplicationServices.Logger.Logger();
            _customSettings = new CustomSettings();

            _reportRepoMock.Insert(new DriveReport()).ReturnsForAnyArgs(x => x.Arg<DriveReport>()).AndDoes(x => repoList.Add(x.Arg<DriveReport>())).AndDoes(x => x.Arg<DriveReport>().Id = idCounter).AndDoes(x => idCounter++);
            _reportRepoMock.AsQueryable().ReturnsForAnyArgs(repoList.AsQueryable());

            _calculatorMock.Calculate(new RouteInformation(), new DriveReport()).ReturnsForAnyArgs(x => x.Arg<DriveReport>());

            _coordinatesMock.GetAddressCoordinates(new Address()).ReturnsForAnyArgs(new DriveReportPoint()
            {
                Latitude = "1",
                Longitude = "2",
            });

            _routeMock.GetRoute(DriveReportTransportType.Car, new List<Address>()).ReturnsForAnyArgs(new RouteInformation()
            {
                Length = 2000
            });

            _uut = new DriveReportService(_mailServiceMock, _reportRepoMock, _calculatorMock, _orgUnitMock, _emplMock, _subMock, _coordinatesMock, _routeMock, _rateTypeMock, _personMock, _logger, _customSettings);
        }
        public void SetUp()
        {
            var idCounter = 0;

            repoList         = new List <DriveReport>();
            _emplMock        = Substitute.For <IGenericRepository <Employment> >();
            _calculatorMock  = Substitute.For <IReimbursementCalculator>();
            _orgUnitMock     = Substitute.For <IGenericRepository <OrgUnit> >();
            _rateTypeMock    = Substitute.For <IGenericRepository <RateType> >();
            _routeMock       = Substitute.For <IRoute <RouteInformation> >();
            _coordinatesMock = Substitute.For <IAddressCoordinates>();
            _subMock         = Substitute.For <IGenericRepository <Core.DomainModel.Substitute> >();
            _mailServiceMock = Substitute.For <IMailService>();
            _subServiceMock  = Substitute.For <ISubstituteService>();
            _reportRepoMock  = NSubstitute.Substitute.For <IGenericRepository <DriveReport> >();
            _personMock      = Substitute.For <IGenericRepository <Person> >();
            _logger          = new Core.ApplicationServices.Logger.Logger();
            _customSettings  = new CustomSettings();

            _reportRepoMock.Insert(new DriveReport()).ReturnsForAnyArgs(x => x.Arg <DriveReport>()).AndDoes(x => repoList.Add(x.Arg <DriveReport>())).AndDoes(x => x.Arg <DriveReport>().Id = idCounter).AndDoes(x => idCounter++);
            _reportRepoMock.AsQueryable().ReturnsForAnyArgs(repoList.AsQueryable());

            _calculatorMock.Calculate(new RouteInformation(), new DriveReport()).ReturnsForAnyArgs(x => x.Arg <DriveReport>());
            // The mocked reports share the exact same timestamp if they are driven on same day, so for test purposes we simplify the method and check if they are identical, so we are able to mock the method.
            _calculatorMock.AreReportsDrivenOnSameDay(1, 1).ReturnsForAnyArgs(x => (long)x[0] == (long)x[1]);

            _rateTypeMock.AsQueryable().ReturnsForAnyArgs(new List <RateType>
            {
                new RateType()
                {
                    TFCode = "1234",
                    IsBike = false,
                    RequiresLicensePlate = true,
                    Id          = 1,
                    Description = "TestRate"
                }
            }.AsQueryable());

            _coordinatesMock.GetAddressCoordinates(new Address()).ReturnsForAnyArgs(new DriveReportPoint()
            {
                Latitude  = "1",
                Longitude = "2",
            });

            _routeMock.GetRoute(DriveReportTransportType.Car, new List <Address>()).ReturnsForAnyArgs(new RouteInformation()
            {
                Length = 2000
            });

            _uut = new DriveReportService(_mailServiceMock, _reportRepoMock, _calculatorMock, _orgUnitMock, _emplMock, _subMock, _coordinatesMock, _routeMock, _rateTypeMock, _personMock, _logger, _customSettings);
        }
        public void SetUp()
        {
            var idCounter = 0;

            repoList         = new List <DriveReport>();
            _emplMock        = Substitute.For <IGenericRepository <Employment> >();
            _calculatorMock  = Substitute.For <IReimbursementCalculator>();
            _orgUnitMock     = Substitute.For <IGenericRepository <OrgUnit> >();
            _rateTypeMock    = Substitute.For <IGenericRepository <RateType> >();
            _routeMock       = Substitute.For <IRoute <RouteInformation> >();
            _coordinatesMock = Substitute.For <IAddressCoordinates>();
            _subMock         = Substitute.For <IGenericRepository <Core.DomainModel.Substitute> >();
            _mailMock        = Substitute.For <IMailSender>();
            _reportRepoMock  = NSubstitute.Substitute.For <IGenericRepository <DriveReport> >();
            _loggerMock      = NSubstitute.Substitute.For <ILogger>();

            _reportRepoMock.Insert(new DriveReport()).ReturnsForAnyArgs(x => x.Arg <DriveReport>()).AndDoes(x => repoList.Add(x.Arg <DriveReport>())).AndDoes(x => x.Arg <DriveReport>().Id = idCounter).AndDoes(x => idCounter++);
            _reportRepoMock.AsQueryable().ReturnsForAnyArgs(repoList.AsQueryable());

            _calculatorMock.Calculate(new RouteInformation(), new DriveReport()).ReturnsForAnyArgs(x => x.Arg <DriveReport>());

            _rateTypeMock.AsQueryable().ReturnsForAnyArgs(new List <RateType>
            {
                new RateType()
                {
                    TFCode = "1234",
                    IsBike = false,
                    RequiresLicensePlate = true,
                    Id          = 1,
                    Description = "TestRate"
                }
            }.AsQueryable());

            _coordinatesMock.GetAddressCoordinates(new Address()).ReturnsForAnyArgs(new DriveReportPoint()
            {
                Latitude  = "1",
                Longitude = "2",
            });

            _routeMock.GetRoute(DriveReportTransportType.Car, new List <Address>()).ReturnsForAnyArgs(new RouteInformation()
            {
                Length = 2000
            });

            _uut = new DriveReportService(_reportRepoMock, _calculatorMock, _coordinatesMock, _routeMock, _rateTypeMock, _mailMock, _orgUnitMock, _emplMock, _subMock, _loggerMock);
        }
        /// <summary>
        /// Validates report and creates it in the database if it validates.
        /// </summary>
        /// <param name="report">Report to be created.</param>
        /// <returns>Created report.</returns>
        public DriveReport Create(DriveReport report)
        {
            if (report.PersonId == 0)
            {
                throw new Exception("No person provided");
            }
            if (!Validate(report))
            {
                throw new Exception("DriveReport has some invalid parameters");
            }

            if (report.IsFromApp)
            {
                report = _calculator.Calculate(null, report);
            }
            else
            {
                if (report.KilometerAllowance != KilometerAllowance.Read)
                {
                    var pointsWithCoordinates = new List <DriveReportPoint>();
                    foreach (var driveReportPoint in report.DriveReportPoints)
                    {
                        if (string.IsNullOrEmpty(driveReportPoint.Latitude) || driveReportPoint.Latitude == "0" ||
                            string.IsNullOrEmpty(driveReportPoint.Longitude) || driveReportPoint.Longitude == "0")
                        {
                            pointsWithCoordinates.Add(
                                (DriveReportPoint)_coordinates.GetAddressCoordinates(driveReportPoint));
                        }
                        else
                        {
                            pointsWithCoordinates.Add(driveReportPoint);
                        }
                    }

                    report.DriveReportPoints = pointsWithCoordinates;

                    var isBike = _rateTypeRepo.AsQueryable().First(x => x.TFCode.Equals(report.TFCode)).IsBike;


                    // Set transportType to Bike if isBike is true. Otherwise set it to Car.
                    var drivenRoute = _route.GetRoute(
                        isBike ? DriveReportTransportType.Bike : DriveReportTransportType.Car, report.DriveReportPoints);


                    report.Distance = drivenRoute.Length / 1000;

                    if (report.Distance < 0)
                    {
                        report.Distance = 0;
                    }

                    report = _calculator.Calculate(drivenRoute, report);
                }
                else
                {
                    report = _calculator.Calculate(null, report);
                }
            }

            // Round off Distance and AmountToReimburse to two decimals.
            report.Distance          = Convert.ToDouble(report.Distance.ToString("0.##", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
            report.AmountToReimburse = Convert.ToDouble(report.AmountToReimburse.ToString("0.##", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);

            var createdReport = _driveReportRepository.Insert(report);

            createdReport.UpdateResponsibleLeaders(GetResponsibleLeadersForReport(report));
            var actualLeader = GetActualLeaderForReport(report);

            if (actualLeader != null)
            {
                createdReport.ActualLeaderId = actualLeader.Id;
            }

            if (report.Status == ReportStatus.Rejected)
            {
                // User is editing a rejected report to try and get it approved.
                report.Status = ReportStatus.Pending;
            }

            _driveReportRepository.Save();

            // If the report is calculated or from an app, then we would like to store the points.
            if (report.KilometerAllowance != KilometerAllowance.Read || report.IsFromApp)
            {
                // Reports from app with manual distance have no drivereportpoints.
                if (report.DriveReportPoints.Count > 1)
                {
                    for (var i = 0; i < createdReport.DriveReportPoints.Count; i++)
                    {
                        var currentPoint = createdReport.DriveReportPoints.ElementAt(i);

                        if (i == report.DriveReportPoints.Count - 1)
                        {
                            // last element
                            currentPoint.PreviousPointId = createdReport.DriveReportPoints.ElementAt(i - 1).Id;
                        }
                        else if (i == 0)
                        {
                            // first element
                            currentPoint.NextPointId = createdReport.DriveReportPoints.ElementAt(i + 1).Id;
                        }
                        else
                        {
                            // between first and last
                            currentPoint.NextPointId     = createdReport.DriveReportPoints.ElementAt(i + 1).Id;
                            currentPoint.PreviousPointId = createdReport.DriveReportPoints.ElementAt(i - 1).Id;
                        }
                    }
                    _driveReportRepository.Save();
                }
            }

            //AddFullName(report);

            SixtyDayRuleCheck(report);

            return(report);
        }