{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE KindSignatures #-}

-- | This module provides data definitions and functions to work with journal
-- entries.
module Haspara.Accounting.Journal where

import qualified Data.Aeson as Aeson
import qualified Data.Text as T
import Data.Time (Day)
import GHC.Generics (Generic)
import GHC.TypeLits (KnownNat, Nat)
import Haspara.Accounting.Account (Account (accountKind))
import Haspara.Accounting.Amount (Amount (..), amountFromValue)
import Haspara.Accounting.Side (Side (..))
import Haspara.Internal.Aeson (commonAesonOptions)
import Haspara.Quantity (Quantity, UnsignedQuantity, sumUnsignedQuantity)


-- | Data definition for the journal entries of interest (like a general
-- ledger.)
--
-- A 'Journal' is a list of 'JournalEntry' records which are polymorphic over
-- the precision of the monetary quantities, the account and event objects.
newtype Journal (precision :: Nat) account event = Journal
  { forall (precision :: Nat) account event.
Journal precision account event
-> [JournalEntry precision account event]
journalEntries :: [JournalEntry precision account event]
  }
  deriving ((forall x.
 Journal precision account event
 -> Rep (Journal precision account event) x)
-> (forall x.
    Rep (Journal precision account event) x
    -> Journal precision account event)
-> Generic (Journal precision account event)
forall (precision :: Nat) account event x.
Rep (Journal precision account event) x
-> Journal precision account event
forall (precision :: Nat) account event x.
Journal precision account event
-> Rep (Journal precision account event) x
forall x.
Rep (Journal precision account event) x
-> Journal precision account event
forall x.
Journal precision account event
-> Rep (Journal precision account event) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (precision :: Nat) account event x.
Journal precision account event
-> Rep (Journal precision account event) x
from :: forall x.
Journal precision account event
-> Rep (Journal precision account event) x
$cto :: forall (precision :: Nat) account event x.
Rep (Journal precision account event) x
-> Journal precision account event
to :: forall x.
Rep (Journal precision account event) x
-> Journal precision account event
Generic, Int -> Journal precision account event -> ShowS
[Journal precision account event] -> ShowS
Journal precision account event -> String
(Int -> Journal precision account event -> ShowS)
-> (Journal precision account event -> String)
-> ([Journal precision account event] -> ShowS)
-> Show (Journal precision account event)
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> Journal precision account event -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[Journal precision account event] -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Journal precision account event -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> Journal precision account event -> ShowS
showsPrec :: Int -> Journal precision account event -> ShowS
$cshow :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Journal precision account event -> String
show :: Journal precision account event -> String
$cshowList :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[Journal precision account event] -> ShowS
showList :: [Journal precision account event] -> ShowS
Show)


instance (KnownNat precision, Aeson.FromJSON account, Aeson.FromJSON event) => Aeson.FromJSON (Journal precision account event) where
  parseJSON :: Value -> Parser (Journal precision account event)
parseJSON = Options -> Value -> Parser (Journal precision account event)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON (Options -> Value -> Parser (Journal precision account event))
-> Options -> Value -> Parser (Journal precision account event)
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journal"


instance (KnownNat precision, Aeson.ToJSON account, Aeson.ToJSON event) => Aeson.ToJSON (Journal precision account event) where
  toJSON :: Journal precision account event -> Value
toJSON = Options -> Journal precision account event -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON (Options -> Journal precision account event -> Value)
-> Options -> Journal precision account event -> Value
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journal"
  toEncoding :: Journal precision account event -> Encoding
toEncoding = Options -> Journal precision account event -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding (Options -> Journal precision account event -> Encoding)
-> Options -> Journal precision account event -> Encoding
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journal"


-- | Data definition for a journal entry.
--
-- A journal entry has a (unique) identifier, date and description, and a list
-- of 'JournalEntryItem's. Journal entry definition is polymorphic over the
-- precision of the monetary quantities, the account and event objects.
data JournalEntry (precision :: Nat) account event = JournalEntry
  { forall (precision :: Nat) account event.
JournalEntry precision account event -> Text
journalEntryId :: !T.Text
  , forall (precision :: Nat) account event.
JournalEntry precision account event -> Day
journalEntryDate :: !Day
  , forall (precision :: Nat) account event.
JournalEntry precision account event
-> [JournalEntryItem precision account event]
journalEntryItems :: ![JournalEntryItem precision account event]
  , forall (precision :: Nat) account event.
JournalEntry precision account event -> Text
journalEntryDescription :: !T.Text
  }
  deriving ((forall x.
 JournalEntry precision account event
 -> Rep (JournalEntry precision account event) x)
-> (forall x.
    Rep (JournalEntry precision account event) x
    -> JournalEntry precision account event)
-> Generic (JournalEntry precision account event)
forall (precision :: Nat) account event x.
Rep (JournalEntry precision account event) x
-> JournalEntry precision account event
forall (precision :: Nat) account event x.
JournalEntry precision account event
-> Rep (JournalEntry precision account event) x
forall x.
Rep (JournalEntry precision account event) x
-> JournalEntry precision account event
forall x.
JournalEntry precision account event
-> Rep (JournalEntry precision account event) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (precision :: Nat) account event x.
JournalEntry precision account event
-> Rep (JournalEntry precision account event) x
from :: forall x.
JournalEntry precision account event
-> Rep (JournalEntry precision account event) x
$cto :: forall (precision :: Nat) account event x.
Rep (JournalEntry precision account event) x
-> JournalEntry precision account event
to :: forall x.
Rep (JournalEntry precision account event) x
-> JournalEntry precision account event
Generic, Int -> JournalEntry precision account event -> ShowS
[JournalEntry precision account event] -> ShowS
JournalEntry precision account event -> String
(Int -> JournalEntry precision account event -> ShowS)
-> (JournalEntry precision account event -> String)
-> ([JournalEntry precision account event] -> ShowS)
-> Show (JournalEntry precision account event)
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> JournalEntry precision account event -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[JournalEntry precision account event] -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
JournalEntry precision account event -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> JournalEntry precision account event -> ShowS
showsPrec :: Int -> JournalEntry precision account event -> ShowS
$cshow :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
JournalEntry precision account event -> String
show :: JournalEntry precision account event -> String
$cshowList :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[JournalEntry precision account event] -> ShowS
showList :: [JournalEntry precision account event] -> ShowS
Show)


instance (KnownNat precision, Aeson.FromJSON account, Aeson.FromJSON event) => Aeson.FromJSON (JournalEntry precision account event) where
  parseJSON :: Value -> Parser (JournalEntry precision account event)
parseJSON = Options -> Value -> Parser (JournalEntry precision account event)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON (Options -> Value -> Parser (JournalEntry precision account event))
-> Options
-> Value
-> Parser (JournalEntry precision account event)
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntry"


instance (KnownNat precision, Aeson.ToJSON account, Aeson.ToJSON event) => Aeson.ToJSON (JournalEntry precision account event) where
  toJSON :: JournalEntry precision account event -> Value
toJSON = Options -> JournalEntry precision account event -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON (Options -> JournalEntry precision account event -> Value)
-> Options -> JournalEntry precision account event -> Value
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntry"
  toEncoding :: JournalEntry precision account event -> Encoding
toEncoding = Options -> JournalEntry precision account event -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding (Options -> JournalEntry precision account event -> Encoding)
-> Options -> JournalEntry precision account event -> Encoding
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntry"


-- | Returns the total debit amount of a journal entry.
journalEntryTotalDebit
  :: KnownNat precision
  => JournalEntry precision account event
  -> UnsignedQuantity precision
journalEntryTotalDebit :: forall (precision :: Nat) account event.
KnownNat precision =>
JournalEntry precision account event -> UnsignedQuantity precision
journalEntryTotalDebit =
  [UnsignedQuantity precision] -> UnsignedQuantity precision
forall (s :: Nat).
KnownNat s =>
[UnsignedQuantity s] -> UnsignedQuantity s
sumUnsignedQuantity
    ([UnsignedQuantity precision] -> UnsignedQuantity precision)
-> (JournalEntry precision account event
    -> [UnsignedQuantity precision])
-> JournalEntry precision account event
-> UnsignedQuantity precision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JournalEntryItem precision account event
 -> UnsignedQuantity precision)
