using System.Collections.Generic;
using System.Diagnostics;
public string Title { get; set; }
public DateTime CreatedAt { get ; set; }
public ResolutionState Status { get ; set; }
public IEnumerable<Ticket> SubTickets { get; set; }
public static IEnumerable<Ticket> GetOverdue(IEnumerable<Ticket> tickets, DateTime cutoff) {
return FilterTickets(tickets, x => x.Status != ResolutionState.Closed && x.CreatedAt <= cutoff);
public static IEnumerable<Ticket> FilterTickets(IEnumerable<Ticket> tickets, Func<Ticket, bool> predicate)
default == tickets ? Enumerable.Empty<Ticket>()
: tickets.Where(predicate).Concat(tickets.SelectMany(x => FilterTickets(x.SubTickets, predicate)));
static void Main(string[] args)
var priya = TestData.OnboardPriya();
var marcus = TestData.OnboardMarcus();
var carly = TestData.OnboardCarly();
var tickets = new Ticket[] {priya, marcus, carly};
var cutoff = DateTime.Today.AddDays(-7);
var overdue = Ticket.GetOverdue(tickets, cutoff);
Console.Error.WriteLine("null overdue");
if (overdue.Count() != TestData.OverdueTitles.Count()) {
Console.Error.WriteLine("incorrect count");
foreach (var expired in TestData.OverdueTitles) {
if (!overdue.Any(t => t.Title == expired)) {
Console.Error.WriteLine($"missing {expired}");
Console.WriteLine("Finished");
public static Ticket OnboardPriya()
CreatedAt = DateTime.Today.AddDays(-10),
Status = ResolutionState.Opened,
Title = "Network Access for Priya",
CreatedAt = DateTime.Today.AddDays(-8),
Status = ResolutionState.Assigned,
Title = "AWS access for Priya",
CreatedAt = DateTime.Today.AddDays(-4),
Status = ResolutionState.Assigned
Title = "VPN Access for Priya",
CreatedAt = DateTime.Today.AddDays(-8),
Status = ResolutionState.Assigned,
Title = "VPN 2FA acquired",
CreatedAt = DateTime.Today.AddDays(-8),
Status = ResolutionState.Blocked
Title = "Desk Setup for Priya",
CreatedAt = DateTime.Today.AddDays(-9),
Status = ResolutionState.Closed
Title = "Laptop for Priya",
CreatedAt = DateTime.Today.AddDays(-10),
Status = ResolutionState.Assigned
public static Ticket OnboardMarcus()
Title = "Onboard Marcus",
CreatedAt = DateTime.Today.AddDays(-12),
Status = ResolutionState.Assigned,
Title = "Network Access for Marcus",
CreatedAt = DateTime.Today.AddDays(-10),
Status = ResolutionState.Closed,
Title = "AWS access for Marcus",
CreatedAt = DateTime.Today.AddDays(-9),
Status = ResolutionState.Closed
Title = "VPN Access for Marcus",
CreatedAt = DateTime.Today.AddDays(-10),
Status = ResolutionState.Closed
Title = "Desk Setup for Marcus",
CreatedAt = DateTime.Today.AddDays(-10),
Status = ResolutionState.Opened
Title = "Laptop for Marcus",
CreatedAt = DateTime.Today.AddDays(-8),
Status = ResolutionState.Closed,
public static Ticket OnboardCarly()
CreatedAt = DateTime.Today.AddDays(-6),
Status = ResolutionState.Assigned,
Title = "Network Access for Carly",
CreatedAt = DateTime.Today.AddDays(-6),
Status = ResolutionState.Closed,
Title = "AWS access for Carly",
CreatedAt = DateTime.Today.AddDays(-6),
Status = ResolutionState.Closed
Title = "VPN Access for Carly",
CreatedAt = DateTime.Today.AddDays(-6),
Status = ResolutionState.Assigned
Title = "Desk Setup for Carly",
CreatedAt = DateTime.Today.AddDays(-6),
Status = ResolutionState.Closed
Title = "Laptop for Carly",
CreatedAt = DateTime.Today.AddDays(-5),
Status = ResolutionState.Assigned,
public static IEnumerable<string> OverdueTitles = new [] {
"Network Access for Priya",