public async Task PopulateTimedWorkItemOccurences(RecurringWorkItem workItem, int userId, List <int> assigneeUserIds, DateTime now, bool populateWorkItemAssignments = true) { var existingWorkItems = (await _workItemRepository.GetWorkItems(workItem.Id, now)).ToList(); var calculatedWorkItems = new List <WorkItem>(); for (var scheduledAt = workItem.RecurStart.Value; scheduledAt <= workItem.RecurEnd.Value; scheduledAt = AddInterval(scheduledAt, workItem.RecurInterval.Value, workItem.RecurIntervalCount.Value)) { if (scheduledAt >= now) { calculatedWorkItems.Add(new WorkItem() { AdminGroupId = workItem.AdminGroupId, CompletionMode = workItem.CompletionMode, CreatedAt = now, CreatedByUserId = userId, DescriptionMarkup = workItem.DescriptionMarkup, Location = workItem.Location, Name = workItem.Name, PatrolId = workItem.PatrolId, RecurringWorkItemId = workItem.Id, ScheduledAt = scheduledAt, }); } } var allAssignments = await _workItemRepository.GetWorkItemAssignments(workItem.Id, now); var missing = calculatedWorkItems.Where(x => !existingWorkItems.Any(y => y.ScheduledAt == x.ScheduledAt)).ToList(); var toRemove = existingWorkItems.Where(x => x.ScheduledAt > now && !calculatedWorkItems.Any(y => y.ScheduledAt == x.ScheduledAt)); var toUpdate = existingWorkItems.Where(x => x.ScheduledAt > now && calculatedWorkItems.Any(y => y.ScheduledAt == x.ScheduledAt)); foreach (var wi in missing) { await _workItemRepository.InsertWorkItem(wi); if (populateWorkItemAssignments && assigneeUserIds != null) { foreach (var uid in assigneeUserIds) { var assignment = new WorkItemAssignment() { WorkItemId = wi.Id, UserId = uid }; await _workItemRepository.InsertWorkItemAssignment(assignment); } } } foreach (var wi in toRemove) { var toRemoveAssignments = allAssignments.Where(x => x.WorkItemId == wi.Id).ToList(); foreach (var wis in toRemoveAssignments) { await _workItemRepository.DeleteWorkItemAssignment(wis); } await _workItemRepository.DeleteWorkItem(wi); } foreach (var wi in toUpdate) { wi.AdminGroupId = workItem.AdminGroupId; wi.CompletionMode = workItem.CompletionMode; wi.DescriptionMarkup = workItem.DescriptionMarkup; wi.Location = workItem.Location; wi.Name = workItem.Name; await _workItemRepository.UpdateWorkItem(wi); if (populateWorkItemAssignments) { var assignees = allAssignments.Where(x => x.WorkItemId == wi.Id).ToList(); if (assigneeUserIds != null) { await assignees.DifferenceWith(assigneeUserIds, (a, id) => a.UserId == id, id => _workItemRepository.InsertWorkItemAssignment(new WorkItemAssignment() { WorkItemId = wi.Id, UserId = id }), wia => _workItemRepository.DeleteWorkItemAssignment(wia)); } } } }