예제 #1
0
        private static async Task RestClientTest()
        {
            var testAddress = "ANrL4vPnQCCi5Mro4fqKK1rxrkxEHqmp2E";

            var restService = new NeoScanRestService(NeoScanNet.MainNet);             // service creation

            // api calls
            var getBalance = await restService.GetBalanceAsync(testAddress);

            var getClaimed = await restService.GetClaimedAsync(testAddress);             // returns internal server error

            var getClaimable = await restService.GetClaimableAsync(testAddress);

            var getUnclaimed = await restService.GetUnclaimedAsync(testAddress);

            var getAddress = await restService.GetAddressAsync(testAddress);

            //Deserialization

            var balance_model   = AddressBalance.FromJson(getBalance);
            var claimed_model   = Claimed.FromJson(getClaimed);
            var claimable_model = Claimable.FromJson(getClaimable);
            var unclaimed_model = Unclaimed.FromJson(getUnclaimed);
            var address_model   = AddressHistory.FromJson(getAddress);
        }
예제 #2
0
        /// <summary>
        /// Reads employee AddressHistories from Kommune database and returns them asqueryable.
        /// </summary>
        /// <returns></returns>
        public IQueryable <AddressHistory> GetAddressHistoriesAsQueryable()
        {
            var result = new List <AddressHistory>();



            using (var sqlConnection1 = new SqlConnection(_connectionString))
            {
                var cmd = new SqlCommand
                {
                    CommandText = "SELECT * FROM eindberetning.Medarbejder_Temp",
                    CommandType = CommandType.Text,
                    Connection  = sqlConnection1
                };

                sqlConnection1.Open();

                var reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    var currentRow = new AddressHistory
                    {
                        AktivFra       = SafeGetDate(reader, 0) ?? DateTime.Now,
                        AktivTil       = SafeGetDate(reader, 1) ?? DateTime.Now,
                        MaNr           = SafeGetInt32(reader, 2) ?? 0,
                        Navn           = SafeGetString(reader, 3),
                        HjemmeAdresse  = SafeGetString(reader, 4),
                        HjemmePostNr   = Convert.ToInt32(SafeGetString(reader, 5)),
                        HjemmeBy       = SafeGetString(reader, 6),
                        HjemmeLand     = SafeGetString(reader, 7),
                        ArbejdsAdresse = SafeGetString(reader, 8),
                        ArbejdsPostNr  = SafeGetInt16(reader, 9) ?? 0,
                        ArbejdsBy      = SafeGetString(reader, 10),
                    };
                    result.Add(currentRow);
                }
            }
            return(result.AsQueryable());
        }
        /// <summary>
        /// Takes a DriveReport as input and returns it with data.
        ///
        /// FourKmRule: If a user has set the FourKmRule to be used, the distance between
        /// the users home and municipality is used in the correction of the driven distance.
        /// If the rule is not used, the distance between the users home and work address are
        /// calculated and used, provided that the user has not set a override for this value.
        ///
        /// Calculated: The driven route is calculated, and based on whether the user starts
        /// and/or ends at home, the driven distance is corrected by subtracting the distance
        /// between the users home address and work address.
        /// Again, this is dependend on wheter the user has overridden this value.
        ///
        /// Calculated without extra distance: If this method is used, the driven distance is
        /// still calculated, but the distance is not corrected with the distance between the
        /// users home address and work address. The distance calculated from the service is
        /// therefore used directly in the calculation of the amount to reimburse
        ///
        /// </summary>
        public DriveReport Calculate(RouteInformation drivenRoute, DriveReport report)
        {
            //Check if user has manually provided a distance between home address and work address
            var homeWorkDistance = 0.0;

            var person = _personRepo.AsQueryable().First(x => x.Id == report.PersonId);

            var homeAddress = _personService.GetHomeAddress(person);

            // Get Work and Homeaddress of employment at time of DriveDateTimestamp for report.
            AddressHistory addressHistory = null;

            try
            {
                addressHistory = _addressHistoryRepo.AsQueryable().SingleOrDefault(x => x.EmploymentId == report.EmploymentId && x.StartTimestamp <report.DriveDateTimestamp && x.EndTimestamp> report.DriveDateTimestamp);
            }
            catch (InvalidOperationException)
            {
                _logger.LogForAdmin(report.FullName + " har et overlap i sin adressehistorik");
                throw;
            }

            if (homeAddress.Type != PersonalAddressType.AlternativeHome)
            {
                if (addressHistory != null && addressHistory.HomeAddress != null)
                {
                    // If user doesn't have an alternative address set up then use the homeaddress at the time of DriveDateTimestamp
                    // If the user does have an alternative address then always use that.
                    homeAddress = addressHistory.HomeAddress;
                }
            }


            var employment = _emplrepo.AsQueryable().FirstOrDefault(x => x.Id.Equals(report.EmploymentId));

            Address workAddress = employment.OrgUnit.Address;

            if (addressHistory != null && addressHistory.WorkAddress != null)
            {
                // If an AddressHistory.WorkAddress exists, then use that.
                workAddress = addressHistory.WorkAddress;
            }


            if (employment.AlternativeWorkAddress != null)
            {
                // Overwrite workaddress if an alternative work address exists.
                workAddress = employment.AlternativeWorkAddress;
            }

            if (report.WorkAddressId != 0)
            {
                if (report.WorkAddressId != employment.AlternativeWorkAddress?.Id && report.WorkAddressId != employment.OrgUnit.Address.Id)
                {
                    // only allow work address id that is either the address of the orgunit or is the alternative address
                    throw new Exception("Invalid WorkAddressId for report");
                }
                // Overwrite workaddress if chosen on web report page
                workAddress = _addressRepo.AsQueryable().First(a => a.Id == report.WorkAddressId);
            }

            if (report.KilometerAllowance != KilometerAllowance.Read && !report.IsFromApp)
            {
                //Check if drivereport starts at users home address.
                report.StartsAtHome = areAddressesCloseToEachOther(homeAddress, report.DriveReportPoints.First());
                //Check if drivereport ends at users home address.
                report.EndsAtHome = areAddressesCloseToEachOther(homeAddress, report.DriveReportPoints.Last());
            }


            homeWorkDistance = employment.WorkDistanceOverride;

            if (homeWorkDistance <= 0)
            {
                homeWorkDistance = _route.GetRoute(DriveReportTransportType.Car, new List <Address>()
                {
                    homeAddress, workAddress
                }).Length;
            }

            //Calculate distance to subtract
            double toSubtract = 0;

            //If user indicated to use the Four Km Rule
            if (report.FourKmRule)
            {
                //Take users provided distance from home to border of municipality. If report is from app, use distance provided in report, else use distance saved on person.
                var borderDistance = report.IsFromApp ? report.HomeToBorderDistance : person.DistanceFromHomeToBorder;

                //Adjust distance based on if user starts or ends at home
                if (report.StartsAtHome)
                {
                    toSubtract += borderDistance;
                }

                if (report.EndsAtHome)
                {
                    toSubtract += borderDistance;
                }
            }
            else
            {
                //Same logic as above, but uses calculated distance between home and work
                if (report.StartsAtHome)
                {
                    toSubtract += homeWorkDistance;
                }

                if (report.EndsAtHome)
                {
                    toSubtract += homeWorkDistance;
                }
            }

            switch (report.KilometerAllowance)
            {
            case KilometerAllowance.Calculated:
            {
                // Norddjurs Kommune uses an alternative way of calculating the amount to reimburse. Instead of subtracting the distance from home to work from the driven distance,
                // either the home-to-destination or work-to-destination distance is used, which ever is shortest. This only applies to routes starting from home, in any other case
                // the standard calculation method is used.
                bool useNorddjursAltCalculation;
                bool parseSucces = bool.TryParse(_customSettings.AlternativeCalculationMethod, out useNorddjursAltCalculation);
                useNorddjursAltCalculation = parseSucces ? useNorddjursAltCalculation : false;

                // Use Norddjurs alternative reimbursemnt calculation method if configured so.
                if (useNorddjursAltCalculation)
                {
                    // The alternative calculationmethod is only used for reports starting at home.
                    if (report.StartsAtHome)
                    {
                        // Distance from home.
                        var homeDistance = report.Distance;
                        if (!report.IsFromApp)
                        {
                            // In case the report is not from app then get distance from the supplied route.
                            homeDistance = drivenRoute.Length;
                        }

                        // Get distance from work.
                        var addresses = new List <Address>();
                        addresses.Add(workAddress);
                        foreach (Address address in report.DriveReportPoints)
                        {
                            if (!(address.Latitude == homeAddress.Latitude && address.Longitude == homeAddress.Longitude))
                            {
                                addresses.Add(address);
                            }
                        }

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

                        var workDistance = _route.GetRoute(isBike ? DriveReportTransportType.Bike : DriveReportTransportType.Car, addresses).Length;

                        // Compare the distance from home to the distance from work and apply the shortest of them.
                        report.Distance = homeDistance < workDistance ? homeDistance : workDistance;

                        if (!report.IsFromApp)
                        {
                            //Get RouteGeometry from driven route if the report is not from app. If it is from App then RouteGeometry is already set.
                            report.RouteGeometry = drivenRoute.GeoPoints;
                        }

                        break;
                    }
                    else
                    {
                        if (!report.IsFromApp)
                        {
                            report.Distance = drivenRoute.Length;

                            //Save RouteGeometry
                            report.RouteGeometry = drivenRoute.GeoPoints;
                        }

                        break;
                    }
                }

                if ((report.StartsAtHome || report.EndsAtHome) && !report.FourKmRule)
                {
                    report.IsExtraDistance = true;
                }

                double drivenDistance = report.Distance;

                if (!report.IsFromApp)
                {
                    // In case the report is not from app then get distance from the supplied route.
                    drivenDistance = drivenRoute.Length;
                }
                //Adjust distance based on FourKmRule and if user start and/or ends at home
                var correctDistance = drivenDistance - toSubtract;

                //Set distance to corrected
                report.Distance = correctDistance;

                if (!report.IsFromApp)
                {
                    //Get RouteGeometry from driven route if the report is not from app. If it is from App then RouteGeometry is already set.
                    report.RouteGeometry = drivenRoute.GeoPoints;
                }

                break;
            }

            case KilometerAllowance.CalculatedWithoutExtraDistance:
            {
                report.Distance = drivenRoute.Length;

                //Save RouteGeometry
                report.RouteGeometry = drivenRoute.GeoPoints;


                break;
            }

            case KilometerAllowance.Read:
            {
                if ((report.StartsAtHome || report.EndsAtHome) && !report.FourKmRule)
                {
                    report.IsExtraDistance = true;
                }

                //Take distance from report
                var manuallyProvidedDrivenDistance = report.Distance;

                report.Distance = manuallyProvidedDrivenDistance - toSubtract;

                break;
            }

            default:
            {
                throw new Exception("No calculation method provided");
            }
            }

            //Calculate the actual amount to reimburse

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

            // Multiply the distance by two if the report is a return trip
            if (report.IsRoundTrip == true)
            {
                report.Distance *= 2;
            }

            CalculateFourKmRuleForReport(report);

            SetAmountToReimburse(report);

            return(report);
        }
