first commit
This commit is contained in:
209
Controllers/Vehicle/GasController.cs
Normal file
209
Controllers/Vehicle/GasController.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetGasRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
//check if the user uses MPG or Liters per 100km.
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
bool useMPG = userConfig.UseMPG;
|
||||
bool useUKMPG = userConfig.UseUKMPG;
|
||||
var computedResults = _gasHelper.GetGasRecordViewModels(result, useMPG, useUKMPG);
|
||||
if (userConfig.UseDescending)
|
||||
{
|
||||
computedResults = computedResults.OrderByDescending(x => DateTime.Parse(x.Date)).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var vehicleIsElectric = vehicleData.IsElectric;
|
||||
var vehicleUseHours = vehicleData.UseHours;
|
||||
var viewModel = new GasRecordViewModelContainer()
|
||||
{
|
||||
UseKwh = vehicleIsElectric,
|
||||
UseHours = vehicleUseHours,
|
||||
GasRecords = computedResults
|
||||
};
|
||||
return PartialView("Gas/_Gas", viewModel);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveGasRecordToVehicleId(GasRecordInput gasRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), gasRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
if (gasRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = DateTime.Parse(gasRecord.Date),
|
||||
VehicleId = gasRecord.VehicleId,
|
||||
Mileage = gasRecord.Mileage,
|
||||
Notes = $"Auto Insert From Gas Record. {gasRecord.Notes}"
|
||||
});
|
||||
}
|
||||
gasRecord.Files = gasRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
var result = _gasRecordDataAccess.SaveGasRecordToVehicle(gasRecord.ToGasRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(gasRecord.ToGasRecord(), gasRecord.Id == default ? "gasrecord.add" : "gasrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetAddGasRecordPartialView(int vehicleId)
|
||||
{
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var vehicleIsElectric = vehicleData.IsElectric;
|
||||
var vehicleUseHours = vehicleData.UseHours;
|
||||
return PartialView("Gas/_GasModal", new GasRecordInputContainer() { UseKwh = vehicleIsElectric, UseHours = vehicleUseHours, GasRecord = new GasRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields } });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetGasRecordForEditById(int gasRecordId)
|
||||
{
|
||||
var result = _gasRecordDataAccess.GetGasRecordById(gasRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
var convertedResult = new GasRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Mileage = result.Mileage,
|
||||
VehicleId = result.VehicleId,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Files = result.Files,
|
||||
Gallons = result.Gallons,
|
||||
IsFillToFull = result.IsFillToFull,
|
||||
MissedFuelUp = result.MissedFuelUp,
|
||||
Notes = result.Notes,
|
||||
Tags = result.Tags,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields)
|
||||
};
|
||||
var vehicleData = _dataAccess.GetVehicleById(convertedResult.VehicleId);
|
||||
var vehicleIsElectric = vehicleData.IsElectric;
|
||||
var vehicleUseHours = vehicleData.UseHours;
|
||||
var viewModel = new GasRecordInputContainer()
|
||||
{
|
||||
UseKwh = vehicleIsElectric,
|
||||
UseHours = vehicleUseHours,
|
||||
GasRecord = convertedResult
|
||||
};
|
||||
return PartialView("Gas/_GasModal", viewModel);
|
||||
}
|
||||
private bool DeleteGasRecordWithChecks(int gasRecordId)
|
||||
{
|
||||
var existingRecord = _gasRecordDataAccess.GetGasRecordById(gasRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = _gasRecordDataAccess.DeleteGasRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteGasRecordById(int gasRecordId)
|
||||
{
|
||||
var result = DeleteGasRecordWithChecks(gasRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveUserGasTabPreferences(string gasUnit, string fuelMileageUnit)
|
||||
{
|
||||
var currentConfig = _config.GetUserConfig(User);
|
||||
currentConfig.PreferredGasUnit = gasUnit;
|
||||
currentConfig.PreferredGasMileageUnit = fuelMileageUnit;
|
||||
var result = _config.SaveUserConfig(User, currentConfig);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult GetGasRecordsEditModal(List<int> recordIds)
|
||||
{
|
||||
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields;
|
||||
return PartialView("Gas/_GasRecordsModal", new GasRecordEditModel { RecordIds = recordIds, EditRecord = new GasRecord { ExtraFields = extraFields } });
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveMultipleGasRecords(GasRecordEditModel editModel)
|
||||
{
|
||||
var dateIsEdited = editModel.EditRecord.Date != default;
|
||||
var mileageIsEdited = editModel.EditRecord.Mileage != default;
|
||||
var consumptionIsEdited = editModel.EditRecord.Gallons != default;
|
||||
var costIsEdited = editModel.EditRecord.Cost != default;
|
||||
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
|
||||
var tagsIsEdited = editModel.EditRecord.Tags.Any();
|
||||
var extraFieldIsEdited = editModel.EditRecord.ExtraFields.Any();
|
||||
//handle clear overrides
|
||||
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
|
||||
{
|
||||
editModel.EditRecord.Tags = new List<string>();
|
||||
}
|
||||
if (noteIsEdited && editModel.EditRecord.Notes == "---")
|
||||
{
|
||||
editModel.EditRecord.Notes = "";
|
||||
}
|
||||
bool result = false;
|
||||
foreach (int recordId in editModel.RecordIds)
|
||||
{
|
||||
var existingRecord = _gasRecordDataAccess.GetGasRecordById(recordId);
|
||||
if (dateIsEdited)
|
||||
{
|
||||
existingRecord.Date = editModel.EditRecord.Date;
|
||||
}
|
||||
if (consumptionIsEdited)
|
||||
{
|
||||
existingRecord.Gallons = editModel.EditRecord.Gallons;
|
||||
}
|
||||
if (costIsEdited)
|
||||
{
|
||||
existingRecord.Cost = editModel.EditRecord.Cost;
|
||||
}
|
||||
if (mileageIsEdited)
|
||||
{
|
||||
existingRecord.Mileage = editModel.EditRecord.Mileage;
|
||||
}
|
||||
if (noteIsEdited)
|
||||
{
|
||||
existingRecord.Notes = editModel.EditRecord.Notes;
|
||||
}
|
||||
if (tagsIsEdited)
|
||||
{
|
||||
existingRecord.Tags = editModel.EditRecord.Tags;
|
||||
}
|
||||
if (extraFieldIsEdited)
|
||||
{
|
||||
foreach (ExtraField extraField in editModel.EditRecord.ExtraFields)
|
||||
{
|
||||
if (existingRecord.ExtraFields.Any(x => x.Name == extraField.Name))
|
||||
{
|
||||
var insertIndex = existingRecord.ExtraFields.FindIndex(x => x.Name == extraField.Name);
|
||||
existingRecord.ExtraFields.RemoveAll(x => x.Name == extraField.Name);
|
||||
existingRecord.ExtraFields.Insert(insertIndex, extraField);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingRecord.ExtraFields.Add(extraField);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = _gasRecordDataAccess.SaveGasRecordToVehicle(existingRecord);
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
665
Controllers/Vehicle/ImportController.cs
Normal file
665
Controllers/Vehicle/ImportController.cs
Normal file
@@ -0,0 +1,665 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.MapProfile;
|
||||
using MotoVaultPro.Models;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[HttpGet]
|
||||
public IActionResult GetBulkImportModalPartialView(ImportMode mode)
|
||||
{
|
||||
return PartialView("_BulkDataImporter", mode);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GenerateCsvSample(ImportMode mode)
|
||||
{
|
||||
string uploadDirectory = "temp/";
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
var fileNameToExport = $"temp/{Guid.NewGuid()}.csv";
|
||||
var fullExportFilePath = _fileHelper.GetFullFilePath(fileNameToExport, false);
|
||||
switch (mode)
|
||||
{
|
||||
case ImportMode.ServiceRecord:
|
||||
case ImportMode.RepairRecord:
|
||||
case ImportMode.UpgradeRecord:
|
||||
{
|
||||
var exportData = new List<GenericRecordExportModel> { new GenericRecordExportModel
|
||||
{
|
||||
Date = DateTime.Now.ToShortDateString(),
|
||||
Description = "Test",
|
||||
Cost = 123.45M.ToString("C"),
|
||||
Notes = "Test Note",
|
||||
Odometer = 12345.ToString(),
|
||||
Tags = "test1 test2"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.GasRecord:
|
||||
{
|
||||
var exportData = new List<GasRecordExportModel> { new GasRecordExportModel
|
||||
{
|
||||
Date = DateTime.Now.ToShortDateString(),
|
||||
Odometer = 12345.ToString(),
|
||||
FuelConsumed = 12.34M.ToString(),
|
||||
Cost = 45.67M.ToString("C"),
|
||||
IsFillToFull = true.ToString(),
|
||||
MissedFuelUp = false.ToString(),
|
||||
Notes = "Test Note",
|
||||
Tags = "test1 test2"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteGasRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.OdometerRecord:
|
||||
{
|
||||
var exportData = new List<OdometerRecordExportModel> { new OdometerRecordExportModel
|
||||
{
|
||||
Date = DateTime.Now.ToShortDateString(),
|
||||
InitialOdometer = 12345.ToString(),
|
||||
Odometer = 12345.ToString(),
|
||||
Notes = "Test Note",
|
||||
Tags = "test1 test2"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteOdometerRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.TaxRecord:
|
||||
{
|
||||
var exportData = new List<TaxRecordExportModel> { new TaxRecordExportModel
|
||||
{
|
||||
Date = DateTime.Now.ToShortDateString(),
|
||||
Description = "Test",
|
||||
Cost = 123.45M.ToString("C"),
|
||||
Notes = "Test Note",
|
||||
Tags = "test1 test2"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteTaxRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.SupplyRecord:
|
||||
{
|
||||
var exportData = new List<SupplyRecordExportModel> { new SupplyRecordExportModel
|
||||
{
|
||||
Date = DateTime.Now.ToShortDateString(),
|
||||
PartNumber = "TEST-123456",
|
||||
PartSupplier = "Test Supplier",
|
||||
PartQuantity = 1.5M.ToString(),
|
||||
Description = "Test",
|
||||
Cost = 123.45M.ToString("C"),
|
||||
Notes = "Test Note",
|
||||
Tags = "test1 test2"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteSupplyRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ImportMode.PlanRecord:
|
||||
{
|
||||
var exportData = new List<PlanRecordExportModel> { new PlanRecordExportModel
|
||||
{
|
||||
DateCreated = DateTime.Now.ToString(),
|
||||
DateModified = DateTime.Now.ToString(),
|
||||
Description = "Test",
|
||||
Type = ImportMode.RepairRecord.ToString(),
|
||||
Priority = PlanPriority.Normal.ToString(),
|
||||
Progress = PlanProgress.Testing.ToString(),
|
||||
Cost = 123.45M.ToString("C"),
|
||||
Notes = "Test Note"
|
||||
} };
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WritePlanRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return Json(OperationResponse.Failed("No parameters"));
|
||||
}
|
||||
try
|
||||
{
|
||||
var fileBytes = _fileHelper.GetFileBytes(fullExportFilePath, true);
|
||||
if (fileBytes.Length > 0)
|
||||
{
|
||||
return File(fileBytes, "text/csv", $"{mode.ToString().ToLower()}sample.csv");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(OperationResponse.Failed("An error has occurred while generating CSV sample: file has zero bytes"));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return Json(OperationResponse.Failed($"An error has occurred while generating CSV sample: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult ExportFromVehicleToCsv(int vehicleId, ImportMode mode)
|
||||
{
|
||||
if (vehicleId == default && mode != ImportMode.SupplyRecord)
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
string uploadDirectory = "temp/";
|
||||
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
var fileNameToExport = $"temp/{Guid.NewGuid()}.csv";
|
||||
var fullExportFilePath = _fileHelper.GetFullFilePath(fileNameToExport, false);
|
||||
if (mode == ImportMode.ServiceRecord)
|
||||
{
|
||||
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
Notes = x.Notes,
|
||||
Odometer = x.Mileage.ToString(),
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
//custom writer
|
||||
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
|
||||
}
|
||||
writer.Dispose();
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.RepairRecord)
|
||||
{
|
||||
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
Notes = x.Notes,
|
||||
Odometer = x.Mileage.ToString(),
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.UpgradeRecord)
|
||||
{
|
||||
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
Notes = x.Notes,
|
||||
Odometer = x.Mileage.ToString(),
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.OdometerRecord)
|
||||
{
|
||||
var vehicleRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new OdometerRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Notes = x.Notes,
|
||||
InitialOdometer = x.InitialMileage.ToString(),
|
||||
Odometer = x.Mileage.ToString(),
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteOdometerRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.SupplyRecord)
|
||||
{
|
||||
var vehicleRecords = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new SupplyRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
PartNumber = x.PartNumber,
|
||||
PartQuantity = x.Quantity.ToString(),
|
||||
PartSupplier = x.PartSupplier,
|
||||
Notes = x.Notes,
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteSupplyRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.TaxRecord)
|
||||
{
|
||||
var vehicleRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new TaxRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToShortDateString(),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
Notes = x.Notes,
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteTaxRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.PlanRecord)
|
||||
{
|
||||
var vehicleRecords = _planRecordDataAccess.GetPlanRecordsByVehicleId(vehicleId);
|
||||
if (vehicleRecords.Any())
|
||||
{
|
||||
var exportData = vehicleRecords.Select(x => new PlanRecordExportModel
|
||||
{
|
||||
DateCreated = x.DateCreated.ToString("G"),
|
||||
DateModified = x.DateModified.ToString("G"),
|
||||
Description = x.Description,
|
||||
Cost = x.Cost.ToString("C"),
|
||||
Type = x.ImportMode.ToString(),
|
||||
Priority = x.Priority.ToString(),
|
||||
Progress = x.Progress.ToString(),
|
||||
Notes = x.Notes,
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WritePlanRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.GasRecord)
|
||||
{
|
||||
var vehicleRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
bool useMPG = _config.GetUserConfig(User).UseMPG;
|
||||
bool useUKMPG = _config.GetUserConfig(User).UseUKMPG;
|
||||
var convertedRecords = _gasHelper.GetGasRecordViewModels(vehicleRecords, useMPG, useUKMPG);
|
||||
var exportData = convertedRecords.Select(x => new GasRecordExportModel
|
||||
{
|
||||
Date = x.Date.ToString(),
|
||||
Cost = x.Cost.ToString(),
|
||||
FuelConsumed = x.Gallons.ToString(),
|
||||
FuelEconomy = x.MilesPerGallon.ToString(),
|
||||
Odometer = x.Mileage.ToString(),
|
||||
IsFillToFull = x.IsFillToFull.ToString(),
|
||||
MissedFuelUp = x.MissedFuelUp.ToString(),
|
||||
Notes = x.Notes,
|
||||
Tags = string.Join(" ", x.Tags),
|
||||
ExtraFields = x.ExtraFields
|
||||
});
|
||||
using (var writer = new StreamWriter(fullExportFilePath))
|
||||
{
|
||||
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
|
||||
{
|
||||
StaticHelper.WriteGasRecordExportModel(csv, exportData);
|
||||
}
|
||||
}
|
||||
return Json($"/{fileNameToExport}");
|
||||
}
|
||||
return Json(false);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult ImportToVehicleIdFromCsv(int vehicleId, ImportMode mode, string fileName)
|
||||
{
|
||||
if (vehicleId == default && mode != ImportMode.SupplyRecord)
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
var fullFileName = _fileHelper.GetFullFilePath(fileName);
|
||||
if (string.IsNullOrWhiteSpace(fullFileName))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(fullFileName))
|
||||
{
|
||||
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
|
||||
config.MissingFieldFound = null;
|
||||
config.HeaderValidated = null;
|
||||
config.PrepareHeaderForMatch = args => { return args.Header.Trim().ToLower(); };
|
||||
using (var csv = new CsvReader(reader, config))
|
||||
{
|
||||
csv.Context.RegisterClassMap<ImportMapper>();
|
||||
var records = csv.GetRecords<ImportModel>().ToList();
|
||||
if (records.Any())
|
||||
{
|
||||
var requiredExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)mode).ExtraFields.Where(x => x.IsRequired).Select(y => y.Name);
|
||||
foreach (ImportModel importModel in records)
|
||||
{
|
||||
var parsedDate = DateTime.Now.Date;
|
||||
if (!string.IsNullOrWhiteSpace(importModel.Date))
|
||||
{
|
||||
parsedDate = DateTime.Parse(importModel.Date);
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(importModel.Day) && !string.IsNullOrWhiteSpace(importModel.Month) && !string.IsNullOrWhiteSpace(importModel.Year))
|
||||
{
|
||||
parsedDate = new DateTime(int.Parse(importModel.Year), int.Parse(importModel.Month), int.Parse(importModel.Day));
|
||||
}
|
||||
if (mode == ImportMode.GasRecord)
|
||||
{
|
||||
//convert to gas model.
|
||||
var convertedRecord = new GasRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
|
||||
Gallons = decimal.Parse(importModel.FuelConsumed, NumberStyles.Any),
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
if (string.IsNullOrWhiteSpace(importModel.Cost) && !string.IsNullOrWhiteSpace(importModel.Price))
|
||||
{
|
||||
//cost was not given but price is.
|
||||
//fuelly sometimes exports CSVs without total cost.
|
||||
var parsedPrice = decimal.Parse(importModel.Price, NumberStyles.Any);
|
||||
convertedRecord.Cost = convertedRecord.Gallons * parsedPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedRecord.Cost = decimal.Parse(importModel.Cost, NumberStyles.Any);
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(importModel.IsFillToFull) && !string.IsNullOrWhiteSpace(importModel.PartialFuelUp))
|
||||
{
|
||||
var parsedBool = importModel.PartialFuelUp.Trim() == "1";
|
||||
convertedRecord.IsFillToFull = !parsedBool;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(importModel.IsFillToFull))
|
||||
{
|
||||
var possibleFillToFullValues = new List<string> { "1", "true", "full" };
|
||||
var parsedBool = possibleFillToFullValues.Contains(importModel.IsFillToFull.Trim().ToLower());
|
||||
convertedRecord.IsFillToFull = parsedBool;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(importModel.MissedFuelUp))
|
||||
{
|
||||
var possibleMissedFuelUpValues = new List<string> { "1", "true" };
|
||||
var parsedBool = possibleMissedFuelUpValues.Contains(importModel.MissedFuelUp.Trim().ToLower());
|
||||
convertedRecord.MissedFuelUp = parsedBool;
|
||||
}
|
||||
//insert record into db, check to make sure fuelconsumed is not zero so we don't get a divide by zero error.
|
||||
if (convertedRecord.Gallons > 0)
|
||||
{
|
||||
_gasRecordDataAccess.SaveGasRecordToVehicle(convertedRecord);
|
||||
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = convertedRecord.Date,
|
||||
VehicleId = convertedRecord.VehicleId,
|
||||
Mileage = convertedRecord.Mileage,
|
||||
Notes = $"Auto Insert From Gas Record via CSV Import. {convertedRecord.Notes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.ServiceRecord)
|
||||
{
|
||||
var convertedRecord = new ServiceRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
|
||||
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Service Record on {parsedDate.ToShortDateString()}" : importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_serviceRecordDataAccess.SaveServiceRecordToVehicle(convertedRecord);
|
||||
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = convertedRecord.Date,
|
||||
VehicleId = convertedRecord.VehicleId,
|
||||
Mileage = convertedRecord.Mileage,
|
||||
Notes = $"Auto Insert From Service Record via CSV Import. {convertedRecord.Notes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.OdometerRecord)
|
||||
{
|
||||
var convertedRecord = new OdometerRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
InitialMileage = string.IsNullOrWhiteSpace(importModel.InitialOdometer) ? 0 : decimal.ToInt32(decimal.Parse(importModel.InitialOdometer, NumberStyles.Any)),
|
||||
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(convertedRecord);
|
||||
}
|
||||
else if (mode == ImportMode.PlanRecord)
|
||||
{
|
||||
var progressIsEnum = Enum.TryParse(importModel.Progress, out PlanProgress parsedProgress);
|
||||
var typeIsEnum = Enum.TryParse(importModel.Type, out ImportMode parsedType);
|
||||
var priorityIsEnum = Enum.TryParse(importModel.Priority, out PlanPriority parsedPriority);
|
||||
var convertedRecord = new PlanRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
DateCreated = DateTime.Parse(importModel.DateCreated),
|
||||
DateModified = DateTime.Parse(importModel.DateModified),
|
||||
Progress = parsedProgress,
|
||||
ImportMode = parsedType,
|
||||
Priority = parsedPriority,
|
||||
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Plan Record on {importModel.DateCreated}" : importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
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>()
|
||||
};
|
||||
_planRecordDataAccess.SavePlanRecordToVehicle(convertedRecord);
|
||||
}
|
||||
else if (mode == ImportMode.RepairRecord)
|
||||
{
|
||||
var convertedRecord = new CollisionRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
|
||||
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Repair Record on {parsedDate.ToShortDateString()}" : importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(convertedRecord);
|
||||
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = convertedRecord.Date,
|
||||
VehicleId = convertedRecord.VehicleId,
|
||||
Mileage = convertedRecord.Mileage,
|
||||
Notes = $"Auto Insert From Repair Record via CSV Import. {convertedRecord.Notes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.UpgradeRecord)
|
||||
{
|
||||
var convertedRecord = new UpgradeRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
|
||||
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Upgrade Record on {parsedDate.ToShortDateString()}" : importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(convertedRecord);
|
||||
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = convertedRecord.Date,
|
||||
VehicleId = convertedRecord.VehicleId,
|
||||
Mileage = convertedRecord.Mileage,
|
||||
Notes = $"Auto Insert From Upgrade Record via CSV Import. {convertedRecord.Notes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (mode == ImportMode.SupplyRecord)
|
||||
{
|
||||
var convertedRecord = new SupplyRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
PartNumber = importModel.PartNumber,
|
||||
PartSupplier = importModel.PartSupplier,
|
||||
Quantity = decimal.Parse(importModel.PartQuantity, NumberStyles.Any),
|
||||
Description = importModel.Description,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
Notes = importModel.Notes,
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_supplyRecordDataAccess.SaveSupplyRecordToVehicle(convertedRecord);
|
||||
}
|
||||
else if (mode == ImportMode.TaxRecord)
|
||||
{
|
||||
var convertedRecord = new TaxRecord()
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
Date = parsedDate,
|
||||
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Tax Record on {parsedDate.ToShortDateString()}" : importModel.Description,
|
||||
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
|
||||
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
|
||||
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
|
||||
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>()
|
||||
};
|
||||
_taxRecordDataAccess.SaveTaxRecordToVehicle(convertedRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Json(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error Occurred While Bulk Inserting");
|
||||
return Json(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
Controllers/Vehicle/NoteController.cs
Normal file
102
Controllers/Vehicle/NoteController.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetNotesByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _noteDataAccess.GetNotesByVehicleId(vehicleId);
|
||||
result = result.OrderByDescending(x => x.Pinned).ThenBy(x => x.Description).ToList();
|
||||
return PartialView("Note/_Notes", result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetPinnedNotesByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _noteDataAccess.GetNotesByVehicleId(vehicleId);
|
||||
result = result.Where(x => x.Pinned).ToList();
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveNoteToVehicleId(Note note)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), note.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
note.Files = note.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
bool isCreate = note.Id == default; //needed here since Notes don't use an input object.
|
||||
var result = _noteDataAccess.SaveNoteToVehicle(note);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromNoteRecord(note, isCreate ? "noterecord.add" : "noterecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddNotePartialView()
|
||||
{
|
||||
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.NoteRecord).ExtraFields;
|
||||
return PartialView("Note/_NoteModal", new Note() { ExtraFields = extraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetNoteForEditById(int noteId)
|
||||
{
|
||||
var result = _noteDataAccess.GetNoteById(noteId);
|
||||
result.ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.NoteRecord).ExtraFields);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
return PartialView("Note/_NoteModal", result);
|
||||
}
|
||||
private bool DeleteNoteWithChecks(int noteId)
|
||||
{
|
||||
var existingRecord = _noteDataAccess.GetNoteById(noteId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = _noteDataAccess.DeleteNoteById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromNoteRecord(existingRecord, "noterecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteNoteById(int noteId)
|
||||
{
|
||||
var result = DeleteNoteWithChecks(noteId);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult PinNotes(List<int> noteIds, bool isToggle = false, bool pinStatus = false)
|
||||
{
|
||||
var result = false;
|
||||
foreach (int noteId in noteIds)
|
||||
{
|
||||
var existingNote = _noteDataAccess.GetNoteById(noteId);
|
||||
if (isToggle)
|
||||
{
|
||||
existingNote.Pinned = !existingNote.Pinned;
|
||||
}
|
||||
else
|
||||
{
|
||||
existingNote.Pinned = pinStatus;
|
||||
}
|
||||
result = _noteDataAccess.SaveNoteToVehicle(existingNote);
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
176
Controllers/Vehicle/OdometerController.cs
Normal file
176
Controllers/Vehicle/OdometerController.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult ForceRecalculateDistanceByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
result = _odometerLogic.AutoConvertOdometerRecord(result);
|
||||
return Json(result.Any());
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetOdometerRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
//determine if conversion is needed.
|
||||
if (result.All(x => x.InitialMileage == default))
|
||||
{
|
||||
result = _odometerLogic.AutoConvertOdometerRecord(result);
|
||||
}
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
|
||||
}
|
||||
return PartialView("Odometer/_OdometerRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveOdometerRecordToVehicleId(OdometerRecordInput odometerRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), odometerRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
//move files from temp.
|
||||
odometerRecord.Files = odometerRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
var result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometerRecord.ToOdometerRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(odometerRecord.ToOdometerRecord(), odometerRecord.Id == default ? "odometerrecord.add" : "odometerrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[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 });
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult GetOdometerRecordsEditModal(List<int> recordIds)
|
||||
{
|
||||
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields;
|
||||
return PartialView("Odometer/_OdometerRecordsModal", new OdometerRecordEditModel { RecordIds = recordIds, EditRecord = new OdometerRecord { ExtraFields = extraFields } });
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveMultipleOdometerRecords(OdometerRecordEditModel editModel)
|
||||
{
|
||||
var dateIsEdited = editModel.EditRecord.Date != default;
|
||||
var initialMileageIsEdited = editModel.EditRecord.InitialMileage != default;
|
||||
var mileageIsEdited = editModel.EditRecord.Mileage != default;
|
||||
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
|
||||
var tagsIsEdited = editModel.EditRecord.Tags.Any();
|
||||
var extraFieldIsEdited = editModel.EditRecord.ExtraFields.Any();
|
||||
//handle clear overrides
|
||||
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
|
||||
{
|
||||
editModel.EditRecord.Tags = new List<string>();
|
||||
}
|
||||
if (noteIsEdited && editModel.EditRecord.Notes == "---")
|
||||
{
|
||||
editModel.EditRecord.Notes = "";
|
||||
}
|
||||
bool result = false;
|
||||
foreach (int recordId in editModel.RecordIds)
|
||||
{
|
||||
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(recordId);
|
||||
if (dateIsEdited)
|
||||
{
|
||||
existingRecord.Date = editModel.EditRecord.Date;
|
||||
}
|
||||
if (initialMileageIsEdited)
|
||||
{
|
||||
existingRecord.InitialMileage = editModel.EditRecord.InitialMileage;
|
||||
}
|
||||
if (mileageIsEdited)
|
||||
{
|
||||
existingRecord.Mileage = editModel.EditRecord.Mileage;
|
||||
}
|
||||
if (noteIsEdited)
|
||||
{
|
||||
existingRecord.Notes = editModel.EditRecord.Notes;
|
||||
}
|
||||
if (tagsIsEdited)
|
||||
{
|
||||
existingRecord.Tags = editModel.EditRecord.Tags;
|
||||
}
|
||||
if (extraFieldIsEdited)
|
||||
{
|
||||
foreach (ExtraField extraField in editModel.EditRecord.ExtraFields)
|
||||
{
|
||||
if (existingRecord.ExtraFields.Any(x => x.Name == extraField.Name))
|
||||
{
|
||||
var insertIndex = existingRecord.ExtraFields.FindIndex(x => x.Name == extraField.Name);
|
||||
existingRecord.ExtraFields.RemoveAll(x => x.Name == extraField.Name);
|
||||
existingRecord.ExtraFields.Insert(insertIndex, extraField);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingRecord.ExtraFields.Add(extraField);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetOdometerRecordForEditById(int odometerRecordId)
|
||||
{
|
||||
var result = _odometerRecordDataAccess.GetOdometerRecordById(odometerRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new OdometerRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
InitialMileage = result.InitialMileage,
|
||||
Mileage = result.Mileage,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Odometer/_OdometerRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteOdometerRecordWithChecks(int odometerRecordId)
|
||||
{
|
||||
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(odometerRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = _odometerRecordDataAccess.DeleteOdometerRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(existingRecord, "odometerrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteOdometerRecordById(int odometerRecordId)
|
||||
{
|
||||
var result = DeleteOdometerRecordWithChecks(odometerRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
324
Controllers/Vehicle/PlanController.cs
Normal file
324
Controllers/Vehicle/PlanController.cs
Normal file
@@ -0,0 +1,324 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetPlanRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _planRecordDataAccess.GetPlanRecordsByVehicleId(vehicleId);
|
||||
return PartialView("Plan/_PlanRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SavePlanRecordToVehicleId(PlanRecordInput planRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), planRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
//populate createdDate
|
||||
if (planRecord.Id == default)
|
||||
{
|
||||
planRecord.DateCreated = DateTime.Now.ToString("G");
|
||||
}
|
||||
planRecord.DateModified = DateTime.Now.ToString("G");
|
||||
//move files from temp.
|
||||
planRecord.Files = planRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
if (planRecord.Supplies.Any())
|
||||
{
|
||||
planRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(planRecord.Supplies, DateTime.Parse(planRecord.DateCreated), planRecord.Description));
|
||||
if (planRecord.CopySuppliesAttachment)
|
||||
{
|
||||
planRecord.Files.AddRange(GetSuppliesAttachments(planRecord.Supplies));
|
||||
}
|
||||
}
|
||||
if (planRecord.DeletedRequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(planRecord.DeletedRequisitionHistory, planRecord.Description);
|
||||
}
|
||||
var result = _planRecordDataAccess.SavePlanRecordToVehicle(planRecord.ToPlanRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromPlanRecord(planRecord.ToPlanRecord(), planRecord.Id == default ? "planrecord.add" : "planrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SavePlanRecordTemplateToVehicleId(PlanRecordInput planRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), planRecord.VehicleId))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Access Denied"));
|
||||
}
|
||||
//check if template name already taken.
|
||||
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(planRecord.VehicleId).Where(x => x.Description == planRecord.Description).Any();
|
||||
if (planRecord.Id == default && existingRecord)
|
||||
{
|
||||
return Json(OperationResponse.Failed("A template with that description already exists for this vehicle"));
|
||||
}
|
||||
planRecord.Files = planRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
var result = _planRecordTemplateDataAccess.SavePlanRecordTemplateToVehicle(planRecord);
|
||||
return Json(OperationResponse.Conditional(result, "Template Added", string.Empty));
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetPlanRecordTemplatesForVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(vehicleId);
|
||||
return PartialView("Plan/_PlanRecordTemplateModal", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeletePlanRecordTemplateById(int planRecordTemplateId)
|
||||
{
|
||||
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
|
||||
if (existingRecord.Id == default)
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
var result = _planRecordTemplateDataAccess.DeletePlanRecordTemplateById(planRecordTemplateId);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult OrderPlanSupplies(int planRecordTemplateId)
|
||||
{
|
||||
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
|
||||
if (existingRecord.Id == default)
|
||||
{
|
||||
return Json(OperationResponse.Failed("Unable to find template"));
|
||||
}
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Access Denied"));
|
||||
}
|
||||
if (existingRecord.Supplies.Any())
|
||||
{
|
||||
var suppliesToOrder = CheckSupplyRecordsAvailability(existingRecord.Supplies);
|
||||
return PartialView("Plan/_PlanOrderSupplies", suppliesToOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(OperationResponse.Failed("Template has No Supplies"));
|
||||
}
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult ConvertPlanRecordTemplateToPlanRecord(int planRecordTemplateId)
|
||||
{
|
||||
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
|
||||
if (existingRecord.Id == default)
|
||||
{
|
||||
return Json(OperationResponse.Failed("Unable to find template"));
|
||||
}
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Access Denied"));
|
||||
}
|
||||
if (existingRecord.Supplies.Any())
|
||||
{
|
||||
//check if all supplies are available
|
||||
var supplyAvailability = CheckSupplyRecordsAvailability(existingRecord.Supplies);
|
||||
if (supplyAvailability.Any(x => x.Missing))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Missing Supplies, Please Delete This Template and Recreate It."));
|
||||
}
|
||||
else if (supplyAvailability.Any(x => x.Insufficient))
|
||||
{
|
||||
return Json(OperationResponse.Failed("Insufficient Supplies"));
|
||||
}
|
||||
}
|
||||
if (existingRecord.ReminderRecordId != default)
|
||||
{
|
||||
//check if reminder still exists and is still recurring.
|
||||
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(existingRecord.ReminderRecordId);
|
||||
if (existingReminder is null || existingReminder.Id == default || !existingReminder.IsRecurring)
|
||||
{
|
||||
return Json(OperationResponse.Failed("Missing or Non-recurring Reminder, Please Delete This Template and Recreate It."));
|
||||
}
|
||||
}
|
||||
//populate createdDate
|
||||
existingRecord.DateCreated = DateTime.Now.ToString("G");
|
||||
existingRecord.DateModified = DateTime.Now.ToString("G");
|
||||
existingRecord.Id = default;
|
||||
if (existingRecord.Supplies.Any())
|
||||
{
|
||||
existingRecord.RequisitionHistory = RequisitionSupplyRecordsByUsage(existingRecord.Supplies, DateTime.Parse(existingRecord.DateCreated), existingRecord.Description);
|
||||
if (existingRecord.CopySuppliesAttachment)
|
||||
{
|
||||
existingRecord.Files.AddRange(GetSuppliesAttachments(existingRecord.Supplies));
|
||||
}
|
||||
}
|
||||
var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord.ToPlanRecord());
|
||||
return Json(OperationResponse.Conditional(result, "Plan Record Added", string.Empty));
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddPlanRecordPartialView()
|
||||
{
|
||||
return PartialView("Plan/_PlanRecordModal", new PlanRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields });
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult GetAddPlanRecordPartialView(PlanRecordInput? planModel)
|
||||
{
|
||||
if (planModel is not null)
|
||||
{
|
||||
planModel.ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields;
|
||||
return PartialView("Plan/_PlanRecordModal", planModel);
|
||||
}
|
||||
return PartialView("Plan/_PlanRecordModal", new PlanRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields });
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult UpdatePlanRecordProgress(int planRecordId, PlanProgress planProgress, int odometer = 0)
|
||||
{
|
||||
if (planRecordId == default)
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
var existingRecord = _planRecordDataAccess.GetPlanRecordById(planRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
existingRecord.Progress = planProgress;
|
||||
existingRecord.DateModified = DateTime.Now;
|
||||
var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord);
|
||||
if (planProgress == PlanProgress.Done)
|
||||
{
|
||||
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = DateTime.Now.Date,
|
||||
VehicleId = existingRecord.VehicleId,
|
||||
Mileage = odometer,
|
||||
Notes = $"Auto Insert From Plan Record: {existingRecord.Description}",
|
||||
ExtraFields = existingRecord.ExtraFields
|
||||
});
|
||||
}
|
||||
//convert plan record to service/upgrade/repair record.
|
||||
if (existingRecord.ImportMode == ImportMode.ServiceRecord)
|
||||
{
|
||||
var newRecord = new ServiceRecord()
|
||||
{
|
||||
VehicleId = existingRecord.VehicleId,
|
||||
Date = DateTime.Now.Date,
|
||||
Mileage = odometer,
|
||||
Description = existingRecord.Description,
|
||||
Cost = existingRecord.Cost,
|
||||
Notes = existingRecord.Notes,
|
||||
Files = existingRecord.Files,
|
||||
RequisitionHistory = existingRecord.RequisitionHistory,
|
||||
ExtraFields = existingRecord.ExtraFields
|
||||
};
|
||||
_serviceRecordDataAccess.SaveServiceRecordToVehicle(newRecord);
|
||||
}
|
||||
else if (existingRecord.ImportMode == ImportMode.RepairRecord)
|
||||
{
|
||||
var newRecord = new CollisionRecord()
|
||||
{
|
||||
VehicleId = existingRecord.VehicleId,
|
||||
Date = DateTime.Now.Date,
|
||||
Mileage = odometer,
|
||||
Description = existingRecord.Description,
|
||||
Cost = existingRecord.Cost,
|
||||
Notes = existingRecord.Notes,
|
||||
Files = existingRecord.Files,
|
||||
RequisitionHistory = existingRecord.RequisitionHistory,
|
||||
ExtraFields = existingRecord.ExtraFields
|
||||
};
|
||||
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(newRecord);
|
||||
}
|
||||
else if (existingRecord.ImportMode == ImportMode.UpgradeRecord)
|
||||
{
|
||||
var newRecord = new UpgradeRecord()
|
||||
{
|
||||
VehicleId = existingRecord.VehicleId,
|
||||
Date = DateTime.Now.Date,
|
||||
Mileage = odometer,
|
||||
Description = existingRecord.Description,
|
||||
Cost = existingRecord.Cost,
|
||||
Notes = existingRecord.Notes,
|
||||
Files = existingRecord.Files,
|
||||
RequisitionHistory = existingRecord.RequisitionHistory,
|
||||
ExtraFields = existingRecord.ExtraFields
|
||||
};
|
||||
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(newRecord);
|
||||
}
|
||||
//push back any reminders
|
||||
if (existingRecord.ReminderRecordId != default)
|
||||
{
|
||||
PushbackRecurringReminderRecordWithChecks(existingRecord.ReminderRecordId, DateTime.Now, odometer);
|
||||
}
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetPlanRecordTemplateForEditById(int planRecordTemplateId)
|
||||
{
|
||||
var result = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
|
||||
return PartialView("Plan/_PlanRecordTemplateEditModal", result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetPlanRecordForEditById(int planRecordId)
|
||||
{
|
||||
var result = _planRecordDataAccess.GetPlanRecordById(planRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new PlanRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Description = result.Description,
|
||||
DateCreated = result.DateCreated.ToString("G"),
|
||||
DateModified = result.DateModified.ToString("G"),
|
||||
ImportMode = result.ImportMode,
|
||||
Priority = result.Priority,
|
||||
Progress = result.Progress,
|
||||
Cost = result.Cost,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
RequisitionHistory = result.RequisitionHistory,
|
||||
ReminderRecordId = result.ReminderRecordId,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Plan/_PlanRecordModal", convertedResult);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeletePlanRecordById(int planRecordId)
|
||||
{
|
||||
var existingRecord = _planRecordDataAccess.GetPlanRecordById(planRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
//restore any requisitioned supplies if it has not been converted to other record types.
|
||||
if (existingRecord.RequisitionHistory.Any() && existingRecord.Progress != PlanProgress.Done)
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
|
||||
}
|
||||
var result = _planRecordDataAccess.DeletePlanRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromPlanRecord(existingRecord, "planrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
187
Controllers/Vehicle/ReminderController.cs
Normal file
187
Controllers/Vehicle/ReminderController.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
private List<ReminderRecordViewModel> GetRemindersAndUrgency(int vehicleId, DateTime dateCompare)
|
||||
{
|
||||
var currentMileage = _vehicleLogic.GetMaxMileage(vehicleId);
|
||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||
List<ReminderRecordViewModel> results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, dateCompare);
|
||||
return results;
|
||||
}
|
||||
private bool GetAndUpdateVehicleUrgentOrPastDueReminders(int vehicleId)
|
||||
{
|
||||
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||
//check if user wants auto-refresh past-due reminders
|
||||
if (_config.GetUserConfig(User).EnableAutoReminderRefresh)
|
||||
{
|
||||
//check for past due reminders that are eligible for recurring.
|
||||
var pastDueAndRecurring = result.Where(x => x.Urgency == ReminderUrgency.PastDue && x.IsRecurring);
|
||||
if (pastDueAndRecurring.Any())
|
||||
{
|
||||
foreach (ReminderRecordViewModel reminderRecord in pastDueAndRecurring)
|
||||
{
|
||||
//update based on recurring intervals.
|
||||
//pull reminderRecord based on ID
|
||||
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(reminderRecord.Id);
|
||||
existingReminder = _reminderHelper.GetUpdatedRecurringReminderRecord(existingReminder, null, null);
|
||||
//save to db.
|
||||
_reminderRecordDataAccess.SaveReminderRecordToVehicle(existingReminder);
|
||||
//set urgency to not urgent so it gets excluded in count.
|
||||
reminderRecord.Urgency = ReminderUrgency.NotUrgent;
|
||||
}
|
||||
}
|
||||
}
|
||||
//check for very urgent or past due reminders that were not eligible for recurring.
|
||||
var pastDueAndUrgentReminders = result.Where(x => x.Urgency == ReminderUrgency.VeryUrgent || x.Urgency == ReminderUrgency.PastDue);
|
||||
if (pastDueAndUrgentReminders.Any())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
|
||||
{
|
||||
var result = GetAndUpdateVehicleUrgentOrPastDueReminders(vehicleId);
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetReminderRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||
result = result.OrderByDescending(x => x.Urgency).ToList();
|
||||
return PartialView("Reminder/_ReminderRecords", result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetRecurringReminderRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||
result.RemoveAll(x => !x.IsRecurring);
|
||||
result = result.OrderByDescending(x => x.Urgency).ThenBy(x => x.Description).ToList();
|
||||
return PartialView("_RecurringReminderSelector", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult PushbackRecurringReminderRecord(int reminderRecordId)
|
||||
{
|
||||
var result = PushbackRecurringReminderRecordWithChecks(reminderRecordId, null, null);
|
||||
return Json(result);
|
||||
}
|
||||
private bool PushbackRecurringReminderRecordWithChecks(int reminderRecordId, DateTime? currentDate, int? currentMileage)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
|
||||
if (existingReminder is not null && existingReminder.Id != default && existingReminder.IsRecurring)
|
||||
{
|
||||
existingReminder = _reminderHelper.GetUpdatedRecurringReminderRecord(existingReminder, currentDate, currentMileage);
|
||||
//save to db.
|
||||
var reminderUpdateResult = _reminderRecordDataAccess.SaveReminderRecordToVehicle(existingReminder);
|
||||
if (!reminderUpdateResult)
|
||||
{
|
||||
_logger.LogError("Unable to update reminder either because the reminder no longer exists or is no longer recurring");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Unable to update reminder because it no longer exists.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveReminderRecordToVehicleId(ReminderRecordInput reminderRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), reminderRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
var result = _reminderRecordDataAccess.SaveReminderRecordToVehicle(reminderRecord.ToReminderRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromReminderRecord(reminderRecord.ToReminderRecord(), reminderRecord.Id == default ? "reminderrecord.add" : "reminderrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult GetAddReminderRecordPartialView(ReminderRecordInput? reminderModel)
|
||||
{
|
||||
if (reminderModel is not null)
|
||||
{
|
||||
return PartialView("Reminder/_ReminderRecordModal", reminderModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PartialView("Reminder/_ReminderRecordModal", new ReminderRecordInput());
|
||||
}
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetReminderRecordForEditById(int reminderRecordId)
|
||||
{
|
||||
var result = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new ReminderRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Mileage = result.Mileage,
|
||||
Metric = result.Metric,
|
||||
IsRecurring = result.IsRecurring,
|
||||
UseCustomThresholds = result.UseCustomThresholds,
|
||||
CustomThresholds = result.CustomThresholds,
|
||||
ReminderMileageInterval = result.ReminderMileageInterval,
|
||||
ReminderMonthInterval = result.ReminderMonthInterval,
|
||||
CustomMileageInterval = result.CustomMileageInterval,
|
||||
CustomMonthInterval = result.CustomMonthInterval,
|
||||
CustomMonthIntervalUnit = result.CustomMonthIntervalUnit,
|
||||
Tags = result.Tags
|
||||
};
|
||||
return PartialView("Reminder/_ReminderRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteReminderRecordWithChecks(int reminderRecordId)
|
||||
{
|
||||
var existingRecord = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = _reminderRecordDataAccess.DeleteReminderRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromReminderRecord(existingRecord, "reminderrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteReminderRecordById(int reminderRecordId)
|
||||
{
|
||||
var result = DeleteReminderRecordWithChecks(reminderRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Controllers/Vehicle/RepairController.cs
Normal file
131
Controllers/Vehicle/RepairController.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCollisionRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
|
||||
}
|
||||
return PartialView("Collision/_CollisionRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveCollisionRecordToVehicleId(CollisionRecordInput collisionRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), collisionRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
if (collisionRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = DateTime.Parse(collisionRecord.Date),
|
||||
VehicleId = collisionRecord.VehicleId,
|
||||
Mileage = collisionRecord.Mileage,
|
||||
Notes = $"Auto Insert From Repair Record: {collisionRecord.Description}"
|
||||
});
|
||||
}
|
||||
//move files from temp.
|
||||
collisionRecord.Files = collisionRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
if (collisionRecord.Supplies.Any())
|
||||
{
|
||||
collisionRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(collisionRecord.Supplies, DateTime.Parse(collisionRecord.Date), collisionRecord.Description));
|
||||
if (collisionRecord.CopySuppliesAttachment)
|
||||
{
|
||||
collisionRecord.Files.AddRange(GetSuppliesAttachments(collisionRecord.Supplies));
|
||||
}
|
||||
}
|
||||
if (collisionRecord.DeletedRequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(collisionRecord.DeletedRequisitionHistory, collisionRecord.Description);
|
||||
}
|
||||
//push back any reminders
|
||||
if (collisionRecord.ReminderRecordId.Any())
|
||||
{
|
||||
foreach (int reminderRecordId in collisionRecord.ReminderRecordId)
|
||||
{
|
||||
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(collisionRecord.Date), collisionRecord.Mileage);
|
||||
}
|
||||
}
|
||||
var result = _collisionRecordDataAccess.SaveCollisionRecordToVehicle(collisionRecord.ToCollisionRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(collisionRecord.ToCollisionRecord(), collisionRecord.Id == default ? "repairrecord.add" : "repairrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddCollisionRecordPartialView()
|
||||
{
|
||||
return PartialView("Collision/_CollisionRecordModal", new CollisionRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetCollisionRecordForEditById(int collisionRecordId)
|
||||
{
|
||||
var result = _collisionRecordDataAccess.GetCollisionRecordById(collisionRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new CollisionRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
Mileage = result.Mileage,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
RequisitionHistory = result.RequisitionHistory,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Collision/_CollisionRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteCollisionRecordWithChecks(int collisionRecordId)
|
||||
{
|
||||
var existingRecord = _collisionRecordDataAccess.GetCollisionRecordById(collisionRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//restore any requisitioned supplies.
|
||||
if (existingRecord.RequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
|
||||
}
|
||||
var result = _collisionRecordDataAccess.DeleteCollisionRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "repairrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteCollisionRecordById(int collisionRecordId)
|
||||
{
|
||||
var result = DeleteCollisionRecordWithChecks(collisionRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
762
Controllers/Vehicle/ReportController.cs
Normal file
762
Controllers/Vehicle/ReportController.cs
Normal file
@@ -0,0 +1,762 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetReportPartialView(int vehicleId)
|
||||
{
|
||||
//get records
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
|
||||
var serviceRecords = vehicleRecords.ServiceRecords;
|
||||
var gasRecords = vehicleRecords.GasRecords;
|
||||
var collisionRecords = vehicleRecords.CollisionRecords;
|
||||
var taxRecords = vehicleRecords.TaxRecords;
|
||||
var upgradeRecords = vehicleRecords.UpgradeRecords;
|
||||
var odometerRecords = vehicleRecords.OdometerRecords;
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
var viewModel = new ReportViewModel() { ReportHeaderForVehicle = new ReportHeader() };
|
||||
//check if custom widgets are configured
|
||||
viewModel.CustomWidgetsConfigured = _fileHelper.WidgetsExist();
|
||||
//get totalCostMakeUp
|
||||
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
|
||||
{
|
||||
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost)
|
||||
};
|
||||
//get costbymonth
|
||||
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
|
||||
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, 0));
|
||||
allCosts.AddRange(_reportHelper.GetRepairRecordSum(collisionRecords, 0));
|
||||
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
|
||||
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, 0));
|
||||
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, 0));
|
||||
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, 0));
|
||||
viewModel.CostForVehicleByMonth = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthName = x.Key.MonthName,
|
||||
Cost = x.Sum(y => y.Cost),
|
||||
DistanceTraveled = x.Max(y => y.DistanceTraveled)
|
||||
}).ToList();
|
||||
|
||||
//set available metrics
|
||||
var visibleTabs = userConfig.VisibleTabs;
|
||||
if (visibleTabs.Contains(ImportMode.OdometerRecord) || odometerRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.OdometerRecord);
|
||||
}
|
||||
if (visibleTabs.Contains(ImportMode.ServiceRecord) || serviceRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.ServiceRecord);
|
||||
}
|
||||
if (visibleTabs.Contains(ImportMode.RepairRecord) || collisionRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.RepairRecord);
|
||||
}
|
||||
if (visibleTabs.Contains(ImportMode.UpgradeRecord) || upgradeRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.UpgradeRecord);
|
||||
}
|
||||
if (visibleTabs.Contains(ImportMode.GasRecord) || gasRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.GasRecord);
|
||||
}
|
||||
if (visibleTabs.Contains(ImportMode.TaxRecord) || taxRecords.Any())
|
||||
{
|
||||
viewModel.AvailableMetrics.Add(ImportMode.TaxRecord);
|
||||
}
|
||||
|
||||
//get reminders
|
||||
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
|
||||
viewModel.ReminderMakeUpForVehicle = new ReminderMakeUpForVehicle
|
||||
{
|
||||
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
|
||||
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
|
||||
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
|
||||
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
|
||||
};
|
||||
//populate year dropdown.
|
||||
var numbersArray = new List<int>();
|
||||
if (serviceRecords.Any())
|
||||
{
|
||||
numbersArray.Add(serviceRecords.Min(x => x.Date.Year));
|
||||
}
|
||||
if (collisionRecords.Any())
|
||||
{
|
||||
numbersArray.Add(collisionRecords.Min(x => x.Date.Year));
|
||||
}
|
||||
if (gasRecords.Any())
|
||||
{
|
||||
numbersArray.Add(gasRecords.Min(x => x.Date.Year));
|
||||
}
|
||||
if (upgradeRecords.Any())
|
||||
{
|
||||
numbersArray.Add(upgradeRecords.Min(x => x.Date.Year));
|
||||
}
|
||||
if (odometerRecords.Any())
|
||||
{
|
||||
numbersArray.Add(odometerRecords.Min(x => x.Date.Year));
|
||||
}
|
||||
var minYear = numbersArray.Any() ? numbersArray.Min() : DateTime.Now.AddYears(-5).Year;
|
||||
var yearDifference = DateTime.Now.Year - minYear + 1;
|
||||
for (int i = 0; i < yearDifference; i++)
|
||||
{
|
||||
viewModel.Years.Add(DateTime.Now.AddYears(i * -1).Year);
|
||||
}
|
||||
//get collaborators
|
||||
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||
viewModel.Collaborators = collaborators;
|
||||
//get MPG per month.
|
||||
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleData.IsElectric, vehicleData.UseHours, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
var averageMPG = _gasHelper.GetAverageGasMileage(mileageData, userConfig.UseMPG);
|
||||
mileageData.RemoveAll(x => x.MilesPerGallon == default);
|
||||
bool invertedFuelMileageUnit = fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l";
|
||||
var monthlyMileageData = StaticHelper.GetBaseLineCostsNoMonthName();
|
||||
monthlyMileageData.AddRange(mileageData.GroupBy(x => x.MonthId).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthId = x.Key,
|
||||
Cost = x.Average(y => y.MilesPerGallon)
|
||||
}));
|
||||
monthlyMileageData = monthlyMileageData.GroupBy(x => x.MonthId).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthId = x.Key,
|
||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||
Cost = x.Sum(y => y.Cost)
|
||||
}).ToList();
|
||||
if (invertedFuelMileageUnit)
|
||||
{
|
||||
foreach (CostForVehicleByMonth monthMileage in monthlyMileageData)
|
||||
{
|
||||
if (monthMileage.Cost != default)
|
||||
{
|
||||
monthMileage.Cost = 100 / monthMileage.Cost;
|
||||
}
|
||||
}
|
||||
var newAverageMPG = decimal.Parse(averageMPG, NumberStyles.Any);
|
||||
if (newAverageMPG != 0)
|
||||
{
|
||||
newAverageMPG = 100 / newAverageMPG;
|
||||
}
|
||||
averageMPG = newAverageMPG.ToString("F");
|
||||
}
|
||||
var mpgViewModel = new MPGForVehicleByMonth {
|
||||
CostData = monthlyMileageData,
|
||||
Unit = invertedFuelMileageUnit ? preferredFuelMileageUnit : fuelEconomyMileageUnit,
|
||||
SortedCostData = (userConfig.UseMPG || invertedFuelMileageUnit) ? monthlyMileageData.OrderByDescending(x => x.Cost).ToList() : monthlyMileageData.OrderBy(x => x.Cost).ToList()
|
||||
};
|
||||
viewModel.FuelMileageForVehicleByMonth = mpgViewModel;
|
||||
//report header
|
||||
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
|
||||
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
|
||||
|
||||
viewModel.ReportHeaderForVehicle.TotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords);
|
||||
viewModel.ReportHeaderForVehicle.AverageMPG = $"{averageMPG} {mpgViewModel.Unit}";
|
||||
viewModel.ReportHeaderForVehicle.MaxOdometer = maxMileage;
|
||||
viewModel.ReportHeaderForVehicle.DistanceTraveled = maxMileage - minMileage;
|
||||
return PartialView("_Report", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCollaboratorsForVehicle(int vehicleId)
|
||||
{
|
||||
var result = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||
return PartialView("_Collaborators", result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult AddCollaboratorsToVehicle(int vehicleId, string username)
|
||||
{
|
||||
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult DeleteCollaboratorFromVehicle(int userId, int vehicleId)
|
||||
{
|
||||
var result = _userLogic.DeleteCollaboratorFromVehicle(userId, vehicleId);
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult GetSummaryForVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
|
||||
|
||||
var serviceRecords = vehicleRecords.ServiceRecords;
|
||||
var gasRecords = vehicleRecords.GasRecords;
|
||||
var collisionRecords = vehicleRecords.CollisionRecords;
|
||||
var taxRecords = vehicleRecords.TaxRecords;
|
||||
var upgradeRecords = vehicleRecords.UpgradeRecords;
|
||||
var odometerRecords = vehicleRecords.OdometerRecords;
|
||||
|
||||
if (year != default)
|
||||
{
|
||||
serviceRecords.RemoveAll(x => x.Date.Year != year);
|
||||
gasRecords.RemoveAll(x => x.Date.Year != year);
|
||||
collisionRecords.RemoveAll(x => x.Date.Year != year);
|
||||
taxRecords.RemoveAll(x => x.Date.Year != year);
|
||||
upgradeRecords.RemoveAll(x => x.Date.Year != year);
|
||||
odometerRecords.RemoveAll(x => x.Date.Year != year);
|
||||
}
|
||||
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
|
||||
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleData.IsElectric, vehicleData.UseHours, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
var averageMPG = _gasHelper.GetAverageGasMileage(mileageData, userConfig.UseMPG);
|
||||
bool invertedFuelMileageUnit = fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l";
|
||||
|
||||
if (invertedFuelMileageUnit)
|
||||
{
|
||||
var newAverageMPG = decimal.Parse(averageMPG, NumberStyles.Any);
|
||||
if (newAverageMPG != 0)
|
||||
{
|
||||
newAverageMPG = 100 / newAverageMPG;
|
||||
}
|
||||
averageMPG = newAverageMPG.ToString("F");
|
||||
}
|
||||
|
||||
var mpgUnit = invertedFuelMileageUnit ? preferredFuelMileageUnit : fuelEconomyMileageUnit;
|
||||
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
|
||||
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
|
||||
|
||||
var viewModel = new ReportHeader()
|
||||
{
|
||||
TotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords),
|
||||
AverageMPG = $"{averageMPG} {mpgUnit}",
|
||||
MaxOdometer = maxMileage,
|
||||
DistanceTraveled = maxMileage - minMileage
|
||||
};
|
||||
|
||||
return PartialView("_ReportHeader", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
var collisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
if (year != default)
|
||||
{
|
||||
serviceRecords.RemoveAll(x => x.Date.Year != year);
|
||||
gasRecords.RemoveAll(x => x.Date.Year != year);
|
||||
collisionRecords.RemoveAll(x => x.Date.Year != year);
|
||||
taxRecords.RemoveAll(x => x.Date.Year != year);
|
||||
upgradeRecords.RemoveAll(x => x.Date.Year != year);
|
||||
}
|
||||
var viewModel = new CostMakeUpForVehicle
|
||||
{
|
||||
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost)
|
||||
};
|
||||
return PartialView("_CostMakeUpReport", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCostTableForVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
|
||||
var serviceRecords = vehicleRecords.ServiceRecords;
|
||||
var gasRecords = vehicleRecords.GasRecords;
|
||||
var collisionRecords = vehicleRecords.CollisionRecords;
|
||||
var taxRecords = vehicleRecords.TaxRecords;
|
||||
var upgradeRecords = vehicleRecords.UpgradeRecords;
|
||||
var odometerRecords = vehicleRecords.OdometerRecords;
|
||||
if (year != default)
|
||||
{
|
||||
serviceRecords.RemoveAll(x => x.Date.Year != year);
|
||||
gasRecords.RemoveAll(x => x.Date.Year != year);
|
||||
collisionRecords.RemoveAll(x => x.Date.Year != year);
|
||||
taxRecords.RemoveAll(x => x.Date.Year != year);
|
||||
upgradeRecords.RemoveAll(x => x.Date.Year != year);
|
||||
odometerRecords.RemoveAll(x => x.Date.Year != year);
|
||||
}
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
|
||||
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
var totalDistanceTraveled = maxMileage - minMileage;
|
||||
var totalDays = _vehicleLogic.GetOwnershipDays(vehicleData.PurchaseDate, vehicleData.SoldDate, year, serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords, taxRecords);
|
||||
var viewModel = new CostTableForVehicle
|
||||
{
|
||||
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost),
|
||||
TotalDistance = totalDistanceTraveled,
|
||||
DistanceUnit = vehicleData.UseHours ? "Cost Per Hour" : userConfig.UseMPG ? "Cost Per Mile" : "Cost Per Kilometer",
|
||||
NumberOfDays = totalDays
|
||||
};
|
||||
return PartialView("_CostTableReport", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd)
|
||||
{
|
||||
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now.AddDays(daysToAdd));
|
||||
var viewModel = new ReminderMakeUpForVehicle
|
||||
{
|
||||
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
|
||||
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
|
||||
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
|
||||
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
|
||||
};
|
||||
return PartialView("_ReminderMakeUpReport", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult GetVehicleAttachments(int vehicleId, List<ImportMode> exportTabs)
|
||||
{
|
||||
List<GenericReportModel> attachmentData = new List<GenericReportModel>();
|
||||
if (exportTabs.Contains(ImportMode.ServiceRecord))
|
||||
{
|
||||
var records = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.ServiceRecord,
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.RepairRecord))
|
||||
{
|
||||
var records = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.RepairRecord,
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.UpgradeRecord))
|
||||
{
|
||||
var records = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.UpgradeRecord,
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.GasRecord))
|
||||
{
|
||||
var records = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.GasRecord,
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.TaxRecord))
|
||||
{
|
||||
var records = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.TaxRecord,
|
||||
Date = x.Date,
|
||||
Odometer = 0,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.OdometerRecord))
|
||||
{
|
||||
var records = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.OdometerRecord,
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (exportTabs.Contains(ImportMode.NoteRecord))
|
||||
{
|
||||
var records = _noteDataAccess.GetNotesByVehicleId(vehicleId).Where(x => x.Files.Any());
|
||||
attachmentData.AddRange(records.Select(x => new GenericReportModel
|
||||
{
|
||||
DataType = ImportMode.NoteRecord,
|
||||
Date = DateTime.Now,
|
||||
Odometer = 0,
|
||||
Files = x.Files
|
||||
}));
|
||||
}
|
||||
if (attachmentData.Any())
|
||||
{
|
||||
attachmentData = attachmentData.OrderBy(x => x.Date).ThenBy(x => x.Odometer).ToList();
|
||||
var result = _fileHelper.MakeAttachmentsExport(attachmentData);
|
||||
if (string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
return Json(OperationResponse.Failed());
|
||||
}
|
||||
return Json(OperationResponse.Succeed(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(OperationResponse.Failed("No Attachments Found"));
|
||||
}
|
||||
}
|
||||
public IActionResult GetReportParameters()
|
||||
{
|
||||
var viewModel = new ReportParameter() {
|
||||
VisibleColumns = new List<string> {
|
||||
nameof(GenericReportModel.DataType),
|
||||
nameof(GenericReportModel.Date),
|
||||
nameof(GenericReportModel.Odometer),
|
||||
nameof(GenericReportModel.Description),
|
||||
nameof(GenericReportModel.Cost),
|
||||
nameof(GenericReportModel.Notes)
|
||||
}
|
||||
};
|
||||
//get all extra fields from service records, repairs, upgrades, and tax records.
|
||||
var recordTypes = new List<int>() { 0, 1, 3, 4 };
|
||||
var extraFields = new List<string>();
|
||||
foreach(int recordType in recordTypes)
|
||||
{
|
||||
extraFields.AddRange(_extraFieldDataAccess.GetExtraFieldsById(recordType).ExtraFields.Select(x => x.Name));
|
||||
}
|
||||
viewModel.ExtraFields = extraFields.Distinct().ToList();
|
||||
|
||||
return PartialView("_ReportParameters", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
public IActionResult GetVehicleHistory(int vehicleId, ReportParameter reportParameter)
|
||||
{
|
||||
var vehicleHistory = new VehicleHistoryViewModel();
|
||||
vehicleHistory.ReportParameters = reportParameter;
|
||||
vehicleHistory.VehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
|
||||
bool useMPG = _config.GetUserConfig(User).UseMPG;
|
||||
bool useUKMPG = _config.GetUserConfig(User).UseUKMPG;
|
||||
var gasViewModels = _gasHelper.GetGasRecordViewModels(vehicleRecords.GasRecords, useMPG, useUKMPG);
|
||||
//filter by tags
|
||||
if (reportParameter.Tags.Any())
|
||||
{
|
||||
if (reportParameter.TagFilter == TagFilter.Exclude)
|
||||
{
|
||||
vehicleRecords.OdometerRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.ServiceRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.CollisionRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.UpgradeRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.TaxRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
gasViewModels.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.GasRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
}
|
||||
else if (reportParameter.TagFilter == TagFilter.IncludeOnly)
|
||||
{
|
||||
vehicleRecords.OdometerRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.ServiceRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.CollisionRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.UpgradeRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.TaxRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
gasViewModels.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
vehicleRecords.GasRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
|
||||
}
|
||||
}
|
||||
//filter by date range.
|
||||
if (reportParameter.FilterByDateRange && !string.IsNullOrWhiteSpace(reportParameter.StartDate) && !string.IsNullOrWhiteSpace(reportParameter.EndDate))
|
||||
{
|
||||
var startDate = DateTime.Parse(reportParameter.StartDate).Date;
|
||||
var endDate = DateTime.Parse(reportParameter.EndDate).Date;
|
||||
//validate date range
|
||||
if (endDate >= startDate) //allow for same day.
|
||||
{
|
||||
vehicleHistory.StartDate = reportParameter.StartDate;
|
||||
vehicleHistory.EndDate = reportParameter.EndDate;
|
||||
//remove all records with dates after the end date and dates before the start date.
|
||||
vehicleRecords.OdometerRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
vehicleRecords.ServiceRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
vehicleRecords.CollisionRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
vehicleRecords.UpgradeRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
vehicleRecords.TaxRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
gasViewModels.RemoveAll(x => DateTime.Parse(x.Date).Date > endDate || DateTime.Parse(x.Date).Date < startDate);
|
||||
vehicleRecords.GasRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
|
||||
}
|
||||
}
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
|
||||
vehicleHistory.Odometer = maxMileage.ToString("N0");
|
||||
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
|
||||
var distanceTraveled = maxMileage - minMileage;
|
||||
if (!string.IsNullOrWhiteSpace(vehicleHistory.VehicleData.PurchaseDate))
|
||||
{
|
||||
var endDate = vehicleHistory.VehicleData.SoldDate;
|
||||
int daysOwned = 0;
|
||||
if (string.IsNullOrWhiteSpace(endDate))
|
||||
{
|
||||
endDate = DateTime.Now.ToShortDateString();
|
||||
}
|
||||
try
|
||||
{
|
||||
daysOwned = (DateTime.Parse(endDate) - DateTime.Parse(vehicleHistory.VehicleData.PurchaseDate)).Days;
|
||||
vehicleHistory.DaysOwned = daysOwned.ToString("N0");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
vehicleHistory.DaysOwned = string.Empty;
|
||||
}
|
||||
//calculate depreciation
|
||||
var totalDepreciation = vehicleHistory.VehicleData.PurchasePrice - vehicleHistory.VehicleData.SoldPrice;
|
||||
//we only calculate depreciation if a sold price is provided.
|
||||
if (totalDepreciation != default && vehicleHistory.VehicleData.SoldPrice != default)
|
||||
{
|
||||
vehicleHistory.TotalDepreciation = totalDepreciation;
|
||||
if (daysOwned != default)
|
||||
{
|
||||
vehicleHistory.DepreciationPerDay = Math.Abs(totalDepreciation / daysOwned);
|
||||
}
|
||||
if (distanceTraveled != default)
|
||||
{
|
||||
vehicleHistory.DepreciationPerMile = Math.Abs(totalDepreciation / distanceTraveled);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GenericReportModel> reportData = new List<GenericReportModel>();
|
||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||
vehicleHistory.DistanceUnit = vehicleHistory.VehicleData.UseHours ? "h" : useMPG ? "mi." : "km";
|
||||
vehicleHistory.TotalGasCost = gasViewModels.Sum(x => x.Cost);
|
||||
vehicleHistory.TotalCost = vehicleRecords.ServiceRecords.Sum(x => x.Cost) + vehicleRecords.CollisionRecords.Sum(x => x.Cost) + vehicleRecords.UpgradeRecords.Sum(x => x.Cost) + vehicleRecords.TaxRecords.Sum(x => x.Cost);
|
||||
if (distanceTraveled != default)
|
||||
{
|
||||
vehicleHistory.DistanceTraveled = distanceTraveled.ToString("N0");
|
||||
vehicleHistory.TotalCostPerMile = vehicleHistory.TotalCost / distanceTraveled;
|
||||
vehicleHistory.TotalGasCostPerMile = vehicleHistory.TotalGasCost / distanceTraveled;
|
||||
}
|
||||
var averageMPG = "0";
|
||||
if (gasViewModels.Any())
|
||||
{
|
||||
averageMPG = _gasHelper.GetAverageGasMileage(gasViewModels, useMPG);
|
||||
}
|
||||
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleHistory.VehicleData.IsElectric, vehicleHistory.VehicleData.UseHours, useMPG, useUKMPG);
|
||||
if (fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l")
|
||||
{
|
||||
//conversion needed.
|
||||
var newAverageMPG = decimal.Parse(averageMPG, NumberStyles.Any);
|
||||
if (newAverageMPG != 0)
|
||||
{
|
||||
newAverageMPG = 100 / newAverageMPG;
|
||||
}
|
||||
averageMPG = newAverageMPG.ToString("F");
|
||||
fuelEconomyMileageUnit = preferredFuelMileageUnit;
|
||||
}
|
||||
vehicleHistory.MPG = $"{averageMPG} {fuelEconomyMileageUnit}";
|
||||
//insert servicerecords
|
||||
reportData.AddRange(vehicleRecords.ServiceRecords.Select(x => new GenericReportModel
|
||||
{
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Description = x.Description,
|
||||
Notes = x.Notes,
|
||||
Cost = x.Cost,
|
||||
DataType = ImportMode.ServiceRecord,
|
||||
ExtraFields = x.ExtraFields,
|
||||
RequisitionHistory = x.RequisitionHistory
|
||||
}));
|
||||
//repair records
|
||||
reportData.AddRange(vehicleRecords.CollisionRecords.Select(x => new GenericReportModel
|
||||
{
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Description = x.Description,
|
||||
Notes = x.Notes,
|
||||
Cost = x.Cost,
|
||||
DataType = ImportMode.RepairRecord,
|
||||
ExtraFields = x.ExtraFields,
|
||||
RequisitionHistory = x.RequisitionHistory
|
||||
}));
|
||||
reportData.AddRange(vehicleRecords.UpgradeRecords.Select(x => new GenericReportModel
|
||||
{
|
||||
Date = x.Date,
|
||||
Odometer = x.Mileage,
|
||||
Description = x.Description,
|
||||
Notes = x.Notes,
|
||||
Cost = x.Cost,
|
||||
DataType = ImportMode.UpgradeRecord,
|
||||
ExtraFields = x.ExtraFields,
|
||||
RequisitionHistory = x.RequisitionHistory
|
||||
}));
|
||||
reportData.AddRange(vehicleRecords.TaxRecords.Select(x => new GenericReportModel
|
||||
{
|
||||
Date = x.Date,
|
||||
Odometer = 0,
|
||||
Description = x.Description,
|
||||
Notes = x.Notes,
|
||||
Cost = x.Cost,
|
||||
DataType = ImportMode.TaxRecord,
|
||||
ExtraFields = x.ExtraFields
|
||||
}));
|
||||
vehicleHistory.VehicleHistory = reportData.OrderBy(x => x.Date).ThenBy(x => x.Odometer).ToList();
|
||||
return PartialView("_VehicleHistory", vehicleHistory);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult GetMonthMPGByVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleData.IsElectric, vehicleData.UseHours, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
bool invertedFuelMileageUnit = fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l";
|
||||
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
|
||||
if (year != 0)
|
||||
{
|
||||
mileageData.RemoveAll(x => DateTime.Parse(x.Date).Year != year);
|
||||
}
|
||||
mileageData.RemoveAll(x => x.MilesPerGallon == default);
|
||||
var monthlyMileageData = StaticHelper.GetBaseLineCostsNoMonthName();
|
||||
monthlyMileageData.AddRange(mileageData.GroupBy(x => x.MonthId).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthId = x.Key,
|
||||
Cost = x.Average(y => y.MilesPerGallon)
|
||||
}));
|
||||
monthlyMileageData = monthlyMileageData.GroupBy(x => x.MonthId).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthId = x.Key,
|
||||
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
|
||||
Cost = x.Sum(y => y.Cost)
|
||||
}).ToList();
|
||||
if (invertedFuelMileageUnit)
|
||||
{
|
||||
foreach (CostForVehicleByMonth monthMileage in monthlyMileageData)
|
||||
{
|
||||
if (monthMileage.Cost != default)
|
||||
{
|
||||
monthMileage.Cost = 100 / monthMileage.Cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
var mpgViewModel = new MPGForVehicleByMonth
|
||||
{
|
||||
CostData = monthlyMileageData,
|
||||
Unit = invertedFuelMileageUnit ? preferredFuelMileageUnit : fuelEconomyMileageUnit,
|
||||
SortedCostData = (userConfig.UseMPG || invertedFuelMileageUnit) ? monthlyMileageData.OrderByDescending(x => x.Cost).ToList() : monthlyMileageData.OrderBy(x => x.Cost).ToList()
|
||||
};
|
||||
return PartialView("_MPGByMonthReport", mpgViewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult GetCostByMonthByVehicle(int vehicleId, List<ImportMode> selectedMetrics, int year = 0)
|
||||
{
|
||||
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
|
||||
if (selectedMetrics.Contains(ImportMode.ServiceRecord))
|
||||
{
|
||||
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, year));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.RepairRecord))
|
||||
{
|
||||
var repairRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetRepairRecordSum(repairRecords, year));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.UpgradeRecord))
|
||||
{
|
||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, year));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.GasRecord))
|
||||
{
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, year));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.TaxRecord))
|
||||
{
|
||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.OdometerRecord))
|
||||
{
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, year));
|
||||
}
|
||||
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
MonthName = x.Key.MonthName,
|
||||
Cost = x.Sum(y => y.Cost),
|
||||
DistanceTraveled = x.Max(y => y.DistanceTraveled)
|
||||
}).ToList();
|
||||
return PartialView("_GasCostByMonthReport", groupedRecord);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult GetCostByMonthAndYearByVehicle(int vehicleId, List<ImportMode> selectedMetrics, int year = 0)
|
||||
{
|
||||
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
|
||||
if (selectedMetrics.Contains(ImportMode.ServiceRecord))
|
||||
{
|
||||
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, year, true));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.RepairRecord))
|
||||
{
|
||||
var repairRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetRepairRecordSum(repairRecords, year, true));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.UpgradeRecord))
|
||||
{
|
||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, year, true));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.GasRecord))
|
||||
{
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, year, true));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.TaxRecord))
|
||||
{
|
||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year, true));
|
||||
}
|
||||
if (selectedMetrics.Contains(ImportMode.OdometerRecord))
|
||||
{
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, year, true));
|
||||
}
|
||||
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId, x.Year }).OrderByDescending(x=>x.Key.Year).Select(x => new CostForVehicleByMonth
|
||||
{
|
||||
Year = x.Key.Year,
|
||||
MonthName = x.Key.MonthName,
|
||||
Cost = x.Sum(y => y.Cost),
|
||||
DistanceTraveled = x.Max(y => y.DistanceTraveled),
|
||||
MonthId = x.Key.MonthId
|
||||
}).ToList();
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
var viewModel = new CostDistanceTableForVehicle { CostData = groupedRecord };
|
||||
viewModel.DistanceUnit = vehicleData.UseHours ? "h" : userConfig.UseMPG ? "mi." : "km";
|
||||
return PartialView("_CostDistanceTableReport", viewModel);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAdditionalWidgets()
|
||||
{
|
||||
var widgets = _fileHelper.GetWidgets();
|
||||
return PartialView("_ReportWidgets", widgets);
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Controllers/Vehicle/ServiceController.cs
Normal file
131
Controllers/Vehicle/ServiceController.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetServiceRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
|
||||
}
|
||||
return PartialView("Service/_ServiceRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveServiceRecordToVehicleId(ServiceRecordInput serviceRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), serviceRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
if (serviceRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = DateTime.Parse(serviceRecord.Date),
|
||||
VehicleId = serviceRecord.VehicleId,
|
||||
Mileage = serviceRecord.Mileage,
|
||||
Notes = $"Auto Insert From Service Record: {serviceRecord.Description}"
|
||||
});
|
||||
}
|
||||
//move files from temp.
|
||||
serviceRecord.Files = serviceRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
if (serviceRecord.Supplies.Any())
|
||||
{
|
||||
serviceRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(serviceRecord.Supplies, DateTime.Parse(serviceRecord.Date), serviceRecord.Description));
|
||||
if (serviceRecord.CopySuppliesAttachment)
|
||||
{
|
||||
serviceRecord.Files.AddRange(GetSuppliesAttachments(serviceRecord.Supplies));
|
||||
}
|
||||
}
|
||||
if (serviceRecord.DeletedRequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(serviceRecord.DeletedRequisitionHistory, serviceRecord.Description);
|
||||
}
|
||||
//push back any reminders
|
||||
if (serviceRecord.ReminderRecordId.Any())
|
||||
{
|
||||
foreach (int reminderRecordId in serviceRecord.ReminderRecordId)
|
||||
{
|
||||
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(serviceRecord.Date), serviceRecord.Mileage);
|
||||
}
|
||||
}
|
||||
var result = _serviceRecordDataAccess.SaveServiceRecordToVehicle(serviceRecord.ToServiceRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(serviceRecord.ToServiceRecord(), serviceRecord.Id == default ? "servicerecord.add" : "servicerecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddServiceRecordPartialView()
|
||||
{
|
||||
return PartialView("Service/_ServiceRecordModal", new ServiceRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetServiceRecordForEditById(int serviceRecordId)
|
||||
{
|
||||
var result = _serviceRecordDataAccess.GetServiceRecordById(serviceRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new ServiceRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
Mileage = result.Mileage,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
RequisitionHistory = result.RequisitionHistory,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Service/_ServiceRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteServiceRecordWithChecks(int serviceRecordId)
|
||||
{
|
||||
var existingRecord = _serviceRecordDataAccess.GetServiceRecordById(serviceRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//restore any requisitioned supplies.
|
||||
if (existingRecord.RequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
|
||||
}
|
||||
var result = _serviceRecordDataAccess.DeleteServiceRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "servicerecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteServiceRecordById(int serviceRecordId)
|
||||
{
|
||||
var result = DeleteServiceRecordWithChecks(serviceRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
215
Controllers/Vehicle/SupplyController.cs
Normal file
215
Controllers/Vehicle/SupplyController.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
private List<SupplyAvailability> CheckSupplyRecordsAvailability(List<SupplyUsage> supplyUsage)
|
||||
{
|
||||
//returns empty string if all supplies are available
|
||||
var result = new List<SupplyAvailability>();
|
||||
foreach (SupplyUsage supply in supplyUsage)
|
||||
{
|
||||
//get supply record.
|
||||
var supplyData = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
|
||||
if (supplyData == null)
|
||||
{
|
||||
result.Add(new SupplyAvailability { Missing = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(new SupplyAvailability { Missing = false, Description = supplyData.Description, Required = supply.Quantity, InStock = supplyData.Quantity });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private List<UploadedFiles> GetSuppliesAttachments(List<SupplyUsage> supplyUsage)
|
||||
{
|
||||
List<UploadedFiles> results = new List<UploadedFiles>();
|
||||
foreach (SupplyUsage supply in supplyUsage)
|
||||
{
|
||||
var result = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
|
||||
results.AddRange(result.Files);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
private List<SupplyUsageHistory> RequisitionSupplyRecordsByUsage(List<SupplyUsage> supplyUsage, DateTime dateRequisitioned, string usageDescription)
|
||||
{
|
||||
List<SupplyUsageHistory> results = new List<SupplyUsageHistory>();
|
||||
foreach (SupplyUsage supply in supplyUsage)
|
||||
{
|
||||
//get supply record.
|
||||
var result = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
|
||||
var unitCost = (result.Quantity != 0) ? result.Cost / result.Quantity : 0;
|
||||
//deduct quantity used.
|
||||
result.Quantity -= supply.Quantity;
|
||||
//deduct cost.
|
||||
result.Cost -= (supply.Quantity * unitCost);
|
||||
//check decimal places to ensure that it always has a max of 3 decimal places.
|
||||
var roundedDecimal = decimal.Round(result.Cost, 3);
|
||||
if (roundedDecimal != result.Cost)
|
||||
{
|
||||
//Too many decimals
|
||||
result.Cost = roundedDecimal;
|
||||
}
|
||||
//create new requisitionrrecord
|
||||
var requisitionRecord = new SupplyUsageHistory
|
||||
{
|
||||
Id = supply.SupplyId,
|
||||
Date = dateRequisitioned,
|
||||
Description = usageDescription,
|
||||
Quantity = supply.Quantity,
|
||||
Cost = (supply.Quantity * unitCost)
|
||||
};
|
||||
result.RequisitionHistory.Add(requisitionRecord);
|
||||
//save
|
||||
_supplyRecordDataAccess.SaveSupplyRecordToVehicle(result);
|
||||
requisitionRecord.Description = result.Description; //change the name of the description for plan/service/repair/upgrade records
|
||||
requisitionRecord.PartNumber = result.PartNumber; //populate part number if not displayed in supplies modal.
|
||||
results.Add(requisitionRecord);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetSupplyRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ToList();
|
||||
}
|
||||
return PartialView("Supply/_SupplyRecords", result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetSupplyRecordsForPlanRecordTemplate(int planRecordTemplateId)
|
||||
{
|
||||
var viewModel = new SupplyUsageViewModel();
|
||||
var planRecordTemplate = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
|
||||
if (planRecordTemplate != default && planRecordTemplate.VehicleId != default)
|
||||
{
|
||||
var supplies = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(planRecordTemplate.VehicleId);
|
||||
if (_config.GetServerEnableShopSupplies())
|
||||
{
|
||||
supplies.AddRange(_supplyRecordDataAccess.GetSupplyRecordsByVehicleId(0)); // add shop supplies
|
||||
}
|
||||
supplies.RemoveAll(x => x.Quantity <= 0);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
supplies = supplies.OrderByDescending(x => x.Date).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
supplies = supplies.OrderBy(x => x.Date).ToList();
|
||||
}
|
||||
viewModel.Supplies = supplies;
|
||||
viewModel.Usage = planRecordTemplate.Supplies;
|
||||
}
|
||||
return PartialView("Supply/_SupplyUsage", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetSupplyRecordsForRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
|
||||
if (_config.GetServerEnableShopSupplies())
|
||||
{
|
||||
result.AddRange(_supplyRecordDataAccess.GetSupplyRecordsByVehicleId(0)); // add shop supplies
|
||||
}
|
||||
result.RemoveAll(x => x.Quantity <= 0);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ToList();
|
||||
}
|
||||
var viewModel = new SupplyUsageViewModel
|
||||
{
|
||||
Supplies = result
|
||||
};
|
||||
return PartialView("Supply/_SupplyUsage", viewModel);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveSupplyRecordToVehicleId(SupplyRecordInput supplyRecord)
|
||||
{
|
||||
//move files from temp.
|
||||
supplyRecord.Files = supplyRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
var result = _supplyRecordDataAccess.SaveSupplyRecordToVehicle(supplyRecord.ToSupplyRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromSupplyRecord(supplyRecord.ToSupplyRecord(), supplyRecord.Id == default ? "supplyrecord.add" : "supplyrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddSupplyRecordPartialView()
|
||||
{
|
||||
return PartialView("Supply/_SupplyRecordModal", new SupplyRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetSupplyRecordForEditById(int supplyRecordId)
|
||||
{
|
||||
var result = _supplyRecordDataAccess.GetSupplyRecordById(supplyRecordId);
|
||||
if (result.RequisitionHistory.Any())
|
||||
{
|
||||
//requisition history when viewed through the supply is always immutable.
|
||||
result.RequisitionHistory = result.RequisitionHistory.Select(x => new SupplyUsageHistory { Id = default, Cost = x.Cost, Description = x.Description, Date = x.Date, PartNumber = x.PartNumber, Quantity = x.Quantity }).ToList();
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new SupplyRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
PartNumber = result.PartNumber,
|
||||
Quantity = result.Quantity,
|
||||
PartSupplier = result.PartSupplier,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
RequisitionHistory = result.RequisitionHistory,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Supply/_SupplyRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteSupplyRecordWithChecks(int supplyRecordId)
|
||||
{
|
||||
var existingRecord = _supplyRecordDataAccess.GetSupplyRecordById(supplyRecordId);
|
||||
if (existingRecord.VehicleId != default)
|
||||
{
|
||||
//security check only if not editing shop supply.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var result = _supplyRecordDataAccess.DeleteSupplyRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromSupplyRecord(existingRecord, "supplyrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteSupplyRecordById(int supplyRecordId)
|
||||
{
|
||||
var result = DeleteSupplyRecordWithChecks(supplyRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Controllers/Vehicle/TaxController.cs
Normal file
122
Controllers/Vehicle/TaxController.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetTaxRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ToList();
|
||||
}
|
||||
return PartialView("Tax/_TaxRecords", result);
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpPost]
|
||||
public IActionResult CheckRecurringTaxRecords(int vehicleId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _vehicleLogic.UpdateRecurringTaxes(vehicleId);
|
||||
return Json(result);
|
||||
} catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return Json(false);
|
||||
}
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveTaxRecordToVehicleId(TaxRecordInput taxRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), taxRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
//move files from temp.
|
||||
taxRecord.Files = taxRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
//push back any reminders
|
||||
if (taxRecord.ReminderRecordId.Any())
|
||||
{
|
||||
foreach (int reminderRecordId in taxRecord.ReminderRecordId)
|
||||
{
|
||||
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(taxRecord.Date), null);
|
||||
}
|
||||
}
|
||||
var result = _taxRecordDataAccess.SaveTaxRecordToVehicle(taxRecord.ToTaxRecord());
|
||||
_vehicleLogic.UpdateRecurringTaxes(taxRecord.VehicleId);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(taxRecord.ToTaxRecord(), taxRecord.Id == default ? "taxrecord.add" : "taxrecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddTaxRecordPartialView()
|
||||
{
|
||||
return PartialView("Tax/_TaxRecordModal", new TaxRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetTaxRecordForEditById(int taxRecordId)
|
||||
{
|
||||
var result = _taxRecordDataAccess.GetTaxRecordById(taxRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new TaxRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
IsRecurring = result.IsRecurring,
|
||||
RecurringInterval = result.RecurringInterval,
|
||||
CustomMonthInterval = result.CustomMonthInterval,
|
||||
CustomMonthIntervalUnit = result.CustomMonthIntervalUnit,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Tax/_TaxRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteTaxRecordWithChecks(int taxRecordId)
|
||||
{
|
||||
var existingRecord = _taxRecordDataAccess.GetTaxRecordById(taxRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = _taxRecordDataAccess.DeleteTaxRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(existingRecord, "taxrecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteTaxRecordById(int taxRecordId)
|
||||
{
|
||||
var result = DeleteTaxRecordWithChecks(taxRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Controllers/Vehicle/UpgradeController.cs
Normal file
131
Controllers/Vehicle/UpgradeController.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using MotoVaultPro.Filter;
|
||||
using MotoVaultPro.Helper;
|
||||
using MotoVaultPro.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MotoVaultPro.Controllers
|
||||
{
|
||||
public partial class VehicleController
|
||||
{
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetUpgradeRecordsByVehicleId(int vehicleId)
|
||||
{
|
||||
var result = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
bool _useDescending = _config.GetUserConfig(User).UseDescending;
|
||||
if (_useDescending)
|
||||
{
|
||||
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
|
||||
}
|
||||
return PartialView("Upgrade/_UpgradeRecords", result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult SaveUpgradeRecordToVehicleId(UpgradeRecordInput upgradeRecord)
|
||||
{
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), upgradeRecord.VehicleId))
|
||||
{
|
||||
return Json(false);
|
||||
}
|
||||
if (upgradeRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
|
||||
{
|
||||
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
|
||||
{
|
||||
Date = DateTime.Parse(upgradeRecord.Date),
|
||||
VehicleId = upgradeRecord.VehicleId,
|
||||
Mileage = upgradeRecord.Mileage,
|
||||
Notes = $"Auto Insert From Upgrade Record: {upgradeRecord.Description}"
|
||||
});
|
||||
}
|
||||
//move files from temp.
|
||||
upgradeRecord.Files = upgradeRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
|
||||
if (upgradeRecord.Supplies.Any())
|
||||
{
|
||||
upgradeRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(upgradeRecord.Supplies, DateTime.Parse(upgradeRecord.Date), upgradeRecord.Description));
|
||||
if (upgradeRecord.CopySuppliesAttachment)
|
||||
{
|
||||
upgradeRecord.Files.AddRange(GetSuppliesAttachments(upgradeRecord.Supplies));
|
||||
}
|
||||
}
|
||||
if (upgradeRecord.DeletedRequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(upgradeRecord.DeletedRequisitionHistory, upgradeRecord.Description);
|
||||
}
|
||||
//push back any reminders
|
||||
if (upgradeRecord.ReminderRecordId.Any())
|
||||
{
|
||||
foreach (int reminderRecordId in upgradeRecord.ReminderRecordId)
|
||||
{
|
||||
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(upgradeRecord.Date), upgradeRecord.Mileage);
|
||||
}
|
||||
}
|
||||
var result = _upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(upgradeRecord.ToUpgradeRecord());
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(upgradeRecord.ToUpgradeRecord(), upgradeRecord.Id == default ? "upgraderecord.add" : "upgraderecord.update", User.Identity.Name));
|
||||
}
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetAddUpgradeRecordPartialView()
|
||||
{
|
||||
return PartialView("Upgrade/_UpgradeRecordModal", new UpgradeRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetUpgradeRecordForEditById(int upgradeRecordId)
|
||||
{
|
||||
var result = _upgradeRecordDataAccess.GetUpgradeRecordById(upgradeRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
|
||||
{
|
||||
return Redirect("/Error/Unauthorized");
|
||||
}
|
||||
//convert to Input object.
|
||||
var convertedResult = new UpgradeRecordInput
|
||||
{
|
||||
Id = result.Id,
|
||||
Cost = result.Cost,
|
||||
Date = result.Date.ToShortDateString(),
|
||||
Description = result.Description,
|
||||
Mileage = result.Mileage,
|
||||
Notes = result.Notes,
|
||||
VehicleId = result.VehicleId,
|
||||
Files = result.Files,
|
||||
Tags = result.Tags,
|
||||
RequisitionHistory = result.RequisitionHistory,
|
||||
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields)
|
||||
};
|
||||
return PartialView("Upgrade/_UpgradeRecordModal", convertedResult);
|
||||
}
|
||||
private bool DeleteUpgradeRecordWithChecks(int upgradeRecordId)
|
||||
{
|
||||
var existingRecord = _upgradeRecordDataAccess.GetUpgradeRecordById(upgradeRecordId);
|
||||
//security check.
|
||||
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//restore any requisitioned supplies.
|
||||
if (existingRecord.RequisitionHistory.Any())
|
||||
{
|
||||
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
|
||||
}
|
||||
var result = _upgradeRecordDataAccess.DeleteUpgradeRecordById(existingRecord.Id);
|
||||
if (result)
|
||||
{
|
||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "upgraderecord.delete", User.Identity.Name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteUpgradeRecordById(int upgradeRecordId)
|
||||
{
|
||||
var result = DeleteUpgradeRecordWithChecks(upgradeRecordId);
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user