hledger-lib 0.16.1 → 0.17
raw patch · 4 files changed
+52/−45 lines, 4 filesdep ~cmdargsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: cmdargs
API changes (from Hackage documentation)
- Hledger.Data.Amount: normaliseMixedAmount :: MixedAmount -> MixedAmount
+ Hledger.Data.Amount: normaliseMixedAmountPreservingFirstPrice :: MixedAmount -> MixedAmount
Files
- Hledger/Data/Amount.hs +32/−26
- Hledger/Data/Journal.hs +4/−6
- Hledger/Data/Transaction.hs +13/−10
- hledger-lib.cabal +3/−3
Hledger/Data/Amount.hs view
@@ -60,7 +60,7 @@ nullmixedamt, missingamt, amounts,- normaliseMixedAmount,+ normaliseMixedAmountPreservingFirstPrice, canonicaliseMixedAmountCommodity, mixedAmountWithCommodity, setMixedAmountPrecision,@@ -262,7 +262,7 @@ instance Num MixedAmount where fromInteger i = Mixed [Amount (comm "") (fromInteger i) Nothing] negate (Mixed as) = Mixed $ map negate as- (+) (Mixed as) (Mixed bs) = normaliseMixedAmountPreservingPrice $ Mixed $ as ++ bs+ (+) (Mixed as) (Mixed bs) = normaliseMixedAmountPreservingPrices $ Mixed $ as ++ bs (*) = error' "programming error, mixed amounts do not support multiplication" abs = error' "programming error, mixed amounts do not support abs" signum = error' "programming error, mixed amounts do not support signum"@@ -275,11 +275,11 @@ missingamt :: MixedAmount missingamt = Mixed [Amount unknown{symbol="AUTO"} 0 Nothing] --- | Simplify a mixed amount's component amounts: combine amounts with the--- same commodity and price, remove any zero amounts, and replace an empty--- amount list with a single zero amount.-normaliseMixedAmountPreservingPrice :: MixedAmount -> MixedAmount-normaliseMixedAmountPreservingPrice (Mixed as) = Mixed as''+-- | Simplify a mixed amount's component amounts: combine amounts with+-- the same commodity and price. Also remove any zero amounts and+-- replace an empty amount list with a single zero amount.+normaliseMixedAmountPreservingPrices :: MixedAmount -> MixedAmount+normaliseMixedAmountPreservingPrices (Mixed as) = Mixed as'' where as'' = if null nonzeros then [nullamt] else nonzeros (_,nonzeros) = partition (\a -> isReallyZeroAmount a && Mixed [a] /= missingamt) as'@@ -288,13 +288,13 @@ group = groupBy (\a1 a2 -> sym a1 == sym a2 && price a1 == price a2) sym = symbol . commodity --- | Simplify a mixed amount's component amounts: combine amounts with the--- same commodity, remove any zero amounts, and replace an empty amount--- list with a single zero amount. Unlike normaliseMixedAmountPreservingPrice,--- this one discards all but the first price encountered in each commodity.--- (This is used more for display than arithmetic, but seems a bit odd. XXX)-normaliseMixedAmount :: MixedAmount -> MixedAmount-normaliseMixedAmount (Mixed as) = Mixed as''+-- | Simplify a mixed amount's component amounts: combine amounts with+-- the same commodity, using the first amount's price for subsequent+-- amounts in each commodity (ie, this function alters the amount and+-- is best used as a rendering helper.). Also remove any zero amounts+-- and replace an empty amount list with a single zero amount.+normaliseMixedAmountPreservingFirstPrice :: MixedAmount -> MixedAmount+normaliseMixedAmountPreservingFirstPrice (Mixed as) = Mixed as'' where as'' = if null nonzeros then [nullamt] else nonzeros (_,nonzeros) = partition (\a -> isReallyZeroAmount a && Mixed [a] /= missingamt) as'@@ -303,6 +303,12 @@ group = groupBy (\a1 a2 -> sym a1 == sym a2) sym = symbol . commodity +-- discardPrice :: Amount -> Amount+-- discardPrice a = a{price=Nothing}++-- discardPrices :: MixedAmount -> MixedAmount+-- discardPrices (Mixed as) = Mixed $ map discardPrice as+ sumAmountsUsingFirstPrice [] = nullamt sumAmountsUsingFirstPrice as = (sum as){price=price $ head as} @@ -323,15 +329,15 @@ isNegativeMixedAmount :: MixedAmount -> Maybe Bool isNegativeMixedAmount m = case as of [a] -> Just $ isNegativeAmount a _ -> Nothing- where as = amounts $ normaliseMixedAmount m+ where as = amounts $ normaliseMixedAmountPreservingFirstPrice m -- | Does this mixed amount appear to be zero when displayed with its given precision ? isZeroMixedAmount :: MixedAmount -> Bool-isZeroMixedAmount = all isZeroAmount . amounts . normaliseMixedAmount+isZeroMixedAmount = all isZeroAmount . amounts . normaliseMixedAmountPreservingFirstPrice -- | Is this mixed amount "really" zero ? See isReallyZeroAmount. isReallyZeroMixedAmount :: MixedAmount -> Bool-isReallyZeroMixedAmount = all isReallyZeroAmount . amounts . normaliseMixedAmount+isReallyZeroMixedAmount = all isReallyZeroAmount . amounts . normaliseMixedAmountPreservingFirstPrice -- | Is this mixed amount "really" zero, after converting to cost -- commodities where possible ?@@ -349,14 +355,14 @@ -- -- For now, use this when cross-commodity zero equality is important. -- mixedAmountEquals :: MixedAmount -> MixedAmount -> Bool -- mixedAmountEquals a b = amounts a' == amounts b' || (isZeroMixedAmount a' && isZeroMixedAmount b')--- where a' = normaliseMixedAmount a--- b' = normaliseMixedAmount b+-- where a' = normaliseMixedAmountPreservingFirstPrice a+-- b' = normaliseMixedAmountPreservingFirstPrice b -- | Get the string representation of a mixed amount, showing each of -- its component amounts. NB a mixed amount can have an empty amounts -- list in which case it shows as \"\". showMixedAmount :: MixedAmount -> String-showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmount m+showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmountPreservingFirstPrice m -- | Set the display precision in the amount's commodities. setMixedAmountPrecision :: Int -> MixedAmount -> MixedAmount@@ -367,19 +373,19 @@ -- commoditys' display precision settings. showMixedAmountWithPrecision :: Int -> MixedAmount -> String showMixedAmountWithPrecision p m =- vConcatRightAligned $ map (showAmountWithPrecision p) $ amounts $ normaliseMixedAmount m+ vConcatRightAligned $ map (showAmountWithPrecision p) $ amounts $ normaliseMixedAmountPreservingFirstPrice m -- | Get an unambiguous string representation of a mixed amount for debugging. showMixedAmountDebug :: MixedAmount -> String showMixedAmountDebug m = printf "Mixed [%s]" as- where as = intercalate "\n " $ map showAmountDebug $ amounts $ normaliseMixedAmount m+ where as = intercalate "\n " $ map showAmountDebug $ amounts $ normaliseMixedAmountPreservingFirstPrice m -- | Get the string representation of a mixed amount, but without -- any \@ prices. showMixedAmountWithoutPrice :: MixedAmount -> String showMixedAmountWithoutPrice m = concat $ intersperse "\n" $ map showfixedwidth as where- (Mixed as) = normaliseMixedAmount $ stripPrices m+ (Mixed as) = normaliseMixedAmountPreservingFirstPrice $ stripPrices m stripPrices (Mixed as) = Mixed $ map stripprice as where stripprice a = a{price=Nothing} width = maximum $ map (length . show) as showfixedwidth = printf (printf "%%%ds" width) . showAmountWithoutPrice@@ -434,9 +440,9 @@ -- MixedAmount - ,"normaliseMixedAmount" ~: do- normaliseMixedAmount (Mixed []) `is` Mixed [nullamt]- assertBool "" $ isZeroMixedAmount $ normaliseMixedAmount (Mixed [Amount {commodity=dollar, quantity=10, price=Nothing}+ ,"normaliseMixedAmountPreservingFirstPrice" ~: do+ normaliseMixedAmountPreservingFirstPrice (Mixed []) `is` Mixed [nullamt]+ assertBool "" $ isZeroMixedAmount $ normaliseMixedAmountPreservingFirstPrice (Mixed [Amount {commodity=dollar, quantity=10, price=Nothing} ,Amount {commodity=dollar, quantity=10, price=Just (TotalPrice (Mixed [Amount {commodity=euro, quantity=7, price=Nothing}]))} ,Amount {commodity=dollar, quantity=(-10), price=Nothing} ,Amount {commodity=dollar, quantity=(-10), price=Just (TotalPrice (Mixed [Amount {commodity=euro, quantity=7, price=Nothing}]))}
Hledger/Data/Journal.hs view
@@ -266,7 +266,6 @@ journalFinalise tclock tlocal path txt ctx j@Journal{files=fs} = journalBalanceTransactions $ journalCanonicaliseAmounts $- journalApplyHistoricalPrices $ journalCloseTimeLogEntries tlocal j{files=(path,txt):fs, filereadtime=tclock, jContext=ctx} @@ -280,11 +279,10 @@ Left e -> Left e where balance = balanceTransaction (Just $ journalCanonicalCommodities j) --- | Convert all the journal's amounts to their canonical display--- settings. Ie, all amounts in a given commodity will use (a) the--- display settings of the first, and (b) the greatest precision, of the--- amounts in that commodity. Prices are canonicalised as well, so consider--- calling journalApplyHistoricalPrices before this.+-- | Convert all the journal's posting amounts (not price amounts) to+-- their canonical display settings. Ie, all amounts in a given+-- commodity will use (a) the display settings of the first, and (b)+-- the greatest precision, of the posting amounts in that commodity. journalCanonicaliseAmounts :: Journal -> Journal journalCanonicaliseAmounts j@Journal{jtxns=ts} = j{jtxns=map fixtransaction ts} where
Hledger/Data/Transaction.hs view
@@ -141,17 +141,20 @@ bvsum' = canonicaliseMixedAmountCommodity canonicalcommoditymap $ costOfMixedAmount bvsum -- | Ensure this transaction is balanced, possibly inferring a missing--- amount or a conversion price first, or return an error message.+-- amount or conversion price, or return an error message. ----- Balancing is affected by the provided commodities' display precisions.+-- Balancing is affected by commodity display precisions, so those may+-- be provided. ----- We can infer an amount when there are multiple real postings and--- exactly one of them is amountless; likewise for balanced virtual--- postings. Inferred amounts are converted to cost basis when possible.+-- We can infer a missing real amount when there are multiple real+-- postings and exactly one of them is amountless (likewise for+-- balanced virtual postings). Inferred amounts are converted to cost+-- basis when possible. ----- We can infer a price when all amounts were specified and the sum of--- real postings' amounts is exactly two non-explicitly-priced amounts in--- different commodities; likewise for balanced virtual postings.+-- We can infer a conversion price when all real amounts are specified+-- and the sum of real postings' amounts is exactly two+-- non-explicitly-priced amounts in different commodities (likewise+-- for balanced virtual postings). balanceTransaction :: Maybe (Map.Map String Commodity) -> Transaction -> Either String Transaction balanceTransaction canonicalcommoditymap t@Transaction{tpostings=ps} | length rwithoutamounts > 1 || length bvwithoutamounts > 1@@ -166,8 +169,8 @@ bvamounts = map pamount bvwithamounts t' = t{tpostings=map inferamount ps} where - inferamount p | not (hasAmount p) && isReal p = p{pamount = (- sum ramounts)}- | not (hasAmount p) && isBalancedVirtual p = p{pamount = (- sum bvamounts)}+ inferamount p | not (hasAmount p) && isReal p = p{pamount = costOfMixedAmount (- sum ramounts)}+ | not (hasAmount p) && isBalancedVirtual p = p{pamount = costOfMixedAmount (- sum bvamounts)} | otherwise = p -- maybe infer conversion prices, for real postings
hledger-lib.cabal view
@@ -1,5 +1,5 @@ name: hledger-lib-version: 0.16.1+version: 0.17 category: Finance synopsis: Core data types, parsers and utilities for the hledger accounting tool. description:@@ -17,7 +17,7 @@ homepage: http://hledger.org bug-reports: http://code.google.com/p/hledger/issues stability: beta-tested-with: GHC==6.12, GHC==7.0+tested-with: GHC==7.0, GHC==7.2 cabal-version: >= 1.6 build-type: Simple -- data-dir: data@@ -56,7 +56,7 @@ Build-Depends: base >= 3 && < 5 ,bytestring- ,cmdargs >= 0.8 && < 0.9+ ,cmdargs >= 0.9.1 && < 0.10 ,containers ,directory ,filepath