hledger-forecast 2.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/{test.yml → ci.yml} +18 -10
- data/.github/workflows/publish_ruby_gem.yml +24 -0
- data/.github/workflows/release.yml +12 -13
- data/.mise.toml +2 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +1 -0
- data/README.md +149 -112
- data/Rakefile +6 -0
- data/example.csv +15 -15
- data/example.journal +17 -18
- data/hledger-forecast.gemspec +20 -18
- data/lib/hledger_forecast/calculator.rb +8 -15
- data/lib/hledger_forecast/cli.rb +98 -71
- data/lib/hledger_forecast/comparator.rb +12 -11
- data/lib/hledger_forecast/forecast.rb +29 -0
- data/lib/hledger_forecast/formatter.rb +13 -15
- data/lib/hledger_forecast/generator.rb +32 -72
- data/lib/hledger_forecast/settings.rb +34 -47
- data/lib/hledger_forecast/summarizer.rb +34 -55
- data/lib/hledger_forecast/summarizer_formatter.rb +75 -78
- data/lib/hledger_forecast/transaction.rb +63 -0
- data/lib/hledger_forecast/transactions/default.rb +45 -72
- data/lib/hledger_forecast/version.rb +1 -1
- data/lib/hledger_forecast.rb +21 -22
- data/spec/calculator_spec.rb +53 -0
- data/spec/cli_spec.rb +19 -17
- data/spec/compare_spec.rb +16 -14
- data/spec/computed_amounts_spec.rb +7 -7
- data/spec/custom_spec.rb +9 -9
- data/spec/formatter_spec.rb +51 -0
- data/spec/half-yearly_spec.rb +5 -5
- data/spec/monthly_end_date_spec.rb +6 -6
- data/spec/monthly_end_date_transaction_spec.rb +10 -10
- data/spec/monthly_spec.rb +7 -7
- data/spec/once_spec.rb +5 -5
- data/spec/quarterly_spec.rb +5 -5
- data/spec/settings_spec.rb +101 -0
- data/spec/stubs/forecast.csv +4 -4
- data/spec/summarizer_spec.rb +28 -33
- data/spec/tags_spec.rb +92 -0
- data/spec/verbose_output_spec.rb +8 -8
- data/spec/yearly_spec.rb +5 -5
- metadata +54 -15
- data/lib/hledger_forecast/transactions/modifiers.rb +0 -90
- data/lib/hledger_forecast/transactions/trackers.rb +0 -88
- data/lib/hledger_forecast/utilities.rb +0 -14
- data/spec/track_spec.rb +0 -105
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 914475b3b188c0bf0950e6d2e0a88eb374a4486d41c901603c8cb41332e268f7
|
|
4
|
+
data.tar.gz: 241b415b6b95b42e757fd5302700cb4b6395bdce105f00782a49b0149be6b2d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cc7ee657e34ec05931165642761b797ec783d1c5c370d6085777d494503782efd32d140aea61e1e9f0d005ce5a6b69f5e28250a3c4150225ce70e5fbcc840a22
|
|
7
|
+
data.tar.gz: 5e6de9e3a6da7531b7d6a4f47b6126e6c34f92ba387cbdcb21584053530f46447d74c9a472bd34e89b566b731c6f71b56a826d17e2613632ae46f435bdbe9d65
|
|
@@ -1,29 +1,37 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Continuous Integration
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [main]
|
|
6
4
|
push:
|
|
7
|
-
branches:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request: ~
|
|
8
8
|
|
|
9
9
|
jobs:
|
|
10
|
-
|
|
10
|
+
tests:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
ruby-version: ['3.
|
|
14
|
+
ruby-version: ['3.3', '3.4']
|
|
15
15
|
|
|
16
16
|
steps:
|
|
17
17
|
- uses: actions/checkout@v4
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
- name: Update packages 📦️
|
|
19
20
|
run: sudo apt-get update
|
|
20
|
-
|
|
21
|
+
|
|
22
|
+
- name: Install packages 📦️
|
|
21
23
|
run: sudo apt-get -y install hledger
|
|
22
|
-
|
|
24
|
+
|
|
25
|
+
- name: Set up Ruby env 💎️
|
|
23
26
|
uses: ruby/setup-ruby@v1
|
|
24
27
|
with:
|
|
25
28
|
bundler-cache: true
|
|
26
29
|
ruby-version: ${{ matrix.ruby-version }}
|
|
27
|
-
|
|
30
|
+
|
|
31
|
+
- name: Run tests 🧪
|
|
28
32
|
run: |
|
|
29
33
|
bundle exec rspec
|
|
34
|
+
|
|
35
|
+
- name: Build gem 💎️
|
|
36
|
+
run: gem build *.gemspec
|
|
37
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish Ruby Gem
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
release:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- name: Publish Gem 💎️
|
|
16
|
+
run: |
|
|
17
|
+
mkdir -p $HOME/.gem
|
|
18
|
+
touch $HOME/.gem/credentials
|
|
19
|
+
chmod 0600 $HOME/.gem/credentials
|
|
20
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
21
|
+
gem build *.gemspec
|
|
22
|
+
gem push *.gem
|
|
23
|
+
env:
|
|
24
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
6
7
|
|
|
7
8
|
jobs:
|
|
8
9
|
release:
|
|
9
10
|
runs-on: ubuntu-latest
|
|
10
11
|
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
pull-requests: write
|
|
15
|
+
|
|
11
16
|
steps:
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
chmod 0600 $HOME/.gem/credentials
|
|
18
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
19
|
-
gem build *.gemspec
|
|
20
|
-
gem push *.gem
|
|
21
|
-
env:
|
|
22
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
|
17
|
+
- name: Release 📦
|
|
18
|
+
uses: googleapis/release-please-action@v4
|
|
19
|
+
with:
|
|
20
|
+
release-type: ruby
|
|
21
|
+
|
data/.mise.toml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [3.1.0](https://github.com/olimorris/hledger-forecast/compare/v3.0.0...v3.1.0) (2026-04-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* dates now support `+` prefix ([#14](https://github.com/olimorris/hledger-forecast/issues/14)) ([16ee70e](https://github.com/olimorris/hledger-forecast/commit/16ee70ec6d3a717f679fddcbf22324f71010e93d))
|
|
9
|
+
|
|
10
|
+
## [3.0.0](https://github.com/olimorris/hledger-forecast/compare/v2.0.1...v3.0.0) (2026-03-27)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* plugin rewrite and removal of tracking ([#9](https://github.com/olimorris/hledger-forecast/issues/9))
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add tag support ([#12](https://github.com/olimorris/hledger-forecast/issues/12)) ([2c341aa](https://github.com/olimorris/hledger-forecast/commit/2c341aa1270699d4bdd13431d5a1a7301169b7a0))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Code Refactoring
|
|
23
|
+
|
|
24
|
+
* plugin rewrite and removal of tracking ([#9](https://github.com/olimorris/hledger-forecast/issues/9)) ([1fadce6](https://github.com/olimorris/hledger-forecast/commit/1fadce6c1db34a93f5700997fb39800e4716c967))
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -5,25 +5,49 @@
|
|
|
5
5
|
<h1 align="center">hledger-forecast</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<a href="https://github.com/olimorris/hledger-forecast/stargazers"><img src="https://img.shields.io/github/stars/olimorris/hledger-forecast?
|
|
9
|
-
<a href="https://github.com/olimorris/hledger-forecast/
|
|
10
|
-
<a href="https://github.com/olimorris/hledger-forecast/
|
|
11
|
-
<a href="https://github.com/olimorris/hledger-forecast/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/olimorris/hledger-forecast/test.yml?branch=main&label=tests&style=for-the-badge"></a>
|
|
8
|
+
<a href="https://github.com/olimorris/hledger-forecast/stargazers"><img src="https://img.shields.io/github/stars/olimorris/hledger-forecast?style=for-the-badge"></a>
|
|
9
|
+
<a href="https://github.com/olimorris/hledger-forecast/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/olimorris/hledger-forecast/ci.yml?branch=main&label=tests&style=for-the-badge"></a>
|
|
10
|
+
<a href="https://github.com/olimorris/hledger-forecast/releases"><img src="https://img.shields.io/github/v/release/olimorris/hledger-forecast?style=for-the-badge"</a>
|
|
12
11
|
</p>
|
|
13
12
|
|
|
14
13
|
**"Improved", you say?** Using a _CSV_ file, forecasts can be quickly generated into a _journal_ file ready to be fed into [hledger](https://github.com/simonmichael/hledger). **A 16 line [CSV file](https://github.com/olimorris/hledger-forecast/blob/main/example.csv) can generate a 46 line hledger [forecast file](https://github.com/olimorris/hledger-forecast/blob/main/example.journal)!**
|
|
15
14
|
|
|
16
|
-
Forecasts can also be constrained between dates, inflated by modifiers, tracked until they appear in your bank statements and summarized into your own daily/weekly/monthly/yearly personal forecast income and expenditure statement.
|
|
17
|
-
|
|
18
15
|
## :sparkles: Features
|
|
19
16
|
|
|
20
|
-
- :rocket:
|
|
21
|
-
- :
|
|
22
|
-
- :
|
|
23
|
-
- :
|
|
24
|
-
- :
|
|
25
|
-
- :
|
|
26
|
-
|
|
17
|
+
- :rocket: Simple CSV file drives the whole forecast
|
|
18
|
+
- :mag: Supports maths in your amounts _and_ dates
|
|
19
|
+
- :label: Apply tags to your transactions
|
|
20
|
+
- :bar_chart: Summarize forecasts as daily/weekly/monthly/yearly income and expenditure reports
|
|
21
|
+
- :twisted_rightwards_arrows: Compare and highlight the difference between two hledger CSV outputs
|
|
22
|
+
- :computer: Straightforward CLI
|
|
23
|
+
|
|
24
|
+
## :brain: The problem statement
|
|
25
|
+
|
|
26
|
+
Forecasting is essential to how I plan and budget with hledger. It enables me to know my financial position in 1 month, 10 months or even 100 months from now.
|
|
27
|
+
|
|
28
|
+
But forecasting in hledger is verbose and unintelligent. Consider this scenario: you purchase a new $3,000 laptop on a 0% finance deal and spread it over 20 months. In hledger, this would be accounted for with:
|
|
29
|
+
|
|
30
|
+
```ledger
|
|
31
|
+
~ monthly from 2026-01-01 to 2027-08-31 * New Laptop
|
|
32
|
+
Expenses:General Expenses $150.00
|
|
33
|
+
Assets:Checking
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Except, you'd need to work out what 20 months from `2026-01-01` is and do $3000 \div 20$.
|
|
37
|
+
|
|
38
|
+
In `hledger-forecast`, you add a single line to your CSV:
|
|
39
|
+
|
|
40
|
+
```csv
|
|
41
|
+
monthly,,Assets:Checking,01/01/2026,+20,New Laptop,Expenses:General Expenses,=3000/20,,,
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The tool calculates the amount and the end date for you.
|
|
45
|
+
|
|
46
|
+
Now the natural next question: _what does that $150/month do to your monthly surplus_? With `hledger-forecast`, that's one command:
|
|
47
|
+
|
|
48
|
+
hledger-forecast summarize -f forecast.csv -r monthly
|
|
49
|
+
|
|
50
|
+
You get an [income statement](https://en.wikipedia.org/wiki/Income_statement) in your terminal - income, expenses, totals, and savings rate.
|
|
27
51
|
|
|
28
52
|
## :camera_flash: Screenshots
|
|
29
53
|
|
|
@@ -31,28 +55,24 @@ Forecasts can also be constrained between dates, inflated by modifiers, tracked
|
|
|
31
55
|
|
|
32
56
|
<img src="https://github.com/olimorris/hledger-forecast/assets/9512444/430503b5-f447-4972-b122-b48f8628aff9" alt="hledger-Forecast" />
|
|
33
57
|
|
|
34
|
-
**The
|
|
58
|
+
**The output from the `summarize` command**
|
|
35
59
|
|
|
36
60
|
<img src="https://github.com/olimorris/hledger-forecast/assets/9512444/f5017ea2-9606-46ec-8b38-8840dc175e7b" alt="Summarize command" />
|
|
37
61
|
|
|
38
62
|
## :package: Installation
|
|
39
63
|
|
|
40
|
-
Assuming you have Ruby and [
|
|
64
|
+
Assuming you have Ruby and [RubyGems](http://rubygems.org/pages/download) installed:
|
|
41
65
|
|
|
42
|
-
gem install
|
|
66
|
+
gem install hledger-forecast
|
|
43
67
|
|
|
44
68
|
## :rocket: Usage
|
|
45
69
|
|
|
46
|
-
Run:
|
|
47
|
-
|
|
48
70
|
hledger-forecast
|
|
49
71
|
|
|
50
|
-
The available options are:
|
|
51
|
-
|
|
52
72
|
Usage: hledger-forecast [command] [options]
|
|
53
73
|
|
|
54
74
|
Commands:
|
|
55
|
-
generate Generate a forecast from a file
|
|
75
|
+
generate Generate a forecast from a CSV file
|
|
56
76
|
summarize Summarize the forecast file and output to the terminal
|
|
57
77
|
compare Compare and highlight the differences between two CSV files
|
|
58
78
|
|
|
@@ -60,165 +80,182 @@ The available options are:
|
|
|
60
80
|
-h, --help Show this help message
|
|
61
81
|
-v, --version Show version
|
|
62
82
|
|
|
63
|
-
### Generate
|
|
83
|
+
### Generate
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
Reads your CSV file and creates a journal file ready to use with hledger. See [example.journal](https://github.com/olimorris/hledger-forecast/blob/main/example.journal) for an example of the output.
|
|
66
86
|
|
|
67
|
-
|
|
87
|
+
hledger-forecast generate -f my_forecast.csv -o forecast.journal
|
|
68
88
|
|
|
69
89
|
Usage: hledger-forecast generate [options]
|
|
70
90
|
|
|
71
91
|
-f, --forecast FILE The path to the FORECAST CSV file to generate from
|
|
72
92
|
-o, --output-file FILE The path to the OUTPUT file to create
|
|
73
|
-
-t, --
|
|
93
|
+
-t, --tags TAGS Only include transactions with given tags (comma-separated)
|
|
74
94
|
-v, --verbose Don't group transactions by type in the output file
|
|
75
95
|
--force Force an overwrite of the output file
|
|
76
|
-
--no-track Don't track any transactions
|
|
77
96
|
-h, --help Show this help message
|
|
78
97
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Running the command with no options will assume a `forecast.csv` file exists.
|
|
98
|
+
Running with no options assumes a `forecast.csv` file exists in the current directory.
|
|
82
99
|
|
|
83
100
|
### Using with hledger
|
|
84
101
|
|
|
85
|
-
|
|
102
|
+
Include the generated journal file and use hledger's `--forecast` flag:
|
|
86
103
|
|
|
87
|
-
hledger -f bank_transactions.journal -f forecast.journal --forecast bal assets -e
|
|
104
|
+
hledger -f bank_transactions.journal -f forecast.journal --forecast bal assets -e 2027-02
|
|
88
105
|
|
|
89
|
-
|
|
106
|
+
This will generate a forecast up to the end of Feb 2027, showing asset balances with your bank transactions overlaid. Forecasting in hledger has some nuance, so please refer to the [hledger docs](https://hledger.org/dev/hledger.html) or open a [discussion](https://github.com/olimorris/hledger-forecast/discussions/new?category=q-a) if you get stuck.
|
|
90
107
|
|
|
91
|
-
If you use
|
|
108
|
+
> **Tip:** If you use `hledger-ui`, the `--verbose` flag is worth using. It keeps each transaction as its own entry in the journal, making descriptions much easier to read in the UI.
|
|
92
109
|
|
|
93
|
-
### Summarize
|
|
110
|
+
### Summarize
|
|
94
111
|
|
|
95
|
-
As your forecast
|
|
112
|
+
As your forecast grows, it's useful to see the totals at a glance. Think of this as your income statement, rolled up to whatever period makes sense.
|
|
96
113
|
|
|
97
114
|
hledger-forecast summarize -f my_forecast.csv
|
|
98
115
|
|
|
99
|
-
The available options are:
|
|
100
|
-
|
|
101
116
|
Usage: hledger-forecast summarize [options]
|
|
102
117
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
118
|
+
-f, --forecast FILE The path to the FORECAST CSV file to summarize
|
|
119
|
+
-r, --roll-up PERIOD The period to roll-up your forecasts into. One of:
|
|
120
|
+
[yearly], [half-yearly], [quarterly], [monthly], [weekly], [daily]
|
|
121
|
+
-t, --tags TAGS Only include transactions with given tags (comma-separated)
|
|
122
|
+
-v, --verbose Show additional information in the summary
|
|
123
|
+
-h, --help Show this help message
|
|
108
124
|
|
|
109
|
-
### Compare
|
|
125
|
+
### Compare
|
|
110
126
|
|
|
111
|
-
A core part of managing
|
|
127
|
+
A core part of managing personal finances is comparing what you _expected_ to happen with what _actually_ happened. The `compare` command makes this easy:
|
|
112
128
|
|
|
113
|
-
hledger-forecast compare
|
|
129
|
+
hledger-forecast compare path/to/expected.csv path/to/actual.csv
|
|
114
130
|
|
|
115
|
-
To generate CSV output
|
|
131
|
+
To generate CSV output from hledger, append `-O csv > output.csv` to any hledger command.
|
|
116
132
|
|
|
117
|
-
|
|
133
|
+
For wide output, pipe through a pager like [most](https://en.wikipedia.org/wiki/Most_(Unix)):
|
|
118
134
|
|
|
119
|
-
|
|
135
|
+
hledger-forecast compare file1.csv file2.csv | most
|
|
120
136
|
|
|
121
|
-
|
|
137
|
+
> **Note:** The two CSV files must have the same structure.
|
|
122
138
|
|
|
123
|
-
|
|
139
|
+
## :gear: Creating your forecast
|
|
124
140
|
|
|
125
141
|
### Columns
|
|
126
142
|
|
|
127
|
-
The
|
|
128
|
-
|
|
129
|
-
- `type` - (string) - The type of forecast entry. One of `monthly`, `quarterly`, `half-yearly`, `yearly`, `once` or `custom`
|
|
130
|
-
- `frequency` - (string) - The frequency that the type repeats with (only if `custom`). As per hledger's [periodic rule syntax](https://hledger.org/dev/hledger.html#periodic-transactions)
|
|
131
|
-
- `account` - (string) - The account the transaction applies to e.g. _Expenses:Food_
|
|
132
|
-
- `from` - (date) - The date the transaction should start from e.g. _2023-06-01_
|
|
133
|
-
- `to` - (date) _(optional)_ - The date the transaction should end on e.g. _2023-12-31_
|
|
134
|
-
- `description` - (string) - A description of the transaction
|
|
135
|
-
- `category` - (string) - The classification or category of the transaction
|
|
136
|
-
- `amount` - (integer/float) - The amount of the transaction
|
|
137
|
-
- `roll-up` - (integer/float) _(optional)_ - For use with the summarizer, the value you need to multiply the amount by to get it into a yearly amount
|
|
138
|
-
- `summary_exclude` - (boolean) _(optional)_ - Exclude the transaction from the summarizer?
|
|
139
|
-
- `track` - (boolean) _(optional)_ - Track the transaction against your confirmed transactions?
|
|
143
|
+
The CSV file should have a header row with these columns:
|
|
140
144
|
|
|
141
|
-
|
|
145
|
+
| Column | Type | Required | Description |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| `type` | string | yes | One of: `monthly`, `quarterly`, `half-yearly`, `yearly`, `once`, `custom` |
|
|
148
|
+
| `frequency` | string | `custom` only | Repeating frequency, using hledger's [periodic rule syntax](https://hledger.org/dev/hledger.html#periodic-transactions) |
|
|
149
|
+
| `account` | string | yes | The account the transaction applies to, e.g. `Assets:Bank` |
|
|
150
|
+
| `from` | date | yes | Start date, e.g. `01/03/2023` |
|
|
151
|
+
| `to` | date | no | End date, e.g. `01/01/2025`. Supports `+` prefix for calculated values, e.g. `+12` for 12 months |
|
|
152
|
+
| `description` | string | yes | A description of the transaction |
|
|
153
|
+
| `category` | string | yes | The category account, e.g. `Expenses:Food` |
|
|
154
|
+
| `amount` | number | yes | The transaction amount. Supports `=` prefix for calculated values |
|
|
155
|
+
| `roll-up` | number | no | Multiplier for the summarizer — use this for `custom` types to annualise them |
|
|
156
|
+
| `summary_exclude` | boolean | no | Set to `TRUE` to exclude from the summarizer |
|
|
157
|
+
| `tag` | string | no | Pipe-separated tags, e.g. `fixed|essential`. Outputs as native hledger tags |
|
|
142
158
|
|
|
143
|
-
|
|
159
|
+
### Example
|
|
144
160
|
|
|
145
161
|
```csv
|
|
146
|
-
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,
|
|
147
|
-
monthly,,Assets:Bank,01/03/2023,,Salary,Income:Salary,-3500,,,
|
|
148
|
-
monthly,,Assets:Bank,01/03/2023,01/01/2025,Mortgage,Expenses:Mortgage,2000,,,
|
|
149
|
-
monthly,,Assets:Bank,01/03/2023,,Bills,Expenses:Bills,175,,,
|
|
150
|
-
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,
|
|
151
|
-
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,
|
|
152
|
-
monthly,,Assets:Bank,01/03/2023
|
|
153
|
-
monthly,,Assets:Bank,01/03/2023,01/03/2025,Rainy day fund,Assets:Savings,300,,,
|
|
154
|
-
monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,
|
|
155
|
-
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,
|
|
156
|
-
half-yearly,,Assets:Bank,01/04/2023,,Top up holiday funds,Expenses:Holiday,500,,,
|
|
157
|
-
yearly,,Assets:Bank,01/04/2023,,Annual bonus,Income:Bonus,-2000,,,
|
|
158
|
-
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000
|
|
159
|
-
custom,every 2 weeks,Assets:Bank,01/03/2023,,Hair and beauty,Expenses:Personal Care,80,26,,
|
|
160
|
-
custom,every 5 weeks,Assets:Bank,01/03/2023,,Misc expenses,Expenses:General Expenses,30,10.4,,
|
|
162
|
+
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,tag
|
|
163
|
+
monthly,,Assets:Bank,01/03/2023,,Salary,Income:Salary,-3500,,,fixed|essential
|
|
164
|
+
monthly,,Assets:Bank,01/03/2023,01/01/2025,Mortgage,Expenses:Mortgage,2000,,,fixed|essential
|
|
165
|
+
monthly,,Assets:Bank,01/03/2023,,Bills,Expenses:Bills,175,,,fixed|essential
|
|
166
|
+
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,living|essential
|
|
167
|
+
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,living
|
|
168
|
+
monthly,,Assets:Bank,01/03/2023,+12,Holiday,Expenses:Holiday,125,,,living
|
|
169
|
+
monthly,,Assets:Bank,01/03/2023,01/03/2025,Rainy day fund,Assets:Savings,300,,,saving
|
|
170
|
+
monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,fixed|essential
|
|
171
|
+
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,fixed
|
|
172
|
+
half-yearly,,Assets:Bank,01/04/2023,,Top up holiday funds,Expenses:Holiday,500,,,living
|
|
173
|
+
yearly,,Assets:Bank,01/04/2023,,Annual bonus,Income:Bonus,-2000,,,fixed
|
|
174
|
+
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000,TRUE,
|
|
175
|
+
custom,every 2 weeks,Assets:Bank,01/03/2023,,Hair and beauty,Expenses:Personal Care,80,26,,living
|
|
176
|
+
custom,every 5 weeks,Assets:Bank,01/03/2023,,Misc expenses,Expenses:General Expenses,30,10.4,,living
|
|
161
177
|
settings,currency,USD,,,,,,,,
|
|
162
178
|
```
|
|
163
179
|
|
|
164
|
-
###
|
|
180
|
+
### Calculated amounts
|
|
165
181
|
|
|
166
|
-
|
|
182
|
+
Prefix any `amount` with `=` and write it as a standard formula — the app will evaluate it for you. Great for spreading a lump sum across months:
|
|
167
183
|
|
|
168
|
-
|
|
184
|
+
```csv
|
|
185
|
+
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
> Calculations are evaluated to two decimal places.
|
|
169
189
|
|
|
170
|
-
|
|
190
|
+
### Calculated dates
|
|
171
191
|
|
|
172
|
-
|
|
192
|
+
The `to` column supports calculated values. Use `+` followed by a number to mean "N months from the `from` date":
|
|
173
193
|
|
|
174
194
|
```csv
|
|
175
|
-
|
|
176
|
-
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,
|
|
195
|
+
monthly,,Assets:Bank,01/03/2026,+12,Holiday,Expenses:Holiday,125,,
|
|
177
196
|
```
|
|
178
197
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
#### Calculated dates
|
|
182
|
-
|
|
183
|
-
It may also be helpful for `to` dates to be calculated:
|
|
198
|
+
That sets the end date to 12 months after `01/03/2026`. The `=` prefix also supports formulas — useful for longer periods:
|
|
184
199
|
|
|
185
200
|
```csv
|
|
186
|
-
|
|
187
|
-
monthly,,Assets:Bank,01/03/2023,=12,Holiday,Expenses:Holiday,125,,,
|
|
201
|
+
monthly,,Assets:Bank,01/03/2026,=12*5,Mortgage,Expenses:Mortgage,2000,,
|
|
188
202
|
```
|
|
189
203
|
|
|
190
|
-
|
|
204
|
+
That sets the end date to 5 years (60 months) after `01/03/2026`.
|
|
191
205
|
|
|
192
|
-
|
|
206
|
+
### Tags
|
|
207
|
+
|
|
208
|
+
Add a `tag` column to your CSV to tag transactions. Tags are output as native [hledger tags](https://hledger.org/tags-tutorial.html), making them queryable in hledger itself. Multiple tags are separated by pipes (`|`):
|
|
193
209
|
|
|
194
210
|
```csv
|
|
195
|
-
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
211
|
+
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,tag
|
|
212
|
+
monthly,,Assets:Bank,01/03/2023,,Salary,Income:Salary,-3500,,,fixed|essential
|
|
213
|
+
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,living|essential
|
|
214
|
+
monthly,,Assets:Bank,01/03/2023,,Netflix,Expenses:Subscriptions,15,,,living
|
|
199
215
|
```
|
|
200
216
|
|
|
201
|
-
|
|
217
|
+
This generates journal entries with proper hledger tags on each posting:
|
|
202
218
|
|
|
203
|
-
|
|
219
|
+
```
|
|
220
|
+
~ monthly from 2023-03-01 * Salary, Food, Netflix
|
|
221
|
+
Income:Salary £-3,500.00; fixed:, essential:
|
|
222
|
+
Expenses:Food £500.00 ; living:, essential:
|
|
223
|
+
Expenses:Subscriptions £15.00 ; living:
|
|
224
|
+
Assets:Bank
|
|
225
|
+
```
|
|
204
226
|
|
|
205
|
-
|
|
227
|
+
**Filtering by tags** - both `generate` and `summarize` accept a `--tags` flag to include only transactions matching any of the given tags:
|
|
206
228
|
|
|
207
|
-
|
|
229
|
+
```bash
|
|
230
|
+
# Generate a journal with only your fixed costs
|
|
231
|
+
hledger-forecast generate -f forecast.csv -o fixed.journal --tags=fixed
|
|
208
232
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
233
|
+
# Summarize only essential spending
|
|
234
|
+
hledger-forecast summarize -f forecast.csv --tags=essential
|
|
235
|
+
|
|
236
|
+
# Multiple tags use OR logic — matches any
|
|
237
|
+
hledger-forecast summarize -f forecast.csv --tags=fixed,living
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Querying in hledger** - because the tags are native hledger format, you can query them directly:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
hledger bal tag:fixed -f forecast.journal
|
|
244
|
+
hledger bal tag:essential not:tag:living -f forecast.journal
|
|
212
245
|
```
|
|
213
246
|
|
|
214
|
-
|
|
247
|
+
### Settings
|
|
215
248
|
|
|
216
|
-
|
|
249
|
+
Settings rows live in the same CSV file. The defaults are:
|
|
217
250
|
|
|
218
|
-
|
|
251
|
+
```csv
|
|
252
|
+
settings,currency,USD,,,,,,,,
|
|
253
|
+
settings,show_symbol,true,,,,,,,,
|
|
254
|
+
settings,thousands_separator,true,,,,,,,,
|
|
255
|
+
```
|
|
219
256
|
|
|
220
|
-
|
|
257
|
+
Override any of them by adding a `settings` row. Multiple settings rows are fine — they won't clobber each other.
|
|
221
258
|
|
|
222
259
|
## :pencil2: Contributing
|
|
223
260
|
|
|
224
|
-
I
|
|
261
|
+
I'm open to pull requests that fix bugs. For new functionality, please open a discussion first so we can figure out whether it's the right direction before any code is written.
|
data/Rakefile
ADDED
data/example.csv
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,
|
|
2
|
-
monthly,,Assets:Bank,01/03/2023,,Salary,Income:Salary,-3500,,,
|
|
3
|
-
monthly,,Assets:Bank,01/03/2023,01/01/2025,Mortgage,Expenses:Mortgage,2000,,,
|
|
4
|
-
monthly,,Assets:Bank,01/03/2023,,Bills,Expenses:Bills,175,,,
|
|
5
|
-
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,
|
|
6
|
-
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,
|
|
7
|
-
monthly,,Assets:Bank,01/03/2023,=12,Holiday,Expenses:Holiday,125,,,
|
|
8
|
-
monthly,,Assets:Bank,01/03/2023,01/03/2025,Rainy day fund,Assets:Savings,300,,,
|
|
9
|
-
monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,
|
|
10
|
-
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,
|
|
11
|
-
half-yearly,,Assets:Bank,01/04/2023,,Top up holiday funds,Expenses:Holiday,500,,,
|
|
12
|
-
yearly,,Assets:Bank,01/04/2023,,Annual bonus,Income:Bonus,-2000,,,
|
|
13
|
-
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000
|
|
14
|
-
custom,every 2 weeks,Assets:Bank,01/03/2023,,Hair and beauty,Expenses:Personal Care,80,26,,
|
|
15
|
-
custom,every 5 weeks,Assets:Bank,01/03/2023,,Misc expenses,Expenses:General Expenses,30,10.4,,
|
|
1
|
+
type,frequency,account,from,to,description,category,amount,roll-up,summary_exclude,tag
|
|
2
|
+
monthly,,Assets:Bank,01/03/2023,,Salary,Income:Salary,-3500,,,fixed|essential
|
|
3
|
+
monthly,,Assets:Bank,01/03/2023,01/01/2025,Mortgage,Expenses:Mortgage,2000,,,fixed|essential
|
|
4
|
+
monthly,,Assets:Bank,01/03/2023,,Bills,Expenses:Bills,175,,,fixed|essential
|
|
5
|
+
monthly,,Assets:Bank,01/03/2023,,Food,Expenses:Food,500,,,living|essential
|
|
6
|
+
monthly,,Assets:Bank,01/03/2023,,New Kitchen,Expenses:House,=5000/24,,,living
|
|
7
|
+
monthly,,Assets:Bank,01/03/2023,=12,Holiday,Expenses:Holiday,125,,,living
|
|
8
|
+
monthly,,Assets:Bank,01/03/2023,01/03/2025,Rainy day fund,Assets:Savings,300,,,saving
|
|
9
|
+
monthly,,Assets:Pension,01/01/2024,,Pension draw down,Income:Pension,-500,,,fixed|essential
|
|
10
|
+
quarterly,,Assets:Bank,01/04/2023,,Quarterly bonus,Income:Bonus,-1000,,,fixed
|
|
11
|
+
half-yearly,,Assets:Bank,01/04/2023,,Top up holiday funds,Expenses:Holiday,500,,,living
|
|
12
|
+
yearly,,Assets:Bank,01/04/2023,,Annual bonus,Income:Bonus,-2000,,,fixed
|
|
13
|
+
once,,Assets:Bank,05/03/2023,,Refund for that damn laptop,Expenses:Shopping,-3000,,,
|
|
14
|
+
custom,every 2 weeks,Assets:Bank,01/03/2023,,Hair and beauty,Expenses:Personal Care,80,26,,living
|
|
15
|
+
custom,every 5 weeks,Assets:Bank,01/03/2023,,Misc expenses,Expenses:General Expenses,30,10.4,,living
|
|
16
16
|
settings,currency,USD,,,,,,,,
|