def view_calendar(request, item_type, item_id, date=None): item_type = ReservationItemType(item_type) item = get_object_or_404(item_type.get_object_class(), id=item_id) if date: try: date = extract_date(date) except: render(request, 'mobile/error.html', {'message': 'Invalid date requested for tool calendar'}) return HttpResponseBadRequest() else: date = datetime.now() start = beginning_of_the_day(date, in_local_timezone=True) end = end_of_the_day(date, in_local_timezone=True) reservations = Reservation.objects.filter(**{ item_type.value: item }).filter(cancelled=False, missed=False, shortened=False).filter(**{}) # Exclude events for which the following is true: # The event starts and ends before the time-window, and... # The event starts and ends after the time-window. reservations = reservations.exclude(start__lt=start, end__lt=start) reservations = reservations.exclude(start__gt=end, end__gt=end) outages = ScheduledOutage.objects.none() if item_type == ReservationItemType.TOOL: outages = ScheduledOutage.objects.filter( Q(tool=item) | Q(resource__fully_dependent_tools__in=[item])) elif item_type == ReservationItemType.AREA: outages = item.scheduled_outage_queryset() # Exclude outages for which the following is true: # The outage starts and ends before the time-window, and... # The outage starts and ends after the time-window. outages = outages.exclude(start__lt=start, end__lt=start) outages = outages.exclude(start__gt=end, end__gt=end) events = list(chain(reservations, outages)) events.sort(key=lambda x: x.start) dictionary = { 'item': item, 'item_type': item_type.value, 'previous_day': start - timedelta(days=1), 'current_day': start, 'current_day_string': date.strftime('%Y-%m-%d'), 'next_day': start + timedelta(days=1), 'events': events, } return render(request, 'mobile/view_calendar.html', dictionary)
def view_calendar(request, tool_id, date=None): tool = get_object_or_404(Tool, id=tool_id) if date: try: date = extract_date(date) except: render(request, 'mobile/error.html', {'message': 'Invalid date requested for tool calendar'}) return HttpResponseBadRequest() else: date = datetime.now() start = beginning_of_the_day(date, in_local_timezone=True) end = end_of_the_day(date, in_local_timezone=True) reservations = Reservation.objects.filter(tool=tool, cancelled=False, missed=False, shortened=False) # Exclude events for which the following is true: # The event starts and ends before the time-window, and... # The event starts and ends after the time-window. reservations = reservations.exclude(start__lt=start, end__lt=start) reservations = reservations.exclude(start__gt=end, end__gt=end) outages = ScheduledOutage.objects.filter( Q(tool=tool) | Q(resource__fully_dependent_tools__in=[tool])) outages = outages.exclude(start__lt=start, end__lt=start) outages = outages.exclude(start__gt=end, end__gt=end) events = list(chain(reservations, outages)) events.sort(key=lambda x: x.start) dictionary = { 'tool': tool, 'previous_day': start - timedelta(days=1), 'current_day': start, 'current_day_string': date.strftime('%Y-%m-%d'), 'next_day': start + timedelta(days=1), 'events': events, } return render(request, 'mobile/view_calendar.html', dictionary)
def usage_data_history(request, tool_id): """ This method return a dictionary of headers and rows containing run_data information for Usage Events """ csv_export = bool(request.POST.get("csv", False)) start, end = extract_times(request.POST, start_required=False, end_required=False) last = request.POST.get("data_history_last") user_id = request.POST.get("data_history_user_id") if not last and not start and not end: # Default to last 25 records last = 25 usage_events = UsageEvent.objects.filter( tool_id=tool_id, end__isnull=False).order_by("-end") if start: usage_events = usage_events.filter( end__gte=beginning_of_the_day(start)) if end: usage_events = usage_events.filter(end__lte=end_of_the_day(end)) if user_id: try: usage_events = usage_events.filter(user_id=int(user_id)) except ValueError: pass if last: try: last = int(last) except ValueError: last = 25 usage_events = usage_events[:last] table_result = BasicDisplayTable() table_result.add_header(("user", "User")) table_result.add_header(("date", "Date")) for usage_event in usage_events: if usage_event.run_data: usage_data = {} try: user_data = f"{usage_event.user.first_name} {usage_event.user.last_name}" date_data = usage_event.end.astimezone( timezone.get_current_timezone()).strftime( "%m/%d/%Y @ %I:%M %p") run_data: Dict = loads(usage_event.run_data) for question_key, question in run_data.items(): if "user_input" in question: if question["type"] == "group": for sub_question in question["questions"]: table_result.add_header( (sub_question["name"], sub_question["title"])) for index, user_inputs in question[ "user_input"].items(): if index == "0": # Special case here the "initial" group of user inputs will go along with the rest of the non-group user inputs for name, user_input in user_inputs.items( ): usage_data[name] = user_input else: # For the other groups of user inputs, we have to add a whole new row group_usage_data = {} for name, user_input in user_inputs.items( ): group_usage_data[name] = user_input if group_usage_data: group_usage_data["user"] = user_data group_usage_data["date"] = date_data table_result.add_row(group_usage_data) else: table_result.add_header( (question_key, question["title"])) usage_data[question_key] = question["user_input"] if usage_data: usage_data["user"] = user_data usage_data["date"] = date_data table_result.add_row(usage_data) except JSONDecodeError: tool_control_logger.debug("error decoding run_data: " + usage_event.run_data) if csv_export: response = table_result.to_csv() filename = f"tool_usage_data_export_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.csv" response["Content-Disposition"] = f'attachment; filename="{filename}"' return response else: dictionary = { "tool_id": tool_id, "data_history_start": start, "data_history_end": end, "data_history_last": str(last), "usage_data_table": table_result, "data_history_user": User.objects.get(id=user_id) if user_id else None, "users": User.objects.filter(is_active=True) } return render(request, "tool_control/usage_data.html", dictionary)