enable csv imports for all pages.

This commit is contained in:
ivancheahhh
2024-01-04 16:34:02 -07:00
parent a72637db0f
commit 83470a9a6c
12 changed files with 261 additions and 106 deletions

View File

@@ -138,22 +138,78 @@ namespace CarCareTracker.Controllers
config.HeaderValidated = null;
using (var csv = new CsvReader(reader, config))
{
if (mode == "gas")
if (mode == "gasrecord")
{
var records = csv.GetRecords<GasRecordImport>().ToList();
if (records.Any())
{
foreach (GasRecordImport gasRecordToInsert in records)
foreach (GasRecordImport recordToInsert in records)
{
var convertedGasRecord = new GasRecord()
var convertedRecord = new GasRecord()
{
VehicleId = vehicleId,
Date = gasRecordToInsert.Date,
Mileage = gasRecordToInsert.Odometer,
Gallons = gasRecordToInsert.FuelConsumed,
Cost = gasRecordToInsert.Cost
Date = recordToInsert.Date,
Mileage = recordToInsert.Odometer,
Gallons = recordToInsert.FuelConsumed,
Cost = recordToInsert.Cost
};
_gasRecordDataAccess.SaveGasRecordToVehicle(convertedGasRecord);
_gasRecordDataAccess.SaveGasRecordToVehicle(convertedRecord);
}
}
} else if (mode == "servicerecord")
{
var records = csv.GetRecords<ServiceRecordImport>().ToList();
if (records.Any())
{
foreach (ServiceRecordImport recordToInsert in records)
{
var convertedRecord = new ServiceRecord()
{
VehicleId = vehicleId,
Date = recordToInsert.Date,
Mileage = recordToInsert.Odometer,
Description = recordToInsert.Description,
Notes = recordToInsert.Notes,
Cost = recordToInsert.Cost
};
_serviceRecordDataAccess.SaveServiceRecordToVehicle(convertedRecord);
}
}
} else if (mode == "repairrecord")
{
var records = csv.GetRecords<ServiceRecordImport>().ToList();
if (records.Any())
{
foreach (ServiceRecordImport recordToInsert in records)
{
var convertedRecord = new CollisionRecord()
{
VehicleId = vehicleId,
Date = recordToInsert.Date,
Mileage = recordToInsert.Odometer,
Description = recordToInsert.Description,
Notes = recordToInsert.Notes,
Cost = recordToInsert.Cost
};
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(convertedRecord);
}
}
} else if (mode == "taxrecord")
{
var records = csv.GetRecords<TaxRecordImport>().ToList();
if (records.Any())
{
foreach (TaxRecordImport recordToInsert in records)
{
var convertedRecord = new TaxRecord()
{
VehicleId = vehicleId,
Date = recordToInsert.Date,
Description = recordToInsert.Description,
Notes = recordToInsert.Notes,
Cost = recordToInsert.Cost
};
_taxRecordDataAccess.SaveTaxRecordToVehicle(convertedRecord);
}
}
}

View File

@@ -1,10 +0,0 @@
namespace CarCareTracker.Models
{
public class GasRecordImport
{
public DateTime Date { get; set; }
public int Odometer { get; set; }
public decimal FuelConsumed { get; set; }
public decimal Cost { get; set; }
}
}

34
Models/ImportModels.cs Normal file
View File

@@ -0,0 +1,34 @@
namespace CarCareTracker.Models
{
/// <summary>
/// Import model used for importing Gas records.
/// </summary>
public class GasRecordImport
{
public DateTime Date { get; set; }
public int Odometer { get; set; }
public decimal FuelConsumed { get; set; }
public decimal Cost { get; set; }
}
/// <summary>
/// Import model used for importing Service and Repair records.
/// </summary>
public class ServiceRecordImport
{
public DateTime Date { get; set; }
public int Odometer { get; set; }
public string Description { get; set; }
public string Notes { get; set; }
public decimal Cost { get; set; }
}
/// <summary>
/// Import model used for importing tax records.
/// </summary>
public class TaxRecordImport
{
public DateTime Date { get; set; }
public string Description { get; set; }
public string Notes { get; set; }
public decimal Cost { get; set; }
}
}

View File

@@ -46,8 +46,14 @@
if (data) {
successToast("Data Imported Successfully");
hideBulkImportModal();
if (mode == "gas") {
if (mode == "gasrecord") {
getVehicleGasRecords(vehicleId);
} else if (mode == "servicerecord") {
getVehicleServiceRecords(vehicleId);
} else if (mode == "repairrecord") {
getVehicleCollisionRecords(vehicleId);
} else if (mode == "taxrecord") {
getVehicleTaxRecords(vehicleId);
}
} else {
errorToast("An error has occurred, please double check the data and try again.");

View File

@@ -14,7 +14,7 @@
<input type="text" id="collisionRecordDate" class="form-control" value="@Model.Date">
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
</div>
<label for="collisionRecordMileage">Mileage</label>
<label for="collisionRecordMileage">Odometer</label>
<input type="number" id="collisionRecordMileage" class="form-control" value="@Model.Mileage">
<label for="collisionRecordDescription">Description</label>
<input type="text" id="collisionRecordDescription" class="form-control" value="@Model.Description">

View File

@@ -1,4 +1,8 @@
@model List<CollisionRecord>
@inject IConfiguration Configuration
@{
var enableCsvImports = bool.Parse(Configuration[nameof(UserConfig.EnableCsvImports)]);
}
@model List<CollisionRecord>
<div class="row">
<div class="d-flex justify-content-between">
<div class="d-flex align-items-center flex-wrap">
@@ -6,7 +10,22 @@
<span class="ms-2 badge bg-primary">@($"Total: {Model.Sum(x => x.Cost).ToString("C")}")</span>
</div>
<div>
<button onclick="showAddCollisionRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Repair Record</button>
@if (enableCsvImports)
{
<div class="btn-group">
<button onclick="showAddCollisionRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Repair Record</button>
<button type="button" class="btn btn-md btn-primary btn-md mt-1 mb-1 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="showBulkImportModal('repairrecord')">Import via CSV</a></li>
</ul>
</div>
}
else
{
<button onclick="showAddCollisionRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Repair Record</button>
}
</div>
</div>
</div>
@@ -16,7 +35,7 @@
<thead>
<tr class="d-flex">
<th scope="col" class="col-1">Date</th>
<th scope="col" class="col-2">Mileage</th>
<th scope="col" class="col-2">Odometer</th>
<th scope="col" class="col-4">Description</th>
<th scope="col" class="col-2">Cost</th>
<th scope="col" class="col-3">Notes</th>

View File

@@ -1,41 +1,47 @@
@model CostMakeUpForVehicle
<canvas id="pie-chart"></canvas>
<script>
renderChart();
function renderChart() {
var useDarkMode = getGlobalConfig().useDarkMode;
new Chart($("#pie-chart"), {
type: 'pie',
data: {
labels: ["Planned Maintenance(Service Records)", "Unplanned Maintenance(Repairs)", "Tax", "Fuel"],
datasets: [
{
label: "Expenses by Category",
backgroundColor: ["#003f5c", "#58508d", "#bc5090", "#ff6361"],
data: [
@Model.ServiceRecordSum,
@Model.CollisionRecordSum,
@Model.TaxRecordSum,
@Model.GasRecordSum
]
}
]
},
options: {
plugins: {
legend: {
position: "bottom",
labels: {
color: useDarkMode ? "#fff" : "#000"
@if (Model.CollisionRecordSum + Model.ServiceRecordSum + Model.GasRecordSum + Model.TaxRecordSum > 0)
{
<canvas id="pie-chart"></canvas>
<script>
renderChart();
function renderChart() {
var useDarkMode = getGlobalConfig().useDarkMode;
new Chart($("#pie-chart"), {
type: 'pie',
data: {
labels: ["Planned Maintenance(Service Records)", "Unplanned Maintenance(Repairs)", "Tax", "Fuel"],
datasets: [
{
label: "Expenses by Category",
backgroundColor: ["#003f5c", "#58508d", "#bc5090", "#ff6361"],
data: [
@Model.ServiceRecordSum,
@Model.CollisionRecordSum,
@Model.TaxRecordSum,
@Model.GasRecordSum
]
}
},
title: {
display: true,
text: "Expenses by Type",
color: useDarkMode ? "#fff" : "#000"
},
]
},
options: {
plugins: {
legend: {
position: "bottom",
labels: {
color: useDarkMode ? "#fff" : "#000"
}
},
title: {
display: true,
text: "Expenses by Type",
color: useDarkMode ? "#fff" : "#000"
},
}
}
}
});
}
</script>
});
}
</script>
} else
{
<h1>No data found or all records have zero sums, insert records with non-zero sums to see visualizations here.</h1>
}

View File

@@ -14,7 +14,7 @@
<span class="ms-2 badge bg-primary">@($"Min Fuel Economy: {Model.Where(y => y.MilesPerGallon > 0)?.Min(x => x.MilesPerGallon).ToString("F") ?? "0"}")</span>
<span class="ms-2 badge bg-primary">@($"Max Fuel Economy: {Model.Max(x => x.MilesPerGallon).ToString("F") ?? "0"}")</span>
}
<span class="ms-2 badge bg-success">@($"Total Fuel Consumed: {Model.Sum(x=>x.Gallons)}")</span>
<span class="ms-2 badge bg-success">@($"Total Fuel Consumed: {Model.Sum(x=>x.Gallons).ToString("F")}")</span>
<span class="ms-2 badge bg-success">@($"Total Cost: {Model.Sum(x => x.Cost).ToString("C")}")</span>
</div>
@if (enableCsvImports)
@@ -25,7 +25,7 @@
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="showBulkImportModal('gas')">Import via CSV</a></li>
<li><a class="dropdown-item" href="#" onclick="showBulkImportModal('gasrecord')">Import via CSV</a></li>
</ul>
</div>
} else {

View File

@@ -1,50 +1,56 @@
@model List<GasCostForVehicleByMonth>
<canvas id="bar-chart" class="vehicleDetailTabContainer"></canvas>
<script>
renderChart();
function renderChart() {
var barGraphLabels = [];
var barGraphData = [];
var useDarkMode = getGlobalConfig().useDarkMode;
@if (Model.Any())
{
<canvas id="bar-chart" class="vehicleDetailTabContainer"></canvas>
<script>
renderChart();
function renderChart() {
var barGraphLabels = [];
var barGraphData = [];
var useDarkMode = getGlobalConfig().useDarkMode;
@foreach (GasCostForVehicleByMonth gasCost in Model)
{
@:barGraphLabels.push("@gasCost.MonthName");
@:barGraphData.push(@gasCost.Cost);
}
new Chart($("#bar-chart"), {
type: 'bar',
data: {
labels: barGraphLabels,
datasets: [
{
label: "Gas Expenses by Month",
backgroundColor: ["#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f"],
data: barGraphData
}
]
},
options: {
plugins: {
legend: {
labels: {
color: useDarkMode ? "#fff" : "#000"
new Chart($("#bar-chart"), {
type: 'bar',
data: {
labels: barGraphLabels,
datasets: [
{
label: "Gas Expenses by Month",
backgroundColor: ["#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f"],
data: barGraphData
}
}
]
},
scales: {
y: {
beginAtZero: true,
ticks: {
color: useDarkMode ? "#fff" : "#000"
options: {
plugins: {
legend: {
labels: {
color: useDarkMode ? "#fff" : "#000"
}
}
},
x: {
ticks: {
color: useDarkMode ? "#fff" : "#000"
scales: {
y: {
beginAtZero: true,
ticks: {
color: useDarkMode ? "#fff" : "#000"
}
},
x: {
ticks: {
color: useDarkMode ? "#fff" : "#000"
}
}
}
}
}
});
}
</script>
});
}
</script>
} else
{
<h1>No data found, insert some gas data to see visualizations here.</h1>
}

View File

@@ -14,7 +14,7 @@
<input type="text" id="serviceRecordDate" class="form-control" value="@Model.Date">
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
</div>
<label for="serviceRecordMileage">Mileage</label>
<label for="serviceRecordMileage">Odometer</label>
<input type="number" id="serviceRecordMileage" class="form-control" value="@Model.Mileage">
<label for="serviceRecordDescription">Description</label>
<input type="text" id="serviceRecordDescription" class="form-control" value="@Model.Description">

View File

@@ -1,4 +1,8 @@
@model List<ServiceRecord>
@inject IConfiguration Configuration
@{
var enableCsvImports = bool.Parse(Configuration[nameof(UserConfig.EnableCsvImports)]);
}
@model List<ServiceRecord>
<div class="row">
<div class="d-flex justify-content-between">
<div class="d-flex align-items-center flex-wrap">
@@ -6,7 +10,22 @@
<span class="ms-2 badge bg-primary">@($"Total: {Model.Sum(x => x.Cost).ToString("C")}")</span>
</div>
<div>
<button onclick="showAddServiceRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Service Record</button>
@if (enableCsvImports)
{
<div class="btn-group">
<button onclick="showAddServiceRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Service Record</button>
<button type="button" class="btn btn-md btn-primary btn-md mt-1 mb-1 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="showBulkImportModal('servicerecord')">Import via CSV</a></li>
</ul>
</div>
}
else
{
<button onclick="showAddServiceRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Service Record</button>
}
</div>
</div>
</div>
@@ -16,7 +35,7 @@
<thead>
<tr class="d-flex">
<th scope="col" class="col-1">Date</th>
<th scope="col" class="col-2">Mileage</th>
<th scope="col" class="col-2">Odometer</th>
<th scope="col" class="col-4">Description</th>
<th scope="col" class="col-2">Cost</th>
<th scope="col" class="col-3">Notes</th>

View File

@@ -1,4 +1,8 @@
@model List<TaxRecord>
@inject IConfiguration Configuration
@{
var enableCsvImports = bool.Parse(Configuration[nameof(UserConfig.EnableCsvImports)]);
}
@model List<TaxRecord>
<div class="row">
<div class="d-flex justify-content-between">
<div class="d-flex align-items-center flex-wrap">
@@ -6,7 +10,22 @@
<span class="ms-2 badge bg-primary">@($"Total: {Model.Sum(x => x.Cost).ToString("C")}")</span>
</div>
<div>
<button onclick="showAddTaxRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Tax Record</button>
@if (enableCsvImports)
{
<div class="btn-group">
<button onclick="showAddTaxRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Tax Record</button>
<button type="button" class="btn btn-md btn-primary btn-md mt-1 mb-1 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="showBulkImportModal('taxrecord')">Import via CSV</a></li>
</ul>
</div>
}
else
{
<button onclick="showAddTaxRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>Add Tax Record</button>
}
</div>
</div>
</div>