{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-|

Journal entries report, used by the print command.

-}

module Hledger.Reports.EntriesReport (
  EntriesReport,
  EntriesReportItem,
  entriesReport,
  -- * Tests
  tests_EntriesReport
)
where

import Data.List (sortBy)
import Data.Ord (comparing)
import Data.Time (fromGregorian)

import Hledger.Data
import Hledger.Query (Query(..))
import Hledger.Reports.ReportOptions
import Hledger.Utils


-- | A journal entries report is a list of whole transactions as
-- originally entered in the journal (mostly). This is used by eg
-- hledger's print command and hledger-web's journal entries view.
type EntriesReport = [EntriesReportItem]
type EntriesReportItem = Transaction

-- | Select transactions for an entries report.
entriesReport :: ReportSpec -> Journal -> EntriesReport
entriesReport :: ReportSpec -> Journal -> EntriesReport
entriesReport rspec :: ReportSpec
rspec@ReportSpec{rsOpts :: ReportSpec -> ReportOpts
rsOpts=ReportOpts
ropts} =
    (Transaction -> Transaction -> Ordering)
-> EntriesReport -> EntriesReport
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((Transaction -> Day) -> Transaction -> Transaction -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ((Transaction -> Day) -> Transaction -> Transaction -> Ordering)
-> (Transaction -> Day) -> Transaction -> Transaction -> Ordering
forall a b. (a -> b) -> a -> b
$ ReportOpts -> Transaction -> Day
transactionDateFn ReportOpts
ropts) (EntriesReport -> EntriesReport)
-> (Journal -> EntriesReport) -> Journal -> EntriesReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Journal -> EntriesReport
jtxns
    (Journal -> EntriesReport)
-> (Journal -> Journal) -> Journal -> EntriesReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReportSpec -> Journal -> Journal
journalApplyValuationFromOpts ReportSpec
rspec{rsOpts :: ReportOpts
rsOpts=ReportOpts
ropts{show_costs_ :: Bool
show_costs_=Bool
True}}
    (Journal -> Journal) -> (Journal -> Journal) -> Journal -> Journal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Query -> Journal -> Journal
filterJournalTransactions (ReportSpec -> Query
rsQuery ReportSpec
rspec)

tests_EntriesReport :: TestTree
tests_EntriesReport = String -> [TestTree] -> TestTree
tests String
"EntriesReport" [
  String -> [TestTree] -> TestTree
tests String
"entriesReport" [
     String -> Assertion -> TestTree
test String
"not acct" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ (EntriesReport -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (EntriesReport -> Int) -> EntriesReport -> Int
forall a b. (a -> b) -> a -> b
$ ReportSpec -> Journal -> EntriesReport
entriesReport ReportSpec
defreportspec{rsQuery :: Query
rsQuery=Query -> Query
Not (Query -> Query) -> (Regexp -> Query) -> Regexp -> Query
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Regexp -> Query
Acct (Regexp -> Query) -> Regexp -> Query
forall a b. (a -> b) -> a -> b
$ Text -> Regexp
toRegex' Text
"bank"} Journal
samplejournal) Int -> Int -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Int
1
    ,String -> Assertion -> TestTree
test String
"date" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ (EntriesReport -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (EntriesReport -> Int) -> EntriesReport -> Int
forall a b. (a -> b) -> a -> b
$ ReportSpec -> Journal -> EntriesReport
entriesReport ReportSpec
defreportspec{rsQuery :: Query
rsQuery=DateSpan -> Query
Date (DateSpan -> Query) -> DateSpan -> Query
forall a b. (a -> b) -> a -> b
$ Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ Integer -> Int -> Int -> Day
fromGregorian Integer
2008 Int
06 Int
01) (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ Integer -> Int -> Int -> Day
fromGregorian Integer
2008 Int
07 Int
01)} Journal
samplejournal) Int -> Int -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Int
3
  ]
 ]