public async Task <IHttpActionResult> Post(string budgetId, TransactionModel transactionModel)
        {
            var userId  = User.Identity.GetUserId();
            var account = _AccountRepo.GetAccount(User.Identity.GetAccountId());

            var budget = account.Budgets.FirstOrDefault(x => x.Id.ToString() == budgetId);

            if (budget == null)
            {
                return(BadRequest(string.Format("Budget {0} does not exist.", budgetId)));
            }

            var transaction = ModelFactory.Parse(transactionModel);

            transaction.CreatedBy  = userId;
            transaction.ModifiedBy = transaction.CreatedBy;
            //transaction.BudgetId = budgetId;

            budget.Transactions.Add(transaction);
            account.ModifiedOn = DateTime.UtcNow;
            account.ModifiedBy = transaction.ModifiedBy;

            // insert into account collection
            var result = _AccountRepo.SaveAccount(account);

            if (!result)
            {
                Log.Error("Tandem.API.TransactionsController, Post",
                          new Exception("An unknown error occurred while saving the account."));
                return(InternalServerError(new Exception("Could not save transaction.")));
            }

            if (budget.NotifyAllTransactions ||
                ThresholdStatus.Critical == budget.ThresholdStatus ||
                ThresholdStatus.Warning == budget.ThresholdStatus ||
                budget.TransactionLimit < transaction.Amount)
            {
                // Sending notification
                var data = new Dictionary <string, string>
                {
                    { "BudgetName", budget.Name },
                    { "TransactionAmount", transaction.Amount.ToString("C") }
                };
                var notificationServiceFactory = new NotificationServiceFactory(
                    NotificationOrigins.TransactionController
                    , userId
                    , data
                    , budget.ThresholdStatus
                    );
                var success = await notificationServiceFactory.SendNotificationsAsync();

                if (!success)
                {
                    Log.Warn("API could not push notification successfully.");
                }
            }

            transactionModel = ModelFactory.Create(transaction, budgetId);
            return(Created(transactionModel.Url, transactionModel));
        }
        public async Task <IHttpActionResult> Delete(string budgetId, string id)
        {
            var userId  = User.Identity.GetUserId();
            var account = _AccountRepo.GetAccount(User.Identity.GetAccountId());

            var budget = account.Budgets.FirstOrDefault(x => x.Id.ToString() == budgetId);

            if (budget == null || budget.IsDeleted)
            {
                return(BadRequest(string.Format("Budget {0} could not be found.", budgetId)));
            }

            var transaction = budget.Transactions.FirstOrDefault(x => x.Id.ToString() == id);

            if (transaction == null)
            {
                return(NotFound());
            }

            transaction.IsDeleted = true;
            transaction.DeletedOn = DateTime.UtcNow;

            account.ModifiedBy = userId;
            account.ModifiedOn = DateTime.UtcNow;
            var result = _AccountRepo.SaveAccount(account);

            if (result)
            {
                if (budget.NotifyAllTransactions)
                {
                    // Sending notification
                    var data = new Dictionary <string, string>
                    {
                        { "BudgetName", budget.Name },
                        { "TransactionAmount", transaction.Amount.ToString("C") }
                    };
                    var notificationServiceFactory = new NotificationServiceFactory(
                        NotificationOrigins.TransactionController
                        , userId
                        , data
                        , budget.ThresholdStatus
                        );
                    var success = await notificationServiceFactory.SendNotificationsAsync();

                    if (!success)
                    {
                        Log.Warn("API could not push notification successfully.");
                    }
                }

                return(Ok());
            }

            Log.Error("Tandem.API.TransactionsController, Delete", new Exception("An unknown error occurred while saving the account."));
            return(InternalServerError());
        }
        public async Task <IHttpActionResult> Patch(string budgetId, string id, TransactionModel transactionModel, string toBudgetId = "")
        {
            var userId  = User.Identity.GetUserId();
            var account = _AccountRepo.GetAccount(User.Identity.GetAccountId());

            // used for routing in the reponse.
            var routeBudgetId = budgetId;

            var budget = account.Budgets.FirstOrDefault(x => x.Id.ToString() == budgetId);

            if (budget == null || budget.IsDeleted)
            {
                return(BadRequest(string.Format("Budget {0} could not be found.", budgetId)));
            }

            // updating the budget; set the account id
            var transactionToUpdate = budget.Transactions.FirstOrDefault(t => t.Id.ToString() == id);

            if (transactionToUpdate == null)
            {
                return(NotFound());
            }

            // required fields
            transactionToUpdate.Description = transactionModel.Description;
            transactionToUpdate.Amount      = transactionModel.Amount;
            transactionToUpdate.ModifiedBy  = userId;
            transactionToUpdate.ModifiedOn  = DateTime.UtcNow;

            // optional fields
            if (!string.IsNullOrWhiteSpace(transactionModel.Location))
            {
                transactionToUpdate.Location = transactionModel.Location;
            }

            if (transactionModel.TransactionDate.HasValue)
            {
                transactionToUpdate.TransactionDate = transactionModel.TransactionDate.Value;
            }

            var budgetForNotification = budget;

            // move the budget if requested
            if (!string.IsNullOrWhiteSpace(toBudgetId) && toBudgetId != budgetId)
            {
                // move the transaction to the new budget
                var newBudget = account.Budgets.FirstOrDefault(x => x.Id.ToString() == toBudgetId);
                if (newBudget == null || newBudget.IsDeleted)
                {
                    return(BadRequest(string.Format("Budget {0} could not be found.", toBudgetId)));
                }

                newBudget.Transactions.Add(transactionToUpdate);
                newBudget.ModifiedOn = DateTime.UtcNow;
                newBudget.ModifiedBy = transactionToUpdate.ModifiedBy;

                budget.Transactions.Remove(transactionToUpdate);
                budgetForNotification = newBudget;
                routeBudgetId         = toBudgetId;
            }

            budget.ModifiedOn = DateTime.UtcNow;
            budget.ModifiedBy = transactionToUpdate.ModifiedBy;

            account.ModifiedOn = DateTime.UtcNow;
            account.ModifiedBy = transactionToUpdate.ModifiedBy;
            var result = _AccountRepo.SaveAccount(account);

            if (result)
            {
                if (budgetForNotification.NotifyAllTransactions ||
                    ThresholdStatus.Critical == budgetForNotification.ThresholdStatus ||
                    ThresholdStatus.Warning == budgetForNotification.ThresholdStatus ||
                    budgetForNotification.TransactionLimit < transactionModel.Amount)
                {
                    // Sending notification
                    var data = new Dictionary <string, string>
                    {
                        { "BudgetName", budget.Name },
                        { "TransactionAmount", transactionToUpdate.Amount.ToString("C") }
                    };
                    var notificationServiceFactory = new NotificationServiceFactory(
                        NotificationOrigins.TransactionController
                        , userId
                        , data
                        , budget.ThresholdStatus
                        );
                    var success = await notificationServiceFactory.SendNotificationsAsync();

                    if (!success)
                    {
                        Log.Warn("API could not push notification successfully.");
                    }
                }

                return(Ok(ModelFactory.Create(transactionToUpdate, routeBudgetId)));
            }

            Log.Error("Tandem.API.TransactionsController, Patch", new Exception("An unknown error occurred while saving the account."));
            return(InternalServerError(new Exception("Could not update transaction.")));
        }