    {-# LANGUAGE OverloadedStrings, RecordWildCards, FlexibleInstances, 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.Maybe (fromMaybe)
    import Data.Ord (comparing)
    import Data.Time (fromGregorian)

    import Hledger.Data
    import Hledger.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 :: ReportOpts -> Query -> Journal -> EntriesReport
    entriesReport :: ReportOpts -> Query -> Journal -> EntriesReport
    entriesReport ropts :: ReportOpts
    ropts@ReportOpts{..} q :: Query
    q j :: Journal
    j@Journal{..} =
      (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
    getdate) (EntriesReport -> EntriesReport) -> EntriesReport -> EntriesReport
    forall a b. (a -> b) -> a -> b
    $ (Transaction -> Bool) -> EntriesReport -> EntriesReport
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Query
    q Query -> Transaction -> Bool
    `matchesTransaction`) (EntriesReport -> EntriesReport) -> EntriesReport -> EntriesReport
    forall a b. (a -> b) -> a -> b
    $ (Transaction -> Transaction) -> EntriesReport -> EntriesReport
    forall a b. (a -> b) -> [a] -> [b]
    map Transaction -> Transaction
    tvalue EntriesReport
    jtxns
      where
        getdate :: Transaction -> Day
    getdate = ReportOpts -> Transaction -> Day
    transactionDateFn ReportOpts
    ropts
        -- We may be converting posting amounts to value, per hledger_options.m4.md "Effect of --value on reports".
        tvalue :: Transaction -> Transaction
    tvalue t :: Transaction
    t@Transaction{..} = Transaction
    t{tpostings :: [Posting]
    tpostings=(Posting -> Posting) -> [Posting] -> [Posting]
    forall a b. (a -> b) -> [a] -> [b]
    map Posting -> Posting
    pvalue [Posting]
    tpostings}
          where
            pvalue :: Posting -> Posting
    pvalue p :: Posting
    p = Posting
    -> (ValuationType -> Posting) -> Maybe ValuationType -> Posting
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Posting
    p
              (PriceOracle
    -> Map Text AmountStyle
    -> Day
    -> Maybe Day
    -> Day
    -> Bool
    -> Posting
    -> ValuationType
    -> Posting
    postingApplyValuation (Bool -> Journal -> PriceOracle
    journalPriceOracle Bool
    infer_value_ Journal
    j) (Journal -> Map Text AmountStyle
    journalCommodityStyles Journal
    j) Day
    periodlast Maybe Day
    mreportlast Day
    today Bool
    False Posting
    p)
              Maybe ValuationType
    value_
              where
                periodlast :: Day
    periodlast  = Day -> Maybe Day -> Day
    forall a. a -> Maybe a -> a
    fromMaybe Day
    today (Maybe Day -> Day) -> Maybe Day -> Day
    forall a b. (a -> b) -> a -> b
    $ ReportOpts -> Journal -> Maybe Day
    reportPeriodOrJournalLastDay ReportOpts
    ropts Journal
    j
                mreportlast :: Maybe Day
    mreportlast = ReportOpts -> Maybe Day
    reportPeriodLastDay ReportOpts
    ropts
                today :: Day
    today       = Day -> Maybe Day -> Day
    forall a. a -> Maybe a -> a
    fromMaybe (String -> Day
    forall a. String -> a
    error' "erValue: could not pick a valuation date, ReportOpts today_ is unset") Maybe Day
    today_  -- PARTIAL: should not happen

    tests_EntriesReport :: TestTree
    tests_EntriesReport = String -> [TestTree] -> TestTree
    tests "EntriesReport" [
      String -> [TestTree] -> TestTree
    tests "entriesReport" [
         String -> Assertion -> TestTree
    test "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
    $ ReportOpts -> Query -> Journal -> EntriesReport
    entriesReport ReportOpts
    defreportopts (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
    $ String -> Regexp
    toRegex' "bank") Journal
    samplejournal) Int -> Int -> Assertion
    forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
    @?= 1
        ,String -> Assertion -> TestTree
    test "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
    $ ReportOpts -> Query -> Journal -> EntriesReport
    entriesReport ReportOpts
    defreportopts (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
    $ Year -> Int -> Int -> Day
    fromGregorian 2008 06 01) (Day -> Maybe Day
    forall a. a -> Maybe a
    Just (Day -> Maybe Day) -> Day -> Maybe Day
    forall a b. (a -> b) -> a -> b
    $ Year -> Int -> Int -> Day
    fromGregorian 2008 07 01)) Journal
    samplejournal) Int -> Int -> Assertion
    forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
    @?= 3
      ]
     ]