diff --git a/gnucash/report/reports/standard/test/test-transaction.scm b/gnucash/report/reports/standard/test/test-transaction.scm index dc5f662de8..d155e499bd 100644 --- a/gnucash/report/reports/standard/test/test-transaction.scm +++ b/gnucash/report/reports/standard/test/test-transaction.scm @@ -477,7 +477,7 @@ (lambda (name) (set-option! options "Display" name #f)) (list "Date" "Reconciled Date" "Num" "Description" "Memo" "Notes" - "Account Name" "Other Account Name" "Shares" "Price" "Running Balance" + "Account Name" "Other Account Name" "Shares" "Price" "Account Balance" "Totals")) (let ((sxml (options->sxml options "all columns off"))) (test-assert "all display columns off, except amount and subtotals are enabled, there should be 2 columns" @@ -535,12 +535,12 @@ (lambda (name) (set-option! options "Display" name #t)) (list "Date" "Reconciled Date" "Num" "Description" "Memo" "Notes" - "Account Name" "Other Account Name" "Shares" "Price" "Running Balance" + "Account Name" "Other Account Name" "Shares" "Price" "Account Balance" "Totals" "Use Full Other Account Name" "Use Full Account Name")) (let* ((sxml (options->sxml options "all columns on"))) (test-equal "all display columns on, displays correct columns" (list "Date" "Reconciled Date" "Num" "Description" "Memo/Notes" "Account" - "Transfer from/to" "Shares" "Price" "Amount" "Running Balance") + "Transfer from/to" "Shares" "Price" "Amount" "Account Balance") (get-row-col sxml 0 #f)) (test-assert "reconciled dates must be 01/03/70 or whitespace" (and-map @@ -679,6 +679,27 @@ (test-equal "dual amount column, first transaction correct" (list "$103 income" "Root.Asset.Bank" "$103.00" "$103.00") (cdr (get-row-col sxml 1 #f)))) + + ;; test account balance displayed as running balance + (set! options (default-testing-options)) + (set-option! options "Display" "Account Balance" #t) + (let* ((sxml (options->sxml options "running balance, default options"))) + (test-equal "running balance, default sort" + (list "Date" "Num" "Description" "Memo/Notes" "Account" "Amount" "Running Balance") + (get-row-col sxml 0 #f)) + (test-equal "running balance, showing Balance b/f" + (list "Bank: Balance b/f" "-$99.00") + (get-row-col sxml 1 #f))) + + (set-option! options "Sorting" "Primary Key" 'account-code) + (set-option! options "Sorting" "Secondary Key" 'date) + (let* ((sxml (options->sxml options "running balance, primary sort by account code, secondary sort by date"))) + (test-equal "running balance, secondary sort by date" + (list "Date" "Num" "Description" "Memo/Notes" "Account" "Amount" "Running Balance") + (get-row-col sxml 0 #f)) + (test-equal "running balance, showing Balance b/f" + (list "Bank: Balance b/f" "-$99.00") + (get-row-col sxml 1 #f))) ) (test-end "display options") diff --git a/gnucash/report/trep-engine.scm b/gnucash/report/trep-engine.scm index 977f5ad2ca..a0f2f90d3d 100644 --- a/gnucash/report/trep-engine.scm +++ b/gnucash/report/trep-engine.scm @@ -918,7 +918,7 @@ be excluded from periodic reporting.") (list (N_ "Price") "l" (G_ "Display the shares price?") #f) ;; note the "Amount" multichoice option in between here (list optname-grid "m5" (G_ "Display a subtotal summary table.") #f) - (list (N_ "Running Balance") "n" (G_ "Display a running balance?") #f) + (list (N_ "Account Balance") "n" (G_ "Display the balance of the underlying account on each line?") #f) (list (N_ "Totals") "o" (G_ "Display the totals?") #t))) (when BOOK-SPLIT-ACTION @@ -1033,7 +1033,7 @@ be excluded from periodic reporting.") (and (opt-val pagename-sorting optname-show-subtotals-only) (or (primary-get-info 'renderer-fn) (secondary-get-info 'renderer-fn)))) - (cons 'running-balance (opt-val gnc:pagename-display (N_ "Running Balance"))) + (cons 'running-balance (opt-val gnc:pagename-display (N_ "Account Balance"))) (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name"))) (cons 'memo (opt-val gnc:pagename-display (N_ "Memo"))) @@ -1091,6 +1091,26 @@ be excluded from periodic reporting.") (define (column-uses? param) (assq-ref used-columns param)) + ; Helper function to decide if an account balance can be displayed + ; as a running balance with a balance forward at the top. + ; It implies most default options are maintained : + ; - Detail level is set to one transaction per line, + ; - Date filter is set to date posted + ; - Filtering on transactions is kept as per default + ; - The primary sort is set to account name (or code) + ; - The primary subtotals are displayed (to separate accounts) + ; - The secondary sort is set to register order or date ascending. + (define show-bal-bf? + (and (eq? (opt-val gnc:pagename-display optname-detail-level) 'single) + (eq? (opt-val gnc:pagename-general optname-date-source) 'posted) + (string-null? (opt-val pagename-filter optname-transaction-matcher)) + (eq? (opt-val pagename-filter optname-reconcile-status) 'all) + (eq? (opt-val pagename-filter optname-void-transactions) 'non-void-only) + (memq (opt-val pagename-sorting optname-prime-sortkey) '(account-name account-code)) + (memq (opt-val pagename-sorting optname-sec-sortkey) '(register-order date)) + (opt-val pagename-sorting optname-prime-subtotal) + (eq? (opt-val pagename-sorting optname-sec-sortorder) 'ascend))) + (define exchange-fn (if (column-uses? 'common-currency) (gnc:case-exchange-time-fn @@ -1274,6 +1294,13 @@ be excluded from periodic reporting.") (converted-credit-amount (lambda (s) (and (not (positive? (split-amount s))) (gnc:monetary-neg (converted-amount s))))) + (converted-account-balance (lambda (s) + (exchange-fn + (gnc:make-gnc-monetary (split-currency s) + (xaccSplitGetBalance s)) + (row-currency s) + (time64CanonicalDayTime + (xaccTransGetDate (xaccSplitGetParent s)))))) (original-amount (lambda (s) (gnc:make-gnc-monetary (split-currency s) (split-amount s)))) @@ -1283,7 +1310,7 @@ be excluded from periodic reporting.") (original-credit-amount (lambda (s) (and (not (positive? (split-amount s))) (gnc:monetary-neg (original-amount s))))) - (running-balance (lambda (s) + (original-account-balance (lambda (s) (gnc:make-gnc-monetary (split-currency s) (xaccSplitGetBalance s))))) (append @@ -1299,6 +1326,8 @@ be excluded from periodic reporting.") ;; friendly-heading-fn (friendly-heading-fn account) to retrieve ;; friendly name for account debit/credit ;; or 'bal-bf for balance-brought-forward + ;; or 'original-bal-bf for bal-bf in original currency + ;; when currency conversion is used ;; start-dual-column? #t: merge with next cell for subtotal table. (if (column-uses? 'amount-single) @@ -1316,6 +1345,16 @@ be excluded from periodic reporting.") friendly-credit #f)) '()) + (if (column-uses? 'running-balance) + (if show-bal-bf? + (list (vector (header-commodity (G_ "Running Balance")) + converted-account-balance #t #f #f + 'bal-bf #f)) + (list (vector (header-commodity (G_ "Account Balance")) + converted-account-balance #t #f #f + #f #f))) + '()) + (if (and (column-uses? 'amount-original-currency) (column-uses? 'amount-single)) (list (vector (G_ "Amount") @@ -1333,10 +1372,15 @@ be excluded from periodic reporting.") friendly-credit #f)) '()) - (if (column-uses? 'running-balance) - (list (vector (G_ "Running Balance") - running-balance #t #f #f - 'bal-bf #f)) + (if (and (column-uses? 'amount-original-currency) + (column-uses? 'running-balance)) + (if show-bal-bf? + (list (vector (G_ "Running Balance") + original-account-balance #t #f #f + 'original-bal-bf #f)) + (list (vector (G_ "Account Balance") + original-account-balance #t #f #f + #f #f))) '())))) (define calculated-cells @@ -1411,6 +1455,21 @@ be excluded from periodic reporting.") (match (vector-ref cell 5) (#f #f) ('bal-bf + (let* ((acc (xaccSplitGetAccount split)) + (bal (exchange-fn + (gnc:make-gnc-monetary + (xaccAccountGetCommodity acc) + (xaccAccountGetBalanceAsOfDate acc begindate)) + (if (column-uses? 'common-currency) + (opt-val pagename-currency optname-currency) + (xaccAccountGetCommodity acc)) + (time64CanonicalDayTime + (xaccTransGetDate (xaccSplitGetParent split)))))) + (and (memq sortkey ACCOUNT-SORTING-TYPES) + (gnc:make-html-table-cell/markup + "number-cell" + (if (acc-reverse? acc) (gnc:monetary-neg bal) bal))))) + ('original-bal-bf (let* ((acc (xaccSplitGetAccount split)) (bal (xaccAccountGetBalanceAsOfDate acc begindate))) (and (memq sortkey ACCOUNT-SORTING-TYPES) diff --git a/libgnucash/engine/gnc-optiondb.cpp b/libgnucash/engine/gnc-optiondb.cpp index 021b119968..a7498805c1 100644 --- a/libgnucash/engine/gnc-optiondb.cpp +++ b/libgnucash/engine/gnc-optiondb.cpp @@ -115,6 +115,8 @@ const OptionAliases Aliases::c_option_aliases // ... replaced to …, Dec 2022 {"Filter By...", {nullptr, "Filter By…"}}, {"Specify date to filter by...", {nullptr, "Specify date to filter by…"}}, + // trep-engine: + {"Running Balance", {nullptr, "Account Balance"}}, }; static bool