Skip to content

Commit

Permalink
update for changes in edc-appointment
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvw committed Sep 23, 2023
1 parent 19a6c76 commit d36c661
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 53 deletions.
9 changes: 9 additions & 0 deletions edc_next_appointment/form_validators/form_validator_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import TYPE_CHECKING

from django.utils.translation import gettext_lazy as _
from edc_appointment.utils import get_allow_skipped_appt_using
from edc_form_validators import INVALID_ERROR
from edc_utils.date import to_local

Expand All @@ -20,6 +21,14 @@ def __init__(self, **kwargs):
self.day_abbr = calendar.weekheader(3).split(" ")
super().__init__(**kwargs)

@property
def visit_code_fld(self):
return get_allow_skipped_appt_using().get(self._meta.model._meta.label_lower)[1]

@property
def dt_fld(self):
return get_allow_skipped_appt_using().get(self._meta.model._meta.label_lower)[1]

@property
def clinic_days(self) -> list[int]:
if not self._clinic_days:
Expand Down
66 changes: 33 additions & 33 deletions edc_next_appointment/modelform_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@
class NextAppointmentModelFormMixin:
def clean(self):
cleaned_data = super().clean()
self.validate_appt_date_with_next()
self.validate_best_next_visit_code()
self.validate_suggested_date_with_future_appointments()
self.validate_suggested_visit_code()
return cleaned_data

@property
def next_appt_date(self) -> date | None:
def suggested_date(self) -> date | None:
return self.cleaned_data.get("appt_date")

def validate_appt_date_with_next(self):
if self.next_appt_date and self.related_visit.appointment.next.appt_status not in [
@property
def suggested_visit_code(self) -> str | None:
return getattr(
self.cleaned_data.get("visitschedule"),
"visit_code",
self.cleaned_data.get("visitschedule"),
)

def validate_suggested_date_with_future_appointments(self):
if self.suggested_date and self.related_visit.appointment.next.appt_status not in [
NEW_APPT,
SKIPPED_APPT,
]:
if (
self.next_appt_date
self.suggested_date
!= to_local(self.related_visit.appointment.next.appt_datetime).date()
):
next_appt = self.related_visit.appointment.next
Expand All @@ -40,45 +48,45 @@ def validate_appt_date_with_next(self):
{
"appt_date": _(
"Invalid. Next visit report already submitted. Expected "
"`%(next_appt_date)s`. See `%(next_appt_visit_code)s`."
"`%(dt)s`. See `%(visit_code)s`."
)
% {
"next_appt_date": next_appt_date,
"next_appt_visit_code": next_appt.visit_code,
"dt": next_appt_date,
"visit_code": next_appt.visit_code,
}
}
)

if (
self.next_appt_date
self.suggested_date
and self.related_visit.appointment.next.appt_status not in [NEW_APPT, SKIPPED_APPT]
and self.next_appt_date
and self.suggested_date
> to_local(self.related_visit.appointment.next.appt_datetime).date()
):
next_appt = self.related_visit.appointment.next
date_format = convert_php_dateformat(settings.SHORT_DATE_FORMAT)
raise forms.ValidationError(
{
"appt_date": _(
"Invalid. Expected a date before next appointment "
"`%(next_appt_visit_code)s` on "
"%(next_appt_date_str)s."
"Invalid. Expected a date before appointment "
"`%(visit_code)s` on "
"%(dt_str)s."
)
% {
"next_appt_visit_code": next_appt.visit_code,
"next_appt_date_str": to_local(next_appt.appt_datetime)
"visit_code": next_appt.visit_code,
"dt_str": to_local(next_appt.appt_datetime)
.date()
.strftime(date_format),
}
}
)

def validate_best_next_visit_code(self):
if appt_date := self.next_appt_date:
def validate_suggested_visit_code(self):
if suggested_date := self.suggested_date:
subject_visit = self.cleaned_data.get("subject_visit")
try:
appointment = get_appointment_by_datetime(
self.as_appt_datetime(appt_date),
self.as_datetime(suggested_date),
subject_identifier=subject_visit.subject_identifier,
visit_schedule_name=subject_visit.visit_schedule.name,
schedule_name=subject_visit.schedule.name,
Expand All @@ -103,30 +111,22 @@ def validate_best_next_visit_code(self):
)

if (
self.cleaned_data.get("visitschedule")
and self.cleaned_data.get("visitschedule").visit_code != appointment.visit_code
self.suggested_visit_code
and self.suggested_visit_code != appointment.visit_code
):
date_format = convert_php_dateformat(settings.SHORT_DATE_FORMAT)
raise forms.ValidationError(
{
"visitschedule": _(
"Expected %(visit_code)s using %(appt_date_str)s from above."
"Expected %(visit_code)s using %(dt_str)s from above."
)
% {
"visit_code": appointment.visit_code,
"appt_date_str": appt_date.strftime(date_format),
"dt_str": suggested_date.strftime(date_format),
}
}
)

