using Disco.Data.Repository; using Disco.Models.Repository; using Disco.Models.Services.Jobs.JobLists; using Disco.Services.Authorization; using Disco.Services.Users; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Disco.Services { public static class JobTableExtensions { private static JobTableModel CloneEmptyJobTableModel(JobTableModel Model) { return new JobTableModel() { ShowId = Model.ShowId, ShowDeviceAddress = Model.ShowDeviceAddress, ShowDates = Model.ShowDates, ShowType = Model.ShowType, ShowDevice = Model.ShowDevice, ShowUser = Model.ShowUser, ShowTechnician = Model.ShowTechnician, ShowLocation = Model.ShowLocation, ShowStatus = Model.ShowStatus, ShowLastActivityDate = Model.ShowLastActivityDate, IsSmallTable = Model.IsSmallTable, HideClosedJobs = Model.HideClosedJobs, EnablePaging = Model.EnablePaging, EnableFilter = Model.EnableFilter }; } public static IDictionary MultiCampusModels(this JobTableModel Model) { var items = Model.Items; if (items == null || items.Count() > 0) { return items.OrderBy(i => i.DeviceAddress).GroupBy(i => i.DeviceAddress).ToDictionary( ig => ig.Key ?? string.Empty, ig => { var jtm = CloneEmptyJobTableModel(Model); jtm.Items = ig.ToList(); return jtm; } ); } else { return null; } } private static List FilterAllowedTypes(AuthorizationToken Authorization) { if (!Authorization.HasAll(Claims.Job.Types.ShowHMisc, Claims.Job.Types.ShowHNWar, Claims.Job.Types.ShowHWar, Claims.Job.Types.ShowSApp, Claims.Job.Types.ShowSImg, Claims.Job.Types.ShowSOS, Claims.Job.Types.ShowUMgmt)) { // Must Filter List allowedTypes = new List(6); if (Authorization.Has(Claims.Job.Types.ShowHMisc)) allowedTypes.Add(JobType.JobTypeIds.HMisc); if (Authorization.Has(Claims.Job.Types.ShowHNWar)) allowedTypes.Add(JobType.JobTypeIds.HNWar); if (Authorization.Has(Claims.Job.Types.ShowHWar)) allowedTypes.Add(JobType.JobTypeIds.HWar); if (Authorization.Has(Claims.Job.Types.ShowSApp)) allowedTypes.Add(JobType.JobTypeIds.SApp); if (Authorization.Has(Claims.Job.Types.ShowSImg)) allowedTypes.Add(JobType.JobTypeIds.SImg); if (Authorization.Has(Claims.Job.Types.ShowSOS)) allowedTypes.Add(JobType.JobTypeIds.SOS); if (Authorization.Has(Claims.Job.Types.ShowUMgmt)) allowedTypes.Add(JobType.JobTypeIds.UMgmt); return allowedTypes; } return null; } public static IQueryable FilterPermissions(this JobTableModel model, IQueryable Jobs, AuthorizationToken Authorization) { var allowedTypes = FilterAllowedTypes(Authorization); if (allowedTypes != null) { return Jobs.Where(j => allowedTypes.Contains(j.JobTypeId)); } return Jobs; } public static IEnumerable PermissionsFiltered(this IEnumerable Items, AuthorizationToken Authorization) { if (Items != null && Items.Count() > 0) { var allowedTypes = FilterAllowedTypes(Authorization); if (allowedTypes != null) { return Items.Where(j => allowedTypes.Contains(j.JobTypeId)).ToList(); } } return Items; } public static IEnumerable DetermineItems(this JobTableModel model, DiscoDataContext Database, IQueryable Jobs, bool FilterAuthorization) { List items; // Permissions if (FilterAuthorization) Jobs = model.FilterPermissions(Jobs, UserService.CurrentAuthorization); if (model.ShowStatus || model.ShowLastActivityDate) { var jobItems = Jobs.Select(j => new JobTableStatusItemModel() { JobId = j.Id, OpenedDate = j.OpenedDate, ClosedDate = j.ClosedDate, JobTypeId = j.JobTypeId, JobTypeDescription = j.JobType.Description, DeviceSerialNumber = j.Device.SerialNumber, DeviceProfileId = j.Device.DeviceProfileId, DeviceModelId = j.Device.DeviceModelId, DeviceModelDescription = j.Device.DeviceModel.Description, DeviceAddressId = j.Device.DeviceProfile.DefaultOrganisationAddress, UserId = j.UserId, UserDisplayName = j.User.DisplayName, OpenedTechUserId = j.OpenedTechUserId, OpenedTechUserDisplayName = j.OpenedTechUser.DisplayName, DeviceHeldLocation = j.DeviceHeldLocation, Flags = j.Flags, JobMetaWarranty_ExternalReference = j.JobMetaWarranty.ExternalReference, JobMetaWarranty_ExternalLoggedDate = j.JobMetaWarranty.ExternalLoggedDate, JobMetaWarranty_ExternalCompletedDate = j.JobMetaWarranty.ExternalCompletedDate, JobMetaNonWarranty_RepairerLoggedDate = j.JobMetaNonWarranty.RepairerLoggedDate, JobMetaNonWarranty_RepairerCompletedDate = j.JobMetaNonWarranty.RepairerCompletedDate, JobMetaNonWarranty_AccountingChargeAddedDate = j.JobMetaNonWarranty.AccountingChargeAddedDate, JobMetaNonWarranty_AccountingChargePaidDate = j.JobMetaNonWarranty.AccountingChargePaidDate, JobMetaNonWarranty_AccountingChargeRequiredDate = j.JobMetaNonWarranty.AccountingChargeRequiredDate, JobMetaNonWarranty_IsInsuranceClaim = j.JobMetaNonWarranty.IsInsuranceClaim, JobMetaInsurance_ClaimFormSentDate = j.JobMetaInsurance.ClaimFormSentDate, JobMetaNonWarranty_InvoiceReceivedDate = j.JobMetaNonWarranty.InvoiceReceivedDate, JobMetaNonWarranty_PurchaseOrderRaisedDate = j.JobMetaNonWarranty.PurchaseOrderRaisedDate, JobMetaNonWarranty_PurchaseOrderSentDate = j.JobMetaNonWarranty.PurchaseOrderSentDate, RecentAttachmentDate = j.JobAttachments.Max(ja => ja.Timestamp), RecentLogDate = j.JobLogs.Max(jl => jl.Timestamp), WaitingForUserAction = j.WaitingForUserAction, DeviceReadyForReturn = j.DeviceReadyForReturn, DeviceHeld = j.DeviceHeld, DeviceReturnedDate = j.DeviceReturnedDate, JobMetaWarranty_ExternalName = j.JobMetaWarranty.ExternalName, JobMetaNonWarranty_RepairerName = j.JobMetaNonWarranty.RepairerName, ActiveJobQueues = j.JobQueues.Where(jq => !jq.RemovedDate.HasValue).Select(jq => new JobTableStatusQueueItemModel() { Id = jq.Id, QueueId = jq.JobQueueId, AddedDate = jq.AddedDate, SLAExpiresDate = jq.SLAExpiresDate, Priority = jq.Priority }) }); items = new List(); foreach (var j in jobItems) { j.StatusId = j.CalculateStatusId(); j.StatusDescription = JobExtensions.JobStatusDescription(j.StatusId, j); var activityDates = new DateTime?[] { j.ActiveJobQueues.Max(jq => jq.AddedDate), j.ClosedDate, j.DeviceHeld, j.DeviceReadyForReturn, j.DeviceReturnedDate, j.JobMetaInsurance_ClaimFormSentDate, j.JobMetaNonWarranty_AccountingChargeAddedDate, j.JobMetaNonWarranty_AccountingChargePaidDate, j.JobMetaNonWarranty_AccountingChargeRequiredDate, j.JobMetaNonWarranty_InvoiceReceivedDate, j.JobMetaNonWarranty_PurchaseOrderRaisedDate, j.JobMetaNonWarranty_PurchaseOrderSentDate, j.JobMetaNonWarranty_RepairerCompletedDate, j.JobMetaNonWarranty_RepairerLoggedDate, j.JobMetaWarranty_ExternalCompletedDate, j.JobMetaWarranty_ExternalLoggedDate, j.OpenedDate, j.RecentAttachmentDate, j.RecentLogDate, j.WaitingForUserAction }; j.LastActivityDate = activityDates.Max().Value; items.Add(j); } } else { items = Jobs.Select(j => new JobTableItemModel() { JobId = j.Id, OpenedDate = j.OpenedDate, ClosedDate = j.ClosedDate, JobTypeId = j.JobTypeId, JobTypeDescription = j.JobType.Description, DeviceSerialNumber = j.Device.SerialNumber, DeviceProfileId = j.Device.DeviceProfileId, DeviceModelId = j.Device.DeviceModelId, DeviceModelDescription = j.Device.DeviceModel.Description, DeviceAddressId = j.Device.DeviceProfile.DefaultOrganisationAddress, UserId = j.UserId, UserDisplayName = j.User.DisplayName, OpenedTechUserId = j.OpenedTechUserId, OpenedTechUserDisplayName = j.OpenedTechUser.DisplayName, DeviceHeldLocation = j.DeviceHeldLocation, Flags = j.Flags }).ToList(); } if (!model.ShowDeviceAddress.HasValue) model.ShowDeviceAddress = Database.DiscoConfiguration.MultiSiteMode; foreach (var j in items) { j.UserFriendlyId =j.UserId == null ? null : UserExtensions.FriendlyUserId(j.UserId); j.OpenedTechUserFriendlyId = UserExtensions.FriendlyUserId(j.OpenedTechUserId); if (j.DeviceAddressId.HasValue) j.DeviceAddress = Database.DiscoConfiguration.OrganisationAddresses.GetAddress(j.DeviceAddressId.Value).Name; } return items; } public static JobTableModel Fill(this JobTableModel model, DiscoDataContext Database, IQueryable Jobs, bool FilterAuthorization) { model.Items = model.DetermineItems(Database, Jobs, FilterAuthorization); return model; } public static JobTableModel Score(this JobTableModel model, string Test, double Fuzziness = 0) { model.Items = model.Items.OrderByDescending(i => i.ScoreValues.Score(Test)).ToList(); return model; } public static double? SlaPrecentageRemaining(this IEnumerable queueItems) { return queueItems.Where(i => i.SLAExpiresDate.HasValue).Min(i => { var total = (i.SLAExpiresDate.Value - i.AddedDate).Ticks; var remaining = (i.SLAExpiresDate.Value - DateTime.Now).Ticks; return ((double)remaining / total); }); } public static IEnumerable UsersQueueItems(this IEnumerable queueItems, AuthorizationToken Authorization) { var usersQueues = Jobs.JobQueues.JobQueueService.UsersQueues(Authorization).ToDictionary(q => q.JobQueue.Id); return queueItems.Where(qi => usersQueues.ContainsKey(qi.QueueId)); } public static IEnumerable JobLocationReferences(this IEnumerable Items, IEnumerable IncludeLocations) { var innerItems = Items.Where(i => !string.IsNullOrWhiteSpace(i.DeviceHeldLocation) && i.DeviceHeld.HasValue && !i.DeviceReturnedDate.HasValue); return IncludeLocations.GroupJoin(innerItems, o => o, i => i.DeviceHeldLocation, (i, o) => new JobLocationReference { Location = i, References = o.ToList() }, StringComparer.OrdinalIgnoreCase); } public static IEnumerable JobLocationReferences(this IEnumerable Items) { return Items.Where(i => !string.IsNullOrWhiteSpace(i.DeviceHeldLocation) && i.DeviceHeld.HasValue && !i.DeviceReturnedDate.HasValue) .GroupBy(i => i.DeviceHeldLocation, StringComparer.OrdinalIgnoreCase) .Select(i => new JobLocationReference() { Location = i.Key, References = i.ToList() }); } } }