1 {-# LANGUAGE BangPatterns #-}
2 {-# LANGUAGE DeriveDataTypeable #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE ScopedTypeVariables #-}
7 {-# LANGUAGE StandaloneDeriving #-}
8 {-# LANGUAGE TupleSections #-}
9 {-# LANGUAGE TypeFamilies #-}
10 module Hcompta.Filter where
12 -- import Control.Applicative (pure, (<$>), (<*>))
13 import Control.Applicative (Const(..))
15 import qualified Data.Fixed
16 import qualified Data.Foldable
17 -- import Data.Foldable (Foldable(..))
18 -- import Data.Functor.Compose (Compose(..))
19 -- import qualified Data.List
20 import Data.Map.Strict (Map)
21 import qualified Data.Map.Strict as Data.Map
22 import qualified Data.Monoid
23 -- import Data.Monoid (Monoid(..))
24 import Data.Text (Text)
25 -- import qualified Data.Text as Text
26 -- import qualified Data.Time.Calendar as Time
27 -- import Data.Traversable (Traversable(..))
28 import Data.Typeable ()
29 import Prelude hiding (filter)
30 import Text.Regex.Base ()
31 import Text.Regex.TDFA ()
32 import Text.Regex.TDFA.Text ()
34 import qualified Data.List.NonEmpty as NonEmpty
35 -- import Data.List.NonEmpty (NonEmpty(..))
36 import Hcompta.Lib.Consable (Consable(..))
37 import Hcompta.Lib.Interval (Interval)
38 import qualified Hcompta.Lib.Interval as Interval
39 import qualified Hcompta.Lib.Regex as Regex
40 import Hcompta.Lib.Regex (Regex)
41 -- import qualified Hcompta.Lib.TreeMap as TreeMap
42 -- import Hcompta.Lib.TreeMap (TreeMap)
43 import qualified Hcompta.Amount as Amount
44 import qualified Hcompta.Amount.Unit as Amount.Unit
45 import qualified Hcompta.Date as Date
46 import Hcompta.Date (Date)
47 import qualified Hcompta.Account as Account
48 import Hcompta.Account (Account)
49 -- import qualified Hcompta.Date as Date
50 import qualified Hcompta.Balance as Balance
51 import qualified Hcompta.GL as GL
52 import qualified Hcompta.Journal as Journal
54 -- * Requirements' interface
59 unit_text :: a -> Text
61 instance Unit Amount.Unit where
62 unit_text = Amount.Unit.text
64 instance Unit Text where
70 ( Ord (Amount_Quantity a)
71 , Show (Amount_Quantity a)
72 , Show (Amount_Unit a)
73 , Unit (Amount_Unit a)
77 type Amount_Quantity a
78 amount_unit :: a -> Amount_Unit a
79 amount_quantity :: a -> Amount_Quantity a
81 instance Amount Amount.Amount where
82 type Amount_Unit Amount.Amount = Amount.Unit
83 type Amount_Quantity Amount.Amount = Amount.Quantity
84 amount_quantity = Amount.quantity
85 amount_unit = Amount.unit
87 instance (Amount a, GL.Amount a)
88 => Amount (Amount.Sum a) where
89 type Amount_Unit (Amount.Sum a) = Amount_Unit a
90 type Amount_Quantity (Amount.Sum a) = Amount_Quantity a
91 amount_quantity = amount_quantity . Amount.sum_balance
92 amount_unit = amount_unit . Amount.sum_balance
96 class Amount (Posting_Amount p)
99 posting_account :: p -> Account
100 posting_amounts :: p -> Map (Amount_Unit (Posting_Amount p)) (Posting_Amount p)
102 -- ** Class 'Transaction'
105 ( Posting (Transaction_Posting t)
106 , Foldable (Transaction_Postings t)
108 => Transaction t where
109 type Transaction_Posting t
110 type Transaction_Postings t :: * -> *
111 transaction_date :: t -> Date
112 transaction_description :: t -> Text
113 transaction_postings :: t -> Transaction_Postings t (Transaction_Posting t)
114 transaction_tags :: t -> Map Text [Text]
116 -- ** Class 'Balance'
118 class Amount (Balance_Amount b)
120 type Balance_Amount b
121 balance_account :: b -> Account
122 balance_amount :: b -> Balance_Amount b
123 balance_positive :: b -> Maybe (Balance_Amount b)
124 balance_negative :: b -> Maybe (Balance_Amount b)
126 instance (Amount a, Balance.Amount a)
127 => Balance (Account, Amount.Sum a) where
128 type Balance_Amount (Account, Amount.Sum a) = a
129 balance_account = fst
130 balance_amount (_, amt) =
132 Amount.Sum_Negative n -> n
133 Amount.Sum_Positive p -> p
134 Amount.Sum_Both n p -> Balance.amount_add n p
135 balance_positive = Amount.sum_positive . snd
136 balance_negative = Amount.sum_negative . snd
140 class Amount (GL_Amount r)
143 gl_account :: r -> Account
145 gl_amount_positive :: r -> Maybe (GL_Amount r)
146 gl_amount_negative :: r -> Maybe (GL_Amount r)
147 gl_amount_balance :: r -> GL_Amount r
148 gl_sum_positive :: r -> Maybe (GL_Amount r)
149 gl_sum_negative :: r -> Maybe (GL_Amount r)
150 gl_sum_balance :: r -> GL_Amount r
152 instance (Amount a, GL.Amount a)
153 => GL (Account, Date, Amount.Sum a, Amount.Sum a) where
154 type GL_Amount (Account, Date, Amount.Sum a, Amount.Sum a) = a
155 gl_account (x, _, _, _) = x
156 gl_date (_, x, _, _) = x
157 gl_amount_positive (_, _, x, _) = Amount.sum_positive x
158 gl_amount_negative (_, _, x, _) = Amount.sum_negative x
159 gl_amount_balance (_, _, x, _) = Amount.sum_balance x
160 gl_sum_positive (_, _, _, x) = Amount.sum_positive x
161 gl_sum_negative (_, _, _, x) = Amount.sum_negative x
162 gl_sum_balance (_, _, _, x) = Amount.sum_balance x
164 -- * Newtypes to avoid overlapping instances
168 instance Functor Scalar where
169 fmap f (Scalar x) = Scalar (f x)
174 = Simplified (Either p Bool)
176 simplified :: Simplified p -> Either p Bool
177 simplified (Simplified x) = x
179 instance Functor Simplified where
180 fmap _f (Simplified (Right b)) = Simplified (Right b)
181 fmap f (Simplified (Left x)) = Simplified (Left $ f x)
182 instance Filter p x => Filter (Simplified p) x where
183 test (Simplified (Right b)) _x = b
184 test (Simplified (Left f)) x = test f x
185 simplify (Simplified (Right b)) _x = Simplified $ Right b
186 simplify (Simplified (Left f)) x =
188 case simplified $ simplify f x of
190 Left sf -> Left (Simplified $ Left sf)
192 -- | Conjonctive ('&&') 'Monoid'.
193 instance Monoid p => Monoid (Simplified p) where
194 mempty = Simplified (Right True)
195 mappend (Simplified x) (Simplified y) =
198 (Right bx , Right by ) -> Right (bx && by)
199 (Right True , Left _fy ) -> y
200 (Right False, Left _fy ) -> x
201 (Left _fx , Right True ) -> x
202 (Left _fx , Right False) -> y
203 (Left fx , Left fy ) -> Left $ fx `mappend` fy
205 class Filter p x where
206 test :: p -> x -> Bool
207 simplify :: p -> Maybe x -> Simplified p
208 simplify p _x = Simplified $ Left p
211 :: (Foldable t, Filter p x, Monoid x)
214 Data.Foldable.foldMap
215 (\x -> if test p x then x else mempty)
217 -- ** Type 'Filter_Text'
221 | Filter_Text_Exact Text
222 | Filter_Text_Regex Regex
223 deriving (Eq, Show, Typeable)
225 instance Filter Filter_Text Text where
228 Filter_Text_Any -> True
229 Filter_Text_Exact m -> (==) m x
230 Filter_Text_Regex m -> Regex.match m x
232 -- ** Type 'Filter_Ord'
241 deriving (Data, Eq, Show, Typeable)
243 instance Functor Filter_Ord where
246 Filter_Ord_Lt o -> Filter_Ord_Lt (f o)
247 Filter_Ord_Le o -> Filter_Ord_Le (f o)
248 Filter_Ord_Gt o -> Filter_Ord_Gt (f o)
249 Filter_Ord_Ge o -> Filter_Ord_Ge (f o)
250 Filter_Ord_Eq o -> Filter_Ord_Eq (f o)
251 Filter_Ord_Any -> Filter_Ord_Any
252 instance (Ord o, o ~ x)
253 => Filter (Filter_Ord o) (Scalar x) where
256 Filter_Ord_Lt o -> (<) x o
257 Filter_Ord_Le o -> (<=) x o
258 Filter_Ord_Gt o -> (>) x o
259 Filter_Ord_Ge o -> (>=) x o
260 Filter_Ord_Eq o -> (==) x o
261 Filter_Ord_Any -> True
262 instance (Ord o, o ~ x)
263 => Filter (Filter_Ord o) (Interval x) where
265 let l = Interval.low i in
266 let h = Interval.high i in
268 Filter_Ord_Lt o -> case compare (Interval.limit h) o of
270 EQ -> Interval.adherence h == Interval.Out
272 Filter_Ord_Le o -> Interval.limit h <= o
273 Filter_Ord_Gt o -> case compare (Interval.limit l) o of
275 EQ -> Interval.adherence l == Interval.Out
277 Filter_Ord_Ge o -> Interval.limit l >= o
278 Filter_Ord_Eq o -> Interval.limit l == o && Interval.limit h == o
279 Filter_Ord_Any -> True
281 -- ** Type 'Filter_Interval'
283 data Filter_Interval x
284 = Filter_Interval_In (Interval (Interval.Unlimitable x))
285 deriving (Eq, Ord, Show)
286 --instance Functor Filter_Interval where
287 -- fmap f (Filter_Interval_In i) = Filter_Interval_In (fmap (fmap f) i)
288 instance (Ord o, o ~ x)
289 => Filter (Filter_Interval o) (Scalar (Interval.Unlimitable x)) where
290 test (Filter_Interval_In p) (Scalar x) =
291 Interval.locate x p == EQ
292 instance (Ord o, o ~ x)
293 => Filter (Filter_Interval o) (Interval (Interval.Unlimitable x)) where
294 test (Filter_Interval_In p) i = Interval.into i p
296 -- ** Type 'Filter_Num_Abs'
300 = Filter_Num_Abs (Filter_Ord n)
301 deriving (Data, Eq, Show, Typeable)
303 instance (Num n, Ord x, n ~ x)
304 => Filter (Filter_Num_Abs n) x where
305 test (Filter_Num_Abs f) x = test f (Scalar (abs x))
307 -- ** Type 'Filter_Bool'
312 | Not (Filter_Bool p)
313 | And (Filter_Bool p) (Filter_Bool p)
314 | Or (Filter_Bool p) (Filter_Bool p)
316 deriving instance Eq p => Eq (Filter_Bool p)
317 instance Functor Filter_Bool where
319 fmap f (Bool x) = Bool (f x)
320 fmap f (Not t) = Not (fmap f t)
321 fmap f (And t0 t1) = And (fmap f t0) (fmap f t1)
322 fmap f (Or t0 t1) = Or (fmap f t0) (fmap f t1)
323 -- | Conjonctive ('And') 'Monoid'.
324 instance Monoid (Filter_Bool p) where
327 instance Foldable Filter_Bool where
328 foldr _ acc Any = acc
329 foldr f acc (Bool p) = f p acc
330 foldr f acc (Not t) = Data.Foldable.foldr f acc t
331 foldr f acc (And t0 t1) = Data.Foldable.foldr f (Data.Foldable.foldr f acc t0) t1
332 foldr f acc (Or t0 t1) = Data.Foldable.foldr f (Data.Foldable.foldr f acc t0) t1
333 instance Traversable Filter_Bool where
334 traverse _ Any = pure Any
335 traverse f (Bool x) = Bool <$> f x
336 traverse f (Not t) = Not <$> traverse f t
337 traverse f (And t0 t1) = And <$> traverse f t0 <*> traverse f t1
338 traverse f (Or t0 t1) = Or <$> traverse f t0 <*> traverse f t1
339 instance Filter p x => Filter (Filter_Bool p) x where
341 test (Bool p) x = test p x
342 test (Not t) x = not $ test t x
343 test (And t0 t1) x = test t0 x && test t1 x
344 test (Or t0 t1) x = test t0 x || test t1 x
346 simplify Any _ = Simplified $ Right True
347 simplify (Bool p) x =
349 case simplified (simplify p x) of
350 Left p' -> Left (Bool p')
354 case simplified (simplify t x) of
355 Left p' -> Left (Not $ p')
357 simplify (And t0 t1) x =
359 case (simplified $ simplify t0 x, simplified $ simplify t1 x) of
360 (Right b0, Right b1) -> Right (b0 && b1)
361 (Right b0, Left p1) -> if b0 then Left p1 else Right False
362 (Left p0, Right b1) -> if b1 then Left p0 else Right False
363 (Left p0, Left p1) -> Left (And p0 p1)
364 simplify (Or t0 t1) x =
366 case (simplified $ simplify t0 x, simplified $ simplify t1 x) of
367 (Right b0, Right b1) -> Right (b0 || b1)
368 (Right b0, Left p1) -> if b0 then Right True else Left p1
369 (Left p0, Right b1) -> if b1 then Right True else Left p0
370 (Left p0, Left p1) -> Left (Or p0 p1)
372 bool :: Filter p x => Filter_Bool p -> x -> Bool
374 bool (Bool p) x = test p x
375 bool (Not t) x = not $ test t x
376 bool (And t0 t1) x = test t0 x && test t1 x
377 bool (Or t0 t1) x = test t0 x || test t1 x
379 -- ** Type 'Filter_Unit'
382 = Filter_Unit Filter_Text
383 deriving (Eq, Show, Typeable)
385 instance Unit u => Filter Filter_Unit u where
386 test (Filter_Unit f) = test f . unit_text
388 -- ** Type 'Filter_Account'
391 = [Filter_Account_Section]
393 data Filter_Account_Section
394 = Filter_Account_Section_Any
395 | Filter_Account_Section_Many
396 | Filter_Account_Section_Text Filter_Text
397 deriving (Eq, Show, Typeable)
399 instance Filter Filter_Account Account where
401 comp f (NonEmpty.toList acct)
403 comp :: [Filter_Account_Section] -> [Account.Name] -> Bool
405 comp [Filter_Account_Section_Many] _ = True
410 Filter_Account_Section_Any -> True
411 Filter_Account_Section_Many -> True
412 Filter_Account_Section_Text m -> test m n
414 comp so@(s:ss) no@(n:ns) =
416 Filter_Account_Section_Any -> comp ss ns
417 Filter_Account_Section_Many -> comp ss no || comp so ns
418 Filter_Account_Section_Text m -> test m n && comp ss ns
421 -- ** Type 'Filter_Amount'
423 type Filter_Quantity q
429 { filter_amount_quantity :: Filter_Quantity (Amount_Quantity a)
430 , filter_amount_unit :: Filter_Unit
431 } deriving (Typeable)
432 deriving instance Amount a => Eq (Filter_Amount a)
433 deriving instance Amount a => Show (Filter_Amount a)
436 => Filter (Filter_Amount a) a where
437 test (Filter_Amount fq fu) amt =
438 test fu (amount_unit amt) &&
439 test fq (Scalar (amount_quantity amt))
441 -- ** Type 'Filter_Date'
444 = Filter_Date_UTC (Filter_Ord Date)
445 | Filter_Date_Year (Filter_Interval Integer)
446 | Filter_Date_Month (Filter_Interval Int)
447 | Filter_Date_DoM (Filter_Interval Int)
448 | Filter_Date_Hour (Filter_Interval Int)
449 | Filter_Date_Minute (Filter_Interval Int)
450 | Filter_Date_Second (Filter_Interval Data.Fixed.Pico)
452 deriving instance Show (Filter_Date)
454 instance Filter Filter_Date Date where
455 test (Filter_Date_UTC f) d = test f $ Scalar d
456 test (Filter_Date_Year f) d = test f $ Scalar $ Interval.Limited $ Date.year d
457 test (Filter_Date_Month f) d = test f $ Scalar $ Interval.Limited $ Date.month d
458 test (Filter_Date_DoM f) d = test f $ Scalar $ Interval.Limited $ Date.dom d
459 test (Filter_Date_Hour f) d = test f $ Scalar $ Interval.Limited $ Date.hour d
460 test (Filter_Date_Minute f) d = test f $ Scalar $ Interval.Limited $ Date.minute d
461 test (Filter_Date_Second f) d = test f $ Scalar $ Interval.Limited $ Date.second d
463 instance Filter Filter_Date (Interval (Interval.Unlimitable Date)) where
464 test (Filter_Date_UTC f) d = test (Interval.Limited <$> f) d
465 test (Filter_Date_Year f) d = maybe False (test f) $ Interval.fmap (fmap Date.year) d
466 test (Filter_Date_Month f) d = maybe False (test f) $ Interval.fmap (fmap Date.month) d
467 test (Filter_Date_DoM f) d = maybe False (test f) $ Interval.fmap (fmap Date.dom) d
468 test (Filter_Date_Hour f) d = maybe False (test f) $ Interval.fmap (fmap Date.hour) d
469 test (Filter_Date_Minute f) d = maybe False (test f) $ Interval.fmap (fmap Date.minute) d
470 test (Filter_Date_Second f) d = maybe False (test f) $ Interval.fmap (fmap Date.second) d
472 -- ** Type 'Filter_Tag'
475 = Filter_Tag_Name Filter_Text
476 | Filter_Tag_Value Filter_Text
478 deriving instance Show (Filter_Tag)
480 instance Filter Filter_Tag (Text, Text) where
481 test (Filter_Tag_Name f) (x, _) = test f x
482 test (Filter_Tag_Value f) (_, x) = test f x
484 -- ** Type 'Filter_Posting'
487 => Filter_Posting posting
488 = Filter_Posting_Account Filter_Account
489 | Filter_Posting_Amount (Filter_Amount (Posting_Amount posting))
490 | Filter_Posting_Unit Filter_Unit
493 -- Description Comp_String String
495 -- Account_Tag Comp_String String (Maybe (Comp_String, String))
496 -- Account_Balance Comp_Num Comp_Num_Absolute Amount
497 -- Depth Comp_Num Int
501 -- Tag Comp_String Tag.Name (Maybe (Comp_String, Tag.Value))
502 deriving instance Posting p => Eq (Filter_Posting p)
503 deriving instance Posting p => Show (Filter_Posting p)
506 => Filter (Filter_Posting p) p where
507 test (Filter_Posting_Account f) p =
508 test f $ posting_account p
509 test (Filter_Posting_Amount f) p =
510 Data.Foldable.any (test f) $ posting_amounts p
511 test (Filter_Posting_Unit f) p =
512 Data.Foldable.any (test f . amount_unit) $ posting_amounts p
514 newtype Cross t = Cross t
515 instance (Transaction t, Transaction_Posting t ~ p, Posting p)
516 => Filter (Filter_Transaction t) (Cross p) where
519 (Filter_Transaction_Description _) -> True
520 (Filter_Transaction_Posting f) -> test f p
521 (Filter_Transaction_Date _) -> True -- TODO: use posting_date
522 (Filter_Transaction_Tag _) -> False -- TODO: use posting_tags
524 -- ** Type 'Filter_Transaction'
527 => Filter_Transaction t
528 = Filter_Transaction_Description Filter_Text
529 | Filter_Transaction_Posting (Filter_Posting (Transaction_Posting t))
530 | Filter_Transaction_Date (Filter_Bool Filter_Date)
531 | Filter_Transaction_Tag (Filter_Bool Filter_Tag)
533 deriving instance Transaction t => Show (Filter_Transaction t)
535 instance Transaction t
536 => Filter (Filter_Transaction t) t where
537 test (Filter_Transaction_Description f) t =
538 test f $ transaction_description t
539 test (Filter_Transaction_Posting f) t =
540 Data.Foldable.any (test f) $
541 transaction_postings t
542 test (Filter_Transaction_Date f) t =
543 test f $ transaction_date t
544 test (Filter_Transaction_Tag f) t =
546 Data.Map.foldrWithKey
547 (\n -> mappend . Data.Monoid.Any .
548 Data.Foldable.any (test f . (n,)))
549 (Data.Monoid.Any False) $
553 ( Transaction transaction
554 , Journal.Transaction transaction
557 ( Journal.Journal transaction
560 (Filter_Transaction transaction))
563 mcons t (Const (!j, ft)) =
566 then Journal.journal t j
571 , Transaction transaction
572 , Journal.Transaction transaction
575 ( Journal.Journal transaction
578 (Filter_Transaction transaction))
580 (foldable transaction) where
581 mcons ts (Const (!j, ft)) =
583 case simplified ft of
593 then Journal.journal t
597 -- ** Type 'Filter_Balance'
601 = Filter_Balance_Account Filter_Account
602 | Filter_Balance_Amount (Filter_Amount (Balance_Amount b))
603 | Filter_Balance_Positive (Filter_Amount (Balance_Amount b))
604 | Filter_Balance_Negative (Filter_Amount (Balance_Amount b))
606 deriving instance Balance b => Eq (Filter_Balance b)
607 deriving instance Balance b => Show (Filter_Balance b)
610 => Filter (Filter_Balance b) b where
611 test (Filter_Balance_Account f) b =
612 test f $ balance_account b
613 test (Filter_Balance_Amount f) b =
614 test f $ balance_amount b
615 test (Filter_Balance_Positive f) b =
616 Data.Foldable.any (test f) $
618 test (Filter_Balance_Negative f) b =
619 Data.Foldable.any (test f) $
623 ( Balance.Posting posting
625 , amount ~ Balance.Posting_Amount posting
628 ( Balance.Balance_by_Account amount
631 (Filter_Posting posting))
634 mcons p (Const (!b, fp)) =
636 case simplified fp of
638 Right True -> Balance.by_account p b
641 then Balance.by_account p b
645 ( Transaction transaction
646 , posting ~ Transaction_Posting transaction
647 , amount ~ Balance.Posting_Amount posting
648 , Balance.Amount amount
649 , Balance.Posting posting
652 ( Balance.Balance_by_Account amount
655 (Filter_Transaction transaction))
658 (Filter_Posting posting))
661 mcons t (Const (!bal, ft, fp)) =
663 case simplified ft of
665 Right True -> filter_postings $ transaction_postings t
668 then filter_postings $ transaction_postings t
670 where filter_postings ps =
671 case simplified fp of
675 (flip Balance.by_account)
679 (\b p -> if test ff p then Balance.by_account p b else b)
683 , Balance.Posting posting
685 , amount ~ Balance.Posting_Amount posting
688 ( Balance.Balance_by_Account amount
691 (Filter_Posting posting))
693 (foldable posting) where
694 mcons ps (Const (!bal, fp)) =
696 case simplified fp of
700 (flip Balance.by_account) bal ps
702 Data.Foldable.foldl' (\b p ->
704 then Balance.by_account p b
707 -- ** Type 'Filter_GL'
711 = Filter_GL_Account Filter_Account
712 | Filter_GL_Amount_Positive (Filter_Amount (GL_Amount r))
713 | Filter_GL_Amount_Negative (Filter_Amount (GL_Amount r))
714 | Filter_GL_Amount_Balance (Filter_Amount (GL_Amount r))
715 | Filter_GL_Sum_Positive (Filter_Amount (GL_Amount r))
716 | Filter_GL_Sum_Negative (Filter_Amount (GL_Amount r))
717 | Filter_GL_Sum_Balance (Filter_Amount (GL_Amount r))
719 deriving instance GL r => Eq (Filter_GL r)
720 deriving instance GL r => Show (Filter_GL r)
723 => Filter (Filter_GL r) r where
724 test (Filter_GL_Account f) r =
725 test f $ gl_account r
726 test (Filter_GL_Amount_Positive f) r =
727 Data.Foldable.any (test f) $
729 test (Filter_GL_Amount_Negative f) r =
730 Data.Foldable.any (test f) $
732 test (Filter_GL_Amount_Balance f) r =
733 test f $ gl_amount_balance r
734 test (Filter_GL_Sum_Positive f) r =
735 Data.Foldable.any (test f) $
737 test (Filter_GL_Sum_Negative f) r =
738 Data.Foldable.any (test f) $
740 test (Filter_GL_Sum_Balance f) r =
741 test f $ gl_sum_balance r
744 ( GL.Transaction transaction
745 , Transaction transaction
747 , posting ~ GL.Transaction_Posting transaction
753 (Filter_Transaction transaction))
756 (Filter_Posting posting))
759 mcons t (Const (!gl, ft, fp)) =
761 case simplified ft of
764 case simplified fp of
766 Right True -> GL.general_ledger t gl
769 (GL.transaction_postings_filter (test f) t)
774 case simplified fp of
776 Right True -> GL.general_ledger t gl
779 (GL.transaction_postings_filter (test ff) t)
784 , GL.Transaction transaction
785 , Transaction transaction
787 , posting ~ GL.Transaction_Posting transaction
793 (Filter_Transaction transaction))
796 (Filter_Posting posting))
798 (foldable transaction) where
799 mcons ts (Const (!gl, ft, fp)) =
801 case simplified ft of
804 case simplified fp of
813 . GL.transaction_postings_filter (test f) )
820 case simplified fp of
822 Right True -> GL.general_ledger t
823 Left ff -> GL.general_ledger $
824 GL.transaction_postings_filter (test ff) t