DocSpace-client/web/ASC.Web.Core/Notify/StudioPeriodicNotify.cs
2022-10-20 13:50:08 +03:00

571 lines
24 KiB
C#

// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Studio.Core.Notify;
[Scope]
public class StudioPeriodicNotify
{
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly WorkContext _workContext;
private readonly TenantManager _tenantManager;
private readonly UserManager _userManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly PaymentManager _paymentManager;
private readonly TenantExtra _tenantExtra;
private readonly AuthContext _authContext;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly ApiSystemHelper _apiSystemHelper;
private readonly SetupInfo _setupInfo;
private readonly IDbContextFactory<FeedDbContext> _dbContextFactory;
private readonly IConfiguration _configuration;
private readonly SettingsManager _settingsManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly AuthManager _authManager;
private readonly SecurityContext _securityContext;
private readonly ILogger _log;
public StudioPeriodicNotify(
ILoggerProvider log,
NotifyEngineQueue notifyEngineQueue,
WorkContext workContext,
TenantManager tenantManager,
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
PaymentManager paymentManager,
TenantExtra tenantExtra,
AuthContext authContext,
CommonLinkUtility commonLinkUtility,
ApiSystemHelper apiSystemHelper,
SetupInfo setupInfo,
IDbContextFactory<FeedDbContext> dbContextFactory,
IConfiguration configuration,
SettingsManager settingsManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
AuthManager authManager,
SecurityContext securityContext)
{
_notifyEngineQueue = notifyEngineQueue;
_workContext = workContext;
_tenantManager = tenantManager;
_userManager = userManager;
_studioNotifyHelper = studioNotifyHelper;
_paymentManager = paymentManager;
_tenantExtra = tenantExtra;
_authContext = authContext;
_commonLinkUtility = commonLinkUtility;
_apiSystemHelper = apiSystemHelper;
_setupInfo = setupInfo;
_dbContextFactory = dbContextFactory;
_configuration = configuration;
_settingsManager = settingsManager;
_coreBaseSettings = coreBaseSettings;
_displayUserSettingsHelper = displayUserSettingsHelper;
_authManager = authManager;
_securityContext = securityContext;
_log = log.CreateLogger("ASC.Notify");
}
public Task SendSaasLettersAsync(string senderName, DateTime scheduleDate)
{
_log.InformationStartSendSaasTariffLetters();
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.InformationEndSendSaasTariffLetters();
return Task.CompletedTask;
}
return InternalSendSaasLettersAsync(senderName, scheduleDate, activeTenants);
}
private async Task InternalSendSaasLettersAsync(string senderName, DateTime scheduleDate, List<Tenant> activeTenants)
{
var nowDate = scheduleDate.Date;
foreach (var tenant in activeTenants)
{
try
{
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var tariff = _paymentManager.GetTariff(tenant.Id);
var quota = _tenantManager.GetTenantQuota(tenant.Id);
var createdDate = tenant.CreationDateTime.Date;
var dueDateIsNotMax = tariff.DueDate != DateTime.MaxValue;
var dueDate = tariff.DueDate.Date;
var delayDueDateIsNotMax = tariff.DelayDueDate != DateTime.MaxValue;
var delayDueDate = tariff.DelayDueDate.Date;
INotifyAction action = null;
var paymentMessage = true;
var toadmins = false;
var tousers = false;
var toowner = false;
Func<string> greenButtonText = () => string.Empty;
var greenButtonUrl = string.Empty;
if (quota.Free)
{
}
else if (quota.Trial)
{
#region After registration letters
#region 1 days after registration to admins SAAS TRIAL
if (createdDate.AddDays(1) == nowDate)
{
action = Actions.SaasAdminModulesV1;
paymentMessage = false;
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonConfigureRightNow;
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/portal-settings/");
}
#endregion
#region 7 days after registration to admins and users SAAS TRIAL
else if (createdDate.AddDays(7) == nowDate)
{
action = Actions.SaasAdminUserDocsTipsV1;
paymentMessage = false;
toadmins = true;
tousers = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonCollaborateDocSpace;
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/');
}
#endregion
#region 14 days after registration to admins and users SAAS TRIAL
else if (createdDate.AddDays(14) == nowDate)
{
action = Actions.SaasAdminUserAppsTipsV1;
paymentMessage = false;
toadmins = true;
tousers = true;
}
#endregion
#endregion
#region 6 months after SAAS TRIAL expired
else if (dueDateIsNotMax && dueDate.AddMonths(6) == nowDate)
{
action = Actions.SaasAdminTrialWarningAfterHalfYearV1;
toowner = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonLeaveFeedback;
var owner = _userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = _setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
HttpUtility.UrlEncode(Convert.ToBase64String(
Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
"\",\"alias\":\"" + tenant.Alias +
"\",\"email\":\"" + owner.Email + "\"}")));
}
else if (dueDateIsNotMax && dueDate.AddMonths(6).AddDays(7) <= nowDate)
{
_tenantManager.RemoveTenant(tenant.Id, true);
if (!string.IsNullOrEmpty(_apiSystemHelper.ApiCacheUrl))
{
await _apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, _authContext.CurrentAccount.ID);
}
}
#endregion
}
else if (tariff.State >= TariffState.Paid)
{
#region Payment warning letters
#region 6 months after SAAS PAID expired
if (tariff.State == TariffState.NotPaid && dueDateIsNotMax && dueDate.AddMonths(6) == nowDate)
{
action = Actions.SaasAdminTrialWarningAfterHalfYearV1;
toowner = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonLeaveFeedback;
var owner = _userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = _setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
HttpUtility.UrlEncode(Convert.ToBase64String(
Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
"\",\"alias\":\"" + tenant.Alias +
"\",\"email\":\"" + owner.Email + "\"}")));
}
else if (tariff.State == TariffState.NotPaid && dueDateIsNotMax && dueDate.AddMonths(6).AddDays(7) <= nowDate)
{
_tenantManager.RemoveTenant(tenant.Id, true);
if (!string.IsNullOrEmpty(_apiSystemHelper.ApiCacheUrl))
{
await _apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, _authContext.CurrentAccount.ID);
}
}
#endregion
#endregion
}
if (action == null)
{
continue;
}
var users = toowner
? new List<UserInfo> { _userManager.GetUsers(tenant.OwnerId) }
: _studioNotifyHelper.GetRecipients(toadmins, tousers, false);
foreach (var u in users.Where(u => paymentMessage || _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var rquota = _tenantExtra.GetRightQuota() ?? TenantQuota.Default;
client.SendNoticeToAsync(
action,
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.ActiveUsers, _userManager.GetUsers().Length),
new TagValue(Tags.Price, rquota.Price),
new TagValue(Tags.PricePeriod, rquota.Year3 ? UserControlsCommonResource.TariffPerYear3 : rquota.Year ? UserControlsCommonResource.TariffPerYear : UserControlsCommonResource.TariffPerMonth),
new TagValue(Tags.DueDate, dueDate.ToLongDateString()),
new TagValue(Tags.DelayDueDate, (delayDueDateIsNotMax ? delayDueDate : dueDate).ToLongDateString()),
TagValues.GreenButton(greenButtonText, greenButtonUrl),
new TagValue(CommonTags.Footer, _userManager.IsAdmin(u) ? "common" : "social"));
}
}
catch (Exception err)
{
_log.ErrorSendSaasLettersAsync(err);
}
}
_log.InformationEndSendSaasTariffLetters();
}
public void SendEnterpriseLetters(string senderName, DateTime scheduleDate)
{
var nowDate = scheduleDate.Date;
_log.InformationStartSendTariffEnterpriseLetters();
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.InformationEndSendTariffEnterpriseLetters();
return;
}
foreach (var tenant in activeTenants)
{
try
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var tariff = _paymentManager.GetTariff(tenant.Id);
var quota = _tenantManager.GetTenantQuota(tenant.Id);
var createdDate = tenant.CreationDateTime.Date;
var actualEndDate = tariff.DueDate != DateTime.MaxValue ? tariff.DueDate : tariff.LicenseDate;
var dueDateIsNotMax = actualEndDate != DateTime.MaxValue;
var dueDate = actualEndDate.Date;
var delayDueDateIsNotMax = tariff.DelayDueDate != DateTime.MaxValue;
var delayDueDate = tariff.DelayDueDate.Date;
INotifyAction action = null;
var paymentMessage = true;
var toadmins = false;
var tousers = false;
Func<string> greenButtonText = () => string.Empty;
var greenButtonUrl = string.Empty;
if (quota.Trial && defaultRebranding)
{
#region After registration letters
#region 7 days after registration to admins and users ENTERPRISE TRIAL + defaultRebranding
if (createdDate.AddDays(7) == nowDate)
{
action = Actions.EnterpriseAdminUserDocsTipsV1;
paymentMessage = false;
toadmins = true;
tousers = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonCollaborateDocSpace;
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/');
}
#endregion
#region 14 days after registration to admins and users ENTERPRISE TRIAL + defaultRebranding
else if (createdDate.AddDays(14) == nowDate)
{
action = Actions.EnterpriseAdminUserAppsTipsV1;
paymentMessage = false;
toadmins = true;
tousers = true;
}
#endregion
#endregion
}
if (action == null)
{
continue;
}
var users = _studioNotifyHelper.GetRecipients(toadmins, tousers, false);
foreach (var u in users.Where(u => paymentMessage || _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var rquota = _tenantExtra.GetRightQuota() ?? TenantQuota.Default;
client.SendNoticeToAsync(
action,
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.ActiveUsers, _userManager.GetUsers().Length),
new TagValue(Tags.Price, rquota.Price),
new TagValue(Tags.PricePeriod, rquota.Year3 ? UserControlsCommonResource.TariffPerYear3 : rquota.Year ? UserControlsCommonResource.TariffPerYear : UserControlsCommonResource.TariffPerMonth),
new TagValue(Tags.DueDate, dueDate.ToLongDateString()),
new TagValue(Tags.DelayDueDate, (delayDueDateIsNotMax ? delayDueDate : dueDate).ToLongDateString()),
TagValues.GreenButton(greenButtonText, greenButtonUrl));
}
}
catch (Exception err)
{
_log.ErrorSendEnterpriseLetters(err);
}
}
_log.InformationEndSendTariffEnterpriseLetters();
}
public void SendOpensourceLetters(string senderName, DateTime scheduleDate)
{
var nowDate = scheduleDate.Date;
_log.InformationStartSendOpensourceTariffLetters();
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.InformationEndSendOpensourceTariffLetters();
return;
}
foreach (var tenant in activeTenants)
{
try
{
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var createdDate = tenant.CreationDateTime.Date;
#region After registration letters
#region 7 days after registration to admins
if (createdDate.AddDays(7) == nowDate)
{
var users = _studioNotifyHelper.GetRecipients(true, true, false);
var greenButtonText = () => WebstudioNotifyPatternResource.ButtonCollaborateDocSpace;
var greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/');
foreach (var u in users.Where(u => _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
client.SendNoticeToAsync(
_userManager.IsAdmin(u) ? Actions.OpensourceAdminDocsTipsV1 : Actions.OpensourceUserDocsTipsV1,
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(CommonTags.Footer, "opensource"),
TagValues.GreenButton(greenButtonText, greenButtonUrl));
}
}
#endregion
#endregion
}
catch (Exception err)
{
_log.ErrorSendOpensourceLetters(err);
}
}
_log.InformationEndSendOpensourceTariffLetters();
}
public void SendPersonalLetters(string senderName, DateTime scheduleDate)
{
_log.InformationStartSendLettersPersonal();
var activeTenants = _tenantManager.GetTenants().ToList();
foreach (var tenant in activeTenants)
{
try
{
Func<string> greenButtonText = () => string.Empty;
var greenButtonUrl = string.Empty;
var sendCount = 0;
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
_log.InformationCurrentTenant(tenant.Id);
var users = _userManager.GetUsers(EmployeeStatus.Active);
foreach (var user in users.Where(u => _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
INotifyAction action;
_securityContext.AuthenticateMeWithoutCookie(_authManager.GetAccountByID(tenant.Id, user.Id));
var culture = tenant.GetCulture();
if (!string.IsNullOrEmpty(user.CultureName))
{
try
{
culture = user.GetCulture();
}
catch (CultureNotFoundException exception)
{
_log.ErrorSendPersonalLetters(exception);
}
}
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var dayAfterRegister = (int)scheduleDate.Date.Subtract(user.CreateDate.Date).TotalDays;
switch (dayAfterRegister)
{
case 14:
action = Actions.PersonalAfterRegistration14V1;
break;
default:
continue;
}
if (action == null)
{
continue;
}
_log.InformationSendLetterPersonal(action.ID, user.Email, culture, tenant.Id, user.GetCulture(), user.CreateDate, scheduleDate.Date);
sendCount++;
client.SendNoticeToAsync(
action,
null,
_studioNotifyHelper.RecipientFromEmail(user.Email, true),
new[] { senderName },
TagValues.PersonalHeaderStart(),
TagValues.PersonalHeaderEnd(),
TagValues.GreenButton(greenButtonText, greenButtonUrl),
new TagValue(CommonTags.Footer, _coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"));
}
_log.InformationTotalSendCount(sendCount);
}
catch (Exception err)
{
_log.ErrorSendPersonalLetters(err);
}
}
_log.InformationEndSendLettersPersonal();
}
public static bool ChangeSubscription(Guid userId, StudioNotifyHelper studioNotifyHelper)
{
var recipient = studioNotifyHelper.ToRecipient(userId);
var isSubscribe = studioNotifyHelper.IsSubscribedToNotify(recipient, Actions.PeriodicNotify);
studioNotifyHelper.SubscribeToNotify(recipient, Actions.PeriodicNotify, !isSubscribe);
return !isSubscribe;
}
}