renalware-core 2.0.0.pre.rc8 → 2.0.0.pre.rc9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/renalware/modules/_clinical.scss +73 -0
- data/app/models/concerns/renalware/clinics/most_recent_measurement_scopes.rb.dead +43 -0
- data/app/models/renalware/clinics/clinic_visit.rb +2 -2
- data/app/models/renalware/clinics/current_observations.rb +57 -0
- data/app/models/renalware/letters/letter.rb +5 -1
- data/app/models/renalware/pathology/current_observation_set.rb +6 -0
- data/app/models/renalware/pathology/observation.rb +1 -0
- data/app/models/renalware/pathology/observation_request.rb +3 -0
- data/app/models/renalware/pathology/observations_jsonb_serializer.rb +7 -6
- data/app/models/renalware/pathology/{view_current_observation_results.rb → view_current_observation_results.rb.dead} +0 -0
- data/app/presenters/renalware/clinical/header_presenter.rb +33 -0
- data/app/presenters/renalware/letters/letter_presenter.rb +5 -1
- data/app/presenters/renalware/letters/part_class_filter.rb +36 -0
- data/app/presenters/renalware/renal/clinical_summary_presenter.rb +0 -1
- data/app/presenters/renalware/ukrdc/patient_presenter.rb +8 -2
- data/app/values/renalware/bmi.rb +20 -0
- data/app/views/renalware/admissions/consults/_table.html.slim +1 -1
- data/app/views/renalware/api/ukrdc/patients/_clinic_visit_observation.xml.builder +1 -1
- data/app/views/renalware/api/ukrdc/patients/_lab_orders.xml.builder +3 -3
- data/app/views/renalware/api/ukrdc/patients/_observations.xml.builder +3 -1
- data/app/views/renalware/api/ukrdc/patients/lab_orders/_lab_order.xml.builder +2 -2
- data/app/views/renalware/api/ukrdc/patients/lab_orders/_result_item.xml.builder +7 -2
- data/app/views/renalware/clinical/_header.html.slim +47 -0
- data/app/views/renalware/clinics/clinic_visits/_table.html.slim +0 -1
- data/app/views/renalware/clinics/visits/_table.html.slim +4 -1
- data/app/views/renalware/events/events/_event.html.slim +1 -1
- data/app/views/renalware/events/events/_table.html.slim +3 -0
- data/app/views/renalware/layouts/_patient.html.slim +1 -0
- data/app/views/renalware/letters/letters/_form.html.slim +1 -1
- data/app/views/renalware/letters/letters/_pathology.html.slim +0 -1
- data/app/views/renalware/mdm_patients/_table.html.slim +1 -1
- data/app/views/renalware/pathology/_navigation.html.slim +1 -1
- data/app/views/renalware/patients/patients/_table.html.slim +2 -2
- data/config/initializers/core_extensions.rb +1 -0
- data/config/initializers/inflections.rb +1 -0
- data/config/locales/renalware/clinical/allergies.en.yml +0 -2
- data/config/locales/renalware/clinical/{dry_weight.yml → dry_weight.en.yml} +0 -0
- data/config/locales/renalware/clinical/header.en.yml +14 -0
- data/db/functions/audit_view_as_json_v01.sql +25 -0
- data/db/functions/count_estimate_v01.sql +20 -0
- data/db/functions/generate_patient_secure_id_v01.sql +21 -0
- data/db/functions/generate_secure_id_v01.sql +18 -0
- data/db/functions/import_gps_csv_v01.sql +129 -0
- data/db/functions/import_practice_memberships_csv_v01.sql +48 -0
- data/db/functions/import_practices_csv_v01.sql +109 -0
- data/db/functions/preprocess_hl7_message_v01.sql +29 -0
- data/db/functions/preprocess_hl7_message_v02.sql +31 -0
- data/db/functions/refresh_all_matierialized_views_v01.sql +32 -0
- data/db/functions/refresh_current_observation_set_v01.sql +39 -0
- data/db/functions/update_current_observation_set_from_trigger_v01.sql +88 -0
- data/db/functions/update_current_observation_set_from_trigger_v02.sql +90 -0
- data/db/migrate/20161124152732_add_deleted_at_to_patient_bookmarks.rb +1 -1
- data/db/migrate/20170608135553_create_functions_to_generate_secure_patient_id.rb +4 -48
- data/db/migrate/20170705090219_create_refresh_all_materialized_views_fn.rb +2 -37
- data/db/migrate/20170707110155_rename_access_plans_to_access_plan_types.rb +1 -1
- data/db/migrate/20170831142819_enable_crosstab_extension.rb +2 -2
- data/db/migrate/20170911133224_add_type_to_messaging_messages.rb +1 -1
- data/db/migrate/20170915115228_add_schedule_diurnal_period_id_to_hd_profiles.rb +1 -1
- data/db/migrate/20171013145849_set_patients_secure_id.rb +1 -1
- data/db/migrate/20171101121130_create_function_to_render_audit_view_as_json.rb +2 -29
- data/db/migrate/20171127092158_create_function_to_import_practices.rb +4 -118
- data/db/migrate/20171127092359_create_fn_to_insert_gps.rb +3 -139
- data/db/migrate/20171206140738_create_fn_to_load_practice_memberships_csv.rb +2 -53
- data/db/migrate/20171213111513_create_fn_to_refresh_current_obs.rb +2 -43
- data/db/migrate/20171214141335_create_trigger_to_update_current_observation_sets.rb +3 -101
- data/db/migrate/20180119121243_create_trigger_to_preprocess_hl7_msg.rb +2 -41
- data/db/migrate/20180121115246_add_include_pathology_in_letter_to_letters_letterheads.rb +5 -0
- data/db/migrate/20180125201356_make_obs_set_trigger_change_updated_at.rb +2 -184
- data/db/migrate/20180130165803_add_deleted_at_indexes.rb +16 -0
- data/db/migrate/20180201090444_add_created_at_to_delayed_jobs_in_hl7_trig_fn.rb +9 -0
- data/db/migrate/20180207082540_create_count_estimate_function.rb +9 -0
- data/db/triggers/feed_messages_preprocessing_trigger_v01.sql +5 -0
- data/db/triggers/update_current_observation_set_trigger_v01.sql +7 -0
- data/lib/core_extensions/active_record/migration_helpers.rb +43 -0
- data/lib/renalware/engine.rb +6 -4
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/pathology/observation_descriptions.rb +7 -1
- data/spec/support/shared_examples/accountable_examples.rb +6 -0
- data/spec/support/shared_examples/supersedable_examples.rb +12 -0
- metadata +33 -10
- data/app/models/renalware/letters/delivery/deliver_letter.rb.dead +0 -41
- data/app/models/renalware/pathology/current_key_observation_set.rb.dead +0 -10
- data/app/models/renalware/pathology/update_current_observations.rb.dead +0 -25
- data/app/presenters/renalware/pathology/current_observation_results.dead/presenter.rb.dead +0 -54
- data/app/views/renalware/letters/formatted_letters/show.rtf.slim.ol +0 -1
- data/app/views/renalware/patients/_prescriptions.html.slim.dead +0 -23
@@ -6,7 +6,7 @@ xml.Observation do
|
|
6
6
|
|
7
7
|
xml.ObservationCode do
|
8
8
|
# xml.CodingStandard "2.16.840.1.113883.4.642.2.115"
|
9
|
-
xml.CodingStandard "
|
9
|
+
xml.CodingStandard "PV"
|
10
10
|
xml.Code I18n.t("loinc.#{i18n_key}.code")
|
11
11
|
xml.Description I18n.t("loinc.#{i18n_key}.description")
|
12
12
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
xml = builder
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
# TODO: Implement start stop dates
|
4
|
+
# xml.LabOrders (start: Time.zone.today.iso8601, stop: Time.zone.today.iso8601) do
|
5
|
+
xml.LabOrders do
|
6
6
|
render partial: "renalware/api/ukrdc/patients/lab_orders/lab_order",
|
7
7
|
collection: patient.observation_requests.includes(
|
8
8
|
:description,
|
@@ -4,7 +4,9 @@
|
|
4
4
|
# - bp
|
5
5
|
xml = builder
|
6
6
|
|
7
|
-
|
7
|
+
# TODO: Implement start stop dates
|
8
|
+
# xml.Observations do(start: Time.zone.today.iso8601, stop: Time.zone.today.iso8601) do
|
9
|
+
xml.Observations do
|
8
10
|
patient.clinic_visits.includes(:updated_by).each do |visit|
|
9
11
|
render "clinic_visit_observation",
|
10
12
|
visit: visit,
|
@@ -20,7 +20,7 @@ xml.LabOrder do
|
|
20
20
|
xml.OrderCategory do
|
21
21
|
xml.Code request.description.code
|
22
22
|
end
|
23
|
-
xml.SpecimenCollectedTime request.requested_at.iso8601
|
23
|
+
# xml.SpecimenCollectedTime request.requested_at.iso8601
|
24
24
|
# xml.SpecimenReceivedTime "TODO"
|
25
25
|
# xml.Priority do
|
26
26
|
# xml.Code "TODO: Probably n/a"
|
@@ -30,7 +30,7 @@ xml.LabOrder do
|
|
30
30
|
|
31
31
|
xml.ResultItems do
|
32
32
|
render partial: "renalware/api/ukrdc/patients/lab_orders/result_item",
|
33
|
-
collection: request.observations,
|
33
|
+
collection: request.observations.having_a_loinc_code,
|
34
34
|
as: :observation,
|
35
35
|
locals: { builder: builder, patient: patient }
|
36
36
|
end
|
@@ -7,8 +7,13 @@ xml.ResultItem do
|
|
7
7
|
xml.EnteredOn observation.updated_at&.iso8601
|
8
8
|
xml.PrePost observation.pre_post(patient_is_on_hd: patient.current_modality_hd?)
|
9
9
|
xml.ServiceId do
|
10
|
-
|
11
|
-
|
10
|
+
if observation.description_loinc_code.present?
|
11
|
+
xml.CodingStandard "PV"
|
12
|
+
xml.Code observation.description_loinc_code
|
13
|
+
else
|
14
|
+
xml.CodingStandard "LOCAL"
|
15
|
+
xml.Code observation.description_code
|
16
|
+
end
|
12
17
|
xml.Description observation.description_name
|
13
18
|
end
|
14
19
|
# xml.SubId
|
@@ -0,0 +1,47 @@
|
|
1
|
+
ruby:
|
2
|
+
header = local_assigns[:header] || Renalware::Clinical::HeaderPresenter.new(patient)
|
3
|
+
current_pathology = header.current_pathology
|
4
|
+
|
5
|
+
.clinical-header.lozenge
|
6
|
+
ul
|
7
|
+
li
|
8
|
+
dl
|
9
|
+
dt= t(".blood_pressure")
|
10
|
+
- result = header.blood_pressure_measurement.compact.join("/")
|
11
|
+
- if result.present?
|
12
|
+
dd= result
|
13
|
+
dd.date= l(header.blood_pressure_date)
|
14
|
+
- else
|
15
|
+
dd.empty
|
16
|
+
li
|
17
|
+
dl
|
18
|
+
dt= t(".weight")
|
19
|
+
- result = header.weight_measurement
|
20
|
+
- if result.present?
|
21
|
+
dd= "#{result} kg"
|
22
|
+
dd.date= l(header.weight_date)
|
23
|
+
- else
|
24
|
+
dd.empty
|
25
|
+
li
|
26
|
+
dl
|
27
|
+
dt= t(".height")
|
28
|
+
- result = header.height_measurement
|
29
|
+
- if result.present?
|
30
|
+
dd= "#{result} m"
|
31
|
+
- else
|
32
|
+
dd.empty
|
33
|
+
li
|
34
|
+
dl
|
35
|
+
dt= t(".bmi")
|
36
|
+
dd= header.bmi_measurement
|
37
|
+
|
38
|
+
- %i(hgb cre pot egfr ure).each do |code|
|
39
|
+
li
|
40
|
+
dl
|
41
|
+
dt= t(".#{code}")
|
42
|
+
- result = current_pathology.send(:"#{code}_result")
|
43
|
+
- if result.present?
|
44
|
+
dd= result
|
45
|
+
dd.date= l(current_pathology.send(:"#{code}_observed_at"))
|
46
|
+
- else
|
47
|
+
dd.empty
|
@@ -8,13 +8,16 @@ table.global-clinic-visits
|
|
8
8
|
th.col-width-nhs-no NHS Number
|
9
9
|
th.col-width-tiny Sex
|
10
10
|
th.col-width-tiny Age
|
11
|
-
th.col-width-
|
11
|
+
th.col-width-medium Modality
|
12
12
|
th.col-width-medium Clinic Type
|
13
13
|
th.col-width-tiny BMI
|
14
14
|
th.col-width-tiny BP
|
15
15
|
th.no-print
|
16
16
|
th.col-width-medium Created by
|
17
17
|
tbody
|
18
|
+
/ Note we can't use cached: true yet when rendering the events collection, as each row is
|
19
|
+
/ used in a different context and displays there slightly differently, for example showing
|
20
|
+
/ an Edit link or Type column in certain circumstances.
|
18
21
|
= render partial: "table_row",
|
19
22
|
collection: clinic_visits,
|
20
23
|
as: :clinic_visit
|
@@ -9,7 +9,7 @@ tr
|
|
9
9
|
= link_to("Edit", edit_proc.call(event))
|
10
10
|
|
11
11
|
td.nowrap= l event.created_at.to_date
|
12
|
-
- unless local_assigns
|
12
|
+
- unless local_assigns[:exclude_type_column] == true
|
13
13
|
td= event.event_type
|
14
14
|
td.col-width-medium-with-ellipsis
|
15
15
|
= render partial: "renalware/events/events/cell/#{event.to_partial_path}",
|
@@ -11,6 +11,9 @@ table.has-togglable-rows.events-table
|
|
11
11
|
th.created_at.col-width-date-time= t(".date_time")
|
12
12
|
th.created_by.col-width-medium= t(".created_by")
|
13
13
|
tbody
|
14
|
+
/ Note we can't use cached: true yet when rendering the events collection, as each row is
|
15
|
+
/ used in a different context and displays there slightly differently, for example showing
|
16
|
+
/ an Edit link or Type column in certain circumstances.
|
14
17
|
= render partial: "renalware/events/events/event",
|
15
18
|
collection: events,
|
16
19
|
locals: { exclude_type_column: local_assigns[:exclude_type_column],
|
@@ -8,6 +8,7 @@
|
|
8
8
|
.patient-content.full-screenable
|
9
9
|
.layout-wrapper
|
10
10
|
= render "renalware/patients/mini_profile", patient: current_patient
|
11
|
+
= render "renalware/clinical/header", patient: current_patient
|
11
12
|
= render "renalware/patients/alerts/list", patient: current_patient
|
12
13
|
.row.collapse
|
13
14
|
- if local_assigns[:title].present?
|
@@ -29,7 +29,7 @@ ruby:
|
|
29
29
|
}
|
30
30
|
= hidden_field_tag "description_id"
|
31
31
|
= f.input :clinical, as: :hidden
|
32
|
-
= f.input :issued_on, as: :date_picker
|
32
|
+
= f.input :issued_on, as: :date_picker, wrapper: :horizontal_datepicker
|
33
33
|
= f.association :author,
|
34
34
|
as: :user_picker,
|
35
35
|
collection: Renalware::System::UsersPresenter.new.list_for_dropdown( \
|
@@ -7,7 +7,7 @@ table#patients.mdm-patients.columns
|
|
7
7
|
th.col-width-reference-no= t(".hosp_no")
|
8
8
|
th.col-width-tiny= t(".sex")
|
9
9
|
th.col-width-tiny= t(".age")
|
10
|
-
th.col-width-
|
10
|
+
th.col-width-medium= t(".modality")
|
11
11
|
- %i(hgb ure cre).each do |code|
|
12
12
|
th.col-width-tiny= sort_link(path, code, t(".#{code}"))
|
13
13
|
th.col-width-date= sort_link(path, :"#{code}_date", t(".#{code}_date"))
|
@@ -1,7 +1,7 @@
|
|
1
1
|
dl.sub-nav
|
2
2
|
dd= link_to "Historical", patient_pathology_historical_observations_path(@patient)
|
3
3
|
dd= link_to "Current", patient_pathology_current_observations_path(@patient)
|
4
|
-
dd= link_to "Recent", patient_pathology_recent_observations_path(@patient)
|
4
|
+
/ dd= link_to "Recent", patient_pathology_recent_observations_path(@patient)
|
5
5
|
dd= link_to "Investigations", patient_pathology_observation_requests_path(@patient)
|
6
6
|
dd= link_to "Required Observations", patient_pathology_required_observations_path(@patient)
|
7
7
|
dd= link_to "New Patient Rule", new_patient_pathology_patient_rule_path(@patient)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
table#patients
|
2
2
|
thead
|
3
3
|
tr
|
4
|
-
th.col-width-
|
4
|
+
th.col-width-large= attr_name(Renalware::Patient, :name)
|
5
5
|
th.col-width-nhs-no NHS Number
|
6
6
|
- Renalware.config.patient_hospital_identifiers.each_key do |key|
|
7
7
|
th.col-width-reference-without-prefix="#{key} No"
|
@@ -10,7 +10,7 @@ table#patients
|
|
10
10
|
th.col-width-tiny= attr_name(Renalware::Patient, :age)
|
11
11
|
th.col-width-tiny= sort_link(search, :send_to_rpv, "RPV")
|
12
12
|
th.col-width-tiny= sort_link(search, :send_to_renalreg, "RReg")
|
13
|
-
th.col-width-
|
13
|
+
th.col-width-medium Modality
|
14
14
|
|
15
15
|
tbody
|
16
16
|
= render partial: "patient", collection: patients
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "core_extensions/i18n/handle_blank_value"
|
2
2
|
require "core_extensions/i18n/always_cascade"
|
3
3
|
require "core_extensions/dumb_delegator"
|
4
|
+
require "core_extensions/active_record/migration_helpers"
|
4
5
|
require "core_extensions/active_record/sort"
|
5
6
|
require "core_extensions/date"
|
6
7
|
require "core_extensions/active_support/duration"
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION audit_view_as_json(view_name text)
|
2
|
+
/*
|
3
|
+
Converts the specified view into its json representation suitable for feeding for example
|
4
|
+
into jQuery datatables plugin, or creating a historical snapshot.
|
5
|
+
Example usage:
|
6
|
+
select audit_view_as_json('reporting_bone_audit')
|
7
|
+
TC 1.11.2017
|
8
|
+
*/
|
9
|
+
RETURNS json
|
10
|
+
LANGUAGE 'plpgsql'
|
11
|
+
as $$
|
12
|
+
DECLARE result json;
|
13
|
+
BEGIN
|
14
|
+
EXECUTE format('
|
15
|
+
select row_to_json(t)
|
16
|
+
from (
|
17
|
+
select
|
18
|
+
current_timestamp as runat,
|
19
|
+
(select array_to_json(array_agg(row_to_json(d))
|
20
|
+
)
|
21
|
+
from (select * from %s) d) as data) t;
|
22
|
+
', quote_ident(view_name)) into result;
|
23
|
+
return result;
|
24
|
+
END
|
25
|
+
$$;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
A plpgsql function by Michael Fuhr for faster counting.
|
3
|
+
See https://wiki.postgresql.org/wiki/Count_estimate
|
4
|
+
Normal count(*) can be slow where that are millions of rows.
|
5
|
+
This is a faster way to count filtered rows by parsing the output of an explain query.
|
6
|
+
*/
|
7
|
+
CREATE FUNCTION count_estimate(query text) RETURNS INTEGER AS
|
8
|
+
$func$
|
9
|
+
DECLARE
|
10
|
+
rec record;
|
11
|
+
ROWS INTEGER;
|
12
|
+
BEGIN
|
13
|
+
FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP
|
14
|
+
ROWS := SUBSTRING(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)');
|
15
|
+
EXIT WHEN ROWS IS NOT NULL;
|
16
|
+
END LOOP;
|
17
|
+
|
18
|
+
RETURN ROWS;
|
19
|
+
END
|
20
|
+
$func$ LANGUAGE plpgsql;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION generate_patient_secure_id()
|
2
|
+
/*
|
3
|
+
Generates and returns a unique base 58 token 24 characters long for use as a secure_id on
|
4
|
+
the Renalware patients table. If the generated token is in use already (very unlikely) it
|
5
|
+
retries until a unique one is generated.
|
6
|
+
Example usage:
|
7
|
+
select generate_patient_secure_id #=> 0KPNXf4X5x1o6O4mXWE5MC9H
|
8
|
+
TC 8.6.2017
|
9
|
+
*/
|
10
|
+
RETURNS varchar AS $$
|
11
|
+
DECLARE
|
12
|
+
new_secure_id varchar;
|
13
|
+
BEGIN
|
14
|
+
LOOP
|
15
|
+
new_secure_id := generate_secure_id(24);
|
16
|
+
EXIT WHEN NOT EXISTS(select 1 from patients where 'secure_id' = new_secure_id);
|
17
|
+
RAISE NOTICE 'The generated secure_id % was already in use - now generating another', new_secure_id;
|
18
|
+
END LOOP;
|
19
|
+
RETURN new_secure_id;
|
20
|
+
END
|
21
|
+
$$ LANGUAGE plpgsql;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION generate_secure_id(length integer default 24)
|
2
|
+
/*
|
3
|
+
Generates and returns a unique base 58 token of <length> length for use in for example
|
4
|
+
the obfuscation of database ids in URLs.
|
5
|
+
Note base58 tokens are case sensitive.
|
6
|
+
Example usage:
|
7
|
+
select generate_secure_id(24) #=> 0KPNXf4X5x1o6O4mXWE5MC9H
|
8
|
+
TC 8.6.2017
|
9
|
+
*/
|
10
|
+
RETURNS text AS
|
11
|
+
$body$
|
12
|
+
SELECT string_agg (substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
|
13
|
+
ceil (random() * 62)::integer,
|
14
|
+
1), '')
|
15
|
+
FROM generate_series(1, length)
|
16
|
+
;
|
17
|
+
$body$
|
18
|
+
LANGUAGE sql;
|
@@ -0,0 +1,129 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION renalware.import_gps_csv(file text) RETURNS void
|
2
|
+
AS $$
|
3
|
+
BEGIN
|
4
|
+
-- Imports a egpcur.csv.csv file created from ODS.
|
5
|
+
-- Returns counts of changed (insert/updated) and (soft) deleted rows.
|
6
|
+
|
7
|
+
DROP TABLE IF EXISTS tmp_gps_copy;
|
8
|
+
|
9
|
+
-- Create a tmp table to hold the ODS-defined standard 27 field format into which we will insert out CSV data
|
10
|
+
CREATE TEMP TABLE tmp_gps_copy (
|
11
|
+
code text NOT NULL,
|
12
|
+
name text NOT NULL,
|
13
|
+
unused3 text,
|
14
|
+
unused4 text,
|
15
|
+
street_1 text,
|
16
|
+
street_2 text,
|
17
|
+
street_3 text,
|
18
|
+
town text,
|
19
|
+
county text,
|
20
|
+
postcode text,
|
21
|
+
unused11 text,
|
22
|
+
unused12 text,
|
23
|
+
status text, -- A = Active B = Retired C = Closed P = Proposed
|
24
|
+
unused14 text,
|
25
|
+
unused15 text,
|
26
|
+
unused16 text,
|
27
|
+
unused17 text,
|
28
|
+
telephone text,
|
29
|
+
unused19 text,
|
30
|
+
unused20 text,
|
31
|
+
unused21 text,
|
32
|
+
amended_record_indicator text,
|
33
|
+
unused23 text,
|
34
|
+
unused24 text,
|
35
|
+
unused25 text,
|
36
|
+
unused26 text,
|
37
|
+
unused27 text,
|
38
|
+
CONSTRAINT tmp_gps_pkey PRIMARY KEY (code)
|
39
|
+
);
|
40
|
+
|
41
|
+
-- Import the CSV file into tmp_practices - note there is no CSV header in this file
|
42
|
+
EXECUTE format ('COPY tmp_gps_copy FROM %L DELIMITER %L CSV ', file, ',');
|
43
|
+
|
44
|
+
DROP TABLE IF EXISTS tmp_gps;
|
45
|
+
CREATE TEMP TABLE tmp_gps AS SELECT
|
46
|
+
code,
|
47
|
+
name,
|
48
|
+
telephone,
|
49
|
+
street_1,
|
50
|
+
street_2,
|
51
|
+
street_3,
|
52
|
+
town,
|
53
|
+
county,
|
54
|
+
postcode,
|
55
|
+
left(status,1) as status from tmp_gps_copy ;
|
56
|
+
ALTER TABLE tmp_gps ADD PRIMARY KEY (code);
|
57
|
+
|
58
|
+
RAISE NOTICE 'Calling cs_create_job(%)', (select status from tmp_gps limit 1);
|
59
|
+
|
60
|
+
-- Upsert GPs
|
61
|
+
WITH
|
62
|
+
data AS (select * from tmp_gps),
|
63
|
+
gp_changes AS (
|
64
|
+
INSERT INTO renalware.patient_primary_care_physicians (code, name, telephone, practitioner_type, created_at, updated_at)
|
65
|
+
SELECT code, name, telephone, 'GP', clock_timestamp(), clock_timestamp()
|
66
|
+
FROM data
|
67
|
+
ON CONFLICT (code) DO UPDATE
|
68
|
+
SET
|
69
|
+
telephone = excluded.telephone,
|
70
|
+
name = excluded.name,
|
71
|
+
updated_at = excluded.updated_at
|
72
|
+
where (patient_primary_care_physicians.telephone) is distinct from (excluded.telephone)
|
73
|
+
RETURNING code, id
|
74
|
+
)
|
75
|
+
|
76
|
+
-- Upsert GP addresses
|
77
|
+
INSERT INTO renalware.addresses (
|
78
|
+
addressable_type,
|
79
|
+
addressable_id,
|
80
|
+
street_1,
|
81
|
+
street_2,
|
82
|
+
street_3,
|
83
|
+
town,
|
84
|
+
county,
|
85
|
+
postcode,
|
86
|
+
created_at,
|
87
|
+
updated_at)
|
88
|
+
SELECT
|
89
|
+
'Renalware::Patients::PrimaryCarePhysician' as addressable_type,
|
90
|
+
gps.id as addressable_id,
|
91
|
+
street_1,
|
92
|
+
street_2,
|
93
|
+
street_3,
|
94
|
+
town,
|
95
|
+
county,
|
96
|
+
postcode,
|
97
|
+
CURRENT_TIMESTAMP as created_at,
|
98
|
+
CURRENT_TIMESTAMP as updated_at
|
99
|
+
FROM data join patient_primary_care_physicians gps using(code)
|
100
|
+
ON CONFLICT (addressable_type, addressable_id) DO UPDATE
|
101
|
+
SET
|
102
|
+
street_1 = excluded.street_1,
|
103
|
+
street_2 = excluded.street_2,
|
104
|
+
street_3 = excluded.street_3,
|
105
|
+
town = excluded.town,
|
106
|
+
county = excluded.county,
|
107
|
+
postcode = excluded.postcode,
|
108
|
+
updated_at = clock_timestamp()
|
109
|
+
where (addresses.street_1, addresses.street_2, addresses.street_3)
|
110
|
+
is distinct from (excluded.street_1, excluded.street_2, excluded.street_3);
|
111
|
+
|
112
|
+
--GET DIAGNOSTICS changed_count = ROW_COUNT;
|
113
|
+
|
114
|
+
-- Update the deleted_at column of any gps which do not have an Active status_code
|
115
|
+
UPDATE renalware.patient_primary_care_physicians AS p
|
116
|
+
SET deleted_at = CURRENT_TIMESTAMP
|
117
|
+
FROM tmp_gps AS tp
|
118
|
+
WHERE p.code = tp.code AND tp.status IN ('C', 'P', 'B');
|
119
|
+
|
120
|
+
-- Un-delete any previously deleted GPs
|
121
|
+
UPDATE renalware.patient_primary_care_physicians AS gp
|
122
|
+
SET deleted_at = NULL
|
123
|
+
FROM tmp_gps
|
124
|
+
WHERE gp.code = tmp_gps.code AND tmp_gps.status IN ('A') AND gp.code NOT IN ('A');
|
125
|
+
|
126
|
+
--GET DIAGNOSTICS deleted_count = ROW_COUNT;
|
127
|
+
--select changed_count, deleted_count;
|
128
|
+
END;
|
129
|
+
$$ LANGUAGE plpgsql;
|