示例#1
0
        public async Task <Result> RefundMoney(int accountId, ChargedMoneyData paymentData, UserInfo user)
        {
            return(await GetAccount(accountId)
                   .Ensure(IsReasonProvided, "Payment reason cannot be empty")
                   .Ensure(a => AreCurrenciesMatch(a, paymentData), "Account and payment currency mismatch")
                   .BindWithLock(_locker, a => Result.Success(a)
                                 .BindWithTransaction(_context, account => Result.Success(account)
                                                      .Map(Refund)
                                                      .Map(WriteAuditLog))));

            bool IsReasonProvided(AgencyAccount account) => !string.IsNullOrEmpty(paymentData.Reason);


            async Task <AgencyAccount> Refund(AgencyAccount account)
            {
                account.Balance += paymentData.Amount;
                _context.Update(account);
                await _context.SaveChangesAsync();

                return(account);
            }

            Task <AgencyAccount> WriteAuditLog(AgencyAccount account) =>
            WriteAuditLogWithReferenceCode(account, paymentData, AccountEventType.Refund, user);
        }
        public async Task <Result> ChargeMoney(int accountId, ChargedMoneyData paymentData, ApiCaller apiCaller)
        {
            return(await GetAccount(accountId)
                   .Ensure(IsReasonProvided, "Payment reason cannot be empty")
                   .Ensure(a => AreCurrenciesMatch(a, paymentData), "Account and payment currency mismatch")
                   .BindWithLock(_locker, a => Result.Success(a)
                                 .Ensure(IsBalanceSufficient, "Could not charge money, insufficient balance")
                                 .BindWithTransaction(_context, account => Result.Success(account)
                                                      .Map(ChargeMoney)
                                                      .Map(WriteAuditLog))));

            bool IsReasonProvided(AgencyAccount account) => !string.IsNullOrEmpty(paymentData.Reason);

            bool IsBalanceSufficient(AgencyAccount account) => this.IsBalanceSufficient(account, paymentData.Amount);


            async Task <AgencyAccount> ChargeMoney(AgencyAccount account)
            {
                account.Balance -= paymentData.Amount;
                _context.Update(account);
                await _context.SaveChangesAsync();

                _context.Detach(account);
                return(account);
            }

            async Task <AgencyAccount> WriteAuditLog(AgencyAccount account)
            {
                var eventData = new AccountBalanceLogEventData(paymentData.Reason, account.Balance);
                await _auditService.Write(AccountEventType.Charge,
                                          account.Id,
                                          paymentData.Amount,
                                          apiCaller,
                                          eventData,
                                          paymentData.ReferenceCode);

                return(account);
            }
        }
示例#3
0
        private async Task <AgencyAccount> WriteAuditLogWithReferenceCode(AgencyAccount account, ChargedMoneyData paymentData, AccountEventType eventType,
                                                                          UserInfo user)
        {
            var eventData = new AccountBalanceLogEventData(paymentData.Reason, account.Balance);
            await _auditService.Write(eventType,
                                      account.Id,
                                      paymentData.Amount,
                                      user,
                                      eventData,
                                      paymentData.ReferenceCode);

            return(account);
        }
示例#4
0
 private bool AreCurrenciesMatch(AgencyAccount account, ChargedMoneyData paymentData) => account.Currency == paymentData.Currency;