Compare commits
7 Commits
c64c30ed19
...
3680938041
Author | SHA1 | Date |
---|---|---|
Yann Weber | 3680938041 | |
Frédéric Péters | 9a1b37a5f7 | |
Frédéric Péters | 5204fcda47 | |
Yann Weber | 9945568a57 | |
Yann Weber | d428ef8385 | |
Frédéric Péters | 9c660e7a1e | |
Yann Weber | 47e7558298 |
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.2.18 on 2024-01-22 10:55
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('agendas', '0169_urlfield_maxlength_increase'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='agenda',
|
||||
name='events_type',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='agendas',
|
||||
to='agendas.eventstype',
|
||||
verbose_name='Events type',
|
||||
),
|
||||
),
|
||||
]
|
|
@ -278,7 +278,7 @@ class Agenda(models.Model):
|
|||
events_type = models.ForeignKey(
|
||||
'agendas.EventsType',
|
||||
verbose_name=_('Events type'),
|
||||
on_delete=models.CASCADE,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='agendas',
|
||||
null=True,
|
||||
blank=True,
|
||||
|
@ -2009,6 +2009,10 @@ class MeetingType(models.Model):
|
|||
class Meta:
|
||||
ordering = ['duration', 'label']
|
||||
unique_together = ['agenda', 'slug']
|
||||
verbose_name = _('Meeting type')
|
||||
|
||||
def __str__(self):
|
||||
return '%s - %s' % (self._meta.verbose_name, self.label)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
assert self.agenda.kind != 'virtual', "a meetingtype can't reference a virtual agenda"
|
||||
|
|
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: chrono 0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-12-22 10:50+0000\n"
|
||||
"PO-Revision-Date: 2023-12-22 11:50+0100\n"
|
||||
"POT-Creation-Date: 2024-01-23 13:18+0000\n"
|
||||
"PO-Revision-Date: 2024-01-23 14:20+0100\n"
|
||||
"Last-Translator: Frederic Peters <fpeters@entrouvert.com>\n"
|
||||
"Language: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -404,6 +404,10 @@ msgstr "Durée (en minutes)"
|
|||
msgid "Deleted"
|
||||
msgstr "Supprimé"
|
||||
|
||||
#: agendas/models.py
|
||||
msgid "Meeting type"
|
||||
msgstr "Type de rendez-vous"
|
||||
|
||||
#: agendas/models.py manager/forms.py
|
||||
msgid "Every week"
|
||||
msgstr "Toutes les semaines"
|
||||
|
@ -1401,14 +1405,14 @@ msgstr "il n’est pas possible de modifier la valeur de user_external_id"
|
|||
msgid "missing param user_external_id"
|
||||
msgstr "paramètre manquant user_external_id"
|
||||
|
||||
#: api/views.py
|
||||
msgid "booking is cancelled"
|
||||
msgstr "la réservation est annulée"
|
||||
|
||||
#: api/views.py
|
||||
msgid "secondary booking"
|
||||
msgstr "réservation secondaire"
|
||||
|
||||
#: api/views.py
|
||||
msgid "booking is cancelled"
|
||||
msgstr "la réservation est annulée"
|
||||
|
||||
#: api/views.py
|
||||
msgid "booking is in waiting list"
|
||||
msgstr "la réservation est dans la liste d’attente"
|
||||
|
@ -3797,6 +3801,15 @@ msgstr "Se connecter"
|
|||
msgid "Week %s"
|
||||
msgstr "Semaine %s"
|
||||
|
||||
#: manager/views.py
|
||||
#, python-format
|
||||
msgid "Cannot delete event type \"%(event_type_name)s\""
|
||||
msgstr "Impossible de supprimer le type d’évènement « %(event_type_name)s »"
|
||||
|
||||
#: manager/views.py
|
||||
msgid "Following agendas are still using this event type:"
|
||||
msgstr "Ces agendas utilisent ce type d’évènement :"
|
||||
|
||||
#: manager/views.py
|
||||
msgid "File is not in the expected JSON format."
|
||||
msgstr "Le fichier n’est pas dans le format JSON attendu."
|
||||
|
|
|
@ -44,6 +44,7 @@ from django.utils.encoding import force_str
|
|||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import format_html
|
||||
from django.utils.safestring import SafeString
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ngettext
|
||||
from django.views.generic import (
|
||||
|
@ -884,6 +885,41 @@ class EventsTypeDeleteView(DeleteView):
|
|||
raise PermissionDenied()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def can_be_deleted(self):
|
||||
return self.get_object().agendas.count() == 0
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
if self.can_be_deleted():
|
||||
return ctx
|
||||
|
||||
obj = self.get_object()
|
||||
ctx['cannot_delete'] = True
|
||||
|
||||
title = '<h3>%(title)s</h3>' % {
|
||||
'title': _('Cannot delete event type "%(event_type_name)s"') % {'event_type_name': obj}
|
||||
}
|
||||
msg = _('Following agendas are still using this event type:')
|
||||
lst = '<ul><li>%(agendas)s</li></ul>' % {
|
||||
'agendas': '</li><li>'.join(
|
||||
[
|
||||
'<a href="%s">%s</a>'
|
||||
% (reverse('chrono-manager-agenda-view', kwargs={'pk': agenda.pk}), agenda)
|
||||
for agenda in obj.agendas.all()
|
||||
]
|
||||
)
|
||||
}
|
||||
ctx['cannot_delete_msg'] = SafeString(
|
||||
'%(title)s %(msg)s %(agendas)s' % {'title': title, 'msg': msg, 'agendas': lst}
|
||||
)
|
||||
|
||||
return ctx
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
if self.can_be_deleted():
|
||||
return super().post(*args, **kwargs)
|
||||
raise PermissionDenied()
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('chrono-manager-events-type-list')
|
||||
|
||||
|
|
|
@ -3206,6 +3206,15 @@ def test_cant_modify_meetingtype_used_by_virtual_agenda(app, admin_user):
|
|||
assert mt.label == 'MTT'
|
||||
|
||||
|
||||
def test_meetingtype_delete_popup_translation(app, admin_user):
|
||||
meeting_agenda_1 = Agenda.objects.create(label='Meeting agenda 1', kind='meetings')
|
||||
mt = MeetingType.objects.create(agenda=meeting_agenda_1, label='MT', slug='mt', duration=10)
|
||||
app = login(app)
|
||||
|
||||
resp = app.get('/manage/meetingtypes/%s/delete' % mt.pk)
|
||||
assert f'Meeting type - {mt.label}' in resp.text
|
||||
|
||||
|
||||
def test_cant_add_meetingtype_if_virtual_agenda(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='My Virtual agenda', kind='virtual')
|
||||
meeting_agenda_1 = Agenda.objects.create(label='Meeting agenda 1', kind='meetings')
|
||||
|
|
|
@ -162,6 +162,45 @@ def test_delete_events_type(app, admin_user):
|
|||
assert EventsType.objects.exists() is False
|
||||
|
||||
|
||||
def test_delete_referenced_events_type(app):
|
||||
events_type = EventsType.objects.create(label='Foobar')
|
||||
agenda = Agenda.objects.create(label='Foo Bar', events_type=events_type)
|
||||
|
||||
events_type.delete()
|
||||
|
||||
agenda = Agenda.objects.get(pk=agenda.pk)
|
||||
assert agenda
|
||||
assert agenda.events_type is None
|
||||
|
||||
|
||||
def test_delete_referenced_events_type_error(app, admin_user):
|
||||
events_type = EventsType.objects.create(label='Foobar')
|
||||
agenda = Agenda.objects.create(label='Foo Bar', events_type=events_type)
|
||||
|
||||
app = login(app)
|
||||
|
||||
resp = app.get('/manage/events-types/', status=200)
|
||||
resp = resp.click(href='/manage/events-type/%s/delete/' % events_type.pk)
|
||||
|
||||
resp.form.submit(status=403)
|
||||
|
||||
assert EventsType.objects.get(pk=events_type.pk)
|
||||
assert 'Cannot delete event type "' in resp
|
||||
assert '<a href="/manage/agendas/%s/">%s</a>' % (agenda.pk, agenda) in resp
|
||||
|
||||
agenda.delete()
|
||||
|
||||
# Now deletion should be OK
|
||||
resp = app.get('/manage/events-types/', status=200)
|
||||
resp = resp.click(href='/manage/events-type/%s/delete/' % events_type.pk)
|
||||
|
||||
assert 'Cannot delete event type "' not in resp
|
||||
assert '<a href="/manage/agendas/%s/">%s</a>' % (agenda.pk, agenda) not in resp
|
||||
|
||||
resp.form.submit()
|
||||
assert EventsType.objects.exists() is False
|
||||
|
||||
|
||||
def test_delete_events_type_as_manager(app, manager_user):
|
||||
agenda = Agenda(label='Foo Bar')
|
||||
agenda.view_role = manager_user.groups.all()[0]
|
||||
|
|
Loading…
Reference in New Issue