notes: backlog updates

This commit is contained in:
Simon Michael 2013-03-29 23:25:43 +00:00
parent 03f6119a8d
commit ba207ce391

842
NOTES.org
View File

@ -1,5 +1,9 @@
hledger project notes hledger project notes
*We are all wandering the orderly halls of Castle Haskell.*
*This whole plain is gunpowder a mile deep.*
* about * about
This emacs org-mode outline contains Simon's project backlog, activity This emacs org-mode outline contains Simon's project backlog, activity
log, and random developer notes. Currently only I use this file, but log, and random developer notes. Currently only I use this file, but
@ -16,11 +20,9 @@ assuming 4 hours in day, 5 days in a week, and 4 weeks in a month.
At some point there might be a process to aggregate estimates, log them At some point there might be a process to aggregate estimates, log them
(including deleted items as 0) on commit, and make burndown charts. (including deleted items as 0) on commit, and make burndown charts.
* routines * routines
standard procedures/checklists for various activities standard procedures/checklists for various activities
* misc * misc
** inspiration ** inspiration
"...simplicity of design was the most essential, guiding principle. "...simplicity of design was the most essential, guiding principle.
@ -2118,150 +2120,421 @@ move *FromOpts into toOpts
*** 6/30 announce, notes *** 6/30 announce, notes
*** 7/1 notes *** 7/1 notes
* in progress
* next up
** web: code review/refactor
** web: use bootstrap
** more powerful csv conversion
** formats: ofx reader
*** clint's code
Date: Sun, 18 Sep 2011 12:26:16 -0400
From: Clint Adams <clint@softwarefreedom.org>
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: <hledger.googlegroups.com>
X-Google-Group-Id: 895107692464
List-Post: <http://groups.google.com/group/hledger/post?hl=en_US>, <mailto:hledger@googlegroups.com>
List-Help: <http://groups.google.com/support/?hl=en_US>, <mailto:hledger+help@googlegroups.com>
List-Archive: <http://groups.google.com/group/hledger?hl=en_US>
Sender: hledger@googlegroups.com
List-Subscribe: <http://groups.google.com/group/hledger/subscribe?hl=en_US>, <mailto:hledger+subscribe@googlegroups.com>
List-Unsubscribe: <http://groups.google.com/group/hledger/subscribe?hl=en_US>, <mailto:hledger+unsubscribe@googlegroups.com>
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.
{-# 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
* backlog * 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]
** 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]
**** clarify upgrade process
***** base-currency -> default-currency
***** base-account -> default-account1
***** FIELDNAME-field N -> FIELDNAME %N+1
***** update each account-assigning rule
****** add a line containing ~ before the regexps
****** add account2: before the account name
**** set up versioned manual
**** 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
%account %amount
%default-account
(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 issue tracking/roadmap cleanup
*** clarify wish tracking, project hosting
*** 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
*** try trello boards
** 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
** errors ** errors
*** add: should not accept . as an amount
*** add: default amount adds one decimal place when journal contains no decimals 2d
*** add: excessive precision in default balancing amount 1d
**** shelltest tests/add.test -- -t10
**** find original justification or drop
*** add: learn decimal point/thousands separator from the journal and/or add session ? 2d
Eg: comma is already used as thousands separator in the journal, but add
interprets it as decimal point giving a wrong default for amount 2 (though
the correct journal transaction is written in this case)
$ hledger -f t add
Adding transactions to journal file "t".
To complete a transaction, enter . (period) at an account prompt.
To stop adding transactions, enter . at a date prompt, or control-d/control-c.
date, or . to end [2011/09/30]:
description []: z
account 1: a
amount 1: 1,000
account 2: b
amount 2 [-1,0]:
account 3, or . to record: .
date, or . to end [2011/09/30]: .
$ cat t
; journal created 2011-09-30 by hledger
2011/09/30
a $1,000,000.00
b
2011/09/30 x
a $1,2
b
2011/09/30 y
a $1.2
b
2011/09/30 z
a 1,000
b
*** web: unknown flag --port
$ hledger web --port=5001 -f all.journal paypal
hledger: Unknown flag: --port
*** print: virtual posting parentheses throwing off layout
*** bal: should --flat show inclusive or exclusive balances ??
*** double quote matches everything ? 1 *** double quote matches everything ? 1
*** web: stray bracket in journal edit form title 1 *** web: stray bracket in journal edit form title 1
*** web: enter doesn't work in add form completing fields 1d *** web: enter doesn't work in add form completing fields 1d
@ -2319,52 +2592,30 @@ hledger: could not parse journal data in t.j
unexpected "b" unexpected "b"
expecting comment or new-line expecting comment or new-line
*** add: default amount adds one decimal place when journal contains no decimals 2d
*** add: excessive precision in default balancing amount 1d
**** shelltest tests/add.test -- -t10
**** find original justification or drop
*** add: learn decimal point/thousands separator from the journal and/or add session ? 2d
Eg: comma is already used as thousands separator in the journal, but add
interprets it as decimal point giving a wrong default for amount 2 (though
the correct journal transaction is written in this case)
$ hledger -f t add
Adding transactions to journal file "t".
To complete a transaction, enter . (period) at an account prompt.
To stop adding transactions, enter . at a date prompt, or control-d/control-c.
date, or . to end [2011/09/30]:
description []: z
account 1: a
amount 1: 1,000
account 2: b
amount 2 [-1,0]:
account 3, or . to record: .
date, or . to end [2011/09/30]: .
$ cat t
; journal created 2011-09-30 by hledger
2011/09/30
a $1,000,000.00
b
2011/09/30 x
a $1,2
b
2011/09/30 y
a $1.2
b
2011/09/30 z
a 1,000
b
*** convert: 49 convert should report rules file parse errors better 1d *** convert: 49 convert should report rules file parse errors better 1d
*** not: does not work with date: etc.
*** 25 hledger in windows console does not print non-ascii characters 3d *** 25 hledger in windows console does not print non-ascii characters 3d
http://stackoverflow.com/questions/10779149/unicode-console-i-o-in-haskell-on-windows http://stackoverflow.com/questions/10779149/unicode-console-i-o-in-haskell-on-windows
http://hackage.haskell.org/trac/ghc/ticket/4471 http://hackage.haskell.org/trac/ghc/ticket/4471
*** journalAddFile is called in reverse order of includes 2 *** journalAddFile is called in reverse order of includes 2
** documentation, marketing *** cli: short flags not passed through to subcommand
*** irr: flags require preceding --
** documentation
*** hledger intro tutorial:
**** what problem did ledger solve when I started ?
***** I needed to track my time at work
***** I needed a transparent, open, future-proof data format
***** I needed simple, reliable, fixable software with no lock-in
***** I wanted an accounting tool without distracting/frustrating unfixable usability/functionality bugs
**** what problem did hledger solve when I started ?
***** I neededed a better implementation of ledger (for me; that meant ie more installable, intuitive, documented, bug free, easy to hack on and extend)
***** I needed to make consistent bookkeeping more fun and motivating
***** I wanted a not-too-demanding learn haskell project
***** I wanted reusable accounting libraries available in haskell for experiments
***** I wanted to explore making an easy accounting app I could sell
**** what problem is hledger solving now ?
***** same as above ?
*** doc: manual rewrites
*** developer notes *** developer notes
**** 2012/7 cleanup **** 2012/7 cleanup
***** quick cleanup finance onwards 2 ***** quick cleanup finance onwards 2
@ -2602,9 +2853,11 @@ binaries for all platforms
*** internal code docs *** internal code docs
*** live demos/talks *** live demos/talks
** marketing
*** reference
http://www.geekwire.com/2013/marketing-advice-startups/
** finance ** finance
*** develop funding process *** develop funding process
**** license change ?
**** donate button, see chimoo guy **** donate button, see chimoo guy
**** funding document 2009/01 **** funding document 2009/01
***** text ***** text
@ -2805,6 +3058,7 @@ competitors/fellow niche inhabitants
****** gwern ****** gwern
most haskellers have never heard of hledger, sounds arrogant or hubristic to talk of charging for it most haskellers have never heard of hledger, sounds arrogant or hubristic to talk of charging for it
**** license change ?
**** home edition **** home edition
**** real-time project ledger **** real-time project ledger
**** in-place transaction editing fund drive **** in-place transaction editing fund drive
@ -2959,6 +3213,8 @@ $ ledger -V -f test.dat --no-rounding bal
Is there something off with how the data aboce is set up? Should I be Is there something off with how the data aboce is set up? Should I be
using be more place holders? using be more place holders?
*** performance *** performance
**** reference
http://stackoverflow.com/questions/3276240/tools-for-analyzing-performance-of-a-haskell-program/3276557#3276557
**** speed, benchmark tests **** speed, benchmark tests
**** memory usage **** memory usage
*** build & packaging *** build & packaging
@ -2989,6 +3245,7 @@ using be more place holders?
***** easy installer ***** easy installer
***** easy startup ***** easy startup
** refactoring ** refactoring
*** clarify need for & usage of primary/secondary/transaction/posting dates
*** makefile cleanups *** makefile cleanups
*** make shell tests version independent *** make shell tests version independent
tests/no-such-file.test: rm -f $$; bin/hledger register -f $$; rm -f $$ tests/no-such-file.test: rm -f $$; bin/hledger register -f $$; rm -f $$
@ -3045,11 +3302,33 @@ http://ajaxcssblog.com/jquery/url-read-request-variables/
**** unix/windows/mac platform **** unix/windows/mac platform
*** inspiration *** inspiration
http://community.haskell.org/~ndm/downloads/paper-hoogle_overview-19_nov_2008.pdf -> Design Guidelines http://community.haskell.org/~ndm/downloads/paper-hoogle_overview-19_nov_2008.pdf -> Design Guidelines
** features *** perf tuning experiments
*** add: don't offer record txn option in account N prompt if it's not balanced yet **** string -> text
*** add: rewrite a short description (trader) to the full description from the matched txn (trader joe's) ? **** strict data fields
*** add: try wizards, vty-ui libs ? **** more profiling
*** add: would be nice to create the journal file only if a txn is actually recorded **** 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: --depth with --flat should show aggregate balances including the non-displayed deeper accounts
*** balance: try indenting amounts *** balance: try indenting amounts
@ -3134,6 +3413,12 @@ hledger -f demo.journal reg inacct:expenses:food:pets date:2010/8/25
2010/08/25 catfood expenses:food:pets $10.00 $10.00 2010/08/25 catfood expenses:food:pets $10.00 $10.00
assets:cash $-10.00 0 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 *** 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. cf clients & profits interactive user guide, php.net, realworldhaskell etc.
*** docs: better intro, less wall-of-text, separate tutorial & reference sections *** docs: better intro, less wall-of-text, separate tutorial & reference sections
@ -3242,7 +3527,6 @@ dataType = do string "Cash"
transaction :: GenParser Char st [TransactionDetail] transaction :: GenParser Char st [TransactionDetail]
*** parsing: accept all real-world ledger files *** parsing: accept all real-world ledger files
As far as I know it currently accepts all ledger 2.6-era 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. Add support for ledger 3 file format as/when that stabilises.
@ -3277,6 +3561,7 @@ $ hledger -f time.journal bal -p aug -B
1 1
17.75h 17.75h
*** parsing: better date tag syntax errors
*** parsing: canonicalise account names to be case-insensitive ? *** parsing: canonicalise account names to be case-insensitive ?
*** parsing: end directive may also be spelled end account; or end ends last directive *** parsing: end directive may also be spelled end account; or end ends last directive
*** parsing: enforce positive price amounts, like ledger *** parsing: enforce positive price amounts, like ledger
@ -3328,11 +3613,13 @@ eg support -p 'from 1/1 to 2/1 weekly'
*** print: shouldn't support -M and --depth ? *** print: shouldn't support -M and --depth ?
*** queries: tag value queries
*** register: for the love of god, show full descriptions *** register: for the love of god, show full descriptions
*** web: api *** web: api
*** web: auto-complete accounts & amount as well as description *** web: auto-complete accounts & amount as well as description
*** web: auto-complete from substrings, not just prefixes *** 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: better web ui/gui
*** web: completes one account name component in add form account fields *** 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 net worth, /register?q=assets+liabilities shows nothing
@ -3646,3 +3933,174 @@ gather data on real-world installation & usage issues
simplify bug reporting/handling simplify bug reporting/handling
improve reliability improve reliability
*** upload feature *** upload feature
*** ofx reader
**** clint's code
Date: Sun, 18 Sep 2011 12:26:16 -0400
From: Clint Adams <clint@softwarefreedom.org>
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: <hledger.googlegroups.com>
X-Google-Group-Id: 895107692464
List-Post: <http://groups.google.com/group/hledger/post?hl=en_US>, <mailto:hledger@googlegroups.com>
List-Help: <http://groups.google.com/support/?hl=en_US>, <mailto:hledger+help@googlegroups.com>
List-Archive: <http://groups.google.com/group/hledger?hl=en_US>
Sender: hledger@googlegroups.com
List-Subscribe: <http://groups.google.com/group/hledger/subscribe?hl=en_US>, <mailto:hledger+subscribe@googlegroups.com>
List-Unsubscribe: <http://groups.google.com/group/hledger/subscribe?hl=en_US>, <mailto:hledger+unsubscribe@googlegroups.com>
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.
{-# 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