Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
scheduling-system
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
External wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
SMASCH
scheduling-system
Commits
95830ed5
Commit
95830ed5
authored
1 year ago
by
Carlos Vega
Browse files
Options
Downloads
Patches
Plain Diff
attempt to avoid the migrations issue in the CI
parent
3cf4389d
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!445
Support for Python 3.11
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
smash/web/models/study_subject.py
+91
-130
91 additions, 130 deletions
smash/web/models/study_subject.py
with
91 additions
and
130 deletions
smash/web/models/study_subject.py
+
91
−
130
View file @
95830ed5
...
...
@@ -16,12 +16,13 @@ logger = logging.getLogger(__name__)
class
StudySubject
(
models
.
Model
):
class
Meta
:
app_label
=
'
web
'
app_label
=
"
web
"
@property
def
provenances
(
self
):
return
Provenance
.
objects
.
filter
(
modified_table
=
StudySubject
.
_meta
.
db_table
,
modified_table_id
=
self
.
id
).
order_by
(
'
-modification_date
'
)
return
Provenance
.
objects
.
filter
(
modified_table
=
StudySubject
.
_meta
.
db_table
,
modified_table_id
=
self
.
id
).
order_by
(
"
-modification_date
"
)
def
finish_all_visits
(
self
):
visits
=
Visit
.
objects
.
filter
(
subject
=
self
,
is_finished
=
False
)
...
...
@@ -30,8 +31,7 @@ class StudySubject(models.Model):
visit
.
save
()
def
finish_all_appointments
(
self
):
appointments
=
Appointment
.
objects
.
filter
(
visit__subject
=
self
,
status
=
Appointment
.
APPOINTMENT_STATUS_SCHEDULED
)
appointments
=
Appointment
.
objects
.
filter
(
visit__subject
=
self
,
status
=
Appointment
.
APPOINTMENT_STATUS_SCHEDULED
)
for
appointment
in
appointments
:
appointment
.
status
=
Appointment
.
APPOINTMENT_STATUS_CANCELLED
appointment
.
save
()
...
...
@@ -51,143 +51,92 @@ class StudySubject(models.Model):
self
.
finish_all_visits
()
self
.
finish_all_appointments
()
subject
=
models
.
ForeignKey
(
"
web.Subject
"
,
verbose_name
=
'
Subject
'
,
editable
=
False
,
null
=
False
,
on_delete
=
models
.
CASCADE
)
study
=
models
.
ForeignKey
(
"
web.Study
"
,
verbose_name
=
'
Study
'
,
editable
=
False
,
null
=
False
,
on_delete
=
models
.
CASCADE
)
postponed
=
models
.
BooleanField
(
choices
=
BOOL_CHOICES
,
verbose_name
=
'
Postponed
'
,
default
=
False
)
subject
=
models
.
ForeignKey
(
"
web.Subject
"
,
verbose_name
=
"
Subject
"
,
editable
=
False
,
null
=
False
,
on_delete
=
models
.
CASCADE
)
study
=
models
.
ForeignKey
(
"
web.Study
"
,
verbose_name
=
"
Study
"
,
editable
=
False
,
null
=
False
,
on_delete
=
models
.
CASCADE
)
postponed
=
models
.
BooleanField
(
choices
=
BOOL_CHOICES
,
verbose_name
=
"
Postponed
"
,
default
=
False
)
datetime_contact_reminder
=
models
.
DateTimeField
(
null
=
True
,
blank
=
True
,
verbose_name
=
'
Please make a contact on
'
,
verbose_name
=
"
Please make a contact on
"
,
)
type
=
models
.
ForeignKey
(
"
web.SubjectType
"
,
null
=
False
,
blank
=
False
,
on_delete
=
models
.
PROTECT
,
verbose_name
=
"
Type
"
)
visit_used_to_compute_followup_date
=
models
.
ForeignKey
(
"
web.Visit
"
,
null
=
True
,
on_delete
=
models
.
SET_NULL
,
editable
=
False
,
)
type
=
models
.
ForeignKey
(
"
web.SubjectType
"
,
null
=
False
,
blank
=
False
,
on_delete
=
models
.
PROTECT
,
verbose_name
=
'
Type
'
)
visit_used_to_compute_followup_date
=
models
.
ForeignKey
(
"
web.Visit
"
,
null
=
True
,
on_delete
=
models
.
SET_NULL
,
editable
=
False
,
)
default_location
=
models
.
ForeignKey
(
Location
,
verbose_name
=
'
Default appointment location
'
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
,
limit_choices_to
=
{
"
removed
"
:
False
}
)
flying_team
=
models
.
ForeignKey
(
"
web.FlyingTeam
"
,
verbose_name
=
'
Default flying team location (if applicable)
'
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
)
screening_number
=
models
.
CharField
(
max_length
=
50
,
verbose_name
=
'
Screening number
'
,
blank
=
True
,
null
=
True
)
nd_number
=
models
.
CharField
(
max_length
=
25
,
blank
=
True
,
verbose_name
=
'
Subject number
'
,
)
comments
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
'
Comments
'
)
date_added
=
models
.
DateField
(
verbose_name
=
'
Added on
'
,
auto_now_add
=
True
)
referral
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
'
Referred by
'
)
default_location
=
models
.
ForeignKey
(
Location
,
verbose_name
=
"
Default appointment location
"
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
,
limit_choices_to
=
{
"
removed
"
:
False
},
)
flying_team
=
models
.
ForeignKey
(
"
web.FlyingTeam
"
,
verbose_name
=
"
Default flying team location (if applicable)
"
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
,
)
screening_number
=
models
.
CharField
(
max_length
=
50
,
verbose_name
=
"
Screening number
"
,
blank
=
True
,
null
=
True
)
nd_number
=
models
.
CharField
(
max_length
=
25
,
blank
=
True
,
verbose_name
=
"
Subject number
"
,
)
comments
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
"
Comments
"
)
date_added
=
models
.
DateField
(
verbose_name
=
"
Added on
"
,
auto_now_add
=
True
)
referral
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
"
Referred by
"
)
referral_letter
=
models
.
FileField
(
storage
=
FILE_STORAGE
,
upload_to
=
'
referral_letters
'
,
verbose_name
=
'
Referral letter
'
,
upload_to
=
"
referral_letters
"
,
verbose_name
=
"
Referral letter
"
,
blank
=
True
,
null
=
True
,
)
health_partner
=
models
.
ForeignKey
(
"
web.Worker
"
,
verbose_name
=
'
Health partner
'
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
CASCADE
)
health_partner
=
models
.
ForeignKey
(
"
web.Worker
"
,
verbose_name
=
"
Health partner
"
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
CASCADE
)
health_partner_feedback_agreement
=
models
.
BooleanField
(
verbose_name
=
'
Agrees to give information to referral
'
,
verbose_name
=
"
Agrees to give information to referral
"
,
default
=
False
,
)
voucher_types
=
models
.
ManyToManyField
(
VoucherType
,
blank
=
True
,
verbose_name
=
'
Voucher types
'
)
voucher_types
=
models
.
ManyToManyField
(
VoucherType
,
blank
=
True
,
verbose_name
=
"
Voucher types
"
)
information_sent
=
models
.
BooleanField
(
verbose_name
=
'
Information sent
'
,
default
=
False
)
information_sent
=
models
.
BooleanField
(
verbose_name
=
"
Information sent
"
,
default
=
False
)
resigned
=
models
.
BooleanField
(
verbose_name
=
'
Resigned
'
,
default
=
False
,
editable
=
True
)
resign_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
'
Resign reason
'
)
excluded
=
models
.
BooleanField
(
verbose_name
=
'
Excluded
'
,
default
=
False
,
editable
=
True
)
exclude_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
'
Exclude reason
'
)
endpoint_reached
=
models
.
BooleanField
(
verbose_name
=
'
Endpoint Reached
'
,
default
=
False
,
editable
=
True
)
endpoint_reached_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
'
Endpoint reached comments
'
)
resigned
=
models
.
BooleanField
(
verbose_name
=
"
Resigned
"
,
default
=
False
,
editable
=
True
)
resign_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
"
Resign reason
"
)
excluded
=
models
.
BooleanField
(
verbose_name
=
"
Excluded
"
,
default
=
False
,
editable
=
True
)
exclude_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
"
Exclude reason
"
)
endpoint_reached
=
models
.
BooleanField
(
verbose_name
=
"
Endpoint Reached
"
,
default
=
False
,
editable
=
True
)
endpoint_reached_reason
=
models
.
TextField
(
max_length
=
2000
,
blank
=
True
,
verbose_name
=
"
Endpoint reached comments
"
)
def
sort_matched_screening_first
(
self
,
pattern
,
reverse
=
False
):
if
self
.
screening_number
is
None
:
return
None
parts
=
self
.
screening_number
.
split
(
'
;
'
)
parts
=
self
.
screening_number
.
split
(
"
;
"
)
matches
,
reminder
=
[],
[]
try
:
for
part
in
parts
:
chunks
=
part
.
strip
().
split
(
'
-
'
)
chunks
=
part
.
strip
().
split
(
"
-
"
)
if
len
(
chunks
)
==
2
:
letter
,
number
=
chunks
try
:
...
...
@@ -195,8 +144,11 @@ class StudySubject(models.Model):
except
ValueError
:
# better than isdigit because isdigit fails with negative numbers and others
tupl
=
(
letter
,
number
)
else
:
logger
.
warning
(
'
There are %d chunks in some parts of this screening_number: |%s|.
'
,
len
(
chunks
),
self
.
screening_number
)
logger
.
warning
(
"
There are %d chunks in some parts of this screening_number: |%s|.
"
,
len
(
chunks
),
self
.
screening_number
,
)
tupl
=
(
part
.
strip
(),
None
)
if
pattern
is
not
None
and
pattern
in
part
:
matches
.
append
(
tupl
)
...
...
@@ -209,8 +161,13 @@ class StudySubject(models.Model):
@staticmethod
def
check_nd_number_regex
(
regex_str
,
study
):
nd_numbers
=
StudySubject
.
objects
.
filter
(
study
=
study
).
exclude
(
nd_number__isnull
=
True
).
exclude
(
nd_number__exact
=
''
).
all
().
values_list
(
'
nd_number
'
,
flat
=
True
)
nd_numbers
=
(
StudySubject
.
objects
.
filter
(
study
=
study
)
.
exclude
(
nd_number__isnull
=
True
)
.
exclude
(
nd_number__exact
=
""
)
.
all
()
.
values_list
(
"
nd_number
"
,
flat
=
True
)
)
regex
=
re
.
compile
(
regex_str
)
for
nd_number
in
nd_numbers
:
if
regex
.
match
(
nd_number
)
is
None
:
...
...
@@ -223,15 +180,15 @@ class StudySubject(models.Model):
@property
def
status
(
self
):
if
self
.
subject
.
dead
:
return
'
Deceased
'
return
"
Deceased
"
elif
self
.
resigned
:
return
'
Resigned
'
return
"
Resigned
"
elif
self
.
excluded
:
return
'
Excluded
'
return
"
Excluded
"
elif
self
.
endpoint_reached
:
return
'
Endpoint Reached
'
return
"
Endpoint Reached
"
else
:
return
'
Normal
'
return
"
Normal
"
@property
def
custom_data_values
(
self
):
...
...
@@ -240,8 +197,9 @@ class StudySubject(models.Model):
for
value
in
values
:
fields
.
remove
(
value
.
study_subject_field
)
for
field
in
fields
:
CustomStudySubjectValue
.
objects
.
create
(
study_subject
=
self
,
value
=
field
.
default_value
,
study_subject_field
=
field
)
CustomStudySubjectValue
.
objects
.
create
(
study_subject
=
self
,
value
=
field
.
default_value
,
study_subject_field
=
field
)
return
CustomStudySubjectValue
.
objects
.
filter
(
study_subject
=
self
)
def
set_custom_data_value
(
self
,
custom_study_subject_field
:
CustomStudySubjectField
,
value
:
str
):
...
...
@@ -253,11 +211,14 @@ class StudySubject(models.Model):
existing_value
.
save
()
if
not
found
:
self
.
customstudysubjectvalue_set
.
add
(
CustomStudySubjectValue
.
objects
.
create
(
study_subject
=
self
,
value
=
value
,
study_subject_field
=
custom_study_subject_field
))
CustomStudySubjectValue
.
objects
.
create
(
study_subject
=
self
,
value
=
value
,
study_subject_field
=
custom_study_subject_field
)
)
def
__str__
(
self
):
return
f
"
{
self
.
subject
.
first_name
}
{
self
.
subject
.
last_name
}
"
# pylint: disable-next=C0209
return
"
%s %s
"
%
(
self
.
subject
.
first_name
,
self
.
subject
.
last_name
)
def
get_custom_data_value
(
self
,
custom_field
:
CustomStudySubjectField
)
->
Optional
[
CustomStudySubjectValue
]:
for
value
in
self
.
custom_data_values
:
...
...
@@ -269,7 +230,7 @@ class StudySubject(models.Model):
for
value
in
self
.
custom_data_values
.
all
():
if
value
.
study_subject_field
.
name
==
param
:
return
value
.
value
return
''
return
""
def
set_custom_field_value
(
self
,
param
:
str
,
value
:
str
):
for
custom_value
in
self
.
custom_data_values
.
all
():
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment