renalware-core 2.0.113 → 2.0.115
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/Rakefile +0 -2
- data/app/assets/javascripts/renalware/application.js.erb +0 -1
- data/app/assets/javascripts/renalware/feed_only_inputs.js.erb +26 -0
- data/app/assets/javascripts/renalware/feeds.js +50 -0
- data/app/assets/javascripts/renalware/person_ajax_search.js +43 -0
- data/app/assets/stylesheets/renalware/application.scss +0 -1
- data/app/assets/stylesheets/renalware/modules/_admin.scss +7 -0
- data/app/assets/stylesheets/renalware/modules/_pathology.scss +1 -1
- data/app/assets/stylesheets/renalware/modules/_patients.scss +6 -0
- data/app/assets/stylesheets/renalware/modules/_snippets.scss +2 -2
- data/app/assets/stylesheets/renalware/partials/_forms.scss +5 -1
- data/app/assets/stylesheets/renalware/partials/_layout.scss +4 -0
- data/app/{views/renalware/patients/_side_menu.html.slim → components/renalware/patients/side_menu_component.html.slim} +0 -0
- data/app/components/renalware/patients/side_menu_component.rb +18 -0
- data/app/controllers/renalware/clinical/body_compositions_controller.rb +6 -0
- data/app/controllers/renalware/feeds/hl7_test_messages_controller.rb +60 -0
- data/app/controllers/renalware/hd/mdm_patients_controller.rb +16 -6
- data/app/controllers/renalware/hd/scheduling/diaries_controller.rb +91 -0
- data/app/controllers/renalware/hd/scheduling/diary_slots_controller.rb +169 -0
- data/app/controllers/renalware/hd/session_forms/batches_controller.rb +1 -1
- data/app/controllers/renalware/pathology/observation_requests_controller.rb +23 -4
- data/app/controllers/renalware/pathology/requests/requests_controller.rb +0 -4
- data/app/controllers/renalware/patients/abridgements_controller.rb +39 -0
- data/app/controllers/renalware/pd/regimes_controller.rb +26 -0
- data/app/controllers/renalware/problems/problems_controller.rb +2 -2
- data/app/helpers/renalware/application_helper.rb +9 -0
- data/app/helpers/renalware/article_helper.rb +18 -0
- data/app/helpers/renalware/form_helper.rb +3 -2
- data/app/helpers/renalware/users_helper.rb +5 -1
- data/app/javascript/controllers/clipboard_controller.js +16 -0
- data/app/javascript/packs/renalware_core.js +20 -0
- data/app/jobs/feed_job.rb +1 -3
- data/app/jobs/hl7_message_example.yml +2 -2
- data/app/models/renalware/feeds/files/practice_memberships/import_job.rb +3 -0
- data/app/models/renalware/feeds/files/primary_care_physicians/import_job.rb +2 -0
- data/app/models/renalware/feeds/hl7_message.rb +57 -6
- data/app/models/renalware/feeds/hl7_test_form.rb +10 -0
- data/app/models/renalware/feeds/hl7_test_message.rb +11 -0
- data/app/models/renalware/feeds/message_parser.rb +6 -2
- data/app/models/renalware/feeds/message_processor.rb +44 -32
- data/app/models/renalware/feeds/persist_message.rb +9 -3
- data/app/models/renalware/feeds.rb +2 -0
- data/app/models/renalware/hd/scheduling/archive_arguments.rb +19 -0
- data/app/models/renalware/hd/scheduling/diary.rb +54 -0
- data/app/models/renalware/hd/scheduling/diary_housekeeping_job.rb +84 -0
- data/app/models/renalware/hd/scheduling/diary_range.rb +69 -0
- data/app/models/renalware/hd/scheduling/diary_slot.rb +88 -0
- data/app/models/renalware/hd/scheduling/find_or_create_diary_by_week_query.rb +52 -0
- data/app/models/renalware/hd/scheduling/find_or_create_master_diary.rb +27 -0
- data/app/models/renalware/hd/scheduling/master_diary.rb +35 -0
- data/app/models/renalware/hd/scheduling/weekly_diary.rb +47 -0
- data/app/models/renalware/pathology/message_listener.rb +2 -2
- data/app/models/renalware/pathology/requests/global_rule/latest_crf_older_than_weeks.rb +38 -0
- data/app/models/renalware/pathology/requests/global_rule/patient_is_diabetic.rb +1 -1
- data/app/models/renalware/patient.rb +1 -1
- data/app/models/renalware/patients/abridgement.rb +18 -0
- data/app/models/renalware/patients/abridgement_search_form.rb +12 -0
- data/app/models/renalware/patients/ingestion/command.rb +25 -0
- data/app/models/renalware/patients/ingestion/command_factory.rb +135 -0
- data/app/models/renalware/patients/ingestion/commands/add_or_update_patient.rb +65 -0
- data/app/models/renalware/patients/ingestion/message_listener.rb +21 -0
- data/app/models/renalware/patients/ingestion/message_mapper.rb +26 -0
- data/app/models/renalware/patients/ingestion/message_mappers/patient.rb +73 -0
- data/app/models/renalware/patients/ingestion/update_master_patient_index.rb +60 -0
- data/app/models/renalware/patients/ingestion/update_master_patient_index_job.rb.dead +20 -0
- data/app/models/renalware/patients.rb +4 -3
- data/app/models/renalware/problems/problem.rb +6 -2
- data/app/models/renalware/ukrdc/incoming/paths.rb +6 -7
- data/app/policies/renalware/admin/devops_policy.rb +18 -0
- data/app/policies/renalware/hd/{diary_policy.rb → scheduling/diary_policy.rb} +3 -1
- data/app/presenters/renalware/clinical/profile_presenter.rb +2 -1
- data/app/presenters/renalware/directory/person_auto_complete_presenter.rb +1 -1
- data/app/presenters/renalware/hd/scheduling/diary_presenter.rb +84 -0
- data/app/presenters/renalware/hd/scheduling/diary_slot_presenter.rb +74 -0
- data/app/presenters/renalware/hd/scheduling/null_slot.rb +42 -0
- data/app/presenters/renalware/pd/dashboard_presenter.rb +3 -2
- data/app/views/renalware/accesses/procedures/_form.html.slim +5 -1
- data/app/views/renalware/accesses/procedures/_list.html.slim +11 -4
- data/app/views/renalware/accesses/procedures/show.html.slim +17 -19
- data/app/views/renalware/addresses/_form.html.slim +17 -12
- data/app/views/renalware/admin/cache/show.html.slim +24 -0
- data/app/views/renalware/clinical/body_compositions/_list.html.slim +7 -43
- data/app/views/renalware/clinical/body_compositions/_table.html.slim +42 -0
- data/app/views/renalware/clinical/body_compositions/index.html.slim +9 -0
- data/app/views/renalware/clinical/dry_weights/_list.html.slim +2 -8
- data/app/views/renalware/clinical/dry_weights/_table.html.slim +7 -0
- data/app/views/renalware/clinical/profiles/show.html.slim +4 -2
- data/app/views/renalware/feeds/hl7_test_messages/create.js.erb +10 -0
- data/app/views/renalware/feeds/hl7_test_messages/new.slim +18 -0
- data/app/views/renalware/hd/mdm_patients/_filters.html.slim +0 -11
- data/app/views/renalware/hd/mdm_patients/_page_actions.html.slim +29 -0
- data/app/views/renalware/hd/mdm_patients/index.html.slim +7 -4
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/_page_actions.html.slim +4 -4
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/_table.html.slim +0 -0
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/_weekly_diary.html.slim +1 -1
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/edit.html.slim +6 -6
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/index.html.slim +0 -0
- data/app/views/renalware/hd/{diaries → scheduling/diaries}/show.pdf.slim +0 -0
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/_form.html.slim +15 -6
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/_slot.html.slim +2 -2
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/_tab.html.slim +1 -1
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/create.js.erb +1 -1
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/destroy.js.erb +1 -1
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/edit.html.slim +2 -2
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/new.html.slim +0 -0
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/new.js.erb +0 -0
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/show.js.erb +0 -0
- data/app/views/renalware/hd/{diary_slots → scheduling/diary_slots}/update.js.erb +1 -1
- data/app/views/renalware/hospitals/units/index.html.slim +2 -2
- data/app/views/renalware/layouts/_patient.html.slim +2 -1
- data/app/views/renalware/letters/contacts/_form.html.slim +10 -13
- data/app/views/renalware/letters/letters/_form.html.slim +2 -9
- data/app/views/renalware/navigation/_developer.html.slim +4 -0
- data/app/views/renalware/navigation/_menu.html.slim +2 -0
- data/app/views/renalware/pathology/observation_requests/_filters.html.slim +17 -0
- data/app/views/renalware/pathology/observation_requests/index.html.slim +2 -1
- data/app/views/renalware/patients/_layout.html.slim +1 -1
- data/app/views/renalware/patients/_side_menu.html.slim.dead +7 -0
- data/app/views/renalware/patients/abridgements/_abridgement.html.slim +8 -0
- data/app/views/renalware/patients/abridgements/_table.html.slim +12 -0
- data/app/views/renalware/patients/abridgements/index.html.slim +22 -0
- data/app/views/renalware/patients/alerts/create.json +3 -0
- data/app/views/renalware/patients/patients/_form.html.slim +36 -17
- data/app/views/renalware/patients/patients/edit.html.slim +1 -1
- data/app/views/renalware/patients/patients/new.html.slim +1 -1
- data/app/views/renalware/patients/side_menu/_actions.html.slim +2 -0
- data/app/views/renalware/pd/_apd_regimes.html.slim +1 -1
- data/app/views/renalware/pd/_capd_regimes.html.slim +1 -1
- data/app/views/renalware/pd/dashboards/show/_apd_regimes.html.slim +11 -2
- data/app/views/renalware/pd/dashboards/show/_capd_regimes.html.slim +11 -2
- data/app/views/renalware/pd/regimes/index.html.slim +7 -0
- data/app/views/renalware/renal/profiles/_form.html.slim +7 -24
- data/app/views/renalware/shared/documents/_binary_marker_input.html.slim +2 -2
- data/app/views/renalware/shared/documents/_blood_group_input.html.slim +4 -2
- data/app/views/renalware/transplants/registrations/_form.html.slim +22 -17
- data/config/locales/renalware/clinical/body_composition.yml +6 -3
- data/config/locales/renalware/clinical/dry_weight.en.yml +4 -3
- data/config/locales/renalware/hd/diary_slots.en.yml +3 -2
- data/config/locales/renalware/letters/contact.en.yml +0 -2
- data/config/routes/feeds.rb +5 -0
- data/config/routes/hd.rb +11 -7
- data/config/routes/letters.rb +0 -5
- data/config/routes/patients.rb +1 -0
- data/config/routes/pd.rb +2 -2
- data/config/routes/renal.rb +0 -5
- data/config/routes.rb +1 -0
- data/config/webpack/development.js +5 -0
- data/config/webpack/environment.js +3 -0
- data/config/webpack/production.js +5 -0
- data/config/webpack/test.js +5 -0
- data/config/webpacker.yml +103 -0
- data/db/functions/hd_diary_archive_elapsed_master_slots_v01.sql +40 -0
- data/db/migrate/20190322120025_create_feed_hl7_test_messages.rb +12 -0
- data/db/migrate/20190325134823_create_patients_master_index.rb +24 -0
- data/db/migrate/20190327100851_add_handled_to_feed_messages.rb +5 -0
- data/db/migrate/20191012121433_add_consultant_to_users.rb +7 -0
- data/db/migrate/20191018143635_create_hd_diary_matrix_view.rb +7 -0
- data/db/migrate/20191018144917_create_fn_to_archive_master_slots.rb +9 -0
- data/db/views/hd_diary_matrix_v01.sql +38 -0
- data/lib/core_extensions/active_record/sort.rb +27 -9
- data/lib/renalware/configuration.rb +3 -0
- data/lib/renalware/engine.rb +31 -0
- data/lib/renalware/version.rb +1 -1
- data/lib/renalware/week_period.rb +8 -7
- data/lib/renalware.rb +13 -1
- data/lib/tasks/hd.rake +7 -0
- data/lib/tasks/pathology.rake +1 -1
- data/lib/tasks/renalware.rake +89 -4
- data/spec/factories/hd/scheduling/diaries.rb +18 -0
- data/spec/factories/hd/{slots.rb → scheduling/slots.rb} +1 -1
- data/spec/factories/patients/abridgements.rb +9 -0
- data/spec/support/hl7_helpers.rb +13 -0
- data/spec/support/pages/letters/form.rb +4 -1
- metadata +126 -50
- data/app/assets/javascripts/renalware/auto_complete.js +0 -63
- data/app/controllers/renalware/hd/diaries_controller.rb +0 -89
- data/app/controllers/renalware/hd/diary_slots_controller.rb +0 -175
- data/app/controllers/renalware/letters/descriptions_controller.rb +0 -22
- data/app/controllers/renalware/renal/prd_descriptions_controller.rb +0 -15
- data/app/models/renalware/hd/archive_yesterdays_slots_job.rb +0 -69
- data/app/models/renalware/hd/diary.rb +0 -41
- data/app/models/renalware/hd/diary_slot.rb +0 -83
- data/app/models/renalware/hd/find_or_create_diary_by_week_query.rb +0 -50
- data/app/models/renalware/hd/find_or_create_master_diary.rb +0 -26
- data/app/models/renalware/hd/master_diary.rb +0 -32
- data/app/models/renalware/hd/weekly_diary.rb +0 -45
- data/app/models/renalware/renal/prd_descriptions/search_query.rb +0 -35
- data/app/presenters/renalware/hd/diary_presenter.rb +0 -79
- data/app/presenters/renalware/hd/diary_slot_presenter.rb +0 -72
- data/app/presenters/renalware/hd/null_slot.rb +0 -40
- data/app/views/renalware/renal/prd_descriptions/search.json.jbuilder +0 -6
- data/lib/test_support/autocomplete_helpers.rb +0 -14
- data/spec/factories/hd/diaries.rb +0 -14
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd/base_controller"
|
|
4
|
-
|
|
5
|
-
# The route to the edit route for this controller takes /:year/:week_number segments
|
|
6
|
-
# rather than an id. THat is because when we load the diary, and when we navigate back and forth
|
|
7
|
-
# through diaries, we are concerned with the week more then an id. Its easier to navigate to the
|
|
8
|
-
# next week with /2017/52 than by looking up the id of the next diary ahead of time.
|
|
9
|
-
module Renalware
|
|
10
|
-
module HD
|
|
11
|
-
class DiariesController < BaseController
|
|
12
|
-
include Renalware::Concerns::PdfRenderable
|
|
13
|
-
include Renalware::Concerns::Pageable
|
|
14
|
-
|
|
15
|
-
def edit
|
|
16
|
-
authorize weekly_diary, :show?
|
|
17
|
-
render locals: {
|
|
18
|
-
unit: unit,
|
|
19
|
-
diary: DiaryPresenter.new(current_user, weekly_diary)
|
|
20
|
-
}
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Renders a list of diaries for a hospital unit
|
|
24
|
-
def index
|
|
25
|
-
authorize WeeklyDiary, :index?
|
|
26
|
-
render locals: { unit: unit, diaries: weekly_diaries }
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def show
|
|
30
|
-
diary = WeeklyDiary.find(params[:id])
|
|
31
|
-
respond_to do |format|
|
|
32
|
-
format.pdf do
|
|
33
|
-
authorize diary
|
|
34
|
-
options = default_pdf_options.merge!(
|
|
35
|
-
pdf: pdf_filename,
|
|
36
|
-
locals: { unit: unit, diary: DiaryPresenter.new(current_user, diary) }
|
|
37
|
-
)
|
|
38
|
-
render options
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
# TODO: give a sensible name
|
|
46
|
-
def pdf_filename
|
|
47
|
-
"hd_unit_diary"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def weekly_diary
|
|
51
|
-
@weekly_diary ||= begin
|
|
52
|
-
FindOrCreateDiaryByWeekQuery.new(
|
|
53
|
-
relation: WeeklyDiary.eager_load(
|
|
54
|
-
slots: [:patient, :station, :diurnal_period_code],
|
|
55
|
-
master_diary: { slots: [:patient, :station, :diurnal_period_code] }
|
|
56
|
-
),
|
|
57
|
-
unit_id: unit_id,
|
|
58
|
-
week_period: week_period,
|
|
59
|
-
by: current_user
|
|
60
|
-
).call
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# The route segments are /:year/:week_number
|
|
65
|
-
# We use a WeekPeriod value object to wrap those two things.
|
|
66
|
-
def week_period
|
|
67
|
-
WeekPeriod.new(
|
|
68
|
-
week_number: params[:week_number],
|
|
69
|
-
year: params[:year]
|
|
70
|
-
)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def unit_id
|
|
74
|
-
params[:unit_id]
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def unit
|
|
78
|
-
Hospitals::Unit.find(unit_id)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def weekly_diaries
|
|
82
|
-
WeeklyDiary
|
|
83
|
-
.where(hospital_unit_id: unit_id)
|
|
84
|
-
.ordered
|
|
85
|
-
.page(page).per(per_page)
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# rubocop:disable Metrics/ClassLength
|
|
4
|
-
require_dependency "renalware/hd/base_controller"
|
|
5
|
-
|
|
6
|
-
module Renalware
|
|
7
|
-
module HD
|
|
8
|
-
class DiarySlotsController < BaseController
|
|
9
|
-
# GET html - renders a form
|
|
10
|
-
# Here we will have been passed in the query string:
|
|
11
|
-
# - the unit id
|
|
12
|
-
# - the dirunal_period_code id
|
|
13
|
-
# - the week and year (and thus the diary)
|
|
14
|
-
# and from that lot we could look up the master and weekly diaries
|
|
15
|
-
def new
|
|
16
|
-
# Be default this assume we are going to add a slot to the weekly diary
|
|
17
|
-
# but in which button is clicked in the modal dialog determines which diary
|
|
18
|
-
# (master or weekly) the slot will be added to.
|
|
19
|
-
slot = DiarySlot.new(
|
|
20
|
-
diary: weekly_diary,
|
|
21
|
-
station_id: params[:station_id],
|
|
22
|
-
day_of_week: params[:day_of_week],
|
|
23
|
-
diurnal_period_code_id: params[:diurnal_period_code_id]
|
|
24
|
-
)
|
|
25
|
-
authorize slot
|
|
26
|
-
render locals: locals_for(slot), layout: false
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# POST create js
|
|
30
|
-
# Here we may be adding a slot to the weekly or master diary.
|
|
31
|
-
# That should be transparent to us - we make the change and render
|
|
32
|
-
# create.js.erb which, on the client, will cause an ajax js call to #show. That secondary call
|
|
33
|
-
# is the one that refreshes the slot in the table with its latest state.
|
|
34
|
-
# We do this to avoid having to to a check (in each action in this controller) to see if we
|
|
35
|
-
# are on the master or weekly diary; if we always refresh the diary slot in the ui after any
|
|
36
|
-
# action, then it will always update correctly.
|
|
37
|
-
def create
|
|
38
|
-
diary = Diary.find(params[:diary_id])
|
|
39
|
-
slot = diary.slots.new(slot_params)
|
|
40
|
-
slot.patient_id = posted_patient_id
|
|
41
|
-
authorize slot
|
|
42
|
-
if slot.save_by(current_user)
|
|
43
|
-
render locals: { diary: diary, slot: diary.decorate_slot(slot) }
|
|
44
|
-
else
|
|
45
|
-
render :new, locals: { slot: DiarySlotPresenter.new(slot) }, layout: false
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# GET .js refresh a slot in a *weekly* diary
|
|
50
|
-
# See comment on #create.
|
|
51
|
-
# See show.js.erb where we refresh the slot in the diary
|
|
52
|
-
# To get here we will have manufactured a url like this
|
|
53
|
-
# hd/diaries/2/slots/day/1/period/1/station/1
|
|
54
|
-
# as those bit are will we know.
|
|
55
|
-
# Basically we are saying find for this weekly diary, find the matching
|
|
56
|
-
# slot for the station/day/period combo and render the weekly slot if there is
|
|
57
|
-
# one, or the master behind it if there is one of those, otherwise render an Add button.
|
|
58
|
-
def show
|
|
59
|
-
authorize DiarySlot, :show?
|
|
60
|
-
slot = weekly_then_master_then_empty_slot
|
|
61
|
-
render layout: false, locals: { slot: DiarySlotPresenter.new(slot) }
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def edit
|
|
65
|
-
authorize slot
|
|
66
|
-
render layout: false, locals: { slot: DiarySlotPresenter.new(slot) }
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# DELETE js
|
|
70
|
-
# Delete the slot (we don't know if its on the master or weekly diary).
|
|
71
|
-
# NB as per #create and #update, the rendered js file (destroy.js.erb) will make a secondary
|
|
72
|
-
# back into #show to refresh the UI (i.e. we don't attempt to update the UI in destroy.js.erb)
|
|
73
|
-
def destroy
|
|
74
|
-
authorize slot
|
|
75
|
-
slot.destroy!
|
|
76
|
-
render locals: { slot: DiarySlotPresenter.new(slot) }
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# PATCH js
|
|
80
|
-
# See also comments in #create and #destroy.
|
|
81
|
-
def update
|
|
82
|
-
authorize slot
|
|
83
|
-
slot.patient_id = slot_params[:patient_id]
|
|
84
|
-
slot.save_by!(current_user)
|
|
85
|
-
diary = slot.diary
|
|
86
|
-
render locals: { diary: diary, slot: diary.decorate_slot(slot) }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
|
|
91
|
-
# Find the corresponding slot in the master if there is one, otherwise an empty slot
|
|
92
|
-
# with an 'Add' button ready to set up a new patient
|
|
93
|
-
def weekly_then_master_then_empty_slot
|
|
94
|
-
empty_slot = build_empty_weekly_slot
|
|
95
|
-
find_weekly_slot(empty_slot) || find_master_slot(empty_slot) || empty_slot
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def find_master_slot(args)
|
|
99
|
-
slot = master_diary.slots.find_by(
|
|
100
|
-
diurnal_period_code_id: args.diurnal_period_code_id,
|
|
101
|
-
station_id: args.station_id,
|
|
102
|
-
day_of_week: args.day_of_week
|
|
103
|
-
)
|
|
104
|
-
slot && master_diary.decorate_slot(slot)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def find_weekly_slot(args)
|
|
108
|
-
slot = weekly_diary.slots.find_by(
|
|
109
|
-
diurnal_period_code_id: args.diurnal_period_code_id,
|
|
110
|
-
station_id: args.station_id,
|
|
111
|
-
day_of_week: args.day_of_week
|
|
112
|
-
)
|
|
113
|
-
slot && weekly_diary.decorate_slot(slot)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Used for searching etc
|
|
117
|
-
def build_empty_weekly_slot
|
|
118
|
-
weekly_diary.slots.new(
|
|
119
|
-
day_of_week: params[:day_of_week],
|
|
120
|
-
station_id: params[:station_id],
|
|
121
|
-
diurnal_period_code_id: params[:diurnal_period_code_id]
|
|
122
|
-
)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def slot
|
|
126
|
-
@slot ||= HD::DiarySlot.find(params[:id])
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# In the url the :diary_id param is always the weekly diary id!
|
|
130
|
-
def weekly_diary
|
|
131
|
-
@weekly_diary ||= WeeklyDiary.find(params[:diary_id])
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def master_diary
|
|
135
|
-
weekly_diary.master_diary
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def locals_for(slot)
|
|
139
|
-
{
|
|
140
|
-
slot: DiarySlotPresenter.new(slot),
|
|
141
|
-
weekly_diary: weekly_diary
|
|
142
|
-
}
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# In the modal dialog that submits the patient_id there are several (select2) dropdown
|
|
146
|
-
# a user can use to choose the patient. Each one has the name patient_id[] so they are
|
|
147
|
-
# submitted in the form as an array. However the array can only hold one id value ie we
|
|
148
|
-
# might get posted patient_id: ["", "123", ""] but never ["2", "123", ""].
|
|
149
|
-
# Here we reduce that array down to one patient id.
|
|
150
|
-
def posted_patient_id
|
|
151
|
-
patient_ids = Array(slot_params[:patient_id]).reject(&:blank?).uniq
|
|
152
|
-
if patient_ids.length > 1
|
|
153
|
-
raise ArgumentError, "More than one id submitted in patient_id[] : #{patient_ids}"
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
patient_ids.first
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def slot_params
|
|
160
|
-
params
|
|
161
|
-
.require(:hd_diary_slot)
|
|
162
|
-
.permit(
|
|
163
|
-
:master_slot,
|
|
164
|
-
:day_of_week,
|
|
165
|
-
:diurnal_period_code_id,
|
|
166
|
-
:station_id,
|
|
167
|
-
:target_diary_id,
|
|
168
|
-
:change_type,
|
|
169
|
-
patient_id: []
|
|
170
|
-
)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
# rubocop:enable Metrics/ClassLength
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/letters"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module Letters
|
|
7
|
-
class DescriptionsController < ApplicationController
|
|
8
|
-
def search
|
|
9
|
-
query = Letters::Descriptions::SearchQuery.new(params[:term])
|
|
10
|
-
render json: DescriptionAutocompleteResponse.to_json(query.call)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
class DescriptionAutocompleteResponse
|
|
14
|
-
def self.to_json(collection)
|
|
15
|
-
collection.map do |item|
|
|
16
|
-
{ id: item.id, label: item.text }
|
|
17
|
-
end.to_json
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/renal"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module Renal
|
|
7
|
-
class PRDDescriptionsController < BaseController
|
|
8
|
-
skip_after_action :verify_authorized, only: [:search]
|
|
9
|
-
|
|
10
|
-
def search
|
|
11
|
-
@prd_descriptions = PRDDescriptions::SearchQuery.new(term: params[:term]).call
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "renalware/hd"
|
|
4
|
-
|
|
5
|
-
# A cron job creates this delayed job, which does the following:
|
|
6
|
-
# For all Weekly Diaries in the past, plus this week
|
|
7
|
-
# for each day that is in the past
|
|
8
|
-
# mark any slots in the weekly diary as archived
|
|
9
|
-
# and where the weekly diary is inheriting slots from the master diary
|
|
10
|
-
# create corresponding slots in the weekly diary (ie migrate thos slots from master to weekly)
|
|
11
|
-
# and archive them.
|
|
12
|
-
# Not slots before the current day (or the up_until: arg) should be touched
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# OK we have a problem,
|
|
16
|
-
# If last week there was no weekly diary created... then there is nothing to archive if eg today is
|
|
17
|
-
# Monday.
|
|
18
|
-
# So really whats the query for finding slots to archive?
|
|
19
|
-
# We need to really always inner join onto weekly diaryies, and within tose for their slots
|
|
20
|
-
# select unarchved onces in the past.
|
|
21
|
-
# So we MUST always have weekly diaries for every possible week and not rely om a user working te UI
|
|
22
|
-
# to create these JIT - because if they don't, unless we have a fn to creatae missing diaries,
|
|
23
|
-
# (from which date?) then we can't query
|
|
24
|
-
# So either
|
|
25
|
-
# - seed next 10 years (520 per unit)
|
|
26
|
-
# - have a fn to generate missing diaries - might be better and safer in the long run?
|
|
27
|
-
# - Otherwise after 5 or 10 years or whatever its bound to have cased a problem.
|
|
28
|
-
|
|
29
|
-
module Renalware
|
|
30
|
-
module HD
|
|
31
|
-
class ArchiveYesterdaysSlotsJob < ApplicationJob
|
|
32
|
-
attr_reader :up_until
|
|
33
|
-
|
|
34
|
-
# :reek:UtilityFunction
|
|
35
|
-
def perform(up_until: nil)
|
|
36
|
-
@up_until = up_until&.to_date
|
|
37
|
-
@up_until ||= (Time.zone.today - 1.day)
|
|
38
|
-
|
|
39
|
-
diary = Diary.find_by(year: @up_until.year, week_number: @up_until.cweek)
|
|
40
|
-
return unless diary
|
|
41
|
-
|
|
42
|
-
diary
|
|
43
|
-
.slots
|
|
44
|
-
.unarchived
|
|
45
|
-
.where(day_of_week: @up_until.cwday)
|
|
46
|
-
.update_all(archived: true, archived_at: Time.zone.now)
|
|
47
|
-
# DiarySlot
|
|
48
|
-
# .unarchived
|
|
49
|
-
# .joins(:diary)
|
|
50
|
-
# .where(hd_diaries: { year: up_until.year, week_number: up_until.cweek)
|
|
51
|
-
|
|
52
|
-
# .update_all(archived: true, archived_at: Time.zone.now)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
def create_missing_weekly_diaries
|
|
58
|
-
# intering query
|
|
59
|
-
# basic implemenraiton
|
|
60
|
-
# select all weeklydiaries pluch year week from installation start date??? to now
|
|
61
|
-
# loop through
|
|
62
|
-
# diary year 2017 week 1
|
|
63
|
-
# MISSING diary year 2017 week 1 - so create
|
|
64
|
-
# diary year 2017 week 3
|
|
65
|
-
# select
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd"
|
|
4
|
-
|
|
5
|
-
# A Diary is the schedule of HD Station/Patients assignments for one week for a particular unit.
|
|
6
|
-
# A Diary is split into Periods (eg. am pm eve), and each Period has a matrix of slots
|
|
7
|
-
# Imagine Days eg 1 to 6 on the X axis and Stations on the Y axis, and into each 'slot' we
|
|
8
|
-
# put a patient.
|
|
9
|
-
# A patient can only be in one slot in any period.
|
|
10
|
-
#
|
|
11
|
-
# Do not create instances of this class explicity, always use the STI sub classes eg MasterDiary.
|
|
12
|
-
module Renalware
|
|
13
|
-
module HD
|
|
14
|
-
class Diary < ApplicationRecord
|
|
15
|
-
include Accountable
|
|
16
|
-
|
|
17
|
-
has_many :slots, class_name: "Renalware::HD::DiarySlot"
|
|
18
|
-
has_many :patients, through: :slots, class_name: "Renalware::HD::Patient"
|
|
19
|
-
validates :hospital_unit_id, presence: true
|
|
20
|
-
validates :master, inclusion: { in: [true, false], allow_nil: true }
|
|
21
|
-
composed_of :week,
|
|
22
|
-
mapping: [%w(week_number week_number), %w(year year)],
|
|
23
|
-
constructor: lambda { |week_number, year|
|
|
24
|
-
WeekPeriod.new(week_number: week_number, year: year)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
def self.policy_class
|
|
28
|
-
DiaryPolicy
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Searchs the object graph rather than a SQL search
|
|
32
|
-
def slot_for(diurnal_period_code_id, station_id, day_of_week)
|
|
33
|
-
slots.find do |slot|
|
|
34
|
-
slot.diurnal_period_code_id == diurnal_period_code_id &&
|
|
35
|
-
slot.station_id == station_id &&
|
|
36
|
-
slot.day_of_week == day_of_week
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module HD
|
|
7
|
-
# TODO: Document
|
|
8
|
-
class DiarySlot < ApplicationRecord
|
|
9
|
-
# Changing to_ary from private to public here is a hack required to remove a SimpleDelgator
|
|
10
|
-
# warning in eg Renalware::HD::WeeklyDiary::WeeklySlotDecorator:
|
|
11
|
-
#
|
|
12
|
-
# `respond_to?': delegator does not forward private method #to_ary
|
|
13
|
-
#
|
|
14
|
-
# Yielding a slot from DiaryPresenter to the view seems to want to call #to_ary on it, (have
|
|
15
|
-
# not looked into why) and as the slot is wrapped in a decorator using SimpleDelegator,
|
|
16
|
-
# SimpleDelegatr complains it can't delegate to a private method.
|
|
17
|
-
# An alternative is to define the following in each Slot decorator
|
|
18
|
-
#
|
|
19
|
-
# def respond_to?(method, include_private = false)
|
|
20
|
-
# return false if method == :to_ary
|
|
21
|
-
# super
|
|
22
|
-
# end
|
|
23
|
-
#
|
|
24
|
-
# or to use method_missnig instead of SimpleDelegator in Slot Decorators.
|
|
25
|
-
#
|
|
26
|
-
public :to_ary
|
|
27
|
-
|
|
28
|
-
# Virtual attribute used on a form to determine what action as preformed on the slot
|
|
29
|
-
attr_accessor :change_type
|
|
30
|
-
|
|
31
|
-
include Accountable
|
|
32
|
-
belongs_to :diary, class_name: "Renalware::HD::Diary", touch: true
|
|
33
|
-
belongs_to :patient, touch: true
|
|
34
|
-
belongs_to :station, class_name: "Renalware::HD::Station"
|
|
35
|
-
belongs_to :diurnal_period_code
|
|
36
|
-
|
|
37
|
-
validates :diary, presence: true
|
|
38
|
-
validates :patient, presence: true
|
|
39
|
-
validates :station, presence: true
|
|
40
|
-
validates :diurnal_period_code, presence: true
|
|
41
|
-
validates :day_of_week, presence: true, inclusion: { in: 1..7 }
|
|
42
|
-
|
|
43
|
-
scope :weekly, -> { joins(:diary).where(hd_diaries: { master: false }) }
|
|
44
|
-
scope :archived, -> { weekly.where(archived: true) }
|
|
45
|
-
scope :unarchived, -> { weekly.where(archived: false) }
|
|
46
|
-
|
|
47
|
-
# A patient can only be assigned to one station in any period (e.g. am)/day combination
|
|
48
|
-
# for a diary. I.e. they can't be on two stations on Monday morning.
|
|
49
|
-
validates :patient_id,
|
|
50
|
-
uniqueness: { scope: [:diary, :diurnal_period_code, :day_of_week] }
|
|
51
|
-
|
|
52
|
-
# Scoped to a diary, the combination of day + station + diurnal_period is unique
|
|
53
|
-
validates :diurnal_period_code_id, uniqueness: { scope: [:diary, :station_id, :day_of_week] }
|
|
54
|
-
|
|
55
|
-
delegate :id, to: :diary, prefix: true
|
|
56
|
-
|
|
57
|
-
def self.policy_class
|
|
58
|
-
DiaryPolicy
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def on_master_diary?
|
|
62
|
-
diary&.master?
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def description
|
|
66
|
-
period = diurnal_period_code.code.upcase # e.g. AM
|
|
67
|
-
if diary.master
|
|
68
|
-
"Recurring every #{day_of_week_name} #{period}"
|
|
69
|
-
else
|
|
70
|
-
"This week only on #{day_of_week_name} #{period}"
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def day_of_week_name
|
|
75
|
-
Time::DAYS_INTO_WEEK.keys[day_of_week - 1].capitalize
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def cell_id
|
|
79
|
-
"#{diurnal_period_code&.id}-#{station&.id}-#{day_of_week}"
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd"
|
|
4
|
-
require "renalware/week_period"
|
|
5
|
-
##
|
|
6
|
-
# Returns a hospital unit's diary for the requested week (passed to #new as a WeekPeriod
|
|
7
|
-
# value object).
|
|
8
|
-
#
|
|
9
|
-
module Renalware
|
|
10
|
-
module HD
|
|
11
|
-
class FindOrCreateDiaryByWeekQuery
|
|
12
|
-
attr_reader :unit_id, :period, :by, :relation
|
|
13
|
-
|
|
14
|
-
def initialize(unit_id:, week_period:, by:, relation: WeeklyDiary.all)
|
|
15
|
-
@relation = relation
|
|
16
|
-
@period = week_period
|
|
17
|
-
@unit_id = unit_id
|
|
18
|
-
@by = by
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def call
|
|
22
|
-
find_or_create_diary
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
# Find the diary for the current unit/week/year, or, if for example if a user wants to fill
|
|
28
|
-
# next week's diary and it does not yet exist, create it
|
|
29
|
-
# NB we _always_ return a diary from this method - whether it is found or built just-in-time,
|
|
30
|
-
def find_or_create_diary
|
|
31
|
-
attrs = {
|
|
32
|
-
hospital_unit_id: unit_id,
|
|
33
|
-
week_number: period.week_number,
|
|
34
|
-
year: period.year,
|
|
35
|
-
master: false
|
|
36
|
-
}
|
|
37
|
-
relation.find_by(**attrs) || build_diary(**attrs)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Create a new Weekly diary for the current week/year/unit
|
|
41
|
-
# Add in DiaryPeriods for each currently defined diurnal period eg am pm eve
|
|
42
|
-
def build_diary(attrs)
|
|
43
|
-
master_diary = FindOrCreateMasterDiary.for_unit(unit_id, by)
|
|
44
|
-
diary = WeeklyDiary.create!(**attrs, by: by, master_diary: master_diary)
|
|
45
|
-
# Reload the diary using the supplied relation (might be egager_loads etc)
|
|
46
|
-
relation.find(diary.id)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Renalware
|
|
4
|
-
module HD
|
|
5
|
-
class FindOrCreateMasterDiary
|
|
6
|
-
attr_reader :unit_id, :user
|
|
7
|
-
|
|
8
|
-
def self.for_unit(unit_id, user)
|
|
9
|
-
new(unit_id, user).call
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def initialize(unit_id, user)
|
|
13
|
-
@unit_id = unit_id
|
|
14
|
-
@user = user
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# TODO: !alwasy suing first :0)
|
|
18
|
-
def call
|
|
19
|
-
MasterDiary.find_or_initialize_by(hospital_unit_id: unit_id).tap do |master|
|
|
20
|
-
master.by = user
|
|
21
|
-
master.save!
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module HD
|
|
7
|
-
class MasterDiary < Diary
|
|
8
|
-
# Overwrite the existing master attribute to ensure it defaults to true
|
|
9
|
-
attribute :master, :boolean, default: true
|
|
10
|
-
validates :hospital_unit_id, uniqueness: true
|
|
11
|
-
has_many :weekly_diaries, class_name: "Renalware::HD::WeeklyDiary"
|
|
12
|
-
# While out DB constraints could check for the string "Renalware::HD::MasterDiary" in the type
|
|
13
|
-
# column, this feels a bit fragile, so instead a MasterDiary must have a corresponding
|
|
14
|
-
# master = TRUE column
|
|
15
|
-
validates :master, inclusion: { in: [true], allow_nil: false }
|
|
16
|
-
|
|
17
|
-
class MasterSlotDecorator < SimpleDelegator
|
|
18
|
-
def master?
|
|
19
|
-
true
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def decorate_slot(slot)
|
|
24
|
-
MasterSlotDecorator.new(slot)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def slot_for(*args)
|
|
28
|
-
(slot = super) && decorate_slot(slot)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/hd"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module HD
|
|
7
|
-
class WeeklyDiary < Diary
|
|
8
|
-
# Overwrite the existing master attribute to ensure it defaults to false
|
|
9
|
-
attribute :master, :boolean, default: false
|
|
10
|
-
belongs_to :master_diary, class_name: "Renalware::HD::MasterDiary"
|
|
11
|
-
validates :week_number,
|
|
12
|
-
presence: true,
|
|
13
|
-
uniqueness: { scope: [:year, :hospital_unit_id] },
|
|
14
|
-
inclusion: { in: 1..53 }
|
|
15
|
-
validates :year, presence: true
|
|
16
|
-
validates :master, inclusion: { in: [false], allow_nil: false }
|
|
17
|
-
validates :master_diary, presence: true
|
|
18
|
-
delegate :to_s, to: :week
|
|
19
|
-
scope :ordered, -> { order(year: :desc, week_number: :desc) }
|
|
20
|
-
|
|
21
|
-
def applies_to_current_week?
|
|
22
|
-
today = Time.zone.today
|
|
23
|
-
[today.cweek, today.year] == [week.week_number, week.year]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def archived?
|
|
27
|
-
false
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
class WeeklySlotDecorator < SimpleDelegator
|
|
31
|
-
def master?
|
|
32
|
-
false
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def decorate_slot(slot)
|
|
37
|
-
WeeklySlotDecorator.new(slot)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def slot_for(*args)
|
|
41
|
-
(slot = super) && decorate_slot(slot)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_dependency "renalware/renal"
|
|
4
|
-
|
|
5
|
-
module Renalware
|
|
6
|
-
module Renal
|
|
7
|
-
module PRDDescriptions
|
|
8
|
-
class SearchQuery
|
|
9
|
-
attr_reader :term, :page, :per_page
|
|
10
|
-
|
|
11
|
-
def initialize(term:, page: 1, per_page: 50)
|
|
12
|
-
@term = term
|
|
13
|
-
@page = page
|
|
14
|
-
@per_page = per_page
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def call
|
|
18
|
-
search.result.page(page).per(per_page).select(fields)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def search
|
|
24
|
-
@search ||= PRDDescription.ransack(term_or_code_cont: term).tap do |s|
|
|
25
|
-
s.sorts = ["term"]
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def fields
|
|
30
|
-
%i(id code term)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|