/// <summary>
        /// Calculates how many of the 4 km from the Four Km Rule should be deducted from this report based on how many of the daily 4 km has
        /// allready been deducted from other of the users reports from the same day.
        /// The calculated amount will then be deducted from the distance, and saved in the FourKmRuleDeducted property
        /// </summary>
        /// <param name="report"></param>
        /// <returns></returns>
        public DriveReport CalculateFourKmRuleForReport(DriveReport report)
        {
            var result = report;

            if (report.FourKmRule)
            {
                // Find all the reports of the employment from the same day that uses the four km rule and has not been rejected, and select the FourKmRuleDeducted property.
                List <DriveReport> reportsFromSameDayWithFourKmRule;
                reportsFromSameDayWithFourKmRule = _driveReportRepository.AsQueryable().Where(x => x.PersonId == report.PersonId &&
                                                                                              x.Status != ReportStatus.Rejected &&
                                                                                              x.FourKmRule).ToList();

                reportsFromSameDayWithFourKmRule.RemoveAll(x => !AreReportsDrivenOnSameDay(report.DriveDateTimestamp, x.DriveDateTimestamp));

                // Sum the values selected to get the total deducted amount of the day.
                var totalDeductedFromSameDay = reportsFromSameDayWithFourKmRule.Take(reportsFromSameDayWithFourKmRule.Count()).Sum(x => x.FourKmRuleDeducted);

                // If less than four km has been deducted, deduct the remaining amount from the current report. Cannot deduct more than the distance of the report.
                if (totalDeductedFromSameDay < FourKmAdjustment)
                {
                    if (report.Distance < FourKmAdjustment - totalDeductedFromSameDay)
                    {
                        report.FourKmRuleDeducted = report.Distance;
                        report.Distance           = 0;
                    }
                    else
                    {
                        report.FourKmRuleDeducted = FourKmAdjustment - totalDeductedFromSameDay;
                        report.Distance          -= report.FourKmRuleDeducted;
                    }
                }
            }

            return(report);
        }
        /// <summary>
        /// Sends an email to the owner of and person responsible for a report that has been edited or rejected by an admin.
        /// </summary>
        /// <param name="report">The edited report</param>
        /// <param name="emailText">The message to be sent to the owner and responsible leader</param>
        /// <param name="admin">The admin rejecting or editing</param>
        /// <param name="action">A string included in the email. Should be "afvist" or "redigeret"</param>
        public void SendMailToUserAndApproverOfEditedReport(DriveReport report, string emailText, Person admin, string action)
        {
            var mailContent = "Hej," + Environment.NewLine + Environment.NewLine +
                              "Jeg, " + admin.FullName + ", har pr. dags dato " + action + " den følgende godkendte kørselsindberetning:" + Environment.NewLine + Environment.NewLine;

            mailContent += "Formål: " + report.Purpose + Environment.NewLine;

            if (report.KilometerAllowance != KilometerAllowance.Read)
            {
                mailContent += "Startadresse: " + report.DriveReportPoints.ElementAt(0).ToString() + Environment.NewLine
                               + "Slutadresse: " + report.DriveReportPoints.Last().ToString() + Environment.NewLine;
            }

            mailContent += "Afstand: " + report.Distance.ToString().Replace(".", ",") + Environment.NewLine
                           + "Kørselsdato: " + Utilities.FromUnixTime(report.DriveDateTimestamp) + Environment.NewLine + Environment.NewLine
                           + "Hvis du mener at dette er en fejl, så kontakt mig da venligst på " + admin.Mail + Environment.NewLine
                           + "Med venlig hilsen " + admin.FullName + Environment.NewLine + Environment.NewLine
                           + "Besked fra administrator: " + Environment.NewLine + emailText;
            if (report.Person.IsActive)
            {
                _mailService.SendMail(report.Person.Mail, "En administrator har ændret i din indberetning.", mailContent);
            }
            if (report.ApprovedBy.IsActive)
            {
                _mailService.SendMail(report.ApprovedBy.Mail, "En administrator har ændret i en indberetning du har godkendt.", mailContent);
            }
        }
        /// <summary>
        /// Adds report to the stored report list
        /// </summary>
        /// <param name="report">the DriveReport to be added to the list</param>
        /// <returns>true on success, false on failure</returns>
        public static async Task <bool> AddReportToList(DriveReport report)
        {
            try
            {
                var content = await FileHandler.ReadFileContent(Definitions.ReportsFileName, Definitions.ReportsFolderName);

                var list = JsonConvert.DeserializeObject <List <DriveReport> >(content);
                if (list == null)
                {
                    list = new List <DriveReport>();
                }

                list.Add(report);

                var toBeWritten = JsonConvert.SerializeObject(list);

                var test = await FileHandler.WriteFileContent(Definitions.ReportsFileName, Definitions.ReportsFolderName, toBeWritten);

                if (test)
                {
                    Definitions.storedReportsCount = list.Count;
                }

                return(test);
            }
            catch (Exception e)
            {
                return(false);
            }
        }
