diff --git a/Core/Resgrid.Services/AuthorizationService.cs b/Core/Resgrid.Services/AuthorizationService.cs index a1af8817..bc24aeee 100644 --- a/Core/Resgrid.Services/AuthorizationService.cs +++ b/Core/Resgrid.Services/AuthorizationService.cs @@ -335,6 +335,9 @@ public async Task CanUserViewUserAsync(string viewerUserId, string targetU var department = await _departmentsService.GetDepartmentByUserIdAsync(viewerUserId); var department1 = await _departmentsService.GetDepartmentByUserIdAsync(targetUserId); + if (department == null || department1 == null) + return false; + if (department.DepartmentId != department1.DepartmentId) return false; diff --git a/Core/Resgrid.Services/CallEmailTemplates/ResgridEmailTemplate.cs b/Core/Resgrid.Services/CallEmailTemplates/ResgridEmailTemplate.cs index 1270757f..7ed34568 100644 --- a/Core/Resgrid.Services/CallEmailTemplates/ResgridEmailTemplate.cs +++ b/Core/Resgrid.Services/CallEmailTemplates/ResgridEmailTemplate.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -57,8 +58,25 @@ public async Task GenerateCall(CallEmail email, string managingUser, List< c.MapPage = data[4]; c.NatureOfCall = data[5]; - c.Address = data[3]; + if (!string.IsNullOrEmpty(data[3])) + { + c.Address = data[3]; + + try + { + var address = await geolocationProvider.GetLatLonFromAddress(c.Address); + + + if (address != null) + c.GeoLocationData = address; + } + catch (Exception ex) + { + Resgrid.Framework.Logging.LogException( ex, + $"Failed to geocode address '{c.Address}' for email {email.MessageId}"); + } + } StringBuilder title = new StringBuilder(); title.Append("Email Call "); diff --git a/Core/Resgrid.Services/ShiftsService.cs b/Core/Resgrid.Services/ShiftsService.cs index 35563854..bdc8bec9 100644 --- a/Core/Resgrid.Services/ShiftsService.cs +++ b/Core/Resgrid.Services/ShiftsService.cs @@ -488,7 +488,10 @@ public async Task>> GetShiftDayNeedsObjAsyn } } - shiftGroups.Add(group.DepartmentGroupId, roleRequirements); + if (shiftGroups.ContainsKey(group.DepartmentGroupId)) + shiftGroups[group.DepartmentGroupId] = roleRequirements; + else + shiftGroups.Add(group.DepartmentGroupId, roleRequirements); } } diff --git a/Web/Resgrid.Web.Services/Controllers/v3/AuthController.cs b/Web/Resgrid.Web.Services/Controllers/v3/AuthController.cs deleted file mode 100644 index 51b3bcb6..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/AuthController.cs +++ /dev/null @@ -1,185 +0,0 @@ -using Resgrid.Model; -using Resgrid.Model.Services; -using System; -using Resgrid.Web.Services.Controllers.Version3.Models.Auth; -using RestSharp; -using System.Net.Mime; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.ServicesCore.Middleware; -using Resgrid.Web.Services.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Service to generate an authentication token that is required to communicate with all other v3 services - /// -#if (!DEBUG && !DOCKER) - //[RequireHttps] -#endif - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiController] - [AllowAnonymous] - [ApiExplorerSettings(GroupName = "v3")] - //[EnableCors("_resgridWebsiteAllowSpecificOrigins")] - public class AuthController : ControllerBase - { - private readonly SignInManager _signInManager; - private readonly IUsersService _usersService; - private readonly IUserProfileService _userProfileService; - private readonly IDepartmentsService _departmentsService; - private readonly ISystemAuditsService _systemAuditsService; - - public AuthController( - IUsersService usersService, - IUserProfileService userProfileService, - IDepartmentsService departmentsService, - SignInManager signInManager, - ISystemAuditsService systemAuditsService - ) - { - _usersService = usersService; - _userProfileService = userProfileService; - _departmentsService = departmentsService; - _signInManager = signInManager; - _systemAuditsService = systemAuditsService; - } - - /// - /// Generates a token that is then used for subsquent requests to the API. - /// - /// ValidateInput object with values populated - /// ValidateResult object, with IsValid set if the settings are correct - [HttpPost("Validate")] - [AllowAnonymous] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> Validate([FromBody]ValidateInput authInput) - { - if (this.ModelState.IsValid) - { - if (authInput == null) - return BadRequest(); - - var signInResult = await _signInManager.PasswordSignInAsync(authInput.Usr, authInput.Pass, true, lockoutOnFailure: true); - SystemAudit audit = new SystemAudit(); - audit.System = (int)SystemAuditSystems.Api; - audit.Type = (int)SystemAuditTypes.Login; - audit.Username = authInput.Usr; - audit.Successful = signInResult.Succeeded; - audit.IpAddress = IpAddressHelper.GetRequestIP(Request, true); - audit.ServerName = Environment.MachineName; - audit.Data = $"V3 Validate, {Request.Headers["User-Agent"]} {Request.Headers["Accept-Language"]}"; - await _systemAuditsService.SaveSystemAuditAsync(audit); - - if (signInResult.Succeeded) - { - if (await _usersService.DoesUserHaveAnyActiveDepartments(authInput.Usr)) - { - var user = await _usersService.GetUserByNameAsync(authInput.Usr); - Department department = await _departmentsService.GetDepartmentForUserAsync(authInput.Usr); - - var result = new ValidateResult - { - Eml = user.Email, - Uid = user.Id, - Dnm = department.Name, - Did = department.DepartmentId - }; - - if (department.CreatedOn.HasValue) - result.Dcd = (department.CreatedOn.Value - new DateTime(1970, 1, 1).ToLocalTime()) - .TotalSeconds.ToString(); - else - result.Dcd = new DateTime(1970, 1, 1).ToLocalTime().ToString(); - - result.Tkn = V3AuthToken.Create(authInput.Usr, department.DepartmentId); - result.Txd = DateTime.UtcNow.AddMonths(Config.SystemBehaviorConfig.APITokenMonthsTTL) - .ToShortDateString(); - - var profile = await _userProfileService.GetProfileByUserIdAsync(user.Id); - result.Nme = profile.FullName.AsFirstNameLastName; - - return result; - } - } - } - - return BadRequest(); - } - - [AllowAnonymous] - [HttpPost("ValidateForDepartment")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> ValidateForDepartment([FromBody]SetActiveComapnyInput authInput) - { - if (this.ModelState.IsValid) - { - if (authInput == null) - return BadRequest(); - - var signInResult = await _signInManager.PasswordSignInAsync(authInput.Usr, authInput.Pass, true, lockoutOnFailure: true); - SystemAudit audit = new SystemAudit(); - audit.System = (int)SystemAuditSystems.Api; - audit.Type = (int)SystemAuditTypes.Login; - audit.Username = authInput.Usr; - audit.Successful = signInResult.Succeeded; - audit.IpAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString(); - audit.ServerName = Environment.MachineName; - audit.Data = $"V3 ValidateForDepartment, {Request.Headers["User-Agent"]} {Request.Headers["Accept-Language"]}"; - await _systemAuditsService.SaveSystemAuditAsync(audit); - - if (signInResult.Succeeded) - { - if (await _usersService.DoesUserHaveAnyActiveDepartments(authInput.Usr)) - { - - var user = await _usersService.GetUserByNameAsync(authInput.Usr); - - if (await _departmentsService.IsMemberOfDepartmentAsync(authInput.Did, user.Id)) - { - Department department = await _departmentsService.GetDepartmentForUserAsync(authInput.Usr); - - var result = new ActiveCompanyResult - { - Eml = user.Email, - Uid = user.Id, - Dnm = department.Name, - Did = department.DepartmentId - }; - - if (department.CreatedOn.HasValue) - result.Dcd = (department.CreatedOn.Value - new DateTime(1970, 1, 1).ToLocalTime()) - .TotalSeconds.ToString(); - else - result.Dcd = new DateTime(1970, 1, 1).ToLocalTime().ToString(); - - result.Tkn = V3AuthToken.Create(authInput.Usr, authInput.Did); - result.Txd = DateTime.UtcNow.AddMonths(Config.SystemBehaviorConfig.APITokenMonthsTTL) - .ToShortDateString(); - - var profile = await _userProfileService.GetProfileByUserIdAsync(user.Id); - result.Nme = profile.FullName.AsFirstNameLastName; - - return Ok(result); - } - } - } - - return Unauthorized(); - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/AvatarsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/AvatarsController.cs deleted file mode 100644 index a080a31f..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/AvatarsController.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; -using System.IO; -using System.Net.Mime; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Services; - - -using Resgrid.Web.Services.Models; -using Resgrid.Web.ServicesCore.Helpers; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Processing; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Used to interact with the user avatars (profile pictures) in the Resgrid system. The authentication header isn't required to access this method. - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - //[EnableCors("_resgridWebsiteAllowSpecificOrigins")] - public class AvatarsController : ControllerBase - { - private readonly IImageService _imageService; - private static byte[] _defaultProfileImage; - - public AvatarsController(IImageService imageService) - { - _imageService = imageService; - } - - /// - /// Get a users avatar from the Resgrid system based on their ID - /// - /// ID of the user - /// - [HttpGet("Get")] - [Produces(MediaTypeNames.Image.Jpeg)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task Get(string id, int? type) - { - byte[] data = null; - if (type == null) - data = await _imageService.GetImageAsync(ImageTypes.Avatar, id); - else - data = await _imageService.GetImageAsync((ImageTypes)type.Value, id); - - if (data == null || data.Length <= 0) - return File(GetDefaultProfileImage(), "image/png"); - - return File(data, "image/jpeg"); - } - - ///// - ///// Get a users avatar from the Resgrid system based on their ID - ///// - ///// ID of the user - ///// - //[HttpGet("Get")] - //[Produces(MediaTypeNames.Image.Jpeg)] - //[ProducesResponseType(StatusCodes.Status200OK)] - //[ProducesResponseType(StatusCodes.Status404NotFound)] - //public async Task Get(string id) - //{ - // var result = Ok(); - - // // User profile images (will have a null type) are by Guid - // Guid newId; - // if (!Guid.TryParse(id, out newId)) - // return NotFound(); - - // byte[] data = await _imageService.GetImageAsync(ImageTypes.Avatar, id); - - // if (data == null || data.Length <= 0) - // return NotFound(); - - // return File(data, "image/jpeg"); - //} - - [HttpPost("Upload")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task Upload([FromQuery] string id, int? type) - { - var img = HttpContext.Request.Form.Files.Count > 0 ? - HttpContext.Request.Form.Files[0] : null; - - // check for a valid mediatype - if (!img.ContentType.StartsWith("image/")) - return BadRequest(); - - // load the image from the upload and generate a new filename - //var image = Image.FromStream(img.OpenReadStream()); - var extension = Path.GetExtension(img.FileName); - byte[] imgArray; - int width = 0; - int height = 0; - - using (Image image = Image.Load(img.OpenReadStream())) - { - //image.Mutate(x => x - // .Resize(image.Width / 2, image.Height / 2) - // .Grayscale()); - - width = image.Width; - height = image.Height; - - MemoryStream ms = new MemoryStream(); - await image.SaveAsPngAsync(ms); - imgArray = ms.ToArray(); - - //image.Save()"output/fb.png"); // Automatic encoder selected based on extension. - } - - //ImageConverter converter = new ImageConverter(); - //byte[] imgArray = (byte[])converter.ConvertTo(image, typeof(byte[])); - - if (type == null) - await _imageService.SaveImageAsync(ImageTypes.Avatar, id, imgArray); - else - await _imageService.SaveImageAsync((ImageTypes)type.Value, id, imgArray); - - var baseUrl = Config.SystemBehaviorConfig.ResgridApiBaseUrl; - - string url; - - if (type == null) - url = baseUrl + "/api/v3/Avatars/Get?id=" + id; - else - url = baseUrl + "/api/v3/Avatars/Get?id=" + id + "?type=" + type.Value; - - var obj = new - { - status = CroppicStatuses.Success, - url = url, - width = width, - height = height - }; - - return CreatedAtAction(nameof(Upload), new { id = obj.url }, obj); - } - - [HttpPut("Crop")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task Crop([FromBody]CropRequest model) - { - // extract original image ID and generate a new filename for the cropped result - var originalUri = new Uri(model.imgUrl); - var originalId = originalUri.Query.Replace("?id=", "");//.Last(); - //var extension = Path.GetExtension(originalId); - //var croppedId = GenerateIdFor(model.CroppedWidth, model.CroppedHeight, extension); - - try - { - var ms = new MemoryStream(await _imageService.GetImageAsync(ImageTypes.Avatar, originalId)); - //var img = Image.FromStream(ms); - - byte[] imgArray; - - Image image = Image.Load(ms); - - // load the original picture and resample it to the scaled values - var bitmap = ImageUtils.Resize(image, (int)model.imgW, (int)model.imgH); - - var croppedBitmap = ImageUtils.Crop(bitmap, model.imgX1, model.imgY1, model.cropW, model.cropH); - - MemoryStream ms2 = new MemoryStream(); - await croppedBitmap.SaveAsPngAsync(ms2); - imgArray = ms.ToArray(); - - //ImageConverter converter = new ImageConverter(); - //byte[] imgArray = (byte[])converter.ConvertTo(croppedBitmap, typeof(byte[])); - - await _imageService.SaveImageAsync(ImageTypes.Avatar, originalId, imgArray); - } - catch (Exception e) - { - return BadRequest(); - } - - var obj = new - { - status = CroppicStatuses.Success, - url = originalId - }; - - return CreatedAtAction(nameof(Crop), new { id = obj.url }, obj); - } - - //public HttpResponseMessage Options() - //{ - // var response = new HttpResponseMessage(); - // response.StatusCode = HttpStatusCode.OK; - // response.Headers.Add("Access-Control-Allow-Origin", "*"); - // response.Headers.Add("Access-Control-Request-Headers", "*"); - // response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); - - // return response; - //} - - private byte[] GetDefaultProfileImage() - { - if (_defaultProfileImage == null) - _defaultProfileImage = EmbeddedResources.GetApiRequestFile(typeof(AvatarsController), "Resgrid.Web.Services.Properties.Resources.defaultProfile.png"); - - return _defaultProfileImage; - } - } - - internal static class CroppicStatuses - { - public const string Success = "success"; - public const string Error = "error"; - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/BigBoardController.cs b/Web/Resgrid.Web.Services/Controllers/v3/BigBoardController.cs deleted file mode 100644 index c62fb824..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/BigBoardController.cs +++ /dev/null @@ -1,687 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Resgrid.Model; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.BigBoard; -using Resgrid.Web.Services.Controllers.Version3.Models.BigBoard.BigBoardX; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Helpers; -using Resgrid.Web.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Calls to get information specific for displaying data on a dashboard or big board application. Data returned - /// is formatted and optimized for these scenarios to be outputted directly into a web application. - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class BigBoardController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IDepartmentSettingsService _departmentSettingsService; - private readonly IGeoLocationProvider _geoLocationProvider; - - public BigBoardController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IDepartmentSettingsService departmentSettingsService, - IGeoLocationProvider geoLocationProvider - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _departmentSettingsService = departmentSettingsService; - _geoLocationProvider = geoLocationProvider; - } - - [HttpGet("GetPersonnelStatuses")] - public async Task>> GetPersonnelStatuses() - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var stations = await _departmentGroupsService.GetAllStationGroupsForDepartmentAsync(DepartmentId); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - var allUsers = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var hideUnavailable = await _departmentSettingsService.GetBigBoardHideUnavailableDepartmentAsync(DepartmentId); - //var lastUserActionlogs = await _actionLogsService.GetAllActionLogsForDepartmentAsync(DepartmentId); - var lastUserActionlogs = await _actionLogsService.GetLastActionLogsForDepartmentAsync(DepartmentId); - var departmentGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - var lastUserStates = await _userStateService.GetLatestStatesForDepartmentAsync(DepartmentId); - var personnelNames = await _departmentsService.GetAllPersonnelNamesForDepartmentAsync(DepartmentId); - - var names = new Dictionary(); - - var userStates = new List(); - - foreach (var u in allUsers) - { - var state = lastUserStates.FirstOrDefault(x => x.UserId == u.UserId); - - if (state != null) - userStates.Add(state); - else - userStates.Add(await _userStateService.GetLastUserStateByUserIdAsync(u.UserId)); - - var name = personnelNames.FirstOrDefault(x => x.UserId == u.UserId); - if (name != null) - names.Add(u.UserId, name.Name); - } - - var personnelViewModels = new List(); - - - - var sortedUngroupedUsers = from u in allUsers - // let mu = Membership.GetUser(u.UserId) - let userGroup = departmentGroups.FirstOrDefault(x => x.Members.Any(y => y.UserId == u.UserId)) - let groupName = userGroup == null ? "" : userGroup.Name - //let roles = _personnelRolesService.GetRolesForUserAsync(u.UserId, DepartmentId).Result - //let name = (ProfileBase.Create(mu.UserName, true)).GetPropertyValue("Name").ToString() - let name = names.ContainsKey(u.UserId) ? names[u.UserId] : "Unknown User" - let weight = lastUserActionlogs.Where(x => x.UserId == u.UserId).FirstOrDefault().GetWeightForAction() - orderby groupName, weight, name ascending - select new - { - Name = name, - User = u, - Group = userGroup, - Roles = new List() - }; - - foreach (var u in sortedUngroupedUsers) - { - //var mu = Membership.GetUser(u.User.UserId); - var al = lastUserActionlogs.Where(x => x.UserId == u.User.UserId).FirstOrDefault(); - var us = userStates.Where(x => x.UserId == u.User.UserId).FirstOrDefault(); - - // if setting is such, ignore unavailable users. - if (hideUnavailable.HasValue && hideUnavailable.Value && us.State != (int)UserStateTypes.Unavailable) - continue; - - u.Roles.AddRange(await _personnelRolesService.GetRolesForUserAsync(u.User.UserId, DepartmentId)); - - string callNumber = ""; - if (al != null && al.ActionTypeId == (int)ActionTypes.RespondingToScene || - (al != null && al.DestinationType.HasValue && al.DestinationType.Value == 2)) - { - if (al.DestinationId.HasValue) - { - var call = calls.FirstOrDefault(x => x.CallId == al.DestinationId.Value); - - if (call != null) - callNumber = call.Number; - } - } - var respondingToDepartment = - stations.Where(s => al != null && s.DepartmentGroupId == al.DestinationId).FirstOrDefault(); - var personnelViewModel = await PersonnelViewModel.Create(u.Name, al, us, department, respondingToDepartment, u.Group, - u.Roles, callNumber); - - personnelViewModels.Add(personnelViewModel); - } - - return personnelViewModels; - } - - [HttpGet("GetCalls")] - public async Task>> GetCalls() - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - var usersNames = await _departmentsService.GetAllPersonnelNamesForDepartmentAsync(DepartmentId); - - var callViewModels = new List(); - - foreach (var call in calls) - { - - string name = ""; - var personName = usersNames.FirstOrDefault(x => x.UserId == call.ReportingUserId); - - if (personName != null) - { - name = personName.Name; - } - else - { - name = "Unknown"; - } - - - var callViewModel = new CallViewModel - { - Id = call.Number, - Name = call.Name, - Timestamp = call.LoggedOn.TimeConverter(department), - LoggingUser = name, - Priority = call.ToCallPriorityDisplayText(), - PriorityCss = call.ToCallPriorityCss(), - State = call.ToCallStateDisplayText(), - StateCss = call.ToCallStateCss(), - Address = call.Address - }; - - callViewModels.Add(callViewModel); - } - - return callViewModels; - } - - [HttpGet("GetUnitStatuses")] - public async Task>> GetUnitStatuses() - { - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitStates = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - var activeCalls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - var unitViewModels = new List(); - - var sortedUnits = from u in units - let station = u.StationGroup - let stationName = station == null ? "" : station.Name - orderby stationName, u.Name ascending - select new - { - Unit = u, - Station = station, - StationName = stationName - }; - - foreach (var unit in sortedUnits) - { - var stateFound = unitStates.FirstOrDefault(x => x.UnitId == unit.Unit.UnitId); - var state = "Unknown"; - var stateCss = ""; - var stateStyle = ""; - int? destinationId = 0; - decimal? latitude = 0; - decimal? longitude = 0; - var destinationName = ""; - DateTime? timestamp = null; - - if (stateFound != null) - { - var customState = await CustomStatesHelper.GetCustomUnitState(stateFound); - if (customState != null) - { - state = customState.ButtonText; - stateCss = customState.ButtonColor; - stateStyle = customState.ButtonColor; - - if (customState.DetailType == (int)CustomStateDetailTypes.Calls) - { - var call = activeCalls.FirstOrDefault(x => x.CallId == stateFound.DestinationId); - if (call != null) - { - destinationName = call.Number; - } - } - else if (customState.DetailType == (int)CustomStateDetailTypes.Stations) - { - var station = groups.FirstOrDefault(x => x.DepartmentGroupId == stateFound.DestinationId); - if (station != null) - { - destinationName = station.Name; - } - } - else if (customState.DetailType == (int)CustomStateDetailTypes.CallsAndStations) - { - // First try and get the station, as a station can get a call (based on Id) but the inverse is hard - var station = groups.FirstOrDefault(x => x.DepartmentGroupId == stateFound.DestinationId); - if (station != null) - { - destinationName = station.Name; - } - else - { - var call = activeCalls.FirstOrDefault(x => x.CallId == stateFound.DestinationId); - if (call != null) - { - destinationName = call.Number; - } - } - } - } - else - { - state = stateFound.ToStateDisplayText(); - stateCss = stateFound.ToStateCss(); - } - - destinationId = stateFound.DestinationId; - latitude = stateFound.Latitude; - longitude = stateFound.Longitude; - timestamp = stateFound.Timestamp; - } - - int groupId = 0; - if (unit.Station != null) - groupId = unit.Station.DepartmentGroupId; - - var latestUnitLocation = await _unitsService.GetLatestUnitLocationAsync(unit.Unit.UnitId, timestamp); - if (latestUnitLocation != null) - { - latitude = latestUnitLocation.Latitude; - longitude = latestUnitLocation.Longitude; - } - - var unitViewModel = new UnitViewModel - { - UnitId = unit.Unit.UnitId, - Name = unit.Unit.Name, - Type = unit.Unit.Type, - State = state, - StateCss = stateCss, - StateStyle = stateStyle, - Timestamp = timestamp, - DestinationId = destinationId, - Latitude = latitude, - Longitude = longitude, - GroupId = groupId, - GroupName = unit.StationName, - DestinationName = destinationName - }; - - unitViewModels.Add(unitViewModel); - } - - return unitViewModels; - } - - [HttpGet("GetMap")] - public async Task> GetMap() - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var stations = await _departmentGroupsService.GetAllStationGroupsForDepartmentAsync(DepartmentId); - - var address = await _departmentSettingsService.GetBigBoardCenterAddressDepartmentAsync(DepartmentId); - var gpsCoordinates = await _departmentSettingsService.GetBigBoardCenterGpsCoordinatesDepartmentAsync(DepartmentId); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitStates = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - - var personnelViewModels = (await GetPersonnelStatuses()).Value; - - string weatherUnits = ""; - double? centerLat = null; - double? centerLon = null; - - if (address != null && !String.IsNullOrWhiteSpace(address.Country)) - { - if (address.Country == "Canada") - weatherUnits = "ca"; - else if (address.Country == "United Kingdom") - weatherUnits = "uk"; - else if (address.Country == "Australia") - weatherUnits = "uk"; - else - weatherUnits = "us"; - } - else if (department.Address != null && !String.IsNullOrWhiteSpace(department.Address.Country)) - { - if (department.Address.Country == "Canada") - weatherUnits = "ca"; - else if (department.Address.Country == "United Kingdom") - weatherUnits = "uk"; - else if (department.Address.Country == "Australia") - weatherUnits = "uk"; - else - weatherUnits = "us"; - } - - if (!String.IsNullOrWhiteSpace(gpsCoordinates)) - { - string[] coordinates = gpsCoordinates.Split(char.Parse(",")); - - if (coordinates.Count() == 2) - { - double newLat; - double newLon; - if (double.TryParse(coordinates[0], out newLat) && double.TryParse(coordinates[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue && !centerLon.HasValue && address != null) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3}", address.Address1, - address.City, address.State, address.PostalCode)); - - if (!String.IsNullOrEmpty(coordinates)) - { - double newLat; - double newLon; - var coordinatesArr = coordinates.Split(char.Parse(",")); - if (double.TryParse(coordinatesArr[0], out newLat) && double.TryParse(coordinatesArr[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue && !centerLon.HasValue && department.Address != null) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3}", department.Address.Address1, - department.Address.City, - department.Address.State, - department.Address.PostalCode)); - - if (!String.IsNullOrEmpty(coordinates)) - { - double newLat; - double newLon; - var coordinatesArr = coordinates.Split(char.Parse(",")); - if (double.TryParse(coordinatesArr[0], out newLat) && double.TryParse(coordinatesArr[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue || !centerLon.HasValue) - { - centerLat = 39.14086268299356; - centerLon = -119.7583809782715; - } - - var zoomLevel = await _departmentSettingsService.GetBigBoardMapZoomLevelForDepartmentAsync(department.DepartmentId); - - var mapModel = new BigBoardMapModel - { - CenterLat = centerLat.Value, - CenterLon = centerLon.Value, - ZoomLevel = zoomLevel.HasValue ? zoomLevel.Value : 9, - }; - - foreach (var station in stations) - { - MapMakerInfo info = new MapMakerInfo(); - info.Id = $"s{station.DepartmentGroupId}"; - info.ImagePath = "Station"; - info.Title = station.Name; - info.InfoWindowContent = station.Name; - - if (station.Address != null) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3}", station.Address.Address1, - station.Address.City, - station.Address.State, - station.Address.PostalCode)); - - if (!String.IsNullOrEmpty(coordinates)) - { - info.Latitude = double.Parse(coordinates.Split(char.Parse(","))[0]); - info.Longitude = double.Parse(coordinates.Split(char.Parse(","))[1]); - - mapModel.MapMakerInfos.Add(info); - } - } - else if (!String.IsNullOrWhiteSpace(station.Latitude) && !String.IsNullOrWhiteSpace(station.Longitude)) - { - info.Latitude = double.Parse(station.Latitude); - info.Longitude = double.Parse(station.Longitude); - - mapModel.MapMakerInfos.Add(info); - } - } - - foreach (var call in calls) - { - MapMakerInfo info = new MapMakerInfo(); - info.ImagePath = "Call"; - info.Id = $"c{call.CallId}"; - info.Title = call.Name; - info.InfoWindowContent = call.NatureOfCall; - - if (!String.IsNullOrEmpty(call.GeoLocationData) && call.GeoLocationData.Length > 1) - { - try - { - info.Latitude = double.Parse(call.GeoLocationData.Split(char.Parse(","))[0]); - info.Longitude = double.Parse(call.GeoLocationData.Split(char.Parse(","))[1]); - - mapModel.MapMakerInfos.Add(info); - } - catch { } - } - else if (!String.IsNullOrEmpty(call.Address)) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(call.Address); - if (!String.IsNullOrEmpty(coordinates)) - { - info.Latitude = double.Parse(coordinates.Split(char.Parse(","))[0]); - info.Longitude = double.Parse(coordinates.Split(char.Parse(","))[1]); - } - - mapModel.MapMakerInfos.Add(info); - } - } - - foreach (var unit in unitStates) - { - if (unit.Latitude.HasValue && unit.Latitude.Value != 0 && unit.Longitude.HasValue && - unit.Longitude.Value != 0) - { - MapMakerInfo info = new MapMakerInfo(); - info.ImagePath = "Engine_Responding"; - info.Id = $"u{unit.UnitId}"; - info.Title = unit.Unit.Name; - info.InfoWindowContent = ""; - info.Latitude = double.Parse(unit.Latitude.Value.ToString()); - info.Longitude = double.Parse(unit.Longitude.Value.ToString()); - - mapModel.MapMakerInfos.Add(info); - } - } - - foreach (var person in personnelViewModels) - { - if (person.Latitude.HasValue && person.Latitude.Value != 0 && person.Longitude.HasValue && - person.Longitude.Value != 0) - { - MapMakerInfo info = new MapMakerInfo(); - - if (person.StatusValue <= 25) - { - if (person.StatusValue == 5) - info.ImagePath = "Person_RespondingStation"; - else if (person.StatusValue == 6) - info.ImagePath = "Person_RespondingCall"; - else if (person.StatusValue == 3) - info.ImagePath = "Person_OnScene"; - else - info.ImagePath = "Person_RespondingCall"; - } - else if (person.DestinationType > 0) - { - if (person.DestinationType == 1) - info.ImagePath = "Person_RespondingStation"; - else if (person.DestinationType == 2) - info.ImagePath = "Person_RespondingCall"; - else - info.ImagePath = "Person_RespondingCall"; - } - else - { - info.ImagePath = "Person_RespondingCall"; - } - - //info.Id = $"p{person.}"; - info.Title = person.Name; - info.InfoWindowContent = ""; - info.Latitude = double.Parse(person.Latitude.Value.ToString()); - info.Longitude = double.Parse(person.Longitude.Value.ToString()); - - mapModel.MapMakerInfos.Add(info); - } - } - - return Ok(mapModel); - } - - [HttpGet("GetWeather")] - public async Task> GetWeather() - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var address = await _departmentSettingsService.GetBigBoardCenterAddressDepartmentAsync(DepartmentId); - var gpsCoordinates = await _departmentSettingsService.GetBigBoardCenterGpsCoordinatesDepartmentAsync(DepartmentId); - - - string weatherUnits = ""; - double? centerLat = null; - double? centerLon = null; - - if (address != null && !String.IsNullOrWhiteSpace(address.Country)) - { - if (address.Country == "Canada") - weatherUnits = "ca"; - else if (address.Country == "United Kingdom") - weatherUnits = "uk"; - else if (address.Country == "Australia") - weatherUnits = "uk"; - else - weatherUnits = "us"; - } - else if (department.Address != null && !String.IsNullOrWhiteSpace(department.Address.Country)) - { - if (department.Address.Country == "Canada") - weatherUnits = "ca"; - else if (department.Address.Country == "United Kingdom") - weatherUnits = "uk"; - else if (department.Address.Country == "Australia") - weatherUnits = "uk"; - else - weatherUnits = "us"; - } - - if (!String.IsNullOrWhiteSpace(gpsCoordinates)) - { - string[] coordinates = gpsCoordinates.Split(char.Parse(",")); - - if (coordinates.Count() == 2) - { - double newLat; - double newLon; - if (double.TryParse(coordinates[0], out newLat) && double.TryParse(coordinates[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue && !centerLon.HasValue && address != null) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3}", address.Address1, - address.City, address.State, address.PostalCode)); - - if (!String.IsNullOrEmpty(coordinates)) - { - double newLat; - double newLon; - var coordinatesArr = coordinates.Split(char.Parse(",")); - if (double.TryParse(coordinatesArr[0], out newLat) && double.TryParse(coordinatesArr[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue && !centerLon.HasValue && department.Address != null) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3}", department.Address.Address1, - department.Address.City, - department.Address.State, - department.Address.PostalCode)); - - if (!String.IsNullOrEmpty(coordinates)) - { - double newLat; - double newLon; - var coordinatesArr = coordinates.Split(char.Parse(",")); - if (double.TryParse(coordinatesArr[0], out newLat) && double.TryParse(coordinatesArr[1], out newLon)) - { - centerLat = newLat; - centerLon = newLon; - } - } - } - - if (!centerLat.HasValue || !centerLon.HasValue) - { - centerLat = 39.14086268299356; - centerLon = -119.7583809782715; - } - - var mapModel = new WeatherModel - { - Latitude = centerLat.Value, - Longitude = centerLon.Value, - WeatherUnit = weatherUnits, - }; - - - - return Ok(mapModel); - } - - [HttpGet("GetGroups")] - public async Task> GetGroups() - { - var result = new GroupsModel(); - result.Groups = new List(); - var groups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - foreach (var group in groups) - { - var newGroup = new GroupInfoResult(); - newGroup.Gid = group.DepartmentGroupId; - newGroup.Nme = group.Name; - newGroup.Typ = group.Type.GetValueOrDefault(); - - result.Groups.Add(newGroup); - } - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CalendarController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CalendarController.cs deleted file mode 100644 index c395a1f3..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CalendarController.cs +++ /dev/null @@ -1,355 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Web; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Calendar; -using CalendarItem = Resgrid.Web.Services.Controllers.Version3.Models.Calendar.CalendarItem; -using CalendarItemAttendee = Resgrid.Web.Services.Controllers.Version3.Models.Calendar.CalendarItemAttendee; -using CalendarItemType = Resgrid.Web.Services.Controllers.Version3.Models.Calendar.CalendarItemType; -using Resgrid.Framework; -using Resgrid.Model.Helpers; -using System.Globalization; -using System.Linq; -using System.Net.Mime; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Swashbuckle.AspNetCore.Annotations; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Used to interact with the calendar system - /// Implements the - /// - /// - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CalendarController : V3AuthenticatedApiControllerbase - { - private readonly ICalendarService _calendarService; - private readonly IDepartmentsService _departmentsService; - - public CalendarController(ICalendarService calendarService, IDepartmentsService departmentsService) - { - _calendarService = calendarService; - _departmentsService = departmentsService; - } - - /// - /// Gets the department calendar items. - /// - /// ActionResult<List<CalendarItem>>. - [HttpGet("GetDepartmentCalendarItems")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [Produces(typeof(List))] - [SwaggerResponse(200, Type = typeof(List))] - public async Task>> GetDepartmentCalendarItems() - { - List jsonItems = new List(); - List items = null; - - items = await _calendarService.GetAllCalendarItemsForDepartmentAsync(DepartmentId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var item in items) - { - CalendarItem calendarItem = new CalendarItem(); - calendarItem.CalendarItemId = item.CalendarItemId; - calendarItem.Title = item.Title; - calendarItem.Start = item.Start.TimeConverter(department); - calendarItem.End = item.End.TimeConverter(department); - calendarItem.StartTimezone = item.StartTimezone; - calendarItem.EndTimezone = item.EndTimezone; - calendarItem.Description = item.Description; - calendarItem.RecurrenceId = item.RecurrenceId; - calendarItem.RecurrenceRule = item.RecurrenceRule; - calendarItem.RecurrenceException = item.RecurrenceException; - calendarItem.IsAllDay = item.IsAllDay; - calendarItem.ItemType = item.ItemType; - calendarItem.Location = item.Location; - calendarItem.SignupType = item.SignupType; - calendarItem.Reminder = item.Reminder; - calendarItem.LockEditing = item.LockEditing; - calendarItem.Entities = item.Entities; - calendarItem.RequiredAttendes = item.RequiredAttendes; - calendarItem.OptionalAttendes = item.OptionalAttendes; - - if (!String.IsNullOrWhiteSpace(item.CreatorUserId)) - calendarItem.CreatorUserId = item.CreatorUserId.ToString(); - - if (department.IsUserAnAdmin(UserId)) - calendarItem.IsAdminOrCreator = true; - else if (!String.IsNullOrWhiteSpace(item.CreatorUserId) && item.CreatorUserId == UserId) - calendarItem.IsAdminOrCreator = true; - else - calendarItem.IsAdminOrCreator = false; - - - jsonItems.Add(calendarItem); - } - - return Ok(jsonItems); - } - - - /// - /// Gets the department calendar items in range. - /// - /// The start. - /// The end. - /// ActionResult<List<CalendarItem>>. - [HttpGet("GetDepartmentCalendarItemsInRange")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - [Produces(typeof(List))] - [SwaggerResponse(200, Type = typeof(List))] - public async Task>> GetDepartmentCalendarItemsInRange(DateTime start, DateTime end) - { - List jsonItems = new List(); - List items = null; - - items = await _calendarService.GetAllCalendarItemsForDepartmentInRangeAsync(DepartmentId, start.SetToMidnight(), end.SetToEndOfDay()); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var item in items) - { - CalendarItem calendarItem = new CalendarItem(); - calendarItem.CalendarItemId = item.CalendarItemId; - calendarItem.Title = item.Title; - calendarItem.Start = item.Start.TimeConverter(department); - calendarItem.End = item.End.TimeConverter(department); - calendarItem.StartTimezone = item.StartTimezone; - calendarItem.EndTimezone = item.EndTimezone; - calendarItem.Description = item.Description; - calendarItem.RecurrenceId = item.RecurrenceId; - calendarItem.RecurrenceRule = item.RecurrenceRule; - calendarItem.RecurrenceException = item.RecurrenceException; - calendarItem.IsAllDay = item.IsAllDay; - calendarItem.ItemType = item.ItemType; - calendarItem.Location = item.Location; - calendarItem.SignupType = item.SignupType; - calendarItem.Reminder = item.Reminder; - calendarItem.LockEditing = item.LockEditing; - calendarItem.Entities = item.Entities; - calendarItem.RequiredAttendes = item.RequiredAttendes; - calendarItem.OptionalAttendes = item.OptionalAttendes; - - if (!String.IsNullOrWhiteSpace(item.CreatorUserId)) - calendarItem.CreatorUserId = item.CreatorUserId.ToString(); - - if (department.IsUserAnAdmin(UserId)) - calendarItem.IsAdminOrCreator = true; - else if (!String.IsNullOrWhiteSpace(item.CreatorUserId) && item.CreatorUserId == UserId) - calendarItem.IsAdminOrCreator = true; - else - calendarItem.IsAdminOrCreator = false; - - - jsonItems.Add(calendarItem); - } - - return jsonItems; - } - - - /// - /// Gets the calendar items specified in the date range. - /// - /// Must be in MM/dd/yyyy HH:mm:ss zzz format - /// Must be in MM/dd/yyyy HH:mm:ss zzz format - /// - [HttpGet("GetAllDepartmentCalendarItemsInRange")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [Produces(typeof(List))] - [SwaggerResponse(200, Type = typeof(List))] - public async Task>> GetAllDepartmentCalendarItemsInRange(string startDate, string endDate) - { - List jsonItems = new List(); - List items = null; - - var startDateString = HttpUtility.UrlDecode(startDate); - var endDateString = HttpUtility.UrlDecode(endDate); - - var start = DateTime.ParseExact(startDateString, "MM/dd/yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture); - var end = DateTime.ParseExact(endDateString, "MM/dd/yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture); - - items = await _calendarService.GetAllCalendarItemsForDepartmentInRangeAsync(DepartmentId, start.SetToMidnight(), end.SetToEndOfDay()); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var item in items) - { - CalendarItem calendarItem = new CalendarItem(); - calendarItem.CalendarItemId = item.CalendarItemId; - calendarItem.Title = item.Title; - calendarItem.Start = item.Start.TimeConverter(department); - calendarItem.End = item.End.TimeConverter(department); - calendarItem.StartTimezone = item.StartTimezone; - calendarItem.EndTimezone = item.EndTimezone; - calendarItem.Description = item.Description; - calendarItem.RecurrenceId = item.RecurrenceId; - calendarItem.RecurrenceRule = item.RecurrenceRule; - calendarItem.RecurrenceException = item.RecurrenceException; - calendarItem.IsAllDay = item.IsAllDay; - calendarItem.ItemType = item.ItemType; - calendarItem.Location = item.Location; - calendarItem.SignupType = item.SignupType; - calendarItem.Reminder = item.Reminder; - calendarItem.LockEditing = item.LockEditing; - calendarItem.Entities = item.Entities; - calendarItem.RequiredAttendes = item.RequiredAttendes; - calendarItem.OptionalAttendes = item.OptionalAttendes; - - if (!String.IsNullOrWhiteSpace(item.CreatorUserId)) - calendarItem.CreatorUserId = item.CreatorUserId.ToString(); - - if (department.IsUserAnAdmin(UserId)) - calendarItem.IsAdminOrCreator = true; - else if (!String.IsNullOrWhiteSpace(item.CreatorUserId) && item.CreatorUserId == UserId) - calendarItem.IsAdminOrCreator = true; - else - calendarItem.IsAdminOrCreator = false; - - - jsonItems.Add(calendarItem); - } - - return Ok(jsonItems); - } - - /// - /// Gets the calendar item. - /// - /// The identifier. - /// ActionResult<CalendarItem>. - [HttpGet("GetCalendarItem")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [Produces(typeof(CalendarItem))] - [SwaggerResponse(200, Type = typeof(CalendarItem))] - public async Task> GetCalendarItem(int id) - { - var calendarItem = new CalendarItem(); - var item = await _calendarService.GetCalendarItemByIdAsync(id); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - if (item == null || department == null) - return NotFound(); - - calendarItem.CalendarItemId = item.CalendarItemId; - calendarItem.Title = item.Title; - calendarItem.Start = item.Start.TimeConverter(department); - calendarItem.End = item.End.TimeConverter(department); - calendarItem.StartTimezone = item.StartTimezone; - calendarItem.EndTimezone = item.EndTimezone; - calendarItem.Description = item.Description; - calendarItem.RecurrenceId = item.RecurrenceId; - calendarItem.RecurrenceRule = item.RecurrenceRule; - calendarItem.RecurrenceException = item.RecurrenceException; - calendarItem.IsAllDay = item.IsAllDay; - calendarItem.ItemType = item.ItemType; - calendarItem.Location = item.Location; - calendarItem.SignupType = item.SignupType; - calendarItem.Reminder = item.Reminder; - calendarItem.LockEditing = item.LockEditing; - calendarItem.Entities = item.Entities; - calendarItem.RequiredAttendes = item.RequiredAttendes; - calendarItem.OptionalAttendes = item.OptionalAttendes; - - if (!String.IsNullOrWhiteSpace(item.CreatorUserId)) - calendarItem.CreatorUserId = item.CreatorUserId.ToString(); - - if (department.IsUserAnAdmin(UserId)) - calendarItem.IsAdminOrCreator = true; - else if (!String.IsNullOrWhiteSpace(item.CreatorUserId) && item.CreatorUserId == UserId) - calendarItem.IsAdminOrCreator = true; - else - calendarItem.IsAdminOrCreator = false; - - if (item.Attendees == null || !item.Attendees.Any()) - calendarItem.Attending = false; - else - { - calendarItem.Attending = item.Attendees.Any(x => x.UserId == UserId); - calendarItem.Attendees = new List(); - - foreach (var attendee in item.Attendees) - { - CalendarItemAttendee attend = new CalendarItemAttendee(); - attend.CalendarItemId = attendee.CalendarItemId; - attend.UserId = attendee.UserId; - attend.AttendeeType = attendee.AttendeeType; - attend.Note = attendee.Note; - - calendarItem.Attendees.Add(attend); - } - } - - return calendarItem; - } - - /// - /// Gets the department calendar item types. - /// - /// ActionResult<List<CalendarItemType>>. - [HttpGet("GetDepartmentCalendarItemTypes")] - [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(typeof(List))] - [SwaggerResponse(200, Type = typeof(List))] - public async Task>> GetDepartmentCalendarItemTypes() - { - var jsonItems = new List(); - var items = await _calendarService.GetAllCalendarItemTypesForDepartmentAsync(DepartmentId); - - jsonItems.Add(new CalendarItemType() - { - CalendarItemTypeId = "0", - Color = "#EEE", - Name = "None" - }); - - foreach (var item in items) - { - var calendarItemType = new CalendarItemType(); - calendarItemType.CalendarItemTypeId = item.CalendarItemTypeId.ToString(); - calendarItemType.Name = item.Name; - calendarItemType.Color = item.Color; - - jsonItems.Add(calendarItemType); - } - - return Ok(jsonItems); - } - - [HttpPost("SetCalendarAttendingStatus")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SetCalendarAttendingStatus(CalendarItemAttendInput input) - { - if (String.IsNullOrWhiteSpace(input.CalendarEventId)) - return NotFound(); - - var calendarItem = await _calendarService.GetCalendarItemByIdAsync(int.Parse(input.CalendarEventId)); - - if (calendarItem == null) - return NotFound(); - - if (calendarItem.DepartmentId != DepartmentId) - return Unauthorized(); - - var result = await _calendarService.SignupForEvent(int.Parse(input.CalendarEventId), UserId, input.Note, input.Type); - - return CreatedAtAction(nameof(SetCalendarAttendingStatus), new { id = result.CalendarItemAttendeeId }, result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CallPrioritiesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CallPrioritiesController.cs deleted file mode 100644 index 1a9043fc..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CallPrioritiesController.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Framework; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to be performed against calls - /// - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CallPrioritiesController : V3AuthenticatedApiControllerbase - { - #region Members and Constructors - private ICallsService _callsService; - private IDepartmentsService _departmentsService; - private IUserProfileService _userProfileService; - private IGeoLocationProvider _geoLocationProvider; - private readonly IAuthorizationService _authorizationService; - private readonly IQueueService _queueService; - private readonly IUsersService _usersService; - - public CallPrioritiesController( - ICallsService callsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IGeoLocationProvider geoLocationProvider, - IAuthorizationService authorizationService, - IQueueService queueService, - IUsersService usersService - ) - { - _callsService = callsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _geoLocationProvider = geoLocationProvider; - _authorizationService = authorizationService; - _queueService = queueService; - _usersService = usersService; - } - #endregion Members and Constructors - - /// - /// Returns all the call priorities (including deleted ones) for a department - /// - /// Array of CallPriorityResult objects for each call priority in the department - [HttpGet("GetAllCallPriorites")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllCallPriorites() - { - var result = new List(); - var priorities = await _callsService.GetCallPrioritiesForDepartmentAsync(DepartmentId); - - foreach (var p in priorities) - { - var priority = new CallPriorityResult(); - - priority.Id = p.DepartmentCallPriorityId; - priority.DepartmentId = p.DepartmentId; - priority.Name = StringHelpers.SanitizeHtmlInString(p.Name); - priority.Color = p.Color; - priority.Sort = p.Sort; - priority.IsDeleted = p.IsDeleted; - priority.IsDefault = p.IsDefault; - priority.Tone = p.Tone; - - result.Add(priority); - } - - return result; - } - - /// - /// Returns all the call priorities (including deleted ones) for a selected department - /// - /// Array of CallPriorityResult objects for each call priority in the department - [HttpGet("GetAllCallPrioritesForDepartment")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task>> GetAllCallPrioritesForDepartment(int departmentId) - { - var result = new List(); - - if (departmentId != DepartmentId && !IsSystem) - Unauthorized(); - - var priorities = await _callsService.GetCallPrioritiesForDepartmentAsync(departmentId); - - foreach (var p in priorities) - { - var priority = new CallPriorityResult(); - - priority.Id = p.DepartmentCallPriorityId; - priority.DepartmentId = p.DepartmentId; - priority.Name = StringHelpers.SanitizeHtmlInString(p.Name); - priority.Color = p.Color; - priority.Sort = p.Sort; - priority.IsDeleted = p.IsDeleted; - priority.IsDefault = p.IsDefault; - priority.Tone = p.Tone; - - result.Add(priority); - } - - return Ok(result); - } - - /// - /// Return the audio file for push notifications for a specific call priority - /// - /// File download result for push dispatch audio for a call priority - [HttpGet("GetPushAudioForPriority")] - public async Task GetPushAudioForPriority(int priorityId) - { - var priority = await _callsService.GetCallPrioritiesByIdAsync(DepartmentId, priorityId, true); - - if (priority == null || priority.PushNotificationSound == null) - return BadRequest(); - - return File(new MemoryStream(priority.PushNotificationSound), "audio/wav", $"CallPAudio_{priorityId}.wav"); - } - - /// - /// Return the ios audio file for push notifications for a specific call priority - /// - /// File download result for push dispatch audio for a call priority - [HttpGet("GetIOSPushAudioForPriority")] - public async Task GetIOSPushAudioForPriority(int priorityId) - { - var priority = await _callsService.GetCallPrioritiesByIdAsync(DepartmentId, priorityId, true); - - if (priority == null || priority.IOSPushNotificationSound == null) - return BadRequest(); - - return File(new MemoryStream(priority.PushNotificationSound), "audio/x-caf", $"CallPAudio_{priorityId}.caf"); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CallsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CallsController.cs deleted file mode 100644 index 24c59209..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CallsController.cs +++ /dev/null @@ -1,1826 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Configuration; -using System.IO; -using System.Linq; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; -using Resgrid.Framework; -using Resgrid.Model.Events; -using Resgrid.Model.Queue; -using Resgrid.Providers.Bus; -using Resgrid.Web.Services.Controllers.Version3.Models.Calls; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using Resgrid.Web.Services.Controllers.Version3.Models.Protocols; -using Resgrid.Web.ServicesCore.Options; -using IAuthorizationService = Resgrid.Model.Services.IAuthorizationService; -using Resgrid.Web.Helpers; -using System.Text; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to be performed against calls - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CallsController : V3AuthenticatedApiControllerbase - { - #region Members and Constructors - private readonly ICallsService _callsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly IAuthorizationService _authorizationService; - private readonly IQueueService _queueService; - private readonly IUsersService _usersService; - private readonly IUnitsService _unitsService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly IProtocolsService _protocolsService; - private readonly IOptions _appSettingsAccessor; - private readonly IEventAggregator _eventAggregator; - - public CallsController( - ICallsService callsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IGeoLocationProvider geoLocationProvider, - IAuthorizationService authorizationService, - IQueueService queueService, - IUsersService usersService, - IUnitsService unitsService, - IActionLogsService actionLogsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - IProtocolsService protocolsService, - IOptions appSettingsAccessor, - IEventAggregator eventAggregator - ) - { - _callsService = callsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _geoLocationProvider = geoLocationProvider; - _authorizationService = authorizationService; - _queueService = queueService; - _usersService = usersService; - _unitsService = unitsService; - _actionLogsService = actionLogsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _protocolsService = protocolsService; - _appSettingsAccessor = appSettingsAccessor; - _eventAggregator = eventAggregator; - } - #endregion Members and Constructors - - /// - /// Returns all the active calls for the department - /// - /// Array of CallResult objects for each active call in the department - [HttpGet("GetActiveCalls")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetActiveCalls() - { - var result = new List(); - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var c in calls) - { - var call = new CallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Utc = c.LoggedOn; - call.Ste = c.State; - call.Num = c.Number; - - result.Add(call); - } - - return Ok(result); - } - - /// - /// Returns all the active calls for the department - /// - /// Array of CallResult objects for each active call in the department - [HttpGet("GetActiveCallsEx")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetActiveCallsEx() - { - var result = new List(); - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var c in calls) - { - var call = new CallResultEx(); - call.Protocols = new List(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Utc = c.LoggedOn; - call.Ste = c.State; - call.Num = c.Number; - - if (c.Protocols != null && c.Protocols.Any()) - { - foreach (var protocol in c.Protocols) - { - var p = new CallProtocolResult(); - p.Id = protocol.DispatchProtocolId; - p.Code = protocol.Protocol.Code; - p.Name = protocol.Protocol.Name; - - call.Protocols.Add(p); - } - } - - result.Add(call); - } - - return Ok(result); - } - - /// - /// Returns all the active calls for the department (extended object result, more verbose then GetActiveCalls) - /// - /// Array of DepartmentCallResult objects for each active call in the department - [HttpGet("GetActiveCallsForDepartment")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetActiveCallsForDepartment(int departmentId) - { - var result = new List(); - - if (departmentId != DepartmentId && !IsSystem) - Unauthorized(); - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(departmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(departmentId, false); - - foreach (var c in calls) - { - var call = new DepartmentCallResult(); - - call.Name = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.NatureOfCall = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Notes = StringHelpers.SanitizeHtmlInString(c.Notes); - - call.LoggedOn = c.LoggedOn.TimeConverter(department); - call.LoggedOnUtc = c.LoggedOn; - call.CallId = c.CallId; - call.Number = c.Number; - call.DepartmentId = c.DepartmentId; - call.ReportingUserId = c.ReportingUserId; - call.Priority = c.Priority; - call.IsCritical = c.IsCritical; - call.Type = c.Type; - call.IncidentNumber = c.IncidentNumber; - call.MapPage = c.MapPage; - call.CompletedNotes = c.CompletedNotes; - call.Address = c.Address; - call.GeoLocationData = c.GeoLocationData; - call.ClosedByUserId = c.ClosedByUserId; - call.ClosedOn = c.ClosedOn; - call.State = c.State; - call.IsDeleted = c.IsDeleted; - call.CallSource = c.CallSource; - call.DispatchCount = c.DispatchCount; - call.LastDispatchedOn = c.LastDispatchedOn; - call.SourceIdentifier = c.SourceIdentifier; - call.ContactName = c.ContactName; - call.ContactNumber = c.ContactNumber; - call.Public = c.Public; - call.ExternalIdentifier = c.ExternalIdentifier; - call.ReferenceNumber = c.ReferenceNumber; - - if (c.Dispatches != null) - { - foreach (var dispatch in c.Dispatches) - { - var dispatchResult = new DepartmentCallDispatchResult(); - dispatchResult.CallDispatchId = dispatch.CallDispatchId; - dispatchResult.CallId = dispatch.CallId; - dispatchResult.UserId = dispatch.UserId; - dispatchResult.GroupId = dispatch.GroupId; - dispatchResult.DispatchCount = dispatch.DispatchCount; - dispatchResult.LastDispatchedOn = dispatch.LastDispatchedOn; - dispatchResult.ActionLogId = dispatch.ActionLogId; - - call.Dispatches.Add(dispatchResult); - } - } - - if (c.GroupDispatches != null) - { - foreach (var dispatch in c.GroupDispatches) - { - var dispatchResult = new DepartmentCallDispatchGroupResult(); - dispatchResult.CallDispatchGroupId = dispatch.CallDispatchGroupId; - dispatchResult.CallId = dispatch.CallId; - dispatchResult.DepartmentGroupId = dispatch.DepartmentGroupId; - dispatchResult.DispatchCount = dispatch.DispatchCount; - dispatchResult.LastDispatchedOn = dispatch.LastDispatchedOn; - - call.GroupDispatches.Add(dispatchResult); - } - } - - if (c.UnitDispatches != null) - { - foreach (var dispatch in c.UnitDispatches) - { - var dispatchResult = new DepartmentCallDispatchUnitResult(); - dispatchResult.CallDispatchUnitId = dispatch.CallDispatchUnitId; - dispatchResult.CallId = dispatch.CallId; - dispatchResult.UnitId = dispatch.UnitId; - dispatchResult.DispatchCount = dispatch.DispatchCount; - dispatchResult.LastDispatchedOn = dispatch.LastDispatchedOn; - - call.UnitDispatches.Add(dispatchResult); - } - } - - if (c.RoleDispatches != null) - { - foreach (var dispatch in c.RoleDispatches) - { - var dispatchResult = new DepartmentCallDispatchRoleResult(); - dispatchResult.CallDispatchRoleId = dispatch.CallDispatchRoleId; - dispatchResult.CallId = dispatch.CallId; - dispatchResult.RoleId = dispatch.RoleId; - dispatchResult.DispatchCount = dispatch.DispatchCount; - dispatchResult.LastDispatchedOn = dispatch.LastDispatchedOn; - - call.RoleDispatches.Add(dispatchResult); - } - } - - result.Add(call); - } - - return Ok(result); - } - - /// - /// Returns a specific call from the Resgrid System - /// - /// CallResult of the call in the Resgrid system - [HttpGet("GetCall")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetCall(int callId) - { - var c = await _callsService.GetCallByIdAsync(callId); - c = await _callsService.PopulateCallData(c, false, true, true, false, false, false, false, true, true); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var call = new CallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = c.Name; - call.Noc = c.NatureOfCall; - call.Map = c.MapPage; - call.Not = c.Notes; - call.Eid = c.ExternalIdentifier; - call.Rnm = c.ContactName; - call.Rci = c.ContactNumber; - call.Rid = c.ReferenceNumber; - call.Typ = c.Type; - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - - if (call.Aud > 0) - { - var audio = c.Attachments.FirstOrDefault(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - - if (audio != null) - call.Aid = SymmetricEncryption.Encrypt(audio.CallAttachmentId.ToString(), Config.SystemBehaviorConfig.ExternalAudioUrlParamPasshprase); - } - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - { - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - call.Gla = geo[0].Trim(); - call.Glo = geo[1].Trim(); - } - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Utc = c.LoggedOn; - call.Ste = c.State; - call.Num = c.Number; - - if (c.DispatchOn.HasValue) - call.Don = c.DispatchOn.Value.TimeConverter(department); - - if (!String.IsNullOrWhiteSpace(c.W3W)) - call.w3w = c.W3W; - - - return Ok(call); - } - - /// - /// Gets all the meta-data around a call, dispatched personnel, units, groups and responses - /// - /// CallId to get data for - /// - [HttpGet("GetCallExtraData")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetCallExtraData(int callId) - { - var result = new CallDataResult(); - - var call = await _callsService.GetCallByIdAsync(callId); - - if (call.DepartmentId != DepartmentId) - Unauthorized(); - - call = await _callsService.PopulateCallData(call, true, true, true, true, true, true, true, true, true); - - var groups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(call.DepartmentId); - var unitStates = (await _unitsService.GetUnitStatesForCallAsync(call.DepartmentId, callId)).OrderBy(x => x.UnitId).OrderBy(y => y.Timestamp).ToList(); - var actionLogs = (await _actionLogsService.GetActionLogsForCallAsync(call.DepartmentId, callId)).OrderBy(x => x.UserId).OrderBy(y => y.Timestamp).ToList(); - var names = await _usersService.GetUserGroupAndRolesByDepartmentIdAsync(DepartmentId, true, true, true); - var priority = await _callsService.GetCallPrioritiesByIdAsync(call.DepartmentId, call.Priority, false); - var roles = await _personnelRolesService.GetAllRolesForDepartmentAsync(call.DepartmentId); - - if (priority != null) - { - result.Priority = new CallPriorityDataResult(); - result.Priority.Id = priority.DepartmentCallPriorityId; - result.Priority.DepartmentId = priority.DepartmentId; - result.Priority.Name = priority.Name; - result.Priority.Color = priority.Color; - result.Priority.Sort = priority.Sort; - result.Priority.IsDeleted = priority.IsDeleted; - result.Priority.IsDefault = priority.IsDefault; - result.Priority.DispatchPersonnel = priority.DispatchPersonnel; - result.Priority.DispatchUnits = priority.DispatchUnits; - result.Priority.ForceNotifyAllPersonnel = priority.ForceNotifyAllPersonnel; - result.Priority.Tone = priority.Tone; - result.Priority.IsSystemPriority = priority.IsSystemPriority; - } - - foreach (var actionLog in actionLogs) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = actionLog.ActionLogId.ToString(); - eventResult.Timestamp = actionLog.Timestamp; - eventResult.Type = "User"; - - var name = names.FirstOrDefault(x => x.UserId == actionLog.UserId); - if (name != null) - { - eventResult.Name = name.Name; - - if (name.DepartmentGroupId.HasValue) - { - eventResult.GroupId = name.DepartmentGroupId.Value; - eventResult.Group = name.DepartmentGroupName; - } - } - else - { - eventResult.Name = "Unknown User"; - } - - eventResult.StatusId = actionLog.ActionTypeId; - eventResult.Location = actionLog.GeoLocationData; - eventResult.Note = actionLog.Note; - - result.Activity.Add(eventResult); - } - - foreach (var unitLog in unitStates) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = unitLog.UnitStateId.ToString(); - eventResult.Timestamp = unitLog.Timestamp; - eventResult.Type = "Unit"; - eventResult.Name = unitLog.Unit.Name; - - var group = groups.FirstOrDefault(x => x.DepartmentGroupId == unitLog.Unit.StationGroupId); - if (group != null) - { - eventResult.GroupId = group.DepartmentGroupId; - eventResult.Group = group.Name; - } - - eventResult.StatusId = eventResult.StatusId; - eventResult.Location = eventResult.Location; - eventResult.Note = eventResult.Note; - - result.Activity.Add(eventResult); - } - - foreach (var dispatch in call.Dispatches) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = dispatch.UserId; - if (dispatch.LastDispatchedOn.HasValue) - { - eventResult.Timestamp = dispatch.LastDispatchedOn.Value; - } - eventResult.Type = "User"; - - var name = names.FirstOrDefault(x => x.UserId == dispatch.UserId); - if (name != null) - { - eventResult.Name = name.Name; - - if (name.DepartmentGroupId.HasValue) - { - eventResult.GroupId = name.DepartmentGroupId.Value; - eventResult.Group = name.DepartmentGroupName; - } - } - else - { - eventResult.Name = "Unknown User"; - } - - result.Dispatches.Add(eventResult); - } - - if (call.GroupDispatches != null && call.GroupDispatches.Any()) - { - foreach (var groupDispatch in call.GroupDispatches) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = groupDispatch.DepartmentGroupId.ToString(); - if (groupDispatch.LastDispatchedOn.HasValue) - { - eventResult.Timestamp = groupDispatch.LastDispatchedOn.Value; - } - eventResult.Type = "Group"; - - var name = groups.FirstOrDefault(x => x.DepartmentGroupId == groupDispatch.DepartmentGroupId); - if (name != null) - { - eventResult.Name = name.Name; - eventResult.GroupId = name.DepartmentGroupId; - eventResult.Group = name.Name; - - } - else - { - eventResult.Name = "Unknown Group"; - } - - result.Dispatches.Add(eventResult); - } - } - - if (call.UnitDispatches != null && call.UnitDispatches.Any()) - { - foreach (var unitDispatch in call.UnitDispatches) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = unitDispatch.UnitId.ToString(); - if (unitDispatch.LastDispatchedOn.HasValue) - { - eventResult.Timestamp = unitDispatch.LastDispatchedOn.Value; - } - eventResult.Type = "Unit"; - - var unit = units.FirstOrDefault(x => x.UnitId == unitDispatch.UnitId); - if (unit != null) - { - eventResult.Name = unit.Name; - - if (unit.StationGroupId.HasValue) - { - var group = groups.FirstOrDefault(x => x.DepartmentGroupId == unit.StationGroupId.GetValueOrDefault()); - if (group != null) - { - eventResult.GroupId = group.DepartmentGroupId; - eventResult.Group = group.Name; - - } - } - - } - else - { - eventResult.Name = "Unknown Unit"; - } - - result.Dispatches.Add(eventResult); - } - } - - if (call.RoleDispatches != null && call.RoleDispatches.Any()) - { - foreach (var roleDispatch in call.RoleDispatches) - { - var eventResult = new DispatchedEventResult(); - eventResult.Id = roleDispatch.RoleId.ToString(); - if (roleDispatch.LastDispatchedOn.HasValue) - { - eventResult.Timestamp = roleDispatch.LastDispatchedOn.Value; - } - eventResult.Type = "Role"; - - var role = roles.FirstOrDefault(x => x.PersonnelRoleId == roleDispatch.RoleId); - if (role != null) - { - eventResult.Name = role.Name; - } - else - { - eventResult.Name = "Unknown Role"; - } - - result.Dispatches.Add(eventResult); - } - } - - if (call.Protocols != null && call.Protocols.Any()) - { - foreach (var callProtocol in call.Protocols) - { - var protocol = await _protocolsService.GetProtocolByIdAsync(callProtocol.CallProtocolId); - var protocolResult = ProtocolResult.Convert(protocol); - - if (protocolResult != null) - result.Protocols.Add(protocolResult); - } - } - - return Ok(result); - } - - /// - /// Saves a call in the Resgrid system - /// - /// - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - [HttpPost("SaveCall")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task SaveCall([FromBody] NewCallInput newCallInput, CancellationToken cancellationToken) - { - if (!ModelState.IsValid) - return BadRequest(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - - var call = new Call - { - DepartmentId = DepartmentId, - ReportingUserId = UserId, - Priority = (int)Enum.Parse(typeof(CallPriority), newCallInput.Pri), - Name = newCallInput.Nme, - NatureOfCall = newCallInput.Noc - }; - - if (!string.IsNullOrWhiteSpace(newCallInput.CNme)) - call.ContactName = newCallInput.CNme; - - if (!string.IsNullOrWhiteSpace(newCallInput.CNum)) - call.ContactName = newCallInput.CNum; - - if (!string.IsNullOrWhiteSpace(newCallInput.EId)) - call.ExternalIdentifier = newCallInput.EId; - - if (!string.IsNullOrWhiteSpace(newCallInput.InI)) - call.IncidentNumber = newCallInput.InI; - - if (!string.IsNullOrWhiteSpace(newCallInput.RId)) - call.ReferenceNumber = newCallInput.RId; - - if (!string.IsNullOrWhiteSpace(newCallInput.Add)) - call.Address = newCallInput.Add; - - if (!string.IsNullOrWhiteSpace(newCallInput.W3W)) - call.W3W = newCallInput.W3W; - - if (!string.IsNullOrWhiteSpace(newCallInput.Cfd)) - call.CallFormData = newCallInput.Cfd; - - if (newCallInput.Don.HasValue) - { - call.DispatchOn = newCallInput.Don.Value; - - call.DispatchOn = DateTimeHelpers.ConvertToUtc(newCallInput.Don.Value, department.TimeZone); - call.HasBeenDispatched = false; - } - - //if (call.Address.Equals("Current Coordinates", StringComparison.InvariantCultureIgnoreCase)) - // call.Address = ""; - - if (!string.IsNullOrWhiteSpace(newCallInput.Not)) - call.Notes = newCallInput.Not; - - if (!string.IsNullOrWhiteSpace(newCallInput.Geo)) - call.GeoLocationData = newCallInput.Geo; - - if (string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.Address)) - call.GeoLocationData = await _geoLocationProvider.GetLatLonFromAddress(call.Address); - - if (string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.W3W)) - { - var coords = await _geoLocationProvider.GetCoordinatesFromW3WAsync(call.W3W); - - if (coords != null) - { - call.GeoLocationData = $"{coords.Latitude},{coords.Longitude}"; - } - } - - call.LoggedOn = DateTime.UtcNow; - - if (!String.IsNullOrWhiteSpace(newCallInput.Typ) && newCallInput.Typ != "No Type") - { - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - var type = callTypes.FirstOrDefault(x => x.Type == newCallInput.Typ); - - if (type != null) - { - call.Type = type.Type; - } - } - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - call.Dispatches = new Collection(); - call.GroupDispatches = new List(); - call.RoleDispatches = new List(); - - if (newCallInput.Dis == "0") - { - // Use case, existing clients and non-ionic2 app this will be null dispatch all users. Or we've specified everyone (0). - foreach (var u in users) - { - var cd = new CallDispatch { UserId = u.UserId }; - - call.Dispatches.Add(cd); - } - } - else - { - var dispatch = newCallInput.Dis.Split(char.Parse("|")); - - try - { - var usersToDispatch = dispatch.Where(x => x.StartsWith("P:")).Select(y => y.Replace("P:", "")); - foreach (var user in usersToDispatch) - { - var cd = new CallDispatch { UserId = user }; - call.Dispatches.Add(cd); - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - var groupsToDispatch = dispatch.Where(x => x.StartsWith("G:")).Select(y => int.Parse(y.Replace("G:", ""))); - foreach (var group in groupsToDispatch) - { - var cd = new CallDispatchGroup { DepartmentGroupId = group }; - call.GroupDispatches.Add(cd); - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - var rolesToDispatch = dispatch.Where(x => x.StartsWith("R:")).Select(y => int.Parse(y.Replace("R:", ""))); - foreach (var role in rolesToDispatch) - { - var cd = new CallDispatchRole { RoleId = role }; - call.RoleDispatches.Add(cd); - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - var unitsToDispatch = dispatch.Where(x => x.StartsWith("U:")).Select(y => int.Parse(y.Replace("U:", ""))); - foreach (var unit in unitsToDispatch) - { - var cdu = new CallDispatchUnit { UnitId = unit }; - call.UnitDispatches.Add(cdu); - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - } - - // Call is in the past or is now, were dispatching now (at the end of this func) - if (call.DispatchOn.HasValue && call.DispatchOn.Value <= DateTime.UtcNow) - call.HasBeenDispatched = true; - - var savedCall = await _callsService.SaveCallAsync(call, cancellationToken); - - //OutboundEventProvider handler = new OutboundEventProvider.CallAddedTopicHandler(); - //OutboundEventProvider..Handle(new CallAddedEvent() { DepartmentId = DepartmentId, Call = savedCall }); - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = savedCall }); - - var profiles = new List(); - - if (call.Dispatches != null && call.Dispatches.Any()) - { - profiles.AddRange(call.Dispatches.Select(x => x.UserId).ToList()); - } - - if (call.GroupDispatches != null && call.GroupDispatches.Any()) - { - foreach (var groupDispatch in call.GroupDispatches) - { - var group = await _departmentGroupsService.GetGroupByIdAsync(groupDispatch.DepartmentGroupId); - - if (group != null && group.Members != null) - { - profiles.AddRange(group.Members.Select(x => x.UserId)); - } - } - } - - if (call.RoleDispatches != null && call.RoleDispatches.Any()) - { - foreach (var roleDispatch in call.RoleDispatches) - { - var members = await _personnelRolesService.GetAllMembersOfRoleAsync(roleDispatch.RoleId); - - if (members != null) - { - profiles.AddRange(members.Select(x => x.UserId).ToList()); - } - } - } - - var cqi = new CallQueueItem(); - cqi.Call = savedCall; - - if (profiles.Any()) - cqi.Profiles = await _userProfileService.GetSelectedUserProfilesAsync(profiles); - - if (!savedCall.DispatchOn.HasValue || savedCall.DispatchOn.Value <= DateTime.UtcNow) - await _queueService.EnqueueCallBroadcastAsync(cqi, cancellationToken); - - return CreatedAtAction(nameof(SaveCall), new { id = savedCall.CallId }, savedCall); - } - - /// - /// Adds a new call into Resgrid and Dispatches the call - /// - /// Call data to add into the system - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// AddCallInput. - [HttpPost("AddCall")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status201Created)] - [Obsolete] - public async Task> AddCall([FromBody] AddCallInput callInput, CancellationToken cancellationToken) - { - try - { - - var call = new Call - { - DepartmentId = DepartmentId, - ReportingUserId = UserId, - Priority = callInput.Priority, - Name = callInput.Name, - NatureOfCall = callInput.NatureOfCall, - Number = callInput.Number, - IsCritical = callInput.IsCritical, - IncidentNumber = callInput.IncidentNumber, - MapPage = callInput.MapPage, - Notes = callInput.Notes, - CompletedNotes = callInput.CompletedNotes, - Address = callInput.Address, - GeoLocationData = callInput.GeoLocationData, - LoggedOn = callInput.LoggedOn, - ClosedByUserId = callInput.ClosedByUserId, - ClosedOn = callInput.ClosedOn, - State = callInput.State, - IsDeleted = callInput.IsDeleted, - CallSource = callInput.CallSource, - DispatchCount = callInput.DispatchCount, - LastDispatchedOn = callInput.LastDispatchedOn, - SourceIdentifier = callInput.SourceIdentifier, - W3W = callInput.W3W, - ContactName = callInput.ContactName, - ContactNumber = callInput.ContactNumber, - Public = callInput.Public, - ExternalIdentifier = callInput.ExternalIdentifier, - ReferenceNumber = callInput.ReferenceNumber - }; - - if (!string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.Address)) - call.GeoLocationData = await _geoLocationProvider.GetLatLonFromAddress(call.Address); - - if (string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.W3W)) - { - var coords = await _geoLocationProvider.GetCoordinatesFromW3WAsync(call.W3W); - - if (coords != null) - { - call.GeoLocationData = $"{coords.Latitude},{coords.Longitude}"; - } - } - - call.LoggedOn = DateTime.UtcNow; - - if (!String.IsNullOrWhiteSpace(callInput.Type) && callInput.Type != "No Type") - { - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - var type = callTypes.FirstOrDefault(x => x.Type == callInput.Type); - - if (type != null) - { - call.Type = type.Type; - } - } - - call.Dispatches = new List(); - call.GroupDispatches = new List(); - call.RoleDispatches = new List(); - - List groupUserIds = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - if (callInput.AllCall) - { - foreach (var u in users) - { - var cd = new CallDispatch { UserId = u.UserId }; - - call.Dispatches.Add(cd); - } - } - else - { - if (callInput.GroupCodesToDispatch != null && callInput.GroupCodesToDispatch.Count > 0) - { - var allGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - foreach (var groupCode in callInput.GroupCodesToDispatch) - { - var groupsToDispatch = allGroups.FirstOrDefault(x => x.DispatchEmail == groupCode); - - if (groupsToDispatch != null) - { - var cd = new CallDispatchGroup { DepartmentGroupId = groupsToDispatch.DepartmentGroupId }; - call.GroupDispatches.Add(cd); - - if (groupsToDispatch.Members != null && groupsToDispatch.Members.Any()) - { - foreach (var departmentGroupMember in groupsToDispatch.Members) - { - if (!groupUserIds.Contains(departmentGroupMember.UserId)) - groupUserIds.Add(departmentGroupMember.UserId); - } - } - } - } - } - } - - if (callInput.Attachments != null && callInput.Attachments.Any()) - { - call.Attachments = new List(); - - foreach (var attachment in callInput.Attachments) - { - var newAttachment = new CallAttachment(); - newAttachment.Data = attachment.Data; - newAttachment.Timestamp = DateTime.UtcNow; - newAttachment.FileName = attachment.FileName; - newAttachment.Size = attachment.Size; - newAttachment.CallAttachmentType = attachment.CallAttachmentType; - - call.Attachments.Add(newAttachment); - } - } - - var savedCall = await _callsService.SaveCallAsync(call, cancellationToken); - - - //OutboundEventProvider.CallAddedTopicHandler handler = new OutboundEventProvider.CallAddedTopicHandler(); - //await handler.Handle(new CallAddedEvent() { DepartmentId = DepartmentId, Call = savedCall }); - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = savedCall }); - - var cqi = new CallQueueItem(); - cqi.Call = savedCall; - - if (cqi.Call.Dispatches != null && cqi.Call.Dispatches.Any()) - { - cqi.Profiles = - await _userProfileService.GetSelectedUserProfilesAsync(cqi.Call.Dispatches.Select(x => x.UserId).ToList()); - } - else - { - if (groupUserIds.Any()) - cqi.Profiles = await _userProfileService.GetSelectedUserProfilesAsync(groupUserIds); - } - - await _queueService.EnqueueCallBroadcastAsync(cqi, cancellationToken); - - callInput.CallId = savedCall.CallId; - callInput.Number = savedCall.Number; - } - catch (Exception ex) - { - Logging.LogException(ex); - - throw ex; - } - - return Ok(callInput); - } - - /// - /// Closes a Resgrid call - /// - /// Data to close a call - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// OK status code if successful - [HttpPut("CloseCall")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task CloseCall([FromBody] CloseCallInput closeCallInput, CancellationToken cancellationToken) - { - if (!ModelState.IsValid) - return BadRequest(); - - var call = await _callsService.GetCallByIdAsync(closeCallInput.Id); - - if (call == null) - return NotFound(); - - call.ClosedByUserId = UserId; - call.ClosedOn = DateTime.UtcNow; - call.CompletedNotes = closeCallInput.Msg; - call.State = (int)closeCallInput.Typ; - - await _callsService.SaveCallAsync(call, cancellationToken); - - //OutboundEventProvider.CallAddedTopicHandler handler = new OutboundEventProvider.CallAddedTopicHandler(); - //await handler.Handle(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); - - return Ok(); - } - - /// - /// Updates an existing Active Call in the Resgrid system - /// - /// Data to updated the call - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// OK status code if successful - [HttpPut("EditCall")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task EditCall([FromBody] EditCallInput editCallInput, CancellationToken cancellationToken) - { - var call = await _callsService.GetCallByIdAsync(editCallInput.Cid); - - call = await _callsService.PopulateCallData(call, true, true, true, true, true, true, true, true, true); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - if (call.State != (int)CallStates.Active) - return BadRequest(); - - call.Priority = (int)Enum.Parse(typeof(CallPriority), editCallInput.Pri); - call.Name = editCallInput.Nme; - call.NatureOfCall = editCallInput.Noc; - - if (!string.IsNullOrWhiteSpace(editCallInput.CNme)) - call.ContactName = editCallInput.CNme; - - if (!string.IsNullOrWhiteSpace(editCallInput.CNum)) - call.ContactName = editCallInput.CNum; - - if (!string.IsNullOrWhiteSpace(editCallInput.EId)) - call.ExternalIdentifier = editCallInput.EId; - - if (!string.IsNullOrWhiteSpace(editCallInput.InI)) - call.IncidentNumber = editCallInput.InI; - - if (!string.IsNullOrWhiteSpace(editCallInput.RId)) - call.ReferenceNumber = editCallInput.RId; - - if (!string.IsNullOrWhiteSpace(editCallInput.Add)) - call.Address = editCallInput.Add; - - if (!string.IsNullOrWhiteSpace(editCallInput.W3W)) - call.W3W = editCallInput.W3W; - - if (!string.IsNullOrWhiteSpace(editCallInput.Cfd)) - call.CallFormData = editCallInput.Cfd; - - if (editCallInput.Don.HasValue) - { - call.DispatchOn = editCallInput.Don.Value; - - call.DispatchOn = DateTimeHelpers.ConvertToUtc(editCallInput.Don.Value, department.TimeZone); - call.HasBeenDispatched = false; - } - - if (!string.IsNullOrWhiteSpace(editCallInput.Not)) - call.Notes = editCallInput.Not; - - if (!string.IsNullOrWhiteSpace(editCallInput.Geo)) - call.GeoLocationData = editCallInput.Geo; - - if (string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.Address)) - call.GeoLocationData = await _geoLocationProvider.GetLatLonFromAddress(call.Address); - - if (string.IsNullOrWhiteSpace(call.GeoLocationData) && !string.IsNullOrWhiteSpace(call.W3W)) - { - var coords = await _geoLocationProvider.GetCoordinatesFromW3WAsync(call.W3W); - - if (coords != null) - { - call.GeoLocationData = $"{coords.Latitude},{coords.Longitude}"; - } - } - - if (!String.IsNullOrWhiteSpace(editCallInput.Typ) && editCallInput.Typ != "No Type") - { - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - var type = callTypes.FirstOrDefault(x => x.Type == editCallInput.Typ); - - if (type != null) - { - call.Type = type.Type; - } - } - - if (string.IsNullOrWhiteSpace(editCallInput.Dis) || editCallInput.Dis == "0") - { - if (call.Dispatches == null) - call.Dispatches = new List(); - - if (call.GroupDispatches == null) - call.GroupDispatches = new List(); - - if (call.RoleDispatches == null) - call.RoleDispatches = new List(); - - if (call.UnitDispatches == null) - call.UnitDispatches = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - // Use case, existing clients and non-ionic2 app this will be null dispatch all users. Or we've specified everyone (0). - foreach (var u in users) - { - var cd = new CallDispatch { UserId = u.UserId }; - - call.Dispatches.Add(cd); - } - } - else - { - var dispatch = editCallInput.Dis.Split(char.Parse("|")); - var usersToDispatch = dispatch.Where(x => x.StartsWith("P:")).Select(y => y.Replace("P:", "")); - var groupsToDispatch = dispatch.Where(x => x.StartsWith("G:")).Select(y => int.Parse(y.Replace("G:", ""))); - var rolesToDispatch = dispatch.Where(x => x.StartsWith("R:")).Select(y => int.Parse(y.Replace("R:", ""))); - var unitsToDispatch = dispatch.Where(x => x.StartsWith("U:")).Select(y => int.Parse(y.Replace("U:", ""))); - - try - { - if (call.Dispatches == null) - call.Dispatches = new List(); - - var dispatchesToRemove = call.Dispatches.Select(x => x.UserId).Where(y => !usersToDispatch.Contains(y)).ToList(); - - foreach (var userId in dispatchesToRemove) - { - var item = call.Dispatches.First(x => x.UserId == userId); - call.Dispatches.Remove(item); - } - - foreach (var user in usersToDispatch) - { - if (!call.Dispatches.Any(x => x.UserId == user)) - { - var cd = new CallDispatch { CallId = call.CallId, UserId = user }; - call.Dispatches.Add(cd); - } - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - if (call.GroupDispatches == null) - call.GroupDispatches = new List(); - - var dispatchesToRemove = call.GroupDispatches.Select(x => x.DepartmentGroupId).Where(y => !groupsToDispatch.Contains(y)).ToList(); - - foreach (var id in dispatchesToRemove) - { - call.GroupDispatches.Remove(call.GroupDispatches.First(x => x.DepartmentGroupId == id)); - } - - foreach (var group in groupsToDispatch) - { - if (!call.GroupDispatches.Any(x => x.DepartmentGroupId == group)) - { - var cd = new CallDispatchGroup { CallId = call.CallId, DepartmentGroupId = group }; - call.GroupDispatches.Add(cd); - } - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - if (call.RoleDispatches == null) - call.RoleDispatches = new List(); - - var dispatchesToRemove = call.RoleDispatches.Select(x => x.RoleId).Where(y => !rolesToDispatch.Contains(y)).ToList(); - - foreach (var id in dispatchesToRemove) - { - call.RoleDispatches.Remove(call.RoleDispatches.First(x => x.RoleId == id)); - } - - foreach (var role in rolesToDispatch) - { - if (!call.RoleDispatches.Any(x => x.RoleId == role)) - { - var cd = new CallDispatchRole { CallId = call.CallId, RoleId = role }; - call.RoleDispatches.Add(cd); - } - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - - try - { - if (call.UnitDispatches == null) - call.UnitDispatches = new List(); - - var dispatchesToRemove = call.UnitDispatches.Select(x => x.UnitId).Where(y => !unitsToDispatch.Contains(y)).ToList(); - - foreach (var id in dispatchesToRemove) - { - call.UnitDispatches.Remove(call.UnitDispatches.First(x => x.UnitId == id)); - } - - foreach (var unit in unitsToDispatch) - { - if (!call.UnitDispatches.Any(x => x.UnitId == unit)) - { - var cdu = new CallDispatchUnit { CallId = call.CallId, UnitId = unit }; - call.UnitDispatches.Add(cdu); - } - } - } - catch (Exception ex) - { - Logging.LogException(ex); - } - } - - // Call is in the past or is now, were dispatching now (at the end of this func) - if (call.DispatchOn.HasValue && call.DispatchOn.Value <= DateTime.UtcNow) - call.HasBeenDispatched = true; - - await _callsService.SaveCallAsync(call, cancellationToken); - - if (editCallInput.RebroadcastCall) - { - var cqi = new CallQueueItem(); - cqi.Call = call; - - // If we have any group, unit or role dispatches just bet the farm and all all profiles for now. - if (cqi.Call.GroupDispatches.Any() || cqi.Call.UnitDispatches.Any() || cqi.Call.RoleDispatches.Any()) - cqi.Profiles = (await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId)).Select(x => x.Value).ToList(); - else if (cqi.Call.Dispatches != null && cqi.Call.Dispatches.Any()) - cqi.Profiles = await _userProfileService.GetSelectedUserProfilesAsync(cqi.Call.Dispatches.Select(x => x.UserId).ToList()); - else - cqi.Profiles = new List(); - - - if (cqi.Call.Dispatches.Any() || cqi.Call.GroupDispatches.Any() || cqi.Call.UnitDispatches.Any() || cqi.Call.RoleDispatches.Any()) - await _queueService.EnqueueCallBroadcastAsync(cqi, cancellationToken); - } - - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); - - return Ok(); - } - - /// - /// Get notes for a call - /// - /// CallId of the call you want to get notes for - /// - [HttpGet("GetCallNotes")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetCallNotes(int callId) - { - var call = await _callsService.GetCallByIdAsync(callId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - call = await _callsService.PopulateCallData(call, false, false, true, false, false, false, false, false, false); - - if (call.CallNotes == null || !call.CallNotes.Any()) - return NotFound(); - - var result = new List(); - - foreach (var note in call.CallNotes) - { - var noteResult = new CallNoteResult(); - noteResult.Cnd = note.CallNoteId; - noteResult.Cid = note.CallId; - noteResult.Src = note.Source; - noteResult.Uid = note.UserId.ToString(); - noteResult.Tme = note.Timestamp.TimeConverter(department).FormatForDepartment(department); - noteResult.Tsp = note.Timestamp; - noteResult.Not = note.Note; - noteResult.Lat = note.Latitude; - noteResult.Lng = note.Longitude; - noteResult.Fnm = await UserHelper.GetFullNameForUser(note.UserId); - - result.Add(noteResult); - } - - return Ok(result); - } - - /// - /// Get the files for a call in the Resgrid System - /// - /// CallId to get the files for - /// Include the data in the result - /// Type of file to get (Any = 0, Audio = 1, Images = 2, Files = 3, Videos = 4) - /// - [HttpGet("GetFilesForCall")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetFilesForCall(int callId, bool includeData, int type) - { - var result = new List(); - - var call = await _callsService.GetCallByIdAsync(callId); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - call = await _callsService.PopulateCallData(call, false, true, false, false, false, false, false, false, false); - - var baseUrl = Config.SystemBehaviorConfig.ResgridApiBaseUrl; - - foreach (var attachment in call.Attachments) - { - var file = new CallFileResult(); - file.Id = attachment.CallAttachmentId; - file.Cid = attachment.CallId; - file.Fln = attachment.FileName; - file.Typ = attachment.CallAttachmentType; - file.Url = baseUrl + "/api/v3/Calls/GetFile?departmentId=" + DepartmentId + "&id=" + attachment.CallAttachmentId; - file.Nme = attachment.Name; - file.Sze = attachment.Size.GetValueOrDefault(); - file.Mime = FileHelper.GetContentTypeByExtension(Path.GetExtension(attachment.FileName)); - - if (attachment.Timestamp.HasValue) - file.Tme = attachment.Timestamp.Value.TimeConverterToString(department); - else - file.Tme = DateTime.UtcNow.TimeConverterToString(department); - - if (!String.IsNullOrWhiteSpace(attachment.UserId)) - file.Uid = attachment.UserId; - - if (includeData) - file.Data = Convert.ToBase64String(attachment.Data); - - if (type == 0) - result.Add(file); - else if (type == attachment.CallAttachmentType) - result.Add(file); - } - - return Ok(result); - } - - /// - /// Get a users avatar from the Resgrid system based on their ID - /// - /// ID of the user - /// The department id of the file your requesting - /// - [HttpGet("GetFile")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetFile(int departmentId, int id) - { - var attachment = await _callsService.GetCallAttachmentAsync(id); - - if (attachment == null) - return NotFound(); - - var call = await _callsService.GetCallByIdAsync(attachment.CallId); - if (call.DepartmentId != departmentId) - return Unauthorized(); - - //result.Content = new ByteArrayContent(attachment.Data); - //result.Content.Headers.ContentType = new MediaTypeHeaderValue(FileHelper.GetContentTypeByExtension(Path.GetExtension(attachment.FileName))); - - return File(attachment.Data, FileHelper.GetContentTypeByExtension(Path.GetExtension(attachment.FileName))); - } - - /// - /// Attaches a file to a call - /// - /// ID of the user - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - [HttpPost("UploadFile")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task UploadFile(CallFileInput input, CancellationToken cancellationToken) - { - var result = Ok(); - - var call = await _callsService.GetCallByIdAsync(input.Cid); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - if (call.State != (int)CallStates.Active) - return BadRequest(); - - var callAttachment = new CallAttachment(); - callAttachment.CallId = input.Cid; - callAttachment.CallAttachmentType = input.Typ; - - if (String.IsNullOrWhiteSpace(input.Nme)) - callAttachment.FileName = "cameraPhoneUpload.png"; - else - callAttachment.FileName = input.Nme; - - callAttachment.UserId = input.Uid; - callAttachment.Timestamp = DateTime.UtcNow; - callAttachment.Data = Convert.FromBase64String(input.Data); - - if (!String.IsNullOrWhiteSpace(input.Lat)) - { - callAttachment.Latitude = decimal.Parse(input.Lat); - } - - if (!String.IsNullOrWhiteSpace(input.Lon)) - { - callAttachment.Longitude = decimal.Parse(input.Lon); - } - - var saved = await _callsService.SaveCallAttachmentAsync(callAttachment, cancellationToken); - - return CreatedAtAction(nameof(UploadFile), new { id = saved.CallAttachmentId }, saved); - } - - /// - /// Get notes for a call - /// - /// CallId of the call you want to get notes for - /// The cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// ActionResult. - [HttpPost("AddCallNote")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task AddCallNote(AddCallNoteInput input, CancellationToken cancellationToken) - { - var note = new CallNote(); - note.CallId = input.CallId; - note.Timestamp = DateTime.UtcNow; - note.Note = input.Note; - note.UserId = input.UserId; - note.Source = (int)CallNoteSources.Mobile; - - var saved = await _callsService.SaveCallNoteAsync(note, cancellationToken); - - return CreatedAtAction(nameof(AddCallNote), new { id = saved.CallNoteId }, saved); - } - - - /// - /// Returns the call audio for a specific call (Allow Anonymous) - /// - /// Encrypted query string for the call - /// Http response type matching call audio format with data - [HttpGet("GetCallAudio")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCallAudio(string query) - { - if (String.IsNullOrWhiteSpace(query)) - return NotFound(); - - var decodedQuery = Encoding.UTF8.GetString(Convert.FromBase64String(query)); - - string plainText = SymmetricEncryption.Decrypt(decodedQuery, Config.SystemBehaviorConfig.ExternalAudioUrlParamPasshprase); - - if (String.IsNullOrWhiteSpace(plainText)) - return NotFound(); - - var callAttachment = await _callsService.GetCallAttachmentAsync(int.Parse(plainText)); - - if (callAttachment != null && callAttachment.Data != null) - { - //result.Content = new ByteArrayContent(callAttachment.Data); - ////result.Content.Headers.ContentDisposition.FileName = callAttachment.FileName; - //result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); - //result.Content.Headers.ContentDisposition.FileName = callAttachment.FileName; - //result.Content.Headers.ContentType = new MediaTypeHeaderValue("audio/mpeg"); - //result.Content.Headers.ContentLength = callAttachment.Data.Length; - - return File(new MemoryStream(callAttachment.Data), "audio/mpeg", callAttachment.FileName); - } - - return NotFound(); - } - - /// - /// Get notes for a call - /// - /// CallId of the call you want to get notes for - /// - [HttpGet("GetActiveCallPrioritiesForDepartment")] - public List GetActiveCallPrioritiesForDepartment(int departmentId) - { - var result = new List(); - - - return result; - } - - /// - /// Get all the call types for a department - /// - /// An array of call types - [HttpGet("GetCallTypes")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetCallTypes() - { - var result = new List(); - - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - - if (callTypes != null && callTypes.Any()) - { - foreach (var callType in callTypes) - { - var type = new CallTypeResult(); - type.Id = callType.CallTypeId; - type.Name = callType.Type; - - result.Add(type); - } - } - - return result; - } - - /// - /// Returns all the non-dispatched (pending) scheduled calls for the department - /// - /// Array of CallResult objects for each active call in the department - [HttpGet("GetAllPendingScheduledCalls")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetAllPendingScheduledCalls() - { - var result = new List(); - - var calls = (await _callsService.GetAllNonDispatchedScheduledCallsByDepartmentIdAsync(DepartmentId)).OrderBy(x => x.DispatchOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var c in calls) - { - var call = new CallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Utc = c.LoggedOn; - call.Ste = c.State; - call.Num = c.Number; - - if (c.DispatchOn.HasValue) - call.Don = c.DispatchOn.Value.TimeConverter(department); - - result.Add(call); - } - - return Ok(result); - } - - /// - /// Updates a call's scheduled dispatch time if it has not been dispatched - /// - /// ID of the call - /// UTC date to change the dispatch to - /// - [HttpGet("UpdateScheduledDispatchTime")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task UpdateScheduledDispatchTime(int callId, DateTime date) - { - var call = await _callsService.GetCallByIdAsync(callId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var canDoOperation = await _authorizationService.CanUserCreateCallAsync(UserId, DepartmentId); - - if (!canDoOperation) - return Unauthorized(); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - if (call.HasBeenDispatched.HasValue && call.HasBeenDispatched.Value) - return BadRequest(); - - call.DispatchOn = DateTimeHelpers.ConvertToUtc(date, department.TimeZone); - call.HasBeenDispatched = false; - - var savedCall = await _callsService.SaveCallAsync(call); - - return Ok(); - } - - /// - /// Deletes a call - /// - /// ID of the call - /// - [HttpDelete("DeleteCall")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task DeleteCall(int callId) - { - var call = await _callsService.GetCallByIdAsync(callId); - var canDoOperation = await _authorizationService.CanUserCreateCallAsync(UserId, DepartmentId); - - if (!canDoOperation) - return Unauthorized(); - - if (call == null) - return NotFound(); - - if (call.DepartmentId != DepartmentId) - return Unauthorized(); - - if (call.HasBeenDispatched.HasValue && call.HasBeenDispatched.Value) - return BadRequest(); - - call.IsDeleted = true; - - var savedCall = await _callsService.SaveCallAsync(call); - - return Ok(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/ChatController.cs b/Web/Resgrid.Web.Services/Controllers/v3/ChatController.cs deleted file mode 100644 index baa19e71..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/ChatController.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System; -using System.Collections.Generic; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Chat; -using Resgrid.Model; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Events; -using Resgrid.Framework; -using Resgrid.Model.Providers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to be performed against the chat system - /// - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class ChatController : V3AuthenticatedApiControllerbase - { - #region Members and Constructors - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IUsersService _usersService; - private readonly ICommunicationService _communicationService; - private readonly ICqrsProvider _cqrsProvider; - - public ChatController( - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IDepartmentGroupsService departmentGroupsService, - IUsersService usersService, - ICommunicationService communicationService, - ICqrsProvider cqrsProvider - ) - { - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _departmentGroupsService = departmentGroupsService; - _usersService = usersService; - _communicationService = communicationService; - _cqrsProvider = cqrsProvider; - } - #endregion Members and Constructors - - /// - /// Gets the department and group information needed to seed the initial standard groups for chat - /// - /// - [HttpGet("GetResponderChatInfo")] - [AllowAnonymous] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetResponderChatInfo() - { - var result = new ResponderChatResult(); - result.UserId = UserId; - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - var departmentGroup = new ResponderChatGroupInfo(); - departmentGroup.Id = $"{Config.ChatConfig.DepartmentChatPrefix}{department.Code}"; - departmentGroup.Name = department.Name; - departmentGroup.Type = 1; - result.Groups.Add(departmentGroup); - - if (department.IsUserAnAdmin(UserId)) - { - foreach (var group in groups) - { - var newGroup = new ResponderChatGroupInfo() { Id = $"{Config.ChatConfig.DepartmentGroupChatPrefix}{department.Code}_{group.DepartmentGroupId}", Name = group.Name, Count = group.Members.Count }; - - if (group.Type.HasValue) - { - newGroup.Type = 3; - } - else if (group.Type.GetValueOrDefault() == (int)DepartmentGroupTypes.Station) - { - newGroup.Type = 2; - } - else if (group.Type.GetValueOrDefault() == (int)DepartmentGroupTypes.Orginizational) - { - newGroup.Type = 3; - } - - result.Groups.Add(newGroup); - } - } - else - { - var group = await _departmentGroupsService.GetGroupForUserAsync(UserId, DepartmentId); - if (group != null) - { - var newGroup = new ResponderChatGroupInfo() { Id = $"{Config.ChatConfig.DepartmentGroupChatPrefix}{department.Code}_{group.DepartmentGroupId}", Name = group.Name, Count = group.Members.Count }; - - if (group.Type.HasValue) - { - newGroup.Type = 3; - } - else if (group.Type.GetValueOrDefault() == (int)DepartmentGroupTypes.Station) - { - newGroup.Type = 2; - } - else if (group.Type.GetValueOrDefault() == (int)DepartmentGroupTypes.Orginizational) - { - newGroup.Type = 3; - } - - result.Groups.Add(newGroup); - } - } - - return Ok(result); - } - - /// - /// Gets personnel information for the department to utilize within a chat system - /// - /// - [HttpGet("GetPersonnelForChat")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetPersonnelForChat() - { - var result = new List(); - var personnel = await _usersService.GetUserGroupAndRolesByDepartmentIdInLimitAsync(DepartmentId, false, false, false); - - foreach (var person in personnel) - { - if (person.UserId != UserId) - { - var presult = new PersonnelChatResult(); - presult.UserId = person.UserId; - presult.Name = person.Name; - presult.Group = person.DepartmentGroupName; - presult.Roles = person.RoleNames; - - - result.Add(presult); - } - } - - return Ok(result); - } - - /// - /// Send a Push Notification out to the personnel involved in a chat - /// - /// - /// - [HttpPost("NotifyNewChat")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task NotifyNewChat([FromBody] NotifyChatInput notifyChatInput) - { - if (notifyChatInput != null && notifyChatInput.RecipientUserIds != null && notifyChatInput.RecipientUserIds.Count > 0) - { - var newChatEvent = new NewChatNotificationEvent(); - newChatEvent.Id = notifyChatInput.Id; - newChatEvent.GroupName = notifyChatInput.GroupName; - newChatEvent.Message = notifyChatInput.Message; - newChatEvent.RecipientUserIds = notifyChatInput.RecipientUserIds; - newChatEvent.SendingUserId = notifyChatInput.SendingUserId; - newChatEvent.Type = notifyChatInput.Type; - newChatEvent.DepartmentId = DepartmentId; - - CqrsEvent registerUnitPushEvent = new CqrsEvent(); - registerUnitPushEvent.Type = (int)CqrsEventTypes.NewChatMessage; - registerUnitPushEvent.Timestamp = DateTime.UtcNow; - registerUnitPushEvent.Data = ObjectSerialization.Serialize(newChatEvent); - - await _cqrsProvider.EnqueueCqrsEventAsync(registerUnitPushEvent); - } - - return Ok(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CommandAppController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CommandAppController.cs deleted file mode 100644 index efa0cad7..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CommandAppController.cs +++ /dev/null @@ -1,346 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Resgrid.Model; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Calls; -using Resgrid.Web.Services.Controllers.Version3.Models.CoreData; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Roles; -using Resgrid.Web.Services.Controllers.Version3.Models.Security; -using Resgrid.Web.Services.Controllers.Version3.Models.UnitApp; -using UnitInfoResult = Resgrid.Web.Services.Controllers.Version3.Models.Units.UnitInfoResult; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Helpers; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CommandAppController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUnitsService _unitsService; - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly IIncidentService _incidentService; - - public CommandAppController( - IUsersService usersService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUnitsService unitsService, - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IGeoLocationProvider geoLocationProvider, - IIncidentService incidentService - ) - { - _usersService = usersService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _unitsService = unitsService; - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _geoLocationProvider = geoLocationProvider; - _incidentService = incidentService; - } - - /// - /// Gets the command application core data. - /// - /// ActionResult<UnitAppPayloadResult>. - [HttpGet("GetCommandAppCoreData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetCommandAppCoreData() - { - var results = new UnitAppPayloadResult(); - results.Personnel = new List(); - results.Groups = new List(); - results.Units = new List(); - results.Roles = new List(); - results.Statuses = new List(); - results.Calls = new List(); - results.UnitStatuses = new List(); - results.UnitRoles = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var rolesForUsersInDepartment = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var allRoles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - var allProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId); - var allGroups =await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitTypes = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId); - - - foreach (var user in users) - { - //var profile = _userProfileService.GetProfileByUserId(user.UserId); - //var group = _departmentGroupsService.GetGroupForUser(user.UserId); - - UserProfile profile = null; - if (allProfiles.ContainsKey(user.UserId)) - profile = allProfiles[user.UserId]; - - DepartmentGroup group = null; - if (groups.ContainsKey(user.UserId)) - group = groups[user.UserId]; - - //var roles = _personnelRolesService.GetRolesForUser(user.UserId); - - List roles = null; - if (rolesForUsersInDepartment.ContainsKey(user.UserId)) - roles = rolesForUsersInDepartment[user.UserId]; - - var result = new PersonnelInfoResult(); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - - result.Eml = user.Email; - result.Did = DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - if (role != null) - result.Roles.Add(role.Name); - } - } - - results.Personnel.Add(result); - } - - - results.Rights = new DepartmentRightsResult(); - var currentUser = await _usersService.GetUserByNameAsync(UserName); - - if (currentUser == null) - return Unauthorized(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - results.Rights.Adm = department.IsUserAnAdmin(currentUser.UserId); - results.Rights.Grps = new List(); - - var currentGroup = await _departmentGroupsService.GetGroupForUserAsync(currentUser.UserId, DepartmentId); - - if (currentGroup != null) - { - var groupRight = new GroupRight(); - groupRight.Gid = currentGroup.DepartmentGroupId; - groupRight.Adm = currentGroup.IsUserGroupAdmin(currentUser.UserId); - - results.Rights.Grps.Add(groupRight); - } - - foreach (var group in allGroups) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Groups.Add(groupInfo); - } - - foreach (var unit in units) - { - var unitResult = new UnitInfoResult(); - unitResult.Uid = unit.UnitId; - unitResult.Did = DepartmentId; - unitResult.Nme = unit.Name; - unitResult.Typ = unit.Type; - - if (!string.IsNullOrWhiteSpace(unit.Type)) - { - var unitType = unitTypes.FirstOrDefault(x => x.Type == unit.Type); - - if (unitType != null) - unitResult.Cid = unitType.CustomStatesId.GetValueOrDefault(); - } - else - { - unitResult.Cid = 0; - } - - if (unit.StationGroup != null) - { - unitResult.Sid = unit.StationGroup.DepartmentGroupId; - unitResult.Snm = unit.StationGroup.Name; - } - - results.Units.Add(unitResult); - - // Add unit roles for this unit - var roles = await _unitsService.GetRolesForUnitAsync(unit.UnitId); - foreach (var role in roles) - { - var roleResult = new UnitRoleResult(); - roleResult.Name = role.Name; - roleResult.UnitId = role.UnitId; - roleResult.UnitRoleId = role.UnitRoleId; - - results.UnitRoles.Add(roleResult); - } - } - - var unitStatuses = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - - foreach (var us in unitStatuses) - { - var unitStatus = new UnitStatusCoreResult(); - unitStatus.UnitId = us.UnitId; - unitStatus.StateType = (UnitStateTypes)us.State; - unitStatus.StateTypeId = us.State; - unitStatus.Type = us.Unit.Type; - unitStatus.Timestamp = us.Timestamp.TimeConverter(department); - unitStatus.Name = us.Unit.Name; - - if (us.DestinationId.HasValue) - unitStatus.DestinationId = us.DestinationId.Value; - - results.UnitStatuses.Add(unitStatus); - } - - foreach (var role in allRoles) - { - var roleResult = new RoleInfoResult(); - roleResult.Rid = role.PersonnelRoleId; - roleResult.Nme = role.Name; - - results.Roles.Add(roleResult); - } - - var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(DepartmentId); - - foreach (var customState in customStates) - { - if (customState.IsDeleted) - continue; - - foreach (var stateDetail in customState.GetActiveDetails()) - { - if (stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customState.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - results.Statuses.Add(customStateResult); - } - - } - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId)).OrderByDescending(x => x.LoggedOn); - - if (calls != null && calls.Any()) - { - foreach (var c in calls) - { - var call = new CallResultEx(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = c.Name; - call.Noc = c.NatureOfCall; - call.Map = c.MapPage; - call.Not = c.Notes; - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Add = c.Address; - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Ste = c.State; - call.Num = c.Number; - - results.Calls.Add(call); - } - } - else - { - // This is a hack due to a bug in the current units app! -SJ 1-31-2016 - var call = new CallResultEx(); - call.Cid = 0; - call.Pri = 0; - call.Ctl = false; - call.Nme = "No Call"; - call.Noc = ""; - call.Map = ""; - call.Not = ""; - call.Add = ""; - call.Geo = ""; - call.Lon = DateTime.UtcNow; - call.Ste = 0; - call.Num = ""; - - results.Calls.Add(call); - } - - - return Ok(results); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CommandsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CommandsController.cs deleted file mode 100644 index f9fa28f9..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CommandsController.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System.Collections.Generic; -using Resgrid.Model.Services; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Controllers.Version3.Models.Commands; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against the security sub-system - /// - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CommandsController : V3AuthenticatedApiControllerbase - { - private readonly ICommandsService _commandsService; - - /// - /// Operations to perform against the security sub-system - /// - public CommandsController(ICommandsService commandsService) - { - _commandsService = commandsService; - } - - /// - /// Gets all the command definitions for the department - /// - /// AllCommandsResult object with a list of CommandResult's for each command - [HttpGet("GetAllCommands")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetAllCommands() - { - var result = new AllCommandsResult(); - result.Commmands = new List(); - - var commands = await _commandsService.GetAllCommandsForDepartmentAsync(DepartmentId); - - if (commands != null && commands.Count > 0) - { - foreach (var command in commands) - { - var cmd = new CommandResult(); - cmd.Id = command.CommandDefinitionId; - cmd.CallTypeId = command.CallTypeId; - cmd.Timer = command.Timer; - cmd.TimerMinutes = command.TimerMinutes; - cmd.Name = command.Name; - cmd.Description = command.Description; - cmd.Assignments = new List(); - - if (command.Assignments != null && command.Assignments.Count > 0) - { - foreach (var assignment in command.Assignments) - { - var ass = new CommandAssignmentResult(); - ass.RoleId = assignment.CommandDefinitionRoleId; - ass.CommandId = assignment.CommandDefinitionId; - ass.Name = assignment.Name; - ass.Description = assignment.Description; - ass.MinUnitPersonnel = assignment.MinUnitPersonnel; - ass.MaxUnitPersonnel = assignment.MaxUnitPersonnel; - ass.MaxUnits = assignment.MaxUnits; - ass.MinTimeInRole = assignment.MinTimeInRole; - ass.MaxTimeInRole = assignment.MaxTimeInRole; - ass.ForceRequirements = assignment.ForceRequirements; - ass.RequiredUnitTypes = new List(); - ass.RequiredCerts = new List(); - ass.RequiredRoles = new List(); - - if (assignment.RequiredUnitTypes != null && assignment.RequiredUnitTypes.Count > 0) - { - foreach (var unitType in assignment.RequiredUnitTypes) - { - var ut = new AssignmentUnitTypeResult(); - ut.Id = unitType.CommandDefinitionRoleUnitTypeId; - ut.RoleId = unitType.CommandDefinitionRoleId; - ut.UnitTypeId = unitType.UnitTypeId; - - ass.RequiredUnitTypes.Add(ut); - } - } - - if (assignment.RequiredCerts != null && assignment.RequiredCerts.Count > 0) - { - foreach (var cert in assignment.RequiredCerts) - { - var rc = new AssignmentCertResult(); - rc.Id = cert.CommandDefinitionRoleCertId; - rc.RoleId = cert.CommandDefinitionRoleId; - rc.CertificationTypeId = cert.DepartmentCertificationTypeId; - - ass.RequiredCerts.Add(rc); - } - } - - if (assignment.RequiredRoles != null && assignment.RequiredRoles.Count > 0) - { - foreach (var role in assignment.RequiredRoles) - { - var rr = new AssignmentPersonnelResult(); - rr.Id = role.CommandDefinitionRolePersonnelRoleId; - rr.RoleId = role.CommandDefinitionRoleId; - rr.PersonnelRoleId = role.PersonnelRoleId; - - ass.RequiredRoles.Add(rr); - } - } - - cmd.Assignments.Add(ass); - } - } - - result.Commmands.Add(cmd); - } - } - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/ConnectController.cs b/Web/Resgrid.Web.Services/Controllers/v3/ConnectController.cs deleted file mode 100644 index 4aaffb25..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/ConnectController.cs +++ /dev/null @@ -1,253 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Net; -//using System.Net.Http; -//using GeoCoordinatePortable; -//using Microsoft.AspNetCore.Mvc; -//using Resgrid.Model; -//using Resgrid.Model.Services; -//using Resgrid.Web.Services.Controllers.Version3.Models.Connect; -//using DepartmentProfile = Resgrid.Web.Services.Controllers.Version3.Models.Connect.DepartmentProfile; - -//namespace Resgrid.Web.Services.Controllers.Version3 -//{ -// /// -// /// Operations to perform against the connect sub-system. Connect allows the public to communicate with a department. -// /// -// public class ConnectController : ControllerBase -// { -// private readonly IDepartmentsService _departmentsService; -// private readonly IDepartmentProfileService _departmentProfileService; - -// /// -// /// Operations to perform against the connect sub-system -// /// -// public ConnectController(IDepartmentsService departmentsService, IDepartmentProfileService departmentProfileService) -// { -// _departmentsService = departmentsService; -// _departmentProfileService = departmentProfileService; -// } - -// [HttpGet] -// public List ListDepartments(string latitude = null, string longitude = null) -// { -// var departments = new List(); -// var profiles = _departmentProfileService.GetAllActive(); - -// if (profiles != null && profiles.Any()) -// { -// GeoCoordinate source; -// if (!String.IsNullOrWhiteSpace(latitude) && !String.IsNullOrWhiteSpace(longitude)) -// source = new GeoCoordinate(double.Parse(latitude), double.Parse(longitude)); -// else -// source = new GeoCoordinate(0, 0); - -// foreach (var profile in profiles.OrderBy(x => x.Coordinate.GetDistanceTo(source))) -// { -// var department = new DepartmentProfile(); -// department.ProfileId = profile.DepartmentProfileId; -// department.Did = profile.DepartmentId; -// department.Name = profile.Name; -// department.ShortName = profile.ShortName; -// department.Description = profile.Description; -// department.InCaseOfEmergency = profile.InCaseOfEmergency; -// department.ServiceArea = profile.ServiceArea; -// department.ServicesProvided = profile.ServicesProvided; -// department.Founded = profile.Founded; -// //department.Logo = profile.Logo; -// department.Keywords = profile.Keywords; -// department.InviteOnly = profile.InviteOnly; -// department.AllowMessages = profile.AllowMessages; -// department.VolunteerPositionsAvailable = profile.VolunteerPositionsAvailable; -// department.ShareStats = profile.ShareStats; -// department.VolunteerKeywords = profile.VolunteerKeywords; -// department.VolunteerDescription = profile.VolunteerDescription; -// department.VolunteerContactName = profile.VolunteerContactName; -// department.VolunteerContactInfo = profile.VolunteerContactInfo; -// department.Geofence = profile.Geofence; -// department.Address = profile.Address; -// department.Latitude = profile.Latitude; -// department.Longitude = profile.Longitude; -// department.What3Words = profile.What3Words; -// department.Facebook = profile.Facebook; -// department.Twitter = profile.Twitter; -// department.GooglePlus = profile.GooglePlus; -// department.LinkedIn = profile.LinkedIn; -// department.Instagram = profile.Instagram; -// department.YouTube = profile.YouTube; -// department.Website = profile.Website; -// department.PhoneNumber = profile.PhoneNumber; - -// departments.Add(department); -// } -// } - -// return departments; -// } - -// [HttpGet] -// public DepartmentProfile GetDepartment(string profileId, string userId) -// { -// int id; -// Guid uid; - -// if (!int.TryParse(profileId, out id)) -// return null; - -// var department = new DepartmentProfile(); -// var profile = _departmentProfileService.GetProfileById(id); - -// if (profile != null) -// { -// department.ProfileId = profile.DepartmentProfileId; -// department.Did = profile.DepartmentId; -// department.Name = profile.Name; -// department.ShortName = profile.ShortName; -// department.Description = profile.Description; -// department.InCaseOfEmergency = profile.InCaseOfEmergency; -// department.ServiceArea = profile.ServiceArea; -// department.ServicesProvided = profile.ServicesProvided; -// department.Founded = profile.Founded; -// //department.Logo = profile.Logo; -// department.Keywords = profile.Keywords; -// department.InviteOnly = profile.InviteOnly; -// department.AllowMessages = profile.AllowMessages; -// department.VolunteerPositionsAvailable = profile.VolunteerPositionsAvailable; -// department.ShareStats = profile.ShareStats; -// department.VolunteerKeywords = profile.VolunteerKeywords; -// department.VolunteerDescription = profile.VolunteerDescription; -// department.VolunteerContactName = profile.VolunteerContactName; -// department.VolunteerContactInfo = profile.VolunteerContactInfo; -// department.Geofence = profile.Geofence; -// department.Address = profile.Address; -// department.Latitude = profile.Latitude; -// department.Longitude = profile.Longitude; -// department.What3Words = profile.What3Words; -// department.Facebook = profile.Facebook; -// department.Twitter = profile.Twitter; -// department.GooglePlus = profile.GooglePlus; -// department.LinkedIn = profile.LinkedIn; -// department.Instagram = profile.Instagram; -// department.YouTube = profile.YouTube; -// department.Website = profile.Website; -// department.PhoneNumber = profile.PhoneNumber; - -// var userFollows = _departmentProfileService.GetFollowsForUser(userId); - -// if (userFollows != null && userFollows.Any(x => x.DepartmentProfileId == id)) -// department.Following = true; -// } - -// return department; -// } - -// [HttpPost] -// public RegisterResult Register(RegisterInput input) -// { -// var result = new RegisterResult(); -// var user = _departmentProfileService.GetUserByIdentity(input.Id); - -// if (user != null) -// { -// result.Success = false; -// result.Message = "User was already created"; -// result.UserId = user.DepartmentProfileUserId; -// } -// else -// { -// var profileUser = new DepartmentProfileUser(); -// profileUser.Identity = input.Id; -// profileUser.Name = input.Name; -// profileUser.Email = input.Email; - -// _departmentProfileService.SaveUser(profileUser); - -// result.Success = true; -// result.UserId = profileUser.DepartmentProfileUserId; -// } - -// return result; -// } - -// [HttpGet] -// public List GetFollows(string userId) -// { -// var list = new List(); -// var follows = _departmentProfileService.GetFollowsForUser(userId); - -// foreach (var follow in follows) -// { -// var result = new DepartmentListResult(); -// result.Id = follow.DepartmentProfileId; -// result.Name = follow.DepartmentProfile.Name; - -// list.Add(result); -// } - -// return list; -// } - -// public List GetFeed(string userId) -// { -// var result = new List(); -// var articles = _departmentProfileService.GetArticlesForUser(userId); - -// foreach (var article in articles) -// { -// var articleResult = new ArticleResult(); -// articleResult.Id = article.DepartmentProfileArticleId; -// articleResult.Title = article.Title; -// articleResult.Body = article.Body; -// articleResult.SmallImage = article.SmallImage; -// articleResult.LargeImage = article.LargeImage; -// articleResult.Keywords = article.Keywords; -// articleResult.CreatedOn = article.CreatedOn; -// articleResult.CreatedByUserId = article.CreatedByUserId; -// articleResult.StartOn = article.StartOn; -// articleResult.ExpiresOn = article.ExpiresOn; - -// result.Add(articleResult); -// } - -// return result; -// } - -// public FollowResult Follow(FollowInput input) -// { -// var result = new FollowResult(); -// var follow = _departmentProfileService.FollowDepartment(input.UserId, input.Id, input.Code); - -// if (follow != null) -// result.Successful = true; -// else -// { -// result.Successful = false; -// result.Message = "Could not follow department. It's either Disabled, Missing or you supplied the incorrect code."; -// } - -// return result; -// } - -// public FollowResult UnFollow(FollowInput input) -// { -// var result = new FollowResult(); -// _departmentProfileService.UnFollowDepartment(input.UserId, input.Id); - -// result.Successful = true; - -// return result; -// } - -// public ActionResult Options() -// { -// var response = new HttpResponseMessage(); -// response.StatusCode = HttpStatusCode.OK; -// response.Headers.Add("Access-Control-Allow-Origin", "*"); -// response.Headers.Add("Access-Control-Request-Headers", "*"); -// response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); - -// return response; -// } -// } -//} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/CoreDataController.cs b/Web/Resgrid.Web.Services/Controllers/v3/CoreDataController.cs deleted file mode 100644 index 259b79ba..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/CoreDataController.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Resgrid.Model; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.CoreData; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Roles; -using Resgrid.Web.Services.Controllers.Version3.Models.Security; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; -using CoreDataResult = Resgrid.Web.Services.Controllers.Version3.Models.CoreDataResult; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - [Produces("application/json")] - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class CoreDataController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUnitsService _unitsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IPermissionsService _permissionsService; - private readonly ICallsService _callsService; - private readonly IFirebaseService _firebaseService; - private readonly IDepartmentSettingsService _departmentSettingsService; - - public CoreDataController( - IUsersService usersService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUnitsService unitsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IPermissionsService permissionsService, - ICallsService callsService, - IFirebaseService firebaseService, - IDepartmentSettingsService departmentSettingsService - ) - { - _usersService = usersService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _unitsService = unitsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _permissionsService = permissionsService; - _callsService = callsService; - _firebaseService = firebaseService; - _departmentSettingsService = departmentSettingsService; - } - - /// - /// Gets the core data. - /// - /// CoreDataResult. - [HttpGet("GetCoreData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetCoreData() - { - var results = new CoreDataResult(); - results.Personnel = new List(); - results.Groups = new List(); - results.Units = new List(); - results.Roles = new List(); - results.Statuses = new List(); - results.Priorities = new List(); - results.Departments = new List(); - results.PersonnelListStatusOrders = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var rolesForUsersInDepartment = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var allRoles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - var allProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId); - var allGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitTypes = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId); - var callPriorites = await _callsService.GetCallPrioritiesForDepartmentAsync(DepartmentId); - var personnelListStatusOrderings = await _departmentSettingsService.GetDepartmentPersonnelListStatusSortOrderAsync(DepartmentId); - var personnelListSortOrder = await _departmentSettingsService.GetDepartmentPersonnelSortOrderAsync(DepartmentId); - - - if (personnelListStatusOrderings != null) - results.PersonnelListStatusOrders = personnelListStatusOrderings; - - results.PersonnelNameSorting = (int)personnelListSortOrder; - - foreach (var user in users) - { - UserProfile profile = null; - if (allProfiles.ContainsKey(user.UserId)) - profile = allProfiles[user.UserId]; - - DepartmentGroup group = null; - if (groups.ContainsKey(user.UserId)) - group = groups[user.UserId]; - - List roles = null; - if (rolesForUsersInDepartment.ContainsKey(user.UserId)) - roles = rolesForUsersInDepartment[user.UserId]; - - var result = new PersonnelInfoResult(); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - - - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - - if (user != null) - result.Eml = user.Email; - - result.Did = DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - if (role != null) - result.Roles.Add(role.Name); - } - } - - results.Personnel.Add(result); - } - - - results.Rights = new DepartmentRightsResult(); - var currentUser = await _usersService.GetUserByNameAsync(UserName); - - if (currentUser == null) - return Unauthorized(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - results.Rights.Adm = department.IsUserAnAdmin(currentUser.UserId); - results.Rights.Grps = new List(); - - var currentGroup = await _departmentGroupsService.GetGroupForUserAsync(currentUser.UserId, DepartmentId); - - if (currentGroup != null) - { - var groupRight = new GroupRight(); - groupRight.Gid = currentGroup.DepartmentGroupId; - groupRight.Adm = currentGroup.IsUserGroupAdmin(currentUser.UserId); - - results.Rights.Grps.Add(groupRight); - } - - foreach (var group in allGroups) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Groups.Add(groupInfo); - } - - foreach (var unit in units) - { - var unitResult = new UnitInfoResult(); - unitResult.Uid = unit.UnitId; - unitResult.Did = DepartmentId; - unitResult.Nme = unit.Name; - unitResult.Typ = unit.Type; - - if (!string.IsNullOrWhiteSpace(unit.Type)) - { - var unitType = unitTypes.FirstOrDefault(x => x.Type == unit.Type); - - if (unitType != null) - unitResult.Cid = unitType.CustomStatesId.GetValueOrDefault(); - } - else - { - unitResult.Cid = 0; - } - - if (unit.StationGroup != null) - { - unitResult.Sid = unit.StationGroup.DepartmentGroupId; - unitResult.Snm = unit.StationGroup.Name; - } - - results.Units.Add(unitResult); - } - - foreach (var role in allRoles) - { - var roleResult = new RoleInfoResult(); - roleResult.Rid = role.PersonnelRoleId; - roleResult.Nme = role.Name; - - results.Roles.Add(roleResult); - } - - var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(DepartmentId); - - foreach (var customState in customStates) - { - if (customState != null) - { - if (customState.IsDeleted || customState.Details == null) - continue; - - foreach (var stateDetail in customState.Details) - { - if (stateDetail == null || stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customState.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - if (customState.IsDeleted) - customStateResult.IsDeleted = true; - else - customStateResult.IsDeleted = stateDetail.IsDeleted; - - results.Statuses.Add(customStateResult); - } - } - } - - foreach (var priority in callPriorites) - { - var priorityResult = new CallPriorityResult(); - priorityResult.Id = priority.DepartmentCallPriorityId; - priorityResult.DepartmentId = priority.DepartmentId; - priorityResult.Name = priority.Name; - priorityResult.Color = priority.Color; - priorityResult.Sort = priority.Sort; - priorityResult.IsDeleted = priority.IsDeleted; - priorityResult.IsDefault = priority.IsDefault; - - results.Priorities.Add(priorityResult); - } - - var members = await _departmentsService.GetAllDepartmentsForUserAsync(UserId); - foreach (var member in members) - { - if (member.IsDeleted) - continue; - - if (member.IsDisabled.GetValueOrDefault()) - continue; - - var depRest = new JoinedDepartmentResult(); - depRest.Did = member.DepartmentId; - depRest.Nme = member.Department.Name; - - results.Departments.Add(depRest); - } - - return Ok(results); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DepartmentController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DepartmentController.cs deleted file mode 100644 index a4a6bb51..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/DepartmentController.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Departments; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// General department level options - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class DepartmentController : V3AuthenticatedApiControllerbase - { - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IDepartmentSettingsService _departmentSettingsService; - private readonly IDepartmentsService _departmentsService; - - public DepartmentController( - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IDepartmentSettingsService departmentSettingsService, - IDepartmentsService departmentsService - ) - { - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _departmentSettingsService = departmentSettingsService; - _departmentsService = departmentsService; - } - - /// - /// Returns all the available responding options (Calls/Stations) for the department - /// - /// Array of RespondingOptionResult objects for each responding option in the department - [HttpGet("GetRespondingOptions")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetRespondingOptions() - { - var result = new List(); - - var stations = await _departmentGroupsService.GetAllStationGroupsForDepartmentAsync(DepartmentId); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - - /* Removed the Parallel.ForEach statement here as this data needs to be sorted - * and there isn't enough sort data (at least for calls) for the client to do it. - * Also during JMeter testing the perf gains wernt there (10ms average for both). - */ - - foreach (var s in stations.OrderBy(x => x.Name)) - { - var respondingTo = new RespondingOptionResult(); - respondingTo.Id = s.DepartmentGroupId; - respondingTo.Typ = 1; - respondingTo.Nme = ""; - - result.Add(respondingTo); - } - - foreach (var c in calls.OrderByDescending(x => x.LoggedOn)) - { - var respondingTo = new RespondingOptionResult(); - respondingTo.Id = c.CallId; - respondingTo.Typ = 2; - respondingTo.Nme = c.Name; - - result.Add(respondingTo); - } - - return result; - } - - /// - /// Returns basic high level department information for the request department - /// - /// - /// Array of DepartmentResult objects with the department data populated - [HttpGet("Get")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> Get(int departmentId) - { - List result = new List(); - - if (departmentId == 0 && IsSystem) - { - // Get All - var departments = await _departmentsService.GetAllAsync(); - - foreach (var department in departments) - { - result.Add(await DepartmentToResult(department)); - } - - return Ok(result); - } - else if (departmentId >= 1) - { - if (departmentId == DepartmentId) - { - var department = await _departmentsService.GetDepartmentByIdAsync(departmentId); - result.Add(await DepartmentToResult(department)); - - return Ok(result); - } - else - { - return Unauthorized(); - } - } - else - { - return BadRequest(); - } - } - - - /// - /// Returns basic high level department information for the request department - /// - /// - /// Array of DepartmentResult objects with the department data populated - [HttpGet("GetDepartmentOptions")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetDepartmentOptions(int departmentId) - { - List result = new List(); - - if (departmentId == 0 && IsSystem) - { - // Get All - var departments = await _departmentsService.GetAllAsync(); - - foreach (var department in departments) - { - var emailSettings = await _departmentsService.GetDepartmentEmailSettingsAsync(department.DepartmentId); - - var optionsResult = new DepartmentOptionResult(); - optionsResult.DepartmentId = department.DepartmentId; - optionsResult.EmailFormatType = emailSettings.FormatType; - result.Add(optionsResult); - } - - return result; - } - else if (departmentId >= 1) - { - if (departmentId == DepartmentId) - { - var emailSettings = await _departmentsService.GetDepartmentEmailSettingsAsync(departmentId); - - var optionsResult = new DepartmentOptionResult(); - optionsResult.DepartmentId = departmentId; - optionsResult.EmailFormatType = emailSettings.FormatType; - result.Add(optionsResult); - - return result; - } - else - { - return Unauthorized(); - } - } - else - { - return BadRequest(); - } - } - - - private async Task DepartmentToResult(Department department) - { - var departmentResult = new DepartmentResult(); - departmentResult.Id = department.DepartmentId; - departmentResult.Name = department.Name; - departmentResult.ManagingUserId = department.ManagingUserId; - departmentResult.AddressId = department.AddressId; - departmentResult.DepartmentType = department.DepartmentType; - departmentResult.TimeZone = department.TimeZone; - departmentResult.CreatedOn = department.CreatedOn; - departmentResult.UpdatedOn = department.UpdatedOn; - departmentResult.Use24HourTime = department.Use24HourTime; - departmentResult.AdminUsers = department.AdminUsers; - - if (department.Members != null && department.Members.Any()) - departmentResult.Members = department.Members.Select(x => x.UserId).ToList(); - else - departmentResult.Members = new List(); - - departmentResult.EmailCode = await _departmentSettingsService.GetDispatchEmailForDepartmentAsync(department.DepartmentId); - - return departmentResult; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DepartmentStatusController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DepartmentStatusController.cs deleted file mode 100644 index 283a58ff..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/DepartmentStatusController.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3; -using Resgrid.Web.Services.Controllers.Version3.Models.Departments; - -namespace Resgrid.Web.Services.Controllers.v3 -{ - /// - /// General department level options - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class DepartmentStatusController : V3AuthenticatedApiControllerbase - { - private readonly IDepartmentSettingsService _departmentSettingsService; - private readonly IDepartmentsService _departmentsService; - - public DepartmentStatusController(IDepartmentSettingsService departmentSettingsService, IDepartmentsService departmentsService) - { - _departmentSettingsService = departmentSettingsService; - _departmentsService = departmentsService; - } - - /// - /// Gets the department status. - /// - /// DepartmentStatusResult. - [HttpGet("GetDepartmentStatus")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetDepartmentStatus() - { - var result = new DepartmentStatusResult(); - - result.Lup = await _departmentSettingsService.GetDepartmentUpdateTimestampAsync(DepartmentId); - result.Users = (await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId)).Select(x => x.UserId.ToString()).ToList(); - - return result; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs deleted file mode 100644 index 66d6eb6a..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using System.Web; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Events; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Devices; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against devices for personnel - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class DevicesController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly IAuthorizationService _authorizationService; - private readonly IPushService _pushService; - private readonly ICqrsProvider _cqrsProvider; - - /// - /// Default Constructor - /// - /// - /// - /// - /// - /// - public DevicesController( - IUsersService usersService, - IDepartmentsService departmentsService, - IAuthorizationService authorizationService, - IPushService pushService, - ICqrsProvider cqrsProvider - ) - { - _usersService = usersService; - _departmentsService = departmentsService; - _authorizationService = authorizationService; - _pushService = pushService; - _cqrsProvider = cqrsProvider; - } - - /// - /// Register a device to receive push notification from the Resgrid system - /// - /// Input to create the registration for - /// Result for the registration - [HttpPost("RegisterDevice")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task> RegisterDevice([FromBody] DeviceRegistrationInput registrationInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - var result = new DeviceRegistrationResult(); - - try - { - if (registrationInput == null) - return BadRequest(); - - var push = new PushUri(); - push.UserId = UserId; - push.PlatformType = registrationInput.Plt; - - if (!String.IsNullOrWhiteSpace(registrationInput.Uri)) - push.PushLocation = HttpUtility.UrlDecode(registrationInput.Uri); - else if (registrationInput.Plt == (int)Platforms.Android) - push.PushLocation = "Android"; - else if (registrationInput.Plt == 1 || registrationInput.Plt == 2)//(int)Platforms.iPhone || registrationInput.Plt == (int)Platforms.iPad) - push.PushLocation = "Apple"; - - push.DeviceId = registrationInput.Did; - push.Uuid = registrationInput.Id; - push.DepartmentId = DepartmentId; - - CqrsEvent registerUnitPushEvent = new CqrsEvent(); - registerUnitPushEvent.Type = (int)CqrsEventTypes.PushRegistration; - registerUnitPushEvent.Data = ObjectSerialization.Serialize(push); - - await _cqrsProvider.EnqueueCqrsEventAsync(registerUnitPushEvent); - - result.Sfl = true; - result.Id = push.PushUriId; - - return result; - } - catch (Exception ex) - { - result.Sfl = false; - Framework.Logging.LogException(ex); - - return result; - } - } - - return BadRequest(); - } - - /// - /// Removed a Push Notification support by PushUriId. - /// - /// Input to de-register the device for - /// - [HttpDelete("UnRegisterDevice")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task UnRegisterDevice([FromQuery] DeviceUnRegistrationInput input) - { - if (input == null) - return BadRequest(); - - if (this.ModelState.IsValid) - { - try - { - if (!String.IsNullOrWhiteSpace(input.Did)) - { - var deviceId = HttpUtility.UrlDecode(input.Did); - await _pushService.UnRegister(new PushUri() {UserId = UserId, DeviceId = deviceId, PushUriId = input.Pid}); - } - - return Ok(); - } - catch (Exception ex) - { - Framework.Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - - /// - /// Register a unit device to receive push notification from the Resgrid system - /// - /// Input to create the registration for - /// Result for the registration - [HttpPost("RegisterUnitDevice")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task> RegisterUnitDevice([FromBody] DeviceRegistrationInput registrationInput) - { - if (this.ModelState.IsValid) - { - var result = new DeviceRegistrationResult(); - - try - { - if (registrationInput == null) - return BadRequest(); - - var push = new PushUri(); - push.UserId = UserId; - push.PlatformType = registrationInput.Plt; - push.PushLocation = registrationInput.Id; - push.DepartmentId = DepartmentId; - - if (!String.IsNullOrWhiteSpace(registrationInput.Uri)) - push.PushLocation = HttpUtility.UrlDecode(registrationInput.Uri); - - push.DeviceId = registrationInput.Did; - - if (registrationInput.Uid != 0) - push.UnitId = registrationInput.Uid; - - PushRegisterionEvent pushRegisterionEvent = new PushRegisterionEvent(); - pushRegisterionEvent.PushUriId = push.PushUriId; - pushRegisterionEvent.UserId = UserId; - pushRegisterionEvent.PlatformType = registrationInput.Plt; - pushRegisterionEvent.PushLocation = registrationInput.Id; - pushRegisterionEvent.DepartmentId = DepartmentId; - pushRegisterionEvent.DeviceId = registrationInput.Did; - pushRegisterionEvent.Uuid = registrationInput.Id; - - if (registrationInput.Uid != 0) - pushRegisterionEvent.UnitId = registrationInput.Uid; - - CqrsEvent registerUnitPushEvent = new CqrsEvent(); - registerUnitPushEvent.Type = (int)CqrsEventTypes.UnitPushRegistration; - registerUnitPushEvent.Data = ObjectSerialization.Serialize(pushRegisterionEvent); - - await _cqrsProvider.EnqueueCqrsEventAsync(registerUnitPushEvent); - - //await _pushService.RegisterUnit(push); - - result.Sfl = true; - result.Id = push.PushUriId; - - return Ok(result); - } - catch (Exception ex) - { - result.Sfl = false; - Framework.Logging.LogException(ex); - - return result; - } - } - - return BadRequest(); - } - - /// - /// Removed a Unit Push Notification support by PushUriId. - /// - /// Input to deregister the device for - /// - [HttpDelete("UnRegisterUnitDevice")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task UnRegisterUnitDevice([FromQuery] DeviceUnRegistrationInput input) - { - if (input == null) - return BadRequest(); - - if (this.ModelState.IsValid) - { - try - { - if (!String.IsNullOrWhiteSpace(input.Did)) - { - var deviceId = HttpUtility.UrlDecode(input.Did); - - await _pushService.UnRegisterUnit(new PushUri() {UserId = UserId, DeviceId = deviceId, PushUriId = input.Pid}); - } - - return Ok(); - } - catch (Exception ex) - { - Framework.Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DispatchAppController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DispatchAppController.cs deleted file mode 100644 index 3bd9179d..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/DispatchAppController.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System.Collections.Generic; -using Resgrid.Model.Services; -using Resgrid.Model; -using Resgrid.Web.Services.Controllers.Version3.Models.DispatchApp; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; -using Resgrid.Web.Services.Controllers.Version3.Models.Roles; -using Resgrid.Web.Services.Controllers.Version3.Models.CoreData; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using Resgrid.Web.Services.Controllers.Version3.Models.Calls; -using Resgrid.Model.Providers; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to support Dispatch operations - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - public class DispatchAppController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly ICqrsProvider _cqrsProvider; - - public DispatchAppController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IGeoLocationProvider geoLocationProvider, - ICqrsProvider cqrsProvider - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _geoLocationProvider = geoLocationProvider; - _cqrsProvider = cqrsProvider; - } - - [HttpGet("GetNewCallData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetNewCallData() - { - var results = new NewCallPayloadResult(); - results.Personnel = new List(); - results.Groups = new List(); - results.Units = new List(); - results.Roles = new List(); - results.Statuses = new List(); - results.UnitStatuses = new List(); - results.UnitRoles = new List(); - results.Priorities = new List(); - results.CallTypes = new List(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var rolesForUsersInDepartment = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var allRoles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - var allProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId); - var allGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitTypes = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId); - var callPriorites = await _callsService.GetCallPrioritiesForDepartmentAsync(DepartmentId); - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - - - foreach (var user in users) - { - //var profile = _userProfileService.GetProfileByUserId(user.UserId); - //var group = _departmentGroupsService.GetGroupForUser(user.UserId); - - UserProfile profile = null; - if (allProfiles.ContainsKey(user.UserId)) - profile = allProfiles[user.UserId]; - - DepartmentGroup group = null; - if (groups.ContainsKey(user.UserId)) - group = groups[user.UserId]; - - //var roles = _personnelRolesService.GetRolesForUser(user.UserId); - - List roles = null; - if (rolesForUsersInDepartment.ContainsKey(user.UserId)) - roles = rolesForUsersInDepartment[user.UserId]; - - var result = new PersonnelInfoResult(); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - - result.Eml = user.Email; - result.Did = DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - if (role != null) - result.Roles.Add(role.Name); - } - } - - results.Personnel.Add(result); - } - - foreach (var group in allGroups) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Groups.Add(groupInfo); - } - - foreach (var unit in units) - { - var unitResult = new UnitInfoResult(); - unitResult.Uid = unit.UnitId; - unitResult.Did = DepartmentId; - unitResult.Nme = unit.Name; - unitResult.Typ = unit.Type; - - if (!string.IsNullOrWhiteSpace(unit.Type)) - { - var unitType = unitTypes.FirstOrDefault(x => x.Type == unit.Type); - - if (unitType != null) - unitResult.Cid = unitType.CustomStatesId.GetValueOrDefault(); - } - else - { - unitResult.Cid = 0; - } - - if (unit.StationGroup != null) - { - unitResult.Sid = unit.StationGroup.DepartmentGroupId; - unitResult.Snm = unit.StationGroup.Name; - } - - results.Units.Add(unitResult); - - // Add unit roles for this unit - var roles = await _unitsService.GetRolesForUnitAsync(unit.UnitId); - foreach (var role in roles) - { - var roleResult = new UnitRoleResult(); - roleResult.Name = role.Name; - roleResult.UnitId = role.UnitId; - roleResult.UnitRoleId = role.UnitRoleId; - - results.UnitRoles.Add(roleResult); - } - } - - var unitStatuses = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - - foreach (var us in unitStatuses) - { - var unitStatus = new UnitStatusCoreResult(); - unitStatus.UnitId = us.UnitId; - unitStatus.StateType = (UnitStateTypes)us.State; - unitStatus.StateTypeId = us.State; - unitStatus.Type = us.Unit.Type; - unitStatus.Timestamp = us.Timestamp.TimeConverter(department); - unitStatus.Name = us.Unit.Name; - unitStatus.Note = us.Note; - - if (us.DestinationId.HasValue) - unitStatus.DestinationId = us.DestinationId.Value; - - if (us.LocalTimestamp.HasValue) - unitStatus.LocalTimestamp = us.LocalTimestamp.Value; - - if (us.Latitude.HasValue) - unitStatus.Latitude = us.Latitude.Value; - - if (us.Longitude.HasValue) - unitStatus.Longitude = us.Longitude.Value; - - results.UnitStatuses.Add(unitStatus); - } - - foreach (var role in allRoles) - { - var roleResult = new RoleInfoResult(); - roleResult.Rid = role.PersonnelRoleId; - roleResult.Nme = role.Name; - - results.Roles.Add(roleResult); - } - - var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(DepartmentId); - - foreach (var customState in customStates) - { - if (customState.IsDeleted) - continue; - - foreach (var stateDetail in customState.GetActiveDetails()) - { - if (stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customState.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - results.Statuses.Add(customStateResult); - } - - } - - foreach (var priority in callPriorites) - { - var priorityResult = new CallPriorityResult(); - priorityResult.Id = priority.DepartmentCallPriorityId; - priorityResult.DepartmentId = priority.DepartmentId; - priorityResult.Name = priority.Name; - priorityResult.Color = priority.Color; - priorityResult.Sort = priority.Sort; - priorityResult.IsDeleted = priority.IsDeleted; - priorityResult.IsDefault = priority.IsDefault; - - results.Priorities.Add(priorityResult); - } - - if (callTypes != null && callTypes.Any()) - { - foreach (var callType in callTypes) - { - var type = new CallTypeResult(); - type.Id = callType.CallTypeId; - type.Name = callType.Type; - - results.CallTypes.Add(type); - } - } - - - return results; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DispatchController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DispatchController.cs deleted file mode 100644 index 7bf00009..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/DispatchController.cs +++ /dev/null @@ -1,778 +0,0 @@ -using System.Collections.Generic; -using Resgrid.Model.Services; -using Resgrid.Model; -using Resgrid.Web.Services.Controllers.Version3.Models.DispatchApp; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; -using Resgrid.Web.Services.Controllers.Version3.Models.Roles; -using Resgrid.Web.Services.Controllers.Version3.Models.CoreData; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using Resgrid.Web.Services.Controllers.Version3.Models.Calls; -using Resgrid.Model.Providers; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Helpers; -using Resgrid.Web.Services.Models.v3.Dispatch; -using Resgrid.Framework; -using System; -using Resgrid.Web.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to support Dispatch operations - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class DispatchController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly ICqrsProvider _cqrsProvider; - private readonly IDepartmentSettingsService _departmentSettingsService; - private readonly ITemplatesService _templatesService; - private readonly IFormsService _formsService; - - public DispatchController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IGeoLocationProvider geoLocationProvider, - ICqrsProvider cqrsProvider, - IDepartmentSettingsService departmentSettingsService, - ITemplatesService templatesService, - IFormsService formsService - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _geoLocationProvider = geoLocationProvider; - _cqrsProvider = cqrsProvider; - _departmentSettingsService = departmentSettingsService; - _templatesService = templatesService; - _formsService = formsService; - } - - [HttpGet("GetNewCallData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetNewCallData() - { - var results = new NewCallPayloadResult(); - results.Personnel = new List(); - results.Groups = new List(); - results.Units = new List(); - results.Roles = new List(); - results.Statuses = new List(); - results.UnitStatuses = new List(); - results.UnitRoles = new List(); - results.Priorities = new List(); - results.CallTypes = new List(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var rolesForUsersInDepartment = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var allRoles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - var allProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId); - var allGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitTypes = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId); - var callPriorites = await _callsService.GetActiveCallPrioritiesForDepartmentAsync(DepartmentId); - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - - - foreach (var user in users) - { - //var profile = _userProfileService.GetProfileByUserId(user.UserId); - //var group = _departmentGroupsService.GetGroupForUser(user.UserId); - - UserProfile profile = null; - if (allProfiles.ContainsKey(user.UserId)) - profile = allProfiles[user.UserId]; - - DepartmentGroup group = null; - if (groups.ContainsKey(user.UserId)) - group = groups[user.UserId]; - - //var roles = _personnelRolesService.GetRolesForUser(user.UserId); - - List roles = null; - if (rolesForUsersInDepartment.ContainsKey(user.UserId)) - roles = rolesForUsersInDepartment[user.UserId]; - - var result = new PersonnelInfoResult(); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - - result.Eml = user.Email; - result.Did = DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - if (role != null) - result.Roles.Add(role.Name); - } - } - - results.Personnel.Add(result); - } - - foreach (var group in allGroups) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Groups.Add(groupInfo); - } - - foreach (var unit in units) - { - var unitResult = new UnitInfoResult(); - unitResult.Uid = unit.UnitId; - unitResult.Did = DepartmentId; - unitResult.Nme = unit.Name; - unitResult.Typ = unit.Type; - - if (!string.IsNullOrWhiteSpace(unit.Type)) - { - var unitType = unitTypes.FirstOrDefault(x => x.Type == unit.Type); - - if (unitType != null) - unitResult.Cid = unitType.CustomStatesId.GetValueOrDefault(); - } - else - { - unitResult.Cid = 0; - } - - if (unit.StationGroup != null) - { - unitResult.Sid = unit.StationGroup.DepartmentGroupId; - unitResult.Snm = unit.StationGroup.Name; - } - - results.Units.Add(unitResult); - - // Add unit roles for this unit - var roles = await _unitsService.GetRolesForUnitAsync(unit.UnitId); - foreach (var role in roles) - { - var roleResult = new UnitRoleResult(); - roleResult.Name = role.Name; - roleResult.UnitId = role.UnitId; - roleResult.UnitRoleId = role.UnitRoleId; - - results.UnitRoles.Add(roleResult); - } - } - - var unitStatuses = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - - foreach (var us in unitStatuses) - { - var unitStatus = new UnitStatusCoreResult(); - unitStatus.UnitId = us.UnitId; - unitStatus.StateType = (UnitStateTypes)us.State; - unitStatus.StateTypeId = us.State; - unitStatus.Type = us.Unit.Type; - unitStatus.Timestamp = us.Timestamp.TimeConverter(department); - unitStatus.Name = us.Unit.Name; - unitStatus.Note = us.Note; - - if (us.DestinationId.HasValue) - unitStatus.DestinationId = us.DestinationId.Value; - - if (us.LocalTimestamp.HasValue) - unitStatus.LocalTimestamp = us.LocalTimestamp.Value; - - if (us.Latitude.HasValue) - unitStatus.Latitude = us.Latitude.Value; - - if (us.Longitude.HasValue) - unitStatus.Longitude = us.Longitude.Value; - - results.UnitStatuses.Add(unitStatus); - } - - foreach (var role in allRoles) - { - var roleResult = new RoleInfoResult(); - roleResult.Rid = role.PersonnelRoleId; - roleResult.Nme = role.Name; - - results.Roles.Add(roleResult); - } - - var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(DepartmentId); - - foreach (var customState in customStates) - { - if (customState.IsDeleted) - continue; - - foreach (var stateDetail in customState.GetActiveDetails()) - { - if (stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customState.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - results.Statuses.Add(customStateResult); - } - - } - - foreach (var priority in callPriorites) - { - var priorityResult = new CallPriorityResult(); - priorityResult.Id = priority.DepartmentCallPriorityId; - priorityResult.DepartmentId = priority.DepartmentId; - priorityResult.Name = priority.Name; - priorityResult.Color = priority.Color; - priorityResult.Sort = priority.Sort; - priorityResult.IsDeleted = priority.IsDeleted; - priorityResult.IsDefault = priority.IsDefault; - - results.Priorities.Add(priorityResult); - } - - if (callTypes != null && callTypes.Any()) - { - foreach (var callType in callTypes) - { - var type = new CallTypeResult(); - type.Id = callType.CallTypeId; - type.Name = callType.Type; - - results.CallTypes.Add(type); - } - } - - - return results; - } - - [HttpGet("GetSetUnitStatusData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetSetUnitStatusData(int unitId) - { - var results = new GetSetUnitStateDataResult(); - results.UnitId = unitId; - results.Stations = new List(); - results.Calls = new List(); - results.Statuses = new List(); - - var unit = await _unitsService.GetUnitByIdAsync(unitId); - results.UnitName = unit.Name; - - var type = await _unitsService.GetUnitTypeByNameAsync(DepartmentId, unit.Type); - var activeCalls = await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var stations = await _departmentGroupsService.GetAllStationGroupsForDepartmentAsync(DepartmentId); - - var callDefault = new CallResult(); - callDefault.Cid = 0; - callDefault.Nme = "No Call"; - results.Calls.Add(callDefault); - - if (activeCalls != null) - { - foreach (var c in activeCalls) - { - var call = new CallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Utc = c.LoggedOn; - call.Ste = c.State; - call.Num = c.Number; - - results.Calls.Add(call); - } - } - - var groupInfoDefault = new GroupInfoResult(); - groupInfoDefault.Gid = 0; - groupInfoDefault.Nme = "No Station"; - results.Stations.Add(groupInfoDefault); - - if (stations != null) - { - foreach (var group in stations) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Stations.Add(groupInfo); - } - } - - if (type != null && type.CustomStatesId.HasValue) - { - var customStates = await _customStateService.GetCustomSateByIdAsync(type.CustomStatesId.Value); - - if (!customStates.IsDeleted) - { - foreach (var stateDetail in customStates.GetActiveDetails()) - { - if (stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customStates.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - results.Statuses.Add(customStateResult); - } - } - } - else - { - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = 0; - customStateResult.Type = 0; - customStateResult.StateId = 0; - customStateResult.Text = "Available"; - customStateResult.BColor = "#FFFFFF"; - customStateResult.Color = "#000000"; - customStateResult.Gps = false; - customStateResult.Note = 0; - customStateResult.Detail = 0; - - results.Statuses.Add(customStateResult); - - var customStateResult2 = new CustomStatusesResult(); - customStateResult2.Id = 3; - customStateResult2.Type = 3; - customStateResult2.StateId = 3; - customStateResult2.Text = "Committed"; - customStateResult2.BColor = "#FFFFFF"; - customStateResult2.Color = "#000000"; - customStateResult2.Gps = false; - customStateResult2.Note = 0; - customStateResult2.Detail = 0; - - results.Statuses.Add(customStateResult2); - - var customStateResult3 = new CustomStatusesResult(); - customStateResult3.Id = 1; - customStateResult3.Type = 1; - customStateResult3.StateId = 1; - customStateResult3.Text = "Delayed"; - customStateResult3.BColor = "#FFFFFF"; - customStateResult3.Color = "#000000"; - customStateResult3.Gps = false; - customStateResult3.Note = 0; - customStateResult3.Detail = 0; - - results.Statuses.Add(customStateResult3); - - var customStateResult4 = new CustomStatusesResult(); - customStateResult4.Id = 4; - customStateResult4.Type = 4; - customStateResult4.StateId = 4; - customStateResult4.Text = "Out Of Service"; - customStateResult4.BColor = "#FFFFFF"; - customStateResult4.Color = "#000000"; - customStateResult4.Gps = false; - customStateResult4.Note = 0; - customStateResult4.Detail = 0; - - results.Statuses.Add(customStateResult4); - - var customStateResult5 = new CustomStatusesResult(); - customStateResult5.Id = 2; - customStateResult5.Type = 2; - customStateResult5.StateId = 2; - customStateResult5.Text = "Unavailable"; - customStateResult5.BColor = "#FFFFFF"; - customStateResult5.Color = "#000000"; - customStateResult5.Gps = false; - customStateResult5.Note = 0; - customStateResult5.Detail = 0; - - results.Statuses.Add(customStateResult5); - } - - - return results; - } - - /// - /// Returns all the personnel for display in the new call personnel table - /// - /// Array of PersonnelForCallResult objects for each person in the department - [HttpGet("GetPersonnelForCallGrid")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetPersonnelForCallGrid() - { - var result = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId);//.GetAllUsersForDepartmentUnlimitedMinusDisabled(DepartmentId); - var personnelNames = await _departmentsService.GetAllPersonnelNamesForDepartmentAsync(DepartmentId); - - var lastUserActionlogs = await _actionLogsService.GetLastActionLogsForDepartmentAsync(DepartmentId); - var userStates = await _userStateService.GetLatestStatesForDepartmentAsync(DepartmentId); - - var personnelSortOrder = await _departmentSettingsService.GetDepartmentPersonnelSortOrderAsync(DepartmentId); - var personnelStatusSortOrder = await _departmentSettingsService.GetDepartmentPersonnelListStatusSortOrderAsync(DepartmentId); - - foreach (var user in users) - { - PersonnelForCallResult person = new PersonnelForCallResult(); - person.UserId = user.UserId; - person.Name = await UserHelper.GetFullNameForUser(personnelNames, user.UserName, user.UserId); - - var group = await _departmentGroupsService.GetGroupForUserAsync(user.UserId, DepartmentId); - if (group != null) - person.Group = group.Name; - - var roles = await _personnelRolesService.GetRolesForUserAsync(user.UserId, DepartmentId); - person.Roles = new List(); - foreach (var role in roles) - { - person.Roles.Add(role.Name); - } - - var currentStaffing = userStates.FirstOrDefault(x => x.UserId == user.UserId); - if (currentStaffing != null) - { - var staffing = await CustomStatesHelper.GetCustomPersonnelStaffing(DepartmentId, currentStaffing); - - if (staffing != null) - { - person.Staffing = staffing.ButtonText; - person.StaffingColor = staffing.ButtonClassToColor(); - } - } - else - { - person.Staffing = "Available"; - person.StaffingColor = "#000"; - } - - var currentStatus = lastUserActionlogs.FirstOrDefault(x => x.UserId == user.UserId); - if (currentStatus != null) - { - var status = await CustomStatesHelper.GetCustomPersonnelStatus(DepartmentId, currentStatus); - if (status != null) - { - person.Status = status.ButtonText; - person.StatusColor = status.ButtonClassToColor(); - } - - person.Location = currentStatus.GeoLocationData; - } - else - { - person.Status = "Standing By"; - person.StatusColor = "#000"; - } - - person.Eta = "N/A"; - - if (currentStatus != null) - { - if (personnelStatusSortOrder != null && personnelStatusSortOrder.Any()) - { - var statusSorting = personnelStatusSortOrder.FirstOrDefault(x => x.StatusId == currentStatus.ActionTypeId); - if (statusSorting != null) - person.Weight = statusSorting.Weight; - else - person.Weight = 9000; - } - else - { - person.Weight = 9000; - } - } - else - person.Weight = 9000; - - result.Add(person); - } - - switch (personnelSortOrder) - { - case PersonnelSortOrders.Default: - result = result.OrderBy(x => x.Weight).ToList(); - break; - case PersonnelSortOrders.FirstName: - result = result.OrderBy(x => x.Weight).ThenBy(x => x.FirstName).ToList(); - break; - case PersonnelSortOrders.LastName: - result = result.OrderBy(x => x.Weight).ThenBy(x => x.LastName).ToList(); - break; - case PersonnelSortOrders.Group: - result = result.OrderBy(x => x.Weight).ThenBy(x => x.GroupId).ToList(); - break; - default: - result = result.OrderBy(x => x.Weight).ToList(); - break; - } - - return Ok(result); - } - - - /// - /// Returns all the groups for display in the new call groups table - /// - /// Array of GroupsForCallResult objects for each group in the department - [HttpGet("GetGroupsForCallGrid")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - - public async Task>> GetGroupsForCallGrid() - { - List groupsJson = new List(); - var groups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - foreach (var group in groups) - { - GroupsForCallResult groupJson = new GroupsForCallResult(); - groupJson.GroupId = group.DepartmentGroupId; - groupJson.Name = group.Name; - - if (group.Members != null) - groupJson.Count = group.Members.Count; - else - groupJson.Count = 0; - - groupsJson.Add(groupJson); - } - - return Ok(groupsJson); - } - - /// - /// Returns all the roles for display in the new call groups table - /// - /// Array of RolesForCallResult objects for each role in the department - [HttpGet("GetRolesForCallGrid")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetRolesForCallGrid() - { - List rolesJson = new List(); - var roles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - - foreach (var role in roles) - { - RolesForCallResult roleJson = new RolesForCallResult(); - roleJson.RoleId = role.PersonnelRoleId; - roleJson.Name = role.Name; - - if (role.Users != null) - roleJson.Count = role.Users.Count; - else - roleJson.Count = 0; - - rolesJson.Add(roleJson); - } - - return Ok(rolesJson); - } - - /// - /// Returns all the call quick templates - /// - /// Array of CallTemplateResult objects for each role in the department - [HttpGet("GetCallTemplates")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task>> GetCallTemplates() - { - List templatesJson = new List(); - var templates = await _templatesService.GetAllCallQuickTemplatesForDepartmentAsync(DepartmentId); - - foreach (var template in templates) - { - CallTemplateResult templateJson = new CallTemplateResult(); - templateJson.Id = template.CallQuickTemplateId; - templateJson.IsDisabled = template.IsDisabled; - templateJson.Name = template.Name; - templateJson.CallName = template.CallName; - templateJson.CallNature = template.CallNature; - templateJson.CallType = template.CallType; - templateJson.CallPriority = template.CallPriority; - templateJson.CreatedByUserId = template.CreatedByUserId; - templateJson.CreatedOn = template.CreatedOn; - - templatesJson.Add(templateJson); - } - - return Ok(templatesJson); - } - - /// - /// Returns the custom new call form if any exists and is active - /// - /// FormDataResult object with the new call form data - [HttpGet("GetNewCallForm")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetNewCallForm() - { - var formResult = new FormDataResult(); - var form = await _formsService.GetNewCallFormByDepartmentIdAsync(DepartmentId); - - if (form != null) - { - formResult.Id = form.FormId; - formResult.Name = form.Name; - formResult.Type = form.Type; - formResult.Data = form.Data; - - if (form.Automations != null && form.Automations.Any()) - { - formResult.Automations = new List(); - - foreach (var automation in form.Automations) - { - var automationResult = new FormDataAutomationResult(); - automationResult.Id = automation.FormAutomationId; - automationResult.FormId = automation.FormId; - automationResult.TriggerField = automation.TriggerField; - automationResult.TriggerValue = automation.TriggerValue; - automationResult.OperationType = automation.OperationType; - automationResult.OperationValue = automation.OperationValue; - - formResult.Automations.Add(automationResult); - } - } - } - - return Ok(formResult); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/FeedsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/FeedsController.cs deleted file mode 100644 index 48b5945e..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/FeedsController.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net.Mime; -using System.ServiceModel.Syndication; -using System.Text; -using System.Threading.Tasks; -using System.Xml; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Services; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - [Route("api/v{version:ApiVersion}/[controller]")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - //[EnableCors("_resgridWebsiteAllowSpecificOrigins")] - public class FeedsController : ControllerBase - { - private readonly IDepartmentsService _departmentsService; - private readonly IDepartmentSettingsService _departmentSettingsService; - private readonly ICallsService _callsService; - - public FeedsController(IDepartmentsService departmentsService, IDepartmentSettingsService departmentSettingsService, ICallsService callsService) - { - _departmentsService = departmentsService; - _departmentSettingsService = departmentSettingsService; - _callsService = callsService; - } - - [HttpGet("GetActiveCallsAsRSS")] - [Produces(MediaTypeNames.Text.Xml)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActiveCallsAsRSS(string key) - { - if (String.IsNullOrWhiteSpace(key)) - return null; - - var departmentId = await _departmentSettingsService.GetDepartmentIdForRssKeyAsync(key); - - if (!departmentId.HasValue) - return null; - - var department = await _departmentsService.GetDepartmentByIdAsync(departmentId.Value); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(departmentId.Value); - - var feed = new SyndicationFeed(string.Format("{0} Active Calls", department.Name), string.Format("The active calls for the department {0}", department.Name), new Uri(Config.SystemBehaviorConfig.ResgridBaseUrl)); - feed.Authors.Add(new SyndicationPerson("team@resgrid.com")); - feed.Categories.Add(new SyndicationCategory("Resgrid Calls")); - feed.Description = new TextSyndicationContent(string.Format("The active calls for the department {0}", department.Name)); - feed.Items = calls.Select(call => new SyndicationItem(call.Name, call.NatureOfCall, new Uri($"{Config.SystemBehaviorConfig.ResgridBaseUrl}/User/Dispatch/ViewCall?callId=" + call.CallId), call.CallId.ToString(), call.LoggedOn)).ToList(); - - - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - NewLineHandling = NewLineHandling.Entitize, - NewLineOnAttributes = true, - Indent = true - }; - - using (var stream = new MemoryStream()) - { - using (var xmlWriter = XmlWriter.Create(stream, settings)) - { - var rssFormatter = new Rss20FeedFormatter(feed, false); - rssFormatter.WriteTo(xmlWriter); - xmlWriter.Flush(); - } - return File(stream.ToArray(), "application/rss+xml; charset=utf-8"); - } - } - - [HttpGet("GetActiveCallsAsAtom")] - [Produces(MediaTypeNames.Text.Xml)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetActiveCallsAsAtom(string key) - { - if (String.IsNullOrWhiteSpace(key)) - return null; - - var departmentId = await _departmentSettingsService.GetDepartmentIdForRssKeyAsync(key); - - if (!departmentId.HasValue) - return null; - - var department = await _departmentsService.GetDepartmentByIdAsync(departmentId.Value); - var calls = await _callsService.GetActiveCallsByDepartmentAsync(departmentId.Value); - - var feed = new SyndicationFeed(string.Format("{0} Active Calls", department.Name), string.Format("The active calls for the department {0}", department.Name), new Uri(Config.SystemBehaviorConfig.ResgridBaseUrl)); - feed.Authors.Add(new SyndicationPerson("team@resgrid.com")); - feed.Categories.Add(new SyndicationCategory("Resgrid Calls")); - feed.Description = new TextSyndicationContent(string.Format("The active calls for the department {0}", department.Name)); - feed.Items = calls.Select(call => new SyndicationItem(call.Name, call.NatureOfCall, new Uri($"{Config.SystemBehaviorConfig.ResgridBaseUrl}/User/Dispatch/ViewCall?callId=" + call.CallId), call.CallId.ToString(), call.LoggedOn)).ToList(); - - return new Atom10FeedFormatter(feed); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/GeoController.cs b/Web/Resgrid.Web.Services/Controllers/v3/GeoController.cs deleted file mode 100644 index c3f35768..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/GeoController.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Threading.Tasks; -using System.Web; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Providers; -using Resgrid.Web.Services.Controllers.Version3.Models.Geo; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Geolocation API methods for gps and other functions (like what3words) - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class GeoController : V3AuthenticatedApiControllerbase - { - private readonly IGeoLocationProvider _geoLocationProvider; - - public GeoController(IGeoLocationProvider geoLocationProvider) - { - _geoLocationProvider = geoLocationProvider; - } - - /// - /// Gets coordinates (Latitude and Longitude) for a what3words address - /// - /// Full 3 part what 3 words string - /// - [HttpGet] - public async Task> GetLocationForWhatThreeWords(string w3w) - { - WhatThreeWordsResult result = new WhatThreeWordsResult(); - var coords = await _geoLocationProvider.GetCoordinatesFromW3WAsync(w3w); - - if (coords != null && coords.Latitude.HasValue && coords.Longitude.HasValue) - { - result.Latitude = coords.Latitude; - result.Longitude = coords.Longitude; - - try - { - result.Address = await _geoLocationProvider.GetAddressFromLatLong(coords.Latitude.Value, coords.Longitude.Value); - } - catch - { - return NotFound(); - } - } - - return Ok(result); - } - - /// - /// Gets coordinates (Latitude and Longitude) for an address - /// - /// URL Encoded address - /// - [HttpGet("GetCoordinatesForAddress")] - public async Task> GetCoordinatesForAddress(string address) - { - var plainTextAddress = HttpUtility.UrlDecode(address); - CoordinatesResult result = new CoordinatesResult(); - - if (!String.IsNullOrWhiteSpace(address)) - { - try - { - var coords = await _geoLocationProvider.GetLatLonFromAddressLocationIQ(plainTextAddress); - - if (coords != null && coords.Longitude.HasValue && coords.Latitude.HasValue) - { - result.Latitude = coords.Latitude; - result.Longitude = coords.Longitude; - } - } - catch - { - return NotFound(); - } - } - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/HealthController.cs b/Web/Resgrid.Web.Services/Controllers/v3/HealthController.cs deleted file mode 100644 index d69755ab..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/HealthController.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Reflection; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Health; - -namespace Resgrid.Web.Services.Controllers.v3 -{ - /// - /// Health Check system to get information and health status of the services - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - [ApiController] - [AllowAnonymous] - public class HealthController: Controller - { - #region Members and Constructors - private readonly IHealthService _healthService; - private readonly IWebHostEnvironment _env; - - public HealthController( - IHealthService healthService, - IWebHostEnvironment env - ) - { - _healthService = healthService; - _env = env; - } - #endregion Members and Constructors - - /// - /// Returns all the call priorities (including deleted ones) for a department - /// - /// Array of CallPriorityResult objects for each call priority in the department - [AllowAnonymous] - [HttpGet("GetCurrent")] - public async Task GetCurrent() - { - var result = new HealthResult(); - - result.ServicesVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(); - result.ApiVersion = "v3"; - result.SiteId = "0"; - result.CacheOnline = _healthService.IsCacheProviderConnected(); - - var dbTime = await _healthService.GetDatabaseTimestamp(); - - if (!string.IsNullOrWhiteSpace(dbTime)) - result.DatabaseOnline = true; - else - result.DatabaseOnline = false; - - return result; - } - - //[AllowAnonymous] - //public HttpResponseMessage Options() - //{ - // var response = new HttpResponseMessage(); - // response.StatusCode = HttpStatusCode.OK; - // response.Headers.Add("Access-Control-Allow-Origin", "*"); - // response.Headers.Add("Access-Control-Request-Headers", "*"); - // response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); - - // return response; - //} - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/LinksController.cs b/Web/Resgrid.Web.Services/Controllers/v3/LinksController.cs deleted file mode 100644 index 52ed258c..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/LinksController.cs +++ /dev/null @@ -1,407 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.BigBoard; -using Resgrid.Web.Services.Controllers.Version3.Models.BigBoard.BigBoardX; -using Resgrid.Web.Services.Controllers.Version3.Models.Links; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against the security sub-system - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class LinksController : V3AuthenticatedApiControllerbase - { - private readonly IDepartmentsService _departmentsService; - private readonly IDepartmentLinksService _departmentLinksService; - private readonly ILimitsService _limitsService; - private readonly ICallsService _callsService; - private readonly IUserProfileService _userProfileService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly IUnitsService _unitsService; - private readonly IActionLogsService _actionLogsService; - private readonly IUserStateService _userStateService; - - /// - /// Operations to perform against the department links system. Department Links allow departments to - /// share data to other departments, for example calls or resource orders. - /// - public LinksController(IDepartmentsService departmentsService, IDepartmentLinksService departmentLinksService, ILimitsService limitsService, - ICallsService callsService, IUserProfileService userProfileService, IGeoLocationProvider geoLocationProvider, IUnitsService unitsService, - IActionLogsService actionLogsService, IUserStateService userStateService) - { - _departmentsService = departmentsService; - _departmentLinksService = departmentLinksService; - _limitsService = limitsService; - _callsService = callsService; - _userProfileService = userProfileService; - _geoLocationProvider = geoLocationProvider; - _unitsService = unitsService; - _actionLogsService = actionLogsService; - _userStateService = userStateService; - } - - /// - /// Gets the current active department links for this department where data is bring shared to it - /// - /// List of DepartmentLinkResult objects with the information about the links - [ProducesResponseType(StatusCodes.Status200OK)] - [HttpGet("GetActiveDepartmentLinks")] - public async Task>> GetActiveDepartmentLinks() - { - if (!await _limitsService.CanDepartmentUseLinksAsync(DepartmentId)) - return new List(); - - var linkResults = new List(); - var links = await _departmentLinksService.GetAllLinksForDepartmentAsync(DepartmentId); - - foreach (var link in links) - { - if (link.LinkedDepartmentId == DepartmentId && link.LinkEnabled) - { - var department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId); - - var result = new DepartmentLinkResult(); - result.LinkId = link.DepartmentLinkId; - result.DepartmentName = department.Name; - result.Color = link.DepartmentColor; - result.ShareCalls = link.DepartmentShareCalls; - result.ShareOrders = link.DepartmentShareOrders; - result.SharePersonnel = link.DepartmentSharePersonnel; - result.ShareUnits = link.DepartmentShareUnits; - - linkResults.Add(result); - } - } - - return linkResults; - } - - /// - /// Returns all the active calls for a specific department link - /// - /// Array of CallResult objects for each active call in the department - [HttpGet("GetActiveCallsForLink")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetActiveCallsForLink(int linkId) - { - var result = new List(); - - var link = await _departmentLinksService.GetLinkByIdAsync(linkId); - - if (link.DepartmentId != DepartmentId && link.LinkedDepartmentId != DepartmentId) - return new List(); - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(link.DepartmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId, false); - - foreach (var c in calls) - { - var call = new LinkedCallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int)CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Ste = c.State; - call.Num = c.Number; - - call.Priority = c.ToCallPriorityDisplayText(); - call.PriorityCss = c.ToCallPriorityCss(); - call.State = c.ToCallStateDisplayText(); - call.StateCss = c.ToCallStateCss(); - - result.Add(call); - } - - return Ok(result); - } - - /// - /// Get's all the units for a department link and their current status information - /// - /// List of UnitStatusResult objects, with status information for each unit. - [HttpGet("GetUnitStatusesForLink")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetUnitStatusesForLink(int linkId) - { - var results = new List(); - - var link = await _departmentLinksService.GetLinkByIdAsync(linkId); - if (link.DepartmentId != DepartmentId && link.LinkedDepartmentId != DepartmentId) - return new List(); - - var units = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(link.DepartmentId); - var department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId, false); - - foreach (var u in units) - { - var unitStatus = new UnitStatusResult(); - unitStatus.Uid = u.UnitId; - unitStatus.Typ = u.State; - unitStatus.Tmp = u.Timestamp.TimeConverter(department); - - if (u.DestinationId.HasValue) - unitStatus.Did = u.DestinationId.Value; - - results.Add(unitStatus); - } - - return Ok(results); - } - - /// - /// Get's all the personnel in a department link and their current status and staffing information - /// - /// List of PersonnelStatusResult objects, with status and staffing information for each user. - [HttpGet("GetPersonnelStatusesForLink")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetPersonnelStatusesForLink(int linkId) - { - var link = await _departmentLinksService.GetLinkByIdAsync(linkId); - if (link.DepartmentId != DepartmentId && link.LinkedDepartmentId != DepartmentId) - return new List(); - - var results = new List(); - - var actionLogs = await _actionLogsService.GetAllActionLogsForDepartmentAsync(link.DepartmentId); - var userStates = await _userStateService.GetLatestStatesForDepartmentAsync(link.DepartmentId); - var users = await _departmentsService.GetAllUsersForDepartmentAsync(link.DepartmentId); - Department department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId, false); - - foreach (var u in users) - { - var log = (from l in actionLogs - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var state = (from l in userStates - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var s = new PersonnelStatusResult(); - s.Uid = u.UserId.ToString(); - - if (log != null) - { - s.Atp = log.ActionTypeId; - s.Atm = log.Timestamp.TimeConverter(department); - - if (log.DestinationId.HasValue) - { - if (log.ActionTypeId == (int)ActionTypes.RespondingToScene) - s.Did = log.DestinationId.Value.ToString(); - else if (log.ActionTypeId == (int)ActionTypes.RespondingToStation) - s.Did = log.DestinationId.Value.ToString(); - else if (log.ActionTypeId == (int)ActionTypes.AvailableStation) - s.Did = log.DestinationId.Value.ToString(); - } - } - else - { - s.Atp = (int)ActionTypes.StandingBy; - s.Atm = DateTime.UtcNow.TimeConverter(department); - } - - if (state != null) - { - s.Ste = state.State; - s.Stm = state.Timestamp.TimeConverter(department); - } - else - { - s.Ste = (int)UserStateTypes.Available; - s.Stm = DateTime.UtcNow.TimeConverter(department); - } - results.Add(s); - } - - - return Ok(results); - } - - /// - /// Returns all the map markers for all active links - /// - /// Array of MapMakerInfo objects for each active call in all linked departments - [HttpGet("GetAllLinkedCallMapMarkers")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllLinkedCallMapMarkers() - { - var result = new List(); - - var links = await _departmentLinksService.GetAllLinksForDepartmentAsync(DepartmentId); - - foreach (var link in links.Where(x => x.LinkEnabled && x.LinkedDepartmentId == DepartmentId)) - { - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(link.DepartmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId, false); - - foreach (var call in calls) - { - MapMakerInfo info = new MapMakerInfo(); - info.ImagePath = "Call"; - info.Title = call.Name; - info.InfoWindowContent = call.NatureOfCall; - info.Color = link.DepartmentColor; - - if (!String.IsNullOrEmpty(call.GeoLocationData)) - { - try - { - info.Latitude = double.Parse(call.GeoLocationData.Split(char.Parse(","))[0]); - info.Longitude = double.Parse(call.GeoLocationData.Split(char.Parse(","))[1]); - } - catch { } - } - else if (!String.IsNullOrEmpty(call.Address)) - { - string coordinates = await _geoLocationProvider.GetLatLonFromAddress(call.Address); - if (!String.IsNullOrEmpty(coordinates)) - { - info.Latitude = double.Parse(coordinates.Split(char.Parse(","))[0]); - info.Longitude = double.Parse(coordinates.Split(char.Parse(","))[1]); - } - } - - result.Add(info); - } - } - - return Ok(result); - } - - /// - /// Returns all the active calls for a specific department link - /// - /// Array of CallResult objects for each active call in the department - [HttpGet("GetAllActiveCallsForLinks")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllActiveCallsForLinks() - { - var result = new List(); - - var links = await _departmentLinksService.GetAllLinksForDepartmentAsync(DepartmentId); - - foreach (var link in links) - { - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(link.DepartmentId)).OrderByDescending(x => x.LoggedOn); - var department = await _departmentsService.GetDepartmentByIdAsync(link.DepartmentId, false); - - foreach (var c in calls) - { - var call = new LinkedCallResult(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = StringHelpers.SanitizeHtmlInString(c.Name); - - if (!String.IsNullOrWhiteSpace(c.NatureOfCall)) - call.Noc = StringHelpers.SanitizeHtmlInString(c.NatureOfCall); - - call.Map = c.MapPage; - - if (!String.IsNullOrWhiteSpace(c.Notes)) - call.Not = StringHelpers.SanitizeHtmlInString(c.Notes); - - if (c.CallNotes != null) - call.Nts = c.CallNotes.Count(); - else - call.Nts = 0; - - if (c.Attachments != null) - { - call.Aud = c.Attachments.Count(x => x.CallAttachmentType == (int) CallAttachmentTypes.DispatchAudio); - call.Img = c.Attachments.Count(x => x.CallAttachmentType == (int) CallAttachmentTypes.Image); - call.Fls = c.Attachments.Count(x => x.CallAttachmentType == (int) CallAttachmentTypes.File); - } - else - { - call.Aud = 0; - call.Img = 0; - call.Fls = 0; - } - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Ste = c.State; - call.Num = c.Number; - - call.Color = link.LinkedDepartmentColor; - call.Priority = c.ToCallPriorityDisplayText(); - call.PriorityCss = c.ToCallPriorityCss(); - call.State = c.ToCallStateDisplayText(); - call.StateCss = c.ToCallStateCss(); - - result.Add(call); - } - } - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/MessagesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/MessagesController.cs deleted file mode 100644 index 5ffb7a54..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/MessagesController.cs +++ /dev/null @@ -1,504 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Controllers.Version3.Models.Messages; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Collection of methods to perform operations against messages - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class MessagesController : V3AuthenticatedApiControllerbase - { - #region Private Members and Constructors - private ICallsService _callsService; - private IDepartmentsService _departmentsService; - private IUserProfileService _userProfileService; - private IGeoLocationProvider _geoLocationProvider; - private readonly IAuthorizationService _authorizationService; - private readonly IMessageService _messageService; - private readonly IUsersService _usersService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - - public MessagesController( - ICallsService callsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IGeoLocationProvider geoLocationProvider, - IAuthorizationService authorizationService, - IMessageService messageService, - IUsersService usersService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService) - { - _callsService = callsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _geoLocationProvider = geoLocationProvider; - _authorizationService = authorizationService; - _messageService = messageService; - _usersService = usersService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - } - #endregion Private Members and Constructors - - /// - /// Returns all inbox messages for a user. - /// - /// Note that the body of these messages is truncated to 100 characters. - /// Array of MessageResult objects for all the messages in the users Inbox - [HttpGet("GetMessages")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetMessages() - { - var result = new List(); - var messages = (await _messageService.GetInboxMessagesByUserIdAsync(UserId)).OrderBy(x => x.SentOn).OrderByDescending(x => x.SentOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var m in messages) - { - var message = new MessageResult(); - - message.Mid = m.MessageId; - message.Sub = m.Subject; - message.Bdy = StringHelpers.StripHtmlTagsCharArray(m.Body).Truncate(100); - message.Son = m.SentOn.TimeConverter(department); - message.SUtc = m.SentOn; - message.Typ = m.Type; - - if (!String.IsNullOrWhiteSpace(m.SendingUserId)) - message.Uid = m.SendingUserId; - - var respose = m.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (respose != null) - { - if (String.IsNullOrWhiteSpace(respose.Response)) - message.Rsp = true; - - message.Ron = respose.ReadOn; - } - else - { - message.Ron = m.ReadOn; - } - - result.Add(message); - } - - return Ok(result); - } - - /// - /// Returns all inbox messages for a user. - /// - /// Note that the body of these messages is truncated to 100 characters. - /// Array of MessageResult objects for all the messages in the users Inbox - [HttpGet("GetMessagesPaged")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetMessagesPaged(int page) - { - var result = new List(); - var messages = (await _messageService.GetInboxMessagesByUserIdAsync(UserId)).OrderByDescending(x => x.SentOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var m in messages) - { - var message = new MessageResult(); - - message.Mid = m.MessageId; - message.Sub = m.Subject; - message.Bdy = StringHelpers.StripHtmlTagsCharArray(m.Body).Truncate(100); - message.Son = m.SentOn.TimeConverter(department); - message.SUtc = m.SentOn; - message.Typ = m.Type; - - if (!String.IsNullOrWhiteSpace(m.SendingUserId)) - message.Uid = m.SendingUserId; - - var respose = m.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (respose != null) - { - if (String.IsNullOrWhiteSpace(respose.Response)) - message.Rsp = true; - - message.Ron = respose.ReadOn; - } - else - { - message.Ron = m.ReadOn; - } - - result.Add(message); - } - - return Ok(result.Skip(25 * page).Take(25)); - } - - /// - /// Returns all the outbox messages for a user. - /// - /// Note that the body of these messages is truncated to 100 characters. - /// Array of MessageResult objects for all the messages in the users Inbox - [HttpGet("GetOutboxMessages")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetOutboxMessages() - { - var result = new List(); - var messages = (await _messageService.GetSentMessagesByUserIdAsync(UserId)).OrderBy(x => x.SentOn).OrderByDescending(x => x.SentOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var m in messages) - { - var message = new MessageResult(); - - message.Mid = m.MessageId; - message.Sub = m.Subject; - message.Bdy = StringHelpers.StripHtmlTagsCharArray(m.Body).Truncate(100); - message.Son = m.SentOn.TimeConverter(department); - message.SUtc = m.SentOn; - message.Typ = m.Type; - - if (!String.IsNullOrWhiteSpace(m.SendingUserId)) - message.Uid = m.SendingUserId; - - var respose = m.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (respose != null) - { - if (String.IsNullOrWhiteSpace(respose.Response)) - message.Rsp = true; - - message.Ron = respose.ReadOn; - } - else - { - message.Ron = m.ReadOn; - } - - result.Add(message); - } - - return Ok(result); - } - - /// - /// Returns all the outbox messages for a user. - /// - /// Note that the body of these messages is truncated to 100 characters. - /// Array of MessageResult objects for all the messages in the users Inbox - [HttpGet("GetOutboxMessagesPaged")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetOutboxMessagesPaged(int page) - { - var result = new List(); - var messages = (await _messageService.GetSentMessagesByUserIdAsync(UserId)).OrderBy(x => x.SentOn).OrderByDescending(x => x.SentOn); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var m in messages) - { - var message = new MessageResult(); - - message.Mid = m.MessageId; - message.Sub = m.Subject; - message.Bdy = StringHelpers.StripHtmlTagsCharArray(m.Body).Truncate(100); - message.Son = m.SentOn.TimeConverter(department); - message.SUtc = m.SentOn; - message.Typ = m.Type; - - if (!String.IsNullOrWhiteSpace(m.SendingUserId)) - message.Uid = m.SendingUserId; - - var respose = m.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (respose != null) - { - if (String.IsNullOrWhiteSpace(respose.Response)) - message.Rsp = true; - - message.Ron = respose.ReadOn; - } - else - { - message.Ron = m.ReadOn; - } - - result.Add(message); - } - - return Ok(result.Skip(25 * page).Take(25)); - } - - /// - /// Gets a specific message by it's Id. - /// - /// Integer message Identifier - /// MessageResult object populated with message information from the system. - [HttpGet("GetMessage")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> GetMessage(int messageId, CancellationToken cancellationToken) - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var savedMessage = await _messageService.GetMessageByIdAsync(messageId); - bool outboxMessage = false; - - if (savedMessage != null) - { - if (!_authorizationService.CanUserViewMessage(UserId, savedMessage)) - return Unauthorized(); - - if (savedMessage.SendingUserId == UserId) - outboxMessage = true; - - await _messageService.ReadMessageRecipientAsync(messageId, UserId, cancellationToken); - - var message = new MessageResult(); - message.Mid = savedMessage.MessageId; - message.Sub = savedMessage.Subject; - message.Sys = savedMessage.SystemGenerated; - - if (!String.IsNullOrEmpty(savedMessage.Body)) - message.Bdy = HtmlToTextHelper.ConvertHtml(savedMessage.Body); - - message.Son = savedMessage.SentOn.TimeConverter(department); - message.SUtc = savedMessage.SentOn; - message.Typ = savedMessage.Type; - message.Exp = savedMessage.ExpireOn; - - if (!String.IsNullOrWhiteSpace(savedMessage.SendingUserId)) - message.Uid = savedMessage.SendingUserId; - - if (!outboxMessage) - { - var respose = savedMessage.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (respose != null) - { - if (!String.IsNullOrWhiteSpace(respose.Response)) - { - message.Rsp = true; - message.Rty = respose.Response; - } - - message.Not = respose.Note; - message.Ron = respose.ReadOn; - } - else - { - message.Ron = savedMessage.ReadOn; - } - - message.Rcpts = new List(); - - foreach (var recipient in savedMessage.MessageRecipients) - { - var recipResult = new MessageRecipientResult(); - recipResult.Mid = savedMessage.MessageId; - recipResult.Uid = recipient.UserId; - recipResult.Rty = recipient.Response; - recipResult.Not = recipient.Note; - recipResult.Ron = recipient.ReadOn; - - message.Rcpts.Add(recipResult); - } - } - else - { - message.Rcpts = new List(); - - foreach (var recipient in savedMessage.MessageRecipients) - { - var recipResult = new MessageRecipientResult(); - recipResult.Mid = savedMessage.MessageId; - recipResult.Uid = recipient.UserId; - recipResult.Rty = recipient.Response; - recipResult.Not = recipient.Note; - recipResult.Ron = recipient.ReadOn; - - message.Rcpts.Add(recipResult); - } - } - - return message; - } - - return null; - } - - /// - /// Sends a new message to users in the system - /// - /// Input data to send a new message - /// Created result if the message was sent - [HttpPost("SendMessage")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task SendMessage([FromBody] NewMessageInput newMessageInput, CancellationToken cancellationToken) - { - if (newMessageInput.Rcps == null || newMessageInput.Rcps.Count <= 0) - return BadRequest(); - - Message savedMessage = null; - - try - { - var message = new Message(); - message.Subject = newMessageInput.Ttl; - message.Body = System.Net.WebUtility.HtmlDecode(newMessageInput.Bdy); - message.IsBroadcast = true; - message.SendingUserId = UserId; - message.Type = newMessageInput.Typ; - message.SentOn = DateTime.UtcNow; - - var usersToSendTo = new List(); - - if (newMessageInput.Rcps.Any(x => x.Nme == "Everyone")) - { - var departmentUsers = await _departmentsService.GetAllMembersForDepartmentAsync(DepartmentId); - - foreach (var departmentMember in departmentUsers) - { - message.AddRecipient(departmentMember.UserId); - } - } - else - { - // Add all the explict people - foreach (var person in newMessageInput.Rcps.Where(x => x.Typ == 1)) - { - if (usersToSendTo.All(x => x != person.Id) && person.Id != UserId) - { - usersToSendTo.Add(person.Id); - message.AddRecipient(person.Id); - } - } - - // Add all memebers of the group - foreach (var group in newMessageInput.Rcps.Where(x => x.Typ == 2)) - { - if (!String.IsNullOrWhiteSpace(group.Id)) - { - int groupId = 0; - if (int.TryParse(group.Id.Trim(), out groupId)) - { - var members = await _departmentGroupsService.GetAllMembersForGroupAsync(groupId); - - foreach (var member in members) - { - if (usersToSendTo.All(x => x != member.UserId) && member.UserId != UserId) - { - usersToSendTo.Add(member.UserId); - message.AddRecipient(member.UserId); - } - } - } - } - } - - // Add all the users of a specific role - foreach (var role in newMessageInput.Rcps.Where(x => x.Typ == 3)) - { - var roleMembers = await _personnelRolesService.GetAllMembersOfRoleAsync(int.Parse(role.Id)); - - foreach (var member in roleMembers) - { - if (usersToSendTo.All(x => x != member.UserId) && member.UserId != UserId) - { - usersToSendTo.Add(member.UserId); - message.AddRecipient(member.UserId); - } - } - } - } - - savedMessage = await _messageService.SaveMessageAsync(message, cancellationToken); - await _messageService.SendMessageAsync(savedMessage, "", DepartmentId, false, cancellationToken); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - - return CreatedAtAction(nameof(SendMessage), new { id = savedMessage.MessageId }, savedMessage); - } - - /// - /// Deletes a messsage from the system - /// - /// Returns OK status code if successful - [HttpPut("RespondToMessage")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task RespondToMessage([FromBody] MessageResponseInput responseInput, CancellationToken cancellationToken) - { - var message = await _messageService.GetMessageByIdAsync(responseInput.Id); - - if (message == null) - return NotFound(); - - var response = message.MessageRecipients.FirstOrDefault(x => x.UserId == UserId); - - if (response == null) - return NotFound(); - - response.Response = responseInput.Typ.ToString(); - response.ReadOn = DateTime.UtcNow; - response.Note = responseInput.Not; - - await _messageService.SaveMessageRecipientAsync(response, cancellationToken); - - return Ok(); - } - - /// - /// Deletes a messsage from the system - /// - /// MessageId of the message to delete - /// Returns OK status code if successful - [HttpDelete("DeleteMessage")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task DeleteMessage(int messageId, CancellationToken cancellationToken) - { - var user = await _usersService.GetUserByNameAsync(UserName); - var message = await _messageService.GetMessageByIdAsync(messageId); - - if (user == null) - return NotFound(); - - if (message == null) - return NotFound(); - - if (!await _authorizationService.CanUserViewMessageAsync(user.UserId, messageId)) - return Unauthorized(); - - if (message.SendingUserId == UserId) - await _messageService.MarkMessageAsDeletedAsync(messageId, cancellationToken); - else - await _messageService.MarkMessageRecipientAsDeletedAsync(messageId, UserId, cancellationToken); - - return Ok(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/NotesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/NotesController.cs deleted file mode 100644 index d060b277..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/NotesController.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model.Services; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Web.Services.Controllers.Version3.Models.Notes; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against a departments notes - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class NotesController : V3AuthenticatedApiControllerbase - { - private readonly IDepartmentsService _departmentsService; - private readonly INotesService _notesService; - - public NotesController(IDepartmentsService departmentsService, INotesService notesService) - { - _departmentsService = departmentsService; - _notesService = notesService; - } - - /// - /// Get's all the notes in a department - /// - /// List of NotesResult objects. - [HttpGet("GetAllNotes")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllNotes() - { - var results = new List(); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var notes = await _notesService.GetNotesForDepartmentFilteredAsync(DepartmentId, department.IsUserAnAdmin(UserId)); - - foreach (var n in notes) - { - var noteResult = new NotesResult(); - noteResult.Nid = n.NoteId; - noteResult.Uid = n.UserId; - noteResult.Ttl = n.Title; - noteResult.Bdy = StringHelpers.StripHtmlTagsCharArray(n.Body).Truncate(100); - noteResult.Adn = n.AddedOn.TimeConverter(department); - noteResult.Cat = n.Category; - noteResult.Clr = n.Color; - - if (n.ExpiresOn.HasValue) - noteResult.Exp = n.ExpiresOn.Value; - - results.Add(noteResult); - } - - return Ok(results); - } - - /// - /// Get's all the notes in a department - /// - /// List of NotesResult objects. - [HttpGet("GetAllUnexpiredNotesByCategory")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllUnexpiredNotesByCategory(string category, bool includeUnCategorized) - { - var results = new List(); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var notes = await _notesService.GetNotesForDepartmentFilteredAsync(DepartmentId, department.IsUserAnAdmin(UserId)); - - foreach (var n in notes) - { - if ((!n.StartsOn.HasValue || n.StartsOn.Value >= DateTime.UtcNow) && (!n.ExpiresOn.HasValue || n.ExpiresOn.Value <= DateTime.UtcNow)) - { - if (!String.IsNullOrWhiteSpace(category) && !String.IsNullOrWhiteSpace(n.Category) && n.Category.Trim().Equals(category, StringComparison.InvariantCultureIgnoreCase)) - { - var noteResult = new NotesResult(); - noteResult.Nid = n.NoteId; - noteResult.Uid = n.UserId; - noteResult.Ttl = n.Title; - noteResult.Bdy = StringHelpers.StripHtmlTagsCharArray(n.Body).Truncate(100); - noteResult.Adn = n.AddedOn.TimeConverter(department); - noteResult.Cat = n.Category; - noteResult.Clr = n.Color; - - if (n.ExpiresOn.HasValue) - noteResult.Exp = n.ExpiresOn.Value; - - results.Add(noteResult); - } - else if (includeUnCategorized && String.IsNullOrWhiteSpace(n.Category)) - { - var noteResult = new NotesResult(); - noteResult.Nid = n.NoteId; - noteResult.Uid = n.UserId; - noteResult.Ttl = n.Title; - noteResult.Bdy = StringHelpers.StripHtmlTagsCharArray(n.Body).Truncate(100); - noteResult.Adn = n.AddedOn.TimeConverter(department); - noteResult.Cat = n.Category; - noteResult.Clr = n.Color; - - if (n.ExpiresOn.HasValue) - noteResult.Exp = n.ExpiresOn.Value; - - results.Add(noteResult); - } - } - } - - return Ok(results); - } - - /// - /// Gets a specific note by it's Id. - /// - /// Integer note Identifier - /// NotesResult object populated with note information from the system. - [HttpGet("GetNote")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetNote(int noteId) - { - var note = await _notesService.GetNoteByIdAsync(noteId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - if (note != null) - { - if (note.DepartmentId != DepartmentId) - return Unauthorized(); - - var noteResult = new NotesResult(); - noteResult.Nid = note.NoteId; - noteResult.Uid = note.UserId; - noteResult.Ttl = note.Title; - noteResult.Bdy = StringHelpers.StripHtmlTagsCharArray(note.Body).Truncate(100); - noteResult.Adn = note.AddedOn.TimeConverter(department); - noteResult.Cat = note.Category; - noteResult.Clr = note.Color; - - if (note.ExpiresOn.HasValue) - noteResult.Exp = note.ExpiresOn.Value; - - return Ok(noteResult); - } - - return NotFound(); - } - - /// - /// Get's all the notes in a department - /// - /// List of NotesResult objects. - [HttpPost("SaveNote")] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SaveNote(NewNoteInput input, CancellationToken cancellationToken) - { - var note = new Note(); - note.DepartmentId = DepartmentId; - note.AddedOn = DateTime.UtcNow; - note.IsAdminOnly = input.Ado; - note.Category = input.Cat; - note.Title = input.Ttl; - note.Body = input.Bdy; - note.UserId = UserId; - - var saved = await _notesService.SaveAsync(note, cancellationToken); - - return CreatedAtAction(nameof(SaveNote), new { id = saved.NoteId }, saved); - } - - /// - /// Get's all the note Categories for a Department - /// - /// List of string of distinct note category. - [HttpGet("GetNoteCategories")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetNoteCategories() - { - var result = await _notesService.GetDistinctCategoriesByDepartmentIdAsync(DepartmentId); - - return result; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/PersonnelController.cs b/Web/Resgrid.Web.Services/Controllers/v3/PersonnelController.cs deleted file mode 100644 index cef6aea5..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/PersonnelController.cs +++ /dev/null @@ -1,385 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Web; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using System; -using System.Threading.Tasks; -using Amazon.Runtime; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against personnel in a department - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class PersonnelController : V3AuthenticatedApiControllerbase - { - #region Members and Constructors - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly IDepartmentSettingsService _departmentSettingsService; - - public PersonnelController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - IDepartmentSettingsService departmentSettingsService - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _departmentSettingsService = departmentSettingsService; - } - #endregion Members and Constructors - - /// - /// Get's all the personnel in a department and their current status and staffing information with a filter - /// - /// - /// $ curl https://api.resgrid.com/api/v2/Personnel/GetPersonnelStatuses -u VXNlck5hbWV8MXxBQkNE: - /// - /// List of PersonnelStatusResult objects, with status and staffing information for each user. - [HttpGet("GetPersonnelStatuses")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetPersonnelStatuses(string activeFilter) - { - var results = new List(); - - string[] activeFilters = null; - if (!String.IsNullOrWhiteSpace(activeFilter)) - { - var filter = HttpUtility.UrlDecode(activeFilter); - activeFilters = filter.Split(char.Parse("|")); - } - - var filters = await GetFilterOptions(); - var actionLogs = await _actionLogsService.GetLastActionLogsForDepartmentAsync(DepartmentId); - var userStates = await _userStateService.GetLatestStatesForDepartmentAsync(DepartmentId); - //var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - - var users = await _usersService.GetUserGroupAndRolesByDepartmentIdInLimitAsync(DepartmentId, false, false, false); - - - Department department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - //var allGroups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - //var allRoles = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - - var personnelSortOrder = await _departmentSettingsService.GetDepartmentPersonnelSortOrderAsync(DepartmentId); - var personnelStatusSortOrder = await _departmentSettingsService.GetDepartmentPersonnelListStatusSortOrderAsync(DepartmentId); - - foreach (var u in users) - { - var log = (from l in actionLogs - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var state = (from l in userStates - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var s = new PersonnelStatusResult(); - s.Uid = u.UserId.ToString(); - - if (log != null) - { - s.Atp = log.ActionTypeId; - s.Atm = log.Timestamp.TimeConverter(department); - - if (log.DestinationId.HasValue) - { - if (log.ActionTypeId == (int)ActionTypes.RespondingToScene) - s.Did = log.DestinationId.Value.ToString(); - else if (log.ActionTypeId == (int)ActionTypes.RespondingToStation) - s.Did = log.DestinationId.Value.ToString(); - else if (log.ActionTypeId == (int)ActionTypes.AvailableStation) - s.Did = log.DestinationId.Value.ToString(); - } - } - else - { - s.Atp = (int)ActionTypes.StandingBy; - s.Atm = DateTime.UtcNow.TimeConverter(department); - } - - if (state != null) - { - s.Ste = state.State; - s.Stm = state.Timestamp.TimeConverter(department); - } - else - { - s.Ste = (int)UserStateTypes.Available; - s.Stm = DateTime.UtcNow.TimeConverter(department); - } - - //DepartmentGroup userGroup = null; - //if (allGroups.ContainsKey(u.UserId)) - // userGroup = allGroups[u.UserId]; - - //var roles = new List(); - //if (allRoles.ContainsKey(u.UserId)) - // roles = allRoles[u.UserId]; - - if (u.DepartmentGroupId.HasValue) - s.Gid = u.DepartmentGroupId.Value; - - if (log != null) - { - if (personnelStatusSortOrder != null && personnelStatusSortOrder.Any()) - { - var statusSorting = personnelStatusSortOrder.FirstOrDefault(x => x.StatusId == log.ActionTypeId); - if (statusSorting != null) - s.Weight = statusSorting.Weight; - else - s.Weight = 9000; - } - else - { - s.Weight = 9000; - } - } - else - s.Weight = 9000; - - if (activeFilter != null && activeFilter.Any()) - { - foreach (var afilter in activeFilters) - { - var text = GetTextValue(afilter, filters); - - if (afilter.Substring(0, 2) == "G:") - { - if (u.DepartmentGroupName != null && text == u.DepartmentGroupName) - { - results.Add(s); - break; - } - } - else if (afilter.Substring(0, 2) == "R:") - { - if (u.RoleNamesList.Any(x => x == text)) - { - results.Add(s); - break; - } - } - else if (afilter.Substring(0, 2) == "U:") - { - if (s.Ste.ToString() == text || s.Ste.ToString() == text.Replace(" ", "")) - { - results.Add(s); - break; - } - } - - } - } - else - { - results.Add(s); - } - } - - switch (personnelSortOrder) - { - case PersonnelSortOrders.Default: - results = results.OrderBy(x => x.Weight).ToList(); - break; - case PersonnelSortOrders.FirstName: - results = results.OrderBy(x => x.Weight).ThenBy(x => users.First(y => y.UserId == x.Uid).FirstName).ToList(); - break; - case PersonnelSortOrders.LastName: - results = results.OrderBy(x => x.Weight).ThenBy(x => users.First(y => y.UserId == x.Uid).LastName).ToList(); - break; - case PersonnelSortOrders.Group: - results = results.OrderBy(x => x.Weight).ThenBy(x => x.Gid).ToList(); - break; - default: - results = results.OrderBy(x => x.Weight).ToList(); - break; - } - - return Ok(results); - } - - /// - /// Gets information about a specific person - /// - /// UserId of the person to get info for - /// PersonnelInfoResult with information pertaining to that user - [HttpGet("GetPersonnelInfo")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetPersonnelInfo(string userId) - { - var result = new PersonnelInfoResult(); - var user = _usersService.GetUserById(userId); - - - if (user == null) - return NotFound(); - - var department = await _departmentsService.GetDepartmentByUserIdAsync(user.UserId); - - if (department == null) - return NotFound(); - - if (department.DepartmentId != DepartmentId) - return Unauthorized(); - - var profile = await _userProfileService.GetProfileByUserIdAsync(user.UserId); - var group = await _departmentGroupsService.GetGroupForUserAsync(user.UserId, DepartmentId); - var roles = await _personnelRolesService.GetRolesForUserAsync(user.UserId, DepartmentId); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - result.Eml = user.Email; - result.Did = department.DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - result.Roles.Add(role.Name); - } - } - - var action = await _actionLogsService.GetLastActionLogForUserAsync(user.UserId, DepartmentId); - var userState = await _userStateService.GetLastUserStateByUserIdAsync(user.UserId); - - result.Ats = (int)ActionTypes.StandingBy; - result.Stf = userState.State; - result.Stm = userState.Timestamp.TimeConverter(department); - - if (action == null) - { - result.Stm = DateTime.UtcNow.TimeConverter(department); - } - else - { - result.Ats = action.ActionTypeId; - result.Atm = action.Timestamp.TimeConverter(department); - - if (action.DestinationId.HasValue) - { - if (action.ActionTypeId == (int)ActionTypes.RespondingToScene) - result.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.RespondingToStation) - result.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.AvailableStation) - result.Did = action.DestinationId.Value; - } - } - - return Ok(result); - } - - private string GetTextValue(string filter, List filters) - { - return filters.Where(x => x.Id == filter).Select(y => y.Name).FirstOrDefault(); - } - - private async Task> GetFilterOptions() - { - var result = new List(); - - var stations = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var roles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - - foreach (var s in stations) - { - var respondingTo = new FilterResult(); - respondingTo.Id = string.Format("G:{0}", s.DepartmentGroupId); - respondingTo.Type = "Group"; - respondingTo.Name = s.Name; - - result.Add(respondingTo); - } - - foreach (var r in roles) - { - var respondingTo = new FilterResult(); - respondingTo.Id = string.Format("R:{0}", r.PersonnelRoleId); - respondingTo.Type = "Role"; - respondingTo.Name = r.Name; - - result.Add(respondingTo); - } - - var status1 = new FilterResult(); - status1.Id = string.Format("U:{0}", (int)UserStateTypes.Available); - status1.Type = "Staffing"; - status1.Name = UserStateTypes.Available.GetDisplayString(); - result.Add(status1); - - var status2 = new FilterResult(); - status2.Id = string.Format("U:{0}", (int)UserStateTypes.Delayed); - status2.Type = "Staffing"; - status2.Name = UserStateTypes.Delayed.GetDisplayString(); - result.Add(status2); - - var status3 = new FilterResult(); - status3.Id = string.Format("U:{0}", (int)UserStateTypes.Committed); - status3.Type = "Staffing"; - status3.Name = UserStateTypes.Committed.GetDisplayString(); - result.Add(status3); - - var status4 = new FilterResult(); - status4.Id = string.Format("U:{0}", (int)UserStateTypes.OnShift); - status4.Type = "Staffing"; - status4.Name = UserStateTypes.OnShift.GetDisplayString(); - result.Add(status4); - - var status5 = new FilterResult(); - status5.Id = string.Format("U:{0}", (int)UserStateTypes.Unavailable); - status5.Type = "Staffing"; - status5.Name = UserStateTypes.Unavailable.GetDisplayString(); - result.Add(status5); - - return result; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/ProfileController.cs b/Web/Resgrid.Web.Services/Controllers/v3/ProfileController.cs deleted file mode 100644 index 588c86dd..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/ProfileController.cs +++ /dev/null @@ -1,265 +0,0 @@ -using Resgrid.Model; -using Resgrid.Model.Services; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Controllers.Version3.Models.Profile; -using Resgrid.Model.Events; -using Resgrid.Framework; -using Resgrid.Model.Providers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against a logged in users (determined via the token) profile - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class ProfileController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly ILimitsService _limitsService; - private readonly IUserProfileService _userProfileService; - private readonly IAuthorizationService _authorizationService; - private readonly IAddressService _addressService; - private readonly IEventAggregator _eventAggregator; - - public ProfileController(IUsersService usersService, IDepartmentsService departmentsService, ILimitsService limitsService, - IUserProfileService userProfileService, IAuthorizationService authorizationService, IAddressService addressService, - IEventAggregator eventAggregator) - { - _usersService = usersService; - _departmentsService = departmentsService; - _limitsService = limitsService; - _userProfileService = userProfileService; - _authorizationService = authorizationService; - _addressService = addressService; - _eventAggregator = eventAggregator; - } - - /// - /// Gets the mobile carriers in the Resgrid system. If you need a mobile carrier added contact team@resgrid.com. - /// - /// - [HttpGet("GetMobileCarriers")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult> GetMobileCarriers() - { - var carriers = new List(); - - foreach (var field in typeof(MobileCarriers).GetFields()) - { - DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; - - if (attribute == null) - continue; - - carriers.Add(new MobileCarriersResult() - { - Cid = (int)field.GetValue(null), - Nme = attribute.Description - }); - } - - return Ok(carriers); - } - - /// - /// Gets the time zones in the Resgrid system. If you need a time zone added or corrected contact team@resgrid.com. - /// - /// - [HttpGet("GetTimeZones")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult> GetTimeZones() - { - return Ok(TimeZones.Zones.Select(zone => new TimeZoneResult() - { - Id = zone.Key, Nme = zone.Value - }).ToList()); - } - - /// - /// Gets the Resgrid user profile for the user - /// - /// ProfileResult object with the users profile data - [HttpGet("GetProfile")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetProfile() - { - var profile = await _userProfileService.GetProfileByUserIdAsync(UserId.ToUpper(), true); - - if (profile == null) - return NotFound(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var dm = await _departmentsService.GetDepartmentMemberAsync(UserId.ToUpper(), DepartmentId); - var membership = _usersService.GetMembershipByUserId(UserId.ToUpper()); - - var result = new ProfileResult - { - Uid = UserId.ToUpper().ToString(), - Adm = department.IsUserAnAdmin(UserId.ToUpper()), - Hid = dm.IsHidden.GetValueOrDefault(), - Dis = dm.IsDisabled.GetValueOrDefault(), - Fnm = profile.FirstName, - Lnm = profile.LastName, - Eml = membership.Email, - Tz = profile.TimeZone, - Mob = profile.MobileNumber, - Moc = profile.MobileCarrier, - Hmn = profile.HomeNumber, - Sce = profile.SendEmail, - Scp = profile.SendPush, - Scs = profile.SendSms, - Sme = profile.SendMessageEmail, - Smp = profile.SendMessagePush, - Sms = profile.SendMessageSms, - Sne = profile.SendNotificationEmail, - Snp = profile.SendNotificationPush, - Sns = profile.SendNotificationSms, - Id = profile.IdentificationNumber, - Val = await _limitsService.CanDepartmentUseVoiceAsync(DepartmentId), - Voc = profile.VoiceForCall, - Vcm = profile.VoiceCallMobile, - Vch = profile.VoiceCallHome, - Lup = profile.LastUpdated - }; - - if (membership.LockoutEnd.HasValue) - result.Lkd = true; - else - result.Lkd = false; - - if (profile.HomeAddressId.HasValue) - { - var address = await _addressService.GetAddressByIdAsync(profile.HomeAddressId.Value); - - if (address != null) - { - result.Hme = new AddressResult() - { - Aid = address.AddressId, - Str = address.Address1, - Cty = address.City, - Ste = address.State, - Zip = address.PostalCode, - Cnt = address.Country - }; - } - } - - if (profile.MailingAddressId.HasValue) - { - var address = await _addressService.GetAddressByIdAsync(profile.MailingAddressId.Value); - - if (address != null) - { - result.Mal = new AddressResult() - { - Aid = address.AddressId, - Str = address.Address1, - Cty = address.City, - Ste = address.State, - Zip = address.PostalCode, - Cnt = address.Country - }; - } - } - - return Ok(result); - } - - /// - /// Toggles a users profile to enable/disable custom push sounds when the app is backgrounded. - /// - /// An HTTP Result - [HttpGet("ToggleCustomPushSounds")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult ToggleCustomPushSounds(bool enableCustomPushSounds, CancellationToken cancellationToken) - { - return Ok(); - } - - /// - /// Updates a users profile - /// - /// An HTTP Result - [HttpPost("UpdateProfile")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateProfile(UpdateProfileInput input, CancellationToken cancellationToken) - { - var result = Ok(); - - var profile = await _userProfileService.GetProfileByUserIdAsync(UserId.ToUpper()); - - if (profile == null) - return NotFound(); - - var auditEvent = new AuditEvent(); - auditEvent.DepartmentId = DepartmentId; - auditEvent.UserId = UserId; - auditEvent.Type = AuditLogTypes.ProfileUpdated; - auditEvent.Before = profile.CloneJsonToString(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - var dm = await _departmentsService.GetDepartmentMemberAsync(UserId.ToUpper(), DepartmentId); - var membership = _usersService.GetMembershipByUserId(UserId.ToUpper()); - - - if (!String.IsNullOrWhiteSpace(input.Email) && membership.Email != input.Email) - { - membership.Email = input.Email; - _usersService.SaveUser(membership); - } - - if (!String.IsNullOrWhiteSpace(input.FirstName) && profile.FirstName != input.FirstName) - profile.FirstName = input.FirstName; - - if (!String.IsNullOrWhiteSpace(input.LastName) && profile.LastName != input.LastName) - profile.LastName = input.LastName; - - if (profile.IdentificationNumber != input.Id) - profile.IdentificationNumber = input.Id; - - if (profile.HomeNumber != input.HomePhone) - profile.HomeNumber = input.HomePhone; - - if (input.MobileCarrier != 0 && !String.IsNullOrWhiteSpace(input.MobilePhone)) - { - profile.MobileCarrier = input.MobileCarrier; - profile.MobileNumber = input.MobilePhone; - } - - profile.SendSms = input.SendCallSms; - profile.SendPush = input.SendCallPush; - profile.SendEmail = input.SendCallEmail; - - profile.SendMessageSms = input.SendMessageSms; - profile.SendMessagePush = input.SendMessagePush; - profile.SendMessageEmail = input.SendMessageEmail; - - profile.SendNotificationSms = input.SendNotificationSms; - profile.SendNotificationPush = input.SendNotificationPush; - profile.SendNotificationEmail = input.SendNotificationEmail; - - await _userProfileService.SaveProfileAsync(DepartmentId, profile, cancellationToken); - _departmentsService.InvalidateDepartmentUsersInCache(department.DepartmentId); - - auditEvent.After = profile.CloneJsonToString(); - _eventAggregator.SendMessage(auditEvent); - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/ProtocolsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/ProtocolsController.cs deleted file mode 100644 index 22b33eb4..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/ProtocolsController.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Collections.Generic; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Protocols; -using Newtonsoft.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against dispatch protocols that are established in a department - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class ProtocolsController : V3AuthenticatedApiControllerbase - { - private readonly IDepartmentsService _departmentsService; - private readonly IProtocolsService _protocolsService; - - public ProtocolsController(IDepartmentsService departmentsService, IProtocolsService protocolsService) - { - _departmentsService = departmentsService; - _protocolsService = protocolsService; - } - - /// - /// Get's all the protocols for a department - /// - /// List of ProtocolResult objects. - [HttpGet("GetAllProtocols")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllProtocols() - { - var results = new List(); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - - var protocols = await _protocolsService.GetAllProtocolsForDepartmentAsync(DepartmentId); - - foreach (var p in protocols) - { - results.Add(ProtocolResult.Convert(p)); - } - - return Ok(results); - } - - /// - /// Get's all the protocols for a department - /// - /// List of ProtocolResult objects. - [HttpGet("GetProtocol")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task GetProtocol(int protocolId) - { - var protocol = await _protocolsService.GetProtocolByIdAsync(protocolId); - - if (protocol == null) - return NotFound(); - - if (protocol.DepartmentId != DepartmentId) - return Unauthorized(); - - var result = ProtocolResult.Convert(protocol); - - - return Ok(result); - } - - /// - /// Gets a protocol attachment by it's id - /// - /// ID of the protocol attachment - /// - [HttpGet("GetFile")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task GetFile(int protocolAttachmentId) - { - var result = Ok(); - - var attachment = await _protocolsService.GetAttachmentByIdAsync(protocolAttachmentId); - - if (attachment == null) - return NotFound(); - - var protocol = await _protocolsService.GetProtocolByIdAsync(attachment.DispatchProtocolId); - - if (protocol == null || protocol.DepartmentId != DepartmentId) - return Unauthorized(); - - return File(attachment.Data, attachment.FileType); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/SecurityController.cs b/Web/Resgrid.Web.Services/Controllers/v3/SecurityController.cs deleted file mode 100644 index e6bbce3f..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/SecurityController.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using Resgrid.Model; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Security; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against the security sub-system - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class SecurityController : V3AuthenticatedApiControllerbase - { - private readonly IDepartmentsService _departmentsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPermissionsService _permissionsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly IFirebaseService _firebaseService; - - /// - /// Operations to perform against the security sub-system - /// - public SecurityController(IDepartmentsService departmentsService, IDepartmentGroupsService departmentGroupsService, - IPermissionsService permissionsService, IPersonnelRolesService personnelRolesService, IFirebaseService firebaseService) - { - _departmentsService = departmentsService; - _departmentGroupsService = departmentGroupsService; - _permissionsService = permissionsService; - _personnelRolesService = personnelRolesService; - _firebaseService = firebaseService; - } - - /// - /// Gets the current users department rights - /// - /// DepartmentRightsResult object with the department rights and group memberships - [HttpGet("GetCurrentUsersRights")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> GetCurrentUsersRights() - { - var result = new DepartmentRightsResult(); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var departmentMembership = await _departmentsService.GetDepartmentMemberAsync(UserId, DepartmentId, false); - var roles = await _personnelRolesService.GetRolesForUserAsync(UserId, DepartmentId); - - if (departmentMembership == null) - return Unauthorized(); - - if (departmentMembership.IsAdmin.HasValue) - result.Adm = departmentMembership.IsAdmin.Value; - - if (department.ManagingUserId == UserId) - result.Adm = true; - - bool isGroupAdmin = false; - result.Grps = new List(); - - var group = await _departmentGroupsService.GetGroupForUserAsync(UserId, DepartmentId); - - if (group != null) - { - var groupRight = new GroupRight(); - groupRight.Gid = group.DepartmentGroupId; - groupRight.Adm = group.IsUserGroupAdmin(UserId); - - if (groupRight.Adm) - isGroupAdmin = true; - - result.Grps.Add(groupRight); - } - - var createCallPermission = await _permissionsService.GetPermissionByDepartmentTypeAsync(DepartmentId, PermissionTypes.CreateCall); - var viewPIIPermission = await _permissionsService.GetPermissionByDepartmentTypeAsync(DepartmentId, PermissionTypes.ViewPersonalInfo); - var createNotePermission = await _permissionsService.GetPermissionByDepartmentTypeAsync(DepartmentId, PermissionTypes.CreateNote); - var createMessagePermission = await _permissionsService.GetPermissionByDepartmentTypeAsync(DepartmentId, PermissionTypes.CreateMessage); - - result.VPii = _permissionsService.IsUserAllowed(viewPIIPermission, result.Adm, isGroupAdmin, roles); - result.CCls = _permissionsService.IsUserAllowed(createCallPermission, result.Adm, isGroupAdmin, roles); - result.ANot = _permissionsService.IsUserAllowed(createNotePermission, result.Adm, isGroupAdmin, roles); - result.CMsg = _permissionsService.IsUserAllowed(createMessagePermission, result.Adm, isGroupAdmin, roles); - - if (!String.IsNullOrWhiteSpace(Config.FirebaseConfig.ResponderJsonFile) && !String.IsNullOrWhiteSpace(Config.FirebaseConfig.ResponderProjectEmail)) - { - result.FirebaseApiToken = await _firebaseService.CreateTokenAsync(UserId, null); - } - - return result; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/ShiftsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/ShiftsController.cs deleted file mode 100644 index c3b32180..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/ShiftsController.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Mime; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Shifts; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against shifts in a department - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class ShiftsController : V3AuthenticatedApiControllerbase - { - private readonly IShiftsService _shiftsService; - private readonly IUsersService _usersService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IDepartmentGroupsService _departmentGroupsService; - - public ShiftsController( - IShiftsService shiftsService, - IUsersService usersService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IPersonnelRolesService personnelRolesService, - IDepartmentGroupsService departmentGroupsService - ) - { - _usersService = usersService; - _shiftsService = shiftsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _personnelRolesService = personnelRolesService; - _departmentGroupsService = departmentGroupsService; - } - - /// - /// Get's all the shifts in a department - /// - /// List of ShiftResult objects. - [HttpGet("GetShifts")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetShifts() - { - var results = new List(); - - var shifts = await _shiftsService.GetAllShiftsByDepartmentAsync(DepartmentId); - - foreach (var s in shifts) - { - var shiftData = await _shiftsService.PopulateShiftData(s, true, true, true, false, false); - - var shift = new ShiftResult(); - shift.Id = shiftData.ShiftId; - shift.Name = shiftData.Name; - shift.Code = shiftData.Code; - shift.Color = shiftData.Color; - shift.SType = shiftData.ScheduleType; - shift.AType = shiftData.AssignmentType; - - if (shiftData.Personnel != null) - shift.PCount = shiftData.Personnel.Count; - - if (shiftData.Groups != null) - shift.GCount = shiftData.Groups.Count; - - var nextDay = shiftData.GetNextShiftDayforDateTime(DateTime.UtcNow); - - if (nextDay != null) - { - shift.NextDay = nextDay.Day.ToString("O"); - shift.NextDayId = nextDay.ShiftDayId; - } - - if (s.Personnel != null && shiftData.Personnel.Any(x => x.UserId == UserId)) - shift.InShift = true; - - results.Add(shift); - } - - return Ok(results); - } - - /// - /// Get's all the shifts in a department - /// - /// List of ShiftResult objects. - [HttpGet("GetShift")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task GetShift(int id) - { - var shift = await _shiftsService.GetShiftByIdAsync(id); - - if (shift != null) - if (shift.DepartmentId != DepartmentId) - return Unauthorized(); - - return Ok(shift); - } - - /// - /// Get's all the shift days for today - /// - /// List of ShiftDayResult objects. - [HttpGet("GetTodaysShifts")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetTodaysShifts() - { - var result = new List(); - var days = await _shiftsService.GetShiftDaysForDayAsync(DateTime.UtcNow, DepartmentId); - - foreach (var shiftDay in days) - { - shiftDay.Shift = await _shiftsService.GetShiftByIdAsync(shiftDay.ShiftId); - var dayResult = new ShiftDayResult(); - - dayResult.ShiftDayId = shiftDay.ShiftDayId; - dayResult.ShiftId = shiftDay.ShiftId; - dayResult.ShiftName = shiftDay.Shift.Name; - dayResult.ShitDay = shiftDay.Day; - dayResult.Start = shiftDay.Start; - dayResult.End = shiftDay.End; - dayResult.ShiftType = shiftDay.Shift.AssignmentType; - - var needs = await _shiftsService.GetShiftDayNeedsAsync(shiftDay.ShiftDayId); - var personnelRoles = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var signups = await _shiftsService.GetShiftSignpsForShiftDayAsync(shiftDay.ShiftDayId); - - dayResult.SignedUp = await _shiftsService.IsUserSignedUpForShiftDayAsync(shiftDay, UserId, null); - - dayResult.Signups = new List(); - foreach (var signup in signups) - { - if (!signup.Denied) - { - var signupResult = new ShiftDaySignupResult(); - signupResult.UserId = signup.UserId; - signupResult.Roles = personnelRoles[signup.UserId].Select(x => x.PersonnelRoleId).ToList(); - - dayResult.Signups.Add(signupResult); - } - - } - - if (needs != null && needs.Any()) - { - dayResult.Needs = new List(); - foreach (var need in needs.Keys) - { - var dayNeed = new ShiftDayGroupNeedsResult(); - dayNeed.GroupId = need; - - dayNeed.GroupNeeds = new List(); - foreach (var dNeed in needs[need]) - { - var groupNeed = new ShiftDayGroupRoleNeedsResult(); - groupNeed.RoleId = dNeed.Key; - groupNeed.Needed = dNeed.Value; - - dayNeed.GroupNeeds.Add(groupNeed); - } - - dayResult.Needs.Add(dayNeed); - } - } - - result.Add(dayResult); - } - - return Ok(result); - } - - /// - /// Get's all the shifts in a department - /// - /// List of ShiftResult objects. - [HttpGet("GetShiftDay")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetShiftDay(int id) - { - var result = new ShiftDayResult(); - - var shiftDay = await _shiftsService.GetShiftDayByIdAsync(id); - - result.ShiftDayId = id; - result.ShiftId = shiftDay.ShiftId; - result.ShiftName = shiftDay.Shift.Name; - result.ShitDay = shiftDay.Day; - result.Start = shiftDay.Start; - result.End = shiftDay.End; - result.ShiftType = shiftDay.Shift.AssignmentType; - - var needs = await _shiftsService.GetShiftDayNeedsAsync(id); - var personnelRoles = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var signups = await _shiftsService.GetShiftSignpsForShiftDayAsync(id); - - result.SignedUp = await _shiftsService.IsUserSignedUpForShiftDayAsync(shiftDay, UserId, null); - - result.Signups = new List(); - foreach (var signup in signups) - { - if (!signup.Denied) - { - var signupResult = new ShiftDaySignupResult(); - signupResult.UserId = signup.UserId; - signupResult.Roles = personnelRoles[signup.UserId].Select(x => x.PersonnelRoleId).ToList(); - - result.Signups.Add(signupResult); - } - - } - - if (needs != null && needs.Any()) - { - result.Needs = new List(); - foreach (var need in needs.Keys) - { - var dayNeed = new ShiftDayGroupNeedsResult(); - dayNeed.GroupId = need; - - dayNeed.GroupNeeds = new List(); - foreach (var dNeed in needs[need]) - { - var groupNeed = new ShiftDayGroupRoleNeedsResult(); - groupNeed.RoleId = dNeed.Key; - groupNeed.Needed = dNeed.Value; - - dayNeed.GroupNeeds.Add(groupNeed); - } - - result.Needs.Add(dayNeed); - } - } - - return Ok(result); - } - - [HttpPost("SignupForShiftDay")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task SignupForShiftDay(ShiftDaySignupInput input) - { - var shiftDay = await _shiftsService.GetShiftDayByIdAsync(input.ShiftDayId); - - if (shiftDay == null) - return NotFound(); - - if (shiftDay.Shift != null && shiftDay.Shift.DepartmentId != DepartmentId) - return Unauthorized(); - - var signup = await _shiftsService.SignupForShiftDayAsync(shiftDay.ShiftId, shiftDay.Day, input.GroupId, UserId); - - return CreatedAtAction(nameof(SignupForShiftDay), new { id = signup.ShiftSignupId }, signup); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/StaffingController.cs b/Web/Resgrid.Web.Services/Controllers/v3/StaffingController.cs deleted file mode 100644 index 196e8ea2..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/StaffingController.cs +++ /dev/null @@ -1,151 +0,0 @@ -using Resgrid.Framework; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Staffing; -using System; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Model; -using Resgrid.Model.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against user statuses and their actions - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class StaffingController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserStateService _userStateService; - private readonly IUserProfileService _userProfileService; - private readonly IAuthorizationService _authorizationService; - - public StaffingController( - IUsersService usersService, - IDepartmentsService departmentsService, - IUserStateService userStateService, - IUserProfileService userProfileService, - IAuthorizationService authorizationService) - { - _usersService = usersService; - _departmentsService = departmentsService; - _userStateService = userStateService; - _userProfileService = userProfileService; - _authorizationService = authorizationService; - } - - /// - /// Gets the current staffing level (state) for the user - /// - /// StateResult object with the users current staffing level - [HttpGet("GetCurrentStaffing")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetCurrentStaffing() - { - var profile = await _userProfileService.GetProfileByUserIdAsync(UserId); - - if (profile == null) - return Unauthorized(); - - var userState = await _userStateService.GetLastUserStateByUserIdAsync(UserId); - - var result = new StaffingResult - { - Uid = UserId.ToString(), - Nme = profile.FullName.AsFirstNameLastName, - Typ = userState.State, - Tms = userState.Timestamp.TimeConverter(await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false)), - Not = userState.Note - }; - - return Ok(result); - } - - /// - /// Sets the staffing level (state) for the current user. - /// - /// StateInput object with the State to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("SetStaffing")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SetStaffing(StaffingInput staffingInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - UserState savedState = null; - - if (String.IsNullOrWhiteSpace(staffingInput.Not)) - savedState = await _userStateService.CreateUserState(UserId, DepartmentId, staffingInput.Typ, cancellationToken); - else - savedState = await _userStateService.CreateUserState(UserId, DepartmentId, staffingInput.Typ, staffingInput.Not, cancellationToken); - - return CreatedAtAction(nameof(SetStaffing), new { id = savedState.UserStateId }, savedState); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - /// - /// Sets the staffing level (state) for the UserId specificed in the input data. - /// - /// StateInput object with the State to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPut("SetStaffingForUser")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SetStaffingForUser(StaffingInput staffingInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - UserState savedState = null; - var userToSetStatusFor = await _departmentsService.GetDepartmentMemberAsync(staffingInput.Uid, DepartmentId); - - if (userToSetStatusFor == null) - return NotFound(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(staffingInput.Uid, DepartmentId)) - return Unauthorized(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(userToSetStatusFor.UserId, DepartmentId)) - return Unauthorized(); - - // TODO: We need to check here if the user is a department admin, or the admin that the user is a part of - - if (String.IsNullOrWhiteSpace(staffingInput.Not)) - savedState = await _userStateService.CreateUserState(userToSetStatusFor.UserId, DepartmentId, staffingInput.Typ, cancellationToken); - else - savedState = await _userStateService.CreateUserState(userToSetStatusFor.UserId, DepartmentId, staffingInput.Typ, staffingInput.Not, cancellationToken); - - return CreatedAtAction(nameof(SetStaffingForUser), new { id = savedState.UserStateId }, savedState); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/StaffingSchedulesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/StaffingSchedulesController.cs deleted file mode 100644 index 7a4a1fc9..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/StaffingSchedulesController.cs +++ /dev/null @@ -1,264 +0,0 @@ -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Services; -using System; -using System.Collections.Generic; -using System.Text; -using Resgrid.Web.Services.Controllers.Version3.Models.StaffingSchedules; -using System.Globalization; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against user statuses and their actions - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class StaffingSchedulesController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserStateService _userStateService; - private readonly IUserProfileService _userProfileService; - private readonly IAuthorizationService _authorizationService; - private readonly IScheduledTasksService _scheduledTasksService; - - public StaffingSchedulesController( - IUsersService usersService, - IDepartmentsService departmentsService, - IUserStateService userStateService, - IUserProfileService userProfileService, - IAuthorizationService authorizationService, - IScheduledTasksService scheduledTasksService) - { - _usersService = usersService; - _departmentsService = departmentsService; - _userStateService = userStateService; - _userProfileService = userProfileService; - _authorizationService = authorizationService; - _scheduledTasksService = scheduledTasksService; - } - - /// - /// Gets the current staffing level (state) for the user - /// - /// StateResult object with the users current staffing level - [HttpGet("GetStaffingSchedules")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetStaffingSchedules() - { - var results = new List(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var tasks = await _scheduledTasksService.GetScheduledStaffingTasksForUserAsync(UserId); - - foreach (var task in tasks) - { - var st = new StaffingScheduleResult(); - st.Id = task.ScheduledTaskId; - if (task.ScheduleType == (int)ScheduleTypes.Weekly) - st.Typ = "Weekly"; - else - st.Typ = "Date"; - - if (task.SpecifcDate.HasValue) - st.Spc = TimeConverterHelper.TimeConverter(task.SpecifcDate.Value, department); - - st.Act = task.Active; - - var days = new StringBuilder(); - - if (task.Monday) - days.Append("M"); - - if (task.Tuesday) - days.Append("T"); - - if (task.Wednesday) - days.Append("W"); - - if (task.Thursday) - days.Append("Th"); - - if (task.Friday) - days.Append("F"); - - if (task.Saturday) - days.Append("S"); - - if (task.Sunday) - days.Append("Su"); - - days.Append(" @ " + task.Time); - - if (task.ScheduleType == (int)ScheduleTypes.Weekly) - st.Dow = days.ToString(); - - st.Data = task.Data; - - results.Add(st); - } - - return Ok(results); - } - - /// - /// Toggles and Scheduled Staffing Level Change (Enabling or Disabling It) - /// - /// StateInput object with the Staffing to toggle and it's value. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPut("ToggleStaffingSchedule")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task ToggleStaffingSchedule(ToggleStaffingScheduleInput toggleInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - var staffingSchedule = await _scheduledTasksService.GetScheduledTaskByIdAsync(toggleInput.Id); - - if (staffingSchedule == null) - return NotFound(); - - if (staffingSchedule.UserId != UserId) - return Unauthorized(); - - staffingSchedule.Active = toggleInput.Act; - var task = await _scheduledTasksService.SaveScheduledTaskAsync(staffingSchedule); - - return CreatedAtAction(nameof(ToggleStaffingSchedule), new { id = task.IdValue }, task); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - /// - /// Toggles and Scheduled Staffing Level Change (Enabling or Disabling It) - /// - /// StateInput object with the Staffing to toggle and it's value. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("CreateStaffingSchedule")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task CreateStaffingSchedule(StaffingScheduleInput staffingScheduleInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - var task = new ScheduledTask(); - task.UserId = UserId; - - if (staffingScheduleInput.Typ == 1) - { - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - DateTime inputDate = DateTime.Parse(staffingScheduleInput.Spd); - - task.ScheduleType = (int)ScheduleTypes.SpecifcDateTime; - - string[] timeParts = new List().ToArray(); - timeParts = staffingScheduleInput.Spt.Split(char.Parse(":")); - - var dateOffset = new DateTimeOffset(inputDate.Year, inputDate.Month, inputDate.Day, int.Parse(timeParts[0]), int.Parse(timeParts[1]), 0, TimeConverterHelper.GetOffsetForDepartment(department)); - - task.SpecifcDate = dateOffset.UtcDateTime; - } - else - { - task.ScheduleType = (int)ScheduleTypes.Weekly; - - if (staffingScheduleInput.Spt.Contains("AM") || staffingScheduleInput.Spt.Contains("PM")) - { - task.Time = staffingScheduleInput.Spt; - } - else - { - var timeFromInput = DateTime.ParseExact(staffingScheduleInput.Spt, "H:m", null, DateTimeStyles.None); - string time12Hour = timeFromInput.ToString("t", CultureInfo.CreateSpecificCulture("en-us")); - - task.Time = time12Hour; - } - } - - task.Sunday = staffingScheduleInput.Sun; - task.Monday = staffingScheduleInput.Mon; - task.Tuesday = staffingScheduleInput.Tue; - task.Wednesday = staffingScheduleInput.Wed; - task.Thursday = staffingScheduleInput.Thu; - task.Friday = staffingScheduleInput.Fri; - task.Saturday = staffingScheduleInput.Sat; - task.AddedOn = DateTime.UtcNow; - task.Active = true; - task.Data = staffingScheduleInput.Ste; - task.TaskType = (int)TaskTypes.UserStaffingLevel; - task.Note = staffingScheduleInput.Not; - - var saved = await _scheduledTasksService.SaveScheduledTaskAsync(task, cancellationToken); - - return CreatedAtAction(nameof(CreateStaffingSchedule), new { id = saved.IdValue }, saved); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - [HttpDelete("DeleteStaffingSchedule")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeleteStaffingSchedule(int staffingSecheduleId) - { - if (this.ModelState.IsValid) - { - try - { - var staffingSchedule = await _scheduledTasksService.GetScheduledTaskByIdAsync(staffingSecheduleId); - - if (staffingSchedule == null) - return NotFound(); - - if (staffingSchedule.UserId != UserId) - return Unauthorized(); - - await _scheduledTasksService.DeleteScheduledTask(staffingSecheduleId); - - return Ok(); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/StationsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/StationsController.cs deleted file mode 100644 index 5283b8f9..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/StationsController.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Stations; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations that can be performed against resgrid recipients, usually for sending messages - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class StationsController : V3AuthenticatedApiControllerbase - { - private ICallsService _callsService; - private IDepartmentsService _departmentsService; - private IUserProfileService _userProfileService; - private IGeoLocationProvider _geoLocationProvider; - private readonly IAuthorizationService _authorizationService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly IUnitsService _unitsService; - private readonly IActionLogsService _actionLogsService; - private readonly IUserStateService _userStateService; - - public StationsController( - ICallsService callsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IGeoLocationProvider geoLocationProvider, - IAuthorizationService authorizationService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - IUnitsService unitsService, - IActionLogsService actionLogsService, - IUserStateService userStateService) - { - _callsService = callsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _geoLocationProvider = geoLocationProvider; - _authorizationService = authorizationService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _unitsService = unitsService; - _actionLogsService = actionLogsService; - _userStateService = userStateService; - } - - /// - /// Returns all the available responding options (Calls/Stations) for the department - /// - /// Array of RecipientResult objects for each responding option in the department - [HttpGet("GetStationResources")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetStationResources() - { - var result = new List(); - - var unitStatuses = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - var actionLogs = await _actionLogsService.GetAllActionLogsForDepartmentAsync(DepartmentId); - var userStates = await _userStateService.GetLatestStatesForDepartmentAsync(DepartmentId); - var stations = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var userGroups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - Department department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - Parallel.ForEach(users, u => - { - var log = (from l in actionLogs - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var state = (from l in userStates - where l.UserId == u.UserId - select l).FirstOrDefault(); - - var s = new StationResult(); - s.Id = u.UserId.ToString(); - s.Typ = 1; - - if (log != null) - { - s.Sts = log.ActionTypeId; - s.Stm = log.Timestamp.TimeConverter(department); - - if (log.DestinationId.HasValue) - { - if (log.ActionTypeId == (int)ActionTypes.RespondingToStation) - { - s.Did = log.DestinationId.GetValueOrDefault(); - - var group = stations.First(x => x.DepartmentGroupId == log.DestinationId.Value); - s.Dnm = group.Name; - } - else if (log.ActionTypeId == (int)ActionTypes.AvailableStation) - { - s.Did = log.DestinationId.GetValueOrDefault(); - - var group = stations.First(x => x.DepartmentGroupId == log.DestinationId.Value); - s.Dnm = group.Name; - } - } - } - else - { - s.Sts = (int)ActionTypes.StandingBy; - s.Stm = DateTime.UtcNow.TimeConverter(department); - } - - if (s.Did == 0) - { - if (userGroups.ContainsKey(u.UserId)) - { - var homeGroup = userGroups[u.UserId]; - if (homeGroup != null && homeGroup.Type.HasValue && - ((DepartmentGroupTypes)homeGroup.Type) == DepartmentGroupTypes.Station) - { - s.Did = homeGroup.DepartmentGroupId; - s.Dnm = homeGroup.Name; - } - } - } - - if (state != null) - { - s.Ste = state.State; - s.Stt = state.Timestamp.TimeConverter(department); - } - else - { - s.Ste = (int)UserStateTypes.Available; - s.Stt = DateTime.UtcNow.TimeConverter(department); - } - - if (!String.IsNullOrWhiteSpace(s.Dnm)) - result.Add(s); - }); - - Parallel.ForEach(unitStatuses, unit => - { - var unitResult = new StationResult(); - var savedUnit = units.FirstOrDefault(x => x.UnitId == unit.UnitId); - - if (savedUnit != null) - { - unitResult.Id = savedUnit.UnitId.ToString(); - //unitResult.Nme = savedUnit.Name; - unitResult.Typ = 2; - unitResult.Sts = unit.State; - unitResult.Stm = unit.Timestamp.TimeConverter(department); - - if (savedUnit.StationGroupId.HasValue) - { - unitResult.Did = savedUnit.StationGroupId.Value; - unitResult.Dnm = stations.First(x => x.DepartmentGroupId == savedUnit.StationGroupId.Value).Name; - - result.Add(unitResult); - } - } - }); - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/StatusController.cs b/Web/Resgrid.Web.Services/Controllers/v3/StatusController.cs deleted file mode 100644 index c576848e..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/StatusController.cs +++ /dev/null @@ -1,302 +0,0 @@ -using System; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Events; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Providers.Bus; -using Resgrid.Web.Services.Controllers.Version3.Models.Status; -using Stripe; -using IAuthorizationService = Resgrid.Model.Services.IAuthorizationService; -using StatusResult = Resgrid.Web.Services.Controllers.Version3.Models.Status.StatusResult; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against user statuses and their actions - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class StatusController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IUserStateService _userStateService; - private readonly IAuthorizationService _authorizationService; - private readonly IOutboundEventProvider _outboundEventProvider; - private readonly IEventAggregator _eventAggregator; - - public StatusController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IDepartmentGroupsService departmentGroupsService, - IUserStateService userStateService, - IAuthorizationService authorizationService, - IOutboundEventProvider outboundEventProvider, - IEventAggregator eventAggregator) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _departmentGroupsService = departmentGroupsService; - _authorizationService = authorizationService; - _outboundEventProvider = outboundEventProvider; - _eventAggregator = eventAggregator; - } - - /// - /// Gets the status/action for the current user. User credentials are supplied via the Auth header. - /// - /// StatusResult object with the users current status - [HttpGet("GetCurrentUserStatus")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetCurrentUserStatus() - { - var action = await _actionLogsService.GetLastActionLogForUserAsync(UserId, DepartmentId); - var userState = await _userStateService.GetLastUserStateByUserIdAsync(UserId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var statusResult = new StatusResult - { - Act = (int)ActionTypes.StandingBy, - Uid = UserId.ToString(), - Ste = userState.State, - Sts = userState.Timestamp.TimeConverter(department) - }; - - if (action == null) - { - statusResult.Ats = DateTime.UtcNow.TimeConverter(department); - } - else - { - statusResult.Act = action.ActionTypeId; - statusResult.Ats = action.Timestamp.TimeConverter(department); - - if (action.DestinationId.HasValue) - { - if (action.ActionTypeId == (int)ActionTypes.RespondingToScene) - statusResult.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.RespondingToStation) - statusResult.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.AvailableStation) - statusResult.Did = action.DestinationId.Value; - } - } - - return Ok(statusResult); - } - - - [HttpGet("GetCurrentStatus")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetCurrentStatus() - { - var action = await _actionLogsService.GetLastActionLogForUserAsync(UserId, DepartmentId); - var userState = await _userStateService.GetLastUserStateByUserIdAsync(UserId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - var statusResult = new StatusResult - { - Act = (int)ActionTypes.StandingBy, - Uid = UserId.ToString(), - Ste = userState.State, - Sts = userState.Timestamp.TimeConverter(department) - }; - - if (action == null) - { - statusResult.Ats = DateTime.UtcNow.TimeConverter(department); - } - else - { - statusResult.Act = action.ActionTypeId; - statusResult.Ats = action.Timestamp.TimeConverter(department); - - if (action.DestinationId.HasValue) - { - if (action.ActionTypeId == (int)ActionTypes.RespondingToScene) - statusResult.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.RespondingToStation) - statusResult.Did = action.DestinationId.Value; - else if (action.ActionTypeId == (int)ActionTypes.AvailableStation) - statusResult.Did = action.DestinationId.Value; - } - } - - return Ok(statusResult); - } - - /// - /// - /// Sets the status/action for the current user. - /// - /// StatusInput object with the Status/Action to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("SetCurrentStatus")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SetCurrentStatus(StatusInput statusInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - ActionLog log = null; - if (statusInput.Rto == 0) - log = await _actionLogsService.SetUserActionAsync(UserId, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Not, cancellationToken); - else if (statusInput.Dtp == 0) - log = await _actionLogsService.SetUserActionAsync(UserId, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto, statusInput.Not, cancellationToken); - else - log = await _actionLogsService.SetUserActionAsync(UserId, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto, statusInput.Dtp, statusInput.Not, cancellationToken); - - //OutboundEventProvider.PersonnelStatusChangedTopicHandler handler = new OutboundEventProvider.PersonnelStatusChangedTopicHandler(); - //await handler.Handle(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - _eventAggregator.SendMessage(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - - return CreatedAtAction(nameof(SetCurrentStatus), new { id = log.ActionLogId }, log); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - /// - /// Sets the status/action for the UserId passed into the data posted - /// - /// StatusInput object with the Status/Action to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - //[System.Web.Http.AcceptVerbs(new string[] { "PUT", "POST"})] - [HttpPut("SetStatusForUser")] - [HttpPost("SetStatusForUser")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task SetStatusForUser(StatusInput statusInput, CancellationToken cancellationToken) - { - if (this.ModelState.IsValid) - { - try - { - var userToSetStatusFor = await _departmentsService.GetDepartmentMemberAsync(statusInput.Uid, DepartmentId); - - if (userToSetStatusFor == null) - return NotFound(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(statusInput.Uid, DepartmentId)) - return Unauthorized(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(userToSetStatusFor.UserId, DepartmentId)) - return Unauthorized(); - - if (DepartmentId != userToSetStatusFor.DepartmentId) - return Unauthorized(); - - // TODO: We need to check here if the user is a department admin, or the admin that the user is a part of - - ActionLog log = null; - if (statusInput.Rto == 0) - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo, cancellationToken); - else if (statusInput.Dtp == 0) - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto, statusInput.Not, cancellationToken); - else - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto, cancellationToken); - - - //OutboundEventProvider.PersonnelStatusChangedTopicHandler handler = new OutboundEventProvider.PersonnelStatusChangedTopicHandler(); - //await handler.Handle(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - _eventAggregator.SendMessage(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - - return CreatedAtAction(nameof(SetStatusForUser), new { id = log.ActionLogId }, log); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - - /// - /// Sets the status/action for the UserId passed into the data posted - /// - /// StatusInput object with the Status/Action to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - //[System.Web.Http.AcceptVerbs(new string[] { "PUT", "POST"})] - [HttpPost("PostStatusForUser")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task PostStatusForUser(StatusInput statusInput) - { - if (this.ModelState.IsValid) - { - try - { - var userToSetStatusFor = await _departmentsService.GetDepartmentMemberAsync(statusInput.Uid, DepartmentId); - - if (userToSetStatusFor == null) - return NotFound(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(statusInput.Uid, DepartmentId)) - return Unauthorized(); - - if (!await _authorizationService.IsUserValidWithinLimitsAsync(userToSetStatusFor.UserId, DepartmentId)) - return Unauthorized(); - - if (DepartmentId != userToSetStatusFor.DepartmentId) - return Unauthorized(); - - // TODO: We need to check here if the user is a department admin, or the admin that the user is a part of - - ActionLog log = null; - if (statusInput.Rto == 0) - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo); - else if (statusInput.Dtp == 0) - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto, statusInput.Not); - else - log = await _actionLogsService.SetUserActionAsync(statusInput.Uid, DepartmentId, statusInput.Typ, statusInput.Geo, statusInput.Rto); - - //OutboundEventProvider.PersonnelStatusChangedTopicHandler handler = new OutboundEventProvider.PersonnelStatusChangedTopicHandler(); - //await handler.Handle(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - _eventAggregator.SendMessage(new UserStatusEvent() { DepartmentId = DepartmentId, Status = log }); - - return CreatedAtAction(nameof(SetStatusForUser), new { id = log.ActionLogId }, log); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/UnitAppController.cs b/Web/Resgrid.Web.Services/Controllers/v3/UnitAppController.cs deleted file mode 100644 index 4f7f33d2..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/UnitAppController.cs +++ /dev/null @@ -1,537 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Resgrid.Model; -using Resgrid.Model.Helpers; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Calls; -using Resgrid.Web.Services.Controllers.Version3.Models.CoreData; -using Resgrid.Web.Services.Controllers.Version3.Models.Groups; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; -using Resgrid.Web.Services.Controllers.Version3.Models.Roles; -using Resgrid.Web.Services.Controllers.Version3.Models.Security; -using Resgrid.Web.Services.Controllers.Version3.Models.UnitApp; -using UnitInfoResult = Resgrid.Web.Services.Controllers.Version3.Models.Units.UnitInfoResult; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Controllers.Version3.Models.CallPriorities; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; -using Resgrid.Framework; -using Resgrid.Model.Events; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class UnitAppController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly ICallsService _callsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - private readonly IPersonnelRolesService _personnelRolesService; - private readonly ICustomStateService _customStateService; - private readonly IGeoLocationProvider _geoLocationProvider; - private readonly ICqrsProvider _cqrsProvider; - - public UnitAppController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - ICallsService callsService, - IDepartmentGroupsService departmentGroupsService, - IPersonnelRolesService personnelRolesService, - ICustomStateService customStateService, - IGeoLocationProvider geoLocationProvider, - ICqrsProvider cqrsProvider - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _callsService = callsService; - _departmentGroupsService = departmentGroupsService; - _personnelRolesService = personnelRolesService; - _customStateService = customStateService; - _geoLocationProvider = geoLocationProvider; - _cqrsProvider = cqrsProvider; - } - - [HttpGet("GetUnitAppCoreData")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetUnitAppCoreData() - { - var results = new UnitAppPayloadResult(); - results.Personnel = new List(); - results.Groups = new List(); - results.Units = new List(); - results.Roles = new List(); - results.Statuses = new List(); - results.Calls = new List(); - results.UnitStatuses = new List(); - results.UnitRoles = new List(); - results.Priorities = new List(); - results.Departments = new List(); - results.CallTypes = new List(); - - var users = await _departmentsService.GetAllUsersForDepartmentAsync(DepartmentId); - var groups = await _departmentGroupsService.GetAllDepartmentGroupsForDepartmentAsync(DepartmentId); - var rolesForUsersInDepartment = await _personnelRolesService.GetAllRolesForUsersInDepartmentAsync(DepartmentId); - var allRoles = await _personnelRolesService.GetRolesForDepartmentAsync(DepartmentId); - var allProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(DepartmentId); - var allGroups = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - var units = await _unitsService.GetUnitsForDepartmentAsync(DepartmentId); - var unitTypes = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId); - var callPriorites = await _callsService.GetCallPrioritiesForDepartmentAsync(DepartmentId); - var callTypes = await _callsService.GetCallTypesForDepartmentAsync(DepartmentId); - - - foreach (var user in users) - { - //var profile = _userProfileService.GetProfileByUserId(user.UserId); - //var group = _departmentGroupsService.GetGroupForUser(user.UserId); - - UserProfile profile = null; - if (allProfiles.ContainsKey(user.UserId)) - profile = allProfiles[user.UserId]; - - DepartmentGroup group = null; - if (groups.ContainsKey(user.UserId)) - group = groups[user.UserId]; - - //var roles = _personnelRolesService.GetRolesForUser(user.UserId); - - List roles = null; - if (rolesForUsersInDepartment.ContainsKey(user.UserId)) - roles = rolesForUsersInDepartment[user.UserId]; - - var result = new PersonnelInfoResult(); - - if (profile != null) - { - result.Fnm = profile.FirstName; - result.Lnm = profile.LastName; - result.Id = profile.IdentificationNumber; - result.Mnu = profile.MobileNumber; - } - else - { - result.Fnm = "Unknown"; - result.Lnm = "Check Profile"; - result.Id = ""; - result.Mnu = ""; - } - - result.Eml = user.Email; - result.Did = DepartmentId; - result.Uid = user.UserId.ToString(); - - if (group != null) - { - result.Gid = group.DepartmentGroupId; - result.Gnm = group.Name; - } - - result.Roles = new List(); - if (roles != null && roles.Count > 0) - { - foreach (var role in roles) - { - if (role != null) - result.Roles.Add(role.Name); - } - } - - results.Personnel.Add(result); - } - - - results.Rights = new DepartmentRightsResult(); - var currentUser = await _usersService.GetUserByNameAsync(UserName); - - if (currentUser == null) - return Unauthorized(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - results.Rights.Adm = department.IsUserAnAdmin(currentUser.UserId); - results.Rights.Grps = new List(); - - var currentGroup = await _departmentGroupsService.GetGroupForUserAsync(currentUser.UserId, DepartmentId); - - if (currentGroup != null) - { - var groupRight = new GroupRight(); - groupRight.Gid = currentGroup.DepartmentGroupId; - groupRight.Adm = currentGroup.IsUserGroupAdmin(currentUser.UserId); - - results.Rights.Grps.Add(groupRight); - } - - foreach (var group in allGroups) - { - var groupInfo = new GroupInfoResult(); - groupInfo.Gid = group.DepartmentGroupId; - groupInfo.Nme = group.Name; - - if (group.Type.HasValue) - groupInfo.Typ = group.Type.Value; - - if (group.Address != null) - groupInfo.Add = group.Address.FormatAddress(); - - results.Groups.Add(groupInfo); - } - - foreach (var unit in units) - { - var unitResult = new UnitInfoResult(); - unitResult.Uid = unit.UnitId; - unitResult.Did = DepartmentId; - unitResult.Nme = unit.Name; - unitResult.Typ = unit.Type; - - if (!string.IsNullOrWhiteSpace(unit.Type)) - { - var unitType = unitTypes.FirstOrDefault(x => x.Type == unit.Type); - - if (unitType != null) - unitResult.Cid = unitType.CustomStatesId.GetValueOrDefault(); - } - else - { - unitResult.Cid = 0; - } - - if (unit.StationGroup != null) - { - unitResult.Sid = unit.StationGroup.DepartmentGroupId; - unitResult.Snm = unit.StationGroup.Name; - } - - results.Units.Add(unitResult); - - // Add unit roles for this unit - var roles = await _unitsService.GetRolesForUnitAsync(unit.UnitId); - foreach (var role in roles) - { - var roleResult = new UnitRoleResult(); - roleResult.Name = role.Name; - roleResult.UnitId = role.UnitId; - roleResult.UnitRoleId = role.UnitRoleId; - - results.UnitRoles.Add(roleResult); - } - } - - var unitStatuses = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - - foreach (var us in unitStatuses) - { - var unitStatus = new UnitStatusCoreResult(); - unitStatus.UnitId = us.UnitId; - unitStatus.StateType = (UnitStateTypes)us.State; - unitStatus.StateTypeId = us.State; - unitStatus.Type = us.Unit.Type; - unitStatus.Timestamp = us.Timestamp.TimeConverter(department); - unitStatus.Name = us.Unit.Name; - unitStatus.Note = us.Note; - - if (us.DestinationId.HasValue) - unitStatus.DestinationId = us.DestinationId.Value; - - if (us.LocalTimestamp.HasValue) - unitStatus.LocalTimestamp = us.LocalTimestamp.Value; - - if (us.Latitude.HasValue) - unitStatus.Latitude = us.Latitude.Value; - - if (us.Longitude.HasValue) - unitStatus.Longitude = us.Longitude.Value; - - results.UnitStatuses.Add(unitStatus); - } - - foreach (var role in allRoles) - { - var roleResult = new RoleInfoResult(); - roleResult.Rid = role.PersonnelRoleId; - roleResult.Nme = role.Name; - - results.Roles.Add(roleResult); - } - - var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(DepartmentId); - - foreach (var customState in customStates) - { - if (customState.IsDeleted) - continue; - - foreach (var stateDetail in customState.GetActiveDetails()) - { - if (stateDetail.IsDeleted) - continue; - - var customStateResult = new CustomStatusesResult(); - customStateResult.Id = stateDetail.CustomStateDetailId; - customStateResult.Type = customState.Type; - customStateResult.StateId = stateDetail.CustomStateId; - customStateResult.Text = stateDetail.ButtonText; - customStateResult.BColor = stateDetail.ButtonColor; - customStateResult.Color = stateDetail.TextColor; - customStateResult.Gps = stateDetail.GpsRequired; - customStateResult.Note = stateDetail.NoteType; - customStateResult.Detail = stateDetail.DetailType; - - results.Statuses.Add(customStateResult); - } - - } - - - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId)).OrderByDescending(x => x.LoggedOn); - - if (calls != null && calls.Any()) - { - foreach (var c in calls) - { - var call = new CallResultEx(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = c.Name; - call.Noc = c.NatureOfCall; - call.Map = c.MapPage; - call.Not = c.Notes; - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Add = c.Address; - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Ste = c.State; - call.Num = c.Number; - - c.Protocols = await _callsService.GetCallProtocolsByCallIdAsync(c.CallId); - call.Protocols = new List(); - if (c.Protocols != null && c.Protocols.Any()) - { - foreach (var protocol in c.Protocols) - { - var p = new CallProtocolResult(); - p.Id = protocol.DispatchProtocolId; - p.Code = protocol.Protocol.Code; - p.Name = protocol.Protocol.Name; - - call.Protocols.Add(p); - } - } - - results.Calls.Add(call); - } - } - else - { - // This is a hack due to a bug in the current units app! -SJ 1-31-2016 - var call = new CallResultEx(); - call.Cid = 0; - call.Pri = 0; - call.Ctl = false; - call.Nme = "No Call"; - call.Noc = ""; - call.Map = ""; - call.Not = ""; - call.Add = ""; - call.Geo = ""; - call.Lon = DateTime.UtcNow; - call.Ste = 0; - call.Num = ""; - - results.Calls.Add(call); - } - - foreach (var priority in callPriorites) - { - var priorityResult = new CallPriorityResult(); - priorityResult.Id = priority.DepartmentCallPriorityId; - priorityResult.DepartmentId = priority.DepartmentId; - priorityResult.Name = priority.Name; - priorityResult.Color = priority.Color; - priorityResult.Sort = priority.Sort; - priorityResult.IsDeleted = priority.IsDeleted; - priorityResult.IsDefault = priority.IsDefault; - - results.Priorities.Add(priorityResult); - } - - var members = await _departmentsService.GetAllDepartmentsForUserAsync(UserId); - foreach (var member in members) - { - if (member.IsDeleted) - continue; - - if (member.IsDisabled.GetValueOrDefault()) - continue; - - var depRest = new JoinedDepartmentResult(); - depRest.Did = member.DepartmentId; - depRest.Nme = member.Department.Name; - - results.Departments.Add(depRest); - } - - if (callTypes != null && callTypes.Any()) - { - foreach (var callType in callTypes) - { - var type = new CallTypeResult(); - type.Id = callType.CallTypeId; - type.Name = callType.Type; - - results.CallTypes.Add(type); - } - } - - - return results; - } - - [HttpGet("GetUnitAppCallDataOnly")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetUnitAppCallDataOnly() - { - var results = new UnitAppPayloadResult(); - results.Calls = new List(); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - var calls = (await _callsService.GetActiveCallsByDepartmentAsync(DepartmentId)).OrderByDescending(x => x.LoggedOn); - - if (calls != null && calls.Any()) - { - foreach (var c in calls) - { - var call = new CallResultEx(); - - call.Cid = c.CallId; - call.Pri = c.Priority; - call.Ctl = c.IsCritical; - call.Nme = c.Name; - call.Noc = c.NatureOfCall; - call.Map = c.MapPage; - call.Not = c.Notes; - - if (String.IsNullOrWhiteSpace(c.Address) && c.HasValidGeolocationData()) - { - var geo = c.GeoLocationData.Split(char.Parse(",")); - - if (geo.Length == 2) - call.Add = await _geoLocationProvider.GetAddressFromLatLong(double.Parse(geo[0]), double.Parse(geo[1])); - } - else - call.Add = c.Address; - - call.Add = c.Address; - call.Geo = c.GeoLocationData; - call.Lon = c.LoggedOn.TimeConverter(department); - call.Ste = c.State; - call.Num = c.Number; - - c.Protocols = await _callsService.GetCallProtocolsByCallIdAsync(c.CallId); - call.Protocols = new List(); - if (c.Protocols != null && c.Protocols.Any()) - { - foreach (var protocol in c.Protocols) - { - var p = new CallProtocolResult(); - p.Id = protocol.DispatchProtocolId; - p.Code = protocol.Protocol.Code; - p.Name = protocol.Protocol.Name; - - call.Protocols.Add(p); - } - } - - results.Calls.Add(call); - } - } - else - { - // This is a hack due to a bug in the current units app! -SJ 1-31-2016 - var call = new CallResultEx(); - call.Cid = 0; - call.Pri = 0; - call.Ctl = false; - call.Nme = "No Call"; - call.Noc = ""; - call.Map = ""; - call.Not = ""; - call.Add = ""; - call.Geo = ""; - call.Lon = DateTime.UtcNow; - call.Ste = 0; - call.Num = ""; - - results.Calls.Add(call); - } - - return results; - } - - [HttpPost("TroubleAlert")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task TroubleAlert(TroubleAlertEvent troubleInput) - { - if (troubleInput == null) - return NotFound(); - - try - { - troubleInput.DepartmentId = DepartmentId; - troubleInput.UserId = UserId; - troubleInput.TimeStamp = DateTime.UtcNow; - - CqrsEvent registerUnitPushEvent = new CqrsEvent(); - registerUnitPushEvent.Type = (int)CqrsEventTypes.TroubleAlert; - registerUnitPushEvent.Data = ObjectSerialization.Serialize(troubleInput); - - await _cqrsProvider.EnqueueCqrsEventAsync(registerUnitPushEvent); - - return CreatedAtAction(nameof(TroubleAlert), new { id = troubleInput.DepartmentId }, troubleInput); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/UnitLocationController.cs b/Web/Resgrid.Web.Services/Controllers/v3/UnitLocationController.cs deleted file mode 100644 index 83393380..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/UnitLocationController.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Events; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.UnitLocation; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against units in a department - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class UnitLocationController : V3AuthenticatedApiControllerbase - { - private readonly IUnitsService _unitsService; - private readonly IUnitLocationEventProvider _unitLocationEventProvider; - - public UnitLocationController(IUnitsService unitsService, IUnitLocationEventProvider unitLocationEventProvider) - { - _unitsService = unitsService; - _unitLocationEventProvider = unitLocationEventProvider; - } - - /// - /// Sets the location of a unit - /// - /// UnitLocationInput object with the gps information. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("SetUnitLocation")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task SetUnitLocation(UnitLocationInput locationInput, CancellationToken cancellationToken) - { - var unit = await _unitsService.GetUnitByIdAsync(locationInput.Uid); - - if (unit == null) - return NotFound(); - - if (unit.DepartmentId != DepartmentId) - return Unauthorized(); - - if (this.ModelState.IsValid) - { - try - { - var location = new UnitLocationEvent(); - location.UnitId = locationInput.Uid; - location.DepartmentId = DepartmentId; - - if (locationInput.Tms.HasValue) - location.Timestamp = locationInput.Tms.Value; - else - location.Timestamp = DateTime.UtcNow; - - if (!String.IsNullOrWhiteSpace(locationInput.Lat) && locationInput.Lat != "NaN" && !String.IsNullOrWhiteSpace(locationInput.Lon) && locationInput.Lon != "NaN") - { - if (decimal.TryParse(locationInput.Lat, out var lat) && decimal.TryParse(locationInput.Lon, out var lon)) - { - location.Latitude = lat; - location.Longitude = lon; - - if (!String.IsNullOrWhiteSpace(locationInput.Acc) && locationInput.Acc != "NaN" && decimal.TryParse(locationInput.Acc, out var acc)) - location.Accuracy = acc; - - if (!String.IsNullOrWhiteSpace(locationInput.Alt) && locationInput.Alt != "NaN" && decimal.TryParse(locationInput.Alt, out var alt)) - location.Altitude = alt; - - if (!String.IsNullOrWhiteSpace(locationInput.Alc) && locationInput.Alc != "NaN" && decimal.TryParse(locationInput.Alc, out var alc)) - location.AltitudeAccuracy = alc; - - if (!String.IsNullOrWhiteSpace(locationInput.Spd) && locationInput.Spd != "NaN" && decimal.TryParse(locationInput.Spd, out var spd)) - location.Speed = spd; - - if (!String.IsNullOrWhiteSpace(locationInput.Hdn) && locationInput.Hdn != "NaN" && decimal.TryParse(locationInput.Hdn, out var hdn)) - location.Heading = hdn; - - await _unitLocationEventProvider.EnqueueUnitLocationEventAsync(location); - - return CreatedAtAction(nameof(SetUnitLocation), new { id = locationInput.Uid }, location); - } - } - else - { - return Ok(); - } - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/UnitStateController.cs b/Web/Resgrid.Web.Services/Controllers/v3/UnitStateController.cs deleted file mode 100644 index a772aa92..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/UnitStateController.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Mime; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Framework; -using Resgrid.Model; -using Resgrid.Model.Events; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Providers.Bus; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against unit statuses - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class UnitStateController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly IEventAggregator _eventAggregator; - - public UnitStateController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - IEventAggregator eventAggregator - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _eventAggregator = eventAggregator; - } - - /// - /// Sets the status/action for the current user. - /// - /// StatusInput object with the Status/Action to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("SetUnitState")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task SetUnitState(UnitStateInput stateInput) - { - return await ProcessSetUnitState(stateInput); - } - - /// - /// Sets the status/action for the current user. - /// - /// StatusInput object with the Status/Action to set. - /// Returns HttpStatusCode Created if successful, BadRequest otherwise. - [HttpPost("CommitUnitStates")] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status201Created)] - public async Task CommitUnitStates(List stateInputs) - { - foreach (var stateInput in stateInputs) - { - await ProcessSetUnitState(stateInput); - } - - return CreatedAtAction(nameof(CommitUnitStates), new { id = 0 }, null); - } - - private async Task ProcessSetUnitState(UnitStateInput stateInput) - { - var unit = await _unitsService.GetUnitByIdAsync(stateInput.Uid); - - if (unit == null) - return NotFound(); - - if (unit.DepartmentId != DepartmentId) - return Unauthorized(); - - if (this.ModelState.IsValid) - { - try - { - var state = new UnitState(); - - state.UnitId = stateInput.Uid; - state.LocalTimestamp = stateInput.Lts; - - if (!String.IsNullOrWhiteSpace(stateInput.Lat)) - state.Latitude = decimal.Parse(stateInput.Lat); - - if (!String.IsNullOrWhiteSpace(stateInput.Lon)) - state.Longitude = decimal.Parse(stateInput.Lon); - - if (!String.IsNullOrWhiteSpace(stateInput.Acc)) - state.Accuracy = decimal.Parse(stateInput.Acc); - - if (!String.IsNullOrWhiteSpace(stateInput.Alt)) - state.Altitude = decimal.Parse(stateInput.Alt); - - if (!String.IsNullOrWhiteSpace(stateInput.Alc)) - state.AltitudeAccuracy = decimal.Parse(stateInput.Alc); - - if (!String.IsNullOrWhiteSpace(stateInput.Spd)) - state.Speed = decimal.Parse(stateInput.Spd); - - if (!String.IsNullOrWhiteSpace(stateInput.Hdn)) - state.Heading = decimal.Parse(stateInput.Hdn); - - state.State = (int)stateInput.Typ; - state.Timestamp = stateInput.Tms ?? DateTime.UtcNow; - state.Note = stateInput.Not; - - if (state.Latitude.HasValue && state.Longitude.HasValue) - { - state.GeoLocationData = string.Format("{0},{1}", state.Latitude.Value, state.Longitude.Value); - } - - if (stateInput.Rto > 0) - state.DestinationId = stateInput.Rto; - - var savedState = await _unitsService.SetUnitStateAsync(state, DepartmentId); - - if (stateInput.Roles != null && stateInput.Roles.Count > 0) - { - var unitRoles = await _unitsService.GetRolesForUnitAsync(savedState.UnitId); - var roles = new List(); - foreach (var role in stateInput.Roles) - { - if (!string.IsNullOrWhiteSpace(role.Uid)) - { - var unitRole = new UnitStateRole(); - unitRole.UnitStateId = savedState.UnitStateId; - unitRole.UserId = role.Uid; ; - unitRole.UnitStateRoleId = role.Rid; - - if (String.IsNullOrWhiteSpace(role.Nme)) - { - var savedRole = unitRoles.FirstOrDefault(x => x.UnitRoleId == unitRole.UnitStateRoleId); - - if (savedRole != null) - unitRole.Role = savedRole.Name; - } - else - { - unitRole.Role = role.Nme; - } - - unitRole.IdValue = 0; - unitRole.UnitStateRoleId = 0; - - roles.Add(unitRole); - //_unitsService.AddUnitStateRoleForEvent(savedState.UnitStateId, role.Uid, role.Rid, savedState.Unit.Name, savedState.Timestamp); - } - } - - await _unitsService.AddAllUnitStateRolesAsync(roles); - } - - //OutboundEventProvider.UnitStatusTopicHandler handler = new OutboundEventProvider.UnitStatusTopicHandler(); - //handler.Handle(new UnitStatusEvent() { DepartmentId = DepartmentId, Status = savedState }); - _eventAggregator.SendMessage(new UnitStatusEvent() { DepartmentId = DepartmentId, Status = savedState }); - - if (savedState.UnitStateId > 0) - return CreatedAtAction("SetUnitState", new { id = savedState.UnitStateId }, savedState); - } - catch (Exception ex) - { - Logging.LogException(ex); - return BadRequest(); - } - } - - return BadRequest(); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/UnitsController.cs b/Web/Resgrid.Web.Services/Controllers/v3/UnitsController.cs deleted file mode 100644 index 518dd425..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/UnitsController.cs +++ /dev/null @@ -1,276 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Web; -using Resgrid.Model.Helpers; -using Resgrid.Model.Services; -using Resgrid.Web.Services.Controllers.Version3.Models.Units; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Controllers.Version3.Models.Personnel; - - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations to perform against units in a department - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class UnitsController : V3AuthenticatedApiControllerbase - { - private readonly IUsersService _usersService; - private readonly IActionLogsService _actionLogsService; - private readonly IDepartmentsService _departmentsService; - private readonly IUserProfileService _userProfileService; - private readonly IUserStateService _userStateService; - private readonly IUnitsService _unitsService; - private readonly IDepartmentGroupsService _departmentGroupsService; - - public UnitsController( - IUsersService usersService, - IActionLogsService actionLogsService, - IDepartmentsService departmentsService, - IUserProfileService userProfileService, - IUserStateService userStateService, - IUnitsService unitsService, - IDepartmentGroupsService departmentGroupsService - ) - { - _usersService = usersService; - _actionLogsService = actionLogsService; - _departmentsService = departmentsService; - _userProfileService = userProfileService; - _userStateService = userStateService; - _unitsService = unitsService; - _departmentGroupsService = departmentGroupsService; - } - - ///// - ///// Get's all the units in a department and their current status information - ///// - ///// List of UnitStatusResult objects, with status information for each unit. - //[HttpGet("GetUnitStatuses")] - //[ProducesResponseType(StatusCodes.Status200OK)] - //public async Task>> GetUnitStatuses() - //{ - // var results = new List(); - - // var units = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - // var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - // foreach (var u in units) - // { - // var unitStatus = new UnitStatusResult(); - // unitStatus.Uid = u.UnitId; - // unitStatus.Typ = u.State; - // unitStatus.Tmp = u.Timestamp.TimeConverter(department); - - // if (u.DestinationId.HasValue) - // unitStatus.Did = u.DestinationId.Value; - - // results.Add(unitStatus); - // } - - // return Ok(results); - //} - - /// - /// Get's all the units in a department and their current status information - /// - /// List of UnitStatusResult objects, with status information for each unit. - [HttpGet("GetUnitStatuses")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetUnitStatuses(string activeFilter) - { - var results = new List(); - - string filter = null; - string[] activeFilters = null; - if (!String.IsNullOrWhiteSpace(activeFilter)) - { - filter = HttpUtility.UrlDecode(activeFilter); - activeFilters = filter.Split(char.Parse("|")); - } - var filters = await GetFilterOptions(); - - var units = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); - - foreach (var u in units) - { - var unitStatus = new UnitStatusResult(); - unitStatus.Uid = u.UnitId; - unitStatus.Typ = u.State; - unitStatus.Tmp = u.Timestamp.TimeConverter(department); - - if (u.DestinationId.HasValue) - unitStatus.Did = u.DestinationId.Value; - - if (activeFilters != null) - { - foreach (var afilter in activeFilters) - { - var text = GetTextValue(afilter, filters); - - if (afilter.Substring(0, 2) == "G:") - { - if (u.Unit != null && u.Unit.StationGroup != null && text == u.Unit.StationGroup.Name) - { - results.Add(unitStatus); - break; - } - } - } - } - else - { - results.Add(unitStatus); - } - } - - return Ok(results); - } - - /// - /// Get's all the units in a department and their basic info - /// - /// List of UnitResult objects, with basic information for each unit. - [HttpGet("GetUnitsForDepartment")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetUnitsForDepartment(int departmentId) - { - var results = new List(); - - if (departmentId != DepartmentId && !IsSystem) - return Unauthorized(); - - - if (departmentId == 0 && IsSystem) - { - // Get All - var departments = await _departmentsService.GetAllAsync(); - - foreach (var department in departments) - { - var units = await _unitsService.GetUnitsForDepartmentAsync(departmentId); - - foreach (var u in units) - { - var unitResult = new UnitResult(); - unitResult.Id = u.UnitId; - unitResult.DepartmentId = u.DepartmentId; - unitResult.Name = u.Name; - unitResult.Type = u.Type; - unitResult.StationId = u.StationGroupId; - unitResult.VIN = u.VIN; - unitResult.PlateNumber = u.PlateNumber; - unitResult.FourWheel = u.FourWheel; - unitResult.SpecialPermit = u.SpecialPermit; - - results.Add(unitResult); - } - } - - return results; - } - else - { - var units = await _unitsService.GetUnitsForDepartmentAsync(departmentId); - - foreach (var u in units) - { - var unitResult = new UnitResult(); - unitResult.Id = u.UnitId; - unitResult.DepartmentId = u.DepartmentId; - unitResult.Name = u.Name; - unitResult.Type = u.Type; - unitResult.StationId = u.StationGroupId; - unitResult.VIN = u.VIN; - unitResult.PlateNumber = u.PlateNumber; - unitResult.FourWheel = u.FourWheel; - unitResult.SpecialPermit = u.SpecialPermit; - - results.Add(unitResult); - } - } - - return Ok(results); - } - - [HttpGet("GetUnitDetail")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetUnitDetail() - { - List result = new List(); - var units = await _unitsService.GetAllLatestStatusForUnitsByDepartmentIdAsync(DepartmentId); - var names = await _departmentsService.GetAllPersonnelNamesForDepartmentAsync(DepartmentId); - - foreach (var unit in units) - { - var unitResult = new UnitDetailResult(); - unitResult.Roles = new List(); - unitResult.Id = unit.UnitId; - unitResult.Name = unit.Unit.Name; - unitResult.Type = unit.Unit.Type; - unitResult.GroupId = unit.Unit.StationGroupId.GetValueOrDefault(); - unitResult.VIN = unit.Unit.VIN; - unitResult.PlateNumber = unit.Unit.PlateNumber; - unitResult.Offroad = unit.Unit.FourWheel.GetValueOrDefault(); - unitResult.SpecialPermit = unit.Unit.SpecialPermit.GetValueOrDefault(); - unitResult.StatusId = unit.UnitStateId; - - if (unit.Roles != null && unit.Roles.Count() > 0) - { - foreach (var role in unit.Roles) - { - var roleResult = new UnitDetailRoleResult(); - roleResult.RoleName = role.Role; - roleResult.RoleId = role.UnitStateRoleId; - roleResult.UserId = role.UserId; - - var name = names.FirstOrDefault(x => x.UserId == role.UserId); - - if (name != null) - roleResult.Name = name.Name; - else - roleResult.Name = "Unknown"; - - unitResult.Roles.Add(roleResult); - } - } - - result.Add(unitResult); - } - - return Ok(result); - } - - private string GetTextValue(string filter, List filters) - { - return filters.Where(x => x.Id == filter).Select(y => y.Name).FirstOrDefault(); - } - - private async Task> GetFilterOptions() - { - var result = new List(); - - var stations = await _departmentGroupsService.GetAllGroupsForDepartmentAsync(DepartmentId); - - Parallel.ForEach(stations, s => - { - var respondingTo = new FilterResult(); - respondingTo.Id = string.Format("G:{0}", s.DepartmentGroupId); - respondingTo.Type = "Group"; - respondingTo.Name = s.Name; - - result.Add(respondingTo); - }); - - return result; - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/V3AuthenticatedApiControllerBase.cs b/Web/Resgrid.Web.Services/Controllers/v3/V3AuthenticatedApiControllerBase.cs deleted file mode 100644 index 6d3b22b1..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/V3AuthenticatedApiControllerBase.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.ServicesCore.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ -#if (!DEBUG && !DOCKER) - //[RequireHttps] -#endif - [ApiVersion("3.0")] - [ApiController] - [Authorize(AuthenticationSchemes = "BasicAuthentication")] - //[EnableCors("_resgridWebsiteAllowSpecificOrigins")] - public class V3AuthenticatedApiControllerbase : ControllerBase - { - - protected string UserId => ClaimsAuthorizationHelper.GetUserId(); - - protected int DepartmentId => ClaimsAuthorizationHelper.GetDepartmentId(); - - protected string UserName => ClaimsAuthorizationHelper.GetUsername(); - - protected bool IsSystem - { - get - { - //return ((App_Start.ResgridPrincipleV3)this.User).IsSystem; - return false; - } - } - - //[HttpOptions("Options")] - //public HttpResponseMessage Options() - //{ - // var response = new HttpResponseMessage(); - // response.StatusCode = HttpStatusCode.OK; - // response.Headers.Add("Access-Control-Allow-Origin", "*"); - // response.Headers.Add("Access-Control-Request-Headers", "*"); - // response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); - - // return response; - //} - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v3/VoiceController.cs b/Web/Resgrid.Web.Services/Controllers/v3/VoiceController.cs deleted file mode 100644 index d4daccaf..00000000 --- a/Web/Resgrid.Web.Services/Controllers/v3/VoiceController.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Threading.Tasks; -using Resgrid.Model.Services; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Resgrid.Web.Services.Models.v3.Voice; -using Resgrid.Framework; -using System.Collections.Generic; -using System.Linq; -using Resgrid.Web.Helpers; - -namespace Resgrid.Web.Services.Controllers.Version3 -{ - /// - /// Operations that can be performed against resgrid voice (voip) services - /// - [Route("api/v{version:ApiVersion}/[controller]")] - [Produces("application/json")] - [ApiVersion("3.0")] - [ApiExplorerSettings(GroupName = "v3")] - public class VoiceController : V3AuthenticatedApiControllerbase - { - private readonly IAuthorizationService _authorizationService; - private readonly IVoiceService _voiceService; - private readonly IDepartmentsService _departmentsService; - - public VoiceController( - IAuthorizationService authorizationService, - IVoiceService voiceService, - IDepartmentsService departmentsService) - { - _authorizationService = authorizationService; - _voiceService = voiceService; - _departmentsService = departmentsService; - } - - /// - /// Returns all the available responding options (Calls/Stations) for the department - /// - /// Array of RecipientResult objects for each responding option in the department - [HttpGet("GetDepartmentVoiceSettings")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetDepartmentVoiceSettings() - { - var result = new DepartmentVoiceResult(); - result.VoipServerWebsocketSslAddress = Config.VoipConfig.VoipServerWebsocketSslAddress; - result.VoiceEnabled = await _voiceService.CanDepartmentUseVoiceAsync(DepartmentId); - result.Realm = Config.VoipConfig.VoipDomain; - result.CallerIdName = await UserHelper.GetFullNameForUser(UserId); - - if (result.VoiceEnabled) - { - result.Channels = new List(); - - var voice = await _voiceService.GetVoiceSettingsForDepartmentAsync(DepartmentId); - - if (voice != null) - { - if (voice.Channels != null && voice.Channels.Any()) - { - foreach (var chan in voice.Channels) - { - var channel = new DepartmentVoiceChannelResult(); - channel.Name = chan.Name; - channel.IsDefault = chan.IsDefault; - channel.ConferenceNumber = chan.ConferenceNumber; - - result.Channels.Add(channel); - } - } - - result.UserInfo = new DepartmentVoiceUserInfoResult(); - result.UserInfo.Username = UserId.Replace("-", ""); - - var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId); - result.UserInfo.Pin = _departmentsService.ConvertDepartmentCodeToDigitPin(department.Code); - result.UserInfo.Password = Hashing.ComputeMD5Hash($"{UserId}{Config.SymmetricEncryptionConfig.InitVector}"); - } - } - - return Ok(result); - } - } -} diff --git a/Web/Resgrid.Web.Services/Controllers/v4/MessagesController.cs b/Web/Resgrid.Web.Services/Controllers/v4/MessagesController.cs index 17739762..8026d34a 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/MessagesController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/MessagesController.cs @@ -275,6 +275,12 @@ public async Task> SendMessage([FromBody] NewMes if (newMessageInput.Recipients == null || newMessageInput.Recipients.Count <= 0) return BadRequest(); + if (String.IsNullOrWhiteSpace(newMessageInput.Title)) + return BadRequest(); + + if (String.IsNullOrWhiteSpace(newMessageInput.Body)) + return BadRequest(); + var result = new SendMessageResult(); Message savedMessage = null; diff --git a/Web/Resgrid.Web.Services/Controllers/v4/PersonnelController.cs b/Web/Resgrid.Web.Services/Controllers/v4/PersonnelController.cs index 4382abd9..13780950 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/PersonnelController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/PersonnelController.cs @@ -16,6 +16,7 @@ using System.Web; using Resgrid.Framework; using Resgrid.Web.Helpers; +using System.Reflection.Metadata.Ecma335; namespace Resgrid.Web.Services.Controllers.v4 { @@ -188,6 +189,9 @@ public async Task> GetAllPersonnelInfos { foreach (var afilter in activeFilters) { + if (String.IsNullOrWhiteSpace(afilter) || afilter.Length <= 2) + continue; + var text = GetTextValue(afilter, filters); if (afilter.Substring(0, 2) == "G:") @@ -304,7 +308,7 @@ public async Task> GetPersonnelFil if (groups != null && groups.Any()) { - foreach(var group in groups) + foreach (var group in groups) { result.Data.Add(new FilterResult() { @@ -317,7 +321,7 @@ public async Task> GetPersonnelFil if (roles != null && roles.Any()) { - foreach(var role in roles) + foreach (var role in roles) { result.Data.Add(new FilterResult() { @@ -330,7 +334,7 @@ public async Task> GetPersonnelFil if (staffing != null && staffing.Any()) { - foreach(var staff in staffing) + foreach (var staff in staffing) { result.Data.Add(new FilterResult() { @@ -493,7 +497,7 @@ private async Task> GetFilterOptions() if (groups != null && groups.Any()) { - foreach(var group in groups) + foreach (var group in groups) { result.Add(new FilterResult() { @@ -506,7 +510,7 @@ private async Task> GetFilterOptions() if (roles != null && roles.Any()) { - foreach(var role in roles) + foreach (var role in roles) { result.Add(new FilterResult() { @@ -519,7 +523,7 @@ private async Task> GetFilterOptions() if (staffing != null && staffing.Any()) { - foreach(var staff in staffing) + foreach (var staff in staffing) { result.Add(new FilterResult() { diff --git a/Web/Resgrid.Web.Services/Controllers/v4/UnitRolesController.cs b/Web/Resgrid.Web.Services/Controllers/v4/UnitRolesController.cs index 07b5e6fe..ab7c0444 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/UnitRolesController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/UnitRolesController.cs @@ -187,7 +187,7 @@ public async Task> SetRoleAssignmentsForUnit foreach (var unitRole in setRolesInput.Roles) { - if (!string.IsNullOrWhiteSpace(unitRole.UserId)) + if (!string.IsNullOrWhiteSpace(unitRole.UserId) && !string.IsNullOrWhiteSpace(unitRole.RoleId)) { var role = await _unitsService.GetRoleByIdAsync(int.Parse(unitRole.RoleId)); diff --git a/Web/Resgrid.Web.Services/Controllers/v4/UnitStatusController.cs b/Web/Resgrid.Web.Services/Controllers/v4/UnitStatusController.cs index 217206a5..1ed1fc1b 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/UnitStatusController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/UnitStatusController.cs @@ -266,7 +266,7 @@ public async Task> GetUnitStatus(string unitId) var roles = new List(); foreach (var role in stateInput.Roles) { - if (!string.IsNullOrWhiteSpace(role.UserId)) + if (!string.IsNullOrWhiteSpace(role.UserId) && !string.IsNullOrWhiteSpace(role.RoleId)) { var unitRole = new UnitStateRole(); unitRole.UnitStateId = savedState.UnitStateId; diff --git a/Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs b/Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs index 49916e80..00ca6268 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/UnitsController.cs @@ -134,6 +134,9 @@ public async Task> GetAllUnitsInfos(string activeF { foreach (var afilter in activeFilters) { + if (String.IsNullOrWhiteSpace(afilter) || afilter.Length <= 2) + continue; + //var text = GetTextValue(afilter, filters); if (afilter.Substring(0, 2) == "G:") diff --git a/Web/Resgrid.Web.Services/Resgrid.Web.Services.xml b/Web/Resgrid.Web.Services/Resgrid.Web.Services.xml index 7b1d9f63..398c5eec 100644 --- a/Web/Resgrid.Web.Services/Resgrid.Web.Services.xml +++ b/Web/Resgrid.Web.Services/Resgrid.Web.Services.xml @@ -12,50 +12,36 @@ The cancellation token that can be used by other objects or threads to receive notice of cancellation.
- - - Service to generate an authentication token that is required to communicate with all other v3 services - - - - - Generates a token that is then used for subsquent requests to the API. - - ValidateInput object with values populated - ValidateResult object, with IsValid set if the settings are correct - - + - Used to interact with the user avatars (profile pictures) in the Resgrid system. The authentication header isn't required to access this method. + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - + - Get a users avatar from the Resgrid system based on their ID + Gets all the autofills in a department - ID of the user - + - Calls to get information specific for displaying data on a dashboard or big board application. Data returned - is formatted and optimized for these scenarios to be outputted directly into a web application. + Gets the autofills for a specific type + Type to get + - + - Used to interact with the calendar system - Implements the + Mobile or Tablet Device specific operations - - + Gets the department calendar items. ActionResult<List<CalendarItem>>. - + Gets the department calendar items in range. @@ -63,801 +49,888 @@ The end. ActionResult<List<CalendarItem>>. - - - Gets the calendar items specified in the date range. - - Must be in MM/dd/yyyy HH:mm:ss zzz format - Must be in MM/dd/yyyy HH:mm:ss zzz format - - - + Gets the calendar item. The identifier. ActionResult<CalendarItem>. - + Gets the department calendar item types. ActionResult<List<CalendarItemType>>. - + + + + + + + + - Operations to be performed against calls + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - + - Returns all the call priorities (including deleted ones) for a department + Get the files for a call in the Resgrid System - Array of CallPriorityResult objects for each call priority in the department + CallId to get the files for + Include the data in the result + Type of file to get (Any = 0, Audio = 1, Images = 2, Files = 3, Videos = 4) + - + - Returns all the call priorities (including deleted ones) for a selected department + Get a users avatar from the Resgrid system based on their ID - Array of CallPriorityResult objects for each call priority in the department + ID of the file + - + - Return the audio file for push notifications for a specific call priority + Get a users avatar from the Resgrid system based on their ID - File download result for push dispatch audio for a call priority + ID of the file + - + - Return the ios audio file for push notifications for a specific call priority + Attaches a file to a call - File download result for push dispatch audio for a call priority + ID of the user + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + - + - Operations to be performed against calls + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - + - Returns all the active calls for the department + Get notes for a call - Array of CallResult objects for each active call in the department + CallId of the call you want to get notes for + - + - Returns all the active calls for the department + Saves a call note - Array of CallResult objects for each active call in the department + CallId of the call you want to get notes for + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + ActionResult. - + - Returns all the active calls for the department (extended object result, more verbose then GetActiveCalls) + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - Array of DepartmentCallResult objects for each active call in the department - + - Returns a specific call from the Resgrid System + Gets all the call priorities in a department - CallResult of the call in the Resgrid system + - + - Gets all the meta-data around a call, dispatched personnel, units, groups and responses + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - CallId to get data for - - + - Saves a call in the Resgrid system + Gets all the call protocols in a department - - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - + - Adds a new call into Resgrid and Dispatches the call + Gets a single protocol by id - Call data to add into the system - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - AddCallInput. + List of ProtocolResult objects. - + - Closes a Resgrid call + Gets a protocol attachment by it's id - Data to close a call - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - OK status code if successful + ID of the protocol attachment + - + - Updates an existing Active Call in the Resgrid system + Calls, also referred to as Dispatches. - Data to updated the call - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - OK status code if successful - + - Get notes for a call + Returns all the active calls for the department - CallId of the call you want to get notes for - + Array of CallResult objects for each active call in the department - + - Get the files for a call in the Resgrid System + Returns a specific call from the Resgrid System - CallId to get the files for - Include the data in the result - Type of file to get (Any = 0, Audio = 1, Images = 2, Files = 3, Videos = 4) - + Id of the call trying to be retrived + CallResult of the call in the Resgrid system - + - Get a users avatar from the Resgrid system based on their ID + Gets all the meta-data around a call, dispatched personnel, units, groups and responses - ID of the user - The department id of the file your requesting + CallId to get data for - + - Attaches a file to a call + Saves a call in the Resgrid system - ID of the user + The cancellation token that can be used by other objects or threads to receive notice of cancellation. - + - Get notes for a call + Updates an existing Active Call in the Resgrid system - CallId of the call you want to get notes for + Data to updated the call The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. + OK status code if successful - + - Returns the call audio for a specific call (Allow Anonymous) + Updates a call's scheduled dispatch time if it has not been dispatched - Encrypted query string for the call - Http response type matching call audio format with data + Data to update + - + - Get notes for a call + Deletes a call - CallId of the call you want to get notes for + ID of the call - + - Get all the call types for a department + Closes a Resgrid call - An array of call types + Data to close a call + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + OK status code if successful - + Returns all the non-dispatched (pending) scheduled calls for the department Array of CallResult objects for each active call in the department - + - Updates a call's scheduled dispatch time if it has not been dispatched + Gets all the meta-data around a call, dispatched personnel, units, groups and responses - ID of the call - UTC date to change the dispatch to + CallId to get data for - + - Deletes a call + Returns all the calls for the department inclusive in the date range - ID of the call - + Start date as UTC to get calls for + End date as UTC to get calls for + Array of CallResult objects for each call in the department within the range - + - Operations to be performed against the chat system + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - + - Gets the department and group information needed to seed the initial standard groups for chat + Gets all the call priorities in a department - + - Gets personnel information for the department to utilize within a chat system + Generic configuration api endpoints - - + - Send a Push Notification out to the personnel involved in a chat + Gets the system config - - + - Gets the command application core data. + Gets the config values for a key - ActionResult<UnitAppPayloadResult>. + + The key to get config data for - + - Operations to perform against the security sub-system + Service to generate an authentication token that is required to communicate with all other v4 services - + - Operations to perform against the security sub-system + Generates a token that is then used for subsquent requests to the API. + ValidateResult object, with IsValid set if the settings are correct - + - Gets all the command definitions for the department + Contacts, which are people, entities, and things that can be contacted (i.e. people, departments, groups, etc.) to dispatch a call to. - AllCommandsResult object with a list of CommandResult's for each command - + - Gets the core data. + Gets all the contact categories for the department. - CoreDataResult. + - + - General department level options + Gets all the contacts for the department. + - + - Returns all the available responding options (Calls/Stations) for the department + Gets the contact by id - Array of RespondingOptionResult objects for each responding option in the department + - + - Returns basic high level department information for the request department + Gets all the Notes for a Contact by the contact id - - Array of DepartmentResult objects with the department data populated + - + - Returns basic high level department information for the request department + Custom statuses - - Array of DepartmentResult objects with the department data populated - + - Operations to perform against devices for personnel + All custom statuses for a department + - + - Default Constructor + Gets the active statuses that personnel can currently set for the department - - - - - + - + - Register a device to receive push notification from the Resgrid system + Gets the active staffing levels that personnel can currently set for the department - Input to create the registration for - Result for the registration + - + - Removed a Push Notification support by PushUriId. + Gets the active states that units can currently set for the department - Input to de-register the device for - + + + Mobile or Tablet Device specific operations + + + Register a unit device to receive push notification from the Resgrid system Input to create the registration for Result for the registration - + Removed a Unit Push Notification support by PushUriId. - Input to deregister the device for - + Input to deregister the device for + Result for the unregistration + + + + Register a device to receive push notification from the Resgrid system + + Input to create the registration for + Result for the registration + + + + Removed a Push Notification support by PushUriId. + + Input to deregister the device for + Result for the unregistration + + + + API Calls that are used for the Dispatch App + - + - Operations to support Dispatch operations + Gets all the information required to populate the New Call form + - + - Operations to support Dispatch operations + + + - + Returns all the personnel for display in the new call personnel table Array of PersonnelForCallResult objects for each person in the department - + Returns all the groups for display in the new call groups table Array of GroupsForCallResult objects for each group in the department - + Returns all the roles for display in the new call groups table Array of RolesForCallResult objects for each role in the department - + Returns all the call quick templates Array of CallTemplateResult objects for each role in the department - + - Returns the custom new call form if any exists and is active + Gets calls and other data formatted for different feed formats, like RSS. - FormDataResult object with the new call form data - + - Geolocation API methods for gps and other functions (like what3words) + User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - + - Gets coordinates (Latitude and Longitude) for a what3words address + Gets the Department Form that can be used for the new call process (i.e. call intake/triage form) - Full 3 part what 3 words string - + - Gets coordinates (Latitude and Longitude) for an address + User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - URL Encoded address - - + - Operations to perform against the security sub-system + Gets the Department Group by it's id + - + - Operations to perform against the department links system. Department Links allow departments to - share data to other departments, for example calls or resource orders. + Gets all deparment groups for a department + - + - Gets the current active department links for this department where data is bring shared to it + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - List of DepartmentLinkResult objects with the information about the links - + - Returns all the active calls for a specific department link + Gets the current users department rights - Array of CallResult objects for each active call in the department + DepartmentRightsResult object with the department rights and group memberships - + - Get's all the units for a department link and their current status information + For interacting with the Inbox - List of UnitStatusResult objects, with status information for each unit. - + - Get's all the personnel in a department link and their current status and staffing information + Deletes a message from the inbox by its ID - List of PersonnelStatusResult objects, with status and staffing information for each user. + - + - Returns all the map markers for all active links + Mapping operations - Array of MapMakerInfo objects for each active call in all linked departments - + - Returns all the active calls for a specific department link + Data to center the map and it's default location plus marker information for displaying makers on the map. - Array of CallResult objects for each active call in the department + GetMapDataResult object - + - Collection of methods to perform operations against messages + Gets the user created map layers in the system. + GetMapLayersResult object - + - Returns all inbox messages for a user. + Messaging system interaction - Note that the body of these messages is truncated to 100 characters. - Array of MessageResult objects for all the messages in the users Inbox - + Returns all inbox messages for a user. Note that the body of these messages is truncated to 100 characters. Array of MessageResult objects for all the messages in the users Inbox - + Returns all the outbox messages for a user. Note that the body of these messages is truncated to 100 characters. Array of MessageResult objects for all the messages in the users Inbox - + - Returns all the outbox messages for a user. + Gets a specific message by it's Id. - Note that the body of these messages is truncated to 100 characters. - Array of MessageResult objects for all the messages in the users Inbox + Integer message Identifier + MessageResult object populated with message information from the system. - + - Gets a specific message by it's Id. + Gets all the recipients in the department plus default values the system accepts - Integer message Identifier + Disallow adding a noone option + Include units in the response list MessageResult object populated with message information from the system. - + Sends a new message to users in the system Input data to send a new message Created result if the message was sent - + - Deletes a messsage from the system + Deletes a message from the system Returns OK status code if successful - + Deletes a messsage from the system MessageId of the message to delete Returns OK status code if successful - + + + The options for Notes in the Resgrid system + + + - Operations to perform against a departments notes + Gets all notes for a department + - + - Get's all the notes in a department + Gets the dispatch note (if any). A dispatch note is a Department note with the + title of "Dispatch" or a note in a Category of "Dispatch". - List of NotesResult objects. + - + - Get's all the notes in a department + Get's all the notes in a department that are not expired by a category - List of NotesResult objects. + Category name to get notes for + Also include notes that do not have a + - + - Gets a specific note by it's Id. + Gets the dispatch note (if any). A dispatch note is a Department note with the + title of "Dispatch" or a note in a Category of "Dispatch". - Integer note Identifier - NotesResult object populated with note information from the system. + Id of the note to get + - + - Get's all the notes in a department + Saves a new note in the system - List of NotesResult objects. + Input data to send a new note + Created result if the note was saved - + Get's all the note Categories for a Department List of string of distinct note category. - + Operations to perform against personnel in a department - + - Get's all the personnel in a department and their current status and staffing information with a filter + Gets information about a specific person - - $ curl https://api.resgrid.com/api/v2/Personnel/GetPersonnelStatuses -u VXNlck5hbWV8MXxBQkNE: - - List of PersonnelStatusResult objects, with status and staffing information for each user. + UserId of the person to get info for + PersonnelInfoResult with information pertaining to that user - + - Gets information about a specific person + Gets information about all users in a department - UserId of the person to get info for + The active filter to reduce personnel returned PersonnelInfoResult with information pertaining to that user - + - Operations to perform against a logged in users (determined via the token) profile + Gets all the options available to filter personnel against compatible Resgrid APIs + GetPersonnelFilterOptionsResult with information pertaining to each filter option - + - Gets the mobile carriers in the Resgrid system. If you need a mobile carrier added contact team@resgrid.com. + Operations involving the location of a person setting the real-time location or getting the latest location for people. - - + - Gets the time zones in the Resgrid system. If you need a time zone added or corrected contact team@resgrid.com. + Sets the location of a person - + PersonnelLocationInput object with the gps information. + Returns HttpStatusCode Created if successful, BadRequest otherwise. - + - Gets the Resgrid user profile for the user + Gets the latest location for a specified unit - ProfileResult object with the users profile data + - + - Toggles a users profile to enable/disable custom push sounds when the app is backgrounded. + Operations to perform against personnel staffing, i.e. Available, Delayed, in a department - An HTTP Result - + - Updates a users profile + Gets the current staffing for a user - An HTTP Result + UserId to get the status for + - + - Operations to perform against dispatch protocols that are established in a department + Saves a staffing for a person + Staffing and related data + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + ActionResult. - + - Get's all the protocols for a department + Saves a staffing for multiple personnel - List of ProtocolResult objects. + Staffing and related data + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + ActionResult. - + - Get's all the protocols for a department + Operations to perform against personnel in a department - List of ProtocolResult objects. - + - Gets a protocol attachment by it's id + Gets the current status for a user - ID of the protocol attachment + UserId to get the status for - + - Operations to perform against the security sub-system + Saves a status for a person + Status and related data + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + ActionResult. - + - Operations to perform against the security sub-system + Saves a status for multiple personnel + Status and related data + The cancellation token that can be used by other objects or threads to receive notice of cancellation. + ActionResult. - + - Gets the current users department rights + The options for Protocols in the Resgrid system - DepartmentRightsResult object with the department rights and group memberships - + - Operations to perform against shifts in a department + Gets all protocols for a department + - + - Get's all the shifts in a department + Gets a single protocol by id - List of ShiftResult objects. + List of ProtocolResult objects. - + - Get's all the shifts in a department + Gets a protocol attachment by it's id - List of ShiftResult objects. + ID of the protocol attachment + - + - Get's all the shift days for today + User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - List of ShiftDayResult objects. - + - Get's all the shifts in a department + Gets the Department Form that can be used for the new call process (i.e. call intake/triage form) - List of ShiftResult objects. + - + - Operations to perform against user statuses and their actions + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - + - Gets the current staffing level (state) for the user + Operations to perform against the security sub-system - StateResult object with the users current staffing level - + - Sets the staffing level (state) for the current user. + Gets the current users department rights - StateInput object with the State to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + DepartmentRightsResult object with the department rights and group memberships - + - Sets the staffing level (state) for the UserId specificed in the input data. + Unit roles - StateInput object with the State to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. - + - Operations to perform against user statuses and their actions + Gets all the shifts in a department + List of ShiftResult objects. - + - Gets the current staffing level (state) for the user + Gets all the shifts in a department - StateResult object with the users current staffing level + ShiftResult - + - Toggles and Scheduled Staffing Level Change (Enabling or Disabling It) + Gets all the shift days for today - StateInput object with the Staffing to toggle and it's value. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + List of ShiftDayResult objects. - + - Toggles and Scheduled Staffing Level Change (Enabling or Disabling It) + Gets all the shifts in a department - StateInput object with the Staffing to toggle and it's value. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + List of ShiftResult objects. - + - Operations that can be performed against resgrid recipients, usually for sending messages + The options for Personnel Statuses, Staffing and Unit Statuses that can be used to submit their status to Resgrid. + Do not use Deleted versions for submittion, they should only be used for display of previous used values. - + - Returns all the available responding options (Calls/Stations) for the department + Gets all available statuses for Personnel for the department - Array of RecipientResult objects for each responding option in the department + - + - Operations to perform against user statuses and their actions + Gets all available staffing levels for Personnel for the department + - + - Gets the status/action for the current user. User credentials are supplied via the Auth header. + Gets all active unit statuses for each unit type - StatusResult object with the users current status + - - + - Sets the status/action for the UserId passed into the data posted + Templates in the system. Templates can be call Templates, Autofills (i.e. Call Notes) + and a few other template types. - StatusInput object with the Status/Action to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. - + - Sets the status/action for the UserId passed into the data posted + Gets all call note Templates for the department - StatusInput object with the Status/Action to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + - + - Operations to perform against units in a department + Operations involving the location of a unit setting the real-time location or getting the latest location for a unit. - + Sets the location of a unit UnitLocationInput object with the gps information. Returns HttpStatusCode Created if successful, BadRequest otherwise. - + - Operations to perform against units in a department + Gets the latest location for a specified unit + - + - Get's all the units in a department and their current status information + Unit roles - List of UnitStatusResult objects, with status information for each unit. - + - Get's all the units in a department and their basic info + Gets the accountability roles for a unit - List of UnitResult objects, with basic information for each unit. + - + - Operations to perform against unit statuses + Gets the accountability roles and the current assignments for a unit + - + - Sets the status/action for the current user. + Sets the accountability roles and the current assignments for a unit - StatusInput object with the Status/Action to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + - + - Sets the status/action for the current user. + Gets all the roles for every unit in a department plus who is currently assigned to that unit role (accountability) - StatusInput object with the Status/Action to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. + - + - Operations that can be performed against resgrid voice (voip) services + Information regarding Units - + - Returns all the available responding options (Calls/Stations) for the department + Gets all the Units for a Department - Array of RecipientResult objects for each responding option in the department + - + - Object that verifies that the user's credentials + Gets all the Units for a Department + + + + + + Gets all the options available to filter units against compatible Resgrid APIs + + GetUnitsFilterOptionsResult with information pertaining to each filter option + + + + Units Status (State) information. For example is the unit Responding to a Call, or Available. + + + + + Gets all the units in a departments current (latest) status (state) or a default + + + + + + Gets the unit status for a specific unit id + + + + + + Sets the status/action for the current user. + + StatusInput object with the Status/Action to set. + Returns HttpStatusCode Created if successful, BadRequest otherwise. + + + + Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department + + + + + Returns all the available responding options (Calls/Stations) for the department + + Array of RecipientResult objects for each responding option in the department + + + + Connects to an voip session, limited to only OpenVidu. + + Voice connection result containing the data needed to connect to a voip session + + + + Determines if a user can connect to an voice session, limited to only LiveKit. + + Voice connection result containing the data needed to determine if a user can connect to a voice session + + + + Returns all the department audio streams + + Array of RecipientResult objects for each responding option in the department + + + + Object that verifies that the user's credentials @@ -3079,944 +3152,6 @@ The Timestamp of the status
- - - General department level options - - - - - Gets the department status. - - DepartmentStatusResult. - - - - Health Check system to get information and health status of the services - - - - - Returns all the call priorities (including deleted ones) for a department - - Array of CallPriorityResult objects for each call priority in the department - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Gets all the autofills in a department - - - - - - Gets the autofills for a specific type - - Type to get - - - - - Mobile or Tablet Device specific operations - - - - - Gets the department calendar items. - - ActionResult<List<CalendarItem>>. - - - - Gets the department calendar items in range. - - The start. - The end. - ActionResult<List<CalendarItem>>. - - - - Gets the calendar item. - - The identifier. - ActionResult<CalendarItem>. - - - - Gets the department calendar item types. - - ActionResult<List<CalendarItemType>>. - - - - - - - - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Get the files for a call in the Resgrid System - - CallId to get the files for - Include the data in the result - Type of file to get (Any = 0, Audio = 1, Images = 2, Files = 3, Videos = 4) - - - - - Get a users avatar from the Resgrid system based on their ID - - ID of the file - - - - - Get a users avatar from the Resgrid system based on their ID - - ID of the file - - - - - Attaches a file to a call - - ID of the user - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Get notes for a call - - CallId of the call you want to get notes for - - - - - Saves a call note - - CallId of the call you want to get notes for - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Gets all the call priorities in a department - - - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Gets all the call protocols in a department - - - - - - Gets a single protocol by id - - List of ProtocolResult objects. - - - - Gets a protocol attachment by it's id - - ID of the protocol attachment - - - - - Calls, also referred to as Dispatches. - - - - - Returns all the active calls for the department - - Array of CallResult objects for each active call in the department - - - - Returns a specific call from the Resgrid System - - Id of the call trying to be retrived - CallResult of the call in the Resgrid system - - - - Gets all the meta-data around a call, dispatched personnel, units, groups and responses - - CallId to get data for - - - - - Saves a call in the Resgrid system - - - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - - - - - Updates an existing Active Call in the Resgrid system - - Data to updated the call - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - OK status code if successful - - - - Updates a call's scheduled dispatch time if it has not been dispatched - - Data to update - - - - - Deletes a call - - ID of the call - - - - - Closes a Resgrid call - - Data to close a call - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - OK status code if successful - - - - Returns all the non-dispatched (pending) scheduled calls for the department - - Array of CallResult objects for each active call in the department - - - - Gets all the meta-data around a call, dispatched personnel, units, groups and responses - - CallId to get data for - - - - - Returns all the calls for the department inclusive in the date range - - Start date as UTC to get calls for - End date as UTC to get calls for - Array of CallResult objects for each call in the department within the range - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Gets all the call priorities in a department - - - - - - Generic configuration api endpoints - - - - - Gets the system config - - - - - - Gets the config values for a key - - - The key to get config data for - - - - Service to generate an authentication token that is required to communicate with all other v4 services - - - - - Generates a token that is then used for subsquent requests to the API. - - ValidateResult object, with IsValid set if the settings are correct - - - - Contacts, which are people, entities, and things that can be contacted (i.e. people, departments, groups, etc.) to dispatch a call to. - - - - - Gets all the contact categories for the department. - - - - - - Gets all the contacts for the department. - - - - - - Gets the contact by id - - - - - - Gets all the Notes for a Contact by the contact id - - - - - - Custom statuses - - - - - All custom statuses for a department - - - - - - Gets the active statuses that personnel can currently set for the department - - - - - - Gets the active staffing levels that personnel can currently set for the department - - - - - - Gets the active states that units can currently set for the department - - - - - - Mobile or Tablet Device specific operations - - - - - Register a unit device to receive push notification from the Resgrid system - - Input to create the registration for - Result for the registration - - - - Removed a Unit Push Notification support by PushUriId. - - Input to deregister the device for - Result for the unregistration - - - - Register a device to receive push notification from the Resgrid system - - Input to create the registration for - Result for the registration - - - - Removed a Push Notification support by PushUriId. - - Input to deregister the device for - Result for the unregistration - - - - API Calls that are used for the Dispatch App - - - - - Gets all the information required to populate the New Call form - - - - - - - - - - - - - Returns all the personnel for display in the new call personnel table - - Array of PersonnelForCallResult objects for each person in the department - - - - Returns all the groups for display in the new call groups table - - Array of GroupsForCallResult objects for each group in the department - - - - Returns all the roles for display in the new call groups table - - Array of RolesForCallResult objects for each role in the department - - - - Returns all the call quick templates - - Array of CallTemplateResult objects for each role in the department - - - - Gets calls and other data formatted for different feed formats, like RSS. - - - - - User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - - - - - Gets the Department Form that can be used for the new call process (i.e. call intake/triage form) - - - - - - User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - - - - - Gets the Department Group by it's id - - - - - - Gets all deparment groups for a department - - - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Gets the current users department rights - - DepartmentRightsResult object with the department rights and group memberships - - - - For interacting with the Inbox - - - - - Deletes a message from the inbox by its ID - - - - - - Mapping operations - - - - - Data to center the map and it's default location plus marker information for displaying makers on the map. - - GetMapDataResult object - - - - Gets the user created map layers in the system. - - GetMapLayersResult object - - - - Messaging system interaction - - - - - Returns all inbox messages for a user. - - Note that the body of these messages is truncated to 100 characters. - Array of MessageResult objects for all the messages in the users Inbox - - - - Returns all the outbox messages for a user. - - Note that the body of these messages is truncated to 100 characters. - Array of MessageResult objects for all the messages in the users Inbox - - - - Gets a specific message by it's Id. - - Integer message Identifier - MessageResult object populated with message information from the system. - - - - Gets all the recipients in the department plus default values the system accepts - - Disallow adding a noone option - Include units in the response list - MessageResult object populated with message information from the system. - - - - Sends a new message to users in the system - - Input data to send a new message - Created result if the message was sent - - - - Deletes a message from the system - - Returns OK status code if successful - - - - Deletes a messsage from the system - - MessageId of the message to delete - Returns OK status code if successful - - - - The options for Notes in the Resgrid system - - - - - Gets all notes for a department - - - - - - Gets the dispatch note (if any). A dispatch note is a Department note with the - title of "Dispatch" or a note in a Category of "Dispatch". - - - - - - Get's all the notes in a department that are not expired by a category - - Category name to get notes for - Also include notes that do not have a - - - - - Gets the dispatch note (if any). A dispatch note is a Department note with the - title of "Dispatch" or a note in a Category of "Dispatch". - - Id of the note to get - - - - - Saves a new note in the system - - Input data to send a new note - Created result if the note was saved - - - - Get's all the note Categories for a Department - - List of string of distinct note category. - - - - Operations to perform against personnel in a department - - - - - Gets information about a specific person - - UserId of the person to get info for - PersonnelInfoResult with information pertaining to that user - - - - Gets information about all users in a department - - The active filter to reduce personnel returned - PersonnelInfoResult with information pertaining to that user - - - - Gets all the options available to filter personnel against compatible Resgrid APIs - - GetPersonnelFilterOptionsResult with information pertaining to each filter option - - - - Operations involving the location of a person setting the real-time location or getting the latest location for people. - - - - - Sets the location of a person - - PersonnelLocationInput object with the gps information. - Returns HttpStatusCode Created if successful, BadRequest otherwise. - - - - Gets the latest location for a specified unit - - - - - - Operations to perform against personnel staffing, i.e. Available, Delayed, in a department - - - - - Gets the current staffing for a user - - UserId to get the status for - - - - - Saves a staffing for a person - - Staffing and related data - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. - - - - Saves a staffing for multiple personnel - - Staffing and related data - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. - - - - Operations to perform against personnel in a department - - - - - Gets the current status for a user - - UserId to get the status for - - - - - Saves a status for a person - - Status and related data - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. - - - - Saves a status for multiple personnel - - Status and related data - The cancellation token that can be used by other objects or threads to receive notice of cancellation. - ActionResult. - - - - The options for Protocols in the Resgrid system - - - - - Gets all protocols for a department - - - - - - Gets a single protocol by id - - List of ProtocolResult objects. - - - - Gets a protocol attachment by it's id - - ID of the protocol attachment - - - - - User generated forms that are dispayed to get custom information for New Calls, Unit Checks, etc - - - - - Gets the Department Form that can be used for the new call process (i.e. call intake/triage form) - - - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Operations to perform against the security sub-system - - - - - Gets the current users department rights - - DepartmentRightsResult object with the department rights and group memberships - - - - Unit roles - - - - - Gets all the shifts in a department - - List of ShiftResult objects. - - - - Gets all the shifts in a department - - ShiftResult - - - - Gets all the shift days for today - - List of ShiftDayResult objects. - - - - Gets all the shifts in a department - - List of ShiftResult objects. - - - - The options for Personnel Statuses, Staffing and Unit Statuses that can be used to submit their status to Resgrid. - Do not use Deleted versions for submittion, they should only be used for display of previous used values. - - - - - Gets all available statuses for Personnel for the department - - - - - - Gets all available staffing levels for Personnel for the department - - - - - - Gets all active unit statuses for each unit type - - - - - - Templates in the system. Templates can be call Templates, Autofills (i.e. Call Notes) - and a few other template types. - - - - - Gets all call note Templates for the department - - - - - - Operations involving the location of a unit setting the real-time location or getting the latest location for a unit. - - - - - Sets the location of a unit - - UnitLocationInput object with the gps information. - Returns HttpStatusCode Created if successful, BadRequest otherwise. - - - - Gets the latest location for a specified unit - - - - - - Unit roles - - - - - Gets the accountability roles for a unit - - - - - - Gets the accountability roles and the current assignments for a unit - - - - - - Sets the accountability roles and the current assignments for a unit - - - - - - Gets all the roles for every unit in a department plus who is currently assigned to that unit role (accountability) - - - - - - Information regarding Units - - - - - Gets all the Units for a Department - - - - - - Gets all the Units for a Department - - - - - - Gets all the options available to filter units against compatible Resgrid APIs - - GetUnitsFilterOptionsResult with information pertaining to each filter option - - - - Units Status (State) information. For example is the unit Responding to a Call, or Available. - - - - - Gets all the units in a departments current (latest) status (state) or a default - - - - - - Gets the unit status for a specific unit id - - - - - - Sets the status/action for the current user. - - StatusInput object with the Status/Action to set. - Returns HttpStatusCode Created if successful, BadRequest otherwise. - - - - Call Priorities, for example Low, Medium, High. Call Priorities can be system provided ones or custom for a department - - - - - Returns all the available responding options (Calls/Stations) for the department - - Array of RecipientResult objects for each responding option in the department - - - - Connects to an voip session, limited to only OpenVidu. - - Voice connection result containing the data needed to connect to a voip session - - - - Determines if a user can connect to an voice session, limited to only LiveKit. - - Voice connection result containing the data needed to determine if a user can connect to a voice session - - - - Returns all the department audio streams - - Array of RecipientResult objects for each responding option in the department - Gets or sets the on authentication failed. diff --git a/Web/Resgrid.Web/Areas/User/Controllers/ContactsController.cs b/Web/Resgrid.Web/Areas/User/Controllers/ContactsController.cs index 0a945540..8253aa47 100644 --- a/Web/Resgrid.Web/Areas/User/Controllers/ContactsController.cs +++ b/Web/Resgrid.Web/Areas/User/Controllers/ContactsController.cs @@ -495,7 +495,7 @@ public async Task Edit(EditContactView model, CancellationToken c var physicalAddress = new Address(); if (contact.PhysicalAddressId.HasValue) - physicalAddress = await _addressService.GetAddressByIdAsync(model.Contact.PhysicalAddressId.Value); + physicalAddress = await _addressService.GetAddressByIdAsync(contact.PhysicalAddressId.Value); physicalAddress.Address1 = model.PhysicalAddress1; physicalAddress.City = model.PhysicalCity; @@ -515,7 +515,7 @@ public async Task Edit(EditContactView model, CancellationToken c var mailingAddress = new Address(); if (contact.MailingAddressId.HasValue) - mailingAddress = await _addressService.GetAddressByIdAsync(model.Contact.MailingAddressId.Value); + mailingAddress = await _addressService.GetAddressByIdAsync(contact.MailingAddressId.Value); mailingAddress.Address1 = model.PhysicalAddress1; mailingAddress.City = model.PhysicalCity; diff --git a/Web/Resgrid.Web/Areas/User/Views/Groups/Geofence.cshtml b/Web/Resgrid.Web/Areas/User/Views/Groups/Geofence.cshtml index 03c87193..1ad3ea88 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Groups/Geofence.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Groups/Geofence.cshtml @@ -21,7 +21,7 @@ Groups
  • - GeoFence Station + Geofence Station
  • @@ -71,7 +71,7 @@ @section Scripts { - @if (String.IsNullOrWhiteSpace(Model.Group.Geofence)) + @if (Model.Group == null || String.IsNullOrWhiteSpace(Model.Group.Geofence)) {