Added an additional column to the ticket forum table to store the linked project ID, and updated both the view models and data transfer models accordingly.

This commit is contained in:
ashutosh.nehete 2025-04-25 21:47:06 +05:30
parent ace2fe7d54
commit c338140210
9 changed files with 2802 additions and 14 deletions

View File

@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_ProjectId_Column_In_TicketForum_Table : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "LinkedActivityId",
table: "Tickets",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddColumn<int>(
name: "LinkedProjectId",
table: "Tickets",
type: "int",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "LinkedProjectId",
table: "Tickets");
migrationBuilder.AlterColumn<int>(
name: "LinkedActivityId",
table: "Tickets",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
}
}
}

View File

@ -1227,7 +1227,10 @@ namespace Marco.Pms.DataAccess.Migrations
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("LinkedActivityId")
b.Property<int?>("LinkedActivityId")
.HasColumnType("int");
b.Property<int>("LinkedProjectId")
.HasColumnType("int");
b.Property<Guid>("PriorityId")

View File

@ -9,7 +9,8 @@
public Guid TypeId { get; set; } // QualityIssue, HelpDesk, Feedback
public int CreatedById { get; set; }
public DateTime CreatedAt { get; set; }
public int LinkedActivityId { get; set; } // task or project ID
public int LinkedProjectId { get; set; }
public int? LinkedActivityId { get; set; } // task or project ID
public ICollection<ForumAttachmentDto>? Attachments { get; set; }
public Guid PriorityId { get; set; }
public ICollection<Guid>? TagIds { get; set; }

View File

@ -9,7 +9,8 @@
public Guid TypeId { get; set; } // QualityIssue, HelpDesk, Feedback
public int CreatedById { get; set; }
public DateTime CreatedAt { get; set; }
public int LinkedActivityId { get; set; } // task or project ID
public int LinkedProjectId { get; set; }
public int? LinkedActivityId { get; set; } // task or project ID
public ICollection<ForumAttachmentDto>? Attachments { get; set; }
public Guid PriorityId { get; set; }
public ICollection<Guid>? TagIds { get; set; }

View File

@ -20,7 +20,9 @@ namespace Marco.Pms.Model.Forum
public TicketTypeMaster? TicketTypeMaster { get; set; }
public int CreatedById { get; set; }
public DateTime CreatedAt { get; set; }
public int LinkedActivityId { get; set; } // task or project ID
public int LinkedProjectId { get; set; }
public int? LinkedActivityId { get; set; } // task or project ID
//public ICollection<TicketComment>? Comments { get; set; } // view model
//public ICollection<TicketAttachment>? Attachments { get; set; } // view model

View File

@ -18,6 +18,7 @@ namespace Marco.Pms.Model.Mapper
TypeId = createTicketDto.TypeId,
CreatedById = createTicketDto.CreatedById,
CreatedAt = createTicketDto.CreatedAt,
LinkedProjectId = createTicketDto.LinkedProjectId,
LinkedActivityId = createTicketDto.LinkedActivityId,
PriorityId = createTicketDto.PriorityId,
TenantId = createTicketDto.TenantId,
@ -34,7 +35,8 @@ namespace Marco.Pms.Model.Mapper
TypeId = updateTicketDto.TypeId,
CreatedById = ticket.CreatedById,
CreatedAt = ticket.CreatedAt,
LinkedActivityId = updateTicketDto.LinkedActivityId,
LinkedProjectId = ticket.LinkedProjectId,
LinkedActivityId = ticket.LinkedActivityId,
PriorityId = updateTicketDto.PriorityId,
TenantId = ticket.TenantId
};
@ -98,6 +100,7 @@ namespace Marco.Pms.Model.Mapper
Subject = ticket.Subject,
Description = ticket.Description,
CreatedAt = ticket.CreatedAt,
LinkedProjectId = ticket.LinkedProjectId,
LinkedActivityId = ticket.LinkedActivityId,
Status = ticket.TicketStatusMaster.ToTicketStatusVMFromTicketStatusMaster(),
Priority = ticket.Priority.ToTicketPriorityVMFromTicketPriorityMaster(),

View File

