diff --git a/Controllers/HomeController.cs b/Controllers/HomeController.cs index 6213670..c406da6 100644 --- a/Controllers/HomeController.cs +++ b/Controllers/HomeController.cs @@ -59,22 +59,49 @@ namespace CarCareTracker.Controllers { vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID()); } - var vehicleViewModels = vehiclesStored.Select(x => new VehicleViewModel - { - Id = x.Id, - ImageLocation = x.ImageLocation, - Year = x.Year, - Make = x.Make, - Model = x.Model, - LicensePlate = x.LicensePlate, - SoldDate = x.SoldDate, - IsElectric = x.IsElectric, - IsDiesel = x.IsDiesel, - UseHours = x.UseHours, - ExtraFields = x.ExtraFields, - Tags = x.Tags, - LastReportedMileage = _vehicleLogic.GetMaxMileage(x.Id), - HasReminders = _vehicleLogic.GetVehicleHasUrgentOrPastDueReminders(x.Id) + var vehicleViewModels = vehiclesStored.Select(x => { + var vehicleVM = new VehicleViewModel + { + Id = x.Id, + ImageLocation = x.ImageLocation, + Year = x.Year, + Make = x.Make, + Model = x.Model, + LicensePlate = x.LicensePlate, + SoldDate = x.SoldDate, + IsElectric = x.IsElectric, + IsDiesel = x.IsDiesel, + UseHours = x.UseHours, + ExtraFields = x.ExtraFields, + Tags = x.Tags, + DashboardMetrics = x.DashboardMetrics + }; + //dashboard metrics + if (x.DashboardMetrics.Any()) + { + var vehicleRecords = _vehicleLogic.GetVehicleRecords(x.Id); + var userConfig = _config.GetUserConfig(User); + var distanceUnit = x.UseHours ? "h" : userConfig.UseMPG ? "mi." : "km"; + if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.Default)) + { + vehicleVM.LastReportedMileage = _vehicleLogic.GetMaxMileage(vehicleRecords); + vehicleVM.HasReminders = _vehicleLogic.GetVehicleHasUrgentOrPastDueReminders(x.Id, vehicleVM.LastReportedMileage); + } + if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.CostPerMile)) + { + var vehicleTotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords); + var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords); + var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords); + var totalDistance = maxMileage - minMileage; + vehicleVM.CostPerMile = vehicleTotalCost / totalDistance; + vehicleVM.DistanceUnit = distanceUnit; + } + if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.TotalCost)) + { + vehicleVM.TotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords); + } + } + return vehicleVM; }).ToList(); return PartialView("_GarageDisplay", vehicleViewModels); } diff --git a/Controllers/VehicleController.cs b/Controllers/VehicleController.cs index cb6e023..bda751a 100644 --- a/Controllers/VehicleController.cs +++ b/Controllers/VehicleController.cs @@ -1275,12 +1275,13 @@ namespace CarCareTracker.Controllers [HttpGet] public IActionResult GetCostTableForVehicle(int vehicleId, int year = 0) { - var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId); - var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId); - var collisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId); - var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId); - var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId); - var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId); + var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId); + var serviceRecords = vehicleRecords.ServiceRecords; + var gasRecords = vehicleRecords.GasRecords; + var collisionRecords = vehicleRecords.CollisionRecords; + var taxRecords = vehicleRecords.TaxRecords; + var upgradeRecords = vehicleRecords.UpgradeRecords; + var odometerRecords = vehicleRecords.OdometerRecords; if (year != default) { serviceRecords.RemoveAll(x => x.Date.Year != year); @@ -1290,8 +1291,8 @@ namespace CarCareTracker.Controllers upgradeRecords.RemoveAll(x => x.Date.Year != year); odometerRecords.RemoveAll(x => x.Date.Year != year); } - var maxMileage = _vehicleLogic.GetMaxMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords); - var minMileage = _vehicleLogic.GetMinMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords); + var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords); + var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords); var vehicleData = _dataAccess.GetVehicleById(vehicleId); var userConfig = _config.GetUserConfig(User); var totalDistanceTraveled = maxMileage - minMileage; diff --git a/Enum/DashboardMetric.cs b/Enum/DashboardMetric.cs new file mode 100644 index 0000000..b5a084a --- /dev/null +++ b/Enum/DashboardMetric.cs @@ -0,0 +1,9 @@ +namespace CarCareTracker.Models +{ + public enum DashboardMetric + { + Default = 0, + TotalCost = 1, + CostPerMile = 2 + } +} diff --git a/Logic/VehicleLogic.cs b/Logic/VehicleLogic.cs index e656443..421814c 100644 --- a/Logic/VehicleLogic.cs +++ b/Logic/VehicleLogic.cs @@ -6,12 +6,14 @@ namespace CarCareTracker.Logic { public interface IVehicleLogic { + VehicleRecords GetVehicleRecords(int vehicleId); + decimal GetVehicleTotalCost(VehicleRecords vehicleRecords); int GetMaxMileage(int vehicleId); - int GetMaxMileage(List serviceRecords, List repairRecords, List gasRecords, List upgradeRecords, List odometerRecords); + int GetMaxMileage(VehicleRecords vehicleRecords); int GetMinMileage(int vehicleId); - int GetMinMileage(List serviceRecords, List repairRecords, List gasRecords, List upgradeRecords, List odometerRecords); + int GetMinMileage(VehicleRecords vehicleRecords); int GetOwnershipDays(string purchaseDate, string soldDate, List serviceRecords, List repairRecords, List gasRecords, List upgradeRecords, List odometerRecords, List taxRecords); - bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId); + bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId, int currentMileage); } public class VehicleLogic: IVehicleLogic { @@ -19,6 +21,7 @@ namespace CarCareTracker.Logic private readonly IGasRecordDataAccess _gasRecordDataAccess; private readonly ICollisionRecordDataAccess _collisionRecordDataAccess; private readonly IUpgradeRecordDataAccess _upgradeRecordDataAccess; + private readonly ITaxRecordDataAccess _taxRecordDataAccess; private readonly IOdometerRecordDataAccess _odometerRecordDataAccess; private readonly IReminderRecordDataAccess _reminderRecordDataAccess; private readonly IReminderHelper _reminderHelper; @@ -27,6 +30,7 @@ namespace CarCareTracker.Logic IGasRecordDataAccess gasRecordDataAccess, ICollisionRecordDataAccess collisionRecordDataAccess, IUpgradeRecordDataAccess upgradeRecordDataAccess, + ITaxRecordDataAccess taxRecordDataAccess, IOdometerRecordDataAccess odometerRecordDataAccess, IReminderRecordDataAccess reminderRecordDataAccess, IReminderHelper reminderHelper @@ -35,10 +39,32 @@ namespace CarCareTracker.Logic _gasRecordDataAccess = gasRecordDataAccess; _collisionRecordDataAccess = collisionRecordDataAccess; _upgradeRecordDataAccess = upgradeRecordDataAccess; + _taxRecordDataAccess = taxRecordDataAccess; _odometerRecordDataAccess = odometerRecordDataAccess; _reminderRecordDataAccess = reminderRecordDataAccess; _reminderHelper = reminderHelper; } + public VehicleRecords GetVehicleRecords(int vehicleId) + { + return new VehicleRecords + { + ServiceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId), + GasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId), + CollisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId), + TaxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId), + UpgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId), + OdometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId), + }; + } + public decimal GetVehicleTotalCost(VehicleRecords vehicleRecords) + { + var serviceRecordSum = vehicleRecords.ServiceRecords.Sum(x => x.Cost); + var repairRecordSum = vehicleRecords.CollisionRecords.Sum(x => x.Cost); + var upgradeRecordSum = vehicleRecords.UpgradeRecords.Sum(x => x.Cost); + var taxRecordSum = vehicleRecords.TaxRecords.Sum(x => x.Cost); + var gasRecordSum = vehicleRecords.GasRecords.Sum(x => x.Cost); + return serviceRecordSum + repairRecordSum + upgradeRecordSum + taxRecordSum + gasRecordSum; + } public int GetMaxMileage(int vehicleId) { var numbersArray = new List(); @@ -69,28 +95,28 @@ namespace CarCareTracker.Logic } return numbersArray.Any() ? numbersArray.Max() : 0; } - public int GetMaxMileage(List serviceRecords, List repairRecords, List gasRecords, List upgradeRecords, List odometerRecords) + public int GetMaxMileage(VehicleRecords vehicleRecords) { var numbersArray = new List(); - if (serviceRecords.Any()) + if (vehicleRecords.ServiceRecords.Any()) { - numbersArray.Add(serviceRecords.Max(x => x.Mileage)); + numbersArray.Add(vehicleRecords.ServiceRecords.Max(x => x.Mileage)); } - if (repairRecords.Any()) + if (vehicleRecords.CollisionRecords.Any()) { - numbersArray.Add(repairRecords.Max(x => x.Mileage)); + numbersArray.Add(vehicleRecords.CollisionRecords.Max(x => x.Mileage)); } - if (gasRecords.Any()) + if (vehicleRecords.GasRecords.Any()) { - numbersArray.Add(gasRecords.Max(x => x.Mileage)); + numbersArray.Add(vehicleRecords.GasRecords.Max(x => x.Mileage)); } - if (upgradeRecords.Any()) + if (vehicleRecords.UpgradeRecords.Any()) { - numbersArray.Add(upgradeRecords.Max(x => x.Mileage)); + numbersArray.Add(vehicleRecords.UpgradeRecords.Max(x => x.Mileage)); } - if (odometerRecords.Any()) + if (vehicleRecords.OdometerRecords.Any()) { - numbersArray.Add(odometerRecords.Max(x => x.Mileage)); + numbersArray.Add(vehicleRecords.OdometerRecords.Max(x => x.Mileage)); } return numbersArray.Any() ? numbersArray.Max() : 0; } @@ -124,30 +150,30 @@ namespace CarCareTracker.Logic } return numbersArray.Any() ? numbersArray.Min() : 0; } - public int GetMinMileage(List serviceRecords, List repairRecords, List gasRecords, List upgradeRecords, List odometerRecords) + public int GetMinMileage(VehicleRecords vehicleRecords) { var numbersArray = new List(); - var _serviceRecords = serviceRecords.Where(x => x.Mileage != default).ToList(); + var _serviceRecords = vehicleRecords.ServiceRecords.Where(x => x.Mileage != default).ToList(); if (_serviceRecords.Any()) { numbersArray.Add(_serviceRecords.Min(x => x.Mileage)); } - var _repairRecords = repairRecords.Where(x => x.Mileage != default).ToList(); + var _repairRecords = vehicleRecords.CollisionRecords.Where(x => x.Mileage != default).ToList(); if (_repairRecords.Any()) { numbersArray.Add(_repairRecords.Min(x => x.Mileage)); } - var _gasRecords = gasRecords.Where(x => x.Mileage != default).ToList(); + var _gasRecords = vehicleRecords.GasRecords.Where(x => x.Mileage != default).ToList(); if (_gasRecords.Any()) { numbersArray.Add(_gasRecords.Min(x => x.Mileage)); } - var _upgradeRecords = upgradeRecords.Where(x => x.Mileage != default).ToList(); + var _upgradeRecords = vehicleRecords.UpgradeRecords.Where(x => x.Mileage != default).ToList(); if (_upgradeRecords.Any()) { numbersArray.Add(_upgradeRecords.Min(x => x.Mileage)); } - var _odometerRecords = odometerRecords.Where(x => x.Mileage != default).ToList(); + var _odometerRecords = vehicleRecords.OdometerRecords.Where(x => x.Mileage != default).ToList(); if (_odometerRecords.Any()) { numbersArray.Add(_odometerRecords.Min(x => x.Mileage)); @@ -186,9 +212,8 @@ namespace CarCareTracker.Logic return 1; } } - public bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId) + public bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId, int currentMileage) { - var currentMileage = GetMaxMileage(vehicleId); var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId); var results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, DateTime.Now); return results.Any(x => x.Urgency == ReminderUrgency.VeryUrgent || x.Urgency == ReminderUrgency.PastDue); diff --git a/Models/Report/CostTableForVehicle.cs b/Models/Report/CostTableForVehicle.cs index 937bdbf..7b49662 100644 --- a/Models/Report/CostTableForVehicle.cs +++ b/Models/Report/CostTableForVehicle.cs @@ -14,13 +14,14 @@ public decimal GasRecordPerMile { get { return TotalDistance != default ? GasRecordSum / TotalDistance : 0; } } public decimal CollisionRecordPerMile { get { return TotalDistance != default ? CollisionRecordSum / TotalDistance : 0; } } public decimal UpgradeRecordPerMile { get { return TotalDistance != default ? UpgradeRecordSum / TotalDistance : 0; } } - public decimal ServiceRecordPerMonth { get { return NumberOfDays != default ? ServiceRecordSum / NumberOfDays : 0; } } - public decimal GasRecordPerMonth { get { return NumberOfDays != default ? GasRecordSum / NumberOfDays : 0; } } - public decimal CollisionRecordPerMonth { get { return NumberOfDays != default ? CollisionRecordSum / NumberOfDays : 0; } } - public decimal UpgradeRecordPerMonth { get { return NumberOfDays != default ? UpgradeRecordSum / NumberOfDays : 0; } } - public decimal TaxRecordPerMonth { get { return NumberOfDays != default ? TaxRecordSum / NumberOfDays : 0; } } - public decimal TotalPerMonth { get { return ServiceRecordPerMonth + CollisionRecordPerMonth + UpgradeRecordPerMonth + GasRecordPerMonth + TaxRecordPerMonth; } } - public decimal TotalPerMile { get { return ServiceRecordPerMile + CollisionRecordPerMile + UpgradeRecordPerMile + GasRecordPerMile; } } + public decimal TaxRecordPerMile { get { return TotalDistance != default ? TaxRecordSum / TotalDistance : 0; } } + public decimal ServiceRecordPerDay { get { return NumberOfDays != default ? ServiceRecordSum / NumberOfDays : 0; } } + public decimal GasRecordPerDay { get { return NumberOfDays != default ? GasRecordSum / NumberOfDays : 0; } } + public decimal CollisionRecordPerDay { get { return NumberOfDays != default ? CollisionRecordSum / NumberOfDays : 0; } } + public decimal UpgradeRecordPerDay { get { return NumberOfDays != default ? UpgradeRecordSum / NumberOfDays : 0; } } + public decimal TaxRecordPerDay { get { return NumberOfDays != default ? TaxRecordSum / NumberOfDays : 0; } } + public decimal TotalPerDay { get { return ServiceRecordPerDay + CollisionRecordPerDay + UpgradeRecordPerDay + GasRecordPerDay + TaxRecordPerDay; } } + public decimal TotalPerMile { get { return ServiceRecordPerMile + CollisionRecordPerMile + UpgradeRecordPerMile + GasRecordPerMile + TaxRecordPerMile; } } public decimal TotalCost { get { return ServiceRecordSum + CollisionRecordSum + UpgradeRecordSum + GasRecordSum + TaxRecordSum; } } } } diff --git a/Models/Shared/VehicleRecords.cs b/Models/Shared/VehicleRecords.cs new file mode 100644 index 0000000..bbff7d6 --- /dev/null +++ b/Models/Shared/VehicleRecords.cs @@ -0,0 +1,12 @@ +namespace CarCareTracker.Models +{ + public class VehicleRecords + { + public List ServiceRecords { get; set; } = new List(); + public List CollisionRecords { get; set; } = new List(); + public List UpgradeRecords { get; set; } = new List(); + public List GasRecords { get; set; } = new List(); + public List TaxRecords { get; set; } = new List(); + public List OdometerRecords { get; set; } = new List(); + } +} diff --git a/Models/Vehicle.cs b/Models/Vehicle.cs index 3a50cab..c2789f0 100644 --- a/Models/Vehicle.cs +++ b/Models/Vehicle.cs @@ -26,5 +26,6 @@ /// Primarily used for vehicles where the odometer does not reflect actual mileage. /// public string OdometerDifference { get; set; } = "0"; + public List DashboardMetrics { get; set; } = new List(); } } diff --git a/Models/VehicleViewModel.cs b/Models/VehicleViewModel.cs index d8b8fb9..6d2a5d6 100644 --- a/Models/VehicleViewModel.cs +++ b/Models/VehicleViewModel.cs @@ -14,7 +14,12 @@ public bool UseHours { get; set; } = false; public List ExtraFields { get; set; } = new List(); public List Tags { get; set; } = new List(); - public int LastReportedMileage; - public bool HasReminders = false; + //Dashboard Metric Attributes + public List DashboardMetrics { get; set; } = new List(); + public int LastReportedMileage { get; set; } + public bool HasReminders { get; set; } = false; + public decimal CostPerMile { get; set; } + public decimal TotalCost { get; set; } + public string DistanceUnit { get; set; } } } diff --git a/Views/Home/_GarageDisplay.cshtml b/Views/Home/_GarageDisplay.cshtml index 7beb380..0985115 100644 --- a/Views/Home/_GarageDisplay.cshtml +++ b/Views/Home/_GarageDisplay.cshtml @@ -36,21 +36,40 @@ @if (!string.IsNullOrWhiteSpace(vehicle.SoldDate)) {

@translator.Translate(userLanguage, "SOLD")

- } else if (vehicle.LastReportedMileage != default) + } else if (vehicle.DashboardMetrics.Any()) {
-
-
- @vehicle.LastReportedMileage.ToString("N0") -
- @if (vehicle.HasReminders) - { + @if (vehicle.DashboardMetrics.Contains(DashboardMetric.Default) && vehicle.LastReportedMileage != default) + { + +
- + @vehicle.LastReportedMileage.ToString("N0")
- } -
- + @if (vehicle.HasReminders) + { +
+ +
+ } +
+ } + @if (vehicle.DashboardMetrics.Contains(DashboardMetric.CostPerMile) && vehicle.CostPerMile != default) + { +
+
+ @($"{vehicle.CostPerMile.ToString("C2")}/{vehicle.DistanceUnit}") +
+
+ } + @if (vehicle.DashboardMetrics.Contains(DashboardMetric.TotalCost) && vehicle.TotalCost != default) + { +
+
+ @($"{vehicle.TotalCost.ToString("C2")}") +
+
+ }
}
diff --git a/Views/Vehicle/_VehicleModal.cshtml b/Views/Vehicle/_VehicleModal.cshtml index 0890c56..f17ca17 100644 --- a/Views/Vehicle/_VehicleModal.cshtml +++ b/Views/Vehicle/_VehicleModal.cshtml @@ -87,6 +87,29 @@
+
+
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+