15.3.18. crate_anon.crateweb.consent.models¶
Copyright (C) 2015-2018 Rudolf Cardinal (rudolf@pobox.com).
This file is part of CRATE.
CRATE is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
CRATE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with CRATE. If not, see <http://www.gnu.org/licenses/>.
-
class
crate_anon.crateweb.consent.models.
CharityPaymentRecord
(id, created_at, payee, amount)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
ClinicianResponse
(id, created_at, contact_request, token, responded, responded_at, response_route, email_choice, response, veto_reason, ineligible_reason, pt_uncontactable_reason, clinician_confirm_name, charity_amount_due, processed, processed_at)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
ConsentMode
(id, decision_signed_by_patient, decision_otherwise_directly_authorized_by_patient, decision_under16_signed_by_parent, decision_under16_signed_by_clinician, decision_lack_capacity_signed_by_representative, decision_lack_capacity_signed_by_clinician, nhs_number, current, created_at, created_by, exclude_entirely, consent_mode, consent_after_discharge, max_approaches_per_year, other_requests, prefers_email, changed_by_clinician_override, source, skip_letter_to_patient, needs_processing, processed, processed_at)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
consider_withdrawal
() → None[source]¶ If required, withdraw consent for other studies.
Note that as per Major Amendment 1 to 12/EE/0407, this happens automatically, rather than having a special flag to control it.
-
get_confirm_traffic_to_patient_letter_html
() → str[source]¶ REC DOCUMENT 07. Confirming patient’s traffic-light choice.
-
classmethod
get_or_create
(nhs_number: int, created_by: auth.User) → ConsentMode[source]¶ Fetches the current ConsentMode for this patient. If there isn’t one, creates a default one and returns that.
-
classmethod
get_or_none
(nhs_number: int) → Union[ConsentMode, NoneType][source]¶ Fetches the current ConsentMode for this patient. If there isn’t one, returns None
-
process_change
() → None[source]¶ Called upon saving. Will create a letter to patient. May create a withdrawal-of-consent letter to researcher.
Major Amendment 1 (Oct 2014) to 12/EE/0407: always withdraw consent and tell researchers, i.e. “active cancellation” of ongoing permission, where the researchers have not yet made contact.
-
classmethod
refresh_from_primary_clinical_record
(nhs_number: int, created_by: auth.User, source_db: str = None) → List[str][source]¶ Checks the primary clinical record and CRATE’s own records for consent modes for this patient. If the most recent one is in the external database, copies it to CRATE’s database and marks that one as current.
This has the effect that external primary clinical records (e.g. RiO) take priority, but if there’s no record in RiO, we can still proceed.
Returns a list of human-readable decisions.
Internally, we do this:
- Fetch the most recent record.
- If its date is later than the most recent CRATE record:
- create a new ConsentMode with (…, source=source_db)
- save it
Todo
also: use celery beat to refresh regularly +/- trigger withdrawal of consent if consent mode changed; http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html
Todo
also make automatic opt-out list
-
save
(*args, **kwargs) → None[source]¶ Custom save method. Ensures that only one ConsentMode has current == True for a given patient.
Better than a get_latest_by clause, because with a flag like this, we can have a simple query that says “get the current records for all patients” – harder if done by date (group by patient, order by patient/date, pick last one for each patient…).
-
exception
-
class
crate_anon.crateweb.consent.models.
ContactRequest
(id, created_at, request_by, study, request_direct_approach, lookup_nhs_number, lookup_rid, lookup_mrid, processed, processed_at, nhs_number, patient_lookup, consent_mode, approaches_in_past_year, decisions, decided_no_action, decided_send_to_researcher, decided_send_to_clinician, clinician_involvement, consent_withdrawn, consent_withdrawn_at)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
classmethod
create
(request: django.http.request.HttpRequest, study: crate_anon.crateweb.consent.models.Study, request_direct_approach: bool, lookup_nhs_number: int = None, lookup_rid: str = None, lookup_mrid: str = None) → crate_anon.crateweb.consent.models.ContactRequest[source]¶ Create a contact request and act on it.
-
get_clinician_email_html
(save: bool = True) → str[source]¶ REC DOCUMENTS 09, 11, 13 (A): E-mail to clinician E-mail to clinician asking them to pass on contact request.
URL method (path, querystring, both?): see notes in core/utils.py
In this case, decision: since we are creating a ClinicianResponse, we should use its ModelForm.
- URL path for PK
- querystring for other parameters, with form-based validation
-
get_letter_clinician_to_pt_re_study
() → str[source]¶ REC DOCUMENTS 10, 12, 14: draft letters from clinician to patient, with decision form.
-
get_permission_date
() → Union[datetime.datetime, NoneType][source]¶ When was the researcher given permission? Used for the letter withdrawing permission.
-
exception
-
class
crate_anon.crateweb.consent.models.
DummyPatientSourceInfo
(id, pt_local_id_description, pt_local_id_number, pt_dob, pt_dod, pt_dead, pt_discharged, pt_discharge_date, pt_sex, pt_title, pt_first_name, pt_last_name, pt_address_1, pt_address_2, pt_address_3, pt_address_4, pt_address_5, pt_address_6, pt_address_7, pt_telephone, pt_email, gp_title, gp_first_name, gp_last_name, gp_address_1, gp_address_2, gp_address_3, gp_address_4, gp_address_5, gp_address_6, gp_address_7, gp_telephone, gp_email, clinician_title, clinician_first_name, clinician_last_name, clinician_address_1, clinician_address_2, clinician_address_3, clinician_address_4, clinician_address_5, clinician_address_6, clinician_address_7, clinician_telephone, clinician_email, clinician_is_consultant, clinician_signatory_title, nhs_number)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
Email
(id, created_at, sender, recipient, subject, msg_text, msg_html, to_clinician, to_researcher, to_patient, study, contact_request, letter)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
EmailAttachment
(*args, **kwargs)[source]¶ E-mail attachment class that does NOT manage its own files, i.e. if the attachment object is deleted, the files won’t be. Use this for referencing files already stored elsewhere in the database.
-
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
EmailTransmission
(id, email, at, by, sent, failure_reason)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
Leaflet
(id, name, pdf)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
Letter
(id, created_at, pdf, to_clinician, to_researcher, to_patient, rdbm_may_view, study, contact_request, sent_manually_at)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
PatientLookup
(*args, **kwargs)[source]¶ Represents a moment of lookup up identifiable data about patient, GP, and clinician from the relevant clinical database.
Inherits from PatientLookupBase so it has the same fields, and more.
-
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
PatientLookupBase
(*args, **kwargs)[source]¶ Base class for PatientLookup and DummyPatientSourceInfo. Must be able to be instantiate with defaults, for the “not found” situation.
-
class
crate_anon.crateweb.consent.models.
PatientResponse
(id, decision_signed_by_patient, decision_otherwise_directly_authorized_by_patient, decision_under16_signed_by_parent, decision_under16_signed_by_clinician, decision_lack_capacity_signed_by_representative, decision_lack_capacity_signed_by_clinician, created_at, contact_request, recorded_by, response, processed, processed_at)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
Study
(id, institutional_id, title, lead_researcher, registered_at, summary, search_methods_planned, patient_contact, include_under_16s, include_lack_capacity, clinical_trial, include_discharged, request_direct_approach, approved_by_rec, rec_reference, approved_locally, local_approval_at, study_details_pdf, subject_form_template_pdf)[source]¶ -
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
class
crate_anon.crateweb.consent.models.
TeamInfo
[source]¶ Class only exists to be able to use @cached_property.
-
class
crate_anon.crateweb.consent.models.
TeamRep
(*args, **kwargs)[source]¶ Clinical team representatives are recorded in CRATE.
-
exception
DoesNotExist
¶
-
exception
MultipleObjectsReturned
¶
-
exception
-
crate_anon.crateweb.consent.models.
auto_delete_emailattachment_files_on_change
(sender: Type[crate_anon.crateweb.consent.models.EmailAttachment], instance: crate_anon.crateweb.consent.models.EmailAttachment, **kwargs) → None[source]¶ Deletes files from filesystem when EmailAttachment object is changed.
-
crate_anon.crateweb.consent.models.
auto_delete_emailattachment_files_on_delete
(sender: Type[crate_anon.crateweb.consent.models.EmailAttachment], instance: crate_anon.crateweb.consent.models.EmailAttachment, **kwargs) → None[source]¶ Deletes files from filesystem when EmailAttachment object is deleted.
-
crate_anon.crateweb.consent.models.
auto_delete_leaflet_files_on_change
(sender: Type[crate_anon.crateweb.consent.models.Leaflet], instance: crate_anon.crateweb.consent.models.Leaflet, **kwargs) → None[source]¶ Deletes files from filesystem when Leaflet object is changed.
-
crate_anon.crateweb.consent.models.
auto_delete_leaflet_files_on_delete
(sender: Type[crate_anon.crateweb.consent.models.Leaflet], instance: crate_anon.crateweb.consent.models.Leaflet, **kwargs) → None[source]¶ Deletes files from filesystem when Leaflet object is deleted.
-
crate_anon.crateweb.consent.models.
auto_delete_letter_files_on_change
(sender: Type[crate_anon.crateweb.consent.models.Letter], instance: crate_anon.crateweb.consent.models.Letter, **kwargs) → None[source]¶ Deletes files from filesystem when Letter object is changed.
-
crate_anon.crateweb.consent.models.
auto_delete_letter_files_on_delete
(sender: Type[crate_anon.crateweb.consent.models.Letter], instance: crate_anon.crateweb.consent.models.Letter, **kwargs) → None[source]¶ Deletes files from filesystem when Letter object is deleted.
-
crate_anon.crateweb.consent.models.
auto_delete_study_files_on_change
(sender: Type[crate_anon.crateweb.consent.models.Study], instance: crate_anon.crateweb.consent.models.Study, **kwargs) → None[source]¶ Deletes files from filesystem when Study object is changed.
-
crate_anon.crateweb.consent.models.
auto_delete_study_files_on_delete
(sender: Type[crate_anon.crateweb.consent.models.Study], instance: crate_anon.crateweb.consent.models.Study, **kwargs) → None[source]¶ Deletes files from filesystem when Study object is deleted.
-
crate_anon.crateweb.consent.models.
leaflet_upload_to
(instance: crate_anon.crateweb.consent.models.Leaflet, filename: str) → str[source]¶ Determines the filename used for leaflet uploads.
Parameters: - instance – instance of Leaflet (potentially unsaved) … and you can’t call save(); it goes into infinite recursion
- filename – uploaded filename
-
crate_anon.crateweb.consent.models.
make_dummy_objects
(request: django.http.request.HttpRequest) → crate_anon.crateweb.consent.models.DummyObjectCollection[source]¶ We want to create these objects in memory, without saving to the DB. However, Django is less good at SQLAlchemy for this, and saves.
- http://stackoverflow.com/questions/7908349/django-making-relationships-in-memory-without-saving-to-db # noqa
- https://code.djangoproject.com/ticket/17253
- http://stackoverflow.com/questions/23372786/django-models-assigning-foreignkey-object-without-saving-to-database # noqa
- http://stackoverflow.com/questions/7121341/django-adding-objects-to-a-related-set-without-saving-to-db # noqa
A simple method works for an SQLite backend database but fails with an IntegrityError for MySQL/SQL Server. For example:
IntegrityError at /draft_traffic_light_decision_form/-1/html/ (1452, ‘Cannot add or update a child row: a foreign key constraint fails (crate_django.`consent_study_researchers`, CONSTRAINT consent_study_researchers_study_id_19bb255f_fk_consent_study_id FOREIGN KEY (study_id) REFERENCES consent_study (id))’)This occurs in the first creation, of a Study, and only if you specify ‘researchers’.
The reason for the crash is that ‘researchers’ is a ManyToManyField, and Django is trying to set the user.studies_as_researcher back-reference, but can’t do so because the Study doesn’t have a PK yet.
Since this is a minor thing, and templates are unaffected, and this is only for debugging, let’s ignore it.
-
crate_anon.crateweb.consent.models.
study_details_upload_to
(instance: crate_anon.crateweb.consent.models.Study, filename: str) → str[source]¶ Determines the filename used for study information PDF uploads.
Parameters: - instance – instance of Study (potentially unsaved) … and you can’t call save(); it goes into infinite recursion
- filename – uploaded filename