crap bad diffs file there, please disregard and use the attached.
A On Fri, 17 Feb 2006 16:33:43 -0800 Andrew Sackville-West <[EMAIL PROTECTED]> wrote: > Okay, the advanced portfolio report was broken in a number of ways. I've > masssaged it pretty well I think, but made some assumptions about how it > should behave. Essentially, there are three cases we encounter, listed below: > > 1). a normal, properly formed stock account with pricedb entries etc. In this > case, the report should work as expected, handling multiple currencies etc. I > do not use multiple currencies and don't really grok them so if someone could > test this properly, that would be great > > 2) a stock account with no shares in it. In this case, the report just spews > a bunch of zeros for the particular stock, as expected. It no longer crashes > which should solve Eildert's problem > > 3) a stock account with shares in it but with no pricedb entry. In this case, > I made the assumption that the file was broken. There should always be a > pricedb entry if there are any shares in an account, IMO. Probably the code > should be fixed so that any buy or sell or similar action automatically > creates a pricedb entry. Still we have to account for 1.8 files that might be > broken in this regard. phew. What it does: flags the particular stock as > being "dirty" and tries to make a reasonable guess at what the current value > and gain is based on data pulled from the actual transactions. I am not > convinced however that this data is properly exchanged across multiple > currencies. So the report spews what it can on this stock, but sticks a * in > the price column and places a warning at the bottom of the report explaining > the situation. Also, any stocks that don't have a pricedb entry are EXCLUDED > from the totals at the bottom of the report as the information is not > reliable. > > please give me feedback on this monster and my assumptions. I would like to > make it behave appropriately and I don't know if my assumptions are correct. > > thanks > > A >
Index: src/report/standard-reports/advanced-portfolio.scm =================================================================== --- src/report/standard-reports/advanced-portfolio.scm (revision 13285) +++ src/report/standard-reports/advanced-portfolio.scm (working copy) @@ -46,6 +46,7 @@ (define optname-show-listing (N_ "Show listings")) (define optname-show-price (N_ "Show prices")) (define optname-show-shares (N_ "Show number of shares")) +(define price-is-dirty #f) ;;keep track of whether we're using good price data (define (options-generator) (let* ((options (gnc:new-options)) @@ -151,7 +152,8 @@ (define (advanced-portfolio-renderer report-obj) (let ((work-done 0) - (work-to-do 0)) + (work-to-do 0) + (warn-price-dirty #f)) ;; These are some helper functions for looking up option values. (define (get-op section name) @@ -201,15 +203,23 @@ (moneyincoll (gnc:make-commodity-collector)) (moneyoutcoll (gnc:make-commodity-collector)) (gaincoll (gnc:make-commodity-collector)) + (dirty-value (gnc:numeric-zero)) + (dirty-amount (gnc:numeric-zero)) (price-list (price-fn commodity to-date)) (price (if (> (length price-list) 0) (car price-list) #f)) - (commod-currency (gnc:price-get-currency price)) + ;; if there is no price, set a sane commod-currency for those zero-share + ;; accounts. if its a no price account with shares, we'll get a currency later. + (commod-currency (if (not price) (gnc:price-get-currency price) currency)) (value (exchange-fn (gnc:make-gnc-monetary commodity units) currency)) + ;;if we have shares but no price in pricedb, we'll make a dirty price guess at things + (price-is-dirty (if (and (not price) (< 0 (gnc:numeric-to-double units))) #t #f)) ) + (if price-is-dirty (set! warn-price-dirty #t)) + ;; (gnc:debug "---" name "---") (for-each (lambda (split) @@ -217,47 +227,69 @@ (gnc:report-percent-done (* 100 (/ work-done work-to-do))) (let ((parent (gnc:split-get-parent split))) (if (gnc:timepair-le (gnc:transaction-get-date-posted parent) to-date) - (for-each - (lambda (s) - (cond - ((same-split? s split) + (begin + (for-each + (lambda (s) + ;; if price-is dirty and this is an asset type account for buy or sell, then grab a + ;; currency and a dirty-value for later computation + (if (and price-is-dirty (not (or (split-account-type? s 'stock) + (split-account-type? s 'mutualfund) + (split-account-type? s 'expense) + (split-account-type? s 'income)))) + (begin + (set! commod-currency (gnc:account-get-commodity (gnc:split-get-account s))) + (set! dirty-value (gnc:split-get-value s)) + (if (gnc:numeric-negative-p dirty-value) + (set! dirty-value (gnc:numeric-sub (gnc:numeric-zero) dirty-value + 10000 GNC-RND-ROUND))))) + ) + + (gnc:transaction-get-splits parent)) + + (for-each + (lambda (s) + (cond + ((same-split? s split) ;; (gnc:debug "amount " (gnc:numeric-to-double (gnc:split-get-amount s)) ;; " acct " (gnc:account-get-name (gnc:split-get-account s)) ) ;; (gnc:debug "value " (gnc:numeric-to-double (gnc:split-get-value s)) ;; " in " (gnc:commodity-get-printname commod-currency) ;; " from " (gnc:transaction-get-description (gnc:split-get-parent s))) - (cond - ((or include-gains (not (gnc:numeric-zero-p (gnc:split-get-amount s)))) - (unitscoll 'add commodity (gnc:split-get-amount s)) ;; Is the stock transaction? - (if (< 0 (gnc:numeric-to-double - (gnc:split-get-amount s))) - (set! totalunits - (+ totalunits - (gnc:numeric-to-double (gnc:split-get-amount s))))) - (set! totalunityears - (+ totalunityears - (* (gnc:numeric-to-double (gnc:split-get-amount s)) - (gnc:date-year-delta - (car (gnc:transaction-get-date-posted parent)) - (current-time))))) - (cond - ((gnc:numeric-negative-p (gnc:split-get-value s)) - (moneyoutcoll - 'add commod-currency - (gnc:numeric-neg (gnc:split-get-value s)))) - (else (moneyincoll - 'add commod-currency - (gnc:numeric-neg (gnc:split-get-value s)))))))) + (cond + ((or include-gains (not (gnc:numeric-zero-p (gnc:split-get-amount s)))) + (unitscoll 'add commodity (gnc:split-get-amount s)) ;; Is the stock transaction? + (set! dirty-amount (gnc:split-get-amount s)) + (if (< 0 (gnc:numeric-to-double + (gnc:split-get-amount s))) + (set! totalunits + (+ totalunits + (gnc:numeric-to-double (gnc:split-get-amount s))))) + + (set! totalunityears + (+ totalunityears + (* (gnc:numeric-to-double (gnc:split-get-amount s)) + (gnc:date-year-delta + (car (gnc:transaction-get-date-posted parent)) + (current-time))))) + (cond + ((gnc:numeric-negative-p (gnc:split-get-value s)) + (moneyoutcoll + 'add commod-currency + (gnc:numeric-neg (gnc:split-get-value s)))) + (else (moneyincoll + 'add commod-currency + (gnc:numeric-neg (gnc:split-get-value s)))))))) - ((split-account-type? s 'expense) - (brokeragecoll 'add commod-currency (gnc:split-get-value s))) - - ((split-account-type? s 'income) - (dividendcoll 'add commod-currency (gnc:split-get-value s))) - ) + ((split-account-type? s 'expense) + (brokeragecoll 'add commod-currency (gnc:split-get-value s))) + + ((split-account-type? s 'income) + (dividendcoll 'add commod-currency (gnc:split-get-value s))) + ) + ) + (gnc:transaction-get-splits parent) ) - (gnc:transaction-get-splits parent) - ) + ) ) ) ) @@ -266,25 +298,41 @@ ;; (gnc:debug "totalunits" totalunits) ;; (gnc:debug "totalunityears" totalunityears) - (moneyincoll 'minusmerge dividendcoll #f) + + (if price-is-dirty + (set! value (gnc:make-gnc-monetary commod-currency + (gnc:numeric-mul units + (gnc:numeric-div dirty-value + dirty-amount + 10000 GNC-RND-ROUND) + 10000 GNC-RND-ROUND)))) + (moneyincoll 'minusmerge dividendcoll #f) (moneyoutcoll 'minusmerge brokeragecoll #f) (gaincoll 'merge moneyoutcoll #f) (gaincoll 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value)) (gaincoll 'merge moneyincoll #f) (if (or include-empty (not (gnc:numeric-zero-p units))) - (let ((moneyin (gnc:monetary-neg + (let* ((moneyin (gnc:monetary-neg (gnc:sum-collector-commodity moneyincoll currency exchange-fn))) (moneyout (gnc:sum-collector-commodity moneyoutcoll currency exchange-fn)) - (gain (gnc:sum-collector-commodity gaincoll currency exchange-fn)) + (gain (if price-is-dirty + (gnc:make-gnc-monetary commod-currency + (gnc:numeric-sub (gnc:gnc-monetary-amount value) + (gnc:gnc-monetary-amount moneyin) + 10000 GNC-RND-ROUND)) + (gnc:sum-collector-commodity gaincoll currency exchange-fn))) (activecols (list (gnc:html-account-anchor current))) ) - (total-value 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value)) - (total-moneyin 'merge moneyincoll #f) - (total-moneyout 'merge moneyoutcoll #f) - (total-gain 'merge gaincoll #f) + (if (not price-is-dirty) + (begin + (total-value 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value)) + (total-moneyin 'merge moneyincoll #f) + (total-moneyout 'merge moneyoutcoll #f) + (total-gain 'merge gaincoll #f))) + ;; build a list for the row based on user selections (if show-symbol (append! activecols (list ticker-symbol))) (if show-listing (append! activecols (list listing))) @@ -298,14 +346,14 @@ (gnc:make-gnc-monetary (gnc:price-get-currency price) (gnc:price-get-value price))) - #f))))) + (if price-is-dirty "*" #f)))))) (append! activecols (list (gnc:make-html-table-header-cell/markup "number-cell" value) (gnc:make-html-table-header-cell/markup "number-cell" - (gnc:monetary-neg (gnc:sum-collector-commodity moneyincoll currency exchange-fn))) + moneyin) (gnc:make-html-table-header-cell/markup "number-cell" - (gnc:sum-collector-commodity moneyoutcoll currency exchange-fn)) + moneyout) (gnc:make-html-table-header-cell/markup "number-cell" - (gnc:sum-collector-commodity gaincoll currency exchange-fn)) + gain) (gnc:make-html-table-header-cell/markup "number-cell" (let ((moneyinvalue (gnc:numeric-to-double (cadr (moneyincoll 'getpair currency #t))))) @@ -423,9 +471,9 @@ (table-add-stock-rows table accounts to-date currency price-fn exchange-fn - include-empty include-gains show-symbol show-listing show-shares show-price + include-empty include-gains show-symbol show-listing show-shares show-price total-value total-moneyin total-moneyout total-gain) - + (gnc:html-table-append-row/markup! table "grand-total" @@ -459,10 +507,15 @@ table "grand-total" totalscols - ) - - (gnc:html-document-add-object! document table)) + ) + (gnc:html-document-add-object! document table) + (if warn-price-dirty + (gnc:html-document-append-objects! document + (list (gnc:make-html-text (_ "* no valid price data for this commodity. It has been exluded from totals and<BR>")) + (gnc:make-html-text (_ "may not be properly exchanged. Please enter a price in the Price Editor."))))) +) + ;if no accounts selected. (gnc:html-document-add-object! document
pgpDyUEzwKWHR.pgp
Description: PGP signature
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel