Merge pull request #54 from hargata/Hargata/consolidated.report
Hargata/consolidated.report
This commit is contained in:
@@ -98,7 +98,7 @@ namespace CarCareTracker.Controllers
|
|||||||
{
|
{
|
||||||
var currentMileage = GetMaxMileage(vehicleId);
|
var currentMileage = GetMaxMileage(vehicleId);
|
||||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||||
var results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage).Select(x=> new ReminderExportModel { Description = x.Description, Urgency = x.Urgency.ToString(), Metric = x.Metric.ToString(), Notes = x.Notes});
|
var results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, DateTime.Now).Select(x=> new ReminderExportModel { Description = x.Description, Urgency = x.Urgency.ToString(), Metric = x.Metric.ToString(), Notes = x.Notes});
|
||||||
return Json(results);
|
return Json(results);
|
||||||
}
|
}
|
||||||
private int GetMaxMileage(int vehicleId)
|
private int GetMaxMileage(int vehicleId)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using CarCareTracker.Helper;
|
|||||||
using CsvHelper;
|
using CsvHelper;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using CarCareTracker.External.Implementations;
|
|
||||||
using CarCareTracker.MapProfile;
|
using CarCareTracker.MapProfile;
|
||||||
|
|
||||||
namespace CarCareTracker.Controllers
|
namespace CarCareTracker.Controllers
|
||||||
@@ -29,11 +28,13 @@ namespace CarCareTracker.Controllers
|
|||||||
private readonly IFileHelper _fileHelper;
|
private readonly IFileHelper _fileHelper;
|
||||||
private readonly IGasHelper _gasHelper;
|
private readonly IGasHelper _gasHelper;
|
||||||
private readonly IReminderHelper _reminderHelper;
|
private readonly IReminderHelper _reminderHelper;
|
||||||
|
private readonly IReportHelper _reportHelper;
|
||||||
|
|
||||||
public VehicleController(ILogger<VehicleController> logger,
|
public VehicleController(ILogger<VehicleController> logger,
|
||||||
IFileHelper fileHelper,
|
IFileHelper fileHelper,
|
||||||
IGasHelper gasHelper,
|
IGasHelper gasHelper,
|
||||||
IReminderHelper reminderHelper,
|
IReminderHelper reminderHelper,
|
||||||
|
IReportHelper reportHelper,
|
||||||
IVehicleDataAccess dataAccess,
|
IVehicleDataAccess dataAccess,
|
||||||
INoteDataAccess noteDataAccess,
|
INoteDataAccess noteDataAccess,
|
||||||
IServiceRecordDataAccess serviceRecordDataAccess,
|
IServiceRecordDataAccess serviceRecordDataAccess,
|
||||||
@@ -51,6 +52,7 @@ namespace CarCareTracker.Controllers
|
|||||||
_fileHelper = fileHelper;
|
_fileHelper = fileHelper;
|
||||||
_gasHelper = gasHelper;
|
_gasHelper = gasHelper;
|
||||||
_reminderHelper = reminderHelper;
|
_reminderHelper = reminderHelper;
|
||||||
|
_reportHelper = reportHelper;
|
||||||
_serviceRecordDataAccess = serviceRecordDataAccess;
|
_serviceRecordDataAccess = serviceRecordDataAccess;
|
||||||
_gasRecordDataAccess = gasRecordDataAccess;
|
_gasRecordDataAccess = gasRecordDataAccess;
|
||||||
_collisionRecordDataAccess = collisionRecordDataAccess;
|
_collisionRecordDataAccess = collisionRecordDataAccess;
|
||||||
@@ -571,9 +573,71 @@ namespace CarCareTracker.Controllers
|
|||||||
#endregion
|
#endregion
|
||||||
#region "Reports"
|
#region "Reports"
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetReportPartialView()
|
public IActionResult GetReportPartialView(int vehicleId)
|
||||||
{
|
{
|
||||||
return PartialView("_Report");
|
//get records
|
||||||
|
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 viewModel = new ReportViewModel();
|
||||||
|
//get totalCostMakeUp
|
||||||
|
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
|
||||||
|
{
|
||||||
|
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||||
|
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||||
|
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||||
|
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||||
|
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost)
|
||||||
|
};
|
||||||
|
//get costbymonth
|
||||||
|
List<CostForVehicleByMonth> allCosts = new List<CostForVehicleByMonth>();
|
||||||
|
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetRepairRecordSum(collisionRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, 0));
|
||||||
|
viewModel.CostForVehicleByMonth = allCosts.GroupBy(x => x.MonthName).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = x.Key,
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
}).ToList();
|
||||||
|
//get reminders
|
||||||
|
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||||
|
viewModel.ReminderMakeUpForVehicle = new ReminderMakeUpForVehicle
|
||||||
|
{
|
||||||
|
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
|
||||||
|
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
|
||||||
|
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
|
||||||
|
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
|
||||||
|
};
|
||||||
|
//populate year dropdown.
|
||||||
|
var numbersArray = new List<int>();
|
||||||
|
if (serviceRecords.Any())
|
||||||
|
{
|
||||||
|
numbersArray.Add(serviceRecords.Min(x => x.Date.Year));
|
||||||
|
}
|
||||||
|
if (collisionRecords.Any())
|
||||||
|
{
|
||||||
|
numbersArray.Add(collisionRecords.Min(x => x.Date.Year));
|
||||||
|
}
|
||||||
|
if (gasRecords.Any())
|
||||||
|
{
|
||||||
|
numbersArray.Add(gasRecords.Min(x => x.Date.Year));
|
||||||
|
}
|
||||||
|
if (upgradeRecords.Any())
|
||||||
|
{
|
||||||
|
numbersArray.Add(upgradeRecords.Min(x => x.Date.Year));
|
||||||
|
}
|
||||||
|
var minYear = numbersArray.Any() ? numbersArray.Min() : DateTime.Now.AddYears(-5).Year;
|
||||||
|
var yearDifference = DateTime.Now.Year - minYear + 1;
|
||||||
|
for(int i = 0; i < yearDifference; i++)
|
||||||
|
{
|
||||||
|
viewModel.Years.Add(DateTime.Now.AddYears(i * -1).Year);
|
||||||
|
}
|
||||||
|
return PartialView("_Report", viewModel);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0)
|
public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0)
|
||||||
@@ -601,19 +665,53 @@ namespace CarCareTracker.Controllers
|
|||||||
};
|
};
|
||||||
return PartialView("_CostMakeUpReport", viewModel);
|
return PartialView("_CostMakeUpReport", viewModel);
|
||||||
}
|
}
|
||||||
public IActionResult GetFuelCostByMonthByVehicle(int vehicleId, int year = 0)
|
public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd)
|
||||||
{
|
{
|
||||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now.AddDays(daysToAdd));
|
||||||
if (year != default)
|
var viewModel = new ReminderMakeUpForVehicle
|
||||||
{
|
{
|
||||||
gasRecords.RemoveAll(x => x.Date.Year != year);
|
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
|
||||||
|
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
|
||||||
|
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
|
||||||
|
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
|
||||||
|
};
|
||||||
|
return PartialView("_ReminderMakeUpReport", viewModel);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult GetCostByMonthByVehicle(int vehicleId, List<ImportMode> selectedMetrics, int year = 0)
|
||||||
|
{
|
||||||
|
List<CostForVehicleByMonth> allCosts = new List<CostForVehicleByMonth>();
|
||||||
|
if (selectedMetrics.Contains(ImportMode.ServiceRecord) || selectedMetrics.Contains(ImportMode.All))
|
||||||
|
{
|
||||||
|
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, year));
|
||||||
}
|
}
|
||||||
var groupedGasRecord = gasRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new GasCostForVehicleByMonth
|
if (selectedMetrics.Contains(ImportMode.RepairRecord) || selectedMetrics.Contains(ImportMode.All))
|
||||||
{
|
{
|
||||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
var repairRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetRepairRecordSum(repairRecords, year));
|
||||||
|
}
|
||||||
|
if (selectedMetrics.Contains(ImportMode.UpgradeRecord) || selectedMetrics.Contains(ImportMode.All))
|
||||||
|
{
|
||||||
|
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, year));
|
||||||
|
}
|
||||||
|
if (selectedMetrics.Contains(ImportMode.GasRecord) || selectedMetrics.Contains(ImportMode.All))
|
||||||
|
{
|
||||||
|
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, year));
|
||||||
|
}
|
||||||
|
if (selectedMetrics.Contains(ImportMode.TaxRecord) || selectedMetrics.Contains(ImportMode.All))
|
||||||
|
{
|
||||||
|
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year));
|
||||||
|
}
|
||||||
|
var groupedRecord = allCosts.GroupBy(x => x.MonthName).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = x.Key,
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return PartialView("_GasCostByMonthReport", groupedGasRecord);
|
return PartialView("_GasCostByMonthReport", groupedRecord);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region "Reminders"
|
#region "Reminders"
|
||||||
@@ -642,17 +740,17 @@ namespace CarCareTracker.Controllers
|
|||||||
}
|
}
|
||||||
return numbersArray.Any() ? numbersArray.Max() : 0;
|
return numbersArray.Any() ? numbersArray.Max() : 0;
|
||||||
}
|
}
|
||||||
private List<ReminderRecordViewModel> GetRemindersAndUrgency(int vehicleId)
|
private List<ReminderRecordViewModel> GetRemindersAndUrgency(int vehicleId, DateTime dateCompare)
|
||||||
{
|
{
|
||||||
var currentMileage = GetMaxMileage(vehicleId);
|
var currentMileage = GetMaxMileage(vehicleId);
|
||||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||||
List<ReminderRecordViewModel> results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage);
|
List<ReminderRecordViewModel> results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, dateCompare);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
|
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = GetRemindersAndUrgency(vehicleId);
|
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||||
if (result.Where(x => x.Urgency == ReminderUrgency.VeryUrgent || x.Urgency == ReminderUrgency.PastDue).Any())
|
if (result.Where(x => x.Urgency == ReminderUrgency.VeryUrgent || x.Urgency == ReminderUrgency.PastDue).Any())
|
||||||
{
|
{
|
||||||
return Json(true);
|
return Json(true);
|
||||||
@@ -662,7 +760,7 @@ namespace CarCareTracker.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetReminderRecordsByVehicleId(int vehicleId)
|
public IActionResult GetReminderRecordsByVehicleId(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = GetRemindersAndUrgency(vehicleId);
|
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||||
result = result.OrderByDescending(x => x.Urgency).ToList();
|
result = result.OrderByDescending(x => x.Urgency).ToList();
|
||||||
return PartialView("_ReminderRecords", result);
|
return PartialView("_ReminderRecords", result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
RepairRecord = 1,
|
RepairRecord = 1,
|
||||||
GasRecord = 2,
|
GasRecord = 2,
|
||||||
TaxRecord = 3,
|
TaxRecord = 3,
|
||||||
UpgradeRecord = 4
|
UpgradeRecord = 4,
|
||||||
|
All = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
public interface IReminderHelper
|
public interface IReminderHelper
|
||||||
{
|
{
|
||||||
List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage);
|
List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage, DateTime dateCompare);
|
||||||
}
|
}
|
||||||
public class ReminderHelper: IReminderHelper
|
public class ReminderHelper: IReminderHelper
|
||||||
{
|
{
|
||||||
public List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage)
|
public List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage, DateTime dateCompare)
|
||||||
{
|
{
|
||||||
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
|
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
|
||||||
foreach (var reminder in reminders)
|
foreach (var reminder in reminders)
|
||||||
@@ -25,7 +25,7 @@ namespace CarCareTracker.Helper
|
|||||||
};
|
};
|
||||||
if (reminder.Metric == ReminderMetric.Both)
|
if (reminder.Metric == ReminderMetric.Both)
|
||||||
{
|
{
|
||||||
if (reminder.Date < DateTime.Now)
|
if (reminder.Date < dateCompare)
|
||||||
{
|
{
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
reminderViewModel.Metric = ReminderMetric.Date;
|
||||||
@@ -35,7 +35,7 @@ namespace CarCareTracker.Helper
|
|||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
}
|
}
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
else if (reminder.Date < dateCompare.AddDays(7))
|
||||||
{
|
{
|
||||||
//if less than a week from today or less than 50 miles from current mileage then very urgent.
|
//if less than a week from today or less than 50 miles from current mileage then very urgent.
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
@@ -47,7 +47,7 @@ namespace CarCareTracker.Helper
|
|||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
}
|
}
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
else if (reminder.Date < dateCompare.AddDays(30))
|
||||||
{
|
{
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
reminderViewModel.Metric = ReminderMetric.Date;
|
||||||
@@ -60,15 +60,15 @@ namespace CarCareTracker.Helper
|
|||||||
}
|
}
|
||||||
else if (reminder.Metric == ReminderMetric.Date)
|
else if (reminder.Metric == ReminderMetric.Date)
|
||||||
{
|
{
|
||||||
if (reminder.Date < DateTime.Now)
|
if (reminder.Date < dateCompare)
|
||||||
{
|
{
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
}
|
}
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
else if (reminder.Date < dateCompare.AddDays(7))
|
||||||
{
|
{
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
}
|
}
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
else if (reminder.Date < dateCompare.AddDays(30))
|
||||||
{
|
{
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
}
|
}
|
||||||
|
|||||||
77
Helper/ReportHelper.cs
Normal file
77
Helper/ReportHelper.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace CarCareTracker.Helper
|
||||||
|
{
|
||||||
|
public interface IReportHelper
|
||||||
|
{
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0);
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0);
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0);
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0);
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0);
|
||||||
|
}
|
||||||
|
public class ReportHelper: IReportHelper
|
||||||
|
{
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
serviceRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return serviceRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
repairRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return repairRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
upgradeRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return upgradeRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
gasRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return gasRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
taxRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return taxRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = x.Sum(y => y.Cost)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace CarCareTracker.Models
|
namespace CarCareTracker.Models
|
||||||
{
|
{
|
||||||
public class GasCostForVehicleByMonth
|
public class CostForVehicleByMonth
|
||||||
{
|
{
|
||||||
public string MonthName { get; set; }
|
public string MonthName { get; set; }
|
||||||
public decimal Cost { get; set; }
|
public decimal Cost { get; set; }
|
||||||
10
Models/Report/ReminderMakeUpForVehicle.cs
Normal file
10
Models/Report/ReminderMakeUpForVehicle.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class ReminderMakeUpForVehicle
|
||||||
|
{
|
||||||
|
public int NotUrgentCount { get; set; }
|
||||||
|
public int UrgentCount { get; set; }
|
||||||
|
public int VeryUrgentCount { get; set; }
|
||||||
|
public int PastDueCount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Models/Report/ReportViewModel.cs
Normal file
10
Models/Report/ReportViewModel.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class ReportViewModel
|
||||||
|
{
|
||||||
|
public List<CostForVehicleByMonth> CostForVehicleByMonth { get; set; } = new List<CostForVehicleByMonth>();
|
||||||
|
public CostMakeUpForVehicle CostMakeUpForVehicle { get; set; } = new CostMakeUpForVehicle();
|
||||||
|
public ReminderMakeUpForVehicle ReminderMakeUpForVehicle { get; set; } = new ReminderMakeUpForVehicle();
|
||||||
|
public List<int> Years { get; set; } = new List<int>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
|||||||
builder.Services.AddSingleton<IGasHelper, GasHelper>();
|
builder.Services.AddSingleton<IGasHelper, GasHelper>();
|
||||||
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
||||||
builder.Services.AddSingleton<ILoginHelper, LoginHelper>();
|
builder.Services.AddSingleton<ILoginHelper, LoginHelper>();
|
||||||
|
builder.Services.AddSingleton<IReportHelper, ReportHelper>();
|
||||||
|
|
||||||
if (!Directory.Exists("data"))
|
if (!Directory.Exists("data"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,5 +45,5 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<h1>No data found or all records have zero sums, insert records with non-zero sums to see visualizations here.</h1>
|
<h4>No data found or all records have zero sums, insert records with non-zero sums to see visualizations here.</h4>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@model List<GasCostForVehicleByMonth>
|
@model List<CostForVehicleByMonth>
|
||||||
@if (Model.Any())
|
@if (Model.Any())
|
||||||
{
|
{
|
||||||
<canvas id="bar-chart" class="vehicleDetailTabContainer"></canvas>
|
<canvas id="bar-chart" class="vehicleDetailTabContainer"></canvas>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
var barGraphLabels = [];
|
var barGraphLabels = [];
|
||||||
var barGraphData = [];
|
var barGraphData = [];
|
||||||
var useDarkMode = getGlobalConfig().useDarkMode;
|
var useDarkMode = getGlobalConfig().useDarkMode;
|
||||||
@foreach (GasCostForVehicleByMonth gasCost in Model)
|
@foreach (CostForVehicleByMonth gasCost in Model)
|
||||||
{
|
{
|
||||||
@:barGraphLabels.push("@gasCost.MonthName");
|
@:barGraphLabels.push("@gasCost.MonthName");
|
||||||
@:barGraphData.push(@gasCost.Cost);
|
@:barGraphData.push(@gasCost.Cost);
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
labels: barGraphLabels,
|
labels: barGraphLabels,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Gas Expenses by Month",
|
label: "Expenses by Month",
|
||||||
backgroundColor: ["#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f"],
|
backgroundColor: ["#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f"],
|
||||||
data: barGraphData
|
data: barGraphData
|
||||||
}
|
}
|
||||||
@@ -52,5 +52,5 @@
|
|||||||
</script>
|
</script>
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
<h1>No data found, insert some gas data to see visualizations here.</h1>
|
<h4>No data found, insert/select some data to see visualizations here.</h4>
|
||||||
}
|
}
|
||||||
48
Views/Vehicle/_ReminderMakeUpReport.cshtml
Normal file
48
Views/Vehicle/_ReminderMakeUpReport.cshtml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
@model ReminderMakeUpForVehicle
|
||||||
|
@if (Model.UrgentCount + Model.VeryUrgentCount + Model.NotUrgentCount + Model.PastDueCount > 0)
|
||||||
|
{
|
||||||
|
<canvas id="donut-chart"></canvas>
|
||||||
|
<script>
|
||||||
|
renderChart();
|
||||||
|
function renderChart() {
|
||||||
|
var useDarkMode = getGlobalConfig().useDarkMode;
|
||||||
|
new Chart($("#donut-chart"), {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: ["Not Urgent", "Urgent", "Very Urgent", "Past Due"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Reminders by Category",
|
||||||
|
backgroundColor: ["#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600"],
|
||||||
|
data: [
|
||||||
|
@Model.NotUrgentCount,
|
||||||
|
@Model.UrgentCount,
|
||||||
|
@Model.VeryUrgentCount,
|
||||||
|
@Model.PastDueCount
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: "bottom",
|
||||||
|
labels: {
|
||||||
|
color: useDarkMode ? "#fff" : "#000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: "Reminders by Urgency",
|
||||||
|
color: useDarkMode ? "#fff" : "#000"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<h4>No data found, create reminders to see visualizations here.</h4>
|
||||||
|
}
|
||||||
@@ -1,36 +1,148 @@
|
|||||||
<div class="row">
|
@model ReportViewModel
|
||||||
<div class="col-sm-6 col-12">
|
<div class="row">
|
||||||
|
<div class="col-md-3 col-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
<select class="form-select" id="yearOption" onchange="yearUpdated()">
|
||||||
|
<option value="0">All Time</option>
|
||||||
|
@foreach(int year in Model.Years)
|
||||||
|
{
|
||||||
|
<option value="@year">@year</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="costMakeUpReportContent">
|
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="costMakeUpReportContent">
|
||||||
|
@await Html.PartialAsync("_CostMakeUpReport", Model.CostMakeUpForVehicle)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-12">
|
<div class="col-md-6 col-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12 d-flex justify-content-center reportsCheckBoxContainer">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="allExpenseCheck" value="0" checked>
|
||||||
|
<label class="form-check-label" for="allExpenseCheck">All</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="serviceExpenseCheck" value="1">
|
||||||
|
<label class="form-check-label" for="serviceExpenseCheck">Service</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="repairExpenseCheck" value="2">
|
||||||
|
<label class="form-check-label" for="repairExpenseCheck">Repairs</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="upgradeExpenseCheck" value="3">
|
||||||
|
<label class="form-check-label" for="upgradeExpenseCheck">Upgrades</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="gasExpenseCheck" value="4">
|
||||||
|
<label class="form-check-label" for="gasExpenseCheck">Gas</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="taxExpenseCheck" value="5">
|
||||||
|
<label class="form-check-label" for="taxExpenseCheck">Tax</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="gasCostByMonthReportContent">
|
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="gasCostByMonthReportContent">
|
||||||
|
@await Html.PartialAsync("_GasCostByMonthReport", Model.CostForVehicleByMonth)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 col-12 mt-2">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<select class="form-select" onchange="updateReminderPie()" id="reminderOption">
|
||||||
|
<option value="0">As of Today</option>
|
||||||
|
<option value="30">+30 Days</option>
|
||||||
|
<option value="60">+60 Days</option>
|
||||||
|
<option value="90">+90 Days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="reminderMakeUpReportContent">
|
||||||
|
@await Html.PartialAsync("_ReminderMakeUpReport", Model.ReminderMakeUpForVehicle)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
initiateChart();
|
function getYear() {
|
||||||
function initiateChart() {
|
return $("#yearOption").val();
|
||||||
|
}
|
||||||
|
var debounce = null;
|
||||||
|
function updateCheck(sender) {
|
||||||
|
if (sender.id == "allExpenseCheck") {
|
||||||
|
$("#serviceExpenseCheck").prop('checked', false);
|
||||||
|
$("#repairExpenseCheck").prop('checked', false);
|
||||||
|
$("#upgradeExpenseCheck").prop('checked', false);
|
||||||
|
$("#gasExpenseCheck").prop('checked', false);
|
||||||
|
$("#taxExpenseCheck").prop('checked', false);
|
||||||
|
} else if ($("#allExpenseCheck").is(':checked')) {
|
||||||
|
$("#allExpenseCheck").prop('checked', false);
|
||||||
|
}
|
||||||
|
clearTimeout(debounce);
|
||||||
|
debounce = setTimeout(function () {
|
||||||
|
refreshBarChart();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
function refreshBarChart(callBack) {
|
||||||
|
var selectedMetrics = [];
|
||||||
var vehicleId = GetVehicleId().vehicleId;
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
$.get(`/Vehicle/GetCostMakeUpForVehicle?vehicleId=${vehicleId}`, function (data) {
|
var year = getYear();
|
||||||
$("#costMakeUpReportContent").html(data);
|
if ($("#allExpenseCheck").is(":checked")) {
|
||||||
$.get(`/Vehicle/GetFuelCostByMonthByVehicle?vehicleId=${vehicleId}`, function (data) {
|
selectedMetrics.push('All');
|
||||||
|
} else {
|
||||||
|
if ($("#serviceExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('ServiceRecord');
|
||||||
|
}
|
||||||
|
if ($("#repairExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('RepairRecord');
|
||||||
|
}
|
||||||
|
if ($("#upgradeExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('UpgradeRecord');
|
||||||
|
}
|
||||||
|
if ($("#gasExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('GasRecord');
|
||||||
|
}
|
||||||
|
if ($("#taxExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('TaxRecord');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.post('/Vehicle/GetCostByMonthByVehicle',
|
||||||
|
{
|
||||||
|
vehicleId: vehicleId,
|
||||||
|
selectedMetrics: selectedMetrics,
|
||||||
|
year: year
|
||||||
|
}, function (data) {
|
||||||
$("#gasCostByMonthReportContent").html(data);
|
$("#gasCostByMonthReportContent").html(data);
|
||||||
})
|
if (callBack != undefined){
|
||||||
|
callBack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function updateReminderPie() {
|
||||||
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
|
var daysToAdd = $("#reminderOption").val();
|
||||||
|
$.get(`/Vehicle/GetReminderMakeUpByVehicle?vehicleId=${vehicleId}`, { daysToAdd: daysToAdd }, function (data) {
|
||||||
|
$("#reminderMakeUpReportContent").html(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//called when year selected is changed.
|
||||||
|
function yearUpdated() {
|
||||||
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
|
var year = getYear();
|
||||||
|
$.get(`/Vehicle/GetCostMakeUpForVehicle?vehicleId=${vehicleId}`, {year: year}, function (data) {
|
||||||
|
$("#costMakeUpReportContent").html(data);
|
||||||
|
refreshBarChart();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -36,8 +36,30 @@ html {
|
|||||||
overflow-x:auto;
|
overflow-x:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.vehicleDetailTabContainer {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: #000 !important;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.chartContainer{
|
.chartContainer{
|
||||||
height:65vh;
|
height:30vh;
|
||||||
overflow:auto;
|
overflow:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +79,10 @@ html {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reportsCheckBoxContainer {
|
||||||
|
padding: 0.375rem 2.25rem 0.375rem 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
.bell-shake {
|
.bell-shake {
|
||||||
animation: bellshake .5s;
|
animation: bellshake .5s;
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
@@ -99,4 +125,5 @@ html {
|
|||||||
100% {
|
100% {
|
||||||
transform: rotate(0);
|
transform: rotate(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ $(document).ready(function () {
|
|||||||
getVehicleTaxRecords(vehicleId);
|
getVehicleTaxRecords(vehicleId);
|
||||||
break;
|
break;
|
||||||
case "report-tab":
|
case "report-tab":
|
||||||
getVehicleReport();
|
getVehicleReport(vehicleId);
|
||||||
break;
|
break;
|
||||||
case "reminder-tab":
|
case "reminder-tab":
|
||||||
getVehicleReminders(vehicleId);
|
getVehicleReminders(vehicleId);
|
||||||
@@ -115,8 +115,8 @@ function getVehicleReminders(vehicleId) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getVehicleReport() {
|
function getVehicleReport(vehicleId) {
|
||||||
$.get(`/Vehicle/GetReportPartialView`, function (data) {
|
$.get(`/Vehicle/GetReportPartialView?vehicleId=${vehicleId}`, function (data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
$("#report-tab-pane").html(data);
|
$("#report-tab-pane").html(data);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user