manager: view to duplicate a desk (#42626)
This commit is contained in:
parent
b61097e250
commit
ea908cde22
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue