Added Distance Traveled Chart
This commit is contained in:
@@ -890,6 +890,7 @@ namespace CarCareTracker.Controllers
|
|||||||
var collisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
var collisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||||
|
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||||
var viewModel = new ReportViewModel();
|
var viewModel = new ReportViewModel();
|
||||||
//get totalCostMakeUp
|
//get totalCostMakeUp
|
||||||
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
|
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
|
||||||
@@ -907,10 +908,12 @@ namespace CarCareTracker.Controllers
|
|||||||
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
|
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
|
||||||
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, 0));
|
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, 0));
|
||||||
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, 0));
|
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, 0));
|
||||||
|
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, 0));
|
||||||
viewModel.CostForVehicleByMonth = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
viewModel.CostForVehicleByMonth = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
||||||
{
|
{
|
||||||
MonthName = x.Key.MonthName,
|
MonthName = x.Key.MonthName,
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
DistanceTraveled = x.Any(y=>y.MinMileage != default) ? x.Max(y=>y.MaxMileage) - x.Where(y=>y.MinMileage != default).Min(y=>y.MinMileage) : 0
|
||||||
}).ToList();
|
}).ToList();
|
||||||
//get reminders
|
//get reminders
|
||||||
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||||
@@ -1239,10 +1242,16 @@ namespace CarCareTracker.Controllers
|
|||||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||||
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year));
|
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year));
|
||||||
}
|
}
|
||||||
|
if (selectedMetrics.Contains(ImportMode.OdometerRecord))
|
||||||
|
{
|
||||||
|
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||||
|
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, year));
|
||||||
|
}
|
||||||
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
||||||
{
|
{
|
||||||
MonthName = x.Key.MonthName,
|
MonthName = x.Key.MonthName,
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
DistanceTraveled = x.Any(y => y.MinMileage != default) ? x.Max(y => y.MaxMileage) - x.Where(y => y.MinMileage != default).Min(y => y.MinMileage) : 0
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return PartialView("_GasCostByMonthReport", groupedRecord);
|
return PartialView("_GasCostByMonthReport", groupedRecord);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
public interface IReportHelper
|
public interface IReportHelper
|
||||||
{
|
{
|
||||||
|
IEnumerable<CostForVehicleByMonth> GetOdometerRecordSum(List<OdometerRecord> odometerRecords, int year = 0);
|
||||||
IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0);
|
IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0);
|
||||||
IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0);
|
IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0);
|
||||||
IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0);
|
IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0);
|
||||||
@@ -13,6 +14,21 @@ namespace CarCareTracker.Helper
|
|||||||
}
|
}
|
||||||
public class ReportHelper: IReportHelper
|
public class ReportHelper: IReportHelper
|
||||||
{
|
{
|
||||||
|
public IEnumerable<CostForVehicleByMonth> GetOdometerRecordSum(List<OdometerRecord> odometerRecords, int year = 0)
|
||||||
|
{
|
||||||
|
if (year != default)
|
||||||
|
{
|
||||||
|
odometerRecords.RemoveAll(x => x.Date.Year != year);
|
||||||
|
}
|
||||||
|
return odometerRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||||
|
{
|
||||||
|
MonthId = x.Key,
|
||||||
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
|
Cost = 0,
|
||||||
|
MaxMileage = x.Max(y => y.Mileage),
|
||||||
|
MinMileage = x.Min(y => y.Mileage)
|
||||||
|
});
|
||||||
|
}
|
||||||
public IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0)
|
public IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0)
|
||||||
{
|
{
|
||||||
if (year != default)
|
if (year != default)
|
||||||
@@ -23,7 +39,9 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
MonthId = x.Key,
|
MonthId = x.Key,
|
||||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
MaxMileage = x.Max(y=>y.Mileage),
|
||||||
|
MinMileage = x.Min(y=>y.Mileage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0)
|
public IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0)
|
||||||
@@ -36,7 +54,9 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
MonthId = x.Key,
|
MonthId = x.Key,
|
||||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
MaxMileage = x.Max(y => y.Mileage),
|
||||||
|
MinMileage = x.Min(y => y.Mileage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0)
|
public IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0)
|
||||||
@@ -49,7 +69,9 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
MonthId = x.Key,
|
MonthId = x.Key,
|
||||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
MaxMileage = x.Max(y => y.Mileage),
|
||||||
|
MinMileage = x.Min(y => y.Mileage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0)
|
public IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0)
|
||||||
@@ -62,7 +84,9 @@ namespace CarCareTracker.Helper
|
|||||||
{
|
{
|
||||||
MonthId = x.Key,
|
MonthId = x.Key,
|
||||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||||
Cost = x.Sum(y => y.Cost)
|
Cost = x.Sum(y => y.Cost),
|
||||||
|
MaxMileage = x.Max(y => y.Mileage),
|
||||||
|
MinMileage = x.Min(y => y.Mileage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0)
|
public IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0)
|
||||||
|
|||||||
@@ -5,5 +5,8 @@
|
|||||||
public int MonthId { get; set; }
|
public int MonthId { get; set; }
|
||||||
public string MonthName { get; set; }
|
public string MonthName { get; set; }
|
||||||
public decimal Cost { get; set; }
|
public decimal Cost { get; set; }
|
||||||
|
public int MaxMileage { get; set; }
|
||||||
|
public int MinMileage { get; set; }
|
||||||
|
public int DistanceTraveled { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,7 +201,7 @@
|
|||||||
<img src="/defaults/lubelogger_logo.png" />
|
<img src="/defaults/lubelogger_logo.png" />
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<small class="text-body-secondary">Version 1.1.9</small>
|
<small class="text-body-secondary">Version 1.2.0</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Proudly developed in the rural town of Price, Utah by Hargata Softworks.
|
Proudly developed in the rural town of Price, Utah by Hargata Softworks.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
var barGraphColors = new string[] { "#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f" };
|
var barGraphColors = new string[] { "#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f" };
|
||||||
var sortedByMPG = Model.OrderBy(x => x.Cost).ToList();
|
var sortedByMPG = Model.OrderBy(x => x.Cost).ToList();
|
||||||
}
|
}
|
||||||
@if (Model.Where(x=>x.Cost > 0).Any())
|
@if (Model.Where(x=>x.Cost > 0).Any() || Model.Where(x=>x.DistanceTraveled > 0).Any())
|
||||||
{
|
{
|
||||||
<canvas id="bar-chart"></canvas>
|
<canvas id="bar-chart"></canvas>
|
||||||
<script>
|
<script>
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
function renderChart() {
|
function renderChart() {
|
||||||
var barGraphLabels = [];
|
var barGraphLabels = [];
|
||||||
var barGraphData = [];
|
var barGraphData = [];
|
||||||
|
var lineChartData = [];
|
||||||
//color gradient from high to low
|
//color gradient from high to low
|
||||||
var barGraphColors = [];
|
var barGraphColors = [];
|
||||||
var useDarkMode = getGlobalConfig().useDarkMode;
|
var useDarkMode = getGlobalConfig().useDarkMode;
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
{
|
{
|
||||||
@:barGraphLabels.push(decodeHTMLEntities("@gasCost.MonthName"));
|
@:barGraphLabels.push(decodeHTMLEntities("@gasCost.MonthName"));
|
||||||
@:barGraphData.push(globalParseFloat('@gasCost.Cost'));
|
@:barGraphData.push(globalParseFloat('@gasCost.Cost'));
|
||||||
|
@:lineChartData.push(globalParseFloat('@gasCost.DistanceTraveled'));
|
||||||
var index = sortedByMPG.FindIndex(x => x.MonthName == gasCost.MonthName);
|
var index = sortedByMPG.FindIndex(x => x.MonthName == gasCost.MonthName);
|
||||||
@:barGraphColors.push('@barGraphColors[index]');
|
@:barGraphColors.push('@barGraphColors[index]');
|
||||||
}
|
}
|
||||||
@@ -34,7 +36,18 @@
|
|||||||
{
|
{
|
||||||
label: decodeHTMLEntities('@translator.Translate(userLanguage, "Expenses by Month")'),
|
label: decodeHTMLEntities('@translator.Translate(userLanguage, "Expenses by Month")'),
|
||||||
backgroundColor: barGraphColors,
|
backgroundColor: barGraphColors,
|
||||||
data: barGraphData
|
data: barGraphData,
|
||||||
|
order: 1,
|
||||||
|
yAxisID: 'y',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: decodeHTMLEntities('@translator.Translate(userLanguage, "Distance Traveled by Month")'),
|
||||||
|
data: lineChartData,
|
||||||
|
borderColor: useDarkMode ? "#fff" : "#000",
|
||||||
|
backgroundColor: useDarkMode ? "#000" : "#fff",
|
||||||
|
type: 'line',
|
||||||
|
order: 0,
|
||||||
|
yAxisID: 'y1',
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -43,7 +56,7 @@
|
|||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
color: useDarkMode ? "#fff" : "#000",
|
color: useDarkMode ? "#fff" : "#000",
|
||||||
text: decodeHTMLEntities('@translator.Translate(userLanguage, "Expenses by Month")')
|
text: decodeHTMLEntities('@translator.Translate(userLanguage, "Expenses and Distance Traveled by Month")')
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
display: false,
|
display: false,
|
||||||
@@ -59,6 +72,13 @@
|
|||||||
color: useDarkMode ? "#fff" : "#000"
|
color: useDarkMode ? "#fff" : "#000"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
y1: {
|
||||||
|
beginAtZero: true,
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
color: useDarkMode ? "#fff" : "#000"
|
||||||
|
}
|
||||||
|
},
|
||||||
x: {
|
x: {
|
||||||
ticks: {
|
ticks: {
|
||||||
color: useDarkMode ? "#fff" : "#000"
|
color: useDarkMode ? "#fff" : "#000"
|
||||||
|
|||||||
@@ -29,26 +29,49 @@
|
|||||||
<div class="col-md-6 col-12 mt-2">
|
<div class="col-md-6 col-12 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-1 d-sm-none d-md-block"></div>
|
<div class="col-md-1 d-sm-none d-md-block"></div>
|
||||||
<div class="col-12 col-md-10 reportsCheckBoxContainer">
|
<div class="col-12 col-md-10">
|
||||||
<div class="form-check form-check-inline">
|
<div class="dropdown d-grid">
|
||||||
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="serviceExpenseCheck" value="1" checked>
|
<button class="btn btn-outline-warning dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<label class="form-check-label" for="serviceExpenseCheck">@translator.Translate(userLanguage,"Service")</label>
|
Metrics
|
||||||
</div>
|
</button>
|
||||||
<div class="form-check form-check-inline">
|
<ul class="dropdown-menu">
|
||||||
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="repairExpenseCheck" value="2" checked>
|
<li>
|
||||||
<label class="form-check-label" for="repairExpenseCheck">@translator.Translate(userLanguage, "Repairs")</label>
|
<div class="dropdown-item">
|
||||||
</div>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="odometerExpenseCheck" value="6" checked>
|
||||||
<div class="form-check form-check-inline">
|
<label class="form-check-label" for="odometerExpenseCheck">@translator.Translate(userLanguage, "Odometer")</label>
|
||||||
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
|
</div>
|
||||||
<label class="form-check-label" for="upgradeExpenseCheck">@translator.Translate(userLanguage, "Upgrades")</label>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
<div class="form-check form-check-inline">
|
<div class="dropdown-item">
|
||||||
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="gasExpenseCheck" value="4" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="serviceExpenseCheck" value="1" checked>
|
||||||
<label class="form-check-label" for="gasExpenseCheck">@translator.Translate(userLanguage, "Fuel")</label>
|
<label class="form-check-label" for="serviceExpenseCheck">@translator.Translate(userLanguage, "Service")</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
</li>
|
||||||
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="taxExpenseCheck" value="5" checked>
|
<li>
|
||||||
<label class="form-check-label" for="taxExpenseCheck">@translator.Translate(userLanguage, "Taxes")</label>
|
<div class="dropdown-item">
|
||||||
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="repairExpenseCheck" value="2" checked>
|
||||||
|
<label class="form-check-label" for="repairExpenseCheck">@translator.Translate(userLanguage, "Repairs")</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="dropdown-item">
|
||||||
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
|
||||||
|
<label class="form-check-label" for="upgradeExpenseCheck">@translator.Translate(userLanguage, "Upgrades")</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="dropdown-item">
|
||||||
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="gasExpenseCheck" value="4" checked>
|
||||||
|
<label class="form-check-label" for="gasExpenseCheck">@translator.Translate(userLanguage, "Fuel")</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="dropdown-item">
|
||||||
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="taxExpenseCheck" value="5" checked>
|
||||||
|
<label class="form-check-label" for="taxExpenseCheck">@translator.Translate(userLanguage, "Taxes")</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-1 d-sm-none d-md-block"></div>
|
<div class="col-md-1 d-sm-none d-md-block"></div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -42,6 +42,9 @@ function refreshBarChart() {
|
|||||||
if ($("#taxExpenseCheck").is(":checked")) {
|
if ($("#taxExpenseCheck").is(":checked")) {
|
||||||
selectedMetrics.push('TaxRecord');
|
selectedMetrics.push('TaxRecord');
|
||||||
}
|
}
|
||||||
|
if ($("#odometerExpenseCheck").is(":checked")) {
|
||||||
|
selectedMetrics.push('OdometerRecord');
|
||||||
|
}
|
||||||
|
|
||||||
$.post('/Vehicle/GetCostByMonthByVehicle',
|
$.post('/Vehicle/GetCostByMonthByVehicle',
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user