From 3c3432367e2f26c3f38244ae2c998ffb4d8b2e95 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Thu, 12 Mar 2026 11:32:07 -0700 Subject: [PATCH] RE1-T46 Bug fixes --- .../DepartmentGroupsService.cs | 39 ++++++++++++------- .../CallsRepository.cs | 4 +- .../User/Controllers/DispatchController.cs | 5 ++- .../User/Controllers/GroupsController.cs | 34 ++++++++++------ .../dispatch/resgrid.dispatch.archive.js | 2 +- 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/Core/Resgrid.Services/DepartmentGroupsService.cs b/Core/Resgrid.Services/DepartmentGroupsService.cs index d2093644..ced86fc6 100644 --- a/Core/Resgrid.Services/DepartmentGroupsService.cs +++ b/Core/Resgrid.Services/DepartmentGroupsService.cs @@ -421,45 +421,54 @@ public async Task GetMapCenterCoordinatesForGroupAsync(int departme Coordinates coordinates = null; var departmentGroup = await GetGroupByIdAsync(departmentGroupId); + + if (departmentGroup == null) + return null; + var department = await _departmentsService.GetDepartmentByIdAsync(departmentGroup.DepartmentId); if (departmentGroup.Address != null) { - coordinates = new Coordinates(); string coordinateString = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3} {4}", departmentGroup.Address.Address1, departmentGroup.Address.City, departmentGroup.Address.State, departmentGroup.Address.PostalCode, departmentGroup.Address.Country)); - var coords = coordinateString.Split(char.Parse(",")); - coordinates.Latitude = double.Parse(coords[0]); - coordinates.Longitude = double.Parse(coords[1]); + coordinates = ParseCoordinates(coordinateString); } - if (coordinates == null && department.Address != null) + if (coordinates == null && department?.Address != null) { - coordinates = new Coordinates(); string coordinateString = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3} {4}", department.Address.Address1, department.Address.City, department.Address.State, department.Address.PostalCode, department.Address.Country)); - var coords = coordinateString.Split(char.Parse(",")); - coordinates.Latitude = double.Parse(coords[0]); - coordinates.Longitude = double.Parse(coords[1]); + coordinates = ParseCoordinates(coordinateString); } var gpsCoordinates = await _departmentSettingsService.GetBigBoardCenterGpsCoordinatesDepartmentAsync(departmentGroup.DepartmentId); if (coordinates == null && !string.IsNullOrWhiteSpace(gpsCoordinates)) { - coordinates = new Coordinates(); - - var coords = gpsCoordinates.Split(char.Parse(",")); - coordinates.Latitude = double.Parse(coords[0]); - coordinates.Longitude = double.Parse(coords[1]); + coordinates = ParseCoordinates(gpsCoordinates); } - return coordinates; } + private static Coordinates ParseCoordinates(string coordinateString) + { + if (string.IsNullOrWhiteSpace(coordinateString)) + return null; + + var coords = coordinateString.Split(','); + if (coords.Length < 2) + return null; + + if (!double.TryParse(coords[0], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double latitude) || + !double.TryParse(coords[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double longitude)) + return null; + + return new Coordinates { Latitude = latitude, Longitude = longitude }; + } + public async Task MoveUserIntoGroupAsync(string userId, int groupId, bool isAdmin, int departmentId, CancellationToken cancellationToken = default(CancellationToken)) { var departmentGroup = await GetGroupByIdAsync(groupId); diff --git a/Repositories/Resgrid.Repositories.DataRepository/CallsRepository.cs b/Repositories/Resgrid.Repositories.DataRepository/CallsRepository.cs index 9eaefac2..24a3b3a0 100644 --- a/Repositories/Resgrid.Repositories.DataRepository/CallsRepository.cs +++ b/Repositories/Resgrid.Repositories.DataRepository/CallsRepository.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data.Common; using System.Threading.Tasks; @@ -164,7 +164,7 @@ public async Task> GetAllClosedCallsByDepartmentYearAsync(int { var dynamicParameters = new DynamicParametersExtension(); dynamicParameters.Add("DepartmentId", departmentId); - dynamicParameters.Add("Year", int.Parse(year)); + dynamicParameters.Add("Year", int.Parse(year.Trim())); var query = _queryFactory.GetQuery(); diff --git a/Web/Resgrid.Web/Areas/User/Controllers/DispatchController.cs b/Web/Resgrid.Web/Areas/User/Controllers/DispatchController.cs index 68648d8d..9d775ee7 100644 --- a/Web/Resgrid.Web/Areas/User/Controllers/DispatchController.cs +++ b/Web/Resgrid.Web/Areas/User/Controllers/DispatchController.cs @@ -1972,10 +1972,11 @@ public async Task GetArchivedCallsList(string year) List callsJson = new List(); List calls; - if (String.IsNullOrWhiteSpace(year)) + var normalizedYear = string.IsNullOrWhiteSpace(year) || year.Trim().Equals("null", StringComparison.OrdinalIgnoreCase) ? null : year.Trim(); + if (normalizedYear == null) calls = await _callsService.GetClosedCallsByDepartmentAsync(DepartmentId); else - calls = await _callsService.GetClosedCallsByDepartmentYearAsync(DepartmentId, year); + calls = await _callsService.GetClosedCallsByDepartmentYearAsync(DepartmentId, normalizedYear); var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); diff --git a/Web/Resgrid.Web/Areas/User/Controllers/GroupsController.cs b/Web/Resgrid.Web/Areas/User/Controllers/GroupsController.cs index d69577df..fd4c8a32 100644 --- a/Web/Resgrid.Web/Areas/User/Controllers/GroupsController.cs +++ b/Web/Resgrid.Web/Areas/User/Controllers/GroupsController.cs @@ -466,7 +466,7 @@ public async Task EditGroup(EditGroupView model, IFormCollection ModelState.AddModelError("", string.Format("{0} cannot be both a Group Admin and a Group Member. Please add them to only one list.", profile.FullName.AsFirstNameLastName)); } - // Check newly added users are not in a *different* group — exclude the group being edited + // Check newly added users are not in a *different* group � exclude the group being edited foreach (var groupUser in allUsers.Distinct()) { if (await _departmentGroupsService.IsUserInAGroupAsync(groupUser, model.EditGroup.DepartmentGroupId, DepartmentId)) @@ -517,7 +517,7 @@ public async Task EditGroup(EditGroupView model, IFormCollection { model.EditGroup.DepartmentId = DepartmentId; - // Build desired member list from submitted values — UpdateAsync handles insert/delete/update against the DB + // Build desired member list from submitted values � UpdateAsync handles insert/delete/update against the DB var desiredMembers = allUsers.Distinct().Select(user => new DepartmentGroupMember { DepartmentId = DepartmentId, @@ -617,26 +617,36 @@ public async Task SaveGeofence([FromBody]SaveGeofenceModel model, { var group = await _departmentGroupsService.GetGroupByIdAsync(model.DepartmentGroupId); - if (group != null) - { - group.GeofenceColor = model.Color; - group.Geofence = model.GeoFence; + if (group == null) + return new StatusCodeResult((int)HttpStatusCode.BadRequest); - await _departmentGroupsService.SaveAsync(group, cancellationToken); - model.Success = true; - model.Message = "Station response area geofence has been saved."; + if (group.DepartmentId != DepartmentId) + return Unauthorized(); - return Json(model); - } + if (!await _authorizationService.CanUserEditDepartmentGroupAsync(UserId, model.DepartmentGroupId)) + return Unauthorized(); - return new StatusCodeResult((int)HttpStatusCode.BadRequest); + group.GeofenceColor = model.Color; + group.Geofence = model.GeoFence; + + await _departmentGroupsService.SaveAsync(group, cancellationToken); + model.Success = true; + model.Message = "Station response area geofence has been saved."; + + return Json(model); } + [HttpGet] [Authorize(Policy = ResgridResources.GenericGroup_View)] public async Task GetMembersForGroup(int groupId, bool includeAdmins = true, bool includeNormal = true) { + var ownerGroup = await _departmentGroupsService.GetGroupByIdAsync(groupId); + + if (ownerGroup == null || ownerGroup.DepartmentId != DepartmentId) + return Unauthorized(); + var groupsJson = new List(); var groups = await _departmentGroupsService.GetAllMembersForGroupAsync(groupId); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.archive.js b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.archive.js index 0fd30645..41a51493 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.archive.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.archive.js @@ -33,7 +33,7 @@ var resgrid; { data: 'CallId', title: 'Actions', orderable: false, render: function (data, type, row) { - var html = 'View '; + var html = 'View '; if (row.CanDeleteCall) { html += 'Delete'; }