diff --git a/Controllers/VehicleController.cs b/Controllers/VehicleController.cs index 952e2d0..c62504e 100644 --- a/Controllers/VehicleController.cs +++ b/Controllers/VehicleController.cs @@ -7,6 +7,7 @@ using CsvHelper; using System.Globalization; using Microsoft.AspNetCore.Authorization; using CarCareTracker.External.Implementations; +using CarCareTracker.MapProfile; namespace CarCareTracker.Controllers { @@ -122,12 +123,12 @@ namespace CarCareTracker.Controllers } #region "Bulk Imports" [HttpGet] - public IActionResult GetBulkImportModalPartialView(string mode) + public IActionResult GetBulkImportModalPartialView(ImportMode mode) { return PartialView("_BulkDataImporter", mode); } [HttpPost] - public IActionResult ImportToVehicleIdFromCsv(int vehicleId, string mode, string fileName) + public IActionResult ImportToVehicleIdFromCsv(int vehicleId, ImportMode mode, string fileName) { if (vehicleId == default || string.IsNullOrWhiteSpace(fileName)) { @@ -145,81 +146,85 @@ namespace CarCareTracker.Controllers var config = new CsvHelper.Configuration.CsvConfiguration(System.Globalization.CultureInfo.InvariantCulture); config.MissingFieldFound = null; config.HeaderValidated = null; + config.PrepareHeaderForMatch = args => { return args.Header.Trim().ToLower(); }; using (var csv = new CsvReader(reader, config)) { - if (mode == "gasrecord") + csv.Context.RegisterClassMap(); + var records = csv.GetRecords().ToList(); + if (records.Any()) { - var records = csv.GetRecords().ToList(); - if (records.Any()) + foreach (ImportModel importModel in records) { - foreach (GasRecordImport recordToInsert in records) + if (mode == ImportMode.GasRecord) { + //convert to gas model. var convertedRecord = new GasRecord() { VehicleId = vehicleId, - Date = recordToInsert.Date, - Mileage = recordToInsert.Odometer, - Gallons = recordToInsert.FuelConsumed, - Cost = recordToInsert.Cost + Date = DateTime.Parse(importModel.Date), + Mileage = int.Parse(importModel.Odometer, NumberStyles.Any), + Gallons = decimal.Parse(importModel.FuelConsumed, NumberStyles.Any) }; - _gasRecordDataAccess.SaveGasRecordToVehicle(convertedRecord); + if (string.IsNullOrWhiteSpace(importModel.Cost) && !string.IsNullOrWhiteSpace(importModel.Price)) + { + //cost was not given but price is. + //fuelly sometimes exports CSVs without total cost. + var parsedPrice = decimal.Parse(importModel.Price, NumberStyles.Any); + convertedRecord.Cost = convertedRecord.Gallons * parsedPrice; + } else + { + convertedRecord.Cost = decimal.Parse(importModel.Cost, NumberStyles.Any); + } + if (string.IsNullOrWhiteSpace(importModel.IsFillToFull) && !string.IsNullOrWhiteSpace(importModel.PartialFuelUp)) + { + var parsedBool = importModel.PartialFuelUp.Trim() == "1"; + convertedRecord.IsFillToFull = !parsedBool; + } else if (!string.IsNullOrWhiteSpace(importModel.IsFillToFull)) + { + var parsedBool = importModel.IsFillToFull.Trim() == "1" || importModel.IsFillToFull.Trim() == "Full"; + convertedRecord.IsFillToFull = parsedBool; + } + //insert record into db, check to make sure fuelconsumed is not zero so we don't get a divide by zero error. + if (convertedRecord.Gallons > 0) + { + _gasRecordDataAccess.SaveGasRecordToVehicle(convertedRecord); + } } - } - } - else if (mode == "servicerecord") - { - var records = csv.GetRecords().ToList(); - if (records.Any()) - { - foreach (ServiceRecordImport recordToInsert in records) + else if (mode == ImportMode.ServiceRecord) { var convertedRecord = new ServiceRecord() { VehicleId = vehicleId, - Date = recordToInsert.Date, - Mileage = recordToInsert.Odometer, - Description = recordToInsert.Description, - Notes = recordToInsert.Notes, - Cost = recordToInsert.Cost + Date = DateTime.Parse(importModel.Date), + Mileage = int.Parse(importModel.Odometer, NumberStyles.Any), + Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Service Record on {importModel.Date}" : importModel.Description, + Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes, + Cost = decimal.Parse(importModel.Cost, NumberStyles.Any) }; _serviceRecordDataAccess.SaveServiceRecordToVehicle(convertedRecord); } - } - } - else if (mode == "repairrecord") - { - var records = csv.GetRecords().ToList(); - if (records.Any()) - { - foreach (ServiceRecordImport recordToInsert in records) + else if (mode == ImportMode.RepairRecord) { var convertedRecord = new CollisionRecord() { VehicleId = vehicleId, - Date = recordToInsert.Date, - Mileage = recordToInsert.Odometer, - Description = recordToInsert.Description, - Notes = recordToInsert.Notes, - Cost = recordToInsert.Cost + Date = DateTime.Parse(importModel.Date), + Mileage = int.Parse(importModel.Odometer, NumberStyles.Any), + Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Repair Record on {importModel.Date}" : importModel.Description, + Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes, + Cost = decimal.Parse(importModel.Cost, NumberStyles.Any) }; _collisionRecordDataAccess.SaveCollisionRecordToVehicle(convertedRecord); } - } - } - else if (mode == "taxrecord") - { - var records = csv.GetRecords().ToList(); - if (records.Any()) - { - foreach (TaxRecordImport recordToInsert in records) + else if (mode == ImportMode.TaxRecord) { var convertedRecord = new TaxRecord() { VehicleId = vehicleId, - Date = recordToInsert.Date, - Description = recordToInsert.Description, - Notes = recordToInsert.Notes, - Cost = recordToInsert.Cost + Date = DateTime.Parse(importModel.Date), + Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Tax Record on {importModel.Date}" : importModel.Description, + Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes, + Cost = decimal.Parse(importModel.Cost, NumberStyles.Any) }; _taxRecordDataAccess.SaveTaxRecordToVehicle(convertedRecord); } @@ -274,7 +279,8 @@ namespace CarCareTracker.Controllers //reset unFactored vars unFactoredConsumption = 0; unFactoredMileage = 0; - } else + } + else { unFactoredConsumption += currentObject.Gallons; unFactoredMileage += deltaMileage; @@ -581,7 +587,7 @@ namespace CarCareTracker.Controllers var currentMileage = GetMaxMileage(vehicleId); var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId); List reminderViewModels = new List(); - foreach(var reminder in reminders) + foreach (var reminder in reminders) { var reminderViewModel = new ReminderRecordViewModel() { @@ -622,12 +628,13 @@ namespace CarCareTracker.Controllers reminderViewModel.Urgency = ReminderUrgency.Urgent; reminderViewModel.Metric = ReminderMetric.Date; } - else if (reminder.Mileage < currentMileage + 100) + else if (reminder.Mileage < currentMileage + 100) { reminderViewModel.Urgency = ReminderUrgency.Urgent; reminderViewModel.Metric = ReminderMetric.Odometer; } - } else if (reminder.Metric == ReminderMetric.Date) + } + else if (reminder.Metric == ReminderMetric.Date) { if (reminder.Date < DateTime.Now) { @@ -641,7 +648,8 @@ namespace CarCareTracker.Controllers { reminderViewModel.Urgency = ReminderUrgency.Urgent; } - } else if (reminder.Metric == ReminderMetric.Odometer) + } + else if (reminder.Metric == ReminderMetric.Odometer) { if (reminder.Mileage < currentMileage) { @@ -665,7 +673,7 @@ namespace CarCareTracker.Controllers public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId) { var result = GetRemindersAndUrgency(vehicleId); - 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); } @@ -675,7 +683,7 @@ namespace CarCareTracker.Controllers public IActionResult GetReminderRecordsByVehicleId(int vehicleId) { var result = GetRemindersAndUrgency(vehicleId); - result = result.OrderByDescending(x=>x.Urgency).ToList(); + result = result.OrderByDescending(x => x.Urgency).ToList(); return PartialView("_ReminderRecords", result); } [HttpPost] diff --git a/Enum/ImportMode.cs b/Enum/ImportMode.cs new file mode 100644 index 0000000..1db71df --- /dev/null +++ b/Enum/ImportMode.cs @@ -0,0 +1,10 @@ +namespace CarCareTracker.Models +{ + public enum ImportMode + { + ServiceRecord = 0, + RepairRecord = 1, + GasRecord = 2, + TaxRecord = 3 + } +} diff --git a/MapProfile/FuellyMappers.cs b/MapProfile/FuellyMappers.cs new file mode 100644 index 0000000..dd90590 --- /dev/null +++ b/MapProfile/FuellyMappers.cs @@ -0,0 +1,20 @@ +using CarCareTracker.Models; +using CsvHelper.Configuration; + +namespace CarCareTracker.MapProfile +{ + public class FuellyMapper: ClassMap + { + public FuellyMapper() + { + Map(m => m.Date).Name(["date", "fuelup_date"]); + Map(m => m.Odometer).Name(["odometer"]); + Map(m => m.FuelConsumed).Name(["gallons", "liters", "litres"]); + Map(m => m.Cost).Name(["cost", "total cost", "totalcost"]); + Map(m => m.Notes).Name("notes", "note"); + Map(m => m.Price).Name(["price"]); + Map(m => m.PartialFuelUp).Name(["partial_fuelup"]); + Map(m => m.IsFillToFull).Name(["isfilltofull", "filled up"]); + } + } +} diff --git a/Models/ImportModel.cs b/Models/ImportModel.cs new file mode 100644 index 0000000..9fb1cdc --- /dev/null +++ b/Models/ImportModel.cs @@ -0,0 +1,18 @@ +namespace CarCareTracker.Models +{ + /// + /// Import model used for importing Gas records. + /// + public class ImportModel + { + public string Date { get; set; } + public string Odometer { get; set; } + public string Description { get; set; } + public string Notes { get; set; } + public string FuelConsumed { get; set; } + public string Cost { get; set; } + public string Price { get; set; } + public string PartialFuelUp { get; set; } + public string IsFillToFull { get; set; } + } +} diff --git a/Models/ImportModels.cs b/Models/ImportModels.cs deleted file mode 100644 index 96b9d29..0000000 --- a/Models/ImportModels.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace CarCareTracker.Models -{ - /// - /// Import model used for importing Gas records. - /// - public class GasRecordImport - { - public DateTime Date { get; set; } - public int Odometer { get; set; } - public decimal FuelConsumed { get; set; } - public decimal Cost { get; set; } - } - /// - /// Import model used for importing Service and Repair records. - /// - 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; } - } - /// - /// Import model used for importing tax records. - /// - public class TaxRecordImport - { - public DateTime Date { get; set; } - public string Description { get; set; } - public string Notes { get; set; } - public decimal Cost { get; set; } - } -} diff --git a/Views/Vehicle/_BulkDataImporter.cshtml b/Views/Vehicle/_BulkDataImporter.cshtml index 62a04f0..dd88d92 100644 --- a/Views/Vehicle/_BulkDataImporter.cshtml +++ b/Views/Vehicle/_BulkDataImporter.cshtml @@ -1,4 +1,4 @@ -@model string +@model ImportMode } diff --git a/Views/Vehicle/_Gas.cshtml b/Views/Vehicle/_Gas.cshtml index 5c07e4a..446315f 100644 --- a/Views/Vehicle/_Gas.cshtml +++ b/Views/Vehicle/_Gas.cshtml @@ -37,7 +37,7 @@ Toggle Dropdown } else { diff --git a/Views/Vehicle/_ServiceRecords.cshtml b/Views/Vehicle/_ServiceRecords.cshtml index efad9c3..db7ff24 100644 --- a/Views/Vehicle/_ServiceRecords.cshtml +++ b/Views/Vehicle/_ServiceRecords.cshtml @@ -18,7 +18,7 @@ Toggle Dropdown } diff --git a/config/userConfig.json b/config/userConfig.json index 62cf701..dd1295e 100644 --- a/config/userConfig.json +++ b/config/userConfig.json @@ -1 +1 @@ -{"UseDarkMode":true,"UsekWh":false,"EnableCsvImports":false,"UseMPG":true,"UseDescending":false,"EnableAuth":false,"UserNameHash":"","UserPasswordHash":""} \ No newline at end of file +{"UseDarkMode":true,"EnableCsvImports":true,"UseMPG":true,"UseDescending":false,"EnableAuth":false,"UserNameHash":"","UserPasswordHash":""} \ No newline at end of file