mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-26 03:42:25 +03:00
Merge pull request #914 from simonmichael/rule-tags
tags for matching rule-generated txns and postings
This commit is contained in:
parent
a5cae2a859
commit
35799142dd
@ -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
|
||||
|
@ -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:"
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -85,9 +85,9 @@ D $1000.
|
||||
(a) €1
|
||||
|
||||
>>>
|
||||
2018/01/01
|
||||
2018/01/01 ; modified:
|
||||
(a) €1
|
||||
(b) €2
|
||||
(b) €2 ; generated-posting:= a
|
||||
|
||||
>>>=
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user