{-# LANGUAGE DeriveDataTypeable #-}{-|
Most data types are defined here to avoid import cycles.
Here is an overview of the hledger data model:
> Journal -- a journal is derived from one or more data files. It contains..
> [Transaction] -- journal transactions, which have date, status, code, description and..
> [Posting] -- multiple account postings (entries), which have account name and amount.
> [HistoricalPrice] -- historical commodity prices
>
> Ledger -- a ledger is derived from a journal, by applying a filter specification. It contains..
> Journal -- the filtered journal, containing only the transactions and postings we are interested in
> Tree AccountName -- account names referenced in the journal's transactions, as a tree
> Map AccountName Account -- per-account postings and balances from the journal's transactions, as a map from account name to account info
For more detailed documentation on each type, see the corresponding modules.
Evolution of transaction\/entry\/posting terminology:
- ledger 2: entries contain transactions
- hledger 0.4: Entrys contain RawTransactions (which are flattened to Transactions)
- ledger 3: transactions contain postings
- hledger 0.5: LedgerTransactions contain Postings (which are flattened to Transactions)
- hledger 0.8: Transactions contain Postings (referencing Transactions, corecursively)
- hledger 0.10: Postings should be called Entrys, but are left as-is for now
-}moduleHledger.Data.TypeswhereimportHledger.Data.UtilsimportqualifiedData.MapasMapimportSystem.Time(ClockTime)importData.Typeable(Typeable)typeSmartDate=(String,String,String)dataWhichDate=ActualDate|EffectiveDatederiving(Eq,Show)dataDateSpan=DateSpan(MaybeDay)(MaybeDay)deriving(Eq,Show,Ord)dataInterval=NoInterval|Daily|Weekly|Monthly|Quarterly|Yearlyderiving(Eq,Show,Ord)typeAccountName=StringdataSide=L|Rderiving(Eq,Show,Ord)dataCommodity=Commodity{symbol::String,-- ^ the commodity's symbol-- display preferences for amounts of this commodityside::Side,-- ^ should the symbol appear on the left or the rightspaced::Bool,-- ^ should there be a space between symbol and quantitycomma::Bool,-- ^ should thousands be comma-separatedprecision::Int-- ^ number of decimal places to display}deriving(Eq,Show,Ord)dataAmount=Amount{commodity::Commodity,quantity::Double,price::MaybeMixedAmount-- ^ unit price/conversion rate for this amount at posting time}deriving(Eq)newtypeMixedAmount=Mixed[Amount]deriving(Eq)dataPostingType=RegularPosting|VirtualPosting|BalancedVirtualPostingderiving(Eq,Show)dataPosting=Posting{pstatus::Bool,paccount::AccountName,pamount::MixedAmount,pcomment::String,ptype::PostingType,ptransaction::MaybeTransaction-- ^ this posting's parent transaction (co-recursive types).-- Tying this knot gets tedious, Maybe makes it easier/optional.}-- The equality test for postings ignores the parent transaction's-- identity, to avoid infinite loops.instanceEqPostingwhere(==)(Postinga1b1c1d1e1_)(Postinga2b2c2d2e2_)=a1==a2&&b1==b2&&c1==c2&&d1==d2&&e1==e2dataTransaction=Transaction{tdate::Day,teffectivedate::MaybeDay,tstatus::Bool,-- XXX tcleared ?tcode::String,tdescription::String,tcomment::String,tpostings::[Posting],-- ^ this transaction's postings (co-recursive types).tpreceding_comment_lines::String}deriving(Eq)dataModifierTransaction=ModifierTransaction{mtvalueexpr::String,mtpostings::[Posting]}deriving(Eq)dataPeriodicTransaction=PeriodicTransaction{ptperiodicexpr::String,ptpostings::[Posting]}deriving(Eq)dataTimeLogCode=SetBalance|SetRequiredHours|In|Out|FinalOutderiving(Eq,Ord)dataTimeLogEntry=TimeLogEntry{tlcode::TimeLogCode,tldatetime::LocalTime,tlcomment::String}deriving(Eq,Ord)dataHistoricalPrice=HistoricalPrice{hdate::Day,hsymbol::String,hamount::MixedAmount}deriving(Eq)-- & Show (in Amount.hs)dataJournal=Journal{jmodifiertxns::[ModifierTransaction],jperiodictxns::[PeriodicTransaction],jtxns::[Transaction],open_timelog_entries::[TimeLogEntry],historical_prices::[HistoricalPrice],final_comment_lines::String,filepath::FilePath,filereadtime::ClockTime,jtext::String}deriving(Eq,Typeable)dataLedger=Ledger{journal::Journal,accountnametree::TreeAccountName,accountmap::Map.MapAccountNameAccount}dataAccount=Account{aname::AccountName,apostings::[Posting],-- ^ postings in this accountabalance::MixedAmount-- ^ sum of postings in this account and subaccounts}-- | A generic, pure specification of how to filter transactions and postings.dataFilterSpec=FilterSpec{datespan::DateSpan-- ^ only include if in this date span,cleared::MaybeBool-- ^ only include if cleared\/uncleared\/don't care,real::Bool-- ^ only include if real\/don't care,empty::Bool-- ^ include if empty (ie amount is zero),costbasis::Bool-- ^ convert all amounts to cost basis,acctpats::[String]-- ^ only include if matching these account patterns,descpats::[String]-- ^ only include if matching these description patterns,whichdate::WhichDate-- ^ which dates to use (actual or effective),depth::MaybeInt}deriving(Show)