-> [JournalEntryItem precision account event]
-> [UnsignedQuantity precision]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Amount precision -> UnsignedQuantity precision
forall (precision :: Nat).
Amount precision -> UnsignedQuantity precision
amountValue (Amount precision -> UnsignedQuantity precision)
-> (JournalEntryItem precision account event -> Amount precision)
-> JournalEntryItem precision account event
-> UnsignedQuantity precision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntryItem precision account event -> Amount precision
forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Amount precision
journalEntryItemAmount)
    ([JournalEntryItem precision account event]
 -> [UnsignedQuantity precision])
-> (JournalEntry precision account event
    -> [JournalEntryItem precision account event])
-> JournalEntry precision account event
-> [UnsignedQuantity precision]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JournalEntryItem precision account event -> Bool)
-> [JournalEntryItem precision account event]
-> [JournalEntryItem precision account event]
forall a. (a -> Bool) -> [a] -> [a]
filter (Side -> Side -> Bool
forall a. Eq a => a -> a -> Bool
(==) Side
SideDebit (Side -> Bool)
-> (JournalEntryItem precision account event -> Side)
-> JournalEntryItem precision account event
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Amount precision -> Side
forall (precision :: Nat). Amount precision -> Side
amountSide (Amount precision -> Side)
-> (JournalEntryItem precision account event -> Amount precision)
-> JournalEntryItem precision account event
-> Side
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntryItem precision account event -> Amount precision
forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Amount precision
journalEntryItemAmount)
    ([JournalEntryItem precision account event]
 -> [JournalEntryItem precision account event])
