예제 #1
0
        public async Task <IActionResult> Put([FromBody] UpdateTransaction command)
        {
            //TODO: implement after DB
            await DispatchAsync(command);

            return(Ok());
        }
예제 #2
0
파일: Calculator.cs 프로젝트: 2garryn/wpay
        internal Transaction UpdateToTransaction(Transaction tran, UpdateTransaction update)
        {
            var meta   = tran.Metadata.Merge(update.Metadata);
            var descr  = tran.Description.Merge(update.Description);
            var amount = UpdateToTransactionAmount(update.Status, tran.Amount);

            return(new Transaction(tran.AccountId, tran.Id, tran.Label, amount, meta, descr, tran.CreatedOn, DateTime.UtcNow));
        }
예제 #3
0
        public async Task Examples_RunSuccessfully()
        {
            // Arrange
            GlobalConfiguration.Instance = GlobalConfiguration.MergeConfigurations(GlobalConfiguration.Instance, new Configuration
            {
                DateTimeFormat = "yyyy-MM-dd"
            });
            var budgetMonthId = "2019-08-01";
            var budgetId      = new Guid("14235236-8085-4cf6-9fa6-92c34ed44b0c");
            var categoryId    = new Guid("3b89df53-1869-4d2f-a636-d09eadc3f0ca");

            // Act
            // Assert
            try {
                using (var stub = new YnabApiStub()) {
                    var api = new API(_token, stub.BasePath);
                    var ble = new BudgetListExample(api);
                    ble.Execute();
                    await ble.ExecuteAsync();

                    var bme = new BudgetMonthExample(api);
                    bme.Execute(budgetId, budgetMonthId);
                    await bme.ExecuteAsync(budgetId, budgetMonthId);

                    var btc = new BulkTransactionCreate(api);
                    // btc.Execute();
                    // await btc.ExecuteAsync();

                    var cbe = new CategoryBalanceExample(api);
                    cbe.Execute(budgetId, categoryId);
                    await cbe.ExecuteAsync(budgetId, categoryId);

                    var cmt = new CreateMultipleTransactions(api);
                    // cmt.Execute();
                    // await cmt.ExecuteAsync();

                    var ct = new CreateTransaction(api);
                    ct.Execute();
                    await ct.ExecuteAsync();

                    var dre = new DeltaRequestExample(api);
                    dre.Execute();
                    await dre.ExecuteAsync();

                    var ucb = new UpdateCategoryBudgeted(api);
                    // ucb.Execute();
                    // await ucb.ExecuteAsync();

                    var ut = new UpdateTransaction(api);
                    // ut.Execute();
                    // await ut.ExecuteAsync();
                }
            } catch (Exception ex) {
                Assert.True(false, ex.Message);
            }
            Assert.True(true, "Finished running examples");
        }
예제 #4
0
        public DataTable Get(string account_id, string adsno, string state)
        {
            DataTable         response = new DataTable("response");
            UpdateTransaction updt     = new UpdateTransaction();
            string            trans    = updt.RunNpgsqlTransaction("update ads_order_state set order_state = " + state + " where adsno = " + adsno + " and account_id =" + account_id);

            response.Columns.Add("response");
            response.Rows.Add(trans);
            return(response);
        }
예제 #5
0
        private static string BuildUpdateTransaction()
        {
            var transaction = new UpdateTransaction()
            {
                Id = 1,
                TransactionType = TransactionTypes.ByCard,
            };

            return(JsonSerializer.Serialize(transaction));
        }
