mirror of
https://github.com/hargata/lubelog.git
synced 2025-12-10 00:46:08 -06:00
Compare commits
9 Commits
4d9c5c7237
...
98561e7f00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98561e7f00 | ||
|
|
780856433d | ||
|
|
5c895b4f82 | ||
|
|
ec52bc09e4 | ||
|
|
c0cfd74fc6 | ||
|
|
066e5ca648 | ||
|
|
e30f1def1e | ||
|
|
a137fbaa52 | ||
|
|
b98585006b |
@ -72,7 +72,11 @@ namespace CarCareTracker.Controllers
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult DeleteUser(int userId)
|
public IActionResult DeleteUser(int userId)
|
||||||
{
|
{
|
||||||
var result =_userLogic.DeleteAllAccessToUser(userId) && _configHelper.DeleteUserConfig(userId) && _loginLogic.DeleteUser(userId);
|
var result =_userLogic.DeleteAllAccessToUser(userId)
|
||||||
|
&& _configHelper.DeleteUserConfig(userId)
|
||||||
|
&& _loginLogic.DeleteUser(userId)
|
||||||
|
&& _userLogic.DeleteAllHouseholdByChildUserId(userId)
|
||||||
|
&& _userLogic.DeleteAllHouseholdByParentUserId(userId);
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@ -81,5 +85,24 @@ namespace CarCareTracker.Controllers
|
|||||||
var result = _loginLogic.MakeUserAdmin(userId, isAdmin);
|
var result = _loginLogic.MakeUserAdmin(userId, isAdmin);
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetUserHouseholdModal(int userId)
|
||||||
|
{
|
||||||
|
var households = _userLogic.GetHouseholdForParentUserId(userId);
|
||||||
|
var viewModel = new UserHouseholdAdminViewModel { Households = households, ParentUserId = userId };
|
||||||
|
return PartialView("_AdminUserHouseholdModal", viewModel);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RemoveUserFromHousehold(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
var result = _userLogic.DeleteUserFromHousehold(parentUserId, childUserId);
|
||||||
|
return Json(result);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult AddUserToHousehold(int parentUserId, string username)
|
||||||
|
{
|
||||||
|
var result = _userLogic.AddUserToHousehold(parentUserId, username);
|
||||||
|
return Json(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -289,6 +289,24 @@ namespace CarCareTracker.Controllers
|
|||||||
var userName = User.Identity.Name;
|
var userName = User.Identity.Name;
|
||||||
return PartialView("_AccountModal", new UserData() { EmailAddress = emailAddress, UserName = userName });
|
return PartialView("_AccountModal", new UserData() { EmailAddress = emailAddress, UserName = userName });
|
||||||
}
|
}
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetHouseholdModal()
|
||||||
|
{
|
||||||
|
var households = _userLogic.GetHouseholdForParentUserId(GetUserID());
|
||||||
|
return PartialView("_UserHouseholdModal", households);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult RemoveUserFromHousehold(int userId)
|
||||||
|
{
|
||||||
|
var result = _userLogic.DeleteUserFromHousehold(GetUserID(), userId);
|
||||||
|
return Json(result);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult AddUserToHousehold(string username)
|
||||||
|
{
|
||||||
|
var result = _userLogic.AddUserToHousehold(GetUserID(), username);
|
||||||
|
return Json(result);
|
||||||
|
}
|
||||||
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetRootAccountInformationModal()
|
public IActionResult GetRootAccountInformationModal()
|
||||||
|
|||||||
@ -54,7 +54,8 @@ namespace CarCareTracker.Controllers
|
|||||||
"CREATE TABLE IF NOT EXISTS app.useraccessrecords (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))",
|
"CREATE TABLE IF NOT EXISTS app.useraccessrecords (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))",
|
||||||
"CREATE TABLE IF NOT EXISTS app.extrafields (id INT primary key, data jsonb not null)",
|
"CREATE TABLE IF NOT EXISTS app.extrafields (id INT primary key, data jsonb not null)",
|
||||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
"CREATE TABLE IF NOT EXISTS app.inspectionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)"
|
"CREATE TABLE IF NOT EXISTS app.inspectionrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||||
|
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, PRIMARY KEY(parentUserId, childUserId))"
|
||||||
};
|
};
|
||||||
foreach(string cmd in cmds)
|
foreach(string cmd in cmds)
|
||||||
{
|
{
|
||||||
@ -103,6 +104,7 @@ namespace CarCareTracker.Controllers
|
|||||||
var extrafields = new List<RecordExtraField>();
|
var extrafields = new List<RecordExtraField>();
|
||||||
var inspectionrecords = new List<InspectionRecord>();
|
var inspectionrecords = new List<InspectionRecord>();
|
||||||
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
||||||
|
var userhouseholdrecords = new List<UserHousehold>();
|
||||||
#region "Part1"
|
#region "Part1"
|
||||||
string cmd = $"SELECT data FROM app.vehicles";
|
string cmd = $"SELECT data FROM app.vehicles";
|
||||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
@ -455,6 +457,32 @@ namespace CarCareTracker.Controllers
|
|||||||
table.Upsert(record);
|
table.Upsert(record);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
cmd = $"SELECT parentUserId, childUserId FROM app.userhouseholdrecords";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UserHousehold result = new UserHousehold()
|
||||||
|
{
|
||||||
|
Id = new HouseholdAccess
|
||||||
|
{
|
||||||
|
ParentUserId = int.Parse(reader["parentUserId"].ToString()),
|
||||||
|
ChildUserId = int.Parse(reader["childUserId"].ToString())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
userhouseholdrecords.Add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var record in userhouseholdrecords)
|
||||||
|
{
|
||||||
|
using (var db = new LiteDatabase(fullFileName))
|
||||||
|
{
|
||||||
|
var table = db.GetCollection<UserHousehold>("userhouseholdrecords");
|
||||||
|
table.Upsert(record);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
var destFilePath = $"{fullFolderPath}.zip";
|
var destFilePath = $"{fullFolderPath}.zip";
|
||||||
ZipFile.CreateFromDirectory(fullFolderPath, destFilePath);
|
ZipFile.CreateFromDirectory(fullFolderPath, destFilePath);
|
||||||
@ -505,6 +533,7 @@ namespace CarCareTracker.Controllers
|
|||||||
var extrafields = new List<RecordExtraField>();
|
var extrafields = new List<RecordExtraField>();
|
||||||
var inspectionrecords = new List<InspectionRecord>();
|
var inspectionrecords = new List<InspectionRecord>();
|
||||||
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
var inspectionrecordtemplates = new List<InspectionRecordInput>();
|
||||||
|
var userhouseholdrecords = new List<UserHousehold>();
|
||||||
#region "Part1"
|
#region "Part1"
|
||||||
using (var db = new LiteDatabase(fullFileName))
|
using (var db = new LiteDatabase(fullFileName))
|
||||||
{
|
{
|
||||||
@ -816,6 +845,22 @@ namespace CarCareTracker.Controllers
|
|||||||
ctext.ExecuteNonQuery();
|
ctext.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
using (var db = new LiteDatabase(fullFileName))
|
||||||
|
{
|
||||||
|
var table = db.GetCollection<UserHousehold>("userhouseholdrecords");
|
||||||
|
userhouseholdrecords = table.FindAll().ToList();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
foreach (var record in userhouseholdrecords)
|
||||||
|
{
|
||||||
|
string cmd = $"INSERT INTO app.userhouseholdrecords (parentUserId, childUserId) VALUES(@parentUserId, @childUserId)";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", record.Id.ParentUserId);
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", record.Id.ChildUserId);
|
||||||
|
ctext.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
return Json(OperationResponse.Succeed("Data Imported Successfully"));
|
return Json(OperationResponse.Succeed("Data Imported Successfully"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,7 +118,8 @@ namespace CarCareTracker.Controllers
|
|||||||
}
|
}
|
||||||
//get collaborators
|
//get collaborators
|
||||||
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||||
viewModel.Collaborators = collaborators;
|
var userCanModify = _userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleId);
|
||||||
|
viewModel.Collaborators = new VehicleCollaboratorViewModel { CanModifyCollaborators = userCanModify, Collaborators = collaborators};
|
||||||
//get MPG per month.
|
//get MPG per month.
|
||||||
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, !vehicleData.IsElectric && userConfig.UseUKMPG);
|
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, !vehicleData.IsElectric && userConfig.UseUKMPG);
|
||||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||||
@ -176,16 +177,22 @@ namespace CarCareTracker.Controllers
|
|||||||
public IActionResult GetCollaboratorsForVehicle(int vehicleId)
|
public IActionResult GetCollaboratorsForVehicle(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
var result = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||||
return PartialView("_Collaborators", result);
|
var userCanModify = _userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleId);
|
||||||
|
var viewModel = new VehicleCollaboratorViewModel
|
||||||
|
{
|
||||||
|
Collaborators = result,
|
||||||
|
CanModifyCollaborators = userCanModify
|
||||||
|
};
|
||||||
|
return PartialView("_Collaborators", viewModel);
|
||||||
}
|
}
|
||||||
[TypeFilter(typeof(CollaboratorFilter))]
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] {false, true})]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult AddCollaboratorsToVehicle(int vehicleId, string username)
|
public IActionResult AddCollaboratorsToVehicle(int vehicleId, string username)
|
||||||
{
|
{
|
||||||
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
|
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[TypeFilter(typeof(CollaboratorFilter))]
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { false, true })]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult DeleteCollaboratorFromVehicle(int userId, int vehicleId)
|
public IActionResult DeleteCollaboratorFromVehicle(int userId, int vehicleId)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -151,8 +151,8 @@ namespace CarCareTracker.Controllers
|
|||||||
return Json(false);
|
return Json(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[TypeFilter(typeof(CollaboratorFilter))]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { false, true })]
|
||||||
public IActionResult DeleteVehicle(int vehicleId)
|
public IActionResult DeleteVehicle(int vehicleId)
|
||||||
{
|
{
|
||||||
//Delete all service records, gas records, notes, etc.
|
//Delete all service records, gas records, notes, etc.
|
||||||
@ -175,42 +175,41 @@ namespace CarCareTracker.Controllers
|
|||||||
{
|
{
|
||||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.Generic(string.Empty, "vehicle.delete", User.Identity.Name, vehicleId.ToString()));
|
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.Generic(string.Empty, "vehicle.delete", User.Identity.Name, vehicleId.ToString()));
|
||||||
}
|
}
|
||||||
return Json(result);
|
return Json(OperationResponse.Succeed());
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { true, true })]
|
||||||
public IActionResult DeleteVehicles(List<int> vehicleIds)
|
public IActionResult DeleteVehicles(List<int> vehicleIds)
|
||||||
{
|
{
|
||||||
List<bool> results = new List<bool>();
|
List<bool> results = new List<bool>();
|
||||||
foreach(int vehicleId in vehicleIds)
|
foreach (int vehicleId in vehicleIds)
|
||||||
{
|
{
|
||||||
if (_userLogic.UserCanEditVehicle(GetUserID(), vehicleId))
|
//Delete all service records, gas records, notes, etc.
|
||||||
|
var result = _gasRecordDataAccess.DeleteAllGasRecordsByVehicleId(vehicleId) &&
|
||||||
|
_serviceRecordDataAccess.DeleteAllServiceRecordsByVehicleId(vehicleId) &&
|
||||||
|
_collisionRecordDataAccess.DeleteAllCollisionRecordsByVehicleId(vehicleId) &&
|
||||||
|
_taxRecordDataAccess.DeleteAllTaxRecordsByVehicleId(vehicleId) &&
|
||||||
|
_noteDataAccess.DeleteAllNotesByVehicleId(vehicleId) &&
|
||||||
|
_reminderRecordDataAccess.DeleteAllReminderRecordsByVehicleId(vehicleId) &&
|
||||||
|
_upgradeRecordDataAccess.DeleteAllUpgradeRecordsByVehicleId(vehicleId) &&
|
||||||
|
_planRecordDataAccess.DeleteAllPlanRecordsByVehicleId(vehicleId) &&
|
||||||
|
_planRecordTemplateDataAccess.DeleteAllPlanRecordTemplatesByVehicleId(vehicleId) &&
|
||||||
|
_inspectionRecordDataAccess.DeleteAllInspectionRecordsByVehicleId(vehicleId) &&
|
||||||
|
_inspectionRecordTemplateDataAccess.DeleteAllInspectionReportTemplatesByVehicleId(vehicleId) &&
|
||||||
|
_supplyRecordDataAccess.DeleteAllSupplyRecordsByVehicleId(vehicleId) &&
|
||||||
|
_odometerRecordDataAccess.DeleteAllOdometerRecordsByVehicleId(vehicleId) &&
|
||||||
|
_userLogic.DeleteAllAccessToVehicle(vehicleId) &&
|
||||||
|
_dataAccess.DeleteVehicle(vehicleId);
|
||||||
|
if (result)
|
||||||
{
|
{
|
||||||
//Delete all service records, gas records, notes, etc.
|
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.Generic(string.Empty, "vehicle.delete", User.Identity.Name, vehicleId.ToString()));
|
||||||
var result = _gasRecordDataAccess.DeleteAllGasRecordsByVehicleId(vehicleId) &&
|
|
||||||
_serviceRecordDataAccess.DeleteAllServiceRecordsByVehicleId(vehicleId) &&
|
|
||||||
_collisionRecordDataAccess.DeleteAllCollisionRecordsByVehicleId(vehicleId) &&
|
|
||||||
_taxRecordDataAccess.DeleteAllTaxRecordsByVehicleId(vehicleId) &&
|
|
||||||
_noteDataAccess.DeleteAllNotesByVehicleId(vehicleId) &&
|
|
||||||
_reminderRecordDataAccess.DeleteAllReminderRecordsByVehicleId(vehicleId) &&
|
|
||||||
_upgradeRecordDataAccess.DeleteAllUpgradeRecordsByVehicleId(vehicleId) &&
|
|
||||||
_planRecordDataAccess.DeleteAllPlanRecordsByVehicleId(vehicleId) &&
|
|
||||||
_planRecordTemplateDataAccess.DeleteAllPlanRecordTemplatesByVehicleId(vehicleId) &&
|
|
||||||
_inspectionRecordDataAccess.DeleteAllInspectionRecordsByVehicleId(vehicleId) &&
|
|
||||||
_inspectionRecordTemplateDataAccess.DeleteAllInspectionReportTemplatesByVehicleId(vehicleId) &&
|
|
||||||
_supplyRecordDataAccess.DeleteAllSupplyRecordsByVehicleId(vehicleId) &&
|
|
||||||
_odometerRecordDataAccess.DeleteAllOdometerRecordsByVehicleId(vehicleId) &&
|
|
||||||
_userLogic.DeleteAllAccessToVehicle(vehicleId) &&
|
|
||||||
_dataAccess.DeleteVehicle(vehicleId);
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.Generic(string.Empty, "vehicle.delete", User.Identity.Name, vehicleId.ToString()));
|
|
||||||
}
|
|
||||||
results.Add(result);
|
|
||||||
}
|
}
|
||||||
|
results.Add(result);
|
||||||
}
|
}
|
||||||
return Json(results.All(x => x));
|
return Json(OperationResponse.Conditional(results.Any() && results.All(x => x), "", StaticHelper.GenericErrorMessage));
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { true, true })]
|
||||||
public IActionResult GetVehiclesCollaborators(List<int> vehicleIds)
|
public IActionResult GetVehiclesCollaborators(List<int> vehicleIds)
|
||||||
{
|
{
|
||||||
var viewModel = new UserCollaboratorViewModel();
|
var viewModel = new UserCollaboratorViewModel();
|
||||||
@ -219,10 +218,10 @@ namespace CarCareTracker.Controllers
|
|||||||
//only one vehicle to manage
|
//only one vehicle to manage
|
||||||
if (_userLogic.UserCanEditVehicle(GetUserID(), vehicleIds.First()))
|
if (_userLogic.UserCanEditVehicle(GetUserID(), vehicleIds.First()))
|
||||||
{
|
{
|
||||||
viewModel.CommonCollaborators = _userLogic.GetCollaboratorsForVehicle(vehicleIds.First()).Select(x=>x.UserName).ToList();
|
viewModel.CommonCollaborators = _userLogic.GetCollaboratorsForVehicle(vehicleIds.First()).Select(x => x.UserName).ToList();
|
||||||
viewModel.VehicleIds.Add(vehicleIds.First());
|
viewModel.VehicleIds.Add(vehicleIds.First());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<UserCollaborator> allCollaborators = new List<UserCollaborator>();
|
List<UserCollaborator> allCollaborators = new List<UserCollaborator>();
|
||||||
@ -239,15 +238,16 @@ namespace CarCareTracker.Controllers
|
|||||||
viewModel.CommonCollaborators = groupedCollaborations.Where(x => x.Count() == vehicleIds.Count()).Select(y => y.Key).ToList();
|
viewModel.CommonCollaborators = groupedCollaborations.Where(x => x.Count() == vehicleIds.Count()).Select(y => y.Key).ToList();
|
||||||
viewModel.PartialCollaborators = groupedCollaborations.Where(x => x.Count() != vehicleIds.Count()).Select(y => y.Key).ToList();
|
viewModel.PartialCollaborators = groupedCollaborations.Where(x => x.Count() != vehicleIds.Count()).Select(y => y.Key).ToList();
|
||||||
}
|
}
|
||||||
return PartialView("_UserCollaborators",viewModel);
|
return PartialView("_UserCollaborators", viewModel);
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { true, true })]
|
||||||
public IActionResult AddCollaboratorsToVehicles(List<string> usernames, List<int> vehicleIds)
|
public IActionResult AddCollaboratorsToVehicles(List<string> usernames, List<int> vehicleIds)
|
||||||
{
|
{
|
||||||
List<OperationResponse> results = new List<OperationResponse>();
|
List<OperationResponse> results = new List<OperationResponse>();
|
||||||
foreach(string username in usernames)
|
foreach (string username in usernames)
|
||||||
{
|
{
|
||||||
foreach(int vehicleId in vehicleIds)
|
foreach (int vehicleId in vehicleIds)
|
||||||
{
|
{
|
||||||
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
|
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
|
||||||
results.Add(result);
|
results.Add(result);
|
||||||
@ -261,6 +261,7 @@ namespace CarCareTracker.Controllers
|
|||||||
return Json(OperationResponse.Succeed());
|
return Json(OperationResponse.Succeed());
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[TypeFilter(typeof(StrictCollaboratorFilter), Arguments = new object[] { true, true })]
|
||||||
public IActionResult RemoveCollaboratorsFromVehicles(List<string> usernames, List<int> vehicleIds)
|
public IActionResult RemoveCollaboratorsFromVehicles(List<string> usernames, List<int> vehicleIds)
|
||||||
{
|
{
|
||||||
List<OperationResponse> results = new List<OperationResponse>();
|
List<OperationResponse> results = new List<OperationResponse>();
|
||||||
@ -279,37 +280,6 @@ namespace CarCareTracker.Controllers
|
|||||||
}
|
}
|
||||||
return Json(OperationResponse.Succeed());
|
return Json(OperationResponse.Succeed());
|
||||||
}
|
}
|
||||||
[HttpPost]
|
|
||||||
public IActionResult DuplicateVehicleCollaborators(int sourceVehicleId, int destVehicleId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//retrieve collaborators for both source and destination vehicle id.
|
|
||||||
if (_userLogic.UserCanEditVehicle(GetUserID(), sourceVehicleId) && _userLogic.UserCanEditVehicle(GetUserID(), destVehicleId))
|
|
||||||
{
|
|
||||||
var sourceCollaborators = _userLogic.GetCollaboratorsForVehicle(sourceVehicleId).Select(x => x.UserVehicle.UserId).ToList();
|
|
||||||
var destCollaborators = _userLogic.GetCollaboratorsForVehicle(destVehicleId).Select(x => x.UserVehicle.UserId).ToList();
|
|
||||||
sourceCollaborators.RemoveAll(x => destCollaborators.Contains(x));
|
|
||||||
if (sourceCollaborators.Any())
|
|
||||||
{
|
|
||||||
foreach (int collaboratorId in sourceCollaborators)
|
|
||||||
{
|
|
||||||
_userLogic.AddUserAccessToVehicle(collaboratorId, destVehicleId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Json(OperationResponse.Failed("Both vehicles already have identical collaborators"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Json(OperationResponse.Succeed("Collaborators Copied"));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex.Message);
|
|
||||||
return Json(OperationResponse.Failed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region "Shared Methods"
|
#region "Shared Methods"
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@ -341,7 +311,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.ServiceRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.ServiceRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.ServiceRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.ServiceRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
@ -354,7 +324,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.RepairRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.RepairRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.RepairRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.RepairRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
@ -367,7 +337,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.UpgradeRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.UpgradeRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.UpgradeRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.UpgradeRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
@ -393,7 +363,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.SupplyRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.SupplyRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.SupplyRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.SupplyRecord, Description = $"{x.Date.ToShortDateString()} - {x.Description}" }));
|
||||||
@ -406,7 +376,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.PlanRecord, Description = $"{x.DateCreated.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.PlanRecord, Description = $"{x.DateCreated.ToShortDateString()} - {x.Description}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.PlanRecord, Description = $"{x.DateCreated.ToShortDateString()} - {x.Description}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.PlanRecord, Description = $"{x.DateCreated.ToShortDateString()} - {x.Description}" }));
|
||||||
@ -419,7 +389,7 @@ namespace CarCareTracker.Controllers
|
|||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.OdometerRecord, Description = $"{x.Date.ToShortDateString()} - {x.Mileage}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.OdometerRecord, Description = $"{x.Date.ToShortDateString()} - {x.Mileage}" }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.OdometerRecord, Description = $"{x.Date.ToShortDateString()} - {x.Mileage}" }));
|
searchResults.AddRange(results.Where(x => JsonSerializer.Serialize(x).ToLower().Contains(searchQuery)).Select(x => new SearchResult { Id = x.Id, RecordType = ImportMode.OdometerRecord, Description = $"{x.Date.ToShortDateString()} - {x.Mileage}" }));
|
||||||
|
|||||||
@ -65,7 +65,7 @@ namespace CarCareTracker.External.Implementations
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delee all access records when a user is deleted.
|
/// Delete all access records when a user is deleted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId"></param>
|
/// <param name="userId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
|||||||
76
External/Implementations/Litedb/UserHouseholdDataAcces.cs
vendored
Normal file
76
External/Implementations/Litedb/UserHouseholdDataAcces.cs
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using CarCareTracker.External.Interfaces;
|
||||||
|
using CarCareTracker.Helper;
|
||||||
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
|
namespace CarCareTracker.External.Implementations
|
||||||
|
{
|
||||||
|
public class UserHouseholdDataAccess : IUserHouseholdDataAccess
|
||||||
|
{
|
||||||
|
private ILiteDBHelper _liteDB { get; set; }
|
||||||
|
private static string tableName = "userhouseholdrecords";
|
||||||
|
public UserHouseholdDataAccess(ILiteDBHelper liteDB)
|
||||||
|
{
|
||||||
|
_liteDB = liteDB;
|
||||||
|
}
|
||||||
|
public List<UserHousehold> GetUserHouseholdByParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
return table.Find(x => x.Id.ParentUserId == parentUserId).ToList();
|
||||||
|
}
|
||||||
|
public List<UserHousehold> GetUserHouseholdByChildUserId(int childUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
return table.Find(x => x.Id.ChildUserId == childUserId).ToList();
|
||||||
|
}
|
||||||
|
public UserHousehold GetUserHouseholdByParentAndChildUserId(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
return table.Find(x => x.Id.ParentUserId == parentUserId && x.Id.ChildUserId == childUserId).FirstOrDefault();
|
||||||
|
}
|
||||||
|
public bool SaveUserHousehold(UserHousehold userHousehold)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
table.Upsert(userHousehold);
|
||||||
|
db.Checkpoint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public bool DeleteUserHousehold(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
table.DeleteMany(x => x.Id.ParentUserId == parentUserId && x.Id.ChildUserId == childUserId);
|
||||||
|
db.Checkpoint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Delete all household records when a parent user is deleted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentUserId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool DeleteAllHouseholdRecordsByParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
table.DeleteMany(x => x.Id.ParentUserId == parentUserId);
|
||||||
|
db.Checkpoint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Delete all household records when a child user is deleted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="childUserId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool DeleteAllHouseholdRecordsByChildUserId(int childUserId)
|
||||||
|
{
|
||||||
|
var db = _liteDB.GetLiteDB();
|
||||||
|
var table = db.GetCollection<UserHousehold>(tableName);
|
||||||
|
table.DeleteMany(x => x.Id.ChildUserId == childUserId);
|
||||||
|
db.Checkpoint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
207
External/Implementations/Postgres/UserHouseholdDataAccess.cs
vendored
Normal file
207
External/Implementations/Postgres/UserHouseholdDataAccess.cs
vendored
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
using CarCareTracker.External.Interfaces;
|
||||||
|
using CarCareTracker.Models;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
|
namespace CarCareTracker.External.Implementations
|
||||||
|
{
|
||||||
|
public class PGUserHouseholdDataAccess : IUserHouseholdDataAccess
|
||||||
|
{
|
||||||
|
private NpgsqlDataSource pgDataSource;
|
||||||
|
private readonly ILogger<PGUserHouseholdDataAccess> _logger;
|
||||||
|
private static string tableName = "userhouseholdrecords";
|
||||||
|
public PGUserHouseholdDataAccess(IConfiguration config, ILogger<PGUserHouseholdDataAccess> logger)
|
||||||
|
{
|
||||||
|
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
|
||||||
|
_logger = logger;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//create table if not exist.
|
||||||
|
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (parentUserId INT, childUserId INT, PRIMARY KEY(parentUserId, childUserId))";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(initCMD))
|
||||||
|
{
|
||||||
|
ctext.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<UserHousehold> GetUserHouseholdByParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"SELECT parentUserId, childUserId FROM app.{tableName} WHERE parentUserId = @parentUserId";
|
||||||
|
var results = new List<UserHousehold>();
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", parentUserId);
|
||||||
|
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UserHousehold result = new UserHousehold()
|
||||||
|
{
|
||||||
|
Id = new HouseholdAccess
|
||||||
|
{
|
||||||
|
ParentUserId = int.Parse(reader["parentUserId"].ToString()),
|
||||||
|
ChildUserId = int.Parse(reader["childUserId"].ToString())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return new List<UserHousehold>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<UserHousehold> GetUserHouseholdByChildUserId(int childUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"SELECT parentUserId, childUserId FROM app.{tableName} WHERE childUserId = @childUserId";
|
||||||
|
var results = new List<UserHousehold>();
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", childUserId);
|
||||||
|
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UserHousehold result = new UserHousehold()
|
||||||
|
{
|
||||||
|
Id = new HouseholdAccess
|
||||||
|
{
|
||||||
|
ParentUserId = int.Parse(reader["parentUserId"].ToString()),
|
||||||
|
ChildUserId = int.Parse(reader["childUserId"].ToString())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return new List<UserHousehold>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public UserHousehold GetUserHouseholdByParentAndChildUserId(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"SELECT parentUserId, childUserId FROM app.{tableName} WHERE parentUserId = @parentUserId AND childUserId = @childUserId";
|
||||||
|
UserHousehold result = null;
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", parentUserId);
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", childUserId);
|
||||||
|
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
result = new UserHousehold()
|
||||||
|
{
|
||||||
|
Id = new HouseholdAccess
|
||||||
|
{
|
||||||
|
ParentUserId = int.Parse(reader["parentUserId"].ToString()),
|
||||||
|
ChildUserId = int.Parse(reader["childUserId"].ToString())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return new UserHousehold();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool SaveUserHousehold(UserHousehold userHousehold)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"INSERT INTO app.{tableName} (parentUserId, childUserId) VALUES(@parentUserId, @childUserId)";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", userHousehold.Id.ParentUserId);
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", userHousehold.Id.ChildUserId);
|
||||||
|
return ctext.ExecuteNonQuery() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool DeleteUserHousehold(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"DELETE FROM app.{tableName} WHERE parentUserId = @parentUserId AND childUserId = @childUserId";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", parentUserId);
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", childUserId);
|
||||||
|
return ctext.ExecuteNonQuery() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Delete all household records when a parent user is deleted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentUserId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool DeleteAllHouseholdRecordsByParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"DELETE FROM app.{tableName} WHERE parentUserId = @parentUserId";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("parentUserId", parentUserId);
|
||||||
|
ctext.ExecuteNonQuery();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Delete all household records when a child user is deleted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="childUserId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool DeleteAllHouseholdRecordsByChildUserId(int childUserId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cmd = $"DELETE FROM app.{tableName} WHERE childUserId = @childUserId";
|
||||||
|
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||||
|
{
|
||||||
|
ctext.Parameters.AddWithValue("childUserId", childUserId);
|
||||||
|
ctext.ExecuteNonQuery();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
External/Interfaces/IUserHouseholdDataAccess.cs
vendored
Normal file
15
External/Interfaces/IUserHouseholdDataAccess.cs
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
|
namespace CarCareTracker.External.Interfaces
|
||||||
|
{
|
||||||
|
public interface IUserHouseholdDataAccess
|
||||||
|
{
|
||||||
|
List<UserHousehold> GetUserHouseholdByParentUserId(int parentUserId);
|
||||||
|
List<UserHousehold> GetUserHouseholdByChildUserId(int childUserId);
|
||||||
|
UserHousehold GetUserHouseholdByParentAndChildUserId(int parentUserId, int childUserId);
|
||||||
|
bool SaveUserHousehold(UserHousehold userHousehold);
|
||||||
|
bool DeleteUserHousehold(int parentUserId, int childUserId);
|
||||||
|
bool DeleteAllHouseholdRecordsByParentUserId(int parentUserId);
|
||||||
|
bool DeleteAllHouseholdRecordsByChildUserId(int childUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
Filter/StrictCollaboratorFilter.cs
Normal file
71
Filter/StrictCollaboratorFilter.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using CarCareTracker.Helper;
|
||||||
|
using CarCareTracker.Logic;
|
||||||
|
using CarCareTracker.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace CarCareTracker.Filter
|
||||||
|
{
|
||||||
|
public class StrictCollaboratorFilter: ActionFilterAttribute
|
||||||
|
{
|
||||||
|
private readonly IUserLogic _userLogic;
|
||||||
|
private readonly IConfigHelper _config;
|
||||||
|
private readonly bool _multiple;
|
||||||
|
private readonly bool _jsonResponse;
|
||||||
|
public StrictCollaboratorFilter(IUserLogic userLogic, IConfigHelper config, bool? multiple = false, bool? jsonResponse = false) {
|
||||||
|
_userLogic = userLogic;
|
||||||
|
_config = config;
|
||||||
|
_multiple = multiple ?? false;
|
||||||
|
_jsonResponse = jsonResponse ?? false;
|
||||||
|
}
|
||||||
|
public override void OnActionExecuting(ActionExecutingContext filterContext)
|
||||||
|
{
|
||||||
|
if (!filterContext.HttpContext.User.IsInRole(nameof(UserData.IsRootUser)))
|
||||||
|
{
|
||||||
|
List<int> vehicleIds = new List<int>();
|
||||||
|
if (!_multiple && filterContext.ActionArguments.ContainsKey("vehicleId"))
|
||||||
|
{
|
||||||
|
vehicleIds.Add(int.Parse(filterContext.ActionArguments["vehicleId"].ToString()));
|
||||||
|
}
|
||||||
|
else if (_multiple && filterContext.ActionArguments.ContainsKey("vehicleIds"))
|
||||||
|
{
|
||||||
|
vehicleIds.AddRange(filterContext.ActionArguments["vehicleIds"] as List<int>);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicleIds.Any())
|
||||||
|
{
|
||||||
|
foreach (int vehicleId in vehicleIds)
|
||||||
|
{
|
||||||
|
if (vehicleId != default)
|
||||||
|
{
|
||||||
|
var userId = int.Parse(filterContext.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
|
||||||
|
if (!_userLogic.UserCanDirectlyEditVehicle(userId, vehicleId))
|
||||||
|
{
|
||||||
|
filterContext.Result = _jsonResponse ? new JsonResult(OperationResponse.Failed("Access Denied")) : new RedirectResult("/Error/Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var shopSupplyEndpoints = new List<string> { "ImportToVehicleIdFromCsv", "GetSupplyRecordsByVehicleId", "ExportFromVehicleToCsv" };
|
||||||
|
if (shopSupplyEndpoints.Contains(filterContext.RouteData.Values["action"].ToString()) && !_config.GetServerEnableShopSupplies())
|
||||||
|
{
|
||||||
|
//user trying to access shop supplies but shop supplies is not enabled by root user.
|
||||||
|
filterContext.Result = _jsonResponse ? new JsonResult(OperationResponse.Failed("Access Denied")) : new RedirectResult("/Error/Unauthorized");
|
||||||
|
}
|
||||||
|
else if (!shopSupplyEndpoints.Contains(filterContext.RouteData.Values["action"].ToString()))
|
||||||
|
{
|
||||||
|
//user trying to access any other endpoints using 0 as vehicle id.
|
||||||
|
filterContext.Result = _jsonResponse ? new JsonResult(OperationResponse.Failed("Access Denied")) : new RedirectResult("/Error/Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filterContext.Result = _jsonResponse ? new JsonResult(OperationResponse.Failed("Access Denied")) : new RedirectResult("/Error/Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using CarCareTracker.External.Interfaces;
|
using CarCareTracker.External.Interfaces;
|
||||||
using CarCareTracker.Helper;
|
|
||||||
using CarCareTracker.Models;
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
namespace CarCareTracker.Logic
|
namespace CarCareTracker.Logic
|
||||||
@ -13,17 +12,26 @@ namespace CarCareTracker.Logic
|
|||||||
OperationResponse AddCollaboratorToVehicle(int vehicleId, string username);
|
OperationResponse AddCollaboratorToVehicle(int vehicleId, string username);
|
||||||
List<Vehicle> FilterUserVehicles(List<Vehicle> results, int userId);
|
List<Vehicle> FilterUserVehicles(List<Vehicle> results, int userId);
|
||||||
bool UserCanEditVehicle(int userId, int vehicleId);
|
bool UserCanEditVehicle(int userId, int vehicleId);
|
||||||
|
bool UserCanDirectlyEditVehicle(int userId, int vehicleId);
|
||||||
bool DeleteAllAccessToVehicle(int vehicleId);
|
bool DeleteAllAccessToVehicle(int vehicleId);
|
||||||
bool DeleteAllAccessToUser(int userId);
|
bool DeleteAllAccessToUser(int userId);
|
||||||
|
List<UserHouseholdViewModel> GetHouseholdForParentUserId(int parentUserId);
|
||||||
|
OperationResponse AddUserToHousehold(int parentUserId, string childUsername);
|
||||||
|
bool DeleteUserFromHousehold(int parentUserId, int childUserId);
|
||||||
|
bool DeleteAllHouseholdByParentUserId(int parentUserId);
|
||||||
|
bool DeleteAllHouseholdByChildUserId(int childUserId);
|
||||||
}
|
}
|
||||||
public class UserLogic: IUserLogic
|
public class UserLogic: IUserLogic
|
||||||
{
|
{
|
||||||
private readonly IUserAccessDataAccess _userAccess;
|
private readonly IUserAccessDataAccess _userAccess;
|
||||||
private readonly IUserRecordDataAccess _userData;
|
private readonly IUserRecordDataAccess _userData;
|
||||||
|
private readonly IUserHouseholdDataAccess _userHouseholdData;
|
||||||
public UserLogic(IUserAccessDataAccess userAccess,
|
public UserLogic(IUserAccessDataAccess userAccess,
|
||||||
IUserRecordDataAccess userData) {
|
IUserRecordDataAccess userData,
|
||||||
|
IUserHouseholdDataAccess userHouseholdData) {
|
||||||
_userAccess = userAccess;
|
_userAccess = userAccess;
|
||||||
_userData = userData;
|
_userData = userData;
|
||||||
|
_userHouseholdData = userHouseholdData;
|
||||||
}
|
}
|
||||||
public List<UserCollaborator> GetCollaboratorsForVehicle(int vehicleId)
|
public List<UserCollaborator> GetCollaboratorsForVehicle(int vehicleId)
|
||||||
{
|
{
|
||||||
@ -108,10 +116,24 @@ namespace CarCareTracker.Logic
|
|||||||
{
|
{
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
var accessibleVehicles = _userAccess.GetUserAccessByUserId(userId);
|
List<int> userIds = new List<int> { userId };
|
||||||
if (accessibleVehicles.Any())
|
List<int> vehicleIds = new List<int>();
|
||||||
|
var userHouseholds = _userHouseholdData.GetUserHouseholdByChildUserId(userId);
|
||||||
|
if (userHouseholds.Any())
|
||||||
|
{
|
||||||
|
//add parent's user ids
|
||||||
|
userIds.AddRange(userHouseholds.Select(x => x.Id.ParentUserId));
|
||||||
|
}
|
||||||
|
foreach(int userIdToCheck in userIds)
|
||||||
|
{
|
||||||
|
var accessibleVehicles = _userAccess.GetUserAccessByUserId(userIdToCheck);
|
||||||
|
if (accessibleVehicles.Any())
|
||||||
|
{
|
||||||
|
vehicleIds.AddRange(accessibleVehicles.Select(x => x.Id.VehicleId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vehicleIds.Any())
|
||||||
{
|
{
|
||||||
var vehicleIds = accessibleVehicles.Select(x => x.Id.VehicleId);
|
|
||||||
return results.Where(x => vehicleIds.Contains(x.Id)).ToList();
|
return results.Where(x => vehicleIds.Contains(x.Id)).ToList();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -120,13 +142,36 @@ namespace CarCareTracker.Logic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public bool UserCanEditVehicle(int userId, int vehicleId)
|
public bool UserCanEditVehicle(int userId, int vehicleId)
|
||||||
|
{
|
||||||
|
if (userId == -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
List<int> userIds = new List<int> { userId };
|
||||||
|
var userHouseholds = _userHouseholdData.GetUserHouseholdByChildUserId(userId);
|
||||||
|
if (userHouseholds.Any())
|
||||||
|
{
|
||||||
|
//add parent's user ids
|
||||||
|
userIds.AddRange(userHouseholds.Select(x => x.Id.ParentUserId));
|
||||||
|
}
|
||||||
|
foreach (int userIdToCheck in userIds)
|
||||||
|
{
|
||||||
|
var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userIdToCheck, vehicleId);
|
||||||
|
if (userAccess != null && userAccess.Id.UserId == userIdToCheck && userAccess.Id.VehicleId == vehicleId)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public bool UserCanDirectlyEditVehicle(int userId, int vehicleId)
|
||||||
{
|
{
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userId, vehicleId);
|
var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userId, vehicleId);
|
||||||
if (userAccess != null)
|
if (userAccess != null && userAccess.Id.UserId == userId && userAccess.Id.VehicleId == vehicleId)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -142,5 +187,74 @@ namespace CarCareTracker.Logic
|
|||||||
var result = _userAccess.DeleteAllAccessRecordsByUserId(userId);
|
var result = _userAccess.DeleteAllAccessRecordsByUserId(userId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
public List<UserHouseholdViewModel> GetHouseholdForParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
var result = _userHouseholdData.GetUserHouseholdByParentUserId(parentUserId);
|
||||||
|
var convertedResult = new List<UserHouseholdViewModel>();
|
||||||
|
//convert useraccess to usercollaborator
|
||||||
|
foreach (UserHousehold userHouseholdAccess in result)
|
||||||
|
{
|
||||||
|
var userCollaborator = new UserHouseholdViewModel
|
||||||
|
{
|
||||||
|
UserName = _userData.GetUserRecordById(userHouseholdAccess.Id.ChildUserId).UserName,
|
||||||
|
UserHousehold = userHouseholdAccess.Id
|
||||||
|
};
|
||||||
|
convertedResult.Add(userCollaborator);
|
||||||
|
}
|
||||||
|
return convertedResult;
|
||||||
|
}
|
||||||
|
public OperationResponse AddUserToHousehold(int parentUserId, string childUsername)
|
||||||
|
{
|
||||||
|
//attempting to add to root user
|
||||||
|
if (parentUserId == -1)
|
||||||
|
{
|
||||||
|
return OperationResponse.Failed("Root user household not allowed");
|
||||||
|
}
|
||||||
|
//try to find existing user.
|
||||||
|
var existingUser = _userData.GetUserRecordByUserName(childUsername);
|
||||||
|
if (existingUser.Id != default)
|
||||||
|
{
|
||||||
|
//user exists.
|
||||||
|
//check if user is trying to add themselves
|
||||||
|
if (parentUserId == existingUser.Id)
|
||||||
|
{
|
||||||
|
return OperationResponse.Failed("Cannot add user to their own household");
|
||||||
|
}
|
||||||
|
//check if user already belongs to the household
|
||||||
|
var householdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(parentUserId, existingUser.Id);
|
||||||
|
if (householdAccess != null && householdAccess.Id.ChildUserId == existingUser.Id && householdAccess.Id.ParentUserId == parentUserId)
|
||||||
|
{
|
||||||
|
return OperationResponse.Failed("User already belongs to this household");
|
||||||
|
}
|
||||||
|
//check if a circular dependency will exist
|
||||||
|
var circularHouseholdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(existingUser.Id, parentUserId);
|
||||||
|
if (circularHouseholdAccess != null && circularHouseholdAccess.Id.ChildUserId == parentUserId && circularHouseholdAccess.Id.ParentUserId == existingUser.Id)
|
||||||
|
{
|
||||||
|
return OperationResponse.Failed("Circular dependency is not allowed");
|
||||||
|
}
|
||||||
|
var result = _userHouseholdData.SaveUserHousehold(new UserHousehold { Id = new HouseholdAccess { ParentUserId = parentUserId, ChildUserId = existingUser.Id} });
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return OperationResponse.Succeed("User Added to Household");
|
||||||
|
}
|
||||||
|
return OperationResponse.Failed();
|
||||||
|
}
|
||||||
|
return OperationResponse.Failed($"Unable to find user {childUsername} in the system");
|
||||||
|
}
|
||||||
|
public bool DeleteUserFromHousehold(int parentUserId, int childUserId)
|
||||||
|
{
|
||||||
|
var result = _userHouseholdData.DeleteUserHousehold(parentUserId, childUserId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public bool DeleteAllHouseholdByParentUserId(int parentUserId)
|
||||||
|
{
|
||||||
|
var result = _userHouseholdData.DeleteAllHouseholdRecordsByParentUserId(parentUserId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public bool DeleteAllHouseholdByChildUserId(int childUserId)
|
||||||
|
{
|
||||||
|
var result = _userHouseholdData.DeleteAllHouseholdRecordsByChildUserId(childUserId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
public CostMakeUpForVehicle CostMakeUpForVehicle { get; set; } = new CostMakeUpForVehicle();
|
public CostMakeUpForVehicle CostMakeUpForVehicle { get; set; } = new CostMakeUpForVehicle();
|
||||||
public ReminderMakeUpForVehicle ReminderMakeUpForVehicle { get; set; } = new ReminderMakeUpForVehicle();
|
public ReminderMakeUpForVehicle ReminderMakeUpForVehicle { get; set; } = new ReminderMakeUpForVehicle();
|
||||||
public List<int> Years { get; set; } = new List<int>();
|
public List<int> Years { get; set; } = new List<int>();
|
||||||
public List<UserCollaborator> Collaborators { get; set; } = new List<UserCollaborator>();
|
public VehicleCollaboratorViewModel Collaborators { get; set; } = new VehicleCollaboratorViewModel();
|
||||||
public bool CustomWidgetsConfigured { get; set; } = false;
|
public bool CustomWidgetsConfigured { get; set; } = false;
|
||||||
public List<ImportMode> AvailableMetrics { get; set; } = new List<ImportMode>();
|
public List<ImportMode> AvailableMetrics { get; set; } = new List<ImportMode>();
|
||||||
public bool HasVehicleImageMap { get; set; } = false;
|
public bool HasVehicleImageMap { get; set; } = false;
|
||||||
|
|||||||
@ -6,4 +6,4 @@
|
|||||||
public List<string> CommonCollaborators { get; set; } = new List<string>();
|
public List<string> CommonCollaborators { get; set; } = new List<string>();
|
||||||
public List<string> PartialCollaborators { get; set; } = new List<string>();
|
public List<string> PartialCollaborators { get; set; } = new List<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
Models/User/UserHousehold.cs
Normal file
12
Models/User/UserHousehold.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class HouseholdAccess
|
||||||
|
{
|
||||||
|
public int ParentUserId { get; set; }
|
||||||
|
public int ChildUserId { get; set; }
|
||||||
|
}
|
||||||
|
public class UserHousehold
|
||||||
|
{
|
||||||
|
public HouseholdAccess Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Models/User/UserHouseholdAdminViewModel.cs
Normal file
8
Models/User/UserHouseholdAdminViewModel.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class UserHouseholdAdminViewModel
|
||||||
|
{
|
||||||
|
public List<UserHouseholdViewModel> Households { get; set; }
|
||||||
|
public int ParentUserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Models/User/UserHouseholdViewModel.cs
Normal file
8
Models/User/UserHouseholdViewModel.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class UserHouseholdViewModel
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public HouseholdAccess UserHousehold { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Models/User/VehicleCollaboratorViewModel.cs
Normal file
8
Models/User/VehicleCollaboratorViewModel.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace CarCareTracker.Models
|
||||||
|
{
|
||||||
|
public class VehicleCollaboratorViewModel
|
||||||
|
{
|
||||||
|
public List<UserCollaborator> Collaborators { get; set; }
|
||||||
|
public bool CanModifyCollaborators { get; set; } = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -60,6 +60,7 @@ if (!string.IsNullOrWhiteSpace(builder.Configuration["POSTGRES_CONNECTION"])){
|
|||||||
builder.Services.AddSingleton<IExtraFieldDataAccess, PGExtraFieldDataAccess>();
|
builder.Services.AddSingleton<IExtraFieldDataAccess, PGExtraFieldDataAccess>();
|
||||||
builder.Services.AddSingleton<IInspectionRecordDataAccess, PGInspectionRecordDataAccess>();
|
builder.Services.AddSingleton<IInspectionRecordDataAccess, PGInspectionRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, PGInspectionRecordTemplateDataAccess>();
|
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, PGInspectionRecordTemplateDataAccess>();
|
||||||
|
builder.Services.AddSingleton<IUserHouseholdDataAccess, PGUserHouseholdDataAccess>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -82,6 +83,7 @@ else
|
|||||||
builder.Services.AddSingleton<IExtraFieldDataAccess, ExtraFieldDataAccess>();
|
builder.Services.AddSingleton<IExtraFieldDataAccess, ExtraFieldDataAccess>();
|
||||||
builder.Services.AddSingleton<IInspectionRecordDataAccess, InspectionRecordDataAccess>();
|
builder.Services.AddSingleton<IInspectionRecordDataAccess, InspectionRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, InspectionRecordTemplateDataAccess>();
|
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, InspectionRecordTemplateDataAccess>();
|
||||||
|
builder.Services.AddSingleton<IUserHouseholdDataAccess, UserHouseholdDataAccess>();
|
||||||
}
|
}
|
||||||
|
|
||||||
//configure helpers
|
//configure helpers
|
||||||
|
|||||||
@ -95,6 +95,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" data-bs-focus="false" id="householdModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content" id="householdModalContent">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
function showTokenModal() {
|
function showTokenModal() {
|
||||||
@ -140,6 +146,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function deleteUser(userId) {
|
function deleteUser(userId) {
|
||||||
|
event.stopPropagation();
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: "Confirm Deletion?",
|
title: "Confirm Deletion?",
|
||||||
text: "Deleted Users cannot be restored.",
|
text: "Deleted Users cannot be restored.",
|
||||||
@ -186,4 +193,48 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function loadUserHousehold(userId){
|
||||||
|
$.get(`/Admin/GetUserHouseholdModal?userId=${userId}`, function(data){
|
||||||
|
$('#householdModalContent').html(data);
|
||||||
|
$('#householdModal').modal('show');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function adminRemoveUserFromHousehold(parentUserId, childUserId){
|
||||||
|
$.post('/Admin/RemoveUserFromHousehold', {parentUserId: parentUserId, childUserId: childUserId}, function(data){
|
||||||
|
if (data) {
|
||||||
|
successToast('User Removed');
|
||||||
|
loadUserHousehold(parentUserId);
|
||||||
|
} else {
|
||||||
|
errorToast(genericErrorMessage())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function adminAddUserToHousehold(parentUserId){
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Add User',
|
||||||
|
html: `
|
||||||
|
<input type="text" id="inputUserName" class="swal2-input" placeholder="Username" onkeydown="handleSwalEnter(event)">
|
||||||
|
`,
|
||||||
|
confirmButtonText: 'Add',
|
||||||
|
focusConfirm: false,
|
||||||
|
preConfirm: () => {
|
||||||
|
const userName = $("#inputUserName").val();
|
||||||
|
if (!userName) {
|
||||||
|
Swal.showValidationMessage(`Please enter a username`);
|
||||||
|
}
|
||||||
|
return { userName }
|
||||||
|
},
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.post('/Admin/AddUserToHousehold', { parentUserId: parentUserId, username: result.value.userName }, function (data) {
|
||||||
|
if (data.success) {
|
||||||
|
loadUserHousehold(parentUserId);
|
||||||
|
successToast('User Added');
|
||||||
|
} else {
|
||||||
|
errorToast(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
40
Views/Admin/_AdminUserHouseholdModal.cshtml
Normal file
40
Views/Admin/_AdminUserHouseholdModal.cshtml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
@using CarCareTracker.Helper
|
||||||
|
@inject IConfigHelper config
|
||||||
|
@inject ITranslationHelper translator
|
||||||
|
@model UserHouseholdAdminViewModel
|
||||||
|
@{
|
||||||
|
var userConfig = config.GetUserConfig(User);
|
||||||
|
var userLanguage = userConfig.UserLanguage;
|
||||||
|
}
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="lead">@translator.Translate(userLanguage, "Manage Household")</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center ms-auto">
|
||||||
|
<button onclick="adminAddUserToHousehold(@Model.ParentUserId)" class="btn btn-primary">
|
||||||
|
<i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage, "Add User")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn-close ms-2" onclick="hideHouseholdModal()" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead class="sticky-top">
|
||||||
|
<tr class="d-flex">
|
||||||
|
<th scope="col" class="col-10">@translator.Translate(userLanguage, "Username")</th>
|
||||||
|
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tokenTable">
|
||||||
|
@foreach(UserHouseholdViewModel viewModel in Model.Households)
|
||||||
|
{
|
||||||
|
<tr class="d-flex">
|
||||||
|
<td class="col-10">@viewModel.UserName</td>
|
||||||
|
<td class="col-2">
|
||||||
|
<button type="button" class="btn btn-danger" onclick="adminRemoveUserFromHousehold(@viewModel.UserHousehold.ParentUserId, @viewModel.UserHousehold.ChildUserId)"><i class="bi bi-trash"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@ -2,10 +2,10 @@
|
|||||||
@model List<UserData>
|
@model List<UserData>
|
||||||
@foreach (UserData userData in Model)
|
@foreach (UserData userData in Model)
|
||||||
{
|
{
|
||||||
<tr class="d-flex" style="cursor:pointer;">
|
<tr class="d-flex" style="cursor:pointer;" onclick="loadUserHousehold(@userData.Id)">
|
||||||
<td class="col-4 d-flex align-items-center">@StaticHelper.TruncateStrings(userData.UserName)</td>
|
<td class="col-4 d-flex align-items-center">@StaticHelper.TruncateStrings(userData.UserName)</td>
|
||||||
<td class="col-4 d-flex align-items-center">@StaticHelper.TruncateStrings(userData.EmailAddress)</td>
|
<td class="col-4 d-flex align-items-center">@StaticHelper.TruncateStrings(userData.EmailAddress)</td>
|
||||||
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="" onchange="updateUserAdmin(@userData.Id, this)" @(userData.IsAdmin ? "checked" : "") /></td>
|
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="" onclick="noPropagation()" onchange="updateUserAdmin(@userData.Id, this)" @(userData.IsAdmin ? "checked" : "") /></td>
|
||||||
<td class="col-2 d-flex align-items-center"><button type="button" class="btn btn-danger" onclick="deleteUser(@userData.Id, this)"><i class="bi bi-trash"></i></button></td>
|
<td class="col-2 d-flex align-items-center"><button type="button" class="btn btn-danger" onclick="deleteUser(@userData.Id, this)"><i class="bi bi-trash"></i></button></td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@ -68,7 +68,11 @@
|
|||||||
<li>
|
<li>
|
||||||
<button class="dropdown-item" onclick="showAccountInformationModal()"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</button>
|
<button class="dropdown-item" onclick="showAccountInformationModal()"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="dropdown-item" onclick="showHouseholdModal()"><i class="bi bi-house me-2"></i>@translator.Translate(userLanguage, "Household")</button>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
<li>
|
<li>
|
||||||
<button class="dropdown-item" onclick="performLogOut()"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage, "Logout")</button>
|
<button class="dropdown-item" onclick="performLogOut()"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage, "Logout")</button>
|
||||||
</li>
|
</li>
|
||||||
@ -121,6 +125,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<button class="nav-link" onclick="showAccountInformationModal()"><span class="display-3 ms-2"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</span></button>
|
<button class="nav-link" onclick="showAccountInformationModal()"><span class="display-3 ms-2"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</span></button>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="nav-link" onclick="showHouseholdModal()"><span class="display-3 ms-2"><i class="bi bi-house me-2"></i>@translator.Translate(userLanguage, "Household")</span></button>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link" onclick="performLogOut()"><span class="display-3 ms-2"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage,"Logout")</span></button>
|
<button class="nav-link" onclick="performLogOut()"><span class="display-3 ms-2"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage,"Logout")</span></button>
|
||||||
@ -159,6 +166,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" data-bs-focus="false" id="householdModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content" id="householdModalContent">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="modal fade" data-bs-focus="false" id="attachmentPreviewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="modal fade" data-bs-focus="false" id="attachmentPreviewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-fullscreen" role="document">
|
<div class="modal-dialog modal-fullscreen" role="document">
|
||||||
<div class="modal-content frosted" id="attachmentPreviewModalContent">
|
<div class="modal-content frosted" id="attachmentPreviewModalContent">
|
||||||
|
|||||||
40
Views/Home/_UserHouseholdModal.cshtml
Normal file
40
Views/Home/_UserHouseholdModal.cshtml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
@using CarCareTracker.Helper
|
||||||
|
@inject IConfigHelper config
|
||||||
|
@inject ITranslationHelper translator
|
||||||
|
@model List<UserHouseholdViewModel>
|
||||||
|
@{
|
||||||
|
var userConfig = config.GetUserConfig(User);
|
||||||
|
var userLanguage = userConfig.UserLanguage;
|
||||||
|
}
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="lead">@translator.Translate(userLanguage, "Manage Household")</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center ms-auto">
|
||||||
|
<button onclick="addUserToHousehold()" class="btn btn-primary">
|
||||||
|
<i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage, "Add User")
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn-close ms-2" onclick="hideHouseholdModal()" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead class="sticky-top">
|
||||||
|
<tr class="d-flex">
|
||||||
|
<th scope="col" class="col-10">@translator.Translate(userLanguage, "Username")</th>
|
||||||
|
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tokenTable">
|
||||||
|
@foreach(UserHouseholdViewModel viewModel in Model)
|
||||||
|
{
|
||||||
|
<tr class="d-flex">
|
||||||
|
<td class="col-10">@viewModel.UserName</td>
|
||||||
|
<td class="col-2">
|
||||||
|
<button type="button" class="btn btn-danger" onclick="removeUserFromHousehold(@viewModel.UserHousehold.ChildUserId, this)"><i class="bi bi-trash"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@ -5,34 +5,43 @@
|
|||||||
var userConfig = config.GetUserConfig(User);
|
var userConfig = config.GetUserConfig(User);
|
||||||
var userLanguage = userConfig.UserLanguage;
|
var userLanguage = userConfig.UserLanguage;
|
||||||
}
|
}
|
||||||
@model List<UserCollaborator>
|
@model VehicleCollaboratorViewModel
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-8">
|
<div class="@(Model.CanModifyCollaborators ? "col-8" : "col-12")">
|
||||||
<span class="lead">@translator.Translate(userLanguage, "Collaborators")</span>
|
<span class="lead">@translator.Translate(userLanguage, "Collaborators")</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
@if (Model.CanModifyCollaborators)
|
||||||
<button onclick="addCollaborator()" class="btn btn-link btn-sm"><i class="bi bi-person-add"></i></button>
|
{
|
||||||
</div>
|
<div class="col-4">
|
||||||
|
<button onclick="addCollaborator()" class="btn btn-link btn-sm"><i class="bi bi-person-add"></i></button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="d-flex">
|
<tr class="d-flex">
|
||||||
<th scope="col" class="col-8">@translator.Translate(userLanguage, "Username")</th>
|
<th scope="col" class="@(Model.CanModifyCollaborators ? "col-8" : "col-12")">@translator.Translate(userLanguage, "Username")</th>
|
||||||
<th scope="col" class="col-4">@translator.Translate(userLanguage, "Delete")</th>
|
@if (Model.CanModifyCollaborators)
|
||||||
|
{
|
||||||
|
<th scope="col" class="col-4">@translator.Translate(userLanguage, "Delete")</th>
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (UserCollaborator user in Model)
|
@foreach (UserCollaborator user in Model.Collaborators)
|
||||||
{
|
{
|
||||||
<tr class="d-flex">
|
<tr class="d-flex">
|
||||||
<td class="col-8">@user.UserName</td>
|
<td class="@(Model.CanModifyCollaborators ? "col-8" : "col-12")">@user.UserName</td>
|
||||||
<td class="col-4">
|
@if (Model.CanModifyCollaborators)
|
||||||
@if(User.Identity.Name != user.UserName)
|
{
|
||||||
{
|
<td class="col-4">
|
||||||
<button onclick="deleteCollaborator(@user.UserVehicle.UserId, @user.UserVehicle.VehicleId)" class="btn btn-outline-danger btn-sm"><i class="bi bi-trash"></i></button>
|
@if (User.Identity.Name != user.UserName && Model.CanModifyCollaborators)
|
||||||
}
|
{
|
||||||
</td>
|
<button onclick="deleteCollaborator(@user.UserVehicle.UserId, @user.UserVehicle.VehicleId)" class="btn btn-outline-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -105,4 +105,4 @@
|
|||||||
@:vehiclesToEdit.push(@recordId);
|
@:vehiclesToEdit.push(@recordId);
|
||||||
}
|
}
|
||||||
adjustCollaboratorsModalSize(@showTwoColumns.ToString().ToLower());
|
adjustCollaboratorsModalSize(@showTwoColumns.ToString().ToLower());
|
||||||
</script>
|
</script>
|
||||||
File diff suppressed because one or more lines are too long
@ -365,9 +365,12 @@ function deleteVehicles(vehicleIds) {
|
|||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
$.post('/Vehicle/DeleteVehicles', { vehicleIds: vehicleIds }, function (data) {
|
$.post('/Vehicle/DeleteVehicles', { vehicleIds: vehicleIds }, function (data) {
|
||||||
if (data) {
|
if (data.success) {
|
||||||
loadGarage();
|
loadGarage();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
errorToast(data.message);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -377,7 +380,9 @@ function manageCollaborators(vehicleIds) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.post('/Vehicle/GetVehiclesCollaborators', { vehicleIds: vehicleIds }, function (data) {
|
$.post('/Vehicle/GetVehiclesCollaborators', { vehicleIds: vehicleIds }, function (data) {
|
||||||
if (data) {
|
if (isOperationResponse(data)) {
|
||||||
|
return;
|
||||||
|
} else if (data) {
|
||||||
$("#userCollaboratorsModalContent").html(data);
|
$("#userCollaboratorsModalContent").html(data);
|
||||||
$("#userCollaboratorsModal").modal('show');
|
$("#userCollaboratorsModal").modal('show');
|
||||||
}
|
}
|
||||||
@ -576,6 +581,54 @@ function sortVehicles(desc) {
|
|||||||
sortedRow.push($('.garage-item-add'))
|
sortedRow.push($('.garage-item-add'))
|
||||||
$('.vehiclesContainer').html(sortedRow);
|
$('.vehiclesContainer').html(sortedRow);
|
||||||
}
|
}
|
||||||
|
function showHouseholdModal() {
|
||||||
|
$.get('/Home/GetHouseholdModal', function (data) {
|
||||||
|
$("#householdModalContent").html(data);
|
||||||
|
$("#householdModal").modal('show');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function hideHouseholdModal() {
|
||||||
|
$("#householdModal").modal('hide');
|
||||||
|
}
|
||||||
|
function removeUserFromHousehold(userId) {
|
||||||
|
$.post('/Home/RemoveUserFromHousehold', { userId: userId }, function (data) {
|
||||||
|
if (data) {
|
||||||
|
successToast('User Removed');
|
||||||
|
showHouseholdModal();
|
||||||
|
} else {
|
||||||
|
errorToast(genericErrorMessage())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function addUserToHousehold() {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Add User',
|
||||||
|
html: `
|
||||||
|
<input type="text" id="inputUserName" class="swal2-input" placeholder="Username" onkeydown="handleSwalEnter(event)">
|
||||||
|
`,
|
||||||
|
confirmButtonText: 'Add',
|
||||||
|
focusConfirm: false,
|
||||||
|
preConfirm: () => {
|
||||||
|
const userName = $("#inputUserName").val();
|
||||||
|
if (!userName) {
|
||||||
|
Swal.showValidationMessage(`Please enter a username`);
|
||||||
|
}
|
||||||
|
return { userName }
|
||||||
|
},
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.post('/Home/AddUserToHousehold', { username: result.value.userName }, function (data) {
|
||||||
|
if (data.success) {
|
||||||
|
showHouseholdModal();
|
||||||
|
successToast('User Added');
|
||||||
|
} else {
|
||||||
|
errorToast(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function showAccountInformationModal() {
|
function showAccountInformationModal() {
|
||||||
$.get('/Home/GetUserAccountInformationModal', function (data) {
|
$.get('/Home/GetUserAccountInformationModal', function (data) {
|
||||||
$('#accountInformationModalContent').html(data);
|
$('#accountInformationModalContent').html(data);
|
||||||
|
|||||||
@ -1812,4 +1812,13 @@ function handleAttachmentCopyLink(e) {
|
|||||||
let textToCopy = $(e).attr('data-link');
|
let textToCopy = $(e).attr('data-link');
|
||||||
navigator.clipboard.writeText(textToCopy);
|
navigator.clipboard.writeText(textToCopy);
|
||||||
successToast("Copied Link to Clipboard");
|
successToast("Copied Link to Clipboard");
|
||||||
|
}
|
||||||
|
function isOperationResponse(result) {
|
||||||
|
//checks if response from controller is operationresponse
|
||||||
|
if (result.success != undefined && result.message != undefined) {
|
||||||
|
if (!result.success) {
|
||||||
|
errorToast(result.message);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -219,8 +219,10 @@ function deleteVehicle(vehicleId) {
|
|||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
$.post('/Vehicle/DeleteVehicle', { vehicleId: vehicleId }, function (data) {
|
$.post('/Vehicle/DeleteVehicle', { vehicleId: vehicleId }, function (data) {
|
||||||
if (data) {
|
if (data.success) {
|
||||||
window.location.href = '/Home';
|
window.location.href = '/Home';
|
||||||
|
} else {
|
||||||
|
errorToast(data.message);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user