Ajout : rangement.
[tool/hledger.git] / script / hledger-print-csv.hs
diff --git a/script/hledger-print-csv.hs b/script/hledger-print-csv.hs
new file mode 100755 (executable)
index 0000000..cac402a
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/env runhaskell
+{-|
+hledger-print-csv [-f JOURNALFILE]
+
+Print matched journal entries as CSV
+Reads the default or specified journal.
+|-}
+
+import Hledger.Cli
+import Text.CSV
+import Data.Char (isSpace)
+import Data.List (mapAccumL)
+
+argsmode :: Mode RawOpts
+argsmode = (defCommandMode ["print-csv"])
+       { modeHelp = "print matched journal entries as CSV"
+       , modeGroupFlags = Group
+               { groupNamed =
+                       [ ("Input",inputflags)
+                       , ("Reporting",reportflags)
+                       , ("Misc",helpflags)
+                       ]
+               , groupUnnamed = []
+               , groupHidden = []
+               }
+       }
+
+chomp :: String -> String
+chomp = reverse . dropWhile isSpace . reverse . dropWhile isSpace
+
+postingToCSV :: Posting -> CSV
+postingToCSV p =
+       map (\(a@(Amount {aquantity=q,acommodity=c})) ->
+               let a_ = a{acommodity=""} in
+               let amount = showAmount a_ in
+               let commodity = c in
+               let credit = if q < 0 then showAmount $ negate a_ else "" in
+               let debit  = if q > 0 then showAmount a_ else "" in
+               account:amount:commodity:credit:debit:status:comment:[])
+        amounts
+       where
+               Mixed amounts = pamount p
+               status = if pstatus p then "*" else ""
+               account = showAccountName Nothing (ptype p) (paccount p)
+               comment = chomp $ pcomment p
+
+postingsToCSV :: [Posting] -> CSV
+postingsToCSV ps =
+       concatMap postingToCSV ps
+
+transactionToCSV :: Integer -> Transaction -> CSV
+transactionToCSV n t =
+       map (\p -> show n:date:date2:status:code:description:comment:p)
+        (postingsToCSV (tpostings t))
+       where
+               description = tdescription t
+               date = showDate (tdate t)
+               date2 = maybe "" showDate (tdate2 t)
+               status = if tstatus t then "*" else ""
+               code = tcode t
+               comment = chomp $ tcomment t
+
+main :: IO ()
+main = do
+       opts <- getCliOpts argsmode
+       withJournalDo opts $
+        \CliOpts{reportopts_=ropts} j -> do
+               d <- getCurrentDay
+               let ropts_ = ropts{flat_=True}
+               let q = queryFromOpts d ropts_
+               putStrLn $ printCSV $ concat $
+                       ([["nth","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","status","posting-comment"]]:).snd $
+                               mapAccumL (\n e -> (n + 1, transactionToCSV n e)) 0 $
+                                       entriesReport ropts_ q j