mirror of https://github.com/snachodog/mybuddy.git
553 lines
18 KiB
Python
553 lines
18 KiB
Python
# -*- coding: utf-8 -*-
|
|
from django.contrib import messages
|
|
from django.contrib.messages.views import SuccessMessageMixin
|
|
from django.forms import Form
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext as _
|
|
from django.views.generic.base import RedirectView, TemplateView
|
|
from django.views.generic.detail import DetailView
|
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView, \
|
|
FormView
|
|
|
|
from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
|
from babybuddy.views import BabyBuddyFilterView
|
|
from core import forms, models, timeline
|
|
|
|
|
|
def _prepare_timeline_context_data(context, date, child=None):
|
|
date = timezone.datetime.strptime(date, '%Y-%m-%d')
|
|
date = timezone.localtime(timezone.make_aware(date))
|
|
context['timeline_objects'] = timeline.get_objects(date, child)
|
|
context['date'] = date
|
|
context['date_previous'] = date - timezone.timedelta(days=1)
|
|
if date.date() < timezone.localdate():
|
|
context['date_next'] = date + timezone.timedelta(days=1)
|
|
pass
|
|
|
|
|
|
class CoreAddView(PermissionRequiredMixin, SuccessMessageMixin, CreateView):
|
|
def get_success_message(self, cleaned_data):
|
|
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
|
if 'child' in cleaned_data:
|
|
self.success_message = _('%(model)s entry for %(child)s added!')
|
|
else:
|
|
self.success_message = _('%(model)s entry added!')
|
|
return self.success_message % cleaned_data
|
|
|
|
def get_form_kwargs(self):
|
|
"""
|
|
Check for and add "child" and "timer" from request query parameters.
|
|
- "child" may provide a slug for a Child instance.
|
|
- "timer" may provided an ID for a Timer instance.
|
|
|
|
These arguments are used in some add views to pre-fill initial data in
|
|
the form fields.
|
|
|
|
:return: Updated keyword arguments.
|
|
"""
|
|
kwargs = super(CoreAddView, self).get_form_kwargs()
|
|
for parameter in ['child', 'timer']:
|
|
value = self.request.GET.get(parameter, None)
|
|
if value:
|
|
kwargs.update({parameter: value})
|
|
return kwargs
|
|
|
|
|
|
class CoreUpdateView(PermissionRequiredMixin, SuccessMessageMixin,
|
|
UpdateView):
|
|
def get_success_message(self, cleaned_data):
|
|
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
|
if 'child' in cleaned_data:
|
|
self.success_message = _('%(model)s entry for %(child)s updated.')
|
|
else:
|
|
self.success_message = _('%(model)s entry updated.')
|
|
return self.success_message % cleaned_data
|
|
|
|
|
|
class CoreDeleteView(PermissionRequiredMixin, SuccessMessageMixin, DeleteView):
|
|
def get_success_message(self, cleaned_data):
|
|
return _('%(model)s entry deleted.') % {
|
|
'model': self.model._meta.verbose_name.title()
|
|
}
|
|
|
|
|
|
class ChildList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Child
|
|
template_name = 'core/child_list.html'
|
|
permission_required = ('core.view_child',)
|
|
paginate_by = 10
|
|
filterset_fields = ('first_name', 'last_name')
|
|
|
|
|
|
class ChildAdd(CoreAddView):
|
|
model = models.Child
|
|
permission_required = ('core.add_child',)
|
|
form_class = forms.ChildForm
|
|
success_url = reverse_lazy('core:child-list')
|
|
success_message = _('%(first_name)s %(last_name)s added!')
|
|
|
|
|
|
class ChildDetail(PermissionRequiredMixin, DetailView):
|
|
model = models.Child
|
|
permission_required = ('core.view_child',)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(ChildDetail, self).get_context_data(**kwargs)
|
|
date = self.request.GET.get('date', str(timezone.localdate()))
|
|
_prepare_timeline_context_data(context, date, self.object)
|
|
return context
|
|
|
|
|
|
class ChildUpdate(CoreUpdateView):
|
|
model = models.Child
|
|
permission_required = ('core.change_child',)
|
|
form_class = forms.ChildForm
|
|
success_url = reverse_lazy('core:child-list')
|
|
|
|
|
|
class ChildDelete(CoreUpdateView):
|
|
model = models.Child
|
|
form_class = forms.ChildDeleteForm
|
|
template_name = 'core/child_confirm_delete.html'
|
|
permission_required = ('core.delete_child',)
|
|
success_url = reverse_lazy('core:child-list')
|
|
|
|
def get_success_message(self, cleaned_data):
|
|
""" This class cannot use `CoreDeleteView` because of the confirmation
|
|
step required so the success message must be overridden."""
|
|
success_message = _('%(model)s entry deleted.') % {
|
|
'model': self.model._meta.verbose_name.title()
|
|
}
|
|
return success_message % cleaned_data
|
|
|
|
|
|
class DiaperChangeList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.DiaperChange
|
|
template_name = 'core/diaperchange_list.html'
|
|
permission_required = ('core.view_diaperchange',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child', 'wet', 'solid', 'color')
|
|
|
|
|
|
class DiaperChangeAdd(CoreAddView):
|
|
model = models.DiaperChange
|
|
permission_required = ('core.add_diaperchange',)
|
|
form_class = forms.DiaperChangeForm
|
|
success_url = reverse_lazy('core:diaperchange-list')
|
|
|
|
|
|
class DiaperChangeUpdate(CoreUpdateView):
|
|
model = models.DiaperChange
|
|
permission_required = ('core.change_diaperchange',)
|
|
form_class = forms.DiaperChangeForm
|
|
success_url = reverse_lazy('core:diaperchange-list')
|
|
|
|
|
|
class DiaperChangeDelete(CoreDeleteView):
|
|
model = models.DiaperChange
|
|
permission_required = ('core.delete_diaperchange',)
|
|
success_url = reverse_lazy('core:diaperchange-list')
|
|
|
|
|
|
class FeedingList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Feeding
|
|
template_name = 'core/feeding_list.html'
|
|
permission_required = ('core.view_feeding',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child', 'type', 'method')
|
|
|
|
|
|
class FeedingAdd(CoreAddView):
|
|
model = models.Feeding
|
|
permission_required = ('core.add_feeding',)
|
|
form_class = forms.FeedingForm
|
|
success_url = reverse_lazy('core:feeding-list')
|
|
|
|
|
|
class FeedingUpdate(CoreUpdateView):
|
|
model = models.Feeding
|
|
permission_required = ('core.change_feeding',)
|
|
form_class = forms.FeedingForm
|
|
success_url = reverse_lazy('core:feeding-list')
|
|
|
|
|
|
class FeedingDelete(CoreDeleteView):
|
|
model = models.Feeding
|
|
permission_required = ('core.delete_feeding',)
|
|
success_url = reverse_lazy('core:feeding-list')
|
|
|
|
|
|
class NoteList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Note
|
|
template_name = 'core/note_list.html'
|
|
permission_required = ('core.view_note',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class NoteAdd(CoreAddView):
|
|
model = models.Note
|
|
permission_required = ('core.add_note',)
|
|
form_class = forms.NoteForm
|
|
success_url = reverse_lazy('core:note-list')
|
|
|
|
|
|
class NoteUpdate(CoreUpdateView):
|
|
model = models.Note
|
|
permission_required = ('core.change_note',)
|
|
form_class = forms.NoteForm
|
|
success_url = reverse_lazy('core:note-list')
|
|
|
|
|
|
class NoteDelete(CoreDeleteView):
|
|
model = models.Note
|
|
permission_required = ('core.delete_note',)
|
|
success_url = reverse_lazy('core:note-list')
|
|
|
|
|
|
class SleepList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Sleep
|
|
template_name = 'core/sleep_list.html'
|
|
permission_required = ('core.view_sleep',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class SleepAdd(CoreAddView):
|
|
model = models.Sleep
|
|
permission_required = ('core.add_sleep',)
|
|
form_class = forms.SleepForm
|
|
success_url = reverse_lazy('core:sleep-list')
|
|
|
|
|
|
class SleepUpdate(CoreUpdateView):
|
|
model = models.Sleep
|
|
permission_required = ('core.change_sleep',)
|
|
form_class = forms.SleepForm
|
|
success_url = reverse_lazy('core:sleep-list')
|
|
|
|
|
|
class SleepDelete(CoreDeleteView):
|
|
model = models.Sleep
|
|
permission_required = ('core.delete_sleep',)
|
|
success_url = reverse_lazy('core:sleep-list')
|
|
|
|
|
|
class TemperatureList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Temperature
|
|
template_name = 'core/temperature_list.html'
|
|
permission_required = ('core.view_temperature',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class TemperatureAdd(CoreAddView):
|
|
model = models.Temperature
|
|
permission_required = ('core.add_temperature',)
|
|
form_class = forms.TemperatureForm
|
|
success_url = reverse_lazy('core:temperature-list')
|
|
success_message = _('%(model)s reading added!')
|
|
|
|
|
|
class TemperatureUpdate(CoreUpdateView):
|
|
model = models.Temperature
|
|
permission_required = ('core.change_temperature',)
|
|
form_class = forms.TemperatureForm
|
|
success_url = reverse_lazy('core:temperature-list')
|
|
success_message = _('%(model)s reading for %(child)s updated.')
|
|
|
|
|
|
class TemperatureDelete(CoreDeleteView):
|
|
model = models.Temperature
|
|
permission_required = ('core.delete_temperature',)
|
|
success_url = reverse_lazy('core:temperature-list')
|
|
|
|
|
|
class Timeline(LoginRequiredMixin, TemplateView):
|
|
template_name = 'timeline/timeline.html'
|
|
|
|
# Show the overall timeline or a child timeline if one Child instance.
|
|
def get(self, request, *args, **kwargs):
|
|
children = models.Child.objects.count()
|
|
if children == 1:
|
|
return HttpResponseRedirect(
|
|
reverse(
|
|
'core:child',
|
|
args={models.Child.objects.first().slug}
|
|
)
|
|
)
|
|
return super(Timeline, self).get(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(Timeline, self).get_context_data(**kwargs)
|
|
date = self.request.GET.get('date', str(timezone.localdate()))
|
|
_prepare_timeline_context_data(context, date)
|
|
return context
|
|
|
|
|
|
class TimerList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Timer
|
|
template_name = 'core/timer_list.html'
|
|
permission_required = ('core.view_timer',)
|
|
paginate_by = 10
|
|
filterset_fields = ('active', 'user')
|
|
|
|
|
|
class TimerDetail(PermissionRequiredMixin, DetailView):
|
|
model = models.Timer
|
|
permission_required = ('core.view_timer',)
|
|
|
|
|
|
class TimerAdd(PermissionRequiredMixin, CreateView):
|
|
model = models.Timer
|
|
permission_required = ('core.add_timer',)
|
|
form_class = forms.TimerForm
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(TimerAdd, self).get_form_kwargs()
|
|
kwargs.update({'user': self.request.user})
|
|
return kwargs
|
|
|
|
def get_success_url(self):
|
|
return reverse('core:timer-detail', kwargs={'pk': self.object.pk})
|
|
|
|
|
|
class TimerUpdate(CoreUpdateView):
|
|
model = models.Timer
|
|
permission_required = ('core.change_timer',)
|
|
form_class = forms.TimerForm
|
|
success_url = reverse_lazy('core:timer-list')
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(TimerUpdate, self).get_form_kwargs()
|
|
kwargs.update({'user': self.request.user})
|
|
return kwargs
|
|
|
|
def get_success_url(self):
|
|
instance = self.get_object()
|
|
return reverse('core:timer-detail', kwargs={'pk': instance.pk})
|
|
|
|
|
|
class TimerAddQuick(PermissionRequiredMixin, RedirectView):
|
|
http_method_names = ['post']
|
|
permission_required = ('core.add_timer',)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
instance = models.Timer.objects.create(user=request.user)
|
|
# Add child relationship if there is only Child instance.
|
|
if models.Child.count() == 1:
|
|
instance.child = models.Child.objects.first()
|
|
instance.save()
|
|
self.url = request.GET.get(
|
|
'next', reverse('core:timer-detail', args={instance.id}))
|
|
return super(TimerAddQuick, self).get(request, *args, **kwargs)
|
|
|
|
|
|
class TimerRestart(PermissionRequiredMixin, RedirectView):
|
|
http_method_names = ['post']
|
|
permission_required = ('core.change_timer',)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
instance = models.Timer.objects.get(id=kwargs['pk'])
|
|
instance.restart()
|
|
messages.success(request, '{} restarted.'.format(instance))
|
|
return super(TimerRestart, self).get(request, *args, **kwargs)
|
|
|
|
def get_redirect_url(self, *args, **kwargs):
|
|
return reverse('core:timer-detail', kwargs={'pk': kwargs['pk']})
|
|
|
|
|
|
class TimerStop(PermissionRequiredMixin, SuccessMessageMixin, RedirectView):
|
|
http_method_names = ['post']
|
|
permission_required = ('core.change_timer',)
|
|
success_message = _('%(timer)s stopped.')
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
instance = models.Timer.objects.get(id=kwargs['pk'])
|
|
instance.stop()
|
|
messages.success(request, '{} stopped.'.format(instance))
|
|
return super(TimerStop, self).get(request, *args, **kwargs)
|
|
|
|
def get_redirect_url(self, *args, **kwargs):
|
|
return reverse('core:timer-detail', kwargs={'pk': kwargs['pk']})
|
|
|
|
|
|
class TimerDelete(CoreDeleteView):
|
|
model = models.Timer
|
|
permission_required = ('core.delete_timer',)
|
|
success_url = reverse_lazy('core:timer-list')
|
|
|
|
|
|
class TimerDeleteInactive(PermissionRequiredMixin, SuccessMessageMixin,
|
|
FormView):
|
|
permission_required = ('core.delete_timer',)
|
|
form_class = Form
|
|
template_name = 'core/timer_confirm_delete_inactive.html'
|
|
success_url = reverse_lazy('core:timer-list')
|
|
success_message = _('All inactive timers deleted.')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
kwargs = super().get_context_data(**kwargs)
|
|
kwargs['timer_count'] = self.get_instances().count()
|
|
return kwargs
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
# Redirect back to list if there are no inactive timers.
|
|
if self.get_instances().count() == 0:
|
|
messages.warning(request, _('No inactive timers exist.'))
|
|
return HttpResponseRedirect(self.success_url)
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def form_valid(self, form):
|
|
self.get_instances().delete()
|
|
return super().form_valid(form)
|
|
|
|
@staticmethod
|
|
def get_instances():
|
|
return models.Timer.objects.filter(active=False)
|
|
|
|
|
|
class TummyTimeList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.TummyTime
|
|
template_name = 'core/tummytime_list.html'
|
|
permission_required = ('core.view_tummytime',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class TummyTimeAdd(CoreAddView):
|
|
model = models.TummyTime
|
|
permission_required = ('core.add_tummytime',)
|
|
form_class = forms.TummyTimeForm
|
|
success_url = reverse_lazy('core:tummytime-list')
|
|
|
|
|
|
class TummyTimeUpdate(CoreUpdateView):
|
|
model = models.TummyTime
|
|
permission_required = ('core.change_tummytime',)
|
|
form_class = forms.TummyTimeForm
|
|
success_url = reverse_lazy('core:tummytime-list')
|
|
|
|
|
|
class TummyTimeDelete(CoreDeleteView):
|
|
model = models.TummyTime
|
|
permission_required = ('core.delete_tummytime',)
|
|
success_url = reverse_lazy('core:tummytime-list')
|
|
|
|
|
|
class WeightList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Weight
|
|
template_name = 'core/weight_list.html'
|
|
permission_required = ('core.view_weight',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class WeightAdd(CoreAddView):
|
|
model = models.Weight
|
|
permission_required = ('core.add_weight',)
|
|
form_class = forms.WeightForm
|
|
success_url = reverse_lazy('core:weight-list')
|
|
|
|
|
|
class WeightUpdate(CoreUpdateView):
|
|
model = models.Weight
|
|
permission_required = ('core.change_weight',)
|
|
form_class = forms.WeightForm
|
|
success_url = reverse_lazy('core:weight-list')
|
|
|
|
|
|
class WeightDelete(CoreDeleteView):
|
|
model = models.Weight
|
|
permission_required = ('core.delete_weight',)
|
|
success_url = reverse_lazy('core:weight-list')
|
|
|
|
|
|
class HeightList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Height
|
|
template_name = 'core/height_list.html'
|
|
permission_required = ('core.view_height',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class HeightAdd(CoreAddView):
|
|
model = models.Height
|
|
permission_required = ('core.add_height',)
|
|
form_class = forms.HeightForm
|
|
success_url = reverse_lazy('core:height-list')
|
|
|
|
|
|
class HeightUpdate(CoreUpdateView):
|
|
model = models.Height
|
|
permission_required = ('core.change_height',)
|
|
form_class = forms.HeightForm
|
|
success_url = reverse_lazy('core:height-list')
|
|
|
|
|
|
class HeightDelete(CoreDeleteView):
|
|
model = models.Height
|
|
permission_required = ('core.delete_height',)
|
|
success_url = reverse_lazy('core:height-list')
|
|
|
|
|
|
class HeadCircumferenceList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.HeadCircumference
|
|
template_name = 'core/head_circumference_list.html'
|
|
permission_required = ('core.view_head_circumference',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class HeadCircumferenceAdd(CoreAddView):
|
|
model = models.HeadCircumference
|
|
template_name = 'core/head_circumference_form.html'
|
|
permission_required = ('core.add_head_circumference',)
|
|
form_class = forms.HeadCircumferenceForm
|
|
success_url = reverse_lazy('core:head-circumference-list')
|
|
|
|
|
|
class HeadCircumferenceUpdate(CoreUpdateView):
|
|
model = models.HeadCircumference
|
|
template_name = 'core/head_circumference_form.html'
|
|
permission_required = ('core.change_head_circumference',)
|
|
form_class = forms.HeadCircumferenceForm
|
|
success_url = reverse_lazy('core:head-circumference-list')
|
|
|
|
|
|
class HeadCircumferenceDelete(CoreDeleteView):
|
|
model = models.HeadCircumference
|
|
template_name = 'core/head_circumference_delete.html'
|
|
permission_required = ('core.delete_head_circumference',)
|
|
success_url = reverse_lazy('core:head-circumference-list')
|
|
|
|
|
|
class BMIList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.BMI
|
|
template_name = 'core/bmi_list.html'
|
|
permission_required = ('core.view_bmi',)
|
|
paginate_by = 10
|
|
filterset_fields = ('child',)
|
|
|
|
|
|
class BMIAdd(CoreAddView):
|
|
model = models.BMI
|
|
permission_required = ('core.add_bmi',)
|
|
form_class = forms.BMIForm
|
|
success_url = reverse_lazy('core:bmi-list')
|
|
|
|
|
|
class BMIUpdate(CoreUpdateView):
|
|
model = models.BMI
|
|
permission_required = ('core.change_bmi',)
|
|
form_class = forms.BMIForm
|
|
success_url = reverse_lazy('core:bmi-list')
|
|
|
|
|
|
class BMIDelete(CoreDeleteView):
|
|
model = models.BMI
|
|
permission_required = ('core.delete_bmi',)
|
|
success_url = reverse_lazy('core:bmi-list')
|