From 474a25d522a5c5b793b33029ef41b34b10fdb0fe Mon Sep 17 00:00:00 2001 From: cuqmbr Date: Sat, 13 May 2023 13:54:15 +0300 Subject: [PATCH] refactor: change statistic methods in database model classes This fixes incorrect data retrieval when all entities (including those whose time does not correspond to the desired period) have been loaded from the database --- Server/Models/Company.cs | 32 ++++++++-------- Server/Models/Route.cs | 43 +++++++++++++++------ Server/Models/Ticket.cs | 4 +- Server/Models/TicketGroup.cs | 63 +++++++++++++++++++++++++++++++ Server/Models/Vehicle.cs | 62 +++++++++++++++++++++++-------- Server/Services/ReportService.cs | 64 ++++++++++++++++---------------- 6 files changed, 190 insertions(+), 78 deletions(-) diff --git a/Server/Models/Company.cs b/Server/Models/Company.cs index 0a471d1..6a54353 100644 --- a/Server/Models/Company.cs +++ b/Server/Models/Company.cs @@ -17,7 +17,7 @@ public class Company public virtual IList Vehicles { get; set; } = null!; public virtual IList CompanyDrivers { get; set; } = null!; - public int GetTotalEnrollmentCount() + public int GetTotalEnrollmentCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -25,14 +25,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetEnrollmentCount(enrollment.RouteId); + result += vehicle.GetRouteEnrollmentCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public int GetTotalCanceledEnrollmentCount() + public int GetTotalCanceledEnrollmentCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -40,14 +40,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetCanceledEnrollmentCount(enrollment.RouteId); + result += vehicle.GetRouteCanceledEnrollmentCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public int GetTotalSoldTicketCount() + public int GetTotalSoldTicketCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -55,14 +55,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetSoldTicketCount(enrollment.RouteId); + result += vehicle.GetRouteSoldTicketCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public int GetTotalReturnedTicketCount() + public int GetTotalReturnedTicketCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -70,14 +70,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetReturnedTicketCount(enrollment.RouteId); + result += vehicle.GetRouteReturnedTicketCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public int GetTotalIndirectTicketCount() + public int GetTotalIndirectTicketCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -85,14 +85,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetIndirectTicketCount(enrollment.RouteId); + result += vehicle.GetRouteIndirectTicketCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public int GetTotalReturnedIndirectTicketCount() + public int GetTotalReturnedIndirectTicketCount(DateTime fromDate, DateTime toDate) { int result = 0; @@ -100,14 +100,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetReturnedIndirectTicketCount(enrollment.RouteId); + result += vehicle.GetRouteReturnedIndirectTicketCount(fromDate, toDate, enrollment.RouteId); } } return result; } - public double GetTotalRevenue() + public double GetTotalRevenue(DateTime fromDate, DateTime toDate) { double result = 0; @@ -115,14 +115,14 @@ public class Company { foreach (var enrollment in vehicle.VehicleEnrollments) { - result += vehicle.GetTotalRevenue(enrollment.RouteId); + result += vehicle.GetRouteTotalRevenue(fromDate, toDate, enrollment.RouteId); } } return result; } - public double GetTotalAverageRating() + public double GetTotalAverageRating(DateTime fromDate, DateTime toDate) { double result = 0; int enrollmentCount = 0; @@ -136,7 +136,7 @@ public class Company continue; } - result += vehicle.GetAverageRating(enrollment.RouteId); + result += vehicle.GetRouteAverageRating(fromDate, toDate, enrollment.RouteId); enrollmentCount++; } } diff --git a/Server/Models/Route.cs b/Server/Models/Route.cs index 00f67d5..24e4463 100644 --- a/Server/Models/Route.cs +++ b/Server/Models/Route.cs @@ -12,29 +12,38 @@ public class Route public virtual IList RouteAddresses { get; set; } = null!; public virtual IList VehicleEnrollments { get; set; } = null!; - public int GetEnrollmentCount() + public int GetCompanyEnrollmentCount(DateTime fromDate, DateTime toDate, int companyId) { - return VehicleEnrollments.Count(ve => !ve.IsCanceled); + return VehicleEnrollments.Count(ve => + !ve.IsCanceled && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.Vehicle.CompanyId == companyId); } - public int GetCanceledEnrollmentCount() + public int GetCompanyCanceledEnrollmentCount(DateTime fromDate, DateTime toDate, int companyId) { - return VehicleEnrollments.Count(ve => ve.IsCanceled); + return VehicleEnrollments.Count(ve => + ve.IsCanceled && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.Vehicle.CompanyId == companyId); } - public int GetSoldTicketCount() + public int GetCompanySoldTicketCount(DateTime fromDate, DateTime toDate, int companyId) { int result = 0; foreach (var enrollment in VehicleEnrollments) { - result += enrollment.Tickets.Count(t => !t.IsReturned); + result += enrollment.Tickets.Count(t => + !t.IsReturned && + t.VehicleEnrollment.DepartureDateTimeUtc >= fromDate && t.VehicleEnrollment.DepartureDateTimeUtc <= toDate && + t.VehicleEnrollment.Vehicle.CompanyId == companyId); } return result; } - public int GetIndirectTicketCount() + public int GetCompanyIndirectTicketCount(DateTime fromDate, DateTime toDate, int companyId) { int result = 0; @@ -45,17 +54,23 @@ public class Route { result += enrollment.Tickets.Count(t => !t.IsReturned && t.FirstRouteAddressId != departureAddressId || - t.LastRouteAddressId != arrivalAddressId); + t.LastRouteAddressId != arrivalAddressId && + t.VehicleEnrollment.DepartureDateTimeUtc >= fromDate && t.VehicleEnrollment.DepartureDateTimeUtc <= toDate && + t.VehicleEnrollment.Vehicle.CompanyId == companyId); } return result; } - public double GetTotalRevenue() + public double GetCompanyTotalRevenue(DateTime fromDate, DateTime toDate, int companyId) { double result = 0; - foreach (var enrollment in VehicleEnrollments) + var enrollments = VehicleEnrollments.Where(ve => + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.Vehicle.CompanyId == companyId); + + foreach (var enrollment in enrollments) { foreach (var ticket in enrollment.Tickets) { @@ -66,12 +81,16 @@ public class Route return result; } - public double GetAverageRating() + public double GetCompanyAverageRating(DateTime fromDate, DateTime toDate, int companyId) { double result = 0; int reviewCount = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.Vehicle.CompanyId == companyId); - foreach (var enrollment in VehicleEnrollments) + foreach (var enrollment in enrollments) { if (enrollment.Reviews.Count == 0) { diff --git a/Server/Models/Ticket.cs b/Server/Models/Ticket.cs index 491f255..aa9d89a 100644 --- a/Server/Models/Ticket.cs +++ b/Server/Models/Ticket.cs @@ -48,7 +48,7 @@ public class Ticket var departureDateTimeUtc = VehicleEnrollment.DepartureDateTimeUtc; var routeAddresses = VehicleEnrollment.Route.RouteAddresses - .OrderBy(ra => ra.Order).ToArray(); + .OrderBy(ra => ra.Order); foreach (var routeAddress in routeAddresses) { @@ -73,7 +73,7 @@ public class Ticket var arrivalDateTimeUtc = VehicleEnrollment.DepartureDateTimeUtc; var routeAddresses = VehicleEnrollment.Route.RouteAddresses - .OrderBy(ra => ra.Order).ToArray(); + .OrderBy(ra => ra.Order); foreach (var routeAddress in routeAddresses) { diff --git a/Server/Models/TicketGroup.cs b/Server/Models/TicketGroup.cs index a40aeb6..b7c22b7 100644 --- a/Server/Models/TicketGroup.cs +++ b/Server/Models/TicketGroup.cs @@ -23,4 +23,67 @@ public class TicketGroup return cost; } + + public DateTime GetDepartureTime() + { + var departureDateTimeUtc = Tickets.First().VehicleEnrollment.DepartureDateTimeUtc; + + var routeAddresses = Tickets.First().VehicleEnrollment.Route.RouteAddresses + .OrderBy(ra => ra.Order).ToArray(); + + foreach (var routeAddress in routeAddresses) + { + var details = routeAddress.RouteAddressDetails + .First(rad => rad.RouteAddressId == routeAddress.Id); + + if (routeAddress.AddressId == Tickets.First().FirstRouteAddressId) + { + departureDateTimeUtc += details.WaitTimeSpan; + break; + } + + departureDateTimeUtc += details.TimeSpanToNextCity; + departureDateTimeUtc += details.WaitTimeSpan; + } + + return departureDateTimeUtc; + } + + public DateTime GetArrivalTime() + { + var arrivalDateTimeUtc = Tickets.First().VehicleEnrollment.DepartureDateTimeUtc; + + var routeAddresses = Tickets.Last().VehicleEnrollment.Route.RouteAddresses + .OrderBy(ra => ra.Order).ToArray(); + + foreach (var routeAddress in routeAddresses) + { + var details = routeAddress.RouteAddressDetails + .First(rad => rad.RouteAddressId == routeAddress.Id); + + if (routeAddress.AddressId == Tickets.Last().LastRouteAddressId) + { + break; + } + + arrivalDateTimeUtc += details.TimeSpanToNextCity; + arrivalDateTimeUtc += details.WaitTimeSpan; + } + + return arrivalDateTimeUtc; + } + + public Address GetDepartureAddress() + { + return Tickets.First().VehicleEnrollment.Route.RouteAddresses + .First(ra => ra.AddressId == Tickets.First().FirstRouteAddressId) + .Address; + } + + public Address GetArrivalAddress() + { + return Tickets.Last().VehicleEnrollment.Route.RouteAddresses + .First(ra => ra.AddressId == Tickets.Last().LastRouteAddressId) + .Address; + } } \ No newline at end of file diff --git a/Server/Models/Vehicle.cs b/Server/Models/Vehicle.cs index 91f1bc8..f4d620c 100644 --- a/Server/Models/Vehicle.cs +++ b/Server/Models/Vehicle.cs @@ -26,21 +26,31 @@ public class Vehicle public IList VehicleEnrollments { get; set; } = null!; - public int GetEnrollmentCount(int routeId) + public int GetRouteEnrollmentCount(DateTime fromDate, DateTime toDate, int routeId) { - return VehicleEnrollments.Count(ve => !ve.IsCanceled && ve.RouteId == routeId); + return VehicleEnrollments.Count(ve => + !ve.IsCanceled && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.RouteId == routeId); } - public int GetCanceledEnrollmentCount(int routeId) + public int GetRouteCanceledEnrollmentCount(DateTime fromDate, DateTime toDate, int routeId) { - return VehicleEnrollments.Count(ve => ve.IsCanceled && ve.RouteId == routeId); + return VehicleEnrollments.Count(ve => + ve.IsCanceled && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate && + ve.RouteId == routeId); } - public int GetSoldTicketCount(int routeId) + public int GetRouteSoldTicketCount(DateTime fromDate, DateTime toDate, int routeId) { int result = 0; - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); + + foreach (var enrollment in enrollments) { result += enrollment.Tickets.Count(t => !t.IsReturned); } @@ -48,11 +58,15 @@ public class Vehicle return result; } - public int GetReturnedTicketCount(int routeId) + public int GetRouteReturnedTicketCount(DateTime fromDate, DateTime toDate, int routeId) { int result = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + foreach (var enrollment in enrollments) { result += enrollment.Tickets.Count(t => t.IsReturned); } @@ -60,11 +74,15 @@ public class Vehicle return result; } - public int GetIndirectTicketCount(int routeId) + public int GetRouteIndirectTicketCount(DateTime fromDate, DateTime toDate, int routeId) { int result = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + foreach (var enrollment in enrollments) { var departureRouteAddressId = enrollment.Route.RouteAddresses.First().AddressId; var arrivalRouteAddressId = enrollment.Route.RouteAddresses.Last().AddressId; @@ -77,11 +95,15 @@ public class Vehicle return result; } - public int GetReturnedIndirectTicketCount(int routeId) + public int GetRouteReturnedIndirectTicketCount(DateTime fromDate, DateTime toDate, int routeId) { int result = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + foreach (var enrollment in enrollments) { var departureRouteAddressId = enrollment.Route.RouteAddresses.First().AddressId; var arrivalRouteAddressId = enrollment.Route.RouteAddresses.Last().AddressId; @@ -94,11 +116,15 @@ public class Vehicle return result; } - public double GetTotalRevenue(int routeId) + public double GetRouteTotalRevenue(DateTime fromDate, DateTime toDate, int routeId) { double result = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + foreach (var enrollment in enrollments) { foreach (var ticket in enrollment.Tickets) { @@ -109,12 +135,16 @@ public class Vehicle return result; } - public double GetAverageRating(int routeId) + public double GetRouteAverageRating(DateTime fromDate, DateTime toDate, int routeId) { double result = 0; int reviewCount = 0; + + var enrollments = VehicleEnrollments.Where(ve => + ve.RouteId == routeId && + ve.DepartureDateTimeUtc >= fromDate && ve.DepartureDateTimeUtc <= toDate); - foreach (var enrollment in VehicleEnrollments.Where(ve => ve.RouteId == routeId)) + foreach (var enrollment in enrollments) { reviewCount += enrollment.Reviews.Count; diff --git a/Server/Services/ReportService.cs b/Server/Services/ReportService.cs index 3b78fdd..a2a3c93 100644 --- a/Server/Services/ReportService.cs +++ b/Server/Services/ReportService.cs @@ -613,22 +613,22 @@ public class ReportService : IReportService row.Shading.Color = Color.FromRgbColor(25, Colors.Black); row.Cells[0].MergeRight = 1; - row.Cells[0].AddParagraph($"{route.GetEnrollmentCount()}"); + row.Cells[0].AddParagraph($"{route.GetCompanyEnrollmentCount(fromDate, toDate, companyId)}"); row.Cells[2].MergeRight = 1; - row.Cells[2].AddParagraph($"{route.GetCanceledEnrollmentCount()}"); + row.Cells[2].AddParagraph($"{route.GetCompanyCanceledEnrollmentCount(fromDate, toDate, companyId)}"); row.Cells[4].MergeRight = 1; - row.Cells[4].AddParagraph($"{route.GetSoldTicketCount()}"); + row.Cells[4].AddParagraph($"{route.GetCompanySoldTicketCount(fromDate, toDate, companyId)}"); row.Cells[6].MergeRight = 1; - row.Cells[6].AddParagraph($"{route.GetIndirectTicketCount()}"); + row.Cells[6].AddParagraph($"{route.GetCompanyIndirectTicketCount(fromDate, toDate, companyId)}"); row.Cells[8].MergeRight = 1; - row.Cells[8].AddParagraph($"{route.GetTotalRevenue()}"); + row.Cells[8].AddParagraph($"{route.GetCompanyTotalRevenue(fromDate, toDate, companyId)}"); row.Cells[10].MergeRight = 1; - var routeAverageRating = route.GetAverageRating(); + var routeAverageRating = route.GetCompanyAverageRating(fromDate, toDate, companyId); row.Cells[10].AddParagraph($"{(routeAverageRating == 0 ? "-" : routeAverageRating)}"); row = table.AddRow(); @@ -670,23 +670,23 @@ public class ReportService : IReportService row.Cells[0].MergeRight = 2; row.Cells[0].AddParagraph($"{vehicle.Id}, {vehicle.Type}, {vehicle.Number}"); - var executedEnrollmentCount = vehicle.GetEnrollmentCount(route.Id); - var canceledEnrollmentCount = vehicle.GetCanceledEnrollmentCount(route.Id); + var executedEnrollmentCount = vehicle.GetRouteEnrollmentCount(fromDate, toDate, route.Id); + var canceledEnrollmentCount = vehicle.GetRouteCanceledEnrollmentCount(fromDate, toDate, route.Id); row.Cells[3].MergeRight = 1; row.Cells[3].AddParagraph($"{executedEnrollmentCount + canceledEnrollmentCount}, " + $"{executedEnrollmentCount}, {canceledEnrollmentCount}"); row.Cells[5].MergeRight = 2; - row.Cells[5].AddParagraph($"{vehicle.GetSoldTicketCount(route.Id)}, " + - $"{vehicle.GetReturnedTicketCount(route.Id)}; " + - $"{vehicle.GetIndirectTicketCount(route.Id)}, " + - $"{vehicle.GetReturnedIndirectTicketCount(route.Id)}"); + row.Cells[5].AddParagraph($"{vehicle.GetRouteSoldTicketCount(fromDate, toDate, route.Id)}, " + + $"{vehicle.GetRouteReturnedTicketCount(fromDate, toDate, route.Id)}; " + + $"{vehicle.GetRouteIndirectTicketCount(fromDate, toDate, route.Id)}, " + + $"{vehicle.GetRouteReturnedIndirectTicketCount(fromDate, toDate, route.Id)}"); row.Cells[8].MergeRight = 1; - row.Cells[8].AddParagraph($"{vehicle.GetTotalRevenue(route.Id)}"); + row.Cells[8].AddParagraph($"{vehicle.GetRouteTotalRevenue(fromDate, toDate, route.Id)}"); row.Cells[10].MergeRight = 1; - var vehicleAverageRating = vehicle.GetAverageRating(route.Id); + var vehicleAverageRating = vehicle.GetRouteAverageRating(fromDate, toDate, route.Id); row.Cells[10].AddParagraph($"{(vehicleAverageRating == 0 ? "-" : vehicleAverageRating)}"); } @@ -704,12 +704,12 @@ public class ReportService : IReportService paragraph = section.AddParagraph( $"У період з {fromDate:dd.MM.yyyy} по {toDate:dd.MM.yyyy} " + $"({(toDate - fromDate).Days} днів) компанією {dbCompany.Name} " + - $"було заплановано {dbCompany.GetTotalEnrollmentCount()} поїздки, " + - $"з яких {dbCompany.GetTotalCanceledEnrollmentCount()} було скасовано, " + - $"продано {dbCompany.GetTotalSoldTicketCount()} квитків, " + - $"з яких {dbCompany.GetTotalReturnedTicketCount()} було повернено. " + - $"За цей час було зароблено {dbCompany.GetTotalRevenue()} гривень. " + - $"Середній рейтинг по всім поїздкам: {dbCompany.GetTotalAverageRating()}"); + $"було заплановано {dbCompany.GetTotalEnrollmentCount(fromDate, toDate)} поїздки, " + + $"з яких {dbCompany.GetTotalCanceledEnrollmentCount(fromDate, toDate)} було скасовано, " + + $"продано {dbCompany.GetTotalSoldTicketCount(fromDate, toDate)} квитків, " + + $"з яких {dbCompany.GetTotalReturnedTicketCount(fromDate, toDate)} було повернено. " + + $"За цей час було зароблено {dbCompany.GetTotalRevenue(fromDate, toDate)} гривень. " + + $"Середній рейтинг по всім поїздкам: {dbCompany.GetTotalAverageRating(fromDate, toDate)}"); paragraph.Format.Alignment = ParagraphAlignment.Justify; paragraph.Format.Font.Size = 14; } @@ -761,12 +761,12 @@ public class ReportService : IReportService var statistics = new StatisticsResponse { - EnrollmentsPlanned = dbCompany.GetTotalEnrollmentCount(), - EnrollmentsCanceled = dbCompany.GetTotalCanceledEnrollmentCount(), - TicketsSold = dbCompany.GetTotalSoldTicketCount(), - TicketsReturned = dbCompany.GetTotalReturnedTicketCount(), - MoneyEarned = dbCompany.GetTotalRevenue(), - AverageRating = dbCompany.GetTotalAverageRating() + EnrollmentsPlanned = dbCompany.GetTotalEnrollmentCount(fromDate, toDate), + EnrollmentsCanceled = dbCompany.GetTotalCanceledEnrollmentCount(fromDate, toDate), + TicketsSold = dbCompany.GetTotalSoldTicketCount(fromDate, toDate), + TicketsReturned = dbCompany.GetTotalReturnedTicketCount(fromDate, toDate), + MoneyEarned = dbCompany.GetTotalRevenue(fromDate, toDate), + AverageRating = dbCompany.GetTotalAverageRating(fromDate, toDate) }; return (true, null, statistics); @@ -817,12 +817,12 @@ public class ReportService : IReportService foreach (var company in dbCompanies) { - statistics.EnrollmentsPlanned += company.GetTotalEnrollmentCount(); - statistics.EnrollmentsCanceled += company.GetTotalCanceledEnrollmentCount(); - statistics.TicketsSold += company.GetTotalSoldTicketCount(); - statistics.TicketsReturned += company.GetTotalReturnedTicketCount(); - statistics.MoneyEarned += company.GetTotalRevenue(); - statistics.AverageRating += company.GetTotalAverageRating(); + statistics.EnrollmentsPlanned += company.GetTotalEnrollmentCount(fromDate, toDate); + statistics.EnrollmentsCanceled += company.GetTotalCanceledEnrollmentCount(fromDate, toDate); + statistics.TicketsSold += company.GetTotalSoldTicketCount(fromDate, toDate); + statistics.TicketsReturned += company.GetTotalReturnedTicketCount(fromDate, toDate); + statistics.MoneyEarned += company.GetTotalRevenue(fromDate, toDate); + statistics.AverageRating += company.GetTotalAverageRating(fromDate, toDate); } return (true, null, statistics);