private long?ResolveParentCategory(Category category, Database database, SpecialCategories specialCategories)
 {
     if (category.Parent == null)
     {
         var groupdID = ResolveChildCategoryGroup(category, database, specialCategories);
         if (groupdID == specialCategories.CategoryGroupExpenseID)
         {
             return(specialCategories.OthersExpenseParentCatID);
         }
         if (groupdID == specialCategories.CategoryGroupIncomeID)
         {
             return(specialCategories.OthersIncomeParentCatID);
         }
         throw new Exception($"Category {category} has no parent and it's type could not be resolved basing on transactions.");
     }
     else
     {
         return(null);
     }
 }
        private long ResolveChildCategoryGroup(Category category, Database database, SpecialCategories specialCategories)
        {
            var categoryTransactions = database.Transactions
                                       .Where(t => t.Category == category)
                                       .Where(t => t.Type != TransactionType.Transfer).
                                       ToList();

            if (!categoryTransactions.Any())
            {
                return(specialCategories.CategoryGroupTransferID);
            }

            var groupsByType = categoryTransactions.GroupBy(t => t.Type).Where(g => g.Any());

            if (groupsByType.Count() != 1)
            {
                throw new Exception($"Child category {category.Name} contains transactions of mixed types. Can't import this category.");
            }

            var transactionType = groupsByType.Single().Key;

            if (transactionType == TransactionType.Adjustment)
            {
                throw new Exception("Ballance adjustments can't belong to a category.");
            }

            if (transactionType == TransactionType.Expense)
            {
                return(specialCategories.CategoryGroupExpenseID);
            }
            if (transactionType == TransactionType.Income)
            {
                return(specialCategories.CategoryGroupIncomeID);
            }

            return(specialCategories.CategoryGroupTransferID);
        }
        private SpecialCategories LoadSpecialCategories(IDbConnection connection)
        {
            var result = new SpecialCategories();

            result.CategoryGroupTransferID = connection.Query <long>("SELECT categoryGroupTableID FROM CATEGORYGROUPTABLE WHERE categoryGroupName = 'Transfer'")
                                             .Single();
            result.CategoryGroupIncomeID = connection.Query <long>("SELECT categoryGroupTableID FROM CATEGORYGROUPTABLE WHERE categoryGroupName = 'Income'")
                                           .Single();
            result.CategoryGroupExpenseID = connection.Query <long>("SELECT categoryGroupTableID FROM CATEGORYGROUPTABLE WHERE categoryGroupName = 'Expense'")
                                            .Single();
            result.OthersExpenseParentCatID = connection.Query <long>(
                "SELECT parentCategoryTableID FROM PARENTCATEGORYTABLE WHERE parentCategoryName = 'Others' AND categoryGroupID = @id",
                new { id = result.CategoryGroupExpenseID }).Single();
            result.OthersIncomeParentCatID = connection.Query <long>(
                "SELECT parentCategoryTableID FROM PARENTCATEGORYTABLE WHERE parentCategoryName = 'Others' AND categoryGroupID = @id",
                new { id = result.CategoryGroupIncomeID }).Single();

            result.NewAccountCatID = connection.Query <CHILDCATEGORYTABLE>(
                "SELECT * FROM CHILDCATEGORYTABLE WHERE childCategoryName = '(New Account)'").Single().categoryTableID;
            result.TransferCatID = connection.Query <CHILDCATEGORYTABLE>(
                "SELECT * FROM CHILDCATEGORYTABLE WHERE childCategoryName = '(Transfer)'").Single().categoryTableID;

            return(result);
        }
        private long ResolveParentCategoryGroup(Category category, Database database, SpecialCategories specialCategories)
        {
            var childGroups = database.Categories.Where(c => c.Parent == category).Select(c => ResolveChildCategoryGroup(c, database, specialCategories)).Distinct().ToList();

            if (childGroups.Count == 0)
            {
                return(specialCategories.CategoryGroupTransferID);
            }

            if (childGroups.Count == 1)
            {
                return(childGroups.Single());
            }

            throw new Exception($"Parent category {category.Name} contains transactions of mixed types. Can't import this category.");
        }