예제 #1
0
        private IEnumerable <CreditAccountStateViewModel> GetClientAccountsStates(ClientViewModel client)
        {
            var clientAccountsQuery = new ClientAccountsQuery()
            {
                ClientId = client.Id
            };
            var clientAccounts = _clientService.GetClientAccounts(clientAccountsQuery).Value;

            if (clientAccounts == null)
            {
                return(Enumerable.Empty <CreditAccountStateViewModel>());
            }
            var accountsStates = clientAccounts.Select(a =>
            {
                var accountStateQuery = new ActualCreditAccountStateQuery()
                {
                    Id = a.Id
                };
                return(_creditAccountService.GetActualAccountState(accountStateQuery)?.Value);
            });

            return(accountsStates);
        }
예제 #2
0
        public async Task <CreditAccountStateDto> HandleAsync(ActualCreditAccountStateQuery query)
        {
            CreditAccountModel creditAccount = null;

            if (query.Id.HasValue)
            {
                creditAccount = await ModelsDao.FindAsync(query.Id.Value);
            }
            if (!string.IsNullOrEmpty(query.AgreementNumber))
            {
                creditAccount = await ModelsDao.FirstOrDefaultAsync(u => u.CreditAgreementNumber == query.AgreementNumber);
            }
            if (creditAccount == null)
            {
                return(null);
            }
            var creditAccountStatesQuery = new CreditAccountStatesQuery {
                CreditAccountId = creditAccount.Id
            };
            var latestCreditAccountState = await HandleAsync(creditAccountStatesQuery);

            return(latestCreditAccountState.OrderBy(s => s.Month).LastOrDefault());
        }
