public async Task <ActionResult> ApproveWithdrawalReprocessing(ReprocessingApprovalsModel model)
        {
            if (!ModelState.IsValid)
            {
                return(CloseModalError("Invalid input."));
            }

            var userId = User.Identity.GetUserId();
            var result = await ReprocessingWriter.ApproveWithdrawalReprocessing(userId, model);

            if (!ModelState.IsWriterResultValid(result))
            {
                return(CloseModalError(result.Message));
            }

            return(CloseModalSuccess("Approval confirmed"));
        }
        public async Task <IWriterResult> ApproveWithdrawalReprocessing(string adminUserId, ReprocessingApprovalsModel model)
        {
            ReprocessingApprovalDataModel dataModel = null;
            ApprovalQueue approval = null;

            using (var context = DataContextFactory.CreateContext())
            {
                approval = await context.ApprovalQueue.FirstOrDefaultNoLockAsync(a => a.Id == model.Id);

                if (approval == null)
                {
                    return(new WriterResult(false, "Unable to find approval to update."));
                }

                if (approval.Status != ApprovalQueueStatus.Pending)
                {
                    if (approval.Status == ApprovalQueueStatus.Approved)
                    {
                        return(new WriterResult(false, "Already approved"));
                    }

                    return(new WriterResult(false, $"Unable to update approval from {approval.Status}."));
                }

                if (adminUserId.Equals(approval.RequestUserId))
                {
                    return(new WriterResult(false, "Cannot approve your own request."));
                }

                try
                {
                    dataModel = JsonConvert.DeserializeObject <ReprocessingApprovalDataModel>(approval.Data);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return(new WriterResult(false, "Unable to complete approval update."));
                }

                approval.Approved      = DateTime.UtcNow;
                approval.ApproveUserId = adminUserId;
                approval.Status        = ApprovalQueueStatus.Approved;
                await context.SaveChangesAsync();
            }

            // ToDo: move to method used to complete approval and commit change to database
            using (var context = ExchangeDataContextFactory.CreateContext())
            {
                int withdrawalId;
                if (!int.TryParse(dataModel.WithdrawalId, out withdrawalId))
                {
                    return(new WriterResult(false, $"Invalid Withdrawal Id: {dataModel.WithdrawalId}"));
                }

                if (withdrawalId == 0 || withdrawalId < 0)
                {
                    return(new WriterResult(false, "Invalid Withdrawal Id supplied."));
                }

                var withdrawal = await context.Withdraw
                                 .Where(w => w.Id == withdrawalId)
                                 .FirstOrDefaultNoLockAsync().ConfigureAwait(false);

                if (withdrawal == null)
                {
                    return(new WriterResult(false, $"Withdrawal {dataModel.WithdrawalId} not found."));
                }

                withdrawal.Txid   = dataModel.TxId;
                withdrawal.Status = WithdrawStatus.Complete;
                withdrawal.RetryCount++;
                await context.SaveChangesAsync().ConfigureAwait(false);

                await context.AuditUserBalance(withdrawal.UserId, withdrawal.CurrencyId);

                await context.SaveChangesAsync().ConfigureAwait(false);
            }

            return(new WriterResult(true, "Successfully updated withdrawal."));
        }