gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Sat Jan 27 01:26:28 EST 2024
Updated via https://github.com/Gnucash/gnucash/commit/a3015443 (commit)
via https://github.com/Gnucash/gnucash/commit/49af9ff1 (commit)
via https://github.com/Gnucash/gnucash/commit/97829185 (commit)
from https://github.com/Gnucash/gnucash/commit/b31baf34 (commit)
commit a3015443768473626e04c5cb68ec6a952c827067
Merge: b31baf344f 49af9ff16b
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sat Jan 27 14:26:13 2024 +0800
Merge branch 'stock-acct-metadata' into stable #1858
commit 49af9ff16bf23a628b4b0e0aa43b83cd14c0b00b
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Fri Jan 26 11:23:03 2024 +0800
[assistant-stock-transaction] store & retrieve associated account as metadata
diff --git a/gnucash/gnome/assistant-stock-transaction.cpp b/gnucash/gnome/assistant-stock-transaction.cpp
index f4efeea365..1b26ac18ab 100644
--- a/gnucash/gnome/assistant-stock-transaction.cpp
+++ b/gnucash/gnome/assistant-stock-transaction.cpp
@@ -88,6 +88,11 @@ void stock_assistant_cancel_cb (GtkAssistant *gtkassistant, gpointer user_data)
static const char* GNC_PREFS_GROUP = "dialogs.stock-assistant";
static const char* ASSISTANT_STOCK_TRANSACTION_CM_CLASS = "assistant-stock-transaction";
+static const char* DIVIDEND_KVP_TAG = "stock-dividends";
+static const char* CAPGAINS_KVP_TAG = "stock-capgains";
+static const char* PROCEEDS_KVP_TAG = "stock-cash-proceeds";
+static const char* FEES_KVP_TAG = "stock-broker-fees";
+
/** A mask-enumerator for defining what information will be collected for a split.
*/
enum class FieldMask : unsigned
@@ -531,13 +536,16 @@ protected:
const char* m_memo;
const char* m_action;
gnc_numeric m_balance = gnc_numeric_zero();
+ const char* m_kvp_tag;
public:
StockTransactionEntry() :
m_enabled{false}, m_debit_side{false}, m_allow_zero{false}, m_account{nullptr},
- m_value{gnc_numeric_error(GNC_ERROR_ARG)}, m_memo{nullptr}, m_action{nullptr} {}
- StockTransactionEntry(const char* action) :
+ m_value{gnc_numeric_error(GNC_ERROR_ARG)}, m_memo{nullptr}, m_action{nullptr},
+ m_kvp_tag{nullptr} {}
+ StockTransactionEntry(const char* action, const char* kvp_tag) :
m_enabled{false}, m_debit_side{false}, m_allow_zero{false}, m_account{nullptr},
- m_value{gnc_numeric_error(GNC_ERROR_ARG)}, m_memo{nullptr}, m_action{action} {}
+ m_value{gnc_numeric_error(GNC_ERROR_ARG)}, m_memo{nullptr}, m_action{action},
+ m_kvp_tag{kvp_tag} {}
StockTransactionEntry(const StockTransactionEntry&) = default;
virtual ~StockTransactionEntry() = default;
/** Set up the state variables from the FieldMask.
@@ -554,6 +562,7 @@ public:
virtual Account* account() const { return m_account; }
virtual const char* print_account() const;
virtual void set_memo(const char* memo) { m_memo = memo; }
+ virtual const char* get_kvp_tag () { return m_kvp_tag; }
virtual const char* memo() const { return m_memo; }
virtual void set_value(gnc_numeric amount);
virtual GncNumeric value() { return (gnc_numeric_check(m_value) ? GncNumeric{} : GncNumeric(m_value)); }
@@ -766,7 +775,7 @@ public:
PINFO("Stock Entry");
}
StockTransactionStockEntry(const char* action) :
- StockTransactionEntry{action}, m_amount{gnc_numeric_error(GNC_ERROR_ARG)}
+ StockTransactionEntry{action, nullptr}, m_amount{gnc_numeric_error(GNC_ERROR_ARG)}
{
PINFO("Stock Entry");
}
@@ -983,7 +992,7 @@ class StockTransactionFeesEntry : public StockTransactionEntry
bool m_capitalize;
public:
StockTransactionFeesEntry() : StockTransactionEntry{}, m_capitalize{false} {}
- StockTransactionFeesEntry(const char* action) : StockTransactionEntry{action}, m_capitalize{false} {}
+ StockTransactionFeesEntry(const char* action, const char *tag) : StockTransactionEntry{action, tag}, m_capitalize{false} {}
void set_fieldmask(FieldMask mask) override;
void set_capitalize(bool capitalize) override { m_capitalize = capitalize; }
bool do_capitalize() const override { return m_capitalize; }
@@ -1098,10 +1107,10 @@ public:
m_acct{account},
m_currency{gnc_account_get_currency_or_parent(account)},
m_stock_entry{std::make_unique<StockTransactionStockEntry>(NC_ ("Stock Assistant: Page name","Stock"))},
- m_cash_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Cash"))},
- m_fees_entry{std::make_unique<StockTransactionFeesEntry>(NC_ ("Stock Assistant: Page name","Fees"))},
- m_dividend_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Dividend"))},
- m_capgains_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Capital Gains"))}
+ m_cash_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Cash"), PROCEEDS_KVP_TAG)},
+ m_fees_entry{std::make_unique<StockTransactionFeesEntry>(NC_ ("Stock Assistant: Page name","Fees"), FEES_KVP_TAG)},
+ m_dividend_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Dividend"), DIVIDEND_KVP_TAG)},
+ m_capgains_entry{std::make_unique<StockTransactionEntry>(NC_ ("Stock Assistant: Page name","Capital Gains"), CAPGAINS_KVP_TAG)}
{
DEBUG ("StockAssistantModel constructor\n");
m_stock_entry->set_account(m_acct);
@@ -1417,7 +1426,12 @@ StockAssistantModel::create_transaction ()
xaccTransSetDatePostedSecsNormalized (trans, m_transaction_date);
AccountVec accounts;
std::for_each (m_list_of_splits.begin(), m_list_of_splits.end(),
- [&](auto& entry){ entry->create_split (trans, accounts); });
+ [&](auto& entry)
+ {
+ entry->create_split (trans, accounts);
+ if (entry->get_kvp_tag() && entry->account())
+ xaccAccountSetAssociatedAccount (m_acct, entry->get_kvp_tag(), entry->account());
+ });
add_price (book);
xaccTransCommitEdit (trans);
std::for_each (accounts.begin(), accounts.end(), xaccAccountCommitEdit);
@@ -1596,7 +1610,7 @@ class GncAccountSelector
GtkWidget* m_selector;
public:
GncAccountSelector (GtkBuilder *builder, AccountTypeList types,
- gnc_commodity *currency);
+ gnc_commodity *currency, Account *default_acct);
void attach (GtkBuilder *builder, const char *table_id,
const char *label_ID, int row);
void connect (StockTransactionEntry*);
@@ -1613,7 +1627,7 @@ gnc_account_sel_changed_cb (GtkWidget* widget, StockTransactionEntry* entry)
}
GncAccountSelector::GncAccountSelector (GtkBuilder *builder, AccountTypeList types,
- gnc_commodity *currency) :
+ gnc_commodity *currency, Account *default_acct) :
m_selector{gnc_account_sel_new ()}
{
auto accum = [](auto a, auto b) { return g_list_prepend(a, (gpointer)b); };
@@ -1624,6 +1638,8 @@ GncAccountSelector::GncAccountSelector (GtkBuilder *builder, AccountTypeList typ
gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(m_selector), acct_list, curr_list);
gnc_account_sel_set_default_new_commodity(GNC_ACCOUNT_SEL(m_selector), currency);
gnc_account_sel_set_new_account_modal (GNC_ACCOUNT_SEL(m_selector), true);
+ if (default_acct)
+ gnc_account_sel_set_account (GNC_ACCOUNT_SEL(m_selector), default_acct, true);
g_list_free(acct_list);
g_list_free(curr_list);
}
@@ -2006,7 +2022,8 @@ public:
PageCash::PageCash(GtkBuilder *builder, Account* account)
: m_page(get_widget(builder, "cash_details_page")),
m_account(builder, {ACCT_TYPE_ASSET, ACCT_TYPE_BANK},
- gnc_account_get_currency_or_parent(account)),
+ gnc_account_get_currency_or_parent(account),
+ xaccAccountGetAssociatedAccount (account, PROCEEDS_KVP_TAG)),
m_memo(get_widget(builder, "cash_memo_entry")),
m_value(builder, gnc_account_get_currency_or_parent(account))
{
@@ -2068,7 +2085,8 @@ PageFees::PageFees(GtkBuilder *builder, Account* account)
: m_page(get_widget(builder, "fees_details_page")),
m_capitalize(
get_widget(builder, "capitalize_fees_checkbutton")),
- m_account(builder, {ACCT_TYPE_EXPENSE}, gnc_account_get_currency_or_parent(account)),
+ m_account(builder, {ACCT_TYPE_EXPENSE}, gnc_account_get_currency_or_parent(account),
+ xaccAccountGetAssociatedAccount (account, FEES_KVP_TAG)),
m_memo(get_widget(builder, "fees_memo_entry")),
m_value(builder, gnc_account_get_currency_or_parent(account)),
m_stock_account(account)
@@ -2155,7 +2173,8 @@ public:
PageDividend::PageDividend(GtkBuilder *builder, Account* account)
: m_page(get_widget(builder, "dividend_details_page")),
- m_account(builder, {ACCT_TYPE_INCOME}, gnc_account_get_currency_or_parent(account)),
+ m_account(builder, {ACCT_TYPE_INCOME}, gnc_account_get_currency_or_parent(account),
+ xaccAccountGetAssociatedAccount (account, DIVIDEND_KVP_TAG)),
m_memo(get_widget(builder, "dividend_memo_entry")),
m_value(builder, gnc_account_get_currency_or_parent(account))
{
@@ -2204,7 +2223,8 @@ public:
PageCapGain::PageCapGain (GtkBuilder *builder, Account* account) :
m_page (get_widget (builder, "capgains_details_page")),
- m_account (builder, { ACCT_TYPE_INCOME }, gnc_account_get_currency_or_parent(account)),
+ m_account (builder, { ACCT_TYPE_INCOME }, gnc_account_get_currency_or_parent(account),
+ xaccAccountGetAssociatedAccount (account, CAPGAINS_KVP_TAG)),
m_memo (get_widget (builder, "capgains_memo_entry")),
m_value (builder, gnc_account_get_currency_or_parent(account))
{
commit 97829185863cc90d51d4034411dcdaa78f618e9f
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Fri Jan 26 00:12:37 2024 +0800
[account.cpp] add more account metadata - assoc account
the tag denotes the type of associated account eg. "dividend"
"capgains" "cash" "fees"
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 1a53ff6026..378aff1a46 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2579,6 +2579,34 @@ xaccAccountSetNotes (Account *acc, const char *str)
set_kvp_string_tag (acc, "notes", str);
}
+
+void
+xaccAccountSetAssociatedAccount (Account *acc, const char *tag, const Account* assoc_acct)
+{
+ g_return_if_fail (GNC_IS_ACCOUNT(acc));
+ g_return_if_fail (tag && *tag);
+
+ std::vector<std::string> path = { "associated-account", tag };
+ xaccAccountBeginEdit(acc);
+
+ PINFO ("setting %s assoc %s account = %s", xaccAccountGetName (acc), tag,
+ assoc_acct ? xaccAccountGetName (assoc_acct) : nullptr);
+
+ if (GNC_IS_ACCOUNT(assoc_acct))
+ {
+ GValue v = G_VALUE_INIT;
+ g_value_init (&v, GNC_TYPE_GUID);
+ g_value_set_static_boxed (&v, xaccAccountGetGUID (assoc_acct));
+ qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
+ g_value_unset (&v);
+ }
+ else
+ qof_instance_set_path_kvp (QOF_INSTANCE (acc), nullptr, path);
+
+ mark_account (acc);
+ xaccAccountCommitEdit(acc);
+}
+
void
xaccAccountSetCommodity (Account * acc, gnc_commodity * com)
{
@@ -3367,6 +3395,28 @@ xaccAccountGetNotes (const Account *acc)
return rv;
}
+Account*
+xaccAccountGetAssociatedAccount (const Account *acc, const char *tag)
+{
+ g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr);
+ g_return_val_if_fail (tag && *tag, nullptr);
+
+ GValue v = G_VALUE_INIT;
+ qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, { "associated-account", tag });
+
+ auto guid = static_cast<GncGUID*>(G_VALUE_HOLDS_BOXED (&v) ? g_value_get_boxed(&v) : nullptr);
+ g_value_unset (&v);
+
+ if (!guid)
+ return nullptr;
+
+ auto assoc_acct = xaccAccountLookup (guid, gnc_account_get_book (acc));
+ PINFO ("retuning %s assoc %s account = %s", xaccAccountGetName (acc), tag,
+ xaccAccountGetName (assoc_acct));
+ return assoc_acct;
+}
+
+
gnc_commodity *
DxaccAccountGetCurrency (const Account *acc)
{
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index f1db851cf4..daac6b52af 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -312,6 +312,11 @@ typedef enum
void xaccAccountSetSortReversed (Account *account, gboolean sortreversed);
/** Set the account's notes */
void xaccAccountSetNotes (Account *account, const char *notes);
+
+ /** Set the account's associated account e.g. stock account -> dividend account */
+ void xaccAccountSetAssociatedAccount (Account *acc, const char *tag,
+ const Account *assoc_acct);
+
/** Set the last num field of an Account */
void xaccAccountSetLastNum (Account *account, const char *num);
/** Set the account's lot order policy */
@@ -416,6 +421,9 @@ typedef enum
gboolean xaccAccountGetSortReversed (const Account *account);
/** Get the account's notes */
const char * xaccAccountGetNotes (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 */
const char * xaccAccountGetLastNum (const Account *account);
/** Get the account's lot order policy */
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index e09e5426b8..fbabc77f93 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -1237,6 +1237,25 @@ test_gnc_account_kvp_setters_getters (Fixture *fixture, gconstpointer pData)
xaccAccountSetNotes (account, nullptr);
g_assert_cmpstr (xaccAccountGetNotes (account), ==, nullptr);
+ // Associated Account getter/setter
+ g_assert_null (xaccAccountGetAssociatedAccount (account, "test"));
+
+ g_test_expect_message ("gnc.engine", G_LOG_LEVEL_CRITICAL,
+ "*xaccAccountSetAssociatedAccount*assertion*tag && *tag*");
+ xaccAccountSetAssociatedAccount (account, nullptr, account);
+ g_test_assert_expected_messages();
+
+ g_test_expect_message ("gnc.engine", G_LOG_LEVEL_CRITICAL,
+ "*xaccAccountSetAssociatedAccount*assertion*GNC_IS_ACCOUNT(acc)*");
+ xaccAccountSetAssociatedAccount (nullptr, "test", account);
+ g_test_assert_expected_messages();
+
+ xaccAccountSetAssociatedAccount (account, "test", account);
+ g_assert_true (xaccAccountGetAssociatedAccount (account, "test") == account);
+
+ xaccAccountSetAssociatedAccount (account, "test", nullptr);
+ g_assert_null (xaccAccountGetAssociatedAccount (account, "test"));
+
// Balance Limits getter/setter
g_assert_true (xaccAccountGetHigherBalanceLimit (account, &balance_limit) == false);
g_assert_true (xaccAccountGetLowerBalanceLimit (account, &balance_limit) == false);
Summary of changes:
gnucash/gnome/assistant-stock-transaction.cpp | 52 ++++++++++++++++++---------
libgnucash/engine/Account.cpp | 50 ++++++++++++++++++++++++++
libgnucash/engine/Account.h | 8 +++++
libgnucash/engine/test/utest-Account.cpp | 19 ++++++++++
4 files changed, 113 insertions(+), 16 deletions(-)
More information about the gnucash-changes
mailing list