/// <summary>
        /// Add new tag
        /// </summary>
        /// <param name="expense">Expense saving model</param>
        /// <param name="userIdentity">Owner</param>
        /// <returns>Result message</returns>
        public Enums.Messages AddExpense(ExpenseModels.SaveExpenseModel expense, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                //find tag. You can edit just yours tags
                var tag = context.Tags.FirstOrDefault(x => x.TagId == expense.Tag);
                var user = context.Users.FirstOrDefault(x => x.Login == userIdentity);
                // check user account
                if (user == null)
                {
                    return Enums.Messages.UserNotRegistrate;
                }
                // new expense will add
                if (tag != null)
                {
                    context.Expenses.Add(new Expense()
                                             {
                                                 Amount = expense.Amount,
                                                 DateOfMakingExpense = expense.DateOfMakingExpense.ToUniversalTime(),
                                                 Description = expense.Description,
                                                 Tag = tag,
                                                 User = user
                                             });

                    return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }

                return Enums.Messages.ErorWriteInDatabase;
            }
        }
        /// <summary>
        /// Search all user's expense
        /// </summary>
        /// <param name="userIdentity">User's identtety info</param>
        /// <returns>Expense list</returns>
        public IEnumerable<ExpenseModels.DisplayExpenseModel> AllUserExpenses(string userIdentity, DateTime beginPeriod,
                                                                              DateTime endPeriod)
        {
            var resultCollection = new List<ExpenseModels.DisplayExpenseModel>();

            using (var context = new ExpenseDatabaseContext())
            {
                var expensesList = context.Expenses.Include("Tag").Where(x => x.User.Login == userIdentity
                                                                              &&
                                                                              DateTime.Compare(beginPeriod,
                                                                                               x.DateOfMakingExpense) <=
                                                                              0
                                                                              &&
                                                                              DateTime.Compare(endPeriod,
                                                                                               x.DateOfMakingExpense) >=
                                                                              0
                    );
                foreach (Expense expense in expensesList.AsQueryable())
                {
                    var displayModel = new ExpenseModels.DisplayExpenseModel
                                           {
                                               Id = expense.ExpenseId,
                                               DateOfMakingExpense = expense.DateOfMakingExpense.ToLocalTime(),
                                               Amount = expense.Amount,
                                               Description = expense.Description,
                                               Tag = expense.Tag
                                           };
                    resultCollection.Add(displayModel);
                }
            }

            return resultCollection.OrderBy(x => x.DateOfMakingExpense);
        }
        /// <summary>
        /// Add new tag
        /// </summary>
        /// <param name="tagName">Name of the tag</param>
        /// <param name="userIdentity">Owner</param>
        /// <returns>Result message</returns>
        public Enums.Messages AddTag(string tagName, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                //find tag. You can edit just yours tags
                var tag = context.Tags.FirstOrDefault(x => x.Name == tagName && !x.IsDelete);
                var user = context.Users.FirstOrDefault(x => x.Login == userIdentity);
                if(user == null)
                {
                    return Enums.Messages.UserNotRegistrate;
                }
                // new tag will add
                if (tag == null)
                {
                    context.Tags.Add(new Tag()
                                         {
                                             Name = tagName,
                                             User = user
                                         });

                    return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }
                else
                {
                    // record exist in user list
                    if (tag.User == user || tag.User == null)
                    {
                        return Enums.Messages.Good;
                    }
                        //add new tag
                    else
                    {
                        // exist in other userTagList
                        context.Tags.Add(new Tag()
                        {
                            Name = tagName,
                            User = user
                        });

                        return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                    }
                }

            }
        }
        /// <summary>
        /// Search all user's tags or genelar tags
        /// </summary>
        /// <param name="userIdentity">user's identtety info</param>
        /// <returns>tag list</returns>
        public List<TagModels.CreateTagModel> AllUserTags(string userIdentity)
        {
            List<TagModels.CreateTagModel> resultCollection = new List<TagModels.CreateTagModel>();

            using (var context = new ExpenseDatabaseContext())
            {
                var sqlResult = context.Tags.Where(x => !x.IsDelete && (x.User.Login == userIdentity || x.User == null));
                foreach (var tag in sqlResult)
                {
                    resultCollection.Add(new TagModels.CreateTagModel()
                                             {
                                                 Id = tag.TagId,
                                                 Name = tag.Name
                                             });
                }
            }

            return resultCollection;
        }
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                User user = context.Users.FirstOrDefault(u => u.Login == username);

                string passwordSHA = UserHelper.hashSHA512(password);

                if (user == null)
                {
                    // ExpenseTrackingSystem.Database.Security.User
                    User userRecord = new User();
                    userRecord.UserGuid = Guid.NewGuid().ToString();
                    userRecord.Login = username;
                    userRecord.Password = passwordSHA;
                    context.Users.Add(userRecord);
                    try
                    {
                        if (context.SaveChanges() != 1)
                        {
                            status = MembershipCreateStatus.ProviderError;
                            MvcApplication.log.Error(" Saving were not completed ");

                            return null;
                        }
                    }
                    catch (UpdateException ex)
                    {
                        status = MembershipCreateStatus.ProviderError;
                        MvcApplication.log.ErrorException(" Exeption during save data in the database: " + ex.StackTrace, ex);

                        return null;
                    }
                }
                else
                {
                    status = MembershipCreateStatus.DuplicateUserName;

                    return null;
                }

                status = MembershipCreateStatus.Success;

                return null;
            }
        }
        public override bool ValidateUser(string username, string password)
        {
            string passwordSHA = UserHelper.hashSHA512(password);
            using (var context = new ExpenseDatabaseContext())
            {
                try
                {
                    User user = context.Users
                        .FirstOrDefault(u => ((u.Login == username) && (u.Password == passwordSHA)));

                    return user != null;
                }
                catch (Exception e)
                {
                    // error read database
                    MvcApplication.log.ErrorException("Exeption during reading database: " + e.Message, e);

                    return false;
                }
            }
        }
        /// <summary>
        /// Delete expense
        /// </summary>
        /// <param name="id">id record</param>
        /// <param name="userIdentity">user account</param>
        /// <returns>result message</returns>
        public Enums.Messages DeleteExpense(int id, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                //find expense. You can edit just yours expenses
                var expense = context.Expenses.FirstOrDefault(x => x.ExpenseId == id && x.User.Login == userIdentity);
                if (expense != null)
                {
                    context.Expenses.Remove(expense);

                    return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }

                return Enums.Messages.RecordNotFound;
            }
        }
        /// <summary>
        /// Edit expense
        /// </summary>
        /// <param name="model">edit model</param>
        /// <param name="userIdentity">user account</param>
        /// <returns>result message</returns>
        public Enums.Messages EditExpense(ExpenseModels.DisplayExpenseModel model, string NewTag, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                // find expense. You can edit just yours expenses
                var expense = context.Expenses.FirstOrDefault(x => x.ExpenseId == model.Id && x.User.Login == userIdentity);
                // seach new tag
                var tag = context.Tags.FirstOrDefault(x => !x.IsDelete && x.Name == NewTag);
                if (expense != null)
                {
                    // if tag didn't find , than create new tag
                    if (tag == null)
                    {
                        tag = (new Tag()
                                   {
                                       Name = NewTag,
                                       User = expense.User
                                   });
                        context.Tags.Add(tag);
                    }

                    // save data
                    expense.Amount = model.Amount;
                    expense.Tag = tag;
                    expense.Description = model.Description;
                    expense.DateOfMakingExpense = model.DateOfMakingExpense;

                    return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }

                return Enums.Messages.RecordNotFound;
            }
        }
        /// <summary>
        /// Delete tag
        /// </summary>
        /// <param name="id">Record id</param>
        /// <param name="userIdentity">User</param>
        /// <returns>Result message</returns>
        public Enums.Messages DeleteTag(int id, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                //find tag. You can edit just yours tags.
                var tag = context.Tags.FirstOrDefault(x => !x.IsDelete && x.TagId == id);
                var user = context.Users.FirstOrDefault(x => x.Login == userIdentity);
                if (user == null)
                {
                    return Enums.Messages.UserNotRegistrate;
                }
                if(tag != null && tag.User == user)
                {
                    tag.IsDelete = true;

                    return context.SaveChanges() >= 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }

                return Enums.Messages.RecordNotFound;
            }
        }
        /// <summary>
        /// Edit tag
        /// </summary>
        /// <param name="id">id tag</param>
        /// <param name="tagName">New name</param>
        /// <returns>Result message</returns>
        public Enums.Messages EditTag(int id, string tagName, string userIdentity)
        {
            using (var context = new ExpenseDatabaseContext())
            {
                //find tag. You can edit just yours tags
                var tag = context.Tags.FirstOrDefault(x => !x.IsDelete && x.TagId == id && x.User.Login == userIdentity);
                if (tag != null)
                {
                    tag.Name = tagName;

                    return context.SaveChanges() == 1 ? Enums.Messages.Good : Enums.Messages.ErorWriteInDatabase;
                }
                else
                {
                    return Enums.Messages.RecordNotFound;
                }

            }
        }