Correct check amount when printed from subaccount

Previously, GnuCash would include only a single split's amount as the check
amount. If a "bank" account has multiple subaccounts for budgeting reasons, and
a transaction involves both "internal" (e.g. from one bank subaccount to
another bank subaccount) and external transfers, then even when a "subaccount"
register showing the top-level bank account is printed from, the check will
have the amount of the first split rather than the total of all splits which
are from subaccounts.

This change communicates the parent account (when viewed from a "subccount"
register) to the check printing dialog so that the check amount matches the
amount displayed in the register.
This commit is contained in:
Mark Browning 2020-02-28 01:59:36 -06:00
parent 2ca6cb2a34
commit c2ef684b59
4 changed files with 58 additions and 8 deletions

View File

@ -1041,7 +1041,7 @@ gnc_payment_ok_cb (G_GNUC_UNUSED GtkWidget *widget, gpointer data)
Split *split = xaccTransFindSplitByAccount (pw->tx_info->txn, pw->xfer_acct);
GList *splits = NULL;
splits = g_list_append(splits, split);
gnc_ui_print_check_dialog_create(NULL, splits);
gnc_ui_print_check_dialog_create(NULL, splits, NULL);
g_list_free (splits);
}

View File

@ -278,6 +278,7 @@ struct _print_check_dialog
Split *split;
GList *splits;
Account* account;
GtkWidget *format_combobox;
gint format_max;
@ -369,6 +370,44 @@ get_check_address( PrintCheckDialog *pcd)
return address;
}
struct _trans_amount
{
const Transaction* trans;
gnc_numeric amount;
};
static void
subtotal_subaccount(const Account *account, struct _trans_amount* trans_amount)
{
/* Get the amount of this account in the transaction.*/
gnc_numeric amount = xaccTransGetAccountAmount(trans_amount->trans, account);
/* Accumulate. */
trans_amount->amount = gnc_numeric_add_fixed(trans_amount->amount, amount);
}
/* This function returns the amount of the check.
*/
static gnc_numeric
get_check_amount(PrintCheckDialog *pcd)
{
gnc_numeric amount;
if (pcd->account)
{
/* A parent account, e.g. from a subaccount register plugin page.
* Subtotal the amount of all splits from descendant accounts. */
struct _trans_amount trans_amount;
trans_amount.trans = xaccSplitGetParent(pcd->split);
trans_amount.amount = gnc_numeric_zero();
gnc_account_foreach_descendant(pcd->account, (AccountCb)subtotal_subaccount, &trans_amount);
amount = trans_amount.amount;
}
else
{
/* Print just the amount of the split. */
amount = xaccSplitGetAmount(pcd->split);
}
return gnc_numeric_abs(amount);
}
//@{
/** @name Split printing functions */
@ -1606,10 +1645,13 @@ initialize_format_combobox (PrintCheckDialog *pcd)
/*****************************************************
* gnc_ui_print_check_dialog_create *
* make a new print check dialog and wait for it. *
* If account is given, this is a parent account to *
* subtotal the amount of all splits under it. *
*****************************************************/
void
gnc_ui_print_check_dialog_create(GtkWidget *parent,
GList *splits)
GList *splits,
Account* account)
{
PrintCheckDialog *pcd;
GtkBuilder *builder;
@ -1620,6 +1662,7 @@ gnc_ui_print_check_dialog_create(GtkWidget *parent,
pcd = g_new0(PrintCheckDialog, 1);
pcd->caller_window = GTK_WINDOW(parent);
pcd->splits = g_list_copy(splits);
pcd->account = account;
builder = gtk_builder_new();
gnc_builder_add_from_file (builder, "dialog-print-check.glade", "adjustment1");
@ -2112,7 +2155,7 @@ draw_page_items(GtkPrintContext *context,
trans = xaccSplitGetParent(pcd->split);
/* This was valid when the check printing dialog was instantiated. */
g_return_if_fail(trans);
amount = gnc_numeric_abs(xaccSplitGetAmount(pcd->split));
amount = get_check_amount(pcd);
if (format->font)
default_desc = pango_font_description_from_string(format->font);

View File

@ -29,6 +29,7 @@
typedef struct _print_check_dialog PrintCheckDialog;
void gnc_ui_print_check_dialog_create(GtkWidget *parent,
GList *splits);
GList *splits,
Account* account);
#endif

View File

@ -3458,7 +3458,7 @@ gnc_plugin_page_register_cmd_print_check (GSimpleAction *simple,
Transaction* trans;
GList* splits = NULL, *item;
GNCLedgerDisplayType ledger_type;
Account* account;
Account* account, *subaccount = NULL;
GtkWidget* window;
ENTER ("(action %p, page %p)", simple, page);
@ -3474,13 +3474,19 @@ gnc_plugin_page_register_cmd_print_check (GSimpleAction *simple,
account = gnc_plugin_page_register_get_account (page);
split = gnc_split_register_get_current_split (reg);
trans = xaccSplitGetParent (split);
if (ledger_type == LD_SUBACCOUNT)
{
/* Set up subaccount printing, where the check amount matches the
* value displayed in the register. */
subaccount = account;
}
if (split && trans)
{
if (xaccSplitGetAccount (split) == account)
{
splits = g_list_prepend (splits, split);
gnc_ui_print_check_dialog_create (window, splits);
gnc_ui_print_check_dialog_create (window, splits, subaccount);
g_list_free (splits);
}
else
@ -3491,7 +3497,7 @@ gnc_plugin_page_register_cmd_print_check (GSimpleAction *simple,
if (split)
{
splits = g_list_prepend (splits, split);
gnc_ui_print_check_dialog_create (window, splits);
gnc_ui_print_check_dialog_create (window, splits, subaccount);
g_list_free (splits);
}
}
@ -3544,7 +3550,7 @@ gnc_plugin_page_register_cmd_print_check (GSimpleAction *simple,
}
}
}
gnc_ui_print_check_dialog_create (window, splits);
gnc_ui_print_check_dialog_create (window, splits, NULL);
}
else
{