diff --git a/Marco.Pms.Model/Dtos/Mail/MailTemeplateDto.cs b/Marco.Pms.Model/Dtos/Mail/MailTemeplateDto.cs deleted file mode 100644 index dcd497c..0000000 --- a/Marco.Pms.Model/Dtos/Mail/MailTemeplateDto.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Marco.Pms.Model.Dtos.Mail -{ - public class MailTemeplateDto - { - public string Title { get; set; } = string.Empty; - public string Body { get; set; } = string.Empty; - public string Subject { get; set; } = string.Empty; - public string Keywords { get; set; } = string.Empty; - } -} diff --git a/Marco.Pms.Model/Dtos/Mail/MailTemplateDto.cs b/Marco.Pms.Model/Dtos/Mail/MailTemplateDto.cs new file mode 100644 index 0000000..9649e06 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Mail/MailTemplateDto.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.Dtos.Mail +{ + public class MailTemplateDto + { + public Guid? Id { get; set; } + public required string Title { get; set; } + public required string Body { get; set; } + public required string Subject { get; set; } + public required string Keywords { get; set; } + } +} diff --git a/Marco.Pms.Services/Controllers/ReportController.cs b/Marco.Pms.Services/Controllers/ReportController.cs index bb1a68b..c21f822 100644 --- a/Marco.Pms.Services/Controllers/ReportController.cs +++ b/Marco.Pms.Services/Controllers/ReportController.cs @@ -28,6 +28,7 @@ namespace Marco.Pms.Services.Controllers private readonly ILoggingService _logger; private readonly UserHelper _userHelper; private readonly IConfiguration _configuration; + private readonly Guid tenantId; public ReportController(IDbContextFactory dbContextFactory, ApplicationDbContext context, ILoggingService logger, @@ -41,6 +42,7 @@ namespace Marco.Pms.Services.Controllers _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _userHelper = userHelper ?? throw new ArgumentNullException(nameof(userHelper)); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + tenantId = userHelper.GetTenantId(); } /// @@ -158,10 +160,9 @@ namespace Marco.Pms.Services.Controllers /// The mail template data. /// An API response indicating success or failure. [HttpPost("mail-template")] // More specific route for adding a template - public async Task AddMailTemplate([FromBody] MailTemeplateDto mailTemplateDto) // Renamed parameter for consistency + public async Task AddMailTemplate([FromBody] MailTemplateDto mailTemplateDto) // Renamed parameter for consistency { - // 1. Get Tenant ID and Basic Authorization Check - Guid tenantId = _userHelper.GetTenantId(); + // 1. Basic Authorization Check if (tenantId == Guid.Empty) { _logger.LogWarning("Authorization Error: Attempt to add mail template with an empty or invalid tenant ID."); @@ -178,21 +179,6 @@ namespace Marco.Pms.Services.Controllers return BadRequest(ApiResponse.ErrorResponse("Invalid Data", "Request body is empty.", 400)); } - if (string.IsNullOrWhiteSpace(mailTemplateDto.Title)) - { - _logger.LogWarning("Validation Error: Mail template title is empty or whitespace. TenantId: {TenantId}", tenantId); - return BadRequest(ApiResponse.ErrorResponse("Validation Failed", "Mail template title cannot be empty.", 400)); - } - - // The original logic checked both body and title, but often a template needs at least a title. - // Re-evalute if body can be empty. If so, remove the body check. Assuming title is always mandatory. - // If both body and title are empty, it's definitely invalid. - if (string.IsNullOrWhiteSpace(mailTemplateDto.Body) && string.IsNullOrWhiteSpace(mailTemplateDto.Subject)) - { - _logger.LogWarning("Validation Error: Mail template body and subject are both empty or whitespace for title '{Title}'. TenantId: {TenantId}", mailTemplateDto.Title, tenantId); - return BadRequest(ApiResponse.ErrorResponse("Validation Failed", "Mail template body or subject must be provided.", 400)); - } - // 3. Check for Existing Template Title (Case-Insensitive) // Use AsNoTracking() for read-only query MailingList? existingTemplate; @@ -250,6 +236,55 @@ namespace Marco.Pms.Services.Controllers } } + [HttpPut("mail-template/edit/{id}")] + public async Task UpdateMailTemplate(Guid id, [FromBody] MailTemplateDto mailTemplateDto) + { + _logger.LogInfo("UpdateMailTemplate called for TemplateId: {TemplateId} TenantId: {TenantId} by User", id, tenantId); + + try + { + // Check if another template with the same title exists in tenant scope but with a different id (to avoid conflict) + var existingTemplateWithTitle = await _context.MailingList + .AsNoTracking() + .FirstOrDefaultAsync(t => t.Title.ToLower() == mailTemplateDto.Title.ToLower() && t.TenantId == tenantId && t.Id != id); + + if (existingTemplateWithTitle != null) + { + _logger.LogWarning("Conflict Error: Attempt to update mail template to title '{Title}' which already exists for TenantId: {TenantId}.", mailTemplateDto.Title, tenantId); + return Conflict(ApiResponse.ErrorResponse("Conflict", $"Email template with title '{mailTemplateDto.Title}' already exists.", 409)); + } + + // Retrieve the template to update by Id and tenant + var existingTemplate = await _context.MailingList + .FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId); + + if (existingTemplate == null) + { + _logger.LogWarning("Mail template not found for Id: {TemplateId}, TenantId: {TenantId}.", id, tenantId); + return NotFound(ApiResponse.ErrorResponse("Not Found", "Mail template not found.", 404)); + } + + // Update fields + existingTemplate.Title = mailTemplateDto.Title; + existingTemplate.Body = mailTemplateDto.Body; + existingTemplate.Subject = mailTemplateDto.Subject; + existingTemplate.Keywords = mailTemplateDto.Keywords; + + _context.MailingList.Update(existingTemplate); + await _context.SaveChangesAsync(); + + _logger.LogInfo("Mail template updated successfully Id: {TemplateId} TenantId: {TenantId}", id, tenantId); + + return Ok(ApiResponse.SuccessResponse(existingTemplate, "Mail template updated successfully.", 200)); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error occurred while updating mail template Id: {TemplateId} TenantId: {TenantId}: {Message}", id, tenantId, ex.Message); + return StatusCode(500, ApiResponse.ErrorResponse("Internal Server Error", "An error occurred while updating the mail template.", 500)); + } + } + + [HttpGet("project-statistics")] public async Task SendProjectReport() {