예제 #6
0
        public void TestRecoverTransactionData()
        {
            // create a store
            var sid = CreateStore();

            // initialise and start the store worker
            var storeWorker = new StoreWorker(Configuration.StoreLocation, sid);

            storeWorker.Start();

            // execute transactions
            const string data = @"<http://www.networkedplanet.com/people/gra> <http://www.networkedplanet.com/types/worksfor> <http://www.networkedplanet.com/companies/np>";

            var jobId = storeWorker.ProcessTransaction("", "", data, "nt");

            JobExecutionStatus jobStatus = storeWorker.GetJobStatus(jobId.ToString());

            while (jobStatus.JobStatus != JobStatus.CompletedOk)
            {
                Thread.Sleep(1000);
                jobStatus = storeWorker.GetJobStatus(jobId.ToString());
            }

            var transactionLog  = storeWorker.TransactionLog;
            var transactionList = transactionLog.GetTransactionList();

            var i = 0;

            while (transactionList.MoveNext())
            {
                i++;
            }

            Assert.AreEqual(1, i);

            // now get txn data
            var txnList = storeWorker.TransactionLog.GetTransactionList();

            txnList.MoveNext();
            var tinfo = txnList.Current;

            Assert.IsNotNull(tinfo);
            Assert.AreEqual(TransactionType.UpdateTransaction, tinfo.TransactionType);
            Assert.AreEqual(TransactionStatus.CompletedOk, tinfo.TransactionStatus);
            Assert.IsTrue(tinfo.TransactionStartTime < DateTime.UtcNow);

            var job = new UpdateTransaction(Guid.NewGuid(), storeWorker);

            using (var tdStream = storeWorker.TransactionLog.GetTransactionData(tinfo.DataStartPosition))
            {
                job.ReadTransactionDataFromStream(tdStream);
            }
            Assert.IsNotNull(job);
            Assert.AreEqual(data, job.InsertData);
        }
예제 #7
0
 public UpdateTransactionCommand From(UpdateTransaction update)
 {
     return(new UpdateTransactionCommand
     {
         Id = update.Id.Value.Value,
         Status = update.Status == UpdateStatus.Complete ? StatusCompleted : StatusCancelled,
         Signature = update.Signature,
         Description = update.Description.Value,
         Metadata = update.Metadata.Value,
     });
 }
        public async Task <Transaction> HandleAsync(UpdateTransaction request, CancellationToken cancellationToken)
        {
            var item = await _dataStorage.GetAsync(request.Key, cancellationToken);

            item.Update(request);

            await _dataStorage.UpdateAsync(item, cancellationToken);

            await PublishNotifications(item);

            return(item);
        }
예제 #9
0
 private async Task UpdateUserTransaction(TransactionContext transactionContext,
                                          UpdateTransaction updateTransaction)
 {
     transactionContext.TransactionType = updateTransaction.TransactionType;
     if (updateTransaction.Products != null)
     {
         transactionContext.Products =
             updateTransaction.Products.Select(item => item.ToProductContext()).ToList();
     }
     if (updateTransaction.Date != new DateTime())
     {
         transactionContext.Date = updateTransaction.Date;
     }
     await _context.SaveChangesAsync();
 }
예제 #10
0
        public async Task <IActionResult> UpdateTransaction([FromBody] UpdateTransaction updateTransaction)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest("Invalid request"));
            }
            var user = HttpContext.Items["User"] as User;

            await GetResponseRabbitTask <UpdateTransactionRequest, BaseResponseMassTransit>(new UpdateTransactionRequest()
            {
                User        = user,
                Transaction = updateTransaction
            });

            return(Ok(ApiResult <int> .Success200(updateTransaction.Id)));
        }
        public async Task UpdateAsync(UpdateTransaction model)
        {
            if (model.FromAccountId.HasValue &&
                !(await _accountsRepository.ExistsAsync(model.FromAccountId.Value, model.UserId)))
            {
                throw new ArgumentException("FromAccount doesn't belong to user with specified userId.");
            }

            if (model.ToAccountId.HasValue &&
                !(await _accountsRepository.ExistsAsync(model.ToAccountId.Value, model.UserId)))
            {
                throw new ArgumentException("ToAccount doesn't belong to user with specified userId.");
            }

            var transaction = _mapper.Map <Transaction>(model);

            await _transactionsRepository.UpdateAsync(transaction);
        }
예제 #12
0
 private async Task <Exception> UpdateTransaction(TransactionContext transactionContext,
                                                  UpdateTransaction updateTransaction)
 {
     if (transactionContext.IsShopCreate)
     {
         if (updateTransaction.Products != null || updateTransaction.Date != new DateTime())
         {
             return(new BadRequestException("You can't change current shop's transaction!"));
         }
         transactionContext.TransactionType = updateTransaction.TransactionType;
         await _context.SaveChangesAsync();
     }
     else
     {
         await UpdateUserTransaction(transactionContext, updateTransaction);
     }
     return(null);
 }
예제 #13
0
        public async Task <Transaction> UpdateAsync(UpdateTransaction update, Action <UpdateTransactionOptions>?setOpts = null)
        {
            var tran = await _repo.GetAsync(update.Id, true);

            if (tran.Amount is AmountIncomeCompleted || tran.Amount is AmountOutcomeCompleted)
            {
                var options = new UpdateTransactionOptions();
                setOpts?.Invoke(options);
                if (options.FailOnUpdateDone)
                {
                    throw new WPayException(TransactionErrors.AlreadyCompleted);
                }
                return(tran);
            }
            var mergedTran = new Calculator().UpdateToTransaction(tran, update);
            var account    = await _repo.GetAsync(tran.AccountId, true);

            var balance = mergedTran.Amount switch
            {
                AmountOutcomeCompleted _ => account.Balance,
                AmountOutcomeCancelled am => account.Balance + am,
                _ => throw new InvalidOperationException("Invalid state")
            };

            account = new Account(account.Id, balance, account.Locked);
            try
            {
                await _repo.UpdateAsync(account);

                await _repo.UpdateAsync(mergedTran.Id, mergedTran.Amount, mergedTran.Metadata, mergedTran.Description, mergedTran.UpdatedOn);

                return(mergedTran);
            }
            catch (TransactionNotFoundException)
            {
                var info = new Dictionary <string, string>()
                {
                    ["Id"] = update.Id.ToString()
                };
                throw new WPayException(TransactionErrors.NotExist, info);
            }
        }
        public async Task <IActionResult> Update([FromBody] UpdateTransaction dto)
        {
            if (dto == null)
            {
                return(BadRequest());
            }

            try
            {
                dto.UserId = IdentityHelper.GetUserId(User);
            }
            catch (UnauthorizedAccessException)
            {
                return(Unauthorized());
            }

            await _transactionService.UpdateAsync(dto);

            return(NoContent());
        }
예제 #15
0
        public async Task <BaseResponseMassTransit> UpdateTransaction(User user,
                                                                      UpdateTransaction transaction)
        {
            await CheckUserIsCreate(user);

            var customer = await _context.Customers
                           .Include(item => item.Transactions)
                           .ThenInclude(item => item.Products)
                           .FirstOrDefaultAsync(item => item.CustomerId == user.Id);

            var currentTransaction = customer?.Transactions.FirstOrDefault(item => item.Id == transaction.Id);

            if (currentTransaction is null)
            {
                throw new NotFoundException("Transaction that is being updated was not found");
            }

            await UpdateTransaction(currentTransaction, transaction);

            var response = new BaseResponseMassTransit();

            return(response);
        }
