Merge pull request #914 from simonmichael/rule-tags

tags for matching rule-generated txns and postings
This commit is contained in:
Simon Michael 2019-07-17 18:38:14 +01:00 committed by GitHub
parent a5cae2a859
commit 35799142dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 211 additions and 114 deletions

View File

@ -21,7 +21,7 @@ import Text.Printf
import Hledger.Data.Types
import Hledger.Data.Dates
import Hledger.Data.Amount
import Hledger.Data.Posting (post)
import Hledger.Data.Posting (post, commentAddTagNextLine)
import Hledger.Data.Transaction
import Hledger.Utils.UTF8IOCompat (error')
-- import Hledger.Utils.Debug
@ -69,6 +69,10 @@ instance Show PeriodicTransaction where
-- | Generate transactions from 'PeriodicTransaction' within a 'DateSpan'
--
-- Note that new transactions require 'txnTieKnot' post-processing.
-- The new transactions will have three tags added:
-- - a recur:PERIODICEXPR tag whose value is the generating periodic expression
-- - a generated-transaction: tag
-- - a hidden _generated-transaction: tag which does not appear in the comment.
--
-- >>> _ptgen "monthly from 2017/1 to 2017/4"
-- 2017/01/01
@ -204,10 +208,14 @@ runPeriodicTransaction PeriodicTransaction{..} requestedspan =
tstatus = ptstatus
,tcode = ptcode
,tdescription = ptdescription
,tcomment = (if T.null ptcomment then "\n" else ptcomment) <> "recur: " <> ptperiodexpr
,ttags = ("recur", ptperiodexpr) : pttags
,tcomment = ptcomment
`commentAddTagNextLine` ("generated-transaction",period)
,ttags = ("_generated-transaction",period) :
("generated-transaction" ,period) :
pttags
,tpostings = ptpostings
}
period = "~ " <> ptperiodexpr
-- | Check that this date span begins at a boundary of this interval,
-- or return an explanatory error message including the provided period expression

View File

