1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE NamedFieldPuns #-}
5 {-# LANGUAGE TypeFamilies #-}
6 module Hcompta.Format.JCC.Transaction where
8 import Control.DeepSeq (NFData(..))
9 import Data.Data (Data(..))
10 import Data.Eq (Eq(..))
11 import Data.Function (($), (.), id)
12 import Data.Functor (Functor(..))
13 import Data.Functor.Compose (Compose(..))
14 import qualified Data.List as List
15 import Data.Map.Strict (Map)
16 import qualified Data.Map.Strict as Map
17 import Data.Maybe (Maybe(..))
18 import Data.Monoid (Monoid(..))
19 import Data.Text (Text)
20 import Data.Tuple (fst)
21 import Data.Typeable (Typeable)
22 import Prelude (flip, seq)
23 import Text.Parsec.Pos (SourcePos, initialPos)
24 import Text.Show (Show)
26 import qualified Hcompta.Chart as Chart
27 import Hcompta.Date (Date)
28 import qualified Hcompta.Date as Date
29 import qualified Hcompta.Filter as Filter
30 import qualified Hcompta.GL as GL
31 import qualified Hcompta.Journal as Journal
32 import Hcompta.Lib.Parsec ()
33 import qualified Hcompta.Stats as Stats
34 import Hcompta.Transaction ( Transaction_Tags(..)
35 , Transaction_Anchors(..) )
37 import Hcompta.Format.JCC.Account
38 import Hcompta.Format.JCC.Posting
39 import Hcompta.Format.JCC.Chart
43 -- * Type 'Transaction'
47 { transaction_anchors :: Transaction_Anchors
48 , transaction_comments :: [Comment]
49 , transaction_dates :: (Date, [Date])
50 , transaction_postings :: Map Account [Posting]
51 , transaction_sourcepos :: SourcePos
52 , transaction_tags :: Transaction_Tags
53 , transaction_wording :: Wording
54 } deriving (Data, Eq, Show, Typeable)
55 instance NFData Transaction where
59 , transaction_comments
61 , transaction_postings
62 -- , transaction_sourcepos
66 rnf transaction_anchors `seq`
67 rnf transaction_comments `seq`
68 rnf transaction_dates `seq`
69 rnf transaction_postings `seq`
70 -- rnf transaction_sourcepos `seq`
71 rnf transaction_tags `seq`
72 rnf transaction_wording
74 transaction :: Transaction
77 { transaction_anchors = mempty
78 , transaction_comments = []
79 , transaction_dates = (Date.nil, [])
80 , transaction_postings = mempty
81 , transaction_sourcepos = initialPos ""
82 , transaction_tags = mempty
83 , transaction_wording = ""
86 instance Filter.Transaction (Charted Transaction) where
87 type Transaction_Posting (Charted Transaction) = Charted Posting
88 type Transaction_Postings (Charted Transaction) = Compose (Map Account) []
89 transaction_date = fst . transaction_dates . Chart.charted
90 transaction_wording = transaction_wording . Chart.charted
91 transaction_postings (Chart.Charted c t) =
92 fmap (Chart.Charted c) $
93 Compose $ transaction_postings t
95 transaction_postings_virtual (Chart.Charted c t) =
96 fmap (Chart.Charted c) $
98 [ Compose $ transaction_virtual_postings t
99 , Compose $ transaction_balanced_virtual_postings t
102 transaction_tags = transaction_tags . Chart.charted
104 instance Journal.Transaction Transaction where
105 transaction_date = fst . transaction_dates
106 instance Journal.Transaction (Charted Transaction) where
107 transaction_date = Journal.transaction_date . Chart.charted
109 instance Stats.Transaction Transaction where
110 type Transaction_Posting Transaction = Posting
111 type Transaction_Postings Transaction = Compose (Map Account) []
112 transaction_date = fst . transaction_dates
113 transaction_postings = Compose . transaction_postings
114 transaction_postings_size = Map.size . transaction_postings
115 transaction_tags = transaction_tags
116 instance Stats.Transaction (Charted Transaction) where
117 type Transaction_Posting (Charted Transaction) = Stats.Transaction_Posting Transaction
118 type Transaction_Postings (Charted Transaction) = Stats.Transaction_Postings Transaction
119 transaction_date = Stats.transaction_date . Chart.charted
120 transaction_postings = Stats.transaction_postings . Chart.charted
121 transaction_postings_size = Stats.transaction_postings_size . Chart.charted
122 transaction_tags = Stats.transaction_tags . Chart.charted
124 instance GL.Transaction Transaction where
125 type Transaction_Line Transaction = Transaction
126 type Transaction_Posting Transaction = Posting
127 type Transaction_Postings Transaction = Compose (Map Account) []
128 transaction_line = id
129 transaction_date = fst . transaction_dates
130 transaction_postings = Compose . transaction_postings
131 transaction_postings_filter f t =
132 t{ transaction_postings =
134 (\p -> case List.filter f p of
137 (transaction_postings t)
139 instance GL.Transaction (Charted Transaction) where
140 type Transaction_Line (Charted Transaction) = Transaction
141 type Transaction_Posting (Charted Transaction) = (Charted (GL.Transaction_Posting Transaction))
142 type Transaction_Postings (Charted Transaction) = GL.Transaction_Postings Transaction
143 transaction_line = Chart.charted
144 transaction_date = GL.transaction_date . Chart.charted
145 transaction_postings (Chart.Charted c t) =
146 fmap (Chart.Charted c) $
147 GL.transaction_postings t
148 transaction_postings_filter f (Chart.Charted c t) =
150 t{ transaction_postings =
152 (\p -> case List.filter f $ fmap (Chart.Charted c) p of
154 ps -> Just $ fmap Chart.charted ps)
155 (transaction_postings t)
158 -- | Return a 'Map' associating
159 -- the given 'Transaction's with their respective 'Date'.
160 transaction_by_date :: [Transaction] -> (Compose (Map Date) []) Transaction
161 transaction_by_date =
163 Map.fromListWith (flip mappend) .
164 List.map (\t -> (fst $ transaction_dates t, [t]))