예제 #3
0
        private CreditAccountStateDto UpdateFinesAndGetAccountState(int creditAccountId, DateTime specifiedDate)
        {
            var query = new ModelQuery()
            {
                Id = creditAccountId
            };
            var account = _creditAccountQueryRepository.Handle(query);
            var latestCreditAccountStateQuery = new ActualCreditAccountStateQuery()
            {
                Id = account.Id
            };
            var latestCreditAccountState   = _creditAccountQueryRepository.Handle(latestCreditAccountStateQuery);
            var creditAccountPaymentsQuery = new CreditPaymentsQuery()
            {
                CreditAccountId = account.Id
            };
            var latestCreditAccountStateDate = account.AgreementDate.AddMonths(latestCreditAccountState.Month);
            var accountPayments         = _creditAccountQueryRepository.Handle(creditAccountPaymentsQuery);
            var paymentsForLatestPeriod = accountPayments.Where(p => latestCreditAccountStateDate < p.Timestamp);
            var accountCurrency         = account.Currency;
            // S
            var sumPaidForLatestPeriod = paymentsForLatestPeriod.Sum(p => p.PaymentSum.Value);

            if (latestCreditAccountState.RemainDebt.Value <= sumPaidForLatestPeriod)
            {
                return(CloseAccount(account, latestCreditAccountState));
            }

            // Z
            var totalDebtRemaining = latestCreditAccountState.RemainDebt.Value;
            // A
            var debtForMonth = GetDebtForMonth(latestCreditAccountState);

            if (latestCreditAccountState.MainDebtRemain.Value > sumPaidForLatestPeriod)
            {
                var finesForOverdue = latestCreditAccountState.FinesForOverdue;
                finesForOverdue.Value += account.CreditType.FineInterest *
                                         latestCreditAccountState.MainDebtRemain.Value;
                var updateFinesCommand = new UpdateModelCommand <PriceDto>()
                {
                    ModelDto = finesForOverdue
                };
                _priceCommandRepository.Execute(updateFinesCommand);

                var totalDebt = latestCreditAccountState.RemainDebt;
                totalDebt.Value += finesForOverdue.Value;
                var updateTotalDebtCommand = new UpdateModelCommand <PriceDto>()
                {
                    ModelDto = totalDebt
                };
                _priceCommandRepository.Execute(updateTotalDebtCommand);
            }
            if (ShouldAccountUpdate(account, specifiedDate))
            {
                var previousFinesForOverdue = latestCreditAccountState.FinesForOverdue;
                // B
                var interestForMonth     = (decimal)account.CreditType.InterestRate / 12 * totalDebtRemaining;
                var totalInterestNotPaid = latestCreditAccountState.TotalInterestSumNotPaid.Value;

                var newTotalDebtRemaining   = totalDebtRemaining;
                var newTotalInterestNotPaid = totalInterestNotPaid;
                var mainDebtRemain          = latestCreditAccountState.MainDebtRemain.Value;
                if (sumPaidForLatestPeriod < debtForMonth + mainDebtRemain)
                {
                    newTotalDebtRemaining   -= sumPaidForLatestPeriod;
                    newTotalDebtRemaining   += debtForMonth;
                    newTotalInterestNotPaid += interestForMonth;
                    mainDebtRemain           = debtForMonth + mainDebtRemain - sumPaidForLatestPeriod;
                }
                else if (sumPaidForLatestPeriod <
                         debtForMonth + mainDebtRemain + totalInterestNotPaid + interestForMonth)
                {
                    newTotalDebtRemaining   -= debtForMonth + mainDebtRemain;
                    newTotalInterestNotPaid += interestForMonth -
                                               (sumPaidForLatestPeriod - debtForMonth - mainDebtRemain);
                    mainDebtRemain = 0m;
                }
                else
                {
                    newTotalInterestNotPaid = 0m;
                    newTotalDebtRemaining  -= sumPaidForLatestPeriod - interestForMonth - totalInterestNotPaid;
                    mainDebtRemain          = 0m;
                }

                var newCreditAccountState = new CreditAccountStateDto()
                {
                    CreditAccount   = account,
                    Month           = latestCreditAccountState.Month + 1,
                    FinesForOverdue = new PriceDto()
                    {
                        Currency = accountCurrency,
                        Value    = previousFinesForOverdue.Value
                    },
                    InterestCounted = new PriceDto()
                    {
                        Currency = accountCurrency,
                        Value    = interestForMonth
                    },
                    RemainDebt = new PriceDto()
                    {
                        Currency = accountCurrency,
                        Value    = Math.Max(newTotalDebtRemaining + previousFinesForOverdue.Value, 0m)
                    },
                    TotalInterestSumNotPaid = new PriceDto()
                    {
                        Currency = accountCurrency,
                        Value    = newTotalInterestNotPaid
                    },
                    MainDebtRemain = new PriceDto()
                    {
                        Currency = accountCurrency,
                        Value    = mainDebtRemain
                    }
                };
                return(newCreditAccountState);
            }
            return(null);
        }
예제 #4
0
 public async Task <QueryResult <CreditAccountStateViewModel> > GetActualAccountStateAsync(
     ActualCreditAccountStateQuery query)
 {
     return((await RunQueryAsync <ActualCreditAccountStateQuery, CreditAccountStateDto>(_queryRepository, query))
            .MapTo <CreditAccountStateViewModel>());
 }
예제 #5
0
 public QueryResult <CreditAccountStateViewModel> GetActualAccountState(ActualCreditAccountStateQuery query)
 {
     return(RunQuery <ActualCreditAccountStateQuery, CreditAccountStateDto>(_queryRepository, query)
            .MapTo <CreditAccountStateViewModel>());
 }
예제 #6
0
 public async Task <QueryResult <CreditAccountStateDto> > GetActualAccountStateDtoAsync(
     ActualCreditAccountStateQuery query)
 {
     return(await RunQueryAsync <ActualCreditAccountStateQuery, CreditAccountStateDto>(_queryRepository, query));
 }
예제 #7
0
 public QueryResult <CreditAccountStateDto> GetActualAccountStateDto(ActualCreditAccountStateQuery query)
 {
     return(RunQuery <ActualCreditAccountStateQuery, CreditAccountStateDto>(_queryRepository, query));
 }