From e7db3ef1b38d67d1b4c94b11787ab7258ea26535 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sun, 14 Apr 2013 17:40:12 -0700 Subject: [PATCH] docs: update NOTES.org backlog, remove items moved to trello --- NOTES.org | 1446 +++++++++++------------------------------------------ 1 file changed, 304 insertions(+), 1142 deletions(-) diff --git a/NOTES.org b/NOTES.org index 150a40e35..f7b33c517 100644 --- a/NOTES.org +++ b/NOTES.org @@ -2120,388 +2120,7 @@ move *FromOpts into toOpts *** 6/30 announce, notes *** 7/1 notes -* backlog -** Archive :ARCHIVE: -*** DONE 98: build issue due to missing template files - CLOSED: [2013-01-24 Thu 09:30] - :PROPERTIES: - :ARCHIVE_TIME: 2013-01-24 Thu 09:30 - :END: -**** test fix -**** publish patch -**** close issue -**** improve clean build testing, possibly with cabal-dev -*** DONE fix/explain build errors - CLOSED: [2013-02-08 Fri 09:05] - :PROPERTIES: - :ARCHIVE_TIME: 2013-02-11 Mon 12:44 - :END: -*** DONE add: djp/sm enhancements - CLOSED: [2013-03-15 Fri 18:35] - :PROPERTIES: - :ARCHIVE_TIME: 2013-03-15 Fri 18:35 - :END: -**** DONE cleanups - CLOSED: [2013-02-25 Mon 16:38] -**** DONE 52 show added txn - CLOSED: [2013-02-25 Mon 16:38] -**** DONE 47 do-over - CLOSED: [2013-02-25 Mon 16:38] -**** DONE 96 command-line defaults - CLOSED: [2013-02-25 Mon 16:38] -**** DONE 45 allow comment/tag entry - CLOSED: [2013-02-25 Mon 16:38] -***** allow DESC ;COMMENT -***** allow AMOUNT ;COMMENT -**** DONE allow DATE CODE - CLOSED: [2013-02-25 Mon 16:38] -**** DONE confirm before adding txn - CLOSED: [2013-02-25 Mon 16:39] -**** DONE don't die after data entry if a partial date was provided on command line - CLOSED: [2013-03-04 Mon 18:09] - -**** DONE decide how to wind this up, complete/announce bounty - CLOSED: [2013-03-09 Sat 07:57] -**** DONE add to release notes - CLOSED: [2013-03-09 Sat 07:57] - -*** DONE update release notes - CLOSED: [2013-03-30 Sat 11:00] - :PROPERTIES: - :ARCHIVE_TIME: 2013-03-30 Sat 11:02 - :END: -*** DONE fix site tocs - CLOSED: [2013-03-30 Sat 11:11] - :PROPERTIES: - :ARCHIVE_TIME: 2013-03-30 Sat 11:11 - :END: -*** DONE split up docs - CLOSED: [2013-04-02 Tue 11:17] - :PROPERTIES: - :ARCHIVE_TIME: 2013-04-02 Tue 11:17 - :END: -*** DONE publish multiple doc versions - CLOSED: [2013-04-02 Tue 11:17] - :PROPERTIES: - :ARCHIVE_TIME: 2013-04-02 Tue 11:17 - :END: - -** TODO issue tracking/project hosting spring cleaning -*** TODO clarify wish tracking -*** TODO try trello boards -*** TODO clarify code hosting - github ? -*** clean up wrong/missing issue fields -**** component -**** type -*** prune/update field values -*** link useful tracker views -**** issues by type grid https://code.google.com/p/hledger/issues/list?q=&colspec=ID+Type+Status+Summary+Reporter+Opened+Stars&sort=&groupby=&mode=grid&y=Type&x=Status&cells=tiles&nobtn=Update -**** enhancements by component grid https://code.google.com/p/hledger/issues/list?can=2&q=type%3Aenhancement&colspec=ID+Type+Status+Summary+Reporter+Opened+Stars&sort=&groupby=&mode=grid&y=Component&x=Status&cells=tiles&nobtn=Update -**** enhancements by reporter grid https://code.google.com/p/hledger/issues/list?can=2&q=type%3Aenhancement&colspec=ID+Type+Status+Summary+Reporter+Opened+Stars&sort=&groupby=&mode=grid&y=Reporter&x=Status&cells=tiles&nobtn=Update -** TODO more powerful csv reading -*** DONE v2 rules file mockup showing new syntax - CLOSED: [2013-01-11 Fri 20:27] -*** DONE write down pseudo grammar - CLOSED: [2013-01-11 Fri 20:27] -*** DONE review status - CLOSED: [2013-01-11 Fri 20:47] -*** DONE parse basic directives & assignments - CLOSED: [2013-01-12 Sat 09:12] -*** DONE apply basic directives & assignments - CLOSED: [2013-01-13 Sun 11:01] -**** DONE directives - CLOSED: [2013-01-13 Sun 10:58] -**** DONE field assignments - CLOSED: [2013-01-13 Sun 10:58] -***** DONE code review - CLOSED: [2013-01-12 Sat 09:41] -***** DONE code cleanup - CLOSED: [2013-01-12 Sat 11:40] -****** DONE conform to new naming - CLOSED: [2013-01-12 Sat 11:40] -****** DONE clarify rules type - CLOSED: [2013-01-12 Sat 10:57] -****** DONE simplify - CLOSED: [2013-01-12 Sat 11:40] -******* DONE get it parsing test rules again - CLOSED: [2013-01-12 Sat 11:05] -******* DONE get it printing correct parsed value - CLOSED: [2013-01-12 Sat 11:05] -******* DONE cleanup - CLOSED: [2013-01-12 Sat 11:40] -***** DONE generate field values from templates - CLOSED: [2013-01-13 Sun 10:58] -****** DONE date-format & date - CLOSED: [2013-01-13 Sun 01:00] -****** DONE other fields - CLOSED: [2013-01-13 Sun 10:58] -*** DONE 1-based field numbering - CLOSED: [2013-01-13 Sun 11:01] -*** DONE conditional assignments - CLOSED: [2013-01-26 Sat 05:47] -**** DONE parsing - CLOSED: [2013-01-14 Mon 07:27] -***** DONE review doc - CLOSED: [2013-01-13 Sun 11:37] -***** DONE update grammar - CLOSED: [2013-01-13 Sun 11:39] -***** DONE multiple assignments - CLOSED: [2013-01-13 Sun 12:55] -***** DONE multiple patterns - CLOSED: [2013-01-13 Sun 13:36] -***** DONE clarify syntax - CLOSED: [2013-01-13 Sun 14:20] -***** DONE update grammar - CLOSED: [2013-01-14 Mon 07:13] -***** DONE clarify backwards compatibility - CLOSED: [2013-01-14 Mon 07:13] -***** DONE lighter conditional syntax (omit field name) - CLOSED: [2013-01-14 Mon 07:27] - -**** DONE functionality - CLOSED: [2013-01-26 Sat 05:47] -***** DONE clarify spec - CLOSED: [2013-01-14 Mon 09:33] -***** DONE implement - CLOSED: [2013-01-14 Mon 09:33] - -***** DONE test - CLOSED: [2013-01-26 Sat 05:47] -****** DONE fix speed - CLOSED: [2013-01-26 Sat 05:46] -******* DONE review/try regex libs - CLOSED: [2013-01-26 Sat 05:29] -******* DONE profile different variants - CLOSED: [2013-01-26 Sat 05:29] -******* DONE handle malformed regexps as well as before - CLOSED: [2013-01-26 Sat 05:46] -*** DONE fix warnings - CLOSED: [2013-01-26 Sat 15:03] -*** DONE field name list - CLOSED: [2013-01-26 Sat 15:03] -**** DONE implement assignment by field name list - CLOSED: [2013-01-26 Sat 14:58] -***** DONE add a date field assignment per its position - CLOSED: [2013-01-26 Sat 14:39] - -***** DONE refactor - CLOSED: [2013-01-26 Sat 14:51] -***** DONE add multiple fields without hard coding - CLOSED: [2013-01-26 Sat 14:58] -***** DONE add all the right fields - CLOSED: [2013-01-26 Sat 14:58] -*** DONE skip - CLOSED: [2013-01-26 Sat 15:38] -*** DONE set currency from csv - CLOSED: [2013-03-19 Tue 06:17] -*** DONE set amount sign based on another field's content (type=debit|credit) - CLOSED: [2013-01-26 Sat 16:57] -*** DONE set amount based on two fields (amount in, amount out) - CLOSED: [2013-03-19 Tue 06:17] - -*** DONE parse parenthesised amounts as negative - CLOSED: [2013-01-27 Sun 17:32] -*** DONE user friendliness - CLOSED: [2013-02-11 Mon 12:43] -**** DONE robust parsing - CLOSED: [2013-01-27 Sun 07:32] -**** DONE clear-ish errors - CLOSED: [2013-02-11 Mon 10:16] -***** DONE catalog errors - CLOSED: [2013-02-09 Sat 15:18] -***** DONE missing date/amount rule error - CLOSED: [2013-02-09 Sat 09:32] -***** DONE better amount parse errors - CLOSED: [2013-02-09 Sat 10:12] -****** DONE clean up csv parsing/validation - CLOSED: [2013-01-28 Mon 08:50] -****** DONE clean up rules parsing/validation - CLOSED: [2013-01-28 Mon 08:50] - -****** DONE no amount assignment - CLOSED: [2013-01-29 Tue 06:50] -****** DONE amount field unparseable - CLOSED: [2013-02-09 Sat 10:12] -****** DONE confusing amount parse error for header line - CLOSED: [2013-02-09 Sat 11:47] -hledgerdev: -Error, could not parse amount "" ((line 1, column 1): -unexpected end of input -expecting left-symbol amount, right-symbol amount or no-symbol amount) -in ["Date","Details","Debit","Credit","Balance"] - -rules: -# - -****** DONE could not parse amount in (data line) - CLOSED: [2013-02-09 Sat 11:48] -hledgerdev: Error, could not parse amount "" ((line 1, column 1): -unexpected end of input expecting left-symbol amount, right-symbol -amount or no-symbol amount) in ["07/12/2012","LODGMENT -529898","","10.0","131.21"] - -rules: -****** DONE poor error on empty amount csv field - CLOSED: [2013-02-09 Sat 14:03] -***** DONE better date parse errors - CLOSED: [2013-02-09 Sat 11:26] -****** DONE don't silently misparse d/m/y - CLOSED: [2013-02-09 Sat 13:34] -***** DONE why x rule triggering ? - CLOSED: [2013-02-09 Sat 17:28] -***** DONE unclear error when conditional block assignment has no field name - CLOSED: [2013-02-09 Sat 17:40] - -**** show what's happening -*** DONE fix parsing of %10 and fields: ...amount... as %1 in .wepay-in.csv.rules - CLOSED: [2013-03-14 Thu 16:19] -*** DONE interpolate by name - CLOSED: [2013-03-14 Thu 17:33] -*** DONE skip-lines -> skip - CLOSED: [2013-03-14 Thu 17:36] -*** DONE amount-in/out - CLOSED: [2013-03-15 Fri 17:45] -*** DONE value-less skip - CLOSED: [2013-03-15 Fri 17:45] -*** DONE make if operator optional - CLOSED: [2013-03-19 Tue 06:47] -*** DONE docs - CLOSED: [2013-03-29 Fri 15:20] -**** DONE reorganize file format docs - CLOSED: [2013-02-11 Mon 12:45] -**** DONE review/record writing tips - CLOSED: [2013-03-14 Thu 16:28] -**** DONE csv introduction - CLOSED: [2013-03-14 Thu 17:54] -**** DONE convert to hakyll 4 - CLOSED: [2013-03-14 Thu 17:54] -**** DONE serve manual from hub - CLOSED: [2013-03-13 Wed 11:03] -**** DONE rewrite intro - CLOSED: [2013-03-17 Sun 16:15] -**** DONE rewrite rules reference - CLOSED: [2013-03-19 Tue 06:15] -**** DONE update manual - CLOSED: [2013-03-29 Fri 14:06] -**** DONE update grammar - CLOSED: [2013-03-29 Fri 14:37] -**** DONE clarify csv / journal entry / transaction terminology - CLOSED: [2013-03-19 Tue 06:15] -**** DONE clarify directives / assignments / rules terminology - CLOSED: [2013-03-29 Fri 15:16] -**** DONE clarify account directives - CLOSED: [2013-03-29 Fri 15:16] -**** DONE clarify optional syntax (:, if, fields) - CLOSED: [2013-03-29 Fri 15:16] -**** DONE clarify upgrade process - CLOSED: [2013-03-30 Sat 10:35] -**** TODO update/add examples - https://gist.github.com/simonmichael/5153401 bofi example - -***** no rules file example -***** rules file example -***** how to archive/import the journal data more permanently -*** DONE update default rules - CLOSED: [2013-03-29 Fri 15:19] -*** DONE testing - CLOSED: [2013-03-29 Fri 15:51] -**** DONE wells fargo checking - CLOSED: [2013-01-27 Sun 17:25] -**** DONE western federal - CLOSED: [2013-01-27 Sun 18:51] -**** DONE b of i - CLOSED: [2013-03-19 Tue 06:17] -**** DONE wepay - CLOSED: [2013-03-19 Tue 06:17] -**** DONE paypal - CLOSED: [2013-03-29 Fri 15:24] -**** DONE mint - CLOSED: [2013-03-29 Fri 15:39] -**** DONE ynab - CLOSED: [2013-03-29 Fri 15:46] -**** wescom -*** DONE commits - CLOSED: [2013-03-29 Fri 16:10] -*** TODO auto skip csv header lines -*** TODO use csv header as initial field name list -*** TODO skip (& other directives ?) in conditional blocks -*** TODO match on individual fields -*** TODO else -*** TODO don't automatically write rules files -*** TODO sign flipping aid: parse --AMT, -(AMT) as AMT ? -*** TODO interpolation enhancements -*** TODO entry templates -**ENTRY TEMPLATES** give most flexibility, defining the entire - journal entry at once. They look like a standard journal entry, but - with CSV field references instead of values, beginning with `%date` - on the first line. Eg, this builds an entry with an extra virtual - posting: - - %date %description - %account1 %amount - %account2 - (some special account) %amount - - -thai -expenses:food:dining - -desc~thai -account=expenses:food:dining - -desc~thai -[date] [description] - ; original-description: [2] - expenses:food:dining [amount] - [base-account] -*** TODO command-line rules -*** TODO smarter default rules -*** TODO generalise rules to non csv ? -** TODO fix tests -*** unit -*** func -** TODO use readFile' everywhere -*** clean up readFile situation -**** drop UTF8IOCompat ? -***** TODO research - -** TODO release -** advertise hledger-irr etc. better -** extra -> hledger-contrib ? -** my personal user wishlist -*** better csv reading -**** more powerful hints -***** rewrite account names -***** select one or both accounts, generate three or more postings, or generate full transactions -***** based on any field -***** set secondary date from date in description -**** simpler syntax -***** list-of-field-names -***** simplify redundant directives -****** currency -> default-commodity ? -**** better rules file handling -***** share hints among different files - include ? -***** literal --rules option -***** don't auto-create missing rules file -****** by default use (and log) simple default rules -****** on command, generate -******* guess fields from data -******* show all directives - -*** balance assertions -*** secure portable/remote access -*** better web ui -**** more speed -***** show page render time -***** profile -**** ability to reduce detail in sidebar -**** bootstrap styling -**** steady, quick evolution - -*** phone-based data entry -**** ixpenseit -**** ynab - +* old/dev/project backlog - see also trello ** errors *** add: should not accept . as an amount *** add: default amount adds one decimal place when journal contains no decimals 2d @@ -3325,589 +2944,6 @@ http://community.haskell.org/~ndm/downloads/paper-hoogle_overview-19_nov_2008.pd **** faster parsec alternative *** web: code/ui review/refactor **** convert all to HTF ? -** new features -*** add: more enhancements -**** display default after accepting it ? -***** try haskeline's defaults -**** use previous values as defaults after restart -**** stop after single txn if 2 or more args -**** be non-interactive if 5 or more args -**** use command-line args as inputs not just defaults -**** don't add space after tab-completing account -expenses:personal:health:personal care - -**** refactor -***** split into entry & append internally -***** get* -> input* -***** askFor -> input -***** expose entry & append in ui -**** don't offer record txn option in account N prompt if it's not balanced yet -**** rewrite a short description (trader) to the full description from the matched txn (trader joe's) ? -**** try wizards, vty-ui libs ? -**** would be nice to create the journal file only if a txn is actually recorded - -*** balance: --depth with --flat should show aggregate balances including the non-displayed deeper accounts -*** balance: try indenting amounts - $260.00 expenses - $260.00 rent -*** balancesheet, incomestatement, cashflow: real-world testing - -*** cli, web: consistent query language with grouping and nesting -ledger's query syntax: http://ledger-cli.org/3.0/doc/ledger.1.html -**** draft 1: - -Filter patterns restrict the postings/transactions that are displayed. -(They often reduce the amount of processing work hledger has to do, as well.) -A pattern is a string or regular expression, usually with a prefix specifying the type of match to do. -The supported prefixes are: - -acct:PAT match postings affecting accounts whose name matches PAT -otheracct:PAT match the other postings in transactions with an acct match (like ledger's --related) -anyacct:PAT match all postings in transactions with an acct match (union of acct and otheracct) -desc:PAT match postings whose description matches PAT -status:PAT match postings whose cleared status matches PAT -code:PAT match postings whose transaction code matches PAT -tag:PAT match postings with a metadata tag whose name matches PAT -tag:TAG=PAT match postings with a metadata tag named TAG whose value matches PAT -from:DATE match postings on or after DATE (like --begin) -to:DATE match postings before DATE (like --end) -in:PERIOD match postings during PERIOD (like --period) -(or ? -begin:DATE match postings on or after DATE (like --begin) -end:DATE match postings before DATE (like --end) -period:PERIOD match postings during PERIOD (like --period) -) - -Prefixes have a short form which is their first letter, except for tag and anyacct. - -Prefix-less patterns are treated like acct: patterns, except by the -register command which treats them as otheracct: . - -Patterns containing whitespace must be enclosed in quotes. - -Matches are always case-insensitive. - -Matches are always substring matches (except for TAG); to match exactly, -wrap the pattern in ^ and $. - -A posting's date, status, code, etc. is usually (but not always) that of -its containing transaction. - -Any of these may be further prefixed with not: for an inverse match. - -Filter patterns may be combined with AND, OR, and parentheses. OR is -assumed by default. -(previously: -When you specify multiple filter patterns, hledger generally selects the -items which match: - - any of the account patterns AND any of the description patterns - -The print command selects transactions which - - match any of the description patterns AND have any postings matching any - of the positive account patterns AND have no postings matching any of - the negative account patterns -) - -*** cli: --empty -> --show-zero-accounts, --show-empty-parents ? Make it default ? -*** cli: --no-elide -> --empty-parents ? Make it the default ? - $260.00 expenses - $260.00 rent -*** cli: --related -*** cli: -X/--show-in-commodity -cf http://bugs.ledger-cli.org/show_bug.cgi?id=538 -*** cli: accept multiple journal file options -*** cli: better control of output format/layout -**** register --format, generalise --format -**** --wide ? window width sensitive ? -**** more tidy/consistent layout from print -**** --output-layout=ledger|traditional -**** --output-format=text|html|pdf -*** cli: inacct: on command line -hledger -f demo.journal reg inacct:expenses:food:pets date:2010/8/25 -2010/08/25 catfood expenses:food:pets $10.00 $10.00 - assets:cash $-10.00 0 - -*** cli: better error message for malformed dates -$ 2012 bal -e 'home care' -hledger: could not parse end date: (line 1, column 1): -unexpected "h" -expecting digit, "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december", "jan", "feb", "mar", "apr", "jun", "jul", "aug", "sep", "oct", "nov", "dec", "today", "yesterday", "tomorrow", "last", "this" or "next" (run with --help for usage) - -*** docs: --help-web and web ui help links that go to online help, with paragraph comments & chat -cf clients & profits interactive user guide, php.net, realworldhaskell etc. -*** docs: better intro, less wall-of-text, separate tutorial & reference sections -*** docs: easy hledger.org/topic help urls, like php.net - -*** formats: easier timelog formats -*** formats: better csv conversion -**** better default rules file -**** consistent multi-field formats allowed for any field -**** optionally generate single-entry txns -**** optionally set final amount blank -**** parse amounts like ($nnn.nn) -**** parse HH:MM[:SS] as an amount, converting to decimal hours -**** reuse add's history awareness -**** select one or both accounts based on csv fields -**** use default rules when converting stdin with no --rules -**** warn and ignore unparsed rows ? -*** formats: ofx protocol downloader -*** formats: IIF/quickbooks writer -*** formats: gnucash reader -*** formats: qif reader -**** clint's code -Date: Tue, 25 Oct 2011 11:46:24 -0400 -From: Clint Adams -To: hledger@googlegroups.com -Cc: thomas@marketpsychdata.com, jjenning@fastmail.fm -Subject: Re: QIF parsing -Message-ID: <20111025154624.GA3097@softwarefreedom.org> -References: <20111006164952.GA734@softwarefreedom.org> -MIME-Version: 1.0 -In-Reply-To: <20111006164952.GA734@softwarefreedom.org> -User-Agent: Mutt/1.5.21 (2010-09-15) -X-Original-Sender: clint@softwarefreedom.org -X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: - domain of clint@softwarefreedom.org designates 207.86.247.70 as permitted - sender) smtp.mail=clint@softwarefreedom.org -Reply-To: hledger@googlegroups.com -Precedence: list -Mailing-list: list hledger@googlegroups.com; contact hledger+owners@googlegroups.com -List-ID: -X-Google-Group-Id: 895107692464 -List-Post: , -List-Help: , -List-Archive: -Sender: hledger@googlegroups.com -List-Subscribe: , -List-Unsubscribe: , -Content-Type: text/plain; charset=iso-8859-1 -Content-Disposition: inline -Content-Transfer-Encoding: 8bit -X-Truedomain-Domain: googlegroups.com -X-Truedomain-SPF: Neutral (mx4: 173.255.219.222 is neither permitted nor denied by domain of googlegroups.com) -X-Truedomain-DKIM: Pass -X-Truedomain-ID: 16FADD416626EE6BDC6CCBB61A94EA31 -X-Truedomain: Neutral - -I had to update my QIF converter for modern hledger; included below. - -Thomas, I didn't see your reply because I'm not subscribed to -this Google Group. I believe that QuickBooks uses OFX, not QIF, -so you'd be more interested in - -http://groups.google.com/group/hledger/browse_thread/thread/e03ccc655347ba72 - -or - -http://www.dingoskidneys.com/~jaredj/ - -------8<------- - -import Text.Parsec -import Text.Parsec.String - -import Control.Monad.State as State - -import System (getArgs) -import Data.List (groupBy) -import Data.Maybe (fromMaybe) -import qualified Data.Map as Map -import Text.Printf (printf) - -import Hledger.Cli.Format (FormatString (FormatField), Field (FieldNo)) -import Hledger.Cli.Convert - -qifFile :: GenParser Char st (String,[[TransactionDetail]]) -qifFile = do - skipMany newline - dtype <- typeHeader - newline - trans <- endBy1 transaction recordSep - return $ (dtype,trans) - -typeHeader :: GenParser Char st String -typeHeader = do - string "!Type:" - dataType - -dataType :: GenParser Char st String -dataType = do string "Cash" - <|> string "Bank" - <|> string "CCard" - <|> string "Invst" - <|> string "Oth A" - <|> string "Oth L" - <|> string "Invoice" - -transaction :: GenParser Char st [TransactionDetail] - -*** parsing: accept all real-world ledger files -As far as I know it currently accepts all ledger 2.6-era files. -Add support for ledger 3 file format as/when that stabilises. -It would be nice to optionally semi/automatically submit parse error reports when they happen -**** things to ignore -***** https://gist.github.com/adamgibbins/278e8b1db58a809da1b3 -***** https://gist.github.com/adamgibbins/08f8c8adb7f74c16c508 -***** https://gist.github.com/adamgibbins/62f10122eea1442a7e9e -*** parsing: alias directives should be modified by account directives -*** parsing: allow price record for null commodity, eg with quotes -P 2009/1/1 "" 0.5h -and why doesn't this work ? time.journal: -P 2010/9/27 h 1 -$ hledger -f time.journal bal -p aug -B - 1 - 17.75h work:jobs - 1 - 17.50h clearview - 1 60 clear glass thermal data - 0.25h admin:cheque issue - 12.75h backups/hosting - 2.00h cleanup - 1.00h move plan - 2.25h move prep - 4.00h testing - 3.50h speed - 1.50h barbara spellcheck issue - 0.50h installation report dates - 0.25h plan change issue - 1.00h planning/discussion - 0.50h speed issue - 0.25h tina quote low-e layout - 0.50h tina title 24 issue - 0.25h kcrw:admin:contract update:unbilled --------------------- - 1 - 17.75h - -*** parsing: better date tag syntax errors -*** parsing: canonicalise account names to be case-insensitive ? -*** parsing: end directive may also be spelled end account; or end ends last directive -*** parsing: enforce positive price amounts, like ledger -eg 1€ @@ $-2 is not allowed -*** parsing: ignore/support all ledger assert directives ? - ; Assertion directives Options - ; These can occur in many places: - ; - ; ; Within an automated transaction, the assert is evaluated every time - ; ; a posting is matched, with the expression context set to the - ; ; matched posting. - ; = /Food/ - ; assert account("Expenses:Food").total >= $100 - ; 2010-06-12 Sample - ; Expenses:Food $100 - ; Assets:Checking - ; - ; ; At file scope, the expression is evaluated within "global" scope. - ; assert account("Expenses:Food").total == $100 - ; - ; ; At the top of a transction, the assertion's scope is the - ; ; transaction. After a posting, the scope is that posting. Note - ; ; however that account totals are only adjusted after successful - ; ; parsing of a transaction, which means that all the assertions below - ; ; are true, even though it appears as though the first posting should - ; ; affect the total immediately, which is not the case. - ; 2010-06-12 Sample 2 - ; assert account("Expenses:Food").total == $100 - ; Expenses:Food $50 - ; assert account("Expenses:Food").total == $100 - ; Assets:Checking - ; assert account("Expenses:Food").total == $100 - -*** parsing: more date syntax ? last nov, next friday, optional this, week of -*** parsing: more flexible file including -currently only journals (not timelog files) can include, and only another journal -*** parsing: more period syntax ? every N days, biweekly -*** parsing: parse YNAB export -$ tail -n +2 YNAB/Exports/personal-Register.csv | hledger -f- print --rules-file YNAB/Exports/personal-Register.rules -using conversion rules file /Users/simon/personal/YNAB/Exports/personal-Register.rules -hledger: using amount-in-field and amount-out-field, found a value in both fiel -ds: ("$0.00","$4.68") -*** parsing: per-posting effective/actual dates -*** parsing: period expressions should allow interval at the end -eg support -p 'from 1/1 to 2/1 weekly' - -*** parsing: safety check that effective date > actual (to catch eg 2009/12/30=1/4) -*** parsing: support apostrophe digit group separator - -*** print: shouldn't support -M and --depth ? - -*** queries: tag value queries -*** register: for the love of god, show full descriptions - -*** web: api -*** web: auto-complete accounts & amount as well as description -*** web: auto-complete from substrings, not just prefixes -*** web: balance chart should end at query end date not last txn date -*** web: better web ui/gui -*** web: completes one account name component in add form account fields -*** web: how to find out net worth, /register?q=assets+liabilities shows nothing -*** web: how to find out total spent in an account during a specific month -*** web: in-place editing -**** http://stackoverflow.com/questions/640971/setfocus-to-textbox-from-javascript-after-just-creating-the-textbox-with-javascr -*** web: lose io-storage -*** web: should display virtual postings with () or [] -*** web: should take port from base-url when appropriate -*** web: update/remove browser startup -*** web: wai-handler-webkit, wai-handler-launch - - -*** account types & metadata -; chart of accounts -; defines allowed account names, hierarchy, default sort order, -; and some metadata (account numbers, cf http://www.netmba.com/accounting/fin/accounts/chart/) -ACCOUNTS - assets ; :number: 1000 - cash ; :number: 1010 - HT7 ; :number: 1011 - jan ; :number: 1011.01 - feb ; :number: 1011.02 - mar ; :number: 1011.03 - RSG ; :number: 1012 - jan ; :number: 1012.01 - feb ; :number: 1012.02 - mar ; :number: 1012.03 - bank ; :number: 1020 - HT7 ; :number: 1021 - RSG ; :number: 1022 - reserve ; :number: 1023 - liabilities ; :number: 2000 - accounts payable ; :number: 2010 - BSG/GI/RSG ; :number: 2011 - equity ; :number: 3000 - opening balances ; :number: 3010 - income ; :number: 4000 - HT7 ; :number: 4010 - RSG ; :number: 4020 - expenses ; :number: 6000 - rent ; :number: 6010 - -or: http://furius.ca/beancount/examples/demo.ledger - -*** anonymisation -**** payees -**** account names -**** amounts -**** dates - -*** balance setting -ledger: You can accomplish "setting to the bank's view" with a transaction like this: - -2011-08-12 Sample - Assets:Checking = $200.00 - Equity:Adjustments - -This tells Ledger (Git/3.0) that your checking account's balance must be $200 -after this transaction is completed. It will put whatever amounts are -required to accomplish this into the Equity:Adjustments account. - -what about balance assertions ? - -*** clear, documented interfaces -*** client-side ui -*** debug logging -*** detect .hs plugins -*** don't recompile between autotest & functest -*** Double -> Decimal -*** query by commodity -*** generalise rules file ? -**** make it applicable to all formats ? -**** absorb its directives into journal format ? -*** i18n -*** journalAddTransaction should check txn balances -*** make generatejournal.hs script a sub-command -*** measure bug open times -http://code.google.com/p/support/wiki/IssueTrackerAPI -http://code.google.com/p/support/wiki/IssueTrackerAPIReference -*** more powerful storage layer -**** Clint's filestore_proof_of_concept.dpatch - -New patches: - -[filestore-proof-of-concept -Clint Adams **20110901172739 - Ignore-this: 1991477c2b70d276665c52478dc54d3d - - This is a somewhat broken replacement of the traditional file - storage with a forced darcs repo. It assumes that the - darcs repo already exists since Data.FileStore refuses to - initialize a repository in an extant directory. It does not - handle any error conditions well. -] hunk ./hledger-lib/Hledger/Read.hs 104 - when (not exists) $ do - hPrintf stderr "No journal file \"%s\", creating it.\n" f - hPrintf stderr "Edit this file or use \"hledger add\" or \"hledger web\" to add transactions.\n" -- emptyJournal >>= writeFile f -+ emptyJournal >>= writeFileWithBackup f - - -- | Give the content for a new auto-created journal file. - emptyJournal :: IO String -hunk ./hledger-lib/Hledger/Utils.hs 40 - import Text.ParserCombinators.Parsec - import Text.Printf - import Text.RegexPR -+import System.FilePath (takeFileName, takeDirectory) -+import qualified Data.FileStore.Types as DFT -+import qualified Data.FileStore.Generic as DFG -+import Data.FileStore.Darcs (darcsFileStore) - -- import qualified Data.Map as Map - -- - -- import Prelude hiding (readFile,writeFile,getContents,putStr,putStrLn) -hunk ./hledger-lib/Hledger/Utils.hs 432 - -- | Apply a function the specified number of times. Possibly uses O(n) stack ? - applyN :: Int -> (a -> a) -> a -> a - applyN n f = (!! n) . iterate f -+ -+-- Store file in VCS; Data.FileStore takes care of only committing -+-- when necessary. -+ -+filestoreSave :: FilePath -> String -> IO () -+filestoreSave f t = DFT.save assumedRepo assumedFilename assumedAuthor logMessage t -+ where -+ assumedRepo = darcsFileStore (takeDirectory f) -+ assumedFilename = takeFileName f -+ assumedAuthor = (DFT.Author "Hledger Role" "hledger@fake") -+ logMessage = "Some kind of change committed by some part of the hledger suite" -+ -+writeFileWithBackup :: FilePath -> String -> IO () -+writeFileWithBackup = filestoreSave -+ -+-- modify existing file in filestore -+filestoreModify :: FilePath -> DFT.RevisionId -> String -> IO (Either DFT.MergeInfo ()) -+filestoreModify f lr t = DFG.modify assumedRepo assumedFilename lr assumedAuthor logMessage t -+ where -+ assumedRepo = darcsFileStore (takeDirectory f) -+ assumedFilename = takeFileName f -+ assumedAuthor = (DFT.Author "Hledger Role" "hledger@fake") -+ logMessage = "Some kind of change committed by some part of the hledger suite" -+ -+filestoreAppend :: FilePath -> String -> IO () -+filestoreAppend f t = do -+ lastrev <- DFT.latest assumedRepo assumedFilename -+ oldcontents <- DFT.retrieve assumedRepo assumedFilename (Just lastrev) -+ result <- filestoreModify f lastrev (oldcontents ++ "\n\n" ++ t) -+ either (\x -> putStrLn "Help, the append didn't work and I am failing miserably.") (\x -> return ()) result -+ where -+ assumedRepo = darcsFileStore (takeDirectory f) -+ assumedFilename = takeFileName f -hunk ./hledger-lib/hledger-lib.cabal 60 - ,containers - ,directory - ,filepath -+ ,filestore - ,mtl - ,old-locale - ,old-time -hunk ./hledger/Hledger/Cli/Add.hs 31 - import qualified Data.Set as Set - - import Hledger --import Prelude hiding (putStr, putStrLn, appendFile) --import Hledger.Utils.UTF8 (putStr, putStrLn, appendFile) -+import Prelude hiding (putStr, putStrLn) -+import Hledger.Utils.UTF8 (putStr, putStrLn) - import Hledger.Cli.Options - import Hledger.Cli.Register (postingsReportAsText) - import Hledger.Cli.Utils -hunk ./hledger/Hledger/Cli/Add.hs 194 - journalAddTransaction :: Journal -> CliOpts -> Transaction -> IO Journal - journalAddTransaction j@Journal{jtxns=ts} opts t = do - let f = journalFilePath j -- appendToJournalFile f $ showTransaction t -+ filestoreAppend f $ showTransaction t - when (debug_ opts) $ do - putStrLn $ printf "\nAdded transaction to %s:" f - putStrLn =<< registerFromString (show t) -hunk ./hledger/Hledger/Cli/Add.hs 200 - return j{jtxns=ts++[t]} - ---- | Append data to a journal file; or if the file is "-", dump it to stdout. --appendToJournalFile :: FilePath -> String -> IO () --appendToJournalFile f s = -- if f == "-" -- then putStr $ sep ++ s -- else appendFile f $ sep++s -- where -- -- appendFile means we don't need file locking to be -- -- multi-user-safe, but also that we can't figure out the minimal -- -- number of newlines needed as separator -- sep = "\n\n" -- -- sep | null $ strip t = "" -- -- | otherwise = replicate (2 - min 2 (length lastnls)) '\n' -- -- where lastnls = takeWhile (=='\n') $ reverse t -- - -- | Convert a string of journal data into a register report. - registerFromString :: String -> IO String - registerFromString s = do -hunk ./hledger/Hledger/Cli/Utils.hs 18 - journalSpecifiedFileIsNewer, - fileModificationTime, - openBrowserOn, -- writeFileWithBackup, -- writeFileWithBackupIfChanged, - readFileStrictly, - Test(TestList), - ) -hunk ./hledger/Hledger/Cli/Utils.hs 25 - import Control.Exception - import Data.List - import Data.Maybe --import Safe (readMay) - import System.Console.CmdArgs -hunk ./hledger/Hledger/Cli/Utils.hs 26 --import System.Directory (getModificationTime, getDirectoryContents, copyFile) -+import System.Directory (getModificationTime) - import System.Exit -hunk ./hledger/Hledger/Cli/Utils.hs 28 --import System.FilePath ((), splitFileName, takeDirectory) - import System.Info (os) - import System.Process (readProcessWithExitCode) - import System.Time (ClockTime, getClockTime, diffClockTimes, TimeDiff(TimeDiff)) -hunk ./hledger/Hledger/Cli/Utils.hs 123 - -- what not. - -- ::ShellExecute(NULL, "open", "www.somepage.com", NULL, NULL, SW_SHOWNORMAL); - ---- | Back up this file with a (incrementing) numbered suffix then ---- overwrite it with this new text, or give an error, but only if the text ---- is different from the current file contents, and return a flag ---- indicating whether we did anything. --writeFileWithBackupIfChanged :: FilePath -> String -> IO Bool --writeFileWithBackupIfChanged f t = do -- s <- readFile f -- if t == s then return False -- else backUpFile f >> writeFile f t >> return True -- ---- | Back up this file with a (incrementing) numbered suffix, then ---- overwrite it with this new text, or give an error. --writeFileWithBackup :: FilePath -> String -> IO () --writeFileWithBackup f t = backUpFile f >> writeFile f t -- - readFileStrictly :: FilePath -> IO String - readFileStrictly f = readFile f >>= \s -> Control.Exception.evaluate (length s) >> return s -hunk ./hledger/Hledger/Cli/Utils.hs 125 -- ---- | Back up this file with a (incrementing) numbered suffix, or give an error. --backUpFile :: FilePath -> IO () --backUpFile fp = do -- fs <- safeGetDirectoryContents $ takeDirectory $ fp -- let (d,f) = splitFileName fp -- versions = catMaybes $ map (f `backupNumber`) fs -- next = maximum (0:versions) + 1 -- f' = printf "%s.%d" f next -- copyFile fp (d f') -- --safeGetDirectoryContents :: FilePath -> IO [FilePath] --safeGetDirectoryContents "" = getDirectoryContents "." --safeGetDirectoryContents fp = getDirectoryContents fp -- ---- | Does the second file represent a backup of the first, and if so which version is it ? --backupNumber :: FilePath -> FilePath -> Maybe Int --backupNumber f g = case regexMatch ("^" ++ f ++ "\\.([0-9]+)$") g of -- Just (_, ((_,suffix):_)) -> readMay suffix -- _ -> Nothing - -*** nice standard financial reports *** plugin architecture/modular packaging **** goals ***** allow separately-packaged functionality to be discovered at run-time and integrated within the hledger ui. @@ -3943,184 +2979,310 @@ types need converting, etc. plugins may run more slowly plugins can be discovered/loaded by module path or by loading files directly -*** runtime report templates -*** separate --display and --limit expressions, eg for --depth -*** perf: more speed, memory optimisation -*** support - in period expressions -*** support -V ? -*** talkback feature -gather data on real-world installation & usage issues -simplify bug reporting/handling -improve reliability -*** upload feature -*** ofx reader -**** clint's code -Date: Sun, 18 Sep 2011 12:26:16 -0400 -From: Clint Adams -To: hledger@googlegroups.com -Subject: OFX conversion -Message-ID: <20110918162616.GA18874@softwarefreedom.org> -MIME-Version: 1.0 -User-Agent: Mutt/1.5.20 (2009-06-14) -X-Original-Sender: clint@softwarefreedom.org -X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: - domain of clint@softwarefreedom.org designates 216.27.154.199 as permitted - sender) smtp.mail=clint@softwarefreedom.org -Reply-To: hledger@googlegroups.com -Precedence: list -Mailing-list: list hledger@googlegroups.com; contact hledger+owners@googlegroups.com -List-ID: -X-Google-Group-Id: 895107692464 -List-Post: , -List-Help: , -List-Archive: -Sender: hledger@googlegroups.com -List-Subscribe: , -List-Unsubscribe: , -Content-Type: text/plain; charset=iso-8859-1 -Content-Disposition: inline -Content-Transfer-Encoding: 8bit -This is definitely suboptimal but it seems to work on -the OFX 1.0.2 output from AmEx. +** Archive :ARCHIVE: +*** DONE 98: build issue due to missing template files + CLOSED: [2013-01-24 Thu 09:30] + :PROPERTIES: + :ARCHIVE_TIME: 2013-01-24 Thu 09:30 + :END: +**** test fix +**** publish patch +**** close issue +**** improve clean build testing, possibly with cabal-dev +*** DONE fix/explain build errors + CLOSED: [2013-02-08 Fri 09:05] + :PROPERTIES: + :ARCHIVE_TIME: 2013-02-11 Mon 12:44 + :END: +*** DONE add: djp/sm enhancements + CLOSED: [2013-03-15 Fri 18:35] + :PROPERTIES: + :ARCHIVE_TIME: 2013-03-15 Fri 18:35 + :END: +**** DONE cleanups + CLOSED: [2013-02-25 Mon 16:38] +**** DONE 52 show added txn + CLOSED: [2013-02-25 Mon 16:38] +**** DONE 47 do-over + CLOSED: [2013-02-25 Mon 16:38] +**** DONE 96 command-line defaults + CLOSED: [2013-02-25 Mon 16:38] +**** DONE 45 allow comment/tag entry + CLOSED: [2013-02-25 Mon 16:38] +***** allow DESC ;COMMENT +***** allow AMOUNT ;COMMENT +**** DONE allow DATE CODE + CLOSED: [2013-02-25 Mon 16:38] +**** DONE confirm before adding txn + CLOSED: [2013-02-25 Mon 16:39] +**** DONE don't die after data entry if a partial date was provided on command line + CLOSED: [2013-03-04 Mon 18:09] + +**** DONE decide how to wind this up, complete/announce bounty + CLOSED: [2013-03-09 Sat 07:57] +**** DONE add to release notes + CLOSED: [2013-03-09 Sat 07:57] + +*** DONE update release notes + CLOSED: [2013-03-30 Sat 11:00] + :PROPERTIES: + :ARCHIVE_TIME: 2013-03-30 Sat 11:02 + :END: +*** DONE fix site tocs + CLOSED: [2013-03-30 Sat 11:11] + :PROPERTIES: + :ARCHIVE_TIME: 2013-03-30 Sat 11:11 + :END: +*** DONE split up docs + CLOSED: [2013-04-02 Tue 11:17] + :PROPERTIES: + :ARCHIVE_TIME: 2013-04-02 Tue 11:17 + :END: +*** DONE publish multiple doc versions + CLOSED: [2013-04-02 Tue 11:17] + :PROPERTIES: + :ARCHIVE_TIME: 2013-04-02 Tue 11:17 + :END: + +*** DONE issue tracking/project hosting spring cleaning + CLOSED: [2013-04-10 Wed 15:04] + :PROPERTIES: + :ARCHIVE_TIME: 2013-04-10 Wed 15:05 + :END: +**** DONE clarify wish tracking + CLOSED: [2013-04-10 Wed 15:04] +**** DONE try trello boards + CLOSED: [2013-04-09 Tue 06:17] +**** DONE clarify code hosting - github ? + CLOSED: [2013-04-09 Tue 06:17] +*** DONE more powerful csv reading + :PROPERTIES: + :ARCHIVE_TIME: 2013-04-10 Wed 15:16 + :END: +**** DONE v2 rules file mockup showing new syntax + CLOSED: [2013-01-11 Fri 20:27] +**** DONE write down pseudo grammar + CLOSED: [2013-01-11 Fri 20:27] +**** DONE review status + CLOSED: [2013-01-11 Fri 20:47] +**** DONE parse basic directives & assignments + CLOSED: [2013-01-12 Sat 09:12] +**** DONE apply basic directives & assignments + CLOSED: [2013-01-13 Sun 11:01] +***** DONE directives + CLOSED: [2013-01-13 Sun 10:58] +***** DONE field assignments + CLOSED: [2013-01-13 Sun 10:58] +****** DONE code review + CLOSED: [2013-01-12 Sat 09:41] +****** DONE code cleanup + CLOSED: [2013-01-12 Sat 11:40] +******* DONE conform to new naming + CLOSED: [2013-01-12 Sat 11:40] +******* DONE clarify rules type + CLOSED: [2013-01-12 Sat 10:57] +******* DONE simplify + CLOSED: [2013-01-12 Sat 11:40] +******** DONE get it parsing test rules again + CLOSED: [2013-01-12 Sat 11:05] +******** DONE get it printing correct parsed value + CLOSED: [2013-01-12 Sat 11:05] +******** DONE cleanup + CLOSED: [2013-01-12 Sat 11:40] +****** DONE generate field values from templates + CLOSED: [2013-01-13 Sun 10:58] +******* DONE date-format & date + CLOSED: [2013-01-13 Sun 01:00] +******* DONE other fields + CLOSED: [2013-01-13 Sun 10:58] +**** DONE 1-based field numbering + CLOSED: [2013-01-13 Sun 11:01] +**** DONE conditional assignments + CLOSED: [2013-01-26 Sat 05:47] +***** DONE parsing + CLOSED: [2013-01-14 Mon 07:27] +****** DONE review doc + CLOSED: [2013-01-13 Sun 11:37] +****** DONE update grammar + CLOSED: [2013-01-13 Sun 11:39] +****** DONE multiple assignments + CLOSED: [2013-01-13 Sun 12:55] +****** DONE multiple patterns + CLOSED: [2013-01-13 Sun 13:36] +****** DONE clarify syntax + CLOSED: [2013-01-13 Sun 14:20] +****** DONE update grammar + CLOSED: [2013-01-14 Mon 07:13] +****** DONE clarify backwards compatibility + CLOSED: [2013-01-14 Mon 07:13] +****** DONE lighter conditional syntax (omit field name) + CLOSED: [2013-01-14 Mon 07:27] + +***** DONE functionality + CLOSED: [2013-01-26 Sat 05:47] +****** DONE clarify spec + CLOSED: [2013-01-14 Mon 09:33] +****** DONE implement + CLOSED: [2013-01-14 Mon 09:33] + +****** DONE test + CLOSED: [2013-01-26 Sat 05:47] +******* DONE fix speed + CLOSED: [2013-01-26 Sat 05:46] +******** DONE review/try regex libs + CLOSED: [2013-01-26 Sat 05:29] +******** DONE profile different variants + CLOSED: [2013-01-26 Sat 05:29] +******** DONE handle malformed regexps as well as before + CLOSED: [2013-01-26 Sat 05:46] +**** DONE fix warnings + CLOSED: [2013-01-26 Sat 15:03] +**** DONE field name list + CLOSED: [2013-01-26 Sat 15:03] +***** DONE implement assignment by field name list + CLOSED: [2013-01-26 Sat 14:58] +****** DONE add a date field assignment per its position + CLOSED: [2013-01-26 Sat 14:39] + +****** DONE refactor + CLOSED: [2013-01-26 Sat 14:51] +****** DONE add multiple fields without hard coding + CLOSED: [2013-01-26 Sat 14:58] +****** DONE add all the right fields + CLOSED: [2013-01-26 Sat 14:58] +**** DONE skip + CLOSED: [2013-01-26 Sat 15:38] +**** DONE set currency from csv + CLOSED: [2013-03-19 Tue 06:17] +**** DONE set amount sign based on another field's content (type=debit|credit) + CLOSED: [2013-01-26 Sat 16:57] +**** DONE set amount based on two fields (amount in, amount out) + CLOSED: [2013-03-19 Tue 06:17] + +**** DONE parse parenthesised amounts as negative + CLOSED: [2013-01-27 Sun 17:32] +**** DONE user friendliness + CLOSED: [2013-02-11 Mon 12:43] +***** DONE robust parsing + CLOSED: [2013-01-27 Sun 07:32] +***** DONE clear-ish errors + CLOSED: [2013-02-11 Mon 10:16] +****** DONE catalog errors + CLOSED: [2013-02-09 Sat 15:18] +****** DONE missing date/amount rule error + CLOSED: [2013-02-09 Sat 09:32] +****** DONE better amount parse errors + CLOSED: [2013-02-09 Sat 10:12] +******* DONE clean up csv parsing/validation + CLOSED: [2013-01-28 Mon 08:50] +******* DONE clean up rules parsing/validation + CLOSED: [2013-01-28 Mon 08:50] + +******* DONE no amount assignment + CLOSED: [2013-01-29 Tue 06:50] +******* DONE amount field unparseable + CLOSED: [2013-02-09 Sat 10:12] +******* DONE confusing amount parse error for header line + CLOSED: [2013-02-09 Sat 11:47] +hledgerdev: +Error, could not parse amount "" ((line 1, column 1): +unexpected end of input +expecting left-symbol amount, right-symbol amount or no-symbol amount) +in ["Date","Details","Debit","Credit","Balance"] + +rules: +# + +******* DONE could not parse amount in (data line) + CLOSED: [2013-02-09 Sat 11:48] +hledgerdev: Error, could not parse amount "" ((line 1, column 1): +unexpected end of input expecting left-symbol amount, right-symbol +amount or no-symbol amount) in ["07/12/2012","LODGMENT +529898","","10.0","131.21"] + +rules: +******* DONE poor error on empty amount csv field + CLOSED: [2013-02-09 Sat 14:03] +****** DONE better date parse errors + CLOSED: [2013-02-09 Sat 11:26] +******* DONE don't silently misparse d/m/y + CLOSED: [2013-02-09 Sat 13:34] +****** DONE why x rule triggering ? + CLOSED: [2013-02-09 Sat 17:28] +****** DONE unclear error when conditional block assignment has no field name + CLOSED: [2013-02-09 Sat 17:40] + +***** show what's happening +**** DONE fix parsing of %10 and fields: ...amount... as %1 in .wepay-in.csv.rules + CLOSED: [2013-03-14 Thu 16:19] +**** DONE interpolate by name + CLOSED: [2013-03-14 Thu 17:33] +**** DONE skip-lines -> skip + CLOSED: [2013-03-14 Thu 17:36] +**** DONE amount-in/out + CLOSED: [2013-03-15 Fri 17:45] +**** DONE value-less skip + CLOSED: [2013-03-15 Fri 17:45] +**** DONE make if operator optional + CLOSED: [2013-03-19 Tue 06:47] +**** DONE docs + CLOSED: [2013-03-29 Fri 15:20] +***** DONE reorganize file format docs + CLOSED: [2013-02-11 Mon 12:45] +***** DONE review/record writing tips + CLOSED: [2013-03-14 Thu 16:28] +***** DONE csv introduction + CLOSED: [2013-03-14 Thu 17:54] +***** DONE convert to hakyll 4 + CLOSED: [2013-03-14 Thu 17:54] +***** DONE serve manual from hub + CLOSED: [2013-03-13 Wed 11:03] +***** DONE rewrite intro + CLOSED: [2013-03-17 Sun 16:15] +***** DONE rewrite rules reference + CLOSED: [2013-03-19 Tue 06:15] +***** DONE update manual + CLOSED: [2013-03-29 Fri 14:06] +***** DONE update grammar + CLOSED: [2013-03-29 Fri 14:37] +***** DONE clarify csv / journal entry / transaction terminology + CLOSED: [2013-03-19 Tue 06:15] +***** DONE clarify directives / assignments / rules terminology + CLOSED: [2013-03-29 Fri 15:16] +***** DONE clarify account directives + CLOSED: [2013-03-29 Fri 15:16] +***** DONE clarify optional syntax (:, if, fields) + CLOSED: [2013-03-29 Fri 15:16] +***** DONE clarify upgrade process + CLOSED: [2013-03-30 Sat 10:35] +***** TODO update/add examples + https://gist.github.com/simonmichael/5153401 bofi example + +****** no rules file example +****** rules file example +****** how to archive/import the journal data more permanently +**** DONE update default rules + CLOSED: [2013-03-29 Fri 15:19] +**** DONE testing + CLOSED: [2013-03-29 Fri 15:51] +***** DONE wells fargo checking + CLOSED: [2013-01-27 Sun 17:25] +***** DONE western federal + CLOSED: [2013-01-27 Sun 18:51] +***** DONE b of i + CLOSED: [2013-03-19 Tue 06:17] +***** DONE wepay + CLOSED: [2013-03-19 Tue 06:17] +***** DONE paypal + CLOSED: [2013-03-29 Fri 15:24] +***** DONE mint + CLOSED: [2013-03-29 Fri 15:39] +***** DONE ynab + CLOSED: [2013-03-29 Fri 15:46] +***** wescom +**** DONE commits + CLOSED: [2013-03-29 Fri 16:10] -{-# LANGUAGE Arrows, NoMonomorphismRestriction #-} -import Text.XML.HXT.Core -import Text.Printf (printf) - -import Data.List (groupBy) -import Data.List.Split (splitOn) - -import Data.Maybe (fromMaybe) - -import Data.Time.Calendar (Day (ModifiedJulianDay)) -import Data.Time.Format (formatTime) -import Data.Time.LocalTime (LocalTime (LocalTime), TimeOfDay (TimeOfDay)) -import Data.Time.Parse (strptime) - -import System.Locale (defaultTimeLocale) -import System.Process (readProcessWithExitCode) - -import Hledger.Cli.Format (FormatString (FormatField), Field (FieldNo)) -import Hledger.Cli.Convert - -normAmount :: String -> String -normAmount amt | amt == "" = "" - | otherwise = printf "%.2f" (read amt :: Double) - -compressWhitespace :: String -> String -compressWhitespace x = map head $ groupSpaces x - where groupSpaces "" = [""] - groupSpaces x = groupBy (\x y -> x==' ' && y==' ') x - -data Transaction = Transaction - { trnType, dtUser, dtPosted, trnAmt, fitId, refNum, name, memo :: String } - deriving (Show, Eq) - --- this doesn't get the timezone right -ofxDateParse :: String -> String -ofxDateParse x = formatTime defaultTimeLocale "%Y-%m-%d" (fst (fromMaybe (LocalTime (ModifiedJulianDay 100) (TimeOfDay 0 0 0), "") (strptime "%Y%m%d%H%M%S.%OS" x))) - -parseFakeXML string = readString [ withValidate no - , withRemoveWS yes - ] string - -atTag tag = deep (isElem >>> hasName tag) -text = getChildren >>> getText -textAtTag tag = atTag tag >>> text - -getTransactions = atTag "STMTTRN" >>> - proc l -> do - trnType <- textAtTag "TRNTYPE" -< l - dtUser <- textAtTag "DTUSER" -< l - dtPosted <- textAtTag "DTPOSTED" -< l - trnAmt <- textAtTag "TRNAMT" -< l - fitId <- textAtTag "FITID" -< l - refNum <- textAtTag "REFNUM" -< l - name <- textAtTag "NAME" -< l - memo <- textAtTag "MEMO" -< l - returnA -< Transaction - { trnType = trnType, - dtUser = ofxDateParse dtUser, - dtPosted = ofxDateParse dtPosted, - trnAmt = trnAmt, - fitId = fitId, - refNum = refNum, - name = name, - memo = memo } - -ofxrules = CsvRules { - dateField=Just 0, - dateFormat=Nothing, - statusField=Nothing, - codeField=Nothing, - descriptionField=[FormatField False Nothing Nothing (FieldNo 2)], - amountField=Just 1, - inField=Nothing, - outField=Nothing, - currencyField=Nothing, - baseCurrency=Nothing, - accountField=Nothing, - account2Field=Nothing, - effectiveDateField=Nothing, - baseAccount="Liabilities:American Express", - accountRules=[] -} - -txnToCsvRecord :: Transaction -> CsvRecord -txnToCsvRecord x = [dtUser x, normAmount (trnAmt x), compressWhitespace (name x) ++ "(" ++ refNum x ++ ")", fitId x, memo x] - -printTxnWithComment :: CsvRecord -> IO () -printTxnWithComment x = putStrLn ("; " ++ x !! 3 ++ " - " ++ x !! 4) >> printTxn False ofxrules x - -main = do - filecontents <- readFile "/tmp/ofx.ofx" - let splitfilecontents = splitOn "\n\n" filecontents - let ofxheader = head splitfilecontents - let ofxsgml = splitfilecontents !! 1 - (_, fakexml, _) <- readProcessWithExitCode "/usr/bin/sgml2xml" [] ofxsgml - - transes <- runX (parseFakeXML fakexml >>> getTransactions) - - let records = map txnToCsvRecord transes - mapM_ (printTxnWithComment) records - -*** gnucash reader -*** accounts: list account names by type, optionally filtered -hledger accounts - -B|--balancesheet|-I|--incomestatement|-C|--cashflow| - -a|--assets|-l|--liabilities|-i|--income|-e|--expenses|-q|--equity -*** config: save config properties -hledger config accounts.asset Asset -*** checkup: check journal for common issues -**** parseable ? -**** transactions balanced ? -**** balance assertions ? -**** balance sheet zeroed out each year ? -**** consistent/recent entry activity ? -*** summary: show overview report by period - week month quarter year - this last average this last average this last average this last average - -you have (assets) -you almost have (receivables) -you owe now (payables) -you owe later (liabilities) -revenues -expenses -cash in -cash out - - -*** filter by commodity -comm:EUR -curr:USD -c:$ -*** parsing: ignore missing included files -$ hledger -f .paypal.journal print -hledger: "/Users/simon/.sm/personal/.paypal.journal" (line 2, column 1) reading /Users/simon/.sm/personal/paypal-2001.journal: -/Users/simon/.sm/personal/paypal-2001.journal: openFile: does not exist (No such file or directory) - -*** lift "At most one alias directive and one alias option will be applied to each account name." restriction