add: suggest only one commodity at a time as default amount #383

Since we currently can't accept more than one commodity as input.
This commit is contained in:
Simon Michael 2016-08-04 11:55:21 -07:00
parent 2276b1c2d1
commit 92b97e7bd3
6 changed files with 76 additions and 19 deletions

View File

@ -48,13 +48,20 @@ nullacct = Account
, asubs = [] , asubs = []
, anumpostings = 0 , anumpostings = 0
, aebalance = nullmixedamt , aebalance = nullmixedamt
, aestartbalance = nullmixedamt
, aeperiodchange = nullmixedamt
, aeendbalance = nullmixedamt
, aibalance = nullmixedamt , aibalance = nullmixedamt
, aistartbalance = nullmixedamt
, aiperiodchange = nullmixedamt
, aiendbalance = nullmixedamt
, aboring = False , aboring = False
} }
-- | Derive 1. an account tree and 2. their balances from a list of postings. -- | Derive 1. an account tree and 2. their total changes from a list of postings.
-- (ledger's core feature). The accounts are returned in a list, but -- (ledger's core feature). The accounts are returned in a list, but
-- retain their tree structure; the first one is the root of the tree. -- also reference each other as a tree structure; the first account is
-- the root of the tree.
accountsFromPostings :: [Posting] -> [Account] accountsFromPostings :: [Posting] -> [Account]
accountsFromPostings ps = accountsFromPostings ps =
let let

View File

