hledger-forecast 0.2.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/README.md +169 -71
- data/example.journal +40 -0
- data/example.yml +38 -36
- data/hledger-forecast.gemspec +6 -4
- data/lib/hledger_forecast/cli.rb +35 -93
- data/lib/hledger_forecast/generator.rb +242 -90
- data/lib/hledger_forecast/summarize.rb +4 -5
- data/lib/hledger_forecast/tracker.rb +37 -0
- data/lib/hledger_forecast/version.rb +1 -1
- data/lib/hledger_forecast.rb +2 -1
- data/spec/command_spec.rb +14 -4
- data/spec/computed_amounts_spec.rb +35 -0
- data/spec/custom_spec.rb +35 -42
- data/spec/half-yearly_spec.rb +22 -6
- data/spec/modifier_spec.rb +87 -0
- data/spec/monthly_end_date_spec.rb +47 -0
- data/spec/monthly_end_date_transaction_spec.rb +32 -0
- data/spec/monthly_spec.rb +35 -27
- data/spec/once_spec.rb +22 -7
- data/spec/quarterly_spec.rb +21 -7
- data/spec/stubs/{monthly/forecast_monthly.yml → forecast.yml} +7 -7
- data/spec/stubs/transactions_found.journal +24 -0
- data/spec/stubs/transactions_found_inverse.journal +24 -0
- data/spec/stubs/transactions_not_found.journal +16 -0
- data/spec/track_spec.rb +197 -0
- data/spec/yearly_spec.rb +21 -7
- metadata +48 -74
- data/spec/start_date_spec.rb +0 -12
- data/spec/stubs/custom/forecast_custom_days.yml +0 -14
- data/spec/stubs/custom/forecast_custom_months.yml +0 -14
- data/spec/stubs/custom/forecast_custom_weeks.yml +0 -14
- data/spec/stubs/custom/forecast_custom_weeks_twice.yml +0 -24
- data/spec/stubs/custom/output_custom_days.journal +0 -24
- data/spec/stubs/custom/output_custom_months.journal +0 -20
- data/spec/stubs/custom/output_custom_weeks.journal +0 -28
- data/spec/stubs/custom/output_custom_weeks_twice.journal +0 -44
- data/spec/stubs/half-yearly/forecast_half-yearly.yml +0 -10
- data/spec/stubs/half-yearly/output_half-yearly.journal +0 -20
- data/spec/stubs/modifiers/forecast_modifiers.yml +0 -13
- data/spec/stubs/modifiers/output_modifiers.journal +0 -44
- data/spec/stubs/monthly/forecast_monthly_enddate.yml +0 -14
- data/spec/stubs/monthly/forecast_monthly_enddate_top.yml +0 -14
- data/spec/stubs/monthly/forecast_monthly_modifier.yml +0 -11
- data/spec/stubs/monthly/output_monthly.journal +0 -44
- data/spec/stubs/monthly/output_monthly_enddate.journal +0 -48
- data/spec/stubs/monthly/output_monthly_enddate_top.journal +0 -40
- data/spec/stubs/monthly/output_monthly_modifier.journal +0 -20
- data/spec/stubs/once/forecast_once.yml +0 -10
- data/spec/stubs/once/output_once.journal +0 -12
- data/spec/stubs/quarterly/forecast_quarterly.yml +0 -10
- data/spec/stubs/quarterly/output_quarterly.journal +0 -20
- data/spec/stubs/start_date/forecast_startdate.yml +0 -26
- data/spec/stubs/start_date/output_startdate.journal +0 -56
- data/spec/stubs/transactions.journal +0 -8
- data/spec/stubs/yearly/forecast_yearly.yml +0 -10
- data/spec/stubs/yearly/output_yearly.journal +0 -16
@@ -0,0 +1,37 @@
|
|
1
|
+
module HledgerForecast
|
2
|
+
# Checks for the existence of a transaction in a journal file and tracks it
|
3
|
+
class Tracker
|
4
|
+
def self.track(transactions, transaction_file)
|
5
|
+
next_month = Date.new(Date.today.year, Date.today.month, 1).next_month
|
6
|
+
|
7
|
+
transactions.each_with_object({}) do |(key, transaction), updated_transactions|
|
8
|
+
found = transaction_exists?(transaction_file, transaction['from'], Date.today, transaction['account'],
|
9
|
+
transaction['transaction'])
|
10
|
+
updated_transactions[key] = transaction.merge('from' => next_month, 'found' => found)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.latest_date(file)
|
15
|
+
command = %(hledger print --file #{file} | grep '^[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}' | awk '{print $1}' | sort -r | head -n 1)
|
16
|
+
|
17
|
+
date_output = `#{command}`
|
18
|
+
date_output.strip
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.transaction_exists?(file, from, to, account, transaction)
|
22
|
+
category = escape_str(transaction['category'])
|
23
|
+
amount = transaction['amount']
|
24
|
+
inverse_amount = transaction['inverse_amount']
|
25
|
+
|
26
|
+
# We run two commands and check to see if category +/- amount or account +/- amount exists
|
27
|
+
command1 = %(hledger print -f #{file} "date:#{from}..#{to}" | tr -s '[:space:]' ' ' | grep -q -Eo "#{category} (#{amount}|#{inverse_amount})")
|
28
|
+
command2 = %(hledger print -f #{file} "date:#{from}..#{to}" | tr -s '[:space:]' ' ' | grep -q -Eo "#{account} (#{amount}|#{inverse_amount})")
|
29
|
+
|
30
|
+
system(command1) || system(command2)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.escape_str(str)
|
34
|
+
str.gsub('[', '\\[').gsub(']', '\\]').gsub('(', '\\(').gsub(')', '\\)')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/hledger_forecast.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'colorize'
|
4
4
|
require 'date'
|
5
|
+
require 'dentaku'
|
5
6
|
require 'highline'
|
6
7
|
require 'money'
|
7
8
|
require 'optparse'
|
@@ -14,5 +15,5 @@ Money.rounding_mode = BigDecimal::ROUND_HALF_UP
|
|
14
15
|
require_relative 'hledger_forecast/version'
|
15
16
|
require_relative 'hledger_forecast/generator'
|
16
17
|
require_relative 'hledger_forecast/summarize'
|
17
|
-
|
18
|
+
require_relative 'hledger_forecast/tracker'
|
18
19
|
require_relative 'hledger_forecast/cli'
|
data/spec/command_spec.rb
CHANGED
@@ -1,15 +1,25 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
+
output = <<~JOURNAL
|
4
|
+
~ monthly from 2023-03-01 * Mortgage, Food
|
5
|
+
Expenses:Mortgage £2,000.55; Mortgage
|
6
|
+
Expenses:Food £100.00 ; Food
|
7
|
+
Assets:Bank
|
8
|
+
|
9
|
+
~ monthly from 2023-03-01 * Savings
|
10
|
+
Assets:Bank £-1,000.00; Savings
|
11
|
+
Assets:Savings
|
12
|
+
|
13
|
+
JOURNAL
|
14
|
+
|
3
15
|
RSpec.describe 'command' do
|
4
16
|
it 'uses the CLI to generate an output' do
|
5
17
|
# Delete the file if it exists
|
6
18
|
generated_journal = './test_output.journal'
|
7
19
|
File.delete(generated_journal) if File.exist?(generated_journal)
|
8
20
|
|
9
|
-
system("./bin/hledger-forecast generate -
|
10
|
-
|
11
|
-
expected_output = File.read('spec/stubs/monthly/output_monthly.journal')
|
21
|
+
system("./bin/hledger-forecast generate -f ./spec/stubs/forecast.yml -o ./test_output.journal --force")
|
12
22
|
|
13
|
-
expect(File.read(generated_journal)).to eq(
|
23
|
+
expect(File.read(generated_journal)).to eq(output)
|
14
24
|
end
|
15
25
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../lib/hledger_forecast'
|
2
|
+
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
monthly:
|
8
|
+
- account: "Liabilities:Amex"
|
9
|
+
from: "2023-05-01"
|
10
|
+
transactions:
|
11
|
+
- amount: "=5000/24"
|
12
|
+
category: "Expenses:House"
|
13
|
+
description: New Kitchen
|
14
|
+
- amount: "=25*4.3"
|
15
|
+
category: "Expenses:Food"
|
16
|
+
description: Monthly food shop
|
17
|
+
- amount: "=(102.50+3.25)/2"
|
18
|
+
category: "Expenses:Food"
|
19
|
+
description: Random food
|
20
|
+
YAML
|
21
|
+
|
22
|
+
output = <<~JOURNAL
|
23
|
+
~ monthly from 2023-05-01 * New Kitchen, Monthly food shop, Random food
|
24
|
+
Expenses:House £208.33 ; New Kitchen
|
25
|
+
Expenses:Food £107.50 ; Monthly food shop
|
26
|
+
Expenses:Food £52.88 ; Random food
|
27
|
+
Liabilities:Amex
|
28
|
+
|
29
|
+
JOURNAL
|
30
|
+
|
31
|
+
RSpec.describe 'generate' do
|
32
|
+
it 'generates a forecast with correct CALCULATED transactions' do
|
33
|
+
expect(HledgerForecast::Generator.generate(config)).to eq(output)
|
34
|
+
end
|
35
|
+
end
|
data/spec/custom_spec.rb
CHANGED
@@ -1,47 +1,40 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
3
|
+
config = <<~YAML
|
4
|
+
custom:
|
5
|
+
- frequency: "every 2 weeks"
|
6
|
+
from: "2023-05-01"
|
7
|
+
account: "[Assets:Bank]"
|
8
|
+
transactions:
|
9
|
+
- amount: 80
|
10
|
+
category: "[Expenses:Personal Care]"
|
11
|
+
description: Hair and beauty
|
12
|
+
- frequency: "every 5 days"
|
13
|
+
from: "2023-05-01"
|
14
|
+
account: "[Assets:Checking]"
|
15
|
+
transactions:
|
16
|
+
- amount: 50
|
17
|
+
category: "[Expenses:Groceries]"
|
18
|
+
description: Gotta feed that stomach
|
19
|
+
|
20
|
+
settings:
|
21
|
+
currency: GBP
|
22
|
+
YAML
|
23
|
+
|
24
|
+
output = <<~JOURNAL
|
25
|
+
~ every 2 weeks from 2023-05-01 * Hair and beauty
|
26
|
+
[Expenses:Personal Care] £80.00; Hair and beauty
|
27
|
+
[Assets:Bank]
|
28
|
+
|
29
|
+
~ every 5 days from 2023-05-01 * Gotta feed that stomach
|
30
|
+
[Expenses:Groceries] £50.00; Gotta feed that stomach
|
31
|
+
[Assets:Checking]
|
32
|
+
|
33
|
+
JOURNAL
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01',
|
31
|
-
'2023-03-30')
|
32
|
-
|
33
|
-
expected_output = File.read('spec/stubs/custom/output_custom_weeks_twice.journal')
|
34
|
-
expect(generated_journal).to eq(expected_output)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'generates a forecast with correct CUSTOM MONTHLY transactions' do
|
38
|
-
transactions = File.read('spec/stubs/transactions.journal')
|
39
|
-
forecast = File.read('spec/stubs/custom/forecast_custom_months.yml')
|
40
|
-
|
41
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01',
|
42
|
-
'2024-02-28')
|
43
|
-
|
44
|
-
expected_output = File.read('spec/stubs/custom/output_custom_months.journal')
|
45
|
-
expect(generated_journal).to eq(expected_output)
|
35
|
+
RSpec.describe 'generate' do
|
36
|
+
it 'generates a forecast with correct CUSTOM transactions' do
|
37
|
+
generated_journal = HledgerForecast::Generator.generate(config)
|
38
|
+
expect(generated_journal).to eq(output)
|
46
39
|
end
|
47
40
|
end
|
data/spec/half-yearly_spec.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
half-yearly:
|
8
|
+
- from: "2023-04-01"
|
9
|
+
account: "Assets:Bank"
|
10
|
+
transactions:
|
11
|
+
- description: Holiday
|
12
|
+
category: "Expenses:Holiday"
|
13
|
+
amount: 500
|
14
|
+
YAML
|
15
|
+
|
16
|
+
output = <<~JOURNAL
|
17
|
+
~ every 6 months from 2023-04-01 * Holiday
|
18
|
+
Expenses:Holiday £500.00; Holiday
|
19
|
+
Assets:Bank
|
20
|
+
|
21
|
+
JOURNAL
|
22
|
+
|
3
23
|
RSpec.describe 'generate' do
|
4
24
|
it 'generates a forecast with correct HALF-YEARLY transactions' do
|
5
|
-
|
6
|
-
forecast = File.read('spec/stubs/half-yearly/forecast_half-yearly.yml')
|
7
|
-
|
8
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01', '2024-04-30')
|
25
|
+
generated_journal = HledgerForecast::Generator.generate(config)
|
9
26
|
|
10
|
-
|
11
|
-
expect(generated_journal).to eq(expected_output)
|
27
|
+
expect(generated_journal).to eq(output)
|
12
28
|
end
|
13
29
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative '../lib/hledger_forecast'
|
2
|
+
|
3
|
+
base_config = <<~YAML
|
4
|
+
monthly:
|
5
|
+
- account: "Assets:Bank"
|
6
|
+
from: "2023-01-01"
|
7
|
+
transactions:
|
8
|
+
- amount: 500
|
9
|
+
category: "Expenses:Groceries"
|
10
|
+
description: Food shopping
|
11
|
+
modifiers:
|
12
|
+
- amount: 0.02
|
13
|
+
description: "Y1 inflation"
|
14
|
+
from: "2024-01-01"
|
15
|
+
to: "2024-12-31"
|
16
|
+
- amount: 0.05
|
17
|
+
description: "Y2 inflation"
|
18
|
+
from: "2025-01-01"
|
19
|
+
to: "2025-12-31"
|
20
|
+
|
21
|
+
settings:
|
22
|
+
currency: USD
|
23
|
+
YAML
|
24
|
+
|
25
|
+
base_journal = <<~JOURNAL
|
26
|
+
~ monthly from 2023-01-01 * Food shopping
|
27
|
+
Expenses:Groceries $500.00; Food shopping
|
28
|
+
Assets:Bank
|
29
|
+
|
30
|
+
= Expenses:Groceries date:2024-01-01..2024-12-31
|
31
|
+
Expenses:Groceries *0.02 ; Food shopping - Y1 inflation
|
32
|
+
Assets:Bank *-0.02
|
33
|
+
|
34
|
+
= Expenses:Groceries date:2025-01-01..2025-12-31
|
35
|
+
Expenses:Groceries *0.05 ; Food shopping - Y2 inflation
|
36
|
+
Assets:Bank *-0.05
|
37
|
+
|
38
|
+
JOURNAL
|
39
|
+
|
40
|
+
no_date_config = <<~YAML
|
41
|
+
monthly:
|
42
|
+
- account: "Assets:Bank"
|
43
|
+
from: "2023-01-01"
|
44
|
+
transactions:
|
45
|
+
- amount: 500
|
46
|
+
category: "Expenses:Groceries"
|
47
|
+
description: Food shopping
|
48
|
+
modifiers:
|
49
|
+
- amount: 0.1
|
50
|
+
description: "Inflation"
|
51
|
+
|
52
|
+
settings:
|
53
|
+
currency: USD
|
54
|
+
YAML
|
55
|
+
|
56
|
+
no_date_journal = <<~JOURNAL
|
57
|
+
~ monthly from 2023-01-01 * Food shopping
|
58
|
+
Expenses:Groceries $500.00; Food shopping
|
59
|
+
Assets:Bank
|
60
|
+
|
61
|
+
= Expenses:Groceries date:2023-01-01
|
62
|
+
Expenses:Groceries *0.1 ; Food shopping - Inflation
|
63
|
+
Assets:Bank *-0.1
|
64
|
+
|
65
|
+
JOURNAL
|
66
|
+
|
67
|
+
RSpec.describe 'Applying modifiers to transactions -' do
|
68
|
+
it 'Auto-postings should be created correctly' do
|
69
|
+
generated = HledgerForecast::Generator
|
70
|
+
generated.modified = {} # Clear modified transactions
|
71
|
+
|
72
|
+
generated_journal = generated.generate(base_config)
|
73
|
+
generated.modified = {} # Clear modified transactions
|
74
|
+
|
75
|
+
expect(generated_journal).to eq(base_journal)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Auto-postings should be created correctly if no dates are set' do
|
79
|
+
generated = HledgerForecast::Generator
|
80
|
+
generated.modified = {} # Clear modified transactions
|
81
|
+
|
82
|
+
generated_journal = generated.generate(no_date_config)
|
83
|
+
generated.modified = {} # Clear modified transactions
|
84
|
+
|
85
|
+
expect(generated_journal).to eq(no_date_journal)
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../lib/hledger_forecast'
|
2
|
+
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
monthly:
|
8
|
+
- from: "2023-03-01"
|
9
|
+
account: "Assets:Bank"
|
10
|
+
transactions:
|
11
|
+
- description: Mortgage
|
12
|
+
to: "2023-06-01"
|
13
|
+
category: "Expenses:Mortgage"
|
14
|
+
amount: 2000.00
|
15
|
+
- description: Mortgage top up
|
16
|
+
to: "2023-06-01"
|
17
|
+
category: "Expenses:Mortgage Top Up"
|
18
|
+
amount: 200.00
|
19
|
+
- description: Food
|
20
|
+
category: "Expenses:Food"
|
21
|
+
amount: 100.00
|
22
|
+
- description: Party time
|
23
|
+
category: "Expenses:Going Out"
|
24
|
+
amount: 50.00
|
25
|
+
YAML
|
26
|
+
|
27
|
+
output = <<~JOURNAL
|
28
|
+
~ monthly from 2023-03-01 * Food, Party time
|
29
|
+
Expenses:Food £100.00 ; Food
|
30
|
+
Expenses:Going Out £50.00 ; Party time
|
31
|
+
Assets:Bank
|
32
|
+
|
33
|
+
~ monthly from 2023-03-01 to 2023-06-01 * Mortgage
|
34
|
+
Expenses:Mortgage £2,000.00; Mortgage
|
35
|
+
Assets:Bank
|
36
|
+
|
37
|
+
~ monthly from 2023-03-01 to 2023-06-01 * Mortgage top up
|
38
|
+
Expenses:Mortgage Top Up £200.00 ; Mortgage top up
|
39
|
+
Assets:Bank
|
40
|
+
|
41
|
+
JOURNAL
|
42
|
+
|
43
|
+
RSpec.describe 'generate' do
|
44
|
+
it 'generates a forecast with correct MONTHLY transactions that have an end date' do
|
45
|
+
expect(HledgerForecast::Generator.generate(config)).to eq(output)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../lib/hledger_forecast'
|
2
|
+
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
monthly:
|
8
|
+
- from: "2023-03-01"
|
9
|
+
to: "2023-06-01"
|
10
|
+
account: "Assets:Bank"
|
11
|
+
transactions:
|
12
|
+
- description: Mortgage
|
13
|
+
category: "Expenses:Mortgage"
|
14
|
+
amount: 2000.00
|
15
|
+
- description: Food
|
16
|
+
category: "Expenses:Food"
|
17
|
+
amount: 100.00
|
18
|
+
YAML
|
19
|
+
|
20
|
+
output = <<~JOURNAL
|
21
|
+
~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Food
|
22
|
+
Expenses:Mortgage £2,000.00; Mortgage
|
23
|
+
Expenses:Food £100.00 ; Food
|
24
|
+
Assets:Bank
|
25
|
+
|
26
|
+
JOURNAL
|
27
|
+
|
28
|
+
RSpec.describe 'generate' do
|
29
|
+
it 'generates a forecast with correct MONTHLY transactions that have an end date, at the top level' do
|
30
|
+
expect(HledgerForecast::Generator.generate(config)).to eq(output)
|
31
|
+
end
|
32
|
+
end
|
data/spec/monthly_spec.rb
CHANGED
@@ -1,33 +1,41 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
+
config = <<~YAML
|
4
|
+
monthly:
|
5
|
+
- account: "Assets:Bank"
|
6
|
+
from: "2023-03-01"
|
7
|
+
transactions:
|
8
|
+
- amount: 2000.55
|
9
|
+
category: "Expenses:Mortgage"
|
10
|
+
description: Mortgage
|
11
|
+
- amount: 100
|
12
|
+
category: "Expenses:Food"
|
13
|
+
description: Food
|
14
|
+
- account: "Assets:Savings"
|
15
|
+
from: "2023-03-01"
|
16
|
+
transactions:
|
17
|
+
- amount: -1000
|
18
|
+
category: "Assets:Bank"
|
19
|
+
description: Savings
|
20
|
+
|
21
|
+
settings:
|
22
|
+
currency: GBP
|
23
|
+
YAML
|
24
|
+
|
25
|
+
output = <<~JOURNAL
|
26
|
+
~ monthly from 2023-03-01 * Mortgage, Food
|
27
|
+
Expenses:Mortgage £2,000.55; Mortgage
|
28
|
+
Expenses:Food £100.00 ; Food
|
29
|
+
Assets:Bank
|
30
|
+
|
31
|
+
~ monthly from 2023-03-01 * Savings
|
32
|
+
Assets:Bank £-1,000.00; Savings
|
33
|
+
Assets:Savings
|
34
|
+
|
35
|
+
JOURNAL
|
36
|
+
|
3
37
|
RSpec.describe 'generate' do
|
4
38
|
it 'generates a forecast with correct MONTHLY transactions' do
|
5
|
-
|
6
|
-
forecast = File.read('spec/stubs/monthly/forecast_monthly.yml')
|
7
|
-
|
8
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01', '2023-05-30')
|
9
|
-
|
10
|
-
expected_output = File.read('spec/stubs/monthly/output_monthly.journal')
|
11
|
-
expect(generated_journal).to eq(expected_output)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'generates a forecast with correct MONTHLY transactions that have an end date' do
|
15
|
-
transactions = File.read('spec/stubs/transactions.journal')
|
16
|
-
forecast = File.read('spec/stubs/monthly/forecast_monthly_enddate.yml')
|
17
|
-
|
18
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01', '2023-08-30')
|
19
|
-
|
20
|
-
expected_output = File.read('spec/stubs/monthly/output_monthly_enddate.journal')
|
21
|
-
expect(generated_journal).to eq(expected_output)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'generates a forecast with correct MONTHLY transactions that have an end date, at the top level' do
|
25
|
-
transactions = File.read('spec/stubs/transactions.journal')
|
26
|
-
forecast = File.read('spec/stubs/monthly/forecast_monthly_enddate_top.yml')
|
27
|
-
|
28
|
-
generated_journal = HledgerForecast::Generator.generate(transactions, forecast, '2023-03-01', '2023-08-30')
|
29
|
-
|
30
|
-
expected_output = File.read('spec/stubs/monthly/output_monthly_enddate_top.journal')
|
31
|
-
expect(generated_journal).to eq(expected_output)
|
39
|
+
expect(HledgerForecast::Generator.generate(config)).to eq(output)
|
32
40
|
end
|
33
41
|
end
|
data/spec/once_spec.rb
CHANGED
@@ -1,13 +1,28 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
once:
|
8
|
+
- from: "2023-07-01"
|
9
|
+
account: "Assets:Bank"
|
10
|
+
transactions:
|
11
|
+
- description: New Kitchen
|
12
|
+
category: "Expense:House"
|
13
|
+
amount: 5,000.00
|
14
|
+
YAML
|
7
15
|
|
8
|
-
|
16
|
+
output = <<~JOURNAL
|
17
|
+
~ 2023-07-01 * New Kitchen
|
18
|
+
Expense:House £5,000.00; New Kitchen
|
19
|
+
Assets:Bank
|
9
20
|
|
10
|
-
|
11
|
-
|
21
|
+
JOURNAL
|
22
|
+
|
23
|
+
RSpec.describe 'generate' do
|
24
|
+
it 'generates a forecast with correct ONCE transactions' do
|
25
|
+
generated_journal = HledgerForecast::Generator.generate(config)
|
26
|
+
expect(generated_journal).to eq(output)
|
12
27
|
end
|
13
28
|
end
|
data/spec/quarterly_spec.rb
CHANGED
@@ -1,13 +1,27 @@
|
|
1
1
|
require_relative '../lib/hledger_forecast'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
config = <<~YAML
|
4
|
+
settings:
|
5
|
+
currency: GBP
|
6
|
+
|
7
|
+
quarterly:
|
8
|
+
- from: "2023-04-01"
|
9
|
+
account: "Assets:Bank"
|
10
|
+
transactions:
|
11
|
+
- description: Bonus
|
12
|
+
category: "Income:Bonus"
|
13
|
+
amount: -1,000.00
|
14
|
+
YAML
|
7
15
|
|
8
|
-
|
16
|
+
output = <<~JOURNAL
|
17
|
+
~ every 3 months from 2023-04-01 * Bonus
|
18
|
+
Income:Bonus £-1,000.00; Bonus
|
19
|
+
Assets:Bank
|
9
20
|
|
10
|
-
|
11
|
-
|
21
|
+
JOURNAL
|
22
|
+
|
23
|
+
RSpec.describe 'generate' do
|
24
|
+
it 'generates a forecast with correct QUARTERLY transactions' do
|
25
|
+
expect(HledgerForecast::Generator.generate(config)).to eq(output)
|
12
26
|
end
|
13
27
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
monthly:
|
2
|
-
- account: "
|
3
|
-
|
2
|
+
- account: "Assets:Bank"
|
3
|
+
from: "2023-03-01"
|
4
4
|
transactions:
|
5
5
|
- amount: 2000.55
|
6
|
-
category: "
|
6
|
+
category: "Expenses:Mortgage"
|
7
7
|
description: Mortgage
|
8
8
|
- amount: 100
|
9
|
-
category: "
|
9
|
+
category: "Expenses:Food"
|
10
10
|
description: Food
|
11
|
-
- account: "
|
12
|
-
|
11
|
+
- account: "Assets:Savings"
|
12
|
+
from: "2023-03-01"
|
13
13
|
transactions:
|
14
14
|
- amount: -1000
|
15
|
-
category: "
|
15
|
+
category: "Assets:Bank"
|
16
16
|
description: Savings
|
17
17
|
|
18
18
|
settings:
|
@@ -0,0 +1,24 @@
|
|
1
|
+
2023-04-01 * Opening balance
|
2
|
+
Assets:Bank £1,000.00
|
3
|
+
Equity:Opening balance
|
4
|
+
|
5
|
+
2023-04-01 * Mortgage payment
|
6
|
+
Expenses:Mortgage £1,500.00
|
7
|
+
Assets:Bank
|
8
|
+
|
9
|
+
2023-05-01 * Mortgage payment
|
10
|
+
Expenses:Mortgage £1,500.00
|
11
|
+
Assets:Bank
|
12
|
+
|
13
|
+
2023-06-01 * Mortgage payment
|
14
|
+
Expenses:Mortgage £1,500.00
|
15
|
+
Assets:Bank
|
16
|
+
|
17
|
+
2023-03-05 * Tax owed
|
18
|
+
Expenses:Tax £3,000.00
|
19
|
+
Assets:Bank
|
20
|
+
|
21
|
+
2023-03-05 * Salary
|
22
|
+
Income:Salary -£1,500.00
|
23
|
+
Assets:Bank
|
24
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
2023-04-01 * Opening balance
|
2
|
+
Assets:Bank
|
3
|
+
Equity:Opening balance £-1,000.00
|
4
|
+
|
5
|
+
2023-04-01 * Mortgage payment
|
6
|
+
Expenses:Mortgage
|
7
|
+
Assets:Bank £-1,500.00
|
8
|
+
|
9
|
+
2023-05-01 * Mortgage payment
|
10
|
+
Expenses:Mortgage
|
11
|
+
Assets:Bank £-1,500.00
|
12
|
+
|
13
|
+
2023-06-01 * Mortgage payment
|
14
|
+
Expenses:Mortgage
|
15
|
+
Assets:Bank £-1,500.00
|
16
|
+
|
17
|
+
2023-03-05 * Tax owed
|
18
|
+
Expenses:Tax
|
19
|
+
Assets:Bank £-3,000.00
|
20
|
+
|
21
|
+
2023-03-05 * Salary
|
22
|
+
Income:Salary
|
23
|
+
Assets:Bank £1,500.00
|
24
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
2023-04-01 * Opening balance
|
2
|
+
Assets:Bank £1,000.00
|
3
|
+
Equity:Opening balance
|
4
|
+
|
5
|
+
2023-04-01 * Mortgage payment
|
6
|
+
Expenses:Mortgage £1,500.00
|
7
|
+
Assets:Bank
|
8
|
+
|
9
|
+
2023-05-01 * Mortgage payment
|
10
|
+
Expenses:Mortgage £1,500.00
|
11
|
+
Assets:Bank
|
12
|
+
|
13
|
+
2023-06-01 * Mortgage payment
|
14
|
+
Expenses:Mortgage £1,500.00
|
15
|
+
Assets:Bank
|
16
|
+
|