-> (JournalEntry precision account event
    -> [JournalEntryItem precision account event])
-> JournalEntry precision account event
-> [JournalEntryItem precision account event]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntry precision account event
-> [JournalEntryItem precision account event]
forall (precision :: Nat) account event.
JournalEntry precision account event
-> [JournalEntryItem precision account event]
journalEntryItems


-- | Returns the total credit amount of a journal entry.
journalEntryTotalCredit
  :: KnownNat precision
  => JournalEntry precision account event
  -> UnsignedQuantity precision
journalEntryTotalCredit :: forall (precision :: Nat) account event.
KnownNat precision =>
JournalEntry precision account event -> UnsignedQuantity precision
journalEntryTotalCredit =
  [UnsignedQuantity precision] -> UnsignedQuantity precision
forall (s :: Nat).
KnownNat s =>
[UnsignedQuantity s] -> UnsignedQuantity s
sumUnsignedQuantity
    ([UnsignedQuantity precision] -> UnsignedQuantity precision)
-> (JournalEntry precision account event
    -> [UnsignedQuantity precision])
-> JournalEntry precision account event
-> UnsignedQuantity precision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JournalEntryItem precision account event
 -> UnsignedQuantity precision)
-> [JournalEntryItem precision account event]
-> [UnsignedQuantity precision]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Amount precision -> UnsignedQuantity precision
forall (precision :: Nat).
Amount precision -> UnsignedQuantity precision
amountValue (Amount precision -> UnsignedQuantity precision)
-> (JournalEntryItem precision account event -> Amount precision)
-> JournalEntryItem precision account event
-> UnsignedQuantity precision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntryItem precision account event -> Amount precision
forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Amount precision
journalEntryItemAmount)
    ([JournalEntryItem precision account event]
 -> [UnsignedQuantity precision])
-> (JournalEntry precision account event
    -> [JournalEntryItem precision account event])
-> JournalEntry precision account event
-> [UnsignedQuantity precision]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JournalEntryItem precision account event -> Bool)
-> [JournalEntryItem precision account event]
-> [JournalEntryItem precision account event]
forall a. (a -> Bool) -> [a] -> [a]
filter (Side -> Side -> Bool
forall a. Eq a => a -> a -> Bool
(==) Side
SideCredit (Side -> Bool)
-> (JournalEntryItem precision account event -> Side)
-> JournalEntryItem precision account event
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Amount precision -> Side
forall (precision :: Nat). Amount precision -> Side
amountSide (Amount precision -> Side)
-> (JournalEntryItem precision account event -> Amount precision)
-> JournalEntryItem precision account event
-> Side
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntryItem precision account event -> Amount precision
forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Amount precision
journalEntryItemAmount)
    ([JournalEntryItem precision account event]
 -> [JournalEntryItem precision account event])
-> (JournalEntry precision account event
    -> [JournalEntryItem precision account event])
-> JournalEntry precision account event
-> [JournalEntryItem precision account event]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JournalEntry precision account event
-> [JournalEntryItem precision account event]
forall (precision :: Nat) account event.
JournalEntry precision account event
-> [JournalEntryItem precision account event]
journalEntryItems


-- | Predicate to check if a journal entry is balanced or not.
--
-- The logical check is indeed whether the total debit amount is equal to the
-- total credit amount or not.
isJournalEntryBalanced
  :: KnownNat precision
  => JournalEntry precision account event
  -> Bool
isJournalEntryBalanced :: forall (precision :: Nat) account event.
KnownNat precision =>
JournalEntry precision account event -> Bool
isJournalEntryBalanced =
  UnsignedQuantity precision -> UnsignedQuantity precision -> Bool
forall a. Eq a => a -> a -> Bool
(==)
    (UnsignedQuantity precision -> UnsignedQuantity precision -> Bool)
-> (JournalEntry precision account event
    -> UnsignedQuantity precision)
-> JournalEntry precision account event
-> UnsignedQuantity precision
-> Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JournalEntry precision account event -> UnsignedQuantity precision
forall (precision :: Nat) account event.
KnownNat precision =>
JournalEntry precision account event -> UnsignedQuantity precision
journalEntryTotalDebit
    (JournalEntry precision account event
 -> UnsignedQuantity precision -> Bool)
-> (JournalEntry precision account event
    -> UnsignedQuantity precision)
-> JournalEntry precision account event
-> Bool
forall a b.
(JournalEntry precision account event -> a -> b)
-> (JournalEntry precision account event -> a)
-> JournalEntry precision account event
-> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> JournalEntry precision account event -> UnsignedQuantity precision
forall (precision :: Nat) account event.
KnownNat precision =>
JournalEntry precision account event -> UnsignedQuantity precision
journalEntryTotalCredit


-- | Data definition for a journal entry item.
--
-- A journal entry item has a 'Side', an unsigned quantity as amount, an account
-- that it belongs to and the event the item is originating from. Journal entry
-- item definition is polymorphic over the precision of the monetary quantities,
-- the account and event objects.
data JournalEntryItem (precision :: Nat) account event = JournalEntryItem
  { forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Amount precision
journalEntryItemAmount :: !(Amount precision)
  , forall (precision :: Nat) account event.
JournalEntryItem precision account event -> Account account
journalEntryItemAccount :: !(Account account)
  , forall (precision :: Nat) account event.
JournalEntryItem precision account event -> event
journalEntryItemEvent :: !event
  , forall (precision :: Nat) account event.
JournalEntryItem precision account event
-> Maybe (JournalEntryItemInventoryEvent account event)
journalEntryItemInventoryEvent :: !(Maybe (JournalEntryItemInventoryEvent account event))
  }
  deriving (JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
(JournalEntryItem precision account event
 -> JournalEntryItem precision account event -> Bool)
-> (JournalEntryItem precision account event
    -> JournalEntryItem precision account event -> Bool)
-> Eq (JournalEntryItem precision account event)
forall (precision :: Nat) account event.
(Eq account, Eq event) =>
JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall (precision :: Nat) account event.
(Eq account, Eq event) =>
JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
== :: JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
$c/= :: forall (precision :: Nat) account event.
(Eq account, Eq event) =>
JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
/= :: JournalEntryItem precision account event
-> JournalEntryItem precision account event -> Bool
Eq, (forall x.
 JournalEntryItem precision account event
 -> Rep (JournalEntryItem precision account event) x)
-> (forall x.
    Rep (JournalEntryItem precision account event) x
    -> JournalEntryItem precision account event)
-> Generic (JournalEntryItem precision account event)
forall (precision :: Nat) account event x.
Rep (JournalEntryItem precision account event) x
-> JournalEntryItem precision account event
forall (precision :: Nat) account event x.
JournalEntryItem precision account event
-> Rep (JournalEntryItem precision account event) x
forall x.
Rep (JournalEntryItem precision account event) x
-> JournalEntryItem precision account event
forall x.
JournalEntryItem precision account event
-> Rep (JournalEntryItem precision account event) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (precision :: Nat) account event x.
JournalEntryItem precision account event
-> Rep (JournalEntryItem precision account event) x
from :: forall x.
JournalEntryItem precision account event
-> Rep (JournalEntryItem precision account event) x
$cto :: forall (precision :: Nat) account event x.
Rep (JournalEntryItem precision account event) x
-> JournalEntryItem precision account event
to :: forall x.
Rep (JournalEntryItem precision account event) x
-> JournalEntryItem precision account event
Generic, Int -> JournalEntryItem precision account event -> ShowS
[JournalEntryItem precision account event] -> ShowS
JournalEntryItem precision account event -> String
(Int -> JournalEntryItem precision account event -> ShowS)
-> (JournalEntryItem precision account event -> String)
-> ([JournalEntryItem precision account event] -> ShowS)
-> Show (JournalEntryItem precision account event)
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> JournalEntryItem precision account event -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[JournalEntryItem precision account event] -> ShowS
forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
JournalEntryItem precision account event -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
Int -> JournalEntryItem precision account event -> ShowS
showsPrec :: Int -> JournalEntryItem precision account event -> ShowS
$cshow :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
JournalEntryItem precision account event -> String
show :: JournalEntryItem precision account event -> String
$cshowList :: forall (precision :: Nat) account event.
(KnownNat precision, Show account, Show event) =>
[JournalEntryItem precision account event] -> ShowS
showList :: [JournalEntryItem precision account event] -> ShowS
Show)


instance (KnownNat precision, Aeson.FromJSON account, Aeson.FromJSON event) => Aeson.FromJSON (JournalEntryItem precision account event) where
  parseJSON :: Value -> Parser (JournalEntryItem precision account event)
parseJSON = Options
-> Value -> Parser (JournalEntryItem precision account event)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON (Options
 -> Value -> Parser (JournalEntryItem precision account event))
-> Options
-> Value
-> Parser (JournalEntryItem precision account event)
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItem"


instance (KnownNat precision, Aeson.ToJSON account, Aeson.ToJSON event) => Aeson.ToJSON (JournalEntryItem precision account event) where
  toJSON :: JournalEntryItem precision account event -> Value
toJSON = Options -> JournalEntryItem precision account event -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON (Options -> JournalEntryItem precision account event -> Value)
-> Options -> JournalEntryItem precision account event -> Value
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItem"
  toEncoding :: JournalEntryItem precision account event -> Encoding
toEncoding = Options -> JournalEntryItem precision account event -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding (Options -> JournalEntryItem precision account event -> Encoding)
-> Options -> JournalEntryItem precision account event -> Encoding
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItem"


-- | Data definition for inventory event.
data JournalEntryItemInventoryEvent account event = JournalEntryItemInventoryEvent
  { forall account event.
JournalEntryItemInventoryEvent account event -> Account account
journalEntryItemInventoryEventPnlAccount :: !(Account account)
  , forall account event.
JournalEntryItemInventoryEvent account event -> event
journalEntryItemInventoryEventEvent :: !event
  , forall account event.
JournalEntryItemInventoryEvent account event -> Quantity 12
journalEntryItemInventoryEventQuantity :: !(Quantity 12)
  }
  deriving (JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
(JournalEntryItemInventoryEvent account event
 -> JournalEntryItemInventoryEvent account event -> Bool)
-> (JournalEntryItemInventoryEvent account event
    -> JournalEntryItemInventoryEvent account event -> Bool)
-> Eq (JournalEntryItemInventoryEvent account event)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall account event.
(Eq account, Eq event) =>
JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
$c== :: forall account event.
(Eq account, Eq event) =>
JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
== :: JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
$c/= :: forall account event.
(Eq account, Eq event) =>
JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
/= :: JournalEntryItemInventoryEvent account event
-> JournalEntryItemInventoryEvent account event -> Bool
Eq, (forall x.
 JournalEntryItemInventoryEvent account event
 -> Rep (JournalEntryItemInventoryEvent account event) x)
-> (forall x.
    Rep (JournalEntryItemInventoryEvent account event) x
    -> JournalEntryItemInventoryEvent account event)
-> Generic (JournalEntryItemInventoryEvent account event)
forall x.
Rep (JournalEntryItemInventoryEvent account event) x
-> JournalEntryItemInventoryEvent account event
forall x.
JournalEntryItemInventoryEvent account event
-> Rep (JournalEntryItemInventoryEvent account event) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall account event x.
Rep (JournalEntryItemInventoryEvent account event) x
-> JournalEntryItemInventoryEvent account event
forall account event x.
JournalEntryItemInventoryEvent account event
-> Rep (JournalEntryItemInventoryEvent account event) x
$cfrom :: forall account event x.
JournalEntryItemInventoryEvent account event
-> Rep (JournalEntryItemInventoryEvent account event) x
from :: forall x.
JournalEntryItemInventoryEvent account event
-> Rep (JournalEntryItemInventoryEvent account event) x
$cto :: forall account event x.
Rep (JournalEntryItemInventoryEvent account event) x
-> JournalEntryItemInventoryEvent account event
to :: forall x.
Rep (JournalEntryItemInventoryEvent account event) x
-> JournalEntryItemInventoryEvent account event
Generic, Int -> JournalEntryItemInventoryEvent account event -> ShowS
[JournalEntryItemInventoryEvent account event] -> ShowS
JournalEntryItemInventoryEvent account event -> String
(Int -> JournalEntryItemInventoryEvent account event -> ShowS)
-> (JournalEntryItemInventoryEvent account event -> String)
-> ([JournalEntryItemInventoryEvent account event] -> ShowS)
-> Show (JournalEntryItemInventoryEvent account event)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall account event.
(Show account, Show event) =>
Int -> JournalEntryItemInventoryEvent account event -> ShowS
forall account event.
(Show account, Show event) =>
[JournalEntryItemInventoryEvent account event] -> ShowS
forall account event.
(Show account, Show event) =>
JournalEntryItemInventoryEvent account event -> String
$cshowsPrec :: forall account event.
(Show account, Show event) =>
Int -> JournalEntryItemInventoryEvent account event -> ShowS
showsPrec :: Int -> JournalEntryItemInventoryEvent account event -> ShowS
$cshow :: forall account event.
(Show account, Show event) =>
JournalEntryItemInventoryEvent account event -> String
show :: JournalEntryItemInventoryEvent account event -> String
$cshowList :: forall account event.
(Show account, Show event) =>
[JournalEntryItemInventoryEvent account event] -> ShowS
showList :: [JournalEntryItemInventoryEvent account event] -> ShowS
Show)


