From 1223791096c2f1793e847e05d480ad93764b59ba Mon Sep 17 00:00:00 2001 From: jessikitty Date: Wed, 6 May 2026 09:29:43 +1000 Subject: [PATCH] feat: add change tracking on ticket updates, plugin version constant --- Services/ServiceTrackerService.cs | 59 ++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/Services/ServiceTrackerService.cs b/Services/ServiceTrackerService.cs index 706f8ad..35bc872 100644 --- a/Services/ServiceTrackerService.cs +++ b/Services/ServiceTrackerService.cs @@ -9,6 +9,8 @@ namespace Disco.Plugins.ServiceTracker.Services { public class ServiceTrackerService { + public const string PluginVersion = "1.1.0"; + private readonly DiscoDataContext _database; private readonly ServiceTrackerDataStore _dataStore; private readonly ServiceTrackerConfig _config; @@ -118,7 +120,7 @@ namespace Disco.Plugins.ServiceTracker.Services else ageBadge = (ageDays / 30) + " mo" + (ageDays / 30 > 1 ? "s" : ""); var eta = (ticket != null ? ticket.EstimatedCompletion : null) ?? job.ExpectedClosedDate; - string etaDisplay = "—"; + string etaDisplay = "\u2014"; if (eta.HasValue) { var etaDays = (int)(eta.Value - now).TotalDays; @@ -152,7 +154,7 @@ namespace Disco.Plugins.ServiceTracker.Services { JobId = job.Id, JobTypeDescription = job.JobType != null ? job.JobType.Description : job.JobTypeId, - DeviceSerialNumber = job.DeviceSerialNumber ?? "—", + DeviceSerialNumber = job.DeviceSerialNumber ?? "\u2014", DeviceModelDescription = job.Device != null && job.Device.DeviceModel != null ? job.Device.DeviceModel.Description : null, DeviceComputerName = job.Device != null ? job.Device.DeviceDomainId : null, UserId = job.UserId, @@ -198,15 +200,13 @@ namespace Disco.Plugins.ServiceTracker.Services AvgAgeDays = tiles.Count > 0 ? Math.Round(tiles.Average(t => (double)t.AgeDays), 1) : 0, OldestJobDays = tiles.Count > 0 ? tiles.Max(t => t.AgeDays) : 0 }; - foreach (var p in _config.Priorities) - stats.ByPriority[p.Id] = tiles.Count(t => t.PriorityId == p.Id); + foreach (var p in _config.Priorities) stats.ByPriority[p.Id] = tiles.Count(t => t.PriorityId == p.Id); stats.Critical = tiles.Count(t => t.PriorityId == "critical"); stats.High = tiles.Count(t => t.PriorityId == "high"); stats.Medium = tiles.Count(t => t.PriorityId == "medium"); stats.Low = tiles.Count(t => t.PriorityId == "low"); stats.Scheduled = tiles.Count(t => t.PriorityId == "scheduled"); - foreach (var l in _config.Locations) - stats.ByLocation[l.Id] = tiles.Count(t => t.LocationId == l.Id); + foreach (var l in _config.Locations) stats.ByLocation[l.Id] = tiles.Count(t => t.LocationId == l.Id); stats.InItOffice = tiles.Count(t => t.LocationId == "it-office"); stats.WithUser = tiles.Count(t => t.LocationId == "with-user"); stats.AtRepairer = tiles.Count(t => t.LocationId == "at-repairer"); @@ -262,13 +262,48 @@ namespace Disco.Plugins.ServiceTracker.Services { var ticket = _dataStore.GetTicket(jobId); if (ticket == null) ticket = new ServiceTicket { JobId = jobId }; - if (priorityId != null) ticket.PriorityId = priorityId; - if (locationId != null) ticket.LocationId = locationId; - if (assignedTechId != null) ticket.AssignedTechId = assignedTechId; - if (eta.HasValue) ticket.EstimatedCompletion = eta; - if (status != null) ticket.StatusOverride = status; - if (summary != null) ticket.Summary = summary; + if (ticket.ChangeLog == null) ticket.ChangeLog = new List(); + + // Track changes + if (priorityId != null && priorityId != ticket.PriorityId) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "Priority", OldValue = ticket.PriorityId, NewValue = priorityId }); + ticket.PriorityId = priorityId; + } + if (locationId != null && locationId != ticket.LocationId) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "Location", OldValue = ticket.LocationId, NewValue = locationId }); + ticket.LocationId = locationId; + } + if (assignedTechId != null && assignedTechId != ticket.AssignedTechId) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "Assigned Tech", OldValue = ticket.AssignedTechId, NewValue = assignedTechId }); + ticket.AssignedTechId = assignedTechId; + } + if (eta.HasValue) + { + var oldEta = ticket.EstimatedCompletion.HasValue ? ticket.EstimatedCompletion.Value.ToString("dd MMM yyyy") : "none"; + var newEta = eta.Value.ToString("dd MMM yyyy"); + if (oldEta != newEta) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "ETA", OldValue = oldEta, NewValue = newEta }); + ticket.EstimatedCompletion = eta; + } + } + if (status != null && status != ticket.StatusOverride) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "Status", OldValue = ticket.StatusOverride ?? "(Disco default)", NewValue = string.IsNullOrEmpty(status) ? "(Disco default)" : status }); + ticket.StatusOverride = status; + } + if (summary != null && summary != ticket.Summary) + { + ticket.ChangeLog.Add(new ChangeEntry { UserId = modifiedBy, Field = "Summary", OldValue = null, NewValue = "(updated)" }); + ticket.Summary = summary; + } + ticket.LastModifiedBy = modifiedBy; + + // Recalculate SLA if priority changed if (priorityId != null) { var priority = _config.Priorities.FirstOrDefault(p => p.Id == priorityId);