From 0c9c9c2594569bed8867eeff55bb1ab6ca76bf1e Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Thu, 19 Sep 2019 21:43:44 +0800 Subject: [PATCH 01/14] [test-trial-balance] augment to test unrealized gains these were already tested -- see previous tests *do* include 'unrealized losses'. augment by adding another couple foreign transfer to change the unrealized gain/loss amount. --- .../test/test-trial-balance.scm | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gnucash/report/standard-reports/test/test-trial-balance.scm b/gnucash/report/standard-reports/test/test-trial-balance.scm index d343fe2e76..43d8be638b 100644 --- a/gnucash/report/standard-reports/test/test-trial-balance.scm +++ b/gnucash/report/standard-reports/test/test-trial-balance.scm @@ -62,13 +62,15 @@ (define (test-trial-balance) (let* ((options (gnc:make-report-options uuid)) (account-alist (create-test-data)) + (gbp-bank (assoc-ref account-alist "GBP Bank")) + (usd-bank (assoc-ref account-alist "Bank")) (expense (assoc-ref account-alist "Expenses")) (equity (assoc-ref account-alist "Equity")) (income (assoc-ref account-alist "Income")) (bank (assoc-ref account-alist "Bank"))) (gnc-commodity-set-user-symbol - (xaccAccountGetCommodity (assoc-ref account-alist "GBP Bank")) + (xaccAccountGetCommodity gbp-bank) "#") (let ((closing-txn (env-transfer #f 30 06 2003 expense equity @@ -167,6 +169,18 @@ (sxml->table-row-col sxml 1 #f 10)) (test-equal "work-sheet bs credits" - ' ("$3.00" "$2,356.00" "$2,359.00" "$760.00" "$3,119.00") + '("$3.00" "$2,356.00" "$2,359.00" "$760.00" "$3,119.00") (sxml->table-row-col sxml 1 #f 11))) - )) + + ;; A couple of transactions which involve foreign currency + ;; conversions. We'll set the currencies to GBP and USD. + (env-transfer-foreign #f 15 01 2000 gbp-bank usd-bank + 10 14 #:description "GBP 10 to USD 14") + (env-transfer-foreign #f 15 02 2000 usd-bank gbp-bank + 9 8 #:description "USD 9 to GBP 8") + + (set-option options "General" "Report variation" 'current) + (let ((sxml (options->sxml options "test-unrealized-gain"))) + (test-equal "unrealized losses" + '("Unrealized Gains" "$3.25") + (sxml->table-row-col sxml 1 -2 #f))))) From f88c54bb50a8527067225ea3586331238844ad79 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Thu, 19 Sep 2019 21:07:01 +0800 Subject: [PATCH 02/14] [trial-balance] use gnc:commodity-collector-get-negated --- gnucash/report/standard-reports/trial-balance.scm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gnucash/report/standard-reports/trial-balance.scm b/gnucash/report/standard-reports/trial-balance.scm index 8b8aed9d5b..35aa425a18 100644 --- a/gnucash/report/standard-reports/trial-balance.scm +++ b/gnucash/report/standard-reports/trial-balance.scm @@ -152,9 +152,7 @@ (amt (and sum (gnc:gnc-monetary-amount sum))) (neg? (and amt (negative? amt))) (bal (if neg? - (let ((bal (gnc:make-commodity-collector))) - (bal 'minusmerge signed-balance #f) - bal) + (gnc:commodity-collector-get-negated signed-balance) signed-balance)) (bal-sum (gnc:sum-collector-commodity bal From acf359a7973aa30686529ce46d18617ac51d77f8 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Thu, 19 Sep 2019 21:07:41 +0800 Subject: [PATCH 03/14] [trial-balance] upgrade coll-plus and coll-minus to report-wide fns --- .../report/standard-reports/trial-balance.scm | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/gnucash/report/standard-reports/trial-balance.scm b/gnucash/report/standard-reports/trial-balance.scm index 35aa425a18..49a4ba4855 100644 --- a/gnucash/report/standard-reports/trial-balance.scm +++ b/gnucash/report/standard-reports/trial-balance.scm @@ -316,6 +316,19 @@ options)) +;; (coll-plus collectors ...) equiv to (+ collectors ...) +(define (coll-plus . collectors) + (let ((res (gnc:make-commodity-collector))) + (for-each (lambda (coll) (res 'merge coll #f)) collectors) + res)) + +;; (coll-minus collectors ...) equiv to (- collector0 collector1 ...) +(define (coll-minus . collectors) + (let ((res (gnc:make-commodity-collector))) + (res 'merge (car collectors) #f) + (for-each (lambda (coll) (res 'minusmerge coll #f)) (cdr collectors)) + res)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; trial-balance-renderer ;; set up the document and add the table @@ -665,12 +678,6 @@ splits) total)) - (define (coll-minus . collectors) - (let ((res (gnc:make-commodity-collector))) - (res 'merge (car collectors) #f) - (for-each (lambda (mon) (res 'minusmerge mon #f)) (cdr collectors)) - res)) - (while (< row rows) (let* ((env (gnc:html-acct-table-get-row-env acct-table row)) (acct (get-val env 'account)) From 6b573de128c6509bb447db0020849cbde764b457 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Thu, 19 Sep 2019 21:07:58 +0800 Subject: [PATCH 04/14] [trial-balance] use coll-plus and coll-minus for functional style --- .../report/standard-reports/trial-balance.scm | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/gnucash/report/standard-reports/trial-balance.scm b/gnucash/report/standard-reports/trial-balance.scm index 49a4ba4855..9a9cc89749 100644 --- a/gnucash/report/standard-reports/trial-balance.scm +++ b/gnucash/report/standard-reports/trial-balance.scm @@ -692,18 +692,14 @@ (and ga-or-is? (coll-minus adjusting pos-adjusting))) (pre-closing-bal (coll-minus curr-bal closing)) (pre-adjusting-bal (coll-minus pre-closing-bal adjusting)) - (atb (if is? - (let* ((debit (gnc:make-commodity-collector)) - (credit (gnc:make-commodity-collector))) - (debit 'merge pos-adjusting #f) - (credit 'merge neg-adjusting #f) - (if (double-col - 'credit-q pre-adjusting-bal - report-commodity exchange-fn show-fcur?) - (credit 'merge pre-adjusting-bal #f) - (debit 'merge pre-adjusting-bal #f)) - (list debit credit)) - pre-closing-bal))) + (atb (cond ((not is?) pre-closing-bal) + ((double-col 'credit-q pre-adjusting-bal + report-commodity exchange-fn show-fcur?) + (list (coll-plus pos-adjusting) + (coll-plus neg-adjusting pre-adjusting-bal))) + (else + (list (coll-plus pos-adjusting pre-adjusting-bal) + (coll-plus neg-adjusting)))))) ;; curr-bal = account-bal with closing & adj entries ;; pre-closing-bal = account-bal with adj entries only @@ -870,8 +866,8 @@ (tot-abs-amt-cell bs-credits)) '()))) (if (eq? report-variant 'work-sheet) - (let* ((net-is (gnc:make-commodity-collector)) - (net-bs (gnc:make-commodity-collector)) + (let* ((net-is (coll-minus is-debits is-credits)) + (net-bs (coll-minus bs-debits bs-credits)) (tot-is (gnc:make-commodity-collector)) (tot-bs (gnc:make-commodity-collector)) (is-entry #f) @@ -880,10 +876,6 @@ (bs-credit? #f) (tbl-width (+ account-cols (* 2 bs-col) 2)) (this-row (gnc:html-table-num-rows build-table))) - (net-is 'merge is-debits #f) - (net-is 'minusmerge is-credits #f) - (net-bs 'merge bs-debits #f) - (net-bs 'minusmerge bs-credits #f) (set! is-entry (double-col 'entry net-is report-commodity exchange-fn show-fcur?)) (set! is-credit? From 656d2718d8e570f6eb21e1ad29b0f7ea8cdd652f Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Thu, 19 Sep 2019 21:21:35 +0800 Subject: [PATCH 05/14] [trial-balance] compact (collect-unrealized-gains) use functional style --- .../report/standard-reports/trial-balance.scm | 39 ++++++------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/gnucash/report/standard-reports/trial-balance.scm b/gnucash/report/standard-reports/trial-balance.scm index 9a9cc89749..fd726ee71d 100644 --- a/gnucash/report/standard-reports/trial-balance.scm +++ b/gnucash/report/standard-reports/trial-balance.scm @@ -523,36 +523,21 @@ ;; ;; This procedure returns a commodity collector. (define (collect-unrealized-gains) + (define (acct->bal acct) + (gnc:account-get-comm-balance-at-date acct end-date #f)) (if (eq? price-source 'average-cost) ;; No need to calculate if doing valuation at cost. (gnc:make-commodity-collector) - (let ((book-balance (gnc:make-commodity-collector)) - (unrealized-gain-collector (gnc:make-commodity-collector)) - (cost-fn (gnc:case-exchange-fn - 'average-cost report-commodity end-date))) - - ;; Calculate book balance. - ;; assets - liabilities - equity; normally 0 - (for-each - (lambda (acct) - (book-balance - 'merge - (gnc:account-get-comm-balance-at-date acct end-date #f) - #f)) - all-accounts) - - (let ((value (gnc:gnc-monetary-amount - (gnc:sum-collector-commodity - book-balance report-commodity exchange-fn))) - (cost (gnc:gnc-monetary-amount - (gnc:sum-collector-commodity - book-balance report-commodity cost-fn)))) - - ;; Get the unrealized gain or loss (value minus cost). - (unrealized-gain-collector - 'add report-commodity (- value cost)) - unrealized-gain-collector)))) - + (let* ((cost-fn (gnc:case-exchange-fn + 'average-cost report-commodity end-date)) + (acct-balances (map acct->bal all-accounts)) + (book-balance (apply coll-plus acct-balances)) + (value (gnc:sum-collector-commodity + book-balance report-commodity exchange-fn)) + (cost (gnc:sum-collector-commodity + book-balance report-commodity cost-fn))) + ;; Get the unrealized gain or loss (value minus cost). + (gnc:monetaries-add value (gnc:monetary-neg cost))))) ;; set default cell alignment (gnc:html-table-set-style! From 0ab0d23b00a674bb655e1d67cb3eb8f5055f7e06 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 11:12:37 +0800 Subject: [PATCH 06/14] Bug 797418 - In budget report, column with Actual Totals for Liabilities and Income are reversed budget.scm had some cleanup whereby totals were accumulated but are now re-retrieved. Forgot to reverse actuals for some account signs reversals. --- gnucash/report/standard-reports/budget.scm | 1 + 1 file changed, 1 insertion(+) diff --git a/gnucash/report/standard-reports/budget.scm b/gnucash/report/standard-reports/budget.scm index 5a994d6d82..a13b566772 100644 --- a/gnucash/report/standard-reports/budget.scm +++ b/gnucash/report/standard-reports/budget.scm @@ -396,6 +396,7 @@ budget acct total-periods)) (act-total (gnc:get-account-periodlist-actual-value budget acct total-periods)) + (act-total (if reverse-balance? (- act-total) act-total)) (dif-total (if income-acct? (- act-total bgt-total) (- bgt-total act-total)))) From 49372e76be61ac4eae479fee645b183a834ad43e Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 09:04:34 +0800 Subject: [PATCH 07/14] Ensure book returns current-book fixes https://lists.gnucash.org/pipermail/gnucash-user/2019-September/086967.html because occasionally account will be null or #f, causing error when passed to gnc-account-get-book. --- gnucash/report/business-reports/owner-report.scm | 4 ++-- gnucash/report/locale-specific/us/taxtxf-de_DE.scm | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/gnucash/report/business-reports/owner-report.scm b/gnucash/report/business-reports/owner-report.scm index d71664229a..6c956d5df7 100644 --- a/gnucash/report/business-reports/owner-report.scm +++ b/gnucash/report/business-reports/owner-report.scm @@ -748,8 +748,8 @@ (end-date (gnc:time64-end-day-time (gnc:date-option-absolute-time (opt-val gnc:pagename-general optname-to-date)))) - (book (gnc-account-get-book account)) - (date-format (if (not (null? book)) (gnc:options-fancy-date book))) + (book (gnc-get-current-book)) + (date-format (gnc:options-fancy-date book)) (type (opt-val "__reg" "owner-type")) (owner-descr (owner-string type)) (date-type (opt-val gnc:pagename-general optname-date-driver)) diff --git a/gnucash/report/locale-specific/us/taxtxf-de_DE.scm b/gnucash/report/locale-specific/us/taxtxf-de_DE.scm index f0a0ab85c1..6557dd0f1c 100644 --- a/gnucash/report/locale-specific/us/taxtxf-de_DE.scm +++ b/gnucash/report/locale-specific/us/taxtxf-de_DE.scm @@ -505,11 +505,7 @@ (validate (reverse (gnc-account-get-children-sorted (gnc-get-current-root-account)))))) - (book (if selected-accounts - (gnc-account-get-book (if (pair? selected-accounts) - (car selected-accounts) - selected-accounts)) - #f)) + (book (gnc-get-current-book)) (generations (if (pair? selected-accounts) (apply max (map (lambda (x) (num-generations x 1)) selected-accounts)) From 3208879e64ea0d692d626cbc9052e6ea590f3ad3 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 10:16:17 +0800 Subject: [PATCH 08/14] [app-utils] upgrade Tax/Tax Number option to all locales Previously de_DE locale will add a *global* 'Tax/Tax Number' option. This is immediately translated. This change will upgrade it to be present in all locales, and can be queried by any report. --- libgnucash/app-utils/app-utils.scm | 3 +++ libgnucash/app-utils/business-prefs.scm | 6 ++++++ libgnucash/tax/us/de_DE.scm | 5 ----- libgnucash/tax/us/txf-de_DE.scm | 13 ------------- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/libgnucash/app-utils/app-utils.scm b/libgnucash/app-utils/app-utils.scm index ca789412ea..fd3f8ef4c2 100644 --- a/libgnucash/app-utils/app-utils.scm +++ b/libgnucash/app-utils/app-utils.scm @@ -300,6 +300,8 @@ (define gnc:*company-contact* (N_ "Company Contact Person")) (define gnc:*fancy-date-label* (N_ "Fancy Date Format")) (define gnc:*fancy-date-format* (N_ "custom")) +(define gnc:*tax-label* (N_ "Tax")) +(define gnc:*tax-nr-label* (N_ "Tax Number")) (define (gnc:company-info book key) ;; Access company info from key-value pairs for current book @@ -328,6 +330,7 @@ gnc:*option-name-currency-accounting* gnc:*option-name-book-currency* gnc:*option-name-default-gains-policy* gnc:*option-name-default-gain-loss-account* + gnc:*tax-label* gnc:*tax-nr-label* gnc:*option-name-auto-readonly-days* gnc:*option-name-num-field-source*) (define gnc:*option-section-budgeting* OPTION-SECTION-BUDGETING) diff --git a/libgnucash/app-utils/business-prefs.scm b/libgnucash/app-utils/business-prefs.scm index 60f7bf6231..5ec94dbe13 100644 --- a/libgnucash/app-utils/business-prefs.scm +++ b/libgnucash/app-utils/business-prefs.scm @@ -157,6 +157,12 @@ gnc:*option-section-budgeting* gnc:*option-name-default-budget* "a" (N_ "Budget to be used when none has been otherwise specified."))) + ;; Tax Tab + (reg-option + (gnc:make-string-option + gnc:*tax-label* gnc:*tax-nr-label* + "a" (N_ "The electronic tax number of your business") "")) + ;; Counters Tab (for-each (lambda (vals) diff --git a/libgnucash/tax/us/de_DE.scm b/libgnucash/tax/us/de_DE.scm index 54bb9f74a6..6388943f2f 100644 --- a/libgnucash/tax/us/de_DE.scm +++ b/libgnucash/tax/us/de_DE.scm @@ -49,10 +49,5 @@ (export txf-asset-categories) (export txf-liab-eq-categories) -(define gnc:*tax-label* (N_ "Tax")) -(define gnc:*tax-nr-label* (N_ "Tax Number")) - -(export gnc:*tax-label* gnc:*tax-nr-label*) - (load-from-path "txf-de_DE") (load-from-path "txf-help-de_DE") diff --git a/libgnucash/tax/us/txf-de_DE.scm b/libgnucash/tax/us/txf-de_DE.scm index c93cdc3f68..92b3d89b75 100644 --- a/libgnucash/tax/us/txf-de_DE.scm +++ b/libgnucash/tax/us/txf-de_DE.scm @@ -312,16 +312,3 @@ Fehlermeldungen + Dankschreiben an: stoll@bomhardt.de")) ) ) )) - -;;; Register global options in this book -(define (book-options-generator options) - (define (reg-option new-option) - (gnc:register-option options new-option)) - - (reg-option - (gnc:make-string-option - gnc:*tax-label* gnc:*tax-nr-label* - "a" (N_ "The electronic tax number of your business") "")) - ) - -(gnc-register-kvp-option-generator QOF-ID-BOOK-SCM book-options-generator) From 2da5944596f5fdee08293839eada5c2e3e1eda30 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 10:17:08 +0800 Subject: [PATCH 09/14] [taxtxf-de_DE] fix invalid code (unless book ...) is equivalent to (if (not book) ...) therefore this snippet was incorrect. previous commit ensures book always returns a non-#f object therefore there's no need to handle #f anymore. --- gnucash/report/locale-specific/us/taxtxf-de_DE.scm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gnucash/report/locale-specific/us/taxtxf-de_DE.scm b/gnucash/report/locale-specific/us/taxtxf-de_DE.scm index 6557dd0f1c..651785b4fb 100644 --- a/gnucash/report/locale-specific/us/taxtxf-de_DE.scm +++ b/gnucash/report/locale-specific/us/taxtxf-de_DE.scm @@ -768,12 +768,7 @@ (to-year (gnc-print-time64 to-value "%Y")) (today-date (gnc-print-time64 (time64CanonicalDayTime (current-time)) "%d.%m.%Y")) - (tax-nr (unless book - (or - (gnc:option-get-value book gnc:*tax-label* gnc:*tax-nr-label*) - "") - "")) - ) + (tax-nr (gnc:option-get-value book gnc:*tax-label* gnc:*tax-nr-label*))) ;; Now, the main body ;; Reset all the balance collectors From 7a662272b31555d010df32f2d4553fec07f3fa5f Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 10:39:33 +0800 Subject: [PATCH 10/14] [invoice] render tax/tax number into 'our-details' section --- gnucash/report/business-reports/invoice.scm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gnucash/report/business-reports/invoice.scm b/gnucash/report/business-reports/invoice.scm index 3bfe1a21b2..af4e29fb47 100644 --- a/gnucash/report/business-reports/invoice.scm +++ b/gnucash/report/business-reports/invoice.scm @@ -729,6 +729,7 @@ for styling the invoice. Please see the exported report for the CSS class names. (fax (gnc:company-info book gnc:*company-fax*)) (email (gnc:company-info book gnc:*company-email*)) (url (gnc:company-info book gnc:*company-url*)) + (taxnr (gnc:option-get-value book gnc:*tax-label* gnc:*tax-nr-label*)) (taxid (gnc:company-info book gnc:*company-id*))) (if (and name (not (string-null? name))) @@ -766,6 +767,11 @@ for styling the invoice. Please see the exported report for the CSS class names. (gnc:make-html-div/markup "maybe-align-right company-tax-id" taxid)))) + (if (and taxnr (not (string-null? taxnr))) + (gnc:html-table-append-row! + table (list (gnc:make-html-div/markup + "maybe-align-right company-tax-nr" taxnr)))) + table)) (define (reg-renderer report-obj) From 0511ce723ee2ee52a9a5992bced6505577029e17 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 22:17:44 +0800 Subject: [PATCH 11/14] [API] gnc:list-flatten flattens lists recursively and is a schemey algorithm rather than a report algorithm, so, belongs centrally. --- gnucash/report/standard-reports/budget.scm | 13 +------------ .../scm/test/test-libgnucash-scm-utilities.scm | 12 ++++++++++++ libgnucash/scm/utilities.scm | 12 ++++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/gnucash/report/standard-reports/budget.scm b/gnucash/report/standard-reports/budget.scm index a13b566772..17274811d1 100644 --- a/gnucash/report/standard-reports/budget.scm +++ b/gnucash/report/standard-reports/budget.scm @@ -317,17 +317,6 @@ (gnc-budget-get-account-period-actual-value budget acct period)) periodlist))) - (define (flatten lst) - (reverse! - (let loop ((lst lst) (result '())) - (if (null? lst) - result - (let ((elt (car lst)) - (rest (cdr lst))) - (if (pair? elt) - (loop rest (append (loop elt '()) result)) - (loop rest (cons elt result)))))))) - ;; Adds a line to the budget report. ;; ;; Parameters: @@ -342,7 +331,7 @@ column-list exchange-fn) (let* ((comm (xaccAccountGetCommodity acct)) (reverse-balance? (gnc-reverse-balance acct)) - (allperiods (filter number? (flatten column-list))) + (allperiods (filter number? (gnc:list-flatten column-list))) (total-periods (if accumulate? (iota (1+ (apply max allperiods))) allperiods)) diff --git a/libgnucash/scm/test/test-libgnucash-scm-utilities.scm b/libgnucash/scm/test/test-libgnucash-scm-utilities.scm index a2e0d4d24d..50903c4315 100644 --- a/libgnucash/scm/test/test-libgnucash-scm-utilities.scm +++ b/libgnucash/scm/test/test-libgnucash-scm-utilities.scm @@ -10,6 +10,7 @@ (test-traverse-vec) (test-substring-replace) (test-sort-and-delete-duplicates) + (test-gnc:list-flatten) (test-begin "test-libgnucash-scm-utilities.scm")) (define (test-traverse-vec) @@ -87,3 +88,14 @@ '(1 2 3) (sort-and-delete-duplicates '(3 1 2) <)) (test-end "sort-and-delete-duplicates")) + +(define (test-gnc:list-flatten) + (test-equal "gnc:list-flatten null" + '() + (gnc:list-flatten '())) + (test-equal "gnc:list-flatten noop" + '(1 2 3) + (gnc:list-flatten '(1 2 3))) + (test-equal "gnc:list-flatten deep" + '(1 2 3 4 5 6) + (gnc:list-flatten '(1 (2) (() () (((((3))) ())) 4 () ((5) (6))))))) diff --git a/libgnucash/scm/utilities.scm b/libgnucash/scm/utilities.scm index aa69e277fa..6665f1b97d 100644 --- a/libgnucash/scm/utilities.scm +++ b/libgnucash/scm/utilities.scm @@ -47,6 +47,7 @@ (export gnc:debug) (export addto!) (export sort-and-delete-duplicates) +(export gnc:list-flatten) ;; Do this stuff very early -- but other than that, don't add any ;; executable code until the end of the file if you can help it. @@ -191,6 +192,17 @@ (define (kons a b) (if (and (pair? b) (= a (car b))) b (cons a b))) (reverse (fold kons '() (sort lst <)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; flattens an arbitrary deep nested list into simple list. this is +;; probably the most efficient algorithm available. '(1 2 (3 4)) --> +;; '(1 2 3 4) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define (gnc:list-flatten . lst) + (reverse + (let lp ((e lst) (accum '())) + (if (list? e) + (fold lp accum e) + (cons e accum))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; compatibility hack for fixing guile-2.0 string handling. this code From 7587c3b4e337e513a4fb68f4b98bb26740e0f8c2 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 22:42:43 +0800 Subject: [PATCH 12/14] [API] gnc:collector+ and gnc:collector- for collector arithmetic (gnc:collector+ ...) equivalent to (+ ...) (gnc:collector- ...) equivalent to (- ...) and will also handle single-argument sign negation. --- .../report/report-system/report-system.scm | 2 ++ .../report/report-system/report-utilities.scm | 19 +++++++++++++++++++ .../test/test-report-utilities.scm | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/gnucash/report/report-system/report-system.scm b/gnucash/report/report-system/report-system.scm index 33c2229b2b..4c2dd8b925 100644 --- a/gnucash/report/report-system/report-system.scm +++ b/gnucash/report/report-system/report-system.scm @@ -693,6 +693,8 @@ (export gnc:make-value-collector) (export gnc:make-number-collector) ;deprecated (export gnc:make-commodity-collector) +(export gnc:collector+) +(export gnc:collector-) (export gnc:commodity-collector-get-negated) (export gnc:commodity-collectorlist-get-merged) ;deprecated (export gnc-commodity-collector-commodity-count) diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm index 75cc9979b3..90e5249ba9 100644 --- a/gnucash/report/report-system/report-utilities.scm +++ b/gnucash/report/report-system/report-utilities.scm @@ -390,6 +390,25 @@ construct gnc:make-gnc-monetary and use gnc:monetary->string instead.") (define (gnc-commodity-collector-allzero? collector) (every zero? (map cdr (collector 'format cons #f)))) +;; (gnc:collector+ collectors ...) equiv to (+ collectors ...) and +;; outputs: a collector +(define (gnc:collector+ . collectors) + (let ((res (gnc:make-commodity-collector))) + (for-each (lambda (coll) (res 'merge coll #f)) collectors) + res)) + +;; (gnc:collectors- collectors ...) equiv to (- collectors ...), can +;; also negate single-argument collector. outputs collector +(define gnc:collector- + (case-lambda + (() (error "gnc:collector- needs at least 1 collector argument")) + ((coll) (gnc:collector- (gnc:make-commodity-collector) coll)) + ((coll . rest) + (let ((res (gnc:make-commodity-collector))) + (res 'merge coll #f) + (res 'minusmerge (apply gnc:collector+ rest) #f) + res)))) + ;; add any number of gnc-monetary objects into a commodity-collector ;; usage: (gnc:monetaries-add monetary1 monetary2 ...) ;; output: a commodity-collector object diff --git a/gnucash/report/report-system/test/test-report-utilities.scm b/gnucash/report/report-system/test/test-report-utilities.scm index fd62cc8fc5..79728dade4 100644 --- a/gnucash/report/report-system/test/test-report-utilities.scm +++ b/gnucash/report/report-system/test/test-report-utilities.scm @@ -213,6 +213,21 @@ (gnc:make-gnc-monetary USD 25) (coll-A 'getmonetary USD #f)) + (test-equal "gnc:collector+" + '(("USD" . 50) ("GBP" . -20)) + (collector->list + (gnc:collector+ coll-A coll-A coll-B))) + + (test-equal "gnc:collector- 1 arg" + '(("GBP" . 20) ("USD" . -25)) + (collector->list + (gnc:collector- coll-A))) + + (test-equal "gnc:collector- 3 args" + '(("USD" . 25) ("GBP" . -60)) + (collector->list + (gnc:collector- coll-A coll-B coll-B))) + (test-equal "gnc:commodity-collector-get-negated" '(("USD" . -25) ("GBP" . 20)) (collector->list From f72df3e1bc70b29ca74b12497044f093cc737fbe Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sat, 21 Sep 2019 13:49:34 +0800 Subject: [PATCH 13/14] [report-utilities] gnc:account-get-balances-at-dates: use quicksort stable-sort! is slower than quicksort. --- gnucash/report/report-system/report-utilities.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm index 90e5249ba9..973608af96 100644 --- a/gnucash/report/report-system/report-utilities.scm +++ b/gnucash/report/report-system/report-utilities.scm @@ -470,7 +470,7 @@ flawed. see report-utilities.scm. please update reports.") (define (amount->monetary bal) (gnc:make-gnc-monetary (xaccAccountGetCommodity account) bal)) (let loop ((splits (xaccAccountGetSplitList account)) - (dates-list (stable-sort! dates-list <)) + (dates-list (sort dates-list <)) (currentbal 0) (lastbal 0) (balancelist '())) From 496ca94a989d0001a64c19f5e2104ae02fe1a604 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Fri, 20 Sep 2019 22:43:00 +0800 Subject: [PATCH 14/14] [reports] use new API gnc:collector+ and gnc:collector- --- .../business-reports/customer-summary.scm | 17 ++++----- .../report/standard-reports/balsheet-pnl.scm | 5 ++- .../standard-reports/category-barchart.scm | 10 ++---- .../report/standard-reports/net-charts.scm | 8 +---- .../report/standard-reports/trial-balance.scm | 35 +++++++------------ 5 files changed, 24 insertions(+), 51 deletions(-) diff --git a/gnucash/report/business-reports/customer-summary.scm b/gnucash/report/business-reports/customer-summary.scm index 2ba1f71b8c..e0ab202cdf 100644 --- a/gnucash/report/business-reports/customer-summary.scm +++ b/gnucash/report/business-reports/customer-summary.scm @@ -262,11 +262,6 @@ (member (xaccSplitGetAccount s) accounts)) splits)))) -(define (coll-minus minuend subtrahend) - (let ((coll (gnc:make-commodity-collector))) - (coll 'merge minuend #f) - (coll 'minusmerge subtrahend #f) - coll)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -348,7 +343,7 @@ (sales (gnc:commodity-collector-get-negated (filter-splits splits sales-accounts))) (expense (filter-splits splits expense-accounts)) - (profit (coll-minus sales expense))) + (profit (gnc:collector- sales expense))) (list owner profit sales expense))) ownerlist)) (sortingtable '())) @@ -403,9 +398,10 @@ ;; Add the "No Customer" lines to the sortingtable for sorting ;; as well - (let* ((other-sales (coll-minus toplevel-total-sales total-sales)) - (other-expense (coll-minus toplevel-total-expense total-expense)) - (other-profit (coll-minus other-sales other-expense))) + (let* ((other-sales (gnc:collector- toplevel-total-sales total-sales)) + (other-expense (gnc:collector- toplevel-total-expense + total-expense)) + (other-profit (gnc:collector- other-sales other-expense))) (for-each (lambda (comm) (let* ((profit (cadr (other-profit 'getpair comm #f))) @@ -479,7 +475,8 @@ (gnc:make-html-text (gnc:html-markup/attr/no-end "hr" "noshade"))))) ;; Summary lines - 1 per currency - (let ((total-profit (coll-minus toplevel-total-sales toplevel-total-expense))) + (let ((total-profit (gnc:collector- toplevel-total-sales + toplevel-total-expense))) (for-each (lambda (comm) (let* ((profit (cadr (total-profit 'getpair comm #f))) diff --git a/gnucash/report/standard-reports/balsheet-pnl.scm b/gnucash/report/standard-reports/balsheet-pnl.scm index 6f9b3b8d68..bca8f5ad40 100644 --- a/gnucash/report/standard-reports/balsheet-pnl.scm +++ b/gnucash/report/standard-reports/balsheet-pnl.scm @@ -961,9 +961,8 @@ also show overall period profit & loss.")) asset-liability (lambda (acc) (gnc:account-get-comm-value-at-date acc date #f)))) - (unrealized (gnc:make-commodity-collector))) - (unrealized 'merge asset-liability-basis #f) - (unrealized 'minusmerge asset-liability-balance #f) + (unrealized (gnc:collector- asset-liability-basis + asset-liability-balance))) (monetaries->exchanged unrealized common-currency price-source date))))) (retained-earnings-fn diff --git a/gnucash/report/standard-reports/category-barchart.scm b/gnucash/report/standard-reports/category-barchart.scm index 0da882b7d7..c217a138cd 100644 --- a/gnucash/report/standard-reports/category-barchart.scm +++ b/gnucash/report/standard-reports/category-barchart.scm @@ -341,12 +341,6 @@ developing over time")) c report-currency (lambda (a b) (exchange-fn a b date))))))) - (define (collector-minus a b) - (let ((coll (gnc:make-commodity-collector))) - (coll 'merge a #f) - (coll 'minusmerge b #f) - coll)) - ;; copy of gnc:not-all-zeros using gnc-monetary (define (not-all-zeros data) (cond ((gnc:gnc-monetary? data) (not (zero? (gnc:gnc-monetary-amount data)))) @@ -401,8 +395,8 @@ developing over time")) (cdr dates-list) (cons (if do-intervals? (collector->monetary - (collector-minus (cadr list-of-mon-collectors) - (car list-of-mon-collectors)) + (gnc:collector- (cadr list-of-mon-collectors) + (car list-of-mon-collectors)) (cadr dates-list)) (collector->monetary (car list-of-mon-collectors) diff --git a/gnucash/report/standard-reports/net-charts.scm b/gnucash/report/standard-reports/net-charts.scm index d7574a2339..396103b2df 100644 --- a/gnucash/report/standard-reports/net-charts.scm +++ b/gnucash/report/standard-reports/net-charts.scm @@ -267,12 +267,6 @@ ;; conversion function above. Returns a list of gnc-monetary. (define (process-datelist account-balances dates left-col?) - (define (collector-minus coll1 coll2) - (let ((res (gnc:make-commodity-collector))) - (res 'merge coll1 #f) - (res 'minusmerge coll2 #f) - res)) - (define accountlist (if inc-exp? (if left-col? @@ -310,7 +304,7 @@ (cons (collector->monetary (if inc-exp? - (collector-minus (car acct-balances) (cadr acct-balances)) + (gnc:collector- (car acct-balances) (cadr acct-balances)) (car acct-balances)) (if inc-exp? (cadr dates) (car dates))) result))))) diff --git a/gnucash/report/standard-reports/trial-balance.scm b/gnucash/report/standard-reports/trial-balance.scm index fd726ee71d..e9cfeeac1b 100644 --- a/gnucash/report/standard-reports/trial-balance.scm +++ b/gnucash/report/standard-reports/trial-balance.scm @@ -316,19 +316,6 @@ options)) -;; (coll-plus collectors ...) equiv to (+ collectors ...) -(define (coll-plus . collectors) - (let ((res (gnc:make-commodity-collector))) - (for-each (lambda (coll) (res 'merge coll #f)) collectors) - res)) - -;; (coll-minus collectors ...) equiv to (- collector0 collector1 ...) -(define (coll-minus . collectors) - (let ((res (gnc:make-commodity-collector))) - (res 'merge (car collectors) #f) - (for-each (lambda (coll) (res 'minusmerge coll #f)) (cdr collectors)) - res)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; trial-balance-renderer ;; set up the document and add the table @@ -531,7 +518,7 @@ (let* ((cost-fn (gnc:case-exchange-fn 'average-cost report-commodity end-date)) (acct-balances (map acct->bal all-accounts)) - (book-balance (apply coll-plus acct-balances)) + (book-balance (apply gnc:collector+ acct-balances)) (value (gnc:sum-collector-commodity book-balance report-commodity exchange-fn)) (cost (gnc:sum-collector-commodity @@ -674,17 +661,19 @@ (pos-adjusting (and ga-or-is? (sum-account-splits acct adjusting-splits #t))) (neg-adjusting - (and ga-or-is? (coll-minus adjusting pos-adjusting))) - (pre-closing-bal (coll-minus curr-bal closing)) - (pre-adjusting-bal (coll-minus pre-closing-bal adjusting)) + (and ga-or-is? (gnc:collector- adjusting pos-adjusting))) + (pre-closing-bal (gnc:collector- curr-bal closing)) + (pre-adjusting-bal (gnc:collector- pre-closing-bal + adjusting)) (atb (cond ((not is?) pre-closing-bal) ((double-col 'credit-q pre-adjusting-bal report-commodity exchange-fn show-fcur?) - (list (coll-plus pos-adjusting) - (coll-plus neg-adjusting pre-adjusting-bal))) + (list (gnc:collector+ pos-adjusting) + (gnc:collector+ neg-adjusting + pre-adjusting-bal))) (else - (list (coll-plus pos-adjusting pre-adjusting-bal) - (coll-plus neg-adjusting)))))) + (list (gnc:collector+ pos-adjusting pre-adjusting-bal) + (gnc:collector+ neg-adjusting)))))) ;; curr-bal = account-bal with closing & adj entries ;; pre-closing-bal = account-bal with adj entries only @@ -851,8 +840,8 @@ (tot-abs-amt-cell bs-credits)) '()))) (if (eq? report-variant 'work-sheet) - (let* ((net-is (coll-minus is-debits is-credits)) - (net-bs (coll-minus bs-debits bs-credits)) + (let* ((net-is (gnc:collector- is-debits is-credits)) + (net-bs (gnc:collector- bs-debits bs-credits)) (tot-is (gnc:make-commodity-collector)) (tot-bs (gnc:make-commodity-collector)) (is-entry #f)