Garde partagée, permettre une date de fin sur un agenda #71633 #13
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 2.2.26 on 2022-11-30 11:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('agendas', '0143_shared_custody_remove_children_field'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='sharedcustodyagenda',
|
||||
name='date_end',
|
||||
field=models.DateField(null=True, verbose_name='End'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='sharedcustodyagenda',
|
||||
constraint=models.UniqueConstraint(
|
||||
condition=models.Q(date_end__isnull=True), fields=('child',), name='unique_child_no_date_end'
|
||||
),
|
||||
),
|
||||
]
|
|
@ -847,10 +847,12 @@ class Agenda(models.Model):
|
|||
@staticmethod
|
||||
def filter_for_guardian(qs, guardian_external_id, child_external_id, min_start=None, max_start=None):
|
||||
agendas = SharedCustodyAgenda.objects.filter(child__user_external_id=child_external_id).order_by(
|
||||
'-date_start'
|
||||
'date_start'
|
||||
)
|
||||
if max_start:
|
||||
agendas = agendas.filter(date_start__lte=max_start)
|
||||
if min_start:
|
||||
agendas = agendas.filter(Q(date_end__isnull=True) | Q(date_end__gte=min_start))
|
||||
|
||||
if not agendas:
|
||||
return qs
|
||||
|
@ -861,20 +863,29 @@ class Agenda(models.Model):
|
|||
.annotate(odd_week=F('week_number') % 2)
|
||||
)
|
||||
|
||||
previous_date_start = None
|
||||
previous_date_end = None
|
||||
filtered_qs = Event.objects.none()
|
||||
for agenda in agendas:
|
||||
if previous_date_start and min_start and previous_date_start < min_start.date():
|
||||
break
|
||||
filtered_qs |= Agenda.filter_for_custody_agenda(
|
||||
qs, agenda, guardian_external_id, date_end=previous_date_start
|
||||
)
|
||||
previous_date_start = agenda.date_start
|
||||
filtered_qs |= Agenda.filter_for_custody_agenda(qs, agenda, guardian_external_id)
|
||||
|
||||
if not previous_date_end:
|
||||
# first shared custody agenda, include all events before it begins
|
||||
filtered_qs |= qs.filter(start_datetime__lt=agenda.date_start)
|
||||
else:
|
||||
# include all events between agendas
|
||||
filtered_qs |= qs.filter(
|
||||
start_datetime__lt=agenda.date_start, start_datetime__date__gt=previous_date_end
|
||||
)
|
||||
previous_date_end = agenda.date_end
|
||||
|
||||
if previous_date_end:
|
||||
# last agenda has end date, include all events after it
|
||||
filtered_qs |= qs.filter(start_datetime__gt=previous_date_end)
|
||||
|
||||
return filtered_qs
|
||||
|
||||
@staticmethod
|
||||
def filter_for_custody_agenda(qs, agenda, guardian_external_id, date_end=None):
|
||||
def filter_for_custody_agenda(qs, agenda, guardian_external_id):
|
||||
rules = (
|
||||
SharedCustodyRule.objects.filter(
|
||||
guardian__user_external_id=guardian_external_id,
|
||||
|
@ -916,8 +927,8 @@ class Agenda(models.Model):
|
|||
(rules_lookup | Q(in_exceptional_period=True)) & Q(in_excluded_exceptional_period=False),
|
||||
start_datetime__gte=agenda.date_start,
|
||||
)
|
||||
if date_end:
|
||||
qs = qs.filter(start_datetime__lt=date_end)
|
||||
if agenda.date_end:
|
||||
qs = qs.filter(start_datetime__date__lte=agenda.date_end)
|
||||
|
||||
return qs
|
||||
|
||||
|
@ -3224,6 +3235,14 @@ class SharedCustodyAgenda(models.Model):
|
|||
)
|
||||
child = models.ForeignKey(Person, verbose_name=_('Child'), on_delete=models.CASCADE, related_name='+')
|
||||
date_start = models.DateField(_('Start'))
|
||||
date_end = models.DateField(_('End'), null=True)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=['child'], condition=Q(date_end__isnull=True), name='unique_child_no_date_end'
|
||||
)
|
||||
]
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
|
|
|
@ -3,7 +3,7 @@ import datetime
|
|||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db import models, transaction
|
||||
from django.db.models import ExpressionWrapper, F
|
||||
from django.db.models import ExpressionWrapper, F, Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
@ -585,7 +585,34 @@ class SubscriptionSerializer(serializers.ModelSerializer):
|
|||
return attrs
|
||||
|
||||
|
||||
class SharedCustodyAgendaCreateSerializer(serializers.Serializer):
|
||||
class SharedCustodyAgendaMixin:
|
||||
def validate(self, attrs):
|
||||
date_start = attrs['date_start']
|
||||
date_end = attrs.get('date_end')
|
||||
|
||||
if date_end and date_start >= date_end:
|
||||
raise ValidationError(_('date_start must be before date_end'))
|
||||
|
||||
child_id = self.get_child_id(attrs)
|
||||
overlapping_agendas = SharedCustodyAgenda.objects.filter(
|
||||
Q(date_end__gte=date_start) | Q(date_end__isnull=True), child__user_external_id=child_id
|
||||
)
|
||||
if date_end:
|
||||
overlapping_agendas = overlapping_agendas.filter(date_start__lte=date_end)
|
||||
if self.instance:
|
||||
overlapping_agendas = overlapping_agendas.exclude(pk=self.instance.pk)
|
||||
|
||||
if overlapping_agendas:
|
||||
request = self.context.get('request')
|
||||
raise ValidationError(
|
||||
_('Invalid date_start/date_end, agenda would overlap with %s.')
|
||||
% request.build_absolute_uri(overlapping_agendas[0].get_absolute_url())
|
||||
)
|
||||
|
||||
return attrs
|
||||
|
||||
|
||||
class SharedCustodyAgendaCreateSerializer(SharedCustodyAgendaMixin, serializers.Serializer):
|
||||
period_mirrors = {
|
||||
'even': 'odd',
|
||||
'odd': 'even',
|
||||
|
@ -606,10 +633,16 @@ class SharedCustodyAgendaCreateSerializer(serializers.Serializer):
|
|||
child_id = serializers.CharField(max_length=250)
|
||||
weeks = serializers.ChoiceField(required=False, choices=['', 'even', 'odd'])
|
||||
date_start = serializers.DateField(required=True)
|
||||
date_end = serializers.DateField(required=False)
|
||||
|
||||
settings_url = serializers.SerializerMethodField()
|
||||
|
||||
def get_child_id(self, attrs):
|
||||
return attrs['child_id']
|
||||
|
||||
def validate(self, attrs):
|
||||
super().validate(attrs)
|
||||
|
||||
attrs['holidays'] = collections.defaultdict(dict)
|
||||
for key, value in self.initial_data.items():
|
||||
if key in attrs or ':' not in key:
|
||||
|
@ -675,6 +708,7 @@ class SharedCustodyAgendaCreateSerializer(serializers.Serializer):
|
|||
second_guardian=other_guardian,
|
||||
child=child,
|
||||
date_start=validated_data['date_start'],
|
||||
date_end=validated_data.get('date_end'),
|
||||
)
|
||||
|
||||
if validated_data.get('weeks'):
|
||||
|
@ -723,7 +757,10 @@ class SharedCustodyAgendaCreateSerializer(serializers.Serializer):
|
|||
return request.build_absolute_uri(obj.get_settings_url())
|
||||
|
||||
|
||||
class SharedCustodyAgendaSerializer(serializers.ModelSerializer):
|
||||
class SharedCustodyAgendaSerializer(SharedCustodyAgendaMixin, serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SharedCustodyAgenda
|
||||
fields = ['date_start']
|
||||
fields = ['date_start', 'date_end']
|
||||
|
||||
def get_child_id(self, attrs):
|
||||
return self.instance.child.user_external_id
|
||||
|
|
|
@ -2988,7 +2988,7 @@ class SharedCustodyAgendas(APIView):
|
|||
serializer_class = serializers.SharedCustodyAgendaCreateSerializer
|
||||
|
||||
def post(self, request):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
serializer = self.serializer_class(data=request.data, context={'request': request})
|
||||
if not serializer.is_valid():
|
||||
raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors)
|
||||
agenda = serializer.save()
|
||||
|
@ -3011,7 +3011,7 @@ class SharedCustodyAgendaAPI(APIView):
|
|||
def patch(self, request, agenda_pk):
|
||||
agenda = get_object_or_404(SharedCustodyAgenda, pk=agenda_pk)
|
||||
|
||||
serializer = self.serializer_class(agenda, data=request.data)
|
||||
serializer = self.serializer_class(agenda, data=request.data, context={'request': request})
|
||||
if not serializer.is_valid():
|
||||
raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors)
|
||||
agenda = serializer.save()
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<tr>
|
||||
<th>{% trans "Week" %} {{ week }}</th>
|
||||
{% for slot in slots %}
|
||||
{% if slot.date < agenda.date_start %}
|
||||
{% if slot.date < agenda.date_start or agenda.date_end and slot.date > agenda.date_end %}
|
||||
<td></td>
|
||||
{% else %}
|
||||
<td class="guardian {% if slot.guardian == agenda.first_guardian %}first-guardian{% else %}second-guardian{% endif %}">{{ slot }}</td>
|
||||
|
|
|
@ -423,7 +423,8 @@ def test_datetimes_multiple_agendas_queries(app):
|
|||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=now() - datetime.timedelta(days=5 + i),
|
||||
date_start=now() - datetime.timedelta(days=5 + 2 * i),
|
||||
date_end=now() - datetime.timedelta(days=5 + 2 * i + 1),
|
||||
)
|
||||
|
||||
SharedCustodyRule.objects.create(agenda=agenda, guardian=father, days=list(range(7)), weeks='even')
|
||||
|
@ -1280,6 +1281,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
|
|||
)
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
agenda.date_end = datetime.date(year=2022, month=3, day=9)
|
||||
agenda.save()
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
|
@ -1306,6 +1309,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
|
|||
'first-agenda@event-wednesday--2022-03-30-1400',
|
||||
]
|
||||
|
||||
agenda.date_end = datetime.date(year=2022, month=3, day=16)
|
||||
agenda.save()
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
|
@ -1348,6 +1353,8 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
|
|||
'first-agenda@event-wednesday--2022-03-09-1400',
|
||||
]
|
||||
|
||||
agenda.date_end = datetime.date(year=2022, month=3, day=21)
|
||||
agenda.save()
|
||||
other_person = Person.objects.create(user_external_id='other_person', first_name='O', last_name='P')
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=other_person,
|
||||
|
@ -1384,6 +1391,78 @@ def test_datetimes_multiple_agendas_shared_custody_date_start(app):
|
|||
]
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2022-03-01 14:00')
|
||||
def test_datetimes_multiple_agendas_shared_custody_date_boundaries(app):
|
||||
agenda = Agenda.objects.create(label='First agenda', kind='events', maximal_booking_delay=0)
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
start_datetime = make_aware(datetime.datetime(year=2022, month=3, day=2, hour=14, minute=0))
|
||||
wednesday_event = Event.objects.create(
|
||||
slug='event-wednesday',
|
||||
start_datetime=start_datetime,
|
||||
recurrence_days=[2],
|
||||
recurrence_end_date=datetime.datetime(year=2022, month=5, day=15),
|
||||
places=5,
|
||||
agenda=agenda,
|
||||
)
|
||||
wednesday_event.create_all_recurrences()
|
||||
Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='child_id',
|
||||
date_start=wednesday_event.start_datetime,
|
||||
date_end=wednesday_event.recurrence_end_date,
|
||||
)
|
||||
|
||||
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
|
||||
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe')
|
||||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=datetime.datetime(year=2022, month=3, day=15), # 15 days after recurring event start
|
||||
date_end=datetime.datetime(year=2022, month=3, day=30), # 30 days after recurring event start
|
||||
)
|
||||
SharedCustodyRule.objects.create(agenda=agenda, guardian=father, days=list(range(7)))
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=datetime.datetime(year=2022, month=4, day=13), # 45 days after recurring event start
|
||||
date_end=datetime.datetime(year=2022, month=4, day=28), # 60 days after recurring event start
|
||||
)
|
||||
SharedCustodyRule.objects.create(agenda=agenda, guardian=mother, days=list(range(7)))
|
||||
|
||||
resp = app.get(
|
||||
'/api/agendas/datetimes/',
|
||||
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
|
||||
)
|
||||
assert [d['id'] for d in resp.json['data']] == [
|
||||
'first-agenda@event-wednesday--2022-03-02-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-03-09-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-03-16-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-03-23-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-03-30-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-04-06-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-05-04-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-05-11-1400', # no custody agenda
|
||||
]
|
||||
|
||||
resp = app.get(
|
||||
'/api/agendas/datetimes/',
|
||||
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
|
||||
)
|
||||
assert [d['id'] for d in resp.json['data']] == [
|
||||
'first-agenda@event-wednesday--2022-03-02-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-03-09-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-04-06-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-04-13-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-04-20-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-04-27-1400', # has custody
|
||||
'first-agenda@event-wednesday--2022-05-04-1400', # no custody agenda
|
||||
'first-agenda@event-wednesday--2022-05-11-1400', # no custody agenda
|
||||
]
|
||||
|
||||
|
||||
def test_datetimes_multiple_agendas_with_status(app):
|
||||
agenda = Agenda.objects.create(label='agenda', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
|
|
@ -277,7 +277,11 @@ def test_recurring_events_api_list_shared_custody_start_date(app):
|
|||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
|
||||
custody_agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father, second_guardian=mother, child=child, date_start=now()
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=now(),
|
||||
date_end=now() + datetime.timedelta(days=14),
|
||||
)
|
||||
SharedCustodyRule.objects.create(agenda=custody_agenda, guardian=father, days=[0], weeks='even')
|
||||
SharedCustodyRule.objects.create(agenda=custody_agenda, guardian=mother, days=[1, 2], weeks='odd')
|
||||
|
|
|
@ -677,7 +677,11 @@ def test_api_events_fillslots_multiple_agendas_shared_custody_date_start(app, us
|
|||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father, second_guardian=mother, child=child, date_start=now()
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=now(),
|
||||
date_end=datetime.date(year=2022, month=3, day=9),
|
||||
)
|
||||
SharedCustodyRule.objects.create(agenda=agenda, guardian=father, days=list(range(7)))
|
||||
|
||||
|
|
|
@ -1376,6 +1376,8 @@ def test_recurring_events_api_fillslots_shared_custody(app, user, freezer):
|
|||
]
|
||||
|
||||
# give father full custody from 14/03/2022
|
||||
agenda.date_end = datetime.date(year=2022, month=3, day=13)
|
||||
agenda.save()
|
||||
agenda2 = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
|
|
|
@ -45,6 +45,53 @@ def test_add_shared_custody_agenda(app, user, settings):
|
|||
'backoffice_url': 'http://testserver/manage/shared-custody/%s/' % agenda.pk,
|
||||
}
|
||||
|
||||
# cannot add agenda without date_end
|
||||
params['date_start'] = '2019-01-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params, status=400)
|
||||
assert resp.json['errors']['non_field_errors'][0] == (
|
||||
'Invalid date_start/date_end, agenda would overlap with http://testserver/manage/shared-custody/%s/.'
|
||||
% agenda.pk
|
||||
)
|
||||
|
||||
# cannot add agenda with date_end after existing agenda date_start
|
||||
params['date_start'] = '2019-01-01'
|
||||
params['date_end'] = '2020-11-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params, status=400)
|
||||
assert resp.json['errors']['non_field_errors'][0] == (
|
||||
'Invalid date_start/date_end, agenda would overlap with http://testserver/manage/shared-custody/%s/.'
|
||||
% agenda.pk
|
||||
)
|
||||
|
||||
# can add agenda with date_end before existing agenda date_start
|
||||
params['date_start'] = '2019-01-01'
|
||||
params['date_end'] = '2020-01-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params)
|
||||
assert resp.json['err'] == 0
|
||||
new_agenda_id = resp.json['data']['id']
|
||||
|
||||
# cannot add agenda that would overlap previous one
|
||||
params['date_start'] = '2018-01-01'
|
||||
params['date_end'] = '2019-01-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params, status=400)
|
||||
assert resp.json['errors']['non_field_errors'][0] == (
|
||||
'Invalid date_start/date_end, agenda would overlap with http://testserver/manage/shared-custody/%s/.'
|
||||
% new_agenda_id
|
||||
)
|
||||
|
||||
params['date_start'] = '2020-01-01'
|
||||
params['date_end'] = '2020-02-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params, status=400)
|
||||
assert resp.json['errors']['non_field_errors'][0] == (
|
||||
'Invalid date_start/date_end, agenda would overlap with http://testserver/manage/shared-custody/%s/.'
|
||||
% new_agenda_id
|
||||
)
|
||||
|
||||
params['date_start'] = '2021-02-01'
|
||||
params['date_end'] = '2021-01-01'
|
||||
resp = app.post_json('/api/shared-custody/', params=params, status=400)
|
||||
assert resp.json['errors']['non_field_errors'][0] == 'date_start must be before date_end'
|
||||
|
||||
# different child, no overlap check
|
||||
params = {
|
||||
'guardian_first_name': 'John',
|
||||
'guardian_last_name': 'Doe',
|
||||
|
@ -59,7 +106,7 @@ def test_add_shared_custody_agenda(app, user, settings):
|
|||
}
|
||||
resp = app.post_json('/api/shared-custody/', params=params)
|
||||
assert resp.json['data']['id'] != agenda.pk
|
||||
assert SharedCustodyAgenda.objects.filter(first_guardian=first_guardian).count() == 2
|
||||
assert SharedCustodyAgenda.objects.filter(first_guardian=first_guardian).count() == 3
|
||||
|
||||
|
||||
def test_add_shared_custody_agenda_with_rules(app, user, settings):
|
||||
|
@ -90,18 +137,21 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
|
|||
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
|
||||
assert not agenda.is_complete()
|
||||
assert not agenda.rules.exists()
|
||||
agenda.delete()
|
||||
|
||||
resp = app.post_json('/api/shared-custody/', params={'weeks': 'even', **params})
|
||||
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
|
||||
assert agenda.is_complete()
|
||||
assert agenda.rules.filter(guardian__first_name='John', weeks='even').exists()
|
||||
assert agenda.rules.filter(guardian__first_name='Jane', weeks='odd').exists()
|
||||
agenda.delete()
|
||||
|
||||
resp = app.post_json('/api/shared-custody/', params={'weeks': 'odd', **params})
|
||||
agenda = SharedCustodyAgenda.objects.get(pk=resp.json['data']['id'])
|
||||
assert agenda.is_complete()
|
||||
assert agenda.rules.filter(guardian__first_name='John', weeks='odd').exists()
|
||||
assert agenda.rules.filter(guardian__first_name='Jane', weeks='even').exists()
|
||||
agenda.delete()
|
||||
|
||||
resp = app.post_json(
|
||||
'/api/shared-custody/', params={'christmas_holidays:periodicity': 'first-half', **params}
|
||||
|
@ -114,6 +164,7 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
|
|||
guardian__first_name='Jane', holiday__slug='christmas_holidays', periodicity='second-half', years=''
|
||||
).exists()
|
||||
assert agenda.periods.count() == 12
|
||||
agenda.delete()
|
||||
|
||||
resp = app.post_json(
|
||||
'/api/shared-custody/',
|
||||
|
@ -149,6 +200,7 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
|
|||
years='odd',
|
||||
).exists()
|
||||
assert agenda.periods.count() == 20
|
||||
agenda.delete()
|
||||
|
||||
# unknown holiday
|
||||
resp = app.post_json(
|
||||
|
@ -179,7 +231,7 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings):
|
|||
assert resp.json['errors']['non_field_errors'][0] == 'Short holidays cannot be cut into quarters.'
|
||||
|
||||
|
||||
def test_shared_custody_agenda_update_date_start(app, user, settings):
|
||||
def test_shared_custody_agenda_update_dates(app, user, settings):
|
||||
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
|
||||
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe')
|
||||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
|
@ -193,6 +245,54 @@ def test_shared_custody_agenda_update_date_start(app, user, settings):
|
|||
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.date_start == datetime.date(year=2020, month=10, day=20)
|
||||
assert agenda.date_end is None
|
||||
|
||||
resp = app.patch_json(
|
||||
'/api/shared-custody/%s/' % agenda.pk, params={'date_start': '2020-10-20', 'date_end': '2021-01-01'}
|
||||
)
|
||||
assert resp.json['err'] == 0
|
||||
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.date_start == datetime.date(year=2020, month=10, day=20)
|
||||
assert agenda.date_end == datetime.date(year=2021, month=1, day=1)
|
||||
|
||||
resp = app.patch_json(
|
||||
'/api/shared-custody/%s/' % agenda.pk, params={'date_start': '2021-01-01', 'date_end': '2022-01-01'}
|
||||
)
|
||||
assert resp.json['err'] == 0
|
||||
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.date_start == datetime.date(year=2021, month=1, day=1)
|
||||
assert agenda.date_end == datetime.date(year=2022, month=1, day=1)
|
||||
|
||||
resp = app.patch_json(
|
||||
'/api/shared-custody/%s/' % agenda.pk, params={'date_start': '2021-01-01', 'date_end': None}
|
||||
)
|
||||
assert resp.json['err'] == 0
|
||||
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.date_start == datetime.date(year=2021, month=1, day=1)
|
||||
assert agenda.date_end is None
|
||||
|
||||
SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=datetime.date(year=2020, month=1, day=1),
|
||||
date_end=datetime.date(year=2020, month=6, day=1),
|
||||
)
|
||||
|
||||
resp = app.patch_json(
|
||||
'/api/shared-custody/%s/' % agenda.pk, params={'date_start': '2020-01-01'}, status=400
|
||||
)
|
||||
assert 'overlap' in resp.json['errors']['non_field_errors'][0]
|
||||
|
||||
resp = app.patch_json(
|
||||
'/api/shared-custody/%s/' % agenda.pk,
|
||||
params={'date_start': '2020-10-20', 'date_end': '2019-10-20'},
|
||||
status=400,
|
||||
)
|
||||
assert resp.json['errors']['non_field_errors'][0] == 'date_start must be before date_end'
|
||||
|
||||
resp = app.patch_json('/api/shared-custody/%s/' % agenda.pk, params={'first_guardian': 'xxx'}, status=400)
|
||||
app.patch_json('/api/shared-custody/%s/' % agenda.pk, params={}, status=400)
|
||||
|
|
|
@ -216,7 +216,7 @@ def test_shared_custody_agenda_month_view(app, admin_user):
|
|||
|
||||
|
||||
@pytest.mark.freeze_time('2022-02-01 14:00') # Tuesday
|
||||
def test_shared_custody_agenda_month_view_date_start(app, admin_user):
|
||||
def test_shared_custody_agenda_month_view_dates(app, admin_user):
|
||||
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
|
||||
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe')
|
||||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
|
@ -248,11 +248,24 @@ def test_shared_custody_agenda_month_view_date_start(app, admin_user):
|
|||
new_days = [x.text for x in resp.pyquery('tbody tr th span')]
|
||||
assert days == new_days
|
||||
|
||||
# custody for only one day
|
||||
agenda.date_end = datetime.date(2022, 2, 14)
|
||||
agenda.save()
|
||||
resp = app.get('/manage/shared-custody/%s/' % agenda.pk).follow()
|
||||
assert resp.text.count('<td></td>') == 34
|
||||
assert len([x.text for x in resp.pyquery('tbody tr td.guardian')]) == 1
|
||||
|
||||
# month before date_start
|
||||
resp = resp.click('←')
|
||||
assert resp.text.count('<td></td>') == 42
|
||||
assert len([x.text for x in resp.pyquery('tbody tr td.guardian')]) == 0
|
||||
|
||||
# month after date_end
|
||||
resp = app.get('/manage/shared-custody/%s/' % agenda.pk).follow()
|
||||
resp = resp.click('→')
|
||||
assert resp.text.count('<td></td>') == 35
|
||||
assert len([x.text for x in resp.pyquery('tbody tr td.guardian')]) == 0
|
||||
|
||||
|
||||
def test_shared_custody_agenda_month_view_queries(app, admin_user):
|
||||
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
|
||||
|
|
|
@ -8,6 +8,7 @@ import requests
|
|||
from django.contrib.auth.models import Group, User
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.management import call_command
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.db.models import Q
|
||||
from django.test import override_settings
|
||||
from django.utils.timezone import localtime, make_aware, now
|
||||
|
@ -3402,3 +3403,34 @@ def test_shared_custody_agenda_update_holiday_rules_command():
|
|||
assert period1.date_end == datetime.date(year=2022, month=1, day=3)
|
||||
assert period2.date_start == datetime.date(year=2022, month=12, day=18)
|
||||
assert period2.date_end == datetime.date(year=2023, month=1, day=3)
|
||||
|
||||
|
||||
def test_shared_custody_agenda_unique_child_no_date_end():
|
||||
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe')
|
||||
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe')
|
||||
child = Person.objects.create(user_external_id='child_id', first_name='James', last_name='Doe')
|
||||
SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=datetime.date(2020, 1, 1),
|
||||
date_end=datetime.date(2021, 1, 1),
|
||||
)
|
||||
agenda = SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father, second_guardian=mother, child=child, date_start=datetime.date(2022, 1, 1)
|
||||
)
|
||||
|
||||
with pytest.raises(IntegrityError):
|
||||
with transaction.atomic():
|
||||
SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father,
|
||||
second_guardian=mother,
|
||||
child=child,
|
||||
date_start=datetime.date(2023, 1, 1),
|
||||
)
|
||||
|
||||
agenda.date_end = datetime.date(2022, 6, 1)
|
||||
agenda.save()
|
||||
SharedCustodyAgenda.objects.create(
|
||||
first_guardian=father, second_guardian=mother, child=child, date_start=datetime.date(2023, 1, 1)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue