packages feed

hledger-interest 1.1 → 1.2

raw patch · 4 files changed

+205/−18 lines, 4 files

Files

Hledger/Interest.hs view
@@ -48,9 +48,8 @@   interestAcc <- asks interestAccount   let posts = [ p | p <- tpostings ts, interestAcc == paccount p ]   forM_ posts $ \p -> do-    bal <- gets (amounts . balance)-    let bal' = bal ++ amounts (pamount p)-    modify (\st -> st { balance = normaliseMixedAmount (Mixed bal') })+    bal <- gets (balance)+    modify (\st -> st { balance = normaliseMixedAmount (bal + (pamount p)) })  computeInterest :: Day -> Computer () computeInterest day = do
Main.hs view
@@ -29,7 +29,7 @@   { optVerbose      = True   , optShowVersion  = False   , optShowHelp     = False-  , optInput        = ""+  , optInput        = "-"   , optSourceAcc    = ""   , optTargetAcc    = ""   , optDCC          = Nothing@@ -43,8 +43,8 @@  , Option ['V'] ["version"]     (NoArg (\o -> o { optShowVersion = True }))                         "show version number and exit"  , Option ['v'] ["verbose"]     (NoArg (\o -> o { optVerbose = True }))                             "echo input ledger to stdout (default)"  , Option ['q'] ["quiet"]       (NoArg (\o -> o { optVerbose = False }))                            "don't echo input ledger to stdout"- , Option []    ["today"]       (NoArg (\o -> o { optBalanceToday = True }))                        "update account until today"- , Option ['f'] ["file"]        (ReqArg (\f o -> o { optInput = f }) "FILE")                        "input ledger file"+ , Option []    ["today"]       (NoArg (\o -> o { optBalanceToday = True }))                        "compute interest up until today"+ , Option ['f'] ["file"]        (ReqArg (\f o -> o { optInput = f }) "FILE")                        "input ledger file (pass '-' for stdin)"  , Option ['s'] ["source"]      (ReqArg (\a o -> o { optSourceAcc = a }) "ACCOUNT")                 "interest source account"  , Option ['t'] ["target"]      (ReqArg (\a o -> o { optTargetAcc = a }) "ACCOUNT")                 "interest target account"  , Option []    ["act"]         (NoArg (\o -> o { optDCC = Just diffAct }))                         "use 'act' day counting convention"@@ -75,16 +75,19 @@   (opts, args) <- getArgs >>= parseOpts   when (optShowVersion opts) (putStrLn (display version) >> exitSuccess)   when (optShowHelp opts) (putStr usageMessage >> exitSuccess)-  when (null (optInput opts)) (commandLineError "required --file option is missing\n")   when (null (optSourceAcc opts)) (commandLineError "required --source option is missing\n")   when (null (optTargetAcc opts)) (commandLineError "required --target option is missing\n")   when (isNothing (optDCC opts)) (commandLineError "no day counting convention specified\n")   when (isNothing (optRate opts)) (commandLineError "no interest rate specified\n")-  when (length args /= 1) (commandLineError "required argument ACCOUNT is missing\n")+  when (length args < 1) (commandLineError "required argument ACCOUNT is missing\n")+  when (length args > 1) (commandLineError "only one interest ACCOUNT may be specified\n")+  input <- case optInput opts of+             "-"  -> getContents+             file -> readFile file+  jnl' <- readJournal Nothing input >>= either fail return   let [interestAcc] = args-  Right jnl' <- readFile (optInput opts) >>= readJournal Nothing-  let jnl = filterJournalTransactionsByAccount [interestAcc] jnl'-      ts = sortBy (comparing tdate) (jtxns jnl)+      jnl = filterJournalTransactionsByAccount [interestAcc] jnl'+      ts  = sortBy (comparing tdate) (jtxns jnl)       cfg = Config             { interestAccount = interestAcc             , sourceAccount = optSourceAcc opts@@ -98,6 +101,6 @@         | otherwise            = return ()       ts' = runComputer cfg (mapM_ processTransaction ts >> finalize)       result-        | optVerbose opts = ts ++ ts'+        | optVerbose opts = ts' ++ ts         | otherwise       = ts'   mapM_ (putStr . show) (sortBy (comparing tdate) result)
+ README.md view
@@ -0,0 +1,184 @@+hledger-interest+================++hledger-interest is a small command-line utility based on [Simon+Michael's hleder library](http://hledger.org/). Its purpose is to+compute interest for a given ledger account. Using command line flags,+the program can be configured to use various [day counting+conventions](http://en.wikipedia.org/wiki/Day_count_convention), such as+"act/act", "30/360", "30E/360", and "30/360isda". Furthermore, it+supports several of different interest schemes, i.e. annual interest+with a fixed rate and the scheme mandated by the German law [§ 288 BGB+Verzugszinsen](http://de.wikipedia.org/wiki/Verzugszinssatz). Extending+support for other schemes is fairly easy, but currently requires hacking+the source code.++An overview over the available run-time options can be displayed by+running "`hleder-interest --help`":++    Usage: hledger-interest [OPTION...] ACCOUNT+      -v          --verbose         echo input ledger to stdout (default)+      -q          --quiet           don't echo input ledger to stdout+                  --today           compute interest up until today+      -f FILE     --file=FILE       input ledger file (pass '-' for stdin)+      -s ACCOUNT  --source=ACCOUNT  interest source account+      -t ACCOUNT  --target=ACCOUNT  interest target account+                  --act             use 'act' day counting convention+                  --30-360          use '30/360' day counting convention+                  --30E-360         use '30E/360' day counting convention+                  --30E-360isda     use '30E/360isda' day counting convention+                  --constant=RATE   constant interest rate+                  --annual=RATE     annual interest rate+                  --bgb288          compute interest according to German BGB288++When run, hledger-interest reads the [ledger+file](http://hledger.org/MANUAL.html#file-format) designated by the+`--file` flag and filters all transactions that change the account+specified on the command line. All other accounts will be ignored. Every+time a transaction modifies the given account's balance -- thereby+changing the amount of money that earns interest --, hledger-interest+transfers the interest that accrued so far. Interest will be debited+from the account designed by the `--source` flag and credited to the+account designed by the `--target` flag.++## Examples++Suppose that you've loaned 1000 Euro from your bank at an annual+interest rate of 5%, and that you would like to see how interest+develops over time. Then you would create a ledger file, say+`loan.ledger`, that looks something like this:++    2010/09/26 Loan+        Assets:Bank                     EUR 1000.00+        Liabilities:Loan++Now, `ledger-interest` is run to determine the interest up until today:++    $ hledger-interest -f loan.ledger --act --annual=0.05 --today -s Expenses:Interest -t Liabilities:Loan:Interest Liabilities:Loan+    2010/09/26 Loan+        Assets:Bank                     EUR 1000.00+        Liabilities:Loan++    2010/12/31 5.00% interest for EUR -1000.00 over 96 days+        Liabilities:Loan:Interest       EUR -13.15+        Expenses:Interest++    2011/08/22 5.00% interest for EUR -1000.00 over 234 days+        Liabilities:Loan:Interest       EUR -32.05+        Expenses:Interest++Note a separate credit account for the interest was chosen:+`Liabilities:Loan:Interest`. Consequently, interest accrued in one+interest period does *not* earn interest in the following periods. If+interest is credited to the main account instead, that behavior changes:++    $ hledger-interest -f loan.ledger --act --annual=0.05 --today -s Expenses:Interest -t Liabilities:Loan Liabilities:Loan+    2010/09/26 Loan+        Assets:Bank                     EUR 1000.00+        Liabilities:Loan++    2010/12/31 5.00% interest for EUR -1000.00 over 96 days+        Liabilities:Loan                EUR -13.15+        Expenses:Interest++    2011/08/22 5.00% interest for EUR -1013.15 over 234 days+        Liabilities:Loan                EUR -32.48+        Expenses:Interest++Of course, loans are supposed to be paid back, and these payments change+the amount of interest accrued. Suppose that `load.ledger` would be+extended by the following transactions:++    2010/12/11 Payment+        Assets:Bank                     EUR -150.00+        Liabilities:Loan++    2011/03/07 Payment+        Assets:Bank                     EUR -300.00+        Liabilities:Loan++    2011/08/21 Payment+        Assets:Bank                     EUR -150.00+        Liabilities:Loan++Then interest would develop as follows:++    $ hledger-interest -f loan.ledger --act --annual=0.05 -s Expenses:Interest -t Liabilities:Loan Liabilities:Loan+    2010/09/26 Loan+        Assets:Bank                     EUR 1000.00+        Liabilities:Loan++    2010/12/11 5.00% interest for EUR -1000.00 over 76 days+        Liabilities:Loan                EUR -10.41+        Expenses:Interest++    2010/12/11 Payment+        Assets:Bank                     EUR -150.00+        Liabilities:Loan++    2010/12/31 5.00% interest for EUR -860.41 over 20 days+        Liabilities:Loan                EUR -2.36+        Expenses:Interest++    2011/03/07 5.00% interest for EUR -862.77 over 66 days+        Liabilities:Loan                EUR -7.80+        Expenses:Interest++    2011/03/07 Payment+        Assets:Bank                     EUR -300.00+        Liabilities:Loan++    2011/08/21 5.00% interest for EUR -570.57 over 167 days+        Liabilities:Loan                EUR -13.05+        Expenses:Interest++    2011/08/21 Payment+        Assets:Bank                     EUR -150.00+        Liabilities:Loan++Last but not least, there is a special case known as "Verzugszinsen" in+German law, which applies when someone is supposed to pay a bill, but+fails to do so on time. For every day past the deadline, interest+accrues according to terms specified in [§ 247+BGB](http://www.gesetze-im-internet.de/bgb/__247.html). The command line+flag `--bgb288` enables this scheme in `hledger-interest`.++Let's assume that customer ACME is supposed to pay 35 Euro by+2010/09/15, but the money actually arrives almost half a year late:++    2010/09/15 Services rendered to Customer ACME+        ACME                            EUR -35.00  ; 1 hour @ EUR 35.00+        Receivable:ACME++    2011/03/17 ACME+        ACME                            EUR 35.00+        Receivable:ACME++According to German law, you are entitled to the following interest:++    $ hledger-interest -f acme.ledger --quiet --bgb288 -s Income:Interest -t Receivable:ACME:Interest Receivable:ACME+    2010/12/31 5.12% interest for EUR 35.00 over 107 days+        Receivable:ACME:Interest        EUR 0.53+        Income:Interest++    2011/03/17 5.12% interest for EUR 35.00 over 76 days+        Receivable:ACME:Interest        EUR 0.37+        Income:Interest++So, if you're smart, then you'll book the payment so that the accrued+interest is paid *first*:++    2011/03/17 ACME+        ACME                            EUR 35.00+        Receivable:ACME:Interest        EUR -0.90+        Receivable:ACME++This gives the following transaction history for the ACME account:++    $ hledger-interest -f acme.ledger --bgb288 -s Income:Interest -t Receivable:ACME:Interest Receivable:ACME |+      hledger -f - reg Receivable:ACME+    2010/09/15 Services rendered .. Receivable:ACME           EUR 35.00    EUR 35.00+    2010/12/31 5.12% interest for.. Re:ACME:Interest           EUR 0.53    EUR 35.53+    2011/03/17 5.12% interest for.. Re:ACME:Interest           EUR 0.37    EUR 35.90+    2011/03/17 ACME                 Re:ACME:Interest          EUR -0.90    EUR 35.00+                                    Receivable:ACME          EUR -34.10     EUR 0.90
hledger-interest.cabal view
@@ -1,5 +1,5 @@ Name:                   hledger-interest-Version:                1.1+Version:                1.2 Synopsis:               computes interest for a given account License:                BSD3 License-file:           LICENSE@@ -9,17 +9,18 @@ Category:               Finance Build-type:             Simple Cabal-version:          >= 1.6-Tested-With:            GHC == 6.12.3, GHC == 7.0.4, GHC == 7.2.1+Tested-with:            GHC == 6.12.3, GHC == 7.0.4, GHC == 7.2.1+Data-files:             README.md Description:  hledger-interest is a small command-line utility based on Simon  Michael's hleder library. Its purpose is to compute interest for a  given ledger account. Using command line flags, the program can be- configured to use various schemes for day-counting, such as act/act,- 30/360, 30E/360, and 30/360isda. Furthermore, it supports a (small)+ configured to use various schemes for day-counting, such as act\/act,+ 30\/360, 30E\/360, and 30\/360isda. Furthermore, it supports a (small)  number of interest schemes, i.e. annual interest with a fixed rate and  the scheme mandated by the German BGB288 (Basiszins für  Verbrauchergeschäfte). Extending support for other schemes is fairly- easy, but currently requires changing to the source code.+ easy, but currently requires changes to the source code.  .  As an example, consider the following loan, stored in a file called  @test.ledger@:@@ -111,7 +112,7 @@  Executable hledger-interest   Main-is:              Main.hs-  Build-depends:        base >= 3 && < 5, hledger-lib >= 0.14, time, mtl, Cabal+  Build-depends:        base >= 3 && < 5, hledger-lib == 0.14, time, mtl, Cabal   other-modules:        Hledger.Interest                         Hledger.Interest.DayCountConvention                         Hledger.Interest.Rate