Ejemplo n.º 4
0
        public FileRecord(DriveReport report, string ownerCpr, IConfiguration config)
        {
            _config = config;
            // Unix timestamp is seconds past epoch
            DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            var      reportDate = dtDateTime.AddSeconds(report.DriveDateTimestamp).ToLocalTime();

            CprNr                  = ownerCpr;
            Date                   = reportDate;
            EmploymentType         = report.Employment.EmploymentType;
            ExtraNumber            = report.Employment.ExtraNumber;
            ReimbursementDistance  = report.Distance;
            TFCode                 = report.TFCode;
            IsAdministrativeWorker =
                report.Employment.CostCenter.ToString()
                .StartsWith(getSetting("AdministrativeCostCenterPrefix"));
            if (!string.IsNullOrWhiteSpace(report.AccountNumber) && report.AccountNumber.Length == 10)
            {
                Account = report.AccountNumber;
            }
            else if (IsAdministrativeWorker)
            {
                Account = getSetting("AdministrativeAccount");
            }
        }
        public void Create_ValidReadReport_ShouldCallCalculate()
        {
            var empl = new Employment
            {
                Id        = 4,
                OrgUnitId = 2,
                OrgUnit   = new OrgUnit(),
                Person    = new Person()
                {
                    Id = 1
                },
                PersonId = 12,
                IsLeader = false
            };

            var leaderEmpl = new Employment
            {
                Id        = 1,
                OrgUnitId = 2,
                OrgUnit   = new OrgUnit()
                {
                    Id = 2
                },
                Person = new Person()
                {
                    Id = 13
                },
                PersonId = 13,
                IsLeader = true
            };

            _orgUnitMock.AsQueryable().ReturnsForAnyArgs(new List <OrgUnit>()
            {
                new OrgUnit()
                {
                    Id = 2
                }
            }.AsQueryable());

            _subMock.AsQueryable().ReturnsForAnyArgs(new List <Core.DomainModel.Substitute>().AsQueryable());

            _emplMock.AsQueryable().ReturnsForAnyArgs(new List <Employment>()
            {
                empl, leaderEmpl
            }.AsQueryable());

            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Read,
                Distance           = 12,
                Purpose            = "Test",
                PersonId           = 12,
                EmploymentId       = 4,
            };

            _uut.Create(report);
            _calculatorMock.ReceivedWithAnyArgs().Calculate(new RouteInformation(), report);
        }
Ejemplo n.º 6
0
        public void ThrowsOnTripWithNoDriver()
        {
            var driveReport = new DriveReport();

            driveReport
            .Invoking(d => d.AddTrip("1", 10, 10, TimeSpan.FromMinutes(20)))
            .Should().Throw <Exception>()
            .WithMessage("Cannot add trip for unregistered driver 1");
        }
        private void SixtyDayRuleCheck(DriveReport report)
        {
            if (report.SixtyDaysRule)
            {
                _logger.LogError($"Brugeren {report.Person.FullName} har angivet at være omfattet af 60-dages reglen");

                SendSixtyDaysRuleNotifications(report);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Used to submit drivereport after finished drive.
        /// </summary>
        /// <param name="report">the report of the drive.</param>
        /// <param name="authorization">the token belonging to the user.</param>
        /// <param name="munUrl">the municipalicy url to be called</param>
        /// <returns>ReturnUserModel</returns>
        public static async Task <ReturnUserModel> SubmitDrive(DriveReport report, Authorization authorization, string munUrl)
        {
            var model = new ReturnUserModel();

            try
            {
                var sendthis = new DriveSubmit();
                sendthis.Authorization = authorization;
                sendthis.DriveReport   = report;
                var json = JsonConvert.SerializeObject(sendthis);

                HttpClientHandler handler = new HttpClientHandler();
                _httpClient = new HttpClient(handler);

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, munUrl + "/report");

                var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
                request.Content = stringContent;
                // Send request
                HttpResponseMessage response = await _httpClient.SendAsync(request);

                // Read response
                string jsonString = await response.Content.ReadAsStringAsync();

                var isValid = IsValidJson(jsonString);

                if (response.IsSuccessStatusCode)
                {
                    model.Error = null;
                }
                else if (string.IsNullOrEmpty(jsonString) || !isValid)
                {
                    model.Error = new Error
                    {
                        Message   = "Netværksfejl",
                        ErrorCode = "404",
                    };
                    model.User = null;
                }
                else
                {
                    model.Error = DeserializeError(jsonString);
                    model.User  = null;
                }

                //return model;
                return(model);
            }
            catch (Exception e)
            {
                model.Error = new Error {
                    ErrorCode = "Exception", Message = "Der skete en uhåndteret fejl. Kontakt venligst Support"
                };
                return(model);
            }
        }
        private void SetAmountToReimburse(DriveReport report)
        {
            // report.KmRate / 100 to go from ører to kroner.
            report.AmountToReimburse = (report.Distance) * (report.KmRate / 100);

            if (report.AmountToReimburse < 0)
            {
                report.AmountToReimburse = 0;
            }
        }
        public void Create_InvalidReadReport_ShouldThrowException()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Read,
                Purpose            = "Test"
            };

            Assert.Throws <Exception>(() => _uut.Create(report));
        }
Ejemplo n.º 11
0
        private void SixtyDayRuleCheck(DriveReport report)
        {
            if (report.SixtyDaysRule)
            {
                _logger.LogForAdmin($"Brugeren {report.Person.FullName} har angivet at være omfattet af 60-dages reglen");

                // Sending notification mails to admins and leader must be done in seperate thread to not block the response to the client.
                var recipients = _personRepository.AsQueryable().Where(x => x.IsAdmin && !string.IsNullOrEmpty(x.Mail)).Select(x => x.Mail).ToList();
                Task.Factory.StartNew(() => SendSixtyDaysRuleNotifications(report, recipients));
            }
        }
Ejemplo n.º 12
0
        private void SendSixtyDaysRuleNotifications(DriveReport report, List <string> recipients)
        {
            // Send mails to admins
            foreach (var recipient in recipients)
            {
                _mailSender.SendMail(recipient, $"{report.Person.FullName} har angivet brug af 60-dages reglen", $"Brugeren {report.Person.FirstName} {report.Person.LastName} med medarbejdernummer {report.Employment.EmploymentId} har angivet at være omfattet af 60-dages reglen");
            }

            // Send mail to leader.
            _mailSender.SendMail(report.ResponsibleLeader.Mail, $"{report.Person.FullName} har angivet brug af 60-dages reglen", $"Brugeren {report.Person.FirstName} {report.Person.LastName} med medarbejdernummer {report.Employment.EmploymentId} har angivet at være omfattet af 60-dages reglen");
        }
        public void ReportWithNoPurpose_ShouldReturn_False()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Read,
                Distance           = 10
            };

            var res = _uut.Validate(report);

            Assert.IsFalse(res);
        }
