Ejemplo n.º 1
0
TEST_F(ImapPlainTest, AddAccount)
{
// prevent the embedded beginedit/commitedit from doing anything
    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account(t_imap, "foo", "bar", t_expense_account1);
    gnc_account_imap_add_account(t_imap, "baz", "waldo", t_expense_account2);
    gnc_account_imap_add_account(t_imap, NULL, "pepper", t_expense_account1);
    gnc_account_imap_add_account(t_imap, NULL, "salt", t_expense_account2);
    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account(t_imap, NULL, NULL, t_expense_account2);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    gnc_account_imap_add_account(t_imap, "pork", "sausage", NULL);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));

    auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
    auto value = root->get_slot({IMAP_FRAME, "foo", "bar"});
    auto check_account = [this](KvpValue* v) {
        return xaccAccountLookup(v->get<GncGUID*>(), this->t_imap->book); };
    EXPECT_EQ(t_expense_account1, check_account(value));
    value = root->get_slot({IMAP_FRAME, "baz", "waldo"});
    EXPECT_EQ(t_expense_account2, check_account(value));
    value = root->get_slot({IMAP_FRAME, "pepper"});
    EXPECT_EQ(t_expense_account1, check_account(value));
    value = root->get_slot({IMAP_FRAME, "salt"});
    EXPECT_EQ(t_expense_account2, check_account(value));
    value = root->get_slot({IMAP_FRAME, "pork", "sausage"});
    EXPECT_EQ(nullptr, value);
}
Ejemplo n.º 2
0
TEST_F(ImapBayesTest, AddAccountBayes)
{
    // prevent the embedded beginedit/commitedit from doing anything
    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account_bayes(t_imap, t_list1, t_expense_account1);
    gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2);
    gnc_account_imap_add_account_bayes(t_imap, t_list3, t_expense_account1);
    gnc_account_imap_add_account_bayes(t_imap, t_list4, t_expense_account2);
    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account_bayes(t_imap, t_list5, NULL);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));

    auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
    auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1));
    auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2));
    auto value = root->get_slot({IMAP_FRAME_BAYES, "foo", "bar"});
    auto check_account = [this](KvpValue* v) {
        return (v->get<const char*>(), this->t_imap->book); };
    value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, bar, acct1_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, waldo, acct2_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, pepper, acct1_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, salt, acct2_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, baz, acct1_guid});
    EXPECT_EQ(nullptr, value);

    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2);
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));
    value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid});
    EXPECT_EQ(2, value->get<int64_t>());
}
Ejemplo n.º 3
0
/* ----------------------------------------------------------------- */
static void
load_tx_guid( const GncSqlBackend* be, GncSqlRow* row,
              /*@ null @*/ QofSetterFunc setter, gpointer pObject,
              const GncSqlColumnTableEntry* table_row )
{
    const GValue* val;
    GncGUID guid;
    Transaction* tx;
    const gchar* guid_str;

    g_return_if_fail( be != NULL );
    g_return_if_fail( row != NULL );
    g_return_if_fail( pObject != NULL );
    g_return_if_fail( table_row != NULL );

    val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
    g_assert( val != NULL );
    guid_str = g_value_get_string(val);
    if ( guid_str != NULL )
    {
        (void)string_to_guid( guid_str, &guid );
        tx = xaccTransLookup( &guid, be->book );

        // If the transaction is not found, try loading it
        if ( tx == NULL )
        {
            gchar* buf;
            GncSqlStatement* stmt;

            buf = g_strdup_printf( "SELECT * FROM %s WHERE guid='%s'",
                                   TRANSACTION_TABLE, guid_str );
            stmt = gnc_sql_create_statement_from_sql( (GncSqlBackend*)be, buf );
            g_free( buf );
            query_transactions( (GncSqlBackend*)be, stmt );
            tx = xaccTransLookup( &guid, be->book );
        }

        if ( tx != NULL )
        {
            if ( table_row->gobj_param_name != NULL )
            {
		qof_instance_increase_editlevel (pObject);
                g_object_set( pObject, table_row->gobj_param_name, tx, NULL );
		qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                g_return_if_fail( setter != NULL );
                (*setter)( pObject, (const gpointer)tx );
            }
        }
    }
}
Ejemplo n.º 4
0
/* ================================================================= */
static void
load_account_guid (const GncSqlBackend* be, GncSqlRow* row,
                   QofSetterFunc setter, gpointer pObject,
                   const GncSqlColumnTableEntry* table_row)
{
    const GValue* val;
    GncGUID guid;
    Account* account = NULL;

    g_return_if_fail (be != NULL);
    g_return_if_fail (row != NULL);
    g_return_if_fail (pObject != NULL);
    g_return_if_fail (table_row != NULL);

    val = gnc_sql_row_get_value_at_col_name (row, table_row->col_name);
    if (val != NULL && G_VALUE_HOLDS_STRING (val) &&
        g_value_get_string (val) != NULL)
    {
        (void)string_to_guid (g_value_get_string (val), &guid);
        account = xaccAccountLookup (&guid, be->book);
        if (account != NULL)
        {
            if (table_row->gobj_param_name != NULL)
            {
                qof_instance_increase_editlevel (pObject);
                g_object_set (pObject, table_row->gobj_param_name, account, NULL);
                qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                g_return_if_fail (setter != NULL);
                (*setter) (pObject, (const gpointer)account);
            }
        }
        else
        {
            PWARN ("Account ref '%s' not found", g_value_get_string (val));
        }
    }
}
Ejemplo n.º 5
0
/* ================================================================= */
static void
load_billterm_guid (const GncSqlBackend* be, GncSqlRow* row,
                    QofSetterFunc setter, gpointer pObject,
                    const GncSqlColumnTableEntry* table_row)
{
    const GValue* val;
    GncGUID guid;
    GncBillTerm* term = NULL;

    g_return_if_fail (be != NULL);
    g_return_if_fail (row != NULL);
    g_return_if_fail (pObject != NULL);
    g_return_if_fail (table_row != NULL);

    val = gnc_sql_row_get_value_at_col_name (row, table_row->col_name);
    if (val != NULL && G_VALUE_HOLDS_STRING (val) &&
        g_value_get_string (val) != NULL)
    {
        string_to_guid (g_value_get_string (val), &guid);
        term = gncBillTermLookup (be->book, &guid);
        if (term != NULL)
        {
            if (table_row->gobj_param_name != NULL)
            {
                qof_instance_increase_editlevel (pObject);
                g_object_set (pObject, table_row->gobj_param_name, term, NULL);
                qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                (*setter) (pObject, (const gpointer)term);
            }
        }
        else
        {
            PWARN ("Billterm ref '%s' not found", g_value_get_string (val));
        }
    }
}
Ejemplo n.º 6
0
TEST_F(ImapPlainTest, DeleteAccount)
{
    Path path1 {IMAP_FRAME, "foo", "waldo"};
    Path path2 {IMAP_FRAME, "foo"};
    Path path3 {IMAP_FRAME};

// prevent the embedded beginedit/commitedit from doing anything
    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account(t_imap, "foo", "bar", t_expense_account1);
    gnc_account_imap_add_account(t_imap, "foo", "waldo", t_expense_account2);
    gnc_account_imap_add_account(t_imap, NULL, "pepper", t_expense_account1);
    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));

    gnc_account_imap_delete_account(t_imap, NULL, NULL);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));

    gnc_account_imap_delete_account(t_imap, "foo", "waldo");
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    EXPECT_EQ(t_expense_account1, gnc_account_imap_find_account(t_imap, "foo", "bar"));
    EXPECT_EQ(nullptr, gnc_account_imap_find_account(t_imap, "foo", "waldo"));
    auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
    EXPECT_EQ(nullptr, root->get_slot(path1));

    gnc_account_imap_delete_account(t_imap, "foo", "bar");
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    EXPECT_EQ(nullptr, root->get_slot(path2));

    gnc_account_imap_delete_account(t_imap, NULL, "pepper");
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    EXPECT_EQ(nullptr, root->get_slot(path3));
    qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));
}
Ejemplo n.º 7
0
static void
load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
                     /*@ null @*/ QofSetterFunc setter, gpointer pObject,
                     const GncSqlColumnTableEntry* table_row )
{
    const GValue* val;
    GncGUID guid;
    gnc_commodity* commodity = NULL;

    g_return_if_fail( be != NULL );
    g_return_if_fail( row != NULL );
    g_return_if_fail( pObject != NULL );
    g_return_if_fail( table_row != NULL );

    val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
    if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
    {
        (void)string_to_guid( g_value_get_string( val ), &guid );
        commodity = gnc_commodity_find_commodity_by_guid( &guid, be->book );
        if ( commodity != NULL )
        {
            if ( table_row->gobj_param_name != NULL )
            {
		qof_instance_increase_editlevel (pObject);
                g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
		qof_instance_decrease_editlevel (pObject);
            }
            else if ( setter != NULL )
            {
                (*setter)( pObject, (const gpointer)commodity );
            }
        }
        else
        {
            PWARN( "Commodity ref '%s' not found", g_value_get_string( val ) );
        }
    }
}
Ejemplo n.º 8
0
void
test_qofsession_aqb_kvp( void )
{
    /* load the accounts from the users datafile */
    /* but first, check to make sure we've got a session going. */
    QofBackendError io_err;
    char *file1 = get_filepath("file-book.gnucash");
    char *file2 = get_filepath("file-book-hbcislot.gnucash");

    if (1)
    {
        // A file with no content at all, but a valid XML file
        QofSession *new_session = qof_session_new ();
        char *newfile = g_strdup_printf("file://%s", file1);

        qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
        io_err = qof_session_get_error (new_session);
        //printf("io_err1 = %d\n", io_err);
        g_assert(io_err != ERR_BACKEND_NO_HANDLER); // Do not have no handler

        g_assert(io_err != ERR_BACKEND_NO_SUCH_DB); // DB must exist
        g_assert(io_err != ERR_BACKEND_LOCKED);
        g_assert(io_err == 0);

        qof_session_load (new_session, NULL);
        io_err = qof_session_get_error (new_session);
        //printf("io_err2 = %d\n", io_err);
        g_assert(io_err == 0);

        g_free(newfile);
        g_free(file1);

        gnc_hook_run(HOOK_BOOK_CLOSED, new_session);
        //qof_session_destroy(new_session); // tries to delete the LCK file but it wasn't created in the first place
    }

    if (1)
    {
        // A file with no content except for the book_template_list kvp
        // slot
        QofSession *new_session = qof_session_new ();
        char *newfile = g_strdup_printf("file://%s", file2);

        qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
        io_err = qof_session_get_error (new_session);
        //printf("io_err1 = %d\n", io_err);
        g_assert(io_err != ERR_BACKEND_NO_HANDLER); // Do not have no handler

        g_assert(io_err != ERR_BACKEND_NO_SUCH_DB); // DB must exist
        g_assert(io_err != ERR_BACKEND_LOCKED);
        g_assert(io_err == 0);

        qof_session_load (new_session, NULL);
        io_err = qof_session_get_error (new_session);
        //printf("io_err2 = %d\n", io_err);
        g_assert(io_err == 0);

        {
            GList *templ_list;
            GncABTransTempl *templ;
            QofBook *book = qof_session_get_book(new_session);
            const char* ORIGINAL_NAME = "Some Name";
            const char* CHANGED_NAME = "Some Changed Name";

            templ_list = gnc_ab_trans_templ_list_new_from_book (book);
            g_assert_cmpint(g_list_length(templ_list), ==, 1);

            templ = templ_list->data;
	    //Raise the edit level so that we can check that it's marked dirty.
	    qof_instance_increase_editlevel(QOF_INSTANCE(book));
	    g_assert_cmpstr(gnc_ab_trans_templ_get_name(templ), ==, ORIGINAL_NAME); // ok, name from file is here

            // Now we change the name into something else and verify it can be saved
            gnc_ab_trans_templ_set_name(templ, CHANGED_NAME);
            {
                g_assert(!qof_instance_get_dirty(QOF_INSTANCE(book))); // not yet dirty

                // Here we save the changed kvp
                gnc_ab_set_book_template_list(book, templ_list);
                g_assert(qof_instance_get_dirty(QOF_INSTANCE(book))); // yup, now dirty
                gnc_ab_trans_templ_list_free(templ_list);
            }

            {
                templ_list = gnc_ab_trans_templ_list_new_from_book (book);
                g_assert_cmpint(g_list_length(templ_list), ==, 1);

                templ = templ_list->data;
                g_assert_cmpstr(gnc_ab_trans_templ_get_name(templ), ==, CHANGED_NAME); // ok, the change has been saved!
                gnc_ab_trans_templ_list_free(templ_list);
            }
        }

        {
            // Check the kvp slots of a aqbanking-enabled account
            QofBook *book = qof_session_get_book(new_session);
            Account* account = gnc_book_get_root_account(book);
            GDate retrieved_date, original_date;
            gchar buff[MAX_DATE_LENGTH];

            g_assert(account);

            // The interesting test case here: Can we read the correct date
            // from the xml file?
            if (1)
            {
                Timespec retrieved_ts = gnc_ab_get_account_trans_retrieval(account);
                g_test_message("retrieved_ts=%s\n", gnc_print_date(retrieved_ts));
                //printf("Time=%s\n", gnc_print_date(retrieved_ts));

                retrieved_date = timespec_to_gdate(retrieved_ts);
                g_date_set_dmy(&original_date, 29, 8, 2014);

                g_assert_cmpint(g_date_compare(&retrieved_date, &original_date), ==, 0);
            }

            // A lower-level test here: Can we write and read again the
            // trans_retrieval date? This wouldn't need this particular
            // Account, just a general Account object.
            if (0)
            {
                Timespec original_ts = timespec_now(), retrieved_ts;

                // Check whether the "ab-trans-retrieval" property of Account
                // is written and read again correctly.
                gnc_ab_set_account_trans_retrieval(account, original_ts);
                retrieved_ts = gnc_ab_get_account_trans_retrieval(account);

//                printf("original_ts=%s = %d  retrieved_ts=%s = %d\n",
//                       gnc_print_date(original_ts), original_ts.tv_sec,
//                       gnc_print_date(retrieved_ts), retrieved_ts.tv_sec);

                original_date = timespec_to_gdate(original_ts);
                retrieved_date = timespec_to_gdate(retrieved_ts);

                qof_print_gdate (buff, sizeof (buff), &original_date);
                //printf("original_date=%s\n", buff);
                qof_print_gdate (buff, sizeof (buff), &retrieved_date);
                //printf("retrieved_date=%s\n", buff);

                // Is the retrieved date identical to the one written
                g_assert_cmpint(g_date_compare(&retrieved_date, &original_date), ==, 0);
            }
Ejemplo n.º 9
0
void
GncSqlAccountBackend::load_all (GncSqlBackend* sql_be)
{
    QofBook* pBook;
    ParentGuidVec l_accounts_needing_parents;
    g_return_if_fail (sql_be != NULL);

    ENTER ("");

    pBook = sql_be->book();

    std::stringstream sql;
    sql << "SELECT * FROM " << TABLE_NAME;
    auto stmt = sql_be->create_statement_from_sql(sql.str());
    auto result = sql_be->execute_select_statement(stmt);
    for (auto row : *result)
        load_single_account (sql_be, row, l_accounts_needing_parents);

    sql.str("");
    sql << "SELECT DISTINCT guid FROM " << TABLE_NAME;
    gnc_sql_slots_load_for_sql_subquery (sql_be, sql.str().c_str(),
                                         (BookLookupFn)xaccAccountLookup);

    /* While there are items on the list of accounts needing parents,
       try to see if the parent has now been loaded.  Theory says that if
       items are removed from the front and added to the back if the
       parent is still not available, then eventually, the list will
       shrink to size 0. */
    if (!l_accounts_needing_parents.empty())
    {
        auto progress_made = true;
        std::reverse(l_accounts_needing_parents.begin(),
                     l_accounts_needing_parents.end());
	auto end = l_accounts_needing_parents.end();
        while (progress_made)
        {
            progress_made = false;
            end = std::remove_if(l_accounts_needing_parents.begin(), end,
				 [&](ParentGuidPtr s)
				 {
				     auto pParent = xaccAccountLookup (&s->guid,
								       sql_be->book());
				     if (pParent != nullptr)
				     {
					 gnc_account_append_child (pParent,
								   s->pAccount);
					 progress_made = true;
					 delete s;
					 return true;
				     }
				     return false;
				 });
        }

        /* Any non-ROOT accounts left over must be parented by the root account */
        auto root = gnc_book_get_root_account (pBook);
        end = std::remove_if(l_accounts_needing_parents.begin(), end,
			     [&](ParentGuidPtr s)
			     {
				 if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
				     gnc_account_append_child (root, s->pAccount);
				 delete s;
				 return true;
			     });
    }

#if LOAD_TRANSACTIONS_AS_NEEDED
    /* Load starting balances */
    auto bal_slist = gnc_sql_get_account_balances_slist (sql_be);
    for (auto bal = bal_slist; bal != NULL; bal = bal->next)
    {
        acct_balances_t* balances = (acct_balances_t*)bal->data;

        qof_instance_increase_editlevel (balances->acct);
        g_object_set (balances->acct,
                      "start-balance", &balances->balance,
                      "start-cleared-balance", &balances->cleared_balance,
                      "start-reconciled-balance", &balances->reconciled_balance,
                      NULL);

        qof_instance_decrease_editlevel (balances->acct);
    }
    if (bal_slist != NULL)
    {
        g_slist_free (bal_slist);
    }
#endif
    LEAVE ("");
}
Ejemplo n.º 10
0
static void
load_all_accounts (GncSqlBackend* be)
{
    GncSqlStatement* stmt = NULL;
    GncSqlResult* result;
    QofBook* pBook;
    GList* l_accounts_needing_parents = NULL;
    GSList* bal_slist;
    GSList* bal;

    g_return_if_fail (be != NULL);

    ENTER ("");

    pBook = be->book;

    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    if (stmt == NULL)
    {
        LEAVE ("stmt == NULL");
        return;
    }
    result = gnc_sql_execute_select_statement (be, stmt);
    gnc_sql_statement_dispose (stmt);
    if (result != NULL)
    {
        GncSqlRow* row = gnc_sql_result_get_first_row (result);
        gchar* sql;

        while (row != NULL)
        {
            load_single_account (be, row, &l_accounts_needing_parents);
            row = gnc_sql_result_get_next_row (result);
        }
        gnc_sql_result_dispose (result);

        sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME);
        gnc_sql_slots_load_for_sql_subquery (be, sql, (BookLookupFn)xaccAccountLookup);
        g_free (sql);

        /* While there are items on the list of accounts needing parents,
           try to see if the parent has now been loaded.  Theory says that if
           items are removed from the front and added to the back if the
           parent is still not available, then eventually, the list will
           shrink to size 0. */
        if (l_accounts_needing_parents != NULL)
        {
            gboolean progress_made = TRUE;
            Account* root;
            Account* pParent;
            GList* elem;

            while (progress_made)
            {
                progress_made = FALSE;
                for (elem = l_accounts_needing_parents; elem != NULL;)
                {
                    account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data;
                    pParent = xaccAccountLookup (&s->guid, be->book);
                    if (pParent != NULL)
                    {
                        GList* next_elem;

                        gnc_account_append_child (pParent, s->pAccount);
                        next_elem = g_list_next (elem);
                        l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                         elem);
                        g_free (s);
                        elem = next_elem;
                        progress_made = TRUE;
                    }
                    else
                    {
                        /* Can't be up in the for loop because the 'then' clause reads inside a node freed
                           by g_list_delete_link(). */
                        elem = g_list_next (elem);
                    }
                }
            }

            /* Any non-ROOT accounts left over must be parented by the root account */
            root = gnc_book_get_root_account (pBook);
            while (l_accounts_needing_parents != NULL)
            {
                account_parent_guid_struct* s = (account_parent_guid_struct*)
                                                l_accounts_needing_parents->data;
                if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
                {
                    gnc_account_append_child (root, s->pAccount);
                }
                g_free (s);
                l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                 l_accounts_needing_parents);
            }
        }

        /* Load starting balances */
        bal_slist = gnc_sql_get_account_balances_slist (be);
        for (bal = bal_slist; bal != NULL; bal = bal->next)
        {
            acct_balances_t* balances = (acct_balances_t*)bal->data;

            qof_instance_increase_editlevel (balances->acct);
            g_object_set (balances->acct,
                          "start-balance", &balances->balance,
                          "start-cleared-balance", &balances->cleared_balance,
                          "start-reconciled-balance", &balances->reconciled_balance,
                          NULL);

            qof_instance_decrease_editlevel (balances->acct);
        }
        if (bal_slist != NULL)
        {
            g_slist_free (bal_slist);
        }
    }

    LEAVE ("");
}
Ejemplo n.º 11
0
/**
 * Executes a transaction query statement and loads the transactions and all
 * of the splits.
 *
 * @param be SQL backend
 * @param stmt SQL statement
 */
