manager: view to duplicate a desk (#42626)

This commit is contained in:
Lauréline Guérin 2020-05-07 17:45:01 +02:00
parent b61097e250
commit ea908cde22
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
4 changed files with 142 additions and 0 deletions

View File

@ -411,6 +411,17 @@ class TimePeriod(models.Model):
'end_time': self.end_time.strftime('%H:%M'),
}
def duplicate(self, desk_target=None):
# clone current period
new_period = copy.deepcopy(self)
new_period.pk = None
# set desk
new_period.desk = desk_target or self.desk
# store new period
new_period.save()
return new_period
def get_effective_timeperiods(self, excluded_timeperiods):
effective_timeperiods = [self]
for excluded_timeperiod in excluded_timeperiods:
@ -787,6 +798,27 @@ class Desk(models.Model):
'exceptions': [exception.export_json() for exception in self.timeperiodexception_set.all()],
}
def duplicate(self, label=None):
# clone current desk
new_desk = copy.deepcopy(self)
new_desk.pk = None
# set label
new_desk.label = label or _('Copy of %s') % self.label
# reset slug
new_desk.slug = None
# store new desk
new_desk.save()
# clone related objects
for time_period in self.timeperiod_set.all():
time_period.duplicate(desk_target=new_desk)
for time_period_exception in self.timeperiodexception_set.all():
time_period_exception.duplicate(desk_target=new_desk)
for time_period_exception_source in self.timeperiodexceptionsource_set.all():
time_period_exception_source.duplicate(desk_target=new_desk)
return new_desk
def get_exceptions_within_two_weeks(self):
in_two_weeks = make_aware(datetime.datetime.today() + datetime.timedelta(days=14))
exceptions = self.timeperiodexception_set.filter(end_datetime__gte=now()).filter(
@ -951,6 +983,21 @@ class TimePeriodExceptionSource(models.Model):
return self.ics_filename
return self.ics_url
def duplicate(self, desk_target=None):
# clone current source
new_source = copy.deepcopy(self)
new_source.pk = None
# set desk
new_source.desk = desk_target or self.desk
# set ics_file
if self.ics_file:
with open(self.ics_file.path) as ics_file:
new_source.ics_file.save(self.ics_filename, ics_file, save=False)
# store new source
new_source.save()
return new_source
class TimePeriodException(models.Model):
desk = models.ForeignKey(Desk, on_delete=models.CASCADE)
@ -1033,3 +1080,14 @@ class TimePeriodException(models.Model):
'recurrence_id': self.recurrence_id,
'update_datetime': export_datetime(self.update_datetime),
}
def duplicate(self, desk_target=None):
# clone current exception
new_exception = copy.deepcopy(self)
new_exception.pk = None
# set desk
new_exception.desk = desk_target or self.desk
# store new exception
new_exception.save()
return new_exception

View File

@ -169,6 +169,10 @@ class TimePeriodForm(forms.ModelForm):
class NewDeskForm(forms.ModelForm):
copy_from = forms.ModelChoiceField(
label=_('Copy settings of desk'), required=False, queryset=Desk.objects.none(),
)
class Meta:
model = Desk
widgets = {
@ -176,6 +180,15 @@ class NewDeskForm(forms.ModelForm):
}
exclude = ['slug']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['copy_from'].queryset = Desk.objects.filter(agenda=self.initial['agenda'])
def save(self):
if self.cleaned_data['copy_from']:
return self.cleaned_data['copy_from'].duplicate(label=self.cleaned_data['label'])
return super().save()
class DeskForm(forms.ModelForm):
class Meta:

View File

@ -684,3 +684,48 @@ def test_get_effective_timeperiods():
assert effective_timeperiod.weekday == time_period.weekday
assert effective_timeperiod.start_time == datetime.time(17, 0)
assert effective_timeperiod.end_time == datetime.time(18, 0)
def test_desk_duplicate():
agenda = Agenda.objects.create(label='Agenda')
desk = Desk.objects.create(label='Desk', agenda=agenda)
time_period = TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
TimePeriodExceptionSource.objects.create(desk=desk, ics_url='http://example.com/sample.ics')
source2 = TimePeriodExceptionSource.objects.create(
desk=desk,
ics_filename='sample.ics',
ics_file=ContentFile(ICS_SAMPLE_WITH_DURATION, name='sample.ics'),
)
time_period_exception = TimePeriodException.objects.create(
label='Exception',
desk=desk,
start_datetime=now() + datetime.timedelta(days=1),
end_datetime=now() + datetime.timedelta(days=2),
)
new_desk = desk.duplicate()
assert new_desk.pk != desk.pk
assert new_desk.label == 'Copy of Desk'
assert new_desk.slug == 'copy-of-desk'
assert new_desk.timeperiod_set.count() == 1
new_time_period = TimePeriod.objects.get(desk=new_desk)
assert new_time_period.weekday == time_period.weekday
assert new_time_period.start_time == time_period.start_time
assert new_time_period.end_time == time_period.end_time
assert new_desk.timeperiodexception_set.count() == 1
new_time_period_exception = TimePeriodException.objects.get(desk=new_desk)
assert new_time_period_exception.label == time_period_exception.label
assert new_time_period_exception.start_datetime == time_period_exception.start_datetime
assert new_time_period_exception.end_datetime == time_period_exception.end_datetime
assert new_desk.timeperiodexceptionsource_set.count() == 2
assert TimePeriodExceptionSource.objects.filter(
desk=new_desk, ics_url='http://example.com/sample.ics'
).exists()
new_source2 = TimePeriodExceptionSource.objects.get(desk=new_desk, ics_filename='sample.ics')
assert new_source2.ics_file.path != source2.ics_file.path
# duplicate again !
new_desk = desk.duplicate()
assert new_desk.slug == 'copy-of-desk-1'

View File

@ -971,12 +971,18 @@ def test_meetings_agenda_add_desk(app, admin_user):
resp.form['label'] = 'Desk A'
resp = resp.form.submit().follow()
assert Desk.objects.count() == 2
desk = Desk.objects.latest('pk')
TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
resp = resp.click('New Desk')
resp.form['label'] = 'Desk A'
resp = resp.form.submit().follow()
assert Desk.objects.count() == 3
assert Desk.objects.filter(slug='desk-a-1').count() == 1
assert 'Desk A' in resp.text
new_desk = Desk.objects.latest('pk')
assert new_desk.timeperiod_set.count() == 0
resp = resp.click('Desk A', index=1)
resp.form['label'] = 'Desk B'
@ -985,6 +991,26 @@ def test_meetings_agenda_add_desk(app, admin_user):
assert 'Desk B' in resp.text
def test_meetings_agenda_add_desk_from_another(app, admin_user):
agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
assert Desk.objects.count() == 1
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('New Desk')
resp.form['label'] = 'Desk B'
resp.form['copy_from'] = desk.pk
resp = resp.form.submit().follow()
assert Desk.objects.count() == 2
new_desk = Desk.objects.latest('pk')
assert new_desk.label == 'Desk B'
assert new_desk.timeperiod_set.count() == 1
def test_meetings_agenda_delete_desk(app, admin_user):
app = login(app)
resp = app.get('/manage/', status=200)