Ejemplo n.º 14
0
        public void AddsInvalidTrips()
        {
            var driveReport = new DriveReport();

            driveReport.AddDriver("1");
            driveReport.AddInvalidTrip("1", 10, DateTime.Parse("1:00"), DateTime.Parse("1:01"));

            driveReport.AllDriverData.Should().BeEquivalentTo(new[]
            {
                new DriverData("1", 0, 0, TimeSpan.Zero, new[] { new InvalidTrip(10, DateTime.Parse("1:00"), DateTime.Parse("1:01")) })
            });
        }
Ejemplo n.º 15
0
        public void ThrowsOnDuplicateDriver()
        {
            var driveReport = new DriveReport();

            driveReport.AddDriver("1");
            driveReport.AddDriver("2");
            driveReport.AddDriver("3");

            driveReport
            .Invoking(d => d.AddDriver("2"))
            .Should().Throw <Exception>()
            .WithMessage("Driver 2 already registered");
        }
        public void ReportWith_PurposeReadCorrectDistance_ShouldReturn_True()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Read,
                Distance           = 10,
                Purpose            = "Test"
            };

            var res = _uut.Validate(report);

            Assert.IsTrue(res);
        }
        private void SendSixtyDaysRuleNotifications(DriveReport report)
        {
            // Send mails to admins
            _mailService.SendMailToAdmins($"{report.Person.FullName} har angivet brug af 60-dages reglen", $"Brugeren {report.Person.FirstName} {report.Person.LastName} med medarbejdernummer {report.Employment.EmploymentId} har angivet at være omfattet af 60-dages reglen");

            // Send mail to leader.
            foreach (var leader in report.PersonReports)
            {
                if (leader.Person.RecieveMail && !string.IsNullOrEmpty(leader.Person.Mail) && leader.Person.IsActive)
                {
                    _mailService.SendMail(leader.Person.Mail, $"{report.Person.FullName} har angivet brug af 60-dages reglen", $"Brugeren {report.Person.FirstName} {report.Person.LastName} med medarbejdernummer {report.Employment.EmploymentId} har angivet at være omfattet af 60-dages reglen");
                }
            }
        }
        public void ReportWith_CalculatedDistance7_ShouldReturn_False()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Calculated,
                Distance           = 7,
                DriveReportPoints  = new List <DriveReportPoint>(),
                Purpose            = "Test"
            };

            var res = _uut.Validate(report);

            Assert.IsFalse(res);
        }
        public void ReportWithCalculated_AndOnePoint_ShouldReturn_False()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Calculated,
                DriveReportPoints  = new List <DriveReportPoint>
                {
                    new DriveReportPoint()
                }
            };

            var res = _uut.Validate(report);

            Assert.IsFalse(res);
        }
