Merge pull request #393 from hargata/Hargata/multi.odo.edit

Added functionality to edit multiple odometer records.
This commit is contained in:
Hargata Softworks
2024-03-13 10:18:13 -06:00
committed by GitHub
6 changed files with 179 additions and 9 deletions

View File

@@ -1008,7 +1008,7 @@ namespace CarCareTracker.Controllers
{
MonthName = x.Key.MonthName,
Cost = x.Sum(y => y.Cost),
DistanceTraveled = x.Max(y=>y.DistanceTraveled)
DistanceTraveled = x.Max(y => y.DistanceTraveled)
}).ToList();
//get reminders
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
@@ -1231,7 +1231,8 @@ namespace CarCareTracker.Controllers
try
{
vehicleHistory.DaysOwned = (DateTime.Parse(endDate) - DateTime.Parse(vehicleHistory.VehicleData.PurchaseDate)).Days.ToString("N0");
} catch (Exception ex)
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
vehicleHistory.DaysOwned = string.Empty;
@@ -1421,7 +1422,7 @@ namespace CarCareTracker.Controllers
private int GetMinMileage(int vehicleId)
{
var numbersArray = new List<int>();
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId).Where(x=>x.Mileage != default);
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId).Where(x => x.Mileage != default);
if (serviceRecords.Any())
{
numbersArray.Add(serviceRecords.Min(x => x.Mileage));
@@ -1706,13 +1707,14 @@ namespace CarCareTracker.Controllers
public IActionResult PinNotes(List<int> noteIds, bool isToggle = false, bool pinStatus = false)
{
var result = false;
foreach(int noteId in noteIds)
foreach (int noteId in noteIds)
{
var existingNote = _noteDataAccess.GetNoteById(noteId);
if (isToggle)
{
existingNote.Pinned = !existingNote.Pinned;
} else
}
else
{
existingNote.Pinned = pinStatus;
}
@@ -2084,7 +2086,7 @@ namespace CarCareTracker.Controllers
{
var result = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
//determine if conversion is needed.
if (result.All(x=>x.InitialMileage == default))
if (result.All(x => x.InitialMileage == default))
{
result = _odometerLogic.AutoConvertOdometerRecord(result);
}
@@ -2112,6 +2114,56 @@ namespace CarCareTracker.Controllers
{
return PartialView("_OdometerRecordModal", new OdometerRecordInput() { InitialMileage = _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()), ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields });
}
[HttpPost]
public IActionResult GetOdometerRecordsEditModal(List<int> recordIds)
{
return PartialView("_OdometerRecordsModal", new OdometerRecordEditModel { RecordIds = recordIds });
}
[HttpPost]
public IActionResult SaveMultipleOdometerRecords(OdometerRecordEditModel editModel)
{
var dateIsEdited = editModel.EditRecord.Date != default;
var initialMileageIsEdited = editModel.EditRecord.InitialMileage != default;
var mileageIsEdited = editModel.EditRecord.Mileage != default;
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
var tagsIsEdited = editModel.EditRecord.Tags.Any();
//handle clear overrides
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
{
editModel.EditRecord.Tags = new List<string>();
}
if (noteIsEdited && editModel.EditRecord.Notes == "---")
{
editModel.EditRecord.Notes = "";
}
bool result = false;
foreach (int recordId in editModel.RecordIds)
{
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = editModel.EditRecord.Date;
}
if (initialMileageIsEdited)
{
existingRecord.InitialMileage = editModel.EditRecord.InitialMileage;
}
if (mileageIsEdited)
{
existingRecord.Mileage = editModel.EditRecord.Mileage;
}
if (noteIsEdited)
{
existingRecord.Notes = editModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = editModel.EditRecord.Tags;
}
result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
}
return Json(result);
}
[HttpGet]
public IActionResult GetOdometerRecordForEditById(int odometerRecordId)
{
@@ -2483,13 +2535,15 @@ namespace CarCareTracker.Controllers
{
var existingPreference = existingUserColumnPreference.Single();
existingPreference.VisibleColumns = columnPreference.VisibleColumns;
} else
}
else
{
userConfig.UserColumnPreferences.Add(columnPreference);
}
var result = _config.SaveUserConfig(User, userConfig);
return Json(result);
} catch (Exception ex)
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(false);

View File

@@ -0,0 +1,8 @@
namespace CarCareTracker.Models
{
public class OdometerRecordEditModel
{
public List<int> RecordIds { get; set; } = new List<int>();
public OdometerRecord EditRecord { get; set; } = new OdometerRecord();
}
}

View File

