From cd329e19447f33dacdd158befe2ade5555d2b7b6 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Sun, 19 Mar 2000 23:46:52 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2092 57a11ea4-9604-0410-9ed3-97b8803252fd --- README.SuSE-6.3 | 11 +- src/scm/main.scm | 1 - src/scm/qif-import/qif-dialog-utils.scm | 40 +++--- src/scm/qif-import/qif-file.scm | 94 +++++++------ src/scm/qif-import/qif-import.scm | 3 + src/scm/qif-import/qif-objects.scm | 88 +++++++----- src/scm/qif-import/qif-parse.scm | 174 ++++++++++-------------- src/scm/qif-import/qif-to-gnc.scm | 84 ++++++++---- src/scm/qif-import/qif-utils.scm | 11 +- src/scm/report/budget-report.scm | 4 - 10 files changed, 277 insertions(+), 233 deletions(-) diff --git a/README.SuSE-6.3 b/README.SuSE-6.3 index 5835c80b75..b27f5a7e38 100644 --- a/README.SuSE-6.3 +++ b/README.SuSE-6.3 @@ -1,7 +1,7 @@ How to install gnucash-1.3.0 on SuSE-6.3 ======================================== (written 2000-01-07 by Peter Pointner ) -(changed for gnucash-1.3.0 2000-03-01 by Herbert Thoma (tma@iis.fhg.de)) +(changed for gnucash-1.3.x 2000-03-01 by Herbert Thoma (tma@iis.fhg.de)) Notes: @@ -13,6 +13,8 @@ Notes: - This is definitely for SuSE 6.3 (Intel). Earlier SuSE distributions lack some required packages. Later SuSE distributions didn't exist at the time of writing. + NOTE: You can install new packages to older versions of SuSE from + CD or ftp.suse.de or ftp.suse.com Let's go: @@ -22,7 +24,7 @@ Let's go: * Install the following packages: + from series d - eperl guile nana swig xmhtml xmhtmld + eperl guile nana swig xmhtml xmhtmld gettext and optionally autoconf automake libtool (You must install libtool if you have autoconf/automake @@ -33,6 +35,8 @@ Let's go: lesstiff lesstifd + from series gnm gnlibs gnlibsd + + from series gra + imlib imlibdev * Download slib from ftp://ftp.gnu.org/pub/gnu/jacal/slib2c7.zip @@ -58,3 +62,6 @@ Let's go: make gnome for gnome version (recommended) or make qt for qt/KDE version (pre alpha, may even not compile) su root -c "make install" + +* You may need to run GnuCash once as root, because guile needs to set up + some things for slib. \ No newline at end of file diff --git a/src/scm/main.scm b/src/scm/main.scm index 2ce8b69b7f..ad15652873 100644 --- a/src/scm/main.scm +++ b/src/scm/main.scm @@ -17,7 +17,6 @@ (gnc:depend "doc.scm") (gnc:depend "extensions.scm") (gnc:depend "text-export.scm") -; (gnc:depend "importqif.scm") (gnc:depend "report.scm") (gnc:depend "report/report-list.scm") diff --git a/src/scm/qif-import/qif-dialog-utils.scm b/src/scm/qif-import/qif-dialog-utils.scm index 18a811fd1f..af0c1b5cdc 100644 --- a/src/scm/qif-import/qif-dialog-utils.scm +++ b/src/scm/qif-import/qif-dialog-utils.scm @@ -21,6 +21,7 @@ (qif-acct:set-description! (list-ref old-map 5) new-descript)) (#t (list-set! old-map 5 new-descript))))) + ;; the account-display is a 3-columned list of accounts in the QIF ;; import dialog (the "Account" page of the notebook). Column 1 is @@ -31,7 +32,7 @@ (define (qif-dialog:make-account-display qif-files gnc-acct-info) (let ((acct-hash (make-hash-table 20)) (retval '())) - + ;; we want to make two passes here. The first pass picks the ;; explicit Account descriptions and implicit "this" description ;; out of each file. These are the best sources of info because @@ -40,7 +41,7 @@ ;; the transactions. Hopefully we'll have most of the accounts ;; already located by that point. Otherwise, we have to guess ;; them. - + ;; guess-acct returns a list that's ;; (qif-name gnc-name gnc-type new-acct?) ;; acct-hash hashes QIF account name to a list that's composed of @@ -60,7 +61,7 @@ gnc-acct-info) (list 0 acct))))) (qif-file:accounts file)) - + ;; then make an implicit account entry for the file (if (and (qif-file:account file) (qif-file:account-type file)) @@ -84,7 +85,7 @@ (length (qif-file:xtns file)) #f))))))) qif-files) - + ;; now make the second pass through the files, looking at the ;; transactions. Hopefully the accounts are all there already. ;; stock accounts can have both a category/account and another @@ -151,14 +152,14 @@ ;; sort by number of transactions with that account so the ;; most important are at the top -; (set! retval (sort-list retval -; (lambda (a b) -; (or -; (> (list-ref a 4) (list-ref b 4)) -; (and -; (eq? (list-ref a 4) (list-ref b 4)) -; (string (list-ref a 4) (list-ref b 4)) + (and + (eq? (list-ref a 4) (list-ref b 4)) + (string (list-ref a 4) (list-ref b 4)) -; (and -; (eq? (list-ref a 4) (list-ref b 4)) -; (string (list-ref a 4) (list-ref b 4)) + (and + (eq? (list-ref a 4) (list-ref b 4)) + (stringgnc acct mappings (gnc:depend "qif-to-gnc.scm") ;; conv QIF xtns/acct to GNC xtns/acct + + diff --git a/src/scm/qif-import/qif-objects.scm b/src/scm/qif-import/qif-objects.scm index fbff0613ed..b0c7651061 100644 --- a/src/scm/qif-import/qif-objects.scm +++ b/src/scm/qif-import/qif-objects.scm @@ -9,6 +9,7 @@ (gnc:support "qif-objects.scm") (gnc:depend "simple-obj.scm") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; qif-file class ;; radix-format : one of 'decimal 'comma or 'unspecified @@ -301,38 +302,51 @@ self)) (define (qif-xtn:reparse self qif-file) - ;; share price - (if (string? (qif-xtn:share-price self)) - (qif-xtn:set-share-price! - self - (qif-file:parse-value qif-file (qif-xtn:share-price self)))) + (let ((reparse-ok #t)) + ;; share price + (if (string? (qif-xtn:share-price self)) + (qif-xtn:set-share-price! + self + (qif-file:parse-value qif-file (qif-xtn:share-price self)))) + + ;; number of shares + (if (string? (qif-xtn:num-shares self)) + (qif-xtn:set-num-shares! + self + (qif-file:parse-value qif-file (qif-xtn:num-shares self)))) + + ;; adjustment + (if (string? (qif-xtn:adjustment self)) + (qif-xtn:set-adjustment! + self + (qif-file:parse-value qif-file (qif-xtn:adjustment self)))) + + (if (or (string? (qif-xtn:share-price self)) + (string? (qif-xtn:num-shares self)) + (string? (qif-xtn:adjustment self))) + (set! reparse-ok #f)) - ;; number of shares - (if (string? (qif-xtn:num-shares self)) - (qif-xtn:set-num-shares! - self - (qif-file:parse-value qif-file (qif-xtn:num-shares self)))) - - ;; adjustment - (if (string? (qif-xtn:adjustment self)) - (qif-xtn:set-adjustment! - self - (qif-file:parse-value qif-file (qif-xtn:adjustment self)))) - - ;; reparse the amount of each split - (for-each - (lambda (split) - (if (string? (qif-split:amount split)) - (qif-split:set-amount! - split - (qif-file:parse-value qif-file (qif-split:amount split))))) - (qif-xtn:splits self)) - - ;; reparse the date - (if (string? (qif-xtn:date self)) - (qif-xtn:set-date! self - (qif-file:parse-date qif-file - (qif-xtn:date self))))) + ;; reparse the amount of each split + (for-each + (lambda (split) + (if (string? (qif-split:amount split)) + (qif-split:set-amount! + split + (qif-file:parse-value qif-file (qif-split:amount split)))) + (if (string? (qif-split:amount split)) + (set! reparse-ok #f))) + + (qif-xtn:splits self)) + + ;; reparse the date + (if (string? (qif-xtn:date self)) + (qif-xtn:set-date! self + (qif-file:parse-date qif-file + (qif-xtn:date self)))) + (if (string? (qif-xtn:date self)) + (set! reparse-ok #f)) + + reparse-ok)) (define (qif-xtn:print self) (simple-obj-print self )) @@ -386,7 +400,11 @@ (define (qif-acct:reparse self file) (if (string? (qif-acct:limit self)) (qif-acct:set-limit! - self (qif-file:parse-value file (qif-acct:limit self))))) + self (qif-file:parse-value file (qif-acct:limit self)))) + (if (or (string? (qif-acct:limit self)) + (string? (qif-acct:type self))) + #f + #t)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -496,7 +514,11 @@ (if (string? (qif-cat:budget-amt self)) (qif-cat:set-budget-amt! - self (qif-file:parse-value file (qif-cat:budget-amt self))))) + self (qif-file:parse-value file (qif-cat:budget-amt self)))) + + (if (or (string? (qif-cat:tax-rate self)) + (string? (qif-cat:budget-amt self))) + #f #t)) (define (qif-file:add-xtn! self xtn) diff --git a/src/scm/qif-import/qif-parse.scm b/src/scm/qif-import/qif-parse.scm index 58ad855093..bd4505ccd0 100644 --- a/src/scm/qif-import/qif-parse.scm +++ b/src/scm/qif-import/qif-parse.scm @@ -126,7 +126,13 @@ GNC-ASSET-TYPE) ((string=? mangled-string "oth l") GNC-LIABILITY-TYPE) - (#t read-value)))) + ((string=? mangled-string "mutual") + GNC-MUTUAL-TYPE) + (#t + (display "qif-file:parse-acct-type : unhandled account type ") + (display read-value) + (display "... substituting Bank.") + GNC-BANK-TYPE)))) (define (qif-file:state-to-account-type self qstate) (cond ((eq? qstate 'type:bank) @@ -208,7 +214,7 @@ (set! numeric-date-parts (map (lambda (elt) (with-input-from-string elt - (lambda () (read)))) + (lambda () (read)))) date-parts)) (cond @@ -349,29 +355,53 @@ (string-remove-leading-space (string-remove-trailing-space str))) +(define decimal-radix-regexp + (make-regexp + "^-?[0-9]+$|^-?[0-9]?[0-9]?[0-9]?(,[0-9][0-9][0-9])*(\\.[0-9]*)?$")) + +(define comma-radix-regexp + (make-regexp + "^-?[0-9]+$|^-?[0-9]?[0-9]?[0-9]?(\\.[0-9][0-9][0-9])*(,[0-9]*)?$")) + +(define (value-is-decimal-radix? value) + (if (regexp-exec decimal-radix-regexp value) + #t #f)) + +(define (value-is-comma-radix? value) + (if (regexp-exec comma-radix-regexp value) + #t #f)) + + +(define (qif-file:parse-value/decimal self value-string) + (+ 0.0 + (with-input-from-string (string-remove-char value-string #\,) + (lambda () (read))))) + + +(define (qif-file:parse-value/comma self value-string) + (+ 0.0 + (with-input-from-string + (string-replace-char! (string-remove-char value-string #\.) + #\, #\.) + (lambda () (read))))) + (define (qif-file:parse-value self value-string) (if (or (not (string? value-string)) (not (> (string-length value-string) 0))) - (set! value-string "0")) + (set! value-string "0") + (set! value-string (string-remove-leading-space + (string-remove-trailing-space value-string)))) - (let ((comma-index (string-rindex value-string #\,)) - (decimal-index (string-rindex value-string #\.)) - (comma-count (string-char-count value-string #\,)) - (decimal-count (string-char-count value-string #\.))) - - ;; if we don't know the radix format, it might be appropriate to - ;; guess. guessed radix format doesn't affect parsing at all - ;; until you set the radix-format from the guessed-radix-format - ;; and call reparse-values on all the values. - + (let ((possibly-comma-radix? (value-is-comma-radix? value-string)) + (possibly-decimal-radix? (value-is-decimal-radix? value-string))) + (if (and (eq? (qif-file:radix-format self) 'unknown) (not (eq? (qif-file:guessed-radix-format self) 'inconsistent))) (cond ;; already think it's decimal ((eq? (qif-file:guessed-radix-format self) 'decimal) - (if (or (> decimal-count 1) - (and decimal-index comma-index - (> comma-index decimal-index))) + (if (and possibly-comma-radix? + (not possibly-decimal-radix?)) (begin (qif-file:set-guessed-radix-format! self 'inconsistent) (display "this QIF file has inconsistent radix notation!") @@ -379,9 +409,8 @@ ;; already think it's comma ((eq? (qif-file:guessed-radix-format self) 'comma) - (if (or (> comma-count 1) - (and decimal-index comma-index - (> decimal-index comma-index))) + (if (and possibly-decimal-radix? + (not possibly-comma-radix?)) (begin (qif-file:set-guessed-radix-format! self 'inconsistent) (display "this QIF file has inconsistent radix notation!") @@ -389,86 +418,29 @@ ;; don't know : look for numbers that are giveaways. ((eq? (qif-file:guessed-radix-format self) 'unknown) - ;; case 1: there's a decimal and a comma, and the - ;; decimal is to the right of the comma, and there's - ;; only one decimal : it's a decimal number. - (if (and decimal-index comma-index - (> decimal-index comma-index) - (eq? decimal-count 1)) - (qif-file:set-guessed-radix-format! self 'decimal)) - - ;; case 2: the opposite. - (if (and decimal-index comma-index - (> comma-index decimal-index) - (eq? comma-count 1)) - (qif-file:set-guessed-radix-format! self 'comma)) - - ;; case 3: there's no decimal and more than one comma: - ;; it's a decimal number. I wish I had more transactions - ;; like this! - (if (and (eq? decimal-count 0) - (> comma-count 1)) - (qif-file:set-guessed-radix-format! self 'decimal)) - - ;; case 4: the opposite (no comma, multiple decimals) - (if (and (eq? comma-count 0) - (> decimal-count 1)) - (qif-file:set-guessed-radix-format! self 'comma)) - - ;; case 5: one decimal, no commas, and not-3 digits - ;; after it --> decimal. - (if (and (eq? comma-count 0) - (eq? decimal-count 1) - (not (eq? (- (string-length value-string) - decimal-index) - 4))) - (qif-file:set-guessed-radix-format! self 'decimal)) - - ;; case 6: the opposite --> comma - (if (and (eq? comma-count 1) - (eq? decimal-count 0) - (not (eq? (- (string-length value-string) - comma-index) - 4))) - (begin - (display "hey!") (display comma-count) - (display comma-index) (display (string-length value-string)) - (newline) - (qif-file:set-guessed-radix-format! self 'comma)))))) - - (cond - ;; decimal radix (US format) - ;; number can't have more than one ., and the rightmost - ;; . must be to the right of the rightmost , - ;; , are ignored otherwise - ((eq? 'decimal (qif-file:radix-format self)) - (if (or (and decimal-count - (> decimal-count 1)) - (and decimal-index comma-index - (> comma-index decimal-index))) - (error "badly-formed decimal-radix number" value-string) - (+ 0.0 - (with-input-from-string (string-remove-char value-string #\,) - (lambda () (read)))))) - - ;; comma radix (German format) - ;; number can't have more than one , and the rightmost - ;; , must be to the right of the rightmost . - ;; . are ignored otherwise. Substitute . for , before - ;; parsing. - ((eq? 'comma (qif-file:radix-format self)) - (if (or (and comma-count - (> comma-count 1)) - (and decimal-index comma-index - (> decimal-index comma-index))) - (error "badly formed comma-radix number" value-string) - (+ 0.0 - (with-input-from-string (string-replace-char! - (string-remove-char value-string #\.) - #\, #\.) - (lambda () (read)))))) - - ;; unknown radix - store the string and we can process it - ;; later. - (#t + (cond ((and possibly-decimal-radix? + (not possibly-comma-radix?)) + (qif-file:set-guessed-radix-format! self 'decimal)) + ((and possibly-comma-radix? + (not possibly-decimal-radix?)) + (qif-file:set-guessed-radix-format! self 'comma)))))) + (cond + ((eq? (qif-file:radix-format self) 'decimal) + (if possibly-decimal-radix? + (qif-file:parse-value/decimal self value-string) + (begin + (display "Format is decimal-radix, but number is") + (write value-string) + (newline) + 0.0))) + ((eq? (qif-file:radix-format self) 'comma) + (if possibly-comma-radix? + (qif-file:parse-value/comma self value-string) + (begin + (display "Format is comma-radix, but number is") + (write value-string) + (newline) + 0.0))) + (#t value-string)))) + diff --git a/src/scm/qif-import/qif-to-gnc.scm b/src/scm/qif-import/qif-to-gnc.scm index 8fcc0462fc..86841c712d 100644 --- a/src/scm/qif-import/qif-to-gnc.scm +++ b/src/scm/qif-import/qif-to-gnc.scm @@ -207,7 +207,7 @@ (let ((gnc-xtn (gnc:transaction-create))) (gnc:transaction-init gnc-xtn) (gnc:transaction-begin-edit gnc-xtn 1) - + ;; destroy any automagic splits in the transaction (let ((numsplits (gnc:transaction-get-split-count gnc-xtn))) (if (not (eqv? 0 numsplits)) @@ -216,14 +216,14 @@ (gnc:transaction-get-split gnc-xtn ind)) (if (> ind 0) (loop (- ind 1)))))) - + ;; build the transaction (qif-import:qif-xtn-to-gnc-xtn xtn qif-file gnc-xtn gnc-acct-hash mapping-data) ;; rebalance and commit everything (gnc:transaction-commit-edit gnc-xtn))))) - + (qif-file:xtns qif-file))) sorted-qif-files-list) @@ -241,6 +241,8 @@ (define (qif-import:qif-xtn-to-gnc-xtn qif-xtn qif-file gnc-xtn gnc-acct-hash mapping-data) (let ((splits (qif-xtn:splits qif-xtn)) + (gnc-near-split (gnc:split-create)) + (near-split-total 0) (qif-cat-map (caddr mapping-data)) (qif-acct-map (cadr mapping-data)) (near-acct-info #f) @@ -257,19 +259,37 @@ ;; find the GNC account for the near end of the transaction ;; (all splits have the same near end) - (set! near-acct-info - (hash-ref qif-acct-map - (if (qif-xtn:bank-xtn? qif-xtn) - (qif-file:account qif-file) - (qif-xtn:security-name qif-xtn)))) - (set! near-acct-name (list-ref near-acct-info 1)) - (set! near-acct (hash-ref gnc-acct-hash near-acct-name)) + (if (qif-xtn:bank-xtn? qif-xtn) + (begin + (set! near-acct-info + (hash-ref qif-acct-map + (qif-file:account qif-file))) + (set! near-acct-name + (list-ref near-acct-info 1)) + (set! near-acct (hash-ref gnc-acct-hash near-acct-name))) + (begin + (set! near-acct-info + (hash-ref qif-acct-map + (qif-xtn:security-name qif-xtn))) + (set! near-acct-name + (list-ref near-acct-info 1)) + (set! near-acct (hash-ref gnc-acct-hash near-acct-name)))) + (if (qif-split:memo (car (qif-xtn:splits qif-xtn))) + (gnc:split-set-memo gnc-near-split + (qif-split:memo (car (qif-xtn:splits qif-xtn))))) + + (let ((cleared (qif-xtn:cleared qif-xtn))) + (cond ((eq? 'cleared cleared) + (gnc:split-set-reconcile gnc-near-split #\c)) + ((eq? 'reconciled cleared) + (gnc:split-set-reconcile gnc-near-split #\r)))) + + ;; iterate over QIF splits (for-each (lambda (qif-split) - (let ((gnc-near-split (gnc:split-create)) - (gnc-far-split (gnc:split-create)) + (let ((gnc-far-split (gnc:split-create)) (far-acct-info #f) (far-acct-name #f) (far-acct-type #f) @@ -281,19 +301,13 @@ ;; fill the splits in (near first). This handles files in ;; multiple currencies by pulling the currency value from the ;; file import. - (if split-amt - (begin - (gnc:split-set-base-value gnc-near-split - split-amt - currency) - (gnc:split-set-base-value gnc-far-split - (- split-amt) - currency)) - (error "No amount in split!" qif-split "txn:" qif-xtn)) + (set! near-split-total + (+ near-split-total split-amt)) + (gnc:split-set-base-value gnc-far-split + (- split-amt) currency) (if memo (begin - (gnc:split-set-memo gnc-near-split memo) (gnc:split-set-memo gnc-far-split memo))) ;; my guess is that you can't have Quicken splits @@ -304,15 +318,15 @@ (begin (display "qif-import:qif-xtn-to-gnc-xtn : ") (display "splits in stock transaction!") (newline))) - (let ((price (qif-xtn:share-price qif-xtn))) - (gnc:split-set-share-price gnc-near-split price) - (gnc:split-set-share-price gnc-far-split price))) + (let ((price (qif-xtn:share-price qif-xtn))) + (gnc:split-set-share-price gnc-near-split price) + (gnc:split-set-share-price gnc-far-split price))) (begin (gnc:split-set-share-price gnc-near-split 1.0) (gnc:split-set-share-price gnc-far-split 1.0))) (if (qif-xtn:num-shares qif-xtn) - (let ((numshares (qif-xtn:num-shares qif-xtn))) + (let ((numshares (qif-xtn:num-shares qif-xtn))) (if (> (length splits) 1) (begin (display "qif-import:qif-xtn-to-gnc-xtn : ") @@ -355,14 +369,24 @@ (list-ref far-acct-info 1)) (set! far-acct (hash-ref gnc-acct-hash far-acct-name)))) + ;; set the reconcile status + (let ((cleared (qif-xtn:cleared qif-xtn))) + (cond ((eq? 'cleared cleared) + (gnc:split-set-reconcile gnc-far-split #\c)) + ((eq? 'reconciled cleared) + (gnc:split-set-reconcile gnc-far-split #\r)))) + ;; finally, plug the splits into the accounts - (gnc:transaction-append-split gnc-xtn gnc-near-split) (gnc:transaction-append-split gnc-xtn gnc-far-split) - (gnc:account-insert-split near-acct gnc-near-split) - (gnc:account-insert-split far-acct gnc-far-split))) - + (gnc:account-insert-split far-acct gnc-far-split))) splits) + (gnc:split-set-base-value gnc-near-split + near-split-total + (qif-file:currency qif-file)) + (gnc:transaction-append-split gnc-xtn gnc-near-split) + (gnc:account-insert-split near-acct gnc-near-split) + ;; return the modified transaction (though it's ignored). gnc-xtn)) diff --git a/src/scm/qif-import/qif-utils.scm b/src/scm/qif-import/qif-utils.scm index d5a4a2e249..51d5eab31f 100644 --- a/src/scm/qif-import/qif-utils.scm +++ b/src/scm/qif-import/qif-utils.scm @@ -38,7 +38,10 @@ ""))) (define (string-remove-char str char) - (let ((rexpstr (make-string 1 char))) + (let ((rexpstr + (if (not (eq? char #\.)) + (make-string 1 char) + "\\."))) (regexp-substitute/global #f rexpstr str 'pre 'post))) (define (string-char-count str char) @@ -46,7 +49,10 @@ (string->list str)))) (define (string-replace-char! str old new) - (let ((rexpstr (make-string 1 old)) + (let ((rexpstr + (if (not (eq? old #\.)) + (make-string 1 old) + "\\.")) (newstr (make-string 1 new))) (regexp-substitute/global #f rexpstr str 'pre newstr 'post))) @@ -62,3 +68,4 @@ (loop first-char)) (set! parts (cons (substring str 0 last-char) parts)))) parts)) + diff --git a/src/scm/report/budget-report.scm b/src/scm/report/budget-report.scm index 8ccdeffcc0..e99d6ed26c 100644 --- a/src/scm/report/budget-report.scm +++ b/src/scm/report/budget-report.scm @@ -515,7 +515,3 @@ budget-list) (html-end-table) (html-end-document)))))) - - - -