Attached is an update to the RC1 patch This patch improves the original "RC1" patch in the following ways: 1. reg_run_balance_RC2.diff adds the gnc_split_register_get_rbaln() function, whose code was originally duplicated in the gnc_split_register_get_balance_fg_color() and gnc_split_register_get_rbaln_entry() functions in the first patch.
2. Modified the gnc_split_register_get_tdebcred_entry() function to display the debit/credit amount for the register's parent account and all subaccounts when the GENERAL_LEDGER register is in use (used by Show Subaccounts feature). 3. Added the get_trans_total_amount_subaccounts() function which returns the total amount of a transaction for the register's parent account and all subaccounts. On Fri, Sep 4, 2009 at 12:01 AM, Tim M <t...@filmchicago.org> wrote: > OK, IMO the updated patch attached to this mail is ready for testing. This > patch does the following: > > 1. When opening an account register and it's subaccounts by right clicking > it in the Accounts tab and selecting "Open Subaccounts," there is now a > Balance column as there normally is in a single account register. > > 2. This new RBALN balance column tallies the balance of the splits for the > account and all subaccounts at runtime. > > 3. Because the balance is calculated at runtime, this also means that the > balance column always reflects an accurate running balance regardless of > sort order. This is a big benefit and could certainly be modified to work > for single account view as well. With the current single account register, > when the sort order is changed the Balance displayed will only reflect the > balance of the account associated with each split - not a running balance in > relation to the sort order of the register, so that the 'Balance' displayed > for each split when the sort order is not the default causes the 'Balance' > column to be more or less unusable. > > I believe this should also resolve the following issue: > http://bugzilla.gnome.org/show_bug.cgi?id=107929 > > I resolved issue #1 in my original mailing list post. Issue #2 remains a > matter of testing by other users to ensure the patch doesn't have any > unintended consequences. > > I've tested this patch locally by opening an account and it's subaccounts > using the "Open Subaccounts" option. The newly added balance column tallies > the balance properly at runtime, and sets the balance color properly as well > (red for negative, black positive). I also tested different sort orders, > and the running balance was spot on regardless. Since this affects only the > "Open Subaccounts" register (and possibly other similar registers?), this > does not affect single account registers so those still do not tally Balance > properly when using a non-default sort order. > > This patch is against an older version of the SVN repository (I think a > trunk snapshot of version 3.1), so it may or may not work OK with the latest > trunk. Let me know if I need to make a new patch with the current trunk. > > > As a side note and as matter of cleanup, it would be useful to > functionalize the part of the new gnc_split_register_get_rbaln_entry() > function which does the actual calculations to get the running balance of > the register at a specific split, because the running balance also has to be > calculated for the gnc_split_register_get_balance_fg_color() function to set > the text color properly when the RBALN cell type is used. Currently I've > just copied the code from the rbaln function to the fg_color function, so it > would be helpful to put this in a function that returns a gnu_numeric value > of the split's running balance for the register which could then be called > by both functions. However, I'm not an experienced C programmer so I was > having some trouble figuring out just where to put such a function and how > to get it working. I did try! > > Also, this is my first FOSS patch, so let me know if there is anything I > can do differently or improve on, thanks! > > -Tim M. > > > > On Fri, Jul 10, 2009 at 10:53 AM, Tim M <t...@filmchicago.org> wrote: > >> Hello, >> >> I've attached a BETA svn diff patch against HEAD which creates a new cell >> type, RBALN_CELL. I could use some help tweaking this patch if someone is >> able to provide answers to my questions below. >> >> This cell calculates the balance of all transactions in a register at >> runtime, allowing a running balance to be displayed when using the "Open >> Subaccounts" feature. The cell currently calculates the running balance of >> all splits that are going to/from the lead account and all of its >> subaccounts, therefore it is not appropriate (currently) to use this cell >> type in a non-subaccount register view. >> >> My Questions: >> >> 1. There is an outstanding issue with this patch where it appears the >> return value of the gnc_split_register_get_rbaln_entry() function is printed >> in the Balance column of the split rows. The running Balance is correctly >> printed on the Transaction rows, but the cells in the Balance column on the >> lines of the split should be blank. Instead, they display 1 (for all >> transactions where a balance is printed) or 0 (for the blank split at the >> bottom because the function returns NULL since we don't print the balance >> for that txn). How can I fix this so that the balance cell of the split >> lines is blank? >> >> 2. The RBALN_CELL was added to the CURSOR_SINGLE_JOURNAL cursor of the >> INCOME_LEDGER/GENERAL_LEDGER/SEARCH_LEDGER cases in >> split-register-layout.c. Will this affect other register views besides the >> subaccount view? I have only tested this with asset accounts (bank, >> checking) so I'm not sure if it might cause problems with different account >> types. >> >> >> Please take a look and let me know how I can further improve it! >> >> Thanks, >> -Tim M. >> > >
Index: src/register/ledger-core/split-register-model.c =================================================================== --- src/register/ledger-core/split-register-model.c (revision 18169) +++ src/register/ledger-core/split-register-model.c (working copy) @@ -56,6 +56,67 @@ static gboolean use_red_for_negative = TRUE; +static gnc_numeric +gnc_split_register_get_rbaln (VirtualLocation virt_loc, gpointer user_data) +{ + SplitRegister *reg = user_data; + Split *split; + SRInfo *info = gnc_split_register_get_info (reg); + gnc_numeric value = gnc_numeric_zero(), balance = gnc_numeric_zero(); + Account *account; + Transaction *trans; + GList *node, *children, *child; + int i, row; + + /* This function calculates the register balance for a particular split at runtime. + * It works regardless of the sort order. */ + balance = gnc_numeric_zero(); + + /* Return NULL if this is a blank transaction. */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + if (split == xaccSplitLookup (&info->blank_split_guid, + gnc_get_current_book ())) + return gnc_numeric_zero(); /* FIXME: Should return an error code or something to indicate it's a blank trans */ + + trans = xaccSplitGetParent (split); + if (!trans) + return gnc_numeric_zero(); /* FIXME: Should return an error code or something to indicate it's not a transaction or? */ + + /* Get a list of all subaccounts for matching */ + children = gnc_account_get_descendants(gnc_split_register_get_default_account(reg)); + children = g_list_append(children, gnc_split_register_get_default_account(reg)); + + /* Get the row number we're on, then start with the first row. */ + row = virt_loc.vcell_loc.virt_row; + virt_loc.vcell_loc.virt_row=0; + + while (virt_loc.vcell_loc.virt_row <= row ) { + /* Get new temporary split and its parent transaction */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + trans = xaccSplitGetParent (split); + + i = 1; + for (node = xaccTransGetSplitList (trans); node; node = node->next) { + Split *secondary = node->data; + i++; + + /* Add up the splits that belong to the transaction if they are + * from the lead account or one of the subaccounts. */ + account = xaccSplitGetAccount (secondary); + + for (child = children; child; child = child->next) { + if (account == child->data) { + balance = gnc_numeric_add_fixed(balance, xaccSplitGetAmount(secondary)); + break; + } + } + } + virt_loc.vcell_loc.virt_row+=i; + } + + return balance; +} + static gboolean gnc_split_register_use_security_cells (SplitRegister *reg, VirtualLocation virt_loc) @@ -402,6 +463,8 @@ if (gnc_cell_name_equal (cell_name, BALN_CELL)) balance = xaccSplitGetBalance (split); + else if (gnc_cell_name_equal (cell_name, RBALN_CELL)) + balance = gnc_split_register_get_rbaln (virt_loc,user_data); else balance = get_trans_total_balance (reg, xaccSplitGetParent (split)); @@ -1313,6 +1376,25 @@ return g_strdup (help); } +/* Return the total amount of the transaction for splits of default account + * and all subaccounts of the register. */ +static gnc_numeric +get_trans_total_amount_subaccounts (SplitRegister *reg, Transaction *trans) +{ + GList *children, *child; + gnc_numeric total = gnc_numeric_zero(); + + /* Get a list of all subaccounts for matching */ + children = gnc_account_get_descendants(gnc_split_register_get_default_account(reg)); + children = g_list_append(children, gnc_split_register_get_default_account(reg)); + + for (child = children; child; child = child->next) { + total = gnc_numeric_add_fixed(total, xaccTransGetAccountAmount(trans, child->data)); + } + + return total; +} + static const char * gnc_split_register_get_tdebcred_entry (VirtualLocation virt_loc, gboolean translate, @@ -1330,7 +1412,11 @@ cell_name = gnc_table_get_cell_name (reg->table, virt_loc); - total = get_trans_total_amount (reg, xaccSplitGetParent (split)); + if (reg->type == GENERAL_LEDGER) + total = get_trans_total_amount_subaccounts (reg, xaccSplitGetParent (split)); + else + total = get_trans_total_amount (reg, xaccSplitGetParent (split)); + if (gnc_numeric_zero_p (total)) return NULL; @@ -1505,6 +1591,32 @@ } } +/* Calculates the register balance for each split at runtime. + * This works regardless of the sort order. */ +static const char * +gnc_split_register_get_rbaln_entry (VirtualLocation virt_loc, + gboolean translate, + gboolean *conditionally_changed, + gpointer user_data) +{ + SplitRegister *reg = user_data; + SRInfo *info = gnc_split_register_get_info (reg); + Split *split; + Transaction *trans; + + /* Return NULL if this is a blank transaction. */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + if (split == xaccSplitLookup (&info->blank_split_guid, + gnc_get_current_book ())) + return NULL; + + trans = xaccSplitGetParent (split); + if (!trans) + return NULL; + + return xaccPrintAmount (gnc_split_register_get_rbaln (virt_loc,user_data), gnc_split_register_print_info (reg)); +} + static gboolean gnc_split_register_cursor_is_readonly (VirtualLocation virt_loc, gpointer user_data) @@ -2012,7 +2124,11 @@ gnc_split_register_get_debcred_entry, CRED_CELL); + gnc_table_model_set_entry_handler (model, + gnc_split_register_get_rbaln_entry, + RBALN_CELL); + gnc_table_model_set_label_handler (model, gnc_split_register_get_date_label, DATE_CELL); @@ -2101,7 +2217,11 @@ gnc_split_register_get_fcredit_label, FCRED_CELL); + gnc_table_model_set_label_handler (model, + gnc_split_register_get_tbalance_label, + RBALN_CELL); + gnc_table_model_set_default_help_handler( model, gnc_split_register_get_default_help); @@ -2231,7 +2351,10 @@ gnc_table_model_set_fg_color_handler( model, gnc_split_register_get_balance_fg_color, TBALN_CELL); + gnc_table_model_set_fg_color_handler( + model, gnc_split_register_get_balance_fg_color, RBALN_CELL); + gnc_table_model_set_default_bg_color_handler( model, gnc_split_register_get_bg_color); Index: src/register/ledger-core/split-register.h =================================================================== --- src/register/ledger-core/split-register.h (revision 18169) +++ src/register/ledger-core/split-register.h (working copy) @@ -209,6 +209,7 @@ #define TYPE_CELL "split-type" #define XFRM_CELL "account" #define VNOTES_CELL "void-notes" +#define RBALN_CELL "reg-run-balance" /** @} */ /** @name Cursor Names Index: src/register/ledger-core/split-register-layout.c =================================================================== --- src/register/ledger-core/split-register-layout.c (revision 18169) +++ src/register/ledger-core/split-register-layout.c (working copy) @@ -248,7 +248,7 @@ gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 6); } - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -268,7 +268,8 @@ gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 2); gnc_table_layout_set_cell (layout, curs, TDEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, TCRED_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -296,7 +297,7 @@ gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 6); } - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); break; } @@ -459,7 +460,7 @@ case INCOME_LEDGER: case GENERAL_LEDGER: case SEARCH_LEDGER: - num_cols = 8; + num_cols = 9; break; case STOCK_REGISTER: @@ -702,6 +703,15 @@ CELL_ALIGN_LEFT, FALSE, FALSE); + + gnc_register_add_cell (layout, + RBALN_CELL, + PRICE_CELL_TYPE_NAME, + N_("sample:999,999.000") + 7, + CELL_ALIGN_RIGHT, + FALSE, + FALSE); + } TableLayout *
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel