mirror of
https://github.com/hargata/lubelog.git
synced 2026-02-03 17:53:02 -06:00
commit
550744b985
@ -26,10 +26,12 @@ namespace CarCareTracker.Controllers
|
||||
private readonly IPlanRecordTemplateDataAccess _planRecordTemplateDataAccess;
|
||||
private readonly IInspectionRecordDataAccess _inspectionRecordDataAccess;
|
||||
private readonly IInspectionRecordTemplateDataAccess _inspectionRecordTemplateDataAccess;
|
||||
private readonly IEquipmentRecordDataAccess _equipmentRecordDataAccess;
|
||||
private readonly IUserAccessDataAccess _userAccessDataAccess;
|
||||
private readonly IUserRecordDataAccess _userRecordDataAccess;
|
||||
private readonly IExtraFieldDataAccess _extraFieldDataAccess;
|
||||
private readonly IReminderHelper _reminderHelper;
|
||||
private readonly IEquipmentHelper _equipmentHelper;
|
||||
private readonly IGasHelper _gasHelper;
|
||||
private readonly IUserLogic _userLogic;
|
||||
private readonly IVehicleLogic _vehicleLogic;
|
||||
@ -41,6 +43,7 @@ namespace CarCareTracker.Controllers
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
public APIController(IVehicleDataAccess dataAccess,
|
||||
IGasHelper gasHelper,
|
||||
IEquipmentHelper equipmentHelper,
|
||||
IReminderHelper reminderHelper,
|
||||
INoteDataAccess noteDataAccess,
|
||||
IServiceRecordDataAccess serviceRecordDataAccess,
|
||||
@ -55,6 +58,7 @@ namespace CarCareTracker.Controllers
|
||||
IPlanRecordTemplateDataAccess planRecordTemplateDataAccess,
|
||||
IInspectionRecordDataAccess inspectionRecordDataAccess,
|
||||
IInspectionRecordTemplateDataAccess inspectionRecordTemplateDataAccess,
|
||||
IEquipmentRecordDataAccess equipmentRecordDataAccess,
|
||||
IUserAccessDataAccess userAccessDataAccess,
|
||||
IUserRecordDataAccess userRecordDataAccess,
|
||||
IExtraFieldDataAccess extraFieldDataAccess,
|
||||
@ -81,11 +85,13 @@ namespace CarCareTracker.Controllers
|
||||
_planRecordTemplateDataAccess = planRecordTemplateDataAccess;
|
||||
_inspectionRecordDataAccess = inspectionRecordDataAccess;
|
||||
_inspectionRecordTemplateDataAccess = inspectionRecordTemplateDataAccess;
|
||||
_equipmentRecordDataAccess = equipmentRecordDataAccess;
|
||||
_userAccessDataAccess = userAccessDataAccess;
|
||||
_userRecordDataAccess = userRecordDataAccess;
|
||||
_extraFieldDataAccess = extraFieldDataAccess;
|
||||
_mailHelper = mailHelper;
|
||||
_gasHelper = gasHelper;
|
||||
_equipmentHelper = equipmentHelper;
|
||||
_reminderHelper = reminderHelper;
|
||||
_userLogic = userLogic;
|
||||
_odometerLogic = odometerLogic;
|
||||
@ -1683,7 +1689,7 @@ namespace CarCareTracker.Controllers
|
||||
var tagsFilter = parameters.Tags.Split(' ').Distinct();
|
||||
vehicleRecords.RemoveAll(x => !x.Tags.Any(y => tagsFilter.Contains(y)));
|
||||
}
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags), EquipmentRecordId = string.Join(' ', x.EquipmentRecordId) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@ -1727,7 +1733,7 @@ namespace CarCareTracker.Controllers
|
||||
var tagsFilter = parameters.Tags.Split(' ').Distinct();
|
||||
vehicleRecords.RemoveAll(x => !x.Tags.Any(y => tagsFilter.Contains(y)));
|
||||
}
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags), EquipmentRecordId = string.Join(' ', x.EquipmentRecordId) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
@ -1766,6 +1772,36 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
input.ExtraFields = new List<ExtraField>();
|
||||
}
|
||||
var equipmentRecordId = new List<int>();
|
||||
//validate equipment record ids
|
||||
if (!string.IsNullOrWhiteSpace(input.EquipmentRecordId))
|
||||
{
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
if (!equipmentRecords.Any())
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment with ids {input.EquipmentRecordId} does not exist."));
|
||||
}
|
||||
var equipmentRecordIds = input.EquipmentRecordId.Split(' ').Distinct().ToList();
|
||||
foreach(string equipmentRecordIdToAdd in equipmentRecordIds)
|
||||
{
|
||||
if (int.TryParse(equipmentRecordIdToAdd, out int cleanEquipmentRecordId))
|
||||
{
|
||||
equipmentRecordId.Add(cleanEquipmentRecordId);
|
||||
} else
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment id {cleanEquipmentRecordId} is not valid."));
|
||||
}
|
||||
}
|
||||
var equipmentRecordIdsToCompare = equipmentRecords.Select(x => x.Id);
|
||||
var invalidEquipmentRecordIds = equipmentRecordId.Where(x => !equipmentRecordIdsToCompare.Contains(x));
|
||||
if (invalidEquipmentRecordIds.Any())
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment with ids {string.Join(' ', invalidEquipmentRecordIds)} does not exist."));
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
var odometerRecord = new OdometerRecord()
|
||||
@ -1777,7 +1813,8 @@ namespace CarCareTracker.Controllers
|
||||
Mileage = int.Parse(input.Odometer),
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList(),
|
||||
EquipmentRecordId = equipmentRecordId
|
||||
};
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometerRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(odometerRecord, "odometerrecord.add.api", User.Identity.Name));
|
||||
@ -1847,6 +1884,37 @@ namespace CarCareTracker.Controllers
|
||||
Response.StatusCode = 401;
|
||||
return Json(OperationResponse.Failed("Access Denied, you don't have access to this vehicle."));
|
||||
}
|
||||
var equipmentRecordId = new List<int>();
|
||||
//validate equipment record ids
|
||||
if (!string.IsNullOrWhiteSpace(input.EquipmentRecordId))
|
||||
{
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(existingRecord.VehicleId);
|
||||
if (!equipmentRecords.Any())
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment with ids {input.EquipmentRecordId} does not exist."));
|
||||
}
|
||||
var equipmentRecordIds = input.EquipmentRecordId.Split(' ').Distinct().ToList();
|
||||
foreach (string equipmentRecordIdToAdd in equipmentRecordIds)
|
||||
{
|
||||
if (int.TryParse(equipmentRecordIdToAdd, out int cleanEquipmentRecordId))
|
||||
{
|
||||
equipmentRecordId.Add(cleanEquipmentRecordId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment id {cleanEquipmentRecordId} is not valid."));
|
||||
}
|
||||
}
|
||||
var equipmentRecordIdsToCompare = equipmentRecords.Select(x => x.Id);
|
||||
var invalidEquipmentRecordIds = equipmentRecordId.Where(x => !equipmentRecordIdsToCompare.Contains(x));
|
||||
if (invalidEquipmentRecordIds.Any())
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed($"Input object invalid, equipment with ids {string.Join(' ', invalidEquipmentRecordIds)} does not exist."));
|
||||
}
|
||||
}
|
||||
existingRecord.Date = DateTime.Parse(input.Date);
|
||||
existingRecord.Mileage = int.Parse(input.Odometer);
|
||||
existingRecord.InitialMileage = int.Parse(input.InitialOdometer);
|
||||
@ -1854,6 +1922,7 @@ namespace CarCareTracker.Controllers
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
existingRecord.EquipmentRecordId = equipmentRecordId;
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(existingRecord, "odometerrecord.update.api", User.Identity.Name));
|
||||
}
|
||||
@ -2697,6 +2766,221 @@ namespace CarCareTracker.Controllers
|
||||
return File(calendarContent, "text/calendar");
|
||||
}
|
||||
#endregion
|
||||
#region EquipmentRecord
|
||||
[HttpGet]
|
||||
[Route("/api/vehicle/equipmentrecords/all")]
|
||||
public IActionResult AllEquipmentRecords(MethodParameter parameters)
|
||||
{
|
||||
List<int> vehicleIds = new List<int>();
|
||||
var vehicles = _dataAccess.GetVehicles();
|
||||
if (!User.IsInRole(nameof(UserData.IsRootUser)))
|
||||
{
|
||||
vehicles = _userLogic.FilterUserVehicles(vehicles, GetUserID());
|
||||
}
|
||||
vehicleIds.AddRange(vehicles.Select(x => x.Id));
|
||||
List<EquipmentRecordViewModel> vehicleRecords = new List<EquipmentRecordViewModel>();
|
||||
foreach (int vehicleId in vehicleIds)
|
||||
{
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
var convertedRecords = _equipmentHelper.GetEquipmentRecordViewModels(equipmentRecords, odometerRecords);
|
||||
vehicleRecords.AddRange(convertedRecords);
|
||||
}
|
||||
if (parameters.Id != default)
|
||||
{
|
||||
vehicleRecords.RemoveAll(x => x.Id != parameters.Id);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(parameters.Tags))
|
||||
{
|
||||
var tagsFilter = parameters.Tags.Split(' ').Distinct();
|
||||
vehicleRecords.RemoveAll(x => !x.Tags.Any(y => tagsFilter.Contains(y)));
|
||||
}
|
||||
var result = vehicleRecords.Select(x => new EquipmentRecordAPIExportModel { Id = x.Id.ToString(), Description = x.Description, IsEquipped = x.IsEquipped.ToString(), DistanceTraveled = x.DistanceTraveled.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
[Route("/api/vehicle/equipmentrecords")]
|
||||
public IActionResult EquipmentRecords(int vehicleId, MethodParameter parameters)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
{
|
||||
var response = OperationResponse.Failed("Must provide a valid vehicle id");
|
||||
Response.StatusCode = 400;
|
||||
return Json(response);
|
||||
}
|
||||
var vehicleRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
if (parameters.Id != default)
|
||||
{
|
||||
vehicleRecords.RemoveAll(x => x.Id != parameters.Id);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(parameters.Tags))
|
||||
{
|
||||
var tagsFilter = parameters.Tags.Split(' ').Distinct();
|
||||
vehicleRecords.RemoveAll(x => !x.Tags.Any(y => tagsFilter.Contains(y)));
|
||||
}
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
var convertedRecords = _equipmentHelper.GetEquipmentRecordViewModels(vehicleRecords, odometerRecords);
|
||||
var result = convertedRecords.Select(x => new EquipmentRecordAPIExportModel { Id = x.Id.ToString(), Description = x.Description, IsEquipped = x.IsEquipped.ToString(), DistanceTraveled = x.DistanceTraveled.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
|
||||
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
|
||||
{
|
||||
return Json(result, StaticHelper.GetInvariantOption());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/equipmentrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddEquipmentRecordJson(int vehicleId, [FromBody] EquipmentRecordExportModel input) => AddEquipmentRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/equipmentrecords/add")]
|
||||
public IActionResult AddEquipmentRecord(int vehicleId, EquipmentRecordExportModel input)
|
||||
{
|
||||
if (vehicleId == default)
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("Must provide a valid vehicle id"));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(input.Description) ||
|
||||
string.IsNullOrWhiteSpace(input.IsEquipped))
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("Input object invalid, Description and IsEquipped cannot be empty."));
|
||||
}
|
||||
if (input.Files == null)
|
||||
{
|
||||
input.Files = new List<UploadedFiles>();
|
||||
}
|
||||
if (input.ExtraFields == null)
|
||||
{
|
||||
input.ExtraFields = new List<ExtraField>();
|
||||
}
|
||||
try
|
||||
{
|
||||
var equipmentRecord = new EquipmentRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Description = input.Description,
|
||||
IsEquipped = bool.Parse(input.IsEquipped),
|
||||
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
|
||||
ExtraFields = input.ExtraFields,
|
||||
Files = input.Files,
|
||||
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
|
||||
};
|
||||
_equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(equipmentRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromEquipmentRecord(equipmentRecord, "equipmentrecord.add.api", User.Identity.Name));
|
||||
return Json(OperationResponse.Succeed("Equipment Record Added", new { recordId = equipmentRecord.Id }));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response.StatusCode = 500;
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/equipmentrecords/delete")]
|
||||
public IActionResult DeleteEquipmentRecord(int id)
|
||||
{
|
||||
var existingRecord = _equipmentRecordDataAccess.GetEquipmentRecordById(id);
|
||||
if (existingRecord == null || existingRecord.Id == default)
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("Invalid Record Id"));
|
||||
}
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId, HouseholdPermission.Delete))
|
||||
{
|
||||
Response.StatusCode = 401;
|
||||
return Json(OperationResponse.Failed("Access Denied, you don't have access to this vehicle."));
|
||||
}
|
||||
//delete link to odometer record
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(existingRecord.VehicleId);
|
||||
var linkedOdometerRecords = odometerRecords.Where(x => x.EquipmentRecordId.Contains(existingRecord.Id));
|
||||
if (linkedOdometerRecords.Any())
|
||||
{
|
||||
foreach (OdometerRecord linkedOdometerRecord in linkedOdometerRecords)
|
||||
{
|
||||
linkedOdometerRecord.EquipmentRecordId.RemoveAll(x => x == existingRecord.Id);
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(linkedOdometerRecord);
|
||||
}
|
||||
}
|
||||
var result = _equipmentRecordDataAccess.DeleteEquipmentRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromEquipmentRecord(existingRecord, "equipmentrecord.delete.api", User.Identity.Name));
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Equipment Record Deleted"));
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/equipmentrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateEquipmentRecordJson([FromBody] EquipmentRecordExportModel input) => UpdateEquipmentRecord(input);
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/equipmentrecords/update")]
|
||||
public IActionResult UpdateEquipmentRecord(EquipmentRecordExportModel input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.Id) ||
|
||||
string.IsNullOrWhiteSpace(input.Description) ||
|
||||
string.IsNullOrWhiteSpace(input.IsEquipped))
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("Input object invalid, Id, Description, and IsEquipped cannot be empty."));
|
||||
}
|
||||
if (input.Files == null)
|
||||
{
|
||||
input.Files = new List<UploadedFiles>();
|
||||
}
|
||||
if (input.ExtraFields == null)
|
||||
{
|
||||
input.ExtraFields = new List<ExtraField>();
|
||||
}
|
||||
try
|
||||
{
|
||||
//retrieve existing record
|
||||
var existingRecord = _equipmentRecordDataAccess.GetEquipmentRecordById(int.Parse(input.Id));
|
||||
if (existingRecord != null && existingRecord.Id == int.Parse(input.Id))
|
||||
{
|
||||
//check if user has access to the vehicleId
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId, HouseholdPermission.Edit))
|
||||
{
|
||||
Response.StatusCode = 401;
|
||||
return Json(OperationResponse.Failed("Access Denied, you don't have access to this vehicle."));
|
||||
}
|
||||
existingRecord.Description = input.Description;
|
||||
existingRecord.IsEquipped = bool.Parse(input.IsEquipped);
|
||||
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
|
||||
existingRecord.ExtraFields = input.ExtraFields;
|
||||
existingRecord.Files = input.Files;
|
||||
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
|
||||
_equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(existingRecord);
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromEquipmentRecord(existingRecord, "equipmentrecord.update.api", User.Identity.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
Response.StatusCode = 400;
|
||||
return Json(OperationResponse.Failed("Invalid Record Id"));
|
||||
}
|
||||
return Json(OperationResponse.Succeed("Equipment Record Updated"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response.StatusCode = 500;
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
[HttpPost]
|
||||
[Route("/api/documents/upload")]
|
||||
public IActionResult UploadDocument(List<IFormFile> documents)
|
||||
@ -2927,6 +3211,7 @@ namespace CarCareTracker.Controllers
|
||||
vehicleDocuments.AddRange(_planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(vehicle.Id).SelectMany(x => x.Files).Select(y => Path.GetFileName(y.Location)));
|
||||
vehicleDocuments.AddRange(_inspectionRecordDataAccess.GetInspectionRecordsByVehicleId(vehicle.Id).SelectMany(x => x.Files).Select(y => Path.GetFileName(y.Location)));
|
||||
vehicleDocuments.AddRange(_inspectionRecordTemplateDataAccess.GetInspectionRecordTemplatesByVehicleId(vehicle.Id).SelectMany(x => x.Files).Select(y => Path.GetFileName(y.Location)));
|
||||
vehicleDocuments.AddRange(_equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicle.Id).SelectMany(x => x.Files).Select(y => Path.GetFileName(y.Location)));
|
||||
}
|
||||
//shop supplies
|
||||
vehicleDocuments.AddRange(_supplyRecordDataAccess.GetSupplyRecordsByVehicleId(0).SelectMany(x => x.Files).Select(y => Path.GetFileName(y.Location)));
|
||||
|
||||
@ -55,6 +55,7 @@ namespace CarCareTracker.Controllers
|
||||
"CREATE TABLE IF NOT EXISTS app.extrafields (id INT primary key, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.equipmentrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, data jsonb not null, PRIMARY KEY(parentUserId, childUserId))"
|
||||
};
|
||||
foreach(string cmd in cmds)
|
||||
@ -104,6 +105,8 @@ namespace CarCareTracker.Controllers
|
||||
var extrafields = new List<RecordExtraField>();
|
||||
var inspectionrecords = new List<InspectionRecord>();
|
||||
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
#region "Part1"
|
||||
string cmd = $"SELECT data FROM app.vehicles";
|
||||
@ -457,6 +460,26 @@ namespace CarCareTracker.Controllers
|
||||
table.Upsert(record);
|
||||
};
|
||||
}
|
||||
cmd = $"SELECT data FROM app.equipmentrecords";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
equipmentrecords.Add(JsonSerializer.Deserialize<EquipmentRecord>(reader["data"] as string));
|
||||
}
|
||||
}
|
||||
foreach (var record in equipmentrecords)
|
||||
{
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<EquipmentRecord>("equipmentrecords");
|
||||
table.Upsert(record);
|
||||
}
|
||||
;
|
||||
}
|
||||
#endregion
|
||||
#region "Part6"
|
||||
cmd = $"SELECT data FROM app.userhouseholdrecords";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
@ -526,6 +549,8 @@ namespace CarCareTracker.Controllers
|
||||
var extrafields = new List<RecordExtraField>();
|
||||
var inspectionrecords = new List<InspectionRecord>();
|
||||
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
#region "Part1"
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
@ -839,6 +864,25 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
}
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<EquipmentRecord>("equipmentrecords");
|
||||
equipmentrecords = table.FindAll().ToList();
|
||||
}
|
||||
;
|
||||
foreach (var record in equipmentrecords)
|
||||
{
|
||||
string cmd = $"INSERT INTO app.equipmentrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.equipmentrecords_id_seq', (SELECT MAX(id) from app.equipmentrecords));";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", record.Id);
|
||||
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
|
||||
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region "Part6"
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<UserHousehold>("userhouseholdrecords");
|
||||
userhouseholdrecords = table.FindAll().ToList();
|
||||
|
||||
113
Controllers/Vehicle/EquipmentController.cs
Normal file
113
Controllers/Vehicle/EquipmentController.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using CarCareTracker.Filter;
|
||||
using CarCareTracker.Helper;
|
||||
using CarCareTracker.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CarCareTracker.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetEquipmentRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = new List<EquipmentRecordViewModel>();
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
//convert to viewmodel and calculate sum of distance traveled
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
result = _equipmentHelper.GetEquipmentRecordViewModels(equipmentRecords, odometerRecords);
|
||||
result = result.OrderByDescending(x => x.IsEquipped).ThenBy(x=>x.Description).ToList();
|
||||
return PartialView("Equipment/_EquipmentRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveEquipmentRecordToVehicleId(EquipmentRecordInput equipmentRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), equipmentRecord.VehicleId, HouseholdPermission.Edit))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Access Denied"));
|
||||
}
|
||||
//move files from temp.
|
||||
equipmentRecord.Files = equipmentRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
var convertedRecord = equipmentRecord.ToEquipmentRecord();
|
||||
var result = _equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(convertedRecord);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromEquipmentRecord(convertedRecord, equipmentRecord.Id == default ? "equipmentrecord.add" : "equipmentrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, string.Empty, StaticHelper.GenericErrorMessage));
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddEquipmentRecordPartialView()
|
||||
{
|
||||
return PartialView("Equipment/_EquipmentRecordModal", new EquipmentRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.EquipmentRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetEquipmentRecordForEditById(int equipmentRecordId)
|
||||
{
|
||||
var result = _equipmentRecordDataAccess.GetEquipmentRecordById(equipmentRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId, HouseholdPermission.View))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(result.VehicleId);
|
||||
var linkedOdometerRecords = odometerRecords.Where(x => x.EquipmentRecordId.Contains(equipmentRecordId));
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
linkedOdometerRecords = linkedOdometerRecords.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
linkedOdometerRecords = linkedOdometerRecords.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new EquipmentRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Description = result.Description,
|
||||
IsEquipped = result.IsEquipped,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
OdometerRecords = linkedOdometerRecords.ToList(),
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.EquipmentRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Equipment/_EquipmentRecordModal", convertedResult);
|
||||
}
|
||||
private OperationResponse DeleteEquipmentRecordWithChecks(int equipmentRecordId)
|
||||
{
|
||||
var existingRecord = _equipmentRecordDataAccess.GetEquipmentRecordById(equipmentRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId, HouseholdPermission.Delete))
|
||||
{
|
||||
return OperationResponse.Failed("Access Denied");
|
||||
}
|
||||
//delete link to odometer record
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(existingRecord.VehicleId);
|
||||
var linkedOdometerRecords = odometerRecords.Where(x => x.EquipmentRecordId.Contains(equipmentRecordId));
|
||||
if (linkedOdometerRecords.Any())
|
||||
{
|
||||
foreach(OdometerRecord linkedOdometerRecord in linkedOdometerRecords)
|
||||
{
|
||||
linkedOdometerRecord.EquipmentRecordId.RemoveAll(x => x == equipmentRecordId);
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(linkedOdometerRecord);
|
||||
}
|
||||
}
|
||||
var result = _equipmentRecordDataAccess.DeleteEquipmentRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromEquipmentRecord(existingRecord, "equipmentrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return OperationResponse.Conditional(result, string.Empty, StaticHelper.GenericErrorMessage);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteEquipmentRecordById(int equipmentRecordId)
|
||||
{
|
||||
var result = DeleteEquipmentRecordWithChecks(equipmentRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,6 +165,26 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var exportData = new List<EquipmentRecordExportModel> { new EquipmentRecordExportModel
|
||||
{
|
||||
Description = "Test",
|
||||
Notes = "Test Note",
|
||||
Tags = "test1 test2",
|
||||
IsEquipped = true.ToString()
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteEquipmentRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return Json(OperationResponse.Failed("No parameters"));
|
||||
}
|
||||
@ -253,7 +273,7 @@ namespace CarCareTracker.Controllers
|
||||
writer.Dispose();
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(OperationResponse.Failed("No Records"));
|
||||
@ -555,6 +575,33 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed("No Records"));
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.EquipmentRecord)
|
||||
{
|
||||
var vehicleRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new EquipmentRecordExportModel
|
||||
{
|
||||
Description = x.Description,
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
Notes = x.Notes,
|
||||
IsEquipped = x.IsEquipped.ToString(),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteEquipmentRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(OperationResponse.Failed("No Records"));
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.GasRecord)
|
||||
{
|
||||
var vehicleRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
@ -830,6 +877,19 @@ namespace CarCareTracker.Controllers
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.EquipmentRecord)
|
||||
{
|
||||
var convertedRecord = new EquipmentRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Description = importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
IsEquipped = bool.Parse(importModel.IsEquipped),
|
||||
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
|
||||
};
|
||||
_equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(convertedRecord);
|
||||
}
|
||||
else if (mode == ImportMode.SupplyRecord)
|
||||
{
|
||||
var convertedRecord = new SupplyRecord()
|
||||
|
||||
@ -62,13 +62,26 @@ namespace CarCareTracker.Controllers
|
||||
[HttpGet]
|
||||
public IActionResult GetAddOdometerRecordPartialView(int vehicleId)
|
||||
{
|
||||
return PartialView("Odometer/_OdometerRecordModal", new OdometerRecordInput() { InitialMileage = _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()), ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields });
|
||||
return PartialView("Odometer/_OdometerRecordModal", new OdometerRecordInput() {
|
||||
InitialMileage = _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()),
|
||||
ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields,
|
||||
EquipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId).OrderByDescending(x => x.IsEquipped).ThenBy(x => x.Description).ToList()
|
||||
});
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult GetOdometerRecordsEditModal(List<int> recordIds)
|
||||
public IActionResult GetOdometerRecordsEditModal(List<int> recordIds, int vehicleId)
|
||||
{
|
||||
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields;
|
||||
return PartialView("Odometer/_OdometerRecordsModal", new OdometerRecordEditModel { RecordIds = recordIds, EditRecord = new OdometerRecord { ExtraFields = extraFields } });
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId).OrderByDescending(x => x.IsEquipped).ThenBy(x => x.Description).ToList();
|
||||
foreach(EquipmentRecord equipmentRecord in equipmentRecords)
|
||||
{
|
||||
equipmentRecord.IsEquipped = false;
|
||||
}
|
||||
return PartialView("Odometer/_OdometerRecordsModal", new OdometerRecordEditModel {
|
||||
RecordIds = recordIds,
|
||||
EditRecord = new OdometerRecord { ExtraFields = extraFields },
|
||||
EquipmentRecords = equipmentRecords
|
||||
});
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveMultipleOdometerRecords(OdometerRecordEditModel editModel)
|
||||
@ -79,6 +92,7 @@ namespace CarCareTracker.Controllers
|
||||
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
|
||||
var tagsIsEdited = editModel.EditRecord.Tags.Any();
|
||||
var extraFieldIsEdited = editModel.EditRecord.ExtraFields.Any();
|
||||
var equipmentIsEdited = editModel.EditEquipment;
|
||||
//handle clear overrides
|
||||
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
|
||||
{
|
||||
@ -133,6 +147,10 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
if (equipmentIsEdited)
|
||||
{
|
||||
existingRecord.EquipmentRecordId = editModel.EditRecord.EquipmentRecordId;
|
||||
}
|
||||
result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, string.Empty, StaticHelper.GenericErrorMessage));
|
||||
@ -146,6 +164,12 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//check for equipment
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(result.VehicleId).OrderByDescending(x => x.IsEquipped).ThenBy(x => x.Description).ToList();
|
||||
foreach(EquipmentRecord equipmentRecord in equipmentRecords)
|
||||
{
|
||||
equipmentRecord.IsEquipped = result.EquipmentRecordId.Contains(equipmentRecord.Id);
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new OdometerRecordInput
|
||||
{
|
||||
@ -157,7 +181,8 @@ namespace CarCareTracker.Controllers
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields)
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields),
|
||||
EquipmentRecords = equipmentRecords
|
||||
};
|
||||
return PartialView("Odometer/_OdometerRecordModal", convertedResult);
|
||||
}
|
||||
|
||||
@ -29,10 +29,12 @@ namespace CarCareTracker.Controllers
|
||||
private readonly IOdometerRecordDataAccess _odometerRecordDataAccess;
|
||||
private readonly IInspectionRecordDataAccess _inspectionRecordDataAccess;
|
||||
private readonly IInspectionRecordTemplateDataAccess _inspectionRecordTemplateDataAccess;
|
||||
private readonly IEquipmentRecordDataAccess _equipmentRecordDataAccess;
|
||||
private readonly IWebHostEnvironment _webEnv;
|
||||
private readonly IConfigHelper _config;
|
||||
private readonly IFileHelper _fileHelper;
|
||||
private readonly IGasHelper _gasHelper;
|
||||
private readonly IEquipmentHelper _equipmentHelper;
|
||||
private readonly IReminderHelper _reminderHelper;
|
||||
private readonly IReportHelper _reportHelper;
|
||||
private readonly IUserLogic _userLogic;
|
||||
@ -43,6 +45,7 @@ namespace CarCareTracker.Controllers
|
||||
public VehicleController(ILogger<VehicleController> logger,
|
||||
IFileHelper fileHelper,
|
||||
IGasHelper gasHelper,
|
||||
IEquipmentHelper equipmentHelper,
|
||||
IReminderHelper reminderHelper,
|
||||
IReportHelper reportHelper,
|
||||
IVehicleDataAccess dataAccess,
|
||||
@ -64,13 +67,15 @@ namespace CarCareTracker.Controllers
|
||||
IWebHostEnvironment webEnv,
|
||||
IConfigHelper config,
|
||||
IInspectionRecordDataAccess inspectionRecordDataAccess,
|
||||
IInspectionRecordTemplateDataAccess inspectionRecordTemplateDataAccess)
|
||||
IInspectionRecordTemplateDataAccess inspectionRecordTemplateDataAccess,
|
||||
IEquipmentRecordDataAccess equipmentRecordDataAccess)
|
||||
{
|
||||
_logger = logger;
|
||||
_dataAccess = dataAccess;
|
||||
_noteDataAccess = noteDataAccess;
|
||||
_fileHelper = fileHelper;
|
||||
_gasHelper = gasHelper;
|
||||
_equipmentHelper = equipmentHelper;
|
||||
_reminderHelper = reminderHelper;
|
||||
_reportHelper = reportHelper;
|
||||
_serviceRecordDataAccess = serviceRecordDataAccess;
|
||||
@ -84,13 +89,14 @@ namespace CarCareTracker.Controllers
|
||||
_planRecordTemplateDataAccess = planRecordTemplateDataAccess;
|
||||
_inspectionRecordDataAccess = inspectionRecordDataAccess;
|
||||
_inspectionRecordTemplateDataAccess = inspectionRecordTemplateDataAccess;
|
||||
_equipmentRecordDataAccess = equipmentRecordDataAccess;
|
||||
_odometerRecordDataAccess = odometerRecordDataAccess;
|
||||
_extraFieldDataAccess = extraFieldDataAccess;
|
||||
_userLogic = userLogic;
|
||||
_odometerLogic = odometerLogic;
|
||||
_vehicleLogic = vehicleLogic;
|
||||
_webEnv = webEnv;
|
||||
_config = config;
|
||||
_config = config;
|
||||
}
|
||||
private int GetUserID()
|
||||
{
|
||||
@ -167,6 +173,7 @@ namespace CarCareTracker.Controllers
|
||||
_planRecordTemplateDataAccess.DeleteAllPlanRecordTemplatesByVehicleId(vehicleId) &&
|
||||
_inspectionRecordDataAccess.DeleteAllInspectionRecordsByVehicleId(vehicleId) &&
|
||||
_inspectionRecordTemplateDataAccess.DeleteAllInspectionReportTemplatesByVehicleId(vehicleId) &&
|
||||
_equipmentRecordDataAccess.DeleteAllEquipmentRecordsByVehicleId(vehicleId) &&
|
||||
_supplyRecordDataAccess.DeleteAllSupplyRecordsByVehicleId(vehicleId) &&
|
||||
_odometerRecordDataAccess.DeleteAllOdometerRecordsByVehicleId(vehicleId) &&
|
||||
_userLogic.DeleteAllAccessToVehicle(vehicleId) &&
|
||||
@ -196,6 +203,7 @@ namespace CarCareTracker.Controllers
|
||||
_planRecordTemplateDataAccess.DeleteAllPlanRecordTemplatesByVehicleId(vehicleId) &&
|
||||
_inspectionRecordDataAccess.DeleteAllInspectionRecordsByVehicleId(vehicleId) &&
|
||||
_inspectionRecordTemplateDataAccess.DeleteAllInspectionReportTemplatesByVehicleId(vehicleId) &&
|
||||
_equipmentRecordDataAccess.DeleteAllEquipmentRecordsByVehicleId(vehicleId) &&
|
||||
_supplyRecordDataAccess.DeleteAllSupplyRecordsByVehicleId(vehicleId) &&
|
||||
_odometerRecordDataAccess.DeleteAllOdometerRecordsByVehicleId(vehicleId) &&
|
||||
_userLogic.DeleteAllAccessToVehicle(vehicleId) &&
|
||||
@ -449,6 +457,19 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var results = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
if (caseSensitive)
|
||||
{
|
||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x, serializerOption).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.EquipmentRecord, Description = $"{x.Description}" }));
|
||||
}
|
||||
else
|
||||
{
|
||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x, serializerOption).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.EquipmentRecord, Description = $"{x.Description}" }));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return PartialView("_GlobalSearchResult", searchResults);
|
||||
@ -537,6 +558,13 @@ namespace CarCareTracker.Controllers
|
||||
searchResults.AddRange(results.Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.InspectionRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var results = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
results.RemoveAll(x => !x.Tags.Any(y => tagsFilter.Contains(y)));
|
||||
searchResults.AddRange(results.Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.EquipmentRecord, Description = $"{x.Description}" }));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return PartialView("_MapSearchResult", searchResults);
|
||||
@ -606,6 +634,11 @@ namespace CarCareTracker.Controllers
|
||||
var results = _inspectionRecordDataAccess.GetInspectionRecordsByVehicleId(vehicleId);
|
||||
return Json(OperationResponse.Conditional(results.Any(x => x.Id == recordId), "", "Inspection Record Not Found"));
|
||||
}
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var results = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(vehicleId);
|
||||
return Json(OperationResponse.Conditional(results.Any(x => x.Id == recordId), "", "Equipment Record Not Found"));
|
||||
}
|
||||
}
|
||||
return Json(OperationResponse.Failed("Record Not Found"));
|
||||
}
|
||||
@ -765,6 +798,9 @@ namespace CarCareTracker.Controllers
|
||||
case ImportMode.InspectionRecord:
|
||||
result = DeleteInspectionRecordWithChecks(recordId);
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
result = DeleteEquipmentRecordWithChecks(recordId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result.Success)
|
||||
@ -979,6 +1015,18 @@ namespace CarCareTracker.Controllers
|
||||
result = _inspectionRecordTemplateDataAccess.SaveInspectionReportTemplateToVehicle(existingRecord);
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var existingRecord = _equipmentRecordDataAccess.GetEquipmentRecordById(recordId);
|
||||
//security check
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId, HouseholdPermission.Edit))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Access Denied"));
|
||||
}
|
||||
existingRecord.Id = default;
|
||||
result = _equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(existingRecord);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
@ -1084,6 +1132,7 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(recordId);
|
||||
existingRecord.Id = default;
|
||||
existingRecord.EquipmentRecordId = new List<int>();
|
||||
foreach (int vehicleId in vehicleIds)
|
||||
{
|
||||
existingRecord.VehicleId = vehicleId;
|
||||
@ -1127,6 +1176,17 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
{
|
||||
var existingRecord = _equipmentRecordDataAccess.GetEquipmentRecordById(recordId);
|
||||
existingRecord.Id = default;
|
||||
foreach (int vehicleId in vehicleIds)
|
||||
{
|
||||
existingRecord.VehicleId = vehicleId;
|
||||
result = _equipmentRecordDataAccess.SaveEquipmentRecordToVehicle(existingRecord);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
@ -1439,7 +1499,6 @@ namespace CarCareTracker.Controllers
|
||||
stickerViewModel.GenericRecords.Add(_serviceRecordDataAccess.GetServiceRecordById(recordId));
|
||||
recordsAdded++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportMode.RepairRecord:
|
||||
@ -1475,7 +1534,6 @@ namespace CarCareTracker.Controllers
|
||||
});
|
||||
recordsAdded++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportMode.TaxRecord:
|
||||
@ -1517,7 +1575,6 @@ namespace CarCareTracker.Controllers
|
||||
});
|
||||
recordsAdded++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportMode.OdometerRecord:
|
||||
@ -1534,7 +1591,6 @@ namespace CarCareTracker.Controllers
|
||||
});
|
||||
recordsAdded++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportMode.ReminderRecord:
|
||||
@ -1544,7 +1600,6 @@ namespace CarCareTracker.Controllers
|
||||
stickerViewModel.ReminderRecords.Add(_reminderRecordDataAccess.GetReminderRecordById(recordId));
|
||||
recordsAdded++;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ImportMode.PlanRecord:
|
||||
@ -1573,6 +1628,15 @@ namespace CarCareTracker.Controllers
|
||||
recordsAdded++;
|
||||
}
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
foreach (int recordId in recordIds)
|
||||
{
|
||||
var record = _equipmentRecordDataAccess.GetEquipmentRecordById(recordId);
|
||||
stickerViewModel.EquipmentRecords.Add(_equipmentHelper.GetEquipmentRecordStickerViewModel(record, odometerRecords));
|
||||
recordsAdded++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (recordsAdded > 0)
|
||||
{
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
PlanRecord = 9,
|
||||
OdometerRecord = 10,
|
||||
VehicleRecord = 11,
|
||||
InspectionRecord = 12
|
||||
InspectionRecord = 12,
|
||||
EquipmentRecord = 13
|
||||
}
|
||||
}
|
||||
|
||||
54
External/Implementations/Litedb/EquipmentRecordDataAccess.cs
vendored
Normal file
54
External/Implementations/Litedb/EquipmentRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Helper;
|
||||
using CarCareTracker.Models;
|
||||
using LiteDB;
|
||||
|
||||
namespace CarCareTracker.External.Implementations
|
||||
{
|
||||
public class EquipmentRecordDataAccess : IEquipmentRecordDataAccess
|
||||
{
|
||||
private ILiteDBHelper _liteDB { get; set; }
|
||||
private static string tableName = "equipmentrecords";
|
||||
public EquipmentRecordDataAccess(ILiteDBHelper liteDB)
|
||||
{
|
||||
_liteDB = liteDB;
|
||||
}
|
||||
public List<EquipmentRecord> GetEquipmentRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<EquipmentRecord>(tableName);
|
||||
var equipmentRecords = table.Find(Query.EQ(nameof(EquipmentRecord.VehicleId), vehicleId));
|
||||
return equipmentRecords.ToList() ?? new List<EquipmentRecord>();
|
||||
}
|
||||
public EquipmentRecord GetEquipmentRecordById(int equipmentRecordId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<EquipmentRecord>(tableName);
|
||||
return table.FindById(equipmentRecordId);
|
||||
}
|
||||
public bool DeleteEquipmentRecordById(int equipmentRecordId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<EquipmentRecord>(tableName);
|
||||
table.Delete(equipmentRecordId);
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
public bool SaveEquipmentRecordToVehicle(EquipmentRecord equipmentRecord)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<EquipmentRecord>(tableName);
|
||||
table.Upsert(equipmentRecord);
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
public bool DeleteAllEquipmentRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<EquipmentRecord>(tableName);
|
||||
var equipmentRecords = table.DeleteMany(Query.EQ(nameof(EquipmentRecord.VehicleId), vehicleId));
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
161
External/Implementations/Postgres/EquipmentRecordDataAccess.cs
vendored
Normal file
161
External/Implementations/Postgres/EquipmentRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Models;
|
||||
using Npgsql;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CarCareTracker.External.Implementations
|
||||
{
|
||||
public class PGEquipmentRecordDataAccess : IEquipmentRecordDataAccess
|
||||
{
|
||||
private NpgsqlDataSource pgDataSource;
|
||||
private readonly ILogger<PGEquipmentRecordDataAccess> _logger;
|
||||
private static string tableName = "equipmentrecords";
|
||||
public PGEquipmentRecordDataAccess(IConfiguration config, ILogger<PGEquipmentRecordDataAccess> logger)
|
||||
{
|
||||
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
|
||||
|
||||
_logger = logger;
|
||||
try
|
||||
{
|
||||
//create table if not exist.
|
||||
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
|
||||
using (var ctext = pgDataSource.CreateCommand(initCMD))
|
||||
{
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
public List<EquipmentRecord> GetEquipmentRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
|
||||
var results = new List<EquipmentRecord>();
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
EquipmentRecord equipmentRecord = JsonSerializer.Deserialize<EquipmentRecord>(reader["data"] as string);
|
||||
results.Add(equipmentRecord);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return new List<EquipmentRecord>();
|
||||
}
|
||||
}
|
||||
public EquipmentRecord GetEquipmentRecordById(int equipmentRecordId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
|
||||
var result = new EquipmentRecord();
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", equipmentRecordId);
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
EquipmentRecord equipmentRecord = JsonSerializer.Deserialize<EquipmentRecord>(reader["data"] as string);
|
||||
result = equipmentRecord;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return new EquipmentRecord();
|
||||
}
|
||||
}
|
||||
public bool DeleteEquipmentRecordById(int equipmentRecordId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", equipmentRecordId);
|
||||
return ctext.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool SaveEquipmentRecordToVehicle(EquipmentRecord equipmentRecord)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (equipmentRecord.Id == default)
|
||||
{
|
||||
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("vehicleId", equipmentRecord.VehicleId);
|
||||
ctext.Parameters.AddWithValue("data", "{}");
|
||||
equipmentRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
|
||||
//update json data
|
||||
if (equipmentRecord.Id != default)
|
||||
{
|
||||
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
|
||||
using (var ctextU = pgDataSource.CreateCommand(cmdU))
|
||||
{
|
||||
var serializedData = JsonSerializer.Serialize(equipmentRecord);
|
||||
ctextU.Parameters.AddWithValue("id", equipmentRecord.Id);
|
||||
ctextU.Parameters.AddWithValue("data", serializedData);
|
||||
return ctextU.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
return equipmentRecord.Id != default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
var serializedData = JsonSerializer.Serialize(equipmentRecord);
|
||||
ctext.Parameters.AddWithValue("id", equipmentRecord.Id);
|
||||
ctext.Parameters.AddWithValue("data", serializedData);
|
||||
return ctext.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool DeleteAllEquipmentRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", vehicleId);
|
||||
ctext.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
External/Interfaces/IEquipmentRecordDataAccess.cs
vendored
Normal file
13
External/Interfaces/IEquipmentRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
using CarCareTracker.Models;
|
||||
|
||||
namespace CarCareTracker.External.Interfaces
|
||||
{
|
||||
public interface IEquipmentRecordDataAccess
|
||||
{
|
||||
public List<EquipmentRecord> GetEquipmentRecordsByVehicleId(int vehicleId);
|
||||
public EquipmentRecord GetEquipmentRecordById(int serviceRecordId);
|
||||
public bool DeleteEquipmentRecordById(int equipmentRecordId);
|
||||
public bool SaveEquipmentRecordToVehicle(EquipmentRecord serviceRecord);
|
||||
public bool DeleteAllEquipmentRecordsByVehicleId(int vehicleId);
|
||||
}
|
||||
}
|
||||
46
Helper/EquipmentHelper.cs
Normal file
46
Helper/EquipmentHelper.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using CarCareTracker.Models;
|
||||
|
||||
namespace CarCareTracker.Helper
|
||||
{
|
||||
public interface IEquipmentHelper
|
||||
{
|
||||
List<EquipmentRecordViewModel> GetEquipmentRecordViewModels(List<EquipmentRecord> equipmentRecords, List<OdometerRecord> odometerRecords);
|
||||
EquipmentRecordStickerViewModel GetEquipmentRecordStickerViewModel(EquipmentRecord equipmentRecord, List<OdometerRecord> odometerRecords);
|
||||
}
|
||||
public class EquipmentHelper : IEquipmentHelper
|
||||
{
|
||||
public List<EquipmentRecordViewModel> GetEquipmentRecordViewModels(List<EquipmentRecord> equipmentRecords, List<OdometerRecord> odometerRecords)
|
||||
{
|
||||
List<EquipmentRecordViewModel> result = new List<EquipmentRecordViewModel>();
|
||||
foreach (EquipmentRecord equipmentRecord in equipmentRecords)
|
||||
{
|
||||
var distanceTraveled = odometerRecords.Where(x => x.EquipmentRecordId.Contains(equipmentRecord.Id)).Sum(y => y.DistanceTraveled);
|
||||
result.Add(new EquipmentRecordViewModel
|
||||
{
|
||||
Id = equipmentRecord.Id,
|
||||
DistanceTraveled = distanceTraveled,
|
||||
Description = equipmentRecord.Description,
|
||||
IsEquipped = equipmentRecord.IsEquipped,
|
||||
VehicleId = equipmentRecord.VehicleId,
|
||||
ExtraFields = equipmentRecord.ExtraFields,
|
||||
Files = equipmentRecord.Files,
|
||||
Notes = equipmentRecord.Notes,
|
||||
Tags = equipmentRecord.Tags
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public EquipmentRecordStickerViewModel GetEquipmentRecordStickerViewModel(EquipmentRecord equipmentRecord, List<OdometerRecord> odometerRecords)
|
||||
{
|
||||
var linkedOdometerRecords = odometerRecords.Where(x => x.EquipmentRecordId.Contains(equipmentRecord.Id)).ToList();
|
||||
return new EquipmentRecordStickerViewModel {
|
||||
Description = equipmentRecord.Description,
|
||||
IsEquipped = equipmentRecord.IsEquipped,
|
||||
Notes = equipmentRecord.Notes,
|
||||
ExtraFields = equipmentRecord.ExtraFields,
|
||||
Distance = linkedOdometerRecords.Sum(x=>x.DistanceTraveled),
|
||||
OdometerRecords = linkedOdometerRecords
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -453,6 +453,8 @@ namespace CarCareTracker.Helper
|
||||
return "bi-bell";
|
||||
case ImportMode.InspectionRecord:
|
||||
return "bi-clipboard-check";
|
||||
case ImportMode.EquipmentRecord:
|
||||
return "bi-disc";
|
||||
default:
|
||||
return "bi-file-bar-graph";
|
||||
}
|
||||
@ -701,6 +703,33 @@ namespace CarCareTracker.Helper
|
||||
_csv.NextRecord();
|
||||
}
|
||||
}
|
||||
public static void WriteEquipmentRecordExportModel(CsvWriter _csv, IEnumerable<EquipmentRecordExportModel> genericRecords)
|
||||
{
|
||||
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
|
||||
//write headers
|
||||
_csv.WriteField(nameof(EquipmentRecordExportModel.Description));
|
||||
_csv.WriteField(nameof(EquipmentRecordExportModel.Notes));
|
||||
_csv.WriteField(nameof(EquipmentRecordExportModel.Tags));
|
||||
_csv.WriteField(nameof(EquipmentRecordExportModel.IsEquipped));
|
||||
foreach (string extraHeader in extraHeaders)
|
||||
{
|
||||
_csv.WriteField($"extrafield_{extraHeader}");
|
||||
}
|
||||
_csv.NextRecord();
|
||||
foreach (EquipmentRecordExportModel genericRecord in genericRecords)
|
||||
{
|
||||
_csv.WriteField(genericRecord.Description);
|
||||
_csv.WriteField(genericRecord.Notes);
|
||||
_csv.WriteField(genericRecord.Tags);
|
||||
_csv.WriteField(genericRecord.IsEquipped);
|
||||
foreach (string extraHeader in extraHeaders)
|
||||
{
|
||||
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
|
||||
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
|
||||
}
|
||||
_csv.NextRecord();
|
||||
}
|
||||
}
|
||||
public static void WriteAttachmentExportModel(CsvWriter _csv, IEnumerable<AttachmentExportModel> genericRecords)
|
||||
{
|
||||
//write headers
|
||||
|
||||
@ -12,10 +12,12 @@ namespace CarCareTracker.Logic
|
||||
public class OdometerLogic: IOdometerLogic
|
||||
{
|
||||
private readonly IOdometerRecordDataAccess _odometerRecordDataAccess;
|
||||
private readonly IEquipmentRecordDataAccess _equipmentRecordDataAccess;
|
||||
private readonly ILogger<IOdometerLogic> _logger;
|
||||
public OdometerLogic(IOdometerRecordDataAccess odometerRecordDataAccess, ILogger<IOdometerLogic> logger)
|
||||
public OdometerLogic(IOdometerRecordDataAccess odometerRecordDataAccess, IEquipmentRecordDataAccess equipmentRecordDataAccess, ILogger<IOdometerLogic> logger)
|
||||
{
|
||||
_odometerRecordDataAccess = odometerRecordDataAccess;
|
||||
_equipmentRecordDataAccess = equipmentRecordDataAccess;
|
||||
_logger = logger;
|
||||
}
|
||||
public int GetLastOdometerRecordMileage(int vehicleId, List<OdometerRecord> odometerRecords)
|
||||
@ -39,7 +41,13 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
var lastReportedMileage = GetLastOdometerRecordMileage(odometer.VehicleId, new List<OdometerRecord>());
|
||||
odometer.InitialMileage = lastReportedMileage != default ? lastReportedMileage : odometer.Mileage;
|
||||
|
||||
//add equipment
|
||||
var equipmentRecords = _equipmentRecordDataAccess.GetEquipmentRecordsByVehicleId(odometer.VehicleId);
|
||||
var equippedEquipment = equipmentRecords.Where(x => x.IsEquipped);
|
||||
if (equippedEquipment.Any())
|
||||
{
|
||||
odometer.EquipmentRecordId = equippedEquipment.Select(x => x.Id).ToList();
|
||||
}
|
||||
var result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometer);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ namespace CarCareTracker.MapProfile
|
||||
Map(m => m.Type).Name(["type"]);
|
||||
Map(m => m.Priority).Name(["priority"]);
|
||||
Map(m => m.Tags).Name(["tags"]);
|
||||
Map(m => m.IsEquipped).Name(["isequipped"]);
|
||||
Map(m => m.ExtraFields).Convert(row =>
|
||||
{
|
||||
var attributes = new Dictionary<string, string>();
|
||||
|
||||
14
Models/EquipmentRecord/EquipmentRecord.cs
Normal file
14
Models/EquipmentRecord/EquipmentRecord.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class EquipmentRecord
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int VehicleId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool IsEquipped { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
}
|
||||
}
|
||||
28
Models/EquipmentRecord/EquipmentRecordInput.cs
Normal file
28
Models/EquipmentRecord/EquipmentRecordInput.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class EquipmentRecordInput
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int VehicleId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool IsEquipped { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<OdometerRecord> OdometerRecords { get; set; } = new List<OdometerRecord>();
|
||||
public EquipmentRecord ToEquipmentRecord() {
|
||||
return new EquipmentRecord
|
||||
{
|
||||
Id = Id,
|
||||
VehicleId = VehicleId,
|
||||
Description = Description,
|
||||
IsEquipped = IsEquipped,
|
||||
Notes = Notes,
|
||||
Files = Files,
|
||||
Tags = Tags,
|
||||
ExtraFields = ExtraFields
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Models/EquipmentRecord/EquipmentRecordStickerViewModel.cs
Normal file
12
Models/EquipmentRecord/EquipmentRecordStickerViewModel.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class EquipmentRecordStickerViewModel
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public bool IsEquipped { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public int Distance { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<OdometerRecord> OdometerRecords { get; set; } = new List<OdometerRecord>();
|
||||
}
|
||||
}
|
||||
15
Models/EquipmentRecord/EquipmentRecordViewModel.cs
Normal file
15
Models/EquipmentRecord/EquipmentRecordViewModel.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class EquipmentRecordViewModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int VehicleId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool IsEquipped { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public int DistanceTraveled { get; set; }
|
||||
}
|
||||
}
|
||||
@ -12,5 +12,6 @@
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<int> EquipmentRecordId { get; set; } = new List<int>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,5 +4,7 @@
|
||||
{
|
||||
public List<int> RecordIds { get; set; } = new List<int>();
|
||||
public OdometerRecord EditRecord { get; set; } = new OdometerRecord();
|
||||
public bool EditEquipment { get; set; } = false;
|
||||
public List<EquipmentRecord> EquipmentRecords { get; set; } = new List<EquipmentRecord>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,19 @@
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public OdometerRecord ToOdometerRecord() { return new OdometerRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Mileage = Mileage, Notes = Notes, Files = Files, Tags = Tags, ExtraFields = ExtraFields, InitialMileage = InitialMileage }; }
|
||||
public List<int> EquipmentRecordId { get; set; } = new List<int>();
|
||||
public List<EquipmentRecord> EquipmentRecords { get; set; } = new List<EquipmentRecord>();
|
||||
public OdometerRecord ToOdometerRecord() { return new OdometerRecord {
|
||||
Id = Id,
|
||||
VehicleId = VehicleId,
|
||||
Date = DateTime.Parse(Date),
|
||||
Mileage = Mileage,
|
||||
Notes = Notes,
|
||||
Files = Files,
|
||||
Tags = Tags,
|
||||
ExtraFields = ExtraFields,
|
||||
InitialMileage = InitialMileage,
|
||||
EquipmentRecordId = EquipmentRecordId
|
||||
}; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ namespace CarCareTracker.Models
|
||||
public string PartSupplier { get; set; }
|
||||
public string PartQuantity { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public string IsEquipped { get; set; }
|
||||
public Dictionary<string,string> ExtraFields {get;set;}
|
||||
}
|
||||
|
||||
@ -81,6 +82,7 @@ namespace CarCareTracker.Models
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
public string EquipmentRecordId { get; set; }
|
||||
}
|
||||
public class TaxRecordExportModel
|
||||
{
|
||||
@ -119,6 +121,35 @@ namespace CarCareTracker.Models
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class EquipmentRecordExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
[JsonConverter(typeof(FromBoolOptional))]
|
||||
public string IsEquipped { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
/// <summary>
|
||||
/// Only used for the API GET Method
|
||||
/// </summary>
|
||||
public class EquipmentRecordAPIExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
[JsonConverter(typeof(FromBoolOptional))]
|
||||
public string IsEquipped { get; set; }
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
public string DistanceTraveled { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
|
||||
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
|
||||
}
|
||||
public class ReminderExportModel
|
||||
{
|
||||
[JsonConverter(typeof(FromIntOptional))]
|
||||
|
||||
@ -8,5 +8,6 @@
|
||||
public List<GenericRecord> GenericRecords { get; set; } = new List<GenericRecord>();
|
||||
public List<SupplyRecord> SupplyRecords { get; set; } = new List<SupplyRecord>();
|
||||
public List<InspectionRecord> InspectionRecords { get; set; } = new List<InspectionRecord>();
|
||||
public List<EquipmentRecordStickerViewModel> EquipmentRecords { get; set; } = new List<EquipmentRecordStickerViewModel>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +168,21 @@ namespace CarCareTracker.Models
|
||||
Action = $"{userName} {GetFriendlyActionType(actionType)} Description: {taxRecord.Description}"
|
||||
};
|
||||
}
|
||||
public static WebHookPayload FromEquipmentRecord(EquipmentRecord equipmentRecord, string actionType, string userName)
|
||||
{
|
||||
Dictionary<string, string> payloadDictionary = new Dictionary<string, string>();
|
||||
payloadDictionary.Add("user", userName);
|
||||
payloadDictionary.Add("description", equipmentRecord.Description);
|
||||
payloadDictionary.Add("vehicleId", equipmentRecord.VehicleId.ToString());
|
||||
return new WebHookPayload
|
||||
{
|
||||
Type = actionType,
|
||||
Data = payloadDictionary,
|
||||
VehicleId = equipmentRecord.VehicleId.ToString(),
|
||||
Username = userName,
|
||||
Action = $"{userName} {GetFriendlyActionType(actionType)} Description: {equipmentRecord.Description}"
|
||||
};
|
||||
}
|
||||
public static WebHookPayload FromPlanRecord(PlanRecord planRecord, string actionType, string userName)
|
||||
{
|
||||
Dictionary<string, string> payloadDictionary = new Dictionary<string, string>();
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
ImportMode.TaxRecord,
|
||||
ImportMode.NoteRecord,
|
||||
ImportMode.InspectionRecord,
|
||||
ImportMode.EquipmentRecord,
|
||||
ImportMode.ReminderRecord
|
||||
};
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ if (!string.IsNullOrWhiteSpace(builder.Configuration["POSTGRES_CONNECTION"])){
|
||||
builder.Services.AddSingleton<IExtraFieldDataAccess, PGExtraFieldDataAccess>();
|
||||
builder.Services.AddSingleton<IInspectionRecordDataAccess, PGInspectionRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, PGInspectionRecordTemplateDataAccess>();
|
||||
builder.Services.AddSingleton<IEquipmentRecordDataAccess, PGEquipmentRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IUserHouseholdDataAccess, PGUserHouseholdDataAccess>();
|
||||
}
|
||||
else
|
||||
@ -83,12 +84,14 @@ else
|
||||
builder.Services.AddSingleton<IExtraFieldDataAccess, ExtraFieldDataAccess>();
|
||||
builder.Services.AddSingleton<IInspectionRecordDataAccess, InspectionRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, InspectionRecordTemplateDataAccess>();
|
||||
builder.Services.AddSingleton<IEquipmentRecordDataAccess, EquipmentRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IUserHouseholdDataAccess, UserHouseholdDataAccess>();
|
||||
}
|
||||
|
||||
//configure helpers
|
||||
builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
||||
builder.Services.AddSingleton<IGasHelper, GasHelper>();
|
||||
builder.Services.AddSingleton<IEquipmentHelper, EquipmentHelper>();
|
||||
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
||||
builder.Services.AddSingleton<IReportHelper, ReportHelper>();
|
||||
builder.Services.AddSingleton<IConfigHelper, ConfigHelper>();
|
||||
|
||||
@ -214,6 +214,7 @@
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
equipmentRecordId - equipment ids separated by space(optional) <br/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@ -237,6 +238,7 @@
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
|
||||
equipmentRecordId - equipment ids separated by space(optional) <br />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
<!option @(Model.Id == (int)ImportMode.PlanRecord ? "selected" : "") value="@((int)ImportMode.PlanRecord)">@translator.Translate(userLanguage, "Planner")</!option>
|
||||
<!option @(Model.Id == (int)ImportMode.OdometerRecord ? "selected" : "") value="@((int)ImportMode.OdometerRecord)">@translator.Translate(userLanguage, "Odometer")</!option>
|
||||
<!option @(Model.Id == (int)ImportMode.NoteRecord ? "selected" : "") value="@((int)ImportMode.NoteRecord)">@translator.Translate(userLanguage, "Notes")</!option>
|
||||
<!option @(Model.Id == (int)ImportMode.EquipmentRecord ? "selected" : "") value="@((int)ImportMode.EquipmentRecord)">@translator.Translate(userLanguage, "Equipment")</!option>
|
||||
<!option @(Model.Id == (int)ImportMode.VehicleRecord ? "selected" : "") value="@((int)ImportMode.VehicleRecord)">@translator.Translate(userLanguage, "Vehicle")</!option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -149,6 +149,9 @@
|
||||
case ImportMode.InspectionRecord:
|
||||
<li><a class="context-menu-active-single dropdown-item @StaticHelper.DefaultActiveTab(userConfig, ImportMode.InspectionRecord)" href="#" onclick="viewVehicleWithTab(selectedVehicles, 'inspection')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Inspections")</span><i class="bi bi-clipboard-check"></i></div></a></li>
|
||||
break;
|
||||
case ImportMode.EquipmentRecord:
|
||||
<li><a class="context-menu-active-single dropdown-item @StaticHelper.DefaultActiveTab(userConfig, ImportMode.EquipmentRecord)" href="#" onclick="viewVehicleWithTab(selectedVehicles, 'equipment')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Equipment")</span><i class="bi bi-disc"></i></div></a></li>
|
||||
break;
|
||||
case ImportMode.ReminderRecord:
|
||||
<li><a class="context-menu-active-single dropdown-item @StaticHelper.DefaultActiveTab(userConfig, ImportMode.ReminderRecord)" href="#" onclick="viewVehicleWithTab(selectedVehicles, 'reminder')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Reminders")</span><i class="bi bi-bell"></i></div></a></li>
|
||||
break;
|
||||
|
||||
@ -131,14 +131,14 @@
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<input onChange="updateSettings()" disabled class="form-check-input me-1" type="checkbox" value="Dashboard" id="dashboardTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.Dashboard) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="dashboardTab">@translator.Translate(userLanguage, "Dashboard")</label>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<input onChange="updateSettings()" class="form-check-input me-1" type="checkbox" value="ServiceRecord" id="serviceRecordTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.ServiceRecord) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="serviceRecordTab">@translator.Translate(userLanguage, "Service Records")</label>
|
||||
</li>
|
||||
<li class="list-group-item d-none">
|
||||
<input onChange="updateSettings()" disabled class="form-check-input me-1" type="checkbox" value="Dashboard" id="dashboardTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.Dashboard) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="dashboardTab">@translator.Translate(userLanguage, "Dashboard")</label>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<input onChange="updateSettings()" class="form-check-input me-1" type="checkbox" value="RepairRecord" id="repairRecordTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.RepairRecord) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="repairRecordTab">@translator.Translate(userLanguage, "Repairs")</label>
|
||||
@ -155,6 +155,10 @@
|
||||
<input onChange="updateSettings()" class="form-check-input me-1" type="checkbox" value="OdometerRecord" id="odometerRecordTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.OdometerRecord) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="odometerRecordTab">@translator.Translate(userLanguage, "Odometer")</label>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<input onChange="updateSettings()" class="form-check-input me-1" type="checkbox" value="EquipmentRecord" id="equipmentRecordTab" @(Model.UserConfig.VisibleTabs.Contains(ImportMode.EquipmentRecord) ? "checked" : "")>
|
||||
<label class="form-check-label stretched-link" for="equipmentRecordTab">@translator.Translate(userLanguage, "Equipment")</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
@ -202,6 +206,7 @@
|
||||
<!option @(StaticHelper.DefaultTabSelected(Model.UserConfig, ImportMode.PlanRecord)) value="PlanRecord">@translator.Translate(userLanguage, "Planner")</!option>
|
||||
<!option @(StaticHelper.DefaultTabSelected(Model.UserConfig, ImportMode.OdometerRecord)) value="OdometerRecord">@translator.Translate(userLanguage, "Odometer")</!option>
|
||||
<!option @(StaticHelper.DefaultTabSelected(Model.UserConfig, ImportMode.InspectionRecord)) value="InspectionRecord">@translator.Translate(userLanguage, "Inspections")</!option>
|
||||
<!option @(StaticHelper.DefaultTabSelected(Model.UserConfig, ImportMode.EquipmentRecord)) value="EquipmentRecord">@translator.Translate(userLanguage, "Equipment")</!option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
@ -384,6 +389,7 @@
|
||||
<li class="list-group-item" style="order: @Model.UserConfig.TabOrder.FindIndex(x=>x == ImportMode.TaxRecord)" draggable="true" data-tab="@ImportMode.TaxRecord">@translator.Translate(userLanguage, "Taxes")</li>
|
||||
<li class="list-group-item" style="order: @Model.UserConfig.TabOrder.FindIndex(x=>x == ImportMode.NoteRecord)" draggable="true" data-tab="@ImportMode.NoteRecord">@translator.Translate(userLanguage, "Notes")</li>
|
||||
<li class="list-group-item" style="order: @Model.UserConfig.TabOrder.FindIndex(x => x == ImportMode.InspectionRecord)" draggable="true" data-tab="@ImportMode.InspectionRecord">@translator.Translate(userLanguage, "Inspections")</li>
|
||||
<li class="list-group-item" style="order: @Model.UserConfig.TabOrder.FindIndex(x => x == ImportMode.EquipmentRecord)" draggable="true" data-tab="@ImportMode.EquipmentRecord">@translator.Translate(userLanguage, "Equipment")</li>
|
||||
<li class="list-group-item" style="order: @Model.UserConfig.TabOrder.FindIndex(x=>x == ImportMode.ReminderRecord)" draggable="true" data-tab="@ImportMode.ReminderRecord">@translator.Translate(userLanguage, "Reminder")</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
74
Views/Vehicle/Equipment/_EquipmentRecordModal.cshtml
Normal file
74
Views/Vehicle/Equipment/_EquipmentRecordModal.cshtml
Normal file
@ -0,0 +1,74 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@model EquipmentRecordInput
|
||||
@{
|
||||
var isNew = Model.Id == 0;
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@(isNew ? translator.Translate(userLanguage, "Add New Equipment Record") : translator.Translate(userLanguage, "Edit Equipment Record"))<small style="display:none; @(isNew ? "" : "cursor:pointer;")" class="cached-banner ms-2 text-warning" onclick='@(isNew ? "" : $"showEditEquipmentRecordModal({Model.Id}, true)" )'>@translator.Translate(userLanguage, "Unsaved Changes")</small></h5>
|
||||
<button type="button" class="btn-close" onclick="hideAddEquipmentRecordModal()" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" onkeydown="handleEnter(this)">
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-12">
|
||||
<input type="text" id="workAroundInput" style="height:0px; width:0px; display:none;">
|
||||
<label for="equipmentRecordDescription">@translator.Translate(userLanguage, "Description")</label>
|
||||
<input type="text" id="equipmentRecordDescription" class="form-control" placeholder="@translator.Translate(userLanguage,"Description of equipment")" value="@Model.Description">
|
||||
<label for="equipmentRecordTag">@translator.Translate(userLanguage, "Tags(optional)")</label>
|
||||
<select multiple class="form-select" id="equipmentRecordTag">
|
||||
@foreach (string tag in Model.Tags)
|
||||
{
|
||||
<!option value="@tag">@tag</!option>
|
||||
}
|
||||
</select>
|
||||
@await Html.PartialAsync("_ExtraField", Model.ExtraFields)
|
||||
</div>
|
||||
<div class="col-md-6 col-12">
|
||||
<label for="equipmentRecordNotes">@translator.Translate(userLanguage, "Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>
|
||||
<textarea id="equipmentRecordNotes" class="form-control" rows="5">@Model.Notes</textarea>
|
||||
<div>
|
||||
<div class="form-check form-switch form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="equipmentEquippedCheck" checked="@Model.IsEquipped">
|
||||
<label class="form-check-label" for="equipmentEquippedCheck">@translator.Translate(userLanguage, "Is Equipped")</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@await Html.PartialAsync("_UploadedFiles", Model.Files)
|
||||
@await Html.PartialAsync("_FileUploader", Model.Files.Any())
|
||||
</div>
|
||||
<div id="filesPendingUpload"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@if (!isNew)
|
||||
{
|
||||
@if (Model.OdometerRecords.Any())
|
||||
{
|
||||
<button type="button" class="btn btn-warning" onclick="toggleOdometerHistory()"><i class="bi bi-speedometer"></i></button>
|
||||
}
|
||||
<button type="button" class="btn btn-danger" onclick="deleteEquipmentRecord(@Model.Id)" style="margin-right:auto;">@translator.Translate(userLanguage, "Delete")</button>
|
||||
}
|
||||
<button type="button" class="btn btn-secondary" onclick="hideAddEquipmentRecordModal()">@translator.Translate(userLanguage, "Cancel")</button>
|
||||
@if (isNew)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" onclick="saveEquipmentRecordToVehicle()">@translator.Translate(userLanguage, "Add New Equipment Record")</button>
|
||||
}
|
||||
else if (!isNew)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" onclick="saveEquipmentRecordToVehicle(true)">@translator.Translate(userLanguage, "Edit Equipment Record")</button>
|
||||
}
|
||||
</div>
|
||||
@await Html.PartialAsync("Odometer/_OdometerHistory", Model.OdometerRecords)
|
||||
<script>
|
||||
function getEquipmentRecordModelData() {
|
||||
return { id: @Model.Id}
|
||||
}
|
||||
</script>
|
||||
188
Views/Vehicle/Equipment/_EquipmentRecords.cshtml
Normal file
188
Views/Vehicle/Equipment/_EquipmentRecords.cshtml
Normal file
@ -0,0 +1,188 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var enableCsvImports = userConfig.EnableCsvImports;
|
||||
var hideZero = userConfig.HideZero;
|
||||
var recordTags = Model.SelectMany(x => x.Tags).Distinct();
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
var extraFields = new List<string>();
|
||||
if (userConfig.EnableExtraFieldColumns)
|
||||
{
|
||||
extraFields = Model.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct().ToList();
|
||||
}
|
||||
var userColumnPreferences = userConfig.UserColumnPreferences.Where(x => x.Tab == ImportMode.EquipmentRecord);
|
||||
}
|
||||
@model List<EquipmentRecordViewModel>
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="d-flex align-items-center flex-wrap">
|
||||
<span class="ms-2 badge bg-success" data-aggregate-type="count">@($"{translator.Translate(userLanguage,"# of Equipment Records")}: {Model.Count()}")</span>
|
||||
@foreach (string recordTag in recordTags)
|
||||
{
|
||||
<span onclick="filterTable('equipment-tab-pane', this)" class="user-select-none ms-2 rounded-pill badge bg-secondary tagfilter" style="cursor:pointer;">@recordTag</span>
|
||||
}
|
||||
<datalist id="tagList">
|
||||
@foreach (string recordTag in recordTags)
|
||||
{
|
||||
<!option value="@recordTag"></!option>
|
||||
}
|
||||
</datalist>
|
||||
</div>
|
||||
<div>
|
||||
@if (enableCsvImports)
|
||||
{
|
||||
<div class="btn-group">
|
||||
<button onclick="showAddEquipmentRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage,"Add Equipment 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('EquipmentRecord')">@translator.Translate(userLanguage,"Import via CSV")</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="exportVehicleData('EquipmentRecord')">@translator.Translate(userLanguage,"Export to CSV")</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="printTab()">@translator.Translate(userLanguage,"Print")</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="searchTableRows('equipment-tab-pane')">@translator.Translate(userLanguage, "Search")</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li>
|
||||
<div class="list-group-item">
|
||||
<input class="btn-check" type="checkbox" id="chkSelectMode">
|
||||
<label class="dropdown-item" for="chkSelectMode">@translator.Translate(userLanguage, "Select Mode")</label>
|
||||
</div>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><h6 class="dropdown-header">@translator.Translate(userLanguage, "Visible Columns")</h6></li>
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='description' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="chkCol_Description" checked>
|
||||
<label class="form-check-label stretched-link" for="chkCol_Description">@translator.Translate(userLanguage, "Description")</label>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='equipped' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="chkCol_Equipped" checked>
|
||||
<label class="form-check-label stretched-link" for="chkCol_Equipped">@translator.Translate(userLanguage, "Equipped")</label>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='distance' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="chkCol_Distance" checked>
|
||||
<label class="form-check-label stretched-link" for="chkCol_Distance">@translator.Translate(userLanguage, "Distance")</label>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='attachments' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="chkCol_Attachment">
|
||||
<label class="form-check-label stretched-link" for="chkCol_Attachment">@translator.Translate(userLanguage, "Attachments")</label>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='notes' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="chkCol_Notes" checked>
|
||||
<label class="form-check-label stretched-link" for="chkCol_Notes">@translator.Translate(userLanguage, "Notes")</label>
|
||||
</div>
|
||||
</li>
|
||||
@foreach (string extraFieldColumn in extraFields)
|
||||
{
|
||||
var elementId = Guid.NewGuid();
|
||||
<li class="dropdown-item" draggable="true" ondragstart="handleTableColumnDragStart(event)" ondragover="handleTableColumnDragOver(event)" ondragend="handleTableColumnDragEnd('EquipmentRecord')">
|
||||
<div class="list-group-item">
|
||||
<input class="form-check-input col-visible-toggle" data-column-toggle='@extraFieldColumn' onChange="showTableColumns(this, 'EquipmentRecord')" type="checkbox" id="@elementId">
|
||||
<label class="form-check-label stretched-link" for="@elementId">@extraFieldColumn</label>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button onclick="showAddEquipmentRecordModal()" class="btn btn-primary btn-md mt-1 mb-1"><i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage,"Add Equipment Record")</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row vehicleDetailTabContainer">
|
||||
<div class="col-12">
|
||||
<div class="row mt-2 showOnPrint">
|
||||
<div class="d-flex">
|
||||
<img src="@config.GetLogoUrl()" class="lubelogger-logo" />
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-3 col-xl-4 flex-grow-1 flex-shrink-1 text-truncate" data-column="description">@translator.Translate(userLanguage, "Description")</th>
|
||||
<th scope="col" class="col-2 flex-grow-1 flex-shrink-1 text-truncate" data-column="equipped" style="cursor:pointer;">@translator.Translate(userLanguage, "Equipped")</th>
|
||||
<th scope="col" class="col-2 flex-grow-1 flex-shrink-1 text-truncate" data-column="distance" onclick="toggleSort('equipment-tab-pane', this)" style="cursor:pointer;">@translator.Translate(userLanguage, "Distance")</th>
|
||||
<th scope="col" class="col-1 flex-grow-1 flex-shrink-1 text-truncate" style='display:none;' data-column="attachments">@translator.Translate(userLanguage, "Attachments")</th>
|
||||
<th scope="col" class="col-3 flex-grow-1 flex-shrink-1 text-truncate" data-column="notes">@translator.Translate(userLanguage, "Notes")</th>
|
||||
@foreach (string extraFieldColumn in extraFields)
|
||||
{
|
||||
<th scope="col" style='display:none;' class="col-2 flex-grow-1 flex-shrink-1 text-truncate" data-column="@extraFieldColumn">@extraFieldColumn</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (EquipmentRecordViewModel equipmentRecord in Model)
|
||||
{
|
||||
<tr class="d-flex user-select-none" style="cursor:pointer;" onmouseup="stopEvent()" ontouchstart="detectRowLongTouch(this)" ontouchend="detectRowTouchEndPremature(this)" data-rowId="@equipmentRecord.Id" oncontextmenu="showTableContextMenu(this)" onmousemove="rangeMouseMove(this)" onclick="handleTableRowClick(this, showEditEquipmentRecordModal,@equipmentRecord.Id)" data-tags='@string.Join(" ", equipmentRecord.Tags)'>
|
||||
<td class="col-3 col-xl-4 flex-grow-1 flex-shrink-1 text-truncate" data-column="description" data-record-type="cost">@equipmentRecord.Description</td>
|
||||
<td class="col-2 flex-grow-1 flex-shrink-1 text-truncate" data-column="equipped"><i class="bi bi-check-lg @(equipmentRecord.IsEquipped ? "" : "d-none")"></i></td>
|
||||
<td class="col-2 flex-grow-1 flex-shrink-1 text-truncate" data-column="distance">@(equipmentRecord.DistanceTraveled == default ? "---" : equipmentRecord.DistanceTraveled)</td>
|
||||
<td class="col-1 flex-grow-1 flex-shrink-1 text-truncate" style='display:none;' data-column="attachments">@await Html.PartialAsync("_AttachmentColumn", equipmentRecord.Files)</td>
|
||||
<td class="col-3 flex-grow-1 flex-shrink-1 text-truncate" data-column="notes">@StaticHelper.TruncateStrings(equipmentRecord.Notes)</td>
|
||||
@foreach (string extraFieldColumn in extraFields)
|
||||
{
|
||||
<td class="col-2 flex-grow-1 flex-shrink-1 text-truncate" style='display:none;' data-column="@extraFieldColumn">
|
||||
@{
|
||||
var extraFieldValue = equipmentRecord.ExtraFields.Where(x => x.Name == extraFieldColumn)?.FirstOrDefault()?.Value ?? "";
|
||||
if (!string.IsNullOrWhiteSpace(extraFieldValue) && Uri.IsWellFormedUriString(extraFieldValue, UriKind.Absolute))
|
||||
{
|
||||
<a href="@extraFieldValue" onclick="noPropagation()" target="_blank">@StaticHelper.TruncateStrings(extraFieldValue)</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
@extraFieldValue
|
||||
}
|
||||
}
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="d-flex">
|
||||
<td class="col-12 showOnPrint lubelogger-report-banner">
|
||||
@StaticHelper.ReportNote
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade" data-bs-focus="false" id="equipmentRecordModal" tabindex="-1" role="dialog" aria-hidden="true" onpaste="handleModalPaste(event)">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content" id="equipmentRecordModalContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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()"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Select All")</span><i class="bi bi-check-square"></i></div></a></li>
|
||||
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="clearSelectedRows()"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Deselect All")</span><i class="bi bi-x-square"></i></div></a></li>
|
||||
<li><hr class="context-menu-multiple dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="duplicateRecords(selectedRow, 'EquipmentRecord')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Duplicate")</span><i class="bi bi-copy"></i></div></a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="duplicateRecordsToOtherVehicles(selectedRow, 'EquipmentRecord')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Duplicate To Vehicle")</span><i class="bi bi-copy"></i></div></a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="printTabStickers(selectedRow, 'EquipmentRecord')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Print")</span><i class="bi bi-printer"></i></div></a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item text-danger" href="#" onclick="deleteRecords(selectedRow, 'EquipmentRecord')"><div class="d-flex justify-content-between"><span class="me-5">@translator.Translate(userLanguage, "Delete")</span><i class="bi bi-trash"></i></div></a></li>
|
||||
</ul>
|
||||
@if (userColumnPreferences.Any())
|
||||
{
|
||||
@await Html.PartialAsync("_UserColumnPreferences", userColumnPreferences)
|
||||
}
|
||||
23
Views/Vehicle/Equipment/_EquipmentSelector.cshtml
Normal file
23
Views/Vehicle/Equipment/_EquipmentSelector.cshtml
Normal file
@ -0,0 +1,23 @@
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@using CarCareTracker.Helper
|
||||
@model List<EquipmentRecord>
|
||||
|
||||
@{
|
||||
var userLanguage = config.GetUserConfig(User).UserLanguage;
|
||||
}
|
||||
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div id="equipmentSelector">
|
||||
<ul class="list-group">
|
||||
@foreach (EquipmentRecord equipmentRecord in Model)
|
||||
{
|
||||
<li class="list-group-item text-start">
|
||||
<input class="form-check-input" type="checkbox" value="@equipmentRecord.Id" id="equipmentCheck_@equipmentRecord.Id" checked="@equipmentRecord.IsEquipped">
|
||||
<label class="form-check-label stretched-link" for="equipmentCheck_@equipmentRecord.Id">@equipmentRecord.Description</label>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
@ -23,6 +23,7 @@
|
||||
<script src="~/js/planrecord.js?v=@StaticHelper.VersionNumber"></script>
|
||||
<script src="~/js/odometerrecord.js?v=@StaticHelper.VersionNumber"></script>
|
||||
<script src="~/js/inspectionrecord.js?v=@StaticHelper.VersionNumber"></script>
|
||||
<script src="~/js/equipmentrecord.js?v=@StaticHelper.VersionNumber"></script>
|
||||
<script src="~/lib/chart-js/chart.umd.js"></script>
|
||||
<script src="~/lib/drawdown/drawdown.js"></script>
|
||||
}
|
||||
@ -71,6 +72,9 @@
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x => x == ImportMode.InspectionRecord)">
|
||||
<button class="nav-link resizable-nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.InspectionRecord)" id="inspection-tab" data-bs-toggle="tab" data-bs-target="#inspection-tab-pane" type="button" role="tab" aria-selected="false"><i class="bi bi-clipboard-check"></i><span class="ms-2">@translator.Translate(userLanguage, "Inspections")</span></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x => x == ImportMode.EquipmentRecord)">
|
||||
<button class="nav-link resizable-nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.EquipmentRecord)" id="equipment-tab" data-bs-toggle="tab" data-bs-target="#equipment-tab-pane" type="button" role="tab" aria-selected="false"><i class="bi bi-disc"></i><span class="ms-2">@translator.Translate(userLanguage, "Equipment")</span></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x=>x == ImportMode.ReminderRecord)">
|
||||
<button class="nav-link resizable-nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.ReminderRecord)" id="reminder-tab" data-bs-toggle="tab" data-bs-target="#reminder-tab-pane" type="button" role="tab" aria-selected="false"><div class="reminderBellDiv" style="display:inline-flex;"><i class="reminderBell bi bi-bell"></i></div><span class="ms-2">@translator.Translate(userLanguage, "Reminders")</span></button>
|
||||
</li>
|
||||
@ -136,6 +140,9 @@
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x => x == ImportMode.InspectionRecord)">
|
||||
<button class="nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.InspectionRecord)" id="inspection-tab" data-bs-toggle="tab" data-bs-target="#inspection-tab-pane" type="button" role="tab" aria-selected="false"><span class="display-3 ms-2"><i class="bi bi-clipboard-check me-2"></i>@translator.Translate(userLanguage, "Inspections")</span></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x => x == ImportMode.EquipmentRecord)">
|
||||
<button class="nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.EquipmentRecord)" id="equipment-tab" data-bs-toggle="tab" data-bs-target="#equipment-tab-pane" type="button" role="tab" aria-selected="false"><span class="display-3 ms-2"><i class="bi bi-disc me-2"></i>@translator.Translate(userLanguage, "Equipment")</span></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation" style="order: @userConfig.TabOrder.FindIndex(x=>x == ImportMode.ReminderRecord)">
|
||||
<button class="nav-link @StaticHelper.DefaultActiveTab(userConfig, ImportMode.ReminderRecord)" id="reminder-tab" data-bs-toggle="tab" data-bs-target="#reminder-tab-pane" type="button" role="tab" aria-selected="false"><span class="display-3 ms-2"><div class="reminderBellDiv" style="display:inline-flex;"><i class="reminderBell bi bi-bell me-2"></i></div>@translator.Translate(userLanguage, "Reminders")</span></button>
|
||||
</li>
|
||||
@ -155,6 +162,7 @@
|
||||
<div class="tab-pane fade" id="plan-tab-pane" role="tabpanel" tabindex="0"></div>
|
||||
<div class="tab-pane fade" id="odometer-tab-pane" role="tabpanel" tabindex="0"></div>
|
||||
<div class="tab-pane fade" id="inspection-tab-pane" role="tabpanel" tabindex="0"></div>
|
||||
<div class="tab-pane fade" id="equipment-tab-pane" role="tabpanel" tabindex="0"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" data-bs-focus="false" id="editVehicleModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
|
||||
53
Views/Vehicle/Odometer/_OdometerHistory.cshtml
Normal file
53
Views/Vehicle/Odometer/_OdometerHistory.cshtml
Normal file
@ -0,0 +1,53 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@model List<OdometerRecord>
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div id="odometerHistoryModalContainer" class="d-none">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@translator.Translate(userLanguage, "Odometer History")</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12" style="max-height:50vh; overflow-y:auto;">
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Date")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Initial Odometer")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Odometer")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Distance")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (OdometerRecord odometerHistory in Model)
|
||||
{
|
||||
<tr class="d-flex">
|
||||
<td class="col-3">@StaticHelper.TruncateStrings(odometerHistory.Date.ToShortDateString())</td>
|
||||
<td class="col-3">@odometerHistory.InitialMileage</td>
|
||||
<td class="col-3">@odometerHistory.Mileage</td>
|
||||
<td class="col-3">@(odometerHistory.DistanceTraveled == default ? "---" : odometerHistory.DistanceTraveled)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="text-center">
|
||||
<h4>@translator.Translate(userLanguage, "No odometer history")</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@ -77,6 +77,11 @@
|
||||
<div class="col-md-6 col-12">
|
||||
<label for="odometerRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<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">@Model.Notes</textarea>
|
||||
@if (Model.EquipmentRecords.Any())
|
||||
{
|
||||
<label for="equipmentSelector">@translator.Translate(userLanguage, "Equipment")</label>
|
||||
@await Html.PartialAsync("Equipment/_EquipmentSelector", Model.EquipmentRecords)
|
||||
}
|
||||
<div>
|
||||
@await Html.PartialAsync("_UploadedFiles", Model.Files)
|
||||
@await Html.PartialAsync("_FileUploader", Model.Files.Any())
|
||||
|
||||
@ -31,6 +31,16 @@
|
||||
<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 class="@(Model.EquipmentRecords.Any() ? "" : "d-none")">
|
||||
<div class="form-check form-switch form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="equipmentEditCheck" onchange="toggleEquipmentEdit()">
|
||||
<label class="form-check-label" for="equipmentEditCheck">@translator.Translate(userLanguage, "Edit Equipment")</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="equipmentEditContainer" class="d-none">
|
||||
<label for="equipmentSelector">@translator.Translate(userLanguage, "Equipment")</label>
|
||||
@await Html.PartialAsync("Equipment/_EquipmentSelector", Model.EquipmentRecords)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -67,6 +67,8 @@
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
} else if (mode == "OdometerRecord") {
|
||||
getVehicleOdometerRecords(vehicleId);
|
||||
} else if (mode == "EquipmentRecord"){
|
||||
getVehicleEquipmentRecords(vehicleId);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
|
||||
@ -178,6 +178,101 @@
|
||||
</div>
|
||||
}
|
||||
<script>setMarkDownStickerNotes()</script>
|
||||
} else if (Model.EquipmentRecords.Any())
|
||||
{
|
||||
@foreach (EquipmentRecordStickerViewModel equipmentRecord in Model.EquipmentRecords)
|
||||
{
|
||||
<div class="d-flex flex-column recordSticker">
|
||||
<div class="d-flex">
|
||||
<img src="@config.GetLogoUrl()" class="lubelogger-logo" />
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<span class="display-6">@($"{Model.VehicleData.Year} {Model.VehicleData.Make} {Model.VehicleData.Model}")</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<span class="lead">@($"{StaticHelper.GetVehicleIdentifier(Model.VehicleData)}")</span>
|
||||
</li>
|
||||
@foreach (ExtraField extraField in Model.VehicleData.ExtraFields)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(extraField.Value))
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<span class="lead">@($"{extraField.Name}: {extraField.Value}")</span>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ul class="list-group">
|
||||
@if (!string.IsNullOrWhiteSpace(equipmentRecord.Description))
|
||||
{
|
||||
<li class="list-group-item">
|
||||
@($"{translator.Translate(userLanguage, "Description")}: {equipmentRecord.Description}")
|
||||
</li>
|
||||
}
|
||||
<li class="list-group-item">
|
||||
@($"{translator.Translate(userLanguage, "Distance")}: {equipmentRecord.Distance}")
|
||||
</li>
|
||||
@if (equipmentRecord.IsEquipped)
|
||||
{
|
||||
<li class="list-group-item">
|
||||
@($"{translator.Translate(userLanguage, "Equipped")}:")<i class="bi ms-2 bi-check-lg"></i>
|
||||
</li>
|
||||
}
|
||||
@foreach (ExtraField extraField in equipmentRecord.ExtraFields)
|
||||
{
|
||||
<li class="list-group-item">
|
||||
@($"{extraField.Name}: {extraField.Value}")
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
@if (equipmentRecord.OdometerRecords.Any())
|
||||
{
|
||||
<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">@translator.Translate(userLanguage, "Date")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Initial Odometer")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Odometer")</th>
|
||||
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Distance")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (OdometerRecord odometerHistory in equipmentRecord.OdometerRecords)
|
||||
{
|
||||
<tr class="d-flex">
|
||||
<td class="col-3">@StaticHelper.TruncateStrings(odometerHistory.Date.ToShortDateString())</td>
|
||||
<td class="col-3">@odometerHistory.InitialMileage</td>
|
||||
<td class="col-3">@odometerHistory.Mileage</td>
|
||||
<td class="col-3">@(odometerHistory.DistanceTraveled == default ? "---" : odometerHistory.DistanceTraveled)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
}
|
||||
<div class="row stickerNoteContainer">
|
||||
<div class="col-12">
|
||||
<div class="stickerNote ms-1 me-1 p-1">
|
||||
@(equipmentRecord.Notes)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<script>setMarkDownStickerNotes()</script>
|
||||
} else if (Model.SupplyRecords.Any()){
|
||||
@foreach (SupplyRecord supplyRecord in Model.SupplyRecords)
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
124
wwwroot/js/equipmentrecord.js
Normal file
124
wwwroot/js/equipmentrecord.js
Normal file
@ -0,0 +1,124 @@
|
||||
function showAddEquipmentRecordModal() {
|
||||
$.get('/Vehicle/GetAddEquipmentRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#equipmentRecordModalContent").html(data);
|
||||
initTagSelector($("#equipmentRecordTag"));
|
||||
$('#equipmentRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditEquipmentRecordModal(equipmentRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#equipmentRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getEquipmentRecordModelData().id;
|
||||
if (existingId == equipmentRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#equipmentRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetEquipmentRecordForEditById?equipmentRecordId=${equipmentRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#equipmentRecordModalContent").html(data);
|
||||
initTagSelector($("#equipmentRecordTag"));
|
||||
$('#equipmentRecordModal').modal('show');
|
||||
bindModalInputChanges('equipmentRecordModal');
|
||||
$('#equipmentRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("equipmentRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddEquipmentRecordModal() {
|
||||
$('#equipmentRecordModal').modal('hide');
|
||||
}
|
||||
function deleteEquipmentRecord(equipmentRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Equipment Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteEquipmentRecordById?equipmentRecordId=${equipmentRecordId}`, function (data) {
|
||||
if (data.success) {
|
||||
hideAddEquipmentRecordModal();
|
||||
successToast("Equipment Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleEquipmentRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveEquipmentRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateEquipmentRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveEquipmentRecordToVehicleId', { equipmentRecord: formValues }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(isEdit ? "Equipment Record Updated" : "Equipment Record Added.");
|
||||
hideAddEquipmentRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleEquipmentRecords(formValues.vehicleId);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateEquipmentRecordValues() {
|
||||
var equipmentDescription = $("#equipmentRecordDescription").val();
|
||||
var equipmentNotes = $("#equipmentRecordNotes").val();
|
||||
var equipmentTags = $("#equipmentRecordTag").val();
|
||||
var equipmentIsEquipped = $("#equipmentEquippedCheck").is(":checked");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var equipmentRecordId = getEquipmentRecordModelData().id;
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (equipmentDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#equipmentRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#equipmentRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: equipmentRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
description: equipmentDescription,
|
||||
isEquipped: equipmentIsEquipped,
|
||||
notes: equipmentNotes,
|
||||
files: uploadedFiles,
|
||||
tags: equipmentTags,
|
||||
extraFields: extraFields.extraFields
|
||||
}
|
||||
}
|
||||
function toggleOdometerHistory() {
|
||||
let odometerHistoryContainer = $("#odometerHistoryModalContainer");
|
||||
if (odometerHistoryContainer.hasClass('d-none')) {
|
||||
odometerHistoryContainer.removeClass('d-none');
|
||||
} else {
|
||||
odometerHistoryContainer.addClass('d-none');
|
||||
}
|
||||
}
|
||||
@ -98,6 +98,7 @@ function getAndValidateOdometerRecordValues() {
|
||||
var serviceTags = $("#odometerRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var odometerRecordId = getOdometerRecordModelData().id;
|
||||
var odometerEquipment = getSelectedEquipment();
|
||||
//Odometer Adjustments
|
||||
serviceMileage = GetAdjustedOdometer(odometerRecordId, serviceMileage);
|
||||
//validation
|
||||
@ -134,7 +135,8 @@ function getAndValidateOdometerRecordValues() {
|
||||
notes: serviceNotes,
|
||||
tags: serviceTags,
|
||||
files: uploadedFiles,
|
||||
extraFields: extraFields.extraFields
|
||||
extraFields: extraFields.extraFields,
|
||||
equipmentRecordId: odometerEquipment
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +158,8 @@ function editMultipleOdometerRecords(ids) {
|
||||
if (ids.length < 2) {
|
||||
return;
|
||||
}
|
||||
$.post('/Vehicle/GetOdometerRecordsEditModal', { recordIds: ids }, function (data) {
|
||||
let vehicleId = GetVehicleId().vehicleId;
|
||||
$.post('/Vehicle/GetOdometerRecordsEditModal', { recordIds: ids, vehicleId: vehicleId }, function (data) {
|
||||
if (data) {
|
||||
$("#odometerRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
@ -175,6 +178,8 @@ function saveMultipleOdometerRecordsToVehicle() {
|
||||
var odometerNotes = $("#odometerRecordNotes").val();
|
||||
var odometerTags = $("#odometerRecordTag").val();
|
||||
var odometerExtraFields = getAndValidateExtraFields();
|
||||
let odometerEditEquipment = $('#equipmentEditCheck').is(':checked');
|
||||
let odometerEquipment = getSelectedEquipment();
|
||||
//validation
|
||||
var hasError = false;
|
||||
if (odometerMileage.trim() != '' && (isNaN(odometerMileageToParse) || parseInt(odometerMileageToParse) < 0)) {
|
||||
@ -195,13 +200,15 @@ function saveMultipleOdometerRecordsToVehicle() {
|
||||
}
|
||||
var formValues = {
|
||||
recordIds: recordsToEdit,
|
||||
editEquipment: odometerEditEquipment,
|
||||
editRecord: {
|
||||
date: odometerDate,
|
||||
initialMileage: initialOdometerMileageToParse,
|
||||
mileage: odometerMileageToParse,
|
||||
notes: odometerNotes,
|
||||
tags: odometerTags,
|
||||
extraFields: odometerExtraFields.extraFields
|
||||
extraFields: odometerExtraFields.extraFields,
|
||||
equipmentRecordId: odometerEquipment
|
||||
}
|
||||
}
|
||||
$.post('/Vehicle/SaveMultipleOdometerRecords', { editModel: formValues }, function (data) {
|
||||
@ -434,4 +441,18 @@ function duplicateDistanceToOtherVehicles(ids) {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getSelectedEquipment() {
|
||||
var selectedEquipmentArray = [];
|
||||
$("#equipmentSelector :checked").map(function () {
|
||||
selectedEquipmentArray.push(this.value);
|
||||
});
|
||||
return selectedEquipmentArray;
|
||||
}
|
||||
function toggleEquipmentEdit() {
|
||||
if ($('#equipmentEditCheck').is(":checked")) {
|
||||
$('#equipmentEditContainer').removeClass('d-none');
|
||||
} else {
|
||||
$('#equipmentEditContainer').addClass('d-none');
|
||||
}
|
||||
}
|
||||
@ -860,7 +860,8 @@ function getSavedCSVExportParameters(mode) {
|
||||
}
|
||||
function exportVehicleData(mode) {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
if (mode != 'PlanRecord') {
|
||||
let bypassRecordTypes = ['PlanRecord', 'EquipmentRecord'];
|
||||
if (!bypassRecordTypes.includes(mode)) {
|
||||
$.get('/Vehicle/GetCSVExportParameters', function (paramData) {
|
||||
if (paramData) {
|
||||
Swal.fire({
|
||||
@ -1056,6 +1057,11 @@ function deleteRecords(ids, source) {
|
||||
case "InspectionRecord":
|
||||
friendlySource = "Inspection Records";
|
||||
refreshDataCallBack = getVehicleInspectionRecords;
|
||||
break;
|
||||
case "EquipmentRecord":
|
||||
friendlySource = "Equipment Records";
|
||||
refreshDataCallBack = getVehicleEquipmentRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
@ -1133,6 +1139,11 @@ function duplicateRecords(ids, source) {
|
||||
case "InspectionRecord":
|
||||
friendlySource = "Inspection Record";
|
||||
refreshDataCallBack = hideInspectionRecordTemplateModal;
|
||||
break;
|
||||
case "EquipmentRecord":
|
||||
friendlySource = "Equipment Records";
|
||||
refreshDataCallBack = getVehicleEquipmentRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
@ -1210,6 +1221,11 @@ function duplicateRecordsToOtherVehicles(ids, source) {
|
||||
case "InspectionRecord":
|
||||
friendlySource = "Inspection Record";
|
||||
refreshDataCallBack = hideInspectionRecordTemplateModal;
|
||||
break;
|
||||
case "EquipmentRecord":
|
||||
friendlySource = "Equipment Records";
|
||||
refreshDataCallBack = getVehicleEquipmentRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
$.get(`/Home/GetVehicleSelector?vehicleId=${GetVehicleId().vehicleId}`, function (data) {
|
||||
|
||||
@ -39,6 +39,9 @@
|
||||
case "inspection-tab":
|
||||
getVehicleInspectionRecords(vehicleId);
|
||||
break;
|
||||
case "equipment-tab":
|
||||
getVehicleEquipmentRecords(vehicleId);
|
||||
break;
|
||||
}
|
||||
$(`.lubelogger-tab #${e.target.id}`).addClass('active');
|
||||
$(`.lubelogger-mobile-nav #${e.target.id}`).addClass('active');
|
||||
@ -80,6 +83,9 @@
|
||||
case "inspection-tab":
|
||||
$("#inspection-tab-pane").html("");
|
||||
break;
|
||||
case "equipment-tab":
|
||||
$("#equipment-tab-pane").html("");
|
||||
break;
|
||||
}
|
||||
$(`.lubelogger-tab #${e.relatedTarget.id}`).removeClass('active');
|
||||
$(`.lubelogger-mobile-nav #${e.relatedTarget.id}`).removeClass('active');
|
||||
@ -187,6 +193,15 @@ function getVehicleInspectionRecords(vehicleId) {
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleEquipmentRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetEquipmentRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#equipment-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleReport(vehicleId) {
|
||||
$.get(`/Vehicle/GetReportPartialView?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
@ -800,6 +815,15 @@ function loadGlobalSearchResult(recordId, recordType) {
|
||||
}
|
||||
$('#inspection-tab').tab('show');
|
||||
waitForElement("#inspectionRecordModalContent", showEditInspectionRecordModal, recordId);
|
||||
break;
|
||||
case "EquipmentRecord":
|
||||
if ($('#equipment-tab').hasClass('d-none')) {
|
||||
errorToast(`${recordType} Tab Not Enabled`);
|
||||
return;
|
||||
}
|
||||
$('#equipment-tab').tab('show');
|
||||
waitForElement("#equipmentRecordModalContent", showEditEquipmentRecordModal, recordId);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
@ -851,5 +875,8 @@ function getDefaultTabName() {
|
||||
case "InspectionRecord":
|
||||
return 'inspection';
|
||||
break;
|
||||
case "EquipmentRecord":
|
||||
return 'equipment';
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user