diff --git a/scheduler/forms.py b/scheduler/forms.py new file mode 100644 index 0000000..fefa188 --- /dev/null +++ b/scheduler/forms.py @@ -0,0 +1,67 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Layout, Submit, HTML, Div +from django import forms +from django.utils.translation import gettext_lazy as _ + +from scheduler.models import ScheduleProfile, ScheduleSlot + + +class ScheduleProfileForm(forms.ModelForm): + class Meta: + model = ScheduleProfile + fields = ['name'] + labels = { + 'name': _('Profile Name'), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.form_tag = False + self.helper.layout = Layout( + Div( + 'name', + css_class='col-12' + ) + ) + + +class ScheduleSlotForm(forms.ModelForm): + class Meta: + model = ScheduleSlot + fields = ['start_weekday', 'start_time', 'end_weekday', 'end_time'] + widgets = { + 'start_time': forms.TimeInput(attrs={'type': 'time'}), + 'end_time': forms.TimeInput(attrs={'type': 'time'}), + } + labels = { + 'start_weekday': _('Start Day'), + 'start_time': _('Start Time'), + 'end_weekday': _('End Day'), + 'end_time': _('End Time'), + } + + def __init__(self, *args, **kwargs): + cancel_url = kwargs.pop('cancel_url', '#') + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.layout = Layout( + Div( + Div('start_weekday', css_class='col-md-6'), + Div('start_time', css_class='col-md-6'), + css_class='row' + ), + Div( + Div('end_weekday', css_class='col-md-6'), + Div('end_time', css_class='col-md-6'), + css_class='row' + ), + Div( + Div( + Submit('submit', _('Save'), css_class='btn btn-primary'), + HTML(f'{_("Cancel")}'), + css_class='col-12 d-flex justify-content-end gap-2 mt-3' + ), + css_class='row' + ) + ) diff --git a/scheduler/models.py b/scheduler/models.py index f99638b..d03c9cf 100644 --- a/scheduler/models.py +++ b/scheduler/models.py @@ -24,7 +24,7 @@ class ScheduleProfile(models.Model): class ScheduleSlot(models.Model): - profile = models.ForeignKey(ScheduleProfile, on_delete=models.CASCADE, related_name="slots") + profile = models.ForeignKey(ScheduleProfile, on_delete=models.CASCADE, related_name="time_interval") start_weekday = models.PositiveSmallIntegerField(choices=WEEK_DAYS) end_weekday = models.PositiveSmallIntegerField(choices=WEEK_DAYS) start_time = models.TimeField() diff --git a/scheduler/views.py b/scheduler/views.py index 60f00ef..175e314 100644 --- a/scheduler/views.py +++ b/scheduler/views.py @@ -1 +1,124 @@ -# Create your views here. +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, get_object_or_404, redirect +from django.urls import reverse +from django.utils.translation import gettext as _ + +from scheduler.forms import ScheduleProfileForm +from scheduler.forms import ScheduleSlotForm +from scheduler.models import ScheduleProfile, ScheduleSlot + + +@login_required +def view_scheduler_profile_list(request): + profiles = ScheduleProfile.objects.all().order_by('name') + context = { + 'profiles': profiles, + } + return render(request, 'scheduler/scheduleprofile_list.html', context) + + +@login_required +def view_manage_scheduler_profile(request): + profile_uuid = request.GET.get('uuid') + if profile_uuid: + profile = get_object_or_404(ScheduleProfile, uuid=profile_uuid) + title = _('Edit Schedule Profile') + slots = profile.time_interval.all() + else: + profile = None + title = _('Create Schedule Profile') + slots = None + + if request.method == 'POST': + form = ScheduleProfileForm(request.POST, instance=profile) + if form.is_valid(): + form.save() + messages.success(request, _('Schedule Profile saved successfully.')) + return redirect('scheduler_profile_list') + else: + form = ScheduleProfileForm(instance=profile) + + context = { + 'form': form, + 'title': title, + 'profile': profile, + 'slots': slots, + } + return render(request, 'scheduler/scheduleprofile_form.html', context) + + +@login_required +def view_delete_scheduler_profile(request): + profile_uuid = request.GET.get('uuid') + profile = get_object_or_404(ScheduleProfile, uuid=profile_uuid) + + if request.method == 'POST': + profile.delete() + messages.success(request, _('Schedule Profile deleted successfully.')) + return redirect('scheduler_profile_list') + + context = { + 'object': profile, + 'title': _('Delete Schedule Profile'), + 'cancel_url': reverse('scheduler_profile_list'), + 'text': _('Are you sure you want to delete the profile "%(name)s"?') % {'name': profile.name} + } + return render(request, 'generic_delete_confirmation.html', context) + + +@login_required +def view_manage_scheduler_slot(request): + slot_uuid = request.GET.get('uuid') + profile_uuid = request.GET.get('profile_uuid') + + if slot_uuid: + slot = get_object_or_404(ScheduleSlot, uuid=slot_uuid) + profile = slot.profile + title = _('Edit Time Interval') + else: + profile = get_object_or_404(ScheduleProfile, uuid=profile_uuid) + slot = None + title = _('Add Time Interval') + + cancel_url = f"{reverse('manage_scheduler_profile')}?uuid={profile.uuid}" + + if request.method == 'POST': + form = ScheduleSlotForm(request.POST, instance=slot, cancel_url=cancel_url) + if form.is_valid(): + new_slot = form.save(commit=False) + new_slot.profile = profile + new_slot.save() + messages.success(request, _('Time Interval saved successfully.')) + return redirect(cancel_url) + else: + form = ScheduleSlotForm(instance=slot, cancel_url=cancel_url) + + context = { + 'form': form, + 'title': title, + 'page_title': title, + 'profile': profile, + } + return render(request, 'generic_form.html', context) + + +@login_required +def view_delete_scheduler_slot(request): + slot_uuid = request.GET.get('uuid') + slot = get_object_or_404(ScheduleSlot, uuid=slot_uuid) + profile = slot.profile + cancel_url = f"{reverse('manage_scheduler_profile')}?uuid={profile.uuid}" + + if request.method == 'POST': + slot.delete() + messages.success(request, _('Time Interval deleted successfully.')) + return redirect(cancel_url) + + context = { + 'object': slot, + 'title': _('Delete Time Interval'), + 'cancel_url': cancel_url, + 'text': _('Are you sure you want to delete this time interval?') + } + return render(request, 'scheduler/generic_delete_confirm.html', context) diff --git a/templates/generic_delete_confirmation.html b/templates/generic_delete_confirmation.html new file mode 100644 index 0000000..14a1bd7 --- /dev/null +++ b/templates/generic_delete_confirmation.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block content %} +
+ {% trans 'Scheduler' %} +
+ +