Quota: refactoring
This commit is contained in:
parent
fa1703be2d
commit
941689b6ca
@ -24,11 +24,6 @@
|
||||
// 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
|
||||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
using JsonConverter = System.Text.Json.Serialization.JsonConverter;
|
||||
|
||||
namespace ASC.Api.Core;
|
||||
@ -122,6 +117,9 @@ public abstract class BaseStartup
|
||||
services.AddEventBus(_configuration);
|
||||
services.AddDistributedTaskQueue();
|
||||
services.AddCacheNotify(_configuration);
|
||||
services.AddScoped<ITenantQuotaFeatureChecker, ActiveUsersChecker>();
|
||||
services.AddScoped<ActiveUsersChecker>();
|
||||
|
||||
|
||||
DIHelper.TryAdd(typeof(IWebhookPublisher), typeof(WebhookPublisher));
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
global using System.ComponentModel;
|
||||
global using System.Globalization;
|
||||
global using System.IdentityModel.Tokens.Jwt;
|
||||
global using System.Linq.Expressions;
|
||||
global using System.Net;
|
||||
global using System.Reflection;
|
||||
@ -57,7 +58,6 @@ global using ASC.Common.Caching;
|
||||
global using ASC.Common.DependencyInjection;
|
||||
global using ASC.Common.Log;
|
||||
global using ASC.Common.Logging;
|
||||
global using ASC.Common.Notify.Engine;
|
||||
global using ASC.Common.Threading;
|
||||
global using ASC.Common.Utils;
|
||||
global using ASC.Common.Web;
|
||||
@ -66,6 +66,8 @@ global using ASC.Core.Common.EF;
|
||||
global using ASC.Core.Common.EF.Context;
|
||||
global using ASC.Core.Common.Hosting;
|
||||
global using ASC.Core.Common.Hosting.Interfaces;
|
||||
global using ASC.Core.Common.Quota;
|
||||
global using ASC.Core.Common.Quota.Features;
|
||||
global using ASC.Core.Common.Settings;
|
||||
global using ASC.Core.Tenants;
|
||||
global using ASC.Core.Users;
|
||||
@ -81,7 +83,6 @@ global using ASC.MessagingSystem.EF.Model;
|
||||
global using ASC.Security.Cryptography;
|
||||
global using ASC.Web.Api.Routing;
|
||||
global using ASC.Web.Core;
|
||||
global using ASC.Web.Core.Helpers;
|
||||
global using ASC.Web.Core.Users;
|
||||
global using ASC.Web.Studio.Utility;
|
||||
global using ASC.Webhooks.Core;
|
||||
@ -97,6 +98,8 @@ global using Confluent.Kafka;
|
||||
global using HealthChecks.UI.Client;
|
||||
|
||||
global using Microsoft.AspNetCore.Authentication;
|
||||
global using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
global using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
global using Microsoft.AspNetCore.Authorization;
|
||||
global using Microsoft.AspNetCore.Builder;
|
||||
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
@ -124,8 +127,8 @@ global using Microsoft.Extensions.Hosting;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
global using Microsoft.Extensions.Options;
|
||||
global using Microsoft.Extensions.Primitives;
|
||||
global using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
global using Microsoft.IdentityModel.Tokens;
|
||||
global using Microsoft.IdentityModel.Tokens;
|
||||
global using Microsoft.Net.Http.Headers;
|
||||
|
||||
global using Newtonsoft.Json;
|
||||
global using Newtonsoft.Json.Serialization;
|
||||
|
@ -79,6 +79,8 @@ public class TariffService : ITariffService
|
||||
private readonly IDbContextFactory<CoreDbContext> _dbContextFactory;
|
||||
private readonly TariffServiceStorage _tariffServiceStorage;
|
||||
private readonly BillingClient _billingClient;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
//private readonly int _activeUsersMin;
|
||||
//private readonly int _activeUsersMax;
|
||||
|
||||
@ -97,7 +99,8 @@ public class TariffService : ITariffService
|
||||
IDbContextFactory<CoreDbContext> coreDbContextManager,
|
||||
TariffServiceStorage tariffServiceStorage,
|
||||
ILogger<TariffService> logger,
|
||||
BillingClient billingClient)
|
||||
BillingClient billingClient,
|
||||
IServiceProvider serviceProvider)
|
||||
: this()
|
||||
|
||||
{
|
||||
@ -108,6 +111,7 @@ public class TariffService : ITariffService
|
||||
_coreSettings = coreSettings;
|
||||
_tariffServiceStorage = tariffServiceStorage;
|
||||
_billingClient = billingClient;
|
||||
_serviceProvider = serviceProvider;
|
||||
_coreBaseSettings = coreBaseSettings;
|
||||
_paymentDelay = configuration.GetSection("core:payment").Get<PaymentConfiguration>().Delay;
|
||||
|
||||
@ -261,7 +265,7 @@ public class TariffService : ITariffService
|
||||
updatedQuota += quota;
|
||||
}
|
||||
|
||||
CheckQuota(updatedQuota);
|
||||
updatedQuota.Check(_serviceProvider);
|
||||
|
||||
var productIds = newQuotas.Select(q => q.ProductId);
|
||||
|
||||
@ -281,20 +285,6 @@ public class TariffService : ITariffService
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: compare fields with current parameters
|
||||
public bool CheckQuota(TenantQuota quota)
|
||||
{
|
||||
if (quota.MaxTotalSize != long.MaxValue
|
||||
&& false) throw new Exception("The used storage size should not exceed " + quota.MaxTotalSize);
|
||||
if (quota.ActiveUsers != int.MaxValue
|
||||
&& false) throw new Exception("The number of active users should not exceed " + quota.ActiveUsers);
|
||||
if (quota.CountAdmin != int.MaxValue
|
||||
&& false) throw new Exception("The number of managers should not exceed " + quota.CountAdmin);
|
||||
if (quota.CountRoom != int.MaxValue
|
||||
&& false) throw new Exception("The number of rooms should not exceed " + quota.CountRoom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetTariff(int tenantId, Tariff tariff)
|
||||
{
|
||||
@ -401,7 +391,7 @@ public class TariffService : ITariffService
|
||||
updatedQuota += quota;
|
||||
}
|
||||
|
||||
CheckQuota(updatedQuota);
|
||||
updatedQuota.Check(_serviceProvider);
|
||||
|
||||
var productIds = newQuotas.Select(q => q.ProductId);
|
||||
|
||||
|
@ -90,6 +90,8 @@ global using ASC.Core.Common.Notify.IntegrationEvents.Events;
|
||||
global using ASC.Core.Common.Notify.Jabber;
|
||||
global using ASC.Core.Common.Notify.Push;
|
||||
global using ASC.Core.Common.Notify.Telegram;
|
||||
global using ASC.Core.Common.Quota;
|
||||
global using ASC.Core.Common.Quota.Features;
|
||||
global using ASC.Core.Common.Security;
|
||||
global using ASC.Core.Common.Settings;
|
||||
global using ASC.Core.Configuration;
|
||||
@ -106,9 +108,9 @@ global using ASC.EventBus.Abstractions;
|
||||
global using ASC.EventBus.Events;
|
||||
global using ASC.Geolocation;
|
||||
global using ASC.MessagingSystem.Core;
|
||||
global using ASC.MessagingSystem.EF.Context;
|
||||
global using ASC.MessagingSystem.EF.Model;
|
||||
global using ASC.MessagingSystem.Mapping;
|
||||
global using ASC.MessagingSystem.EF.Context;
|
||||
global using ASC.Notify;
|
||||
global using ASC.Notify.Channels;
|
||||
global using ASC.Notify.Cron;
|
||||
@ -163,7 +165,7 @@ global using Telegram.Bot;
|
||||
|
||||
global using static ASC.Security.Cryptography.EmailValidationKeyProvider;
|
||||
|
||||
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
||||
global using FirebaseAdminMessaging = FirebaseAdmin.Messaging;
|
||||
global using FirebaseApp = FirebaseAdmin.FirebaseApp;
|
||||
global using AppOptions = FirebaseAdmin.AppOptions;
|
||||
global using FirebaseApp = FirebaseAdmin.FirebaseApp;
|
||||
global using FirebaseAdminMessaging = FirebaseAdmin.Messaging;
|
||||
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
||||
|
55
common/ASC.Core.Common/Quota/Features/ActiveUsersFeature.cs
Normal file
55
common/ASC.Core.Common/Quota/Features/ActiveUsersFeature.cs
Normal file
@ -0,0 +1,55 @@
|
||||
// (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.Core.Common.Quota.Features;
|
||||
|
||||
public class ActiveUsersFeature : TenantQuotaFeatureCount
|
||||
{
|
||||
public override string Name { get => "users"; }
|
||||
public override bool Paid { get => true; }
|
||||
public ActiveUsersFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ActiveUsersChecker : ITenantQuotaFeatureChecker
|
||||
{
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
public ActiveUsersChecker(UserManager userManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
}
|
||||
public bool Check(TenantQuota quota)
|
||||
{
|
||||
return _userManager.GetUsersByGroup(Users.Constants.GroupUser.ID).Length >= quota.ActiveUsers;
|
||||
}
|
||||
|
||||
public string Exception(TenantQuota quota)
|
||||
{
|
||||
return "The number of active users should not exceed " + quota.ActiveUsers;
|
||||
}
|
||||
}
|
34
common/ASC.Core.Common/Quota/Features/CountAdminFeature.cs
Normal file
34
common/ASC.Core.Common/Quota/Features/CountAdminFeature.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// (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.Core.Common.Quota.Features;
|
||||
public class CountAdminFeature : TenantQuotaFeatureCount
|
||||
{
|
||||
public override string Name { get => "admin"; }
|
||||
public CountAdminFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
}
|
34
common/ASC.Core.Common/Quota/Features/CountRoomFeature.cs
Normal file
34
common/ASC.Core.Common/Quota/Features/CountRoomFeature.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// (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.Core.Common.Quota.Features;
|
||||
public class CountRoomFeature : TenantQuotaFeatureCount
|
||||
{
|
||||
public override string Name { get => "room"; }
|
||||
public CountRoomFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
}
|
35
common/ASC.Core.Common/Quota/Features/MaxTotalSizeFeature.cs
Normal file
35
common/ASC.Core.Common/Quota/Features/MaxTotalSizeFeature.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// (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.Core.Common.Quota.Features;
|
||||
|
||||
public class MaxTotalSizeFeature : TenantQuotaFeatureLength
|
||||
{
|
||||
public override string Name { get => "total_size"; }
|
||||
public MaxTotalSizeFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
}
|
32
common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs
Normal file
32
common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// (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.Core.Common.Quota;
|
||||
public interface ITenantQuotaFeatureChecker
|
||||
{
|
||||
public bool Check(TenantQuota value);
|
||||
public string Exception(TenantQuota value);
|
||||
}
|
138
common/ASC.Core.Common/Quota/TenantQuotaFeature.cs
Normal file
138
common/ASC.Core.Common/Quota/TenantQuotaFeature.cs
Normal file
@ -0,0 +1,138 @@
|
||||
// (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.Core.Common.Quota;
|
||||
|
||||
public class TenantQuotaFeature
|
||||
{
|
||||
public int Order { get; init; }
|
||||
public virtual bool Visible { get; init; } = true;
|
||||
public virtual string Name { get; init; }
|
||||
public virtual bool Paid { get; init; }
|
||||
|
||||
protected internal virtual void Multiply(int quantity)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
public class TenantQuotaFeature<T> : TenantQuotaFeature
|
||||
{
|
||||
private readonly TenantQuota _tenantQuota;
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
var parsed = _tenantQuota.GetFeature(Name);
|
||||
|
||||
if (parsed == null)
|
||||
{
|
||||
return Default;
|
||||
}
|
||||
|
||||
if (!TryParse(parsed, out var result))
|
||||
{
|
||||
return Default;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
_tenantQuota.ReplaceFeature(Name, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual T Default { get; }
|
||||
|
||||
public TenantQuotaFeature(TenantQuota tenantQuota)
|
||||
{
|
||||
_tenantQuota = tenantQuota;
|
||||
}
|
||||
|
||||
protected virtual bool TryParse(string s, out T result)
|
||||
{
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class TenantQuotaFeatureCount : TenantQuotaFeature<int>
|
||||
{
|
||||
protected override int Default => int.MaxValue;
|
||||
|
||||
public TenantQuotaFeatureCount(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool TryParse(string s, out int result)
|
||||
{
|
||||
return int.TryParse(s.Substring(s.IndexOf(':') + 1), out result);
|
||||
}
|
||||
|
||||
protected internal override void Multiply(int quantity)
|
||||
{
|
||||
if (Value != int.MaxValue)
|
||||
{
|
||||
Value *= quantity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TenantQuotaFeatureLength : TenantQuotaFeature<long>
|
||||
{
|
||||
protected override long Default => long.MaxValue;
|
||||
|
||||
public TenantQuotaFeatureLength(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool TryParse(string s, out long result)
|
||||
{
|
||||
return long.TryParse(s.Substring(s.IndexOf(':') + 1), out result);
|
||||
}
|
||||
|
||||
protected internal override void Multiply(int quantity)
|
||||
{
|
||||
if (Value != long.MaxValue)
|
||||
{
|
||||
Value *= quantity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TenantQuotaFeatureFlag : TenantQuotaFeature<bool>
|
||||
{
|
||||
public TenantQuotaFeatureFlag(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool TryParse(string s, out bool result)
|
||||
{
|
||||
result = true;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
namespace ASC.Core.Tenants;
|
||||
|
||||
[DebuggerDisplay("{Tenant} {Name}")]
|
||||
public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
public class TenantQuota : IMapFrom<DbQuota>
|
||||
{
|
||||
public static readonly TenantQuota Default = new TenantQuota(Tenants.Tenant.DefaultTenant)
|
||||
{
|
||||
@ -46,6 +46,10 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
public bool Visible { get; set; }
|
||||
public long MaxFileSize { get; set; }
|
||||
|
||||
public IReadOnlyList<TenantQuotaFeature> TenantQuotaFeatures { get; private set; }
|
||||
|
||||
private List<string> _featuresList;
|
||||
|
||||
public string Features
|
||||
{
|
||||
get
|
||||
@ -64,142 +68,213 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly MaxTotalSizeFeature _maxTotalSizeFeature;
|
||||
public long MaxTotalSize
|
||||
{
|
||||
get => ByteConverter.GetInBytes(GetFeature("total_size", () => Default.MaxTotalSize));
|
||||
set => SetFeature("total_size", ByteConverter.GetInMBytes(value));
|
||||
get => ByteConverter.GetInBytes(_maxTotalSizeFeature.Value);
|
||||
set => _maxTotalSizeFeature.Value = ByteConverter.GetInMBytes(value);
|
||||
}
|
||||
|
||||
private readonly ActiveUsersFeature _activeUsersFeature;
|
||||
public int ActiveUsers
|
||||
{
|
||||
get => GetFeature("users", () => Default.ActiveUsers);
|
||||
set => SetFeature("users", value);
|
||||
get => _activeUsersFeature.Value;
|
||||
set => _activeUsersFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly CountAdminFeature _countAdminFeature;
|
||||
public int CountAdmin
|
||||
{
|
||||
get => GetFeature("admin", () => Default.CountAdmin);
|
||||
set => SetFeature("admin", value);
|
||||
get => _countAdminFeature.Value;
|
||||
set => _countAdminFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly CountRoomFeature _countRoomFeature;
|
||||
public int CountRoom
|
||||
{
|
||||
get => GetFeature("room", () => Default.CountRoom);
|
||||
set => SetFeature("room", value);
|
||||
get => _countRoomFeature.Value;
|
||||
set => _countRoomFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _nonProfitFeature;
|
||||
public bool NonProfit
|
||||
{
|
||||
get => GetFeature("non-profit");
|
||||
set => SetFeature("non-profit", value);
|
||||
get => _nonProfitFeature.Value;
|
||||
set => _nonProfitFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _trialFeature;
|
||||
public bool Trial
|
||||
{
|
||||
get => GetFeature("trial");
|
||||
set => SetFeature("trial", value);
|
||||
get => _trialFeature.Value;
|
||||
set => _trialFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _freeFeature;
|
||||
public bool Free
|
||||
{
|
||||
get => GetFeature("free");
|
||||
set => SetFeature("free", value);
|
||||
get => _freeFeature.Value;
|
||||
set => _freeFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _openFeature;
|
||||
public bool Open
|
||||
{
|
||||
get => GetFeature("open");
|
||||
set => SetFeature("open", value);
|
||||
get => _openFeature.Value;
|
||||
set => _openFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _updateFeature;
|
||||
public bool Update
|
||||
{
|
||||
get => GetFeature("update");
|
||||
set => SetFeature("update", value);
|
||||
get => _updateFeature.Value;
|
||||
set => _updateFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _auditFeature;
|
||||
public bool Audit
|
||||
{
|
||||
get => GetFeature("audit");
|
||||
set => SetFeature("audit", value);
|
||||
get => _auditFeature.Value;
|
||||
set => _auditFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _docsEditionFeature;
|
||||
public bool DocsEdition
|
||||
{
|
||||
get => GetFeature("docs");
|
||||
set => SetFeature("docs", value);
|
||||
get => _docsEditionFeature.Value;
|
||||
set => _docsEditionFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _hasMigrationFeature;
|
||||
public bool HasMigration
|
||||
{
|
||||
get => GetFeature("migration");
|
||||
set => SetFeature("migration", value);
|
||||
get => _hasMigrationFeature.Value;
|
||||
set => _hasMigrationFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _ldapFeature;
|
||||
public bool Ldap
|
||||
{
|
||||
get => GetFeature("ldap");
|
||||
set => SetFeature("ldap", value);
|
||||
get => _ldapFeature.Value;
|
||||
set => _ldapFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _ssoFeature;
|
||||
public bool Sso
|
||||
{
|
||||
get => GetFeature("sso");
|
||||
set => SetFeature("sso", value);
|
||||
get => _ssoFeature.Value;
|
||||
set => _ssoFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _whiteLabelFeature;
|
||||
public bool WhiteLabel
|
||||
{
|
||||
get => GetFeature("whitelabel");
|
||||
set => SetFeature("whitelabel", value);
|
||||
get => _whiteLabelFeature.Value;
|
||||
set => _whiteLabelFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _customizationFeature;
|
||||
public bool Customization
|
||||
{
|
||||
get => GetFeature("customization");
|
||||
set => SetFeature("customization", value);
|
||||
get => _customizationFeature.Value;
|
||||
set => _customizationFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _customFeature;
|
||||
public bool Custom
|
||||
{
|
||||
get => GetFeature("custom");
|
||||
set => SetFeature("custom", value);
|
||||
get => _customFeature.Value;
|
||||
set => _customFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _restoreFeature;
|
||||
public bool Restore
|
||||
{
|
||||
get => GetFeature("restore");
|
||||
set => SetFeature("restore", value);
|
||||
get => _restoreFeature.Value;
|
||||
set => _restoreFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _autoBackupFeature;
|
||||
public bool AutoBackup
|
||||
{
|
||||
get => GetFeature("autobackup");
|
||||
set => SetFeature("autobackup", value);
|
||||
get => _autoBackupFeature.Value;
|
||||
set => _autoBackupFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _oauthFeature;
|
||||
public bool Oauth
|
||||
{
|
||||
get => GetFeature("oauth");
|
||||
set => SetFeature("oauth", value);
|
||||
get => _oauthFeature.Value;
|
||||
set => _oauthFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _contentSearchFeature;
|
||||
public bool ContentSearch
|
||||
{
|
||||
get => GetFeature("contentsearch");
|
||||
set => SetFeature("contentsearch", value);
|
||||
get => _contentSearchFeature.Value;
|
||||
set => _contentSearchFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly TenantQuotaFeatureFlag _thirdPartyFeature;
|
||||
public bool ThirdParty
|
||||
{
|
||||
get => GetFeature("thirdparty");
|
||||
set => SetFeature("thirdparty", value);
|
||||
get => _thirdPartyFeature.Value;
|
||||
set => _thirdPartyFeature.Value = value;
|
||||
}
|
||||
|
||||
private List<string> _featuresList;
|
||||
public TenantQuota()
|
||||
{
|
||||
_featuresList = new List<string>();
|
||||
|
||||
_activeUsersFeature = new ActiveUsersFeature(this) { Order = 1 };
|
||||
_countAdminFeature = new CountAdminFeature(this);
|
||||
_countRoomFeature = new CountRoomFeature(this) { Order = 2 };
|
||||
_maxTotalSizeFeature = new MaxTotalSizeFeature(this) { Order = 3 };
|
||||
_nonProfitFeature = new TenantQuotaFeatureFlag(this) { Name = "non-profit", Visible = false };
|
||||
_trialFeature = new TenantQuotaFeatureFlag(this) { Name = "trial", Visible = false };
|
||||
_freeFeature = new TenantQuotaFeatureFlag(this) { Name = "free", Visible = false };
|
||||
_openFeature = new TenantQuotaFeatureFlag(this) { Name = "open", Visible = false };
|
||||
_updateFeature = new TenantQuotaFeatureFlag(this) { Name = "update", Visible = false };
|
||||
_auditFeature = new TenantQuotaFeatureFlag(this) { Name = "audit", Order = 7 };
|
||||
_docsEditionFeature = new TenantQuotaFeatureFlag(this) { Name = "docs", Visible = false };
|
||||
_hasMigrationFeature = new TenantQuotaFeatureFlag(this) { Name = "migration", Visible = false };
|
||||
_ldapFeature = new TenantQuotaFeatureFlag(this) { Name = "ldap", Visible = false };
|
||||
_ssoFeature = new TenantQuotaFeatureFlag(this) { Name = "sso", Order = 5 };
|
||||
_whiteLabelFeature = new TenantQuotaFeatureFlag(this) { Name = "whitelabel", Order = 4 };
|
||||
_customizationFeature = new TenantQuotaFeatureFlag(this) { Name = "customization", Visible = false };
|
||||
_customFeature = new TenantQuotaFeatureFlag(this) { Name = "custom", Visible = false };
|
||||
_restoreFeature = new TenantQuotaFeatureFlag(this) { Name = "restore", Order = 6 };
|
||||
_autoBackupFeature = new TenantQuotaFeatureFlag(this) { Name = "autobackup", Visible = false };
|
||||
_oauthFeature = new TenantQuotaFeatureFlag(this) { Name = "oauth", Visible = false };
|
||||
_contentSearchFeature = new TenantQuotaFeatureFlag(this) { Name = "contentsearch", Visible = false };
|
||||
_thirdPartyFeature = new TenantQuotaFeatureFlag(this) { Name = "thirdparty", Visible = false };
|
||||
|
||||
TenantQuotaFeatures = new List<TenantQuotaFeature>
|
||||
{
|
||||
_activeUsersFeature,
|
||||
_countAdminFeature,
|
||||
_countRoomFeature,
|
||||
_maxTotalSizeFeature,
|
||||
_nonProfitFeature,
|
||||
_trialFeature,
|
||||
_freeFeature,
|
||||
_openFeature,
|
||||
_updateFeature,
|
||||
_auditFeature,
|
||||
_docsEditionFeature,
|
||||
_hasMigrationFeature,
|
||||
_ldapFeature,
|
||||
_ssoFeature,
|
||||
_whiteLabelFeature,
|
||||
_customizationFeature,
|
||||
_customFeature,
|
||||
_restoreFeature,
|
||||
_autoBackupFeature,
|
||||
_oauthFeature,
|
||||
_contentSearchFeature,
|
||||
_thirdPartyFeature
|
||||
};
|
||||
}
|
||||
|
||||
public TenantQuota(int tenant) : this()
|
||||
@ -207,7 +282,7 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
Tenant = tenant;
|
||||
}
|
||||
|
||||
public TenantQuota(TenantQuota quota)
|
||||
public TenantQuota(TenantQuota quota) : this()
|
||||
{
|
||||
Tenant = quota.Tenant;
|
||||
Name = quota.Name;
|
||||
@ -228,78 +303,24 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
return obj is TenantQuota q && q.Tenant == Tenant;
|
||||
}
|
||||
|
||||
private bool GetFeature(string feature)
|
||||
public void Check(IServiceProvider serviceProvider)
|
||||
{
|
||||
return _featuresList.Contains(feature);
|
||||
}
|
||||
|
||||
private int GetFeature(string feature, Func<int> @default)
|
||||
{
|
||||
var featureValue = GetFeatureValue(feature);
|
||||
|
||||
if (featureValue == null || !int.TryParse(featureValue, out var result))
|
||||
foreach (var checker in serviceProvider.GetServices<ITenantQuotaFeatureChecker>())
|
||||
{
|
||||
return @default();
|
||||
if (!checker.Check(this))
|
||||
{
|
||||
throw new Exception(checker.Exception(this));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private long GetFeature(string feature, Func<long> @default)
|
||||
{
|
||||
var featureValue = GetFeatureValue(feature);
|
||||
|
||||
if (featureValue == null || !long.TryParse(featureValue, out var result))
|
||||
{
|
||||
return @default();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string GetFeatureValue(string feature)
|
||||
{
|
||||
var parsed = _featuresList.FirstOrDefault(f => f.StartsWith($"{feature}:"));
|
||||
|
||||
if (parsed == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return parsed.Replace($"{feature}:", "");
|
||||
}
|
||||
|
||||
private void SetFeature(string feature, bool set)
|
||||
{
|
||||
if (set && !_featuresList.Contains(feature))
|
||||
{
|
||||
_featuresList.Add(feature);
|
||||
}
|
||||
else if (!set && _featuresList.Contains(feature))
|
||||
{
|
||||
_featuresList.Remove(feature);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFeature(string feature, int @value)
|
||||
{
|
||||
SetFeature(feature, @value > 0 ? value.ToString() : null);
|
||||
}
|
||||
|
||||
private void SetFeature(string feature, long @value)
|
||||
{
|
||||
SetFeature(feature, @value > 0 ? value.ToString() : null);
|
||||
}
|
||||
|
||||
internal void SetFeature(string feature, string @value)
|
||||
{
|
||||
var featureValue = _featuresList.FirstOrDefault(f => f.StartsWith($"{feature}:"));
|
||||
_featuresList.Remove(featureValue);
|
||||
|
||||
if (!string.IsNullOrEmpty(@value))
|
||||
{
|
||||
_featuresList.Add($"{feature}:{@value}");
|
||||
}
|
||||
//if (MaxTotalSize != long.MaxValue
|
||||
// && false) throw new Exception("The used storage size should not exceed " + MaxTotalSize);
|
||||
//if (ActiveUsers != int.MaxValue
|
||||
// && false) throw new Exception("The number of active users should not exceed " + ActiveUsers);
|
||||
//if (CountAdmin != int.MaxValue
|
||||
// && false) throw new Exception("The number of managers should not exceed " + CountAdmin);
|
||||
//if (CountRoom != int.MaxValue
|
||||
// && false) throw new Exception("The number of rooms should not exceed " + CountRoom);
|
||||
}
|
||||
|
||||
public static TenantQuota operator *(TenantQuota quota, int quantity)
|
||||
@ -308,24 +329,9 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
|
||||
newQuota.Price *= quantity;
|
||||
|
||||
if (newQuota.MaxTotalSize != long.MaxValue)
|
||||
for (var i = 0; i < newQuota.TenantQuotaFeatures.Count; i++)
|
||||
{
|
||||
newQuota.MaxTotalSize *= quantity;
|
||||
}
|
||||
|
||||
if (newQuota.ActiveUsers != int.MaxValue)
|
||||
{
|
||||
newQuota.ActiveUsers *= quantity;
|
||||
}
|
||||
|
||||
if (newQuota.CountAdmin != int.MaxValue)
|
||||
{
|
||||
newQuota.CountAdmin *= quantity;
|
||||
}
|
||||
|
||||
if (newQuota.CountRoom != int.MaxValue)
|
||||
{
|
||||
newQuota.CountRoom *= quantity;
|
||||
newQuota.TenantQuotaFeatures[i].Multiply(quantity);
|
||||
}
|
||||
|
||||
return newQuota;
|
||||
@ -345,58 +351,49 @@ public class TenantQuota : ICloneable, IMapFrom<DbQuota>
|
||||
newQuota.Visible &= quota.Visible;
|
||||
newQuota.ProductId = "";
|
||||
|
||||
var features = newQuota._featuresList.Concat(quota._featuresList).ToList();
|
||||
|
||||
for (var i = 0; i < features.Count - 1; i++)
|
||||
foreach (var f in newQuota.TenantQuotaFeatures)
|
||||
{
|
||||
for (var j = i + 1; j < features.Count; j++)
|
||||
if (f is TenantQuotaFeature<int> count)
|
||||
{
|
||||
if (features[i].Contains(':'))
|
||||
{
|
||||
if (features[j].Contains(':'))
|
||||
{
|
||||
var pref1 = features[i].Split(':')[0];
|
||||
var pref2 = features[j].Split(':')[0];
|
||||
if (pref1 == pref2)
|
||||
{
|
||||
if (int.TryParse(features[i].Replace(pref1 + ":", ""), out var val1) &&
|
||||
int.TryParse(features[j].Replace(pref1 + ":", ""), out var val2))
|
||||
{
|
||||
features[i] = $"{pref1}:{val1 + val2}";
|
||||
features.RemoveAt(j);
|
||||
j--;
|
||||
}
|
||||
else if (long.TryParse(features[i].Replace(pref1 + ":", ""), out var val3) &&
|
||||
long.TryParse(features[j].Replace(pref1 + ":", ""), out var val4))
|
||||
{
|
||||
features[i] = $"{pref1}:{val3 + val4}";
|
||||
features.RemoveAt(j);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (features[i] == features[j])
|
||||
{
|
||||
features.RemoveAt(j);
|
||||
j--;
|
||||
}
|
||||
count.Value += quota.GetFeature<int>(f.Name).Value;
|
||||
}
|
||||
else if (f is TenantQuotaFeatureLength length)
|
||||
{
|
||||
length.Value += quota.GetFeature<long>(f.Name).Value;
|
||||
}
|
||||
else if (f is TenantQuotaFeatureFlag flag)
|
||||
{
|
||||
flag.Value |= quota.GetFeature<bool>(f.Name).Value;
|
||||
}
|
||||
}
|
||||
|
||||
newQuota._featuresList = features;
|
||||
|
||||
return newQuota;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbQuota, TenantQuota>()
|
||||
.ForMember(dest => dest.MaxFileSize, opt => opt.MapFrom(src => ByteConverter.GetInBytes(src.MaxFileSize)));
|
||||
}
|
||||
}
|
||||
|
||||
internal TenantQuotaFeature<T> GetFeature<T>(string name)
|
||||
{
|
||||
return TenantQuotaFeatures.OfType<TenantQuotaFeature<T>>().FirstOrDefault(r => r.Name == name);
|
||||
}
|
||||
|
||||
internal string GetFeature(string name)
|
||||
{
|
||||
return _featuresList.FirstOrDefault(f => f.StartsWith($"{name}"));
|
||||
}
|
||||
|
||||
internal void ReplaceFeature<T>(string name, T value)
|
||||
{
|
||||
var featureValue = GetFeature(name);
|
||||
_featuresList.Remove(featureValue);
|
||||
|
||||
if (!EqualityComparer<T>.Default.Equals(value, default))
|
||||
{
|
||||
_featuresList.Add($"{name}:{value}");
|
||||
}
|
||||
}
|
||||
}
|
@ -49,12 +49,9 @@ public class QuotaHelper
|
||||
|
||||
private QuotaDto ToQuotaDto(TenantQuota tenantQuota, IDictionary<string, Dictionary<string, decimal>> priceInfo, RegionInfo currentRegion)
|
||||
{
|
||||
var defaultFeatures = GetFeatures(TenantQuota.Default, priceInfo, currentRegion);
|
||||
var quotaFeatures = GetFeatures(tenantQuota, priceInfo, currentRegion);
|
||||
var features = GetFeatures(tenantQuota, priceInfo, currentRegion);
|
||||
|
||||
var features = quotaFeatures.Union(defaultFeatures);
|
||||
|
||||
return new QuotaDto()
|
||||
return new QuotaDto
|
||||
{
|
||||
Id = tenantQuota.Tenant,
|
||||
Title = Resource.ResourceManager.GetString($"Tariffs_{tenantQuota.Name}"),
|
||||
@ -96,26 +93,19 @@ public class QuotaHelper
|
||||
|
||||
var features = tenantQuota.Features.Split(' ', ',', ';');
|
||||
|
||||
foreach (var feature in features)
|
||||
foreach (var feature in tenantQuota.TenantQuotaFeatures.Where(r => r.Visible).OrderBy(r => r.Order))
|
||||
{
|
||||
var result = new QuotaFeatureDto();
|
||||
|
||||
var id = feature;
|
||||
|
||||
if (id.Contains(':'))
|
||||
{
|
||||
id = id.Split(':')[0];
|
||||
}
|
||||
|
||||
if (id == "admin" || features.Length == 1) //TODO
|
||||
if (feature.Name == "admin" || features.Length == 1) //TODO
|
||||
{
|
||||
var val = GetPrice(tenantQuota, priceInfo, currentRegion);
|
||||
result.Price = new FeaturePriceDto
|
||||
{
|
||||
Value = val,
|
||||
CurrencySymbol = currentRegion.CurrencySymbol,
|
||||
Per = string.Format(Resource.ResourceManager.GetString($"TariffsFeature_{id}_price_per"), GetPriceString(val, currentRegion)),
|
||||
Count = Resource.ResourceManager.GetString($"TariffsFeature_{id}_price_count"),
|
||||
Per = string.Format(Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}_price_per"), GetPriceString(val, currentRegion)),
|
||||
Count = Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}_price_count"),
|
||||
Range = new FeaturePriceRangeDto
|
||||
{
|
||||
Value = 1,
|
||||
@ -125,15 +115,15 @@ public class QuotaHelper
|
||||
};
|
||||
}
|
||||
|
||||
result.Id = id;
|
||||
result.Title = Resource.ResourceManager.GetString($"TariffsFeature_{id}");
|
||||
result.Id = feature.Name;
|
||||
result.Title = Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}");
|
||||
|
||||
if (id == "total_size") //TODO
|
||||
if (feature.Name == "total_size") //TODO
|
||||
{
|
||||
result.Title = string.Format(result.Title, FileSizeComment.FilesSizeToString(tenantQuota.MaxTotalSize));
|
||||
}
|
||||
|
||||
var img = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.img.{id}.svg");
|
||||
var img = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.img.{feature.Name}.svg");
|
||||
|
||||
if (img != null)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user