From a542c91dc30aaf9aeeb543759ca301f1a78c444f Mon Sep 17 00:00:00 2001 From: "DESKTOP-GENO133\\IvanPlex" Date: Tue, 6 Feb 2024 12:45:39 -0700 Subject: [PATCH 1/3] added backend for saving and retrieving plan record templates. --- Controllers/VehicleController.cs | 65 +++++++++++++++++++ .../PlanRecordTemplateDataAccess.cs | 57 ++++++++++++++++ .../IPlanRecordTemplateDataAccess.cs | 13 ++++ Program.cs | 1 + Views/Vehicle/_PlanRecords.cshtml | 7 ++ 5 files changed, 143 insertions(+) create mode 100644 External/Implementations/PlanRecordTemplateDataAccess.cs create mode 100644 External/Interfaces/IPlanRecordTemplateDataAccess.cs diff --git a/Controllers/VehicleController.cs b/Controllers/VehicleController.cs index 65a6c14..6ac5c58 100644 --- a/Controllers/VehicleController.cs +++ b/Controllers/VehicleController.cs @@ -27,6 +27,7 @@ namespace CarCareTracker.Controllers private readonly IUpgradeRecordDataAccess _upgradeRecordDataAccess; private readonly ISupplyRecordDataAccess _supplyRecordDataAccess; private readonly IPlanRecordDataAccess _planRecordDataAccess; + private readonly IPlanRecordTemplateDataAccess _planRecordTemplateDataAccess; private readonly IOdometerRecordDataAccess _odometerRecordDataAccess; private readonly IWebHostEnvironment _webEnv; private readonly IConfigHelper _config; @@ -51,6 +52,7 @@ namespace CarCareTracker.Controllers IUpgradeRecordDataAccess upgradeRecordDataAccess, ISupplyRecordDataAccess supplyRecordDataAccess, IPlanRecordDataAccess planRecordDataAccess, + IPlanRecordTemplateDataAccess planRecordTemplateDataAccess, IOdometerRecordDataAccess odometerRecordDataAccess, IUserLogic userLogic, IWebHostEnvironment webEnv, @@ -71,6 +73,7 @@ namespace CarCareTracker.Controllers _upgradeRecordDataAccess = upgradeRecordDataAccess; _supplyRecordDataAccess = supplyRecordDataAccess; _planRecordDataAccess = planRecordDataAccess; + _planRecordTemplateDataAccess = planRecordTemplateDataAccess; _odometerRecordDataAccess = odometerRecordDataAccess; _userLogic = userLogic; _webEnv = webEnv; @@ -142,6 +145,7 @@ namespace CarCareTracker.Controllers _reminderRecordDataAccess.DeleteAllReminderRecordsByVehicleId(vehicleId) && _upgradeRecordDataAccess.DeleteAllUpgradeRecordsByVehicleId(vehicleId) && _planRecordDataAccess.DeleteAllPlanRecordsByVehicleId(vehicleId) && + _planRecordTemplateDataAccess.DeleteAllPlanRecordTemplatesByVehicleId(vehicleId) && _supplyRecordDataAccess.DeleteAllSupplyRecordsByVehicleId(vehicleId) && _userLogic.DeleteAllAccessToVehicle(vehicleId) && _dataAccess.DeleteVehicle(vehicleId); @@ -1467,6 +1471,21 @@ namespace CarCareTracker.Controllers } #endregion #region "Supply Records" + private List CheckSupplyRecordsAvailability(List supplyUsage) + { + //returns empty string if all supplies are available + var result = new List(); + foreach (SupplyUsage supply in supplyUsage) + { + //get supply record. + var supplyData = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId); + if (supply.Quantity > supplyData.Quantity) + { + result.Add($"Insufficient Quantity for {supplyData.Description}, need: {supply.Quantity}, available: {supplyData.Quantity}"); + } + } + return result; + } private void RequisitionSupplyRecordsByUsage(List supplyUsage) { foreach(SupplyUsage supply in supplyUsage) @@ -1581,6 +1600,52 @@ namespace CarCareTracker.Controllers } return Json(result); } + [HttpPost] + public IActionResult SavePlanRecordTemplateToVehicleId(PlanRecordInput planRecord) + { + //check if template name already taken. + var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(planRecord.VehicleId).Where(x=>x.Description == planRecord.Description).Any(); + if (existingRecord) + { + return Json(new OperationResponse { Success = false, Message = "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(new OperationResponse { Success = result, Message = result ? "Template Added" : StaticHelper.GenericErrorMessage }); + } + [HttpGet] + public IActionResult GetPlanRecordTemplatesForVehicleId(int vehicleId) + { + var result = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(vehicleId); + return PartialView("_PlanRecordTemplateModal", result); + } + [HttpPost] + public IActionResult ConvertPlanRecordTemplateToPlanRecord(int planRecordTemplateId) + { + var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId); + if (existingRecord.Id == default) + { + return Json(new OperationResponse { Success = false, Message = "Unable to find template" }); + } + if (existingRecord.Supplies.Any()) + { + //check if all supplies are available + var supplyAvailability = CheckSupplyRecordsAvailability(existingRecord.Supplies); + if (supplyAvailability.Any()) + { + return Json(new OperationResponse { Success = false, Message = string.Join("
", supplyAvailability) }); + } + } + //populate createdDate + existingRecord.DateCreated = DateTime.Now.ToString("G"); + existingRecord.DateModified = DateTime.Now.ToString("G"); + var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord.ToPlanRecord()); + if (result && existingRecord.Supplies.Any()) + { + RequisitionSupplyRecordsByUsage(existingRecord.Supplies); + } + return Json(new OperationResponse { Success = result, Message = result ? "Plan Record Added" : StaticHelper.GenericErrorMessage }); + } [HttpGet] public IActionResult GetAddPlanRecordPartialView() { diff --git a/External/Implementations/PlanRecordTemplateDataAccess.cs b/External/Implementations/PlanRecordTemplateDataAccess.cs new file mode 100644 index 0000000..c11efd5 --- /dev/null +++ b/External/Implementations/PlanRecordTemplateDataAccess.cs @@ -0,0 +1,57 @@ +using CarCareTracker.External.Interfaces; +using CarCareTracker.Helper; +using CarCareTracker.Models; +using LiteDB; + +namespace CarCareTracker.External.Implementations +{ + public class PlanRecordTemplateDataAccess : IPlanRecordTemplateDataAccess + { + private static string dbName = StaticHelper.DbName; + private static string tableName = "planrecordtemplates"; + public List GetPlanRecordTemplatesByVehicleId(int vehicleId) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + var planRecords = table.Find(Query.EQ(nameof(PlanRecordInput.VehicleId), vehicleId)); + return planRecords.ToList() ?? new List(); + }; + } + public PlanRecordInput GetPlanRecordTemplateById(int planRecordId) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + return table.FindById(planRecordId); + }; + } + public bool DeletePlanRecordTemplateById(int planRecordId) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + table.Delete(planRecordId); + return true; + }; + } + public bool SavePlanRecordTemplateToVehicle(PlanRecordInput planRecord) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + table.Upsert(planRecord); + return true; + }; + } + public bool DeleteAllPlanRecordTemplatesByVehicleId(int vehicleId) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + var planRecords = table.DeleteMany(Query.EQ(nameof(PlanRecordInput.VehicleId), vehicleId)); + return true; + }; + } + } +} diff --git a/External/Interfaces/IPlanRecordTemplateDataAccess.cs b/External/Interfaces/IPlanRecordTemplateDataAccess.cs new file mode 100644 index 0000000..60a9d2f --- /dev/null +++ b/External/Interfaces/IPlanRecordTemplateDataAccess.cs @@ -0,0 +1,13 @@ +using CarCareTracker.Models; + +namespace CarCareTracker.External.Interfaces +{ + public interface IPlanRecordTemplateDataAccess + { + public List GetPlanRecordTemplatesByVehicleId(int vehicleId); + public PlanRecordInput GetPlanRecordTemplateById(int planRecordId); + public bool DeletePlanRecordTemplateById(int planRecordId); + public bool SavePlanRecordTemplateToVehicle(PlanRecordInput planRecord); + public bool DeleteAllPlanRecordTemplatesByVehicleId(int vehicleId); + } +} diff --git a/Program.cs b/Program.cs index f01d1d0..b212639 100644 --- a/Program.cs +++ b/Program.cs @@ -26,6 +26,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(); //configure helpers diff --git a/Views/Vehicle/_PlanRecords.cshtml b/Views/Vehicle/_PlanRecords.cshtml index a982be8..4ddd231 100644 --- a/Views/Vehicle/_PlanRecords.cshtml +++ b/Views/Vehicle/_PlanRecords.cshtml @@ -100,4 +100,11 @@ + + + \ No newline at end of file From a52ac6a41bb9a692705dd07ae17830ab3711741f Mon Sep 17 00:00:00 2001 From: "DESKTOP-GENO133\\IvanPlex" Date: Tue, 6 Feb 2024 15:54:32 -0700 Subject: [PATCH 2/3] Front end for creating plan records from templates. --- Controllers/VehicleController.cs | 8 ++ Views/Vehicle/_PlanRecordModal.cshtml | 11 ++- Views/Vehicle/_PlanRecordTemplateModal.cshtml | 87 +++++++++++++++++++ Views/Vehicle/_PlanRecords.cshtml | 2 +- wwwroot/js/planrecord.js | 73 ++++++++++++++++ 5 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 Views/Vehicle/_PlanRecordTemplateModal.cshtml diff --git a/Controllers/VehicleController.cs b/Controllers/VehicleController.cs index 6ac5c58..fdada44 100644 --- a/Controllers/VehicleController.cs +++ b/Controllers/VehicleController.cs @@ -1613,6 +1613,7 @@ namespace CarCareTracker.Controllers var result = _planRecordTemplateDataAccess.SavePlanRecordTemplateToVehicle(planRecord); return Json(new OperationResponse { Success = result, Message = result ? "Template Added" : StaticHelper.GenericErrorMessage }); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetPlanRecordTemplatesForVehicleId(int vehicleId) { @@ -1620,6 +1621,12 @@ namespace CarCareTracker.Controllers return PartialView("_PlanRecordTemplateModal", result); } [HttpPost] + public IActionResult DeletePlanRecordTemplateById(int planRecordTemplateId) + { + var result = _planRecordTemplateDataAccess.DeletePlanRecordTemplateById(planRecordTemplateId); + return Json(result); + } + [HttpPost] public IActionResult ConvertPlanRecordTemplateToPlanRecord(int planRecordTemplateId) { var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId); @@ -1639,6 +1646,7 @@ namespace CarCareTracker.Controllers //populate createdDate existingRecord.DateCreated = DateTime.Now.ToString("G"); existingRecord.DateModified = DateTime.Now.ToString("G"); + existingRecord.Id = default; var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord.ToPlanRecord()); if (result && existingRecord.Supplies.Any()) { diff --git a/Views/Vehicle/_PlanRecordModal.cshtml b/Views/Vehicle/_PlanRecordModal.cshtml index a88c0af..b924d03 100644 --- a/Views/Vehicle/_PlanRecordModal.cshtml +++ b/Views/Vehicle/_PlanRecordModal.cshtml @@ -82,7 +82,16 @@ @if (isNew) { - +
+ + + +
} else if (!isNew) { diff --git a/Views/Vehicle/_PlanRecordTemplateModal.cshtml b/Views/Vehicle/_PlanRecordTemplateModal.cshtml new file mode 100644 index 0000000..198e17d --- /dev/null +++ b/Views/Vehicle/_PlanRecordTemplateModal.cshtml @@ -0,0 +1,87 @@ +@using CarCareTracker.Helper +@inject IConfigHelper config +@inject ITranslationHelper translator +@{ + var userConfig = config.GetUserConfig(User); + var userLanguage = userConfig.UserLanguage; +} +@model List + + + \ No newline at end of file diff --git a/Views/Vehicle/_PlanRecords.cshtml b/Views/Vehicle/_PlanRecords.cshtml index 4ddd231..b01cba8 100644 --- a/Views/Vehicle/_PlanRecords.cshtml +++ b/Views/Vehicle/_PlanRecords.cshtml @@ -102,7 +102,7 @@ -