quickpep 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 781926a87ca1e7da51eb37ae4c04241ed58161298e5e30274fdd17b815bfb0b1
4
- data.tar.gz: 1313a750409901529c92fe6d777236fa0eec34ea623cefe2deec5fb7991d2f9f
3
+ metadata.gz: eee7a9fb38833422910265d318aa4637b98e426fdc39b0a50d4d8da5f987021f
4
+ data.tar.gz: 0ed982bf1fcc5c01ab58616b20695716c365739d964f878b47c565bfac4bc92d
5
5
  SHA512:
6
- metadata.gz: ebc1a5b5a6e5accc3ea775a40cada9983d764a5082248acbb9876651f1ad96d43d2ef15e5e91137abc3ac949b8343a10b2b67e30394f80dfbc6f49c38e28d23a
7
- data.tar.gz: b508903ad51617cbaf18d5579172c54966df2d85721e74cb743af55201f48a0a0cbd960781682868d730c86e7e9b26a108d72bcb5b686bf7dd3c080cf322007b
6
+ metadata.gz: 754edefa43a185656451fcd3ddb948cd3cffebb8da581d379c4d752294634141271369dadb2929deff799f5d2b7bdbf16acc46c59cdb79038c2e36629cbaec93
7
+ data.tar.gz: 18a9cc3eb80d9942c887f346699f993d237ddcd456a41db28107279ab2e1914b1d0530c09b4328e29709edad380f48c0489a9edd0d33bd8cacbc8c8baeb9baf5
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/quickpep.rb CHANGED
@@ -11,16 +11,17 @@ require 'event_nlp'
11
11
  class QuickPep
12
12
  using ColouredText
13
13
 
14
- attr_reader :to_s, :to_dx
14
+ attr_reader :to_s, :to_dx, :input
15
15
 
16
- def initialize(s, balance: 0, currency: '', today: Date.today, debug: false)
16
+ def initialize(s, balance: 0, currency: '', today: Date.today,
17
+ ignorewarnings: false, debug: false)
17
18
 
18
19
  @balance, @currency, @debug = balance, currency, debug
19
20
  @today = today
20
21
  @warnings = []
21
22
  @to_s = calc_expenses(s)
22
23
 
23
- warnings() if @warnings.any?
24
+ warnings() if @warnings.any? and not ignorewarnings
24
25
 
25
26
  end
26
27
 
@@ -60,12 +61,51 @@ class QuickPep
60
61
 
61
62
  end
62
63
 
63
- def to_html(title: "Personal Budget #{@today.year}")
64
+ # Each expense annually as a percentage of total expenses
65
+ #
66
+ def breakdown()
67
+
68
+ tot = total_expenses().abs
69
+ r = annual_costs()
70
+ a = r.map {|title, cost| [title, (100 / (tot / cost.abs)).round] }
71
+
72
+ def a.to_table()
73
+ TableFormatter.new(source: self,
74
+ labels: %w(Item %:), markdown: true).display
75
+ end
76
+
77
+ return a
78
+ end
79
+
80
+ def costs_summary()
81
+
82
+ a = %i(year month day).map {|x| annual_costs x}.transpose\
83
+ .map do |x|
84
+ [x.first.first, *x.map {|y| "%s%0.2f" % [@currency, y.last.abs]}]
85
+ end
86
+ TableFormatter.new(source: a, labels: %w(Title Year: Month: Day:),
87
+ markdown: true).display
88
+ end
64
89
 
65
- t = to_dx().to_table
66
- t.labels = %w(date title debit: credit: balance: uid:)
90
+ def to_html(titlex="Personal Budget #{@today.year}", title: titlex)
91
+
92
+ dx = to_dx()
93
+ t = dx.to_table
94
+ t.labels = %w(date: title debit: credit: balance: uid:)
67
95
  table = t.display markdown: true
68
96
 
97
+ tot = year_end_balance().abs
98
+ costs_per_interval = "
99
+ * daily: #{"%s%0.2f" % [@currency, (tot / 365.0)]}
100
+ * weekly: #{"%s%0.2f" % [@currency, (tot / 52.0)]}
101
+ * monthly: #{"%s%0.2f" % [@currency, (tot / 12.0)]}
102
+ * yearly: #{@currency + tot.to_s}
103
+ "
104
+
105
+ t2 = @input.to_table
106
+ t2.labels = %w(Title Amount: :Day: :Recurring: :Notes:)
107
+ table2 = t2.display markdown: true
108
+
69
109
  "<html>
70
110
  <head>
71
111
  <meta name='viewport' content='width=device-width, initial-scale=1'>
@@ -82,32 +122,84 @@ class QuickPep
82
122
  }
83
123
 
84
124
  }
