Class: Renalware::UKRDC::PatientPresenter

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
app/presenters/renalware/ukrdc/patient_presenter.rb

Constant Summary collapse

UKRDC_MAX_PHONE_LEN =
80

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(patient, changes_since: nil) ⇒ PatientPresenter

rubocop:disable Metrics/MethodLength



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 16

def initialize(patient, changes_since: nil)
  if changes_since.present? && changes_since.is_a?(String)
    changes_since = Time.zone.parse(changes_since)
  end
  # TODO: document what's happening here with dates
  @changes_since = changes_since ||
                   patient.sent_to_ukrdc_at ||
                   Renalware.config.ukrdc_default_changes_since_date
  if @changes_since.blank?
    raise(
      ArgumentError,
      "No date for comparison: patient#sent_to_ukrdc_at and changes_since are nil"
    )
  end
  @changes_up_until = Time.zone.now
  super(patient)
end

Instance Attribute Details

#changes_sinceObject (readonly)

Returns the value of attribute changes_since.



11
12
13
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 11

def changes_since
  @changes_since
end

#changes_up_untilObject (readonly)

Returns the value of attribute changes_up_until.



11
12
13
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 11

def changes_up_until
  @changes_up_until
end

Instance Method Details

#allergiesObject



88
89
90
91
92
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 88

def allergies
  clinical_patient
    .allergies
    .where("recorded_at >= ?", changes_since)
end

#clinic_visitsObject



94
95
96
97
98
99
100
101
102
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 94

def clinic_visits
  @clinic_visits ||= begin
    visits = clinics_patient
      .clinic_visits
      .where("date >= ?", changes_since)
      .includes(:updated_by)
    CollectionPresenter.new(visits, Clinics::ClinicVisitPresenter)
  end
end

#clinical_historyObject



158
159
160
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 158

def clinical_history
  @clinical_history ||= document&.history || NullObject.instance
end

#current_modality_hd?Boolean

Returns:

  • (Boolean)


45
46
47
48
49
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 45

def current_modality_hd?
  return false if current_modality.blank?

  current_modality.description.is_a?(Renalware::HD::ModalityDescription)
end

#current_registration_status_rr_codeObject



77
78
79
80
81
82
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 77

def current_registration_status_rr_code
  @current_registration_status_rr_code ||= begin
    status = transplant_patient.current_registration_status
    status&.description&.rr_code
  end
end

#dead?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 41

def dead?
  current_modality_death?
end

#esrf_onObject



180
181
182
183
184
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 180

def esrf_on
  return if profile.esrf_on.blank?

  profile.esrf_on.to_time.iso8601
end

#finished_hd_sessionsObject

Use DISTINCT ON (performed_on) and an order(performed_on: :desc) to make sure we only get one hd session per day - the last of the day. This is becuase currrently RW allows a duplicate session to be added, and this occasionally happens.



68
69
70
71
72
73
74
75
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 68

def finished_hd_sessions
  hd_patient
    .finished_hd_sessions
    .includes(:patient, :dialysate, :updated_by)
    .select("distinct on (hd_sessions.performed_on) *")
    .where("hd_sessions.updated_at > ?", changes_since)
    .order(performed_on: :desc)
end

#first_seen_onObject



174
175
176
177
178
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 174

def first_seen_on
  return if profile.first_seen_on.blank?

  profile.first_seen_on.to_time.iso8601
end

#hospital_unit_codeObject



84
85
86
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 84

def hospital_unit_code
  letter_head.site_code
end

#languageObject

rubocop:enable Metrics/MethodLength



35
36
37
38
39
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 35

def language
  return if super.nil? || super.name == "Unknown"

  super
end

#lettersObject

Note we of course only send letters for RPV patients and exclude them for all others.



52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 52

def letters
  return ::Renalware::Letters::Letter.none if send_to_rpv == false

  CollectionPresenter.new(
    letters_patient
      .letters
      .approved_or_completed
      .includes(:updated_by, :author, :letterhead, :archive)
      .where("updated_at > ?", changes_since),
    Renalware::Letters::LetterPresenterFactory
  )
end

#observation_requestsObject



123
124
125
126
127
128
129
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 123

def observation_requests
  requests = UKRDC::PathologyObservationRequestsQuery.new(
    patient_id: id,
    changes_since: changes_since
  ).call
  CollectionPresenter.new(requests, UKRDC::PathologyObservationRequestPresenter)
end

#prescriptions_with_numeric_dose_amountObject

We always send the patients current prescriptions. Because the XSD rejects non-numeric dose amounts, only send prescriptions with a dose_amount of eg 10 or 10.23 or .23



115
116
117
118
119
120
121
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 115

def prescriptions_with_numeric_dose_amount
  __getobj__
    .prescriptions
    .includes(:termination, :medication_route, :drug)
    .where("dose_amount ~ '^[ ]*(\\d+|\\d+\\.\\d+|\\.\\d+)[ ]*$'")
    .order(:prescribed_on)
end

#profileObject



170
171
172
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 170

def profile
  renal_patient.profile || Renalware::Renal::Profile.new
end

#rr_smoking_historyObject



152
153
154
155
156
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 152

def rr_smoking_history
  return unless smoking_history?

  clinical_history.smoking_rr
end

#smoking_cormbidityObject



166
167
168
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 166

def smoking_cormbidity
  comorbidity_attributes[:smoking]
end

#smoking_history?Boolean

Returns:

  • (Boolean)


162
163
164
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 162

def smoking_history?
  clinical_history.smoking.present?
end

#snomed_smoking_historyObject



146
147
148
149
150
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 146

def snomed_smoking_history
  return unless smoking_history?

  OpenStruct.new(clinical_history.smoking_snomed)
end

#transplant_operationsObject



186
187
188
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 186

def transplant_operations
  Transplants::RecipientOperation.for_patient(id).order(performed_on: :asc)
end

#treatmentsObject



104
105
106
107
108
109
110
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 104

def treatments
  @treatments ||= begin
    UKRDC::Treatment.where(patient_id: id).delete_all
    UKRDC::TreatmentTimeline::GenerateTimeline.new(self).call
    UKRDC::Treatment.where(patient_id: id).order(:patient_id, :started_on)
  end
end

#yes_comorbiditiesObject

Return comorbidities marked as Yes. UKRDC expects a date time and we only have the year, so convert to midnight Jan 1



133
134
135
136
137
138
139
140
141
142
143
144
# File 'app/presenters/renalware/ukrdc/patient_presenter.rb', line 133

def yes_comorbidities
  comorbidity_attributes.each_with_object([]) do |attr, arr|
    name, value = attr
    next unless value.respond_to?(:confirmed_on_year) && value.status == "yes"

    arr << OpenStruct.new(
      name: comorbidities.class.human_attribute_name(name),
      date: comorbidity_date_time_from_year(value.confirmed_on_year),
      code: comorbidities.class.snomed_code_for(name)
    )
  end
end