1 {-# LANGUAGE BangPatterns #-}
2 {-# LANGUAGE DeriveDataTypeable #-}
3 {-# LANGUAGE DeriveFunctor #-}
4 {-# LANGUAGE FlexibleContexts #-}
5 {-# LANGUAGE FlexibleInstances #-}
6 {-# LANGUAGE MultiParamTypeClasses #-}
7 {-# LANGUAGE Rank2Types #-}
8 {-# LANGUAGE ScopedTypeVariables #-}
9 {-# LANGUAGE StandaloneDeriving #-}
10 {-# LANGUAGE TupleSections #-}
11 {-# LANGUAGE TypeFamilies #-}
12 {-# OPTIONS_GHC -fno-warn-orphans #-}
13 module Hcompta.Filter where
15 import Control.Applicative (Applicative(..))
16 -- import Control.Applicative (pure, (<$>), (<*>))
17 import Control.Arrow (second)
20 import Data.Decimal ()
21 import Data.Either (Either(..))
22 import Data.Eq (Eq(..))
23 import qualified Data.Fixed
24 import Data.Foldable (Foldable(..), all, any)
25 import Data.Functor (Functor(..), (<$>))
26 import Data.List (reverse)
27 import Data.List.NonEmpty (NonEmpty(..))
28 import qualified Data.List.NonEmpty as NonEmpty
29 import qualified Data.Map.Strict as Map
30 import Data.Maybe (maybe)
31 import qualified Data.Monoid as Monoid
32 import Data.Monoid (Monoid(..))
33 import Data.Ord (Ord(..), Ordering(..))
34 import Data.Text (Text)
35 import Data.Traversable (Traversable(..))
36 import Data.Tuple (fst, snd)
37 import Data.Typeable ()
38 import Prelude (($), (.), Int, Integer, Num(..), Show(..), const, flip, id)
39 import Text.Regex.Base ()
40 import Text.Regex.TDFA ()
41 import Text.Regex.TDFA.Text ()
43 import qualified Hcompta.Account as Account
44 import Hcompta.Account (Account_Tags(..))
45 import qualified Hcompta.Balance as Balance
46 -- import qualified Hcompta.Chart as Chart
47 import Hcompta.Date (Date)
48 import qualified Hcompta.Date as Date
49 import qualified Hcompta.Filter.Amount as Filter.Amount
50 import qualified Hcompta.GL as GL
51 import qualified Hcompta.Journal as Journal
52 import Hcompta.Lib.Applicative ()
53 import Hcompta.Lib.Consable (Consable(..))
54 import Hcompta.Lib.Interval (Interval)
55 import qualified Hcompta.Lib.Interval as Interval
56 import Hcompta.Lib.Regex (Regex)
57 import qualified Hcompta.Lib.Regex as Regex
58 import Hcompta.Polarize
59 import qualified Hcompta.Posting as Posting
60 -- import Hcompta.Posting (Posting_Tags(..))
61 import Hcompta.Quantity (Addable(..), Zero(..))
62 import qualified Hcompta.Stats as Stats
63 import qualified Hcompta.Tag as Tag
64 import Hcompta.Tag (Tags(..))
65 import Hcompta.Transaction (Transaction_Tags(..))
66 import Hcompta.Unit (Unit(..))
68 -- * Requirements' interface
75 class Path_Section a where
76 path_section_text :: a -> Text
77 instance Path_Section Text where
78 path_section_text = id
82 type Account_Section = Text
83 type Account_Path = Path Account_Section
85 class Account j a where
86 account_path :: a -> Account_Path
87 account_tags :: j -> a -> Account_Tags
89 instance Account (Account_Tags, Account_Path) where
94 instance Account (Chart.Charted Account_Path Account_Path) where
95 account_path = Chart.charted
96 account_tags (Chart.Charted c a) = Chart.account_tags a c
102 ( Addable (Amount_Quantity a)
103 , Eq (Amount_Quantity a)
104 , Ord (Amount_Quantity a)
105 , Unit (Amount_Unit a)
107 type Amount_Quantity a
109 amount_quantity :: a -> Polarized (Amount_Quantity a)
110 amount_unit :: a -> Amount_Unit a
118 ) => Amount (unit, Polarized quantity) where
119 type Amount_Quantity (unit, Polarized quantity) = quantity
120 type Amount_Unit (unit, Polarized quantity) = unit
121 amount_quantity = snd
123 instance Amount Filter.Amount.Amount where
124 type Amount_Unit Filter.Amount.Amount = Filter.Amount.Unit
125 type Amount_Quantity Filter.Amount.Amount = Filter.Amount.Quantity
126 amount_quantity = polarize . Filter.Amount.amount_quantity
127 amount_unit = Filter.Amount.amount_unit
129 -- ** Class 'Posting'
133 , Account j (Posting.Posting_Account p)
134 , Amount (Posting.Posting_Amount p)
137 -- ** Class 'Transaction'
140 ( Posting j (Transaction_Posting t)
141 , Foldable (Transaction_Postings t)
143 => Transaction j t where
144 type Transaction_Posting t
145 type Transaction_Postings t :: * -> *
146 transaction_date :: t -> Date
147 transaction_wording :: t -> Text
148 transaction_postings :: t -> Transaction_Postings t (Transaction_Posting t)
149 transaction_tags :: t -> Transaction_Tags
151 -- ** Class 'Balance'
154 ( Account j (Balance_Account b)
155 , Amount (Balance_Amount b)
156 ) => Balance j b where
157 type Balance_Account b
158 type Balance_Amount b
159 balance_account :: b -> Balance_Account b
160 balance_amount :: b -> Balance_Amount b
165 ) => Balance (acct, amt) where
166 type Balance_Account (acct, amt) = acct
167 type Balance_Amount (acct, amt) = amt
168 balance_account = fst
174 ( Account j (GL_Account g)
175 , Amount (GL_Amount g)
179 gl_account :: g -> GL_Account g
181 gl_amount :: g -> GL_Amount g
182 gl_sum :: g -> GL_Amount g
187 ) => GL (acct, Date, amt, amt) where
188 type GL_Account (acct, Date, amt, amt) = acct
189 type GL_Amount (acct, Date, amt, amt) = amt
190 gl_account (x, _, _, _) = x
191 gl_date (_, x, _, _) = x
192 gl_amount (_, _, x, _) = x
193 gl_sum (_, _, _, x) = x
199 test :: f -> Filter_Key f -> Bool
200 simplify :: f -> Simplified f
201 -- simplify f = Simplified $ Left f
202 -- | Type to pass an 'Interval' to 'test'.
203 newtype With_Interval f
209 , Monoid (Filter_Key f)
210 ) => f -> t (Filter_Key f) -> Filter_Key f
213 (\x -> if test f x then x else mempty)
215 -- ** Type 'Simplified'
217 newtype Simplified filter
218 = Simplified (Either filter Bool)
220 simplified :: Simplified f -> Either f Bool
221 simplified (Simplified e) = e
223 instance Functor Simplified where
224 fmap _f (Simplified (Right b)) = Simplified (Right b)
225 fmap f (Simplified (Left x)) = Simplified (Left $ f x)
226 instance Filter f => Filter (Simplified f) where
227 type Filter_Key (Simplified f) = Filter_Key f
228 test (Simplified (Right b)) _x = b
229 test (Simplified (Left f)) x = test f x
230 simplify (Simplified (Right b)) = Simplified $ Right b
231 simplify (Simplified (Left f)) =
233 case simplified $ simplify f of
235 Left sf -> Left (Simplified $ Left sf)
237 -- | Conjonction ('&&').
238 and :: Filter f => Simplified (Filter_Bool f) -> Simplified (Filter_Bool f) -> Simplified (Filter_Bool f)
239 and (Simplified x) (Simplified y) =
242 (Right bx , Right by ) -> Right (bx && by)
243 (Right True , Left _fy ) -> y
244 (Right False, Left _fy ) -> x
245 (Left _fx , Right True ) -> x
246 (Left _fx , Right False) -> y
247 (Left fx , Left fy ) -> Left $ And fx fy
249 -- | Disjonction ('||').
250 or :: Filter f => Simplified (Filter_Bool f) -> Simplified (Filter_Bool f) -> Simplified (Filter_Bool f)
251 or (Simplified x) (Simplified y) =
254 (Right bx , Right by ) -> Right (bx || by)
255 (Right True , Left _fy ) -> x
256 (Right False, Left _fy ) -> y
257 (Left _fx , Right True ) -> y
258 (Left _fx , Right False) -> x
259 (Left fx , Left fy ) -> Left $ Or fx fy
261 -- ** Type 'Filter_Text'
265 | Filter_Text_Exact Text
266 | Filter_Text_Regex Regex
267 deriving ({-Data, -}Eq, Show, Typeable)
269 instance Filter Filter_Text where
270 type Filter_Key Filter_Text = Text
273 Filter_Text_Any -> True
274 Filter_Text_Exact m -> (==) m x
275 Filter_Text_Regex m -> Regex.match m x
279 Filter_Text_Any -> Right True
282 -- ** Type 'Filter_Ord'
285 = Lt -- ^ Lower than.
286 | Le -- ^ Lower or equal.
288 | Ge -- ^ Greater or equal.
289 | Gt -- ^ Greater than.
290 deriving (Data, Eq, Show, Typeable)
295 deriving (Data, Eq, Show, Typeable)
296 instance Functor Filter_Ord where
299 Filter_Ord Lt o -> Filter_Ord Lt (f o)
300 Filter_Ord Le o -> Filter_Ord Le (f o)
301 Filter_Ord Eq o -> Filter_Ord Eq (f o)
302 Filter_Ord Ge o -> Filter_Ord Ge (f o)
303 Filter_Ord Gt o -> Filter_Ord Gt (f o)
304 Filter_Ord_Any -> Filter_Ord_Any
306 => Filter (Filter_Ord o) where
307 type Filter_Key (Filter_Ord o) = o
310 Filter_Ord Lt o -> (<) x o
311 Filter_Ord Le o -> (<=) x o
312 Filter_Ord Eq o -> (==) x o
313 Filter_Ord Ge o -> (>=) x o
314 Filter_Ord Gt o -> (>) x o
315 Filter_Ord_Any -> True
319 Filter_Ord_Any -> Right True
322 => Filter (With_Interval (Filter_Ord o)) where
323 type Filter_Key (With_Interval (Filter_Ord o)) = Interval o
324 test (With_Interval f) i =
325 let l = Interval.low i in
326 let h = Interval.high i in
328 Filter_Ord Lt o -> case compare (Interval.limit h) o of
330 EQ -> Interval.adherence h == Interval.Out
332 Filter_Ord Le o -> Interval.limit h <= o
333 Filter_Ord Eq o -> Interval.limit l == o && Interval.limit h == o
334 Filter_Ord Ge o -> Interval.limit l >= o
335 Filter_Ord Gt o -> case compare (Interval.limit l) o of
337 EQ -> Interval.adherence l == Interval.Out
339 Filter_Ord_Any -> True
343 With_Interval Filter_Ord_Any -> Right True
346 -- ** Type 'Filter_Interval'
348 data Filter_Interval x
349 = Filter_Interval_In (Interval (Interval.Unlimitable x))
350 deriving (Eq, Ord, Show)
351 --instance Functor Filter_Interval where
352 -- fmap f (Filter_Interval_In i) = Filter_Interval_In (fmap (fmap f) i)
354 => Filter (Filter_Interval o) where
355 type Filter_Key (Filter_Interval o) = Interval.Unlimitable o
356 test (Filter_Interval_In i) x =
357 Interval.locate x i == EQ
358 simplify = Simplified . Left
360 => Filter (With_Interval (Filter_Interval o)) where
361 type Filter_Key (With_Interval (Filter_Interval o)) = Interval (Interval.Unlimitable o)
362 test (With_Interval (Filter_Interval_In i)) x = Interval.into x i
363 simplify = Simplified . Left
365 -- ** Type 'Filter_Num_Abs'
369 = Filter_Num_Abs (Filter_Ord n)
370 deriving (Data, Eq, Show, Typeable)
372 instance (Num x, Ord x)
373 => Filter (Filter_Num_Abs x) where
374 type Filter_Key (Filter_Num_Abs x) = x
375 test (Filter_Num_Abs f) x = test f (abs x)
378 Filter_Num_Abs ff -> Filter_Num_Abs <$> simplify ff
380 -- ** Type 'Filter_Bool'
385 | Not (Filter_Bool f)
386 | And (Filter_Bool f) (Filter_Bool f)
387 | Or (Filter_Bool f) (Filter_Bool f)
388 deriving (Data, Eq, Show, Typeable)
389 instance Functor Filter_Bool where
391 fmap f (Bool x) = Bool (f x)
392 fmap f (Not t) = Not (fmap f t)
393 fmap f (And t0 t1) = And (fmap f t0) (fmap f t1)
394 fmap f (Or t0 t1) = Or (fmap f t0) (fmap f t1)
395 -- | Conjonctive ('And') 'Monoid'.
396 instance Monoid (Filter_Bool f) where
399 instance Foldable Filter_Bool where
400 foldr _ acc Any = acc
401 foldr m acc (Bool f) = m f acc
402 foldr m acc (Not f) = foldr m acc f
403 foldr m acc (And f0 f1) = foldr m (foldr m acc f0) f1
404 foldr m acc (Or f0 f1) = foldr m (foldr m acc f0) f1
405 instance Traversable Filter_Bool where
406 traverse _ Any = pure Any
407 traverse m (Bool f) = Bool <$> m f
408 traverse m (Not f) = Not <$> traverse m f
409 traverse m (And f0 f1) = And <$> traverse m f0 <*> traverse m f1
410 traverse m (Or f0 f1) = Or <$> traverse m f0 <*> traverse m f1
412 => Filter (Filter_Bool f) where
413 type Filter_Key (Filter_Bool f) = Filter_Key f
415 test (Bool f) x = test f x
416 test (Not f) x = not $ test f x
417 test (And f0 f1) x = test f0 x && test f1 x
418 test (Or f0 f1) x = test f0 x || test f1 x
420 simplify Any = Simplified $ Right True
421 simplify (Bool f) = Bool <$> simplify f
424 case simplified (simplify f) of
425 Left ff -> Left $ Not ff
426 Right b -> Right $ not b
427 simplify (And f0 f1) =
430 ( simplified $ simplify f0
431 , simplified $ simplify f1 ) of
432 (Right b0, Right b1) -> Right $ b0 && b1
433 (Right b0, Left s1) -> if b0 then Left s1 else Right False
434 (Left s0, Right b1) -> if b1 then Left s0 else Right False
435 (Left s0, Left s1) -> Left $ And s0 s1
436 simplify (Or f0 f1) =
439 ( simplified $ simplify f0
440 , simplified $ simplify f1 ) of
441 (Right b0, Right b1) -> Right $ b0 || b1
442 (Right b0, Left s1) -> if b0 then Right True else Left s1
443 (Left s0, Right b1) -> if b1 then Right True else Left s0
444 (Left s0, Left s1) -> Left $ Or s0 s1
446 -- ** Type 'Filter_Unit'
448 newtype Filter_Unit u
449 = Filter_Unit Filter_Text
450 deriving (Eq, Show, Typeable)
453 => Filter (Filter_Unit u) where
454 type Filter_Key (Filter_Unit u) = u
455 test (Filter_Unit f) = test f . unit_text
458 Filter_Unit ff -> Filter_Unit <$> simplify ff
460 -- ** Type 'Filter_Wording'
465 -- ** Type 'Filter_Path'
467 data Filter_Path section
468 = Filter_Path Order [Filter_Path_Section]
469 deriving ({-Data, -}Eq, Show, Typeable)
471 data Filter_Path_Section
472 = Filter_Path_Section_Any
473 | Filter_Path_Section_Many
474 | Filter_Path_Section_Text Filter_Text
475 deriving ({-Data, -}Eq, Show, Typeable)
477 instance Path_Section s
478 => Filter (Filter_Path s) where
479 type Filter_Key (Filter_Path s) = Path s
480 test (Filter_Path ord flt) path =
481 go ord (NonEmpty.toList path) flt
483 go :: Order -> [s] -> [Filter_Path_Section] -> Bool
491 go o _ [Filter_Path_Section_Many] =
508 Filter_Path_Section_Any -> True
509 Filter_Path_Section_Many -> True
510 Filter_Path_Section_Text m -> test m n
512 go o no@(n:ns) fo@(f:fs) =
514 Filter_Path_Section_Any -> go o ns fs
515 Filter_Path_Section_Many -> go o no fs || go o ns fo
516 Filter_Path_Section_Text m -> test m (path_section_text n) &&
527 Filter_Path o l | all (Filter_Path_Section_Many ==) l ->
543 Filter_Path _o [Filter_Path_Section_Many] ->
544 Simplified $ Right True
546 Filter_Path o <$> go fa
548 go :: [Filter_Path_Section] -> Simplified [Filter_Path_Section]
551 [] -> Simplified $ Left []
552 Filter_Path_Section_Many:l@(Filter_Path_Section_Many:_) -> go l
554 case simplified $ simplify_section ff of
555 Left fff -> ((fff :) <$> go l)
556 Right True -> ((Filter_Path_Section_Any :) <$> go l)
557 Right False -> Simplified $ Right False
560 Filter_Path_Section_Any -> Simplified $ Left $ Filter_Path_Section_Any
561 Filter_Path_Section_Many -> Simplified $ Left $ Filter_Path_Section_Many
562 Filter_Path_Section_Text ff -> Filter_Path_Section_Text <$> simplify ff
564 -- ** Type 'Filter_Account'
566 type Filter_Account a
568 (Filter_Account_Component a)
570 data Filter_Account_Component a
571 = Filter_Account_Path (Filter_Path Account_Section)
572 | Filter_Account_Tag Filter_Tags
573 deriving instance Account a => Eq (Filter_Account_Component a)
574 deriving instance Account a => Show (Filter_Account_Component a)
577 => Filter (Filter_Account_Component a) where
578 type Filter_Key (Filter_Account_Component a) = a
579 test (Filter_Account_Path f) a = test f $ account_path a
580 test (Filter_Account_Tag f) a =
581 let Account_Tags tags = account_tags a in
585 Filter_Account_Path ff -> Filter_Account_Path <$> simplify ff
586 Filter_Account_Tag ff -> Filter_Account_Tag <$> simplify ff
588 -- ** Type 'Filter_Quantity'
590 type Filter_Quantity q
593 -- ** Type 'Filter_Polarizable'
595 data Filter_Polarized q
596 = Filter_Polarized_Negative (Filter_Quantity q)
597 | Filter_Polarized_Positive (Filter_Quantity q)
598 | Filter_Polarized_Sum (Filter_Quantity q)
599 deriving (Eq, Show, Typeable)
601 instance (Ord q, Addable q)
602 => Filter (Filter_Polarized q) where
603 type Filter_Key (Filter_Polarized q) = Polarized q
606 Filter_Polarized_Negative ff -> maybe False (test ff) $ polarized_negative q
607 Filter_Polarized_Positive ff -> maybe False (test ff) $ polarized_positive q
608 Filter_Polarized_Sum ff -> test ff $ depolarize q
611 Filter_Polarized_Negative ff -> Filter_Polarized_Negative <$> simplify ff
612 Filter_Polarized_Positive ff -> Filter_Polarized_Positive <$> simplify ff
613 Filter_Polarized_Sum ff -> Filter_Polarized_Sum <$> simplify ff
615 -- ** Type 'Filter_Amount'
618 = Filter_Bool (Filter_Amount_Section a)
621 => Filter_Amount_Section a
622 = Filter_Amount_Section_Quantity (Filter_Polarized (Amount_Quantity a))
623 | Filter_Amount_Section_Unit (Filter_Unit (Amount_Unit a))
625 deriving instance Amount a => Eq (Filter_Amount_Section a)
626 deriving instance Amount a => Show (Filter_Amount_Section a)
629 => Filter (Filter_Amount_Section a) where
630 type Filter_Key (Filter_Amount_Section a) = a
633 Filter_Amount_Section_Quantity ff -> test ff $ amount_quantity a
634 Filter_Amount_Section_Unit ff -> test ff $ amount_unit a
637 Filter_Amount_Section_Quantity ff -> Filter_Amount_Section_Quantity <$> simplify ff
638 Filter_Amount_Section_Unit ff -> Filter_Amount_Section_Unit <$> simplify ff
640 -- ** Type 'Filter_Date'
643 = Filter_Date_UTC (Filter_Ord Date)
644 | Filter_Date_Year (Filter_Interval Integer)
645 | Filter_Date_Month (Filter_Interval Int)
646 | Filter_Date_DoM (Filter_Interval Int)
647 | Filter_Date_Hour (Filter_Interval Int)
648 | Filter_Date_Minute (Filter_Interval Int)
649 | Filter_Date_Second (Filter_Interval Data.Fixed.Pico)
650 deriving (Eq, Show, Typeable)
652 instance Filter Filter_Date where
653 type Filter_Key Filter_Date = Date
654 test (Filter_Date_UTC f) d = test f $ d
655 test (Filter_Date_Year f) d = test f $ Interval.Limited $ Date.year d
656 test (Filter_Date_Month f) d = test f $ Interval.Limited $ Date.month d
657 test (Filter_Date_DoM f) d = test f $ Interval.Limited $ Date.dom d
658 test (Filter_Date_Hour f) d = test f $ Interval.Limited $ Date.hour d
659 test (Filter_Date_Minute f) d = test f $ Interval.Limited $ Date.minute d
660 test (Filter_Date_Second f) d = test f $ Interval.Limited $ Date.second d
663 Filter_Date_UTC ff -> Filter_Date_UTC <$> simplify ff
664 Filter_Date_Year ff -> Filter_Date_Year <$> simplify ff
665 Filter_Date_Month ff -> Filter_Date_Month <$> simplify ff
666 Filter_Date_DoM ff -> Filter_Date_DoM <$> simplify ff
667 Filter_Date_Hour ff -> Filter_Date_Hour <$> simplify ff
668 Filter_Date_Minute ff -> Filter_Date_Minute <$> simplify ff
669 Filter_Date_Second ff -> Filter_Date_Second <$> simplify ff
671 instance Filter (With_Interval Filter_Date) where
672 type Filter_Key (With_Interval Filter_Date) = Interval (Interval.Unlimitable Date)
673 test (With_Interval (Filter_Date_UTC f)) d = test (With_Interval (Interval.Limited <$> f)) d
674 test (With_Interval (Filter_Date_Year f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.year) d
675 test (With_Interval (Filter_Date_Month f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.month) d
676 test (With_Interval (Filter_Date_DoM f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.dom) d
677 test (With_Interval (Filter_Date_Hour f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.hour) d
678 test (With_Interval (Filter_Date_Minute f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.minute) d
679 test (With_Interval (Filter_Date_Second f)) d = maybe False (test $ With_Interval f) $ Interval.fmap (fmap Date.second) d
680 simplify (With_Interval f) =
682 Filter_Date_UTC ff -> With_Interval . Filter_Date_UTC <$> simplify ff
683 Filter_Date_Year ff -> With_Interval . Filter_Date_Year <$> simplify ff
684 Filter_Date_Month ff -> With_Interval . Filter_Date_Month <$> simplify ff
685 Filter_Date_DoM ff -> With_Interval . Filter_Date_DoM <$> simplify ff
686 Filter_Date_Hour ff -> With_Interval . Filter_Date_Hour <$> simplify ff
687 Filter_Date_Minute ff -> With_Interval . Filter_Date_Minute <$> simplify ff
688 Filter_Date_Second ff -> With_Interval . Filter_Date_Second <$> simplify ff
690 -- ** Type 'Filter_Tags'
697 = Filter_Tag_Path (Filter_Path Tag.Section)
698 | Filter_Tag_Value Filter_Tag_Value
699 deriving ({-Data, -}Eq, Show, Typeable)
701 data Filter_Tag_Value
702 = Filter_Tag_Value_None
703 | Filter_Tag_Value_Any Filter_Text
704 | Filter_Tag_Value_First Filter_Text
705 | Filter_Tag_Value_Last Filter_Text
706 deriving ({-Data, -}Eq, Show, Typeable)
708 instance Filter Filter_Tag where
709 type Filter_Key Filter_Tag = Tags
713 Filter_Tag_Path ff -> test ff . fst
714 Filter_Tag_Value ff -> test ff . snd in
717 (\p -> mappend . Monoid.Any . tst . (p,))
722 Filter_Tag_Path ff -> Filter_Tag_Path <$> simplify ff
723 Filter_Tag_Value ff -> Filter_Tag_Value <$> simplify ff
725 instance Filter Filter_Tag_Value where
726 type Filter_Key Filter_Tag_Value = [Tag.Value]
727 test (Filter_Tag_Value_None) vs = case vs of { [] -> True; _ -> False }
728 test (Filter_Tag_Value_Any f) vs = any (test f) vs
729 test (Filter_Tag_Value_First f) vs =
733 test (Filter_Tag_Value_Last f) vs =
739 Filter_Tag_Value_None -> Simplified $ Right False
740 Filter_Tag_Value_Any ff -> Filter_Tag_Value_Any <$> simplify ff
741 Filter_Tag_Value_First ff -> Filter_Tag_Value_First <$> simplify ff
742 Filter_Tag_Value_Last ff -> Filter_Tag_Value_Last <$> simplify ff
744 -- ** Type 'Filter_Posting'
747 => Filter_Posting j p
748 = Filter_Posting_Account (Filter_Account (Posting.Posting_Account p))
749 | Filter_Posting_Amount (Filter_Amount (Posting.Posting_Amount p))
750 | Filter_Posting_Unit (Filter_Unit (Amount_Unit (Posting.Posting_Amount p))) -- TODO: remove: Filter_Posting_Amount should be enough
753 -- Wording Comp_String String
755 -- Account_Tag Comp_String String (Maybe (Comp_String, String))
756 -- Account_Balance Comp_Num Comp_Num_Absolute Amount
757 -- Depth Comp_Num Int
761 -- Tag Comp_String Tag.Name (Maybe (Comp_String, Tag.Value))
762 deriving instance Posting p => Eq (Filter_Posting p)
763 deriving instance Posting p => Show (Filter_Posting p)
766 => Filter (Filter_Posting p) where
767 type Filter_Key (Filter_Posting p) = p
768 test (Filter_Posting_Account f) p =
769 test f $ Posting.posting_account p
770 test (Filter_Posting_Amount f) p =
771 any (test f) $ Posting.posting_amounts p
772 test (Filter_Posting_Unit f) p =
773 any (test f . amount_unit) $ Posting.posting_amounts p
776 Filter_Posting_Account ff -> Filter_Posting_Account <$> simplify ff
777 Filter_Posting_Amount ff -> Filter_Posting_Amount <$> simplify ff
778 Filter_Posting_Unit ff -> Filter_Posting_Unit <$> simplify ff
781 -- | A forall type (Rank2Types) to preserve the polymorphism of the filter.
782 newtype Forall_Simplified_Bool_Filter_Posting_Decimal
783 = Forall_Simplified_Bool_Filter_Posting_Decimal
784 { get_Forall_Simplified_Bool_Filter_Posting_Decimal ::
788 (Posting.Posting_Amount ptg)
789 ~ Filter.Amount.Quantity
792 (Filter_Posting ptg))
794 instance Monoid Forall_Simplified_Bool_Filter_Posting_Decimal where
795 mempty = Forall_Simplified_Bool_Filter_Posting_Decimal mempty
797 Forall_Simplified_Bool_Filter_Posting_Decimal $
798 get_Forall_Simplified_Bool_Filter_Posting_Decimal x `mappend`
799 get_Forall_Simplified_Bool_Filter_Posting_Decimal y
802 -- ** Type 'Filter_Transaction'
805 => Filter_Transaction j t
806 = Filter_Transaction_Date (Filter_Bool Filter_Date)
807 -- | Filter_Transaction_Posting (Filter_Bool (Filter_Posting (Posting_Typed (Transaction_Posting t))))
808 | Filter_Transaction_Posting (Filter_Bool (Filter_Posting (Transaction_Posting t)))
809 | Filter_Transaction_Tag Filter_Tags
810 | Filter_Transaction_Wording Filter_Wording
812 deriving instance Transaction t => Eq (Filter_Transaction t)
813 deriving instance Transaction t => Show (Filter_Transaction t)
815 instance Transaction t
816 => Filter (Filter_Transaction t) where
817 type Filter_Key (Filter_Transaction t) = t
818 test (Filter_Transaction_Posting f) t =
819 any (test f) (transaction_postings t)
820 test (Filter_Transaction_Date f) t =
821 test f $ transaction_date t
822 test (Filter_Transaction_Tag f) t =
823 let Transaction_Tags tags = transaction_tags t in
825 test (Filter_Transaction_Wording f) t =
826 test f $ transaction_wording t
829 Filter_Transaction_Date ff -> Filter_Transaction_Date <$> simplify ff
830 Filter_Transaction_Posting ff -> Filter_Transaction_Posting <$> simplify ff
831 Filter_Transaction_Tag ff -> Filter_Transaction_Tag <$> simplify ff
832 Filter_Transaction_Wording ff -> Filter_Transaction_Wording <$> simplify ff
836 { filtered_filter :: f
837 , filtered_content :: !c
842 , Journal.Transaction t
843 , Consable t (Journal.Journal t)
844 ) => Consable (Filtered (Simplified (Filter_Bool (Filter_Transaction t))) t)
847 mcons (Filtered f t) m =
854 , Stats.Transaction t
855 , Consable t (Stats.Stats t)
856 ) => Consable (Filtered (Simplified (Filter_Bool (Filter_Transaction t))) t)
859 mcons (Filtered f t) m =
865 -- *** Type 'Forall_Simplified_Bool_Filter_Transaction_Decimal'
867 -- | A forall type (Rank2Types) to preserve the polymorphism of the filter.
868 newtype Forall_Simplified_Bool_Filter_Transaction_Decimal
869 = Forall_Simplified_Bool_Filter_Transaction_Decimal
870 { get_Forall_Simplified_Bool_Filter_Transaction_Decimal ::
874 (Posting.Posting_Amount
875 (Transaction_Posting txn))
876 ~ Filter.Amount.Quantity
879 (Filter_Transaction txn))
881 instance Monoid Forall_Simplified_Bool_Filter_Transaction_Decimal where
882 mempty = Forall_Simplified_Bool_Filter_Transaction_Decimal mempty
884 Forall_Simplified_Bool_Filter_Transaction_Decimal $
885 get_Forall_Simplified_Bool_Filter_Transaction_Decimal x `mappend`
886 get_Forall_Simplified_Bool_Filter_Transaction_Decimal y
889 -- ** Type 'Filter_Balance'
893 = Filter_Balance_Account (Filter_Account (Balance_Account b))
894 | Filter_Balance_Amount (Filter_Amount (Balance_Amount b))
896 deriving instance Balance b => Eq (Filter_Balance b)
897 deriving instance Balance b => Show (Filter_Balance b)
900 => Filter (Filter_Balance b) where
901 type Filter_Key (Filter_Balance b) = b
902 test (Filter_Balance_Account f) b =
903 test f $ balance_account b
904 test (Filter_Balance_Amount f) b =
905 test f $ balance_amount b
908 Filter_Balance_Account ff -> Filter_Balance_Account <$> simplify ff
909 Filter_Balance_Amount ff -> Filter_Balance_Amount <$> simplify ff
912 ( Balance.Posting posting
914 --, account ~ Balance.Posting_Account posting
915 , account_section ~ Account.Account_Section (Balance.Posting_Account posting)
916 , quantity ~ Balance.Posting_Quantity posting
917 , unit ~ Balance.Posting_Unit posting
921 => Consable (Filtered (Simplified (Filter_Bool (Filter_Posting posting)))
923 (Balance.Balance_by_Account account_section unit quantity)
925 mcons (Filtered f p) m =
928 Right True -> Balance.cons_by_account p m
931 then Balance.cons_by_account p m
935 ( Transaction transaction
936 , posting ~ Transaction_Posting transaction
937 , account_section ~ Account.Account_Section (Balance.Posting_Account (Transaction_Posting transaction))
938 , quantity ~ Balance.Posting_Quantity (Transaction_Posting transaction)
939 , unit ~ Balance.Posting_Unit (Transaction_Posting transaction)
942 , Balance.Posting (Transaction_Posting transaction)
943 ) => Consable (Filtered (Simplified (Filter_Bool (Filter_Transaction transaction)))
945 (Balance.Balance_by_Account account_section unit quantity)
947 mcons (Filtered ft t) m =
948 case simplified ft of
950 Right True -> fold_postings m $ transaction_postings t
953 then fold_postings m $ transaction_postings t
956 fold_postings = foldl' (flip Balance.cons_by_account)
958 ( Transaction transaction
959 , posting ~ Transaction_Posting transaction
960 , account_section ~ Account.Account_Section (Balance.Posting_Account (Transaction_Posting transaction))
961 , quantity ~ Balance.Posting_Quantity (Transaction_Posting transaction)
962 , unit ~ Balance.Posting_Unit (Transaction_Posting transaction)
965 , Balance.Posting (Transaction_Posting transaction)
966 ) => Consable (Filtered ( Simplified (Filter_Bool (Filter_Transaction transaction))
967 , Simplified (Filter_Bool (Filter_Posting posting)) )
969 (Balance.Balance_by_Account account_section unit quantity)
971 mcons (Filtered (ft, fp) t) m =
972 case simplified ft of
974 Right True -> fold_postings m $ transaction_postings t
977 then fold_postings m $ transaction_postings t
982 , account ~ Balance.Posting_Account posting
983 , quantity ~ Balance.Posting_Quantity posting
984 , unit ~ Balance.Posting_Unit posting
986 , Balance.Posting posting
988 => Balance.Balance_by_Account account_section unit quantity
990 -> Balance.Balance_by_Account account_section unit quantity
992 case simplified fp of
994 Right True -> foldl' (flip Balance.cons_by_account)
995 Left fps -> foldl' $ \b p ->
997 then Balance.cons_by_account p b
1001 , Balance.Posting posting
1003 -- , account ~ Balance.Posting_Account posting
1004 , account_section ~ Account.Account_Section (Balance.Posting_Account posting)
1005 , quantity ~ Balance.Posting_Quantity posting
1006 , unit ~ Balance.Posting_Unit posting
1010 => Consable (Filtered (Simplified (Filter_Bool (Filter_Posting posting)))
1012 (Balance.Balance_by_Account account_section unit quantity)
1014 mcons (Filtered f ps) m =
1015 case simplified f of
1017 Right True -> foldl' (flip Balance.cons_by_account) m ps
1021 then Balance.cons_by_account p b
1025 -- ** Type 'Filter_GL'
1029 = Filter_GL_Account (Filter_Account (GL_Account g))
1030 | Filter_GL_Amount (Filter_Amount (GL_Amount g))
1031 | Filter_GL_Sum (Filter_Amount (GL_Amount g))
1033 deriving instance GL g => Eq (Filter_GL g)
1034 deriving instance GL g => Show (Filter_GL g)
1037 => Filter (Filter_GL g) where
1038 type Filter_Key (Filter_GL g) = g
1039 test (Filter_GL_Account f) g =
1040 test f $ gl_account g
1041 test (Filter_GL_Amount f) g =
1042 test f $ gl_amount g
1043 test (Filter_GL_Sum f) g =
1047 Filter_GL_Account ff -> Filter_GL_Account <$> simplify ff
1048 Filter_GL_Amount ff -> Filter_GL_Amount <$> simplify ff
1049 Filter_GL_Sum ff -> Filter_GL_Sum <$> simplify ff
1052 ( Transaction transaction
1053 , GL.Transaction transaction
1054 ) => Consable (Filtered (Simplified (Filter_Bool (Filter_Transaction transaction)))
1058 mcons (Filtered ft t) m =
1059 case simplified ft of
1061 Right True -> GL.cons t m
1067 ( Transaction transaction
1068 , GL.Transaction transaction
1070 , posting ~ GL.Transaction_Posting transaction
1072 => Consable (Filtered ( (Simplified (Filter_Bool (Filter_Transaction transaction)))
1073 , (Simplified (Filter_Bool (Filter_Posting posting ))) )
1077 mcons (Filtered (ft, fp) t) m =
1078 case simplified ft of
1081 case simplified fp of
1083 Right True -> GL.cons t m
1086 (GL.transaction_postings_filter (test fps) t)
1091 case simplified fp of
1093 Right True -> GL.cons t m
1096 (GL.transaction_postings_filter (test fps) t)
1101 , Transaction transaction
1102 , GL.Transaction transaction
1104 , posting ~ GL.Transaction_Posting transaction
1106 => Consable (Filtered ( (Simplified (Filter_Bool (Filter_Transaction transaction)))
1107 , (Simplified (Filter_Bool (Filter_Posting posting ))) )
1108 (foldable transaction))
1111 mcons (Filtered (ft, fp) ts) m =
1112 case simplified ft of
1115 case simplified fp of
1117 Right True -> foldr (GL.cons) m ts
1121 . GL.transaction_postings_filter (test fps) )
1128 case simplified fp of
1130 Right True -> GL.cons t
1131 Left fps -> GL.cons $
1132 GL.transaction_postings_filter (test fps) t