pacing 2.0.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -0
- data/lib/pacing/error.rb +1 -2
- data/lib/pacing/normalizer.rb +9 -7
- data/lib/pacing/pacer.rb +13 -3
- data/lib/pacing/version.rb +1 -1
- data/spec/pacing_spec.rb +77 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11132b13902786c1b44efc9c3dc217f0e56675de6e9c90ee7f9e86ed8b8c297d
|
4
|
+
data.tar.gz: 5ecf36d92525e32a963cc1ec0739535c23085679fb40edb64ed4e354f2661dd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8ba5d05efddeb02e010e036073b12faf2a9bc5ecf0ee9eabcae2004aa132388babdd07f7d11a290c84f8a389ddbe1ff9a7b809d3e70dc100937963557c7f877
|
7
|
+
data.tar.gz: b37f58965f1f2aac5f78c56b5e1b8144dc9f993387103bd28a51fc6f241d81ebd7bd4edef7cd002e9df0f29075db8a22a1a17218f7fb3e260ad7138e1bf755eb
|
data/README.md
CHANGED
@@ -117,6 +117,39 @@ paced.calculate
|
|
117
117
|
]
|
118
118
|
=end
|
119
119
|
|
120
|
+
# Optionally if we want to include the frequency of the discipline in the pacing output we can
|
121
|
+
# pass in the optional param `show_frequency`. This value defaults to false.
|
122
|
+
|
123
|
+
paced = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, mode: :liberal, summer_holidays: summer_holidays, state: state, show_frequency: true)
|
124
|
+
paced.calculate
|
125
|
+
|
126
|
+
# Below is the output we will get when in strict mode and also showing the frequency in the pacing output.
|
127
|
+
=begin
|
128
|
+
=> [
|
129
|
+
{
|
130
|
+
discipline: 'Speech Therapy',
|
131
|
+
remaining_visits: 0,
|
132
|
+
used_visits: 7,
|
133
|
+
expected_visits_at_date: 3,
|
134
|
+
reset_date: '05-11-2022',
|
135
|
+
pace: 4,
|
136
|
+
pace_indicator: "🐇",
|
137
|
+
pace_suggestion: "less than once per week".
|
138
|
+
frequency: "6Mx30ST"
|
139
|
+
}, {
|
140
|
+
discipline: 'Physical Therapy',
|
141
|
+
remaining_visits: 0,
|
142
|
+
expected_visits_at_date: 3,
|
143
|
+
used_visits: 7,
|
144
|
+
reset_date: '05-11-2022',
|
145
|
+
pace: 4,
|
146
|
+
pace_indicator: "🐇",
|
147
|
+
pace_suggestion: "less than once per week",
|
148
|
+
frequency: "6Mx30PT"
|
149
|
+
}
|
150
|
+
]
|
151
|
+
=end
|
152
|
+
|
120
153
|
paced.interval # Return current interval start and end dates
|
121
154
|
|
122
155
|
# Below is the result you will get
|
data/lib/pacing/error.rb
CHANGED
@@ -53,7 +53,7 @@ module Pacing
|
|
53
53
|
|
54
54
|
begin
|
55
55
|
@school_plan[:school_plan_services].each do |school_plan_service|
|
56
|
-
if (parse_date(school_plan_service[:start_date])
|
56
|
+
if (parse_date(school_plan_service[:start_date]) <= parse_date(@date) && parse_date(@date) <= parse_date(school_plan_service[:end_date]))
|
57
57
|
valid_range_or_exceptions = true
|
58
58
|
end
|
59
59
|
end
|
@@ -72,4 +72,3 @@ module Pacing
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
data/lib/pacing/normalizer.rb
CHANGED
@@ -32,7 +32,7 @@ module Pacing
|
|
32
32
|
discipline_services = services.filter do |service|
|
33
33
|
["pragmatic language", "speech and language", "language", "speech", "language therapy", "speech therapy", "speech and language therapy", "speech language therapy"].include?(service[:type_of_service].downcase)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
return {} if discipline_services.empty?
|
37
37
|
|
38
38
|
discipline_services = normalize_to_monthly_frequency(discipline_services)
|
@@ -57,7 +57,7 @@ module Pacing
|
|
57
57
|
discipline_services = services.filter do |service|
|
58
58
|
["occupation therapy", "occupational therapy", "occupation"].include?(service[:type_of_service].downcase)
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
return {} if discipline_services.empty?
|
62
62
|
|
63
63
|
discipline_services = normalize_to_monthly_frequency(discipline_services)
|
@@ -82,7 +82,7 @@ module Pacing
|
|
82
82
|
discipline_services = services.filter do |service|
|
83
83
|
["physical therapy", "physical"].include?(service[:type_of_service].downcase)
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
return {} if discipline_services.empty?
|
87
87
|
|
88
88
|
discipline_services = normalize_to_monthly_frequency(discipline_services)
|
@@ -107,7 +107,7 @@ module Pacing
|
|
107
107
|
discipline_services = services.filter do |service|
|
108
108
|
["feeding therapy", "feeding"].include?(service[:type_of_service].downcase)
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
return {} if discipline_services.empty?
|
112
112
|
|
113
113
|
discipline_services = normalize_to_monthly_frequency(discipline_services)
|
@@ -155,8 +155,11 @@ module Pacing
|
|
155
155
|
# average business days for each interval
|
156
156
|
interval_average_days = {
|
157
157
|
"weekly" => 5,
|
158
|
+
"per week" => 5,
|
158
159
|
"monthly" => 22,
|
159
|
-
"
|
160
|
+
"per month" => 22,
|
161
|
+
"yearly" => 210,
|
162
|
+
"per year" => 210 # take away average holidays period with is 2.5 months
|
160
163
|
}
|
161
164
|
|
162
165
|
return services if same_interval(services)
|
@@ -164,7 +167,7 @@ module Pacing
|
|
164
167
|
services.map do |service|
|
165
168
|
if !(service[:interval] == "monthly")
|
166
169
|
# weekly(5 days) = frequency # weekly
|
167
|
-
# monthly(20 days) = frequency * monthly
|
170
|
+
# monthly(20 days) = frequency * monthly
|
168
171
|
# yearly(200 days)
|
169
172
|
|
170
173
|
f = service[:frequency]
|
@@ -207,4 +210,3 @@ module Pacing
|
|
207
210
|
end
|
208
211
|
end
|
209
212
|
end
|
210
|
-
|
data/lib/pacing/pacer.rb
CHANGED
@@ -4,13 +4,14 @@ require 'holidays'
|
|
4
4
|
module Pacing
|
5
5
|
class Pacer
|
6
6
|
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
7
|
-
attr_reader :school_plan, :date, :non_business_days, :state, :mode, :interval, :summer_holidays
|
7
|
+
attr_reader :school_plan, :date, :non_business_days, :state, :mode, :interval, :summer_holidays, :show_frequency
|
8
8
|
|
9
|
-
def initialize(school_plan:, date:, non_business_days:, state: :us_tn, mode: :liberal, summer_holidays: [])
|
9
|
+
def initialize(school_plan:, date:, non_business_days:, state: :us_tn, mode: :liberal, summer_holidays: [], show_frequency: false)
|
10
10
|
@school_plan = school_plan
|
11
11
|
@non_business_days = non_business_days
|
12
12
|
@date = date
|
13
13
|
@state = state
|
14
|
+
@show_frequency = show_frequency
|
14
15
|
@mode = [:strict, :liberal].include?(mode) ? mode : :liberal
|
15
16
|
|
16
17
|
Pacing::Error.new(school_plan: school_plan, date: date, non_business_days: non_business_days, state: state, mode: mode, summer_holidays: summer_holidays)
|
@@ -86,6 +87,10 @@ module Pacing
|
|
86
87
|
discipline[:pace_indicator] = pace_indicator(discipline[:pace])
|
87
88
|
discipline[:pace_suggestion] = readable_suggestion(rate: discipline[:suggested_rate])
|
88
89
|
|
90
|
+
if show_frequency
|
91
|
+
discipline[:frequency] = discipline_frequency(service)
|
92
|
+
end
|
93
|
+
|
89
94
|
discipline.delete(:suggested_rate)
|
90
95
|
|
91
96
|
discipline
|
@@ -94,6 +99,11 @@ module Pacing
|
|
94
99
|
services
|
95
100
|
end
|
96
101
|
|
102
|
+
# discipline iep frequency
|
103
|
+
def discipline_frequency(service)
|
104
|
+
service[:frequency].to_s + service[:interval].gsub(/(per)|p/i, "").strip[0].upcase + "x" + service[:time_per_session_in_minutes].to_s + service[:type_of_service][0].upcase + "T"
|
105
|
+
end
|
106
|
+
|
97
107
|
# get a spreadout of visit dates over an interval by using simple proportion.
|
98
108
|
def expected_visits(start_date:, end_date:, frequency:, interval:)
|
99
109
|
reset_start = start_of_treatment_date(start_date, interval)
|
@@ -338,6 +348,6 @@ module Pacing
|
|
338
348
|
holidays_start += 1 until holidays_start.wday == 1
|
339
349
|
|
340
350
|
[holidays_start, holidays_end]
|
341
|
-
end
|
351
|
+
end
|
342
352
|
end
|
343
353
|
end
|
data/lib/pacing/version.rb
CHANGED
data/spec/pacing_spec.rb
CHANGED
@@ -5182,4 +5182,80 @@ RSpec.describe Pacing::Pacer do
|
|
5182
5182
|
expect(results).to eq([{:discipline=>"Occupational Therapy", :remaining_visits=>1, :used_visits=>0, :pace=>0, :pace_indicator=>"😁", :pace_suggestion=>"once a week", :expected_visits_at_date=>0, :reset_date=>"10-24-2022"}, {:discipline=>"Physical Therapy", :remaining_visits=>1, :used_visits=>0, :pace=>0, :pace_indicator=>"😁", :pace_suggestion=>"once a week", :expected_visits_at_date=>0, :reset_date=>"10-24-2022"}])
|
5183
5183
|
end
|
5184
5184
|
end
|
5185
|
-
end
|
5185
|
+
end
|
5186
|
+
|
5187
|
+
describe "should include frequency in the output if show frequency is true" do
|
5188
|
+
it "should correctly parse the pacing for patient 4558" do
|
5189
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"02-23-2022", :end_date=>"02-23-2023", :type_of_service=>"Speech Therapy", :frequency=>12, :interval=>"monthly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>3, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"monthly"}, {:school_plan_type=>"IEP", :start_date=>"05-19-2022", :end_date=>"11-01-2022", :type_of_service=>"Language Therapy", :frequency=>3, :interval=>"weekly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>0, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"weekly"}]}
|
5190
|
+
date = "10-17-2022"
|
5191
|
+
non_business_days = []
|
5192
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5193
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>22, :used_visits=>3, :pace=>-10, :pace_indicator=>"🐢", :pace_suggestion=>"once a day", :expected_visits_at_date=>13, :reset_date=>"11-01-2022", :frequency=>"25Mx20ST"}])
|
5194
|
+
end
|
5195
|
+
|
5196
|
+
it "should correctly parse the pacing for patient 4559" do
|
5197
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"10-27-2021", :end_date=>"10-27-2022", :type_of_service=>"Speech Therapy", :frequency=>8, :interval=>"monthly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>1, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"monthly"}, {:school_plan_type=>"IEP", :start_date=>"10-27-2021", :end_date=>"10-27-2022", :type_of_service=>"Speech Therapy", :frequency=>1, :interval=>"weekly", :time_per_session_in_minutes=>45, :completed_visits_for_current_interval=>0, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"weekly"}]}
|
5198
|
+
date = "10-17-2022"
|
5199
|
+
non_business_days = []
|
5200
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5201
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>11, :used_visits=>1, :pace=>-5, :pace_indicator=>"🐢", :pace_suggestion=>"about once every other day", :expected_visits_at_date=>6, :reset_date=>"11-01-2022", :frequency=>"12Mx45ST"}])
|
5202
|
+
end
|
5203
|
+
|
5204
|
+
it "should also accept 'Language' as a type of service 4560" do
|
5205
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"05-23-2022", :end_date=>"05-23-2023", :type_of_service=>"Speech Therapy", :frequency=>6, :interval=>"monthly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>4, :extra_sessions_allowable=>1, :interval_for_extra_sessions_allowable=>"monthly"}, {:school_plan_type=>"IEP", :start_date=>"05-23-2022", :end_date=>"05-23-2023", :type_of_service=>"Language", :frequency=>6, :interval=>"monthly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>4, :extra_sessions_allowable=>1, :interval_for_extra_sessions_allowable=>"monthly"}]}
|
5206
|
+
date = "10-17-2022"
|
5207
|
+
non_business_days = []
|
5208
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5209
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>10, :used_visits=>4, :pace=>-2, :pace_indicator=>"🐢", :pace_suggestion=>"about once every other day", :expected_visits_at_date=>6, :reset_date=>"11-01-2022", :frequency=>"12Mx20ST"}])
|
5210
|
+
end
|
5211
|
+
|
5212
|
+
it "should correctly parse the pacing for patient 4561" do
|
5213
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"12-03-2021", :end_date=>"12-03-2022", :type_of_service=>"Speech and language", :frequency=>12, :interval=>"monthly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>4, :extra_sessions_allowable=>1, :interval_for_extra_sessions_allowable=>"monthly"}]}
|
5214
|
+
date = "10-17-2022"
|
5215
|
+
non_business_days = []
|
5216
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5217
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>9, :used_visits=>4, :pace=>-2, :pace_indicator=>"🐢", :pace_suggestion=>"about once every other day", :expected_visits_at_date=>6, :reset_date=>"11-01-2022", :frequency=>"12Mx20ST"}])
|
5218
|
+
end
|
5219
|
+
|
5220
|
+
it "should correctly parse the pacing for patient 4562" do
|
5221
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"09-27-2022", :end_date=>"09-27-2023", :type_of_service=>"Language Therapy", :frequency=>30, :interval=>"yearly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>4, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"yearly"}]}
|
5222
|
+
date = "10-17-2022"
|
5223
|
+
non_business_days = []
|
5224
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5225
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>26, :used_visits=>4, :pace=>2, :pace_indicator=>"🐇", :pace_suggestion=>"less than once per week", :expected_visits_at_date=>2, :reset_date=>"09-27-2023", :frequency=>"30Yx20ST"}])
|
5226
|
+
end
|
5227
|
+
|
5228
|
+
it "should correctly parse the pacing for patient 4563" do
|
5229
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"11-03-2021", :end_date=>"11-03-2022", :type_of_service=>"Speech Therapy", :frequency=>1, :interval=>"weekly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>0, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"weekly"}]}
|
5230
|
+
date = "10-17-2022"
|
5231
|
+
non_business_days = []
|
5232
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5233
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>1, :used_visits=>0, :pace=>0, :pace_indicator=>"😁", :pace_suggestion=>"once a week", :expected_visits_at_date=>0, :reset_date=>"10-24-2022", :frequency=>"1Wx20ST"}])
|
5234
|
+
end
|
5235
|
+
|
5236
|
+
it "should correctly parse the pacing for patient 4564 when start_date is same as date" do
|
5237
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"01-09-2023", :end_date=>"03-30-2023", :type_of_service=>"Speech Therapy", :frequency=>1, :interval=>"weekly", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>0, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"weekly"}]}
|
5238
|
+
date = "01-09-2023"
|
5239
|
+
non_business_days = []
|
5240
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5241
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>1, :used_visits=>0, :pace=>0, :pace_indicator=>"😁", :pace_suggestion=>"once a week", :expected_visits_at_date=>0, :reset_date=>"01-16-2023", :frequency=>"1Wx20ST"}])
|
5242
|
+
end
|
5243
|
+
end
|
5244
|
+
|
5245
|
+
describe "should calculate pacing correctly when interval starts with 'per month, per week, and per year'" do
|
5246
|
+
it "should correctly parse the pacing for patient 4565" do
|
5247
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"02-23-2022", :end_date=>"02-23-2023", :type_of_service=>"Speech Therapy", :frequency=>12, :interval=>"per month", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>3, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"per month"}, {:school_plan_type=>"IEP", :start_date=>"05-19-2022", :end_date=>"11-01-2022", :type_of_service=>"Language Therapy", :frequency=>3, :interval=>"per week", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>0, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"per week"}]}
|
5248
|
+
date = "10-17-2022"
|
5249
|
+
non_business_days = []
|
5250
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5251
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>22, :used_visits=>3, :pace=>-10, :pace_indicator=>"🐢", :pace_suggestion=>"once a day", :expected_visits_at_date=>13, :reset_date=>"11-01-2022", :frequency=>"25Mx20ST"}])
|
5252
|
+
end
|
5253
|
+
|
5254
|
+
it "should correctly parse the pacing for patient 4566" do
|
5255
|
+
school_plan = {:school_plan_services=>[{:school_plan_type=>"IEP", :start_date=>"09-27-2022", :end_date=>"09-27-2023", :type_of_service=>"Language Therapy", :frequency=>30, :interval=>"per year", :time_per_session_in_minutes=>20, :completed_visits_for_current_interval=>4, :extra_sessions_allowable=>0, :interval_for_extra_sessions_allowable=>"per year"}]}
|
5256
|
+
date = "10-17-2022"
|
5257
|
+
non_business_days = []
|
5258
|
+
results = Pacing::Pacer.new(school_plan: school_plan, date: date, non_business_days: non_business_days, show_frequency: true).calculate
|
5259
|
+
expect(results).to eq([{:discipline=>"Speech Therapy", :remaining_visits=>26, :used_visits=>4, :pace=>2, :pace_indicator=>"🐇", :pace_suggestion=>"less than once per week", :expected_visits_at_date=>2, :reset_date=>"09-27-2023", :frequency=>"30Yx20ST"}])
|
5260
|
+
end
|
5261
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pacing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin S. Dias
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|