{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-} module Hcompta.LCC.Transaction where import Control.DeepSeq (NFData(..)) import Data.Data (Data(..)) import Data.Eq (Eq(..)) import Data.Function (($), (.)) -- import Data.Functor (Functor(..), (<$>)) import Data.Functor.Compose (Compose(..)) import qualified Data.List as List import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map -- import Data.Maybe (Maybe(..)) import qualified Data.MonoTraversable as MT import Data.Monoid (Monoid(..)) import Data.NonNull (NonNull) import qualified Data.NonNull as NonNull import Data.String (IsString) import Data.Text (Text) import Data.Typeable (Typeable) import Prelude (flip, seq) import Text.Parsec.Pos (SourcePos, initialPos) import Text.Show (Show) import qualified Hcompta as H import Hcompta.LCC.Account import Hcompta.LCC.Anchor import Hcompta.LCC.Tag import Hcompta.LCC.Posting -- import Hcompta.LCC.Chart -- * Type 'Transaction' data Transaction = Transaction { transaction_anchors :: Transaction_Anchors , transaction_comments :: [Comment] , transaction_dates :: NonNull [Date] , transaction_postings :: Postings , transaction_sourcepos :: SourcePos , transaction_tags :: Transaction_Tags , transaction_wording :: Wording } deriving (Data, Eq, Show, Typeable) instance NFData Transaction where rnf Transaction{..} = rnf transaction_anchors `seq` rnf transaction_comments `seq` rnf transaction_dates `seq` rnf transaction_postings `seq` -- rnf transaction_sourcepos `seq` rnf transaction_tags `seq` rnf transaction_wording instance H.Transaction Transaction type instance H.Date H.:@ Transaction = Date instance H.GetI H.Date Transaction where getI _ = NonNull.head . transaction_dates instance H.SetI H.Date Transaction where setI _ d t = t{transaction_dates = NonNull.ncons d $ NonNull.tail $ transaction_dates t} type instance H.Postings H.:@ Transaction = Postings instance H.GetI H.Postings Transaction where getI _ = transaction_postings instance H.SetI H.Postings Transaction where setI _ transaction_postings t = t{transaction_postings} transaction :: Transaction transaction = Transaction { transaction_anchors = mempty , transaction_comments = [] , transaction_dates = NonNull.ncons H.date_epoch [] , transaction_postings = mempty , transaction_sourcepos = initialPos "" , transaction_tags = mempty , transaction_wording = "" } -- ** Type 'Transaction_Anchor' newtype Transaction_Anchor = Transaction_Anchor Anchor deriving (Data, Eq, NFData, Show, Typeable) -- ** Type 'Transaction_Anchors' newtype Transaction_Anchors = Transaction_Anchors Anchors deriving (Data, Eq, Monoid, NFData, Show, Typeable) type instance MT.Element Transaction_Anchors = Transaction_Anchor -- ** Type 'Transaction_Tag' newtype Transaction_Tag = Transaction_Tag Tag deriving (Data, Eq, NFData, Show, Typeable) -- ** Type 'Transaction_Tags' newtype Transaction_Tags = Transaction_Tags Tags deriving (Data, Eq, Monoid, NFData, Show, Typeable) type instance MT.Element Transaction_Tags = Transaction_Tag -- ** Type 'Transactions' newtype Transactions = Transactions (Map Account [Transaction]) deriving (Data, Eq, NFData, Show, Typeable) type instance MT.Element Transactions = Transaction instance H.Transactions Transactions -- ** Type 'Wording' newtype Wording = Wording Text deriving (Data, Eq, NFData, IsString, Show, Typeable) {- -- Transaction instance H.Transaction Transaction where type Transaction_Posting Transaction = Posting type Transaction_Postings Transaction = Compose (Map Account) [] Posting transaction_date = fst . transaction_dates transaction_description = transaction_wording transaction_postings = Compose . transaction_postings transaction_tags = transaction_tags instance H.Transaction (Charted Transaction) where type Transaction_Posting (Charted Transaction) = H.Transaction_Posting Transaction type Transaction_Postings (Charted Transaction) = H.Transaction_Postings Transaction transaction_date = H.transaction_date . charted transaction_description = H.transaction_description . charted transaction_postings = H.transaction_postings . charted transaction_tags = H.transaction_tags . charted -- Journal instance H.Journal_Transaction Transaction instance H.Journal_Transaction (Charted Transaction) -- Stats instance H.Stats_Transaction Transaction where stats_transaction_postings_count = Map.size . transaction_postings instance H.Stats_Transaction (Charted Transaction) where stats_transaction_postings_count = H.stats_transaction_postings_count . charted -- GL instance H.GL_Transaction Transaction where type GL_Transaction_Line Transaction = Transaction gl_transaction_line = id {- gl_transaction_postings_filter f t = t{ transaction_postings = Map.mapMaybe (\post -> case List.filter f post of [] -> Nothing posts -> Just posts) (transaction_postings t) } -} instance H.GL_Transaction (Charted Transaction) where type GL_Transaction_Line (Charted Transaction) = H.GL_Transaction_Line Transaction gl_transaction_line = H.gl_transaction_line . charted {- gl_transaction_postings_filter f (Charted c t) = Charted c t{ transaction_postings = Map.mapMaybe (\post -> case List.filter f $ ({-Charted c <$>-} post) of [] -> Nothing posts -> Just $ {-charted <$>-} posts) (transaction_postings t) } -} {- instance Filter.Transaction (Charted Transaction) where type Transaction_Posting (Charted Transaction) = Charted Posting type Transaction_Postings (Charted Transaction) = Compose (Map Account) [] transaction_date = fst . transaction_dates . Chart.charted transaction_wording = transaction_wording . Chart.charted transaction_postings (Chart.Charted c t) = fmap (Chart.Charted c) $ Compose $ transaction_postings t {- transaction_postings_virtual (Chart.Charted c t) = fmap (Chart.Charted c) $ Compose [ Compose $ transaction_virtual_postings t , Compose $ transaction_balanced_virtual_postings t ] -} transaction_tags = transaction_tags . Chart.charted -} -} -- | Return a 'Map' associating -- the given 'Transaction's with their respective 'Date'. transaction_by_date :: [Transaction] -> (Compose (Map Date) []) Transaction transaction_by_date = Compose . Map.fromListWith (flip mappend) . List.map (\t -> (NonNull.head $ transaction_dates t, [t]))