private async Task <EWallet> GenerateEWalletByDeduct(DeductResource deductResource, string userId)
        {
            var eWallet = await _eWalletRepository.FindByUserIdAsync(userId);

            if (eWallet == null)
            {
                throw new Exception(string.Format(Constants.DeductUserNotExistsErrMsg, userId));
            }

            if (ExistSuccessDeductTransactionId(deductResource.TransactionId, eWallet.DeductHistories))
            {
                var errorMessage = string.Format(Constants.TransactionIdExistsErrMsg, deductResource.TransactionId);
                await SaveDeductHistory(deductResource, eWallet, Status.Fail, errorMessage);

                throw new Exception(errorMessage);
            }

            if (!(eWallet.Balance >= deductResource.Amount))
            {
                var errorMessage = string.Format(Constants.BalanceLessThanDeductionErrMsg,
                                                 deductResource.TransactionId, eWallet.Balance, deductResource.Amount);
                await SaveDeductHistory(deductResource, eWallet, Status.Fail, errorMessage);

                throw new Exception(errorMessage);
            }

            eWallet.Balance -= deductResource.Amount;
            await SaveDeductHistory(deductResource, eWallet, Status.Success);

            return(eWallet);
        }
        private async Task <EWallet> SaveDeductHistory(DeductResource deductResource, EWallet eWallet, Status status,
                                                       string errorMessage = "")
        {
            var deductHistory = _mapper.Map <DeductResource, DeductHistory>(deductResource);

            deductHistory.Status  = status;
            deductHistory.Comment = errorMessage;
            eWallet.DeductHistories.Add(deductHistory);
            eWallet.LastUpdateDate = deductResource.ActionDate;
            _eWalletRepository.AddOrUpdateEWallet(eWallet, false);
            await _unitOfWork.CompleteAsync();

            return(eWallet);
        }
        public async Task <SaveTransactionResponse> SaveDeductAsync(DeductResource deductResource, string userId)
        {
            try
            {
                var eWallet = await GenerateEWalletByDeduct(deductResource, userId);

                await _unitOfWork.CompleteAsync();

                return(new SaveTransactionResponse(eWallet));
            }
            catch (Exception ex)
            {
                var errorMessage = string.Format(Constants.DeductWrapperErrMsg, ex.Message);
                _logger.LogError(errorMessage);
                return(new SaveTransactionResponse(
                           errorMessage));
            }
        }
        public async Task <IActionResult> SaveDeductAsync([FromBody] DeductResource resource)
        {
            var userId = getUserIdFromAuthHeader();

            _logger.LogInformation("saveDeduct Request:" + JsonConvert.SerializeObject(resource));
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState.GetErrorMessages()));
            }

            var result = await _eWalletService.SaveDeductAsync(resource, userId);

            if (!result.BaseResponse.Success)
            {
                return(BadRequest(result.BaseResponse.Message));
            }

            var eWalletResource = _mapper.Map <EWallet, TopUpDeductionResource>(result.EWallet);

            eWalletResource.TransactionId = resource.TransactionId;
            _logger.LogInformation("saveDeduct Response:" + JsonConvert.SerializeObject(eWalletResource));
            return(Ok(eWalletResource));
        }