Coverage for baibu/metrics/forms.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-10-06 13:07 +0000

1from datetime import timedelta 

2 

3from django import forms 

4from django.conf import settings 

5from django.utils import timezone 

6from django.utils.translation import gettext_lazy as _ 

7 

8from .report import COLUMNS 

9 

10DEFAULT_RANGE_DAYS = 30 

11 

12 

13class RangeForm(forms.Form): 

14 """The days to show (inclusive) and the figure to chart.""" 

15 

16 start = forms.DateField( 

17 label=_("From"), required=False, widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d") 

18 ) 

19 end = forms.DateField( 

20 label=_("To"), required=False, widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d") 

21 ) 

22 chart = forms.ChoiceField( 

23 label=_("Chart"), required=False, choices=[(column.key, column.label) for column in COLUMNS] 

24 ) 

25 

26 @staticmethod 

27 def defaults() -> dict: 

28 end = timezone.localdate() - timedelta(days=1) 

29 return {"start": end - timedelta(days=DEFAULT_RANGE_DAYS - 1), "end": end, "chart": "active_users"} 

30 

31 def clean(self): 

32 data = super().clean() 

33 defaults = self.defaults() 

34 end = data.get("end") or defaults["end"] 

35 start = data.get("start") or end - timedelta(days=DEFAULT_RANGE_DAYS - 1) 

36 if end > timezone.localdate(): 

37 self.add_error("end", _("Choose a day that is not in the future.")) 

38 if start > end: 

39 self.add_error("start", _("The first day must not be after the last day.")) 

40 elif (end - start).days + 1 > settings.METRICS_MAX_RANGE_DAYS: 

41 self.add_error( 

42 None, 

43 _("Choose at most %(days)s days.") % {"days": settings.METRICS_MAX_RANGE_DAYS}, 

44 ) 

45 return {"start": start, "end": end, "chart": data.get("chart") or defaults["chart"]} 

46 

47 def range(self) -> dict: 

48 """The chosen range if the form is valid, otherwise the default.""" 

49 return self.cleaned_data if self.is_valid() else self.defaults()