125
+ table tr td, table thead th {padding: 0.3em; margin: 0.1em}
126
+ #input table {border: 4px; background-color: #d3a;}
127
+ #input table thead {color: #131;}
128
+ #input table tr, #input table td {border: 1px solid green; padding: 3px; background-color: #dea;}
129
+ #input table tr td {
130
+ text-align: center;
131
+ }
132
+ #summary div {background-color: transparent; float: left; margin: 0.3em; padding: 1.2em; border: 1px solid #18e}
133
+
134
+ #breakdown table {background-color: transparent; width: 190px}
135
+ #breakdown table tr {background-color: transparent;}
136
+ #costsum table {background-color: transparent; width: 400px}
137
+ #costsum table tr {background-color: transparent; border-bottom: 1px solid #888;}
138
+ #costsum table tr td {background-color: transparent; padding: 1.0em 0.5em; margin: 0.4em 0.2em}
139
+ #summary div ul {list-style-type: none; background-color: transparent; padding: 0.5em; }
140
+ .break {page-break-before: always}
141
+ #input {clear: both;}
142
+ footer {font-size: 0.8em; color: #888;}
85
143
  </style>
144
+
86
145
  </head>
87
146
  <body>
88
147
  <h1>#{title}</h1>
89
148
  #{RDiscount.new(table).to_html}
149
+ <div id='summary'>
150
+ <h2>Summary</h2>
151
+
152
+ <div id='breakdown'>
153
+ <h3>Breakdown</h3>
154
+ #{RDiscount.new(breakdown().to_table()).to_html}
155
+ </div>
156
+
157
+ <div id='costsum'>
158
+ <h3>Expense per item</h3>
159
+ #{RDiscount.new(costs_summary()).to_html}
160
+ </div>
161
+ <div>
162
+ <h3>Running expense</h3>
163
+
164
+ #{RDiscount.new(costs_per_interval).to_html}
165
+ </div>
166
+ </div>
167
+ <div id='input'>
168
+ <h3>Input</h3>
169
+
170
+ #{RDiscount.new(table2).to_html}
171
+ </div>
90
172
  <hr/>
91
- <footer>Generated by QuickPEP</footer>
173
+ <footer>Generated by QuickPEP; #{Time.now.strftime("%d %b %Y")}</footer>
92
174
  </body>
93
175
  </html>"
94
176
  end
95
177
 
178
+ def total_expenses()
179
+ to_dx().all.map {|x| x.debit.sub(/\D/,'').to_f}.sum
180
+ end
181
+
96
182
  def warnings()
97
183
  @warnings.each {|warning| puts warning.warn }
98
184
  end
99
185
 
186
+ def year_end_balance()
187
+ to_dx().all.last.balance.sub(/[^-0-9]+/,'').to_f
188
+ end
189
+
100
190
  private
101
191
 
102
192
  def calc_expenses(s)
103
193
 
104
- dx = Dynarex.new(s)
194
+ @input = dx = Dynarex.new(s)
105
195
 
106
196
  @h = dx.all.map {|x| [x.title, x]}.to_h
197
+ puts '@h: ' + @h.inspect if @debug
107
198
 
108
199
  date_events = dx.all.flat_map do |rx|
109
200
 
110
- title = [rx.title, rx.day, rx.recurring].join(' ')
201
+ recurring = rx.recurring.gsub(/(?:yearly|annually)/,'')
202
+ title = [rx.title, rx.day, recurring].join(' ')
111
203
  puts '1. title: ' + title.inspect if @debug
112
204
  e = EventNlp.new(@today.to_time)
113
205
  e.project(title).map {|x| [x.to_date, e.parse(title).title]}
@@ -133,7 +225,8 @@ class QuickPep
133
225
  end
134
226
 
135
227
  credit, debit = 0.0, 0.0
136
- amount = @h[title].amount
228
+ puts 'title: ' + title.inspect if @debug
229
+ amount = @h[title] ? @h[title].amount : ''
137
230
 
138
231
  if amount[0] == '+' then
139
232
 
@@ -180,7 +273,7 @@ class QuickPep
180
273
  puts [title, debit, credit, balance].inspect if @debug
181
274
 
182
275
  row = {
183
- date: date.to_s,
276
+ date: date.strftime("%b %d"),
184
277
  title: title,
185
278
  debit: debit > 0 ? (@currency + "%.2f" % debit) : '',
186
279
  credit: credit > 0 ? (@currency + "%.2f" % credit) : '',
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickpep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,7 +35,7 @@ cert_chain:
35
35
  kmcJnzHNiVwSBry7rnILYU3ouLJeHEtQY1v/S4KqPXGNS1FPvas3Wb429Cui2LtB
36
36
  CkYfvLZCZS1SZGB2dGilreNS
37
37
  -----END CERTIFICATE-----
38
- date: 2022-05-03 00:00:00.000000000 Z
38
+ date: 2022-05-04 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: event_nlp
@@ -46,7 +46,7 @@ dependencies:
46
46
  version: '0.6'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.6.6
49
+ version: 0.6.8
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,7 +56,7 @@ dependencies:
56
56
  version: '0.6'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.6.6
59
+ version: 0.6.8
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: dynarex
62
62
  requirement: !ruby/object:Gem::Requirement
metadata.gz.sig CHANGED
Binary file