@ -18,9 +18,11 @@ import Text.Printf
import Hledger.Data.Types import Hledger.Data.Types
import Hledger.Data.Account import Hledger.Data.Account
import Hledger.Data.Dates
import Hledger.Data.Journal import Hledger.Data.Journal
import Hledger.Data.Posting import Hledger.Data.Posting
import Hledger.Query import Hledger.Query
import Hledger.Utils.Debug
instance Show Ledger where instance Show Ledger where
@ -39,16 +41,33 @@ nullledger = Ledger {
-- | Filter a journal's transactions with the given query, then derive -- | Filter a journal's transactions with the given query, then derive
-- a ledger containing the chart of accounts and balances. If the -- a ledger containing the chart of accounts and balances. If the
-- query includes a depth limit, that will affect the this ledger's -- query includes a depth limit, that will affect the ledger's
-- journal but not the ledger's account tree. -- journal but not the ledger's account tree.
ledgerFromJournal :: Query -> Journal -> Ledger ledgerFromJournal :: Query -> Journal -> Ledger
ledgerFromJournal q j = nullledger{ljournal=j'', laccounts=as} ledgerFromJournal q j = nullledger{ljournal=depthclippedperiodj, laccounts=as}
where where
(q',depthq) = (filterQuery (not . queryIsDepth) q, filterQuery queryIsDepth q) symq = filterQuery queryIsSym q
j' = filterJournalAmounts (filterQuery queryIsSym q) $ -- remove amount parts which the query's sym: terms would exclude depthq = filterQuery queryIsDepth q
filterJournalPostings q' j periodq = filterQuery (not . queryIsDepth) q
as = accountsFromPostings $ journalPostings j' -- get account totals before and during report period
j'' = filterJournalPostings depthq j' datelessq = filterQuery (not . queryIsDateOrDate2) periodq
dateqcons = Date -- if date2_ opts then Date2 else Date -- import cycle, don't bother supporting date2
reportspan = queryDateSpan False {-(date2_ opts)-} q -- date span specified by -b/-e/-p options and query args
mstartdate = dbg1 "mstartdate" $ spanStart reportspan
menddate = dbg1 "menddate" $ spanEnd reportspan
precedingq = dbg1 "precedingq" $
case mstartdate of
Just _ -> And [datelessq, dateqcons $ DateSpan Nothing mstartdate]
Nothing -> None
-- remove amount parts which the query's sym: terms would exclude
precedingj = filterJournalAmounts symq $ filterJournalPostings precedingq j
periodj = filterJournalAmounts symq $ filterJournalPostings periodq j
precedingas = accountsFromPostings $ journalPostings precedingj
as = accountsFromPostings $ journalPostings periodj
depthclippedperiodj = filterJournalPostings depthq periodj
-- j' = journalSelectingAmountFromOpts opts j
-- | List a ledger's account names. -- | List a ledger's account names.
ledgerAccountNames :: Ledger -> [AccountName] ledgerAccountNames :: Ledger -> [AccountName]

View File

@ -281,8 +281,8 @@ instance NFData MarketPrice
-- --
data Journal = Journal { data Journal = Journal {
-- parsing-related data -- parsing-related data
jparsedefaultyear :: (Maybe Year) -- ^ the current default year, specified by the most recent Y directive (or current date) jparsedefaultyear :: Maybe Year -- ^ the current default year, specified by the most recent Y directive (or current date)
,jparsedefaultcommodity :: (Maybe (CommoditySymbol,AmountStyle)) -- ^ the current default commodity and its format, specified by the most recent D directive ,jparsedefaultcommodity :: Maybe (CommoditySymbol,AmountStyle) -- ^ the current default commodity and its format, specified by the most recent D directive
,jparseparentaccounts :: [AccountName] -- ^ the current stack of parent account names, specified by apply account directives ,jparseparentaccounts :: [AccountName] -- ^ the current stack of parent account names, specified by apply account directives
,jparsealiases :: [AccountAlias] -- ^ the current account name aliases in effect, specified by alias directives (& options ?) ,jparsealiases :: [AccountAlias] -- ^ the current account name aliases in effect, specified by alias directives (& options ?)
,jparsetransactioncount :: Integer -- ^ the current count of transactions parsed so far (only journal format txns, currently) ,jparsetransactioncount :: Integer -- ^ the current count of transactions parsed so far (only journal format txns, currently)
@ -329,15 +329,23 @@ data Reader = Reader {
instance Show Reader where show r = rFormat r ++ " reader" instance Show Reader where show r = rFormat r ++ " reader"
-- | An account, with name, balances and links to parent/subaccounts -- | An account, with name, links to parent/subaccounts
-- which let you walk up or down the account tree. -- which let you walk up or down the account tree, and
-- and start/end balances and balance change amount relative to
-- some report period.
data Account = Account { data Account = Account {
aname :: AccountName, -- ^ this account's full name aname :: AccountName, -- ^ this account's full name
aebalance :: MixedAmount, -- ^ this account's balance, excluding subaccounts aebalance :: MixedAmount, -- ^ this account's balance, excluding subaccounts
aestartbalance :: MixedAmount, -- ^ this account's balance at start of report period, excluding subaccounts
aeperiodchange :: MixedAmount, -- ^ the change in this account's balance during the report period, excluding subaccounts
aeendbalance :: MixedAmount, -- ^ this account's balance at end of report period, excluding subaccounts
asubs :: [Account], -- ^ sub-accounts asubs :: [Account], -- ^ sub-accounts
anumpostings :: Int, -- ^ number of postings to this account anumpostings :: Int, -- ^ number of postings to this account
-- derived from the above : -- derived from the above :
aibalance :: MixedAmount, -- ^ this account's balance, including subaccounts aibalance :: MixedAmount, -- ^ this account's balance, including subaccounts
aistartbalance :: MixedAmount, -- ^ this account's balance at start of report period, excluding subaccounts
aiperiodchange :: MixedAmount, -- ^ the change in this account's balance during the report period, excluding subaccounts
aiendbalance :: MixedAmount, -- ^ this account's balance at end of report period, excluding subaccounts
aparent :: Maybe Account, -- ^ parent account aparent :: Maybe Account, -- ^ parent account
aboring :: Bool -- ^ used in the accounts report to label elidable parents aboring :: Bool -- ^ used in the accounts report to label elidable parents
} deriving (Typeable, Data, Generic) } deriving (Typeable, Data, Generic)

View File

@ -22,7 +22,7 @@ import Hledger.Reports.ReportOptions
import Hledger.Reports.TransactionsReports import Hledger.Reports.TransactionsReports
-- | Get the historical running inclusive balance of a particular account, -- | Get the historical inclusive balance of a particular account over time,
-- from earliest to latest posting date. -- from earliest to latest posting date.
accountBalanceHistory :: ReportOpts -> Journal -> Account -> [(Day, MixedAmount)] accountBalanceHistory :: ReportOpts -> Journal -> Account -> [(Day, MixedAmount)]
accountBalanceHistory ropts j a = [(getdate t, bal) | (t,_,_,_,_,bal) <- items] accountBalanceHistory ropts j a = [(getdate t, bal) | (t,_,_,_,_,bal) <- items]

View File

@ -5,6 +5,13 @@ Balance report, used by the balance command.
-} -}
module Hledger.Reports.BalanceReport ( module Hledger.Reports.BalanceReport (
BalanceReport, BalanceReport,
BalanceReportItem, BalanceReportItem,
@ -31,6 +38,12 @@ import Hledger.Utils
import Hledger.Reports.ReportOptions import Hledger.Reports.ReportOptions
-- | A simple single-column balance report. It has: -- | A simple single-column balance report. It has:
-- --
-- 1. a list of rows, each containing a renderable account name and a corresponding amount -- 1. a list of rows, each containing a renderable account name and a corresponding amount
@ -141,8 +154,8 @@ mixedAmountValue :: Journal -> Day -> MixedAmount -> MixedAmount
mixedAmountValue j d (Mixed as) = Mixed $ map (amountValue j d) as mixedAmountValue j d (Mixed as) = Mixed $ map (amountValue j d) as
-- | Find the market value of this amount on the given date, in it's -- | Find the market value of this amount on the given date, in it's
-- default valuation commodity, based on historical prices. If no -- default valuation commodity, based on recorded market prices.
-- default valuation commodity can be found, the amount is left -- If no default valuation commodity can be found, the amount is left
-- unchanged. -- unchanged.
amountValue :: Journal -> Day -> Amount -> Amount amountValue :: Journal -> Day -> Amount -> Amount
amountValue j d a = amountValue j d a =
@ -155,7 +168,7 @@ amountValue j d a =
-- | Find the market value, if known, of one unit of this commodity on -- | Find the market value, if known, of one unit of this commodity on
-- the given date, in the commodity in which it has most recently been -- the given date, in the commodity in which it has most recently been
-- market-priced (ie the commodity mentioned in the most recent -- market-priced (ie the commodity mentioned in the most recent
-- applicable historical price directive before this date). -- applicable market price directive before this date).
commodityValue :: Journal -> Day -> CommoditySymbol -> Maybe Amount commodityValue :: Journal -> Day -> CommoditySymbol -> Maybe Amount
commodityValue j d c commodityValue j d c
| null applicableprices = Nothing | null applicableprices = Nothing
@ -163,6 +176,13 @@ commodityValue j d c
where where
applicableprices = [p | p <- sort $ jmarketprices j, mpcommodity p == c, mpdate p <= d] applicableprices = [p | p <- sort $ jmarketprices j, mpcommodity p == c, mpdate p <= d]
tests_balanceReport = tests_balanceReport =
let let
(opts,journal) `gives` r = do (opts,journal) `gives` r = do

View File

@ -260,6 +260,7 @@ accountWizard EntryState{..} = do
| otherwise = Just t | otherwise = Just t
dbg1 = id -- strace dbg1 = id -- strace
amountAndCommentWizard :: EntryState -> Wizard Haskeline (Amount, Text)
amountAndCommentWizard EntryState{..} = do amountAndCommentWizard EntryState{..} = do
let pnum = length esPostings + 1 let pnum = length esPostings + 1
(mhistoricalp,followedhistoricalsofar) = (mhistoricalp,followedhistoricalsofar) =
@ -270,7 +271,7 @@ amountAndCommentWizard EntryState{..} = do
def = case (esArgs, mhistoricalp, followedhistoricalsofar) of def = case (esArgs, mhistoricalp, followedhistoricalsofar) of
(d:_,_,_) -> d (d:_,_,_) -> d
(_,Just hp,True) -> showamt $ pamount hp (_,Just hp,True) -> showamt $ pamount hp
_ | pnum > 1 && not (isZeroMixedAmount balancingamt) -> showamt balancingamt _ | pnum > 1 && not (isZeroMixedAmount balancingamt) -> showamt balancingamtfirstcommodity
_ -> "" _ -> ""
retryMsg "A valid hledger amount is required. Eg: 1, $2, 3 EUR, \"4 red apples\"." $ retryMsg "A valid hledger amount is required. Eg: 1, $2, 3 EUR, \"4 red apples\"." $
parser parseAmountAndComment $ parser parseAmountAndComment $
@ -293,7 +294,9 @@ amountAndCommentWizard EntryState{..} = do
-- eof -- eof
return (a,c) return (a,c)
balancingamt = negate $ sum $ map pamount realps where realps = filter isReal esPostings balancingamt = negate $ sum $ map pamount realps where realps = filter isReal esPostings
showamt = showMixedAmountWithPrecision balancingamtfirstcommodity = Mixed $ take 1 $ amounts balancingamt
showamt =
showMixedAmountWithPrecision
-- what should this be ? -- what should this be ?
-- 1 maxprecision (show all decimal places or none) ? -- 1 maxprecision (show all decimal places or none) ?
-- 2 maxprecisionwithpoint (show all decimal places or .0 - avoids some but not all confusion with thousands separators) ? -- 2 maxprecisionwithpoint (show all decimal places or .0 - avoids some but not all confusion with thousands separators) ?