journal: also support lot dates ([DATE])

This commit is contained in:
Simon Michael 2020-04-08 19:55:55 -07:00
parent fedde7fab1
commit f4a1a31712
3 changed files with 37 additions and 23 deletions

View File

@ -137,6 +137,7 @@ import Text.Megaparsec
import Text.Megaparsec.Char
import Text.Megaparsec.Char.Lexer (decimal)
import Text.Megaparsec.Custom
import Control.Applicative.Permutations
import Hledger.Data
import Hledger.Utils
@ -610,11 +611,11 @@ spaceandamountormissingp =
amountp :: JournalParser m Amount
amountp = label "amount" $ do
let spaces = lift $ skipMany spacenonewline
amount <- amountwithoutpricep
spaces
_elotprice <- optional $ lotpricep <* spaces
mprice <- optional $ priceamountp <* spaces
_elotprice <- optional $ lotpricep
amount <- amountwithoutpricep <* spaces
(mprice, _elotprice, _elotdate) <- runPermutation $
(,,) <$> toPermutationWithDefault Nothing (Just <$> priceamountp <* spaces)
<*> toPermutationWithDefault Nothing (Just <$> lotpricep <* spaces)
<*> toPermutationWithDefault Nothing (Just <$> lotdatep <* spaces)
pure $ amount { aprice = mprice }
-- XXX Just like amountp but don't allow lot prices. Needed for balanceassertionp.
@ -761,21 +762,33 @@ balanceassertionp = do
, baposition = sourcepos
}
-- Parse a Ledger-style fixed {=PRICE} or non-fixed {PRICE} lot price,
-- as a Left or Right Amount respectively.
-- Parse a Ledger-style fixed {=UNITPRICE} or non-fixed {UNITPRICE}
-- or fixed {{=TOTALPRICE}} or non-fixed {{TOTALPRICE}} lot price,
-- and ignore it.
-- https://www.ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices .
lotpricep :: JournalParser m (Either Amount Amount)
lotpricep = (do
lotpricep :: JournalParser m ()
lotpricep = label "ledger-style lot price" $ do
char '{'
doublebrace <- option False $ char '{' >> pure True
fixed <- fmap isJust $ optional $ lift (skipMany spacenonewline) >> char '='
_fixed <- fmap isJust $ optional $ lift (skipMany spacenonewline) >> char '='
lift (skipMany spacenonewline)
a <- amountwithoutpricep
_a <- amountwithoutpricep
lift (skipMany spacenonewline)
char '}'
when (doublebrace) $ void $ char '}'
return $ (if fixed then Left else Right) a
) <?> "ledger-style lot price or fixed lot price"
return ()
-- Parse a Ledger-style lot date [DATE], and ignore it.
-- https://www.ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices .
lotdatep :: JournalParser m ()
lotdatep = (do
char '['
lift (skipMany spacenonewline)
_d <- datep
lift (skipMany spacenonewline)
char ']'
return ()
) <?> "ledger-style lot date"
-- | Parse a string representation of a number for its value and display
-- attributes.

View File

@ -862,6 +862,9 @@ tests_JournalReader = tests "JournalReader" [
,test "lot price before transaction price" $ assertParse (postingp Nothing) " a 1A {1B} @ 1B\n"
,test "lot price after transaction price" $ assertParse (postingp Nothing) " a 1A @ 1B {1B}\n"
,test "lot price after balance assertion not allowed" $ assertParseError (postingp Nothing) " a 1A @ 1B = 1A {1B}\n" "unexpected '{'"
,test "only lot date" $ assertParse (postingp Nothing) " a 1A [2000-01-01]\n"
,test "transaction price, lot price, lot date" $ assertParse (postingp Nothing) " a 1A @ 1B {1B} [2000-01-01]\n"
,test "lot date, lot price, transaction price" $ assertParse (postingp Nothing) " a 1A [2000-01-01] {1B} @ 1B\n"
,test "balance assertion over entire contents of account" $ assertParse (postingp Nothing) " a $1 == $1\n"
]

View File

@ -579,18 +579,16 @@ $ hledger bal -N --flat -B
€100 assets:euros
```
## Lot Prices
## Lot Prices and Lot Dates
Ledger allows another kind of price,
[lot price](http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices),
to be specified in curly braces
(three variants: `{UNITPRICE}`, `{{TOTALPRICE}}`, `{=FIXEDUNITPRICE}`).
This is normally used to select a lot when selling investments.
hledger will parse these, for compatibility with Ledger journals, but
currently ignores them.
They may appear after the posting amount, before or after the
[transaction price](#transaction-prices) if any, and before the
balance assertion if any.
[lot price](http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices)
(four variants: `{UNITPRICE}`, `{{TOTALPRICE}}`, `{=FIXEDUNITPRICE}`, `{{=FIXEDTOTALPRICE}}`),
and/or a lot date (`[DATE]`) to be specified.
These are normally used to select a lot when selling investments.
hledger will parse these, for compatibility with Ledger journals, but currently ignores them.
A [transaction price](#transaction-prices), lot price and/or lot date may appear in any order,
after the posting amount and before the balance assertion if any.
## Balance Assertions