mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-10-25 23:50:06 -05:00
[engine] Add first-class online_id accessors for Split and Account
Promote the OFX/HBCI online_id to named engine accessors:
xaccSplitGetOnlineID / SetOnlineID / HasOnlineID
xaccAccountGetOnlineID / SetOnlineID
The getters return an instance-owned const char* (mirroring
xaccTransGetDocLink / xaccTransGetNotes), so the existing
add_methods_with_prefix auto-wrapper exposes them in the Python bindings
with no .i changes and no %newobject. They write to the same engine KVP
slot ("online_id") the desktop importer uses, so there is no data or
behavior change.
With the accessors in place the gnc_import_*_online_id wrappers in
import-utilities are redundant, so replace every call site (OFX,
AqBanking, and the generic matcher/backend) with them, delete
import-utilities.cpp, and drop the online_id declarations from
import-utilities.h (its importer preference-key macros are retained).
- The engine getters return an instance-owned const char* instead of a
g_strdup'd copy, so callers no longer free the result; the affected
locals are retyped const and their g_free()s dropped.
hash_account_online_ids() g_strdups before inserting, since its hash
table owns its keys (g_free key-destructor).
- xaccAccountSetOnlineID(acc, "") clears the slot, matching the OFX
"delete the online_id" intent (the old wrapper stored an empty string).
- Drop the two unused wrappers: gnc_import_set_trans_online_id (marked
"Not actually used") and gnc_import_trans_has_online_id (no callers).
- Add xaccSplitGet/SetOnlineID to the Split gmock so test-import-backend
links without import-utilities.
This commit is contained in:
1 parent
222714d764
commit
3e98c5d8c8
19 files changed
+191
-201
No files matched your search
@@ -17,6 +17,15 @@ class TestAccount(AccountSession):
|
||||
self.account.SetName(NAME)
|
||||
self.assertEqual( NAME, self.account.GetName() )
|
||||
|
||||
def test_online_id(self):
|
||||
ONLINE_ID = "061000104:0123456789:CHECKING"
|
||||
self.assertEqual( None, self.account.GetOnlineID() )
|
||||
self.account.SetOnlineID(ONLINE_ID)
|
||||
self.assertEqual( ONLINE_ID, self.account.GetOnlineID() )
|
||||
# Passing None (or "") clears it.
|
||||
self.account.SetOnlineID(None)
|
||||
self.assertEqual( None, self.account.GetOnlineID() )
|
||||
|
||||
def test_split(self):
|
||||
SPLIT = Split(self.book)
|
||||
self.assertTrue(self.account.insert_split(SPLIT))
|
||||
|
||||
@@ -21,6 +21,19 @@ class TestSplit(SplitSession):
|
||||
self.split.SetMemo(MEMO)
|
||||
self.assertEqual( MEMO, self.split.GetMemo() )
|
||||
|
||||
def test_online_id(self):
|
||||
FITID = "20240131-0001-1234567890"
|
||||
# Unset online_id reads back as None (no KVP slot present).
|
||||
self.assertEqual( None, self.split.GetOnlineID() )
|
||||
self.assertFalse( self.split.HasOnlineID() )
|
||||
self.split.SetOnlineID(FITID)
|
||||
self.assertEqual( FITID, self.split.GetOnlineID() )
|
||||
self.assertTrue( self.split.HasOnlineID() )
|
||||
# Passing "" (or None) clears it.
|
||||
self.split.SetOnlineID("")
|
||||
self.assertEqual( None, self.split.GetOnlineID() )
|
||||
self.assertFalse( self.split.HasOnlineID() )
|
||||
|
||||
def test_account(self):
|
||||
ACCT = Account(self.book)
|
||||
ACCT.SetCommodity(self.currency)
|
||||
|
||||
@@ -20,7 +20,6 @@ set (generic_import_SOURCES
|
||||
import-format-dialog.cpp
|
||||
import-match-picker.cpp
|
||||
import-parse.cpp
|
||||
import-utilities.cpp
|
||||
import-settings.cpp
|
||||
import-main-matcher.cpp
|
||||
import-pending-matches.cpp
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-session.h"
|
||||
#include "import-account-matcher.h"
|
||||
#include "import-utilities.h"
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_ASSISTANT;
|
||||
|
||||
@@ -684,7 +683,7 @@ save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
|
||||
const gchar *ab_accountid, *gnc_accountid;
|
||||
const gchar *ab_bankcode, *gnc_bankcode;
|
||||
gchar *ab_online_id;
|
||||
gchar *gnc_online_id;
|
||||
const gchar *gnc_online_id;
|
||||
|
||||
g_return_if_fail(ab_acc && gnc_acc);
|
||||
|
||||
@@ -707,11 +706,10 @@ save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
|
||||
gnc_ab_set_account_bankcode(gnc_acc, ab_bankcode);
|
||||
|
||||
ab_online_id = gnc_ab_create_online_id(ab_bankcode, ab_accountid);
|
||||
gnc_online_id = gnc_import_get_acc_online_id(gnc_acc);
|
||||
gnc_online_id = xaccAccountGetOnlineID(gnc_acc);
|
||||
if (ab_online_id && (!gnc_online_id || (strcmp(ab_online_id, gnc_online_id) != 0)))
|
||||
gnc_import_set_acc_online_id(gnc_acc, ab_online_id);
|
||||
xaccAccountSetOnlineID(gnc_acc, ab_online_id);
|
||||
g_free(ab_online_id);
|
||||
g_free (gnc_online_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#include "gnc-ui.h"
|
||||
#include "import-account-matcher.h"
|
||||
#include "import-main-matcher.h"
|
||||
#include "import-utilities.h"
|
||||
#include "qof.h"
|
||||
#include "engine-helpers.h"
|
||||
#include <aqbanking/gui/abgui.h>
|
||||
@@ -569,7 +568,7 @@ gnc_ab_trans_to_gnc (const AB_TRANSACTION *ab_trans, Account *gnc_acc)
|
||||
|
||||
/* Set OFX unique transaction ID */
|
||||
if (fitid && *fitid)
|
||||
gnc_import_set_split_online_id (split, fitid);
|
||||
xaccSplitSetOnlineID (split, fitid);
|
||||
|
||||
/* FIXME: Extract function */
|
||||
{
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "import-account-matcher.h"
|
||||
#include "import-utilities.h"
|
||||
#include "dialog-account.h"
|
||||
#include "dialog-utils.h"
|
||||
|
||||
@@ -70,15 +69,11 @@ typedef struct
|
||||
static gpointer test_acct_online_id_match(Account *acct, gpointer data)
|
||||
{
|
||||
AccountOnlineMatch *match = (AccountOnlineMatch*)data;
|
||||
char *acct_online_id = gnc_import_get_acc_online_id(acct);
|
||||
const char *acct_online_id = xaccAccountGetOnlineID(acct);
|
||||
int acct_len, match_len;
|
||||
|
||||
if (acct_online_id == NULL || match->online_id == NULL)
|
||||
{
|
||||
if (acct_online_id)
|
||||
g_free (acct_online_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
acct_len = strlen(acct_online_id);
|
||||
match_len = strlen(match->online_id);
|
||||
@@ -91,10 +86,7 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
|
||||
if (strncmp (acct_online_id, match->online_id, acct_len) == 0)
|
||||
{
|
||||
if (strncmp(acct_online_id, match->online_id, match_len) == 0)
|
||||
{
|
||||
g_free (acct_online_id);
|
||||
return (gpointer *) acct;
|
||||
}
|
||||
if (match->partial_match == NULL)
|
||||
{
|
||||
match->partial_match = acct;
|
||||
@@ -102,8 +94,8 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
|
||||
}
|
||||
else
|
||||
{
|
||||
char *partial_online_id =
|
||||
gnc_import_get_acc_online_id(match->partial_match);
|
||||
const char *partial_online_id =
|
||||
xaccAccountGetOnlineID(match->partial_match);
|
||||
int partial_len = strlen(partial_online_id);
|
||||
if (partial_online_id[partial_len - 1] == ' ')
|
||||
--partial_len;
|
||||
@@ -133,11 +125,9 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
|
||||
g_free (name1);
|
||||
g_free (name2);
|
||||
}
|
||||
g_free (partial_online_id);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (acct_online_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -469,7 +459,7 @@ Account * gnc_import_select_account(GtkWidget *parent,
|
||||
|
||||
if (account_online_id_value)
|
||||
{
|
||||
gnc_import_set_acc_online_id(retval, account_online_id_value);
|
||||
xaccAccountSetOnlineID(retval, account_online_id_value);
|
||||
}
|
||||
ok_pressed_retval = TRUE;
|
||||
break;
|
||||
|
||||
@@ -861,11 +861,9 @@ process_reconcile(Account *base_acc,
|
||||
|
||||
/* Copy the online id to the reconciled transaction, so
|
||||
* the match will be remembered */
|
||||
auto online_id = gnc_import_get_split_online_id(trans_info->first_split);
|
||||
auto online_id = xaccSplitGetOnlineID(trans_info->first_split);
|
||||
if (online_id && *online_id)
|
||||
gnc_import_set_split_online_id(selected_match->split, online_id);
|
||||
|
||||
g_free (online_id);
|
||||
xaccSplitSetOnlineID(selected_match->split, online_id);
|
||||
|
||||
/* Done editing. */
|
||||
/*DEBUG("CommitEdit selected_match")*/
|
||||
@@ -1040,9 +1038,9 @@ hash_account_online_ids (Account *account)
|
||||
(g_str_hash, g_str_equal, g_free, nullptr);
|
||||
for (auto split : xaccAccountGetSplits (account))
|
||||
{
|
||||
auto id = gnc_import_get_split_online_id (split);
|
||||
auto id = xaccSplitGetOnlineID (split);
|
||||
if (id && *id)
|
||||
g_hash_table_insert (acct_hash, (void*) id, GINT_TO_POINTER (1));
|
||||
g_hash_table_insert (acct_hash, (void*) g_strdup (id), GINT_TO_POINTER (1));
|
||||
}
|
||||
return acct_hash;
|
||||
}
|
||||
@@ -1056,7 +1054,7 @@ gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_ha
|
||||
auto source_split = xaccTransGetSplit(trans, 0);
|
||||
g_assert(source_split);
|
||||
|
||||
auto source_online_id = gnc_import_get_split_online_id (source_split);
|
||||
auto source_online_id = xaccSplitGetOnlineID (source_split);
|
||||
|
||||
// No online id, no point in continuing. We'd crash if we tried.
|
||||
if (!source_online_id)
|
||||
@@ -1081,7 +1079,6 @@ gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_ha
|
||||
DEBUG("Transaction with online ID %s already exists, date: %s", source_online_id, date_str);
|
||||
g_free (date_str);
|
||||
}
|
||||
g_free (source_online_id);
|
||||
return online_id_exists;
|
||||
}
|
||||
|
||||
|
||||
@@ -2360,7 +2360,7 @@ create_hash_of_potential_matches (GList *candidate_splits,
|
||||
candidate = g_list_next (candidate))
|
||||
{
|
||||
auto split = static_cast<Split*>(candidate->data);
|
||||
if (gnc_import_split_has_online_id (split))
|
||||
if (xaccSplitHasOnlineID (split))
|
||||
continue;
|
||||
/* In this context an open transaction represents a freshly
|
||||
* downloaded one. That can't possibly be a match yet */
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/********************************************************************\
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @internal
|
||||
@file import-utilities.c
|
||||
@brief Utility functions for writing import modules.
|
||||
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "import-utilities.h"
|
||||
#include "qof.h"
|
||||
#include "Account.h"
|
||||
#include "Transaction.h"
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* Setter and getter functions for the online_id kvp frame in
|
||||
* Account, Transaction and Split
|
||||
\********************************************************************/
|
||||
|
||||
gchar *
|
||||
gnc_import_get_acc_online_id (Account * account)
|
||||
{
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (account), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Used in the midst of editing a transaction; make it save the
|
||||
* account data. */
|
||||
void
|
||||
gnc_import_set_acc_online_id (Account *account, const gchar *id)
|
||||
{
|
||||
g_return_if_fail (account != NULL);
|
||||
xaccAccountBeginEdit (account);
|
||||
qof_instance_set (QOF_INSTANCE (account), "online-id", id, NULL);
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_import_get_trans_online_id (Transaction * transaction)
|
||||
{
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Not actually used */
|
||||
void
|
||||
gnc_import_set_trans_online_id (Transaction *transaction, const gchar *id)
|
||||
{
|
||||
g_return_if_fail (transaction != NULL);
|
||||
xaccTransBeginEdit (transaction);
|
||||
qof_instance_set (QOF_INSTANCE (transaction), "online-id", id, NULL);
|
||||
xaccTransCommitEdit (transaction);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_import_trans_has_online_id (Transaction * transaction)
|
||||
{
|
||||
gchar *online_id = gnc_import_get_trans_online_id(transaction);
|
||||
gboolean retval = (online_id && *online_id);
|
||||
g_free (online_id);
|
||||
return retval;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_import_get_split_online_id (Split * split)
|
||||
{
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (split), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Used several places in a transaction edit where many other
|
||||
* parameters are also being set, so individual commits wouldn't be
|
||||
* appropriate. Besides, there isn't a function for one.*/
|
||||
void
|
||||
gnc_import_set_split_online_id (Split *split, const gchar *id)
|
||||
{
|
||||
g_return_if_fail (split != NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split), "online-id", id, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_import_split_has_online_id (Split * split)
|
||||
{
|
||||
gchar *online_id = gnc_import_get_split_online_id(split);
|
||||
gboolean retval = (online_id && *online_id);
|
||||
g_free (online_id);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
@@ -19,7 +19,7 @@
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @file import-utilities.h
|
||||
@brief Utility functions for writing import modules.
|
||||
@brief Preference keys for the generic importer.
|
||||
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
|
||||
*/
|
||||
#ifndef IMPORT_UTILITIES_H
|
||||
@@ -40,50 +40,5 @@
|
||||
|
||||
#include "Account.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/** @name Setter-getters
|
||||
Setter and getter functions for the online_id field for
|
||||
Accounts.
|
||||
@{
|
||||
*/
|
||||
gchar * gnc_import_get_acc_online_id(Account * account);
|
||||
void gnc_import_set_acc_online_id(Account * account,
|
||||
const gchar * string_value);
|
||||
/** @} */
|
||||
/** @name Setter-getters
|
||||
Setter and getter functions for the online_id field for
|
||||
Transactions.
|
||||
@{
|
||||
*/
|
||||
gchar * gnc_import_get_trans_online_id(Transaction * transaction);
|
||||
void gnc_import_set_trans_online_id(Transaction * transaction,
|
||||
const gchar * string_value);
|
||||
/** @} */
|
||||
|
||||
gboolean gnc_import_trans_has_online_id(Transaction * transaction);
|
||||
|
||||
/** @name Setter-getters
|
||||
Setter and getter functions for the online_id field for
|
||||
Splits.
|
||||
@{
|
||||
*/
|
||||
gchar * gnc_import_get_split_online_id(Split * split);
|
||||
void gnc_import_set_split_online_id(Split * split,
|
||||
const gchar * string_value);
|
||||
/** @} */
|
||||
|
||||
gboolean gnc_import_split_has_online_id(Split * split);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
@@ -592,8 +592,7 @@ process_bank_transaction(Transaction *transaction, Account *import_account,
|
||||
}
|
||||
if (data->fi_id_valid)
|
||||
{
|
||||
gnc_import_set_split_online_id(split,
|
||||
sanitize_string (data->fi_id));
|
||||
xaccSplitSetOnlineID(split, sanitize_string (data->fi_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +617,7 @@ create_investment_subaccount(GtkWindow *parent, Account* parent_acct,
|
||||
ACCT_TYPE_STOCK);
|
||||
if (investment_account)
|
||||
{
|
||||
gnc_import_set_acc_online_id(investment_account, inv_data->online_id);
|
||||
xaccAccountSetOnlineID(investment_account, inv_data->online_id);
|
||||
inv_data->choosing = FALSE;
|
||||
ofx_parent_account = parent_acct;
|
||||
}
|
||||
@@ -644,7 +643,7 @@ continue_account_selection(GtkWidget* parent, Account* account,
|
||||
gnc_commodity_get_fullname(commodity),
|
||||
gnc_commodity_get_fullname(xaccAccountGetCommodity(account)));
|
||||
// We must also delete the online_id that was set in gnc_import_select_account()
|
||||
gnc_import_set_acc_online_id(account, "");
|
||||
xaccAccountSetOnlineID(account, "");
|
||||
return keep_going;
|
||||
}
|
||||
|
||||
@@ -815,8 +814,7 @@ add_investment_split(Transaction* transaction, Account* account,
|
||||
xaccAccountTypesCompatible(xaccAccountGetType(account),
|
||||
ACCT_TYPE_ASSET))
|
||||
{
|
||||
gnc_import_set_split_online_id(split,
|
||||
sanitize_string (data->fi_id));
|
||||
xaccSplitSetOnlineID(split, sanitize_string (data->fi_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,7 +835,7 @@ add_currency_split(Transaction *transaction, Account* account,
|
||||
// Set split memo from ofx transaction name or memo
|
||||
gnc_ofx_set_split_memo(data, split);
|
||||
if (data->fi_id_valid)
|
||||
gnc_import_set_split_online_id (split, sanitize_string (data->fi_id));
|
||||
xaccSplitSetOnlineID (split, sanitize_string (data->fi_id));
|
||||
}
|
||||
|
||||
/* ******** Process an investment transaction **********/
|
||||
|
||||
@@ -59,7 +59,6 @@ set(gtest_import_backend_SOURCES
|
||||
gtest-import-backend.cpp
|
||||
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-backend.cpp
|
||||
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-settings.cpp
|
||||
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-utilities.cpp
|
||||
${CMAKE_SOURCE_DIR}/libgnucash/engine/mocks/gmock-qofinstance.cpp
|
||||
${CMAKE_SOURCE_DIR}/libgnucash/app-utils/mocks/gmock-gnc-prefs.cpp
|
||||
${CMAKE_SOURCE_DIR}/libgnucash/engine/mocks/gmock-qofbook.cpp
|
||||
|
||||
@@ -2638,6 +2638,13 @@ xaccAccountSetNotes (Account *acc, const char *str)
|
||||
set_kvp_string_path (acc, {"notes"}, str);
|
||||
}
|
||||
|
||||
void
|
||||
xaccAccountSetOnlineID (Account *acc, const char *id)
|
||||
{
|
||||
g_return_if_fail (GNC_IS_ACCOUNT(acc));
|
||||
set_kvp_string_path (acc, {KEY_ONLINE_ID}, id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xaccAccountSetAssociatedAccount (Account *acc, const char *tag, const Account* assoc_acct)
|
||||
@@ -3350,6 +3357,13 @@ xaccAccountGetNotes (const Account *acc)
|
||||
return get_kvp_string_path (acc, {"notes"});
|
||||
}
|
||||
|
||||
const char *
|
||||
xaccAccountGetOnlineID (const Account *acc)
|
||||
{
|
||||
g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr);
|
||||
return get_kvp_string_path (acc, {KEY_ONLINE_ID});
|
||||
}
|
||||
|
||||
Account*
|
||||
xaccAccountGetAssociatedAccount (const Account *acc, const char *tag)
|
||||
{
|
||||
|
||||
@@ -317,6 +317,14 @@ typedef enum
|
||||
/** Set the account's notes */
|
||||
void xaccAccountSetNotes (Account *account, const char *notes);
|
||||
|
||||
/** Set the account's online_id, the identifier (e.g. an OFX/HBCI
|
||||
* BANKID+ACCTID composite) of the online account this GnuCash account
|
||||
* is mapped to for bank imports. This is the same value (engine KVP
|
||||
* slot "online_id") that the desktop OFX/HBCI importer uses to match a
|
||||
* downloaded statement to its GnuCash account. Passing NULL or ""
|
||||
* clears it. Wraps its own begin/commit edit. */
|
||||
void xaccAccountSetOnlineID (Account *account, const char *id);
|
||||
|
||||
/** Set the account's associated account e.g. stock account -> dividend account */
|
||||
void xaccAccountSetAssociatedAccount (Account *acc, const char *tag,
|
||||
const Account *assoc_acct);
|
||||
@@ -426,6 +434,11 @@ typedef enum
|
||||
/** Get the account's notes */
|
||||
const char * xaccAccountGetNotes (const Account *account);
|
||||
|
||||
/** Get the account's online_id (see xaccAccountSetOnlineID). The
|
||||
* returned string is owned by the account and must NOT be freed;
|
||||
* returns NULL if no online_id is set. */
|
||||
const char * xaccAccountGetOnlineID (const Account *account);
|
||||
|
||||
/** Get the account's associated account e.g. stock account -> dividend account */
|
||||
Account* xaccAccountGetAssociatedAccount (const Account *acc, const char *tag);
|
||||
/** Get the last num field of an Account */
|
||||
|
||||
@@ -101,6 +101,7 @@ enum
|
||||
|
||||
static const char * split_type_normal = "normal";
|
||||
static const char * split_type_stock_split = "stock-split";
|
||||
static const char * split_online_id = "online_id";
|
||||
|
||||
/* GObject Initialization */
|
||||
G_DEFINE_TYPE(Split, gnc_split, QOF_TYPE_INSTANCE)
|
||||
@@ -1901,6 +1902,35 @@ xaccSplitGetMemo (const Split *split)
|
||||
return split ? split->memo : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetOnlineID (Split *split, const char *id)
|
||||
{
|
||||
if (!split) return;
|
||||
/* No xaccTransBeginEdit/CommitEdit here: the online_id is normally set
|
||||
* while many other parameters of a transaction are being changed, so
|
||||
* the caller wraps this in the parent transaction's edit. */
|
||||
std::optional<const char*> val;
|
||||
if (id && *id)
|
||||
val = g_strdup (id);
|
||||
qof_instance_set_path_kvp<const char*> (QOF_INSTANCE(split), val, {split_online_id});
|
||||
qof_instance_set_dirty (QOF_INSTANCE(split));
|
||||
}
|
||||
|
||||
const char *
|
||||
xaccSplitGetOnlineID (const Split *split)
|
||||
{
|
||||
if (!split) return nullptr;
|
||||
auto rv{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE(split), {split_online_id})};
|
||||
return rv ? *rv : nullptr;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccSplitHasOnlineID (const Split *split)
|
||||
{
|
||||
auto id = xaccSplitGetOnlineID (split);
|
||||
return (id && *id);
|
||||
}
|
||||
|
||||
const char *
|
||||
xaccSplitGetAction (const Split *split)
|
||||
{
|
||||
|
||||
@@ -160,6 +160,25 @@ void xaccSplitSetMemo (Split *split, const char *memo);
|
||||
/** Returns the memo string. */
|
||||
const char * xaccSplitGetMemo (const Split *split);
|
||||
|
||||
/** The online_id is the OFX/HBCI "FITID" recorded on a split when it is
|
||||
* imported. It is used to recognise the split on re-import so that
|
||||
* overlapping or re-downloaded statements don't create duplicates. This
|
||||
* is the same value (engine KVP slot "online_id") that the desktop
|
||||
* OFX/HBCI importer reads and writes.
|
||||
*
|
||||
* The setter only changes engine data: call it inside the parent
|
||||
* transaction's edit (xaccTransBeginEdit()/xaccTransCommitEdit()), and a
|
||||
* session save persists it. Passing NULL or "" clears the online_id. */
|
||||
void xaccSplitSetOnlineID (Split *split, const char *id);
|
||||
|
||||
/** Returns the split's online_id. The returned string is owned by the
|
||||
* split and must NOT be freed; it is valid until the online_id is changed
|
||||
* or the split is destroyed. Returns NULL if no online_id is set. */
|
||||
const char * xaccSplitGetOnlineID (const Split *split);
|
||||
|
||||
/** Returns TRUE if the split has a non-empty online_id. */
|
||||
gboolean xaccSplitHasOnlineID (const Split *split);
|
||||
|
||||
/** The Action is an arbitrary user-assigned string.
|
||||
* The action field is an arbitrary user-assigned value.
|
||||
* It is meant to be a very short (one to ten character) string that
|
||||
|
||||
@@ -110,6 +110,21 @@ xaccSplitSetMemo (Split *split, const char *memo)
|
||||
gnc_mocksplit(split)->set_memo(memo);
|
||||
}
|
||||
|
||||
const char *
|
||||
xaccSplitGetOnlineID (const Split *split)
|
||||
{
|
||||
SCOPED_TRACE("");
|
||||
auto mocksplit = gnc_mocksplit(split);
|
||||
return mocksplit ? mocksplit->get_online_id() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetOnlineID (Split *split, const char *id)
|
||||
{
|
||||
ASSERT_TRUE(GNC_IS_MOCKSPLIT(split));
|
||||
gnc_mocksplit(split)->set_online_id(id);
|
||||
}
|
||||
|
||||
char
|
||||
xaccSplitGetReconcile (const Split *split)
|
||||
{
|
||||
|
||||
@@ -73,6 +73,8 @@ public:
|
||||
MOCK_METHOD1(set_value, void(gnc_numeric));
|
||||
MOCK_CONST_METHOD0(get_memo, const char *());
|
||||
MOCK_METHOD1(set_memo, void(const char *));
|
||||
MOCK_CONST_METHOD0(get_online_id, const char *());
|
||||
MOCK_METHOD1(set_online_id, void(const char *));
|
||||
MOCK_CONST_METHOD0(get_reconcile, char());
|
||||
MOCK_METHOD1(set_reconcile, void(char));
|
||||
MOCK_METHOD1(set_date_reconciled_secs, void(time64));
|
||||
|
||||
@@ -442,11 +442,67 @@ test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_split_online_id_accessors (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Split *split = fixture->split;
|
||||
const char *fitid = "20240131-0001-1234567890";
|
||||
gchar *raw = NULL;
|
||||
|
||||
/* Initially unset. */
|
||||
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
|
||||
g_assert_true (!xaccSplitHasOnlineID (split));
|
||||
|
||||
/* Round-trip via the new accessors. */
|
||||
xaccSplitSetOnlineID (split, fitid);
|
||||
g_assert_cmpstr (xaccSplitGetOnlineID (split), ==, fitid);
|
||||
g_assert_true (xaccSplitHasOnlineID (split));
|
||||
|
||||
/* GUI parity: the value is stored in the engine KVP slot "online_id",
|
||||
* readable via the "online-id" GObject property used by the importer. */
|
||||
qof_instance_get (QOF_INSTANCE (split), "online-id", &raw, NULL);
|
||||
g_assert_cmpstr (raw, ==, fitid);
|
||||
g_free (raw);
|
||||
|
||||
/* "" clears it. */
|
||||
xaccSplitSetOnlineID (split, "");
|
||||
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
|
||||
g_assert_true (!xaccSplitHasOnlineID (split));
|
||||
|
||||
/* NULL clears it too. */
|
||||
xaccSplitSetOnlineID (split, fitid);
|
||||
xaccSplitSetOnlineID (split, NULL);
|
||||
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_account_online_id_accessors (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Account *acct = fixture->acct;
|
||||
const char *acct_online_id = "061000104:0123456789:CHECKING";
|
||||
gchar *raw = NULL;
|
||||
|
||||
g_assert_true (xaccAccountGetOnlineID (acct) == NULL);
|
||||
|
||||
xaccAccountSetOnlineID (acct, acct_online_id);
|
||||
g_assert_cmpstr (xaccAccountGetOnlineID (acct), ==, acct_online_id);
|
||||
|
||||
/* GUI parity: stored in the "online_id" KVP slot. */
|
||||
qof_instance_get (QOF_INSTANCE (acct), "online-id", &raw, NULL);
|
||||
g_assert_cmpstr (raw, ==, acct_online_id);
|
||||
g_free (raw);
|
||||
|
||||
xaccAccountSetOnlineID (acct, NULL);
|
||||
g_assert_true (xaccAccountGetOnlineID (acct) == NULL);
|
||||
}
|
||||
|
||||
void test_suite_engine_kvp_properties (void)
|
||||
{
|
||||
GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Split online_id accessors", Fixture, NULL, setup_split, test_split_online_id_accessors, teardown);
|
||||
GNC_TEST_ADD (suitename, "Account online_id accessors", Fixture, NULL, setup_account, test_account_online_id_accessors, teardown);
|
||||
GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);
|
||||
|
||||
Reference in new issue
Block a user