예제 #4
0
        private static async Task RestClientTest()
        {
            var testAddress = "ANrL4vPnQCCi5Mro4fqKK1rxrkxEHqmp2E";

            var restService = new NeoScanRestService(NeoScanNet.MainNet); // service creation
            var token       = await restService.GetAllTokens();

            var tokenList = JsonConvert.DeserializeObject <TokenList>(token);

            // api calls
            var getBalance = await restService.GetBalanceAsync(testAddress);

            var getClaimed = await restService.GetClaimedAsync(testAddress);

            var getClaimable = await restService.GetClaimableAsync(testAddress);

            var getUnclaimed = await restService.GetUnclaimedAsync(testAddress);

            var getAddress = await restService.GetAddressAsync(testAddress);

            var nodes = await restService.GetAllNodesAsync();

            var transaction = await restService.GetTransactionAsync("599dec5897d416e9a668e7a34c073832fe69ad01d885577ed841eec52c1c52cf");

            var assets = await restService.GetAssetsAsync();

            var asset = await restService.GetAssetAsync("089cd37714d43511e304dc559e05a5a965274685dc21686bdcd05a45e17aab7a");

            var height = await restService.GetHeight();

            var highestBlock = await restService.GetHighestBlock();

            var lastBlocks = await restService.GetLastBlocks();

            var feesInRange = await restService.GetFeesInRange(4, 6);

            var abstractAddress = await restService.GetAddressAbstracts("AGbj6WKPUWHze12zRyEL5sx8nGPVN6NXUn", 0);

            var neonAddress = await restService.GetNeonAddress("AGbj6WKPUWHze12zRyEL5sx8nGPVN6NXUn");

            var addressToAddressAbstract = await restService.GetAddressToAddressAbstract("AJ5UVvBoz3Nc371Zq11UV6C2maMtRBvTJK",
                                                                                         "AZCcft1uYtmZXxzHPr5tY7L6M85zG7Dsrv", 0);

            var block = await restService.GetBlock("54ffd56d6a052567c5d9abae43cc0504ccb8c1efe817c2843d154590f0b572f7");

            var lastTransactions = await restService.GetLastTransactions();

            var lastTransactionsByAddress =
                await restService.GetLastTransactionsByAddress("AGbj6WKPUWHze12zRyEL5sx8nGPVN6NXUn", 0);

            //Deserialization
            var  balanceDto                   = AddressBalance.FromJson(getBalance);
            var  claimedDto                   = Claimed.FromJson(getClaimed);
            var  claimableDto                 = Claimable.FromJson(getClaimable);
            var  unclaimedDto                 = Unclaimed.FromJson(getUnclaimed);
            var  addressDto                   = AddressHistory.FromJson(getAddress);
            var  nodesDto                     = Node.FromJson(nodes);
            var  transactionDto               = Transaction.FromJson(transaction);
            var  assetsDto                    = Asset.FromJsonList(assets);
            var  assetDto                     = Asset.FromJson(asset);
            long chainHeight                  = Convert.ToInt64(height);
            var  highestBlockDto              = Rest.DTOs.Block.FromJson(highestBlock);
            var  lastBlocksDto                = Blocks.FromJson(lastBlocks);
            var  feesInRangeDto               = FeesInRange.FromJson(feesInRange);
            var  abstractAddressDto           = AbstractAddress.FromJson(abstractAddress);
            var  neonAddressDto               = NeonAddress.FromJson(neonAddress);
            var  addressToAddressAbstractDto  = AbstractAddress.FromJson(addressToAddressAbstract);
            var  blockDto                     = Block.FromJson(block);
            var  lastTransactionsDto          = Transactions.FromJson(lastTransactions);
            var  lastTransactionsByAddressDto = Transactions.FromJson(lastTransactionsByAddress);
        }
