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 (Const(..))
13 -- import Control.Applicative (pure, (<$>), (<*>))
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
168 test :: p -> Filter_Key p -> Bool
169 simplify :: p -> Simplified p
170 -- simplify p = Simplified $ Left p
171 -- | Type to pass an 'Interval' to 'test'.
172 newtype With_Interval t
176 :: (Foldable t, Filter p, Monoid (Filter_Key p))
177 => p -> t (Filter_Key p) -> Filter_Key p
179 Data.Foldable.foldMap
180 (\x -> if test p x then x else mempty)
182 -- ** Type 'Simplified'
184 newtype Simplified filter
185 = Simplified (Either filter Bool)
187 simplified :: Simplified f -> Either f Bool
188 simplified (Simplified e) = e
190 instance Functor Simplified where
191 fmap _f (Simplified (Right b)) = Simplified (Right b)
192 fmap f (Simplified (Left x)) = Simplified (Left $ f x)
193 instance Filter f => Filter (Simplified f) where
194 type Filter_Key (Simplified f) = Filter_Key f
195 test (Simplified (Right b)) _x = b
196 test (Simplified (Left f)) x = test f x
197 simplify (Simplified (Right b)) = Simplified $ Right b
198 simplify (Simplified (Left f)) =
200 case simplified $ simplify f of
202 Left sf -> Left (Simplified $ Left sf)
203 -- | Conjonctive ('&&') 'Monoid'.
204 instance Monoid f => Monoid (Simplified f) where
205 mempty = Simplified (Right True)
206 mappend (Simplified x) (Simplified y) =
209 (Right bx , Right by ) -> Right (bx && by)
210 (Right True , Left _fy ) -> y
211 (Right False, Left _fy ) -> x
212 (Left _fx , Right True ) -> x
213 (Left _fx , Right False) -> y
214 (Left fx , Left fy ) -> Left $ fx `mappend` fy
216 -- ** Type 'Filter_Text'
220 | Filter_Text_Exact Text
221 | Filter_Text_Regex Regex
222 deriving (Eq, Show, Typeable)
224 instance Filter Filter_Text where
225 type Filter_Key Filter_Text = Text
228 Filter_Text_Any -> True
229 Filter_Text_Exact m -> (==) m x
230 Filter_Text_Regex m -> Regex.match m x
234 Filter_Text_Any -> Right True
237 -- ** Type 'Filter_Ord'
240 = Lt -- ^ Lower than.
241 | Le -- ^ Lower or equal.
243 | Ge -- ^ Greater or equal.
244 | Gt -- ^ Greater than.
245 deriving (Data, Eq, Show, Typeable)
250 deriving (Data, Eq, Show, Typeable)
251 instance Functor Filter_Ord where
254 Filter_Ord Lt o -> Filter_Ord Lt (f o)
255 Filter_Ord Le o -> Filter_Ord Le (f o)
256 Filter_Ord Eq o -> Filter_Ord Eq (f o)
257 Filter_Ord Ge o -> Filter_Ord Ge (f o)
258 Filter_Ord Gt o -> Filter_Ord Gt (f o)
259 Filter_Ord_Any -> Filter_Ord_Any
261 => Filter (Filter_Ord o) where
262 type Filter_Key (Filter_Ord o) = o
265 Filter_Ord Lt o -> (<) x o
266 Filter_Ord Le o -> (<=) x o
267 Filter_Ord Eq o -> (==) x o
268 Filter_Ord Ge o -> (>=) x o
269 Filter_Ord Gt o -> (>) x o
270 Filter_Ord_Any -> True
274 Filter_Ord_Any -> Right True
277 => Filter (With_Interval (Filter_Ord o)) where
278 type Filter_Key (With_Interval (Filter_Ord o)) = Interval o
279 test (With_Interval f) i =
280 let l = Interval.low i in
281 let h = Interval.high i in
283 Filter_Ord Lt o -> case compare (Interval.limit h) o of
285 EQ -> Interval.adherence h == Interval.Out
287 Filter_Ord Le o -> Interval.limit h <= o
288 Filter_Ord Eq o -> Interval.limit l == o && Interval.limit h == o
289 Filter_Ord Ge o -> Interval.limit l >= o
290 Filter_Ord Gt o -> case compare (Interval.limit l) o of
292 EQ -> Interval.adherence l == Interval.Out
294 Filter_Ord_Any -> True
298 With_Interval Filter_Ord_Any -> Right True
301 -- ** Type 'Filter_Interval'
303 data Filter_Interval x
304 = Filter_Interval_In (Interval (Interval.Unlimitable x))
305 deriving (Eq, Ord, Show)
306 --instance Functor Filter_Interval where
307 -- fmap f (Filter_Interval_In i) = Filter_Interval_In (fmap (fmap f) i)
309 => Filter (Filter_Interval o) where
310 type Filter_Key (Filter_Interval o) = Interval.Unlimitable o
311 test (Filter_Interval_In i) x =
312 Interval.locate x i == EQ
313 simplify = Simplified . Left
315 => Filter (With_Interval (Filter_Interval o)) where
316 type Filter_Key (With_Interval (Filter_Interval o)) = Interval (Interval.Unlimitable o)
317 test (With_Interval (Filter_Interval_In i)) x = Interval.into x i
318 simplify = Simplified . Left
320 -- ** Type 'Filter_Num_Abs'
324 = Filter_Num_Abs (Filter_Ord n)
325 deriving (Data, Eq, Show, Typeable)
327 instance (Num x, Ord x)
328 => Filter (Filter_Num_Abs x) where
329 type Filter_Key (Filter_Num_Abs x) = x
330 test (Filter_Num_Abs f) x = test f (abs x)
333 Filter_Num_Abs ff -> Filter_Num_Abs <$> simplify ff
335 -- ** Type 'Filter_Bool'
340 | Not (Filter_Bool f)
341 | And (Filter_Bool f) (Filter_Bool f)
342 | Or (Filter_Bool f) (Filter_Bool f)
343 deriving (Eq, Show, Typeable)
344 instance Functor Filter_Bool where
346 fmap f (Bool x) = Bool (f x)
347 fmap f (Not t) = Not (fmap f t)
348 fmap f (And t0 t1) = And (fmap f t0) (fmap f t1)
349 fmap f (Or t0 t1) = Or (fmap f t0) (fmap f t1)
350 -- | Conjonctive ('And') 'Monoid'.
351 instance Monoid (Filter_Bool f) where
354 instance Foldable Filter_Bool where
355 foldr _ acc Any = acc
356 foldr m acc (Bool f) = m f acc
357 foldr m acc (Not f) = Data.Foldable.foldr m acc f
358 foldr m acc (And f0 f1) = Data.Foldable.foldr m (Data.Foldable.foldr m acc f0) f1
359 foldr m acc (Or f0 f1) = Data.Foldable.foldr m (Data.Foldable.foldr m acc f0) f1
360 instance Traversable Filter_Bool where
361 traverse _ Any = pure Any
362 traverse m (Bool f) = Bool <$> m f
363 traverse m (Not f) = Not <$> traverse m f
364 traverse m (And f0 f1) = And <$> traverse m f0 <*> traverse m f1
365 traverse m (Or f0 f1) = Or <$> traverse m f0 <*> traverse m f1
367 => Filter (Filter_Bool f) where
368 type Filter_Key (Filter_Bool f) = Filter_Key f
370 test (Bool f) x = test f x
371 test (Not f) x = not $ test f x
372 test (And f0 f1) x = test f0 x && test f1 x
373 test (Or f0 f1) x = test f0 x || test f1 x
375 simplify Any = Simplified $ Right True
376 simplify (Bool f) = Bool <$> simplify f
379 case simplified (simplify f) of
380 Left ff -> Left $ Not ff
381 Right b -> Right $ not b
382 simplify (And f0 f1) =
385 ( simplified $ simplify f0
386 , simplified $ simplify f1 ) of
387 (Right b0, Right b1) -> Right $ b0 && b1
388 (Right b0, Left s1) -> if b0 then Left s1 else Right False
389 (Left s0, Right b1) -> if b1 then Left s0 else Right False
390 (Left s0, Left s1) -> Left $ And s0 s1
391 simplify (Or f0 f1) =
394 ( simplified $ simplify f0
395 , simplified $ simplify f1 ) of
396 (Right b0, Right b1) -> Right $ b0 || b1
397 (Right b0, Left s1) -> if b0 then Right True else Left s1
398 (Left s0, Right b1) -> if b1 then Right True else Left s0
399 (Left s0, Left s1) -> Left $ Or s0 s1
401 -- ** Type 'Filter_Unit'
403 newtype Filter_Unit u
404 = Filter_Unit Filter_Text
405 deriving (Eq, Show, Typeable)
408 => Filter (Filter_Unit u) where
409 type Filter_Key (Filter_Unit u) = u
410 test (Filter_Unit f) = test f . unit_text
413 Filter_Unit ff -> Filter_Unit <$> simplify ff
415 -- ** Type 'Filter_Account'
418 = Filter_Account Order [Filter_Account_Section]
419 deriving (Eq, Show, Typeable)
421 data Filter_Account_Section
422 = Filter_Account_Section_Any
423 | Filter_Account_Section_Many
424 | Filter_Account_Section_Text Filter_Text
425 deriving (Eq, Show, Typeable)
427 instance Filter Filter_Account where
428 type Filter_Key Filter_Account = Account
429 test (Filter_Account ord flt) acct =
430 go ord (NonEmpty.toList acct) flt
432 go :: Order -> [Account.Name] -> [Filter_Account_Section] -> Bool
440 go o _ [Filter_Account_Section_Many] =
457 Filter_Account_Section_Any -> True
458 Filter_Account_Section_Many -> True
459 Filter_Account_Section_Text m -> test m n
461 go o no@(n:ns) fo@(f:fs) =
463 Filter_Account_Section_Any -> go o ns fs
464 Filter_Account_Section_Many -> go o no fs || go o ns fo
465 Filter_Account_Section_Text m -> test m n && go o ns fs
475 Filter_Account o [Filter_Account_Section_Many] ->
483 Filter_Account o [] ->
491 Filter_Account o fa ->
492 Filter_Account o <$> go fa
494 go :: [Filter_Account_Section] -> Simplified [Filter_Account_Section]
497 [] -> Simplified $ Left []
499 case simplified $ simplify_section ff of
500 Left fff -> ((fff :) <$> go l)
501 Right True -> ((Filter_Account_Section_Any :) <$> go l)
502 Right False -> Simplified $ Right False
505 Filter_Account_Section_Any -> Simplified $ Left $ Filter_Account_Section_Any
506 Filter_Account_Section_Many -> Simplified $ Left $ Filter_Account_Section_Many
507 Filter_Account_Section_Text ff -> Filter_Account_Section_Text <$> simplify ff
509 -- ** Type 'Filter_Amount'
511 type Filter_Quantity q
515 = [Filter_Amount_Section a]
518 => Filter_Amount_Section a
519 = Filter_Amount_Section_Quantity (Filter_Quantity (Amount_Quantity a))
520 | Filter_Amount_Section_Unit (Filter_Unit (Amount_Unit a))
522 deriving instance Amount a => Eq (Filter_Amount_Section a)
523 deriving instance Amount a => Show (Filter_Amount_Section a)
526 => Filter (Filter_Amount a) where
527 type Filter_Key (Filter_Amount a) = a
531 Filter_Amount_Section_Quantity fff -> test fff $ amount_quantity a
532 Filter_Amount_Section_Unit fff -> test fff $ amount_unit a)
538 [] -> Simplified $ Right True
540 case simplified $ simplify_section ff of
541 Left fff -> (:) fff <$> go l
543 Right False -> Simplified $ Right False
546 Filter_Amount_Section_Quantity ff -> Filter_Amount_Section_Quantity <$> simplify ff
547 Filter_Amount_Section_Unit ff -> Filter_Amount_Section_Unit <$> simplify ff
549 -- ** Type 'Filter_Date'
552 = Filter_Date_UTC (Filter_Ord Date)
553 | Filter_Date_Year (Filter_Interval Integer)
554 | Filter_Date_Month (Filter_Interval Int)
555 | Filter_Date_DoM (Filter_Interval Int)
556 | Filter_Date_Hour (Filter_Interval Int)
557 | Filter_Date_Minute (Filter_Interval Int)
558 | Filter_Date_Second (Filter_Interval Data.Fixed.Pico)
559 deriving (Eq, Show, Typeable)
561 instance Filter Filter_Date where
562 type Filter_Key Filter_Date = Date
563 test (Filter_Date_UTC f) d = test f $ d
564 test (Filter_Date_Year f) d = test f $ Interval.Limited $ Date.year d
565 test (Filter_Date_Month f) d = test f $ Interval.Limited $ Date.month d
566 test (Filter_Date_DoM f) d = test f $ Interval.Limited $ Date.dom d
567 test (Filter_Date_Hour f) d = test f $ Interval.Limited $ Date.hour d
568 test (Filter_Date_Minute f) d = test f $ Interval.Limited $ Date.minute d
569 test (Filter_Date_Second f) d = test f $ Interval.Limited $ Date.second d
572 Filter_Date_UTC ff -> Filter_Date_UTC <$> simplify ff
573 Filter_Date_Year ff -> Filter_Date_Year <$> simplify ff
574 Filter_Date_Month ff -> Filter_Date_Month <$> simplify ff
575 Filter_Date_DoM ff -> Filter_Date_DoM <$> simplify ff
576 Filter_Date_Hour ff -> Filter_Date_Hour <$> simplify ff
577 Filter_Date_Minute ff -> Filter_Date_Minute <$> simplify ff
578 Filter_Date_Second ff -> Filter_Date_Second <$> simplify ff
580 instance Filter (With_Interval Filter_Date) where
581 type Filter_Key (With_Interval Filter_Date) = Interval (Interval.Unlimitable Date)
582 test (With_Interval (Filter_Date_UTC f)) d = test (With_Interval (Interval.Limited <$> f)) d
583 test (With_Interval (Filter_Date_Year f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.year) d
584 test (With_Interval (Filter_Date_Month f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.month) d
585 test (With_Interval (Filter_Date_DoM f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.dom) d
586 test (With_Interval (Filter_Date_Hour f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.hour) d
587 test (With_Interval (Filter_Date_Minute f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.minute) d
588 test (With_Interval (Filter_Date_Second f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.second) d
589 simplify (With_Interval f) =
591 Filter_Date_UTC ff -> With_Interval . Filter_Date_UTC <$> simplify ff
592 Filter_Date_Year ff -> With_Interval . Filter_Date_Year <$> simplify ff
593 Filter_Date_Month ff -> With_Interval . Filter_Date_Month <$> simplify ff
594 Filter_Date_DoM ff -> With_Interval . Filter_Date_DoM <$> simplify ff
595 Filter_Date_Hour ff -> With_Interval . Filter_Date_Hour <$> simplify ff
596 Filter_Date_Minute ff -> With_Interval . Filter_Date_Minute <$> simplify ff
597 Filter_Date_Second ff -> With_Interval . Filter_Date_Second <$> simplify ff
599 -- ** Type 'Filter_Tag'
602 = Filter_Tag_Name Filter_Text
603 | Filter_Tag_Value Filter_Text
604 deriving (Eq, Show, Typeable)
606 instance Filter Filter_Tag where
607 type Filter_Key Filter_Tag = (Text, Text)
608 test (Filter_Tag_Name f) (x, _) = test f x
609 test (Filter_Tag_Value f) (_, x) = test f x
612 Filter_Tag_Name ff -> Filter_Tag_Name <$> simplify ff
613 Filter_Tag_Value ff -> Filter_Tag_Value <$> simplify ff
615 -- ** Type 'Filter_Posting'
618 => Filter_Posting posting
619 = Filter_Posting_Account Filter_Account
620 | Filter_Posting_Amount (Filter_Amount (Posting_Amount posting))
621 | Filter_Posting_Unit (Filter_Unit (Amount_Unit (Posting_Amount posting)))
624 -- Description Comp_String String
626 -- Account_Tag Comp_String String (Maybe (Comp_String, String))
627 -- Account_Balance Comp_Num Comp_Num_Absolute Amount
628 -- Depth Comp_Num Int
632 -- Tag Comp_String Tag.Name (Maybe (Comp_String, Tag.Value))
633 deriving instance Posting p => Eq (Filter_Posting p)
634 deriving instance Posting p => Show (Filter_Posting p)
637 => Filter (Filter_Posting p) where
638 type Filter_Key (Filter_Posting p) = p
639 test (Filter_Posting_Account f) p =
640 test f $ posting_account p
641 test (Filter_Posting_Amount f) p =
642 Data.Foldable.any (test f) $ posting_amounts p
643 test (Filter_Posting_Unit f) p =
644 Data.Foldable.any (test f . amount_unit) $ posting_amounts p
647 Filter_Posting_Account ff -> Filter_Posting_Account <$> simplify ff
648 Filter_Posting_Amount ff -> Filter_Posting_Amount <$> simplify ff
649 Filter_Posting_Unit ff -> Filter_Posting_Unit <$> simplify ff
651 newtype Cross t = Cross t
652 instance (Transaction t, p ~ Transaction_Posting t)
653 => Filter (Filter_Transaction t, Cross p) where
654 type Filter_Key (Filter_Transaction t, Cross p) = Cross p
655 test (pr, _) (Cross p) =
657 (Filter_Transaction_Description _) -> True
658 (Filter_Transaction_Posting f) -> test f p
659 (Filter_Transaction_Date _) -> True -- TODO: use posting_date
660 (Filter_Transaction_Tag _) -> False -- TODO: use posting_tags
663 Filter_Transaction_Description ff -> (, c) . Filter_Transaction_Description <$> simplify ff
664 Filter_Transaction_Posting ff -> (, c) . Filter_Transaction_Posting <$> simplify ff
665 Filter_Transaction_Date ff -> (, c) . Filter_Transaction_Date <$> simplify ff
666 Filter_Transaction_Tag ff -> (, c) . Filter_Transaction_Tag <$> simplify ff
668 -- ** Type 'Filter_Transaction'
671 => Filter_Transaction t
672 = Filter_Transaction_Description Filter_Text
673 | Filter_Transaction_Posting (Filter_Posting (Transaction_Posting t))
674 | Filter_Transaction_Date (Filter_Bool Filter_Date)
675 | Filter_Transaction_Tag (Filter_Bool Filter_Tag)
677 deriving instance Transaction t => Eq (Filter_Transaction t)
678 deriving instance Transaction t => Show (Filter_Transaction t)
680 instance Transaction t
681 => Filter (Filter_Transaction t) where
682 type Filter_Key (Filter_Transaction t) = t
683 test (Filter_Transaction_Description f) t =
684 test f $ transaction_description t
685 test (Filter_Transaction_Posting f) t =
686 Data.Foldable.any (test f) $
687 transaction_postings t
688 test (Filter_Transaction_Date f) t =
689 test f $ transaction_date t
690 test (Filter_Transaction_Tag f) t =
692 Data.Map.foldrWithKey
693 (\n -> mappend . Data.Monoid.Any .
694 Data.Foldable.any (test f . (n,)))
695 (Data.Monoid.Any False) $
699 Filter_Transaction_Description ff -> Filter_Transaction_Description <$> simplify ff
700 Filter_Transaction_Posting ff -> Filter_Transaction_Posting <$> simplify ff
701 Filter_Transaction_Date ff -> Filter_Transaction_Date <$> simplify ff
702 Filter_Transaction_Tag ff -> Filter_Transaction_Tag <$> simplify ff
706 , Journal.Transaction t
709 (Simplified (Filter_Bool (Filter_Transaction t)))
710 Journal.Journal t where
713 then Journal.cons t j
716 -- ** Type 'Filter_Balance'
720 = Filter_Balance_Account Filter_Account
721 | Filter_Balance_Amount (Filter_Amount (Balance_Amount b))
722 | Filter_Balance_Positive (Filter_Amount (Balance_Amount b))
723 | Filter_Balance_Negative (Filter_Amount (Balance_Amount b))
725 deriving instance Balance b => Eq (Filter_Balance b)
726 deriving instance Balance b => Show (Filter_Balance b)
729 => Filter (Filter_Balance b) where
730 type Filter_Key (Filter_Balance b) = b
731 test (Filter_Balance_Account f) b =
732 test f $ balance_account b
733 test (Filter_Balance_Amount f) b =
734 test f $ balance_amount b
735 test (Filter_Balance_Positive f) b =
736 Data.Foldable.any (test f) $
738 test (Filter_Balance_Negative f) b =
739 Data.Foldable.any (test f) $
743 Filter_Balance_Account ff -> Filter_Balance_Account <$> simplify ff
744 Filter_Balance_Amount ff -> Filter_Balance_Amount <$> simplify ff
745 Filter_Balance_Positive ff -> Filter_Balance_Positive <$> simplify ff
746 Filter_Balance_Negative ff -> Filter_Balance_Negative <$> simplify ff
751 , amount ~ Balance.Posting_Amount p
753 => Consable (Simplified (Filter_Bool (Filter_Posting p)))
754 (Const (Balance.Balance_by_Account amount))
756 mcons fp p (Const !bal) =
758 case simplified fp of
760 Right True -> Balance.cons_by_account p bal
763 then Balance.cons_by_account p bal
766 ( Transaction transaction
767 , posting ~ Transaction_Posting transaction
768 , amount ~ Balance.Posting_Amount posting
769 , Balance.Amount amount
770 , Balance.Posting posting
772 => Consable ( (Simplified (Filter_Bool (Filter_Transaction transaction)))
773 , (Simplified (Filter_Bool (Filter_Posting posting))) )
774 (Const (Balance.Balance_by_Account amount))
776 mcons (ft, fp) t (Const !bal) =
778 case simplified ft of
780 Right True -> filter_postings $ transaction_postings t
783 then filter_postings $ transaction_postings t
785 where filter_postings ps =
786 case simplified fp of
790 (flip Balance.cons_by_account)
794 (\b p -> if test ff p then Balance.cons_by_account p b else b)
798 , Balance.Posting posting
800 , amount ~ Balance.Posting_Amount posting
802 => Consable (Simplified (Filter_Bool (Filter_Posting posting)))
803 (Const (Balance.Balance_by_Account amount))
804 (foldable posting) where
805 mcons fp ps (Const !bal) =
807 case simplified fp of
811 (flip Balance.cons_by_account) bal ps
813 Data.Foldable.foldl' (\b p ->
815 then Balance.cons_by_account p b
818 -- ** Type 'Filter_GL'
822 = Filter_GL_Account Filter_Account
823 | Filter_GL_Amount_Positive (Filter_Amount (GL_Amount g))
824 | Filter_GL_Amount_Negative (Filter_Amount (GL_Amount g))
825 | Filter_GL_Amount_Balance (Filter_Amount (GL_Amount g))
826 | Filter_GL_Sum_Positive (Filter_Amount (GL_Amount g))
827 | Filter_GL_Sum_Negative (Filter_Amount (GL_Amount g))
828 | Filter_GL_Sum_Balance (Filter_Amount (GL_Amount g))
830 deriving instance GL g => Eq (Filter_GL g)
831 deriving instance GL g => Show (Filter_GL g)
834 => Filter (Filter_GL g) where
835 type Filter_Key (Filter_GL g) = g
836 test (Filter_GL_Account f) g =
837 test f $ gl_account g
838 test (Filter_GL_Amount_Positive f) g =
839 Data.Foldable.any (test f) $
841 test (Filter_GL_Amount_Negative f) g =
842 Data.Foldable.any (test f) $
844 test (Filter_GL_Amount_Balance f) g =
845 test f $ gl_amount_balance g
846 test (Filter_GL_Sum_Positive f) g =
847 Data.Foldable.any (test f) $
849 test (Filter_GL_Sum_Negative f) g =
850 Data.Foldable.any (test f) $
852 test (Filter_GL_Sum_Balance f) g =
853 test f $ gl_sum_balance g
856 Filter_GL_Account ff -> Filter_GL_Account <$> simplify ff
857 Filter_GL_Amount_Positive ff -> Filter_GL_Amount_Positive <$> simplify ff
858 Filter_GL_Amount_Negative ff -> Filter_GL_Amount_Negative <$> simplify ff
859 Filter_GL_Amount_Balance ff -> Filter_GL_Amount_Balance <$> simplify ff
860 Filter_GL_Sum_Positive ff -> Filter_GL_Sum_Positive <$> simplify ff
861 Filter_GL_Sum_Negative ff -> Filter_GL_Sum_Negative <$> simplify ff
862 Filter_GL_Sum_Balance ff -> Filter_GL_Sum_Balance <$> simplify ff
865 ( GL.Transaction transaction
866 , Transaction transaction
868 , posting ~ GL.Transaction_Posting transaction
870 => Consable ( (Simplified (Filter_Bool (Filter_Transaction transaction)))
871 , (Simplified (Filter_Bool (Filter_Posting posting ))) )
874 mcons (ft, fp) t !gl =
875 case simplified ft of
878 case simplified fp of
880 Right True -> GL.cons t gl
883 (GL.transaction_postings_filter (test f) t)
888 case simplified fp of
890 Right True -> GL.cons t gl
893 (GL.transaction_postings_filter (test ff) t)
898 , GL.Transaction transaction
899 , Transaction transaction
901 , posting ~ GL.Transaction_Posting transaction
903 => Consable ( (Simplified (Filter_Bool (Filter_Transaction transaction)))
904 , (Simplified (Filter_Bool (Filter_Posting posting ))) )
905 (Const (GL.GL transaction))
906 (foldable transaction) where
907 mcons (ft, fp) ts (Const !gl) =
909 case simplified ft of
912 case simplified fp of
921 . GL.transaction_postings_filter (test f) )
928 case simplified fp of
930 Right True -> GL.cons t
932 GL.transaction_postings_filter (test ff) t