1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE NoMonomorphismRestriction #-}
3 {-# LANGUAGE UndecidableInstances #-}
4 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
5 {-# OPTIONS_GHC -fno-warn-orphans #-}
6 module Hcompta.LCC.Write.Balance where
8 import Control.Monad (Monad(..))
10 import Data.Char (Char)
12 import Data.Eq (Eq(..))
13 -- import Data.Foldable (Foldable(..))
14 import Data.Function (($), (.), flip, id)
15 import Data.Functor ((<$>))
16 import Data.Functor.Compose (Compose(..))
17 import Data.Proxy (Proxy(..))
18 import Data.Map.Strict (Map)
19 import Data.Maybe (Maybe(..), fromMaybe, maybe)
20 import Data.Monoid (Monoid(..))
21 import Data.Ord (Ord(..))
22 import Data.Semigroup (Semigroup(..))
23 import Data.Text (Text)
24 import Data.Tuple (fst)
25 import GHC.Exts (Int(..))
26 import Prelude (Integer, Num(..), RealFrac(..), Show(..), Integral(..), fromIntegral)
28 import qualified Data.ByteString as BS
29 import qualified Data.Char as Char
30 import qualified Data.List as L
31 import qualified Data.Map.Strict as Map
32 import qualified Data.MonoTraversable as MT
33 import qualified Data.NonNull as NonNull
34 import qualified Data.Strict as S
35 import qualified Data.Text as Text
36 import qualified Data.Text.Encoding as Enc
37 import qualified Data.TreeMap.Strict as TM
39 import qualified Language.Symantic.Document as D
41 import qualified Hcompta as H
43 import Hcompta.LCC.Account
44 import Hcompta.LCC.Amount
45 import Hcompta.LCC.Chart
46 import Hcompta.LCC.Compta
48 import Hcompta.LCC.Journal
49 import Hcompta.LCC.Name
50 import Hcompta.LCC.Posting
51 import Hcompta.LCC.Tag
52 import Hcompta.LCC.Transaction
53 import Hcompta.LCC.Balance
54 import Hcompta.LCC.Write.Compta
55 import Hcompta.LCC.Write.Table
56 import qualified Hcompta.LCC.Read.Compta as G
57 import qualified Hcompta.Lib.Strict as S
60 -- * Class 'Msg_Title'
61 class Msg_Title lang d where
64 msg_Title_Balance :: d
65 msg_Title_Account :: d
69 instance D.Doc_Text d => Msg_Title FR d where
70 msg_Title_Debit = D.textH "Débit"
71 msg_Title_Credit = D.textH "Crédit"
72 msg_Title_Balance = D.textH "Solde"
73 msg_Title_Account = D.textH "Compte"
75 -- * Type 'Config_Balance'
78 { config_balance_heritage :: Bool
79 , config_balance_total_by_unit :: Bool
82 instance Writeable (Style_Amount, Amount) d =>
83 CellPlainOf (Style_Amount, Amount) d
84 instance Writeable Date d => CellPlainOf Date d
85 instance Writeable Account d => CellPlainOf Account d
86 instance ( CellPlainOf () d
87 , CellPlainOf (Style_Amount, Amount) d
88 ) => CellPlainOf (Maybe (Style_Amount, Amount)) d where
89 cellPlainOf = cellPlainOf () `maybe` cellPlainOf
91 -- instance D.Doc_Text d => CellPlainOf Wording d
94 type RowsPlain d = [[CellPlain d]] -> [[CellPlain d]]
96 -- * Class 'RowsPlainOf'
97 class RowsPlainOf a d where
98 rowsPlainOf :: a -> RowsPlain d
100 instance ( CellPlainOf () d
101 , CellPlainOf Account d
102 , CellPlainOf (Style_Amount, Amount) d
103 ) => RowsPlainOf (Style_Amount, BalByAccount) d where
104 rowsPlainOf (sty, bal) =
105 flip (TM.foldrWithPath
110 [ cellPlainOf $ (sty,) . Amount unit <$> H.unPositive qty
111 , cellPlainOf $ (sty,) . Amount unit <$> H.unNegative qty
112 , cellPlainOf $ (sty,) $ Amount unit $ H.depolarize qty
113 , cellPlainOf $ Account acct
118 instance ( CellPlainOf () d
119 , CellPlainOf Account d
120 , CellPlainOf (Style_Amount, Amount) d
121 ) => RowsPlainOf (Style_Amount, ClusiveBalByAccount) d where
122 rowsPlainOf (sty, bal) =
123 flip (TM.foldrWithPath
124 (\acct S.Clusive{S.inclusive=sum} rows ->
128 [ cellPlainOf $ (sty,) . Amount unit <$> H.unPositive qty
129 , cellPlainOf $ (sty,) . Amount unit <$> H.unNegative qty
130 , cellPlainOf $ (sty,) $ Amount unit $ H.depolarize qty
131 , cellPlainOf $ Account acct
136 instance ( CellPlainOf () d
137 , CellPlainOf Account d
138 , CellPlainOf (Style_Amount, Amount) d
139 ) => RowsPlainOf (Style_Amount, BalByUnit) d where
140 rowsPlainOf (sty, bal) =
141 flip (Map.foldrWithKey
142 (\unit H.SumByUnit{H.sumByUnit_quantity=qty} ->
144 [ cellPlainOf $ (sty,) . Amount unit <$> H.unPositive qty
145 , cellPlainOf $ (sty,) . Amount unit <$> H.unNegative qty
146 , cellPlainOf $ (sty,) $ Amount unit $ H.depolarize qty
154 , Msg_Title lang Text
155 ) => TablePlainOf (Proxy lang, Style_Amount, BalByAccount, BalByUnit) d where
156 tablePlainOf (_lang, sty, ba, bu) =
158 [ columnPlain (msg_Title_Debit @lang) AlignPlainR
159 , columnPlain (msg_Title_Credit @lang) AlignPlainR
160 , columnPlain (msg_Title_Balance @lang) AlignPlainR
161 , columnPlain (msg_Title_Account @lang) AlignPlainL
163 rowsPlainOf (sty, ba) $
164 rowsPlainOf (sty, bu) $
168 instance Writeable (Proxy lang, Balance) d where
169 write (lang, H.Balance)
171 instance Writeable (Proxy lang, Compta src ss Balance) d where
172 write (lang, Compta{compta_journals=js, compta_style_amounts=sty}) =
173 tablePlainOf (lang, sty, )
175 instance ( CellPlainOf () d
176 , CellPlainOf Account d
177 , CellPlainOf (Style_Amount, Amount) d
178 ) => RowsPlainOf (Style_Amount, BalByAccount, H.BalByUnit) d where
179 rowsPlainOf (sty, bal) =
181 instance TablePlainOf (Style_Amount, H.BalByUnit NameAccount Unit (H.Polarized Quantity)) where
182 tablePlainOf conf balByAccount =
183 let (rowsByAccount, rowsByUnit) =
184 case config_balance_heritage conf of
185 True -> rowsOfBalByUnit $ H.clusiveBalByAccount balByAccount
186 False -> rowsOfBalByUnit balByAccount in
188 [ tColumn (msg_Title_Debit @lang) AlignR
189 , tColumn (msg_Title_Credit @lang) AlignR
190 , tColumn (msg_Title_Balance @lang) AlignR
191 , tColumn (msg_Title_Account @lang) AlignL
194 (if config_balance_total_by_unit conf
204 expand :: Forall_Journal_Balance_by_Account ->
205 Forall_Journal_Balance_by_Account_Expanded
206 expand = Format.journal_wrap
208 ( Format.Journal_Filter Context (Const BalByAccount) ()
209 , Format.Journal_Wrap BalByAccount Forall_Journal_Balance_by_Unit
210 , Format.Journal_Leijen_Table_Cells (Const BalByAccount) ()
213 ( [[CellPlain d]] -> [[CellPlain d]]
214 , [[CellPlain d]] -> [[CellPlain d]] )
216 (***) tCellsOfBalByAccount tCellsOfBalByUnit .
217 (&&&) id sum_by_unit .
218 Format.journal_filter ctx .
222 Format.Journal_Wrap BalByAccount Forall_Journal_Balance_by_Unit =>
223 Const BalByAccount () ->
224 Const Forall_Journal_Balance_by_Unit ()
225 sum_by_unit = Const . Format.journal_wrap . getConst
228 ttableOf :: forall lang d.
231 BalByAccount -> TTable d
240 instance Leijen.Table.Table_of (C.Context, Context) Forall_Journal_Balance_by_Account where
253 -- * 'H.Balance_by_Account'
255 -- ** Type 'Format_Balance_by_Account'
257 type Format_Journal_Balance_by_Account
259 ( JCC.Journal Balance_by_Account_JCC)
260 (Ledger.Journal Balance_by_Account_Ledger)
263 type Balance_by_Account_JCC
264 = H.Balance_by_Account JCC.Account_Section
266 (H.Polarized JCC.Quantity)
267 instance Format.Journal (JCC.Journal Balance_by_Account_JCC) where
268 type Journal_Format (JCC.Journal Balance_by_Account_JCC)
269 = Format_Journal_Balance_by_Account
270 journal_format = Format_JCC
273 type Balance_by_Account_Ledger
274 = H.Balance_by_Account Ledger.Account_Section
276 (H.Polarized Ledger.Quantity)
277 instance Format.Journal (Ledger.Journal Balance_by_Account_Ledger) where
278 type Journal_Format (Ledger.Journal Balance_by_Account_Ledger)
279 = Format_Journal_Balance_by_Account
280 journal_format = Format_Ledger
282 -- ** Class 'Journal_Balance_by_Account'
285 ( Format.Journal (j m)
286 , Format.Journal_Format (j m) ~ Format_Journal_Balance_by_Account
287 , Format.Journal_Read j
288 , Format.Journal_Monoid (j m)
289 , Format.Journal_Leijen_Table_Cells j m
290 , Format.Journal_Wrap (j m) Forall_Journal_Balance_by_Account_Expanded
291 , Format.Journal_Wrap (j m) Forall_Journal_Balance_by_Unit
292 , Format.Journal_Filter Context j m
293 , Journal_Equilibrium_Transaction j m
294 ) => Journal_Balance_by_Account j m
296 instance Journal_Balance_by_Account JCC.Journal Balance_by_Account_JCC
297 instance Journal_Balance_by_Account Ledger.Journal Balance_by_Account_Ledger
299 -- ** Type 'Forall_Journal_Balance_by_Account'
301 data Forall_Journal_Balance_by_Account
302 = forall j m. Journal_Balance_by_Account j m
303 => Forall_Journal_Balance_by_Account (j m)
305 instance Format.Journal Forall_Journal_Balance_by_Account where
306 type Journal_Format Forall_Journal_Balance_by_Account = Format_Journal_Balance_by_Account
308 (Forall_Journal_Balance_by_Account j) =
309 Format.journal_format j
310 instance Format.Journal_Empty Forall_Journal_Balance_by_Account where
313 Format_JCC () -> Forall_Journal_Balance_by_Account (mempty::JCC.Journal Balance_by_Account_JCC)
314 Format_Ledger () -> Forall_Journal_Balance_by_Account (mempty::Ledger.Journal Balance_by_Account_Ledger)
315 instance Format.Journal_Monoid Forall_Journal_Balance_by_Account where
317 (Forall_Journal_Balance_by_Account j) =
318 Forall_Journal_Balance_by_Account $
319 Format.journal_flatten j
320 journal_fold f (Forall_Journal_Balance_by_Account j) =
321 Format.journal_fold (f . Forall_Journal_Balance_by_Account) j
322 instance Monoid Forall_Journal_Balance_by_Account where
323 mempty = Forall_Journal_Balance_by_Account (mempty::JCC.Journal Balance_by_Account_JCC)
325 case (mappend `on` Format.journal_format) x y of
326 Format_JCC j -> Forall_Journal_Balance_by_Account j
327 Format_Ledger j -> Forall_Journal_Balance_by_Account j
331 j:jn -> List.foldl' mappend j jn
335 type Journal_Filter_Simplified transaction
338 (Filter.Filter_Transaction transaction))
339 type Journal_Read_Cons txn
340 = txn -> Filter.Filtered (Journal_Filter_Simplified txn) txn
342 :: Context -> FilePath
343 -> IO (Either (Format.Message W.Doc) Forall_Journal_Balance_by_Account)
345 case ctx_input_format ctx of
347 let wrap (j::JCC.Journal Balance_by_Account_JCC)
348 = Forall_Journal_Balance_by_Account j in
349 let cons :: Journal_Read_Cons (JCC.Charted JCC.Transaction)
350 = Filter.Filtered (ctx_filter_transaction ctx) in
351 liftM ((+++) Format.Message wrap) .
352 Format.journal_read cons
354 let wrap (j::Ledger.Journal Balance_by_Account_Ledger)
355 = Forall_Journal_Balance_by_Account j in
356 let cons :: Journal_Read_Cons (Ledger.Charted Ledger.Transaction)
357 = Filter.Filtered (ctx_filter_transaction ctx) in
358 liftM ((+++) Format.Message wrap) .
359 Format.journal_read cons
362 -- ** Type family 'Balance_by_Account'
364 type family Balance_by_Account (j:: * -> *) m
365 type instance Balance_by_Account
366 j (Balance.Expanded as u (Polarized q))
367 = j (Balance.Balance_by_Account as u (Polarized q))
368 type instance Balance_by_Account
369 (Const Forall_Journal_Balance_by_Account_Expanded) ()
370 = (Const Forall_Journal_Balance_by_Account ) ()
373 -- Instances 'Format.Journal_Filter'
377 , Format.Journal_Chart j
379 , as ~ Format.Journal_Account_Section j
381 {-, Filter.Account (Account_Tags, TreeMap.Path as)-}
386 , q ~ Format.Journal_Quantity j
387 , Format.Journal_Quantity j ~ Decimal
392 ) => Format.Journal_Filter Context j (H.Balance_by_Account as u (H.Polarized q)) where
393 journal_filter ctx j =
394 case Filter.simplified $ ctx_filter_balance ctx of
395 Right True | ctx_redundant ctx -> j
397 TreeMap.filter_with_Path_and_Node
398 (\n _p -> is_worth n) <$> j
399 Right False -> const mempty <$> j
402 TreeMap.map_Maybe_with_Path_and_Node
403 (\node account (H.Balance_by_Account_Sum bal) ->
404 (if is_worth node bal then id else const Strict.Nothing) $
405 case Map.mapMaybeWithKey
408 ( (H.chart_account_tags account (Format.journal_chart j), account)
414 m | Map.null m -> Strict.Nothing
415 m -> Strict.Just $ H.Balance_by_Account_Sum m
419 :: (Ord k0, Foldable t0, H.Addable a0, H.Zero a0)
420 => TreeMap.Node k0 x0
421 -> t0 (H.Polarized a0)
425 -- NOTE: worth if no descendant
426 -- but Account's exclusive
427 -- has at least a non-zero Amount
429 (not . H.quantity_null . H.depolarize)
431 instance Format.Journal_Filter Context (Const Forall_Journal_Balance_by_Account) () where
433 (Const (Forall_Journal_Balance_by_Account j)) =
434 Const $ Forall_Journal_Balance_by_Account $
435 Format.journal_filter ctx j
437 -- Instances 'Format.Journal_Leijen_Table_Cells'
440 ( Format.Journal_Content j
443 , as ~ Format.Journal_Account_Section j
445 , H.Addable (Format.Journal_Quantity j)
447 , Leijen.Table.Cell_of_forall_param j (TreeMap.Path as)
449 , Balance_by_Account_Sum amt
450 , Balance_by_Account_Sum_Unit amt ~ Format.Journal_Unit j
451 , Balance_by_Account_Sum_Quantity amt ~ H.Polarized (Format.Journal_Quantity j)
452 ) => Format.Journal_Leijen_Table_Cells j (TreeMap as amt) where
453 journal_leijen_table_cells jnl =
454 flip (TreeMap.foldr_with_Path
455 (\account balance rows ->
456 let H.Balance_by_Account_Sum bal = balance_by_account_sum balance in
460 [ cell_of $ (unit,) <$> H.polarized_positive qty
461 , cell_of $ (unit,) <$> H.polarized_negative qty
462 , cell_of (unit, H.depolarize qty)
468 (Format.journal_content jnl)
470 cell_of :: Leijen.Table.Cell_of_forall_param j x => x -> Leijen.Table.Cell
471 cell_of = Leijen.Table.cell_of_forall_param jnl
472 instance Format.Journal_Leijen_Table_Cells (Const Forall_Journal_Balance_by_Account) () where
473 journal_leijen_table_cells
474 (Const (Forall_Journal_Balance_by_Account j)) =
475 Format.journal_leijen_table_cells j
477 -- ** Class 'Balance_by_Account_Sum'
479 -- | A class to get a 'H.Balance_Account_Sum'
480 -- when operating on 'H.Balance_by_Account'
481 -- or 'H.Balance_Expanded' 'Strict.inclusive' field.
482 class Balance_by_Account_Sum amt where
483 type Balance_by_Account_Sum_Unit amt
484 type Balance_by_Account_Sum_Quantity amt
485 balance_by_account_sum
486 :: amt -> H.Balance_by_Account_Sum (Balance_by_Account_Sum_Unit amt)
487 (Balance_by_Account_Sum_Quantity amt)
488 instance Balance_by_Account_Sum (H.Balance_by_Account_Sum u q) where
489 type Balance_by_Account_Sum_Unit (H.Balance_by_Account_Sum u q) = u
490 type Balance_by_Account_Sum_Quantity (H.Balance_by_Account_Sum u q) = q
491 balance_by_account_sum = id
492 instance Balance_by_Account_Sum (H.Balance_by_Account_Sum_Expanded u q) where
493 type Balance_by_Account_Sum_Unit (H.Balance_by_Account_Sum_Expanded u q) = u
494 type Balance_by_Account_Sum_Quantity (H.Balance_by_Account_Sum_Expanded u q) = q
495 balance_by_account_sum = Strict.inclusive
497 -- * 'H.Balance_Expanded'
499 -- ** Type 'Format_Journal_Balance_by_Account_Expanded'
501 type Format_Journal_Balance_by_Account_Expanded
503 ( JCC.Journal Balance_by_Account_Expanded_JCC)
504 (Ledger.Journal Balance_by_Account_Expanded_Ledger)
507 type Balance_by_Account_Expanded_JCC
508 = H.Balance_Expanded JCC.Account_Section
510 (H.Polarized JCC.Quantity)
511 instance Format.Journal (JCC.Journal Balance_by_Account_Expanded_JCC) where
512 type Journal_Format (JCC.Journal Balance_by_Account_Expanded_JCC)
513 = Format_Journal_Balance_by_Account_Expanded
514 journal_format = Format_JCC
517 type Balance_by_Account_Expanded_Ledger
518 = H.Balance_Expanded Ledger.Account_Section
520 (H.Polarized Ledger.Quantity)
521 instance Format.Journal (Ledger.Journal Balance_by_Account_Expanded_Ledger) where
522 type Journal_Format (Ledger.Journal Balance_by_Account_Expanded_Ledger)
523 = Format_Journal_Balance_by_Account_Expanded
524 journal_format = Format_Ledger
526 -- ** Class 'Journal_Balance_by_Account_Expanded'
529 ( Format.Journal (j m)
530 , Format.Journal_Format (j m) ~ Format_Journal_Balance_by_Account_Expanded
531 , Format.Journal_Leijen_Table_Cells j m
532 , Format.Journal_Wrap (j m) Forall_Journal_Balance_by_Unit
533 , Format.Journal_Filter Context j m
534 ) => Journal_Balance_by_Account_Expanded j m
536 instance Journal_Balance_by_Account_Expanded JCC.Journal Balance_by_Account_Expanded_JCC
537 instance Journal_Balance_by_Account_Expanded Ledger.Journal Balance_by_Account_Expanded_Ledger
539 -- ** Type 'Forall_Journal_Balance_by_Account_Expanded'
541 data Forall_Journal_Balance_by_Account_Expanded
542 = forall j m. Journal_Balance_by_Account_Expanded j m
543 => Forall_Journal_Balance_by_Account_Expanded (j m)
545 instance Format.Journal Forall_Journal_Balance_by_Account_Expanded where
546 type Journal_Format Forall_Journal_Balance_by_Account_Expanded = Format_Journal_Balance_by_Account_Expanded
548 (Forall_Journal_Balance_by_Account_Expanded j) =
549 Format.journal_format j
551 -- Instances 'Format.Journal_Filter'
555 , Format.Journal_Chart j
556 , as ~ Format.Journal_Account_Section j
558 {-, Filter.Account (Account_Tags, TreeMap.Path as)-}
562 , q ~ Format.Journal_Quantity j
563 , Format.Journal_Quantity j ~ Decimal
567 ) => Format.Journal_Filter Context j (H.Balance_Expanded as u (H.Polarized q)) where
568 journal_filter ctx j =
569 case Filter.simplified $ ctx_filter_balance ctx of
570 Right True | ctx_redundant ctx -> j
572 TreeMap.filter_with_Path_and_Node
573 (const . is_worth) <$> j
574 Right False -> const mempty <$> j
577 TreeMap.map_Maybe_with_Path_and_Node
578 (\node account bal ->
579 (if is_worth node bal then id else const Strict.Nothing) $
580 case Map.mapMaybeWithKey
583 ( (H.chart_account_tags account (Format.journal_chart j), account)
588 ) (H.unBalance_by_Account_Sum $ Strict.inclusive bal) of
589 m | Map.null m -> Strict.Nothing
590 m -> Strict.Just $ bal{Strict.inclusive=H.Balance_by_Account_Sum m}
594 let descendants = TreeMap.nodes
595 (TreeMap.node_descendants node) in
597 -- NOTE: worth if no descendant
598 -- but Account's inclusive
599 -- has at least a non-zero Amount
600 || (Map.null descendants &&
602 (not . H.quantity_null . H.depolarize)
603 (H.unBalance_by_Account_Sum $ Strict.inclusive bal))
604 -- NOTE: worth if Account's exclusive
605 -- has at least a non-zero Amount
607 (not . H.quantity_null . H.depolarize)
608 (H.unBalance_by_Account_Sum $ Strict.exclusive bal))
609 -- NOTE: worth if Account has at least more than
610 -- one descendant Account whose inclusive
611 -- has at least a non-zero Amount
616 (not . H.quantity_null . H.depolarize)
617 . H.unBalance_by_Account_Sum
619 . TreeMap.node_value )
622 instance Format.Journal_Filter Context (Const Forall_Journal_Balance_by_Account_Expanded) () where
624 (Const (Forall_Journal_Balance_by_Account_Expanded j)) =
625 Const $ Forall_Journal_Balance_by_Account_Expanded $
626 Format.journal_filter ctx j
628 -- Instances 'Format.Journal_Leijen_Table_Cells'
630 instance Format.Journal_Leijen_Table_Cells (Const Forall_Journal_Balance_by_Account_Expanded) x where
631 journal_leijen_table_cells
632 (Const (Forall_Journal_Balance_by_Account_Expanded j)) =
633 Format.journal_leijen_table_cells j
635 -- Instances H.Balance_by_Account -> H.Balance_Expanded
639 , Journal_Balance_by_Account_Expanded j (H.Balance_Expanded as u q)
641 -- NOTE: constraints from H.balance_expanded
645 ) => Format.Journal_Wrap (j (H.Balance_by_Account as u q))
646 Forall_Journal_Balance_by_Account_Expanded where
648 Forall_Journal_Balance_by_Account_Expanded .
649 fmap H.balance_expanded
651 instance Format.Journal_Wrap Forall_Journal_Balance_by_Account
652 Forall_Journal_Balance_by_Account_Expanded where
653 journal_wrap (Forall_Journal_Balance_by_Account j) = Format.journal_wrap j
665 -- * 'H.Balance_by_Unit'
667 type Format_Journal_Balance_by_Unit
669 ( JCC.Journal Balance_by_Unit_JCC)
670 (Ledger.Journal Balance_by_Unit_Ledger)
673 type Balance_by_Unit_JCC
674 = H.Balance_by_Unit JCC.Account
676 (H.Polarized JCC.Quantity)
677 instance Format.Journal (JCC.Journal Balance_by_Unit_JCC) where
678 type Journal_Format (JCC.Journal Balance_by_Unit_JCC)
679 = Format_Journal_Balance_by_Unit
680 journal_format = Format_JCC
683 type Balance_by_Unit_Ledger
684 = H.Balance_by_Unit Ledger.Account
686 (H.Polarized Ledger.Quantity)
687 instance Format.Journal (Ledger.Journal Balance_by_Unit_Ledger) where
688 type Journal_Format (Ledger.Journal Balance_by_Unit_Ledger)
689 = Format_Journal_Balance_by_Unit
690 journal_format = Format_Ledger
692 -- ** Class 'Journal_Balance_by_Unit'
695 ( Format.Journal (j m)
696 , Format.Journal_Format (j m) ~ Format_Journal_Balance_by_Unit
697 , Format.Journal_Leijen_Table_Cells j m
698 -- , Journal_Equilibrium_Postings j m
700 => Journal_Balance_by_Unit j m
702 instance Journal_Balance_by_Unit JCC.Journal Balance_by_Unit_JCC
703 instance Journal_Balance_by_Unit Ledger.Journal Balance_by_Unit_Ledger
705 -- ** Type 'Forall_Journal_Balance_by_Unit'
707 data Forall_Journal_Balance_by_Unit
708 = forall j m. Journal_Balance_by_Unit j m
709 => Forall_Journal_Balance_by_Unit (j m)
711 instance Format.Journal Forall_Journal_Balance_by_Unit where
712 type Journal_Format Forall_Journal_Balance_by_Unit = Format_Journal_Balance_by_Unit
713 journal_format (Forall_Journal_Balance_by_Unit j) = Format.journal_format j
715 -- Instances H.Balance_by_Account -> H.Balance_by_Unit
719 , Journal_Balance_by_Unit j (H.Balance_by_Unit (H.Account_Path as) u q)
721 -- NOTE: constraints from H.balance_by_unit_of_by_account
722 , H.Account (H.Account_Path as)
726 ) => Format.Journal_Wrap (j (H.Balance_by_Account as u q))
727 Forall_Journal_Balance_by_Unit where
729 Forall_Journal_Balance_by_Unit .
730 fmap (flip H.balance_by_unit_of_by_account mempty)
732 instance Format.Journal_Wrap Forall_Journal_Balance_by_Account
733 Forall_Journal_Balance_by_Unit where
735 (Forall_Journal_Balance_by_Account j) =
736 Format.journal_wrap j
738 -- Instances H.Balance_Expanded -> H.Balance_by_Unit
742 , Journal_Balance_by_Unit j (H.Balance_by_Unit (H.Account_Path as) u q)
744 -- NOTE: constraints from H.balance_by_unit_of_expanded
745 , H.Account (H.Account_Path as)
749 ) => Format.Journal_Wrap (j (H.Balance_Expanded as u q))
750 Forall_Journal_Balance_by_Unit where
752 Forall_Journal_Balance_by_Unit .
753 fmap (flip H.balance_by_unit_of_expanded mempty)
755 instance Format.Journal_Wrap Forall_Journal_Balance_by_Account_Expanded
756 Forall_Journal_Balance_by_Unit where
758 (Forall_Journal_Balance_by_Account_Expanded j) =
759 Format.journal_wrap j
761 -- Instances 'Format.Journal_Leijen_Table_Cells'
764 ( Format.Journal_Content j
767 , a ~ Format.Journal_Account j
769 , u ~ Format.Journal_Unit j
771 , q ~ Format.Journal_Quantity j
772 , H.Addable (Format.Journal_Quantity j)
773 ) => Format.Journal_Leijen_Table_Cells j (H.Balance_by_Unit a u (H.Polarized q)) where
774 journal_leijen_table_cells jnl acc =
775 let H.Balance_by_Unit bal = Format.journal_content jnl in
778 let qty = H.balance_by_unit_sum_quantity amt in
780 [ Leijen.Table.cell_of_forall_param jnl $ (unit,) <$> H.polarized_positive qty
781 , Leijen.Table.cell_of_forall_param jnl $ (unit,) <$> H.polarized_negative qty
782 , Leijen.Table.cell_of_forall_param jnl (unit, H.depolarize qty)
786 instance Format.Journal_Leijen_Table_Cells (Const Forall_Journal_Balance_by_Unit) () where
787 journal_leijen_table_cells
788 (Const (Forall_Journal_Balance_by_Unit j)) =
789 Format.journal_leijen_table_cells j
802 ( Leijen.Table.Cell_of_forall_param j (Format.Journal_Unit j, Format.Journal_Quantity j)
803 , W.ToDoc1 j [Format.Journal_Transaction j]
804 ) => Journal (j:: * -> *) where
807 -> H.Account_Path (Format.Journal_Account_Section j)
808 -> Map (Format.Journal_Unit j)
809 (Format.Journal_Quantity j)
810 -> [Text] -- ^ Comments
811 -> Format.Journal_Posting j
815 -> (H.Date, [H.Date])
816 -> Map (H.Account_Path (Format.Journal_Account_Section j))
817 [Format.Journal_Posting j]
818 -> Format.Journal_Transaction j
820 instance Journal JCC.Journal where
821 journal_posting _j acct
825 { JCC.posting_amounts
826 , JCC.posting_comments
828 journal_transaction _j
831 transaction_postings =
833 { JCC.transaction_wording
834 , JCC.transaction_dates
835 , JCC.transaction_postings
837 instance Journal Ledger.Journal where
838 journal_posting _j acct
841 (Ledger.posting acct)
842 { Ledger.posting_amounts
843 , Ledger.posting_comments
845 journal_transaction _j
848 transaction_postings =
850 { Ledger.transaction_wording
851 , Ledger.transaction_dates
852 , Ledger.transaction_postings
867 -- * Class 'Journal_Equilibrium_Transaction'
869 class Journal_Equilibrium_Transaction j m where
870 journal_equilibrium_transaction
879 ( Format.Journal_Content j
882 , as ~ Format.Journal_Account_Section j
883 , Format.Journal_Account_Section j ~ Text
884 , Format.Journal_Account j ~ TreeMap.Path Text
886 , quantity ~ Format.Journal_Quantity j
889 , H.Zero (Format.Journal_Quantity j)
890 , H.Addable (Format.Journal_Quantity j)
891 , unit ~ Format.Journal_Unit j
892 ) => Journal_Equilibrium_Transaction
893 j (H.Balance_by_Account as unit (H.Polarized quantity)) where
894 journal_equilibrium_transaction
896 let bal_by_account = Format.journal_content j in
897 let H.Balance_by_Unit bal_by_unit =
898 H.balance_by_unit_of_by_account bal_by_account mempty in
901 (\acc unit H.Balance_by_Unit_Sum{..} ->
904 Lang.Exercise_Closing -> id
905 Lang.Exercise_Opening -> negate) $
906 H.depolarize balance_by_unit_sum_quantity in
907 case H.quantity_sign qty of
909 let account = snd $ ctx_account_equilibrium ctx in
910 Map.insertWith mappend account
911 [journal_posting j account
912 (Map.singleton unit qty)
913 [ Lang.translate (C.lang c) Lang.Comment_Equilibrium ]]
917 let account = fst $ ctx_account_equilibrium ctx in
918 Map.insertWith mappend account
919 [journal_posting j account
920 (Map.singleton unit qty)
921 [ Lang.translate (C.lang c) Lang.Comment_Equilibrium ]]
928 journal_transaction j
929 (Lang.translate (C.lang c) (Lang.Description_Exercise oc))
930 (now{Time.utctDayTime=0}, []) $
931 Map.unionWith mappend postings $
932 TreeMap.flatten_with_Path
933 (\posting_account (H.Balance_by_Account_Sum amount_by_unit) ->
934 [ journal_posting j posting_account
935 (flip fmap amount_by_unit $
937 Lang.Exercise_Closing -> negate
938 Lang.Exercise_Opening -> id)
946 instance Journal_Equilibrium_Transaction (Const Forall_Journal_Balance_by_Account) () where
947 journal_equilibrium_transaction
948 (Const (Forall_Journal_Balance_by_Account j)) =
949 journal_equilibrium_transaction j
955 ToDoc (C.Context, Context, Date, Lang.Exercise_OC)
956 ( Forall_Journal_Balance_by_Account
957 , Forall_Journal_Balance_by_Unit ) where
959 ( Forall_Journal_Balance_by_Account bal_by_account
960 , Forall_Journal_Balance_by_Unit bal_by_unit
962 toDoc c (bal_by_account, bal_by_unit)