hledger-forecast 0.4.0 → 1.0.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.
@@ -1,32 +1,69 @@
1
1
  require_relative '../lib/hledger_forecast'
2
2
 
3
- config = <<~YAML
3
+ base_config = <<~YAML
4
4
  settings:
5
5
  currency: GBP
6
6
 
7
7
  monthly:
8
8
  - from: "2023-03-01"
9
- to: "2023-06-01"
10
9
  account: "Assets:Bank"
11
10
  transactions:
12
11
  - description: Mortgage
12
+ to: "2023-06-01"
13
13
  category: "Expenses:Mortgage"
14
14
  amount: 2000.00
15
+ - description: Mortgage top up
16
+ to: "2023-06-01"
17
+ category: "Expenses:Mortgage Top Up"
18
+ amount: 200.00
15
19
  - description: Food
16
20
  category: "Expenses:Food"
17
21
  amount: 100.00
22
+ - description: Party time
23
+ category: "Expenses:Going Out"
24
+ amount: 50.00
18
25
  YAML
19
26
 
20
- output = <<~JOURNAL
21
- ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Food
27
+ base_output = <<~JOURNAL
28
+ ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Mortgage top up
29
+ Expenses:Mortgage £2,000.00; Mortgage
30
+ Expenses:Mortgage Top Up £200.00 ; Mortgage top up
31
+ Assets:Bank
32
+
33
+ ~ monthly from 2023-03-01 * Food, Party time
34
+ Expenses:Food £100.00 ; Food
35
+ Expenses:Going Out £50.00 ; Party time
36
+ Assets:Bank
37
+
38
+ JOURNAL
39
+
40
+ computed_config = <<~YAML
41
+ settings:
42
+ currency: GBP
43
+
44
+ monthly:
45
+ - from: "2023-03-01"
46
+ account: "Assets:Bank"
47
+ transactions:
48
+ - description: Mortgage
49
+ category: "Expenses:Mortgage"
50
+ to: "=12"
51
+ amount: 2000.00
52
+ YAML
53
+
54
+ computed_output = <<~JOURNAL
55
+ ~ monthly from 2023-03-01 to 2024-02-29 * Mortgage
22
56
  Expenses:Mortgage £2,000.00; Mortgage
23
- Expenses:Food £100.00 ; Food
24
57
  Assets:Bank
25
58
 
26
59
  JOURNAL
27
60
 
28
61
  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)
62
+ it 'generates a forecast with correct MONTHLY transactions that have an end date' do
63
+ expect(HledgerForecast::Generator.generate(base_config)).to eq(base_output)
64
+ end
65
+
66
+ it 'generates a forecast with correct MONTHLY transactions that have a COMPUTED end date' do
67
+ expect(HledgerForecast::Generator.generate(computed_config)).to eq(computed_output)
31
68
  end
32
69
  end
data/spec/track_spec.rb CHANGED
@@ -42,70 +42,13 @@ base_output = <<~JOURNAL
42
42
  JOURNAL
43
43
 
44
44
  RSpec.describe 'Tracking transactions -' do
45
- it 'Determines which transactions should be tracked' do
46
- generated = HledgerForecast::Generator
47
- generated.generate(base_config)
48
- tracked = generated.tracked
49
-
50
- expect(tracked[0]['transaction']).to eq(
51
- { "amount" => "£3,000.00", "category" => "Expenses:Tax", "description" => "Tax owed",
52
- "inverse_amount" => "£-3,000.00", "track" => true }
53
- )
54
- expect(tracked[0]['account']).to eq("Assets:Bank")
55
-
56
- expect(tracked[1]['transaction']).to eq(
57
- { "amount" => "£-1,500.00", "category" => "Income:Salary", "description" => "Salary", "to" => "2023-08-01",
58
- "inverse_amount" => "£1,500.00", "track" => true }
59
- )
60
- expect(tracked[1]['account']).to eq("Assets:Bank")
61
- end
62
-
63
- it 'marks a transaction as NOT FOUND if it doesnt exist' do
64
- generated = HledgerForecast::Generator
65
- generated.tracked = {} # Clear tracked transactions
66
- generated.generate(base_config)
67
- transactions_to_track = generated.tracked
68
-
69
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_not_found.journal')
70
-
71
- expect(track[0]['found']).to eq(false)
72
- expect(track[1]['found']).to eq(false)
73
- end
74
-
75
- it 'marks a transaction as FOUND if it exists' do
76
- generated = HledgerForecast::Generator
77
- generated.tracked = {} # Clear tracked transactions
78
- generated.generate(base_config)
79
- transactions_to_track = generated.tracked
80
-
81
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_found.journal')
82
-
83
- expect(track[0]['found']).to eq(true)
84
- expect(track[1]['found']).to eq(true)
85
- end
86
-
87
- it 'marks a transaction as FOUND if it exists, even if the category/amount are inversed' do
88
- generated = HledgerForecast::Generator
89
- generated.tracked = {} # Clear tracked transactions
90
- generated.generate(base_config)
91
- transactions_to_track = generated.tracked
92
-
93
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_found_inverse.journal')
94
-
95
- expect(track[0]['found']).to eq(true)
96
- end
97
-
98
45
  it 'writes a NON-FOUND entry into a journal' do
