gnucash master: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Sun Oct 27 11:52:53 EDT 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/02e86a4c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d8937234 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f4a90843 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0ef11d16 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6eab852f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/eb929fd6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/77855a7e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0aad7778 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2dd2f0dc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7ec1596e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dc831084 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b2fcfbd3 (commit)
	from  https://github.com/Gnucash/gnucash/commit/5f6aa6ed (commit)



commit 02e86a4c6af25e43b16ee3106d01e5f89f8f9c8a
Merge: 5f6aa6ed4 d89372347
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 22:03:55 2019 +0800

    Merge branch 'maint'

diff --cc gnucash/report/reports/CMakeLists.txt
index 00032d12f,000000000..b1daa74bc
mode 100644,000000..100644
--- a/gnucash/report/reports/CMakeLists.txt
+++ b/gnucash/report/reports/CMakeLists.txt
@@@ -1,226 -1,0 +1,228 @@@
 +
 +add_subdirectory(standard/test)
 +add_subdirectory(support)
 +
 +set (reports_common_SCHEME
 +  aging.scm
 +)
 +
 +set (reports_standard_SCHEME
 +    standard/account-piecharts.scm
 +    standard/account-summary.scm
 +    standard/advanced-portfolio.scm
 +    standard/balance-sheet.scm
 +    standard/balance-forecast.scm
 +    standard/balsheet-pnl.scm
 +    standard/budget-balance-sheet.scm
 +    standard/budget-barchart.scm
 +    standard/budget-flow.scm
 +    standard/budget-income-statement.scm
 +    standard/budget.scm
 +    standard/cash-flow.scm
 +    standard/cashflow-barchart.scm
 +    standard/category-barchart.scm
 +    standard/dashboard.scm
 +    standard/equity-statement.scm
 +    standard/general-journal.scm
 +    standard/general-ledger.scm
 +    standard/income-gst-statement.scm
 +    standard/income-statement.scm
 +    standard/net-charts.scm
++    standard/new-owner-report.scm
 +    standard/portfolio.scm
 +    standard/price-scatter.scm
 +    standard/reconcile-report.scm
 +    standard/register.scm
 +    standard/transaction.scm
 +    standard/trial-balance.scm
 +    standard/view-column.scm
 +    standard/taxinvoice.scm
 +    standard/receipt.scm
 +    standard/invoice.scm
 +    standard/job-report.scm
 +    standard/owner-report.scm
 +    standard/payables.scm
 +    standard/receivables.scm
 +    standard/balsheet-eg.scm
 +)
 +
 +set (reports_standard_SCHEME_2
 +    standard/customer-summary.scm # Depends on owner-report
++    standard/new-aging.scm        # ditto
 +)
 +
 +set(reports_example_SCHEME
 +  example/average-balance.scm
 +  example/daily-reports.scm
 +  example/hello-world.scm
 +  example/sample-graphs.scm
 +  example/welcome-to-gnucash.scm
 +)
 +
 +set(reports_us_SCHEME
 +  locale-specific/us/taxtxf.scm
 +)
 +
 +set(reports_de_DE_SCHEME
 +  locale-specific/de_DE/taxtxf.scm
 +)
 +
 +set (reports_SCHEME
 +  reports.scm
 +)
 +
 +set(scm_rpts_GUILE_DEPENDS
 +  gncmod-html
 +  scm-core-utils
 +  scm-engine
 +  scm-gettext
 +  scm-scm
 +  scm-gnome-utils
 +  scm-report
 +  )
 +
 +set(scm_rpt_example_GUILE_DEPENDS
 +  gncmod-html
 +  scm-app-utils
 +  scm-core-utils
 +  scm-gettext
 +  scm-gnc-module
 +  scm-scm
 +  scm-reports-example-links
 +  scm-gnome-utils
 +  scm-report
 +  )
 +
 +set(scm_rpt_locale_specific_GUILE_DEPENDS
 +  gncmod-html
 +  scm-core-utils
 +  scm-gettext
 +  scm-gnc-module
 +  scm-scm
 +  scm-test-core
 +  scm-locale-tax
 +  scm-report
 +  scm-gnome-utils
 +  )
 +
 +set(scm_rpt_std_GUILE_DEPENDS
 +  ${scm_rpts_GUILE_DEPENDS}
 +  scm-app-utils
 +  scm-gnc-module
 +  scm-reports-common-links
 +  scm-reports-standard-links
 +  )
 +
 +gnc_add_scheme_targets(scm-reports-common
 +  "${reports_common_SCHEME}"
 +  "gnucash/reports"
 +  "scm-reports-common-links;${scm_rpt_std_GUILE_DEPENDS}"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-reports-standard
 +  "${reports_standard_SCHEME}"
 +  "gnucash/reports/standard"
 +  "scm-reports-common;${scm_rpt_std_GUILE_DEPENDS}"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-reports-example
 +  "${reports_example_SCHEME}"
 +  "gnucash/reports/example"
 +  "${scm_rpt_example_GUILE_DEPENDS}"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-reports-us
 +  "${reports_us_SCHEME}"
 +  "gnucash/reports/locale-specific/us"
 +  "${scm_rpt_locale_specific_GUILE_DEPENDS}"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-reports-de_DE
 +  "${reports_de_DE_SCHEME}"
 +  "gnucash/reports/locale-specific/de_DE"
 +  "${scm_rpt_locale_specific_GUILE_DEPENDS}"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-rpt-reports
 +  "${reports_SCHEME}"
 +  "gnucash"
 +  "scm-reports-standard;scm-reports-example;scm-reports-us;scm-reports-de_DE;${scm_rpts_GUILE_DEPENDS};"
 +  TRUE
 +)
 +
 +gnc_add_scheme_targets(scm-reports-standard-2
 +  "${reports_standard_SCHEME_2}"
 +  "gnucash/reports/standard"
 +  "scm-rpt-reports"
 +  TRUE
 +)
 +
 +add_custom_target(scm-reports ALL DEPENDS
 +    scm-reports-standard
 +    scm-reports-standard-2
 +    scm-reports-example
 +    scm-reports-common
 +    scm-rpt-reports
 +    scm-reports-us
 +    scm-reports-de_DE)
 +
 +# Module interfaces deprecated in 4.x, will be removed for 5.x
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports" "gnucash reports" "scm-rpt-reports" "")
 +gnc_add_scheme_deprecated_module ("gnucash report aging" "gnucash reports aging" "scm-reports-common" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports average-balance" "gnucash reports example average-balance" "scm-reports-example" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports daily-reports" "gnucash reports example daily-reports" "scm-reports-example" "")
 +gnc_add_scheme_deprecated_module ("gnucash report hello-world" "gnucash reports example hello-world" "scm-reports-example" "")
 +gnc_add_scheme_deprecated_module ("gnucash report test-graphing" "gnucash reports example sample-graphs" "scm-reports-example" "")
 +gnc_add_scheme_deprecated_module ("gnucash report locale-specific de_DE" "gnucash reports locale-specific de_DE taxtxf" "scm-reports-de_DE" "")
 +gnc_add_scheme_deprecated_module ("gnucash report taxtxf-de_DE" "gnucash reports locale-specific de_DE taxtxf" "scm-reports-de_DE" "")
 +gnc_add_scheme_deprecated_module ("gnucash report locale-specific us" "gnucash reports locale-specific us taxtxf" "scm-reports-us" "")
 +gnc_add_scheme_deprecated_module ("gnucash report taxtxf" "gnucash reports locale-specific us taxtxf" "scm-reports-us" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports account-piecharts" "gnucash reports standard account-piecharts" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports account-summary" "gnucash reports standard account-summary" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports advanced-portfolio" "gnucash reports standard advanced-portfolio" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports balance-forecast" "gnucash reports standard balance-forecast" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports balance-sheet" "gnucash reports standard balance-sheet" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report balsheet-eg" "gnucash reports standard balsheet-eg" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports balsheet-pnl" "gnucash reports standard balsheet-pnl" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports budget-balance-sheet" "gnucash reports standard budget-balance-sheet" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports budget-barchart" "gnucash reports standard budget-barchart" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports budget-flow" "gnucash reports standard budget-flow" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports budget" "gnucash reports standard budget" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports budget-income-statement" "gnucash reports standard budget-income-statement" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports cashflow-barchart" "gnucash reports standard cashflow-barchart" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports cash-flow" "gnucash reports standard cash-flow" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports category-barchart" "gnucash reports standard category-barchart" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report customer-summary" "gnucash reports standard customer-summary" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report welcome-to-gnucash" "gnucash reports standard dashboard" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports equity-statement" "gnucash reports standard equity-statement" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports general-journal" "gnucash reports standard general-journal" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports general-ledger" "gnucash reports standard general-ledger" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports income-gst-statement" "gnucash reports standard income-gst-statement" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports income-statement" "gnucash reports standard income-statement" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report invoice" "gnucash reports standard invoice" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report job-report" "gnucash reports standard job-report" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports net-charts" "gnucash reports standard net-charts" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report owner-report" "gnucash reports standard owner-report" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report payables" "gnucash reports standard payables" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports portfolio" "gnucash reports standard portfolio" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports price-scatter" "gnucash reports standard price-scatter" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report receipt" "gnucash reports standard receipt" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report receivables" "gnucash reports standard receivables" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports reconcile-report" "gnucash reports standard reconcile-report" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports register" "gnucash reports standard register" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports sx-summary" "gnucash reports standard account-summary" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report taxinvoice" "gnucash reports standard taxinvoice" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports transaction" "gnucash reports standard transaction" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report standard-reports trial-balance" "gnucash reports standard trial-balance" "scm-reports-standard" "")
 +gnc_add_scheme_deprecated_module ("gnucash report view-column" "gnucash reports standard view-column" "scm-reports-standard" "")
 +
 +set_local_dist(reports_DIST_local CMakeLists.txt ${reports_SCHEME}
 +    ${reports_common_SCHEME} ${reports_standard_SCHEME}  ${reports_standard_SCHEME_2}
 +    ${reports_example_SCHEME} ${reports_us_SCHEME} ${reports_de_DE_SCHEME})
 +set(reports_DIST ${reports_DIST_local} ${reports_support_DIST}
 +    ${test_reports_standard_DIST} PARENT_SCOPE)
diff --cc gnucash/report/reports/standard/new-aging.scm
index 000000000,1ef00c521..9129c076a
mode 000000,100644..100644
--- a/gnucash/report/reports/standard/new-aging.scm
+++ b/gnucash/report/reports/standard/new-aging.scm
@@@ -1,0 -1,316 +1,315 @@@
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; new-aging.scm : accounts payable/receivable aging report
+ ;;
+ ;; By Christopher Lam, rewrite and debug
+ ;; By Derek Atkins <warlord at MIT.EDU> taken from the original...
+ ;; By Robert Merkel (rgmerk at mira.net)
+ ;; Copyright (c) 2002, 2003 Derek Atkins <warlord at MIT.EDU>
+ ;;
+ ;; This program is free software; you can redistribute it and/or
+ ;; modify it under the terms of the GNU General Public License as
+ ;; published by the Free Software Foundation; either version 2 of
+ ;; the License, or (at your option) any later version.
+ ;;
+ ;; This program is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;;
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with this program; if not, contact:
+ ;;
+ ;; Free Software Foundation           Voice:  +1-617-542-5942
+ ;; 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ ;; Boston, MA  02110-1301,  USA       gnu at gnu.org
+ ;;
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
 -(define-module (gnucash report new-aging))
++(define-module (gnucash reports standard new-aging))
+ 
+ (use-modules (srfi srfi-1))
+ (use-modules (srfi srfi-11))            ;let-values
+ (use-modules (gnucash utilities))
+ (use-modules (gnucash gnc-module))
+ (use-modules (gnucash gettext))
+ 
 -(gnc:module-load "gnucash/report/report-system" 0)
++(gnc:module-load "gnucash/report" 0)
+ 
 -(use-modules (gnucash report standard-reports))
 -(use-modules (gnucash report business-reports))
++(use-modules (gnucash reports))
+ 
+ (define optname-to-date (N_ "To"))
+ (define optname-sort-order (N_ "Sort Order"))
+ (define optname-report-currency (N_ "Report's currency"))
+ (define optname-price-source (N_ "Price Source"))
+ (define optname-show-zeros (N_ "Show zero balance items"))
+ (define optname-date-driver (N_ "Due or Post Date"))
+ 
+ (define no-APAR-account (_ "No valid A/Payable or A/Receivable \
+ account found. Please ensure valid AP/AR account exists."))
+ 
+ (define empty-APAR-accounts (_ "A/Payable or A/Receivable accounts \
+ exist but have no suitable transactions."))
+ 
+ (define num-buckets 6)
+ 
+ (define (setup-query query accounts date)
+   (qof-query-set-book query (gnc-get-current-book))
+   (gnc:query-set-match-non-voids-only! query (gnc-get-current-book))
+   (xaccQueryAddAccountMatch query accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+   (xaccQueryAddDateMatchTT query #f 0 #t date QOF-QUERY-AND)
+   (qof-query-set-sort-order query (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+   (qof-query-set-sort-increasing query #t #t #t))
+ 
+ (define (aging-options-generator options)
+   (let* ((add-option
+           (lambda (new-option)
+             (gnc:register-option options new-option))))
+ 
+     (gnc:options-add-report-date!
+      options gnc:pagename-general optname-to-date "a")
+ 
+     ;; Use a default report date of 'today'
+     (gnc:option-set-default-value
+      (gnc:lookup-option options gnc:pagename-general optname-to-date)
+      (cons 'relative 'today))
+ 
+     (add-option
+      (gnc:make-multichoice-option
+       gnc:pagename-general optname-sort-order "ia" (N_ "Sort order.") 'increasing
+       (list
+        (vector 'increasing (N_ "Increasing") (N_ "Alphabetical order"))
+        (vector 'decreasing (N_ "Decreasing") (N_ "Reverse alphabetical order")))))
+ 
+     (add-option
+      (gnc:make-simple-boolean-option
+       gnc:pagename-general optname-show-zeros "j"
+       (N_ "Show all vendors/customers even if they have a zero balance.")
+       #f))
+ 
+     (add-option
+      (gnc:make-multichoice-option
+       gnc:pagename-general optname-date-driver "k" (N_ "Leading date.") 'duedate
+       (list
+        ;; Should be using standard label for due date?
+        (vector 'duedate
+                (N_ "Due Date")
+                (N_ "Due date is leading."))
+        ;; Should be using standard label for post date?
+        (vector 'postdate
+                (N_ "Post Date")
+                (N_ "Post date is leading.")))))
+ 
+     (gnc:options-set-default-section options "General")
+     options))
+ 
+ (define (txn-is-invoice? txn)
+   (eqv? (xaccTransGetTxnType txn) TXN-TYPE-INVOICE))
+ 
+ (define (txn-is-payment? txn)
+   (eqv? (xaccTransGetTxnType txn) TXN-TYPE-PAYMENT))
+ 
+ (define (gnc-owner-equal? a b)
+   (string=? (gncOwnerReturnGUID a) (gncOwnerReturnGUID b)))
+ 
+ (define (split-has-owner? split owner)
+   (let* ((split-owner (split->owner split))
+          (retval (gnc-owner-equal? split-owner owner)))
+     (gncOwnerFree split-owner)
+     retval))
+ 
+ (define (split-from-acct? split acct)
+   (equal? acct (xaccSplitGetAccount split)))
+ 
+ (define (list-split lst fn cmp)
+   (let-values (((list-yes list-no) (partition (lambda (elt) (fn elt cmp)) lst)))
+     (cons list-yes list-no)))
+ 
+ ;; simpler version of gnc:owner-from-split. must be gncOwnerFree after
+ ;; use! see split-has-owner? above...
+ (define (split->owner split)
+   (let* ((lot (xaccSplitGetLot (gnc-lot-get-earliest-split (xaccSplitGetLot split))))
+          (owner (gncOwnerNew))
+          (use-lot-owner? (gncOwnerGetOwnerFromLot lot owner)))
+     (unless use-lot-owner?
+       (gncOwnerCopy (gncOwnerGetEndOwner
+                      (gncInvoiceGetOwner (gncInvoiceGetInvoiceFromLot lot)))
+                     owner))
+     owner))
+ 
+ (define (aging-renderer report-obj receivable)
+   (define (op-value section name)
+     (gnc:option-value
+      (gnc:lookup-option (gnc:report-options report-obj) section name)))
+ 
+   (define make-heading-list
+     (list ""
+           (_ "Company")
+           (_ "Prepayments")
+           (_ "Current")
+           (_ "0-30 days")
+           (_ "31-60 days")
+           (_ "61-90 days")
+           (_ "91+ days")
+           (_ "Total")))
+ 
+   (let* ((type (if receivable ACCT-TYPE-RECEIVABLE ACCT-TYPE-PAYABLE))
+          (accounts (filter (lambda (acc) (eqv? (xaccAccountGetType acc) type))
+                            (gnc-account-get-descendants-sorted
+                             (gnc-get-current-root-account))))
+          (report-title (op-value gnc:pagename-general gnc:optname-reportname))
+          (report-date (gnc:time64-end-day-time
+                        (gnc:date-option-absolute-time
+                         (op-value gnc:pagename-general optname-to-date))))
+          (sort-order (op-value gnc:pagename-general optname-sort-order))
+          (show-zeros (op-value gnc:pagename-general optname-show-zeros))
+          (date-type (op-value gnc:pagename-general optname-date-driver))
+          (query (qof-query-create-for-splits))
+          (document (gnc:make-html-document)))
+ 
+     ;; for sorting and delete-duplicates. compare GUIDs
+     (define (ownerGUID<? a b)
+       (string<? (gncOwnerGetGUID a) (gncOwnerGetGUID b)))
+ 
+     ;; for presentation. compare names.
+     (define (owner<? a b)
+       ((if (eq? sort-order 'increasing) string<? string>?)
+        (gncOwnerGetName a) (gncOwnerGetName b)))
+ 
+     ;; set default title
+     (gnc:html-document-set-title! document report-title)
+ 
+     (cond
+      ((null? accounts)
+       (gnc:html-document-add-object!
+        document (gnc:make-html-text no-APAR-account)))
+ 
+      (else
+       (setup-query query accounts report-date)
+       (let* ((splits (qof-query-run query))
+              (accounts (sort-and-delete-duplicates (map xaccSplitGetAccount splits)
+                                                    gnc:account-path-less-p equal?))
+              (table (gnc:make-html-table)))
+         (qof-query-destroy query)
+ 
+         ;; loop into each APAR account
+         (let loop ((accounts accounts)
+                    (splits (filter
+                             (lambda (split)
+                               (or (txn-is-invoice? (xaccSplitGetParent split))
+                                   (txn-is-payment? (xaccSplitGetParent split))))
+                             splits)))
+           (cond
+            ((null? accounts)
+             (gnc:html-table-set-col-headers! table make-heading-list)
+             (gnc:html-document-add-object!
+              document (if (null? (gnc:html-table-data table))
+                           (gnc:make-html-text empty-APAR-accounts)
+                           table)))
+ 
+            (else
+             (let* ((account (car accounts))
+                    (comm (xaccAccountGetCommodity account))
+                    (splits-acc-others (list-split splits split-from-acct? account))
+                    (acc-splits (car splits-acc-others))
+                    (other-acc-splits (cdr splits-acc-others)))
+ 
+               (gnc:debug 'account account)
+               (gnc:html-table-append-row!
+                table (list (gnc:make-html-table-cell/size
+                             1 (+ 2 num-buckets) (xaccAccountGetName account))))
+ 
+               (let* ((split-owners (map split->owner acc-splits))
+                      (acc-owners (sort (sort-and-delete-duplicates
+                                         split-owners ownerGUID<? gnc-owner-equal?)
+                                        owner<?)))
+ 
+                 (gnc:debug 'owners acc-owners)
+ 
+                 ;; loop into each APAR account split
+                 (let lp ((acc-owners acc-owners)
+                          (acc-splits acc-splits)
+                          (acc-totals (make-list (1+ num-buckets) 0)))
+                   (cond
+                    ((null? acc-owners)
+                     (for-each gncOwnerFree split-owners)
+                     (gnc:html-table-append-row!
+                      table
+                      (cons* #f
+                             (gnc:make-html-table-cell/markup
+                              "total-label-cell" (_ "Total"))
+                             (map
+                              (lambda (amt)
+                                (gnc:make-html-table-cell/markup
+                                 "total-number-cell" (gnc:make-gnc-monetary comm amt)))
+                              acc-totals)))
+                     (loop (cdr accounts)
+                           other-acc-splits))
+ 
+                    (else
+                     (let* ((owner (car acc-owners))
+                            (splits-own-others (list-split acc-splits split-has-owner?
+                                                           owner))
+                            (owner-splits (car splits-own-others))
+                            (other-owner-splits (cdr splits-own-others))
+                            (aging (gnc:owner-splits->aging-list
+                                    owner-splits num-buckets report-date
+                                    date-type receivable))
+                            (aging-total (apply + aging)))
+                       (when (or show-zeros (not (every zero? aging)))
+                         (gnc:html-table-append-row!
+                          table
+                          (append
+                           (list #f)
+                           (cons
+                            (gnc:make-html-text
+                             (gnc:html-markup-anchor
+                              (gnc:owner-anchor-text owner)
+                              (gncOwnerGetName owner)))
+                            (map
+                             (lambda (amt)
+                               (gnc:make-html-table-cell/markup
+                                "number-cell" (gnc:make-gnc-monetary comm amt)))
+                             (reverse aging)))
+                           (list
+                            (gnc:make-html-table-cell/markup
+                             "number-cell"
+                             (gnc:make-html-text
+                              (gnc:html-markup-anchor
+                               (gnc:owner-report-text owner account)
+                               (gnc:make-gnc-monetary comm aging-total))))))))
+                       (lp (cdr acc-owners)
+                           other-owner-splits
+                           (map + acc-totals
+                                (reverse (cons aging-total aging))))))))))))))))
+     (gnc:report-finished)
+     document))
+ 
+ (define (payable-options-generator)
+   (aging-options-generator (gnc:new-options)))
+ 
+ (define (receivable-options-generator)
+   (aging-options-generator (gnc:new-options)))
+ 
+ (define (payables-renderer report-obj)
+   (aging-renderer report-obj #f))
+ 
+ (define (receivables-renderer report-obj)
+   (aging-renderer report-obj #t))
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Payable Aging (beta)")
+  'report-guid "e57770f2dbca46619d6dac4ac5469b50-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator payable-options-generator
+  'renderer payables-renderer
+  'in-menu? #t)
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Receivable Aging (beta)")
+  'report-guid "9cf76bed17f14401b8e3e22d0079cb98-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator receivable-options-generator
+  'renderer receivables-renderer
+  'in-menu? #t)
diff --cc gnucash/report/reports/standard/new-owner-report.scm
index 000000000,6665c18b0..05d9071a5
mode 000000,100644..100644
--- a/gnucash/report/reports/standard/new-owner-report.scm
+++ b/gnucash/report/reports/standard/new-owner-report.scm
@@@ -1,0 -1,891 +1,889 @@@
+ ;; -*-scheme-*-
+ ;; owner-report.scm -- Print out a detailed owner report, which is a
+ ;;                     summary of invoices and payments for a particular
+ ;;                     company (the owner) applied to an account.
+ ;;
+ ;; Created by:  Derek Atkins <warlord at MIT.EDU>
+ ;; Copyright (c) 2002, 2003 Derek Atkins <warlord at MIT.EDU>
+ ;; Modified by AMM to show tax figures of invoice.
+ ;; Modified by Christopher Lam to combine job/owner-report
+ ;;
+ ;; This program is free software; you can redistribute it and/or
+ ;; modify it under the terms of the GNU General Public License as
+ ;; published by the Free Software Foundation; either version 2 of
+ ;; the License, or (at your option) any later version.
+ ;;
+ ;; This program is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;;
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with this program; if not, contact:
+ ;;
+ ;; Free Software Foundation           Voice:  +1-617-542-5942
+ ;; 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ ;; Boston, MA  02110-1301,  USA       gnu at gnu.org
+ 
+ 
 -(define-module (gnucash report new-owner-report))
++(define-module (gnucash reports standard new-owner-report))
+ 
+ (use-modules (srfi srfi-1))
+ (use-modules (srfi srfi-8))
+ (use-modules (srfi srfi-11))             ;for let-values
+ (use-modules (gnucash gnc-module))
+ (use-modules (gnucash utilities))        ; for gnc:debug
+ (use-modules (gnucash gettext))
+ 
 -(gnc:module-load "gnucash/report/report-system" 0)
 -(use-modules (gnucash report standard-reports))
 -(use-modules (gnucash report business-reports))
 -(use-modules (gnucash report new-aging)) ;for gnc:owner-splits->aging-list
++(gnc:module-load "gnucash/report" 0)
++(use-modules (gnucash reports))
+ 
+ ;; Option names
+ (define optname-from-date (N_ "From"))
+ (define optname-to-date (N_ "To"))
+ (define optname-date-driver (N_ "Due or Post Date"))
+ 
+ (define owner-page gnc:pagename-general)
+ (define date-header (N_ "Date"))
+ (define due-date-header (N_ "Due Date"))
+ (define reference-header (N_ "Reference"))
+ (define type-header (N_ "Type"))
+ (define desc-header (N_ "Description"))
+ (define sale-header (N_ "Sale"))
+ (define tax-header (N_ "Tax"))
+ (define credit-header (N_ "Credits"))
+ (define debit-header (N_ "Debits"))
+ (define amount-header (N_ "Balance"))
+ (define linked-txns-header (N_ "Links"))
+ 
+ ;; Depending on the report type we want to set up some lists/cases
+ ;; with strings to ease overview and translation
+ (define owner-string-alist
+   (list
+    (list GNC-OWNER-CUSTOMER
+          (N_ "Customer")
+          (_ "No valid customer selected.")
+          (_ "This report requires a customer to be selected."))
+ 
+    (list GNC-OWNER-EMPLOYEE
+          (N_ "Employee")
+          (_ "No valid employee selected.")
+          (_ "This report requires a employee to be selected."))
+ 
+    (list GNC-OWNER-JOB
+          (N_ "Job")
+          (_ "No valid job selected.")
+          (_ "This report requires a job to be selected."))
+ 
+    (list GNC-OWNER-VENDOR
+          (N_ "Vendor")
+          (_ "No valid vendor selected.")
+          (_ "This report requires a vendor to be selected."))))
+ 
+ (define (get-info key)
+   (assv-ref owner-string-alist key))
+ 
+ ;; Names in Option panel (Untranslated! Because it is used for option
+ ;; naming and lookup only, and the display of the option name will be
+ ;; translated somewhere else.)
+ (define (owner-string owner-type)
+   (car (get-info owner-type)))
+ 
+ (define (date-col columns-used)
+   (vector-ref columns-used 0))
+ (define (date-due-col columns-used)
+   (vector-ref columns-used 1))
+ (define (num-col columns-used)
+   (vector-ref columns-used 2))
+ (define (type-col columns-used)
+   (vector-ref columns-used 3))
+ (define (memo-col columns-used)
+   (vector-ref columns-used 4))
+ (define (sale-col columns-used)
+   (vector-ref columns-used 5))
+ (define (tax-col columns-used)
+   (vector-ref columns-used 6))
+ (define (credit-col columns-used)
+   (vector-ref columns-used 7))
+ (define (debit-col columns-used)
+   (vector-ref columns-used 8))
+ (define (value-col columns-used)
+   (vector-ref columns-used 9))
+ 
+ (define columns-used-size 10)
+ 
+ (define (build-column-used options)
+   (define (opt-val section name)
+     (gnc:option-value
+      (gnc:lookup-option options section name)))
+   (define (make-set-col col-vector)
+     (let ((col 0))
+       (lambda (used? index)
+         (if used?
+             (begin
+               (vector-set! col-vector index col)
+               (set! col (+ col 1)))
+             (vector-set! col-vector index #f)))))
+ 
+   (let* ((col-vector (make-vector columns-used-size #f))
+          (set-col (make-set-col col-vector)))
+     (set-col (opt-val "Display Columns" date-header) 0)
+     (set-col (opt-val "Display Columns" due-date-header) 1)
+     (set-col (opt-val "Display Columns" reference-header) 2)
+     (set-col (opt-val "Display Columns" type-header) 3)
+     (set-col (opt-val "Display Columns" desc-header) 4)
+     (set-col (opt-val "Display Columns" sale-header) 5)
+     (set-col (opt-val "Display Columns" tax-header) 6)
+     (set-col (opt-val "Display Columns" credit-header) 7)
+     (set-col (opt-val "Display Columns" debit-header) 8)
+     (set-col (opt-val "Display Columns" amount-header) 9)
+     col-vector))
+ 
+ (define (make-heading-list column-vector link-option)
+   (let ((heading-list '()))
+     (if (date-col column-vector)
+         (addto! heading-list (_ date-header)))
+     (if (date-due-col column-vector)
+         (addto! heading-list (_ due-date-header)))
+     (if (num-col column-vector)
+         (addto! heading-list (_ reference-header)))
+     (if (type-col column-vector)
+         (addto! heading-list (_ type-header)))
+     (if (memo-col column-vector)
+         (addto! heading-list (_ desc-header)))
+     (if (sale-col column-vector)
+         (addto! heading-list (_ sale-header)))
+     (if (tax-col column-vector)
+         (addto! heading-list (_ tax-header)))
+     (if (credit-col column-vector)
+         (addto! heading-list (_ credit-header)))
+     (if (debit-col column-vector)
+         (addto! heading-list (_ debit-header)))
+     (if (value-col column-vector)
+         (addto! heading-list (_ amount-header)))
+     (case link-option
+       ((simple)
+        (addto! heading-list (_ linked-txns-header)))
+       ((detailed)
+        (addto! heading-list (_ "Date"))
+        (addto! heading-list (_ "Details"))
+        (addto! heading-list (_ "Amount"))))
+     (reverse heading-list)))
+ 
+ (define num-buckets 6)
+ (define (new-bucket-vector)
+   (make-vector num-buckets 0))
+ 
+ (define (txn-is-invoice? txn)
+   (eqv? (xaccTransGetTxnType txn) TXN-TYPE-INVOICE))
+ (define (txn-is-payment? txn)
+   (eqv? (xaccTransGetTxnType txn) TXN-TYPE-PAYMENT))
+ 
+ (define (make-aging-table splits to-date reverse? date-type currency)
+   (let ((table (gnc:make-html-table))
+         (aging-list (gnc:owner-splits->aging-list
+                      splits num-buckets to-date date-type reverse?)))
+ 
+     (gnc:html-table-set-col-headers!
+      table (list (_ "Prepayments")
+                  (_ "Current")
+                  (_ "0-30 days")
+                  (_ "31-60 days")
+                  (_ "61-90 days")
+                  (_ "91+ days")
+                  (_ "Total")))
+ 
+     (gnc:html-table-append-row!
+      table (map (lambda (entry) (gnc:make-gnc-monetary currency entry))
+                 (reverse (cons (apply + aging-list) aging-list))))
+     table))
+ 
+ ;; addif is a macro; a simple procedure will always evaluate the
+ ;; arguments pred? and elt which is not desirable; a macro will ensure
+ ;; elt is only evaluated if pred? is not #f
+ (define-syntax-rule (addif pred? elt)
+   (if pred? (list elt) '()))
+ 
+ (define (make-cell elt) (gnc:make-html-table-cell/markup "number-cell" elt))
+ 
+ ;;
+ ;; Make a row list based on the visible columns
+ ;;
+ (define (add-row table odd-row? column-vector date due-date num type-str
+                  memo currency amt credit debit sale tax link-rows)
+   (define empty-cols
+     (count identity
+            (map (lambda (f) (f column-vector))
+                 (list date-col date-due-col num-col type-col
+                       memo-col sale-col tax-col credit-col
+                       debit-col value-col))))
+   (define (cell amt)
+     (and amt (make-cell (gnc:make-gnc-monetary currency amt))))
+   (let lp ((link-rows link-rows)
+            (first-row? #t))
+     (unless (null? link-rows)
+       (if first-row?
+           (gnc:html-table-append-row/markup!
+            table (if odd-row? "normal-row" "alternate-row")
+            (append
+             (addif (date-col column-vector) (qof-print-date date))
+             (addif (date-due-col column-vector)
+                    (and due-date (qof-print-date due-date)))
+             (addif (num-col column-vector)    (gnc:html-string-sanitize num))
+             (addif (type-col column-vector)   type-str)
+             (addif (memo-col column-vector)   (gnc:html-string-sanitize memo))
+             (addif (sale-col column-vector)   (cell sale))
+             (addif (tax-col column-vector)    (cell tax))
+             (addif (credit-col column-vector) (cell credit))
+             (addif (debit-col column-vector)  (cell (and debit (- debit))))
+             (addif (value-col column-vector)  (cell amt))
+             (car link-rows)))
+           (gnc:html-table-append-row/markup!
+            table (if odd-row? "normal-row" "alternate-row")
+            (cons
+             (gnc:make-html-table-cell/size 1 empty-cols #f)
+             (car link-rows))))
+       (lp (cdr link-rows) #f))))
+ 
+ (define (add-owner-table table splits acc start-date end-date date-type
+                          used-columns reverse? link-option)
+   (define currency (xaccAccountGetCommodity acc))
+   (define link-cols (assq-ref '((none . 0) (simple . 1) (detailed . 3)) link-option))
+   (define (print-totals total debit credit tax sale)
+     (define (total-cell cell)
+       (gnc:make-html-table-cell/markup "total-number-cell" cell))
+     (define (make-cell amt)
+       (total-cell (gnc:make-gnc-monetary currency amt)))
+     (define span
+       (count identity (map (lambda (f) (f used-columns))
+                            (list memo-col type-col num-col date-due-col date-col))))
+     ;; print period totals
+     (if (or (sale-col used-columns) (tax-col used-columns)
+             (credit-col used-columns) (debit-col used-columns))
+         (gnc:html-table-append-row/markup!
+          table "grand-total"
+          (append
+           (list (total-cell (_ "Period Totals")))
+           (addif (>= span 2) (gnc:make-html-table-cell/size 1 (1- span) ""))
+           (addif (sale-col used-columns)   (make-cell sale))
+           (addif (tax-col used-columns)    (make-cell tax))
+           (addif (credit-col used-columns) (make-cell credit))
+           (addif (debit-col used-columns)  (make-cell (- debit)))
+           (addif (value-col used-columns) (make-cell (+ credit debit)))
+           (addif (> link-cols 0) (gnc:make-html-table-cell/size 1 link-cols #f)))))
+ 
+     ;; print grand total
+     (if (value-col used-columns)
+         (gnc:html-table-append-row/markup!
+          table "grand-total"
+          (append
+           (list (total-cell
+                  (if (negative? total)
+                      (_ "Total Credit")
+                      (_ "Total Due")))
+                 (gnc:make-html-table-cell/size/markup
+                  1 (value-col used-columns)
+                  "total-number-cell"
+                  (gnc:make-gnc-monetary currency total)))
+           (addif (> link-cols 0)
+                  (gnc:make-html-table-cell/size 1 link-cols #f)))))
+ 
+     ;; print aging table
+     (gnc:html-table-append-row/markup!
+      table "grand-total"
+      (list (gnc:make-html-table-cell/size
+             1 (+ columns-used-size link-cols)
+             (make-aging-table splits
+                               end-date
+                               reverse? date-type currency)))))
+ 
+   (define (add-balance-row odd-row? total)
+     (add-row table odd-row? used-columns start-date #f "" (_ "Balance") ""
+              currency total #f #f #f #f (list (make-list link-cols #f))))
+ 
+   (define (make-invoice->payments-table invoice invoice-splits currency txn)
+     (append
+      (map
+       (lambda (pmt-split)
+         (list
+          (qof-print-date
+           (xaccTransGetDate
+            (xaccSplitGetParent pmt-split)))
+          (let ((text (gnc-get-num-action
+                       (xaccSplitGetParent pmt-split)
+                       pmt-split)))
+            (if (string-null? text)
+                (_ "Payment")
+                text))
+          (make-cell
+           (gnc:make-html-text
+            (gnc:html-markup-anchor
+             (gnc:split-anchor-text pmt-split)
+             (gnc:make-gnc-monetary
+              currency (- (xaccSplitGetAmount pmt-split))))))))
+       (filter (lambda (s) (not (equal? (xaccSplitGetParent s) txn)))
+               invoice-splits))
+      (if (gncInvoiceIsPaid invoice)
+          '()
+          (list
+           (list (gnc:make-html-table-cell/size 1 2 (_ "Outstanding"))
+                 (make-cell
+                  (gnc:make-gnc-monetary
+                   currency
+                   (gnc-lot-get-balance
+                    (gncInvoiceGetPostedLot invoice)))))))))
+ 
+   (define (make-payment->invoices-list invoice payment-splits)
+     (list
+      (list
+       (apply
+        gnc:make-html-text
+        (map
+         (lambda (inv-splits)
+           (gnc:html-markup-anchor
+            (gnc:invoice-anchor-text (car inv-splits))
+            (gnc-get-num-action
+             (gncInvoiceGetPostedTxn (car inv-splits))
+             #f)))
+         payment-splits)))))
+ 
+   (define (make-payment->invoices-table split payment-splits currency)
+     (if (null? payment-splits)
+         (list (list (gnc:make-html-table-cell/size 1 2 (_ "Prepayments"))
+                     (make-cell
+                      (gnc:make-gnc-monetary
+                       currency (- (xaccSplitGetAmount split))))))
+         (map
+          (lambda (inv-splits)
+            (let ((inv (car inv-splits))
+                  (inv-split (cadr inv-splits)))
+              (list
+               (qof-print-date
+                (gncInvoiceGetDatePosted inv))
+               (gnc:make-html-text
+                (gnc:html-markup-anchor
+                 (gnc:invoice-anchor-text inv)
+                 (gnc-get-num-action
+                  (gncInvoiceGetPostedTxn inv) #f)))
+               (make-cell
+                (gnc:make-gnc-monetary
+                 currency
+                 (- (xaccSplitGetAmount inv-split)))))))
+          payment-splits)))
+ 
+   (define (split->type-str split)
+     (let* ((txn (xaccSplitGetParent split))
+            (invoice (gncInvoiceGetInvoiceFromTxn txn)))
+       (cond
+        ((and (txn-is-invoice? txn)
+              (not (null? invoice)))
+         (gnc:make-html-text
+          (gnc:html-markup-anchor
+           (gnc:invoice-anchor-text invoice)
+           (gncInvoiceGetTypeString invoice))))
+        ((txn-is-payment? txn)
+         (gnc:make-html-text
+          (gnc:html-markup-anchor
+           (gnc:split-anchor-text split)
+           (_ "Payment"))))
+        (else (_ "Unknown")))))
+ 
+   (define (invoice->sale invoice)
+     (and (not (null? invoice))
+          ((if (gncInvoiceGetIsCreditNote invoice) - identity)
+           (gncInvoiceGetTotalSubtotal invoice))))
+ 
+   (define (invoice->tax invoice)
+     (and (not (null? invoice))
+          ((if (gncInvoiceGetIsCreditNote invoice) - identity)
+           (gncInvoiceGetTotalTax invoice))))
+ 
+   (define (invoice->due-date invoice)
+     (and (not (null? invoice))
+          (gncInvoiceIsPosted invoice)
+          (gncInvoiceGetDateDue invoice)))
+ 
+   (let lp ((printed? #f)
+            (odd-row? #t)
+            (splits splits)
+            (total 0)
+            (debit 0)
+            (credit 0)
+            (tax 0)
+            (sale 0)
+            (links '()))
+     (cond
+ 
+      ((null? splits)
+       ;;Balance row may not have been added if all transactions were before
+       ;;start-date (and no other rows would be added either) so add it now
+       (when (and (not printed?) (value-col used-columns) (not (zero? total)))
+         (add-balance-row odd-row? total))
+       (print-totals total debit credit tax sale)
+       (gnc:html-table-set-style!
+        table "table"
+        'attribute (list "border" 1)
+        'attribute (list "cellspacing" 0)
+        'attribute (list "cellpadding" 4))
+       table)
+ 
+      ;; not an invoice/payment. skip transaction.
+      ((not (or (txn-is-invoice? (xaccSplitGetParent (car splits)))
+                (txn-is-payment? (xaccSplitGetParent (car splits)))))
+       (lp printed? odd-row? (cdr splits) total debit credit tax sale links))
+ 
+      ;; invalid case: txn-type-invoice but no associated invoice, nor lot
+      ((let* ((txn (xaccSplitGetParent (car splits)))
+              (invoice (gncInvoiceGetInvoiceFromTxn txn)))
+         (and (txn-is-invoice? txn)
+              (or (null? invoice)
+                  (null? (gncInvoiceGetPostedLot invoice)))))
+       (gnc:warn "sanity check fail" txn)
+       (lp printed? odd-row? (cdr splits) total debit credit tax sale links))
+ 
+      ;; start printing txns.
+      (else
+       (let* ((split (car splits))
+              (txn (xaccSplitGetParent split))
+              (date (xaccTransGetDate txn))
+              (value (xaccSplitGetAmount split))
+              (value (if reverse? (- value) value))
+              (invoice (gncInvoiceGetInvoiceFromTxn txn))
+              (invoice-splits
+               (and (txn-is-invoice? txn)
+                    (gnc-lot-get-split-list
+                     (gncInvoiceGetPostedLot invoice))))
+              (payment-splits
+               (and (txn-is-payment? txn)
+                    (filter
+                     (lambda (inv-split)
+                       (member txn (map xaccSplitGetParent (cdr inv-split))))
+                     links))))
+ 
+         (cond
+          ;; txn-date < start-date. skip display, accumulate amounts
+          ((< date start-date)
+           (lp printed? odd-row? (cdr splits) (+ total value)
+               (if (negative? value) (+ debit value) debit)
+               (if (negative? value) credit (+ credit value))
+               tax sale (if (null? invoice) links
+                            (acons invoice invoice-splits links))))
+ 
+          ;; if balance row hasn't been rendered, consider
+          ;; adding here.  skip if value=0.
+          ((not printed?)
+           (let ((print? (and (value-col used-columns) (not (zero? total)))))
+             (if print? (add-balance-row odd-row? total))
+             (lp #t (not print?) splits total debit credit tax sale links)))
+ 
+          (else
+           (add-row
+            table odd-row? used-columns date (invoice->due-date invoice)
+            (gnc-get-num-action txn split) (split->type-str split)
+            (xaccSplitGetMemo split) currency (+ total value)
+            (and (>= value 0) value) (and (< value 0) value)
+            (invoice->sale invoice) (invoice->tax invoice)
+            (cond
+             ((and invoice-splits (eq? link-option 'simple))
+              (if (gnc-lot-is-closed (gncInvoiceGetPostedLot invoice))
+                  (list (list (_ "Paid")))
+                  (list (list #f))))
+             ((and invoice-splits (eq? link-option 'detailed))
+              (make-invoice->payments-table invoice invoice-splits currency txn))
+             ((and payment-splits (eq? link-option 'simple))
+              (make-payment->invoices-list invoice payment-splits))
+             ((and payment-splits (eq? link-option 'detailed))
+              (make-payment->invoices-table split payment-splits currency))
+             ;; some error occurred, show 1 line containing empty-list
+             (else '(()))))
+ 
+           (lp printed? (not odd-row?) (cdr splits) (+ total value)
+               (if (negative? value) (+ debit value) debit)
+               (if (negative? value) credit (+ credit value))
+               (+ tax (or (invoice->tax invoice) 0))
+               (+ sale (or (invoice->sale invoice) 0))
+               (if (null? invoice) links
+                   (acons invoice invoice-splits links))))))))))
+ 
+ (define (options-generator owner-type)
+ 
+   (define gnc:*report-options* (gnc:new-options))
+ 
+   (define (gnc:register-inv-option new-option)
+     (gnc:register-option gnc:*report-options* new-option))
+ 
+   (gnc:register-inv-option
+    (gnc:make-owner-option
+     owner-page (owner-string owner-type) "v"
+     (N_ "The company for this report.")
+     (lambda () '()) #f owner-type))
+ 
+   (gnc:options-add-date-interval!
+    gnc:*report-options* gnc:pagename-general
+    optname-from-date optname-to-date "a")
+ 
+   ;; Use a default report date of 'today'
+   (gnc:option-set-default-value
+    (gnc:lookup-option gnc:*report-options* gnc:pagename-general optname-to-date)
+    (cons 'relative 'today))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") date-header
+     "b" (N_ "Display the transaction date?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") due-date-header
+     "c" (N_ "Display the transaction date?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") reference-header
+     "d" (N_ "Display the transaction reference?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") type-header
+     "g" (N_ "Display the transaction type?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") desc-header
+     "ha" (N_ "Display the transaction description?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") sale-header
+     "haa" (N_ "Display the sale amount column?") #f))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") tax-header
+     "hab" (N_ "Display the tax column?") #f))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") credit-header
+     "hac" (N_ "Display the period credits column?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") debit-header
+     "had" (N_ "Display a period debits column?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-simple-boolean-option
+     (N_ "Display Columns") amount-header
+     "hb" (N_ "Display the transaction amount?") #t))
+ 
+   (gnc:register-inv-option
+    (gnc:make-multichoice-option
+     (N_ "Display Columns") linked-txns-header
+     "hc" (N_ "Show linked transactions") 'none
+     (list (vector 'none
+                   (N_ "Disabled")
+                   (N_ "Linked transactions are hidden."))
+           (vector 'simple
+                   (N_ "Simple")
+                   (N_ "Invoices show if paid, payments show invoice numbers."))
+           (vector 'detailed
+                   (N_ "Detailed")
+                   (N_ "Invoices show list of payments, payments show list of \
+ invoices and amounts.")))))
+ 
+   (gnc:register-inv-option
+    (gnc:make-multichoice-option
+     gnc:pagename-general optname-date-driver "k"
+     (N_ "Leading date.") 'duedate
+     (list
+      ;; Should be using standard label for due date?
+      (vector 'duedate
+              (N_ "Due Date")
+              (N_ "Due date is leading."))
+      ;; Should be using standard label for post date?
+      (vector 'postdate
+              (N_ "Post Date")
+              (N_ "Post date is leading.")))))
+ 
+   (gnc:options-set-default-section gnc:*report-options* "General")
+ 
+   gnc:*report-options*)
+ 
+ (define (multiline-to-html-text str)
+   ;; simple function - splits string containing #\newline into
+   ;; substrings, and convert to a gnc:make-html-text construct which
+   ;; adds gnc:html-markup-br after each substring.
+   (let loop ((list-of-substrings (string-split str #\newline))
+              (result '()))
+     (if (null? list-of-substrings)
+         (apply gnc:make-html-text (if (null? result) '() (reverse (cdr result))))
+         (loop (cdr list-of-substrings)
+               (cons* (gnc:html-markup-br) (car list-of-substrings) result)))))
+ 
+ (define (setup-job-query q owner accounts end-date)
+   (let ((guid (gncOwnerReturnGUID owner)))
+     (qof-query-add-guid-match
+      q  (list SPLIT-TRANS INVOICE-FROM-TXN INVOICE-OWNER QOF-PARAM-GUID)
+      guid QOF-QUERY-OR)
+     (qof-query-add-guid-match
+      q (list SPLIT-LOT OWNER-FROM-LOT QOF-PARAM-GUID)
+      guid QOF-QUERY-OR)
+     (qof-query-add-guid-match
+      q (list SPLIT-LOT INVOICE-FROM-LOT INVOICE-OWNER QOF-PARAM-GUID)
+      guid QOF-QUERY-OR)
+     (xaccQueryAddAccountMatch q accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+     (xaccQueryAddDateMatchTT q #f end-date #t end-date QOF-QUERY-AND)
+     (qof-query-set-book q (gnc-get-current-book))
+     (qof-query-set-sort-order q (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+     q))
+ 
+ (define (setup-query q owner accounts end-date)
+   (let ((guid (gncOwnerReturnGUID (gncOwnerGetEndOwner owner))))
+     (qof-query-add-guid-match
+      q (list SPLIT-TRANS INVOICE-FROM-TXN INVOICE-OWNER OWNER-PARENTG)
+      guid QOF-QUERY-OR)
+     (qof-query-add-guid-match
+      q (list SPLIT-LOT OWNER-FROM-LOT OWNER-PARENTG)
+      guid QOF-QUERY-OR)
+     (qof-query-add-guid-match
+      q (list SPLIT-LOT INVOICE-FROM-LOT INVOICE-OWNER OWNER-PARENTG)
+      guid QOF-QUERY-OR)
+     (xaccQueryAddAccountMatch q accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+     (xaccQueryAddDateMatchTT q #f end-date #t end-date QOF-QUERY-AND)
+     (qof-query-set-book q (gnc-get-current-book))
+     (qof-query-set-sort-order q (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+     q))
+ 
+ (define (make-owner-table owner)
+   (let ((table (gnc:make-html-table)))
+     (gnc:html-table-set-style!
+      table "table"
+      'attribute (list "border" 0)
+      'attribute (list "cellspacing" 0)
+      'attribute (list "cellpadding" 0)
+      'attribute (list "valign" "top"))
+     (gnc:html-table-append-row!
+      table (multiline-to-html-text (gnc:owner-get-name-and-address-dep owner)))
+     table))
+ 
+ (define (make-myname-table book date-format)
+   (let* ((table (gnc:make-html-table))
+          (name (gnc:company-info book gnc:*company-name*))
+          (addy (gnc:company-info book gnc:*company-addy*)))
+ 
+     (gnc:html-table-set-style!
+      table "table"
+      'attribute (list "border" 0)
+      'attribute (list "align" "right")
+      'attribute (list "valign" "top")
+      'attribute (list "cellspacing" 0)
+      'attribute (list "cellpadding" 0))
+ 
+     (when name
+       (gnc:html-table-append-row! table (list name)))
+     (when addy
+       (gnc:html-table-append-row! table (multiline-to-html-text addy)))
+     (gnc:html-table-append-row!
+      table (list (gnc-print-time64 (gnc:get-today) date-format)))
+     table))
+ 
+ (define (make-break! document)
+   (gnc:html-document-add-object!
+    document
+    (gnc:make-html-text
+     (gnc:html-markup-br))))
+ 
+ (define (reg-renderer report-obj type reverse?)
+   (define options (gnc:report-options report-obj))
+   (define (opt-val section name)
+     (gnc:option-value
+      (gnc:lookup-option options section name)))
+ 
+   (let* ((accounts (filter (compose xaccAccountIsAPARType xaccAccountGetType)
+                            (gnc-account-get-descendants-sorted
+                             (gnc-get-current-root-account))))
+          (start-date (gnc:time64-start-day-time
+                       (gnc:date-option-absolute-time
+                        (opt-val gnc:pagename-general optname-from-date))))
+          (end-date (gnc:time64-end-day-time
+                     (gnc:date-option-absolute-time
+                      (opt-val gnc:pagename-general optname-to-date))))
+          (book (gnc-get-current-book))
+          (date-format (gnc:options-fancy-date (gnc-get-current-book)))
+          (used-columns (build-column-used options))
+          (link-option
+           (gnc:option-value
+            (gnc:lookup-option options "Display Columns" linked-txns-header)))
+          (owner-descr (owner-string type))
+          (date-type (opt-val gnc:pagename-general optname-date-driver))
+          (owner (opt-val owner-page owner-descr))
+          (query (qof-query-create-for-splits))
+          (document (gnc:make-html-document))
+          (table (gnc:make-html-table))
+          (headings (make-heading-list used-columns link-option))
+          (report-title (string-append (owner-string type) " " (_ "Report"))))
+ 
+     (cond
+      ((not (gncOwnerIsValid owner))
+       (gnc:html-document-add-object!
+        document (gnc:html-make-generic-warning
+                  report-title (gnc:report-id report-obj)
+                  (cadr (get-info type)) (caddr (get-info type)))))
+ 
+      ((null? accounts)
+       (gnc:html-document-add-object!
+        document
+        (gnc:html-make-generic-warning
+         (string-append report-title ": " (gncOwnerGetName owner))
+         (gnc:report-id report-obj)
+         (_ "No valid account found")
+         (_ "This report requires a valid AP/AR account to be available."))))
+ 
+      (else
+       (if (eqv? GNC-OWNER-JOB type)
+           (setup-job-query query owner accounts end-date)
+           (setup-query query owner accounts end-date))
+ 
+       (let ((splits (xaccQueryGetSplitsUniqueTrans query)))
+         (qof-query-destroy query)
+ 
+         (gnc:html-document-set-title!
+          document (string-append report-title ": " (gncOwnerGetName owner)))
+ 
+         (gnc:html-document-set-headline!
+          document (gnc:html-markup
+                    "span" (owner-string type) " " (_ "Report:") " "
+                    (gnc:html-markup-anchor
+                     (if (eqv? GNC-OWNER-JOB type)
+                         (gnc:job-anchor-text (gncOwnerGetJob owner))
+                         (gnc:owner-anchor-text owner))
+                     (gncOwnerGetName owner))))
+ 
+         (cond
+          ((null? splits)
+ 
+           (gnc:html-document-add-object!
+            document
+            (gnc:make-html-text
+             (gnc:html-markup-h2 (_ "No transactions found."))
+             (gnc:html-markup-p
+              (format #f (_ "No transactions were found associated with the ~a.")
+                      (string-downcase (car (get-info type)))))
+             (gnc:html-make-options-link (gnc:report-id report-obj)))))
+ 
+          (else
+           ;; loops in 2 passes: 1st loop. for each APAR account, filter
+           ;; splits into each account. accumulate non-null results into
+           ;; accounts-and-splits accumulator.
+           (let loop ((accounts accounts)
+                      (accounts-and-splits '())
+                      (splits splits))
+             (cond
+              ((null? accounts)
+ 
+               ;; 2nd loop: for-each accounts-and-splits accumulator, add
+               ;; owner-txns into the html-table. only show header if >1
+               ;; account has splits.
+               (for-each
+                (lambda (acc-splits-pair)
+                  (let* ((account (car acc-splits-pair))
+                         (splits (cdr acc-splits-pair)))
+ 
+                    (when (> (length accounts-and-splits) 1)
+                      (gnc:html-table-append-row!
+                       table (gnc:make-html-table-cell/size
+                              1 (length headings)
+                              (gnc:make-html-text
+                               (gnc:html-markup-h3
+                                (string-append (_ "Account") ": "
+                                               (xaccAccountGetName account)))))))
+ 
+                    (add-owner-table table splits account start-date end-date
+                                     date-type used-columns reverse? link-option)))
+                accounts-and-splits))
+ 
+              (else
+               ;; each 1st loop will slice splits into account-splits and
+               ;; non-account splits, add to accounts-and-splits; and send
+               ;; the non-account splits to be processed in the next loop
+               ;; iteration.
+               (let-values (((acc-splits other-acc-splits)
+                             (partition
+                              (lambda (split)
+                                (equal? (car accounts) (xaccSplitGetAccount split)))
+                              splits)))
+ 
+                 (loop (cdr accounts)
+                       (if (null? acc-splits)
+                           accounts-and-splits
+                           (cons (cons (car accounts) acc-splits)
+                                 accounts-and-splits))
+                       other-acc-splits)))))
+ 
+           (gnc:html-document-add-object!
+            document (make-myname-table book date-format))
+ 
+           (gnc:html-document-add-object!
+            document (make-owner-table owner))
+ 
+           (gnc:html-document-add-object!
+            document (gnc:make-html-text
+                      (string-append (_ "Date Range") ": " (qof-print-date start-date)
+                                     " - " (qof-print-date end-date))))
+ 
+           (make-break! document)
+ 
+           (gnc:html-table-set-col-headers! table headings)
+ 
+           (gnc:html-document-add-object! document table))))))
+ 
+     document))
+ 
+ (define (customer-renderer obj)
+   (reg-renderer obj GNC-OWNER-CUSTOMER #f))
+ 
+ (define (vendor-renderer  obj)
+   (reg-renderer obj GNC-OWNER-VENDOR #t))
+ 
+ (define (employee-renderer obj)
+   (reg-renderer obj GNC-OWNER-EMPLOYEE #t))
+ 
+ (define (job-renderer obj)
+   (reg-renderer obj GNC-OWNER-JOB #f))
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Customer Report (beta)")
+  'report-guid "c146317be32e4948a561ec7fc89d15c1-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator (lambda () (options-generator GNC-OWNER-CUSTOMER))
+  'renderer customer-renderer
+  'in-menu? #t)
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Vendor Report (beta)")
+  'report-guid "d7d1e53505ee4b1b82efad9eacedaea0-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator (lambda () (options-generator GNC-OWNER-VENDOR))
+  'renderer vendor-renderer
+  'in-menu? #t)
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Employee Report (beta)")
+  'report-guid "08ae9c2e884b4f9787144f47eacd7f44-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator (lambda () (options-generator GNC-OWNER-EMPLOYEE))
+  'renderer employee-renderer
+  'in-menu? #t)
+ 
+ (gnc:define-report
+  'version 1
+  'name (N_ "Job Report (beta)")
+  'report-guid "5518ac227e474f47a34439f2d4d049de-new"
+  'menu-path (list gnc:menuname-experimental)
+  'options-generator (lambda () (options-generator GNC-OWNER-JOB))
+  'renderer job-renderer
+  'in-menu? #t)
diff --cc libgnucash/engine/test/test-engine-extras.scm
index 517b73b6f,a0a1027d4..8092653e4
--- a/libgnucash/engine/test/test-engine-extras.scm
+++ b/libgnucash/engine/test/test-engine-extras.scm
@@@ -861,9 -862,9 +862,11 @@@
        (env-create-transaction env (midperiod 2) bank income 67)
        (env-create-transaction env (midperiod 3) bank income 77)
        (env-create-transaction env (midperiod 0) expense bank 20)
-       (env-create-transaction env (midperiod 1) expense bank 20))
+       (env-create-transaction env (midperiod 1) expense bank 20)
+       (let ((clos (env-create-transaction env (midperiod 1) income equity 55)))
+         (xaccTransSetIsClosingTxn clos #t)))
 +    (gnc-budget-set-account-period-note budget income 0 "income-0 -$60")
 +    (gnc-budget-set-account-period-note budget expense 1 "expense-1 $25")
      budget))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --cc po/POTFILES.in
index 75ba04f1f,881dddf6a..ddf68e273
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@@ -419,86 -411,101 +419,88 @@@ gnucash/register/register-gnome/gnucash
  gnucash/register/register-gnome/pricecell-gnome.c
  gnucash/register/register-gnome/quickfillcell-gnome.c
  gnucash/register/register-gnome/table-gnome.c
 -gnucash/report/business-reports/aging.scm
 -gnucash/report/business-reports/balsheet-eg.eguile.scm
 -gnucash/report/business-reports/balsheet-eg.scm
 -gnucash/report/business-reports/business-reports.scm
 -gnucash/report/business-reports/customer-summary.scm
 -gnucash/report/business-reports/invoice.scm
 -gnucash/report/business-reports/job-report.scm
 -gnucash/report/business-reports/new-aging.scm
 -gnucash/report/business-reports/new-owner-report.scm
 -gnucash/report/business-reports/owner-report.scm
 -gnucash/report/business-reports/payables.scm
 -gnucash/report/business-reports/receipt.eguile.scm
 -gnucash/report/business-reports/receipt.scm
 -gnucash/report/business-reports/receivables.scm
 -gnucash/report/business-reports/taxinvoice.eguile.scm
 -gnucash/report/business-reports/taxinvoice.scm
 -gnucash/report/locale-specific/us/de_DE.scm
 -gnucash/report/locale-specific/us/gncmod-locale-reports-us.c
 -gnucash/report/locale-specific/us/taxtxf-de_DE.scm
 -gnucash/report/locale-specific/us/taxtxf.scm
 -gnucash/report/locale-specific/us/us.scm
 -gnucash/report/report-gnome/dialog-custom-report.c
 -gnucash/report/report-gnome/dialog-report-column-view.c
 -gnucash/report/report-gnome/dialog-report-style-sheet.c
 -gnucash/report/report-gnome/gncmod-report-gnome.c
 -gnucash/report/report-gnome/gnc-plugin-page-report.c
 -gnucash/report/report-gnome/report-gnome.scm
 -gnucash/report/report-gnome/window-report.c
 -gnucash/report/report-system/collectors.scm
 -gnucash/report/report-system/commodity-utilities.scm
 -gnucash/report/report-system/eguile-gnc.scm
 -gnucash/report/report-system/eguile-html-utilities.scm
 -gnucash/report/report-system/eguile-utilities.scm
 -gnucash/report/report-system/gncmod-report-system.c
 -gnucash/report/report-system/gnc-report.c
 -gnucash/report/report-system/html-acct-table.scm
 -gnucash/report/report-system/html-anytag.scm
 -gnucash/report/report-system/html-barchart.scm
 -gnucash/report/report-system/html-document.scm
 -gnucash/report/report-system/html-fonts.scm
 -gnucash/report/report-system/html-linechart.scm
 -gnucash/report/report-system/html-piechart.scm
 -gnucash/report/report-system/html-scatter.scm
 -gnucash/report/report-system/html-style-info.scm
 -gnucash/report/report-system/html-style-sheet.scm
 -gnucash/report/report-system/html-table.scm
 -gnucash/report/report-system/html-text.scm
 -gnucash/report/report-system/html-utilities.scm
 -gnucash/report/report-system/options-utilities.scm
 -gnucash/report/report-system/report-collectors.scm
 -gnucash/report/report-system/report.scm
 -gnucash/report/report-system/report-system.scm
 -gnucash/report/report-system/report-utilities.scm
 -gnucash/report/report-system/trep-engine.scm
 -gnucash/report/standard-reports/account-piecharts.scm
 -gnucash/report/standard-reports/account-summary.scm
 -gnucash/report/standard-reports/advanced-portfolio.scm
 -gnucash/report/standard-reports/average-balance.scm
 -gnucash/report/standard-reports/balance-forecast.scm
 -gnucash/report/standard-reports/balance-sheet.scm
 -gnucash/report/standard-reports/balsheet-pnl.scm
 -gnucash/report/standard-reports/budget-balance-sheet.scm
 -gnucash/report/standard-reports/budget-barchart.scm
 -gnucash/report/standard-reports/budget-flow.scm
 -gnucash/report/standard-reports/budget-income-statement.scm
 -gnucash/report/standard-reports/budget.scm
 -gnucash/report/standard-reports/cashflow-barchart.scm
 -gnucash/report/standard-reports/cash-flow.scm
 -gnucash/report/standard-reports/category-barchart.scm
 -gnucash/report/standard-reports/daily-reports.scm
 -gnucash/report/standard-reports/equity-statement.scm
 -gnucash/report/standard-reports/general-journal.scm
 -gnucash/report/standard-reports/general-ledger.scm
 -gnucash/report/standard-reports/income-gst-statement.scm
 -gnucash/report/standard-reports/income-statement.scm
 -gnucash/report/standard-reports/net-charts.scm
 -gnucash/report/standard-reports/portfolio.scm
 -gnucash/report/standard-reports/price-scatter.scm
 -gnucash/report/standard-reports/reconcile-report.scm
 -gnucash/report/standard-reports/register.scm
 -gnucash/report/standard-reports/standard-reports.scm
 -gnucash/report/standard-reports/transaction.scm
 -gnucash/report/standard-reports/trial-balance.scm
 -gnucash/report/stylesheets/gncmod-stylesheets.c
 -gnucash/report/stylesheets/gnc-plugin-stylesheets.c
 -gnucash/report/stylesheets/stylesheet-easy.scm
 -gnucash/report/stylesheets/stylesheet-fancy.scm
 -gnucash/report/stylesheets/stylesheet-footer.scm
 -gnucash/report/stylesheets/stylesheet-head-or-tail.scm
 -gnucash/report/stylesheets/stylesheet-plain.scm
 -gnucash/report/stylesheets/stylesheets.scm
 -gnucash/report/utility-reports/hello-world.scm
 -gnucash/report/utility-reports/utility-reports.scm
 -gnucash/report/utility-reports/view-column.scm
 -gnucash/report/utility-reports/welcome-to-gnucash.scm
 +gnucash/report/commodity-utilities.scm
 +gnucash/report/eguile-html-utilities.scm
 +gnucash/report/eguile.scm
 +gnucash/report/eguile-utilities.scm
 +gnucash/report/gncmod-report.c
 +gnucash/report/gnc-report.c
 +gnucash/report/html-acct-table.scm
 +gnucash/report/html-anytag.scm
 +gnucash/report/html-barchart.scm
 +gnucash/report/html-chart.scm
 +gnucash/report/html-document.scm
 +gnucash/report/html-fonts.scm
 +gnucash/report/html-linechart.scm
 +gnucash/report/html-piechart.scm
 +gnucash/report/html-scatter.scm
 +gnucash/report/html-style-info.scm
 +gnucash/report/html-style-sheet.scm
 +gnucash/report/html-table.scm
 +gnucash/report/html-text.scm
 +gnucash/report/html-utilities.scm
 +gnucash/report/options-utilities.scm
 +gnucash/report/report-core.scm
 +gnucash/report/report-register-hooks.scm
 +gnucash/report/reports/aging.scm
 +gnucash/report/reports/example/average-balance.scm
 +gnucash/report/reports/example/daily-reports.scm
 +gnucash/report/reports/example/hello-world.scm
 +gnucash/report/reports/example/sample-graphs.scm
 +gnucash/report/reports/example/welcome-to-gnucash.scm
 +gnucash/report/reports/locale-specific/de_DE/taxtxf.scm
 +gnucash/report/reports/locale-specific/us/taxtxf.scm
 +gnucash/report/reports/reports.scm
 +gnucash/report/reports/standard/account-piecharts.scm
 +gnucash/report/reports/standard/account-summary.scm
 +gnucash/report/reports/standard/advanced-portfolio.scm
 +gnucash/report/reports/standard/balance-forecast.scm
 +gnucash/report/reports/standard/balance-sheet.scm
 +gnucash/report/reports/standard/balsheet-eg.scm
 +gnucash/report/reports/standard/balsheet-pnl.scm
 +gnucash/report/reports/standard/budget-balance-sheet.scm
 +gnucash/report/reports/standard/budget-barchart.scm
 +gnucash/report/reports/standard/budget-flow.scm
 +gnucash/report/reports/standard/budget-income-statement.scm
 +gnucash/report/reports/standard/budget.scm
 +gnucash/report/reports/standard/cashflow-barchart.scm
 +gnucash/report/reports/standard/cash-flow.scm
 +gnucash/report/reports/standard/category-barchart.scm
 +gnucash/report/reports/standard/customer-summary.scm
 +gnucash/report/reports/standard/dashboard.scm
 +gnucash/report/reports/standard/equity-statement.scm
 +gnucash/report/reports/standard/general-journal.scm
 +gnucash/report/reports/standard/general-ledger.scm
 +gnucash/report/reports/standard/income-gst-statement.scm
 +gnucash/report/reports/standard/income-statement.scm
 +gnucash/report/reports/standard/invoice.scm
 +gnucash/report/reports/standard/job-report.scm
 +gnucash/report/reports/standard/net-charts.scm
++gnucash/report/reports/standard/new-aging.scm
++gnucash/report/reports/standard/new-owner-report.scm
 +gnucash/report/reports/standard/owner-report.scm
 +gnucash/report/reports/standard/payables.scm
 +gnucash/report/reports/standard/portfolio.scm
 +gnucash/report/reports/standard/price-scatter.scm
 +gnucash/report/reports/standard/receipt.scm
 +gnucash/report/reports/standard/receivables.scm
 +gnucash/report/reports/standard/reconcile-report.scm
 +gnucash/report/reports/standard/register.scm
 +gnucash/report/reports/standard/taxinvoice.scm
 +gnucash/report/reports/standard/transaction.scm
 +gnucash/report/reports/standard/trial-balance.scm
 +gnucash/report/reports/standard/view-column.scm
 +gnucash/report/reports/support/balsheet-eg.eguile.scm
 +gnucash/report/reports/support/receipt.eguile.scm
 +gnucash/report/reports/support/taxinvoice.eguile.scm
 +gnucash/report/report.scm
 +gnucash/report/report-utilities.scm
 +gnucash/report/stylesheets/easy.scm
 +gnucash/report/stylesheets/fancy.scm
 +gnucash/report/stylesheets/footer.scm
 +gnucash/report/stylesheets/head-or-tail.scm
 +gnucash/report/stylesheets/plain.scm
 +gnucash/report/trep-engine.scm
  libgnucash/app-utils/app-utils.scm
  libgnucash/app-utils/business-options.c
  libgnucash/app-utils/business-options.scm

commit d893723479e9c63a9288fe56834d78a3b65ffe64
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 15:33:12 2019 +0800

    [new-owner-report] combined job/owner reports

diff --git a/gnucash/report/business-reports/CMakeLists.txt b/gnucash/report/business-reports/CMakeLists.txt
index f72f12a59..c2039d7d3 100644
--- a/gnucash/report/business-reports/CMakeLists.txt
+++ b/gnucash/report/business-reports/CMakeLists.txt
@@ -8,6 +8,7 @@ set (business_reports_SCHEME
   invoice.scm
   job-report.scm
   new-aging.scm
+  new-owner-report.scm
   owner-report.scm
   payables.scm
   receivables.scm
diff --git a/gnucash/report/business-reports/business-reports.scm b/gnucash/report/business-reports/business-reports.scm
index 3191f84ac..7c50821a9 100644
--- a/gnucash/report/business-reports/business-reports.scm
+++ b/gnucash/report/business-reports/business-reports.scm
@@ -117,6 +117,7 @@
 (use-modules (gnucash report owner-report))
 (use-modules (gnucash report job-report))
 (use-modules (gnucash report new-aging))
+(use-modules (gnucash report new-owner-report))
 (use-modules (gnucash report payables))
 (use-modules (gnucash report receivables))
 (use-modules (gnucash report customer-summary))
diff --git a/gnucash/report/business-reports/new-owner-report.scm b/gnucash/report/business-reports/new-owner-report.scm
new file mode 100644
index 000000000..6665c18b0
--- /dev/null
+++ b/gnucash/report/business-reports/new-owner-report.scm
@@ -0,0 +1,891 @@
+;; -*-scheme-*-
+;; owner-report.scm -- Print out a detailed owner report, which is a
+;;                     summary of invoices and payments for a particular
+;;                     company (the owner) applied to an account.
+;;
+;; Created by:  Derek Atkins <warlord at MIT.EDU>
+;; Copyright (c) 2002, 2003 Derek Atkins <warlord at MIT.EDU>
+;; Modified by AMM to show tax figures of invoice.
+;; Modified by Christopher Lam to combine job/owner-report
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation           Voice:  +1-617-542-5942
+;; 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+;; Boston, MA  02110-1301,  USA       gnu at gnu.org
+
+
+(define-module (gnucash report new-owner-report))
+
+(use-modules (srfi srfi-1))
+(use-modules (srfi srfi-8))
+(use-modules (srfi srfi-11))             ;for let-values
+(use-modules (gnucash gnc-module))
+(use-modules (gnucash utilities))        ; for gnc:debug
+(use-modules (gnucash gettext))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+(use-modules (gnucash report standard-reports))
+(use-modules (gnucash report business-reports))
+(use-modules (gnucash report new-aging)) ;for gnc:owner-splits->aging-list
+
+;; Option names
+(define optname-from-date (N_ "From"))
+(define optname-to-date (N_ "To"))
+(define optname-date-driver (N_ "Due or Post Date"))
+
+(define owner-page gnc:pagename-general)
+(define date-header (N_ "Date"))
+(define due-date-header (N_ "Due Date"))
+(define reference-header (N_ "Reference"))
+(define type-header (N_ "Type"))
+(define desc-header (N_ "Description"))
+(define sale-header (N_ "Sale"))
+(define tax-header (N_ "Tax"))
+(define credit-header (N_ "Credits"))
+(define debit-header (N_ "Debits"))
+(define amount-header (N_ "Balance"))
+(define linked-txns-header (N_ "Links"))
+
+;; Depending on the report type we want to set up some lists/cases
+;; with strings to ease overview and translation
+(define owner-string-alist
+  (list
+   (list GNC-OWNER-CUSTOMER
+         (N_ "Customer")
+         (_ "No valid customer selected.")
+         (_ "This report requires a customer to be selected."))
+
+   (list GNC-OWNER-EMPLOYEE
+         (N_ "Employee")
+         (_ "No valid employee selected.")
+         (_ "This report requires a employee to be selected."))
+
+   (list GNC-OWNER-JOB
+         (N_ "Job")
+         (_ "No valid job selected.")
+         (_ "This report requires a job to be selected."))
+
+   (list GNC-OWNER-VENDOR
+         (N_ "Vendor")
+         (_ "No valid vendor selected.")
+         (_ "This report requires a vendor to be selected."))))
+
+(define (get-info key)
+  (assv-ref owner-string-alist key))
+
+;; Names in Option panel (Untranslated! Because it is used for option
+;; naming and lookup only, and the display of the option name will be
+;; translated somewhere else.)
+(define (owner-string owner-type)
+  (car (get-info owner-type)))
+
+(define (date-col columns-used)
+  (vector-ref columns-used 0))
+(define (date-due-col columns-used)
+  (vector-ref columns-used 1))
+(define (num-col columns-used)
+  (vector-ref columns-used 2))
+(define (type-col columns-used)
+  (vector-ref columns-used 3))
+(define (memo-col columns-used)
+  (vector-ref columns-used 4))
+(define (sale-col columns-used)
+  (vector-ref columns-used 5))
+(define (tax-col columns-used)
+  (vector-ref columns-used 6))
+(define (credit-col columns-used)
+  (vector-ref columns-used 7))
+(define (debit-col columns-used)
+  (vector-ref columns-used 8))
+(define (value-col columns-used)
+  (vector-ref columns-used 9))
+
+(define columns-used-size 10)
+
+(define (build-column-used options)
+  (define (opt-val section name)
+    (gnc:option-value
+     (gnc:lookup-option options section name)))
+  (define (make-set-col col-vector)
+    (let ((col 0))
+      (lambda (used? index)
+        (if used?
+            (begin
+              (vector-set! col-vector index col)
+              (set! col (+ col 1)))
+            (vector-set! col-vector index #f)))))
+
+  (let* ((col-vector (make-vector columns-used-size #f))
+         (set-col (make-set-col col-vector)))
+    (set-col (opt-val "Display Columns" date-header) 0)
+    (set-col (opt-val "Display Columns" due-date-header) 1)
+    (set-col (opt-val "Display Columns" reference-header) 2)
+    (set-col (opt-val "Display Columns" type-header) 3)
+    (set-col (opt-val "Display Columns" desc-header) 4)
+    (set-col (opt-val "Display Columns" sale-header) 5)
+    (set-col (opt-val "Display Columns" tax-header) 6)
+    (set-col (opt-val "Display Columns" credit-header) 7)
+    (set-col (opt-val "Display Columns" debit-header) 8)
+    (set-col (opt-val "Display Columns" amount-header) 9)
+    col-vector))
+
+(define (make-heading-list column-vector link-option)
+  (let ((heading-list '()))
+    (if (date-col column-vector)
+        (addto! heading-list (_ date-header)))
+    (if (date-due-col column-vector)
+        (addto! heading-list (_ due-date-header)))
+    (if (num-col column-vector)
+        (addto! heading-list (_ reference-header)))
+    (if (type-col column-vector)
+        (addto! heading-list (_ type-header)))
+    (if (memo-col column-vector)
+        (addto! heading-list (_ desc-header)))
+    (if (sale-col column-vector)
+        (addto! heading-list (_ sale-header)))
+    (if (tax-col column-vector)
+        (addto! heading-list (_ tax-header)))
+    (if (credit-col column-vector)
+        (addto! heading-list (_ credit-header)))
+    (if (debit-col column-vector)
+        (addto! heading-list (_ debit-header)))
+    (if (value-col column-vector)
+        (addto! heading-list (_ amount-header)))
+    (case link-option
+      ((simple)
+       (addto! heading-list (_ linked-txns-header)))
+      ((detailed)
+       (addto! heading-list (_ "Date"))
+       (addto! heading-list (_ "Details"))
+       (addto! heading-list (_ "Amount"))))
+    (reverse heading-list)))
+
+(define num-buckets 6)
+(define (new-bucket-vector)
+  (make-vector num-buckets 0))
+
+(define (txn-is-invoice? txn)
+  (eqv? (xaccTransGetTxnType txn) TXN-TYPE-INVOICE))
+(define (txn-is-payment? txn)
+  (eqv? (xaccTransGetTxnType txn) TXN-TYPE-PAYMENT))
+
+(define (make-aging-table splits to-date reverse? date-type currency)
+  (let ((table (gnc:make-html-table))
+        (aging-list (gnc:owner-splits->aging-list
+                     splits num-buckets to-date date-type reverse?)))
+
+    (gnc:html-table-set-col-headers!
+     table (list (_ "Prepayments")
+                 (_ "Current")
+                 (_ "0-30 days")
+                 (_ "31-60 days")
+                 (_ "61-90 days")
+                 (_ "91+ days")
+                 (_ "Total")))
+
+    (gnc:html-table-append-row!
+     table (map (lambda (entry) (gnc:make-gnc-monetary currency entry))
+                (reverse (cons (apply + aging-list) aging-list))))
+    table))
+
+;; addif is a macro; a simple procedure will always evaluate the
+;; arguments pred? and elt which is not desirable; a macro will ensure
+;; elt is only evaluated if pred? is not #f
+(define-syntax-rule (addif pred? elt)
+  (if pred? (list elt) '()))
+
+(define (make-cell elt) (gnc:make-html-table-cell/markup "number-cell" elt))
+
+;;
+;; Make a row list based on the visible columns
+;;
+(define (add-row table odd-row? column-vector date due-date num type-str
+                 memo currency amt credit debit sale tax link-rows)
+  (define empty-cols
+    (count identity
+           (map (lambda (f) (f column-vector))
+                (list date-col date-due-col num-col type-col
+                      memo-col sale-col tax-col credit-col
+                      debit-col value-col))))
+  (define (cell amt)
+    (and amt (make-cell (gnc:make-gnc-monetary currency amt))))
+  (let lp ((link-rows link-rows)
+           (first-row? #t))
+    (unless (null? link-rows)
+      (if first-row?
+          (gnc:html-table-append-row/markup!
+           table (if odd-row? "normal-row" "alternate-row")
+           (append
+            (addif (date-col column-vector) (qof-print-date date))
+            (addif (date-due-col column-vector)
+                   (and due-date (qof-print-date due-date)))
+            (addif (num-col column-vector)    (gnc:html-string-sanitize num))
+            (addif (type-col column-vector)   type-str)
+            (addif (memo-col column-vector)   (gnc:html-string-sanitize memo))
+            (addif (sale-col column-vector)   (cell sale))
+            (addif (tax-col column-vector)    (cell tax))
+            (addif (credit-col column-vector) (cell credit))
+            (addif (debit-col column-vector)  (cell (and debit (- debit))))
+            (addif (value-col column-vector)  (cell amt))
+            (car link-rows)))
+          (gnc:html-table-append-row/markup!
+           table (if odd-row? "normal-row" "alternate-row")
+           (cons
+            (gnc:make-html-table-cell/size 1 empty-cols #f)
+            (car link-rows))))
+      (lp (cdr link-rows) #f))))
+
+(define (add-owner-table table splits acc start-date end-date date-type
+                         used-columns reverse? link-option)
+  (define currency (xaccAccountGetCommodity acc))
+  (define link-cols (assq-ref '((none . 0) (simple . 1) (detailed . 3)) link-option))
+  (define (print-totals total debit credit tax sale)
+    (define (total-cell cell)
+      (gnc:make-html-table-cell/markup "total-number-cell" cell))
+    (define (make-cell amt)
+      (total-cell (gnc:make-gnc-monetary currency amt)))
+    (define span
+      (count identity (map (lambda (f) (f used-columns))
+                           (list memo-col type-col num-col date-due-col date-col))))
+    ;; print period totals
+    (if (or (sale-col used-columns) (tax-col used-columns)
+            (credit-col used-columns) (debit-col used-columns))
+        (gnc:html-table-append-row/markup!
+         table "grand-total"
+         (append
+          (list (total-cell (_ "Period Totals")))
+          (addif (>= span 2) (gnc:make-html-table-cell/size 1 (1- span) ""))
+          (addif (sale-col used-columns)   (make-cell sale))
+          (addif (tax-col used-columns)    (make-cell tax))
+          (addif (credit-col used-columns) (make-cell credit))
+          (addif (debit-col used-columns)  (make-cell (- debit)))
+          (addif (value-col used-columns) (make-cell (+ credit debit)))
+          (addif (> link-cols 0) (gnc:make-html-table-cell/size 1 link-cols #f)))))
+
+    ;; print grand total
+    (if (value-col used-columns)
+        (gnc:html-table-append-row/markup!
+         table "grand-total"
+         (append
+          (list (total-cell
+                 (if (negative? total)
+                     (_ "Total Credit")
+                     (_ "Total Due")))
+                (gnc:make-html-table-cell/size/markup
+                 1 (value-col used-columns)
+                 "total-number-cell"
+                 (gnc:make-gnc-monetary currency total)))
+          (addif (> link-cols 0)
+                 (gnc:make-html-table-cell/size 1 link-cols #f)))))
+
+    ;; print aging table
+    (gnc:html-table-append-row/markup!
+     table "grand-total"
+     (list (gnc:make-html-table-cell/size
+            1 (+ columns-used-size link-cols)
+            (make-aging-table splits
+                              end-date
+                              reverse? date-type currency)))))
+
+  (define (add-balance-row odd-row? total)
+    (add-row table odd-row? used-columns start-date #f "" (_ "Balance") ""
+             currency total #f #f #f #f (list (make-list link-cols #f))))
+
+  (define (make-invoice->payments-table invoice invoice-splits currency txn)
+    (append
+     (map
+      (lambda (pmt-split)
+        (list
+         (qof-print-date
+          (xaccTransGetDate
+           (xaccSplitGetParent pmt-split)))
+         (let ((text (gnc-get-num-action
+                      (xaccSplitGetParent pmt-split)
+                      pmt-split)))
+           (if (string-null? text)
+               (_ "Payment")
+               text))
+         (make-cell
+          (gnc:make-html-text
+           (gnc:html-markup-anchor
+            (gnc:split-anchor-text pmt-split)
+            (gnc:make-gnc-monetary
+             currency (- (xaccSplitGetAmount pmt-split))))))))
+      (filter (lambda (s) (not (equal? (xaccSplitGetParent s) txn)))
+              invoice-splits))
+     (if (gncInvoiceIsPaid invoice)
+         '()
+         (list
+          (list (gnc:make-html-table-cell/size 1 2 (_ "Outstanding"))
+                (make-cell
+                 (gnc:make-gnc-monetary
+                  currency
+                  (gnc-lot-get-balance
+                   (gncInvoiceGetPostedLot invoice)))))))))
+
+  (define (make-payment->invoices-list invoice payment-splits)
+    (list
+     (list
+      (apply
+       gnc:make-html-text
+       (map
+        (lambda (inv-splits)
+          (gnc:html-markup-anchor
+           (gnc:invoice-anchor-text (car inv-splits))
+           (gnc-get-num-action
+            (gncInvoiceGetPostedTxn (car inv-splits))
+            #f)))
+        payment-splits)))))
+
+  (define (make-payment->invoices-table split payment-splits currency)
+    (if (null? payment-splits)
+        (list (list (gnc:make-html-table-cell/size 1 2 (_ "Prepayments"))
+                    (make-cell
+                     (gnc:make-gnc-monetary
+                      currency (- (xaccSplitGetAmount split))))))
+        (map
+         (lambda (inv-splits)
+           (let ((inv (car inv-splits))
+                 (inv-split (cadr inv-splits)))
+             (list
+              (qof-print-date
+               (gncInvoiceGetDatePosted inv))
+              (gnc:make-html-text
+               (gnc:html-markup-anchor
+                (gnc:invoice-anchor-text inv)
+                (gnc-get-num-action
+                 (gncInvoiceGetPostedTxn inv) #f)))
+              (make-cell
+               (gnc:make-gnc-monetary
+                currency
+                (- (xaccSplitGetAmount inv-split)))))))
+         payment-splits)))
+
+  (define (split->type-str split)
+    (let* ((txn (xaccSplitGetParent split))
+           (invoice (gncInvoiceGetInvoiceFromTxn txn)))
+      (cond
+       ((and (txn-is-invoice? txn)
+             (not (null? invoice)))
+        (gnc:make-html-text
+         (gnc:html-markup-anchor
+          (gnc:invoice-anchor-text invoice)
+          (gncInvoiceGetTypeString invoice))))
+       ((txn-is-payment? txn)
+        (gnc:make-html-text
+         (gnc:html-markup-anchor
+          (gnc:split-anchor-text split)
+          (_ "Payment"))))
+       (else (_ "Unknown")))))
+
+  (define (invoice->sale invoice)
+    (and (not (null? invoice))
+         ((if (gncInvoiceGetIsCreditNote invoice) - identity)
+          (gncInvoiceGetTotalSubtotal invoice))))
+
+  (define (invoice->tax invoice)
+    (and (not (null? invoice))
+         ((if (gncInvoiceGetIsCreditNote invoice) - identity)
+          (gncInvoiceGetTotalTax invoice))))
+
+  (define (invoice->due-date invoice)
+    (and (not (null? invoice))
+         (gncInvoiceIsPosted invoice)
+         (gncInvoiceGetDateDue invoice)))
+
+  (let lp ((printed? #f)
+           (odd-row? #t)
+           (splits splits)
+           (total 0)
+           (debit 0)
+           (credit 0)
+           (tax 0)
+           (sale 0)
+           (links '()))
+    (cond
+
+     ((null? splits)
+      ;;Balance row may not have been added if all transactions were before
+      ;;start-date (and no other rows would be added either) so add it now
+      (when (and (not printed?) (value-col used-columns) (not (zero? total)))
+        (add-balance-row odd-row? total))
+      (print-totals total debit credit tax sale)
+      (gnc:html-table-set-style!
+       table "table"
+       'attribute (list "border" 1)
+       'attribute (list "cellspacing" 0)
+       'attribute (list "cellpadding" 4))
+      table)
+
+     ;; not an invoice/payment. skip transaction.
+     ((not (or (txn-is-invoice? (xaccSplitGetParent (car splits)))
+               (txn-is-payment? (xaccSplitGetParent (car splits)))))
+      (lp printed? odd-row? (cdr splits) total debit credit tax sale links))
+
+     ;; invalid case: txn-type-invoice but no associated invoice, nor lot
+     ((let* ((txn (xaccSplitGetParent (car splits)))
+             (invoice (gncInvoiceGetInvoiceFromTxn txn)))
+        (and (txn-is-invoice? txn)
+             (or (null? invoice)
+                 (null? (gncInvoiceGetPostedLot invoice)))))
+      (gnc:warn "sanity check fail" txn)
+      (lp printed? odd-row? (cdr splits) total debit credit tax sale links))
+
+     ;; start printing txns.
+     (else
+      (let* ((split (car splits))
+             (txn (xaccSplitGetParent split))
+             (date (xaccTransGetDate txn))
+             (value (xaccSplitGetAmount split))
+             (value (if reverse? (- value) value))
+             (invoice (gncInvoiceGetInvoiceFromTxn txn))
+             (invoice-splits
+              (and (txn-is-invoice? txn)
+                   (gnc-lot-get-split-list
+                    (gncInvoiceGetPostedLot invoice))))
+             (payment-splits
+              (and (txn-is-payment? txn)
+                   (filter
+                    (lambda (inv-split)
+                      (member txn (map xaccSplitGetParent (cdr inv-split))))
+                    links))))
+
+        (cond
+         ;; txn-date < start-date. skip display, accumulate amounts
+         ((< date start-date)
+          (lp printed? odd-row? (cdr splits) (+ total value)
+              (if (negative? value) (+ debit value) debit)
+              (if (negative? value) credit (+ credit value))
+              tax sale (if (null? invoice) links
+                           (acons invoice invoice-splits links))))
+
+         ;; if balance row hasn't been rendered, consider
+         ;; adding here.  skip if value=0.
+         ((not printed?)
+          (let ((print? (and (value-col used-columns) (not (zero? total)))))
+            (if print? (add-balance-row odd-row? total))
+            (lp #t (not print?) splits total debit credit tax sale links)))
+
+         (else
+          (add-row
+           table odd-row? used-columns date (invoice->due-date invoice)
+           (gnc-get-num-action txn split) (split->type-str split)
+           (xaccSplitGetMemo split) currency (+ total value)
+           (and (>= value 0) value) (and (< value 0) value)
+           (invoice->sale invoice) (invoice->tax invoice)
+           (cond
+            ((and invoice-splits (eq? link-option 'simple))
+             (if (gnc-lot-is-closed (gncInvoiceGetPostedLot invoice))
+                 (list (list (_ "Paid")))
+                 (list (list #f))))
+            ((and invoice-splits (eq? link-option 'detailed))
+             (make-invoice->payments-table invoice invoice-splits currency txn))
+            ((and payment-splits (eq? link-option 'simple))
+             (make-payment->invoices-list invoice payment-splits))
+            ((and payment-splits (eq? link-option 'detailed))
+             (make-payment->invoices-table split payment-splits currency))
+            ;; some error occurred, show 1 line containing empty-list
+            (else '(()))))
+
+          (lp printed? (not odd-row?) (cdr splits) (+ total value)
+              (if (negative? value) (+ debit value) debit)
+              (if (negative? value) credit (+ credit value))
+              (+ tax (or (invoice->tax invoice) 0))
+              (+ sale (or (invoice->sale invoice) 0))
+              (if (null? invoice) links
+                  (acons invoice invoice-splits links))))))))))
+
+(define (options-generator owner-type)
+
+  (define gnc:*report-options* (gnc:new-options))
+
+  (define (gnc:register-inv-option new-option)
+    (gnc:register-option gnc:*report-options* new-option))
+
+  (gnc:register-inv-option
+   (gnc:make-owner-option
+    owner-page (owner-string owner-type) "v"
+    (N_ "The company for this report.")
+    (lambda () '()) #f owner-type))
+
+  (gnc:options-add-date-interval!
+   gnc:*report-options* gnc:pagename-general
+   optname-from-date optname-to-date "a")
+
+  ;; Use a default report date of 'today'
+  (gnc:option-set-default-value
+   (gnc:lookup-option gnc:*report-options* gnc:pagename-general optname-to-date)
+   (cons 'relative 'today))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") date-header
+    "b" (N_ "Display the transaction date?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") due-date-header
+    "c" (N_ "Display the transaction date?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") reference-header
+    "d" (N_ "Display the transaction reference?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") type-header
+    "g" (N_ "Display the transaction type?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") desc-header
+    "ha" (N_ "Display the transaction description?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") sale-header
+    "haa" (N_ "Display the sale amount column?") #f))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") tax-header
+    "hab" (N_ "Display the tax column?") #f))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") credit-header
+    "hac" (N_ "Display the period credits column?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") debit-header
+    "had" (N_ "Display a period debits column?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-simple-boolean-option
+    (N_ "Display Columns") amount-header
+    "hb" (N_ "Display the transaction amount?") #t))
+
+  (gnc:register-inv-option
+   (gnc:make-multichoice-option
+    (N_ "Display Columns") linked-txns-header
+    "hc" (N_ "Show linked transactions") 'none
+    (list (vector 'none
+                  (N_ "Disabled")
+                  (N_ "Linked transactions are hidden."))
+          (vector 'simple
+                  (N_ "Simple")
+                  (N_ "Invoices show if paid, payments show invoice numbers."))
+          (vector 'detailed
+                  (N_ "Detailed")
+                  (N_ "Invoices show list of payments, payments show list of \
+invoices and amounts.")))))
+
+  (gnc:register-inv-option
+   (gnc:make-multichoice-option
+    gnc:pagename-general optname-date-driver "k"
+    (N_ "Leading date.") 'duedate
+    (list
+     ;; Should be using standard label for due date?
+     (vector 'duedate
+             (N_ "Due Date")
+             (N_ "Due date is leading."))
+     ;; Should be using standard label for post date?
+     (vector 'postdate
+             (N_ "Post Date")
+             (N_ "Post date is leading.")))))
+
+  (gnc:options-set-default-section gnc:*report-options* "General")
+
+  gnc:*report-options*)
+
+(define (multiline-to-html-text str)
+  ;; simple function - splits string containing #\newline into
+  ;; substrings, and convert to a gnc:make-html-text construct which
+  ;; adds gnc:html-markup-br after each substring.
+  (let loop ((list-of-substrings (string-split str #\newline))
+             (result '()))
+    (if (null? list-of-substrings)
+        (apply gnc:make-html-text (if (null? result) '() (reverse (cdr result))))
+        (loop (cdr list-of-substrings)
+              (cons* (gnc:html-markup-br) (car list-of-substrings) result)))))
+
+(define (setup-job-query q owner accounts end-date)
+  (let ((guid (gncOwnerReturnGUID owner)))
+    (qof-query-add-guid-match
+     q  (list SPLIT-TRANS INVOICE-FROM-TXN INVOICE-OWNER QOF-PARAM-GUID)
+     guid QOF-QUERY-OR)
+    (qof-query-add-guid-match
+     q (list SPLIT-LOT OWNER-FROM-LOT QOF-PARAM-GUID)
+     guid QOF-QUERY-OR)
+    (qof-query-add-guid-match
+     q (list SPLIT-LOT INVOICE-FROM-LOT INVOICE-OWNER QOF-PARAM-GUID)
+     guid QOF-QUERY-OR)
+    (xaccQueryAddAccountMatch q accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+    (xaccQueryAddDateMatchTT q #f end-date #t end-date QOF-QUERY-AND)
+    (qof-query-set-book q (gnc-get-current-book))
+    (qof-query-set-sort-order q (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+    q))
+
+(define (setup-query q owner accounts end-date)
+  (let ((guid (gncOwnerReturnGUID (gncOwnerGetEndOwner owner))))
+    (qof-query-add-guid-match
+     q (list SPLIT-TRANS INVOICE-FROM-TXN INVOICE-OWNER OWNER-PARENTG)
+     guid QOF-QUERY-OR)
+    (qof-query-add-guid-match
+     q (list SPLIT-LOT OWNER-FROM-LOT OWNER-PARENTG)
+     guid QOF-QUERY-OR)
+    (qof-query-add-guid-match
+     q (list SPLIT-LOT INVOICE-FROM-LOT INVOICE-OWNER OWNER-PARENTG)
+     guid QOF-QUERY-OR)
+    (xaccQueryAddAccountMatch q accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+    (xaccQueryAddDateMatchTT q #f end-date #t end-date QOF-QUERY-AND)
+    (qof-query-set-book q (gnc-get-current-book))
+    (qof-query-set-sort-order q (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+    q))
+
+(define (make-owner-table owner)
+  (let ((table (gnc:make-html-table)))
+    (gnc:html-table-set-style!
+     table "table"
+     'attribute (list "border" 0)
+     'attribute (list "cellspacing" 0)
+     'attribute (list "cellpadding" 0)
+     'attribute (list "valign" "top"))
+    (gnc:html-table-append-row!
+     table (multiline-to-html-text (gnc:owner-get-name-and-address-dep owner)))
+    table))
+
+(define (make-myname-table book date-format)
+  (let* ((table (gnc:make-html-table))
+         (name (gnc:company-info book gnc:*company-name*))
+         (addy (gnc:company-info book gnc:*company-addy*)))
+
+    (gnc:html-table-set-style!
+     table "table"
+     'attribute (list "border" 0)
+     'attribute (list "align" "right")
+     'attribute (list "valign" "top")
+     'attribute (list "cellspacing" 0)
+     'attribute (list "cellpadding" 0))
+
+    (when name
+      (gnc:html-table-append-row! table (list name)))
+    (when addy
+      (gnc:html-table-append-row! table (multiline-to-html-text addy)))
+    (gnc:html-table-append-row!
+     table (list (gnc-print-time64 (gnc:get-today) date-format)))
+    table))
+
+(define (make-break! document)
+  (gnc:html-document-add-object!
+   document
+   (gnc:make-html-text
+    (gnc:html-markup-br))))
+
+(define (reg-renderer report-obj type reverse?)
+  (define options (gnc:report-options report-obj))
+  (define (opt-val section name)
+    (gnc:option-value
+     (gnc:lookup-option options section name)))
+
+  (let* ((accounts (filter (compose xaccAccountIsAPARType xaccAccountGetType)
+                           (gnc-account-get-descendants-sorted
+                            (gnc-get-current-root-account))))
+         (start-date (gnc:time64-start-day-time
+                      (gnc:date-option-absolute-time
+                       (opt-val gnc:pagename-general optname-from-date))))
+         (end-date (gnc:time64-end-day-time
+                    (gnc:date-option-absolute-time
+                     (opt-val gnc:pagename-general optname-to-date))))
+         (book (gnc-get-current-book))
+         (date-format (gnc:options-fancy-date (gnc-get-current-book)))
+         (used-columns (build-column-used options))
+         (link-option
+          (gnc:option-value
+           (gnc:lookup-option options "Display Columns" linked-txns-header)))
+         (owner-descr (owner-string type))
+         (date-type (opt-val gnc:pagename-general optname-date-driver))
+         (owner (opt-val owner-page owner-descr))
+         (query (qof-query-create-for-splits))
+         (document (gnc:make-html-document))
+         (table (gnc:make-html-table))
+         (headings (make-heading-list used-columns link-option))
+         (report-title (string-append (owner-string type) " " (_ "Report"))))
+
+    (cond
+     ((not (gncOwnerIsValid owner))
+      (gnc:html-document-add-object!
+       document (gnc:html-make-generic-warning
+                 report-title (gnc:report-id report-obj)
+                 (cadr (get-info type)) (caddr (get-info type)))))
+
+     ((null? accounts)
+      (gnc:html-document-add-object!
+       document
+       (gnc:html-make-generic-warning
+        (string-append report-title ": " (gncOwnerGetName owner))
+        (gnc:report-id report-obj)
+        (_ "No valid account found")
+        (_ "This report requires a valid AP/AR account to be available."))))
+
+     (else
+      (if (eqv? GNC-OWNER-JOB type)
+          (setup-job-query query owner accounts end-date)
+          (setup-query query owner accounts end-date))
+
+      (let ((splits (xaccQueryGetSplitsUniqueTrans query)))
+        (qof-query-destroy query)
+
+        (gnc:html-document-set-title!
+         document (string-append report-title ": " (gncOwnerGetName owner)))
+
+        (gnc:html-document-set-headline!
+         document (gnc:html-markup
+                   "span" (owner-string type) " " (_ "Report:") " "
+                   (gnc:html-markup-anchor
+                    (if (eqv? GNC-OWNER-JOB type)
+                        (gnc:job-anchor-text (gncOwnerGetJob owner))
+                        (gnc:owner-anchor-text owner))
+                    (gncOwnerGetName owner))))
+
+        (cond
+         ((null? splits)
+
+          (gnc:html-document-add-object!
+           document
+           (gnc:make-html-text
+            (gnc:html-markup-h2 (_ "No transactions found."))
+            (gnc:html-markup-p
+             (format #f (_ "No transactions were found associated with the ~a.")
+                     (string-downcase (car (get-info type)))))
+            (gnc:html-make-options-link (gnc:report-id report-obj)))))
+
+         (else
+          ;; loops in 2 passes: 1st loop. for each APAR account, filter
+          ;; splits into each account. accumulate non-null results into
+          ;; accounts-and-splits accumulator.
+          (let loop ((accounts accounts)
+                     (accounts-and-splits '())
+                     (splits splits))
+            (cond
+             ((null? accounts)
+
+              ;; 2nd loop: for-each accounts-and-splits accumulator, add
+              ;; owner-txns into the html-table. only show header if >1
+              ;; account has splits.
+              (for-each
+               (lambda (acc-splits-pair)
+                 (let* ((account (car acc-splits-pair))
+                        (splits (cdr acc-splits-pair)))
+
+                   (when (> (length accounts-and-splits) 1)
+                     (gnc:html-table-append-row!
+                      table (gnc:make-html-table-cell/size
+                             1 (length headings)
+                             (gnc:make-html-text
+                              (gnc:html-markup-h3
+                               (string-append (_ "Account") ": "
+                                              (xaccAccountGetName account)))))))
+
+                   (add-owner-table table splits account start-date end-date
+                                    date-type used-columns reverse? link-option)))
+               accounts-and-splits))
+
+             (else
+              ;; each 1st loop will slice splits into account-splits and
+              ;; non-account splits, add to accounts-and-splits; and send
+              ;; the non-account splits to be processed in the next loop
+              ;; iteration.
+              (let-values (((acc-splits other-acc-splits)
+                            (partition
+                             (lambda (split)
+                               (equal? (car accounts) (xaccSplitGetAccount split)))
+                             splits)))
+
+                (loop (cdr accounts)
+                      (if (null? acc-splits)
+                          accounts-and-splits
+                          (cons (cons (car accounts) acc-splits)
+                                accounts-and-splits))
+                      other-acc-splits)))))
+
+          (gnc:html-document-add-object!
+           document (make-myname-table book date-format))
+
+          (gnc:html-document-add-object!
+           document (make-owner-table owner))
+
+          (gnc:html-document-add-object!
+           document (gnc:make-html-text
+                     (string-append (_ "Date Range") ": " (qof-print-date start-date)
+                                    " - " (qof-print-date end-date))))
+
+          (make-break! document)
+
+          (gnc:html-table-set-col-headers! table headings)
+
+          (gnc:html-document-add-object! document table))))))
+
+    document))
+
+(define (customer-renderer obj)
+  (reg-renderer obj GNC-OWNER-CUSTOMER #f))
+
+(define (vendor-renderer  obj)
+  (reg-renderer obj GNC-OWNER-VENDOR #t))
+
+(define (employee-renderer obj)
+  (reg-renderer obj GNC-OWNER-EMPLOYEE #t))
+
+(define (job-renderer obj)
+  (reg-renderer obj GNC-OWNER-JOB #f))
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Customer Report (beta)")
+ 'report-guid "c146317be32e4948a561ec7fc89d15c1-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator (lambda () (options-generator GNC-OWNER-CUSTOMER))
+ 'renderer customer-renderer
+ 'in-menu? #t)
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Vendor Report (beta)")
+ 'report-guid "d7d1e53505ee4b1b82efad9eacedaea0-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator (lambda () (options-generator GNC-OWNER-VENDOR))
+ 'renderer vendor-renderer
+ 'in-menu? #t)
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Employee Report (beta)")
+ 'report-guid "08ae9c2e884b4f9787144f47eacd7f44-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator (lambda () (options-generator GNC-OWNER-EMPLOYEE))
+ 'renderer employee-renderer
+ 'in-menu? #t)
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Job Report (beta)")
+ 'report-guid "5518ac227e474f47a34439f2d4d049de-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator (lambda () (options-generator GNC-OWNER-JOB))
+ 'renderer job-renderer
+ 'in-menu? #t)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b2165e163..881dddf6a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -419,6 +419,7 @@ gnucash/report/business-reports/customer-summary.scm
 gnucash/report/business-reports/invoice.scm
 gnucash/report/business-reports/job-report.scm
 gnucash/report/business-reports/new-aging.scm
+gnucash/report/business-reports/new-owner-report.scm
 gnucash/report/business-reports/owner-report.scm
 gnucash/report/business-reports/payables.scm
 gnucash/report/business-reports/receipt.eguile.scm

commit f4a90843034e09cd4c968f0090a33a3e3da34705
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 15:46:19 2019 +0800

    [new-aging] upgrade owner-splits->aging-list to report-utilities
    
    it can be reused by new-owner-report

diff --git a/gnucash/report/business-reports/new-aging.scm b/gnucash/report/business-reports/new-aging.scm
index 66d70c1f9..1ef00c521 100644
--- a/gnucash/report/business-reports/new-aging.scm
+++ b/gnucash/report/business-reports/new-aging.scm
@@ -103,19 +103,6 @@ exist but have no suitable transactions."))
     (gnc:options-set-default-section options "General")
     options))
 
-(define (make-interval-list to-date)
-  (let* ((begindate to-date)
-         (begindate (decdate begindate ThirtyDayDelta))
-         (begindate (decdate begindate ThirtyDayDelta))
-         (begindate (decdate begindate ThirtyDayDelta)))
-    (gnc:make-date-list begindate to-date ThirtyDayDelta)))
-
-;; Have make-list create a stepped list, then add a date in the future
-;; for the "current" bucket
-(define (make-extended-interval-list to-date)
-  (append (make-interval-list to-date)
-          (list +inf.0)))
-
 (define (txn-is-invoice? txn)
   (eqv? (xaccTransGetTxnType txn) TXN-TYPE-INVOICE))
 
@@ -150,55 +137,6 @@ exist but have no suitable transactions."))
                     owner))
     owner))
 
-(define (owner-splits->aging-list splits to-date date-type receivable)
-  (gnc:debug 'processing: (qof-print-date to-date) date-type 'receivable receivable)
-  (for-each gnc:debug splits)
-  (let ((bucket-dates (make-extended-interval-list to-date))
-        (buckets (make-vector num-buckets 0)))
-    (define (addbucket! idx amt)
-      (vector-set! buckets idx (+ amt (vector-ref buckets idx))))
-    (let lp ((splits splits))
-      (cond
-       ((null? splits)
-        (vector->list buckets))
-
-       ;; next split is an invoice posting split. note we don't need
-       ;; to handle invoice payments because these payments will
-       ;; reduce the lot balance automatically.
-       ((txn-is-invoice? (xaccSplitGetParent (car splits)))
-        (let* ((lot (gncInvoiceGetPostedLot
-                     (gncInvoiceGetInvoiceFromTxn
-                      (xaccSplitGetParent (car splits)))))
-               (invoice (gncInvoiceGetInvoiceFromLot lot))
-               (bal (gnc-lot-get-balance lot))
-               (bal (if receivable bal (- bal)))
-               (date (if (eq? date-type 'postdate)
-                         (gncInvoiceGetDatePosted invoice)
-                         (gncInvoiceGetDateDue invoice))))
-          (gnc:pk 'next=invoice (car splits) invoice bal)
-          (let loop ((idx 0)
-                     (bucket-dates bucket-dates))
-            (gnc:debug idx buckets bal invoice date)
-            (if (< date (car bucket-dates))
-                (addbucket! idx bal)
-                (loop (1+ idx) (cdr bucket-dates))))
-          (gnc:debug '* buckets bal invoice date))
-        (lp (cdr splits)))
-
-       ;; next split is a prepayment
-       ((and (txn-is-payment? (xaccSplitGetParent (car splits)))
-             (null? (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot (car splits)))))
-        (let* ((prepay (xaccSplitGetAmount (car splits)))
-               (prepay (if receivable prepay (- prepay))))
-          (gnc:pk 'next=prepay (car splits) prepay)
-          (addbucket! (1- num-buckets) prepay))
-        (lp (cdr splits)))
-
-       ;; not invoice/prepayment. regular or payment split.
-       (else
-        (gnc:pk 'next=skipped (car splits))
-        (lp (cdr splits)))))))
-
 (define (aging-renderer report-obj receivable)
   (define (op-value section name)
     (gnc:option-value
@@ -314,8 +252,9 @@ exist but have no suitable transactions."))
                                                           owner))
                            (owner-splits (car splits-own-others))
                            (other-owner-splits (cdr splits-own-others))
-                           (aging (owner-splits->aging-list
-                                   owner-splits report-date date-type receivable))
+                           (aging (gnc:owner-splits->aging-list
+                                   owner-splits num-buckets report-date
+                                   date-type receivable))
                            (aging-total (apply + aging)))
                       (when (or show-zeros (not (every zero? aging)))
                         (gnc:html-table-append-row!
diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index 3c09e9be6..9961a6a37 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -1093,6 +1093,68 @@ flawed. see report-utilities.scm. please update reports.")
        (total 'merge (cadr account-balance) #f))
      account-balances)
     total))
+
+
+;; ***************************************************************************
+;; Business Functions
+
+;; create a stepped list, then add a date in the infinite future for
+;; the "current" bucket
+(define (make-extended-interval-list to-date num-buckets)
+  (let lp ((begindate to-date) (num-buckets num-buckets))
+    (if (zero? num-buckets)
+        (append (gnc:make-date-list begindate to-date ThirtyDayDelta) (list +inf.0))
+        (lp (decdate begindate ThirtyDayDelta) (1- num-buckets)))))
+
+;; Outputs: aging list of numbers
+(define-public (gnc:owner-splits->aging-list splits num-buckets
+                                             to-date date-type receivable?)
+  (gnc:pk 'processing: (qof-print-date to-date) date-type 'receivable? receivable?)
+  (let ((bucket-dates (make-extended-interval-list to-date (- num-buckets 2)))
+        (buckets (make-vector num-buckets 0)))
+    (define (addbucket! idx amt)
+      (vector-set! buckets idx (+ amt (vector-ref buckets idx))))
+    (let lp ((splits splits))
+      (cond
+       ((null? splits)
+        (vector->list buckets))
+
+       ;; next split is an invoice posting split. note we don't need
+       ;; to handle invoice payments because these payments will
+       ;; reduce the lot balance automatically.
+       ((eqv? (xaccTransGetTxnType (xaccSplitGetParent (car splits)))
+              TXN-TYPE-INVOICE)
+        (let* ((lot (gncInvoiceGetPostedLot
+                     (gncInvoiceGetInvoiceFromTxn
+                      (xaccSplitGetParent (car splits)))))
+               (invoice (gncInvoiceGetInvoiceFromLot lot))
+               (bal (gnc-lot-get-balance lot))
+               (bal (if receivable? bal (- bal)))
+               (date (if (eq? date-type 'postdate)
+                         (gncInvoiceGetDatePosted invoice)
+                         (gncInvoiceGetDateDue invoice))))
+          (gnc:pk 'next=invoice (car splits) invoice bal)
+          (let loop ((idx 0) (bucket-dates bucket-dates))
+            (if (< date (car bucket-dates))
+                (addbucket! idx bal)
+                (loop (1+ idx) (cdr bucket-dates)))))
+        (lp (cdr splits)))
+
+       ;; next split is a prepayment
+       ((and (eqv? (xaccTransGetTxnType (xaccSplitGetParent (car splits)))
+                   TXN-TYPE-PAYMENT)
+             (null? (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot (car splits)))))
+        (let* ((prepay (xaccSplitGetAmount (car splits)))
+               (prepay (if receivable? prepay (- prepay))))
+          (gnc:pk 'next=prepay (car splits) prepay)
+          (addbucket! (1- num-buckets) prepay))
+        (lp (cdr splits)))
+
+       ;; not invoice/prepayment. regular or payment split.
+       (else
+        (gnc:pk 'next=skipped (car splits))
+        (lp (cdr splits)))))))
+
 ;; ***************************************************************************
 
 ;; Adds "file:///" to the beginning of a URL if it doesn't already exist

commit 0ef11d16e168450682bb218d0a5fcf42dbeae275
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 14:11:13 2019 +0800

    [new-aging] new receivable/payable aging reports

diff --git a/gnucash/report/business-reports/CMakeLists.txt b/gnucash/report/business-reports/CMakeLists.txt
index 7d63798c1..f72f12a59 100644
--- a/gnucash/report/business-reports/CMakeLists.txt
+++ b/gnucash/report/business-reports/CMakeLists.txt
@@ -7,6 +7,7 @@ set (business_reports_SCHEME
   receipt.scm
   invoice.scm
   job-report.scm
+  new-aging.scm
   owner-report.scm
   payables.scm
   receivables.scm
diff --git a/gnucash/report/business-reports/business-reports.scm b/gnucash/report/business-reports/business-reports.scm
index 9c331ee57..3191f84ac 100644
--- a/gnucash/report/business-reports/business-reports.scm
+++ b/gnucash/report/business-reports/business-reports.scm
@@ -116,6 +116,7 @@
 (use-modules (gnucash report receipt))
 (use-modules (gnucash report owner-report))
 (use-modules (gnucash report job-report))
+(use-modules (gnucash report new-aging))
 (use-modules (gnucash report payables))
 (use-modules (gnucash report receivables))
 (use-modules (gnucash report customer-summary))
diff --git a/gnucash/report/business-reports/new-aging.scm b/gnucash/report/business-reports/new-aging.scm
new file mode 100644
index 000000000..66d70c1f9
--- /dev/null
+++ b/gnucash/report/business-reports/new-aging.scm
@@ -0,0 +1,377 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; new-aging.scm : accounts payable/receivable aging report
+;;
+;; By Christopher Lam, rewrite and debug
+;; By Derek Atkins <warlord at MIT.EDU> taken from the original...
+;; By Robert Merkel (rgmerk at mira.net)
+;; Copyright (c) 2002, 2003 Derek Atkins <warlord at MIT.EDU>
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation           Voice:  +1-617-542-5942
+;; 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+;; Boston, MA  02110-1301,  USA       gnu at gnu.org
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-module (gnucash report new-aging))
+
+(use-modules (srfi srfi-1))
+(use-modules (srfi srfi-11))            ;let-values
+(use-modules (gnucash utilities))
+(use-modules (gnucash gnc-module))
+(use-modules (gnucash gettext))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+
+(use-modules (gnucash report standard-reports))
+(use-modules (gnucash report business-reports))
+
+(define optname-to-date (N_ "To"))
+(define optname-sort-order (N_ "Sort Order"))
+(define optname-report-currency (N_ "Report's currency"))
+(define optname-price-source (N_ "Price Source"))
+(define optname-show-zeros (N_ "Show zero balance items"))
+(define optname-date-driver (N_ "Due or Post Date"))
+
+(define no-APAR-account (_ "No valid A/Payable or A/Receivable \
+account found. Please ensure valid AP/AR account exists."))
+
+(define empty-APAR-accounts (_ "A/Payable or A/Receivable accounts \
+exist but have no suitable transactions."))
+
+(define num-buckets 6)
+
+(define (setup-query query accounts date)
+  (qof-query-set-book query (gnc-get-current-book))
+  (gnc:query-set-match-non-voids-only! query (gnc-get-current-book))
+  (xaccQueryAddAccountMatch query accounts QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+  (xaccQueryAddDateMatchTT query #f 0 #t date QOF-QUERY-AND)
+  (qof-query-set-sort-order query (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
+  (qof-query-set-sort-increasing query #t #t #t))
+
+(define (aging-options-generator options)
+  (let* ((add-option
+          (lambda (new-option)
+            (gnc:register-option options new-option))))
+
+    (gnc:options-add-report-date!
+     options gnc:pagename-general optname-to-date "a")
+
+    ;; Use a default report date of 'today'
+    (gnc:option-set-default-value
+     (gnc:lookup-option options gnc:pagename-general optname-to-date)
+     (cons 'relative 'today))
+
+    (add-option
+     (gnc:make-multichoice-option
+      gnc:pagename-general optname-sort-order "ia" (N_ "Sort order.") 'increasing
+      (list
+       (vector 'increasing (N_ "Increasing") (N_ "Alphabetical order"))
+       (vector 'decreasing (N_ "Decreasing") (N_ "Reverse alphabetical order")))))
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-show-zeros "j"
+      (N_ "Show all vendors/customers even if they have a zero balance.")
+      #f))
+
+    (add-option
+     (gnc:make-multichoice-option
+      gnc:pagename-general optname-date-driver "k" (N_ "Leading date.") 'duedate
+      (list
+       ;; Should be using standard label for due date?
+       (vector 'duedate
+               (N_ "Due Date")
+               (N_ "Due date is leading."))
+       ;; Should be using standard label for post date?
+       (vector 'postdate
+               (N_ "Post Date")
+               (N_ "Post date is leading.")))))
+
+    (gnc:options-set-default-section options "General")
+    options))
+
+(define (make-interval-list to-date)
+  (let* ((begindate to-date)
+         (begindate (decdate begindate ThirtyDayDelta))
+         (begindate (decdate begindate ThirtyDayDelta))
+         (begindate (decdate begindate ThirtyDayDelta)))
+    (gnc:make-date-list begindate to-date ThirtyDayDelta)))
+
+;; Have make-list create a stepped list, then add a date in the future
+;; for the "current" bucket
+(define (make-extended-interval-list to-date)
+  (append (make-interval-list to-date)
+          (list +inf.0)))
+
+(define (txn-is-invoice? txn)
+  (eqv? (xaccTransGetTxnType txn) TXN-TYPE-INVOICE))
+
+(define (txn-is-payment? txn)
+  (eqv? (xaccTransGetTxnType txn) TXN-TYPE-PAYMENT))
+
+(define (gnc-owner-equal? a b)
+  (string=? (gncOwnerReturnGUID a) (gncOwnerReturnGUID b)))
+
+(define (split-has-owner? split owner)
+  (let* ((split-owner (split->owner split))
+         (retval (gnc-owner-equal? split-owner owner)))
+    (gncOwnerFree split-owner)
+    retval))
+
+(define (split-from-acct? split acct)
+  (equal? acct (xaccSplitGetAccount split)))
+
+(define (list-split lst fn cmp)
+  (let-values (((list-yes list-no) (partition (lambda (elt) (fn elt cmp)) lst)))
+    (cons list-yes list-no)))
+
+;; simpler version of gnc:owner-from-split. must be gncOwnerFree after
+;; use! see split-has-owner? above...
+(define (split->owner split)
+  (let* ((lot (xaccSplitGetLot (gnc-lot-get-earliest-split (xaccSplitGetLot split))))
+         (owner (gncOwnerNew))
+         (use-lot-owner? (gncOwnerGetOwnerFromLot lot owner)))
+    (unless use-lot-owner?
+      (gncOwnerCopy (gncOwnerGetEndOwner
+                     (gncInvoiceGetOwner (gncInvoiceGetInvoiceFromLot lot)))
+                    owner))
+    owner))
+
+(define (owner-splits->aging-list splits to-date date-type receivable)
+  (gnc:debug 'processing: (qof-print-date to-date) date-type 'receivable receivable)
+  (for-each gnc:debug splits)
+  (let ((bucket-dates (make-extended-interval-list to-date))
+        (buckets (make-vector num-buckets 0)))
+    (define (addbucket! idx amt)
+      (vector-set! buckets idx (+ amt (vector-ref buckets idx))))
+    (let lp ((splits splits))
+      (cond
+       ((null? splits)
+        (vector->list buckets))
+
+       ;; next split is an invoice posting split. note we don't need
+       ;; to handle invoice payments because these payments will
+       ;; reduce the lot balance automatically.
+       ((txn-is-invoice? (xaccSplitGetParent (car splits)))
+        (let* ((lot (gncInvoiceGetPostedLot
+                     (gncInvoiceGetInvoiceFromTxn
+                      (xaccSplitGetParent (car splits)))))
+               (invoice (gncInvoiceGetInvoiceFromLot lot))
+               (bal (gnc-lot-get-balance lot))
+               (bal (if receivable bal (- bal)))
+               (date (if (eq? date-type 'postdate)
+                         (gncInvoiceGetDatePosted invoice)
+                         (gncInvoiceGetDateDue invoice))))
+          (gnc:pk 'next=invoice (car splits) invoice bal)
+          (let loop ((idx 0)
+                     (bucket-dates bucket-dates))
+            (gnc:debug idx buckets bal invoice date)
+            (if (< date (car bucket-dates))
+                (addbucket! idx bal)
+                (loop (1+ idx) (cdr bucket-dates))))
+          (gnc:debug '* buckets bal invoice date))
+        (lp (cdr splits)))
+
+       ;; next split is a prepayment
+       ((and (txn-is-payment? (xaccSplitGetParent (car splits)))
+             (null? (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot (car splits)))))
+        (let* ((prepay (xaccSplitGetAmount (car splits)))
+               (prepay (if receivable prepay (- prepay))))
+          (gnc:pk 'next=prepay (car splits) prepay)
+          (addbucket! (1- num-buckets) prepay))
+        (lp (cdr splits)))
+
+       ;; not invoice/prepayment. regular or payment split.
+       (else
+        (gnc:pk 'next=skipped (car splits))
+        (lp (cdr splits)))))))
+
+(define (aging-renderer report-obj receivable)
+  (define (op-value section name)
+    (gnc:option-value
+     (gnc:lookup-option (gnc:report-options report-obj) section name)))
+
+  (define make-heading-list
+    (list ""
+          (_ "Company")
+          (_ "Prepayments")
+          (_ "Current")
+          (_ "0-30 days")
+          (_ "31-60 days")
+          (_ "61-90 days")
+          (_ "91+ days")
+          (_ "Total")))
+
+  (let* ((type (if receivable ACCT-TYPE-RECEIVABLE ACCT-TYPE-PAYABLE))
+         (accounts (filter (lambda (acc) (eqv? (xaccAccountGetType acc) type))
+                           (gnc-account-get-descendants-sorted
+                            (gnc-get-current-root-account))))
+         (report-title (op-value gnc:pagename-general gnc:optname-reportname))
+         (report-date (gnc:time64-end-day-time
+                       (gnc:date-option-absolute-time
+                        (op-value gnc:pagename-general optname-to-date))))
+         (sort-order (op-value gnc:pagename-general optname-sort-order))
+         (show-zeros (op-value gnc:pagename-general optname-show-zeros))
+         (date-type (op-value gnc:pagename-general optname-date-driver))
+         (query (qof-query-create-for-splits))
+         (document (gnc:make-html-document)))
+
+    ;; for sorting and delete-duplicates. compare GUIDs
+    (define (ownerGUID<? a b)
+      (string<? (gncOwnerGetGUID a) (gncOwnerGetGUID b)))
+
+    ;; for presentation. compare names.
+    (define (owner<? a b)
+      ((if (eq? sort-order 'increasing) string<? string>?)
+       (gncOwnerGetName a) (gncOwnerGetName b)))
+
+    ;; set default title
+    (gnc:html-document-set-title! document report-title)
+
+    (cond
+     ((null? accounts)
+      (gnc:html-document-add-object!
+       document (gnc:make-html-text no-APAR-account)))
+
+     (else
+      (setup-query query accounts report-date)
+      (let* ((splits (qof-query-run query))
+             (accounts (sort-and-delete-duplicates (map xaccSplitGetAccount splits)
+                                                   gnc:account-path-less-p equal?))
+             (table (gnc:make-html-table)))
+        (qof-query-destroy query)
+
+        ;; loop into each APAR account
+        (let loop ((accounts accounts)
+                   (splits (filter
+                            (lambda (split)
+                              (or (txn-is-invoice? (xaccSplitGetParent split))
+                                  (txn-is-payment? (xaccSplitGetParent split))))
+                            splits)))
+          (cond
+           ((null? accounts)
+            (gnc:html-table-set-col-headers! table make-heading-list)
+            (gnc:html-document-add-object!
+             document (if (null? (gnc:html-table-data table))
+                          (gnc:make-html-text empty-APAR-accounts)
+                          table)))
+
+           (else
+            (let* ((account (car accounts))
+                   (comm (xaccAccountGetCommodity account))
+                   (splits-acc-others (list-split splits split-from-acct? account))
+                   (acc-splits (car splits-acc-others))
+                   (other-acc-splits (cdr splits-acc-others)))
+
+              (gnc:debug 'account account)
+              (gnc:html-table-append-row!
+               table (list (gnc:make-html-table-cell/size
+                            1 (+ 2 num-buckets) (xaccAccountGetName account))))
+
+              (let* ((split-owners (map split->owner acc-splits))
+                     (acc-owners (sort (sort-and-delete-duplicates
+                                        split-owners ownerGUID<? gnc-owner-equal?)
+                                       owner<?)))
+
+                (gnc:debug 'owners acc-owners)
+
+                ;; loop into each APAR account split
+                (let lp ((acc-owners acc-owners)
+                         (acc-splits acc-splits)
+                         (acc-totals (make-list (1+ num-buckets) 0)))
+                  (cond
+                   ((null? acc-owners)
+                    (for-each gncOwnerFree split-owners)
+                    (gnc:html-table-append-row!
+                     table
+                     (cons* #f
+                            (gnc:make-html-table-cell/markup
+                             "total-label-cell" (_ "Total"))
+                            (map
+                             (lambda (amt)
+                               (gnc:make-html-table-cell/markup
+                                "total-number-cell" (gnc:make-gnc-monetary comm amt)))
+                             acc-totals)))
+                    (loop (cdr accounts)
+                          other-acc-splits))
+
+                   (else
+                    (let* ((owner (car acc-owners))
+                           (splits-own-others (list-split acc-splits split-has-owner?
+                                                          owner))
+                           (owner-splits (car splits-own-others))
+                           (other-owner-splits (cdr splits-own-others))
+                           (aging (owner-splits->aging-list
+                                   owner-splits report-date date-type receivable))
+                           (aging-total (apply + aging)))
+                      (when (or show-zeros (not (every zero? aging)))
+                        (gnc:html-table-append-row!
+                         table
+                         (append
+                          (list #f)
+                          (cons
+                           (gnc:make-html-text
+                            (gnc:html-markup-anchor
+                             (gnc:owner-anchor-text owner)
+                             (gncOwnerGetName owner)))
+                           (map
+                            (lambda (amt)
+                              (gnc:make-html-table-cell/markup
+                               "number-cell" (gnc:make-gnc-monetary comm amt)))
+                            (reverse aging)))
+                          (list
+                           (gnc:make-html-table-cell/markup
+                            "number-cell"
+                            (gnc:make-html-text
+                             (gnc:html-markup-anchor
+                              (gnc:owner-report-text owner account)
+                              (gnc:make-gnc-monetary comm aging-total))))))))
+                      (lp (cdr acc-owners)
+                          other-owner-splits
+                          (map + acc-totals
+                               (reverse (cons aging-total aging))))))))))))))))
+    (gnc:report-finished)
+    document))
+
+(define (payable-options-generator)
+  (aging-options-generator (gnc:new-options)))
+
+(define (receivable-options-generator)
+  (aging-options-generator (gnc:new-options)))
+
+(define (payables-renderer report-obj)
+  (aging-renderer report-obj #f))
+
+(define (receivables-renderer report-obj)
+  (aging-renderer report-obj #t))
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Payable Aging (beta)")
+ 'report-guid "e57770f2dbca46619d6dac4ac5469b50-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator payable-options-generator
+ 'renderer payables-renderer
+ 'in-menu? #t)
+
+(gnc:define-report
+ 'version 1
+ 'name (N_ "Receivable Aging (beta)")
+ 'report-guid "9cf76bed17f14401b8e3e22d0079cb98-new"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator receivable-options-generator
+ 'renderer receivables-renderer
+ 'in-menu? #t)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 709bb76bc..b2165e163 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -418,6 +418,7 @@ gnucash/report/business-reports/business-reports.scm
 gnucash/report/business-reports/customer-summary.scm
 gnucash/report/business-reports/invoice.scm
 gnucash/report/business-reports/job-report.scm
+gnucash/report/business-reports/new-aging.scm
 gnucash/report/business-reports/owner-report.scm
 gnucash/report/business-reports/payables.scm
 gnucash/report/business-reports/receipt.eguile.scm

commit 6eab852f1cb780ba4046871410168fe4f0ee375f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 11:21:19 2019 +0800

    [report-utilities] fix dangling ) in eb929fd6d

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index 0def54b8f..3c09e9be6 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -1147,7 +1147,7 @@ flawed. see report-utilities.scm. please update reports.")
             (cons GNC-OWNER-EMPLOYEE "Emp")))
     (format #f "[~a:~a]"
             (or (assv-ref owner-alist (gncOwnerGetType owner)) "Owner")
-            (gncOwnerGetName owner))))
+            (gncOwnerGetName owner)))
   (define (invoice->str inv)
     (format #f "~a<Post:~a,Owner:~a,Notes:~a,Total:~a>"
             (gncInvoiceGetTypeString inv)

commit eb929fd6d3020a274562e9860e344239cc2645ce
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Oct 27 11:05:19 2019 +0800

    [report-utilities] gnc:strify add invoice->str, refine owner->str

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index 6daee5c9e..0def54b8f 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -1138,16 +1138,25 @@ flawed. see report-utilities.scm. please update reports.")
     (format #f "[~a]"
             (gnc:monetary->string mon)))
   (define (owner->str owner)
-    (define (fn s . rest) (format #f "[~a:~a]" s ((apply compose rest) owner)))
-    (let ((t (gncOwnerGetType owner)))
-      (cond
-       ((eqv? t GNC-OWNER-NONE) "[None]")
-       ((eqv? t GNC-OWNER-UNDEFINED) "[Undefined]")
-       ((eqv? t GNC-OWNER-JOB) (fn "Job" owner->str gncOwnerGetEndOwner))
-       ((eqv? t GNC-OWNER-CUSTOMER) (fn "Cust" gncCustomerGetName gncOwnerGetCustomer))
-       ((eqv? t GNC-OWNER-VENDOR) (fn "Vend" gncVendorGetName gncOwnerGetVendor))
-       ((eqv? t GNC-OWNER-EMPLOYEE) (fn "Emp" gncEmployeeGetName gncOwnerGetEmployee))
-       (else (format #f "[unknown:~a]" owner)))))
+    (define owner-alist
+      (list (cons GNC-OWNER-NONE "None")
+            (cons GNC-OWNER-UNDEFINED "Undefined")
+            (cons GNC-OWNER-JOB "Job")
+            (cons GNC-OWNER-CUSTOMER "Cust")
+            (cons GNC-OWNER-VENDOR "Vend")
+            (cons GNC-OWNER-EMPLOYEE "Emp")))
+    (format #f "[~a:~a]"
+            (or (assv-ref owner-alist (gncOwnerGetType owner)) "Owner")
+            (gncOwnerGetName owner))))
+  (define (invoice->str inv)
+    (format #f "~a<Post:~a,Owner:~a,Notes:~a,Total:~a>"
+            (gncInvoiceGetTypeString inv)
+            (qof-print-date (gncInvoiceGetDatePosted inv))
+            (gncOwnerGetName (gncInvoiceGetOwner inv))
+            (gncInvoiceGetNotes inv)
+            (monetary->string (gnc:make-gnc-monetary
+                               (gncInvoiceGetCurrency inv)
+                               (gncInvoiceGetTotal inv)))))
   (define (try proc)
     ;; Try proc with d as a parameter, catching exceptions to return
     ;; #f to the (or) evaluator below.
@@ -1177,6 +1186,7 @@ flawed. see report-utilities.scm. please update reports.")
       (try monetary->string)
       (try gnc-budget-get-name)
       (try owner->str)
+      (try invoice->str)
       (object->string d)))
 
 (define (pair->num pair)

commit 77855a7ed641cd4fb94e0803c09e5eada546a99c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Oct 26 23:04:06 2019 +0800

    [report-utilities] add owner printers

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index c7f506f27..6daee5c9e 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -1137,6 +1137,17 @@ flawed. see report-utilities.scm. please update reports.")
   (define (monetary->string mon)
     (format #f "[~a]"
             (gnc:monetary->string mon)))
+  (define (owner->str owner)
+    (define (fn s . rest) (format #f "[~a:~a]" s ((apply compose rest) owner)))
+    (let ((t (gncOwnerGetType owner)))
+      (cond
+       ((eqv? t GNC-OWNER-NONE) "[None]")
+       ((eqv? t GNC-OWNER-UNDEFINED) "[Undefined]")
+       ((eqv? t GNC-OWNER-JOB) (fn "Job" owner->str gncOwnerGetEndOwner))
+       ((eqv? t GNC-OWNER-CUSTOMER) (fn "Cust" gncCustomerGetName gncOwnerGetCustomer))
+       ((eqv? t GNC-OWNER-VENDOR) (fn "Vend" gncVendorGetName gncOwnerGetVendor))
+       ((eqv? t GNC-OWNER-EMPLOYEE) (fn "Emp" gncEmployeeGetName gncOwnerGetEmployee))
+       (else (format #f "[unknown:~a]" owner)))))
   (define (try proc)
     ;; Try proc with d as a parameter, catching exceptions to return
     ;; #f to the (or) evaluator below.
@@ -1165,6 +1176,7 @@ flawed. see report-utilities.scm. please update reports.")
       (try trans->str)
       (try monetary->string)
       (try gnc-budget-get-name)
+      (try owner->str)
       (object->string d)))
 
 (define (pair->num pair)

commit 0aad77787044d010e5bdefec3d5e2663aadc8179
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Oct 25 23:27:57 2019 +0800

    [stylesheets] homogenize easy/fancy/footer
    
    * with these reordering of functions, easy == fancy
    * also footer = easy|fancy + footer

diff --git a/gnucash/report/stylesheets/stylesheet-easy.scm b/gnucash/report/stylesheets/stylesheet-easy.scm
index d4f89476d..5731310a1 100644
--- a/gnucash/report/stylesheets/stylesheet-easy.scm
+++ b/gnucash/report/stylesheets/stylesheet-easy.scm
@@ -211,7 +211,6 @@
          (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-
     (gnc:html-document-set-style!
      ssdoc "body"
      'attribute (list "bgcolor" bgcolor)
@@ -323,6 +322,8 @@
         (gnc:html-document-set-style!
          ssdoc "a" 'tag ""))
 
+    (add-css-information-to-doc options ssdoc doc)
+
     (let ((t (gnc:make-html-table)))
       ;; we don't want a bevel for this table, but we don't want
       ;; that to propagate
@@ -338,11 +339,8 @@
       (if (and logopixmap (> (string-length logopixmap) 0))
           (set! headcolumn 1))
 
-      (add-css-information-to-doc options ssdoc doc)
-
-      (let* ((title (gnc:html-document-title doc))
-             (doc-headline (gnc:html-document-headline doc))
-             (headline (if (eq? doc-headline #f) title doc-headline)))
+      (let* ((headline (or (gnc:html-document-headline doc)
+                           (gnc:html-document-title doc))))
 
         (gnc:html-table-set-cell!
          t 1 headcolumn
@@ -368,11 +366,10 @@
 
       ;; only setup an image if we specified one
       (if (and logopixmap (> (string-length logopixmap) 0))
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 0
-             (gnc:make-html-text
-              (gnc:html-markup-img (make-file-url logopixmap))))))
+          (gnc:html-table-set-cell!
+           t 0 0
+           (gnc:make-html-text
+            (gnc:html-markup-img (make-file-url logopixmap)))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
           (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
diff --git a/gnucash/report/stylesheets/stylesheet-fancy.scm b/gnucash/report/stylesheets/stylesheet-fancy.scm
index 13da065c8..8d2f72ead 100644
--- a/gnucash/report/stylesheets/stylesheet-fancy.scm
+++ b/gnucash/report/stylesheets/stylesheet-fancy.scm
@@ -210,7 +210,6 @@
      'attribute (list "bgcolor" bgcolor)
      'attribute (list "text" textcolor)
      'attribute (list "link" linkcolor))
-
 ;;;;
 ;;;;
 ;;;;
@@ -328,15 +327,14 @@
        'attribute (list "style" "margin-left:auto; margin-right:auto")
        'inheritable? #f)
 
-      (let* ((title (gnc:html-document-title doc))
-             (doc-headline (gnc:html-document-headline doc))
-             (headline (if (eq? doc-headline #f) title doc-headline)))
+      ;; set the header column to be the 2nd when we have a logo
+      ;; do this so that when logo is not present, the document
+      ;; is perfectly centered
+      (if (and logopixmap (> (string-length logopixmap) 0))
+          (set! headcolumn 1))
 
-        ;; set the header column to be the 2nd when we have a logo
-        ;; do this so that when logo is not present, the document
-        ;; is perfectly centered
-        (if (and logopixmap (> (string-length logopixmap) 0))
-            (set! headcolumn 1))
+      (let* ((headline (or (gnc:html-document-headline doc)
+                           (gnc:html-document-title doc))))
 
         (gnc:html-table-set-cell!
          t 1 headcolumn
@@ -360,13 +358,12 @@
               (gnc:html-markup-h3 headline))))
         )
 
-      (if (and logopixmap
-               (not (string=? logopixmap "")))
-          ;; check for logo image file name non blank
+      ;; only setup an image if we specified one
+      (if (and logopixmap (> (string-length logopixmap) 0))
           (gnc:html-table-set-cell!
            t 0 0
            (gnc:make-html-text
-            (gnc:html-markup-img (make-file-url logopixmap)))) )
+            (gnc:html-markup-img (make-file-url logopixmap)))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
           (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
@@ -379,7 +376,6 @@
        gnc:html-table-set-cell!
        t 2 headcolumn
        (gnc:html-document-objects doc))
-
       (gnc:html-document-add-object! ssdoc t))
     ssdoc))
 
diff --git a/gnucash/report/stylesheets/stylesheet-footer.scm b/gnucash/report/stylesheets/stylesheet-footer.scm
index 86649b4b9..abe4eaee8 100644
--- a/gnucash/report/stylesheets/stylesheet-footer.scm
+++ b/gnucash/report/stylesheets/stylesheet-footer.scm
@@ -219,7 +219,7 @@
          (bgpixmap (opt-val "Images" "Background Tile"))
          (headpixmap (opt-val "Images" "Heading Banner"))
          (logopixmap (opt-val "Images" "Logo"))
-         (align (gnc:value->string(opt-val "Images" "Heading Alignment")))
+         (align (gnc:value->string (opt-val "Images" "Heading Alignment")))
          (spacing (opt-val "Tables" "Table cell spacing"))
          (padding (opt-val "Tables" "Table cell padding"))
          (border (opt-val "Tables" "Table border width"))
@@ -333,7 +333,8 @@
 
     ;; don't surround marked-up links with <a> </a>
     (if (not links?)
-        (gnc:html-document-set-style! ssdoc "a" 'tag ""))
+        (gnc:html-document-set-style!
+         ssdoc "a" 'tag ""))
 
     (add-css-information-to-doc options ssdoc doc)
 
@@ -352,9 +353,8 @@
       (if (and logopixmap (> (string-length logopixmap) 0))
           (set! headcolumn 1))
 
-      (let* ((title (gnc:html-document-title doc))
-             (doc-headline (gnc:html-document-headline doc))
-             (headline (if (eq? doc-headline #f) title doc-headline)))
+      (let* ((headline (or (gnc:html-document-headline doc)
+                           (gnc:html-document-title doc))))
 
         (gnc:html-table-set-cell!
          t 1 headcolumn
@@ -380,11 +380,10 @@
 
       ;; only setup an image if we specified one
       (if (and logopixmap (> (string-length logopixmap) 0))
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 0
-             (gnc:make-html-text
-              (gnc:html-markup-img (make-file-url logopixmap))))))
+          (gnc:html-table-set-cell!
+           t 0 0
+           (gnc:make-html-text
+            (gnc:html-markup-img (make-file-url logopixmap)))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
           (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
diff --git a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
index f3cfe664c..ee439d045 100644
--- a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
+++ b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
@@ -285,7 +285,7 @@
          (bgpixmap (opt-val "Images" "Background Tile"))
          (headpixmap (opt-val "Images" "Heading Banner"))
          (logopixmap (opt-val "Images" "Logo"))
-         (align (gnc:value->string(opt-val "Images" "Heading Alignment")))
+         (align (gnc:value->string (opt-val "Images" "Heading Alignment")))
          (spacing (opt-val "Tables" "Table cell spacing"))
          (padding (opt-val "Tables" "Table cell padding"))
          (border (opt-val "Tables" "Table border width"))
@@ -418,9 +418,8 @@
       (if (and logopixmap (> (string-length logopixmap) 0))
           (set! headcolumn 1))
 
-      (let* ((title (gnc:html-document-title doc))
-             (doc-headline (gnc:html-document-headline doc))
-             (headline (if (eq? doc-headline #f) title doc-headline)))
+      (let* ((headline (or (gnc:html-document-headline doc)
+                           (gnc:html-document-title doc))))
 
         (gnc:html-table-set-cell!
          t 1 headcolumn

commit 2dd2f0dc65f7efed804851aac3c9a6e1e94e0d82
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Oct 25 23:10:48 2019 +0800

    [stylesheets] replace raw <center> with style attribute

diff --git a/gnucash/report/stylesheets/stylesheet-easy.scm b/gnucash/report/stylesheets/stylesheet-easy.scm
index 421a8b63c..d4f89476d 100644
--- a/gnucash/report/stylesheets/stylesheet-easy.scm
+++ b/gnucash/report/stylesheets/stylesheet-easy.scm
@@ -211,8 +211,6 @@
          (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-    ;; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
 
     (gnc:html-document-set-style!
      ssdoc "body"
@@ -331,6 +329,7 @@
       (gnc:html-table-set-style!
        t "table"
        'attribute (list "border" 0)
+       'attribute (list "style" "margin-left:auto; margin-right:auto")
        'inheritable? #f)
 
       ;; set the header column to be the 2nd when we have a logo
@@ -387,8 +386,6 @@
        t 2 headcolumn
        (gnc:html-document-objects doc))
       (gnc:html-document-add-object! ssdoc t))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
-    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet
diff --git a/gnucash/report/stylesheets/stylesheet-fancy.scm b/gnucash/report/stylesheets/stylesheet-fancy.scm
index f9eceb323..13da065c8 100644
--- a/gnucash/report/stylesheets/stylesheet-fancy.scm
+++ b/gnucash/report/stylesheets/stylesheet-fancy.scm
@@ -205,9 +205,6 @@
          (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-    ;; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
-
     (gnc:html-document-set-style!
      ssdoc "body"
      'attribute (list "bgcolor" bgcolor)
@@ -328,6 +325,7 @@
       (gnc:html-table-set-style!
        t "table"
        'attribute (list "border" 0)
+       'attribute (list "style" "margin-left:auto; margin-right:auto")
        'inheritable? #f)
 
       (let* ((title (gnc:html-document-title doc))
@@ -383,8 +381,6 @@
        (gnc:html-document-objects doc))
 
       (gnc:html-document-add-object! ssdoc t))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
-    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet
diff --git a/gnucash/report/stylesheets/stylesheet-footer.scm b/gnucash/report/stylesheets/stylesheet-footer.scm
index a5ec521bc..86649b4b9 100644
--- a/gnucash/report/stylesheets/stylesheet-footer.scm
+++ b/gnucash/report/stylesheets/stylesheet-footer.scm
@@ -225,10 +225,6 @@
          (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-    ;; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc
-                                   (gnc:make-html-text "<center>"))
-
     (gnc:html-document-set-style!
      ssdoc "body"
      'attribute (list "bgcolor" bgcolor)
@@ -347,6 +343,7 @@
       (gnc:html-table-set-style!
        t "table"
        'attribute (list "border" 0)
+       'attribute (list "style" "margin-left:auto; margin-right:auto")
        'inheritable? #f)
 
       ;; set the header column to be the 2nd when we have a logo
@@ -406,8 +403,6 @@
       (gnc:html-table-set-cell!
        t 3 headcolumn
        (gnc:make-html-text footer-text)))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
-    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet
diff --git a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
index bcf2d992c..f3cfe664c 100644
--- a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
+++ b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
@@ -291,9 +291,6 @@
          (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-    ;; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
-
     (gnc:html-document-set-style!
      ssdoc "body"
      'attribute (list "bgcolor" bgcolor)
@@ -412,6 +409,7 @@
       (gnc:html-table-set-style!
        t "table"
        'attribute (list "border" 0)
+       'attribute (list "style" "margin-left:auto; margin-right:auto")
        'inheritable? #f)
 
       ;; set the header column to be the 2nd when we have a logo
@@ -570,8 +568,6 @@
             (gnc:html-markup-i additional-comments)
             (gnc:html-markup-br))
            " ")))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
-    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet

commit 7ec1596e9c305bd96022606031730142c85fd8ac
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Oct 25 22:56:57 2019 +0800

    [stylesheets] replace raw <div> for headpixmap with html-table-cell

diff --git a/gnucash/report/stylesheets/stylesheet-easy.scm b/gnucash/report/stylesheets/stylesheet-easy.scm
index 29e1f6754..421a8b63c 100644
--- a/gnucash/report/stylesheets/stylesheet-easy.scm
+++ b/gnucash/report/stylesheets/stylesheet-easy.scm
@@ -376,18 +376,11 @@
               (gnc:html-markup-img (make-file-url logopixmap))))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 headcolumn
-             (gnc:make-html-text
-              (string-append
-               "<div align=\"" align "\">"
-               "<img src=\"" (make-file-url headpixmap) "\">"
-               "</div>")))
-            )
-          (gnc:html-table-set-cell!
-           t 0 headcolumn
-           (gnc:make-html-text " ")))
+          (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
+                 (cell (gnc:make-html-table-cell (gnc:make-html-text div))))
+            (gnc:html-table-cell-set-style! cell "td" 'attribute `("align" ,align))
+            (gnc:html-table-set-cell! t 0 headcolumn cell))
+          (gnc:html-table-set-cell! t 0 headcolumn (gnc:make-html-text " ")))
 
       (apply
        gnc:html-table-set-cell!
diff --git a/gnucash/report/stylesheets/stylesheet-fancy.scm b/gnucash/report/stylesheets/stylesheet-fancy.scm
index a28bf6c86..f9eceb323 100644
--- a/gnucash/report/stylesheets/stylesheet-fancy.scm
+++ b/gnucash/report/stylesheets/stylesheet-fancy.scm
@@ -370,23 +370,12 @@
            (gnc:make-html-text
             (gnc:html-markup-img (make-file-url logopixmap)))) )
 
-      (if (and headpixmap
-               (not (string=? headpixmap "")))
-          ;; check for header image file name nonblank
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 headcolumn
-             (gnc:make-html-text
-              ;; XX: isn't there some way to apply the alignment to
-              ;; (gnc:html-markup-img headpixmap)?
-              (string-append
-               "<div align=\"" align "\">"
-               "<img src=\"" (make-file-url headpixmap) "\">"
-               "</div>")))
-            )
-          (gnc:html-table-set-cell!
-           t 0 headcolumn
-           (gnc:make-html-text " ")))
+      (if (and headpixmap (> (string-length headpixmap) 0))
+          (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
+                 (cell (gnc:make-html-table-cell (gnc:make-html-text div))))
+            (gnc:html-table-cell-set-style! cell "td" 'attribute `("align" ,align))
+            (gnc:html-table-set-cell! t 0 headcolumn cell))
+          (gnc:html-table-set-cell! t 0 headcolumn (gnc:make-html-text " ")))
 
       (apply
        gnc:html-table-set-cell!
diff --git a/gnucash/report/stylesheets/stylesheet-footer.scm b/gnucash/report/stylesheets/stylesheet-footer.scm
index fcebbbb81..a5ec521bc 100644
--- a/gnucash/report/stylesheets/stylesheet-footer.scm
+++ b/gnucash/report/stylesheets/stylesheet-footer.scm
@@ -390,18 +390,11 @@
               (gnc:html-markup-img (make-file-url logopixmap))))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 headcolumn
-             (gnc:make-html-text
-              (string-append
-               "<div align=\"" align "\">"
-               "<img src=\"" (make-file-url headpixmap) "\">"
-               "</div>")))
-            )
-          (gnc:html-table-set-cell!
-           t 0 headcolumn
-           (gnc:make-html-text " ")))
+          (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
+                 (cell (gnc:make-html-table-cell (gnc:make-html-text div))))
+            (gnc:html-table-cell-set-style! cell "td" 'attribute `("align" ,align))
+            (gnc:html-table-set-cell! t 0 headcolumn cell))
+          (gnc:html-table-set-cell! t 0 headcolumn (gnc:make-html-text " ")))
 
       (apply
        gnc:html-table-set-cell!
diff --git a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
index 81bc37e90..bcf2d992c 100644
--- a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
+++ b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
@@ -496,17 +496,11 @@
               (gnc:html-markup-img (make-file-url logopixmap))))))
 
       (if (and headpixmap (> (string-length headpixmap) 0))
-          (begin
-            (gnc:html-table-set-cell!
-             t 0 headcolumn
-             (gnc:make-html-text
-              (string-append
-               "<div align=\"" align "\">"
-               "<img src=\"" (make-file-url headpixmap) "\">"
-               "</div>"))))
-          (gnc:html-table-set-cell!
-           t 0 headcolumn
-           (gnc:make-html-text " ")))
+          (let* ((div (gnc:html-markup-img (make-file-url headpixmap)))
+                 (cell (gnc:make-html-table-cell (gnc:make-html-text div))))
+            (gnc:html-table-cell-set-style! cell "td" 'attribute `("align" ,align))
+            (gnc:html-table-set-cell! t 0 headcolumn cell))
+          (gnc:html-table-set-cell! t 0 headcolumn (gnc:make-html-text " ")))
 
       (apply
        gnc:html-table-set-cell!

commit dc8310843b2dfe9bd56e38cb0adf315bbb9b7020
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Oct 25 22:34:41 2019 +0800

    [stylesheets] remove unnecessary N_ in option section/name

diff --git a/gnucash/report/stylesheets/stylesheet-easy.scm b/gnucash/report/stylesheets/stylesheet-easy.scm
index b1eed52f5..29e1f6754 100644
--- a/gnucash/report/stylesheets/stylesheet-easy.scm
+++ b/gnucash/report/stylesheets/stylesheet-easy.scm
@@ -188,36 +188,31 @@
           (lambda (section name)
             (gnc:color-option->html
              (gnc:lookup-option options section name))))
-         (preparer (opt-val (N_ "General") (N_ "Preparer")))
-         (prepared-for (opt-val (N_ "General") (N_ "Prepared for")))
-         (show-preparer? (opt-val (N_ "General") (N_ "Show preparer info")))
-         (links? (opt-val (N_ "General") (N_ "Enable Links")))
-         (bgcolor (color-val (N_ "Colors") (N_ "Background Color")))
-         (textcolor (color-val (N_ "Colors") (N_ "Text Color")))
-         (linkcolor (color-val (N_ "Colors") (N_ "Link Color")))
-         (normal-row-color (color-val (N_ "Colors") (N_ "Table Cell Color")))
-         (alternate-row-color (color-val (N_ "Colors")
-                                         (N_ "Alternate Table Cell Color")))
+         (preparer (opt-val "General" "Preparer"))
+         (prepared-for (opt-val "General" "Prepared for"))
+         (show-preparer? (opt-val "General" "Show preparer info"))
+         (links? (opt-val "General" "Enable Links"))
+         (bgcolor (color-val "Colors" "Background Color"))
+         (textcolor (color-val "Colors" "Text Color"))
+         (linkcolor (color-val "Colors" "Link Color"))
+         (normal-row-color (color-val "Colors" "Table Cell Color"))
+         (alternate-row-color (color-val "Colors" "Alternate Table Cell Color"))
          (primary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Subheading/Subtotal Cell Color")))
+          (color-val "Colors" "Subheading/Subtotal Cell Color"))
          (secondary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Sub-subheading/total Cell Color")))
-         (grand-total-color (color-val (N_ "Colors")
-                                       (N_ "Grand Total Cell Color")))
-         (bgpixmap (opt-val (N_ "Images") (N_ "Background Tile")))
-         (headpixmap (opt-val (N_ "Images") (N_ "Heading Banner")))
-         (logopixmap (opt-val (N_ "Images") (N_ "Logo")))
-         (align (gnc:value->string(opt-val (N_ "Images") (N_ "Heading Alignment"))))
-         (spacing (opt-val (N_ "Tables") (N_ "Table cell spacing")))
-         (padding (opt-val (N_ "Tables") (N_ "Table cell padding")))
-         (border (opt-val (N_ "Tables") (N_ "Table border width")))
+          (color-val "Colors" "Sub-subheading/total Cell Color"))
+         (grand-total-color (color-val "Colors" "Grand Total Cell Color"))
+         (bgpixmap (opt-val "Images" "Background Tile"))
+         (headpixmap (opt-val "Images" "Heading Banner"))
+         (logopixmap (opt-val "Images" "Logo"))
+         (align (gnc:value->string (opt-val "Images" "Heading Alignment")))
+         (spacing (opt-val "Tables" "Table cell spacing"))
+         (padding (opt-val "Tables" "Table cell padding"))
+         (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-                                        ; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc
-                                   (gnc:make-html-text "<center>"))
+    ;; center the document without elements inheriting anything
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
 
     (gnc:html-document-set-style!
      ssdoc "body"
@@ -338,9 +333,9 @@
        'attribute (list "border" 0)
        'inheritable? #f)
 
-                                        ; set the header column to be the 2nd when we have a logo
-                                        ; do this so that when logo is not present, the document
-                                        ; is perfectly centered
+      ;; set the header column to be the 2nd when we have a logo
+      ;; do this so that when logo is not present, the document
+      ;; is perfectly centered
       (if (and logopixmap (> (string-length logopixmap) 0))
           (set! headcolumn 1))
 
@@ -372,7 +367,7 @@
               (gnc:html-markup-h3 headline))))
         )
 
-                                        ; only setup an image if we specified one
+      ;; only setup an image if we specified one
       (if (and logopixmap (> (string-length logopixmap) 0))
           (begin
             (gnc:html-table-set-cell!
@@ -399,7 +394,8 @@
        t 2 headcolumn
        (gnc:html-document-objects doc))
       (gnc:html-document-add-object! ssdoc t))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>")) ;;TODO: make this a div instead of <center> (deprecated)
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
+    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet
diff --git a/gnucash/report/stylesheets/stylesheet-fancy.scm b/gnucash/report/stylesheets/stylesheet-fancy.scm
index 26dae6e55..a28bf6c86 100644
--- a/gnucash/report/stylesheets/stylesheet-fancy.scm
+++ b/gnucash/report/stylesheets/stylesheet-fancy.scm
@@ -182,36 +182,31 @@
           (lambda (section name)
             (gnc:color-option->html
              (gnc:lookup-option options section name))))
-         (preparer (opt-val (N_ "General") (N_ "Preparer")))
-         (prepared-for (opt-val (N_ "General") (N_ "Prepared for")))
-         (show-preparer? (opt-val (N_ "General") (N_ "Show preparer info")))
-         (links? (opt-val (N_ "General") (N_ "Enable Links")))
-         (bgcolor (color-val (N_ "Colors") (N_ "Background Color")))
-         (textcolor (color-val (N_ "Colors") (N_ "Text Color")))
-         (linkcolor (color-val (N_ "Colors") (N_ "Link Color")))
-         (normal-row-color (color-val (N_ "Colors") (N_ "Table Cell Color")))
-         (alternate-row-color (color-val (N_ "Colors")
-                                         (N_ "Alternate Table Cell Color")))
+         (preparer (opt-val "General" "Preparer"))
+         (prepared-for (opt-val "General" "Prepared for"))
+         (show-preparer? (opt-val "General" "Show preparer info"))
+         (links? (opt-val "General" "Enable Links"))
+         (bgcolor (color-val "Colors" "Background Color"))
+         (textcolor (color-val "Colors" "Text Color"))
+         (linkcolor (color-val "Colors" "Link Color"))
+         (normal-row-color (color-val "Colors" "Table Cell Color"))
+         (alternate-row-color (color-val "Colors" "Alternate Table Cell Color"))
          (primary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Subheading/Subtotal Cell Color")))
+          (color-val "Colors" "Subheading/Subtotal Cell Color"))
          (secondary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Sub-subheading/total Cell Color")))
-         (grand-total-color (color-val (N_ "Colors")
-                                       (N_ "Grand Total Cell Color")))
-         (bgpixmap (opt-val (N_ "Images") (N_ "Background Tile")))
-         (headpixmap (opt-val (N_ "Images") (N_ "Heading Banner")))
-         (logopixmap (opt-val (N_ "Images") (N_ "Logo")))
-         (align (gnc:value->string(opt-val (N_ "Images") (N_ "Heading Alignment"))))
-         (spacing (opt-val (N_ "Tables") (N_ "Table cell spacing")))
-         (padding (opt-val (N_ "Tables") (N_ "Table cell padding")))
-         (border (opt-val (N_ "Tables") (N_ "Table border width")))
+          (color-val "Colors" "Sub-subheading/total Cell Color"))
+         (grand-total-color (color-val "Colors" "Grand Total Cell Color"))
+         (bgpixmap (opt-val "Images" "Background Tile"))
+         (headpixmap (opt-val "Images" "Heading Banner"))
+         (logopixmap (opt-val "Images" "Logo"))
+         (align (gnc:value->string (opt-val "Images" "Heading Alignment")))
+         (spacing (opt-val "Tables" "Table cell spacing"))
+         (padding (opt-val "Tables" "Table cell padding"))
+         (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
-                                        ; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc
-                                   (gnc:make-html-text "<center>"))
+    ;; center the document without elements inheriting anything
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
 
     (gnc:html-document-set-style!
      ssdoc "body"
@@ -339,9 +334,9 @@
              (doc-headline (gnc:html-document-headline doc))
              (headline (if (eq? doc-headline #f) title doc-headline)))
 
-                                        ; set the header column to be the 2nd when we have a logo
-                                        ; do this so that when logo is not present, the document
-                                        ; is perfectly centered
+        ;; set the header column to be the 2nd when we have a logo
+        ;; do this so that when logo is not present, the document
+        ;; is perfectly centered
         (if (and logopixmap (> (string-length logopixmap) 0))
             (set! headcolumn 1))
 
@@ -399,8 +394,8 @@
        (gnc:html-document-objects doc))
 
       (gnc:html-document-add-object! ssdoc t))
-    (gnc:html-document-add-object! ssdoc
-                                   (gnc:make-html-text "</center>")) ;;TODO: make this a div instead of <center> (deprecated)
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
+    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet
diff --git a/gnucash/report/stylesheets/stylesheet-footer.scm b/gnucash/report/stylesheets/stylesheet-footer.scm
index 5f22cbcc1..fcebbbb81 100644
--- a/gnucash/report/stylesheets/stylesheet-footer.scm
+++ b/gnucash/report/stylesheets/stylesheet-footer.scm
@@ -201,32 +201,28 @@
           (lambda (section name)
             (gnc:color-option->html
              (gnc:lookup-option options section name))))
-         (preparer (opt-val (N_ "General") (N_ "Preparer")))
-         (prepared-for (opt-val (N_ "General") (N_ "Prepared for")))
-         (show-preparer? (opt-val (N_ "General") (N_ "Show preparer info")))
-         (links? (opt-val (N_ "General") (N_ "Enable Links")))
-         (footer-text (opt-val (N_ "General") (N_ "Footer")))
-         (bgcolor (color-val (N_ "Colors") (N_ "Background Color")))
-         (textcolor (color-val (N_ "Colors") (N_ "Text Color")))
-         (linkcolor (color-val (N_ "Colors") (N_ "Link Color")))
-         (normal-row-color (color-val (N_ "Colors") (N_ "Table Cell Color")))
-         (alternate-row-color (color-val (N_ "Colors")
-                                         (N_ "Alternate Table Cell Color")))
+         (preparer (opt-val "General" "Preparer"))
+         (prepared-for (opt-val "General" "Prepared for"))
+         (show-preparer? (opt-val "General" "Show preparer info"))
+         (links? (opt-val "General" "Enable Links"))
+         (footer-text (opt-val "General" "Footer"))
+         (bgcolor (color-val "Colors" "Background Color"))
+         (textcolor (color-val "Colors" "Text Color"))
+         (linkcolor (color-val "Colors" "Link Color"))
+         (normal-row-color (color-val "Colors" "Table Cell Color"))
+         (alternate-row-color (color-val "Colors" "Alternate Table Cell Color"))
          (primary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Subheading/Subtotal Cell Color")))
+          (color-val "Colors" "Subheading/Subtotal Cell Color"))
          (secondary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Sub-subheading/total Cell Color")))
-         (grand-total-color (color-val (N_ "Colors")
-                                       (N_ "Grand Total Cell Color")))
-         (bgpixmap (opt-val (N_ "Images") (N_ "Background Tile")))
-         (headpixmap (opt-val (N_ "Images") (N_ "Heading Banner")))
-         (logopixmap (opt-val (N_ "Images") (N_ "Logo")))
-         (align (gnc:value->string(opt-val (N_ "Images") (N_ "Heading Alignment"))))
-         (spacing (opt-val (N_ "Tables") (N_ "Table cell spacing")))
-         (padding (opt-val (N_ "Tables") (N_ "Table cell padding")))
-         (border (opt-val (N_ "Tables") (N_ "Table border width")))
+          (color-val "Colors" "Sub-subheading/total Cell Color"))
+         (grand-total-color (color-val "Colors" "Grand Total Cell Color"))
+         (bgpixmap (opt-val "Images" "Background Tile"))
+         (headpixmap (opt-val "Images" "Heading Banner"))
+         (logopixmap (opt-val "Images" "Logo"))
+         (align (gnc:value->string(opt-val "Images" "Heading Alignment")))
+         (spacing (opt-val "Tables" "Table cell spacing"))
+         (padding (opt-val "Tables" "Table cell padding"))
+         (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
     ;; center the document without elements inheriting anything
diff --git a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
index be64e663b..81bc37e90 100644
--- a/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
+++ b/gnucash/report/stylesheets/stylesheet-head-or-tail.scm
@@ -257,46 +257,42 @@
           (lambda (section name)
             (gnc:color-option->html
              (gnc:lookup-option options section name))))
-         (preparer (opt-val (N_ "General") (N_ "Preparer")))
-         (prepared-for (opt-val (N_ "General") (N_ "Prepared for")))
-         (show-preparer? (opt-val (N_ "General") (N_ "Show preparer info")))
-         (show-receiver? (opt-val (N_ "General") (N_ "Show receiver info")))
-         (show-date? (opt-val (N_ "General") (N_ "Show date")))
-         (show-time? (opt-val (N_ "General") (N_ "Show time in addition to date")))
-         (show-gnucash-version? (opt-val (N_ "General") (N_ "Show GnuCash Version")))
-         (show-preparer-at-bottom? (opt-val (N_ "General") (N_ "Show preparer info at bottom")))
-         (show-receiver-at-bottom? (opt-val (N_ "General") (N_ "Show receiver info at bottom")))
-         (show-date-time-at-bottom? (opt-val (N_ "General") (N_ "Show date/time at bottom")))
-         (show-comments-at-bottom? (opt-val (N_ "General") (N_ "Show comments at bottom")))
-         (show-gnucash-version-at-bottom? (opt-val (N_ "General") (N_ "Show GnuCash version at bottom")))
-         (links? (opt-val (N_ "General") (N_ "Enable Links")))
-         (additional-comments (opt-val (N_ "General") (N_ "Additional Comments")))
-         (bgcolor (color-val (N_ "Colors") (N_ "Background Color")))
-         (textcolor (color-val (N_ "Colors") (N_ "Text Color")))
-         (linkcolor (color-val (N_ "Colors") (N_ "Link Color")))
-         (normal-row-color (color-val (N_ "Colors") (N_ "Table Cell Color")))
-         (alternate-row-color (color-val (N_ "Colors")
-                                         (N_ "Alternate Table Cell Color")))
+         (preparer (opt-val "General" "Preparer"))
+         (prepared-for (opt-val "General" "Prepared for"))
+         (show-preparer? (opt-val "General" "Show preparer info"))
+         (show-receiver? (opt-val "General" "Show receiver info"))
+         (show-date? (opt-val "General" "Show date"))
+         (show-time? (opt-val "General" "Show time in addition to date"))
+         (show-gnucash-version? (opt-val "General" "Show GnuCash Version"))
+         (show-preparer-at-bottom? (opt-val "General" "Show preparer info at bottom"))
+         (show-receiver-at-bottom? (opt-val "General" "Show receiver info at bottom"))
+         (show-date-time-at-bottom? (opt-val "General" "Show date/time at bottom"))
+         (show-comments-at-bottom? (opt-val "General" "Show comments at bottom"))
+         (show-gnucash-version-at-bottom?
+          (opt-val "General" "Show GnuCash version at bottom"))
+         (links? (opt-val "General" "Enable Links"))
+         (additional-comments (opt-val "General" "Additional Comments"))
+         (bgcolor (color-val "Colors" "Background Color"))
+         (textcolor (color-val "Colors" "Text Color"))
+         (linkcolor (color-val "Colors" "Link Color"))
+         (normal-row-color (color-val "Colors" "Table Cell Color"))
+         (alternate-row-color (color-val "Colors" "Alternate Table Cell Color"))
          (primary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Subheading/Subtotal Cell Color")))
+          (color-val "Colors" "Subheading/Subtotal Cell Color"))
          (secondary-subheading-color
-          (color-val (N_ "Colors")
-                     (N_ "Sub-subheading/total Cell Color")))
-         (grand-total-color (color-val (N_ "Colors")
-                                       (N_ "Grand Total Cell Color")))
-         (bgpixmap (opt-val (N_ "Images") (N_ "Background Tile")))
-         (headpixmap (opt-val (N_ "Images") (N_ "Heading Banner")))
-         (logopixmap (opt-val (N_ "Images") (N_ "Logo")))
-         (align (gnc:value->string(opt-val (N_ "Images") (N_ "Heading Alignment"))))
-         (spacing (opt-val (N_ "Tables") (N_ "Table cell spacing")))
-         (padding (opt-val (N_ "Tables") (N_ "Table cell padding")))
-         (border (opt-val (N_ "Tables") (N_ "Table border width")))
+          (color-val "Colors" "Sub-subheading/total Cell Color"))
+         (grand-total-color (color-val "Colors" "Grand Total Cell Color"))
+         (bgpixmap (opt-val "Images" "Background Tile"))
+         (headpixmap (opt-val "Images" "Heading Banner"))
+         (logopixmap (opt-val "Images" "Logo"))
+         (align (gnc:value->string(opt-val "Images" "Heading Alignment")))
+         (spacing (opt-val "Tables" "Table cell spacing"))
+         (padding (opt-val "Tables" "Table cell padding"))
+         (border (opt-val "Tables" "Table border width"))
          (headcolumn 0))
 
     ;; center the document without elements inheriting anything
-    (gnc:html-document-add-object! ssdoc
-                                   (gnc:make-html-text "<center>"))
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "<center>"))
 
     (gnc:html-document-set-style!
      ssdoc "body"
@@ -438,23 +434,17 @@
              (gnc:make-html-text
               (gnc:html-markup-i
                (_ "Prepared by: ")
-               (gnc:html-markup-b preparer)
-               )
-              (gnc:html-markup-br)
-              )
-             " "
-             )
+               (gnc:html-markup-b preparer))
+              (gnc:html-markup-br))
+             " ")
          (if (and show-receiver? (not show-receiver-at-bottom?))
              ;; print receiver info as additional header info
              (gnc:make-html-text
               (gnc:html-markup-i
                (_ "Prepared for: ")
                (gnc:html-markup-b prepared-for)
-               (gnc:html-markup-br)
-               )
-              )
-             " "
-             )
+               (gnc:html-markup-br)))
+             " ")
          (if (and show-date? (not show-date-time-at-bottom?))
              ;; print date/time info as additional header info
              (if show-time?
@@ -463,55 +453,39 @@
                    (_ "Report Creation Date: ")
                    (qof-print-date (gnc:get-today))
                    " "
-                   (gnc-print-time64 (current-time) "%X %Z")
-                   )
-                  (gnc:html-markup-br)
-                  )
+                   (gnc-print-time64 (current-time) "%X %Z"))
+                  (gnc:html-markup-br))
                  (gnc:make-html-text
                   (gnc:html-markup-i
                    (_ "Report Creation Date: ")
-                   (qof-print-date (gnc:get-today))
-                   )
-                  (gnc:html-markup-br)
-                  )
-                 )
-             " "
-             )
+                   (qof-print-date (gnc:get-today)))
+                  (gnc:html-markup-br)))
+             " ")
          (if (and show-gnucash-version? (not show-gnucash-version-at-bottom?))
              ;; print the GnuCash version string as additional header info
              (gnc:make-html-text
               (gnc:html-markup-i
                "GnuCash "
-               gnc:version
-               )
-              (gnc:html-markup-br)
-              )
-             " "
-             )
+               gnc:version)
+              (gnc:html-markup-br))
+             " ")
          (if (not show-comments-at-bottom?)
              ;; print additional comments as additional header info
              (gnc:make-html-text
               (gnc:html-markup-br)
               (gnc:html-markup-i additional-comments)
-              (gnc:html-markup-br)
-              )
-             " "
-             )
+              (gnc:html-markup-br))
+             " ")
          ;; add separator line if any additional header info is printed
          (if (or
               (and show-preparer? (not show-preparer-at-bottom?))
               (and show-receiver? (not show-receiver-at-bottom?))
               (and show-date? (not show-date-time-at-bottom?))
               (and show-gnucash-version? (not show-gnucash-version-at-bottom?))
-              (not show-comments-at-bottom?)
-              )
+              (not show-comments-at-bottom?))
              (gnc:make-html-text
-              (gnc:html-markup-br)
-              )
-             " "
-             )
-         )
-        )
+              (gnc:html-markup-br))
+             " ")))
 
       ;; only setup an image if we specified one
       (if (and logopixmap (> (string-length logopixmap) 0))
@@ -529,8 +503,7 @@
               (string-append
                "<div align=\"" align "\">"
                "<img src=\"" (make-file-url headpixmap) "\">"
-               "</div>")))
-            )
+               "</div>"))))
           (gnc:html-table-set-cell!
            t 0 headcolumn
            (gnc:make-html-text " ")))
@@ -550,36 +523,28 @@
             (and show-preparer? show-preparer-at-bottom?)
             (and show-receiver? show-receiver-at-bottom?)
             (and show-date? show-date-time-at-bottom?)
-            (and show-gnucash-version? show-gnucash-version-at-bottom?)
-            show-comments-at-bottom?
-            )
+            (and show-gnucash-version?
+                 show-gnucash-version-at-bottom?)
+            show-comments-at-bottom?)
            (gnc:make-html-text
-            (gnc:html-markup-br)
-            )
-           " "
-           )
+            (gnc:html-markup-br))
+           " ")
        (if (and show-preparer? show-preparer-at-bottom?)
            ;; print preparer info as additional header info
            (gnc:make-html-text
             (gnc:html-markup-i
              (_ "Prepared by: ")
-             (gnc:html-markup-b preparer)
-             )
-            (gnc:html-markup-br)
-            )
-           " "
-           )
+             (gnc:html-markup-b preparer))
+            (gnc:html-markup-br))
+           " ")
        (if (and show-receiver? show-receiver-at-bottom?)
            ;; print receiver info as additional header info
            (gnc:make-html-text
             (gnc:html-markup-i
              (_ "Prepared for: ")
-             (gnc:html-markup-b prepared-for)
-             )
-            (gnc:html-markup-br)
-            )
-           " "
-           )
+             (gnc:html-markup-b prepared-for))
+            (gnc:html-markup-br))
+           " ")
        (if (and show-date? show-date-time-at-bottom?)
            ;; print date/time info as additional header info
            (if show-time?
@@ -588,42 +553,31 @@
                  (_ "Report Creation Date: ")
                  (qof-print-date (gnc:get-today))
                  " "
-                 (gnc-print-time64 (current-time) "%X %Z")
-                 )
-                (gnc:html-markup-br)
-                )
+                 (gnc-print-time64 (current-time) "%X %Z"))
+                (gnc:html-markup-br))
                (gnc:make-html-text
                 (gnc:html-markup-i
                  (_ "Report Creation Date: ")
                  (qof-print-date (gnc:get-today))
-                 (gnc:html-markup-br)
-                 )
-                )
-               )
-           " "
-           )
+                 (gnc:html-markup-br))))
+           " ")
        (if (and show-gnucash-version? show-gnucash-version-at-bottom?)
            ;; print the GnuCash version string as additional header info
            (gnc:make-html-text
             (gnc:html-markup-i
              (_ "GnuCash ")
-             gnc:version
-             )
-            (gnc:html-markup-br)
-            )
-           " "
-           )
+             gnc:version)
+            (gnc:html-markup-br))
+           " ")
        (if show-comments-at-bottom?
            ;; print additional comments as additional header info
            (gnc:make-html-text
             (gnc:html-markup-br)
             (gnc:html-markup-i additional-comments)
-            (gnc:html-markup-br)
-            )
-           " "
-           )
-       ))
-    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>")) ;;TODO: make this a div instead of <center> (deprecated)
+            (gnc:html-markup-br))
+           " ")))
+    (gnc:html-document-add-object! ssdoc (gnc:make-html-text "</center>"))
+    ;;TODO: make this a div instead of <center> (deprecated)
     ssdoc))
 
 (gnc:define-html-style-sheet

commit b2fcfbd3c6c82c0da77ee781f91ebc84e35080c3
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Oct 25 18:27:47 2019 +0800

    Bug 797326 - Enhancement: budget's Estimate tool should ignore Closing Entries
    
    Addendum to 8b8c957ed -- if budgeted amounts exclude closing entries,
    actual amounts should also exclude closing entries.
    
    Amend documentation, modify budget test to add a closing entry which
    will be ignored.

diff --git a/libgnucash/engine/Recurrence.c b/libgnucash/engine/Recurrence.c
index 093836ac4..cf1ef2904 100644
--- a/libgnucash/engine/Recurrence.c
+++ b/libgnucash/engine/Recurrence.c
@@ -419,7 +419,7 @@ recurrenceGetAccountPeriodValue(const Recurrence *r, Account *acc, guint n)
     g_return_val_if_fail(r && acc, gnc_numeric_zero());
     t1 = recurrenceGetPeriodTime(r, n, FALSE);
     t2 = recurrenceGetPeriodTime(r, n, TRUE);
-    return xaccAccountGetBalanceChangeForPeriod (acc, t1, t2, TRUE);
+    return xaccAccountGetNoclosingBalanceChangeForPeriod (acc, t1, t2, TRUE);
 }
 
 void
diff --git a/libgnucash/engine/Recurrence.h b/libgnucash/engine/Recurrence.h
index aa375d69d..6f8df001e 100644
--- a/libgnucash/engine/Recurrence.h
+++ b/libgnucash/engine/Recurrence.h
@@ -140,7 +140,8 @@ time64 recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end);
 
 /**
  * @return the amount that an Account's value changed between the beginning
- * and end of the nth instance of the Recurrence.
+ * and end of the nth instance of the Recurrence. Please note this function
+ * is only used in budget reports and will exclude closing entries.
  **/
 gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
         Account *acct, guint n);
diff --git a/libgnucash/engine/gnc-budget.h b/libgnucash/engine/gnc-budget.h
index 548275833..af23c43c9 100644
--- a/libgnucash/engine/gnc-budget.h
+++ b/libgnucash/engine/gnc-budget.h
@@ -145,8 +145,12 @@ void gnc_budget_unset_account_period_value(
 gboolean gnc_budget_is_account_period_value_set(
     const GncBudget *budget, const Account *account, guint period_num);
 
+/* get the budget account period's budgeted value */
 gnc_numeric gnc_budget_get_account_period_value(
     const GncBudget *budget, const Account *account, guint period_num);
+
+/* get the budget account period's actual value, including children,
+   excluding closing entries */
 gnc_numeric gnc_budget_get_account_period_actual_value(
     const GncBudget *budget, Account *account, guint period_num);
 
diff --git a/libgnucash/engine/test/test-extras.scm b/libgnucash/engine/test/test-extras.scm
index 126f7e0ec..a0a1027d4 100644
--- a/libgnucash/engine/test/test-extras.scm
+++ b/libgnucash/engine/test/test-extras.scm
@@ -839,6 +839,7 @@
          (budget (gnc-budget-new book))
          (bank (cdr (assoc "Bank" account-alist)))
          (income (cdr (assoc "Income" account-alist)))
+         (equity (cdr (assoc "Equity" account-alist)))
          (expense (cdr (assoc "Expenses" account-alist))))
     (gnc-budget-set-name budget "test budget")
     (gnc-budget-begin-edit budget)
@@ -861,7 +862,9 @@
       (env-create-transaction env (midperiod 2) bank income 67)
       (env-create-transaction env (midperiod 3) bank income 77)
       (env-create-transaction env (midperiod 0) expense bank 20)
-      (env-create-transaction env (midperiod 1) expense bank 20))
+      (env-create-transaction env (midperiod 1) expense bank 20)
+      (let ((clos (env-create-transaction env (midperiod 1) income equity 55)))
+        (xaccTransSetIsClosingTxn clos #t)))
     budget))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



Summary of changes:
 gnucash/report/report-utilities.scm                |  84 ++
 gnucash/report/reports/CMakeLists.txt              |   2 +
 gnucash/report/reports/standard/new-aging.scm      | 315 ++++++++
 .../report/reports/standard/new-owner-report.scm   | 889 +++++++++++++++++++++
 gnucash/report/stylesheets/easy.scm                |  91 +--
 gnucash/report/stylesheets/fancy.scm               |  98 +--
 gnucash/report/stylesheets/footer.scm              |  85 +-
 gnucash/report/stylesheets/head-or-tail.scm        | 209 ++---
 libgnucash/engine/Recurrence.c                     |   2 +-
 libgnucash/engine/Recurrence.h                     |   3 +-
 libgnucash/engine/gnc-budget.h                     |   4 +
 libgnucash/engine/test/test-engine-extras.scm      |   5 +-
 po/POTFILES.in                                     |   2 +
 13 files changed, 1487 insertions(+), 302 deletions(-)
 create mode 100644 gnucash/report/reports/standard/new-aging.scm
 create mode 100644 gnucash/report/reports/standard/new-owner-report.scm



More information about the gnucash-changes mailing list