module Penny.Lincoln.Bits.Open where
import Data.List (sort)
import Data.Monoid ((<>))
import Data.Text (Text)
import qualified Data.Text as X
import qualified Data.Text.Encoding as XE
import GHC.Generics (Generic)
import qualified Penny.Lincoln.Equivalent as Ev
import Penny.Lincoln.Equivalent ((==~))
import qualified Penny.Lincoln.Serial as S
import qualified Penny.Lincoln.Bits.Qty as Q
import qualified Data.Binary as B
newtype SubAccount =
SubAccount { unSubAccount :: Text }
deriving (Eq, Ord, Show)
instance B.Binary SubAccount where
put = B.put . XE.encodeUtf8 . unSubAccount
get = fmap (SubAccount . XE.decodeUtf8) B.get
newtype Account = Account { unAccount :: [SubAccount] }
deriving (Eq, Show, Ord, Generic)
instance B.Binary Account
data Amount = Amount { qty :: Q.Qty
, commodity :: Commodity }
deriving (Eq, Show, Ord, Generic)
instance B.Binary Amount
instance Ev.Equivalent Amount where
equivalent (Amount q1 c1) (Amount q2 c2) =
q1 ==~ q2 && c1 == c2
compareEv (Amount q1 c1) (Amount q2 c2) =
Ev.compareEv q1 q2 <> c1 `compare` c2
newtype Commodity =
Commodity { unCommodity :: Text }
deriving (Eq, Ord, Show)
instance B.Binary Commodity where
get = fmap (Commodity . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unCommodity
data DrCr = Debit | Credit deriving (Eq, Show, Ord, Generic)
instance B.Binary DrCr
opposite :: DrCr -> DrCr
opposite d = case d of
Debit -> Credit
Credit -> Debit
data Entry = Entry { drCr :: DrCr
, amount :: Amount }
deriving (Eq, Show, Ord, Generic)
instance B.Binary Entry
instance Ev.Equivalent Entry where
equivalent (Entry d1 a1) (Entry d2 a2) =
d1 == d2 && a1 ==~ a2
compareEv (Entry d1 a1) (Entry d2 a2) =
d1 `compare` d2 <> Ev.compareEv a1 a2
newtype Flag = Flag { unFlag :: Text }
deriving (Eq, Show, Ord)
instance B.Binary Flag where
get = fmap (Flag . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unFlag
newtype Memo = Memo { unMemo :: [Text] }
deriving (Eq, Show, Ord)
instance B.Binary Memo where
get = fmap (Memo . map XE.decodeUtf8) B.get
put = B.put . map XE.encodeUtf8 . unMemo
newtype Number = Number { unNumber :: Text }
deriving (Eq, Show, Ord)
instance B.Binary Number where
get = fmap (Number . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unNumber
newtype Payee = Payee { unPayee :: Text }
deriving (Eq, Show, Ord)
instance B.Binary Payee where
get = fmap (Payee . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unPayee
newtype Tag = Tag { unTag :: Text }
deriving (Eq, Show, Ord)
instance B.Binary Tag where
get = fmap (Tag . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unTag
newtype Tags = Tags { unTags :: [Tag] }
deriving (Eq, Show, Ord, Generic)
instance Ev.Equivalent Tags where
equivalent (Tags t1) (Tags t2) = sort t1 == sort t2
compareEv (Tags t1) (Tags t2) =
compare (sort t1) (sort t2)
instance B.Binary Tags
newtype TopLineLine = TopLineLine { unTopLineLine :: Int }
deriving (Eq, Show, Generic)
instance B.Binary TopLineLine
newtype TopMemoLine = TopMemoLine { unTopMemoLine :: Int }
deriving (Eq, Show, Generic)
instance B.Binary TopMemoLine
data Side
= CommodityOnLeft
| CommodityOnRight
deriving (Eq, Show, Ord, Generic)
instance B.Binary Side
data SpaceBetween
= SpaceBetween
| NoSpaceBetween
deriving (Eq, Show, Ord, Generic)
instance B.Binary SpaceBetween
newtype Filename = Filename { unFilename :: X.Text }
deriving (Eq, Show)
instance B.Binary Filename where
get = fmap (Filename . XE.decodeUtf8) B.get
put = B.put . XE.encodeUtf8 . unFilename
newtype PriceLine = PriceLine { unPriceLine :: Int }
deriving (Eq, Show, Generic)
instance B.Binary PriceLine
newtype PostingLine = PostingLine { unPostingLine :: Int }
deriving (Eq, Show, Generic)
instance B.Binary PostingLine
newtype GlobalPosting =
GlobalPosting { unGlobalPosting :: S.Serial }
deriving (Eq, Show, Generic)
instance B.Binary GlobalPosting
newtype FilePosting =
FilePosting { unFilePosting :: S.Serial }
deriving (Eq, Show, Generic)
instance B.Binary FilePosting
newtype GlobalTransaction =
GlobalTransaction { unGlobalTransaction :: S.Serial }
deriving (Eq, Show, Generic)
instance B.Binary GlobalTransaction
newtype FileTransaction =
FileTransaction { unFileTransaction :: S.Serial }
deriving (Eq, Show, Generic)
instance B.Binary FileTransaction