예제 #16
0
        public void FindWorkingTransaction()
        {
            Store            store = new Store("c:\\brightstar\\twitteringtest\\", false);
            FileStoreManager fsm   = new FileStoreManager(StoreConfiguration.DefaultStoreConfiguration);
            int txnCount           = 0;

            foreach (var cp in store.GetCommitPoints())
            {
                var oldStore = fsm.OpenStore("c:\\brightstar\\twitteringtest\\", cp.LocationOffset);
                try
                {
                    oldStore.ExecuteSparqlQuery(TestQuery, SparqlResultsFormat.Xml);
                    Console.WriteLine("Query worked for commit point : {0} @ {1}", cp.LocationOffset, cp.CommitTime);
                    break;
                }
                catch (Exception)
                {
                    Console.WriteLine("Query failed for commit point : {0} @ {1}", cp.LocationOffset, cp.CommitTime);
                    txnCount++;
                }
            }
            var txnLog  = fsm.GetTransactionLog("c:\\brightstar\\twitteringtest");
            var txnList = txnLog.GetTransactionList();

            for (int i = 0; i <= txnCount; i++)
            {
                txnList.MoveNext();
                var txnInfo = txnList.Current;
                Console.WriteLine("Transaction #{0}: Start: {1}, Status: {2}, JobId: {3}", i, txnInfo.TransactionStartTime, txnInfo.TransactionStatus, txnInfo.JobId);
            }

            // Going back to last known good
            store.RevertToCommitPoint(new CommitPoint(242472899, 0, DateTime.UtcNow, Guid.Empty));

            var toReplay = new List <ITransactionInfo>();

            txnList = txnLog.GetTransactionList();
            for (int i = 0; i < 10; i++)
            {
                txnList.MoveNext();
                toReplay.Add(txnList.Current);
            }

            var storeWorker = new StoreWorker("c:\\brightstar", "twitteringtest");

            for (int i = 9; i >= 0; i--)
            {
                Console.WriteLine("Applying transaction : {0}", toReplay[i].JobId);
                txnLog.GetTransactionData(toReplay[i].DataStartPosition);

                var jobId     = Guid.NewGuid();
                var updateJob = new UpdateTransaction(jobId, storeWorker);
                updateJob.ReadTransactionDataFromStream(txnLog.GetTransactionData(toReplay[i].DataStartPosition));
                updateJob.Run();

                var readStore = storeWorker.ReadStore as Store;
                var resource  = readStore.Resolve(1518601251);
                Assert.IsNotNull(resource);
                try
                {
                    var query = StoreExtensions.ParseSparql(TestQuery);
                    using (var resultStream = new MemoryStream())
                    {
                        storeWorker.Query(query, SparqlResultsFormat.Xml, resultStream,
                                          new[] { Constants.DefaultGraphUri });
                    }
                    Console.WriteLine("Query succeeded");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Query failed: " + ex.Message);
                    Assert.Fail();
                }
            }
        }
