From 33ecab83f3b1d0cb1ae624b029ef1b9e0a6fcf57 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 19 Jun 2023 16:59:08 +0800 Subject: [PATCH] Range of valid balance values for account groups --- .../Prepayment/Accounts/AccountAppService.cs | 20 ++-- .../Prepayment/PrepaymentConsts.cs | 16 +-- .../Prepayment/Accounts/Account.cs | 104 +++++++++--------- .../Accounts/AccountWithdrawalManager.cs | 25 +++-- .../Accounts/AmountOverflowException.cs | 8 +- .../ChangeAccountBalanceEventHandler.cs | 2 +- .../InsufficientBalanceToLockException.cs | 14 +++ ...kedBalanceIsGreaterThenBalanceException.cs | 13 --- .../AccountGroupConfiguration.cs | 20 +++- .../PrepaymentPaymentServiceProvider.cs | 4 +- .../TopUpPaymentCompletedEventHandler.cs | 2 +- .../Accounts/AccountDomainTests.cs | 71 +++++++++++- 12 files changed, 191 insertions(+), 108 deletions(-) create mode 100644 modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/InsufficientBalanceToLockException.cs delete mode 100644 modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/LockedBalanceIsGreaterThenBalanceException.cs diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Application/EasyAbp/PaymentService/Prepayment/Accounts/AccountAppService.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Application/EasyAbp/PaymentService/Prepayment/Accounts/AccountAppService.cs index f5f82d8f..d5578c67 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Application/EasyAbp/PaymentService/Prepayment/Accounts/AccountAppService.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Application/EasyAbp/PaymentService/Prepayment/Accounts/AccountAppService.cs @@ -30,7 +30,7 @@ public class AccountAppService : ReadOnlyAppService options, @@ -79,7 +79,7 @@ public override async Task> GetListAsync(GetAccountLi } var allAccountGroupNames = _options.AccountGroups.GetAutoCreationAccountGroupNames(); - + var missingAccountGroupNames = allAccountGroupNames.Except(result.Items.Select(x => x.AccountGroupName)).ToArray(); @@ -112,11 +112,11 @@ public virtual async Task ChangeBalanceAsync(Guid id, ChangeBalanceI account.Balance); await _transactionRepository.InsertAsync(transaction, true); - - account.ChangeBalance(input.ChangedBalance); + + account.ChangeBalance(configuration, input.ChangedBalance); await _repository.UpdateAsync(account, true); - + return await MapToGetOutputDtoAsync(account); } @@ -125,10 +125,12 @@ public virtual async Task ChangeLockedBalanceAsync(Guid id, ChangeLo { var account = await _repository.GetAsync(id); - account.ChangeLockedBalance(input.ChangedLockedBalance); + var configuration = _accountGroupConfigurationProvider.Get(account.AccountGroupName); + + account.ChangeLockedBalance(configuration, input.ChangedLockedBalance); await _repository.UpdateAsync(account, true); - + return await MapToGetOutputDtoAsync(account); } @@ -146,7 +148,7 @@ public virtual async Task TopUpAsync(Guid id, TopUpInput input) { throw new TopUpIsAlreadyInProgressException(); } - + var configuration = _accountGroupConfigurationProvider.Get(account.AccountGroupName); await _distributedEventBus.PublishAsync(new CreatePaymentEto( @@ -182,4 +184,4 @@ await accountWithdrawalManager.StartWithdrawalAsync(account, input.WithdrawalMet input.ExtraProperties); } } -} +} \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain.Shared/EasyAbp/PaymentService/Prepayment/PrepaymentConsts.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain.Shared/EasyAbp/PaymentService/Prepayment/PrepaymentConsts.cs index 1b3b444f..ba2e9ef9 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain.Shared/EasyAbp/PaymentService/Prepayment/PrepaymentConsts.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain.Shared/EasyAbp/PaymentService/Prepayment/PrepaymentConsts.cs @@ -3,29 +3,25 @@ public static class PrepaymentConsts { public const decimal AccountMinBalance = decimal.Zero; - + public const decimal AccountMaxBalance = 999999999999.99999999m; - - public const decimal AccountMinLockedBalance = decimal.Zero; - - public const decimal AccountMaxLockedBalance = AccountMaxBalance; public const string ManualOperationPaymentMethod = "ManualOperation"; public const string ChangeBalanceActionName = "ChangeBalance"; public const string ChangeBalancePaymentMethod = ManualOperationPaymentMethod; - + public const string PaymentActionName = "Payment"; - + public const string RefundActionName = "Refund"; public const string TopUpActionName = "TopUp"; - + public const string WithdrawalActionName = "Withdrawal"; - + public const string TopUpPaymentItemType = "EasyAbpPaymentServicePrepaymentTopUp"; - + public const string PaymentAccountIdPropertyName = "AccountId"; } } \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/Account.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/Account.cs index 24040ae0..aa38acc5 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/Account.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/Account.cs @@ -1,4 +1,5 @@ using System; +using EasyAbp.PaymentService.Prepayment.Options.AccountGroups; using JetBrains.Annotations; using Volo.Abp.Data; using Volo.Abp.Domain.Entities.Auditing; @@ -9,20 +10,20 @@ namespace EasyAbp.PaymentService.Prepayment.Accounts public class Account : FullAuditedAggregateRoot, IMultiTenant { public virtual Guid? TenantId { get; protected set; } - + [NotNull] public virtual string AccountGroupName { get; protected set; } - + public virtual Guid UserId { get; protected set; } - + public virtual decimal Balance { get; protected set; } - + public virtual decimal LockedBalance { get; protected set; } - + public virtual Guid? PendingTopUpPaymentId { get; protected set; } - + public virtual Guid? PendingWithdrawalRecordId { get; protected set; } - + public virtual decimal PendingWithdrawalAmount { get; protected set; } protected Account() @@ -43,44 +44,26 @@ public Account(Guid id, LockedBalance = lockedBalance; } - public void ChangeBalance(decimal changedBalance) + public void ChangeBalance(AccountGroupConfiguration config, decimal changedBalance) { var newBalance = decimal.Add(Balance, changedBalance); - if (!newBalance.IsBetween(PrepaymentConsts.AccountMinBalance, PrepaymentConsts.AccountMaxBalance)) - { - throw new AmountOverflowException(PrepaymentConsts.AccountMinBalance, - PrepaymentConsts.AccountMaxBalance); - } - - if (newBalance < LockedBalance) - { - throw new LockedBalanceIsGreaterThenBalanceException(LockedBalance, newBalance); - } + CheckBalanceValue(config, newBalance, LockedBalance); Balance = newBalance; } - - public void ChangeLockedBalance(decimal changedLockedBalance, bool ignorePendingWithdrawalAmount = false) + + public void ChangeLockedBalance(AccountGroupConfiguration config, decimal changedLockedBalance, + bool ignorePendingWithdrawalAmount = false) { var newLockedBalance = decimal.Add(LockedBalance, changedLockedBalance); - - if (Balance < newLockedBalance) - { - throw new LockedBalanceIsGreaterThenBalanceException(newLockedBalance, Balance); - } - if (!newLockedBalance.IsBetween(PrepaymentConsts.AccountMinLockedBalance, - PrepaymentConsts.AccountMaxLockedBalance)) - { - throw new AmountOverflowException(PrepaymentConsts.AccountMinLockedBalance, - PrepaymentConsts.AccountMaxLockedBalance); - } - + CheckBalanceValue(config, Balance, newLockedBalance); + if (!ignorePendingWithdrawalAmount) { var pendingWithdrawalAmount = PendingWithdrawalAmount; - + if (newLockedBalance < pendingWithdrawalAmount) { throw new LockedBalanceIsLessThenPendingWithdrawalAmountException(newLockedBalance, @@ -91,60 +74,81 @@ public void ChangeLockedBalance(decimal changedLockedBalance, bool ignorePending LockedBalance = newLockedBalance; } + private static void CheckBalanceValue(AccountGroupConfiguration config, decimal balance, decimal lockedBalance) + { + var minBalance = config.AccountMinBalance ?? PrepaymentConsts.AccountMinBalance; + var maxBalance = config.AccountMaxBalance ?? PrepaymentConsts.AccountMaxBalance; + + if (!balance.IsBetween(minBalance, maxBalance)) + { + throw new AmountOverflowException("balance", minBalance, maxBalance); + } + + if (lockedBalance < decimal.Zero) + { + throw new AmountOverflowException("locked balance", decimal.Zero, maxBalance); + } + + if (balance - minBalance < lockedBalance) + { + throw new InsufficientBalanceToLockException(lockedBalance, balance); + } + } + public void SetPendingTopUpPaymentId(Guid? pendingTopUpPaymentId) { PendingTopUpPaymentId = pendingTopUpPaymentId; } - public void StartWithdrawal(Guid pendingWithdrawalRecordId, decimal amount) + public void StartWithdrawal(AccountGroupConfiguration config, Guid pendingWithdrawalRecordId, decimal amount) { if (PendingWithdrawalRecordId.HasValue || PendingWithdrawalAmount != decimal.Zero) { throw new WithdrawalIsAlreadyInProgressException(); } - - ChangeLockedBalance(amount); + + ChangeLockedBalance(config, amount); SetPendingWithdrawalRecordId(pendingWithdrawalRecordId); SetPendingWithdrawalAmount(amount); } - - public void CompleteWithdrawal() + + public void CompleteWithdrawal(AccountGroupConfiguration config) { var balanceToChange = -PendingWithdrawalAmount; - ClearPendingWithdrawal(); - - ChangeBalance(balanceToChange); + ClearPendingWithdrawal(config); + + ChangeBalance(config, balanceToChange); } - - public void CancelWithdrawal() + + public void CancelWithdrawal(AccountGroupConfiguration config) { - ClearPendingWithdrawal(); + ClearPendingWithdrawal(config); } - private void ClearPendingWithdrawal() + private void ClearPendingWithdrawal(AccountGroupConfiguration config) { if (!PendingWithdrawalRecordId.HasValue || PendingWithdrawalAmount == decimal.Zero) { throw new WithdrawalInProgressNotFoundException(); } - - ChangeLockedBalance(-PendingWithdrawalAmount, true); + + ChangeLockedBalance(config, -1 * PendingWithdrawalAmount, true); SetPendingWithdrawalRecordId(null); SetPendingWithdrawalAmount(0m); } - + private void SetPendingWithdrawalRecordId(Guid? pendingWithdrawalRecordId) { PendingWithdrawalRecordId = pendingWithdrawalRecordId; } - + private void SetPendingWithdrawalAmount(decimal pendingWithdrawalAmount) { PendingWithdrawalAmount = pendingWithdrawalAmount; } } -} +} \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AccountWithdrawalManager.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AccountWithdrawalManager.cs index cdf2b67b..2ea99e2e 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AccountWithdrawalManager.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AccountWithdrawalManager.cs @@ -34,6 +34,8 @@ public AccountWithdrawalManager( public virtual async Task StartWithdrawalAsync(Account account, string withdrawalMethod, decimal amount, ExtraPropertyDictionary inputExtraProperties) { + var accountGroupConfiguration = _accountGroupConfigurationProvider.Get(account.AccountGroupName); + var withdrawalProvider = GetWithdrawalProvider(withdrawalMethod); await CheckDailyWithdrawalAmountAsync(account, withdrawalMethod, amount); @@ -45,7 +47,7 @@ public virtual async Task StartWithdrawalAsync(Account account, string withdrawa withdrawalMethod, amount); - account.StartWithdrawal(withdrawalRecord.Id, withdrawalRecord.Amount); + account.StartWithdrawal(accountGroupConfiguration, withdrawalRecord.Id, withdrawalRecord.Amount); await _withdrawalRecordRepository.InsertAsync(withdrawalRecord, true); @@ -84,8 +86,8 @@ private IAccountWithdrawalProvider GetWithdrawalProvider(string withdrawalMethod _withdrawalMethodConfigurationProvider.Get(withdrawalMethodName)?.AccountWithdrawalProviderType ?? throw new UnknownWithdrawalMethodException(withdrawalMethodName); - return ServiceProvider.GetService(providerType) as IAccountWithdrawalProvider ?? - throw new UnknownWithdrawalMethodException(withdrawalMethodName); + return LazyServiceProvider.LazyGetService(providerType) as IAccountWithdrawalProvider ?? + throw new UnknownWithdrawalMethodException(withdrawalMethodName); } public virtual async Task CompleteWithdrawalAsync(Account account) @@ -96,21 +98,21 @@ public virtual async Task CompleteWithdrawalAsync(Account account) { throw new WithdrawalInProgressNotFoundException(); } - + var withdrawalRecord = await _withdrawalRecordRepository.GetAsync(withdrawalRecordId.Value); var accountGroupConfiguration = _accountGroupConfigurationProvider.Get(account.AccountGroupName); - + var withdrawalProvider = GetWithdrawalProvider(withdrawalRecord.WithdrawalMethod); var originalBalance = account.Balance; - account.CompleteWithdrawal(); - + account.CompleteWithdrawal(accountGroupConfiguration); + withdrawalRecord.Complete(Clock.Now); await _accountRepository.UpdateAsync(account, true); - + await _withdrawalRecordRepository.UpdateAsync(withdrawalRecord, true); var accountChangedBalance = -1 * withdrawalRecord.Amount; @@ -120,14 +122,15 @@ public virtual async Task CompleteWithdrawalAsync(Account account) null, accountGroupConfiguration.Currency, accountChangedBalance, originalBalance); await _transactionRepository.InsertAsync(transaction, true); - - await withdrawalProvider.OnCompleteWithdrawalAsync(account); + await withdrawalProvider.OnCompleteWithdrawalAsync(account); } public virtual async Task CancelWithdrawalAsync(Account account, string errorCode = null, string errorMessage = null) { + var accountGroupConfiguration = _accountGroupConfigurationProvider.Get(account.AccountGroupName); + var withdrawalRecordId = account.PendingWithdrawalRecordId; if (!withdrawalRecordId.HasValue) @@ -139,7 +142,7 @@ public virtual async Task CancelWithdrawalAsync(Account account, string errorCod var withdrawalProvider = GetWithdrawalProvider(withdrawalRecord.WithdrawalMethod); - account.CancelWithdrawal(); + account.CancelWithdrawal(accountGroupConfiguration); withdrawalRecord.Cancel(Clock.Now, errorCode, errorMessage); diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AmountOverflowException.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AmountOverflowException.cs index 6c60eacb..569f23ef 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AmountOverflowException.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/AmountOverflowException.cs @@ -5,7 +5,13 @@ namespace EasyAbp.PaymentService.Prepayment.Accounts { public class AmountOverflowException : BusinessException { - public AmountOverflowException(decimal min, decimal max) : base(message: $"The amount should be greater than {min} and less then {max}") + public AmountOverflowException(decimal min, decimal max) : base( + message: $"The amount should be greater than {min} and less then {max}") + { + } + + public AmountOverflowException(string field, decimal min, decimal max) : base( + message: $"The {field} should be greater than {min} and less then {max}") { } } diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/ChangeAccountBalanceEventHandler.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/ChangeAccountBalanceEventHandler.cs index 50c346d2..0ce58679 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/ChangeAccountBalanceEventHandler.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/ChangeAccountBalanceEventHandler.cs @@ -53,7 +53,7 @@ public async Task HandleEventAsync(ChangeAccountBalanceEto eventData) await _transactionRepository.InsertAsync(transaction, true); - account.ChangeBalance(changedBalance); + account.ChangeBalance(configuration, changedBalance); await _accountRepository.UpdateAsync(account, true); } diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/InsufficientBalanceToLockException.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/InsufficientBalanceToLockException.cs new file mode 100644 index 00000000..846ff893 --- /dev/null +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/InsufficientBalanceToLockException.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.PaymentService.Prepayment.Accounts +{ + public class InsufficientBalanceToLockException : BusinessException + { + public InsufficientBalanceToLockException(decimal lockedBalance, decimal balance) : base( + message: + $"Failed to lock {lockedBalance} balance. The current balance ({balance}) is insufficient to lock.") + { + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/LockedBalanceIsGreaterThenBalanceException.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/LockedBalanceIsGreaterThenBalanceException.cs deleted file mode 100644 index b35aa055..00000000 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Accounts/LockedBalanceIsGreaterThenBalanceException.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Volo.Abp; - -namespace EasyAbp.PaymentService.Prepayment.Accounts -{ - public class LockedBalanceIsGreaterThenBalanceException : BusinessException - { - public LockedBalanceIsGreaterThenBalanceException(decimal lockedBalance, decimal balance) - : base(message: $"The locked balance ({lockedBalance}) should be less than the current balance ({balance})") - { - } - } -} \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Options/AccountGroups/AccountGroupConfiguration.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Options/AccountGroups/AccountGroupConfiguration.cs index a259dca9..4b12431c 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Options/AccountGroups/AccountGroupConfiguration.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/Options/AccountGroups/AccountGroupConfiguration.cs @@ -9,30 +9,40 @@ public class AccountGroupConfiguration /// [NotNull] public string Currency { get; set; } = "USD"; - + /// /// Admin should manually create users' account. /// public bool DisableAccountAutoCreation { get; set; } - + /// /// Only admin can change accounts' balance. /// public bool DisableUserTopUp { get; set; } - + /// /// The account cannot be a payment method. /// public bool DisableUserPayWithAccount { get; set; } - + /// /// The balance cannot be withdrawn. /// public bool DisableUserWithdrawal { get; set; } - + /// /// Can be the payment method to top up other prepayment accounts. /// public bool AllowedUsingToTopUpOtherAccounts { get; set; } + + /// + /// Minimum allowed account balance. It falls back to if null. + /// + public decimal? AccountMinBalance { get; set; } + + /// + /// Maximum allowed account balance. It falls back to if null. + /// + public decimal? AccountMaxBalance { get; set; } } } \ No newline at end of file diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/PrepaymentPaymentServiceProvider.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/PrepaymentPaymentServiceProvider.cs index eb87c403..f0c72f77 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/PrepaymentPaymentServiceProvider.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/PrepaymentPaymentServiceProvider.cs @@ -98,7 +98,7 @@ public override async Task OnPaymentStartedAsync(Payment payment, ExtraPropertyD await _transactionRepository.InsertAsync(transaction, true); - account.ChangeBalance(accountChangedBalance); + account.ChangeBalance(accountGroupConfiguration, accountChangedBalance); await _accountRepository.UpdateAsync(account, true); @@ -133,7 +133,7 @@ public override async Task OnRefundStartedAsync(Payment payment, Refund refund) await _transactionRepository.InsertAsync(transaction, true); - account.ChangeBalance(accountChangedBalance); + account.ChangeBalance(configuration, accountChangedBalance); await _accountRepository.UpdateAsync(account, true); diff --git a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/TopUpPaymentCompletedEventHandler.cs b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/TopUpPaymentCompletedEventHandler.cs index 14483358..1b1b743c 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/TopUpPaymentCompletedEventHandler.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/src/EasyAbp.PaymentService.Prepayment.Domain/EasyAbp/PaymentService/Prepayment/PaymentService/TopUpPaymentCompletedEventHandler.cs @@ -63,7 +63,7 @@ public virtual async Task HandleEventAsync(PaymentCompletedEto eventData) throw new CurrencyNotSupportedException(payment.Currency); } - account.ChangeBalance(changedBalance); + account.ChangeBalance(configuration, changedBalance); account.SetPendingTopUpPaymentId(null); await _accountRepository.UpdateAsync(account, true); diff --git a/modules/EasyAbp.PaymentService.Prepayment/test/EasyAbp.PaymentService.Prepayment.Domain.Tests/Accounts/AccountDomainTests.cs b/modules/EasyAbp.PaymentService.Prepayment/test/EasyAbp.PaymentService.Prepayment.Domain.Tests/Accounts/AccountDomainTests.cs index 9a9bf9b1..ebcce003 100644 --- a/modules/EasyAbp.PaymentService.Prepayment/test/EasyAbp.PaymentService.Prepayment.Domain.Tests/Accounts/AccountDomainTests.cs +++ b/modules/EasyAbp.PaymentService.Prepayment/test/EasyAbp.PaymentService.Prepayment.Domain.Tests/Accounts/AccountDomainTests.cs @@ -1,4 +1,6 @@ +using System; using System.Threading.Tasks; +using EasyAbp.PaymentService.Prepayment.Options.AccountGroups; using Shouldly; using Xunit; @@ -11,13 +13,72 @@ public AccountDomainTests() } [Fact] - public async Task Test1() + public async Task Change_Balance_Test() { - // Arrange + var config = new AccountGroupConfiguration(); - // Assert + var account = new Account(Guid.NewGuid(), null, "default", Guid.NewGuid(), 0, 0); - // Assert + account.Balance.ShouldBe(0m); + account.LockedBalance.ShouldBe(0m); + + account.ChangeBalance(config, 100m); + + account.Balance.ShouldBe(100m); + account.LockedBalance.ShouldBe(0m); + + config.AccountMinBalance = -100m; + config.AccountMaxBalance = 150m; + + account.ChangeBalance(config, 50m); + + account.Balance.ShouldBe(150m); + account.LockedBalance.ShouldBe(0m); + + Should.Throw(() => account.ChangeBalance(config, 1m)); + + account.ChangeBalance(config, -250m); + + account.Balance.ShouldBe(-100m); + account.LockedBalance.ShouldBe(0m); + + Should.Throw(() => account.ChangeBalance(config, -1m)); + } + + [Fact] + public async Task Change_LockedBalance_Test() + { + var config = new AccountGroupConfiguration(); + + var account = new Account(Guid.NewGuid(), null, "default", Guid.NewGuid(), 100m, 0); + + account.Balance.ShouldBe(100m); + account.LockedBalance.ShouldBe(0m); + + account.ChangeLockedBalance(config, 100m); + + account.Balance.ShouldBe(100m); + account.LockedBalance.ShouldBe(100m); + + Should.Throw(() => account.ChangeLockedBalance(config, 1m)); + + account.ChangeLockedBalance(config, -100m); + + account.Balance.ShouldBe(100m); + account.LockedBalance.ShouldBe(0m); + + Should.Throw(() => account.ChangeLockedBalance(config, -1m)); + + config.AccountMinBalance = -100m; + config.AccountMaxBalance = 150m; + + account.ChangeBalance(config, -150m); + account.ChangeLockedBalance(config, 50m); + + account.Balance.ShouldBe(-50m); + account.LockedBalance.ShouldBe(50m); + + Should.Throw(() => account.ChangeLockedBalance(config, 1m)); } } -} +} \ No newline at end of file