@ -12,7 +12,10 @@ namespace Marco.Pms.Model.ViewModels.Forum
public TicketPriorityVM? Priority { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public int LinkedActivityId { get; set; } // task or project ID
public int LinkedProjectId { get; set; }
public string? ProjectName { get; set; }
public int? LinkedActivityId { get; set; } // task or project ID
public string? ActivityName { get; set; }
public ICollection<TicketCommentVM>? Comments { get; set; } // view model
public ICollection<TicketAttachmentVM>? Attachments { get; set; } // view model
public ICollection<TicketTagVM>? Tags { get; set; }

View File

@ -4,6 +4,7 @@ using Marco.Pms.Model.Dtos.Forum;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Forum;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Forum;
using Marco.Pms.Services.Service;
@ -143,7 +144,21 @@ namespace Marco.Pms.Services.Controllers
attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl));
}
ticketVM.Attachments = attachmentVMs;
_logger.LogInfo("Ticket created by Employee {EmployeeId}", ticketForum.CreatedById);
Project project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == ticketForum.LinkedProjectId) ?? new Project();
ticketVM.ProjectName = project.Name;
if (createTicketDto.LinkedActivityId != null && createTicketDto.LinkedActivityId != 0)
{
WorkItem workItem = await _context.WorkItems.Include(w => w.ActivityMaster).FirstOrDefaultAsync(w => w.Id == ticketForum.LinkedActivityId) ?? new WorkItem();
if (workItem.ActivityMaster != null)
{
ticketVM.ActivityName = workItem.ActivityMaster.ActivityName;
}
else
{
ticketVM.ActivityName = "";
}
}
_logger.LogInfo("Ticket created by Employee {EmployeeId} for project {ProjectId}", ticketForum.CreatedById, project.Id);
return Ok(ApiResponse<object>.SuccessResponse(ticketVM, "Ticket Created Successfully", 200));
}
_logger.LogWarning("Employee {EmployeeId} tries to create ticket in different Tenant", createTicketDto.CreatedById);
@ -312,6 +327,20 @@ namespace Marco.Pms.Services.Controllers
}
ticketVM.Comments = commentVMs;
ticketVM.Attachments = ticketAttachmentVMs;
Project project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == ticketForum.LinkedProjectId) ?? new Project();
ticketVM.ProjectName = project.Name;
if (updateTicketDto.LinkedActivityId != null && updateTicketDto.LinkedActivityId != 0)
{
WorkItem workItem = await _context.WorkItems.Include(w => w.ActivityMaster).FirstOrDefaultAsync(w => w.Id == ticketForum.LinkedActivityId) ?? new WorkItem();
if (workItem.ActivityMaster != null)
{
ticketVM.ActivityName = workItem.ActivityMaster.ActivityName;
}
else
{
ticketVM.ActivityName = "";
}
}
_logger.LogInfo("Ticket {TicketId} updated", updateTicketDto.Id);
return Ok(ApiResponse<object>.SuccessResponse(ticketVM, "Ticket Updated Successfully", 200));
}
@ -406,7 +435,7 @@ namespace Marco.Pms.Services.Controllers
}
commentVM.Attachments = attachmentVMs;
_logger.LogInfo("User {ApplicationUserId} commented on a ticket", comment.AuthorId);
_logger.LogInfo("User {ApplicationUserId} commented on a ticket{TicketId}", comment.AuthorId, comment.TicketId);
return Ok(ApiResponse<object>.SuccessResponse(commentVM, "Comment Created Successfully", 200));
}
[HttpPost("ticket/comment/edit")]
@ -535,6 +564,8 @@ namespace Marco.Pms.Services.Controllers
int tenantId = _userHelper.GetTenantId();
List<TicketAttachmentVM> ticketAttachmentVMs = new List<TicketAttachmentVM>();
TicketAttachment attachment = new TicketAttachment();
foreach (var forumAttachmentDto in forumAttachmentDtos)
{
byte[] fileBytes;
@ -568,7 +599,7 @@ namespace Marco.Pms.Services.Controllers
_context.Documents.Add(document);
await _context.SaveChangesAsync();
var attachment = forumAttachmentDto.ToTicketAttachmentFromForumAttachmentDto(forumAttachmentDto.TicketId, document.Id, forumAttachmentDto.CommentId);
attachment = forumAttachmentDto.ToTicketAttachmentFromForumAttachmentDto(forumAttachmentDto.TicketId, document.Id, forumAttachmentDto.CommentId);
_context.TicketAttachments.Add(attachment);
await _context.SaveChangesAsync();
@ -578,7 +609,14 @@ namespace Marco.Pms.Services.Controllers
ticketAttachmentVMs.Add(attachmentVM);
}
_logger.LogInfo("Attachments were added");
if (attachment.CommentId == null)
{
_logger.LogInfo("Attachments were added to ticket {TicketId}", attachment.TicketId);
}
else
{
_logger.LogInfo("Attachments were added to comment {CommentId}", attachment.CommentId);
}
return Ok(ApiResponse<object>.SuccessResponse(ticketAttachmentVMs, "attechments added Successfully", 200));
}
@ -644,8 +682,21 @@ namespace Marco.Pms.Services.Controllers
}
ticketVM.Comments = commentVMs;
ticketVM.Attachments = ticketAttachmentVMs;
_logger.LogInfo("Status of Ticket {TicketId} is changes to {status}", id, ticket.TicketStatusMaster.Name);
Project project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == ticket.LinkedProjectId) ?? new Project();
ticketVM.ProjectName = project.Name;
if (ticket.LinkedActivityId != null && ticket.LinkedActivityId != 0)
{
WorkItem workItem = await _context.WorkItems.Include(w => w.ActivityMaster).FirstOrDefaultAsync(w => w.Id == ticket.LinkedActivityId) ?? new WorkItem();
if (workItem.ActivityMaster != null)
{
ticketVM.ActivityName = workItem.ActivityMaster.ActivityName;
}
else
{
ticketVM.ActivityName = "";
}
}
_logger.LogInfo("Status of Ticket {TicketId} in project {ProjectId} is changes to {status}", id, ticket.LinkedProjectId, ticket.TicketStatusMaster.Name);
return Ok(ApiResponse<object>.SuccessResponse(ticketVM, "Ticket Fetched Successfully", 200));
}
[HttpGet("ticket/{id}")]
@ -706,8 +757,21 @@ namespace Marco.Pms.Services.Controllers
}
ticketVM.Comments = commentVMs;
ticketVM.Attachments = ticketAttachmentVMs;
_logger.LogInfo("Fetched Ticket {TicketId}", id);
Project project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == ticket.LinkedProjectId) ?? new Project();
ticketVM.ProjectName = project.Name;
if (ticket.LinkedActivityId != null && ticket.LinkedActivityId != 0)
{
WorkItem workItem = await _context.WorkItems.Include(w => w.ActivityMaster).FirstOrDefaultAsync(w => w.Id == ticket.LinkedActivityId) ?? new WorkItem();
if (workItem.ActivityMaster != null)
{
ticketVM.ActivityName = workItem.ActivityMaster.ActivityName;
}
else
{
ticketVM.ActivityName = "";
}
}
_logger.LogInfo("Fetched Ticket {TicketId} form project {ProjectId}", id, ticket.LinkedProjectId);
return Ok(ApiResponse<object>.SuccessResponse(ticketVM, "Ticket Fetched Successfully", 200));
}
@ -718,6 +782,8 @@ namespace Marco.Pms.Services.Controllers
List<TicketForum> tickets = await _context.Tickets.Include(t => t.TicketTypeMaster).Include(t => t.TicketStatusMaster).Include(t => t.Priority).Where(t => t.TenantId == tenantId).ToListAsync();
var createdByIds = tickets.Select(t => t.CreatedById).ToList();
var ticketIds = tickets.Select(t => t.Id).ToList();
var linkedActivityIds = tickets.Select(t => t.LinkedActivityId).ToList();
var linkedProjectIds = tickets.Select(t => t.LinkedProjectId).ToList();
List<TicketComment> ticketComments = await _context.TicketComments.Where(c => ticketIds.Contains(c.TicketId)).ToListAsync();
var authorIds = ticketComments.Select(c => c.AuthorId.ToString()).ToList();
@ -734,6 +800,10 @@ namespace Marco.Pms.Services.Controllers
List<Document> documents = await _context.Documents.Where(d => documentIds.Contains(d.Id)).ToListAsync();
List<Project> projects = await _context.Projects.Where(p => linkedProjectIds.Contains(p.Id)).ToListAsync() ?? new List<Project>();
List<WorkItem> workItems = await _context.WorkItems.Include(w => w.ActivityMaster).Where(w => linkedActivityIds.Contains(w.Id)).ToListAsync() ?? new List<WorkItem>();
List<ForumTicketVM> ticketVMs = new List<ForumTicketVM>();
foreach (var ticket in tickets)
{
@ -787,6 +857,20 @@ namespace Marco.Pms.Services.Controllers
ticketVM.Comments = commentVMs;
ticketVM.Attachments = ticketAttachmentVMs;
ticketVM.Tags = tagVMs;
Project project = projects.Find(p => p.Id == ticket.LinkedProjectId) ?? new Project();
ticketVM.ProjectName = project.Name;
if (ticket.LinkedActivityId != null && ticket.LinkedActivityId != 0)
{
WorkItem workItem = workItems.Find(w => w.Id == ticket.LinkedActivityId) ?? new WorkItem();
if (workItem.ActivityMaster != null)
{
ticketVM.ActivityName = workItem.ActivityMaster.ActivityName;
}
else
{
ticketVM.ActivityName = "";
}
}
ticketVMs.Add(ticketVM);
}
_logger.LogInfo("{count} tickets records fetched successfully from tenant {tenantId}", ticketVMs.Count, tenantId);