@ -54,6 +54,10 @@ module Hledger.Data.Posting (
concatAccountNames,
accountNameApplyAliases,
accountNameApplyAliasesMemo,
-- * comment/tag operations
commentJoin,
commentAddTag,
commentAddTagNextLine,
-- * arithmetic
sumPostings,
-- * rendering
@ -356,6 +360,29 @@ postingValueAtDate prices styles mc d p = postingTransformAmount (mixedAmountVal
postingTransformAmount :: (MixedAmount -> MixedAmount) -> Posting -> Posting
postingTransformAmount f p@Posting{pamount=a} = p{pamount=f a}
-- | Join two parts of a comment, eg a tag and another tag, or a tag
-- and a non-tag, on a single line. Interpolates a comma and space
-- unless one of the parts is empty.
commentJoin :: Text -> Text -> Text
commentJoin c1 c2
| T.null c1 = c2
| T.null c2 = c1
| otherwise = c1 <> ", " <> c2
-- | Add a tag to a comment, comma-separated from any prior content.
commentAddTag :: Text -> Tag -> Text
commentAddTag c (t,v)
| T.null c' = tag
| otherwise = c' `commentJoin` tag
where
c' = textchomp c
tag = t <> ":" <> v
-- | Add a tag on its own line to a comment, preserving any prior content.
commentAddTagNextLine :: Text -> Tag -> Text
commentAddTagNextLine cmt (t,v) =
cmt <> if "\n" `T.isSuffixOf` cmt then "" else "\n" <> t <> ":" <> v
-- tests
@ -387,5 +414,14 @@ tests_Posting = tests "Posting" [
,concatAccountNames ["a","(b)","[c:d]"] `is` "(a:b:c:d)"
]
,tests "commentAddTag" [
commentAddTag "" ("a","") `is` "a:"
,commentAddTag "[1/2]" ("a","") `is` "[1/2], a:"
]
,tests "commentAddTagNextLine" [
commentAddTagNextLine "" ("a","") `is` "\na:"
,commentAddTagNextLine "[1/2]" ("a","") `is` "[1/2]\na:"
]
]

View File

@ -12,6 +12,7 @@ module Hledger.Data.TransactionModifier (
)
where
import Control.Applicative ((<|>))
import Data.Maybe
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid ((<>))
@ -23,6 +24,7 @@ import Hledger.Data.Dates
import Hledger.Data.Amount
import Hledger.Data.Transaction
import Hledger.Query
import Hledger.Data.Posting (commentJoin, commentAddTag)
import Hledger.Utils.UTF8IOCompat (error')
import Hledger.Utils.Debug
@ -36,7 +38,15 @@ import Hledger.Utils.Debug
modifyTransactions :: [TransactionModifier] -> [Transaction] -> [Transaction]
modifyTransactions tmods = map applymods
where
applymods = foldr (flip (.) . transactionModifierToFunction) id tmods
applymods t = taggedt'
where
t' = foldr (flip (.) . transactionModifierToFunction) id tmods t
taggedt'
-- PERF: compares txns to see if any modifier had an effect, inefficient ?
| t' /= t = t'{tcomment = tcomment t' `commentAddTag` ("modified","")
,ttags = ("modified","") : ttags t'
}
| otherwise = t'
-- | Converts a 'TransactionModifier' to a 'Transaction'-transforming function,
-- which applies the modification(s) specified by the TransactionModifier.
@ -61,10 +71,10 @@ modifyTransactions tmods = map applymods
--
transactionModifierToFunction :: TransactionModifier -> (Transaction -> Transaction)
transactionModifierToFunction mt =
\t@(tpostings -> ps) -> txnTieKnot t{ tpostings=generatePostings ps } -- TODO add modifier txn comment/tags ?
\t@(tpostings -> ps) -> txnTieKnot t{ tpostings=generatePostings ps }
where
q = simplifyQuery $ tmParseQuery mt (error' "a transaction modifier's query cannot depend on current date")
mods = map tmPostingRuleToFunction $ tmpostingrules mt
mods = map (tmPostingRuleToFunction (tmquerytxt mt)) $ tmpostingrules mt
generatePostings ps = [p' | p <- ps
, p' <- if q `matchesPosting` p then p:[ m p | m <- mods] else [p]]
@ -86,14 +96,23 @@ tmParseQuery mt = fst . flip parseQuery (tmquerytxt mt)
-- which will be used to make a new posting based on the old one (an "automated posting").
-- The new posting's amount can optionally be the old posting's amount multiplied by a constant.
-- If the old posting had a total-priced amount, the new posting's multiplied amount will be unit-priced.
tmPostingRuleToFunction :: TMPostingRule -> (Posting -> Posting)
tmPostingRuleToFunction pr =
-- The new posting will have two tags added: a normal generated-posting: tag which also appears in the comment,
-- and a hidden _generated-posting: tag which does not.
-- The TransactionModifier's query text is also provided, and saved
-- as the tags' value.
tmPostingRuleToFunction :: T.Text -> TMPostingRule -> (Posting -> Posting)
tmPostingRuleToFunction querytxt pr =
\p -> renderPostingCommentDates $ pr
{ pdate = pdate p
, pdate2 = pdate2 p
, pamount = amount' p
{ pdate = pdate pr <|> pdate p
, pdate2 = pdate2 pr <|> pdate2 p
, pamount = amount' p
, pcomment = pcomment pr `commentAddTag` ("generated-posting",qry)
, ptags = ("generated-posting", qry) :
("_generated-posting",qry) :
ptags pr
}
where
qry = "= " <> querytxt
amount' = case postingRuleMultiplier pr of
Nothing -> const $ pamount pr
Just n -> \p ->
@ -123,7 +142,7 @@ postingRuleMultiplier p =
renderPostingCommentDates :: Posting -> Posting
renderPostingCommentDates p = p { pcomment = comment' }
where
datesComment = T.concat $ catMaybes [T.pack . showDate <$> pdate p, ("=" <>) . T.pack . showDate <$> pdate2 p]
dates = T.concat $ catMaybes [T.pack . showDate <$> pdate p, ("=" <>) . T.pack . showDate <$> pdate2 p]
comment'
| T.null datesComment = pcomment p
| otherwise = T.intercalate "\n" $ filter (not . T.null) [T.strip $ pcomment p, "[" <> datesComment <> "]"]
| T.null dates = pcomment p
| otherwise = ("[" <> dates <> "]") `commentJoin` pcomment p

View File

@ -30,7 +30,7 @@ module Hledger.Utils.Text
textstrip,
textlstrip,
textrstrip,
-- chomp,
textchomp,
-- elideLeft,
textElideRight,
-- formatString,
@ -90,9 +90,9 @@ textlstrip = T.dropWhile (`elem` (" \t" :: String)) :: Text -> Text -- XXX isSpa
textrstrip = T.reverse . textlstrip . T.reverse
textrstrip :: Text -> Text
-- -- | Remove trailing newlines/carriage returns.
-- chomp :: String -> String
-- chomp = reverse . dropWhile (`elem` "\r\n") . reverse
-- | Remove trailing newlines/carriage returns (and other whitespace).
textchomp :: Text -> Text
textchomp = T.stripEnd
-- stripbrackets :: String -> String
-- stripbrackets = dropWhile (`elem` "([") . reverse . dropWhile (`elem` "])") . reverse :: String -> String

View File

@ -1201,8 +1201,16 @@ can not accidentally alter their meaning, as in this example:
With the `--forecast` flag, each periodic transaction rule generates
future transactions recurring at the specified interval.
These are not saved in the journal, but appear in all reports.
They will look like normal transactions, but with an extra
[tag](manual.html#tags-1) named `recur`, whose value is the generating period expression.
They will look like normal transactions, but with an extra [tag](manual.html#tags-1):
- `generated-transaction:~ PERIODICEXPR` - shows that this was generated by a periodic transaction rule, and the period
There is also a hidden tag, with an underscore prefix, which does not appear in hledger's output:
- `_generated-transaction:~ PERIODICEXPR`
This can be used to match transactions generated "just now",
rather than generated in the past and saved to the journal.
Forecast transactions start on the first occurrence, and end on the last occurrence,
of their interval within the forecast period. The forecast period:
@ -1251,11 +1259,11 @@ and
## Auto postings / transaction modifiers
Transaction modifier rules describe changes to be applied automatically to certain matched transactions.
Transaction modifier rules, AKA auto posting rules, describe changes to be applied automatically to certain matched transactions.
Currently just one kind of change is possible - adding extra postings, which we call "automated postings" or just "auto postings".
These rules become active when you use the `--auto` flag.
A transaction modifier, AKA auto posting rule, looks much like a normal transaction
A transaction modifier rule looks much like a normal transaction
except the first line is an equals sign followed by a [query](manual.html#queries) that matches certain postings
(mnemonic: `=` suggests matching).
And each "posting" is actually a posting-generating rule:
@ -1309,6 +1317,12 @@ $ hledger print --auto
assets:checking $20
```
### Auto postings and dates
A [posting date](#posting-dates) (or secondary date) in the matched posting,
or (taking precedence) a posting date in the auto posting rule itself,
will also be used in the generated posting.
### Auto postings and transaction balancing / inferred amounts / balance assertions
Currently, transaction modifiers are applied / auto postings are added:
@ -1321,6 +1335,22 @@ after auto postings are added. This changed in hledger 1.12+; see
[#893](https://github.com/simonmichael/hledger/issues/893) for
background.
### Auto posting tags
Postings added by transaction modifiers will have some extra [tags](#tags-1):
- `generated-posting:= QUERY` - shows this was generated by an auto posting rule, and the query
- `_generated-posting:= QUERY` - a hidden tag, which does not appear in hledger's output.
This can be used to match postings generated "just now",
rather than generated in the past and saved to the journal.
Also, any transaction that has been changed by transaction modifier rules will have these tags added:
- `modified:` - this transaction was modified
- `_modified:` - a hidden tag not appearing in the comment; this transaction was modified "just now".
# EDITOR SUPPORT
Helper modes exist for popular text editors, which make working with

View File

@ -51,7 +51,7 @@ hledger print -b 2016-11 -e 2017-02 -f - --forecast
assets:cash
2017/01/01 * marked cleared, and with a description
; recur: monthly from 2016/1
; generated-transaction:~ monthly from 2016/1
income $-1000
expenses:food $20
expenses:leisure $15
@ -118,7 +118,7 @@ Y 2000
>>>
2000/02/01 forecast
; recur: 2/1
; generated-transaction:~ 2/1
>>>2
>>>=0
@ -135,7 +135,7 @@ Y 2000
>>>
2000/01/15 forecast
; recur: 15
; generated-transaction:~ 15
>>>2
>>>=0
@ -152,7 +152,7 @@ Y 2000
>>>
2000/02/01 forecast
; recur: next month
; generated-transaction:~ next month
>>>2
>>>=0

View File

@ -15,11 +15,11 @@
# 1. print
$ hledger print -f- --auto
2016/01/01 paycheck
2016/01/01 paycheck ; modified:
income:remuneration $-100
(liabilities:tax) $-33 ; income tax
(liabilities:tax) $-33 ; income tax, generated-posting:= ^income
income:donations $-15
(liabilities:tax) $-5 ; income tax
(liabilities:tax) $-5 ; income tax, generated-posting:= ^income
assets:bank
2016/01/01 withdraw
@ -80,10 +80,10 @@ $ hledger register -f- --auto
# 5.
$ hledger print -f- --auto
2018/10/07 * MARKET
2018/10/07 * MARKET ; modified:
expenses:groceries:food
[budget:groceries] $-20
[assets:bank:checking] $20
[budget:groceries] $-20 ; generated-posting:= ^expenses:groceries
[assets:bank:checking] $20 ; generated-posting:= ^expenses:groceries
assets:bank:checking $-20
>=
@ -99,10 +99,10 @@ $ hledger print -f- --auto
# 6.
$ hledger -f- print --auto -x
2018/01/01
2018/01/01 ; modified:
(assets:billable:client1) 0.50h @ $90
assets:receivable:client1 50.00h @ $90
revenues:client1 $-4500
assets:receivable:client1 50.00h @ $90 ; generated-posting:= assets:billable:client1
revenues:client1 $-4500 ; generated-posting:= assets:billable:client1
>=
@ -117,10 +117,10 @@ $ hledger -f- print --auto -x
# 7.
$ hledger -f- print --auto -x
2018/01/01
2018/01/01 ; modified:
(assets:billable:client1) 0.50h
assets:receivable:client1 $50
revenues:client1 $-50
assets:receivable:client1 $50 ; generated-posting:= assets:billable:client1
revenues:client1 $-50 ; generated-posting:= assets:billable:client1
>=
@ -135,10 +135,10 @@ $ hledger -f- print --auto -x
# 8.
$ hledger -f- print --auto -x
2018/01/01
2018/01/01 ; modified:
(assets:billable:client1) 0.50h @ $90
assets:receivable:client1 0.50 "Client1 Hours" @ $100.00
revenues:client1 $-50.00
assets:receivable:client1 0.50 "Client1 Hours" @ $100.00 ; generated-posting:= assets:billable:client1
revenues:client1 $-50.00 ; generated-posting:= assets:billable:client1
>=
@ -180,11 +180,11 @@ $ hledger print -f- --auto
# 10.
$ hledger -f- print --auto
2018/01/01
2018/01/01 ; modified:
Expenses:Joint:Widgets $100.00 @ £0.50
Expenses:Joint $-100.00 @ £0.50
Liabilities:Joint:Bob $50.00 @ £0.50
Liabilities:Joint:Bill $50.00 @ £0.50
Expenses:Joint $-100.00 @ £0.50 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bob $50.00 @ £0.50 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bill $50.00 @ £0.50 ; generated-posting:= ^Expenses:Joint
Assets:Joint:Bank £-50.00
>=0
@ -202,11 +202,11 @@ $ hledger -f- print --auto
# 11.
$ hledger -f- print --auto
2018/01/01
2018/01/01 ; modified:
Expenses:Joint:Widgets $100.00 @@ £50
Expenses:Joint $-100.00 @@ £50
Liabilities:Joint:Bob $50.00 @@ £25
Liabilities:Joint:Bill $50.00 @@ £25
Expenses:Joint $-100.00 @@ £50 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bob $50.00 @@ £25 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bill $50.00 @@ £25 ; generated-posting:= ^Expenses:Joint
Assets:Joint:Bank £-50.00
>=0
@ -231,11 +231,11 @@ $ hledger -f- print --auto
# 12.
$ hledger -f- print --auto
2018/01/01
2018/01/01 ; modified:
Expenses:Joint:Widgets $100.00
Expenses:Joint $-100.00 @@ £50
Liabilities:Joint:Bob $50.00 @@ £25
Liabilities:Joint:Bill $50.00 @@ £25
Expenses:Joint $-100.00 @@ £50 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bob $50.00 @@ £25 ; generated-posting:= ^Expenses:Joint
Liabilities:Joint:Bill $50.00 @@ £25 ; generated-posting:= ^Expenses:Joint
Assets:Joint:Bank £-50.00
>=0
@ -264,11 +264,11 @@ $ hledger print -f- --auto --forecast -b 2016-01 -e 2016-03
assets:bank
2016/02/01 paycheck
; recur: monthly from 2016-01
; generated-transaction:~ monthly from 2016-01, modified:
income:remuneration $-100
(liabilities:tax) $-33 ; income tax
(liabilities:tax) $-33 ; income tax, generated-posting:= ^income
income:donations $-15
(liabilities:tax) $-5 ; income tax
(liabilities:tax) $-5 ; income tax, generated-posting:= ^income
assets:bank
>=
@ -280,7 +280,7 @@ $ hledger print -f- --forecast -b 2016-01 -e 2016-03
assets:bank
2016/02/01 paycheck
; recur: monthly from 2016-01
; generated-transaction:~ monthly from 2016-01
income:remuneration $-100
income:donations $-15
assets:bank

View File

@ -85,9 +85,9 @@ D $1000.
(a) €1
>>>
2018/01/01
2018/01/01 ; modified:
(a) €1
(b) €2
(b) €2 ; generated-posting:= a
>>>=

View File

@ -1,4 +1,4 @@
# Add proportional income tax (from documentation)
# 1. Add proportional income tax (from documentation)
hledger rewrite -f- ^income --add-posting '(liabilities:tax) *.33 ; income tax'
<<<
2016/1/1 paycheck
@ -10,11 +10,11 @@ hledger rewrite -f- ^income --add-posting '(liabilities:tax) *.33 ; income tax
assets:cash $20
assets:bank
>>>
2016/01/01 paycheck
2016/01/01 paycheck ; modified:
income:remuneration $-100
(liabilities:tax) $-33 ; income tax
(liabilities:tax) $-33 ; income tax, generated-posting:= ^income
income:donations $-15
(liabilities:tax) $-5 ; income tax
(liabilities:tax) $-5 ; income tax, generated-posting:= ^income
assets:bank
2016/01/01 withdraw
@ -24,7 +24,8 @@ hledger rewrite -f- ^income --add-posting '(liabilities:tax) *.33 ; income tax
>>>2
>>>=0
# Duplicate posting for budgeting (from documentation)
# 2. Duplicate posting for budgeting (from documentation).
# It uses same date as the matched posting.
hledger rewrite -f- expenses:gifts --add-posting '(budget:gifts) *-1'
<<<
2016/1/1 withdraw
@ -39,15 +40,15 @@ hledger rewrite -f- expenses:gifts --add-posting '(budget:gifts) *-1'
assets:cash $20
assets:bank
2016/01/01 gift
2016/01/01 gift ; modified:
assets:cash $-15
expenses:gifts ; [1/2]
(budget:gifts) $-15 ; [2016/01/02]
(budget:gifts) $-15 ; [2016/01/02], generated-posting:= expenses:gifts
>>>2
>>>=0
# Add postings in another commodity
# 3. Add postings in another commodity
hledger rewrite -f-
<<<
2017/04/24 * 09:00-09:25
@ -66,23 +67,23 @@ hledger rewrite -f-
= ^assets:unbilled:client2
(assets:to bill:client2) *150.00 CAD
>>>
2017/04/24 * 09:00-09:25
2017/04/24 * 09:00-09:25 ; modified:
(assets:unbilled:client1) 0.42h
(assets:to bill:client1) 42.00 CAD
(assets:to bill:client1) 42.00 CAD ; generated-posting:= ^assets:unbilled:client1
2017/04/25 * 10:00-11:15
2017/04/25 * 10:00-11:15 ; modified:
(assets:unbilled:client1) 1.25h
(assets:to bill:client1) 125.00 CAD
(assets:to bill:client1) 125.00 CAD ; generated-posting:= ^assets:unbilled:client1
2017/04/25 * 14:00-15:32
2017/04/25 * 14:00-15:32 ; modified:
(assets:unbilled:client2) 1.54h
(assets:to bill:client2) 231.00 CAD
(assets:to bill:client2) 231.00 CAD ; generated-posting:= ^assets:unbilled:client2
>>>2
>>>=0
# Add postings with prices
# 4. Add postings with prices
hledger rewrite -f- -B
<<<
2017/04/24 * 09:00-09:25
@ -103,25 +104,26 @@ hledger rewrite -f- -B
assets:to bill:client2 *1.00 hours @ $150.00
income:consulting:client2
>>>
2017/04/24 * 09:00-09:25
2017/04/24 * 09:00-09:25 ; modified:
(assets:unbilled:client1) 0.42h
assets:to bill:client1 $42.00
income:consulting:client1
assets:to bill:client1 $42.00 ; generated-posting:= ^assets:unbilled:client1
income:consulting:client1 ; generated-posting:= ^assets:unbilled:client1
2017/04/25 * 10:00-11:15
2017/04/25 * 10:00-11:15 ; modified:
(assets:unbilled:client1) 1.25h
assets:to bill:client1 $125.00
income:consulting:client1
assets:to bill:client1 $125.00 ; generated-posting:= ^assets:unbilled:client1
income:consulting:client1 ; generated-posting:= ^assets:unbilled:client1
2017/04/25 * 14:00-15:32
2017/04/25 * 14:00-15:32 ; modified:
(assets:unbilled:client2) 1.54h
assets:to bill:client2 $231.00
income:consulting:client2
assets:to bill:client2 $231.00 ; generated-posting:= ^assets:unbilled:client2
income:consulting:client2 ; generated-posting:= ^assets:unbilled:client2
>>>2
>>>=0
# Add absolute bank processing fee
# 5. Add absolute bank processing fee
# XXX is "and" really processed here ?
hledger rewrite -f- assets:bank and 'amt:<0' --add-posting 'expenses:fee $5' --add-posting 'assets:bank $-5'
<<<
2016/1/1 withdraw
@ -137,22 +139,22 @@ hledger rewrite -f- assets:bank and 'amt:<0' --add-posting 'expenses:fee $5' -
# income:remuneration $-100
# assets:bank
>>>
2016/01/01 withdraw
2016/01/01 withdraw ; modified:
assets:cash $20
assets:bank
expenses:fee $5
assets:bank $-5
expenses:fee $5 ; generated-posting:= assets:bank and amt:<0
assets:bank $-5 ; generated-posting:= assets:bank and amt:<0
2016/01/02 withdraw
2016/01/02 withdraw ; modified:
assets:cash
assets:bank $-30
expenses:fee $5
assets:bank $-5
expenses:fee $5 ; generated-posting:= assets:bank and amt:<0
assets:bank $-5 ; generated-posting:= assets:bank and amt:<0
>>>2
>>>=0
# Rewrite rule within journal
# 6. Rewrite rule within journal
hledger rewrite -f- date:2017/1 --add-posting 'Here comes Santa $0'
<<<
= ^assets:bank$ date:2017/1 amt:<0
@ -186,32 +188,32 @@ hledger rewrite -f- date:2017/1 --add-posting 'Here comes Santa $0'
= ^expenses not:housing not:grocery not:food
(budget:misc) *-1
>>>
2016/12/31
2016/12/31 ; modified:
expenses:housing $600.00
(budget:housing) $-600.00
(budget:housing) $-600.00 ; generated-posting:= ^expenses:housing
assets:cash
2017/01/01
2017/01/01 ; modified:
expenses:food $20.00
(budget:food) $-20.00
Here comes Santa 0
(budget:food) $-20.00 ; generated-posting:= ^expenses:grocery ^expenses:food
Here comes Santa 0 ; generated-posting:= date:2017/1
expenses:leisure $15.00
(budget:misc) $-15.00
Here comes Santa 0
(budget:misc) $-15.00 ; generated-posting:= ^expenses not:housing not:grocery not:food
Here comes Santa 0 ; generated-posting:= date:2017/1
expenses:grocery $30.00
(budget:food) $-30.00
Here comes Santa 0
(budget:food) $-30.00 ; generated-posting:= ^expenses:grocery ^expenses:food
Here comes Santa 0 ; generated-posting:= date:2017/1
assets:cash
Here comes Santa 0
Here comes Santa 0 ; generated-posting:= date:2017/1
2017/01/02
2017/01/02 ; modified:
assets:cash $200.00
Here comes Santa 0
Here comes Santa 0 ; generated-posting:= date:2017/1
assets:bank
assets:bank $-1.60
expenses:fee $1.60 ; cash withdraw fee
(budget:misc) $-1.60
Here comes Santa 0
assets:bank $-1.60 ; generated-posting:= ^assets:bank$ date:2017/1 amt:<0
expenses:fee $1.60 ; cash withdraw fee, generated-posting:= ^assets:bank$ date:2017/1 amt:<0
(budget:misc) $-1.60 ; generated-posting:= ^expenses not:housing not:grocery not:food
Here comes Santa 0 ; generated-posting:= date:2017/1
2017/02/01
assets:cash $100.00
@ -220,7 +222,7 @@ hledger rewrite -f- date:2017/1 --add-posting 'Here comes Santa $0'
>>>2
>>>=0
# Rewrite using diff output
# 7. Rewrite using diff output
hledger rewrite --diff -f- assets:bank and 'amt:<0' --add-posting 'expenses:fee $5' --add-posting 'assets:bank $-5'
<<<
2016/01/01 withdraw
@ -234,16 +236,18 @@ hledger rewrite --diff -f- assets:bank and 'amt:<0' --add-posting 'expenses:fee
--- -
+++ -
@@ -1,3 +1,5 @@
2016/01/01 withdraw
-2016/01/01 withdraw
+2016/01/01 withdraw ; modified:
assets:cash $20
assets:bank
+ expenses:fee $5
+ assets:bank $-5
+ expenses:fee $5 ; generated-posting:= assets:bank and amt:<0
+ assets:bank $-5 ; generated-posting:= assets:bank and amt:<0
@@ -5,3 +7,5 @@
2016/01/02 withdraw
-2016/01/02 withdraw
+2016/01/02 withdraw ; modified:
assets:cash
assets:bank $-30
+ expenses:fee $5
+ assets:bank $-5
+ expenses:fee $5 ; generated-posting:= assets:bank and amt:<0
+ assets:bank $-5 ; generated-posting:= assets:bank and amt:<0
>>>2
>>>=0