gnucash maint: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Fri Apr 30 07:31:46 EDT 2021


Updated	 via  https://github.com/Gnucash/gnucash/commit/254ccaca (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3168347a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/14c523e4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c38740fc (commit)
	from  https://github.com/Gnucash/gnucash/commit/e3d4bd2e (commit)



commit 254ccacafaa49dac8e848d509708f787aa3d034a
Merge: e3d4bd2e2 3168347ab
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Apr 30 19:31:13 2021 +0800

    Merge branch 'maint-ACB-report' into maint #978


commit 3168347ab7209ce8e85c52ae6a7991a4a1196131
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Jul 8 22:42:57 2020 +0800

    [ifrs-cost-basis] initial commit
    
    Candidate Report https://bugs.gnucash.org/show_bug.cgi?id=797796#c153

diff --git a/gnucash/report/reports/CMakeLists.txt b/gnucash/report/reports/CMakeLists.txt
index deb34de22..6178d4ede 100644
--- a/gnucash/report/reports/CMakeLists.txt
+++ b/gnucash/report/reports/CMakeLists.txt
@@ -38,6 +38,7 @@ set (reports_standard_SCHEME
     standard/equity-statement.scm
     standard/general-journal.scm
     standard/general-ledger.scm
+    standard/ifrs-cost-basis.scm
     standard/income-gst-statement.scm
     standard/income-statement.scm
     standard/lot-viewer.scm
diff --git a/gnucash/report/reports/standard/ifrs-cost-basis.scm b/gnucash/report/reports/standard/ifrs-cost-basis.scm
new file mode 100644
index 000000000..af35c3f54
--- /dev/null
+++ b/gnucash/report/reports/standard/ifrs-cost-basis.scm
@@ -0,0 +1,436 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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 reports standard ifrs-cost-basis))
+
+(use-modules (srfi srfi-1))
+(use-modules (ice-9 match))
+(use-modules (gnucash utilities))
+(use-modules (gnucash report))
+(use-modules (gnucash core-utils))
+(use-modules (gnucash app-utils))
+(use-modules (gnucash engine))
+
+(define disclaimer
+  (gnc:make-html-text
+   (gnc:html-markup-p "This report is designed for cost basis
+accumulation and capital gain/loss reporting using the weighted
+average cost basis method, which is most consistent with typical
+accounting frameworks (US GAAP, IFRS, etc.).  This report allows for
+for the choice to capitalize (most consistent with typical accounting
+frameworks) vs expense (used by some taxing jurisdictions) commissions
+paid on purchase.")
+   (gnc:html-markup-p "This report is not appropriate for FIFO, LIFO, or
+specific-identification methods for cost basis accumulation and
+capital gain/loss reporting.  This report may not be appropriate for
+tax purposes, if the taxing jurisdiction requires a method other than
+the weighted average cost basis method.")
+   (gnc:html-markup-p "This report is not designed with options
+reporting in mind.  If your activity involves options and/or futures
+that are purchased, written, and/or exercised, there is no guarantee
+that this report will accurately portray this options activity.")))
+
+(define reportname "IFRS weighted-average cost basis report")
+
+(define optname-startdate (N_ "Start Date"))
+(define optname-enddate (N_ "End Date"))
+
+(define optname-stock-acct "Stock Account")
+(define optname-proceeds-acct "Proceeds Account")
+(define optname-dividend-acct "Dividend Account")
+(define optname-capgains-acct "Cap Gains Account")
+;; (define optname-fees-acct "Fees Account")
+(define optname-report-currency "Report's currency")
+
+(define optname-format-cells "Format monetary cells")
+(define opthelp-format-cells "Check this option to show cells with currency")
+
+(define optname-format-short "Alternative row-style for shorts")
+(define opthelp-format-short "Check this option to use alternate style \
+for shorts. Disable to use alternate style every other row")
+
+(define optname-cap-purch-costs "Capitalise purchase commissions")
+(define opthelp-cap-purch-costs "Check this option to capitalise purchase \
+commissions in cumulative average cost and gain/loss after commission")
+
+(define (options-generator)
+  (let ((options (gnc:new-options)))
+
+    (define (add-option new-option)
+      (gnc:register-option options new-option))
+
+    (gnc:options-add-date-interval!
+     options gnc:pagename-general optname-startdate optname-enddate " ")
+
+    (gnc:options-add-currency!
+     options gnc:pagename-general optname-report-currency "a")
+
+    (add-option
+     (gnc:make-account-sel-limited-option
+      gnc:pagename-general optname-stock-acct "b" "Stock Account"
+      #f #f (list ACCT-TYPE-STOCK ACCT-TYPE-MUTUAL)))
+
+    (add-option
+     (gnc:make-account-sel-limited-option
+      gnc:pagename-general optname-proceeds-acct "c" "Proceeds Account"
+      #f #f (list ACCT-TYPE-ASSET ACCT-TYPE-BANK)))
+
+    (add-option
+     (gnc:make-account-sel-limited-option
+      gnc:pagename-general optname-dividend-acct "c" "Dividend Account"
+      #f #f (list ACCT-TYPE-INCOME)))
+
+    (add-option
+     (gnc:make-account-sel-limited-option
+      gnc:pagename-general optname-capgains-acct "d" "Cap Gains Account"
+      #f #f (list ACCT-TYPE-INCOME)))
+
+    ;; (add-option
+    ;;  (gnc:make-account-sel-limited-option
+    ;;   gnc:pagename-general optname-fees-acct "c" "Fees Account"
+    ;;   #f #f (list ACCT-TYPE-EXPENSE)))
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-format-cells "e" opthelp-format-cells #t))
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-format-short "f" opthelp-format-short #t))
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-cap-purch-costs "g" opthelp-cap-purch-costs #t))
+
+    options))
+
+(define M+
+  (case-lambda
+    (() (error "M+ needs at least 1 arg"))
+    ((a b) (if a (if b (+ a b) a) b))
+    ((head . tail) (fold M+ head tail))))
+
+(define M-abs
+  (case-lambda
+    (() (error "M-abs needs 1 arg"))
+    ((a) (and a (abs a)))))
+
+(define M*
+  (case-lambda
+    (() (error "M* needs at least 1 arg"))
+    ((a b) (and a b (* a b)))
+    ((head . tail) (fold M* head tail))))
+
+(define M-
+  (case-lambda
+    (() (error "M- needs at least 1 arg"))
+    ((n) (and n (- n)))
+    ((minuend head . tail) (M+ minuend (M- (fold M+ head tail))))))
+
+(define M/
+  (case-lambda
+    (() (error "M/ needs at least 1 arg"))
+    ((n) (and n (not (zero? n)) (/ n)))
+    ((divisor head . tail) (M* divisor (M/ (fold M* head tail))))))
+
+(define (trans-extract trans account numfilter split->amount)
+  (define (not-account? s)
+    (and account (not (equal? (xaccSplitGetAccount s) account))))
+  (define (not-num-filter? s)
+    (and numfilter
+         (not (equal? (gnc-get-action-num (xaccSplitGetParent s) s) numfilter))))
+  (let lp ((splits (xaccTransGetSplitList trans)) (result #f))
+    (match splits
+      (() result)
+      (((? not-account?) . rest) (lp rest result))
+      (((? not-num-filter?) . rest) (lp rest result))
+      ((split . rest) (lp rest (M+ (split->amount split) result))))))
+
+(define (trans-extract-value trans account numfilter)
+  (trans-extract trans account numfilter xaccSplitGetValue))
+
+(define (trans-extract-amount trans account numfilter)
+  (trans-extract trans account numfilter xaccSplitGetAmount))
+
+(define (ifrs-cost-basis-renderer report-obj)
+  (define (opt-val section name)
+    (gnc:option-value
+     (gnc:lookup-option (gnc:report-options report-obj) section name)))
+
+  (define opt-startdate (opt-val gnc:pagename-general optname-startdate))
+  (define opt-enddate   (opt-val gnc:pagename-general optname-enddate))
+  (define startdate
+    (gnc:time64-start-day-time
+     (gnc:date-option-absolute-time opt-startdate)))
+  (define enddate
+    (gnc:time64-start-day-time
+     (gnc:date-option-absolute-time opt-enddate)))
+  (define stock-acct   (opt-val gnc:pagename-general optname-stock-acct))
+  (define proceeds-acct (opt-val gnc:pagename-general optname-proceeds-acct))
+  (define dividend-acct (opt-val gnc:pagename-general optname-dividend-acct))
+  (define capgains-acct (opt-val gnc:pagename-general optname-capgains-acct))
+  ;; (define fees-acct (opt-val gnc:pagename-general optname-fees-acct))
+  (define report-currency (opt-val gnc:pagename-general optname-report-currency))
+  (define format-cells (opt-val gnc:pagename-general optname-format-cells))
+  (define short-alternate-format? (opt-val gnc:pagename-general optname-format-short))
+  (define cap-purch-costs? (opt-val gnc:pagename-general optname-cap-purch-costs))
+  (define document (gnc:make-html-document))
+
+  (define (elt->cell split)
+    (gnc:html-markup-anchor
+     (gnc:split-anchor-text split)
+     (amount->monetary (xaccSplitGetAmount split))))
+
+  (define large 10000000)
+  (define (get-fx db from to time)
+    (/ (gnc-pricedb-convert-balance-nearest-price-t64 db large from to time)
+       large))
+
+  (define (stock-split prev delta)
+    (let ((exact (/ (+ delta prev) prev)))
+      (format #f "~a:~a Split" (numerator exact) (denominator exact))))
+
+  (define (to-cell elt)
+    (gnc:make-html-table-cell/markup "number-cell" elt))
+
+  (define (cmp amt neg zero pos)
+    (cond ((< amt 0) neg)
+          ((= amt 0) zero)
+          (else pos)))
+
+  (gnc:html-document-set-title! document "IFRS weighted average cost basis Report")
+
+  (cond
+   ((null? stock-acct)
+    (gnc:html-document-add-object!
+     document (gnc:html-make-generic-options-warning
+               reportname (gnc:report-id report-obj))))
+
+   (else
+    (let ((commodity (xaccAccountGetCommodity stock-acct))
+          (currency (gnc-account-get-currency-or-parent stock-acct))
+          (pricedb (gnc-pricedb-get-db (gnc-get-current-book)))
+          (splits
+           (let ((query (qof-query-create-for-splits)))
+             (qof-query-set-book query (gnc-get-current-book))
+             (xaccQueryAddSingleAccountMatch query stock-acct QOF-QUERY-AND)
+             (xaccQueryGetSplitsUniqueTrans query))))
+
+      (define (to-commodity amt)
+        (if format-cells
+            (and amt (gnc:make-gnc-monetary commodity amt))
+            amt))
+
+      (define (to-orig-currency amt)
+        (if format-cells
+            (and amt (gnc:make-gnc-monetary currency amt))
+            amt))
+
+      (define (to-report-currency amt)
+        (if format-cells
+            (and amt (gnc:make-gnc-monetary report-currency amt))
+            amt))
+
+      (define table (gnc:make-html-table))
+
+      (gnc:html-document-set-title!
+       document
+       (format #f "Average-Cost (Basis) Report: From ~a to ~a. Report-currency ~a"
+               (qof-print-date startdate)
+               (qof-print-date enddate)
+               (gnc-commodity-get-mnemonic report-currency)))
+
+      (gnc:html-table-set-col-headers!
+       table (list "date" "description" "trans-units" "cumul-units" "note"
+                   "curr" "fx" "purchase-val" "purchase-cost" "cash-dividends"
+                   "proceeds-val" "proceeds-cost" "conv-purchase-val"
+                   "conv-purchase-cost" "conv-dividends"
+                   "conv-proceeds-val" "conv-proceeds-cost"
+                   "average-cost-basis/unit-for-sale" "average-cost-basis-of-sale"
+                   "cumulative-average-cost-basis"
+                   "gain-post-commission" "gain-pre-commission" "net-proceeds"
+                   "cumul-gross-profit" "cumul-net-profit" "cumul-tot-return"))
+
+      (let lp ((splits splits)
+               (odd-row? #t)
+               (cumul-units 0)
+               (cumul-average-cost-basis 0)
+               (cumul-gross-profit 0)
+               (cumul-net-profit 0)
+               (cumul-tot-return 0))
+
+        (match splits
+          (() (gnc:html-document-add-object! document table))
+
+          ((split . rest-splits)
+           (let* ((trans (xaccSplitGetParent split))
+                  (trans-units (trans-extract-amount trans stock-acct #f))
+                  (trans-value (trans-extract-value trans stock-acct #f))
+                  (proceeds-val (trans-extract-value trans proceeds-acct #f))
+                  (dividends-val (trans-extract-value trans dividend-acct #f))
+                  (capgains-val (trans-extract-value trans capgains-acct #f))
+                  (fees-value (trans-extract-value trans #f "Fee"))
+                  (new-units (M+ cumul-units trans-units))
+
+                  (sale?
+                   (cond
+                    ((< trans-units 0) (<= 0 new-units))
+                    ((> trans-units 0) (<= new-units 0))
+                    (else #f)))
+
+                  (purchase?
+                   (cond
+                    ((= trans-value 0) dividends-val)        ;dividends
+                    ((= trans-units 0) proceeds-val)         ;return of capital
+                    ((> trans-units 0) (< 0 new-units))      ;regular buy
+                    ((< trans-units 0) (< new-units 0))))    ;buy during short
+
+                  (shorting? (or (< new-units 0)
+                                 (and (= new-units 0) (< 0 trans-units))))
+
+                  (purchase-cost (and purchase? fees-value))
+                  (purchase-val (and purchase? (M- trans-value purchase-cost)))
+                  (cash-dividends (M- dividends-val))
+                  (proceeds-cost (and sale? fees-value))
+                  (proceeds-val (and sale? (M+ proceeds-val proceeds-cost)))
+
+                  ;; now convert to report-currency
+                  (fx (get-fx pricedb currency report-currency
+                              (time64CanonicalDayTime (xaccTransGetDate trans))))
+                  (conv-purchase-val (M* fx purchase-val))
+                  (conv-purchase-cost (M* fx purchase-cost))
+                  (conv-dividends (M* fx cash-dividends))
+                  (conv-proceeds-val (M* fx proceeds-val))
+                  (conv-proceeds-cost (M* fx proceeds-cost))
+
+                  ;; now perform AVERAGE-COST-BASIS calculations
+                  (average-cost-basis/unit-for-sale
+                   (M-abs (M/ cumul-average-cost-basis cumul-units)))
+                  (average-cost-basis-of-sale
+                   (and proceeds-val (M* average-cost-basis/unit-for-sale
+                                         trans-units)))
+                  (cumul-average-cost-basis
+                   (M+ cumul-average-cost-basis
+                       conv-purchase-val
+                       (and cap-purch-costs? conv-purchase-cost)
+                       average-cost-basis-of-sale))
+
+                  (net-proceeds (M- conv-proceeds-val conv-proceeds-cost))
+                  (gain-post-commission (M+ net-proceeds average-cost-basis-of-sale
+                                            (and (not cap-purch-costs?)
+                                                 conv-purchase-cost)))
+                  (gain-pre-commission (M+ conv-proceeds-val
+                                           average-cost-basis-of-sale))
+
+                  (new-gross-profit (M+ cumul-gross-profit gain-pre-commission))
+                  (new-net-profit (M+ cumul-net-profit gain-post-commission))
+                  (new-tot-return (M+ cumul-tot-return gain-post-commission
+                                      conv-dividends)))
+
+             ;; (gnc:pk trans 'trans-units trans-units 'trans-value trans-value
+             ;;         'cumul-units cumul-units 'proceeds-val proceeds-val
+             ;;         'sale? sale? 'purchase? purchase?)
+             (cond
+              ((not (< startdate (xaccTransGetDate (xaccSplitGetParent (car splits)))
+                       enddate))
+               (lp rest-splits
+                   odd-row?
+                   new-units
+                   cumul-average-cost-basis
+                   new-gross-profit
+                   new-net-profit
+                   new-tot-return))
+
+              (else
+               (gnc:html-table-append-row/markup!
+                table (if short-alternate-format?
+                          (if shorting? "alternate-row" "normal-row")
+                          (if odd-row? "normal-row" "alternate-row"))
+                (list (qof-print-date (xaccTransGetDate trans))
+                      (gnc:html-string-sanitize (xaccTransGetDescription trans))
+                      (to-cell (gnc:html-split-anchor split (to-commodity trans-units)))
+                      (to-cell (to-commodity new-units))
+                      (cond
+                       ((< new-units 0 cumul-units) "ERROR: long→short")
+                       ((< cumul-units 0 new-units) "ERROR: short→long")
+                       ((= 0 cumul-units) (cmp new-units "Open Short" "1" "Open Long"))
+                       ((= 0 new-units) (cmp trans-units "Close Long" "2" "Close Short"))
+                       ((= 0 trans-units trans-value)
+                        (cmp cumul-units "Compensatory Dividend" "7" "Dividend"))
+                       ((= 0 trans-units)
+                        (cond (cash-dividends
+                               (cmp cumul-units
+                                    "Compensatory Notional Distribution"
+                                    "7"
+                                    "Notional Distribution"))
+                              (purchase-val
+                               (cmp cumul-units
+                                    "Compensatory Return Capital"
+                                    "8"
+                                    "Return Capital"))
+                              (else "3")))
+                       ((= 0 trans-value) (stock-split cumul-units trans-units))
+                       (purchase-val (cmp purchase-val "Short Sell" "5" "Buy"))
+                       (proceeds-val (cmp proceeds-val "Short Buy" "6" "Sell"))
+                       (else "4"))
+                      (gnc-commodity-get-mnemonic currency)
+                      (to-cell (gnc:default-price-renderer report-currency fx))
+                      (to-cell (to-orig-currency purchase-val))
+                      (to-cell (to-orig-currency purchase-cost))
+                      (to-cell (to-orig-currency cash-dividends))
+                      (to-cell (to-orig-currency proceeds-val))
+                      (to-cell (to-orig-currency proceeds-cost))
+                      (to-cell (to-report-currency conv-purchase-val))
+                      (to-cell (to-report-currency conv-purchase-cost))
+                      (to-cell (to-report-currency conv-dividends))
+                      (to-cell (to-report-currency conv-proceeds-val))
+                      (to-cell (to-report-currency conv-proceeds-cost))
+                      (to-cell (to-report-currency average-cost-basis/unit-for-sale))
+                      (to-cell (to-report-currency (M- average-cost-basis-of-sale)))
+                      (to-cell (to-report-currency cumul-average-cost-basis))
+                      (to-cell (to-report-currency gain-post-commission))
+                      (to-cell (to-report-currency gain-pre-commission))
+                      (to-cell (to-report-currency net-proceeds))
+                      (to-cell (to-report-currency new-gross-profit))
+                      (to-cell (to-report-currency new-net-profit))
+                      (to-cell (to-report-currency new-tot-return))))
+
+               (lp rest-splits
+                   (not odd-row?)
+                   new-units
+                   cumul-average-cost-basis
+                   new-gross-profit
+                   new-net-profit
+                   new-tot-return))))))))))
+
+  ;; (gnc:dump-all-transactions)
+  (gnc:html-document-add-object! document disclaimer)
+  document)
+
+
+;; Here we define the actual report
+(gnc:define-report
+ 'version 1
+ 'name reportname
+ 'report-guid "15d5b744176c4625a703720338725291"
+ 'menu-path (list gnc:menuname-experimental)
+ 'options-generator options-generator
+ 'renderer ifrs-cost-basis-renderer)
diff --git a/gnucash/report/reports/standard/test/CMakeLists.txt b/gnucash/report/reports/standard/test/CMakeLists.txt
index 0875bcbf1..49a850667 100644
--- a/gnucash/report/reports/standard/test/CMakeLists.txt
+++ b/gnucash/report/reports/standard/test/CMakeLists.txt
@@ -17,6 +17,7 @@ set(scm_test_with_srfi64_SOURCES
   test-trial-balance.scm
   test-equity-statement.scm
   test-average-balance.scm
+  test-ifrs-cost-basis.scm
   test-invoice.scm
   test-new-owner-report.scm
   test-owner-report.scm
diff --git a/gnucash/report/reports/standard/test/test-ifrs-cost-basis.scm b/gnucash/report/reports/standard/test/test-ifrs-cost-basis.scm
new file mode 100644
index 000000000..f0f0492cb
--- /dev/null
+++ b/gnucash/report/reports/standard/test/test-ifrs-cost-basis.scm
@@ -0,0 +1,357 @@
+(use-modules (gnucash engine))
+(use-modules (gnucash app-utils))
+(use-modules (tests test-engine-extras))
+(use-modules (gnucash reports standard average-cost-basis))
+(use-modules (gnucash report stylesheets plain))
+(use-modules (gnucash report))
+(use-modules (tests test-report-extras))
+(use-modules (srfi srfi-64))
+(use-modules (tests srfi64-extras))
+(use-modules (sxml simple))
+(use-modules (sxml xpath))
+
+;; This is implementation testing for both the AVERAGE-COST-BASIS Tool
+(define uuid "15d5b744176c4625a703720338725291")
+
+;; Explicitly set locale to make the report output predictable
+(setlocale LC_ALL "C")
+
+(define (run-test)
+  (test-runner-factory gnc:test-runner)
+  (test-begin "test-ifrs-cost-basis.scm")
+  (null-test)
+  (average-cost-basis-tests)
+  (test-end "test-ifrs-cost-basis.scm"))
+
+(define (options->sxml uuid options test-title)
+  (gnc:options->sxml uuid options "test-ifrs-basis" test-title))
+
+(define (set-option! options section name value)
+  (let ((option (gnc:lookup-option options section name)))
+    (if option
+        (gnc:option-set-value option value)
+        (test-assert (format #f "wrong-option ~a ~a" section name) #f))))
+
+(define (null-test)
+  ;; This null-test tests for the presence of report.
+  (let ((options (gnc:make-report-options uuid)))
+    (test-assert "null-test"
+      (options->sxml uuid options "null-test"))))
+
+(define (mnemonic->commodity sym)
+  (gnc-commodity-table-lookup
+   (gnc-commodity-table-get-table (gnc-get-current-book))
+   (gnc-commodity-get-namespace (gnc-default-report-currency))
+   sym))
+
+(define (new-commodity name ns sym scu)
+  (let* ((book (gnc-get-current-book))
+         (comm-table (gnc-commodity-table-get-table book))
+         (new-comm (gnc-commodity-new book name ns sym "" scu)))
+    (gnc-commodity-table-insert comm-table new-comm)
+    new-comm))
+
+(define (create-average-cost-basis-test-data)
+  (define book (gnc-get-current-book))
+  (define env (create-test-env))
+  (define USD (mnemonic->commodity "USD"))
+  (define CAD (mnemonic->commodity "CAD"))
+  (define SPY (new-commodity "SPY" "NYSE" "SPY" 10000))
+  (define structure
+    (list "Root" (list (cons 'type ACCT-TYPE-ASSET)
+                       (cons 'commodity CAD))
+          (list "Asset"
+                (list "Broker" (list (cons 'commodity CAD))
+                      (list "CAD Cash" (list (cons 'commodity CAD)))
+                      (list "USD Cash" (list (cons 'commodity USD)))
+                      (list "SPY" (list (cons 'commodity SPY)
+                                        (cons 'type ACCT-TYPE-STOCK))))
+                (list "Current Assets"
+                      (list "Checking Account")))
+          (list "Income" (list (cons 'type ACCT-TYPE-INCOME))
+                (list "USD CapGain" (list (cons 'commodity USD)))
+                (list "USD Interest" (list (cons 'commodity USD))))
+          (list "Expenses" (list (cons 'type ACCT-TYPE-EXPENSE))
+                (list "USD Commissions" (list (cons 'commodity USD))))
+          (list "Equity" (list (cons 'type ACCT-TYPE-EQUITY))
+                (list "Opening Balances")
+                (list "Opening Balances USD" (list (cons 'commodity USD))))))
+  (define account-alist (env-create-account-structure-alist env structure))
+  (define (get-acct name)
+    (or (assoc-ref account-alist name) (error "no account" name)))
+  (define usd-cash (get-acct "USD Cash"))
+  (define usd-comm (get-acct "USD Commissions"))
+  (define inc-capg (get-acct "USD CapGain"))
+  (define spy (get-acct "SPY"))
+
+  (env-transfer env 01 05 2020
+                (get-acct "Opening Balances")
+                (get-acct "Checking Account")
+                200000 #:description "opening cash")
+
+  (env-transfer env 06 05 2020
+                (get-acct "Checking Account")
+                (get-acct "CAD Cash")
+                100000 #:description "fund trading account")
+
+  (env-transfer-foreign env 10 05 2020
+                        (get-acct "CAD Cash")
+                        usd-cash
+                        100000 85000
+                        #:description "Convert CAD to USD")
+
+  (env-create-multisplit-transaction
+   env 01 07 2019
+   (list (vector usd-cash  -2000995/100 -2000995/100 "")
+         (vector spy 20000 100 "Buy")
+         (vector spy 995/100 0 "Fee"))
+   #:description "Buy SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 11 12 2019
+   (list (vector usd-cash -1600995/100 -1600995/100 "")
+         (vector spy 16000 50 "Buy")
+         (vector spy 995/100 0 "Fee")
+         )
+   #:description "Buy SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 18 03 2020
+   (list (vector usd-comm 995/100 995/100 "Fee")
+         (vector usd-cash 1199005/100 1199005/100 "")
+         (vector inc-capg 600995/100 600995/100 "")
+         (vector spy -12000 -75 "Sell")
+         (vector spy -600995/100 0 "")  ;gross profit/loss
+         )
+   #:description "Sell SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 01 04 2020
+   (list (vector usd-cash -4200995/100 -4200995/100 "")
+         (vector spy 42000 250 "Buy")
+         (vector spy 995/100 0 "Fee")
+         )
+   #:description "Buy SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 16 04 2020
+   (list (vector usd-cash 2500 -2500)
+         (vector spy -2500 0 "Buy")
+         )
+   #:description "Return of Capital"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 02 05 2020
+   (list (vector usd-cash -47500 -47500 "")
+         (vector spy 47500 125 "Buy")
+         (vector spy 0 0 "Fee")
+         )
+   #:description "Buy spy"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 11 05 2020
+   (list (vector spy 0 450 "Buy"))
+   #:description "stock split"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 21 05 2020
+   (list (vector usd-comm 995/100 995/100 "Fee")
+         (vector usd-cash 2149005/100 2149005/100 "")
+         (vector inc-capg 574702/100 574702/100 "")
+         (vector spy -21500 -135 "Sell")
+         (vector spy -574702/100 0 "")  ;gross profit/loss
+         )
+   #:description "Sell SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 03 06 2020
+   (list (vector usd-cash -21000 -21000 "")
+         (vector spy 21000 150 "Buy")
+         (vector spy 0 0 "Fee")
+         )
+   #:description "Buy spy"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 10 06 2020
+   (list (vector usd-comm 995/100 995/100 "Fee")
+         (vector usd-cash 12809005/100 12809005/100 "")
+         (vector inc-capg  1783309/100  1783309/100 "")
+         (vector spy -128100 -915 "Sell")
+         (vector spy -1783309/100 0 "")  ;gross profit/loss
+         )
+   #:description "Sell SPY"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 10 06 2020
+   (list (vector spy 995/100 0 "Fee")
+         (vector usd-cash 1189005/100 1189005/100 "")
+         (vector spy -11900 -85 "Sell")
+         )
+   #:description "Sell SPY Short"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 15 06 2020
+   (list (vector spy 995/100 0 "Fee")
+         (vector usd-cash 1104005/100 1104005/100 "")
+         (vector spy -11050 -65 "Sell")
+         )
+   #:description "Sell SPY Short"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 18 06 2020
+   (list (vector spy 5000 50 "Sell")
+         (vector usd-comm 995/100 995/100 "Fee")
+         (vector spy 264337/100 0 "")  ;gross profit/loss
+         (vector usd-cash -500995/100 -500995/100 "")
+         (vector inc-capg -264337/100 -264337/100 "")
+         )
+   #:description "Buy SPY Close Short"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 20 06 2020
+   (list (vector spy 8000 100 "Sell")
+         (vector usd-comm 498/100 498/100 "Fee")
+         (vector spy 728673/100 0 "")  ;gross profit/loss
+         (vector usd-cash -800498/100 -800498/100 "")
+         (vector inc-capg -728673/100 -728673/100 "")
+         )
+   #:description "Buy SPY Close Short"
+   #:currency CAD)
+
+  (env-create-multisplit-transaction
+   env 21 06 2020
+   (list (vector usd-cash -800498/100 -800498/100 "")
+         (vector spy 8000 100 "Buy")
+         (vector spy 498/100 0 "Fee")
+         )
+   #:description "Buy SPY"
+   #:currency CAD)
+
+  account-alist)
+
+(define (average-cost-basis-tests)
+  (test-group-with-cleanup "average-cost-basis-tests"
+    (let* ((account-alist (create-average-cost-basis-test-data))
+           (options (gnc:make-report-options uuid)))
+      ;; (set-option! options "General" "Price Source" 'pricedb-latest)
+      (set-option! options "General" "Report's currency" (mnemonic->commodity "CAD"))
+      (set-option! options "General" "Proceeds Account"
+                   (assoc-ref account-alist "USD Cash"))
+      (set-option! options "General" "Start Date"
+                   (cons 'absolute (gnc-dmy2time64 01 01 2019)))
+      (set-option! options "General" "End Date"
+                   (cons 'absolute (gnc-dmy2time64 01 01 2021)))
+
+      ;; (gnc:dump-all-transactions)
+
+      (let ((sxml (options->sxml uuid options "latest")))
+        (test-equal "BUY 100 SPY"
+          '("07/01/19" "Buy SPY" "100 SPY" "100 SPY" "Open Long" "CAD"
+            "C$1.0000" "C$20,000.00" "C$9.95" "C$20,000.00" "C$9.95"
+            "C$20,009.95" "C$0.00" "C$0.00" "C$0.00")
+          (sxml->table-row-col sxml 1 1 #f))
+
+        (test-equal "BUY 50 SPY"
+          '("12/11/19" "Buy SPY" "50 SPY" "150 SPY" "Buy" "CAD" "C$1.0000"
+            "C$16,000.00" "C$9.95" "C$16,000.00" "C$9.95" "C$200.10"
+            "C$36,019.90" "C$0.00" "C$0.00" "C$0.00")
+          (sxml->table-row-col sxml 1 2 #f))
+
+        (test-equal "Sell 75 SPY"
+          '("03/18/20" "Sell SPY" "-75 SPY" "75 SPY" "Sell" "CAD" "C$1.0000"
+            "C$12,000.00" "C$9.95" "C$12,000.00" "C$9.95" "C$240.13"
+            "C$18,009.95" "C$18,009.95" "-C$6,019.90" "-C$6,009.95"
+            "C$11,990.05" "-C$6,009.95" "-C$6,019.90" "-C$6,019.90")
+          (sxml->table-row-col sxml 1 3 #f))
+
+        (test-equal "BUY 250 SPY"
+          '("04/01/20" "Buy SPY" "250 SPY" "325 SPY" "Buy" "CAD" "C$1.0000"
+            "C$42,000.00" "C$9.95" "C$42,000.00" "C$9.95" "C$240.13"
+            "C$60,019.90" "-C$6,009.95" "-C$6,019.90" "-C$6,019.90")
+          (sxml->table-row-col sxml 1 4 #f))
+
+        (test-equal "Return Capital $2500"
+          '("04/16/20" "Return of Capital" "0 SPY" "325 SPY" "Return Capital"
+            "CAD" "C$1.0000" "-C$2,500.00" "-C$2,500.00" "C$184.68"
+            "C$57,519.90" "-C$6,009.95" "-C$6,019.90" "-C$6,019.90")
+          (sxml->table-row-col sxml 1 5 #f))
+
+        (test-equal "BUY 125 SPY"
+          '("05/02/20" "Buy spy" "125 SPY" "450 SPY" "Buy" "CAD" "C$1.0000"
+            "C$47,500.00" "C$0.00" "C$47,500.00" "C$0.00" "C$176.98"
+            "C$105,019.90" "-C$6,009.95" "-C$6,019.90" "-C$6,019.90")
+          (sxml->table-row-col sxml 1 6 #f))
+
+        (test-equal "2:1 split"
+          '("05/11/20" "stock split" "450 SPY" "900 SPY" "2:1 Split"
+            "CAD" "C$1.0000" "C$233.38" "C$105,019.90" "-C$6,009.95"
+            "-C$6,019.90" "-C$6,019.90")
+          (sxml->table-row-col sxml 1 7 #f))
+
+        (test-equal "sell 135 SPY"
+          '("05/21/20" "Sell SPY" "-135 SPY" "765 SPY" "Sell" "CAD" "C$1.0000"
+            "C$21,500.00" "C$9.95" "C$21,500.00" "C$9.95" "C$116.69"
+            "C$15,752.98" "C$89,266.92" "C$5,737.06" "C$5,747.02"
+            "C$21,490.05" "-C$262.94" "-C$282.84" "-C$282.84")
+          (sxml->table-row-col sxml 1 8 #f))
+
+        (test-equal "BUY 150 SPY"
+          '("06/03/20" "Buy spy" "150 SPY" "915 SPY" "Buy" "CAD" "C$1.0000"
+            "C$21,000.00" "C$0.00" "C$21,000.00" "C$0.00" "C$116.69"
+            "C$110,266.92" "-C$262.94" "-C$282.84" "-C$282.84")
+          (sxml->table-row-col sxml 1 9 #f))
+
+        (test-equal "sell 915 SPY close long"
+          '("06/10/20" "Sell SPY" "-915 SPY" "0 SPY" "Close Long" "CAD"
+            "C$1.0000" "C$128,100.00" "C$9.95" "C$128,100.00" "C$9.95"
+            "C$120.51" "C$110,266.92" "C$0.00" "C$17,823.14" "C$17,833.08"
+            "C$128,090.05" "C$17,570.15" "C$17,540.30" "C$17,540.30")
+          (sxml->table-row-col sxml 1 10 #f))
+
+        (test-equal "short-sell 85 SPY"
+          '("06/10/20" "Sell SPY Short" "-85 SPY" "-85 SPY" "Open Short"
+            "CAD" "C$1.0000" "-C$11,900.00" "C$9.95" "-C$11,900.00" "C$9.95"
+            "-C$11,890.05" "C$17,570.15" "C$17,540.30" "C$17,540.30")
+          (sxml->table-row-col sxml 1 11 #f))
+
+        (test-equal "short-sell 65 SPY"
+          '("06/15/20" "Sell SPY Short" "-65 SPY" "-150 SPY" "Short Sell"
+            "CAD" "C$1.0000" "-C$11,050.00" "C$9.95" "-C$11,050.00" "C$9.95"
+            "C$139.88" "-C$22,930.10" "C$17,570.15" "C$17,540.30" "C$17,540.30")
+          (sxml->table-row-col sxml 1 12 #f))
+
+        (test-equal "buy 50 SPY short"
+          '("06/18/20" "Buy SPY Close Short" "50 SPY" "-100 SPY" "Short Buy"
+            "CAD" "C$1.0000" "-C$5,000.00" "C$9.95" "-C$5,000.00" "C$9.95"
+            "C$152.87" "-C$7,643.37" "-C$15,286.73" "C$2,633.42" "C$2,643.37"
+            "-C$5,009.95" "C$20,213.52" "C$20,173.72" "C$20,173.72")
+          (sxml->table-row-col sxml 1 13 #f))
+
+        (test-equal "BUY 100 SPY close short"
+          '("06/20/20" "Buy SPY Close Short" "100 SPY" "0 SPY" "Close Short"
+            "CAD" "C$1.0000" "-C$8,000.00" "C$4.98" "-C$8,000.00" "C$4.98"
+            "C$152.87" "-C$15,286.73" "C$0.00" "C$7,281.75" "C$7,286.73"
+            "-C$8,004.98" "C$27,500.25" "C$27,455.47" "C$27,455.47")
+          (sxml->table-row-col sxml 1 14 #f))
+
+        (test-equal "BUY 100 SPY"
+          '("06/21/20" "Buy SPY" "100 SPY" "100 SPY" "Open Long" "CAD"
+            "C$1.0000" "C$8,000.00" "C$4.98" "C$8,000.00" "C$4.98"
+            "C$8,004.98" "C$27,500.25" "C$27,455.47" "C$27,455.47")
+          (sxml->table-row-col sxml 1 15 #f))))
+    (gnc-clear-current-session)))
+
+

commit 14c523e4f158f677f9ea2211c77eca65f3634104
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Aug 22 00:10:56 2020 +0800

    [test-engine-extras] augment book data generators
    
    * txn-currency can be specified explicitly instead of currency of
    first split
    * split memos can be specified
    
    Note test-register.scm gets some changes because the Trans Num field
    was erroneously saved into Split Action fields. Now the num field is
    only copied into the TransNum field.

diff --git a/bindings/guile/test/test-engine-extras.scm b/bindings/guile/test/test-engine-extras.scm
index 8e3087efa..b873e0d15 100644
--- a/bindings/guile/test/test-engine-extras.scm
+++ b/bindings/guile/test/test-engine-extras.scm
@@ -182,6 +182,7 @@
           num              ; string: num field   (def = null)
           notes            ; string: notes       (def = null)
           memo             ; string: memo        (def = null)
+          currency         ; commodity           (def = commodity of 1st split)
           )
   (env-create-multisplit-transaction
    env
@@ -193,6 +194,7 @@
    #:reconcile reconcile
    #:num num
    #:memo memo
+   #:currency currency
    #:notes notes))
 
 (define* (env-transfer
@@ -239,42 +241,46 @@
           (pricedb? #t)    ; boolean: add pricedb entry?
           void-reason      ; string: void-reason (def = not-voided)
           reconcile        ; pair  : (cons reconciled reconciled-date)
+          currency         ; currency
           num              ; string: num field   (def = null)
           notes            ; string: notes       (def = null)
           memo)            ; string: memo        (def = null)
   (and (pair? list-of-splits)
        (let* ((book (gnc-get-current-book))
               (txn (xaccMallocTransaction book))
-              (first-split (vector-ref (car list-of-splits) 0)))
+              (first-split (vector-ref (car list-of-splits) 0))
+              (txn-curr (or currency (xaccAccountGetCommodity first-split))))
          (xaccTransBeginEdit txn)
          (xaccTransSetDescription txn (or description (env-string env "ponies")))
-         (xaccTransSetCurrency txn (xaccAccountGetCommodity first-split))
+         (xaccTransSetCurrency txn txn-curr)
          (xaccTransSetDate txn DD MM YY)
          (for-each
           (lambda (split)
             (let ((acc (vector-ref split 0))
                   (val (vector-ref split 1))
                   (amt (vector-ref split 2))
+                  (action (and (> (vector-length split) 3)
+                               (vector-ref split 3)))
                   (newsplit (xaccMallocSplit book)))
               (xaccSplitSetParent newsplit txn)
               (xaccSplitSetAccount newsplit acc)
               (xaccSplitSetValue newsplit val)
               (xaccSplitSetAmount newsplit amt)
-              (if num (gnc-set-num-action txn newsplit num num))
-              (if memo (xaccSplitSetMemo newsplit memo))
+              (if memo   (xaccSplitSetMemo newsplit memo))
+              (if action (xaccSplitSetAction newsplit action))
               (when reconcile
                 (xaccSplitSetReconcile newsplit (car reconcile))
                 (xaccSplitSetDateReconciledSecs newsplit (cdr reconcile)))
               (if (and pricedb?
                        (not (zero? amt))
                        (not (gnc-commodity-equiv
-                             (xaccAccountGetCommodity first-split)
-                             (xaccAccountGetCommodity acc))))
-                  (gnc-pricedb-create (xaccAccountGetCommodity first-split)
+                             txn-curr (xaccAccountGetCommodity acc))))
+                  (gnc-pricedb-create txn-curr
                                       (xaccAccountGetCommodity acc)
                                       (gnc-dmy2time64 DD MM YY)
                                       (/ val amt)))))
           list-of-splits)
+         (if num    (xaccTransSetNum txn num))
          (if void-reason (xaccTransVoid txn void-reason))
          (if notes (xaccTransSetNotes txn notes))
          (xaccTransCommitEdit txn)
diff --git a/gnucash/report/reports/standard/test/test-register.scm b/gnucash/report/reports/standard/test/test-register.scm
index eb3967a73..12d6d1d77 100644
--- a/gnucash/report/reports/standard/test/test-register.scm
+++ b/gnucash/report/reports/standard/test/test-register.scm
@@ -66,6 +66,8 @@
       (set-option options "__reg" "query" (gnc-query2scm query)))
 
     (let ((sxml (options->sxml options "basic")))
+      ;; this is a simplistic test - counts the number of populated
+      ;; html-table-cells in the register table.
       (test-equal "table has 232 cells"
         232
         (length (sxml->table-row-col sxml 1 #f #f)))
@@ -80,8 +82,10 @@
 
     (set-option options "__reg" "journal" #t)
     (let ((sxml (options->sxml options "journal")))
-      (test-equal "table has 339 cells"
-        339
+      ;; this is a simplistic test - counts the number of populated
+      ;; html-table-cells in the register table.
+      (test-equal "table has 329 cells"
+        329
         (length (sxml->table-row-col sxml 1 #f #f)))
 
       (test-equal "total debit = #6"
@@ -102,8 +106,10 @@
 
     (set-option options "__reg" "ledger-type" #t)
     (let ((sxml (options->sxml options "ledger-type")))
-      (test-equal "table has 343 cells"
-        343
+      ;; this is a simplistic test - counts the number of populated
+      ;; html-table-cells in the register table.
+      (test-equal "table has 333 cells"
+        333
         (length (sxml->table-row-col sxml 1 #f #f)))
 
       (test-equal "total debit = #6"
@@ -132,8 +138,10 @@
 
     (set-option options "__reg" "double" #t)
     (let ((sxml (options->sxml options "double")))
-      (test-equal "table has 347 cells"
-        347
+      ;; this is a simplistic test - counts the number of populated
+      ;; html-table-cells in the register table.
+      (test-equal "table has 337 cells"
+        337
         (length (sxml->table-row-col sxml 1 #f #f)))
 
       (test-equal "total debit = #6"

commit c38740fcd942a655ef30002bc46609c3d95294cf
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Aug 19 20:19:13 2020 +0800

    [report-utilities] more dump data functions
    
    Two API to dump splits in whole book:
    * gnc:dump-book             - splits grouped by account
    * gnc:dump-all-transactions - splits grouped by transaction
    * gnc:dump-split - dumps single split
    
    Example output -- note (gnc:dump-book) dumps each account followed by
    its splits, then account balance. (gnc:dump-all-transactions) dumps all
    transactions in date order, each followed by its splits.
    
    (gnc:dump-book)
    
    Account 8e56ef54: <Expense> Comm<USD> Type<Expense>
    n Split 5dd1c0a9: 05/11/19 Amt<$200.00> $200.00 Desc<vend1> Memo<AP>
    n Split f9cb052f: 05/11/19 Amt<$20.00> $20.00 Desc<emp1> Memo<vouch1>
    n Split daafc64b: 05/11/19 Amt<$69.00> $69.00 Desc<vend1> Memo<job-bill>
    n Split 5e6af9fe: 14/11/19 Amt<$86.00> $86.00 Desc<emp1> Memo<emp-voucher>
    n Split 6d636ea2: 14/11/19 Amt<$46.00> $46.00 Desc<vend1>
    n Split e618644b: 14/12/19 Amt<-$100.00> -$100.00 Desc<Vend-USD>
    n Split 8be19fbd: 25/12/19 Amt<-$46.00> -$46.00 Desc<Vend-USD> Memo<CN$100-desc>
    n Split ee4fe250: 01/04/20 Amt<$32.00> $32.00 Desc<Cell phone>
    n Split 2cb02dac: 09/05/20 Amt<-$307.00> -$307.00
             Balance: $0.00 Cleared: $0.00 Reconciled: $0.00
    
    Account 6f39f557: <Closing> Comm<USD> Type<Equity>
    n Split 13916652: 09/05/20 Amt<$307.00> $307.00
             Balance: $307.00 Cleared: $0.00 Reconciled: $0.00
    
    Account fa6507e1: <Closing:GBP> Comm<GBP> Type<Equity>
    n Split 34ce3c03: 09/05/20 Amt<-£1,293.00> -£1,293.00
             Balance: -£1,293.00 Cleared: £0.00 Reconciled: £0.00
    
    (gnc:dump-all-transactions)
    
      Trans cfbbc2a4: 12/07/19 Curr GBP  Desc<Customer-GBP>
    n Split d12f74b2: 12/07/19 Acc<AR-GBP> Amt<£120.00> £120.00 Desc<Customer-GBP> Memo<due 91+>
    n Split 3880e99c: 12/07/19 Acc<Standard Sales> Amt<-£20.00> -£20.00 Desc<Customer-GBP> Memo<due 91+>
    n Split 6bd9c7e4: 12/07/19 Acc<Income-GBP> Amt<-£100.00> -£100.00 Desc<Customer-GBP> Memo<due 91+>
    
      Trans 60344bab: 09/10/19 Curr GBP  Desc<Customer-GBP>
    n Split aaca8ee0: 09/10/19 Acc<AR-GBP> Amt<£225.00> £225.00 Desc<Customer-GBP> Memo<due 2-3 months ago>
    n Split ee49bde8: 09/10/19 Acc<Standard Sales> Amt<-£20.00> -£20.00 Desc<Customer-GBP> Memo<due 2-3 months ago>
    n Split e989e863: 09/10/19 Acc<Reduced Sales> Amt<-£5.00> -£5.00 Desc<Customer-GBP> Memo<due 2-3 months ago>
    n Split 91d6cadd: 09/10/19 Acc<Income-GBP> Amt<-£200.00> -£200.00 Desc<Customer-GBP> Memo<due 2-3 months ago

diff --git a/gnucash/report/report-utilities.scm b/gnucash/report/report-utilities.scm
index cb3240a0b..98ad3369c 100644
--- a/gnucash/report/report-utilities.scm
+++ b/gnucash/report/report-utilities.scm
@@ -1206,7 +1206,7 @@ query instead.")
 
 (define-public (gnc:dump-split s show-acc?)
   (define txn (xaccSplitGetParent s))
-  (format #t "~a Split ~a: ~a~a Amt<~a> ~a~a~a\n"
+  (format #t "~a Split ~a: ~a~a Amt<~a> Val<~a> ~a~a~a\n"
           (xaccSplitGetReconcile s)
           (string-take (gncSplitGetGUID s) 8)
           (qof-print-date (xaccTransGetDate txn))
@@ -1220,10 +1220,12 @@ query instead.")
             (xaccTransGetCurrency txn)
             (xaccSplitGetValue s)))
           (maybe-str 'Desc (xaccTransGetDescription txn))
+          (maybe-str 'Action (xaccSplitGetAction s))
           (maybe-str 'Memo (xaccSplitGetMemo s))))
 
 (define-public (gnc:dump-all-transactions)
   (define query (qof-query-create-for-splits))
+  (define (split-has-no-account? split) (null? (xaccSplitGetAccount split)))
   (display "\n(gnc:dump-all-transactions)\n")
   (qof-query-set-book query (gnc-get-current-book))
   (qof-query-set-sort-order query (list SPLIT-TRANS TRANS-DATE-POSTED) '() '())
@@ -1232,6 +1234,7 @@ query instead.")
     (newline)
     (match splits
       (() (qof-query-destroy query))
+      (((? split-has-no-account?) . rest) (lp rest))
       ((split . rest)
        (let ((trans (xaccSplitGetParent split)))
          (format #t "  Trans ~a: ~a Curr ~a ~a~a\n"



Summary of changes:
 bindings/guile/test/test-engine-extras.scm         |  20 +-
 gnucash/report/report-utilities.scm                |   5 +-
 gnucash/report/reports/CMakeLists.txt              |   1 +
 .../report/reports/standard/ifrs-cost-basis.scm    | 436 +++++++++++++++++++++
 .../report/reports/standard/test/CMakeLists.txt    |   1 +
 .../reports/standard/test/test-ifrs-cost-basis.scm | 357 +++++++++++++++++
 .../report/reports/standard/test/test-register.scm |  20 +-
 7 files changed, 826 insertions(+), 14 deletions(-)
 create mode 100644 gnucash/report/reports/standard/ifrs-cost-basis.scm
 create mode 100644 gnucash/report/reports/standard/test/test-ifrs-cost-basis.scm



More information about the gnucash-changes mailing list