Ejemplo n.º 20
0
        public void AddsUnregisteredDrivers()
        {
            var driveReport = new DriveReport();

            driveReport.AddDriver("1");
            driveReport.AddDriver("2");
            driveReport.AddDriver("3");

            driveReport.AllDriverData.Should().BeEquivalentTo(new[]
            {
                new DriverData("1"),
                new DriverData("2"),
                new DriverData("3")
            });
        }
        public void ReCalculateFourKmRuleForOtherReports_WhenReportIsRejected()
        {
            var driveDateTimestampToday     = Utilities.ToUnixTime(DateTime.Now);
            var driveDateTimestampYesterday = Utilities.ToUnixTime(DateTime.Now.AddDays(-1));

            var drivereportToCalculate1 = new DriveReport()
            {
                PersonId           = 1,
                DriveDateTimestamp = driveDateTimestampToday,
                Status             = ReportStatus.Pending,
                Distance           = 50,
                FourKmRule         = true,
                FourKmRuleDeducted = 0
            };

            var drivereportToCalculate2 = new DriveReport()
            {
                PersonId           = 1,
                DriveDateTimestamp = driveDateTimestampYesterday,
                Status             = ReportStatus.Accepted,
                Distance           = 50,
                FourKmRule         = true,
                FourKmRuleDeducted = 0
            };

            var firstDrivereportOfTheDay = new DriveReport()
            {
                PersonId           = 1,
                DriveDateTimestamp = driveDateTimestampToday,
                Status             = ReportStatus.Accepted,
                Distance           = 50,
                FourKmRule         = true,
                FourKmRuleDeducted = 4
            };

            _reportRepoMock.Insert(drivereportToCalculate1);
            _reportRepoMock.Insert(drivereportToCalculate2);
            _reportRepoMock.Insert(firstDrivereportOfTheDay);

            firstDrivereportOfTheDay.Status = ReportStatus.Rejected;
            _uut.CalculateFourKmRuleForOtherReports(firstDrivereportOfTheDay);

            _calculatorMock.Received().CalculateFourKmRuleForReport(drivereportToCalculate1);       // Report from same day should be recalculated
            _calculatorMock.DidNotReceive().CalculateFourKmRuleForReport(drivereportToCalculate2);  // Report from yesterday should not be recalculated
            _calculatorMock.DidNotReceive().CalculateFourKmRuleForReport(firstDrivereportOfTheDay); // Deleted report should not be recalculated
        }
Ejemplo n.º 22
0
        private List <FileRecord> RecordListBuilder(Dictionary <string, List <DriveReport> > usersToReimburse)
        {
            var fileRecords = new List <FileRecord>();

            foreach (var cpr in usersToReimburse.Keys)
            {
                var         driveReports         = usersToReimburse[cpr].OrderBy(x => x.EmploymentId).OrderBy(x => x.TFCode).ThenBy(x => x.AccountNumber).ThenBy(x => x.DriveDateTimestamp);
                DriveReport currentDriveReport   = null;
                var         currentTfCode        = "";
                var         currentMonth         = -1;
                String      currentAccountNumber = null;
                foreach (var driveReport in driveReports)
                {
                    var driveDate = TimestampToDate(driveReport.DriveDateTimestamp);
                    if (!driveReport.TFCode.Equals(currentTfCode) || //We make one file record for each employment and each tf code
                        driveDate.Month != currentMonth ||
                        currentDriveReport == null ||
                        !driveReport.EmploymentId.Equals(currentDriveReport.EmploymentId) ||
                        !(driveReport.AccountNumber == currentAccountNumber))
                    {
                        if (currentDriveReport != null)
                        {
                            fileRecords.Add(new FileRecord(currentDriveReport, cpr));
                        }
                        currentMonth         = driveDate.Month;
                        currentTfCode        = driveReport.TFCode;
                        currentAccountNumber = driveReport.AccountNumber;
                        currentDriveReport   = new DriveReport
                        {
                            TFCode             = driveReport.TFCode,
                            AccountNumber      = currentAccountNumber ?? String.Empty,
                            Employment         = driveReport.Employment,
                            EmploymentId       = driveReport.EmploymentId,
                            Distance           = 0,
                            DriveDateTimestamp = TimetsmpOfLastDayInMonth(driveDate)
                        };
                    }
                    currentDriveReport.Distance += driveReport.Distance;
                }
                if (currentDriveReport != null)
                {
                    fileRecords.Add(new FileRecord(currentDriveReport, cpr));
                }
            }
            return(fileRecords);
        }
        public void ReportWith_PurposeCalculatedTwoPoints_ShouldReturn_True()
        {
            var report = new DriveReport
            {
                KilometerAllowance = KilometerAllowance.Calculated,
                DriveReportPoints  = new List <DriveReportPoint>
                {
                    new DriveReportPoint(),
                    new DriveReportPoint(),
                },
                Purpose = "Test"
            };

            var res = _uut.Validate(report);

            Assert.IsTrue(res);
        }
Ejemplo n.º 24
0
        public Person GetActualLeaderForReport(DriveReport driveReport)
        {
            var currentDateTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            // Fix for bug that sometimes happens when drivereport is from app, where personid is set, but person is not.
            var person = _employmentRepository.AsQueryable().First(x => x.PersonId == driveReport.PersonId).Person;

            // Fix for bug that sometimes happens when drivereport is from app, where personid is set, but person is not.
            var empl = _employmentRepository.AsQueryable().First(x => x.Id == driveReport.EmploymentId);

            //Find an org unit where the person is not the leader, and then find the leader of that org unit to attach to the drive report
            var orgUnit         = _orgUnitRepository.AsQueryable().SingleOrDefault(o => o.Id == empl.OrgUnitId);
            var leaderOfOrgUnit =
                _employmentRepository.AsQueryable().FirstOrDefault(e => e.OrgUnit.Id == orgUnit.Id && e.IsLeader && e.StartDateTimestamp < currentDateTimestamp && (e.EndDateTimestamp > currentDateTimestamp || e.EndDateTimestamp == 0));

            if (orgUnit == null)
            {
                return(null);
            }

            var currentTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            while ((leaderOfOrgUnit == null && orgUnit.Level > 0) || (leaderOfOrgUnit != null && leaderOfOrgUnit.PersonId == person.Id))
            {
                leaderOfOrgUnit = _employmentRepository.AsQueryable().SingleOrDefault(e => e.OrgUnit.Id == orgUnit.ParentId && e.IsLeader &&
                                                                                      e.StartDateTimestamp < currentTimestamp &&
                                                                                      (e.EndDateTimestamp == 0 || e.EndDateTimestamp > currentTimestamp));
                orgUnit = orgUnit.Parent;
            }


            if (orgUnit == null)
            {
                return(null);
            }
            if (leaderOfOrgUnit == null)
            {
                // This statement will be hit when all orgunits up to (not including) level 0 have been checked for a leader.
                // If no actual leader has been found then return the reponsibleleader.
                // This will happen when members of orgunit 0 try to create a report, as orgunit 0 has no leaders and they are all handled by a substitute.
                return(GetResponsibleLeaderForReport(driveReport));
            }

            return(leaderOfOrgUnit.Person);
        }
 /// <summary>
 /// Validates report.
 /// </summary>
 /// <param name="report">Report to be validated.</param>
 /// <returns>True or false</returns>
 public bool Validate(DriveReport report)
 {
     // Report does not validate if it is read and distance is less than zero.
     if (report.KilometerAllowance == KilometerAllowance.Read && report.Distance < 0)
     {
         return(false);
     }
     // Report does not validate if it is calculated and has less than two points.
     if (report.KilometerAllowance != KilometerAllowance.Read && report.DriveReportPoints.Count < 2)
     {
         return(false);
     }
     // Report does not validate if it has no purpose given.
     if (string.IsNullOrEmpty(report.Purpose))
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 26
0
        public void AddsValidTrips()
        {
            var driveReport = new DriveReport();

            driveReport.AddDriver("1");
            driveReport.AddTrip("1", 10, 0.0, TimeSpan.FromMinutes(20));

            driveReport.AddDriver("2");
            driveReport.AddTrip("1", 50, 50.0, TimeSpan.FromMinutes(60));
            driveReport.AddTrip("2", 20, 0.0, TimeSpan.FromMinutes(30));

            driveReport.AddDriver("3");

            driveReport.AllDriverData.Should().BeEquivalentTo(new[]
            {
                new DriverData("1", 60, 50.0, TimeSpan.FromMinutes(80), new InvalidTrip[] { }),
                new DriverData("2", 20, 0.0, TimeSpan.FromMinutes(30), new InvalidTrip[] { }),
                new DriverData("3", 0, 0, TimeSpan.Zero, new InvalidTrip[] { })
            });
        }
Ejemplo n.º 27
0
        private SdKoersel.AnsaettelseKoerselOpretInputType PrepareRequestData(DriveReport report)
        {
            SdKoersel.AnsaettelseKoerselOpretInputType opretInputType = new SdKoersel.AnsaettelseKoerselOpretInputType();

            opretInputType.Item = _customSettings.SdInstitutionNumber; // InstitutionIdentifikator
            if (string.IsNullOrEmpty(opretInputType.Item))
            {
                throw new SdConfigException("PROTECTED_institutionNumber må ikke være tom");
            }
            opretInputType.ItemElementName     = SdKoersel.ItemChoiceType.InstitutionIdentifikator;
            opretInputType.BrugerIdentifikator = report.ApprovedBy.CprNumber;
            opretInputType.Item1 = report.Employment.EmploymentId; // AnsaettelseIdentifikator
            opretInputType.RegistreringTypeIdentifikator = report.TFCode;
            opretInputType.GodkendtIndikator             = true;
            opretInputType.KoerselDato = new System.DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(report.DriveDateTimestamp).ToLocalTime();
            opretInputType.RegistreringNummerIdentifikator = report.LicensePlate;
            opretInputType.KontrolleretIndikator           = true;
            opretInputType.KilometerMaal                 = Convert.ToDecimal(report.Distance);
            opretInputType.Regel60DageIndikator          = false;
            opretInputType.DokumentationEksternIndikator = true;

            return(opretInputType);
        }
        /// <summary>
        /// Removes specific report from the stored list
        /// </summary>
        /// <param name="report">the DriveReport to be removed from the list</param>
        /// <returns>the DriveReport list after removal of the specific DriveReport</returns>
        public static async Task <List <DriveReport> > RemoveReportFromList(DriveReport report)
        {
            try
            {
                var content = await FileHandler.ReadFileContent(Definitions.ReportsFileName, Definitions.ReportsFolderName);

                var list = JsonConvert.DeserializeObject <List <DriveReport> >(content);

                var item = list.FindIndex(x => x.Date == report.Date && x.route.TotalDistance == report.route.TotalDistance);
                list.RemoveAt(item);

                var toBeWritten = JsonConvert.SerializeObject(list);

                await FileHandler.WriteFileContent(Definitions.ReportsFileName, Definitions.ReportsFolderName, toBeWritten);

                Definitions.storedReportsCount = list.Count;
                return(list);
            }
            catch (Exception e)
            {
                return(new List <DriveReport>());;
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Recalculates the deduction of 4 km from the persons reports driven on the date of the given unix time stamp. Does not recalculate rejected or invoiced reports.
        /// </summary>
        /// <param name="DriveDateTimestamp"></param>
        /// <param name="PersonId"></param>
        public void CalculateFourKmRuleForOtherReports(DriveReport report)
        {
            if (report.Status.Equals(ReportStatus.Rejected))
            {
                report.FourKmRuleDeducted = 0;
            }

            var reportsFromSameDayWithFourKmRule = _driveReportRepository.AsQueryable().Where(x => x.PersonId == report.PersonId &&
                                                                                              x.Status != ReportStatus.Rejected &&
                                                                                              x.Status != ReportStatus.Invoiced &&
                                                                                              x.FourKmRule)
                                                   .OrderBy(x => x.DriveDateTimestamp).ToList();

            foreach (var r in reportsFromSameDayWithFourKmRule)
            {
                if (_calculator.AreReportsDrivenOnSameDay(report.DriveDateTimestamp, r.DriveDateTimestamp))
                {
                    _calculator.CalculateFourKmRuleForReport(r);
                }
            }

            _driveReportRepository.Save();
        }
        /// <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.
            var addressHistory = _addressHistoryRepo.AsQueryable().SingleOrDefault(x => x.EmploymentId == report.EmploymentId && x.StartTimestamp <report.DriveDateTimestamp && x.EndTimestamp> report.DriveDateTimestamp);

            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;

            //If user indicated to use the Four Km Rule
            if (report.FourKmRule)
            {
                //Take users provided distance from home to border of municipality
                var borderDistance = 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:
            {
                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;
            }

            if (report.FourKmRule)
            {
                report.Distance -= FourKmAdjustment;
            }

            SetAmountToReimburse(report);

            return(report);
        }