Add Models and Controller methods for Forum feature

This commit is contained in:
Vikas Nale 2025-04-22 09:56:59 +05:30
parent fa5a8c178d
commit 6c99a625b5
16 changed files with 336 additions and 0 deletions

View File

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Forum;
namespace Marco.Pms.DataAccess.Data
{
public class ForumDbContext : IdentityDbContext<IdentityUser>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ForumDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
{
_httpContextAccessor = httpContextAccessor;
}
public DbSet<TicketForum> Tickets { get; set; }
public DbSet<TicketAttachment> TicketAttachments { get; set; }
public DbSet<TicketComment> TicketComments { get; set; }
public DbSet<TicketStatusMaster> TicketStatusMasters { get; set; }
public DbSet<TicketTypeMaster> TicketTypeMasters { get; set; }
}
}

View File

@ -0,0 +1,31 @@
using Marco.Pms.Model.Entitlements;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.DocumentManager
{
public class Document
{
public Guid Id { get; set; }
public Guid BatchId { get; set; }
public string FileName { get; set; } = string.Empty;
/// <summary>
/// Full S3 object key
/// </summary>
public string S3Key { get; set; } = string.Empty;
/// <summary>
/// S3 key for thumbnail image
/// </summary>
public string? ThumbS3Key { get; set; }
public int FileSize { get; set; }
public string ContentType { get; set; } = string.Empty;
public DateTime UploadedAt { get; set; }
public int TenantId { get; set; }
[ValidateNever]
[ForeignKey(nameof(TenantId))]
public Tenant? Tenant { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.Model.Dtos.Forum
{
public class AddCommentDto
{
}
}

View File

@ -0,0 +1,6 @@
namespace Marco.Pms.Model.Dtos.Forum
{
public class CreateTicketDto
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.Model.Dtos.Forum
{
public class ForumAttachmentDto
{
}
}

View File

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Forum
{
public class TicketAttachment
{
public Guid Id { get; set; }
public Guid TicketId { get; set; }
[ValidateNever]
[ForeignKey(nameof(TicketId))]
public TicketForum? Ticket { get; set; }
public Guid CommentId { get; set; }
[ValidateNever]
[ForeignKey(nameof(CommentId))]
public TicketComment? TicketComment { get; set; }
public string FileName { get; set; } = string.Empty;
public Guid FileId { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using Marco.Pms.Model.Entitlements;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel;
namespace Marco.Pms.Model.Forum
{
public class TicketComment
{
public Guid Id { get; set; }
public Guid TicketId { get; set; }
public Guid AuthorId { get; set; }
public string MessageText { get; set; } = string.Empty;
public DateTime SentAt { get; set; }
public Guid? ParentMessageId { get; set; } // For threaded replies
public ICollection<TicketAttachment>? Attachments { get; set; }
[DisplayName("TenantId")]
public int TenantId { get; set; }
[ValidateNever]
[ForeignKey(nameof(TenantId))]
public Tenant? Tenant { get; set; }
}
}

View File

@ -0,0 +1,44 @@
using Marco.Pms.Model.Entitlements;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel;
namespace Marco.Pms.Model.Forum
{
public class TicketForum
{
public Guid Id { get; set; }
public string Subject { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Guid StatusId { get; set; }
[ValidateNever]
[ForeignKey(nameof(StatusId))]
public TicketStatusMaster? TicketStatusMaster { get; set; }
public Guid TypeId { get; set; } // QualityIssue, HelpDesk, Feedback
[ValidateNever]
[ForeignKey(nameof(TypeId))]
public TicketTypeMaster? TicketTypeMaster { get; set; }
public Guid CreatedById { get; set; }
public DateTime CreatedAt { get; set; }
public Guid? LinkedActivityId { get; set; } // task or project ID
public ICollection<TicketComment>? Comments { get; set; }
public ICollection<TicketAttachment>? Attachments { get; set; }
public Guid PriorityId { get; set; }
[ValidateNever]
[ForeignKey(nameof(PriorityId))]
public TicketPriorityMaster? Priority { get; set; }
public ICollection<TicketTag>? Tags { get; set; }
[DisplayName("TenantId")]
public int TenantId { get; set; }
[ValidateNever]
[ForeignKey(nameof(TenantId))]
public Tenant? Tenant { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.Model.Forum
{
public class TicketPriorityMaster
{
public Guid Id { get; set; }
public string Name { get; set; } // e.g., Low, Medium, High, Critical
public int Level { get; set; } // 1 = Low, 2 = Medium...
public string? ColorCode { get; set; }
public bool IsDefault { get; set; }
public Guid TenantId { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace Marco.Pms.Model.Forum
{
public class TicketStatusMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty; // e.g., "Open", "In Progress"
public string? Description { get; set; }
public string? ColorCode { get; set; } // e.g., "#FF0000"
public bool IsDefault { get; set; } // true for system defaults
public Guid TenantId { get; set; } // or nullable if global
}
}

View File

@ -0,0 +1,12 @@
namespace Marco.Pms.Model.Forum
{
public class TicketTag
{
public Guid TicketId { get; set; }
public TicketForum Ticket { get; set; }
public Guid TagId { get; set; }
public TicketTagMaster Tag { get; set; }
}
}

View File

@ -0,0 +1,12 @@
namespace Marco.Pms.Model.Forum
{
public class TicketTagMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty; // e.g., "Bug", "UI", "Urgent"
public string? ColorCode { get; set; }
public Guid TenantId { get; set; }
public bool IsDefault { get; set; }
}
}

View File

@ -0,0 +1,12 @@
namespace Marco.Pms.Model.Forum
{
public class TicketTypeMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty; // e.g., "Quality Issue"
public string? Description { get; set; }
public bool IsDefault { get; set; } // true for system defaults
public Guid TenantId { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace Marco.Pms.Model.ViewModels.Forum
{
public class ForumTicketVM
{
}
}

View File

@ -0,0 +1,73 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Dtos.Forum;
using Marco.Pms.Model.Dtos.Util;
using Marco.Pms.Model.Industries;
using Marco.Pms.Model.Utilities;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace Marco.Pms.Services.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ForumController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly ApplicationDbContext _context;
private readonly JwtSettings _jwtSettings;
private readonly RefreshTokenService _refreshTokenService;
private readonly IEmailSender _emailSender;
private readonly IConfiguration _configuration;
private readonly EmployeeHelper _employeeHelper;
//string tenentId = "1";
public ForumController(UserManager<IdentityUser> userManager, ApplicationDbContext context, JwtSettings jwtSettings, RefreshTokenService refreshTokenService,
IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper)
{
_userManager = userManager;
_jwtSettings = jwtSettings;
_refreshTokenService = refreshTokenService;
_emailSender = emailSender;
_configuration = configuration;
_employeeHelper = employeeHelper;
_context = context;
}
[HttpPost("tickets")]
public async Task<IActionResult> CreateNewTicket([FromBody] CreateTicketDto createTicketDto)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
[HttpPost("tickets/{id}/comment")]
public async Task<IActionResult> AddComment([FromBody] AddCommentDto addCommentDto)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
[HttpPost("tickets/{id}/attachments")]
public async Task<IActionResult> UploadAttachments([FromBody] ForumAttachmentDto forumAttachmentDto)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
[HttpPatch("tickets/{id}/status")]
public async Task<IActionResult> UpdateTicketStatus([FromBody] InquiryDto inquiryDto)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
[HttpGet("tickets/{id}")]
public async Task<IActionResult> GetTicketDetail(Guid id)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
[HttpGet("tickets")]
public async Task<IActionResult> ListTickets([FromBody] InquiryDto inquiryDto)
{
return NotFound(ApiResponse<object>.ErrorResponse("Industry not found.", "Industry not found.", 404));
}
}
}

View File

@ -96,6 +96,10 @@ builder.Services.AddDbContext<ApplicationDbContext>(options =>
{ {
options.UseMySql(connString, ServerVersion.AutoDetect(connString)); options.UseMySql(connString, ServerVersion.AutoDetect(connString));
}); });
builder.Services.AddDbContext<ForumDbContext>(options =>
{
options.UseMySql(connString, ServerVersion.AutoDetect(connString));
});
builder.Services.AddMemoryCache(); builder.Services.AddMemoryCache();