instance (Aeson.FromJSON account, Aeson.FromJSON event) => Aeson.FromJSON (JournalEntryItemInventoryEvent account event) where
  parseJSON :: Value -> Parser (JournalEntryItemInventoryEvent account event)
parseJSON = Options
-> Value -> Parser (JournalEntryItemInventoryEvent account event)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
Aeson.genericParseJSON (Options
 -> Value -> Parser (JournalEntryItemInventoryEvent account event))
-> Options
-> Value
-> Parser (JournalEntryItemInventoryEvent account event)
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItemInventoryEvent"


instance (Aeson.ToJSON account, Aeson.ToJSON event) => Aeson.ToJSON (JournalEntryItemInventoryEvent account event) where
  toJSON :: JournalEntryItemInventoryEvent account event -> Value
toJSON = Options -> JournalEntryItemInventoryEvent account event -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
Aeson.genericToJSON (Options -> JournalEntryItemInventoryEvent account event -> Value)
-> Options -> JournalEntryItemInventoryEvent account event -> Value
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItemInventoryEvent"
  toEncoding :: JournalEntryItemInventoryEvent account event -> Encoding
toEncoding = Options -> JournalEntryItemInventoryEvent account event -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding (Options
 -> JournalEntryItemInventoryEvent account event -> Encoding)
