mirror of https://github.com/snachodog/mybuddy.git
578 lines
19 KiB
Python
578 lines
19 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 PumpingList(PermissionRequiredMixin, BabyBuddyFilterView):
|
|
model = models.Pumping
|
|
template_name = "core/pumping_list.html"
|
|
permission_required = ("core.view_pumping",)
|
|
paginate_by = 10
|
|
filterset_fields = ("child",)
|
|
|
|
|
|
class PumpingAdd(CoreAddView):
|
|
model = models.Pumping
|
|
permission_required = ("core.add_pumping",)
|
|
form_class = forms.PumpingForm
|
|
success_url = reverse_lazy("core:pumping-list")
|
|
success_message = _("%(model)s entry added!")
|
|
|
|
|
|
class PumpingUpdate(CoreUpdateView):
|
|
model = models.Pumping
|
|
permission_required = ("core.change_pumping",)
|
|
form_class = forms.PumpingForm
|
|
success_url = reverse_lazy("core:pumping-list")
|
|
success_message = _("%(model)s entry for %(child)s updated.")
|
|
|
|
|
|
class PumpingDelete(CoreDeleteView):
|
|
model = models.Pumping
|
|
permission_required = ("core.delete_pumping",)
|
|
success_url = reverse_lazy("core:pumping-list")
|
|
|
|
|
|
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")
|