0001-agendas-add-management-role-for-shared-custody-66671.patch
chrono/agendas/migrations/0131_sharedcustodysettings.py | ||
---|---|---|
1 |
# Generated by Django 2.2.26 on 2022-06-27 16:02 |
|
2 | ||
3 |
import django.db.models.deletion |
|
4 |
from django.db import migrations, models |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('auth', '0011_update_proxy_permissions'), |
|
11 |
('agendas', '0130_event_date_range_constraint'), |
|
12 |
] |
|
13 | ||
14 |
operations = [ |
|
15 |
migrations.CreateModel( |
|
16 |
name='SharedCustodySettings', |
|
17 |
fields=[ |
|
18 |
( |
|
19 |
'id', |
|
20 |
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), |
|
21 |
), |
|
22 |
( |
|
23 |
'management_role', |
|
24 |
models.ForeignKey( |
|
25 |
blank=True, |
|
26 |
default=None, |
|
27 |
null=True, |
|
28 |
on_delete=django.db.models.deletion.SET_NULL, |
|
29 |
related_name='+', |
|
30 |
to='auth.Group', |
|
31 |
verbose_name='Management role', |
|
32 |
), |
|
33 |
), |
|
34 |
], |
|
35 |
), |
|
36 |
] |
chrono/agendas/models.py | ||
---|---|---|
3487 | 3487 |
date_format(self.date_end, 'SHORT_DATE_FORMAT'), |
3488 | 3488 |
) |
3489 | 3489 |
return '%s, %s' % (self.guardian, exc_repr) |
3490 | ||
3491 | ||
3492 |
class SharedCustodySettings(models.Model): |
|
3493 |
management_role = models.ForeignKey( |
|
3494 |
Group, |
|
3495 |
blank=True, |
|
3496 |
null=True, |
|
3497 |
default=None, |
|
3498 |
related_name='+', |
|
3499 |
verbose_name=_('Management role'), |
|
3500 |
on_delete=models.SET_NULL, |
|
3501 |
) |
|
3502 | ||
3503 |
@classmethod |
|
3504 |
def get_singleton(cls): |
|
3505 |
try: |
|
3506 |
return cls.objects.get() |
|
3507 |
except cls.DoesNotExist: |
|
3508 |
return cls() |
chrono/manager/forms.py | ||
---|---|---|
57 | 57 |
SharedCustodyHolidayRule, |
58 | 58 |
SharedCustodyPeriod, |
59 | 59 |
SharedCustodyRule, |
60 |
SharedCustodySettings, |
|
60 | 61 |
Subscription, |
61 | 62 |
TimePeriod, |
62 | 63 |
TimePeriodException, |
... | ... | |
1550 | 1551 |
self.add_error('date_end', _('End date must be greater than start date.')) |
1551 | 1552 | |
1552 | 1553 |
return cleaned_data |
1554 | ||
1555 | ||
1556 |
class SharedCustodySettingsForm(forms.ModelForm): |
|
1557 |
management_role = forms.ModelChoiceField( |
|
1558 |
label=_('Management role'), required=False, queryset=Group.objects.all().order_by('name') |
|
1559 |
) |
|
1560 | ||
1561 |
class Meta: |
|
1562 |
model = SharedCustodySettings |
|
1563 |
fields = '__all__' |
chrono/manager/templates/chrono/manager_home.html | ||
---|---|---|
12 | 12 |
<li><a rel="popup" href="{% url 'chrono-manager-agendas-export' %}" data-autoclose-dialog="true">{% trans 'Export' %}</a></li> |
13 | 13 |
<li><a href="{% url 'chrono-manager-events-type-list' %}">{% trans 'Events types' %}</a></li> |
14 | 14 |
<li><a href="{% url 'chrono-manager-check-type-list' %}">{% trans 'Check types' %}</a></li> |
15 |
{% if shared_custody_enabled %} |
|
16 |
<li><a rel="popup" href="{% url 'chrono-manager-shared-custody-settings' %}">{% trans 'Shared custody' %}</a></li> |
|
17 |
{% endif %} |
|
15 | 18 |
{% endif %} |
16 | 19 |
{% if has_access_to_unavailability_calendars %} |
17 | 20 |
<li><a href="{% url 'chrono-manager-unavailability-calendar-list' %}">{% trans 'Unavailability calendars' %}</a></li> |
chrono/manager/urls.py | ||
---|---|---|
400 | 400 |
views.agenda_import_events_sample_csv, |
401 | 401 |
name='chrono-manager-sample-events-csv', |
402 | 402 |
), |
403 |
url( |
|
404 |
r'^shared-custody/settings/$', |
|
405 |
views.shared_custody_settings, |
|
406 |
name='chrono-manager-shared-custody-settings', |
|
407 |
), |
|
403 | 408 |
url( |
404 | 409 |
r'^shared-custody/(?P<pk>\d+)/$', |
405 | 410 |
views.shared_custody_agenda_view, |
chrono/manager/views.py | ||
---|---|---|
26 | 26 | |
27 | 27 |
import requests |
28 | 28 |
from dateutil.relativedelta import MO, relativedelta |
29 |
from django.conf import settings |
|
29 | 30 |
from django.contrib import messages |
30 | 31 |
from django.core.exceptions import PermissionDenied |
31 | 32 |
from django.db import IntegrityError, transaction |
... | ... | |
80 | 81 |
SharedCustodyHolidayRule, |
81 | 82 |
SharedCustodyPeriod, |
82 | 83 |
SharedCustodyRule, |
84 |
SharedCustodySettings, |
|
83 | 85 |
TimePeriod, |
84 | 86 |
TimePeriodException, |
85 | 87 |
TimePeriodExceptionSource, |
... | ... | |
122 | 124 |
SharedCustodyHolidayRuleForm, |
123 | 125 |
SharedCustodyPeriodForm, |
124 | 126 |
SharedCustodyRuleForm, |
127 |
SharedCustodySettingsForm, |
|
125 | 128 |
SubscriptionCheckFilterSet, |
126 | 129 |
TimePeriodAddForm, |
127 | 130 |
TimePeriodExceptionForm, |
... | ... | |
163 | 166 |
def get_context_data(self, **kwargs): |
164 | 167 |
context = super().get_context_data(**kwargs) |
165 | 168 |
context['has_access_to_unavailability_calendars'] = self.has_access_to_unavailability_calendars() |
169 |
context['shared_custody_enabled'] = settings.SHARED_CUSTODY_ENABLED |
|
166 | 170 |
return context |
167 | 171 | |
168 | 172 |
def get(self, request, *args, **kwargs): |
... | ... | |
3685 | 3689 |
return super().dispatch(request, *args, **kwargs) |
3686 | 3690 | |
3687 | 3691 |
def check_permissions(self, user): |
3688 |
return user.is_staff |
|
3692 |
if user.is_staff: |
|
3693 |
return True |
|
3694 |
management_role = SharedCustodySettings.get_singleton().management_role |
|
3695 |
return bool(management_role in user.groups.all()) |
|
3689 | 3696 | |
3690 | 3697 |
def get_context_data(self, **kwargs): |
3691 | 3698 |
context = super().get_context_data(**kwargs) |
... | ... | |
3863 | 3870 |
shared_custody_agenda_delete_period = SharedCustodyAgendaDeletePeriodView.as_view() |
3864 | 3871 | |
3865 | 3872 | |
3873 |
class SharedCustodySettingsView(UpdateView): |
|
3874 |
title = _('Shared custody settings') |
|
3875 |
template_name = 'chrono/manager_agenda_form.html' |
|
3876 |
form_class = SharedCustodySettingsForm |
|
3877 |
model = SharedCustodySettings |
|
3878 |
success_url = reverse_lazy('chrono-manager-homepage') |
|
3879 | ||
3880 |
def dispatch(self, request, *args, **kwargs): |
|
3881 |
if not request.user.is_staff: |
|
3882 |
raise PermissionDenied() |
|
3883 |
return super().dispatch(request, *args, **kwargs) |
|
3884 | ||
3885 |
def get_object(self): |
|
3886 |
return SharedCustodySettings.get_singleton() |
|
3887 | ||
3888 | ||
3889 |
shared_custody_settings = SharedCustodySettingsView.as_view() |
|
3890 | ||
3891 | ||
3866 | 3892 |
def menu_json(request): |
3867 | 3893 |
if not request.user.is_staff: |
3868 | 3894 |
homepage_view = HomepageView(request=request) |
chrono/settings.py | ||
---|---|---|
195 | 195 | |
196 | 196 |
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'chrono.api.utils.exception_handler'} |
197 | 197 | |
198 |
SHARED_CUSTODY_ENABLED = False |
|
199 | ||
198 | 200 |
local_settings_file = os.environ.get( |
199 | 201 |
'CHRONO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py') |
200 | 202 |
) |
tests/manager/test_shared_custody_agenda.py | ||
---|---|---|
286 | 286 | |
287 | 287 |
resp = app.get('/manage/shared-custody/%s/2022/12/' % agenda.pk) |
288 | 288 |
assert 'John Doe (Vacances de Noël)' in resp.text |
289 | ||
290 | ||
291 |
def test_shared_custody_settings_feature_flag(app, admin_user, settings): |
|
292 |
settings.SHARED_CUSTODY_ENABLED = False |
|
293 |
app = login(app) |
|
294 |
resp = app.get('/manage/') |
|
295 |
assert 'Shared custody' not in resp.text |
|
296 | ||
297 |
settings.SHARED_CUSTODY_ENABLED = True |
|
298 |
resp = app.get('/manage/') |
|
299 |
assert 'Shared custody' in resp.text |
|
300 | ||
301 | ||
302 |
def test_shared_custody_settings_management_role(app, admin_user, manager_user): |
|
303 |
father = Person.objects.create(user_external_id='father_id', first_name='John', last_name='Doe') |
|
304 |
mother = Person.objects.create(user_external_id='mother_id', first_name='Jane', last_name='Doe') |
|
305 |
agenda = SharedCustodyAgenda.objects.create(first_guardian=father, second_guardian=mother) |
|
306 | ||
307 |
app = login(app, username='manager', password='manager') |
|
308 |
app.get('/manage/shared-custody/%s/settings/' % agenda.pk, status=403) |
|
309 | ||
310 |
app.reset() |
|
311 |
app = login(app) |
|
312 |
resp = app.get('/manage/') |
|
313 |
resp = resp.click('Shared custody') |
|
314 |
resp.form['management_role'] = manager_user.groups.all()[0].pk |
|
315 |
resp.form.submit() |
|
316 | ||
317 |
app.reset() |
|
318 |
app = login(app, username='manager', password='manager') |
|
319 |
resp = app.get('/manage/shared-custody/%s/settings/' % agenda.pk) |
|
320 |
assert 'Custody agenda of John Doe and Jane Doe' in resp.text |
tests/settings.py | ||
---|---|---|
34 | 34 |
EXCEPTIONS_SOURCES = {} |
35 | 35 | |
36 | 36 |
SITE_BASE_URL = 'https://example.com' |
37 | ||
38 |
SHARED_CUSTODY_ENABLED = True |
|
37 |
- |