99
46
  options = {}
100
47
  options[:transaction_file] = 'spec/stubs/transactions_not_found.journal'
101
48
 
102
- generated = HledgerForecast::Generator
103
- generated.tracked = {} # Clear tracked transactions
104
-
105
- generated_journal = generated.generate(base_config, options)
49
+ generated_journal = HledgerForecast::Generator.generate(base_config, options)
106
50
 
107
- expected_output = base_output
108
- expect(generated_journal).to eq(expected_output)
51
+ expect(generated_journal).to eq(base_output)
109
52
  end
110
53
 
111
54
  it 'writes a NON-FOUND entry for dates that are close to the current period' do
@@ -147,12 +90,10 @@ RSpec.describe 'Tracking transactions -' do
147
90
  options = {}
148
91
  options[:transaction_file] = temp_file.path
149
92
 
150
- generated = HledgerForecast::Generator
151
- generated.tracked = {} # Clear tracked transactions
152
-
153
- generated_journal = generated.generate(forecast_config, options)
93
+ generated_journal = HledgerForecast::Generator.generate(forecast_config, options)
154
94
 
155
95
  expected_output = <<~JOURNAL
96
+
156
97
  ~ #{next_month} * [TRACKED] New kitchen
157
98
  Expenses:House £5,000.00; New kitchen
158
99
  Assets:Bank
@@ -180,10 +121,7 @@ RSpec.describe 'Tracking transactions -' do
180
121
  options = {}
181
122
  options[:transaction_file] = 'spec/stubs/transactions_not_found.journal'
182
123
 
183
- generated = HledgerForecast::Generator
184
- generated.tracked = {} # Clear tracked transactions
185
-
186
- generated_journal = generated.generate(forecast_config, options)
124
+ generated_journal = HledgerForecast::Generator.generate(forecast_config, options)
187
125
 
188
126
  output = <<~JOURNAL
189
127
  ~ monthly from #{next_month} * Food expenses
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hledger-forecast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oli Morris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-09 00:00:00.000000000 Z
11
+ date: 2023-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -113,10 +113,15 @@ files:
113
113
  - example.yml
114
114
  - hledger-forecast.gemspec
115
115
  - lib/hledger_forecast.rb
116
+ - lib/hledger_forecast/calculator.rb
116
117
  - lib/hledger_forecast/cli.rb
118
+ - lib/hledger_forecast/formatter.rb
117
119
  - lib/hledger_forecast/generator.rb
118
- - lib/hledger_forecast/summarize.rb
119
- - lib/hledger_forecast/tracker.rb
120
+ - lib/hledger_forecast/settings.rb
121
+ - lib/hledger_forecast/summarizer.rb
122
+ - lib/hledger_forecast/transactions/default.rb
123
+ - lib/hledger_forecast/transactions/modifiers.rb
124
+ - lib/hledger_forecast/transactions/trackers.rb
120
125
  - lib/hledger_forecast/version.rb
121
126
  - spec/command_spec.rb
122
127
  - spec/computed_amounts_spec.rb
@@ -144,16 +149,16 @@ require_paths:
144
149
  - lib
145
150
  required_ruby_version: !ruby/object:Gem::Requirement
146
151
  requirements:
147
- - - ">="
152
+ - - "~>"
148
153
  - !ruby/object:Gem::Version
149
- version: '0'
154
+ version: '3.0'
150
155
  required_rubygems_version: !ruby/object:Gem::Requirement
151
156
  requirements:
152
157
  - - ">="
153
158
  - !ruby/object:Gem::Version
154
159
  version: '0'
155
160
  requirements: []
156
- rubygems_version: 3.4.12
161
+ rubygems_version: 3.2.3
157
162
  signing_key:
158
163
  specification_version: 4
159
164
  summary: An extended wrapper around hledger's forecasting functionality
@@ -1,37 +0,0 @@
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