@@ -149,6 +149,7 @@
<ul class="table-context-menu dropdown-menu" style="display:none;">
<li><a class="context-menu-multiple context-menu-select-all dropdown-item" href="#" onclick="selectAllRows()">@translator.Translate(userLanguage, "Select All")</a></li>
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="clearSelectedRows()">@translator.Translate(userLanguage, "Deselect All")</a></li>
<li><a class="context-menu-active-multiple dropdown-item" href="#" onclick="editMultipleOdometerRecords(selectedRow)">@translator.Translate(userLanguage, "Edit Multiple")</a></li>
<li><hr class="context-menu-multiple context-menu-deselect-all dropdown-divider"></li>
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="recalculateDistance()">@translator.Translate(userLanguage, "Recalculate Distance")</a></li>
<li><hr class="context-menu-multiple dropdown-divider"></li>

View File

@@ -0,0 +1,48 @@
@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@model OdometerRecordEditModel
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
}
<div class="modal-header">
<h5 class="modal-title">@translator.Translate(userLanguage,"Edit Multiple Odometer Records")</h5>
<button type="button" class="btn-close" onclick="hideAddOdometerRecordModal()" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<div class="row">
<div class="col-md-6 col-12">
<label for="odometerRecordDate">@translator.Translate(userLanguage, "Date")</label>
<div class="input-group">
<input type="text" id="odometerRecordDate" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
</div>
<label for="initialOdometerRecordMileage">@translator.Translate(userLanguage, "Initial Odometer")</label>
<input type="number" inputmode="numeric" id="initialOdometerRecordMileage" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<label for="odometerRecordMileage">@translator.Translate(userLanguage, "Odometer")</label>
<input type="number" inputmode="numeric" id="odometerRecordMileage" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<label for="odometerRecordTag">@translator.Translate(userLanguage, "Tags(use --- to clear all existing tags)")</label>
<select multiple class="form-select" id="odometerRecordTag"></select>
</div>
<div class="col-md-6 col-12">
<label for="odometerRecordNotes">@translator.Translate(userLanguage, "Notes(use --- to clear all existing notes)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>
<textarea id="odometerRecordNotes" class="form-control" rows="5"></textarea>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideAddOdometerRecordModal()">@translator.Translate(userLanguage, "Cancel")</button>
<button type="button" class="btn btn-primary" onclick="saveMultipleOdometerRecordsToVehicle()">@translator.Translate(userLanguage, "Edit")</button>
</div>
<script>
var recordsToEdit = [];
@foreach(int recordId in Model.RecordIds)
{
@:recordsToEdit.push(@recordId);
}
</script>

File diff suppressed because one or more lines are too long

View File

@@ -134,4 +134,63 @@ function recalculateDistance() {
errorToast(genericErrorMessage());
}
});
}
function editMultipleOdometerRecords(ids) {
$.post('/Vehicle/GetOdometerRecordsEditModal', { recordIds: ids }, function (data) {
if (data) {
$("#odometerRecordModalContent").html(data);
//initiate datepicker
initDatePicker($('#odometerRecordDate'));
initTagSelector($("#odometerRecordTag"));
$('#odometerRecordModal').modal('show');
}
});
}
function saveMultipleOdometerRecordsToVehicle() {
var odometerDate = $("#odometerRecordDate").val();
var initialOdometerMileage = $("#initialOdometerRecordMileage").val();
var odometerMileage = $("#odometerRecordMileage").val();
var initialOdometerMileageToParse = parseInt(globalParseFloat($("#initialOdometerRecordMileage").val())).toString();
var odometerMileageToParse = parseInt(globalParseFloat($("#odometerRecordMileage").val())).toString();
var odometerNotes = $("#odometerRecordNotes").val();
var odometerTags = $("#odometerRecordTag").val();
//validation
var hasError = false;
if (odometerMileage.trim() != '' && (isNaN(odometerMileageToParse) || parseInt(odometerMileageToParse) < 0)) {
hasError = true;
$("#odometerRecordMileage").addClass("is-invalid");
} else {
$("#odometerRecordMileage").removeClass("is-invalid");
}
if (initialOdometerMileage.trim() != '' && (isNaN(initialOdometerMileageToParse) || parseInt(initialOdometerMileageToParse) < 0)) {
hasError = true;
$("#odometerRecordMileage").addClass("is-invalid");
} else {
$("#odometerRecordMileage").removeClass("is-invalid");
}
if (hasError) {
errorToast("Please check the form data");
return;
}
var formValues = {
recordIds: recordsToEdit,
editRecord: {
date: odometerDate,
initialMileage: initialOdometerMileageToParse,
mileage: odometerMileageToParse,
notes: odometerNotes,
tags: odometerTags
}
}
$.post('/Vehicle/SaveMultipleOdometerRecords', { editModel: formValues }, function (data) {
if (data) {
successToast("Odometer Records Updated");
hideAddOdometerRecordModal();
saveScrollPosition();
getVehicleOdometerRecords(GetVehicleId().vehicleId);
} else {
errorToast(genericErrorMessage());
}
})
}