@staticmethod
def as_appt_datetime(appt_date: date) -> datetime:
return datetime(
appt_date.year,
appt_date.month,
appt_date.day,
23,
59,
59,
tzinfo=ZoneInfo("UTC"),
)
def as_datetime(dt: date) -> datetime:
return datetime(dt.year, dt.month, dt.day, 23, 59, 59, tzinfo=ZoneInfo("UTC"))
30 changes: 14 additions & 16 deletions edc_next_appointment/tests/tests/test_next_appointment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dateutil.relativedelta import relativedelta
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.test import TestCase, override_settings, tag
from django.test import TestCase, override_settings
from edc_appointment.constants import SKIPPED_APPT
from edc_appointment.models import Appointment
from edc_constants.constants import NOT_APPLICABLE, PATIENT
Expand Down Expand Up @@ -63,9 +63,9 @@ def setUp(self):
)

@override_settings(
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING=[
("next_appointment_app.nextappointment", "appt_date")
]
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING={
"next_appointment_app.nextappointment": ("appt_date", "visitschedule")
}
)
@time_machine.travel(dt.datetime(2019, 6, 11, 8, 00, tzinfo=utc))
def test_ok(self):
Expand All @@ -74,11 +74,10 @@ def test_ok(self):
subject_visit_model_cls = get_related_visit_model_cls()
subject_visit_model_cls.objects.create(appointment=appointment, reason=SCHEDULED)

@tag("1")
@override_settings(
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING=[
("next_appointment_app.nextappointment", "appt_date")
]
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING={
"next_appointment_app.nextappointment": ("appt_date", "visitschedule")
}
)
@time_machine.travel(dt.datetime(2019, 6, 11, 8, 00, tzinfo=utc))
def test_next_appt_ok(self):
Expand All @@ -95,8 +94,8 @@ def test_next_appt_ok(self):
subject_visit=subject_visit,
report_datetime=subject_visit.report_datetime,
appt_date=(appointment.appt_datetime + relativedelta(months=3)).date(),
info_source=InfoSources.objects.get(name=PATIENT),
visitschedule=VisitSchedule.objects.get(visit_code="1000"),
info_source=InfoSources.objects.get(name=PATIENT),
)
form = NextAppointmentForm(data=data)
form.is_valid()
Expand Down Expand Up @@ -135,9 +134,9 @@ def test_next_appt_ok(self):
self.assertEqual(apppointment.appt_timing, NOT_APPLICABLE)

@override_settings(
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING=[
("next_appointment_app.nextappointment", "appt_date")
]
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING={
"next_appointment_app.nextappointment": ("appt_date", "visitschedule")
}
)
@time_machine.travel(dt.datetime(2019, 6, 11, 8, 00, tzinfo=utc))
def test_next_appt_with_health_facility(self):
Expand Down Expand Up @@ -196,11 +195,10 @@ def test_next_appt_with_health_facility(self):
form.is_valid()
self.assertEqual({}, form._errors)

@tag("1")
@override_settings(
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING=[
("next_appointment_app.nextappointment", "appt_date")
],
EDC_APPOINTMENT_ALLOW_SKIPPED_APPT_USING={
"next_appointment_app.nextappointment": ("appt_date", "visitschedule")
},
LANGUAGE_CODE="sw",
)
@time_machine.travel(dt.datetime(2019, 6, 11, 8, 00, tzinfo=utc_tz))
Expand Down
4 changes: 2 additions & 2 deletions next_appointment_app/consents.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
v1 = Consent(
"next_appointment_app.subjectconsent",
version="1",
start=datetime(2018, 1, 1, 0, 0, tzinfo=ZoneInfo("utc")),
end=datetime(2023, 1, 1, 0, 0, tzinfo=ZoneInfo("utc")),
start=datetime(2018, 1, 1, 0, 0, tzinfo=ZoneInfo("UTC")),
end=datetime(2023, 1, 1, 0, 0, tzinfo=ZoneInfo("UTC")),
age_min=18,
age_is_adult=18,
age_max=110,
Expand Down
4 changes: 2 additions & 2 deletions runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
ETC_DIR=os.path.join(base_dir, app_name, "tests", "etc"),
SUBJECT_VISIT_MODEL="edc_visit_tracking.subjectvisit",
SUBJECT_VISIT_MISSED_MODEL="edc_visit_tracking.subjectvisitmissed",
EDC_PROTOCOL_STUDY_OPEN_DATETIME=datetime(2018, 1, 1, 0, 0, tzinfo=ZoneInfo("utc")),
EDC_PROTOCOL_STUDY_CLOSE_DATETIME=datetime(2023, 1, 1, 0, 0, tzinfo=ZoneInfo("utc")),
EDC_PROTOCOL_STUDY_OPEN_DATETIME=datetime(2018, 1, 1, 0, 0, tzinfo=ZoneInfo("UTC")),
EDC_PROTOCOL_STUDY_CLOSE_DATETIME=datetime(2023, 1, 1, 0, 0, tzinfo=ZoneInfo("UTC")),
INSTALLED_APPS=[
"django.contrib.admin",
"django.contrib.auth",
Expand Down

0 comments on commit d36c661

Please sign in to comment.