mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-26 03:42:25 +03:00
Preserve implicit amounts and prices the way user wrote them in output of print command (#471)
* Remember original postings during infer and pivot This includes such functions like: - inferFromAssignment - inferBalancingAmount - inferBalancingPrices - pivotPosting * Use original postings for hledger print - Introduce "--explicit" option for "print" command which brings back old behavior when every inferred number being printed. - Make "print" by default print original postings without inferred amounts. But use effective account name to have effect from aliases. - Instruct shell tests with an new expected output or to use --explicit option when inferred amounts are checked. Resolves simonmichael/hledger#442
This commit is contained in:
parent
ec890b9455
commit
015b764d00
@ -657,7 +657,7 @@ checkInferAndRegisterAmounts (Right oldTx) = do
|
||||
where
|
||||
inferFromAssignment :: Posting -> CurrentBalancesModifier s Posting
|
||||
inferFromAssignment p = maybe (return p)
|
||||
(fmap (\a -> p { pamount = a }) . setBalance (paccount p))
|
||||
(fmap (\a -> p { pamount = a, porigin = Just $ originalPosting p }) . setBalance (paccount p))
|
||||
$ pbalanceassertion p
|
||||
|
||||
-- | Adds a posting's amonut to the posting's account balance and
|
||||
|
@ -15,6 +15,7 @@ module Hledger.Data.Posting (
|
||||
posting,
|
||||
post,
|
||||
-- * operations
|
||||
originalPosting,
|
||||
postingStatus,
|
||||
isReal,
|
||||
isVirtual,
|
||||
@ -83,12 +84,16 @@ nullposting = Posting
|
||||
,ptags=[]
|
||||
,pbalanceassertion=Nothing
|
||||
,ptransaction=Nothing
|
||||
,porigin=Nothing
|
||||
}
|
||||
posting = nullposting
|
||||
|
||||
post :: AccountName -> Amount -> Posting
|
||||
post acct amt = posting {paccount=acct, pamount=Mixed [amt]}
|
||||
|
||||
originalPosting :: Posting -> Posting
|
||||
originalPosting p = fromMaybe p $ porigin p
|
||||
|
||||
-- XXX once rendered user output, but just for debugging now; clean up
|
||||
showPosting :: Posting -> String
|
||||
showPosting p@Posting{paccount=a,pamount=amt,ptype=t} =
|
||||
|
@ -402,7 +402,7 @@ inferBalancingAmount update t@Transaction{tpostings=ps}
|
||||
inferamount p@Posting{ptype=BalancedVirtualPosting}
|
||||
| not (hasAmount p) = updateAmount p bvsum
|
||||
inferamount p = return p
|
||||
updateAmount p amt = update (paccount p) amt' >> return p { pamount=amt' }
|
||||
updateAmount p amt = update (paccount p) amt' >> return p { pamount=amt', porigin=Just $ originalPosting p }
|
||||
where amt' = normaliseMixedAmount $ costOfMixedAmount (-amt)
|
||||
|
||||
-- | Infer prices for this transaction's posting amounts, if needed to make
|
||||
@ -467,7 +467,7 @@ priceInferrerFor t pt = inferprice
|
||||
|
||||
inferprice p@Posting{pamount=Mixed [a]}
|
||||
| caninferprices && ptype p == pt && acommodity a == fromcommodity
|
||||
= p{pamount=Mixed [a{aprice=conversionprice}]}
|
||||
= p{pamount=Mixed [a{aprice=conversionprice}], porigin=Just $ originalPosting p}
|
||||
where
|
||||
fromcommodity = head $ filter (`elem` sumcommodities) pcommodities -- these heads are ugly but should be safe
|
||||
conversionprice
|
||||
|
@ -199,8 +199,9 @@ data Posting = Posting {
|
||||
ptype :: PostingType,
|
||||
ptags :: [Tag], -- ^ tag names and values, extracted from the comment
|
||||
pbalanceassertion :: Maybe Amount, -- ^ optional: the expected balance in this commodity in the account after this posting
|
||||
ptransaction :: Maybe Transaction -- ^ this posting's parent transaction (co-recursive types).
|
||||
ptransaction :: Maybe Transaction, -- ^ this posting's parent transaction (co-recursive types).
|
||||
-- Tying this knot gets tedious, Maybe makes it easier/optional.
|
||||
porigin :: Maybe Posting -- ^ original posting if this one is result of any transformations (one level only)
|
||||
} deriving (Typeable,Data,Generic)
|
||||
|
||||
instance NFData Posting
|
||||
@ -208,7 +209,7 @@ instance NFData Posting
|
||||
-- The equality test for postings ignores the parent transaction's
|
||||
-- identity, to avoid infinite loops.
|
||||
instance Eq Posting where
|
||||
(==) (Posting a1 b1 c1 d1 e1 f1 g1 h1 i1 _) (Posting a2 b2 c2 d2 e2 f2 g2 h2 i2 _) = a1==a2 && b1==b2 && c1==c2 && d1==d2 && e1==e2 && f1==f2 && g1==g2 && h1==h2 && i1==i2
|
||||
(==) (Posting a1 b1 c1 d1 e1 f1 g1 h1 i1 _ _) (Posting a2 b2 c2 d2 e2 f2 g2 h2 i2 _ _) = a1==a2 && b1==b2 && c1==c2 && d1==d2 && e1==e2 && f1==f2 && g1==g2 && h1==h2 && i1==i2
|
||||
|
||||
-- | The position of parse errors (eg), like parsec's SourcePos but generic.
|
||||
-- File name, 1-based line number and 1-based column number.
|
||||
|
@ -34,7 +34,9 @@ printmode = (defCommandMode $ ["print"] ++ aliases) {
|
||||
in
|
||||
flagReq ["match","m"] (\s opts -> Right $ setopt "match" s opts) matcharg
|
||||
("show the transaction whose description is most similar to "++matcharg
|
||||
++ ", and is most recent")
|
||||
++ ", and is most recent"),
|
||||
flagNone ["explicit","x"] (setboolopt "explicit")
|
||||
"make output more explicit than original transactions"
|
||||
]
|
||||
++ outputflags
|
||||
,groupHidden = []
|
||||
@ -43,6 +45,17 @@ printmode = (defCommandMode $ ["print"] ++ aliases) {
|
||||
}
|
||||
where aliases = []
|
||||
|
||||
showTransaction' :: CliOpts -> Transaction -> String
|
||||
showTransaction' opts
|
||||
| boolopt "explicit" $ rawopts_ opts = showTransactionUnelided
|
||||
| otherwise = showTransactionUnelided . originalTransaction
|
||||
|
||||
originalTransaction :: Transaction -> Transaction
|
||||
originalTransaction t = t { tpostings = map originalPosting' $ tpostings t } where
|
||||
-- We don't want plain original postings because print wouldn't issue alias
|
||||
-- directives. Thus we are going to print effective account name.
|
||||
originalPosting' p = (originalPosting p) { paccount = paccount p }
|
||||
|
||||
-- | Print journal transactions in standard format.
|
||||
print' :: CliOpts -> Journal -> IO ()
|
||||
print' opts j = do
|
||||
@ -57,12 +70,15 @@ printEntries opts@CliOpts{reportopts_=ropts} j = do
|
||||
fmt = outputFormatFromOpts opts
|
||||
(render, ropts') = case fmt of
|
||||
"csv" -> ((++"\n") . printCSV . entriesReportAsCsv, ropts{accountlistmode_=ALFlat})
|
||||
_ -> (entriesReportAsText, ropts)
|
||||
_ -> (entriesReportAsText' opts, ropts)
|
||||
writeOutput opts $ render $ entriesReport ropts' q j
|
||||
|
||||
entriesReportAsText :: EntriesReport -> String
|
||||
entriesReportAsText items = concatMap showTransactionUnelided items
|
||||
|
||||
entriesReportAsText' :: CliOpts -> EntriesReport -> String
|
||||
entriesReportAsText' = concatMap . showTransaction'
|
||||
|
||||
-- XXX
|
||||
-- tests_showTransactions = [
|
||||
-- "showTransactions" ~: do
|
||||
|
@ -91,7 +91,7 @@ pivot tag j = j{jtxns = map pivotTrans . jtxns $ j}
|
||||
where
|
||||
pivotTrans t = t{tpostings = map pivotPosting . tpostings $ t}
|
||||
pivotPosting p
|
||||
| Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value}
|
||||
| Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value, porigin = Just $ originalPosting p}
|
||||
| _ <- tagTuple = p
|
||||
where tagTuple = find ((tag ==) . fst) . ptags $ p
|
||||
|
||||
|
@ -13,13 +13,14 @@ runghc ../../bin/hledger-rewrite.hs -f- ^income --add-posting '(liabilities:tax)
|
||||
>>>
|
||||
2016/01/01 paycheck
|
||||
income:remuneration $-100
|
||||
assets:bank $100
|
||||
assets:bank
|
||||
(liabilities:tax) $-33
|
||||
|
||||
2016/01/01 withdraw
|
||||
assets:cash $20
|
||||
assets:bank $-20
|
||||
assets:bank
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# Duplicate posting for budgeting (from documentation)
|
||||
@ -35,13 +36,14 @@ runghc ../../bin/hledger-rewrite.hs -f- expenses:gifts --add-posting '(budget:gi
|
||||
>>>
|
||||
2016/01/01 withdraw
|
||||
assets:cash $20
|
||||
assets:bank $-20
|
||||
assets:bank
|
||||
|
||||
2016/01/01 gift
|
||||
assets:cash $-15
|
||||
expenses:gifts $15
|
||||
expenses:gifts
|
||||
(budget:gifts) $-15
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# Add absolute bank processing fee
|
||||
@ -62,14 +64,15 @@ runghc ../../bin/hledger-rewrite.hs -f- assets:bank and 'amt:<0' --add-posting '
|
||||
>>>
|
||||
2016/01/01 withdraw
|
||||
assets:cash $20
|
||||
assets:bank $-20
|
||||
assets:bank
|
||||
expenses:fee $5
|
||||
assets:bank $-5
|
||||
|
||||
2016/01/02 withdraw
|
||||
assets:cash $30
|
||||
assets:cash
|
||||
assets:bank $-30
|
||||
expenses:fee $5
|
||||
assets:bank $-5
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
@ -25,15 +25,15 @@ hledger print -f personal.journal -f business.journal -f alias.journal -f person
|
||||
>>>
|
||||
2014/01/01
|
||||
expenses:office supplies $1
|
||||
assets:business checking $-1
|
||||
assets:business checking
|
||||
|
||||
2014/01/02
|
||||
expenses:food $1
|
||||
assets:cash $-1
|
||||
assets:cash
|
||||
|
||||
2014/01/02
|
||||
expenses:food $1
|
||||
assets:cash $-1
|
||||
assets:cash
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
@ -47,7 +47,7 @@ hledger print -f personal.journal -f ../journal/a.timeclock -f ../journal/b.time
|
||||
>>>
|
||||
2014/01/02
|
||||
expenses:food $1
|
||||
assets:cash $-1
|
||||
assets:cash
|
||||
|
||||
2016/01/01 * 12:00-16:00
|
||||
(a:aa) 4.00h
|
||||
|
@ -6,6 +6,6 @@ hledger -f - print
|
||||
>>>
|
||||
2009/01/01 проверка
|
||||
счёт:первый 1
|
||||
счёт:второй -1
|
||||
счёт:второй
|
||||
|
||||
>>>=0
|
||||
|
@ -21,11 +21,11 @@ hledger -f - print
|
||||
>>>
|
||||
2014/01/01 transaction 1
|
||||
㐀 㐃㐃1 @ 2 㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂
|
||||
㐀:㐁 -2 㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂 ; 㐃㐃-1
|
||||
㐀:㐁 ; 㐃㐃-1
|
||||
|
||||
2014/01/02 transaction 2
|
||||
㐀:㐁:㐂 USD 1 @@ EUR 1
|
||||
㐀:㐁:㐂:㐃 EUR -1
|
||||
㐀:㐁:㐂 USD 1
|
||||
㐀:㐁:㐂:㐃 EUR -1
|
||||
|
||||
2014/01/03 transaction 3
|
||||
㐀:㐁:㐂:㐃:㐄 1
|
||||
|
@ -13,7 +13,7 @@ hledger -f - print
|
||||
; transaction comment 1
|
||||
; transaction comment 2
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -27,7 +27,7 @@ hledger -f - print
|
||||
>>>
|
||||
2009/01/01 x
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -51,7 +51,7 @@ hledger -f - print
|
||||
; transaction new line comment
|
||||
a 1 ; posting 1 same line comment
|
||||
; posting 1 new line comment
|
||||
b -1
|
||||
b
|
||||
; posting 2 new line comment
|
||||
|
||||
>>>2
|
||||
|
@ -8,7 +8,7 @@ hledger -f- print
|
||||
>>>2 /unexpected/
|
||||
>>>= 1
|
||||
# 2. with quotes, ok; quotes appear in print output
|
||||
hledger -f- print
|
||||
hledger -f- print --explicit
|
||||
<<<
|
||||
2010-04-05 x
|
||||
a 10 "DE 0002 635307"
|
||||
@ -34,7 +34,7 @@ hledger -f- balance
|
||||
>>>=0
|
||||
|
||||
# 4. autobalance with prices
|
||||
hledger -f- print
|
||||
hledger -f- print --explicit
|
||||
<<<
|
||||
2016/1/1
|
||||
saving-card $-105
|
||||
|
@ -24,7 +24,7 @@ hledger -f- print
|
||||
>>>
|
||||
2000/02/29 x
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>= 0
|
||||
# 4. 29th feb on non-leap year should fail
|
||||
|
@ -12,7 +12,7 @@ hledger -f- print
|
||||
>>>
|
||||
2010/01/01
|
||||
a 1000
|
||||
b -1000
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -26,7 +26,7 @@ D £1000.00
|
||||
>>>
|
||||
2010/01/01
|
||||
a £1000.00
|
||||
b £-1000.00
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -40,7 +40,7 @@ D $1,000
|
||||
>>>
|
||||
2010/01/01
|
||||
a $1000,000
|
||||
b $-1000,000
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
|
@ -8,6 +8,6 @@ hledger -f - print
|
||||
2009/01/01 x
|
||||
a 2
|
||||
b (b) b -1
|
||||
c -1
|
||||
c
|
||||
|
||||
>>>=0
|
||||
|
@ -32,7 +32,7 @@ hledger -f - print
|
||||
|
||||
# 2. and here the price should be printed with its original precision, not
|
||||
# the canonical display precision
|
||||
hledger -f - print
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2010/1/1
|
||||
a $0.00
|
||||
@ -130,7 +130,7 @@ D $1000.0
|
||||
# the max precisions of the commodities being converted (#262).
|
||||
# Here the (irrational) price should be displayed with just precision 4
|
||||
# (C's precision 2 + D's precision 2).
|
||||
hledger -f- print
|
||||
hledger -f- print --explicit
|
||||
<<<
|
||||
2015/1/1
|
||||
c C 10.00
|
||||
@ -147,7 +147,7 @@ hledger -f- print
|
||||
|
||||
## 8. Here the price should be displayed with precision 7
|
||||
# (E's precision 4 + F's precision 3).
|
||||
hledger -f- print
|
||||
hledger -f- print --explicit
|
||||
<<<
|
||||
2015/1/1
|
||||
e E 10.0000
|
||||
|
@ -1,6 +1,6 @@
|
||||
# price-related tests
|
||||
# 1. print a transaction with an explicit unit price
|
||||
hledger -f- print
|
||||
hledger -f- print --explicit
|
||||
<<<
|
||||
2011/01/01
|
||||
expenses:foreign currency €100 @ $1.35
|
||||
@ -13,7 +13,7 @@ hledger -f- print
|
||||
>>>=0
|
||||
|
||||
# 2. -B/--cost converts to the price's commodity ("cost")
|
||||
hledger -f- print --cost
|
||||
hledger -f- print --explicit --cost
|
||||
<<<
|
||||
2011/01/01
|
||||
expenses:foreign currency €100 @ $1.35
|
||||
@ -26,7 +26,7 @@ hledger -f- print --cost
|
||||
>>>=0
|
||||
|
||||
# 3. print a transaction with a total price
|
||||
hledger -f - print
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2011/01/01
|
||||
expenses:foreign currency €100 @@ $135
|
||||
@ -40,7 +40,7 @@ hledger -f - print
|
||||
|
||||
# 4. when the balance has exactly two commodities, both unpriced, infer an
|
||||
# implicit conversion price for the first one in terms of the second.
|
||||
hledger -f - print
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2011/01/01
|
||||
expenses:foreign currency €100
|
||||
@ -61,7 +61,7 @@ hledger -f - print
|
||||
>>>=0
|
||||
|
||||
## 5. another, from ledger tests. Just one posting to price so uses @@.
|
||||
hledger -f - print
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2002/09/30 * 1a1a6305d06ce4b284dba0d267c23f69d70c20be
|
||||
c56a21d23a6535184e7152ee138c28974f14280c 866.231000 GGGGG
|
||||
|
@ -73,12 +73,12 @@ alias /A (.)/=\1
|
||||
2011/01/01
|
||||
b b 1
|
||||
b b 2
|
||||
c -3
|
||||
c
|
||||
|
||||
2011/01/01
|
||||
b 1
|
||||
b 2
|
||||
c -3
|
||||
c
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -98,7 +98,7 @@ hledger -f- print --alias '/A (.)/=a' --alias /a/=b
|
||||
2011/01/01
|
||||
b 1
|
||||
b 2
|
||||
c -3
|
||||
c
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -117,7 +117,7 @@ alias E=F
|
||||
>>>
|
||||
2011/01/01
|
||||
[E:x] 1
|
||||
[x:A:x] -1
|
||||
[x:A:x]
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
@ -1,6 +1,6 @@
|
||||
# amount layout tests, using default vertical layout
|
||||
# 1. print
|
||||
hledger -f - print
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2010/1/1
|
||||
a EUR 1 ; a euro
|
||||
@ -47,8 +47,7 @@ hledger -f - balance
|
||||
>>>=0
|
||||
|
||||
# 4. a single-commodity zero amount's commodity/decimal places/price is preserved, when possible
|
||||
#
|
||||
hledger -f- print --empty
|
||||
hledger -f- print --explicit --empty
|
||||
<<<
|
||||
2010/3/1 x
|
||||
a $0.00 @ 3EUR
|
||||
|
@ -17,11 +17,11 @@ hledger -f- print --cleared
|
||||
>>>
|
||||
2010/01/02 * x
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
2010/01/03 *
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
@ -42,7 +42,7 @@ hledger -f- print --uncleared
|
||||
>>>
|
||||
2010/01/01 x
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
||||
|
114
tests/print/explicit.test
Normal file
114
tests/print/explicit.test
Normal file
@ -0,0 +1,114 @@
|
||||
# Tests of --explicit option effect
|
||||
|
||||
# 1. implicit transaction balance w/o --explict
|
||||
hledger -f - print
|
||||
<<<
|
||||
2017/1/1
|
||||
expenses $5
|
||||
assets
|
||||
>>>
|
||||
2017/01/01
|
||||
expenses $5
|
||||
assets
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 2. implicit transaction balance w/ --explict
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2017/1/1
|
||||
expenses $5
|
||||
assets
|
||||
>>>
|
||||
2017/01/01
|
||||
expenses $5
|
||||
assets $-5
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 3. implicit commodity price w/o --explict
|
||||
hledger -f - print
|
||||
<<<
|
||||
2017/1/1
|
||||
expenses 4 EUR
|
||||
assets $-5
|
||||
>>>
|
||||
2017/01/01
|
||||
expenses 4 EUR
|
||||
assets $-5
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 4. implicit commodity price w/ --explict
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2017/1/1
|
||||
expenses 4 EUR
|
||||
assets $-5
|
||||
>>>
|
||||
2017/01/01
|
||||
expenses 4 EUR @@ $5
|
||||
assets $-5
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 5. implicit account balance w/o --explict
|
||||
hledger -f - print
|
||||
<<<
|
||||
2017/1/1
|
||||
assets = $100
|
||||
equity
|
||||
>>>
|
||||
2017/01/01
|
||||
assets = $100
|
||||
equity
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 6. implicit account balance w/ --explict
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2017/1/1
|
||||
assets = $100
|
||||
equity
|
||||
>>>
|
||||
2017/01/01
|
||||
assets $100 = $100
|
||||
equity $-100
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 7. default commodity always applied because print do not issue appropriate directive
|
||||
hledger -f - print
|
||||
<<<
|
||||
D 1000.00 EUR
|
||||
2017/1/1
|
||||
expenses 100
|
||||
assets
|
||||
>>>
|
||||
2017/01/01
|
||||
expenses 100.00 EUR
|
||||
assets
|
||||
|
||||
>>>2
|
||||
>>>=0
|
||||
|
||||
# 8. option --explicit implies effect of --empty
|
||||
hledger -f - print --explicit
|
||||
<<<
|
||||
2017/1/1
|
||||
assets $0
|
||||
equity
|
||||
>>>
|
||||
2017/01/01
|
||||
assets 0
|
||||
equity 0
|
||||
|
||||
>>>2
|
||||
>>>=0
|
@ -6,6 +6,6 @@ hledger -f - print
|
||||
>>>
|
||||
2009/01/01 x
|
||||
aaaaabbbbbcccccdddddeeeeefffffggggghhhhh 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
@ -11,6 +11,6 @@ hledger -f - print desc:x
|
||||
>>>
|
||||
2009/01/01 x
|
||||
a 1
|
||||
b -1
|
||||
b
|
||||
|
||||
>>>=0
|
||||
|
Loading…
Reference in New Issue
Block a user