Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/uSupport/Composers/uSupportNotificationComposer.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
using uSupport.Notifications;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using uSupport.Notifications.Tickets;
using uSupport.Notifications.Handlers;
using Umbraco.Cms.Core.DependencyInjection;

namespace uSupport.Composers
{
public class uSupportNotificationComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.AddNotificationHandler<TicketHistoryNotification, TicketHistoryNotificationHandler>();
builder.AddNotificationHandler<TicketHistoryNotification, TicketHistoryNotificationHandler>()
.AddNotificationHandler<CreateTicketNotification, TicketHistoryNotificationHandler>()
.AddNotificationHandler<EmailSendingNotification, TicketHistoryNotificationHandler>()
.AddNotificationHandler<AddTicketCommentNotification, TicketHistoryNotificationHandler>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,10 @@ public uSupportPage<uSupportTicket> GetPagedResolvedTickets(long page, string? s
}

[HttpGet]
public IEnumerable<uSupportTicketHistory> GetTicketHistory(Guid ticketId)
{
return _uSupportTicketHistoryService.GetByTicketId(ticketId);
}
public uSupportPage<uSupportTicketHistory> GetPagedHistoryByTicketId(Guid ticketId, long page) => _uSupportTicketHistoryService.GetPagedByTicketId(ticketId, page);

[HttpGet]
public IEnumerable<uSupportTicketHistory> GetTicketHistory(Guid ticketId) => _uSupportTicketHistoryService.GetByTicketId(ticketId);

[HttpGet]
public bool AnyResolvedTickets() => _uSupportTicketService.AnyResolvedTickets();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using uSupport.Helpers;
using uSupport.Dtos;
using uSupport.Helpers;
using uSupport.Dtos.Tables;
using uSupport.Notifications;
using Umbraco.Cms.Core.Events;
Expand Down Expand Up @@ -43,7 +44,10 @@ public uSupportTicketCommentAuthorizedApiController(
_uSupportTicketCommentService = uSupportTicketCommentService;
}

[HttpGet]
[HttpGet]
public uSupportPage<uSupportTicketComment> GetPagedCommentsForTicket(Guid ticketId, long page) => _uSupportTicketCommentService.GetPagedCommentsForTicket(ticketId, page);

[HttpGet]
public IEnumerable<uSupportTicketComment> GetCommentsFromTicketId(Guid ticketId) => _uSupportTicketCommentService.GetCommentsFromTicketId(ticketId).ToList();


Expand All @@ -62,14 +66,21 @@ public ActionResult<IEnumerable<uSupportTicketComment>> Comment(uSupportTicketCo

var updatedTicket =_uSupportTicketService.Update(ticket.ConvertDtoToSchema());

string emailSetting = _uSupportSettingsService.GetTicketUpdateEmailSetting();
if (!string.IsNullOrWhiteSpace(emailSetting))
if (_uSupportSettingsService.GetSendEmailOnTicketCommentSetting())
{
string toAddress = _uSupportSettingsService.GetTicketUpdateEmailSetting();
if (ticket.AuthorId != ticketComment.UserId)
{
var author = _userService.GetUserById(ticket.AuthorId);
if(author != null)
toAddress = author.Email;
}

_uSupportSettingsService.SendEmail(
emailSetting,
_uSupportSettingsService.GetEmailSubjectUpdateTicket(),
toAddress,
_uSupportSettingsService.GetEmailSubjectUpdateTicket(updatedTicket),
_uSupportSettingsService.GetEmailTemplateUpdateTicketPath(),
ticket);
updatedTicket);
}

_eventAggregator.Publish(new AddTicketCommentNotification(updatedTicket, comment));
Expand Down
7 changes: 4 additions & 3 deletions src/uSupport/Dtos/Settings/uSupportSettingsTicket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ public class uSupportSettingsTicket
{
public const string Tickets = uSupportConstants.SectionAlias + ":Settings:Tickets";
public bool SendEmailOnTicketCreated { get; set; } = true;
public bool SendEmailOnTicketComment { get; set; } = true;
public string TicketUpdateEmail { get; set; } = "None";
public string EmailSubjectNewTicket { get; set; } = "A new ticket '{ExternalTicketId}' has been created";
public string EmailSubjectUpdateTicket { get; set; } = "Ticket '{ExternalTicketId}' has been updated";
public string EmailTemplateNewTicketPath { get; set; } = "/App_Plugins/uSupport/templates/NewTicketEmail.cshtml";
public string EmailTemplateUpdateTicketPath { get; set; } = "/App_Plugins/uSupport/templates/UpdateTicketEmail.cshtml";
public string EmailTemplateNewTicketPath { get; set; } = "/Views/Partials/uSupport/Emails/NewTicketEmail.cshtml";
public string EmailTemplateUpdateTicketPath { get; set; } = "/Views/Partials/uSupport/Emails/UpdateTicketEmail.cshtml";
}
}
}
9 changes: 3 additions & 6 deletions src/uSupport/Helpers/uSupportPageHelper.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using System;
using uSupport.Dtos;
using uSupport.Dtos.Tables;
using System.Collections.Generic;
using uSupport.Dtos;

namespace uSupport.Helpers
{
public static class uSupportPageHelper
{
public static uSupportPage<uSupportTicket> MapPageToUSupportPage(List<uSupportTicket> items, long totalItems, long currentPage, long itemsPerPage)
public static uSupportPage<T> MapPageToUSupportPage<T>(List<T> items, long totalItems, long currentPage, long itemsPerPage)
{
uSupportPage<uSupportTicket> page = new uSupportPage<uSupportTicket>()
uSupportPage<T> page = new uSupportPage<T>()
{
TotalItems = totalItems,
ItemsPerPage = itemsPerPage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
using Umbraco.Cms.Core.Events;
using uSupport.Migrations.Schemas;
using uSupport.Services.Interfaces;
using uSupport.Notifications.Tickets;

namespace uSupport.Notifications.Handlers
{
public class TicketHistoryNotificationHandler : INotificationHandler<TicketHistoryNotification>
public class TicketHistoryNotificationHandler : INotificationHandler<TicketHistoryNotification>,
INotificationHandler<CreateTicketNotification>,
INotificationHandler<EmailSendingNotification>,
INotificationHandler<AddTicketCommentNotification>
{
private readonly IuSupportTicketHistoryService _uSupportTicketHistoryService;
public TicketHistoryNotificationHandler(IuSupportTicketHistoryService uSupportTicketHistoryService)
Expand All @@ -20,14 +24,9 @@ public void Handle(TicketHistoryNotification notification)
{
TicketId = notification.NewTicket.Id,
UserId = notification.UserId,
ActionType = notification.OldTicket == null ? "Created" : "Updated",
ActionType = "Updated",
};

if (notification.OldTicket == null)
{
_uSupportTicketHistoryService.Create(history);
return;
}

var changes = new List<uSupportChange>();

Expand Down Expand Up @@ -71,5 +70,50 @@ public void Handle(TicketHistoryNotification notification)

_uSupportTicketHistoryService.Create(history);
}

public void Handle(CreateTicketNotification notification)
{
_uSupportTicketHistoryService.Create(new uSupportTicketHistorySchema()
{
TicketId = notification.Ticket.Id,
UserId = notification.Ticket.AuthorId,
ActionType = "Created",
});
}

public void Handle(EmailSendingNotification notification)
{
_uSupportTicketHistoryService.Create(new uSupportTicketHistorySchema()
{
TicketId = notification.TicketId,
UserId = 0,
ActionType = "SentEmail",
ChangesJson = JsonSerializer.Serialize(new List<uSupportChange>()
{
new uSupportChange()
{
Field = "Email",
New = notification.ToAddress
}
})
});
}

public void Handle(AddTicketCommentNotification notification)
{
_uSupportTicketHistoryService.Create(new uSupportTicketHistorySchema()
{
TicketId = notification.Ticket.Id,
UserId = notification.Comment.UserId,
ActionType = "Comment",
ChangesJson = JsonSerializer.Serialize(new List<uSupportChange>()
{
new uSupportChange()
{
Field = "Comment"
}
})
});
}
}
}
20 changes: 20 additions & 0 deletions src/uSupport/Notifications/Tickets/EmailSendingNotification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Umbraco.Cms.Core.Notifications;

namespace uSupport.Notifications.Tickets
{
public class EmailSendingNotification : INotification
{
public Guid TicketId { get; }
public string ToAddress { get; }
public string Subject { get; }
public string TemplatePath { get; }

public EmailSendingNotification(Guid ticketId, string toAddress, string subject, string templatePath)
{
TicketId = ticketId;
ToAddress = toAddress;
Subject = subject;
TemplatePath = templatePath;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace uSupport.Services.Interfaces
public interface IuSupportTicketHistoryService
{
IEnumerable<uSupportTicketHistory> GetByTicketId(Guid ticketId);
uSupportPage<uSupportTicketHistory> GetPagedByTicketId(Guid ticketId, long page);
uSupportTicketHistory Get(Guid id);
uSupportTicketHistory Create(uSupportTicketHistorySchema history);
uSupportTicketHistory Update(uSupportTicketHistorySchema history);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public interface IuSupportSettingsService
{
void SendEmail(string toAddress, string subject, string templateViewPath, object model);
bool GetSendEmailOnTicketCreatedSetting();
bool GetSendEmailOnTicketCommentSetting();
string GetTicketUpdateEmailSetting();
string GetEmailSubjectNewTicket(uSupportTicket? ticket = null);
string GetEmailSubjectUpdateTicket(uSupportTicket? ticket = null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using uSupport.Dtos.Tables;
using uSupport.Dtos;
using uSupport.Dtos.Tables;
using uSupport.Migrations.Schemas;

namespace uSupport.Services.Interfaces
{
public interface IuSupportTicketCommentService
{
IEnumerable<uSupportTicketComment> GetCommentsFromTicketId(Guid ticketId);
uSupportPage<uSupportTicketComment> GetPagedCommentsForTicket(Guid ticketId, long page);
IEnumerable<uSupportTicketComment> GetAll();
uSupportTicketComment Get(Guid id);
uSupportTicketComment Create(uSupportTicketCommentSchema comment);
Expand Down
62 changes: 43 additions & 19 deletions src/uSupport/Services/uSupportSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
using uSupport.Dtos.Tables;
using Umbraco.Cms.Core.Mail;
using uSupport.Dtos.Settings;
using Umbraco.Cms.Core.Events;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using uSupport.Services.Interfaces;
using Umbraco.Cms.Core.Models.Email;
using Microsoft.AspNetCore.Mvc.Razor;
using uSupport.Notifications.Tickets;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.Abstractions;
Expand All @@ -21,35 +22,46 @@ namespace uSupport.Services
{
public class uSupportSettingsService : IuSupportSettingsService
{
private const string LegacyNewTicketTemplatePath = "/App_Plugins/uSupport/templates/NewTicketEmail.cshtml";
private const string LegacyUpdateTicketTemplatePath = "/App_Plugins/uSupport/templates/UpdateTicketEmail.cshtml";
private const string DefaultNewTicketTemplatePath = "/Views/uSupport/Emails/NewTicketEmail.cshtml";
private const string DefaultUpdateTicketTemplatePath = "/Views/uSupport/Emails/UpdateTicketEmail.cshtml";

private readonly uSupportSettingsTicket _defaultSettings;
private readonly ILogger<IuSupportTicketService> _logger;
private readonly IEmailSender _emailSender;
private readonly IEventAggregator _eventAggregator;
private readonly IRazorViewEngine _razorViewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IOptions<GlobalSettings> _globalSettings;
private readonly IHttpContextAccessor _httpContextAccessor;

private readonly IOptions<uSupportSettings> _uSupportSettings;
private readonly ITempDataProvider _tempDataProvider;
private readonly ILogger<IuSupportTicketService> _logger;
public uSupportSettingsService(IEmailSender emailSender,
ITempDataProvider tempDataProvider,


public uSupportSettingsService(ILogger<IuSupportTicketService> logger,
IEmailSender emailSender,
IEventAggregator eventAggregator,
IRazorViewEngine razorViewEngine,
ILogger<IuSupportTicketService> logger,
IHostEnvironment hostingEnvironment,
IHttpContextAccessor httpContextAccessor,
ITempDataProvider tempDataProvider,
IOptions<GlobalSettings> globalSettings,
IHttpContextAccessor httpContextAccessor,
IOptions<uSupportSettings> uSupportSettings)
{
_logger = logger;
_emailSender = emailSender;
_eventAggregator = eventAggregator;
_razorViewEngine = razorViewEngine;
_tempDataProvider = tempDataProvider;
_globalSettings = globalSettings;
Comment thread
Lantzify marked this conversation as resolved.
_uSupportSettings = uSupportSettings;
_httpContextAccessor = httpContextAccessor;
_razorViewEngine = razorViewEngine;
_emailSender = emailSender;
_logger = logger;
_uSupportSettings = uSupportSettings;

_defaultSettings = new uSupportSettingsTicket();
}

public bool GetSendEmailOnTicketCreatedSetting() => _uSupportSettings.Value.Tickets.SendEmailOnTicketCreated;
public bool GetSendEmailOnTicketCommentSetting() => _uSupportSettings.Value.Tickets.SendEmailOnTicketComment;
public string GetTicketUpdateEmailSetting() => _uSupportSettings.Value.Tickets.TicketUpdateEmail;

public string GetEmailSubjectNewTicket(uSupportTicket? ticket = null)
Expand Down Expand Up @@ -128,8 +140,11 @@ public async void SendEmail(string toAddress, string subject, string templateVie
true);
}

if (model is uSupportTicket ticket)
_eventAggregator.Publish(new EmailSendingNotification(ticket.Id, toAddress, subject, templateViewPath));

await _emailSender.SendAsync(message, emailType: "Contact");

await _emailSender.SendAsync(message, emailType: "Contact");
}
catch (Exception ex)
{
Expand All @@ -142,15 +157,24 @@ public async Task<string> RenderEmailTemplateAsync(string templateViewPath, obje
if (string.IsNullOrEmpty(templateViewPath))
throw new Exception("Failed to find email template.");

if (!templateViewPath.EndsWith(".cshtml"))
if (!templateViewPath.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase))
throw new Exception("Template file must end with '.cshtml'");

ActionContext actionContext = new(_httpContextAccessor.HttpContext, new Microsoft.AspNetCore.Routing.RouteData(), new ActionDescriptor());
if(_httpContextAccessor.HttpContext == null)
throw new Exception("HttpContext is null");

ActionContext actionContext = new(_httpContextAccessor.HttpContext, new Microsoft.AspNetCore.Routing.RouteData(), new ActionDescriptor());
using (StringWriter stringWriter = new())
{
ViewEngineResult viewResult = _razorViewEngine.GetView(templateViewPath, templateViewPath, false);
ViewEngineResult viewResult = _razorViewEngine.GetView(null, templateViewPath, false);

if (!viewResult.Success)
{
var searchedLocations = string.Join(", ", viewResult.SearchedLocations ?? []);
throw new Exception($"Failed to find template at '{templateViewPath}'. Searched locations: {searchedLocations}");
}

ViewDataDictionary viewData = new(new EmptyModelMetadataProvider(), new ModelStateDictionary())
ViewDataDictionary viewData = new(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
Expand All @@ -166,5 +190,5 @@ public async Task<string> RenderEmailTemplateAsync(string templateViewPath, obje
return stringWriter.ToString();
}
}
}
}
}
}
Loading
Loading