-> Options
-> JournalEntryItemInventoryEvent account event
-> Encoding
forall a b. (a -> b) -> a -> b
$ String -> Options
commonAesonOptions String
"journalEntryItemInventoryEvent"


-- | Creates a 'JournalEntryItem' from the given signed /value/, the account it
-- belongs to and the event it is originating from.
--
-- The /value/ is defined as in 'amountFromValue' function.
mkJournalEntryItemFromValue
  :: KnownNat precision
  => Quantity precision
  -> Account account
  -> event
  -> JournalEntryItem precision account event
mkJournalEntryItemFromValue :: forall (precision :: Nat) account event.
KnownNat precision =>
Quantity precision
-> Account account
-> event
-> JournalEntryItem precision account event
mkJournalEntryItemFromValue Quantity precision
val Account account
acc event
evt =
  JournalEntryItem
    { journalEntryItemAmount :: Amount precision
journalEntryItemAmount = AccountKind -> Quantity precision -> Amount precision
forall (precision :: Nat).
KnownNat precision =>
AccountKind -> Quantity precision -> Amount precision
amountFromValue (Account account -> AccountKind
forall o. Account o -> AccountKind
accountKind Account account
acc) Quantity precision
val
    , journalEntryItemAccount :: Account account
journalEntryItemAccount = Account account
acc
    , journalEntryItemEvent :: event
journalEntryItemEvent = event
evt
    , journalEntryItemInventoryEvent :: Maybe (JournalEntryItemInventoryEvent account event)
journalEntryItemInventoryEvent = Maybe (JournalEntryItemInventoryEvent account event)
forall a. Maybe a
Nothing
    }


-- | Creates a 'JournalEntryItem' with inventory event informationfrom the given
-- signed /value/, the account it belongs to and the event it is originating
-- from.
--
-- The /value/ is defined as in 'amountFromValue' function.
mkInventoryJournalEntryItemFromValue
  :: KnownNat precision
  => Quantity precision
  -> Account account
  -> event
  -> Account account
  -> event
  -> Quantity 12
  -> JournalEntryItem precision account event
mkInventoryJournalEntryItemFromValue :: forall (precision :: Nat) account event.
KnownNat precision =>
Quantity precision
-> Account account
-> event
-> Account account
-> event
-> Quantity 12
-> JournalEntryItem precision account event
mkInventoryJournalEntryItemFromValue Quantity precision
val Account account
acc event
evt Account account
pnlacc event
pnlevt Quantity 12
evtqty =
  JournalEntryItem
    { journalEntryItemAmount :: Amount precision
journalEntryItemAmount = AccountKind -> Quantity precision -> Amount precision
forall (precision :: Nat).
KnownNat precision =>
AccountKind -> Quantity precision -> Amount precision
amountFromValue (Account account -> AccountKind
forall o. Account o -> AccountKind
accountKind Account account
acc) Quantity precision
val
    , journalEntryItemAccount :: Account account
journalEntryItemAccount = Account account
acc
    , journalEntryItemEvent :: event
journalEntryItemEvent = event
evt
    , journalEntryItemInventoryEvent :: Maybe (JournalEntryItemInventoryEvent account event)
journalEntryItemInventoryEvent =
        JournalEntryItemInventoryEvent account event
-> Maybe (JournalEntryItemInventoryEvent account event)
forall a. a -> Maybe a
Just (JournalEntryItemInventoryEvent account event
 -> Maybe (JournalEntryItemInventoryEvent account event))
-> JournalEntryItemInventoryEvent account event
-> Maybe (JournalEntryItemInventoryEvent account event)
forall a b. (a -> b) -> a -> b
$
          JournalEntryItemInventoryEvent
            { journalEntryItemInventoryEventPnlAccount :: Account account
journalEntryItemInventoryEventPnlAccount = Account account
pnlacc
            , journalEntryItemInventoryEventQuantity :: Quantity 12
journalEntryItemInventoryEventQuantity = Quantity 12
evtqty
            , journalEntryItemInventoryEventEvent :: event
journalEntryItemInventoryEventEvent = event
pnlevt
            }
    }