inferred amounts use the cost commodity if known, like ledger (#69)

This commit is contained in:
Simon Michael 2012-01-03 08:15:48 +00:00
parent 470155dc63
commit 9bdb170a0a
3 changed files with 41 additions and 24 deletions

View File

@ -141,17 +141,20 @@ isTransactionBalanced canonicalcommoditymap t =
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 @@ balanceTransaction canonicalcommoditymap t@Transaction{tpostings=ps}
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

View File

@ -1,21 +1,35 @@
# http://code.google.com/p/hledger/issues/detail?id=23
#
# 1. with explicit price:
# prices' commodities are unobserved, so $'s display precision here should be 2 not 4
bin/hledger -f - print --cost
# 1. original test case, this should balance since price precisions do
# not affect the canonical display precisions used for display and balancing
bin/hledger -f - print
<<<
2010/1/1
a $0.00
a 1C @ $1.0049
a
2010/1/1 x
A 55.3653 C @ 30.92189512 D
A -1712 D
>>>
2010/01/01
a 0
a $1.00
a $-1.00
2010/01/01 x
A 55.3653 C @ 30.92189512 D
A -1712 D
>>>=0
## 1b. here $'s canonical display precision should be 2 not 4
## XXX no, because the inferred amount $1.0049 is observed
# bin/hledger -f - print --cost
# <<<
# 2010/1/1
# a $0.00
# a 1C @ $1.0049
# a
# >>>
# 2010/01/01
# a 0
# a $1.00
# a $-1.00
#
# >>>=0
# 2. and here the price should be printed with its original precision, not
# the canonical display precision
bin/hledger -f - print
@ -28,7 +42,7 @@ bin/hledger -f - print
2010/01/01
a 0
a 1C @ $1.0049
a -1C @ $1.0049
a $-1.0049
>>>=0

View File

@ -8,7 +8,7 @@ bin/hledger -f- print
>>>
2011/01/01
expenses:foreign currency €100 @ $1.35
assets €-100 @ $1.35
assets $-135.00
>>>=0
@ -50,7 +50,7 @@ bin/hledger -f - print
>>>
2011/01/01
expenses:foreign currency €100 @@ $135
assets €-100 @@ $135
assets $-135
>>>=0