Coverage for crateweb/consent/migrations/0001_initial.py: 100%
9 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
1"""
2crate_anon/crateweb/consent/migrations/0001_initial.py
4===============================================================================
6 Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
9 This file is part of CRATE.
11 CRATE is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 CRATE is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with CRATE. If not, see <https://www.gnu.org/licenses/>.
24===============================================================================
26**Consent app, migration 0001.**
28"""
30from __future__ import unicode_literals
32from cardinal_pythonlib.django.fields.restrictedcontentfile import (
33 ContentTypeRestrictedFileField,
34)
35from django.db import migrations, models
36from django.conf import settings
38import crate_anon.crateweb.consent.models as consent_models
39import crate_anon.crateweb.consent.storage as consent_storage
41# !!! warning !!! some fields hard-code a local file path in /home/rudolf/...
42# ... edited; no default is OK here; see
43# https://docs.djangoproject.com/en/1.9/ref/files/storage/#the-filesystemstorage-class # noqa: E501
46class Migration(migrations.Migration):
48 dependencies = [
49 migrations.swappable_dependency(settings.AUTH_USER_MODEL),
50 ]
52 operations = [
53 migrations.CreateModel(
54 name="CharityPaymentRecord",
55 fields=[
56 (
57 "id",
58 models.AutoField(
59 auto_created=True,
60 serialize=False,
61 primary_key=True,
62 verbose_name="ID",
63 ),
64 ),
65 (
66 "created_at",
67 models.DateTimeField(
68 auto_now_add=True, verbose_name="When created"
69 ),
70 ),
71 ("payee", models.CharField(max_length=255)),
72 (
73 "amount",
74 models.DecimalField(decimal_places=2, max_digits=8),
75 ),
76 ],
77 ),
78 migrations.CreateModel(
79 name="ClinicianResponse",
80 fields=[
81 (
82 "id",
83 models.AutoField(
84 auto_created=True,
85 serialize=False,
86 primary_key=True,
87 verbose_name="ID",
88 ),
89 ),
90 (
91 "created_at",
92 models.DateTimeField(
93 auto_now_add=True, verbose_name="When created"
94 ),
95 ),
96 ("token", models.CharField(max_length=20)),
97 (
98 "responded",
99 models.BooleanField(
100 default=False, verbose_name="Responded?"
101 ),
102 ),
103 (
104 "responded_at",
105 models.DateTimeField(
106 null=True, verbose_name="When responded"
107 ),
108 ),
109 (
110 "response_route",
111 models.CharField(
112 choices=[("e", "E-mail"), ("w", "Web")], max_length=1
113 ),
114 ),
115 (
116 "email_choice",
117 models.CharField(
118 choices=[
119 ("y", "Yes"),
120 ("n", "No"),
121 ("more", "Tell me more"),
122 ],
123 max_length=4,
124 ),
125 ),
126 (
127 "response",
128 models.CharField(
129 choices=[
130 (
131 "R",
132 "R: Clinician asks RDBM to pass request to "
133 "patient",
134 ),
135 (
136 "A",
137 "A: Clinician will pass the request to the "
138 "patient",
139 ),
140 ("B", "B: Clinician vetoes on clinical grounds"),
141 ("C", "C: Patient is definitely ineligible"),
142 (
143 "D",
144 "D: Patient is dead/discharged or details are "
145 "defunct",
146 ),
147 ],
148 max_length=1,
149 ),
150 ),
151 (
152 "veto_reason",
153 models.TextField(
154 blank=True, verbose_name="Reason for clinical veto"
155 ),
156 ),
157 (
158 "ineligible_reason",
159 models.TextField(
160 blank=True, verbose_name="Reason patient is ineligible"
161 ),
162 ),
163 (
164 "pt_uncontactable_reason",
165 models.TextField(
166 blank=True,
167 verbose_name="Reason patient is not contactable",
168 ),
169 ),
170 (
171 "clinician_confirm_name",
172 models.CharField(
173 verbose_name="Type your name to confirm",
174 max_length=255,
175 ),
176 ),
177 (
178 "charity_amount_due",
179 models.DecimalField(
180 default=0, decimal_places=2, max_digits=8
181 ),
182 ),
183 ],
184 ),
185 migrations.CreateModel(
186 name="ConsentMode",
187 fields=[
188 (
189 "id",
190 models.AutoField(
191 auto_created=True,
192 serialize=False,
193 primary_key=True,
194 verbose_name="ID",
195 ),
196 ),
197 (
198 "decision_signed_by_patient",
199 models.BooleanField(
200 default=False,
201 verbose_name="Request signed by patient?",
202 ),
203 ),
204 (
205 "decision_otherwise_directly_authorized_by_patient",
206 models.BooleanField(
207 default=False,
208 verbose_name="Request otherwise directly authorized "
209 "by patient?",
210 ),
211 ),
212 (
213 "decision_under16_signed_by_parent",
214 models.BooleanField(
215 default=False,
216 verbose_name="Patient under 16 and request "
217 "countersigned by parent?",
218 ),
219 ),
220 (
221 "decision_under16_signed_by_clinician",
222 models.BooleanField(
223 default=False,
224 verbose_name="Patient under 16 and request "
225 "countersigned by clinician?",
226 ),
227 ),
228 (
229 "decision_lack_capacity_signed_by_representative",
230 models.BooleanField(
231 default=False,
232 verbose_name="Patient lacked capacity and request "
233 "signed by authorized representative?",
234 ),
235 ),
236 (
237 "decision_lack_capacity_signed_by_clinician",
238 models.BooleanField(
239 default=False,
240 verbose_name="Patient lacked capacity and request "
241 "countersigned by clinician?",
242 ),
243 ),
244 (
245 "nhs_number",
246 models.BigIntegerField(verbose_name="NHS number"),
247 ),
248 ("current", models.BooleanField(default=False)),
249 (
250 "created_at",
251 models.DateTimeField(
252 auto_now_add=True,
253 verbose_name="When was this record created?",
254 ),
255 ),
256 (
257 "exclude_entirely",
258 models.BooleanField(
259 default=False,
260 verbose_name="Exclude patient from Research Database "
261 "entirely?",
262 ),
263 ),
264 (
265 "consent_mode",
266 models.CharField(
267 default="",
268 choices=[
269 ("red", "red"),
270 ("yellow", "yellow"),
271 ("green", "green"),
272 ],
273 verbose_name="Consent mode ('red', 'yellow', 'green')",
274 max_length=10,
275 ),
276 ),
277 (
278 "consent_after_discharge",
279 models.BooleanField(
280 default=False,
281 verbose_name="Consent given to contact patient after "
282 "discharge?",
283 ),
284 ),
285 (
286 "max_approaches_per_year",
287 models.PositiveSmallIntegerField(
288 default=0,
289 verbose_name="Maximum number of approaches "
290 "permissible per year (0 = no limit)",
291 ),
292 ),
293 (
294 "other_requests",
295 models.TextField(
296 blank=True,
297 verbose_name="Other special requests by patient",
298 ),
299 ),
300 (
301 "prefers_email",
302 models.BooleanField(
303 default=False,
304 verbose_name="Patient prefers e-mail contact?",
305 ),
306 ),
307 (
308 "changed_by_clinician_override",
309 models.BooleanField(
310 default=False,
311 verbose_name="Consent mode changed by clinician's "
312 "override?",
313 ),
314 ),
315 (
316 "created_by",
317 models.ForeignKey(
318 to=settings.AUTH_USER_MODEL, on_delete=models.PROTECT
319 ),
320 ),
321 ],
322 options={
323 "abstract": False,
324 },
325 ),
326 migrations.CreateModel(
327 name="ContactRequest",
328 fields=[
329 (
330 "id",
331 models.AutoField(
332 auto_created=True,
333 serialize=False,
334 primary_key=True,
335 verbose_name="ID",
336 ),
337 ),
338 (
339 "created_at",
340 models.DateTimeField(
341 auto_now_add=True, verbose_name="When created"
342 ),
343 ),
344 (
345 "request_direct_approach",
346 models.BooleanField(
347 verbose_name="Request direct contact with patient if "
348 "available (not contact with clinician first)"
349 ),
350 ),
351 (
352 "lookup_nhs_number",
353 models.BigIntegerField(
354 null=True, verbose_name="NHS number used for lookup"
355 ),
356 ),
357 (
358 "lookup_rid",
359 models.CharField(
360 verbose_name="Research ID used for lookup",
361 null=True,
362 max_length=128,
363 ),
364 ),
365 (
366 "lookup_mrid",
367 models.CharField(
368 verbose_name="Master research ID used for lookup",
369 null=True,
370 max_length=128,
371 ),
372 ),
373 ("processed", models.BooleanField(default=False)),
374 (
375 "nhs_number",
376 models.BigIntegerField(
377 null=True, verbose_name="NHS number"
378 ),
379 ),
380 (
381 "approaches_in_past_year",
382 models.PositiveIntegerField(null=True),
383 ),
384 (
385 "decisions",
386 models.TextField(
387 blank=True, verbose_name="Decisions made"
388 ),
389 ),
390 ("decided_no_action", models.BooleanField(default=False)),
391 (
392 "decided_send_to_researcher",
393 models.BooleanField(default=False),
394 ),
395 (
396 "decided_send_to_clinician",
397 models.BooleanField(default=False),
398 ),
399 (
400 "clinician_involvement",
401 models.PositiveSmallIntegerField(
402 choices=[
403 (
404 0,
405 "No clinician involvement required or "
406 "requested",
407 ),
408 (
409 1,
410 "Clinician involvement requested by "
411 "researchers",
412 ),
413 (
414 2,
415 "Clinician involvement required by YELLOW "
416 "consent mode",
417 ),
418 (
419 3,
420 "Clinician involvement required by UNKNOWN "
421 "consent mode",
422 ),
423 ],
424 null=True,
425 ),
426 ),
427 ("consent_withdrawn", models.BooleanField(default=False)),
428 (
429 "consent_withdrawn_at",
430 models.DateTimeField(
431 null=True, verbose_name="When consent withdrawn"
432 ),
433 ),
434 (
435 "consent_mode",
436 models.ForeignKey(
437 to="consent.ConsentMode",
438 on_delete=models.SET_NULL,
439 null=True,
440 ),
441 ),
442 ],
443 ),
444 migrations.CreateModel(
445 name="DummyPatientSourceInfo",
446 fields=[
447 (
448 "id",
449 models.AutoField(
450 auto_created=True,
451 serialize=False,
452 primary_key=True,
453 verbose_name="ID",
454 ),
455 ),
456 (
457 "pt_local_id_description",
458 models.CharField(
459 blank=True,
460 verbose_name="Description of database-specific ID",
461 max_length=100,
462 ),
463 ),
464 (
465 "pt_local_id_number",
466 models.BigIntegerField(
467 blank=True,
468 null=True,
469 verbose_name="Database-specific ID",
470 ),
471 ),
472 (
473 "pt_dob",
474 models.DateField(
475 blank=True,
476 null=True,
477 verbose_name="Patient date of birth",
478 ),
479 ),
480 (
481 "pt_dod",
482 models.DateField(
483 blank=True,
484 null=True,
485 verbose_name="Patient date of death (NULL if alive)",
486 ),
487 ),
488 (
489 "pt_dead",
490 models.BooleanField(
491 default=False, verbose_name="Patient is dead"
492 ),
493 ),
494 (
495 "pt_discharged",
496 models.NullBooleanField(verbose_name="Patient discharged"),
497 ),
498 (
499 "pt_sex",
500 models.CharField(
501 choices=[
502 ("M", "Male"),
503 ("F", "Female"),
504 ("X", "Inderminate/intersex"),
505 ("?", "Unknown"),
506 ],
507 blank=True,
508 verbose_name="Patient sex",
509 max_length=1,
510 ),
511 ),
512 (
513 "pt_title",
514 models.CharField(
515 blank=True, verbose_name="Patient title", max_length=20
516 ),
517 ),
518 (
519 "pt_first_name",
520 models.CharField(
521 blank=True,
522 verbose_name="Patient first name",
523 max_length=100,
524 ),
525 ),
526 (
527 "pt_last_name",
528 models.CharField(
529 blank=True,
530 verbose_name="Patient last name",
531 max_length=100,
532 ),
533 ),
534 (
535 "pt_address_1",
536 models.CharField(
537 blank=True,
538 verbose_name="Patient address line 1",
539 max_length=100,
540 ),
541 ),
542 (
543 "pt_address_2",
544 models.CharField(
545 blank=True,
546 verbose_name="Patient address line 2",
547 max_length=100,
548 ),
549 ),
550 (
551 "pt_address_3",
552 models.CharField(
553 blank=True,
554 verbose_name="Patient address line 3",
555 max_length=100,
556 ),
557 ),
558 (
559 "pt_address_4",
560 models.CharField(
561 blank=True,
562 verbose_name="Patient address line 4",
563 max_length=100,
564 ),
565 ),
566 (
567 "pt_address_5",
568 models.CharField(
569 blank=True,
570 verbose_name="Patient address line 5 (county)",
571 max_length=100,
572 ),
573 ),
574 (
575 "pt_address_6",
576 models.CharField(
577 blank=True,
578 verbose_name="Patient address line 6 (postcode)",
579 max_length=100,
580 ),
581 ),
582 (
583 "pt_address_7",
584 models.CharField(
585 blank=True,
586 verbose_name="Patient address line 7 (country)",
587 max_length=100,
588 ),
589 ),
590 (
591 "pt_telephone",
592 models.CharField(
593 blank=True,
594 verbose_name="Patient telephone",
595 max_length=20,
596 ),
597 ),
598 (
599 "pt_email",
600 models.EmailField(
601 blank=True,
602 verbose_name="Patient email",
603 max_length=254,
604 ),
605 ),
606 (
607 "gp_title",
608 models.CharField(
609 blank=True, verbose_name="GP title", max_length=20
610 ),
611 ),
612 (
613 "gp_first_name",
614 models.CharField(
615 blank=True,
616 verbose_name="GP first name",
617 max_length=100,
618 ),
619 ),
620 (
621 "gp_last_name",
622 models.CharField(
623 blank=True, verbose_name="GP last name", max_length=100
624 ),
625 ),
626 (
627 "gp_address_1",
628 models.CharField(
629 blank=True,
630 verbose_name="GP address line 1",
631 max_length=100,
632 ),
633 ),
634 (
635 "gp_address_2",
636 models.CharField(
637 blank=True,
638 verbose_name="GP address line 2",
639 max_length=100,
640 ),
641 ),
642 (
643 "gp_address_3",
644 models.CharField(
645 blank=True,
646 verbose_name="GP address line 3",
647 max_length=100,
648 ),
649 ),
650 (
651 "gp_address_4",
652 models.CharField(
653 blank=True,
654 verbose_name="GP address line 4",
655 max_length=100,
656 ),
657 ),
658 (
659 "gp_address_5",
660 models.CharField(
661 blank=True,
662 verbose_name="GP address line 5 (county)",
663 max_length=100,
664 ),
665 ),
666 (
667 "gp_address_6",
668 models.CharField(
669 blank=True,
670 verbose_name="GP address line 6 (postcode)",
671 max_length=100,
672 ),
673 ),
674 (
675 "gp_address_7",
676 models.CharField(
677 blank=True,
678 verbose_name="GP address line 7 (country)",
679 max_length=100,
680 ),
681 ),
682 (
683 "gp_telephone",
684 models.CharField(
685 blank=True, verbose_name="GP telephone", max_length=20
686 ),
687 ),
688 (
689 "gp_email",
690 models.EmailField(
691 blank=True, verbose_name="GP email", max_length=254
692 ),
693 ),
694 (
695 "clinician_title",
696 models.CharField(
697 blank=True,
698 verbose_name="Clinician title",
699 max_length=20,
700 ),
701 ),
702 (
703 "clinician_first_name",
704 models.CharField(
705 blank=True,
706 verbose_name="Clinician first name",
707 max_length=100,
708 ),
709 ),
710 (
711 "clinician_last_name",
712 models.CharField(
713 blank=True,
714 verbose_name="Clinician last name",
715 max_length=100,
716 ),
717 ),
718 (
719 "clinician_address_1",
720 models.CharField(
721 blank=True,
722 verbose_name="Clinician address line 1",
723 max_length=100,
724 ),
725 ),
726 (
727 "clinician_address_2",
728 models.CharField(
729 blank=True,
730 verbose_name="Clinician address line 2",
731 max_length=100,
732 ),
733 ),
734 (
735 "clinician_address_3",
736 models.CharField(
737 blank=True,
738 verbose_name="Clinician address line 3",
739 max_length=100,
740 ),
741 ),
742 (
743 "clinician_address_4",
744 models.CharField(
745 blank=True,
746 verbose_name="Clinician address line 4",
747 max_length=100,
748 ),
749 ),
750 (
751 "clinician_address_5",
752 models.CharField(
753 blank=True,
754 verbose_name="Clinician address line 5 (county)",
755 max_length=100,
756 ),
757 ),
758 (
759 "clinician_address_6",
760 models.CharField(
761 blank=True,
762 verbose_name="Clinician address line 6 (postcode)",
763 max_length=100,
764 ),
765 ),
766 (
767 "clinician_address_7",
768 models.CharField(
769 blank=True,
770 verbose_name="Clinician address line 7 (country)",
771 max_length=100,
772 ),
773 ),
774 (
775 "clinician_telephone",
776 models.CharField(
777 blank=True,
778 verbose_name="Clinician telephone",
779 max_length=20,
780 ),
781 ),
782 (
783 "clinician_email",
784 models.EmailField(
785 blank=True,
786 verbose_name="Clinician email",
787 max_length=254,
788 ),
789 ),
790 (
791 "clinician_is_consultant",
792 models.BooleanField(
793 default=False, verbose_name="Clinician is a consultant"
794 ),
795 ),
796 (
797 "clinician_signatory_title",
798 models.CharField(
799 blank=True,
800 verbose_name="Clinician's title for signature (e.g. "
801 "'Consultant psychiatrist')",
802 max_length=100,
803 ),
804 ),
805 (
806 "nhs_number",
807 models.BigIntegerField(
808 unique=True, verbose_name="NHS number"
809 ),
810 ),
811 ],
812 options={
813 "verbose_name_plural": "Dummy patient source information",
814 },
815 ),
816 migrations.CreateModel(
817 name="Email",
818 fields=[
819 (
820 "id",
821 models.AutoField(
822 auto_created=True,
823 serialize=False,
824 primary_key=True,
825 verbose_name="ID",
826 ),
827 ),
828 (
829 "created_at",
830 models.DateTimeField(
831 auto_now_add=True, verbose_name="When created"
832 ),
833 ),
834 (
835 "sender",
836 models.CharField(
837 default="CPFT Research Database - DO NOT REPLY "
838 "<noreply@cpft.nhs.uk>",
839 max_length=255,
840 ),
841 ),
842 ("recipient", models.CharField(max_length=255)),
843 ("subject", models.CharField(max_length=255)),
844 ("msg_text", models.TextField()),
845 ("msg_html", models.TextField()),
846 ("to_clinician", models.BooleanField(default=False)),
847 ("to_researcher", models.BooleanField(default=False)),
848 ("to_patient", models.BooleanField(default=False)),
849 (
850 "contact_request",
851 models.ForeignKey(
852 to="consent.ContactRequest",
853 on_delete=models.PROTECT,
854 null=True,
855 ),
856 ),
857 ],
858 ),
859 migrations.CreateModel(
860 name="EmailAttachment",
861 fields=[
862 (
863 "id",
864 models.AutoField(
865 auto_created=True,
866 serialize=False,
867 primary_key=True,
868 verbose_name="ID",
869 ),
870 ),
871 (
872 "file",
873 models.FileField(
874 upload_to="",
875 storage=consent_storage.CustomFileSystemStorage(
876 base_url="download_privatestorage"
877 ),
878 ),
879 ),
880 ("sent_filename", models.CharField(null=True, max_length=255)),
881 ("content_type", models.CharField(null=True, max_length=255)),
882 ("owns_file", models.BooleanField(default=False)),
883 (
884 "email",
885 models.ForeignKey(
886 to="consent.Email", on_delete=models.PROTECT
887 ),
888 ),
889 ],
890 ),
891 migrations.CreateModel(
892 name="EmailTransmission",
893 fields=[
894 (
895 "id",
896 models.AutoField(
897 auto_created=True,
898 serialize=False,
899 primary_key=True,
900 verbose_name="ID",
901 ),
902 ),
903 (
904 "at",
905 models.DateTimeField(
906 auto_now_add=True, verbose_name="When sent"
907 ),
908 ),
909 ("sent", models.BooleanField(default=False)),
910 (
911 "failure_reason",
912 models.TextField(verbose_name="Reason sending failed"),
913 ),
914 (
915 "by",
916 models.ForeignKey(
917 to=settings.AUTH_USER_MODEL,
918 on_delete=models.PROTECT,
919 related_name="emailtransmissions",
920 null=True,
921 ),
922 ),
923 (
924 "email",
925 models.ForeignKey(
926 to="consent.Email", on_delete=models.PROTECT
927 ),
928 ),
929 ],
930 ),
931 migrations.CreateModel(
932 name="Leaflet",
933 fields=[
934 (
935 "id",
936 models.AutoField(
937 auto_created=True,
938 serialize=False,
939 primary_key=True,
940 verbose_name="ID",
941 ),
942 ),
943 (
944 "name",
945 models.CharField(
946 choices=[
947 ("cpft_tpir", "CPFT: Taking part in research"),
948 (
949 "nihr_yhrsl",
950 "NIHR: Your health records save lives",
951 ),
952 (
953 "cpft_trafficlight_choice",
954 "CPFT: traffic-light choice",
955 ),
956 ("cpft_clinres", "CPFT: clinical research"),
957 ],
958 verbose_name="leaflet name",
959 unique=True,
960 max_length=50,
961 ),
962 ),
963 (
964 "pdf",
965 ContentTypeRestrictedFileField(
966 upload_to=consent_models.leaflet_upload_to,
967 blank=True,
968 storage=consent_storage.CustomFileSystemStorage(
969 base_url="download_privatestorage"
970 ),
971 ),
972 ),
973 ],
974 ),
975 migrations.CreateModel(
976 name="Letter",
977 fields=[
978 (
979 "id",
980 models.AutoField(
981 auto_created=True,
982 serialize=False,
983 primary_key=True,
984 verbose_name="ID",
985 ),
986 ),
987 (
988 "created_at",
989 models.DateTimeField(
990 auto_now_add=True, verbose_name="When created"
991 ),
992 ),
993 (
994 "pdf",
995 models.FileField(
996 upload_to="",
997 storage=consent_storage.CustomFileSystemStorage(
998 base_url="download_privatestorage"
999 ),
1000 ),
1001 ),
1002 ("to_clinician", models.BooleanField(default=False)),
1003 ("to_researcher", models.BooleanField(default=False)),
1004 ("to_patient", models.BooleanField(default=False)),
1005 ("rdbm_may_view", models.BooleanField(default=False)),
1006 ("sent_manually_at", models.DateTimeField(null=True)),
1007 (
1008 "contact_request",
1009 models.ForeignKey(
1010 to="consent.ContactRequest",
1011 on_delete=models.PROTECT,
1012 null=True,
1013 ),
1014 ),
1015 ],
1016 ),
1017 migrations.CreateModel(
1018 name="PatientLookup",
1019 fields=[
1020 (
1021 "id",
1022 models.AutoField(
1023 auto_created=True,
1024 serialize=False,
1025 primary_key=True,
1026 verbose_name="ID",
1027 ),
1028 ),
1029 (
1030 "pt_local_id_description",
1031 models.CharField(
1032 blank=True,
1033 verbose_name="Description of database-specific ID",
1034 max_length=100,
1035 ),
1036 ),
1037 (
1038 "pt_local_id_number",
1039 models.BigIntegerField(
1040 blank=True,
1041 null=True,
1042 verbose_name="Database-specific ID",
1043 ),
1044 ),
1045 (
1046 "pt_dob",
1047 models.DateField(
1048 blank=True,
1049 null=True,
1050 verbose_name="Patient date of birth",
1051 ),
1052 ),
1053 (
1054 "pt_dod",
1055 models.DateField(
1056 blank=True,
1057 null=True,
1058 verbose_name="Patient date of death (NULL if alive)",
1059 ),
1060 ),
1061 (
1062 "pt_dead",
1063 models.BooleanField(
1064 default=False, verbose_name="Patient is dead"
1065 ),
1066 ),
1067 (
1068 "pt_discharged",
1069 models.NullBooleanField(verbose_name="Patient discharged"),
1070 ),
1071 (
1072 "pt_sex",
1073 models.CharField(
1074 choices=[
1075 ("M", "Male"),
1076 ("F", "Female"),
1077 ("X", "Inderminate/intersex"),
1078 ("?", "Unknown"),
1079 ],
1080 blank=True,
1081 verbose_name="Patient sex",
1082 max_length=1,
1083 ),
1084 ),
1085 (
1086 "pt_title",
1087 models.CharField(
1088 blank=True, verbose_name="Patient title", max_length=20
1089 ),
1090 ),
1091 (
1092 "pt_first_name",
1093 models.CharField(
1094 blank=True,
1095 verbose_name="Patient first name",
1096 max_length=100,
1097 ),
1098 ),
1099 (
1100 "pt_last_name",
1101 models.CharField(
1102 blank=True,
1103 verbose_name="Patient last name",
1104 max_length=100,
1105 ),
1106 ),
1107 (
1108 "pt_address_1",
1109 models.CharField(
1110 blank=True,
1111 verbose_name="Patient address line 1",
1112 max_length=100,
1113 ),
1114 ),
1115 (
1116 "pt_address_2",
1117 models.CharField(
1118 blank=True,
1119 verbose_name="Patient address line 2",
1120 max_length=100,
1121 ),
1122 ),
1123 (
1124 "pt_address_3",
1125 models.CharField(
1126 blank=True,
1127 verbose_name="Patient address line 3",
1128 max_length=100,
1129 ),
1130 ),
1131 (
1132 "pt_address_4",
1133 models.CharField(
1134 blank=True,
1135 verbose_name="Patient address line 4",
1136 max_length=100,
1137 ),
1138 ),
1139 (
1140 "pt_address_5",
1141 models.CharField(
1142 blank=True,
1143 verbose_name="Patient address line 5 (county)",
1144 max_length=100,
1145 ),
1146 ),
1147 (
1148 "pt_address_6",
1149 models.CharField(
1150 blank=True,
1151 verbose_name="Patient address line 6 (postcode)",
1152 max_length=100,
1153 ),
1154 ),
1155 (
1156 "pt_address_7",
1157 models.CharField(
1158 blank=True,
1159 verbose_name="Patient address line 7 (country)",
1160 max_length=100,
1161 ),
1162 ),
1163 (
1164 "pt_telephone",
1165 models.CharField(
1166 blank=True,
1167 verbose_name="Patient telephone",
1168 max_length=20,
1169 ),
1170 ),
1171 (
1172 "pt_email",
1173 models.EmailField(
1174 blank=True,
1175 verbose_name="Patient email",
1176 max_length=254,
1177 ),
1178 ),
1179 (
1180 "gp_title",
1181 models.CharField(
1182 blank=True, verbose_name="GP title", max_length=20
1183 ),
1184 ),
1185 (
1186 "gp_first_name",
1187 models.CharField(
1188 blank=True,
1189 verbose_name="GP first name",
1190 max_length=100,
1191 ),
1192 ),
1193 (
1194 "gp_last_name",
1195 models.CharField(
1196 blank=True, verbose_name="GP last name", max_length=100
1197 ),
1198 ),
1199 (
1200 "gp_address_1",
1201 models.CharField(
1202 blank=True,
1203 verbose_name="GP address line 1",
1204 max_length=100,
1205 ),
1206 ),
1207 (
1208 "gp_address_2",
1209 models.CharField(
1210 blank=True,
1211 verbose_name="GP address line 2",
1212 max_length=100,
1213 ),
1214 ),
1215 (
1216 "gp_address_3",
1217 models.CharField(
1218 blank=True,
1219 verbose_name="GP address line 3",
1220 max_length=100,
1221 ),
1222 ),
1223 (
1224 "gp_address_4",
1225 models.CharField(
1226 blank=True,
1227 verbose_name="GP address line 4",
1228 max_length=100,
1229 ),
1230 ),
1231 (
1232 "gp_address_5",
1233 models.CharField(
1234 blank=True,
1235 verbose_name="GP address line 5 (county)",
1236 max_length=100,
1237 ),
1238 ),
1239 (
1240 "gp_address_6",
1241 models.CharField(
1242 blank=True,
1243 verbose_name="GP address line 6 (postcode)",
1244 max_length=100,
1245 ),
1246 ),
1247 (
1248 "gp_address_7",
1249 models.CharField(
1250 blank=True,
1251 verbose_name="GP address line 7 (country)",
1252 max_length=100,
1253 ),
1254 ),
1255 (
1256 "gp_telephone",
1257 models.CharField(
1258 blank=True, verbose_name="GP telephone", max_length=20
1259 ),
1260 ),
1261 (
1262 "gp_email",
1263 models.EmailField(
1264 blank=True, verbose_name="GP email", max_length=254
1265 ),
1266 ),
1267 (
1268 "clinician_title",
1269 models.CharField(
1270 blank=True,
1271 verbose_name="Clinician title",
1272 max_length=20,
1273 ),
1274 ),
1275 (
1276 "clinician_first_name",
1277 models.CharField(
1278 blank=True,
1279 verbose_name="Clinician first name",
1280 max_length=100,
1281 ),
1282 ),
1283 (
1284 "clinician_last_name",
1285 models.CharField(
1286 blank=True,
1287 verbose_name="Clinician last name",
1288 max_length=100,
1289 ),
1290 ),
1291 (
1292 "clinician_address_1",
1293 models.CharField(
1294 blank=True,
1295 verbose_name="Clinician address line 1",
1296 max_length=100,
1297 ),
1298 ),
1299 (
1300 "clinician_address_2",
1301 models.CharField(
1302 blank=True,
1303 verbose_name="Clinician address line 2",
1304 max_length=100,
1305 ),
1306 ),
1307 (
1308 "clinician_address_3",
1309 models.CharField(
1310 blank=True,
1311 verbose_name="Clinician address line 3",
1312 max_length=100,
1313 ),
1314 ),
1315 (
1316 "clinician_address_4",
1317 models.CharField(
1318 blank=True,
1319 verbose_name="Clinician address line 4",
1320 max_length=100,
1321 ),
1322 ),
1323 (
1324 "clinician_address_5",
1325 models.CharField(
1326 blank=True,
1327 verbose_name="Clinician address line 5 (county)",
1328 max_length=100,
1329 ),
1330 ),
1331 (
1332 "clinician_address_6",
1333 models.CharField(
1334 blank=True,
1335 verbose_name="Clinician address line 6 (postcode)",
1336 max_length=100,
1337 ),
1338 ),
1339 (
1340 "clinician_address_7",
1341 models.CharField(
1342 blank=True,
1343 verbose_name="Clinician address line 7 (country)",
1344 max_length=100,
1345 ),
1346 ),
1347 (
1348 "clinician_telephone",
1349 models.CharField(
1350 blank=True,
1351 verbose_name="Clinician telephone",
1352 max_length=20,
1353 ),
1354 ),
1355 (
1356 "clinician_email",
1357 models.EmailField(
1358 blank=True,
1359 verbose_name="Clinician email",
1360 max_length=254,
1361 ),
1362 ),
1363 (
1364 "clinician_is_consultant",
1365 models.BooleanField(
1366 default=False, verbose_name="Clinician is a consultant"
1367 ),
1368 ),
1369 (
1370 "clinician_signatory_title",
1371 models.CharField(
1372 blank=True,
1373 verbose_name="Clinician's title for signature (e.g. "
1374 "'Consultant psychiatrist')",
1375 max_length=100,
1376 ),
1377 ),
1378 (
1379 "nhs_number",
1380 models.BigIntegerField(
1381 verbose_name="NHS number used for lookup"
1382 ),
1383 ),
1384 (
1385 "lookup_at",
1386 models.DateTimeField(
1387 auto_now_add=True,
1388 verbose_name="When fetched from clinical database",
1389 ),
1390 ),
1391 (
1392 "source_db",
1393 models.CharField(
1394 choices=[
1395 (
1396 "dummy_clinical",
1397 "Dummy clinical database for testing",
1398 ),
1399 (
1400 "cpft_crs",
1401 "CPFT Care Records System (CRS) 2005-2012",
1402 ),
1403 ("cpft_rio", "CPFT RiO 2013-"),
1404 ],
1405 verbose_name="Source database used for lookup",
1406 max_length=20,
1407 ),
1408 ),
1409 (
1410 "decisions",
1411 models.TextField(
1412 blank=True, verbose_name="Decisions made during lookup"
1413 ),
1414 ),
1415 (
1416 "secret_decisions",
1417 models.TextField(
1418 blank=True,
1419 verbose_name="Secret (identifying) decisions made "
1420 "during lookup",
1421 ),
1422 ),
1423 (
1424 "pt_found",
1425 models.BooleanField(
1426 default=False, verbose_name="Patient found"
1427 ),
1428 ),
1429 (
1430 "gp_found",
1431 models.BooleanField(
1432 default=False, verbose_name="GP found"
1433 ),
1434 ),
1435 (
1436 "clinician_found",
1437 models.BooleanField(
1438 default=False, verbose_name="Clinician found"
1439 ),
1440 ),
1441 ],
1442 options={
1443 "abstract": False,
1444 },
1445 ),
1446 migrations.CreateModel(
1447 name="PatientResponse",
1448 fields=[
1449 (
1450 "id",
1451 models.AutoField(
1452 auto_created=True,
1453 serialize=False,
1454 primary_key=True,
1455 verbose_name="ID",
1456 ),
1457 ),
1458 (
1459 "decision_signed_by_patient",
1460 models.BooleanField(
1461 default=False,
1462 verbose_name="Request signed by patient?",
1463 ),
1464 ),
1465 (
1466 "decision_otherwise_directly_authorized_by_patient",
1467 models.BooleanField(
1468 default=False,
1469 verbose_name="Request otherwise directly authorized "
1470 "by patient?",
1471 ),
1472 ),
1473 (
1474 "decision_under16_signed_by_parent",
1475 models.BooleanField(
1476 default=False,
1477 verbose_name="Patient under 16 and request "
1478 "countersigned by parent?",
1479 ),
1480 ),
1481 (
1482 "decision_under16_signed_by_clinician",
1483 models.BooleanField(
1484 default=False,
1485 verbose_name="Patient under 16 and request "
1486 "countersigned by clinician?",
1487 ),
1488 ),
1489 (
1490 "decision_lack_capacity_signed_by_representative",
1491 models.BooleanField(
1492 default=False,
1493 verbose_name="Patient lacked capacity and request "
1494 "signed by authorized representative?",
1495 ),
1496 ),
1497 (
1498 "decision_lack_capacity_signed_by_clinician",
1499 models.BooleanField(
1500 default=False,
1501 verbose_name="Patient lacked capacity and request "
1502 "countersigned by clinician?",
1503 ),
1504 ),
1505 (
1506 "created_at",
1507 models.DateTimeField(
1508 auto_now_add=True, verbose_name="When created"
1509 ),
1510 ),
1511 (
1512 "response",
1513 models.PositiveSmallIntegerField(
1514 choices=[(1, "1: Yes"), (2, "2: No")],
1515 null=True,
1516 verbose_name="Patient's response",
1517 ),
1518 ),
1519 (
1520 "contact_request",
1521 models.OneToOneField(
1522 to="consent.ContactRequest",
1523 on_delete=models.PROTECT,
1524 related_name="patient_response",
1525 ),
1526 ),
1527 (
1528 "recorded_by",
1529 models.ForeignKey(
1530 to=settings.AUTH_USER_MODEL,
1531 on_delete=models.PROTECT,
1532 null=True,
1533 ),
1534 ),
1535 ],
1536 options={
1537 "abstract": False,
1538 },
1539 ),
1540 migrations.CreateModel(
1541 name="Study",
1542 fields=[
1543 (
1544 "id",
1545 models.AutoField(
1546 auto_created=True,
1547 serialize=False,
1548 primary_key=True,
1549 verbose_name="ID",
1550 ),
1551 ),
1552 (
1553 "institutional_id",
1554 models.PositiveIntegerField(
1555 unique=True,
1556 verbose_name="Institutional (e.g. NHS Trust) study "
1557 "number",
1558 ),
1559 ),
1560 (
1561 "title",
1562 models.CharField(
1563 verbose_name="Study title", max_length=255
1564 ),
1565 ),
1566 (
1567 "registered_at",
1568 models.DateTimeField(
1569 blank=True,
1570 null=True,
1571 verbose_name="When was the study registered?",
1572 ),
1573 ),
1574 ("summary", models.TextField(verbose_name="Summary of study")),
1575 (
1576 "search_methods_planned",
1577 models.TextField(
1578 blank=True, verbose_name="Search methods planned"
1579 ),
1580 ),
1581 (
1582 "patient_contact",
1583 models.BooleanField(
1584 verbose_name="Involves patient contact?"
1585 ),
1586 ),
1587 (
1588 "include_under_16s",
1589 models.BooleanField(
1590 verbose_name="Include patients under 16?"
1591 ),
1592 ),
1593 (
1594 "include_lack_capacity",
1595 models.BooleanField(
1596 verbose_name="Include patients lacking capacity?"
1597 ),
1598 ),
1599 (
1600 "clinical_trial",
1601 models.BooleanField(
1602 verbose_name="Clinical trial (CTIMP)?"
1603 ),
1604 ),
1605 (
1606 "include_discharged",
1607 models.BooleanField(
1608 verbose_name="Include discharged patients?"
1609 ),
1610 ),
1611 (
1612 "request_direct_approach",
1613 models.BooleanField(
1614 verbose_name="Researchers request direct approach to "
1615 "patients?"
1616 ),
1617 ),
1618 (
1619 "approved_by_rec",
1620 models.BooleanField(verbose_name="Approved by REC?"),
1621 ),
1622 (
1623 "rec_reference",
1624 models.CharField(
1625 blank=True,
1626 verbose_name="Research Ethics Committee reference",
1627 max_length=50,
1628 ),
1629 ),
1630 (
1631 "approved_locally",
1632 models.BooleanField(
1633 verbose_name="Approved by local institution?"
1634 ),
1635 ),
1636 (
1637 "local_approval_at",
1638 models.DateTimeField(
1639 blank=True,
1640 null=True,
1641 verbose_name="When approved by local institution?",
1642 ),
1643 ),
1644 (
1645 "study_details_pdf",
1646 ContentTypeRestrictedFileField(
1647 upload_to=consent_models.study_details_upload_to,
1648 blank=True,
1649 storage=consent_storage.CustomFileSystemStorage(
1650 base_url="download_privatestorage"
1651 ),
1652 ),
1653 ),
1654 (
1655 "subject_form_template_pdf",
1656 ContentTypeRestrictedFileField(
1657 upload_to=consent_models.study_form_upload_to,
1658 blank=True,
1659 storage=consent_storage.CustomFileSystemStorage(
1660 base_url="download_privatestorage"
1661 ),
1662 ),
1663 ),
1664 (
1665 "lead_researcher",
1666 models.ForeignKey(
1667 to=settings.AUTH_USER_MODEL,
1668 on_delete=models.PROTECT,
1669 related_name="studies_as_lead",
1670 ),
1671 ),
1672 (
1673 "researchers",
1674 models.ManyToManyField(
1675 to=settings.AUTH_USER_MODEL,
1676 blank=True,
1677 related_name="studies_as_researcher",
1678 ),
1679 ),
1680 ],
1681 options={
1682 "verbose_name_plural": "studies",
1683 },
1684 ),
1685 migrations.CreateModel(
1686 name="TeamRep",
1687 fields=[
1688 (
1689 "id",
1690 models.AutoField(
1691 auto_created=True,
1692 serialize=False,
1693 primary_key=True,
1694 verbose_name="ID",
1695 ),
1696 ),
1697 (
1698 "team",
1699 models.CharField(
1700 choices=[
1701 ("dummy_team_one", "dummy_team_one"),
1702 ("dummy_team_two", "dummy_team_two"),
1703 ("dummy_team_three", "dummy_team_three"),
1704 ],
1705 verbose_name="Team description",
1706 unique=True,
1707 max_length=100,
1708 ),
1709 ),
1710 (
1711 "user",
1712 models.ForeignKey(
1713 to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
1714 ),
1715 ),
1716 ],
1717 options={
1718 "verbose_name_plural": "clinical team representatives",
1719 "verbose_name": "clinical team representative",
1720 },
1721 ),
1722 migrations.AddField(
1723 model_name="letter",
1724 name="study",
1725 field=models.ForeignKey(
1726 to="consent.Study", on_delete=models.PROTECT, null=True
1727 ),
1728 ),
1729 migrations.AddField(
1730 model_name="email",
1731 name="letter",
1732 field=models.ForeignKey(
1733 to="consent.Letter", on_delete=models.PROTECT, null=True
1734 ),
1735 ),
1736 migrations.AddField(
1737 model_name="email",
1738 name="study",
1739 field=models.ForeignKey(
1740 to="consent.Study", on_delete=models.PROTECT, null=True
1741 ),
1742 ),
1743 migrations.AddField(
1744 model_name="contactrequest",
1745 name="patient_lookup",
1746 field=models.ForeignKey(
1747 to="consent.PatientLookup",
1748 on_delete=models.SET_NULL,
1749 null=True,
1750 ),
1751 ),
1752 migrations.AddField(
1753 model_name="contactrequest",
1754 name="request_by",
1755 field=models.ForeignKey(
1756 to=settings.AUTH_USER_MODEL, on_delete=models.PROTECT
1757 ),
1758 ),
1759 migrations.AddField(
1760 model_name="contactrequest",
1761 name="study",
1762 field=models.ForeignKey(
1763 to="consent.Study", on_delete=models.PROTECT
1764 ),
1765 ),
1766 migrations.AddField(
1767 model_name="clinicianresponse",
1768 name="contact_request",
1769 field=models.OneToOneField(
1770 to="consent.ContactRequest",
1771 on_delete=models.PROTECT,
1772 related_name="clinician_response",
1773 ),
1774 ),
1775 ]