예제 #17
0
        private async Task CheckForVenmoDeposits()
        {
            while (true)
            {
                foreach (var workspace in Settings.SettingsObject.Workspaces.Workspaces)
                {
                    WorkspaceInfo workspaceInfo = workspace.Value.ToObject <WorkspaceInfo>() !;
                    logger.LogDebug($"Processing workspace ${workspace.Key}");
                    MongoDatabase database   = new MongoDatabase(workspace.Key, mongoDatabaseLogger);
                    SlackCore     slackApi   = new SlackCore(workspaceInfo.BotToken);
                    var           slackUsers = await slackApi.UsersList();

                    List <Database.Models.VenmoUser> users = database.GetAllUsers();
                    foreach (var user in users)
                    {
                        if (user.YNAB != null && user.YNAB.DefaultAccount != null)
                        {
                            // Get YNAB access token
                            Configuration config          = helperMethods.CreateConfiguration(user.YNAB.Auth !.AccessToken !);
                            string?       ynabAccessToken = await helperMethods.CheckIfYNABAccessTokenIsExpired(user, database, new ApiClient(config));

                            if (ynabAccessToken == null)
                            {
                                logger.LogError($"Unable to refresh YNAB access token for {user.UserId}");
                                await WebhookController.SendSlackMessage(workspaceInfo, "Unable to import your Venmo deposits into YNAB because your YNAB authentication information is invalid. Please refresh it.",
                                                                         user.UserId, httpClient);

                                continue;
                            }
                            config = helperMethods.CreateConfiguration(ynabAccessToken);

                            // Get Venmo access token
                            VenmoApi venmoApi         = new VenmoApi(venmoApiLogger);
                            string?  venmoAccessToken = await helperMethods.CheckIfVenmoAccessTokenIsExpired(user, venmoApi, database);

                            if (string.IsNullOrEmpty(venmoAccessToken))
                            {
                                logger.LogError($"Unable to refresh Venmo access token for {user.UserId}");
                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         "Unable to process scheduled Venmos as your token has expired. Please refresh it.",
                                                                         user.UserId, httpClient);

                                continue;
                            }
                            venmoApi.AccessToken = venmoAccessToken;

                            logger.LogDebug($"Processing slack user {user.UserId}");

                            List <TransactionDetail> venmoDeposits = await GetVenmoDeposits(user, config);

                            if (!ShouldProcessLatestVenmoDeposit(venmoDeposits))
                            {
                                continue;
                            }

                            // (fromDate - toDate]. We can adjust which transactions get included after if the
                            // subtransactions total doesn't match the deposit total
                            DateOnly toDate = DateOnly.FromDateTime(venmoDeposits[0].Date !.Value);
                            DateOnly fromDate;
                            // if multiple deposits were made on the same day (due to Venmo transfer limits) then
                            // make sure we get the first deposit not on the same day
                            foreach (var deposit in venmoDeposits)
                            {
                                fromDate = DateOnly.FromDateTime(deposit.Date !.Value);
                                if (fromDate != toDate)
                                {
                                    break;
                                }
                            }
                            fromDate = fromDate.AddDays(1);

                            var venmoTransactions = await GetVenmoTransactionsBetweenDates(fromDate, toDate, venmoApi, user);

                            TransactionDetail         ynabDeposit         = venmoDeposits[0];
                            SaveTransaction?          newTransaction      = null;
                            List <SaveSubTransaction> subTransactions     = new List <SaveSubTransaction>();
                            VenmoTransaction?         previousTransaction = null;
                            decimal originalDepositAmount = 0;
                            decimal depositAmount         = 0;
                            bool    multipleTransfers     = false;
                            foreach (VenmoTransaction transaction in venmoTransactions)
                            {
                                if (previousTransaction == null)
                                {
                                    depositAmount         = transaction.Transfer !.Amount;
                                    originalDepositAmount = depositAmount;
                                }
                                else
                                {
                                    if (previousTransaction.Type == "transfer" && transaction.Type == "transfer")
                                    {
                                        multipleTransfers     = true;
                                        depositAmount        += transaction.Transfer !.Amount;
                                        originalDepositAmount = depositAmount;
                                    }

                                    if (transaction.Type == "payment")
                                    {
                                        if (previousTransaction.Type == "transfer" && multipleTransfers)
                                        {
                                            long   milliunitAmount = (long)(depositAmount * 1000m);
                                            string importId        = $"YNAB:{milliunitAmount}:{ynabDeposit.Date:yyyy-MM-dd}";
                                            newTransaction = new SaveTransaction(ynabDeposit.AccountId, ynabDeposit.Date,
                                                                                 amount: milliunitAmount, ynabDeposit.PayeeId, ynabDeposit.PayeeName,
                                                                                 ynabDeposit.CategoryId, memo: null, golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared,
                                                                                 ynabDeposit.Approved, ynabDeposit.FlagColor, importId: importId,
                                                                                 subTransactions);
                                        }

                                        if (depositAmount - transaction.Payment !.Amount > 0)
                                        {
                                            string?memo       = transaction.Payment.Note;
                                            Guid?  categoryId = null;
                                            if (user.YNAB.Mapping != null && user.YNAB.Mapping.Count > 0 && memo != null)
                                            {
                                                foreach (var mapping in user.YNAB.Mapping)
                                                {
                                                    if (mapping.VenmoNote.Equals(memo, StringComparison.InvariantCultureIgnoreCase))
                                                    {
                                                        categoryId = new Guid(mapping.CategoryId);
                                                        break;
                                                    }
                                                }
                                            }
                                            var subTransaction = new SaveSubTransaction(amount: (long)(transaction.Payment.Amount * 1000),
                                                                                        payeeId: null, payeeName: null, categoryId: categoryId, memo);
                                            subTransactions.Add(subTransaction);
                                            depositAmount -= transaction.Payment.Amount;
                                        }
                                    }
                                }
                                previousTransaction = transaction;
                            }

                            if (depositAmount > 0)
                            {
                                var unknownSubTransaction = new SaveSubTransaction(amount: (long)(depositAmount * 1000),
                                                                                   payeeId: null, payeeName: null, categoryId: null, memo: "UNKNOWN");
                                subTransactions.Add(unknownSubTransaction);
                            }

                            TransactionsApi transactionsApi = new TransactionsApi(config);
                            if (multipleTransfers)
                            {
                                // we created a new transaction so POST it
                                var createTransactionsResponse = await transactionsApi.CreateTransactionAsync(Default,
                                                                                                              new SaveTransactionsWrapper(newTransaction));

                                // then "delete" the other transfers
                                List <UpdateTransaction> transactionsToDelete = new List <UpdateTransaction>();
                                for (int i = 0; i < venmoDeposits.Count; i++)
                                {
                                    TransactionDetail transactionDetail = venmoDeposits[i];
                                    VenmoTransaction  venmoTransaction  = venmoTransactions[i];
                                    if (venmoTransaction.Type != "transfer")
                                    {
                                        break;
                                    }

                                    UpdateTransaction updateTransaction = new UpdateTransaction(transactionDetail.AccountId,
                                                                                                transactionDetail.Date, transactionDetail.Amount, transactionDetail.PayeeId,
                                                                                                transactionDetail.PayeeName, transactionDetail.CategoryId,
                                                                                                memo: $"<DELETE ME: Combined into ${originalDepositAmount:F2} Transfer from Venmo> {transactionDetail.Memo}",
                                                                                                golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared,
                                                                                                transactionDetail.Approved, transactionDetail.FlagColor, transactionDetail.ImportId,
                                                                                                new List <SaveSubTransaction>());
                                    transactionsToDelete.Add(updateTransaction);
                                }

                                var updateTransactionsResponse = await transactionsApi.UpdateTransactionsAsync(Default, new UpdateTransactionsWrapper(transactionsToDelete));

                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         $"Imported and created a new YNAB Venmo transaction totaling ${originalDepositAmount:F2} with " +
                                                                         $"{subTransactions.Count} Venmo subtransactions combining {transactionsToDelete.Count} " +
                                                                         $"transactions which occured on {newTransaction!.Date:d}. " +
                                                                         $"Please go into YNAB, confirm the new transaction and delete the old transactions.",
                                                                         user.UserId, httpClient);
                            }
                            else
                            {
                                // we didn't create a new transaction so just PUT the existing transaction
                                newTransaction = new SaveTransaction(ynabDeposit.AccountId, ynabDeposit.Date,
                                                                     ynabDeposit.Amount, ynabDeposit.PayeeId, ynabDeposit.PayeeName, ynabDeposit.CategoryId,
                                                                     ynabDeposit.Memo, golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared, ynabDeposit.Approved,
                                                                     ynabDeposit.FlagColor, ynabDeposit.ImportId, subTransactions);
                                var response = await transactionsApi.UpdateTransactionAsync(Default, ynabDeposit.Id,
                                                                                            new SaveTransactionWrapper(newTransaction));

                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         $"Updated a YNAB Venmo transaction with {subTransactions.Count} Venmo subtransactions which occured" +
                                                                         $"on {newTransaction.Date:d}. Please go into YNAB and confirm the updated transaction.",
                                                                         user.UserId, httpClient);
                            }
                        }
                    }
                }
                await Task.Delay(CheckDuration.ToTimeSpan());
            }
        }
예제 #18
0
        private void ProcessJob(JobInfo jobInfo)
        {
            switch (jobInfo.JobType)
            {
            case JobType.Transaction:
            {
                try
                {
                    Trace.TraceInformation("ProcessJob: Starting processing on Transaction job {0}", jobInfo.Id);
                    var storeManager    = GetStoreManager();
                    var worker          = new Server.StoreWorker(jobInfo.StoreId, storeManager);
                    var transactionData = jobInfo.Data.Split(new string[] { AzureConstants.TransactionSeparator },
                                                             StringSplitOptions.None);
                    var update = new UpdateTransaction(Guid.Parse(jobInfo.Id), worker, transactionData[0],
                                                       transactionData[1], transactionData[2]);
                    update.Run();
                    _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedOk, "Transaction completed successfully");
                }
                catch (Exception ex)
                {
                    Trace.TraceError("ProcessJob: Transaction job failed with exception {0}", ex);
                    _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedWithErrors,
                                          String.Format("Transaction failed: {0}", ex));
                }
                break;
            }

            case JobType.Import:
            {
                try
                {
                    Trace.TraceInformation("ProcessJob: Starting processing on Import job {0}", jobInfo.Id);
                    var storeManager = GetStoreManager();
                    var worker       = new Server.StoreWorker(jobInfo.StoreId, storeManager);
                    BlobImportSource importSource;
                    if (!TryDeserialize(jobInfo.Data, out importSource))
                    {
                        importSource = new BlobImportSource {
                            BlobUri = jobInfo.Data
                        };
                    }
                    var import = new AzureImportJob(jobInfo.Id, worker, importSource,
                                                    (jobId, statusMessage) =>
                                                    _jobQueue.UpdateStatus(jobId, statusMessage));
                    import.Run();
                    if (import.Errors)
                    {
                        Trace.TraceError("ProcessJob: Import job {0} failed with error: {1}. Marking job as CompletedWithErrors", jobInfo.Id,
                                         import.ErrorMessage);
                        _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedWithErrors, import.ErrorMessage);
                    }
                    else
                    {
                        _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedOk, "Import completed successfully");
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("ProcessJob: Import job {0} failed with exception {1}", jobInfo.Id, ex);
                    _jobQueue.FailWithException(jobInfo.Id, "Import failed", ex);
                }
                break;
            }

            case JobType.Export:
            {
                try
                {
                    Trace.TraceInformation("ProcessJob: Starting processing on Export job {0}", jobInfo.Id);
                    var storeManager = GetStoreManager();
                    var worker       = new Server.StoreWorker(jobInfo.StoreId, storeManager);
                    BlobImportSource exportSource;
                    if (!TryDeserialize(jobInfo.Data, out exportSource))
                    {
                        exportSource = new BlobImportSource {
                            BlobUri = jobInfo.Data
                        };
                    }
                    var export = new AzureExportJob(jobInfo.Id, worker, exportSource);
                    export.Run();
                    _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedOk, "Export completed successfully");
                }
                catch (Exception ex)
                {
                    Trace.TraceError("ProcessJob: Export job {0} failed with exception {1}", jobInfo.Id, ex);
                    _jobQueue.FailWithException(jobInfo.Id, "Export failed", ex);
                }
                break;
            }

            case JobType.DeleteStore:
            {
                try
                {
                    Trace.TraceInformation("ProcessJob: Starting processing on Delete job {0}", jobInfo.Id);
                    var storeManager = GetStoreManager();
                    storeManager.DeleteStore(jobInfo.StoreId);
                    _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedOk, "Store deleted.");
                }
                catch (Exception ex)
                {
                    Trace.TraceError("ProcessJob: DeleteStore {0} failed with exception {1}", jobInfo.StoreId,
                                     ex);
                    _jobQueue.FailWithException(jobInfo.Id, "Delete failed", ex);
                }
                break;
            }

            default:
                // TODO: Implement me
                Thread.Sleep(1000);
                _jobQueue.UpdateStatus(jobInfo.Id, "20% Complete");
                Thread.Sleep(1000);
                _jobQueue.UpdateStatus(jobInfo.Id, "40% Complete");
                Thread.Sleep(1000);
                _jobQueue.UpdateStatus(jobInfo.Id, "60% Complete");
                Thread.Sleep(1000);
                _jobQueue.UpdateStatus(jobInfo.Id, "80% Complete");
                Thread.Sleep(1000);
                _jobQueue.CompleteJob(jobInfo.Id, JobStatus.CompletedOk, "Completed without any processing");
                break;
            }
        }