Skip to content

Commit

Permalink
Merge pull request #599 from hargata/Hargata/551
Browse files Browse the repository at this point in the history
Added data table
  • Loading branch information
hargata authored Aug 31, 2024
2 parents 00bad98 + a4b3982 commit e6eb2b4
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 2 deletions.
40 changes: 39 additions & 1 deletion Controllers/VehicleController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,7 @@ public IActionResult GetReportPartialView(int vehicleId)
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
var userConfig = _config.GetUserConfig(User);
var viewModel = new ReportViewModel();
//get totalCostMakeUp
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
Expand Down Expand Up @@ -1205,7 +1206,6 @@ public IActionResult GetReportPartialView(int vehicleId)
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
viewModel.Collaborators = collaborators;
//get MPG per month.
var userConfig = _config.GetUserConfig(User);
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
mileageData.RemoveAll(x => x.MilesPerGallon == default);
var monthlyMileageData = StaticHelper.GetBaseLineCostsNoMonthName();
Expand Down Expand Up @@ -1272,6 +1272,44 @@ public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0)
return PartialView("_CostMakeUpReport", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
[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);
if (year != default)
{
serviceRecords.RemoveAll(x => x.Date.Year != year);
gasRecords.RemoveAll(x => x.Date.Year != year);
collisionRecords.RemoveAll(x => x.Date.Year != year);
taxRecords.RemoveAll(x => x.Date.Year != year);
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 vehicleData = _dataAccess.GetVehicleById(vehicleId);
var userConfig = _config.GetUserConfig(User);
var totalDistanceTraveled = maxMileage - minMileage;
var totalDays = _vehicleLogic.GetOwnershipDays(vehicleData.PurchaseDate, vehicleData.SoldDate, serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords, taxRecords);
var viewModel = new CostTableForVehicle
{
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),
TotalDistance = totalDistanceTraveled,
DistanceUnit = vehicleData.UseHours ? "Cost Per Hour" : userConfig.UseMPG ? "Cost Per Mile" : "Cost Per Kilometer",
NumberOfDays = totalDays
};
return PartialView("_CostTableReport", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd)
{
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now.AddDays(daysToAdd));
Expand Down
90 changes: 90 additions & 0 deletions Logic/VehicleLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ namespace CarCareTracker.Logic
public interface IVehicleLogic
{
int GetMaxMileage(int vehicleId);
int GetMaxMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords);
int GetMinMileage(int vehicleId);
int GetMinMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords);
int GetOwnershipDays(string purchaseDate, string soldDate, List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords, List<TaxRecord> taxRecords);
bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId);
}
public class VehicleLogic: IVehicleLogic
Expand Down Expand Up @@ -66,6 +69,31 @@ public int GetMaxMileage(int vehicleId)
}
return numbersArray.Any() ? numbersArray.Max() : 0;
}
public int GetMaxMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords)
{
var numbersArray = new List<int>();
if (serviceRecords.Any())
{
numbersArray.Add(serviceRecords.Max(x => x.Mileage));
}
if (repairRecords.Any())
{
numbersArray.Add(repairRecords.Max(x => x.Mileage));
}
if (gasRecords.Any())
{
numbersArray.Add(gasRecords.Max(x => x.Mileage));
}
if (upgradeRecords.Any())
{
numbersArray.Add(upgradeRecords.Max(x => x.Mileage));
}
if (odometerRecords.Any())
{
numbersArray.Add(odometerRecords.Max(x => x.Mileage));
}
return numbersArray.Any() ? numbersArray.Max() : 0;
}
public int GetMinMileage(int vehicleId)
{
var numbersArray = new List<int>();
Expand Down Expand Up @@ -96,6 +124,68 @@ public int GetMinMileage(int vehicleId)
}
return numbersArray.Any() ? numbersArray.Min() : 0;
}
public int GetMinMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords)
{
var numbersArray = new List<int>();
var _serviceRecords = 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();
if (_repairRecords.Any())
{
numbersArray.Add(_repairRecords.Min(x => x.Mileage));
}
var _gasRecords = 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();
if (_upgradeRecords.Any())
{
numbersArray.Add(_upgradeRecords.Min(x => x.Mileage));
}
var _odometerRecords = odometerRecords.Where(x => x.Mileage != default).ToList();
if (_odometerRecords.Any())
{
numbersArray.Add(_odometerRecords.Min(x => x.Mileage));
}
return numbersArray.Any() ? numbersArray.Min() : 0;
}
public int GetOwnershipDays(string purchaseDate, string soldDate, List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords, List<TaxRecord> taxRecords)
{
var startDate = DateTime.Now;
var endDate = DateTime.Now;
if (!string.IsNullOrWhiteSpace(soldDate))
{
endDate = DateTime.Parse(soldDate);
}
if (!string.IsNullOrWhiteSpace(purchaseDate))
{
//if purchase date is provided, then we just have to subtract the begin date to end date and return number of months
startDate = DateTime.Parse(purchaseDate);
var timeElapsed = (int)Math.Floor((endDate - startDate).TotalDays);
return timeElapsed;
}
var dateArray = new List<DateTime>();
dateArray.AddRange(serviceRecords.Select(x => x.Date));
dateArray.AddRange(repairRecords.Select(x => x.Date));
dateArray.AddRange(gasRecords.Select(x => x.Date));
dateArray.AddRange(upgradeRecords.Select(x => x.Date));
dateArray.AddRange(odometerRecords.Select(x => x.Date));
dateArray.AddRange(taxRecords.Select(x => x.Date));
if (dateArray.Any())
{
startDate = dateArray.Min();
var timeElapsed = (int)Math.Floor((endDate - startDate).TotalDays);
return timeElapsed;
} else
{
return 1;
}
}
public bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId)
{
var currentMileage = GetMaxMileage(vehicleId);
Expand Down
26 changes: 26 additions & 0 deletions Models/Report/CostTableForVehicle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace CarCareTracker.Models
{
public class CostTableForVehicle
{
public string DistanceUnit { get; set; } = "Per Mile";
public int TotalDistance { get; set; }
public int NumberOfDays { get; set; }
public decimal ServiceRecordSum { get; set; }
public decimal GasRecordSum { get; set; }
public decimal TaxRecordSum { get; set; }
public decimal CollisionRecordSum { get; set; }
public decimal UpgradeRecordSum { get; set; }
public decimal ServiceRecordPerMile { get { return TotalDistance != default ? ServiceRecordSum / TotalDistance : 0; } }
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 TotalCost { get { return ServiceRecordSum + CollisionRecordSum + UpgradeRecordSum + GasRecordSum + TaxRecordSum; } }
}
}
3 changes: 3 additions & 0 deletions Views/Vehicle/_CostMakeUpReport.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
]
},
options: {
onClick: (e) => {
showDataTable();
},
plugins: {
legend: {
position: "bottom",
Expand Down
78 changes: 78 additions & 0 deletions Views/Vehicle/_CostTableReport.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
var hideZero = userConfig.HideZero;
}
@model CostTableForVehicle
@if (Model.CollisionRecordSum + Model.ServiceRecordSum + Model.GasRecordSum + Model.TaxRecordSum + Model.UpgradeRecordSum > 0)
{
<div>
<div class="modal-header">
<h5 class="modal-title">@(translator.Translate(userLanguage, "Vehicle Cost Breakdown"))</h5>
<button type="button" class="btn-close" onclick="hideDataTable()" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-12">
<table class="table table-hover">
<thead class="sticky-top">
<tr class="d-flex">
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Type")</th>
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Cost Per Day")</th>
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, Model.DistanceUnit)</th>
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</th>
</tr>
</thead>
<tbody>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Service Records")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.ServiceRecordPerMonth == default ? "---" : Model.ServiceRecordPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.ServiceRecordPerMile == default ? "---" :Model.ServiceRecordPerMile.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.ServiceRecordSum == default ? "---" :Model.ServiceRecordSum.ToString("C2"))</td>
</tr>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Repairs")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.CollisionRecordPerMonth == default ? "---" :Model.CollisionRecordPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.CollisionRecordPerMile == default ? "---" :Model.CollisionRecordPerMile.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.CollisionRecordSum == default ? "---" :Model.CollisionRecordSum.ToString("C2"))</td>
</tr>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Upgrades")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.UpgradeRecordPerMonth == default ? "---" :Model.UpgradeRecordPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.UpgradeRecordPerMile == default ? "---" :Model.UpgradeRecordPerMile.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.UpgradeRecordSum == default ? "---" :Model.UpgradeRecordSum.ToString("C2"))</td>
</tr>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Fuel")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.GasRecordPerMonth == default ? "---" :Model.GasRecordPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.GasRecordPerMile == default ? "---" :Model.GasRecordPerMile.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.GasRecordSum == default ? "---" :Model.GasRecordSum.ToString("C2"))</td>
</tr>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Taxes")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.TaxRecordPerMonth == default ? "---" :Model.TaxRecordPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">---</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.TaxRecordSum == default ? "---" :Model.TaxRecordSum.ToString("C2"))</td>
</tr>
<tr class="d-flex">
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.TotalPerMonth == default ? "---" : Model.TotalPerMonth.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.TotalPerMile == default ? "---" : Model.TotalPerMile.ToString("C2"))</td>
<td class="col-3 flex-grow-1">@(hideZero && Model.TotalCost == default ? "---" : Model.TotalCost.ToString("C2"))</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
}
else
{
<div class="text-center">
<h4>@translator.Translate(userLanguage, "No data found or all records have zero sums, insert records with non-zero sums to see visualizations here.")</h4>
</div>
}
7 changes: 7 additions & 0 deletions Views/Vehicle/_Report.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@
</div>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="vehicleDataTableModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="vehicleDataTableModalContent">

</div>
</div>
</div>
<div id="vehicleHistoryReport" class="showOnPrint"></div>

<script>
Expand Down
Loading

0 comments on commit e6eb2b4

Please sign in to comment.