Alex, That commit is part of https://github.com/Gnucash/gnucash/pull/1965.
Your first proposed change isn’t quite right because a the std::optional<T>::operator==(T) returns false if the optional doesn’t contain a value (see cases 21-33 in https://en.cppreference.com/w/cpp/utility/optional/operator_cmp). You want (copy_number && *copy_number) ? *copy_number : 1; *But* the assumption behind the original code is that if the copy_number was 0 then get_kvp_int64_path would have returned std::nullopt because set_kvp_path<T>(path, nullptr) calls (indirectly) KvpFrame::;set_impl(https://github.com/Gnucash/gnucash/blob/b5c1937702ca7a8fba772a47b2ac7fa6b8857bf5/libgnucash/engine/kvp-frame.cpp#L101) and that removes the path if it’s passed a false value; nulltpr is false. qof_instance_get_path_kvp https://github.com/Gnucash/gnucash/blob/b5c1937702ca7a8fba772a47b2ac7fa6b8857bf5/libgnucash/engine/qofinstance.cpp#L1068) bases that on getting a nullptr from KvpFrame::get_slot (https://github.com/Gnucash/gnucash/blob/b5c1937702ca7a8fba772a47b2ac7fa6b8857bf5/libgnucash/engine/kvp-frame.cpp#L144). I think you’re right about > void > xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) > { > set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number); > } The problem is that it’s set_kvp_int64_path (Account *acc, const Path& path, std::optional<gint64> value) So gint64 copy_number is getting implicitly converted to std::optional<gint64> and that’s what’s passed to qof_instance_set_kvp_path<T> (https://github.com/Gnucash/gnucash/blob/b5c1937702ca7a8fba772a47b2ac7fa6b8857bf5/libgnucash/engine/qofinstance.cpp#L1076) it’s (quite reasonably) the optional that’s tested, not the optional’s contained value. After all, it’s copy_number that’s the special case where 0 isn’t a valid value. The fix (and answer to your question about how to get rid of the KVP) is void xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) { set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number ? std::make_optional<gint64>(copy_number) : std::nullopt); } so that it will evaluate false in qof_instance_set_kvp_path. Regards, John Ralls > On Feb 4, 2025, at 18:04, Alex Aycinena <alex.aycin...@gmail.com> wrote: > > I would request some advice in solving a problem that has been discussed on > the gnucash-users list recently. > > The symptom: a US-based user has reported that on the Accounts tab, when the > Tax Info column is displayed, some accounts show 'Sched B: Total dividend > income' for their assigned tax codes and others show 'Sched B(0): Total > dividend income'. The number in parentheses is the 'copy number' which should > never be zero and should only show up if it is greater than 1 (and the copy > number issue doesn't even apply to Schedule B). > > The problem: investigation shows that not only is the display in the Tax Info > column on the Accounts tab wrong and confusing, but the US Tax Report can > show incomplete information and the TXF export also comes out with incomplete > data and invalid data (there is a copy number field that comes out as 'C0', > which is not valid). > > The cause: a commit was made on Oct 17, 2024, commit 63deaad, that changed > logic, in Account.cpp: > > From: > > gint64 > xaccAccountGetTaxUSCopyNumber (const Account *acc) > { > gint64 copy_number = 0; > GValue v = G_VALUE_INIT; > g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); > qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {"tax-US", > "copy-number"}); > if (G_VALUE_HOLDS_INT64 (&v)) > copy_number = g_value_get_int64 (&v); > > return (copy_number == 0) ? 1 : copy_number; > } > > to: > > gint64 > xaccAccountGetTaxUSCopyNumber (const Account *acc) > { > auto copy_number = get_kvp_int64_path (acc, {"tax-US", "copy-number"}); > return copy_number ? *copy_number : 1; > } > > If I read it correctly, this changed the logic from "if there is a copy > number of '0', return '1'", to "if there is a copy number (even if it is > zero) just return it, otherwise return '1'". > > Also changed in commit 63deaad, > > From: > > void > xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) > { > g_return_if_fail(GNC_IS_ACCOUNT(acc)); > xaccAccountBeginEdit (acc); > if (copy_number != 0) > { > GValue v = G_VALUE_INIT; > g_value_init (&v, G_TYPE_INT64); > g_value_set_int64 (&v, copy_number); > qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {"tax-US", > "copy-number"}); > } > else > { > qof_instance_set_path_kvp (QOF_INSTANCE (acc), nullptr, {"tax-US", > "copy-number"}); > } > mark_account (acc); > xaccAccountCommitEdit (acc); > } > > to > > void > xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) > { > set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number); > } > > Again, if I read it correctly, this changed the logic from "if the copy > number is not zero, create a new KVP for it and save it or, if there is > already a KVP for 'copy number', change it to the new value, otherwise, > delete the KVP (but do not save a zero value)" to "just save the value, even > if it is zero". > > This change caused the problem and symptoms. > > The fix: first correct/retore the logic in ' xaccAccountGetTaxUSCopyNumber' > and ' xaccAccountGetTaxUSCopyNumber'. Second, if any of our users have used > 'Edit->Tax Report Options' to modify their tax code assignments for releases > since Oct 17, 2024, they may have data files with 'copy number' KVPs with > zeros and inaccurate US Income Tax Reports/TXF Exports. We need to figure out > how to clean up their data files. > > The first correction (I implemented this first in 2009, so not sure of > current syntax, thus need your feedback): > > for ' xaccAccountGetTaxUSCopyNumber' > > - return copy_number ? *copy_number : 1; > + return (copy_number == 0) ? 1 : copy_number; > > for 'xaccAccountSetTaxUSCopyNumber' > > - set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number); > + if (copy_number != 0) > + { > + set_kvp_int64_path (acc, {"tax-US", "copy-number"}, copy_number); > + } > + else > + { > + Get rid of KVP {"tax-US", "copy-number"}); <- how do I do this now! > + } > > For the second correction (clean up users data files), I was thinking to add > logic to 'xaccAccountGetTaxUSCopyNumber' that would, if it gets a zero value, > delete the KVP, so it would look like this: > > gint64 > xaccAccountGetTaxUSCopyNumber (const Account *acc) > { > auto copy_number = get_kvp_int64_path (acc, {"tax-US", "copy-number"}); > if (copy_number == 0) > { > Get rid of KVP {"tax-US", "copy-number"}); <- how do I do this > now! > return 1; > } > return copy_number; > } > > Since 'xaccAccountGetTaxUSCopyNumber' is basically used in only three places > ('Edit->Tax Report Options', the 'Tax Info' column of the Accounts tab, and > the 'US Tax Report"), the problem would simply be cleaned up by being called > through normal activity (looking at the data or running a report). > > Feedback welcome, > > Alex > _______________________________________________ > gnucash-devel mailing list > gnucash-devel@gnucash.org > https://lists.gnucash.org/mailman/listinfo/gnucash-devel
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel