gnucash maint: Revert "Calculate rates only for buy transactions in the report commodity

John Ralls jralls at code.gnucash.org
Sun Jan 21 20:33:55 EST 2018


Updated	 via  https://github.com/Gnucash/gnucash/commit/45f61a34 (commit)
	from  https://github.com/Gnucash/gnucash/commit/890a24a3 (commit)



commit 45f61a34a4ff4ec09f51915e3c56726923673b97
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Jan 21 17:09:59 2018 -0800

    Revert "Calculate rates only for buy transactions in the report commodity
    
    This reverts commit 98697a1e23c48737e472eba6314c3d05e6e689ee.
    
    See the extensive discuession in Bug 775368, including references and
    especially
    https://lists.gnucash.org/pipermail/gnucash-devel/2008-July/023297.html
    98697a1 was made without sufficient understanding of the history and
    intent of the code.

diff --git a/src/report/report-system/commodity-utilities.scm b/src/report/report-system/commodity-utilities.scm
index d14afab..ceca9c8 100644
--- a/src/report/report-system/commodity-utilities.scm
+++ b/src/report/report-system/commodity-utilities.scm
@@ -515,10 +515,17 @@
                            ;; report-commodity ((cdadr newrate) 'total
                            ;; #f))))
                            (set! reportlist (cons newrate reportlist))))))
