private async Task CreatePlaceholderItemAsync(SqlConnection cn, int projectId, Milestone milestone) { // if there's already at least one open work item in this milestone, don't create a placeholder var workItems = await cn.QueryAsync <int>( "SELECT [Id] FROM [dbo].[WorkItem] WHERE [ProjectId]=@projectId AND [MilestoneId]=@msId AND [CloseReasonId] IS NULL", new { projectId, msId = milestone.Id }); if (workItems.Any()) { return; } if (!milestone.TeamId.HasValue) { milestone.TeamId = CurrentOrgUser.CurrentTeamId; } // can't create placeholder without known team if (!milestone.TeamId.HasValue) { return; } const string text = @"Placeholder item created with milestone. This enables you to filter for this project on the milestone dashboard. This will automatically close when you add another work item to this milestone."; var team = await cn.FindAsync <Team>(milestone.TeamId.Value); var prj = await cn.FindAsync <Project>(projectId); var workItem = new Ginseng.Models.WorkItem() { OrganizationId = team.OrganizationId, TeamId = team.Id, ApplicationId = prj.ApplicationId, MilestoneId = milestone.Id, ProjectId = projectId, Title = "Placeholder item created with milestone", HtmlBody = $"<p>{text}</p>", TextBody = text }; await workItem.SetNumberAsync(cn); if (await Data.TrySaveAsync(cn, workItem)) { var wil = new WorkItemLabel() { WorkItemId = workItem.Id, LabelId = await GetPlaceholderLabelIdAsync(cn) }; await Data.TrySaveAsync(cn, wil); } }
private async Task <int> CreateWorkItemFromTicketAsync(SqlConnection cn, IFreshdeskClient client, Ticket ticket, int objectId, ActionItemType objectType) { int?appId = (objectType == ActionItemType.Application) ? objectId : (objectId == -1) ? CurrentOrgUser.CurrentAppId : await GetAppFromProjectIdAsync(cn, objectId); int?projectId = (objectType == ActionItemType.Project) ? objectId : default(int?); if (projectId == -1 && ticket.CompanyId.HasValue) { var company = await client.GetCompanyAsync(ticket.CompanyId.Value); projectId = await CreateNewProjectAsync(cn, CurrentOrgUser.CurrentAppId.Value, company); } if (projectId == -1) { projectId = null; } var workItem = new Ginseng.Models.WorkItem() { OrganizationId = OrgId, ApplicationId = appId, TeamId = CurrentOrgUser.CurrentTeamId.Value, ProjectId = projectId, Title = $"FD: {ticket.Subject} (ticket # {ticket.Id})", HtmlBody = ticket.Description + $"<hr/><p>Created from Freshdesk <a href=\"{CurrentOrg.FreshdeskUrl}/a/tickets/{ticket.Id}\">ticket {ticket.Id}</a></p>" }; await workItem.SetNumberAsync(cn); await workItem.SaveHtmlAsync(Data, cn); await Data.TrySaveAsync(workItem); // this will make it "work on next" if it has no priority already var wip = await cn.FindWhereAsync <WorkItemPriority>(new { WorkItemId = workItem.Id }) ?? new WorkItemPriority() { WorkItemId = workItem.Id, Value = 1 }; await Data.TrySaveAsync(wip); return(workItem.Number); }
public async Task <RedirectResult> OnPostImportWorkItemsAsync(int sourceProjectId, int destProjectId) { using (var cn = Data.GetConnection()) { var workItems = await new OpenWorkItems() { OrgId = OrgId, ProjectId = sourceProjectId }.ExecuteAsync(cn); foreach (var item in workItems) { var newItem = new Ginseng.Models.WorkItem() { OrganizationId = OrgId, TeamId = item.TeamId, ProjectId = destProjectId, Title = item.Title, TextBody = item.TextBody, HtmlBody = item.HtmlBody, SizeId = item.SizeId }; await newItem.SetNumberAsync(cn); await cn.SaveAsync(newItem, CurrentUser); await cn.ExecuteAsync( @"INSERT INTO [dbo].[WorkItemLabel] ( [WorkItemId], [LabelId], [CreatedBy], [DateCreated] ) SELECT @destWorkItemId, [wil].[LabelId], [wil].[CreatedBy], getdate() FROM [dbo].[WorkItemLabel] [wil] WHERE [wil].[WorkItemId]=@sourceWorkItemId", new { destWorkItemId = newItem.Id, sourceWorkItemId = item.Id }); } } return(Redirect($"/Dashboard/Projects/{destProjectId}")); }