static void
query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
{
    GncSqlResult* result;

    g_return_if_fail( be != NULL );
    g_return_if_fail( stmt != NULL );

    result = gnc_sql_execute_select_statement( be, stmt );
    if ( result != NULL )
    {
        GList* tx_list = NULL;
        GList* node;
        GncSqlRow* row;
        Transaction* tx;
#if LOAD_TRANSACTIONS_AS_NEEDED
        GSList* bal_list = NULL;
        GSList* nextbal;
        Account* root = gnc_book_get_root_account( be->book );

        qof_event_suspend();
        xaccAccountBeginEdit( root );

        // Save the start/ending balances (balance, cleared and reconciled) for
        // every account.
        gnc_account_foreach_descendant( gnc_book_get_root_account( be->primary_book ),
                                        save_account_balances,
                                        &bal_list );
#endif

        // Load the transactions
        row = gnc_sql_result_get_first_row( result );
        while ( row != NULL )
        {
            tx = load_single_tx( be, row );
            if ( tx != NULL )
            {
                tx_list = g_list_prepend( tx_list, tx );
            }
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );

        // Load all splits and slots for the transactions
        if ( tx_list != NULL )
        {
            gnc_sql_slots_load_for_list( be, tx_list );
            load_splits_for_tx_list( be, tx_list );
        }

        // Commit all of the transactions
        for ( node = tx_list; node != NULL; node = node->next )
        {
            Transaction* pTx = GNC_TRANSACTION(node->data);
            xaccTransCommitEdit( pTx );
        }
        g_list_free( tx_list );

#if LOAD_TRANSACTIONS_AS_NEEDED
        // Update the account balances based on the loaded splits.  If the end
        // balance has changed, update the start balance so that the end
        // balance is the same as it was before the splits were loaded.
        // Repeat for cleared and reconciled balances.
        for ( nextbal = bal_list; nextbal != NULL; nextbal = nextbal->next )
        {
            full_acct_balances_t* balns = (full_acct_balances_t*)nextbal->data;
            gnc_numeric* pnew_end_bal;
            gnc_numeric* pnew_end_c_bal;
            gnc_numeric* pnew_end_r_bal;
            gnc_numeric adj;

            g_object_get( balns->acc,
                          "end-balance", &pnew_end_bal,
                          "end-cleared-balance", &pnew_end_c_bal,
                          "end-reconciled-balance", &pnew_end_r_bal,
                          NULL );

	    qof_instance_increase_editlevel (balns-acc);
            if ( !gnc_numeric_eq( *pnew_end_bal, balns->end_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_bal, *pnew_end_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_bal = gnc_numeric_add( balns->start_bal, adj,
                                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-balance", &balns->start_bal, NULL );
		qof_instance_decrease_editlevel (balns-acc);
            }
            if ( !gnc_numeric_eq( *pnew_end_c_bal, balns->end_cleared_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_cleared_bal, *pnew_end_c_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_cleared_bal = gnc_numeric_add( balns->start_cleared_bal, adj,
                                           GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-cleared-balance", &balns->start_cleared_bal, NULL );
            }
            if ( !gnc_numeric_eq( *pnew_end_r_bal, balns->end_reconciled_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_reconciled_bal, *pnew_end_r_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_reconciled_bal = gnc_numeric_add( balns->start_reconciled_bal, adj,
                                              GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-reconciled-balance", &balns->start_reconciled_bal, NULL );
            }
	    qof_instance_decrease_editlevel (balns-acc);
            xaccAccountRecomputeBalance( balns->acc );
            g_free( pnew_end_bal );
            g_free( pnew_end_c_bal );
            g_free( pnew_end_r_bal );
            g_free( balns );
        }
        if ( bal_list != NULL )
        {
            g_slist_free( bal_list );
        }

        xaccAccountCommitEdit( root );
        qof_event_resume();
#endif
    }
}
Ejemplo n.º 12
0
TEST_F(ImapBayesTest, ConvertAccountBayes)
{
    // prevent the embedded beginedit/commitedit from doing anything
    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account_bayes(t_imap, t_list1, t_expense_account1); //Food
    gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); //Drink

    auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
    auto book = qof_instance_get_slots(QOF_INSTANCE(t_imap->book));
    auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1)); //Food
    auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); //Drink
    auto acct3_guid = guid_to_string (xaccAccountGetGUID(t_asset_account2)); //Asset-Bank
    auto acct4_guid = guid_to_string (xaccAccountGetGUID(t_sav_account)); //Sav Bank

    auto val1 = new KvpValue(static_cast<int64_t>(10));
    auto val2 = new KvpValue(static_cast<int64_t>(5));
    auto val3 = new KvpValue(static_cast<int64_t>(2));

    // Test for existing entries, all will be 1
    auto value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, bar, acct1_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid});
    EXPECT_EQ(1, value->get<int64_t>());
    value = root->get_slot({IMAP_FRAME_BAYES, waldo, acct2_guid});
    EXPECT_EQ(1, value->get<int64_t>());

    // Set up some old entries
    root->set_path({IMAP_FRAME_BAYES, pepper, "Asset-Bank"}, val1);
    root->set_path({IMAP_FRAME_BAYES, salt, "Asset-Bank#Bank"}, val1);
    root->set_path({IMAP_FRAME_BAYES, salt, "Asset>Bank#Bank"}, val2);
    root->set_path({IMAP_FRAME_BAYES, pork, "Expense#Food"}, val2);
    root->set_path({IMAP_FRAME_BAYES, sausage, "Expense#Drink"}, val3);
    root->set_path({IMAP_FRAME_BAYES, foo, "Expense#Food"}, val2);

    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));

    // Start Convert
    gnc_account_imap_convert_bayes (t_imap->book);

    // convert from 'Asset-Bank' to 'Asset-Bank' guid
    value = root->get_slot({IMAP_FRAME_BAYES, pepper, acct3_guid});
    EXPECT_EQ(10, value->get<int64_t>());

    // convert from 'Asset-Bank#Bank' to 'Sav Bank' guid
    value = root->get_slot({IMAP_FRAME_BAYES, salt, acct4_guid});
    EXPECT_EQ(10, value->get<int64_t>());

    // convert from 'Expense#Food' to 'Food' guid
    value = root->get_slot({IMAP_FRAME_BAYES, pork, acct1_guid});
    EXPECT_EQ(5, value->get<int64_t>());

    // convert from 'Expense#Drink' to 'Drink' guid
    value = root->get_slot({IMAP_FRAME_BAYES, sausage, acct2_guid});
    EXPECT_EQ(2, value->get<int64_t>());

    // convert from 'Expense#Food' to 'Food' guid but add to original value
    value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid});
    EXPECT_EQ(6, value->get<int64_t>());

    // Check for run once flag
    auto vals = book->get_slot("changed-bayesian-to-guid");
    EXPECT_STREQ("true", vals->get<const char*>());

    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
}