-               ;; The report-currency showed up on the wrong side, so it was a
-               ;; "sell" for that commodity. We ignore those for cost reports
-               ;; and they're already aggregated for non-cost reports.
-                 ))
+               ;; Huh, the report-currency showed up on the wrong side
+               ;; -- we will just add it to the reportlist on the
+               ;; right side.
+               (let ((newrate (list (car otherlist)
+                                    (cons (cdadr pair) (caadr pair)))))
+                 ;; (warn "created new rate: "
+                 ;; (gnc-commodity-value->string (list (car newrate)
+                 ;; ((caadr newrate) 'total #f))) " = "
+                 ;; (gnc-commodity-value->string (list
+                 ;; report-commodity ((cdadr newrate) 'total #f))))
+                 (set! reportlist (cons newrate reportlist)))))
             (cadr otherlist))))
      sumlist)
 
@@ -530,70 +537,60 @@
 ;; or more runs of gnc:resolve-unknown-comm. Maybe we could transform
 ;; this functions to use some kind of recursiveness.
 
-(define (create-commodity-list inner-comm outer-comm share-amount value-amount)
-  (let ((foreignlist (list inner-comm
+(define (create-commodity-list inner-comm outer-comm value-amount share-amount)
+  (let ((pair (list inner-comm
                     (cons (gnc:make-numeric-collector)
-                          (gnc:make-numeric-collector))))
-        (comm-list #f))
-    ((caadr foreignlist) 'add share-amount)
-    ((cdadr foreignlist) 'add value-amount)
-    (set! comm-list (list outer-comm (list foreignlist)))
-    (gnc:debug "New Outer entry " (gnc-commodity-get-mnemonic outer-comm)
-                   (gnc-commodity-get-mnemonic inner-comm) share-amount
-                   value-amount)
-    comm-list))
-
-(define (create-foreign-list comm-list inner-comm outer-comm
+                          (gnc:make-numeric-collector)))))
+    ((caadr pair) 'add value-amount)
+    ((cdadr pair) 'add share-amount)
+    (set comm-list (list outer-comm (list pair)))))
+
+(define (create-foreign-list comm-list transaction-comm account-comm
                              share-amount value-amount)
   (let ((foreign-list
-             (if (gnc-commodity-equiv inner-comm (car comm-list))
-                 (list outer-comm share-amount value-amount)
-                 (list inner-comm value-amount share-amount))))
-    (gnc:debug "Add value " (gnc-commodity-get-mnemonic (car comm-list))
-               (gnc-commodity-get-mnemonic (car foreign-list))
-               (cadr foreign-list) (cddr foreign-list))
+         (if (gnc-commodity-equiv transaction-comm (car comm-list))
+             (list account-comm share-amount value-amount)
+             (list transaction-comm value-amount share-amount))))
+    foreign-list))
+
+(define (create-foreign-cost-list comm-list transaction-comm account-comm
+                                  share-amount value-amount)
+  (let ((foreign-list
+         (if (gnc-commodity-equiv transaction-comm (car comm-list))
+             (list account-comm share-amount value-amount)
+             (list transaction-comm (gnc-numeric-neg value-amount)
+                   (gnc-numeric-neg share-amount)))))
     foreign-list))
 
 (define (create-commodity-pair foreignlist comm-list sumlist)
   (let ((pair (assoc (car foreignlist) (cadr comm-list))))
     ;; no pair already, create one
     (if (not pair)
-        (begin
-          (set! pair (list (car foreignlist)
+        (set! pair (list (car foreignlist)
                          (cons (gnc:make-numeric-collector)
-                               (gnc:make-numeric-collector))))
-          (gnc:debug "New commodity "
-                     (gnc-commodity-get-mnemonic (car foreignlist)))))
+                               (gnc:make-numeric-collector)))))
     pair))
 
-;; gnc:get-exchange-totals returns a sumlist, which is a multilevel alist. Each
-;; element has a commodity as key, and another alist as a value. The
-;; value-alist's elements consist of a commodity as a key, and a pair of two
-;; value-collectors as value, e.g. with only one (the report-) commodity DEM in
-;; the outer alist: ( {DEM ( [USD (400 .  1000)] [FRF (300 . 100)] ) } ) where
-;; DEM,USD,FRF are <gnc:commodity> and the numbers are a numeric-collector which
-;; in turn store a <gnc:numeric>. In the example, USD 400 were bought for an
-;; amount of DEM 1000, FRF 300 were bought for DEM 100. The reason for the outer
-;; alist is that there might be commodity transactions which do not involve the
-;; report-commodity, but which can still be calculated after *all* transactions
-;; are processed.
-;;
-
+;; sumlist: a multilevel alist. Each element has a commodity as key, and another
+;; alist as a value. The value-alist's elements consist of a commodity as a key,
+;; and a pair of two value-collectors as value, e.g. with only one (the report-)
+;; commodity DEM in the outer alist: ( {DEM ( [USD (400 .  1000)] [FRF (300
+;; . 100)] ) } ) where DEM,USD,FRF are <gnc:commodity> and the numbers are a
+;; numeric-collector which in turn store a <gnc:numeric>. In the example, USD
+;; 400 were bought for an amount of DEM 1000, FRF 300 were bought for DEM
+;; 100. The reason for the outer alist is that there might be commodity
+;; transactions which do not involve the report-commodity, but which can still
+;; be calculated after *all* transactions are processed.  Calculate the weighted
+;; average exchange rate between all commodities and the
+;; 'report-commodity'. Uses all currency transactions up until the
+;; 'end-date'. Returns an alist, see sumlist.
 (define (gnc:get-exchange-totals report-commodity end-date cost)
-;; Finds all splits in the book whose commodity is different from the parent
-;; transaction's commodity and creates a sumlist of the amount and value for
-;; each commodity pair. If 'cost' is true then the totals represent the costs of
-;; buying one commodity with the other; if it's false then the trades in both
-;; directions are agregated.  A side effect of the distinction is that changing
-;; the report currency will change the resulting exchange rate if 'cost' is true
-;; but not if it is false.
   (let ((curr-accounts
          ;;(filter gnc:account-has-shares? ))
          ;; -- use all accounts, not only share accounts, since gnucash-1.7
          (gnc-account-get-descendants-sorted (gnc-get-current-root-account)))
         (sumlist (list (list report-commodity '()))))
-    (gnc:debug "Begin Report " (gnc-commodity-get-mnemonic report-commodity)
-               " cost " cost)
+
     (if (not (null? curr-accounts))
         ;; Go through all splits and add up all value-amounts
         ;; and share-amounts
@@ -603,53 +600,33 @@
                                      (xaccSplitGetParent a)))
                   (account-comm (xaccAccountGetCommodity
                                  (xaccSplitGetAccount a)))
-                  (share-amount (xaccSplitGetAmount a))
-                  (value-amount (xaccSplitGetValue a))
-                  ;; If the share-value is negative then the transaction
-                  ;; purchased something in the transaction currency; otherwise
-                  ;; the purchase is in the account currency.
-                  (outer-comm (if (gnc-numeric-negative-p share-amount)
-                                  account-comm transaction-comm))
-                  (inner-comm (if (gnc-numeric-negative-p share-amount)
-                                  transaction-comm account-comm))
-                  (tmp (assoc outer-comm sumlist))
-                  ;; If cost isn't true then we want one entry for both in
-                  ;; sumlist.
-                  (comm-list (if (and (not tmp) (not cost))
-                                 (assoc inner-comm sumlist)
+                  (share-amount (if cost
+                                    (xaccSplitGetAmount a)
+                                    (gnc-numeric-abs (xaccSplitGetAmount a))))
+                  (value-amount (if cost
+                                    (xaccSplitGetValue a)
+                                    (gnc-numeric-abs (xaccSplitGetValue a))))
+                  (tmp (assoc transaction-comm sumlist))
+                  (comm-list (if (not tmp)
+                                 (assoc account-comm sumlist)
                                  tmp)))
-             ;; We need to reverse and negate the values if they were negative
-             ;; because we already reversed the commodities they applied to.
-             (gnc:debug "Transaction commodity "
-                        (gnc-commodity-get-mnemonic transaction-comm)
-                        " Account commodity "
-                        (gnc-commodity-get-mnemonic account-comm)
-                        " Outer Commodity "
-                        (gnc-commodity-get-mnemonic outer-comm)
-                        " Inner Commodity "
-                        (gnc-commodity-get-mnemonic inner-comm)
-                        " Amount " share-amount " Value " value-amount)
-             (if (gnc-numeric-negative-p share-amount)
-                 ;;(if cost ;; swap as well as negate
-                     ;;(let* ((tmp-amount share-amount))
-                       ;;(set! share-amount (gnc-numeric-neg value-amount))
-                       ;;(set! value-amount (gnc-numeric-neg tmp-amount)))
-                     (begin ;; we just want to make sure they're positive
-                       (set! share-amount (gnc-numeric-abs share-amount))
-                       (set! value-amount (gnc-numeric-abs value-amount));;)
-                 ))
              ;; entry exists already in comm-list?
              (if (not comm-list)
                  ;; no, create sub-alist from scratch
                  (begin
                    (set! comm-list (create-commodity-list
-                                    inner-comm outer-comm
+                                    account-comm transaction-comm
                                     share-amount value-amount))
                    (set! sumlist (cons comm-list sumlist)))
 
-                 ;;yes, add the second commodity if it's not already stored
-                 (let* ((foreignlist (create-foreign-list comm-list outer-comm
-                                      inner-comm share-amount value-amount))
+                 ;;yes, check for second commodity
+                 (let* ((foreignlist (if cost
+                                         (create-foreign-cost-list
+                                          comm-list transaction-comm account-comm
+                                          share-amount value-amount)
+                                         (create-foreign-list
+                                          comm-list transaction-comm account-comm
+                                          share-amount value-amount)))
                         (pair (create-commodity-pair foreignlist comm-list
                                                      sumlist)))
                    (set! comm-list (list (car comm-list)
@@ -660,8 +637,7 @@
                    ((cdadr pair) 'add (caddr foreignlist))))))
 
         (gnc:get-all-commodity-splits curr-accounts end-date)))
-    (gnc:debug "End Report\n")
-    ;; Finally resolve any indirect conversions.
+
   (gnc:resolve-unknown-comm sumlist report-commodity)))
 
 (define (gnc:make-exchange-alist report-commodity end-date cost)



Summary of changes:
 src/report/report-system/commodity-utilities.scm | 156 ++++++++++-------------
 1 file changed, 66 insertions(+), 90 deletions(-)



More information about the gnucash-changes mailing list