def default_detail_value_format(self, val): """Take a value and return as a formatted string based on its type""" if val is None: msg = "No Filter" return "<em>%s</em>" % msg if self.report_format not in [XLS, CSV ] else msg if isinstance(val, str): if val.lower() in relative_dates.ALL_DATE_RANGES: start, end = relative_dates(val).range() return "%s (%s - %s)" % (val, format_as_date(start), format_as_date(end)) return val if isinstance(val, timezone.datetime): return format_as_date(val) try: if len(val) > 0 and isinstance(val[0], timezone.datetime): joiner = " - " if len(val) == 2 else ", " return joiner.join(format_as_date(dt) for dt in val) except: # noqa: E722 # pragma: no cover pass try: return ', '.join(str(x) for x in val) except: # noqa: E722 # pragma: no cover pass return str(val)
def test_today(self): start = self.day_start end = end_of_day(start) r = relative_dates("today", self.now) assert r.start() == start assert r.end() == end
def filter(self, qs, value): if not value: return qs # pragma: no cover try: start_date, end_date = relative_dates(value).range() except: # noqa: E722 # custom period start_date, end_date = value fn = self.field_name qs = qs.filter(**{ "%s__gte" % fn: start_date }).filter(**{"%s__lte" % fn: end_date}) return qs.distinct() if self.distinct else qs
def test_last_year(self): start = start_of_day( timezone.datetime(2019, 1, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2019, 12, 31, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("last year", self.now) assert r.start() == start assert r.end() == end
def test_this_month(self): start = start_of_day( timezone.datetime(2020, 1, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 1, 31, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("this month", self.now) assert r.start() == start assert r.end() == end
def test_last_365_days(self): start = start_of_day( timezone.datetime(2019, 1, 2, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 1, 2, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("last 365 days", self.now) assert r.start() == start assert r.end() == end
def test_next_week(self): start = start_of_day( timezone.datetime(2020, 1, 5, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 1, 11, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("next week", self.now) assert r.start() == start assert r.end() == end
def test_last_month_jan31(self): pivot = timezone.datetime(2020, 1, 31, 11, 38, tzinfo=pytz.timezone("America/Toronto")) start = start_of_day( timezone.datetime(2019, 12, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2019, 12, 31, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("last month", pivot) assert r.start() == start assert r.end() == end
def test_last_week_sun(self): pivot = timezone.datetime(2020, 1, 5, 11, 38, tzinfo=pytz.timezone("America/Toronto")) start = start_of_day( timezone.datetime(2019, 12, 29, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 1, 4, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("last week", pivot) assert r.start() == start assert r.end() == end
def test_this_year_dec_31(self): pivot = timezone.datetime(2020, 12, 31, 11, 38, tzinfo=pytz.timezone("America/Toronto")) start = start_of_day( timezone.datetime(2020, 1, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 12, 31, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("this year", pivot) assert r.start() == start assert r.end() == end
def test_this_week_sat(self): pivot = timezone.datetime(2020, 1, 11, 11, 38, tzinfo=pytz.timezone("America/Toronto")) start = start_of_day( timezone.datetime(2020, 1, 5, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 1, 11, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("this week", pivot) assert r.start() == start assert r.end() == end
def test_next_month_first_day(self): pivot = timezone.datetime(2020, 1, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto")) start = start_of_day( timezone.datetime(2020, 2, 1, 11, 38, tzinfo=pytz.timezone("America/Toronto"))) end = end_of_day( timezone.datetime(2020, 2, 29, tzinfo=pytz.timezone("America/Toronto"))) r = relative_dates("next month", pivot) assert r.start() == start assert r.end() == end
def get_context(self): context = super().get_context() # since we're grouping by site, we need to handle sites separately sites = self.filter_set.qs.order_by( "unit_service_area__unit__site__name", ).values_list( "unit_service_area__unit__site", flat=True, ).distinct() units = ( models.Unit.objects.filter(pk__in=self.filter_set.form.cleaned_data.get("unit_service_area__unit")) or models.Unit.objects.all() ).select_related( "site", ) all_service_types = models.ServiceType.objects.all() service_types = self.filter_set.form.cleaned_data.get("service_type") or all_service_types all_service_areas = models.ServiceArea.objects.all() service_areas = self.filter_set.form.cleaned_data.get("unit_service_area__service_area") or all_service_areas # if the service events are filtered by service type/ service area the uptime # calculation won't make sense self.calc_uptime = ( len(service_areas) == len(all_service_areas) and len(service_types) == len(all_service_types) ) start_date, end_date = relative_dates( self.filter_set.form.cleaned_data.get('datetime_service', 'Last 365 Days') ).range() sites_data = [] for site in sites: if site: # site can be None here since not all units may have a site site = umodels.Site.objects.get(pk=site) sites_data.append((site.name if site else "", [])) ses = self.get_ses_for_site(self.filter_set.qs, site) unit_ses = defaultdict(list) for se in ses: unit_ses[se.unit_service_area.unit_id].append(se) for unit in units.filter(site=site): available = timezone.timedelta(hours=unit.get_potential_time(start_date.date(), end_date.date())) total_lost_time = timezone.timedelta() total_service_time = timezone.timedelta() total_events = 0 service_type_info = {} for st in service_types: service_type_info[st.pk] = { 'name': st.name, 'n_service_events': 0, 'service_time': timezone.timedelta(), 'lost_time': timezone.timedelta(), } for se in unit_ses[unit.id]: service_type_info[se.service_type_id]['n_service_events'] += 1 total_events += 1 st = se.duration_service_time or timezone.timedelta() service_type_info[se.service_type_id]['service_time'] += st total_service_time += st lt = se.duration_lost_time or timezone.timedelta() service_type_info[se.service_type_id]['lost_time'] += lt total_lost_time += lt for st in service_types: service_type_info[st.pk]['service_time'] = hour_min(service_type_info[st.pk]['service_time']) downtime = 100 * service_type_info[st.pk]['lost_time'] / available if available else 100 service_type_info[st.pk]['downtime'] = downtime service_type_info[st.pk]['lost_time'] = hour_min(service_type_info[st.pk]['lost_time']) uptime = None if self.calc_uptime: uptime = 100 * (available - total_lost_time) / available if available else 0 sites_data[-1][-1].append({ 'unit': unit.name, 'n_service_events': total_events, 'service_time': hour_min(total_service_time), 'lost_time': hour_min(total_lost_time), 'available_time': hour_min(available), 'uptime': uptime, 'downtime': 100 * total_lost_time / available if available else 0, 'service_types': list(service_type_info.values()), }) context['sites_data'] = sites_data context['n_service_types'] = len(service_types) return context
def test_next_365_days(self): end = end_of_day(timezone.datetime(2021, 1, 1, tzinfo=self.tz)) r = relative_dates("next 365 days", self.now) assert r.start() == self.day_start assert r.end() == end
def test_next_7_days(self): r = relative_dates("next 7 days", self.now) end = end_of_day(timezone.datetime(2020, 1, 9, tzinfo=self.tz)) assert r.start() == self.day_start assert r.end() == end