Merge branch 'feature/stripe' of github.com:ONLYOFFICE/AppServer into feature/stripe
This commit is contained in:
commit
76a20ed0cf
@ -34,7 +34,7 @@ public class Tariff
|
||||
public DateTime DueDate { get; set; }
|
||||
public DateTime DelayDueDate { get; set; }
|
||||
public DateTime LicenseDate { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string CustomerId { get; set; }
|
||||
public List<Tuple<int, int>> Quotas { get; set; }
|
||||
|
||||
public static Tariff CreateDefault(bool empty = false)
|
||||
@ -48,7 +48,7 @@ public class Tariff
|
||||
DueDate = DateTime.MaxValue,
|
||||
DelayDueDate = DateTime.MaxValue,
|
||||
LicenseDate = DateTime.MaxValue,
|
||||
CustomerId = Guid.Empty,
|
||||
CustomerId = "",
|
||||
Quotas = quotas
|
||||
};
|
||||
}
|
||||
|
@ -174,8 +174,7 @@ public class TariffService : ITariffService
|
||||
|
||||
if (!string.IsNullOrEmpty(email))
|
||||
{
|
||||
var customer = _userService.GetUser(tenantId, email);
|
||||
asynctariff.CustomerId = customer != null && !customer.Removed ? customer.Id : Guid.Empty;
|
||||
asynctariff.CustomerId = email;
|
||||
}
|
||||
|
||||
if (SaveBillingInfo(tenantId, asynctariff))
|
||||
|
@ -31,7 +31,7 @@ public class DbTariff
|
||||
public int Id { get; set; }
|
||||
public int Tenant { get; set; }
|
||||
public DateTime Stamp { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string CustomerId { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public DateTime CreateOn { get; set; }
|
||||
}
|
||||
@ -73,7 +73,7 @@ public static class DbTariffExtension
|
||||
|
||||
entity.Property(e => e.CustomerId)
|
||||
.HasColumnName("customer_id")
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
@ -104,7 +104,7 @@ public static class DbTariffExtension
|
||||
|
||||
entity.Property(e => e.CustomerId)
|
||||
.HasColumnName("customer_id")
|
||||
.HasMaxLength(36)
|
||||
.HasMaxLength(255)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Tenant).HasColumnName("tenant");
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
namespace ASC.Core.Common.Quota.Features;
|
||||
|
||||
internal class MaxFileSizeFeature : TenantQuotaFeatureLength
|
||||
internal class MaxFileSizeFeature : TenantQuotaFeatureSize
|
||||
{
|
||||
public override string Name { get => "file_size"; }
|
||||
public MaxFileSizeFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
namespace ASC.Core.Common.Quota.Features;
|
||||
|
||||
public class MaxTotalSizeFeature : TenantQuotaFeatureLength
|
||||
public class MaxTotalSizeFeature : TenantQuotaFeatureSize
|
||||
{
|
||||
public override string Name { get => "total_size"; }
|
||||
public override bool Paid { get => true; }
|
||||
|
35
common/ASC.Core.Common/Quota/Features/UsersInRoomFeature.cs
Normal file
35
common/ASC.Core.Common/Quota/Features/UsersInRoomFeature.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 UsersInRoomFeature : TenantQuotaFeatureCount
|
||||
{
|
||||
public override string Name { get => "usersInRoom"; }
|
||||
public UsersInRoomFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
}
|
@ -103,11 +103,11 @@ public class TenantQuotaFeatureCount : TenantQuotaFeature<int>
|
||||
}
|
||||
}
|
||||
|
||||
public class TenantQuotaFeatureLength : TenantQuotaFeature<long>
|
||||
public class TenantQuotaFeatureSize : TenantQuotaFeature<long>
|
||||
{
|
||||
protected override long Default => long.MaxValue;
|
||||
|
||||
public TenantQuotaFeatureLength(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
public TenantQuotaFeatureSize(TenantQuota tenantQuota) : base(tenantQuota)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,13 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
set => _countManagerFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly UsersInRoomFeature _usersInRoomFeature;
|
||||
public int UsersInRoom
|
||||
{
|
||||
get => _usersInRoomFeature.Value;
|
||||
set => _usersInRoomFeature.Value = value;
|
||||
}
|
||||
|
||||
private readonly CountRoomFeature _countRoomFeature;
|
||||
public int CountRoom
|
||||
{
|
||||
@ -215,6 +222,7 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
|
||||
_activeUsersFeature = new ActiveUsersFeature(this) { Order = 1 };
|
||||
_countManagerFeature = new CountManagerFeature(this);
|
||||
_usersInRoomFeature = new UsersInRoomFeature(this) { Order = 8 };
|
||||
_countRoomFeature = new CountRoomFeature(this) { Order = 2 };
|
||||
_maxTotalSizeFeature = new MaxTotalSizeFeature(this);
|
||||
_maxFileSizeFeature = new MaxFileSizeFeature(this);
|
||||
@ -238,6 +246,7 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
{
|
||||
_activeUsersFeature,
|
||||
_countManagerFeature,
|
||||
_usersInRoomFeature,
|
||||
_countRoomFeature,
|
||||
_maxTotalSizeFeature,
|
||||
_maxFileSizeFeature,
|
||||
@ -328,11 +337,11 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
{
|
||||
fileSize.Value = Math.Max(fileSize.Value, quota.MaxFileSize);
|
||||
}
|
||||
else if (f is TenantQuotaFeature<int> count)
|
||||
else if (f is TenantQuotaFeatureCount count)
|
||||
{
|
||||
count.Value += quota.GetFeature<int>(f.Name).Value;
|
||||
}
|
||||
else if (f is TenantQuotaFeatureLength length)
|
||||
else if (f is TenantQuotaFeatureSize length)
|
||||
{
|
||||
length.Value += quota.GetFeature<long>(f.Name).Value;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ namespace ASC.Migrations.MySql.Migrations.CoreDb
|
||||
|
||||
b.Property<string>("CustomerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("customer_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
@ -63,7 +63,8 @@ namespace ASC.Migrations.MySql.Migrations.CoreDb
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "customer_id",
|
||||
table: "tenants_tariff",
|
||||
type: "varchar(36)",
|
||||
type: "varchar(255)",
|
||||
maxLength: 255,
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
collation: "utf8_general_ci")
|
||||
|
@ -152,7 +152,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
|
||||
b.Property<string>("CustomerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("customer_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
@ -162,8 +162,8 @@ namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
|
||||
|
||||
b.Property<Guid>("CustomerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(36)
|
||||
.HasColumnType("uuid")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("customer_id")
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
|
@ -67,12 +67,12 @@ namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
|
||||
table: "tenants_quota",
|
||||
newName: "product_id");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "customer_id",
|
||||
schema: "onlyoffice",
|
||||
table: "tenants_tariff",
|
||||
type: "uuid",
|
||||
maxLength: 36,
|
||||
type: "character varying(255)",
|
||||
maxLength: 255,
|
||||
nullable: false,
|
||||
defaultValueSql: "NULL");
|
||||
|
||||
|
@ -151,8 +151,8 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
|
||||
b.Property<Guid>("CustomerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(36)
|
||||
.HasColumnType("uuid")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("customer_id")
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
|
@ -108,8 +108,9 @@ public class PaymentController : ControllerBase
|
||||
public Uri GetPaymentAccount(string backUrl)
|
||||
{
|
||||
var payerId = _tariffService.GetTariff(Tenant.Id).CustomerId;
|
||||
var payer = _userManager.GetUserByEmail(payerId);
|
||||
|
||||
if (_securityContext.CurrentAccount.ID != payerId &&
|
||||
if (_securityContext.CurrentAccount.ID != payer.Id &&
|
||||
_securityContext.CurrentAccount.ID != Tenant.OwnerId)
|
||||
{
|
||||
return null;
|
||||
|
@ -724,7 +724,12 @@ public class SettingsController : BaseSettingsController
|
||||
{
|
||||
var settings = _settingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>();
|
||||
var currentQuota = _tenantExtra.GetTenantQuota();
|
||||
var currentTariff = _tenantExtra.GetCurrentTariff();
|
||||
var currentTariff = _tenantExtra.GetCurrentTariff();
|
||||
|
||||
if (!int.TryParse(_configuration["core:payment:max-quantity"], out var maxQuotaQuantity))
|
||||
{
|
||||
maxQuotaQuantity = 999;
|
||||
}
|
||||
|
||||
return
|
||||
new
|
||||
@ -737,7 +742,8 @@ public class SettingsController : BaseSettingsController
|
||||
{
|
||||
currentQuota.Trial,
|
||||
currentTariff.DueDate.Date
|
||||
}
|
||||
},
|
||||
max = maxQuotaQuantity
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,19 +37,20 @@ public class QuotaDto
|
||||
public bool Free { get; set; }
|
||||
public bool Trial { get; set; }
|
||||
|
||||
public IAsyncEnumerable<QuotaFeatureDto> Features { get; set; }
|
||||
public IAsyncEnumerable<TenantQuotaFeatureDto> Features { get; set; }
|
||||
}
|
||||
|
||||
public class QuotaFeatureDto : IEquatable<QuotaFeatureDto>
|
||||
public class TenantQuotaFeatureDto : IEquatable<TenantQuotaFeatureDto>
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Image { get; set; }
|
||||
public object Value { get; set; }
|
||||
public string Type { get; set; }
|
||||
public FeatureUsedDto Used { get; set; }
|
||||
public FeaturePriceDto Price { get; set; }
|
||||
public string PriceTitle { get; set; }
|
||||
|
||||
public bool Equals(QuotaFeatureDto other)
|
||||
public bool Equals(TenantQuotaFeatureDto other)
|
||||
{
|
||||
if (other is null)
|
||||
{
|
||||
@ -59,7 +60,7 @@ public class QuotaFeatureDto : IEquatable<QuotaFeatureDto>
|
||||
return Id == other.Id;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as QuotaFeatureDto);
|
||||
public override bool Equals(object obj) => Equals(obj as TenantQuotaFeatureDto);
|
||||
public override int GetHashCode() => Id.GetHashCode();
|
||||
}
|
||||
|
||||
@ -69,12 +70,6 @@ public class PriceDto
|
||||
public string CurrencySymbol { get; set; }
|
||||
}
|
||||
|
||||
public class FeaturePriceDto
|
||||
{
|
||||
public string Count { get; set; }
|
||||
public string Per { get; set; }
|
||||
}
|
||||
|
||||
public class FeatureUsedDto
|
||||
{
|
||||
public object Value { get; set; }
|
||||
|
@ -61,7 +61,7 @@ public class QuotaHelper
|
||||
private QuotaDto ToQuotaDto(TenantQuota quota, IDictionary<string, Dictionary<string, decimal>> priceInfo, RegionInfo currentRegion, bool getUsed = false)
|
||||
{
|
||||
var price = GetPrice(quota, priceInfo, currentRegion);
|
||||
var features = GetFeatures(quota, GetPriceString(price, currentRegion), getUsed);
|
||||
var features = GetFeatures(quota, getUsed);
|
||||
|
||||
return new QuotaDto
|
||||
{
|
||||
@ -95,18 +95,7 @@ public class QuotaHelper
|
||||
return quota.Price;
|
||||
}
|
||||
|
||||
private string GetPriceString(decimal price, RegionInfo currentRegion)
|
||||
{
|
||||
var inEuro = "EUR".Equals(currentRegion.ISOCurrencySymbol);
|
||||
|
||||
var priceString = inEuro && Math.Truncate(price) != price ?
|
||||
price.ToString(CultureInfo.InvariantCulture) :
|
||||
((int)price).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
return string.Format("{0}{1}", currentRegion.CurrencySymbol, priceString);
|
||||
}
|
||||
|
||||
private async IAsyncEnumerable<QuotaFeatureDto> GetFeatures(TenantQuota quota, string price, bool getUsed)
|
||||
private async IAsyncEnumerable<TenantQuotaFeatureDto> GetFeatures(TenantQuota quota, bool getUsed)
|
||||
{
|
||||
var assembly = GetType().Assembly;
|
||||
|
||||
@ -114,38 +103,35 @@ public class QuotaHelper
|
||||
|
||||
foreach (var feature in quota.TenantQuotaFeatures.Where(r => r.Visible).OrderBy(r => r.Order))
|
||||
{
|
||||
var result = new QuotaFeatureDto();
|
||||
var result = new TenantQuotaFeatureDto();
|
||||
|
||||
if (feature.Paid)
|
||||
{
|
||||
result.Price = new FeaturePriceDto
|
||||
{
|
||||
Per = string.Format(Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}_price_per"), price),
|
||||
Count = Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}_price_count")
|
||||
};
|
||||
result.PriceTitle = Resource.ResourceManager.GetString($"TariffsFeature_{feature.Name}_price_count");
|
||||
}
|
||||
|
||||
result.Id = feature.Name;
|
||||
|
||||
object used = null;
|
||||
|
||||
if (feature is TenantQuotaFeature<long> length)
|
||||
if (feature is TenantQuotaFeatureSize size)
|
||||
{
|
||||
var maxValue = length.Value == long.MaxValue;
|
||||
result.Value = maxValue ? -1 : length.Value;
|
||||
result.Value = size.Value == long.MaxValue ? -1 : size.Value;
|
||||
result.Type = "size";
|
||||
|
||||
await GetStat<long>();
|
||||
}
|
||||
else if (feature is TenantQuotaFeature<int> count)
|
||||
else if (feature is TenantQuotaFeatureCount count)
|
||||
{
|
||||
var maxValue = count.Value == int.MaxValue;
|
||||
result.Value = maxValue ? -1 : count.Value;
|
||||
result.Value = count.Value == int.MaxValue ? -1 : count.Value;
|
||||
result.Type = "count";
|
||||
|
||||
await GetStat<int>();
|
||||
}
|
||||
else if (feature is TenantQuotaFeature<bool> flag)
|
||||
else if (feature is TenantQuotaFeatureFlag flag)
|
||||
{
|
||||
result.Value = flag.Value;
|
||||
result.Type = "flag";
|
||||
}
|
||||
|
||||
if (getUsed)
|
||||
|
@ -2184,15 +2184,6 @@ namespace ASC.Web.Core.PublicResources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} per manager/month.
|
||||
/// </summary>
|
||||
public static string TariffsFeature_manager_price_per {
|
||||
get {
|
||||
return ResourceManager.GetString("TariffsFeature_manager_price_per", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatic backup & recovery.
|
||||
/// </summary>
|
||||
@ -2239,11 +2230,20 @@ namespace ASC.Web.Core.PublicResources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to .
|
||||
/// Looks up a localized string similar to Managers added:.
|
||||
/// </summary>
|
||||
public static string TariffsFeature_total_size_price_per {
|
||||
public static string TariffsFeature_used_manager {
|
||||
get {
|
||||
return ResourceManager.GetString("TariffsFeature_total_size_price_per", resourceCulture);
|
||||
return ResourceManager.GetString("TariffsFeature_used_manager", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Room:.
|
||||
/// </summary>
|
||||
public static string TariffsFeature_used_room {
|
||||
get {
|
||||
return ResourceManager.GetString("TariffsFeature_used_room", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2257,11 +2257,11 @@ namespace ASC.Web.Core.PublicResources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Managers added:.
|
||||
/// Looks up a localized string similar to Users in room:.
|
||||
/// </summary>
|
||||
public static string TariffsFeature_used_users {
|
||||
public static string TariffsFeature_used_usersInRoom {
|
||||
get {
|
||||
return ResourceManager.GetString("TariffsFeature_used_users", resourceCulture);
|
||||
return ResourceManager.GetString("TariffsFeature_used_usersInRoom", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2274,6 +2274,15 @@ namespace ASC.Web.Core.PublicResources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Users in room.
|
||||
/// </summary>
|
||||
public static string TariffsFeature_usersInRoom {
|
||||
get {
|
||||
return ResourceManager.GetString("TariffsFeature_usersInRoom", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Branding & customization.
|
||||
/// </summary>
|
||||
|
@ -828,9 +828,6 @@
|
||||
<data name="TariffsFeature_manager_price_count" xml:space="preserve">
|
||||
<value>Number of managers</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_manager_price_per" xml:space="preserve">
|
||||
<value>{0} per manager/month</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_audit" xml:space="preserve">
|
||||
<value>Tracking user logins & action</value>
|
||||
</data>
|
||||
@ -858,7 +855,7 @@
|
||||
<data name="TariffsFeature_used_total_size" xml:space="preserve">
|
||||
<value>Storage space used:</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_used_users" xml:space="preserve">
|
||||
<data name="TariffsFeature_used_manager" xml:space="preserve">
|
||||
<value>Managers added:</value>
|
||||
</data>
|
||||
<data name="Tariffs_startup" xml:space="preserve">
|
||||
@ -867,10 +864,16 @@
|
||||
<data name="TariffsFeature_total_size_price_count" xml:space="preserve">
|
||||
<value>Storage space</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_total_size_price_per" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="TariffsFeature_file_size" xml:space="preserve">
|
||||
<value>Max file size</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_used_room" xml:space="preserve">
|
||||
<value>Room:</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_used_usersInRoom" xml:space="preserve">
|
||||
<value>Users in room:</value>
|
||||
</data>
|
||||
<data name="TariffsFeature_usersInRoom" xml:space="preserve">
|
||||
<value>Users in room</value>
|
||||
</data>
|
||||
</root>
|
Loading…
Reference in New Issue
Block a user