예제 #5
0
        /// <summary>
        /// Takes a DriveReport as input and returns it with data.
        ///
        /// FourKmRule: If a user has set the FourKmRule to be used, the distance between
        /// the users home and municipality is used in the correction of the driven distance.
        /// If the rule is not used, the distance between the users home and work address are
        /// calculated and used, provided that the user has not set a override for this value.
        ///
        /// Calculated: The driven route is calculated, and based on whether the user starts
        /// and/or ends at home, the driven distance is corrected by subtracting the distance
        /// between the users home address and work address.
        /// Again, this is dependend on wheter the user has overridden this value.
        ///
        /// Calculated without extra distance: If this method is used, the driven distance is
        /// still calculated, but the distance is not corrected with the distance between the
        /// users home address and work address. The distance calculated from the service is
        /// therefore used directly in the calculation of the amount to reimburse
        ///
        /// </summary>
        public DriveReport Calculate(RouteInformation drivenRoute, DriveReport report)
        {
            //Check if user has manually provided a distance between home address and work address
            var homeWorkDistance = 0.0;

            var person = _personRepo.AsQueryable().First(x => x.Id == report.PersonId);

            var homeAddress = _personService.GetHomeAddress(person);

            // Get Work and Homeaddress of employment at time of DriveDateTimestamp for report.
            AddressHistory addressHistory = null;

            try
            {
                addressHistory = _addressHistoryRepo.AsQueryable().SingleOrDefault(x => x.EmploymentId == report.EmploymentId && x.StartTimestamp <report.DriveDateTimestamp && x.EndTimestamp> report.DriveDateTimestamp);
            }
            catch (InvalidOperationException)
            {
                _logger.LogForAdmin(report.FullName + " har et overlap i sin adressehistorik");
                throw;
            }

            if (homeAddress.Type != PersonalAddressType.AlternativeHome)
            {
                if (addressHistory != null && addressHistory.HomeAddress != null)
                {
                    // If user doesn't have an alternative address set up then use the homeaddress at the time of DriveDateTimestamp
                    // If the user does have an alternative address then always use that.
                    homeAddress = addressHistory.HomeAddress;
                }
            }


            var employment = _emplrepo.AsQueryable().FirstOrDefault(x => x.Id.Equals(report.EmploymentId));

            Address workAddress = employment.OrgUnit.Address;

            if (addressHistory != null && addressHistory.WorkAddress != null)
            {
                // If an AddressHistory.WorkAddress exists, then use that.
                workAddress = addressHistory.WorkAddress;
            }


            if (employment.AlternativeWorkAddress != null)
            {
                // Overwrite workaddress if an alternative work address exists.
                workAddress = employment.AlternativeWorkAddress;
            }

            if (report.KilometerAllowance != KilometerAllowance.Read && !report.IsFromApp)
            {
                //Check if drivereport starts at users home address.
                report.StartsAtHome = areAddressesCloseToEachOther(homeAddress, report.DriveReportPoints.First());
                //Check if drivereport ends at users home address.
                report.EndsAtHome = areAddressesCloseToEachOther(homeAddress, report.DriveReportPoints.Last());
            }


            homeWorkDistance = employment.WorkDistanceOverride;

            if (homeWorkDistance <= 0)
            {
                homeWorkDistance = _route.GetRoute(DriveReportTransportType.Car, new List <Address>()
                {
                    homeAddress, workAddress
                }).Length;
            }

            //Calculate distance to subtract
            //double toSubtract = 0;
            double toSubtractFourKmRule = 0;
            double toSubtractHomeRule   = 0;
            double toSubtractAltRule    = 0;


            //If user indicated to use the Four Km Rule
            if (report.FourKmRule)
            {
                //Take users provided distance from home to border of municipality. If report is from app, use distance provided in report, else use distance saved on person.
                var borderDistance = report.IsFromApp ? report.HomeToBorderDistance : person.DistanceFromHomeToBorder;

                //Adjust distance based on if user starts or ends at home
                if (report.StartsAtHome)
                {
                    //toSubtract += borderDistance;
                    toSubtractFourKmRule += borderDistance;
                }

                if (report.EndsAtHome)
                {
                    //toSubtract += borderDistance;
                    toSubtractFourKmRule += borderDistance;
                }
            }
            else
            {
                //Same logic as above, but uses calculated distance between home and work
                if (report.StartsAtHome)
                {
                    //toSubtract += homeWorkDistance;
                    toSubtractHomeRule += homeWorkDistance;
                }

                if (report.EndsAtHome)
                {
                    //toSubtract += homeWorkDistance;
                    toSubtractHomeRule += homeWorkDistance;
                }
            }

            switch (report.KilometerAllowance)
            {
            case KilometerAllowance.Calculated:
            {
                string alternativeCalculationMethod = ConfigurationManager.AppSettings["AlternativeCalculationMethod"];
                if (alternativeCalculationMethod == null)
                {
                    alternativeCalculationMethod = string.Empty;
                }
                // Use Norddjurs alternative reimbursemnt calculation method if configured so.
                if (alternativeCalculationMethod.ToLower() == "ndk")
                {
                    // Newer subtract the "daily" distance between HOME and WORK.
                    toSubtractHomeRule = 0.0;

                    // Get the drive report points.
                    List <DriveReportPoint> altDriveReportPoints = new List <DriveReportPoint>();
                    foreach (DriveReportPoint altDriveReportPoint in report.DriveReportPoints)
                    {
                        altDriveReportPoints.Add(altDriveReportPoint);
                    }

                    // Get if a bike is used for transportation.
                    Boolean altIsBike = _rateTypeRepo.AsQueryable().First(x => x.TFCode.Equals(report.TFCode)).IsBike;
                    DriveReportTransportType altTransportType = (altIsBike == true) ? DriveReportTransportType.Bike : DriveReportTransportType.Car;
                    Double altToSubtract1 = 0.0;
                    Double altToSubtract2 = 0.0;

                    // 1a. When starting from home
                    if (            //(report.IsFromApp == false) &&
                        (report.StartsAtHome == true) &&
                        (altDriveReportPoints.Count >= 2) &&
                        ((altDriveReportPoints[1].Latitude != workAddress.Latitude) && (altDriveReportPoints[1].Longitude != workAddress.Longitude)))
                    {
                        // A1) Get the distance between HOME and the first LOCATION (the route in the report).
                        //     This is used to select the reported route, or the alternative route.
                        List <Address> altAddressesToHome = new List <Address>();
                        altAddressesToHome.Add(homeAddress);
                        altAddressesToHome.Add(altDriveReportPoints[1]);
                        Double altDistanceToHome = _route.GetRoute(altTransportType, altAddressesToHome).Length;


                        // A2) Get the distance for the entire route (the route in the report).
                        //     This is used to calculate the distance to subtract.
                        altAddressesToHome = new List <Address>(altDriveReportPoints);
                        Double altDistanceA = _route.GetRoute(altTransportType, altAddressesToHome).Length;


                        // B1) Get the distance between WORK and the first LOCATION.
                        //     This is used to select the reported route, or the alternative route.
                        List <Address> altAddressesToWork = new List <Address>();
                        altAddressesToWork.Add(workAddress);
                        altAddressesToWork.Add(altDriveReportPoints[1]);
                        Double altDistanceToWork = _route.GetRoute(altTransportType, altAddressesToWork).Length;


                        // B2) Get the distance for the entire alternative route.
                        //     This is used to calculate the distance to subtract.
                        altAddressesToWork    = new List <Address>(altDriveReportPoints);
                        altAddressesToWork[0] = workAddress;
                        Double altDistanceB = _route.GetRoute(altTransportType, altAddressesToWork).Length;


                        // The current report distance is including the route between HOME and LOCATION.
                        // Substract the difference, if the distance between WORK and LOCATION is smaller.
                        if (altDistanceToWork < altDistanceToHome)
                        {
                            altToSubtract1 = (altDistanceA - altDistanceB);
                        }
                    }

                    // 1b. When starting from home
                    if (            //(report.IsFromApp == false) &&
                        (report.StartsAtHome == true) &&
                        (altDriveReportPoints.Count == 2) &&
                        ((altDriveReportPoints[1].Latitude == workAddress.Latitude) && (altDriveReportPoints[1].Longitude == workAddress.Longitude)))
                    {
                        toSubtractHomeRule += homeWorkDistance;
                    }


                    // 2a. When finishing at home
                    if (                //(report.IsFromApp == false) &&
                        (report.EndsAtHome == true) &&
                        (altDriveReportPoints.Count >= 2) &&
                        ((altDriveReportPoints[altDriveReportPoints.Count - 2].Latitude != workAddress.Latitude) && (altDriveReportPoints[altDriveReportPoints.Count - 2].Longitude != workAddress.Longitude)))
                    {
                        // A1) Get the distance between the second last LOCATION and HOME (the route in the report).
                        //     This is used to select the reported route, or the alternative route.
                        List <Address> altAddressesToHome = new List <Address>();
                        altAddressesToHome.Add(altDriveReportPoints[altDriveReportPoints.Count - 2]);
                        altAddressesToHome.Add(homeAddress);
                        Double altDistanceToHome = _route.GetRoute(altTransportType, altAddressesToHome).Length;


                        // A2) Get the distance for the entire route (the route in the report).
                        //     This is used to calculate the distance to subtract.
                        altAddressesToHome = new List <Address>(altDriveReportPoints);
                        Double altDistanceA = _route.GetRoute(altTransportType, altAddressesToHome).Length;


                        // B1) Get the distance between the second last LOCATION and WORK.
                        //     This is used to select the reported route, or the alternative route.
                        List <Address> altAddressesToWork = new List <Address>();
                        altAddressesToWork.Add(altDriveReportPoints[altDriveReportPoints.Count - 2]);
                        altAddressesToWork.Add(workAddress);
                        Double altDistanceToWork = _route.GetRoute(altTransportType, altAddressesToWork).Length;


                        // B2) Get the distance for the entire alternative route.
                        //     This is used to calculate the distance to subtract.
                        altAddressesToWork = new List <Address>(altDriveReportPoints);
                        altAddressesToWork[altAddressesToWork.Count - 1] = workAddress;
                        Double altDistanceB = _route.GetRoute(altTransportType, altAddressesToWork).Length;


                        // The current report distance is including the route between HOME and LOCATION.
                        // Substract the difference, if the distance between WORK and LOCATION is smaller.
                        if (altDistanceToWork < altDistanceToHome)
                        {
                            altToSubtract2 = (altDistanceA - altDistanceB);
                        }
                    }

                    // 2b. When finishing at home and 2 points and 1 is work
                    if (            //(report.IsFromApp == false) &&
                        (report.EndsAtHome == true) &&
                        (altDriveReportPoints.Count == 2) &&
                        ((altDriveReportPoints[altDriveReportPoints.Count - 2].Latitude == workAddress.Latitude) && (altDriveReportPoints[altDriveReportPoints.Count - 2].Longitude == workAddress.Longitude)))
                    {
                        toSubtractHomeRule += homeWorkDistance;
                    }

                    // Subtract.
                    toSubtractAltRule = altToSubtract1 + altToSubtract2;
                }
                //End NDK

                if ((report.StartsAtHome || report.EndsAtHome) && !report.FourKmRule)
                {
                    report.IsExtraDistance = true;
                }

                double drivenDistance = report.Distance;

                if (!report.IsFromApp)
                {
                    // In case the report is not from app then get distance from the supplied route.
                    drivenDistance = drivenRoute.Length;
                }
                //Adjust distance based on FourKmRule and if user start and/or ends at home
                //var correctDistance = drivenDistance - toSubtract;
                var correctDistance = drivenDistance - (toSubtractFourKmRule + toSubtractHomeRule + toSubtractAltRule);


                //Set distance to corrected
                report.Distance = correctDistance;

                if (!report.IsFromApp)
                {
                    //Get RouteGeometry from driven route if the report is not from app. If it is from App then RouteGeometry is already set.
                    report.RouteGeometry = drivenRoute.GeoPoints;
                }

                break;
            }

            case KilometerAllowance.CalculatedWithoutExtraDistance:
            {
                report.Distance = drivenRoute.Length;

                //Save RouteGeometry
                report.RouteGeometry = drivenRoute.GeoPoints;


                break;
            }

            case KilometerAllowance.Read:
            {
                if ((report.StartsAtHome || report.EndsAtHome) && !report.FourKmRule)
                {
                    report.IsExtraDistance = true;
                }

                //Take distance from report
                var manuallyProvidedDrivenDistance = report.Distance;

                //report.Distance = manuallyProvidedDrivenDistance - toSubtract;
                report.Distance = manuallyProvidedDrivenDistance - toSubtractFourKmRule - toSubtractHomeRule;

                break;
            }

            default:
            {
                throw new Exception("No calculation method provided");
            }
            }

            //Calculate the actual amount to reimburse

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

            // Multiply the distance by two if the report is a return trip
            if (report.IsRoundTrip == true)
            {
                report.Distance *= 2;
            }

            CalculateFourKmRuleForReport(report);

            SetAmountToReimburse(report);

            return(report);
        }