mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bill Gribble's patch to g-wrap the numerics.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3137 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
bfb4ca052a
commit
a30ed47100
40
ChangeLog
40
ChangeLog
@ -1,3 +1,43 @@
|
||||
2000-11-08 Bill Gribble <grib@billgribble.com>
|
||||
|
||||
* src/engine/SplitLedger.c: use new SetShareAmount/SetValue
|
||||
semantics (need to make sure this is correct!)
|
||||
|
||||
* src/engine/Group.c: fix the "splits in GList with NULL data"
|
||||
problem.
|
||||
|
||||
* src/engine/Transaction.c: get rid of Set***Directly functions,
|
||||
and modify the gnc_numeric versions of SetValue and SetShareAmount
|
||||
to use the direct semantics (i.e. SetValue doesn't affect the
|
||||
ShareAmount any more unless you use the deprecated double API).
|
||||
|
||||
* src/engine/gnc-numeric.c: fix gnc_numeric_convert and
|
||||
double_to_gnc_numeric to ameliorate overflow problems. This
|
||||
should fix the wrong balance problems people are seeing.
|
||||
|
||||
* src/gnome/druid-qif-import.c: make selection persistent in
|
||||
account/cat pick lists
|
||||
|
||||
* g-wrap gnc-numeric datatype and API; shuffle the Scheme API in
|
||||
the same way the C was done to add the new gnc-numeric API using
|
||||
the "real" function names and deprecate the old double API by
|
||||
prefixing the names with d-. Now (for example)
|
||||
gnc:split-set-value takes a gnc_numeric arg, and
|
||||
d-gnc:split-set-value takes a double. All calling scheme code was
|
||||
sed'ed to make this change.
|
||||
|
||||
* src/scm/qif-import/qif-dialog-utils.scm: fix stock name regexp
|
||||
parsing bug in QIF importer. This should fix the crash that many
|
||||
people have reported.
|
||||
|
||||
* src/scm/qif-import/qif-file.scm: fix an Opening Balance
|
||||
processing bug that was causing some opening balance transactions
|
||||
to be duplicated.
|
||||
|
||||
* src/scm/qif-import/qif-to-gnc.scm: fix double-counting of
|
||||
Commissions. Change to use gnc_numeric and new Set semantics;
|
||||
this should (maybe) fix some reported off-by-a-penny problems.
|
||||
|
||||
2000-11-05 Rob Browning <rlb@cs.utexas.edu>
|
||||
|
||||
* src/engine/io-gncxml-w.c: sort commodities by namespace and id
|
||||
|
@ -2847,10 +2847,12 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
|
||||
|
||||
if (MOD_SHRS & changed) {
|
||||
gnc_numeric amount = xaccGetPriceCellValue(reg->sharesCell);
|
||||
|
||||
gnc_numeric price = xaccGetPriceCellValue(reg->priceCell);
|
||||
|
||||
DEBUG ("MOD_SHRS");
|
||||
|
||||
xaccSplitSetShareAmount (split, amount);
|
||||
xaccSplitSetSharePrice (split, price);
|
||||
}
|
||||
|
||||
if (MOD_PRIC & changed) {
|
||||
@ -2878,6 +2880,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
|
||||
|
||||
DEBUG ("MOD_AMNT");
|
||||
|
||||
/* FIXME : make sure amount gets updated? -- bg */
|
||||
xaccSplitSetValue (split, new_amount);
|
||||
}
|
||||
|
||||
|
@ -843,13 +843,17 @@ xaccMergeAccounts (AccountGroup *grp)
|
||||
xaccMergeAccounts (ga);
|
||||
|
||||
/* consolidate transactions */
|
||||
lp = acc_b->splits;
|
||||
|
||||
for(lp = acc_b->splits; lp; lp = lp->next) {
|
||||
Split *split = (Split *) lp->data;
|
||||
lp->data = NULL;
|
||||
split->acc = NULL;
|
||||
xaccAccountInsertSplit (acc_a, split);
|
||||
split->acc = NULL;
|
||||
xaccAccountInsertSplit (acc_a, split);
|
||||
}
|
||||
|
||||
|
||||
g_list_free(acc_b->splits);
|
||||
acc_b->splits = NULL;
|
||||
|
||||
/* free the account structure itself */
|
||||
xaccFreeAccount (acc_b);
|
||||
grp->account[j] = grp->account[grp->numAcc -1];
|
||||
|
@ -356,20 +356,6 @@ get_security_denom(Split * s) {
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
/* FIXME: this is probably wrong, but it'll have to wait until Bill
|
||||
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
||||
void
|
||||
xaccSplitSetValueDirectly(Split *s, gnc_numeric n) {
|
||||
if(!s) return;
|
||||
s->value = n;
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetQuantityDirectly(Split *s, gnc_numeric n) {
|
||||
if(!s) return;
|
||||
s->damount = n;
|
||||
}
|
||||
|
||||
void
|
||||
DxaccSplitSetSharePriceAndAmount (Split *s, double price, double amt)
|
||||
{
|
||||
@ -414,46 +400,45 @@ xaccSplitSetSharePrice (Split *s, gnc_numeric price) {
|
||||
}
|
||||
|
||||
void
|
||||
DxaccSplitSetShareAmount (Split *s, double amt) {
|
||||
xaccSplitSetShareAmount(s,
|
||||
double_to_gnc_numeric(amt, get_security_denom(s),
|
||||
GNC_RND_ROUND));
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetShareAmount (Split *s, gnc_numeric amt) {
|
||||
DxaccSplitSetShareAmount (Split *s, double damt) {
|
||||
gnc_numeric old_price;
|
||||
|
||||
gnc_numeric amt = double_to_gnc_numeric(damt, get_security_denom(s),
|
||||
GNC_RND_ROUND);
|
||||
if (!s) return;
|
||||
|
||||
|
||||
MARK_SPLIT(s);
|
||||
if(!gnc_numeric_zero_p(s->damount)) {
|
||||
old_price = gnc_numeric_div(s->value, s->damount, GNC_DENOM_AUTO,
|
||||
GNC_DENOM_EXACT);
|
||||
GNC_DENOM_REDUCE);
|
||||
}
|
||||
else {
|
||||
old_price = gnc_numeric_create(PRICE_DENOM, PRICE_DENOM);
|
||||
}
|
||||
|
||||
|
||||
s->damount = gnc_numeric_convert(amt, get_security_denom(s),
|
||||
GNC_RND_NEVER);
|
||||
s->value = gnc_numeric_mul(s->damount, old_price,
|
||||
get_currency_denom(s), GNC_RND_ROUND);
|
||||
|
||||
|
||||
/* force double entry to always balance */
|
||||
xaccSplitRebalance (s);
|
||||
}
|
||||
|
||||
void
|
||||
DxaccSplitSetValue (Split *s, double amt) {
|
||||
xaccSplitSetValue(s,
|
||||
double_to_gnc_numeric(amt,
|
||||
get_currency_denom(s),
|
||||
GNC_RND_ROUND));
|
||||
xaccSplitSetShareAmount (Split *s, gnc_numeric amt) {
|
||||
if(!s) return;
|
||||
MARK_SPLIT(s);
|
||||
|
||||
s->damount = amt;
|
||||
|
||||
xaccSplitRebalance (s);
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetValue (Split *s, gnc_numeric amt) {
|
||||
DxaccSplitSetValue (Split *s, double damt) {
|
||||
gnc_numeric amt = double_to_gnc_numeric(damt,
|
||||
get_currency_denom(s),
|
||||
GNC_RND_ROUND);
|
||||
gnc_numeric old_price;
|
||||
if (!s) return;
|
||||
|
||||
@ -461,7 +446,7 @@ xaccSplitSetValue (Split *s, gnc_numeric amt) {
|
||||
|
||||
if(!gnc_numeric_zero_p(s->damount)) {
|
||||
old_price = gnc_numeric_div(s->value, s->damount, GNC_DENOM_AUTO,
|
||||
GNC_DENOM_EXACT);
|
||||
GNC_DENOM_REDUCE);
|
||||
}
|
||||
else {
|
||||
old_price = gnc_numeric_create(PRICE_DENOM, PRICE_DENOM);
|
||||
@ -479,6 +464,16 @@ xaccSplitSetValue (Split *s, gnc_numeric amt) {
|
||||
xaccSplitRebalance (s);
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitSetValue (Split *s, gnc_numeric amt) {
|
||||
if(!s) return;
|
||||
MARK_SPLIT(s);
|
||||
|
||||
s->value = amt;
|
||||
|
||||
xaccSplitRebalance (s);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -927,12 +922,12 @@ ComputeValue (GList *splits, Split * skip_me,
|
||||
}
|
||||
else {
|
||||
value = gnc_numeric_add(value, s->value, GNC_DENOM_AUTO,
|
||||
GNC_DENOM_LCD);
|
||||
GNC_DENOM_REDUCE);
|
||||
}
|
||||
}
|
||||
else if ((0x0 == base_currency) && (0 == force_double_entry)) {
|
||||
value = gnc_numeric_add(value, s->value, GNC_DENOM_AUTO,
|
||||
GNC_DENOM_LCD);
|
||||
GNC_DENOM_REDUCE);
|
||||
}
|
||||
else {
|
||||
/* OK, we've got a parent account, we've got currency,
|
||||
|
@ -466,6 +466,7 @@ gnc_numeric_abs(gnc_numeric a) {
|
||||
gnc_numeric
|
||||
gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
|
||||
gnc_numeric out;
|
||||
gnc_numeric temp;
|
||||
gint64 temp_bc;
|
||||
gint64 temp_a;
|
||||
gint64 remainder;
|
||||
@ -529,12 +530,21 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
|
||||
}
|
||||
else {
|
||||
/* do all the modulo and int division on positive values to make
|
||||
* things a little clearer. */
|
||||
out.num = in.num * denom;
|
||||
* things a little clearer. Reduce the fraction denom/in.denom to
|
||||
* help with range errors (FIXME : need bigger intermediate rep) */
|
||||
temp.num = denom;
|
||||
temp.denom = in.denom;
|
||||
temp = gnc_numeric_reduce(temp);
|
||||
|
||||
/* out.num = in.num * denom; */
|
||||
out.num = in.num * temp.num;
|
||||
out.num = (out.num < 0) ? -out.num : out.num;
|
||||
remainder = out.num % in.denom;
|
||||
out.num = out.num / in.denom;
|
||||
remainder = out.num % temp.denom;
|
||||
out.num = out.num / temp.denom;
|
||||
out.denom = denom;
|
||||
if(remainder) {
|
||||
remainder = remainder * in.denom / temp.denom;
|
||||
}
|
||||
}
|
||||
|
||||
if(remainder > 0) {
|
||||
@ -768,34 +778,43 @@ gnc_numeric_reduce(gnc_numeric in) {
|
||||
gnc_numeric
|
||||
double_to_gnc_numeric(double in, gint64 denom, gint how) {
|
||||
gnc_numeric out;
|
||||
gint64 int_part=0;
|
||||
double frac_part;
|
||||
gint64 frac_int=0;
|
||||
|
||||
in = in * (double)denom;
|
||||
int_part = (gint64)(floor(fabs(in)));
|
||||
frac_part = in - (double)int_part;
|
||||
|
||||
int_part = int_part * denom;
|
||||
frac_part = frac_part * (double)denom;
|
||||
|
||||
switch(how) {
|
||||
case GNC_RND_FLOOR:
|
||||
out.num = (gint64)floor(in);
|
||||
frac_int = (gint64)floor(frac_part);
|
||||
break;
|
||||
|
||||
case GNC_RND_CEIL:
|
||||
out.num = (gint64)ceil(in);
|
||||
frac_int = (gint64)ceil(frac_part);
|
||||
break;
|
||||
|
||||
case GNC_RND_TRUNC:
|
||||
out.num = (gint64)in;
|
||||
frac_int = (gint64)frac_part;
|
||||
break;
|
||||
|
||||
case GNC_RND_ROUND:
|
||||
case GNC_RND_ROUND_HALF_UP:
|
||||
out.num = (gint64)rint(in);
|
||||
frac_int = (gint64)rint(frac_part);
|
||||
break;
|
||||
|
||||
case GNC_RND_NEVER:
|
||||
out.num = (gint64)floor(in);
|
||||
if(in != (double) out.num) {
|
||||
frac_int = (gint64)floor(frac_part);
|
||||
if(frac_part != (double) frac_int) {
|
||||
/* signal an error */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out.num = int_part + frac_int;
|
||||
out.denom = denom;
|
||||
return out;
|
||||
}
|
||||
|
@ -3718,19 +3718,15 @@ txn_restore_split_after_child_handler(gpointer data_for_children,
|
||||
child_result->should_cleanup = FALSE;
|
||||
}
|
||||
else if(strcmp(child_result->tag, "quantity") == 0) {
|
||||
/* This is probably going to have to be changed to set quantity
|
||||
and value together in the end handler, but for now, a hack. */
|
||||
gnc_numeric *n = (gnc_numeric *) child_result->data;
|
||||
if(!n) return(FALSE);
|
||||
xaccSplitSetQuantityDirectly(s, *n);
|
||||
xaccSplitSetShareAmount(s, *n);
|
||||
/* let the normal child_result handler clean up n */
|
||||
}
|
||||
else if(strcmp(child_result->tag, "value") == 0) {
|
||||
/* This is probably going to have to be changed to set quantity
|
||||
and value together in the end handler, but for now, a hack. */
|
||||
gnc_numeric *n = (gnc_numeric *) child_result->data;
|
||||
if(!n) return(FALSE);
|
||||
xaccSplitSetValueDirectly(s, *n);
|
||||
xaccSplitSetValue(s, *n);
|
||||
/* let the normal child_result handler clean up n */
|
||||
}
|
||||
|
||||
|
@ -672,8 +672,12 @@ update_accounts_page(QIFImportWindow * wind) {
|
||||
SCM get_gnc_name = gh_eval_str("qif-map-entry:gnc-name");
|
||||
SCM get_new = gh_eval_str("qif-map-entry:new-acct?");
|
||||
SCM accts_left;
|
||||
int sel_row=0;
|
||||
char * row_text[3];
|
||||
|
||||
/* get the old selection row */
|
||||
sel_row = (GTK_CLIST(wind->acct_list))->focus_row;
|
||||
|
||||
/* now get the list of strings to display in the clist widget */
|
||||
accts_left = gh_call3(make_account_display,
|
||||
wind->imported_files,
|
||||
@ -714,7 +718,13 @@ update_accounts_page(QIFImportWindow * wind) {
|
||||
free(row_text[0]);
|
||||
free(row_text[1]);
|
||||
}
|
||||
|
||||
gtk_clist_thaw(GTK_CLIST(wind->acct_list));
|
||||
|
||||
/* move to the old selected row */
|
||||
(GTK_CLIST(wind->acct_list))->focus_row = sel_row;
|
||||
gtk_clist_moveto(GTK_CLIST(wind->acct_list), sel_row, 0, 0.0, 0.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -732,8 +742,12 @@ update_categories_page(QIFImportWindow * wind) {
|
||||
SCM get_gnc_name = gh_eval_str("qif-map-entry:gnc-name");
|
||||
SCM get_new = gh_eval_str("qif-map-entry:new-acct?");
|
||||
SCM cats_left;
|
||||
int sel_row=0;
|
||||
char * row_text[3];
|
||||
|
||||
/* get the old selection row */
|
||||
sel_row = (GTK_CLIST(wind->cat_list))->focus_row;
|
||||
|
||||
/* now get the list of strings to display in the clist widget */
|
||||
cats_left = gh_call3(make_category_display,
|
||||
wind->imported_files,
|
||||
@ -774,7 +788,13 @@ update_categories_page(QIFImportWindow * wind) {
|
||||
free (row_text[0]);
|
||||
free (row_text[1]);
|
||||
}
|
||||
|
||||
gtk_clist_thaw(GTK_CLIST(wind->cat_list));
|
||||
|
||||
/* move to the old selected row */
|
||||
(GTK_CLIST(wind->cat_list))->focus_row = sel_row;
|
||||
gtk_clist_moveto(GTK_CLIST(wind->cat_list), sel_row, 0, 0.0, 0.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,8 +102,8 @@
|
||||
(gnc:split-get-action split)
|
||||
(gnc:split-get-reconcile-state split)
|
||||
(gnc:split-get-reconciled-date split)
|
||||
(gnc:split-get-share-amount split)
|
||||
(gnc:split-get-share-price split)))
|
||||
(d-gnc:split-get-share-amount split)
|
||||
(d-gnc:split-get-share-price split)))
|
||||
|
||||
;; Copy a scheme representation of a split onto a C split.
|
||||
;; If possible, insert the C split into the account of the
|
||||
@ -121,7 +121,7 @@
|
||||
(if memo (gnc:split-set-memo split memo))
|
||||
(if action (gnc:split-set-action split action))
|
||||
(if (and price amount)
|
||||
(gnc:split-set-share-price-and-amount split price amount)))
|
||||
(d-gnc:split-set-share-price-and-amount split price amount)))
|
||||
(let ((account (gnc:account-lookup
|
||||
(gnc:split-scm-get-account-guid split-scm))))
|
||||
(if (and account (gnc:account-can-insert-split? account split))
|
||||
|
@ -455,7 +455,7 @@
|
||||
(qif-file:xtns qif-file)))
|
||||
|
||||
(define qif-import:account-name-regexp
|
||||
(let* ((rstr ":([^:]*)$|^([^:]*)$")
|
||||
(let* ((rstr ":([^:]+)$|^([^:]+)$")
|
||||
(newstr (regexp-substitute/global
|
||||
#f ":" rstr 'pre (gnc:account-separator-char) 'post)))
|
||||
(make-regexp newstr)))
|
||||
@ -463,9 +463,13 @@
|
||||
(define (qif-import:get-account-name fullname)
|
||||
(let ((match (regexp-exec qif-import:account-name-regexp fullname)))
|
||||
(if match
|
||||
(match:substring match 1)
|
||||
(begin
|
||||
(let ((substr (match:substring match 1)))
|
||||
(if substr
|
||||
substr
|
||||
(match:substring match 2))))
|
||||
fullname)))
|
||||
|
||||
|
||||
(define (qif-import:setup-stock-hash hash-table)
|
||||
(let ((newhash (make-hash-table 20))
|
||||
(names '()))
|
||||
@ -482,6 +486,11 @@
|
||||
(qif-map-entry:allowed-types (cdr elt)))))
|
||||
(let* ((name (qif-map-entry:qif-name (cdr elt)))
|
||||
(stock-name (qif-import:get-account-name name)))
|
||||
(if (not stock-name)
|
||||
(begin
|
||||
(display "stock-name #f.. name ==")
|
||||
(display name)(newline)))
|
||||
|
||||
(if (not (hash-ref newhash stock-name))
|
||||
(begin
|
||||
(set! names (cons stock-name names))
|
||||
@ -491,7 +500,7 @@
|
||||
GNC_COMMODITY_NS_NYSE
|
||||
stock-name
|
||||
""
|
||||
1000)))))))
|
||||
100000)))))))
|
||||
bin))
|
||||
(vector->list hash-table))
|
||||
(list newhash (sort names string<?))))
|
||||
|
@ -181,11 +181,12 @@
|
||||
(qif-xtn:set-splits! current-xtn
|
||||
(list default-split)))
|
||||
(if first-xtn
|
||||
(begin
|
||||
(let ((opening-balance-payee
|
||||
(qif-file:process-opening-balance-xtn
|
||||
self current-xtn qstate-type)))
|
||||
(if (not current-account-name)
|
||||
(set! current-account-name
|
||||
(qif-file:process-opening-balance-xtn
|
||||
self current-xtn qstate-type)))
|
||||
opening-balance-payee))
|
||||
(set! first-xtn #f)))
|
||||
|
||||
(if (and (eq? qstate-type 'type:invst)
|
||||
|
@ -9,6 +9,11 @@
|
||||
|
||||
(gnc:support "qif-import/qif-to-gnc.scm")
|
||||
|
||||
(define gnc:*default-denom* 100000)
|
||||
(define GNC-RND-ROUND 7)
|
||||
(define GNC-DENOM-REDUCE 32)
|
||||
(define GNC-DENOM-LCD 48)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; find-or-make-acct:
|
||||
;; given a colon-separated account path, return an Account* to
|
||||
@ -260,7 +265,7 @@
|
||||
gnc-acct-hash qif-acct-map qif-cat-map)
|
||||
(let ((splits (qif-xtn:splits qif-xtn))
|
||||
(gnc-near-split (gnc:split-create))
|
||||
(near-split-total 0.0)
|
||||
(near-split-total (gnc:numeric-zero))
|
||||
(near-acct-info #f)
|
||||
(near-acct-name #f)
|
||||
(near-acct #f)
|
||||
@ -270,7 +275,17 @@
|
||||
(qif-security (qif-xtn:security-name qif-xtn))
|
||||
(qif-memo (qif-split:memo (car (qif-xtn:splits qif-xtn))))
|
||||
(qif-from-acct (qif-xtn:from-acct qif-xtn))
|
||||
(qif-cleared (qif-xtn:cleared qif-xtn)))
|
||||
(qif-cleared (qif-xtn:cleared qif-xtn))
|
||||
(amt-cvt (lambda (n)
|
||||
(if n
|
||||
(gnc:double-to-gnc-numeric n gnc:*default-denom*
|
||||
GNC-RND-ROUND)
|
||||
(gnc:numeric-zero))))
|
||||
(n- (lambda (n) (gnc:numeric-neg n)))
|
||||
(nsub (lambda (a b) (gnc:numeric-sub a b 0 GNC-DENOM-LCD)))
|
||||
(n+ (lambda (a b) (gnc:numeric-add a b 0 GNC-DENOM-LCD)))
|
||||
(n* (lambda (a b) (gnc:numeric-mul a b 0 GNC-DENOM-REDUCE)))
|
||||
(n/ (lambda (a b) (gnc:numeric-div a b 0 GNC-DENOM-REDUCE))))
|
||||
|
||||
;; set properties of the whole transaction
|
||||
(apply gnc:transaction-set-date gnc-xtn (qif-xtn:date qif-xtn))
|
||||
@ -286,7 +301,7 @@
|
||||
(gnc:split-set-reconcile gnc-near-split #\c))
|
||||
(if (eq? qif-cleared 'reconciled)
|
||||
(gnc:split-set-reconcile gnc-near-split #\y))
|
||||
|
||||
|
||||
(if (not qif-security)
|
||||
(begin
|
||||
;; NON-STOCK TRANSACTIONS: the near account is the current
|
||||
@ -307,7 +322,7 @@
|
||||
(far-acct-name #f)
|
||||
(far-acct-type #f)
|
||||
(far-acct #f)
|
||||
(split-amt (qif-split:amount qif-split))
|
||||
(split-amt (amt-cvt (qif-split:amount qif-split)))
|
||||
(memo (qif-split:memo qif-split)))
|
||||
|
||||
(if (not split-amt) (set! split-amt 0.0))
|
||||
@ -315,9 +330,11 @@
|
||||
;; fill the splits in (near first). This handles
|
||||
;; files in multiple currencies by pulling the
|
||||
;; currency value from the file import.
|
||||
(set! near-split-total (+ near-split-total split-amt))
|
||||
(gnc:split-set-value gnc-far-split (- split-amt))
|
||||
|
||||
(set! near-split-total (n+ near-split-total split-amt))
|
||||
(gnc:split-set-value gnc-far-split (n- split-amt))
|
||||
(gnc:split-set-share-amount gnc-far-split
|
||||
(n- split-amt))
|
||||
|
||||
(if memo (gnc:split-set-memo gnc-far-split memo))
|
||||
|
||||
(if (qif-split:category-is-account? qif-split)
|
||||
@ -338,12 +355,13 @@
|
||||
(gnc:split-set-reconcile gnc-far-split #\y)))
|
||||
|
||||
;; finally, plug the split into the account
|
||||
(gnc:transaction-append-split gnc-xtn gnc-far-split)
|
||||
(gnc:account-insert-split far-acct gnc-far-split))))
|
||||
(gnc:account-insert-split far-acct gnc-far-split)
|
||||
(gnc:transaction-append-split gnc-xtn gnc-far-split))))
|
||||
splits)
|
||||
|
||||
;; the value of the near split is the total of the far splits.
|
||||
(gnc:split-set-value gnc-near-split near-split-total)
|
||||
(gnc:split-set-share-amount gnc-near-split near-split-total)
|
||||
(gnc:transaction-append-split gnc-xtn gnc-near-split)
|
||||
(gnc:account-insert-split near-acct gnc-near-split))
|
||||
|
||||
@ -351,9 +369,10 @@
|
||||
;; "action" encoded in the Number field. It's generally the
|
||||
;; security account (for buys, sells, and reinvests) but can
|
||||
;; also be an interest, dividend, or SG/LG account.
|
||||
(let ((share-price (qif-xtn:share-price qif-xtn))
|
||||
(num-shares (qif-xtn:num-shares qif-xtn))
|
||||
(split-amt (qif-split:amount (car (qif-xtn:splits qif-xtn))))
|
||||
(let ((share-price (amt-cvt (qif-xtn:share-price qif-xtn)))
|
||||
(num-shares (amt-cvt (qif-xtn:num-shares qif-xtn)))
|
||||
(split-amt (amt-cvt
|
||||
(qif-split:amount (car (qif-xtn:splits qif-xtn)))))
|
||||
(qif-accts #f)
|
||||
(qif-near-acct #f)
|
||||
(qif-far-acct #f)
|
||||
@ -362,15 +381,19 @@
|
||||
(far-acct-name #f)
|
||||
(far-acct #f)
|
||||
(commission-acct #f)
|
||||
(commission-amt (qif-xtn:commission qif-xtn))
|
||||
(commission-amt (amt-cvt (qif-xtn:commission qif-xtn)))
|
||||
(commission-split #f)
|
||||
(defer-share-price #f)
|
||||
(gnc-far-split (gnc:split-create)))
|
||||
|
||||
(if (not num-shares) (set! num-shares 0.0))
|
||||
(if (not share-price) (set! share-price 0.0))
|
||||
(if (not split-amt) (set! split-amt (* num-shares share-price)))
|
||||
(if (not num-shares) (set! num-shares (gnc:numeric-zero)))
|
||||
(if (not share-price) (set! share-price (gnc:numeric-zero)))
|
||||
(if (not split-amt) (set! split-amt (n* num-shares share-price)))
|
||||
|
||||
;; it appears that the QIF total line contains the commission.
|
||||
(if commission-amt
|
||||
(set! split-amt (nsub split-amt commission-amt)))
|
||||
|
||||
;; I don't think this should ever happen, but I want
|
||||
;; to keep this check just in case.
|
||||
(if (> (length splits) 1)
|
||||
@ -405,79 +428,69 @@
|
||||
;; are amounts currency or shares?
|
||||
(case qif-action
|
||||
((buy buyx reinvint reinvdiv reinvsg reinvsh reinvlg)
|
||||
(if (not share-price) (set! share-price 0.0))
|
||||
(gnc:split-set-share-price gnc-near-split share-price)
|
||||
(gnc:split-set-share-price gnc-far-split share-price)
|
||||
(if (not share-price) (set! share-price (gnc:numeric-zero)))
|
||||
(gnc:split-set-share-amount gnc-near-split num-shares)
|
||||
(gnc:split-set-share-amount gnc-far-split (- num-shares))
|
||||
(gnc:split-set-share-amount gnc-far-split (n- num-shares))
|
||||
(gnc:split-set-value gnc-near-split split-amt)
|
||||
(gnc:split-set-value gnc-far-split (- split-amt)))
|
||||
(gnc:split-set-value gnc-far-split (n- split-amt)))
|
||||
|
||||
((sell sellx)
|
||||
(if (not share-price) (set! share-price 0.0))
|
||||
(gnc:split-set-share-price gnc-near-split share-price)
|
||||
(gnc:split-set-share-price gnc-far-split share-price)
|
||||
(gnc:split-set-share-amount gnc-near-split (- num-shares))
|
||||
(if (not share-price) (set! share-price (gnc:numeric-zero)))
|
||||
(gnc:split-set-share-amount gnc-near-split (n- num-shares))
|
||||
(gnc:split-set-share-amount gnc-far-split num-shares)
|
||||
(gnc:split-set-value gnc-near-split (- split-amt))
|
||||
(gnc:split-set-value gnc-near-split (n- split-amt))
|
||||
(gnc:split-set-value gnc-far-split split-amt))
|
||||
|
||||
((cgshort cgshortx cglong cglongx intinc intincx div divx
|
||||
miscinc miscincx xin)
|
||||
(gnc:split-set-value gnc-near-split split-amt)
|
||||
(gnc:split-set-value gnc-far-split (- split-amt)))
|
||||
(gnc:split-set-value gnc-far-split (n- split-amt))
|
||||
(gnc:split-set-share-amount gnc-near-split split-amt)
|
||||
(gnc:split-set-share-amount gnc-far-split (n- split-amt)))
|
||||
|
||||
((xout miscexp miscexpx )
|
||||
(gnc:split-set-value gnc-near-split (- split-amt))
|
||||
(gnc:split-set-value gnc-far-split split-amt))
|
||||
((xout miscexp miscexpx)
|
||||
(gnc:split-set-value gnc-near-split (n- split-amt))
|
||||
(gnc:split-set-value gnc-far-split split-amt)
|
||||
(gnc:split-set-share-amount gnc-near-split (n- split-amt))
|
||||
(gnc:split-set-share-amount gnc-far-split split-amt))
|
||||
|
||||
((shrsin)
|
||||
;; for shrsin, the near account is the security account.
|
||||
;; we'll need to set the share-price after a little
|
||||
;; trickery post-adding-to-account
|
||||
(if (not share-price)
|
||||
(set! defer-share-price #t)
|
||||
(gnc:split-set-share-price gnc-near-split share-price))
|
||||
(gnc:split-set-share-amount gnc-near-split num-shares)
|
||||
(gnc:split-set-value gnc-far-split num-shares))
|
||||
|
||||
|
||||
((shrsout)
|
||||
;; shrsout is like shrsin
|
||||
(if (not share-price)
|
||||
(set! defer-share-price #t)
|
||||
(gnc:split-set-share-price gnc-near-split share-price))
|
||||
(gnc:split-set-share-amount gnc-near-split (- num-shares))
|
||||
(gnc:split-set-value gnc-far-split (- num-shares)))
|
||||
(gnc:split-set-share-amount gnc-near-split (n- num-shares))
|
||||
(gnc:split-set-value gnc-far-split (n- num-shares)))
|
||||
|
||||
;; stock splits: QIF just specifies the split ratio, not
|
||||
;; the number of shares in and out, so we have to fetch
|
||||
;; the number of shares from the security account
|
||||
|
||||
|
||||
;; FIXME : this could be wrong. Make sure the
|
||||
;; share-amount is at the correct time.
|
||||
((stksplit)
|
||||
(let* ((splitratio (/ num-shares 10))
|
||||
(let* ((splitratio (n/ num-shares (gnc:numeric-create 10 1)))
|
||||
(in-shares
|
||||
(gnc:account-get-share-balance near-acct))
|
||||
(out-shares (* in-shares splitratio)))
|
||||
(if (not share-price) (set! share-price 0.0))
|
||||
(gnc:split-set-share-price gnc-near-split
|
||||
(/ share-price splitratio))
|
||||
(gnc:split-set-share-price gnc-far-split share-price)
|
||||
(out-shares (n* in-shares splitratio)))
|
||||
(gnc:split-set-share-amount gnc-near-split out-shares)
|
||||
(gnc:split-set-share-amount gnc-far-split (- in-shares))
|
||||
(gnc:split-set-value gnc-near-split (- split-amt))
|
||||
(gnc:split-set-share-amount gnc-far-split (n- in-shares))
|
||||
(gnc:split-set-value gnc-near-split (n- split-amt))
|
||||
(gnc:split-set-value gnc-far-split split-amt)))
|
||||
(else
|
||||
(display "symbol = " ) (write qif-action) (newline)))
|
||||
|
||||
|
||||
(let ((cleared (qif-split:matching-cleared
|
||||
(car (qif-xtn:splits qif-xtn)))))
|
||||
(if (eq? 'cleared cleared)
|
||||
(gnc:split-set-reconcile gnc-far-split #\c))
|
||||
(if (eq? 'reconciled cleared)
|
||||
(gnc:split-set-reconcile gnc-far-split #\y)))
|
||||
|
||||
|
||||
(if qif-commission-acct
|
||||
(let* ((commission-acct-info
|
||||
(or (hash-ref qif-acct-map qif-commission-acct)
|
||||
@ -490,7 +503,8 @@
|
||||
(if (and commission-amt commission-acct)
|
||||
(begin
|
||||
(set! commission-split (gnc:split-create))
|
||||
(gnc:split-set-value commission-split commission-amt)))
|
||||
(gnc:split-set-value commission-split commission-amt)
|
||||
(gnc:split-set-share-amount commission-split commission-amt)))
|
||||
|
||||
(if (and qif-near-acct qif-far-acct)
|
||||
(begin
|
||||
@ -504,12 +518,7 @@
|
||||
(begin
|
||||
(gnc:transaction-append-split gnc-xtn commission-split)
|
||||
(gnc:account-insert-split commission-acct
|
||||
commission-split)))
|
||||
|
||||
;; now find the share price if we need to
|
||||
;; (shrsin and shrsout xtns)
|
||||
(if defer-share-price
|
||||
(qif-import:set-share-price gnc-near-split))))))
|
||||
commission-split)))))))
|
||||
;; return the modified transaction (though it's ignored).
|
||||
gnc-xtn))
|
||||
|
||||
@ -917,6 +926,6 @@
|
||||
(let ((ith-split (gnc:account-get-split account i)))
|
||||
(if (pointer-token-eq? ith-split split)
|
||||
(if last-split
|
||||
(gnc:split-set-share-price
|
||||
split (gnc:split-get-share-price last-split)))
|
||||
(d-gnc:split-set-share-price
|
||||
split (d-gnc:split-get-share-price last-split)))
|
||||
(if (< i numsplits) (loop (+ 1 i) ith-split)))))))
|
||||
|
@ -330,7 +330,7 @@
|
||||
(index 0))
|
||||
(if (>= index num-splits)
|
||||
total
|
||||
(loop (+ total (gnc:split-get-value (gnc:ith-split splits index)))
|
||||
(loop (+ total (d-gnc:split-get-value (gnc:ith-split splits index)))
|
||||
(+ index 1))))))
|
||||
|
||||
(define (gnc:split-list-balance splits)
|
||||
@ -338,8 +338,8 @@
|
||||
0
|
||||
(let ((first-split (gnc:ith-split splits 0)))
|
||||
(+ (gnc:split-list-total splits)
|
||||
(gnc:split-get-balance first-split)
|
||||
(- (gnc:split-get-value first-split))))))
|
||||
(d-gnc:split-get-balance first-split)
|
||||
(- (d-gnc:split-get-value first-split))))))
|
||||
|
||||
;; get transaction date from split - needs to be done indirectly
|
||||
;; as it's stored in the parent transaction
|
||||
@ -357,10 +357,10 @@
|
||||
;; get the account balance at the specified date. if include-children?
|
||||
;; is true, the balances of all children (not just direct children)
|
||||
;; are included in the calculation.
|
||||
(define (gnc:account-get-balance-at-date account date include-children?)
|
||||
(define (d-gnc:account-get-balance-at-date account date include-children?)
|
||||
(let ((children-balance
|
||||
(if include-children?
|
||||
(gnc:group-get-balance-at-date
|
||||
(d-gnc:group-get-balance-at-date
|
||||
(gnc:account-get-children account) date)
|
||||
0)))
|
||||
(let loop ((index 0)
|
||||
@ -371,7 +371,7 @@
|
||||
(if (gnc:timepair-lt date (gnc:split-get-transaction-date split))
|
||||
(+ children-balance balance)
|
||||
(loop (+ index 1)
|
||||
(gnc:split-get-balance split)
|
||||
(d-gnc:split-get-balance split)
|
||||
(gnc:account-get-split account (+ index 1))))))))
|
||||
|
||||
;; This works similar as above but returns a currency-collector,
|
||||
@ -393,17 +393,17 @@
|
||||
(balance-collector 'add (gnc:account-get-currency account)
|
||||
balance)
|
||||
(loop (+ index 1)
|
||||
(gnc:split-get-balance split)
|
||||
(d-gnc:split-get-balance split)
|
||||
(gnc:account-get-split account (+ index 1))))))
|
||||
balance-collector))
|
||||
|
||||
;; get the balance of a group of accounts at the specified date.
|
||||
;; all children are included in the calculation
|
||||
(define (gnc:group-get-balance-at-date group date)
|
||||
(define (d-gnc:group-get-balance-at-date group date)
|
||||
(apply +
|
||||
(gnc:group-map-accounts
|
||||
(lambda (account)
|
||||
(gnc:account-get-balance-at-date account date #t)) group)))
|
||||
(d-gnc:account-get-balance-at-date account date #t)) group)))
|
||||
|
||||
;; returns a currency-collector
|
||||
(define (gnc:group-get-curr-balance-at-date group date)
|
||||
@ -417,9 +417,9 @@
|
||||
;; get the change in balance from the 'from' date to the 'to' date.
|
||||
;; this isn't quite as efficient as it could be, but it's a whole lot
|
||||
;; simpler :)
|
||||
(define (gnc:account-get-balance-interval account from to include-children?)
|
||||
(- (gnc:account-get-balance-at-date account to include-children?)
|
||||
(gnc:account-get-balance-at-date account from include-children?)))
|
||||
(define (d-gnc:account-get-balance-interval account from to include-children?)
|
||||
(- (d-gnc:account-get-balance-at-date account to include-children?)
|
||||
(d-gnc:account-get-balance-at-date account from include-children?)))
|
||||
|
||||
;; the version which returns a currency-collector
|
||||
(define (gnc:account-get-curr-balance-interval
|
||||
@ -430,11 +430,11 @@
|
||||
account from include-children?) #f)
|
||||
this-collector))
|
||||
|
||||
(define (gnc:group-get-balance-interval group from to)
|
||||
(define (d-gnc:group-get-balance-interval group from to)
|
||||
(apply +
|
||||
(gnc:group-map-accounts
|
||||
(lambda (account)
|
||||
(gnc:account-get-balance-interval account from to #t)) group)))
|
||||
(d-gnc:account-get-balance-interval account from to #t)) group)))
|
||||
|
||||
;; the version which returns a currency-collector
|
||||
(define (gnc:group-get-curr-balance-interval group from to)
|
||||
|
@ -137,7 +137,7 @@
|
||||
'()
|
||||
(let ((acct (car accts))
|
||||
(rest (non-zero-at-date-accounts (cdr accts) date)))
|
||||
(if (< (gnc:account-get-balance-at-date acct date #t) 0.01)
|
||||
(if (< (d-gnc:account-get-balance-at-date acct date #t) 0.01)
|
||||
rest
|
||||
(cons acct rest)))))
|
||||
|
||||
@ -150,7 +150,7 @@
|
||||
;; do not include accounts which have a zero balance
|
||||
(define (acc-sum-table-row account date do-children?)
|
||||
(let
|
||||
((acc-bal (gnc:account-get-balance-at-date account date #t))
|
||||
((acc-bal (d-gnc:account-get-balance-at-date account date #t))
|
||||
(children (gnc:account-get-children account)))
|
||||
(list
|
||||
(if (and do-children? (> (gnc:group-get-num-accounts children) 0))
|
||||
@ -176,7 +176,7 @@
|
||||
;; all children are included in the calculation
|
||||
(define (account-total-at-date accnts date)
|
||||
(apply +
|
||||
(map (lambda (account) (gnc:account-get-balance-at-date account date #t)) accnts))
|
||||
(map (lambda (account) (d-gnc:account-get-balance-at-date account date #t)) accnts))
|
||||
)
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@
|
||||
|
||||
(define (update-balance split)
|
||||
(let* ((account (gnc:split-get-account split))
|
||||
(split-balance (gnc:split-get-balance split))
|
||||
(split-balance (d-gnc:split-get-balance split))
|
||||
(last-balance (hash-ref balances account)))
|
||||
(hash-set! balances account split-balance)
|
||||
(if last-balance
|
||||
|
@ -378,10 +378,10 @@
|
||||
children))
|
||||
|
||||
(account-balance (if balance-sheet?
|
||||
(gnc:account-get-balance-at-date
|
||||
(d-gnc:account-get-balance-at-date
|
||||
account
|
||||
to-value #f)
|
||||
(gnc:account-get-balance-interval
|
||||
(d-gnc:account-get-balance-interval
|
||||
account
|
||||
from-value
|
||||
to-value #f))))
|
||||
@ -416,8 +416,8 @@
|
||||
(balance (make-currency-collector))
|
||||
(rawbal
|
||||
(if balance-sheet?
|
||||
(gnc:account-get-balance-at-date account to-value #f)
|
||||
(gnc:account-get-balance-interval
|
||||
(d-gnc:account-get-balance-at-date account to-value #f)
|
||||
(d-gnc:account-get-balance-interval
|
||||
account
|
||||
from-value
|
||||
to-value #f))))
|
||||
|
@ -76,7 +76,7 @@
|
||||
;;; useful filter-pred's for a budget entry
|
||||
|
||||
(define (budget-filter-pred-debit split budget-line)
|
||||
(> (gnc:split-get-value split) 0))
|
||||
(> (d-gnc:split-get-value split) 0))
|
||||
|
||||
;; make-budget-entry:
|
||||
;; 1: description,
|
||||
@ -690,14 +690,14 @@
|
||||
((not line)
|
||||
(gnc:debug (list
|
||||
(gnc:account-get-full-name account)
|
||||
(gnc:split-get-value split)))))
|
||||
(d-gnc:split-get-value split)))))
|
||||
(cond
|
||||
(filter-pred
|
||||
(cond
|
||||
((filter-pred split line2)
|
||||
(set! acc (+ acc (gnc:split-get-value split))))))
|
||||
(set! acc (+ acc (d-gnc:split-get-value split))))))
|
||||
(else
|
||||
(set! acc (+ acc (gnc:split-get-value split))))))))))
|
||||
(set! acc (+ acc (d-gnc:split-get-value split))))))))))
|
||||
(budget-report-accumulate-actual! acc line2)))
|
||||
(loop (gnc:account-get-children account))))
|
||||
group)))))
|
||||
|
@ -47,9 +47,9 @@
|
||||
|
||||
(define (report-row account)
|
||||
(let ((last-split (gnc:account-get-last-split account)))
|
||||
(let ((shares (gnc:split-get-share-balance last-split))
|
||||
(price (gnc:split-get-share-price last-split))
|
||||
(balance (gnc:split-get-balance last-split))
|
||||
(let ((shares (d-gnc:split-get-share-balance last-split))
|
||||
(price (d-gnc:split-get-share-price last-split))
|
||||
(balance (d-gnc:split-get-balance last-split))
|
||||
(cost 0) ; fixme (gnc:split-get-cost-basis last-split)))
|
||||
(quantity-print-info
|
||||
(gnc:split-quantity-print-info last-split #f))
|
||||
|
@ -395,7 +395,7 @@
|
||||
|
||||
(account-balance (if (is-key-in-account-notes? tax-key
|
||||
account)
|
||||
(gnc:account-get-balance-interval
|
||||
(d-gnc:account-get-balance-interval
|
||||
account
|
||||
from-value
|
||||
to-value #f)
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
(define (gnc:split-get-sign-adjusted-value split)
|
||||
(let ((acc (gnc:split-get-account split))
|
||||
(unsigned-value (gnc:split-get-value split)))
|
||||
(unsigned-value (d-gnc:split-get-value split)))
|
||||
(gnc:debug "Adjusting value" unsigned-value (gnc:account-reverse-balance? acc))
|
||||
(if (gnc:account-reverse-balance? acc)
|
||||
(- unsigned-value)
|
||||
@ -26,7 +26,7 @@
|
||||
(gnc:get-current-group)
|
||||
acc-name
|
||||
separator))
|
||||
(unsigned-balance (gnc:account-get-balance-at-date
|
||||
(unsigned-balance (d-gnc:account-get-balance-at-date
|
||||
acc
|
||||
from-date
|
||||
#f))
|
||||
@ -162,7 +162,7 @@
|
||||
(make-report-spec
|
||||
(string-db 'lookup 'shares-string)
|
||||
(lambda (split)
|
||||
(gnc:split-get-share-amount split))
|
||||
(d-gnc:split-get-share-amount split))
|
||||
(lambda (num) (html-right-cell (html-string num)))
|
||||
+ ; total-proc
|
||||
#f ; subtotal-html-proc
|
||||
@ -178,7 +178,7 @@
|
||||
(make-report-spec
|
||||
(string-db 'lookup 'price-string)
|
||||
(lambda (split)
|
||||
(gnc:split-get-share-price split))
|
||||
(d-gnc:split-get-share-price split))
|
||||
(lambda (num) (html-right-cell (html-string num)))
|
||||
#f ; total-proc
|
||||
#f ; subtotal-html-proc
|
||||
|
@ -33,7 +33,7 @@
|
||||
;;
|
||||
;; (define-data-contents "split"
|
||||
;; ("memo" 'string gnc:split-get-memo gnc:split-set-memo)
|
||||
;; ("share-amount" 'number gnc:split-get-share-amount ...)
|
||||
;; ("share-amount" 'number d-gnc:split-get-share-amount ...)
|
||||
;; ...)
|
||||
;;
|
||||
;; and then autogenerate the input and output forms or something...
|
||||
@ -106,8 +106,8 @@
|
||||
(list 'reconcile-state (gnc:split-get-reconcile-state split))
|
||||
(list 'reconciled-date
|
||||
(engine-date->editable-date (gnc:split-get-reconciled-date split)))
|
||||
(list 'share-amount (gnc:split-get-share-amount split))
|
||||
(list 'share-price (gnc:split-get-share-price split))
|
||||
(list 'share-amount (d-gnc:split-get-share-amount split))
|
||||
(list 'share-price (d-gnc:split-get-share-price split))
|
||||
(list 'account
|
||||
(let ((xfer-account (gnc:split-get-account split))
|
||||
(xfer-account-id #f))
|
||||
|
Loading…
Reference in New Issue
Block a user