295 lines
13 KiB
C#
295 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Threading.Tasks;
|
|
using Nop.Core;
|
|
using Nop.Core.Domain.Blogs;
|
|
using Nop.Core.Domain.Catalog;
|
|
using Nop.Core.Domain.Common;
|
|
using Nop.Core.Domain.Customers;
|
|
using Nop.Core.Domain.Forums;
|
|
using Nop.Core.Domain.Messages;
|
|
using Nop.Core.Domain.News;
|
|
using Nop.Core.Domain.Orders;
|
|
using Nop.Core.Domain.Shipping;
|
|
using Nop.Core.Domain.Vendors;
|
|
using Nop.Core.Events;
|
|
using Nop.Services.Affiliates;
|
|
using Nop.Services.Catalog;
|
|
using Nop.Services.Common;
|
|
using Nop.Services.Customers;
|
|
using Nop.Services.Localization;
|
|
using Nop.Services.Orders;
|
|
using Nop.Services.Stores;
|
|
using Nop.Services.Messages;
|
|
|
|
namespace Nop.Plugin.Misc.BillingoInvoicing.Services
|
|
{
|
|
/// <summary>
|
|
/// Workflow message service
|
|
/// </summary>
|
|
public partial class BillingoEmailMessageService
|
|
{
|
|
#region Fields
|
|
|
|
private readonly CommonSettings _commonSettings;
|
|
private readonly EmailAccountSettings _emailAccountSettings;
|
|
private readonly IAddressService _addressService;
|
|
private readonly IAffiliateService _affiliateService;
|
|
private readonly ICustomerService _customerService;
|
|
private readonly IEmailAccountService _emailAccountService;
|
|
private readonly IEventPublisher _eventPublisher;
|
|
private readonly ILanguageService _languageService;
|
|
private readonly ILocalizationService _localizationService;
|
|
private readonly IMessageTemplateService _messageTemplateService;
|
|
private readonly IMessageTokenProvider _messageTokenProvider;
|
|
private readonly IOrderService _orderService;
|
|
private readonly IProductService _productService;
|
|
private readonly IQueuedEmailService _queuedEmailService;
|
|
private readonly IStoreContext _storeContext;
|
|
private readonly IStoreService _storeService;
|
|
private readonly ITokenizer _tokenizer;
|
|
private readonly MessagesSettings _messagesSettings;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public BillingoEmailMessageService(CommonSettings commonSettings,
|
|
EmailAccountSettings emailAccountSettings,
|
|
IAddressService addressService,
|
|
IAffiliateService affiliateService,
|
|
ICustomerService customerService,
|
|
IEmailAccountService emailAccountService,
|
|
IEventPublisher eventPublisher,
|
|
ILanguageService languageService,
|
|
ILocalizationService localizationService,
|
|
IMessageTemplateService messageTemplateService,
|
|
IMessageTokenProvider messageTokenProvider,
|
|
IOrderService orderService,
|
|
IProductService productService,
|
|
IQueuedEmailService queuedEmailService,
|
|
IStoreContext storeContext,
|
|
IStoreService storeService,
|
|
ITokenizer tokenizer,
|
|
MessagesSettings messagesSettings)
|
|
{
|
|
_commonSettings = commonSettings;
|
|
_emailAccountSettings = emailAccountSettings;
|
|
_addressService = addressService;
|
|
_affiliateService = affiliateService;
|
|
_customerService = customerService;
|
|
_emailAccountService = emailAccountService;
|
|
_eventPublisher = eventPublisher;
|
|
_languageService = languageService;
|
|
_localizationService = localizationService;
|
|
_messageTemplateService = messageTemplateService;
|
|
_messageTokenProvider = messageTokenProvider;
|
|
_orderService = orderService;
|
|
_productService = productService;
|
|
_queuedEmailService = queuedEmailService;
|
|
_storeContext = storeContext;
|
|
_storeService = storeService;
|
|
_tokenizer = tokenizer;
|
|
_messagesSettings = messagesSettings;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Utilities
|
|
|
|
/// <summary>
|
|
/// Get active message templates by the name
|
|
/// </summary>
|
|
/// <param name="messageTemplateName">Message template name</param>
|
|
/// <param name="storeId">Store identifier</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the list of message templates
|
|
/// </returns>
|
|
protected virtual async Task<IList<MessageTemplate>> GetActiveMessageTemplatesAsync(string messageTemplateName, int storeId)
|
|
{
|
|
//get message templates by the name
|
|
var messageTemplates = await _messageTemplateService.GetMessageTemplatesByNameAsync(messageTemplateName, storeId);
|
|
|
|
//no template found
|
|
if (!messageTemplates?.Any() ?? true)
|
|
return new List<MessageTemplate>();
|
|
|
|
//filter active templates
|
|
messageTemplates = messageTemplates.Where(messageTemplate => messageTemplate.IsActive).ToList();
|
|
|
|
return messageTemplates;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get EmailAccount to use with a message templates
|
|
/// </summary>
|
|
/// <param name="messageTemplate">Message template</param>
|
|
/// <param name="languageId">Language identifier</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the emailAccount
|
|
/// </returns>
|
|
protected virtual async Task<EmailAccount> GetEmailAccountOfMessageTemplateAsync(MessageTemplate messageTemplate, int languageId)
|
|
{
|
|
var emailAccountId = await _localizationService.GetLocalizedAsync(messageTemplate, mt => mt.EmailAccountId, languageId);
|
|
//some 0 validation (for localizable "Email account" dropdownlist which saves 0 if "Standard" value is chosen)
|
|
if (emailAccountId == 0)
|
|
emailAccountId = messageTemplate.EmailAccountId;
|
|
|
|
var emailAccount = (await _emailAccountService.GetEmailAccountByIdAsync(emailAccountId) ?? await _emailAccountService.GetEmailAccountByIdAsync(_emailAccountSettings.DefaultEmailAccountId)) ??
|
|
(await _emailAccountService.GetAllEmailAccountsAsync()).FirstOrDefault();
|
|
return emailAccount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensure language is active
|
|
/// </summary>
|
|
/// <param name="languageId">Language identifier</param>
|
|
/// <param name="storeId">Store identifier</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the return a value language identifier
|
|
/// </returns>
|
|
protected virtual async Task<int> EnsureLanguageIsActiveAsync(int languageId, int storeId)
|
|
{
|
|
//load language by specified ID
|
|
var language = await _languageService.GetLanguageByIdAsync(languageId);
|
|
|
|
if (language == null || !language.Published)
|
|
{
|
|
//load any language from the specified store
|
|
language = (await _languageService.GetAllLanguagesAsync(storeId: storeId)).FirstOrDefault();
|
|
}
|
|
|
|
if (language == null || !language.Published)
|
|
{
|
|
//load any language
|
|
language = (await _languageService.GetAllLanguagesAsync()).FirstOrDefault();
|
|
}
|
|
|
|
if (language == null)
|
|
throw new Exception("No active language could be loaded");
|
|
|
|
return language.Id;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get email and name to send email for store owner
|
|
/// </summary>
|
|
/// <param name="messageTemplateEmailAccount">Message template email account</param>
|
|
/// <returns>Email address and name to send email fore store owner</returns>
|
|
protected virtual async Task<(string email, string name)> GetStoreOwnerNameAndEmailAsync(EmailAccount messageTemplateEmailAccount)
|
|
{
|
|
var storeOwnerEmailAccount = _messagesSettings.UseDefaultEmailAccountForSendStoreOwnerEmails ? await _emailAccountService.GetEmailAccountByIdAsync(_emailAccountSettings.DefaultEmailAccountId) : null;
|
|
storeOwnerEmailAccount ??= messageTemplateEmailAccount;
|
|
|
|
return (storeOwnerEmailAccount.Email, storeOwnerEmailAccount.DisplayName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
public virtual async Task<int> SendErrorToStoreOwnerNotificationMessageAsync(string errorMessage, int languageId, Order order)
|
|
{
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
languageId = await EnsureLanguageIsActiveAsync(languageId, store.Id);
|
|
|
|
|
|
//tokens
|
|
var commonTokens = new List<Token>();
|
|
await _messageTokenProvider.AddOrderTokensAsync(commonTokens, order, languageId);
|
|
await _messageTokenProvider.AddCustomerTokensAsync(commonTokens, order.CustomerId);
|
|
|
|
var messageTemplates = await _messageTemplateService.GetMessageTemplatesByNameAsync(MessageTemplateSystemNames.ORDER_PAID_STORE_OWNER_NOTIFICATION, store.Id);
|
|
var messageTemplate = messageTemplates.First();
|
|
|
|
//email account
|
|
var emailAccount = await GetEmailAccountOfMessageTemplateAsync(messageTemplate, languageId);
|
|
|
|
var tokens = new List<Token>(commonTokens);
|
|
await _messageTokenProvider.AddStoreTokensAsync(tokens, store, emailAccount);
|
|
|
|
var (toEmail, toName) = await GetStoreOwnerNameAndEmailAsync(emailAccount);
|
|
|
|
return await SendNotificationAsync(errorMessage, emailAccount, languageId, tokens, toEmail, toName);
|
|
|
|
}
|
|
|
|
|
|
|
|
#region Common
|
|
|
|
/// <summary>
|
|
/// Send notification
|
|
/// </summary>
|
|
/// <param name="messageTemplate">Message template</param>
|
|
/// <param name="emailAccount">Email account</param>
|
|
/// <param name="languageId">Language identifier</param>
|
|
/// <param name="tokens">Tokens</param>
|
|
/// <param name="toEmailAddress">Recipient email address</param>
|
|
/// <param name="toName">Recipient name</param>
|
|
/// <param name="attachmentFilePath">Attachment file path</param>
|
|
/// <param name="attachmentFileName">Attachment file name</param>
|
|
/// <param name="replyToEmailAddress">"Reply to" email</param>
|
|
/// <param name="replyToName">"Reply to" name</param>
|
|
/// <param name="fromEmail">Sender email. If specified, then it overrides passed "emailAccount" details</param>
|
|
/// <param name="fromName">Sender name. If specified, then it overrides passed "emailAccount" details</param>
|
|
/// <param name="subject">Subject. If specified, then it overrides subject of a message template</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the queued email identifier
|
|
/// </returns>
|
|
public virtual async Task<int> SendNotificationAsync(string errorMessage,
|
|
EmailAccount emailAccount, int languageId, IList<Token> tokens,
|
|
string toEmailAddress, string toName,
|
|
string attachmentFilePath = null, string attachmentFileName = null,
|
|
string replyToEmailAddress = null, string replyToName = null,
|
|
string fromEmail = null, string fromName = null, string subject = null)
|
|
{
|
|
|
|
if (emailAccount == null)
|
|
throw new ArgumentNullException(nameof(emailAccount));
|
|
|
|
if (string.IsNullOrEmpty(subject))
|
|
subject = "BillingoInvoicing error occured";
|
|
var body = errorMessage;
|
|
|
|
//Replace subject and body tokens
|
|
var subjectReplaced = _tokenizer.Replace(subject, tokens, false);
|
|
var bodyReplaced = _tokenizer.Replace(body, tokens, true);
|
|
|
|
//limit name length
|
|
toName = CommonHelper.EnsureMaximumLength(toName, 300);
|
|
|
|
var email = new QueuedEmail
|
|
{
|
|
Priority = QueuedEmailPriority.High,
|
|
From = !string.IsNullOrEmpty(fromEmail) ? fromEmail : emailAccount.Email,
|
|
FromName = !string.IsNullOrEmpty(fromName) ? fromName : emailAccount.DisplayName,
|
|
To = toEmailAddress,
|
|
ToName = toName,
|
|
ReplyTo = replyToEmailAddress,
|
|
ReplyToName = replyToName,
|
|
CC = string.Empty,
|
|
Subject = subjectReplaced,
|
|
Body = bodyReplaced,
|
|
AttachmentFilePath = attachmentFilePath,
|
|
AttachmentFileName = attachmentFileName,
|
|
CreatedOnUtc = DateTime.UtcNow,
|
|
EmailAccountId = emailAccount.Id,
|
|
};
|
|
|
|
await _queuedEmailService.InsertQueuedEmailAsync(email);
|
|
return email.Id;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
}
|