-- | Examining a Posting for a particular component of the main -- posting (as opposed to the sibling postings) in the Posting. For -- some components, such as the payee, the posting might have one -- piece of data while the TopLine has something else. These functions -- will examine the Posting first and, if it has no information, use -- the data from the TopLine if it is there. module Penny.Lincoln.Queries where import qualified Penny.Lincoln.Bits as B import qualified Penny.Lincoln.Ents as E import Penny.Lincoln.Balance (Balance, entryToBalance) import qualified Data.Time as Time -- | Uses the data from the Posting if it is set; otherwise, use the -- data from the TopLine. best :: (B.TopLineData -> Maybe a) -> (E.Ents B.PostingData -> Maybe a) -> E.Posting -> Maybe a best fp ft vp = case fp . fst . E.unPosting $ vp of Nothing -> ft . snd . E.unPosting $ vp Just r -> Just r payee :: E.Posting -> Maybe B.Payee payee = best (B.tPayee . B.tlCore) (B.pPayee . B.pdCore . E.meta . E.headEnt) number :: E.Posting -> Maybe B.Number number = best (B.tNumber . B.tlCore) (B.pNumber . B.pdCore . E.meta . E.headEnt) flag :: E.Posting -> Maybe B.Flag flag = best (B.tFlag . B.tlCore) (B.pFlag . B.pdCore . E.meta . E.headEnt) postingMemo :: E.Posting -> Maybe B.Memo postingMemo = B.pMemo . B.pdCore . E.meta . E.headEnt . snd . E.unPosting transactionMemo :: E.Posting -> Maybe B.Memo transactionMemo = B.tMemo . B.tlCore . fst . E.unPosting dateTime :: E.Posting -> B.DateTime dateTime = B.tDateTime . B.tlCore . fst . E.unPosting localDay :: E.Posting -> Time.Day localDay = B.day . dateTime account :: E.Posting -> B.Account account = B.pAccount . B.pdCore . E.meta . E.headEnt . snd . E.unPosting tags :: E.Posting -> B.Tags tags = B.pTags . B.pdCore . E.meta . E.headEnt . snd . E.unPosting entry :: E.Posting -> Either (B.Entry B.QtyRep) (B.Entry B.Qty) entry = E.entry . E.headEnt . snd . E.unPosting balance :: E.Posting -> Balance balance = either entryToBalance entryToBalance . entry drCr :: E.Posting -> B.DrCr drCr = either B.drCr B.drCr . entry amount :: E.Posting -> Either (B.Amount B.QtyRep) (B.Amount B.Qty) amount = either (Left . B.amount) (Right . B.amount) . entry eiQty :: E.Posting -> Either B.QtyRep B.Qty eiQty = either (Left . B.qty) (Right . B.qty) . amount -- | Every Posting either has a Qty or it can be computed from its QtyRep. qty :: E.Posting -> B.Qty qty = either B.toQty B.toQty . eiQty commodity :: E.Posting -> B.Commodity commodity = either B.commodity B.commodity . amount topMemoLine :: E.Posting -> Maybe B.TopMemoLine topMemoLine p = (B.tlFileMeta . fst . E.unPosting $ p) >>= B.tTopMemoLine topLineLine :: E.Posting -> Maybe B.TopLineLine topLineLine = fmap B.tTopLineLine . B.tlFileMeta . fst . E.unPosting globalTransaction :: E.Posting -> Maybe B.GlobalTransaction globalTransaction = B.tlGlobal . fst . E.unPosting fileTransaction :: E.Posting -> Maybe B.FileTransaction fileTransaction = fmap B.tFileTransaction . B.tlFileMeta . fst . E.unPosting globalPosting :: E.Posting -> Maybe B.GlobalPosting globalPosting = B.pdGlobal . E.meta . E.headEnt . snd . E.unPosting filePosting :: E.Posting -> Maybe B.FilePosting filePosting = fmap B.pFilePosting . B.pdFileMeta . E.meta . E.headEnt . snd . E.unPosting postingLine :: E.Posting -> Maybe B.PostingLine postingLine = fmap B.pPostingLine . B.pdFileMeta . E.meta . E.headEnt . snd . E.unPosting side :: E.Posting -> Maybe B.Side side = B.pSide . B.pdCore . E.meta . E.headEnt . snd . E.unPosting spaceBetween :: E.Posting -> Maybe B.SpaceBetween spaceBetween = B.pSpaceBetween . B.pdCore . E.meta . E.headEnt . snd . E.unPosting filename :: E.Posting -> Maybe B.Filename filename = fmap B.tFilename . B.tlFileMeta . fst . E.unPosting