Exemple #1
0
    def charge_for_consumable(self, customer, merchant, project, run_data):
        try:
            run_data = loads(run_data)
        except:
            return
        for question in self.questions:
            if 'consumable' in question:
                try:
                    consumable = Consumable.objects.get(
                        name=question['consumable'])
                    quantity = 0
                    if question['type'] == 'textbox':
                        if question['name'] in run_data:
                            quantity = quiet_int(run_data[question['name']])
                    elif question['type'] == 'radio':
                        quantity = 1

                    if quantity > 0:
                        ConsumableWithdraw.objects.create(
                            customer=customer,
                            merchant=merchant,
                            consumable=consumable,
                            quantity=quantity,
                            project=project,
                            date=timezone.now())
                except:
                    pass
Exemple #2
0
def disable_tool(request, tool_id):
    if not settings.ALLOW_CONDITIONAL_URLS:
        return HttpResponseBadRequest(
            "Tool control is only available on campus.")

    tool = get_object_or_404(Tool, id=tool_id)
    if tool.get_current_usage_event() is None:
        return HttpResponse()
    downtime = timedelta(minutes=quiet_int(request.POST.get("downtime")))
    bypass_interlock = request.POST.get("bypass", 'False') == 'True'
    response = check_policy_to_disable_tool(tool, request.user, downtime)
    if response.status_code != HTTPStatus.OK:
        return response

    # All policy checks passed so disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        if bypass_interlock and interlock_bypass_allowed(request.user):
            pass
        else:
            return interlock_error("Disable", request.user)

    # Shorten the user's tool reservation since we are now done using the tool
    shorten_reservation(user=request.user,
                        item=tool,
                        new_end=timezone.now() + downtime)

    # End the current usage event for the tool
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime

    # Collect post-usage questions
    dynamic_form = DynamicForm(tool.post_usage_questions, tool.id)

    try:
        current_usage_event.run_data = dynamic_form.extract(request)
    except RequiredUnansweredQuestionsException as e:
        if request.user.is_staff and request.user != current_usage_event.operator and current_usage_event.user != request.user:
            # if a staff is forcing somebody off the tool and there are required questions, send an email and proceed
            current_usage_event.run_data = e.run_data
            email_managers_required_questions_disable_tool(
                current_usage_event.operator, request.user, tool, e.questions)
        else:
            return HttpResponseBadRequest(str(e))

    dynamic_form.charge_for_consumables(current_usage_event.user,
                                        current_usage_event.operator,
                                        current_usage_event.project,
                                        current_usage_event.run_data, request)
    dynamic_form.update_counters(current_usage_event.run_data)

    current_usage_event.save()
    user: User = request.user
    if user.charging_staff_time():
        existing_staff_charge = user.get_staff_charge()
        if (existing_staff_charge.customer == current_usage_event.user and
                existing_staff_charge.project == current_usage_event.project):
            response = render(request, "staff_charges/reminder.html",
                              {"tool": tool})

    return response
Exemple #3
0
def disable_tool(request):
    logger = getLogger(__name__)

    tool = Tool.objects.get(id=request.POST['tool_id'])
    customer = User.objects.get(id=request.POST['customer_id'])
    downtime = timedelta(minutes=quiet_int(request.POST.get('downtime')))
    response = check_policy_to_disable_tool(tool, customer, downtime)
    if response.status_code != HTTPStatus.OK:
        dictionary = {
            'message': response.content,
            'delay': 10,
        }
        return render(request, 'kiosk/acknowledgement.html', dictionary)
    try:
        current_reservation = Reservation.objects.get(start__lt=timezone.now(),
                                                      end__gt=timezone.now(),
                                                      cancelled=False,
                                                      missed=False,
                                                      shortened=False,
                                                      user=customer,
                                                      tool=tool)
        # Staff are exempt from mandatory reservation shortening when tool usage is complete.
        if customer.is_staff is False:
            # Shorten the user's reservation to the current time because they're done using the tool.
            new_reservation = deepcopy(current_reservation)
            new_reservation.id = None
            new_reservation.pk = None
            new_reservation.end = timezone.now()
            new_reservation.save()
            current_reservation.shortened = True
            current_reservation.descendant = new_reservation
            current_reservation.save()
    except Reservation.DoesNotExist:
        pass

    # All policy checks passed so disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        logger.error(
            "The interlock command for this tool failed. The error message returned: "
            + str(tool.interlock.most_recent_reply))
        raise Exception(
            "The interlock command for this tool failed. The error message returned: "
            + str(tool.interlock.most_recent_reply))
    # End the current usage event for the tool and save it.
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime

    # Collect post-usage questions
    current_usage_event.run_data = DynamicForm(
        tool.post_usage_questions).extract(request)
    current_usage_event.save()

    dictionary = {
        'message': 'You are no longer using the {}'.format(tool),
        'badge_number': customer.badge_number,
    }
    return render(request, 'kiosk/acknowledgement.html', dictionary)
Exemple #4
0
def do_disable_tool(request, tool_id):
    tool = Tool.objects.get(id=tool_id)
    customer = User.objects.get(id=request.POST["customer_id"])
    downtime = timedelta(minutes=quiet_int(request.POST.get("downtime")))
    bypass_interlock = request.POST.get("bypass", "False") == "True"
    response = check_policy_to_disable_tool(tool, customer, downtime)
    if response.status_code != HTTPStatus.OK:
        dictionary = {"message": response.content, "delay": 10}
        return render(request, "kiosk/acknowledgement.html", dictionary)

    # All policy checks passed so try to disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        if bypass_interlock and interlock_bypass_allowed(customer):
            pass
        else:
            return interlock_error("Disable", customer)

    # Shorten the user's tool reservation since we are now done using the tool
    shorten_reservation(user=customer,
                        item=tool,
                        new_end=timezone.now() + downtime)

    # End the current usage event for the tool and save it.
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime

    # Collect post-usage questions
    dynamic_form = DynamicForm(tool.post_usage_questions)

    try:
        current_usage_event.run_data = dynamic_form.extract(request)
    except RequiredUnansweredQuestionsException as e:
        if customer.is_staff and customer != current_usage_event.operator and current_usage_event.user != customer:
            # if a staff is forcing somebody off the tool and there are required questions, send an email and proceed
            current_usage_event.run_data = e.run_data
            email_managers_required_questions_disable_tool(
                current_usage_event.operator, customer, tool, e.questions)
        else:
            dictionary = {"message": str(e), "delay": 10}
            return render(request, "kiosk/acknowledgement.html", dictionary)

    dynamic_form.charge_for_consumables(
        current_usage_event.user,
        current_usage_event.operator,
        current_usage_event.project,
        current_usage_event.run_data,
        request,
    )
    dynamic_form.update_tool_counters(current_usage_event.run_data, tool.id)

    current_usage_event.save()
    dictionary = {
        "message": "You are no longer using the {}".format(tool),
        "badge_number": customer.badge_number
    }
    return render(request, "kiosk/acknowledgement.html", dictionary)
Exemple #5
0
def disable_tool(request, tool_id):


	if not settings.ALLOW_CONDITIONAL_URLS:
		return HttpResponseBadRequest('Tool control is only available on campus.')

	tool = get_object_or_404(Tool, id=tool_id)
	if tool.get_current_usage_event() is None:
		return HttpResponse()
	current_usage_event = tool.get_current_usage_event()
	downtime = timedelta(minutes=quiet_int(request.POST.get('downtime')))
	response = check_policy_to_disable_tool(tool, request.user, downtime)
	if response.status_code != HTTPStatus.OK:
		return response
	try:
		current_reservation = Reservation.objects.get(start__lt=timezone.now(), end__gt=timezone.now(), cancelled=False, missed=False, shortened=False, user=current_usage_event.user, tool=tool)
		# Staff are exempt from mandatory reservation shortening when tool usage is complete.
		if request.user.is_staff is False:
			# Shorten the user's reservation to the current time because they're done using the tool.
			new_reservation = deepcopy(current_reservation)
			new_reservation.id = None
			new_reservation.pk = None
			new_reservation.end = timezone.now() + downtime
			new_reservation.save()
			current_reservation.shortened = True
			current_reservation.descendant = new_reservation
			current_reservation.save()
	except Reservation.DoesNotExist:
		pass

	# All policy checks passed so disable the tool for the user.
	if tool.interlock and not tool.interlock.lock():
		error_message = f"The interlock command for the {tool} failed. The error message returned: {tool.interlock.most_recent_reply}"
		logger.error(error_message)
		return HttpResponseServerError(error_message)

	# End the current usage event for the tool
	current_usage_event.end = timezone.now() + downtime

	# Collect post-usage questions
	dynamic_form = DynamicForm(tool.post_usage_questions)
	current_usage_event.run_data = dynamic_form.extract(request)
	dynamic_form.charge_for_consumable(current_usage_event.user, current_usage_event.operator, current_usage_event.project, current_usage_event.run_data)

	current_usage_event.save()
	if request.user.charging_staff_time():
		existing_staff_charge = request.user.get_staff_charge()
		if existing_staff_charge.customer == current_usage_event.user and existing_staff_charge.project == current_usage_event.project:
			response = render(request, 'staff_charges/reminder.html', {'tool': tool})

	return response
Exemple #6
0
	def charge_for_consumables(self, customer, merchant, project, run_data):
		try:
			run_data = loads(run_data)
		except:
			return
		for question in self.questions:
			if 'consumable' in question:
				try:
					consumable = Consumable.objects.get(name=question['consumable'])
					quantity = 0
					if question['type'] == 'textbox':
						if question['name'] in run_data:
							quantity = quiet_int(run_data[question['name']])
					elif question['type'] == 'number':
						if question['name'] in run_data:
							quantity = quiet_int(run_data[question['name']])
					elif question['type'] == 'radio':
						quantity = 1

					if quantity > 0:
						make_withdrawal(consumable=consumable, customer=customer, merchant=merchant, quantity=quantity, project=project)
				except:
					pass
Exemple #7
0
def disable_tool(request, tool_id):
    if not settings.ALLOW_CONDITIONAL_URLS:
        return HttpResponseBadRequest(
            "Tool control is only available on campus.")

    tool = get_object_or_404(Tool, id=tool_id)
    if tool.get_current_usage_event() is None:
        return HttpResponse()
    downtime = timedelta(minutes=quiet_int(request.POST.get("downtime")))
    response = check_policy_to_disable_tool(tool, request.user, downtime)
    if response.status_code != HTTPStatus.OK:
        return response

    # Shorten the user's tool reservation since we are now done using the tool
    shorten_reservation(user=request.user,
                        item=tool,
                        new_end=timezone.now() + downtime)

    # All policy checks passed so disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        error_message = f"The interlock command for the {tool} failed. The error message returned: {tool.interlock.most_recent_reply}"
        tool_control_logger.error(error_message)
        return HttpResponseServerError(error_message)

    # End the current usage event for the tool
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime

    # Collect post-usage questions
    dynamic_form = DynamicForm(tool.post_usage_questions, tool.id)
    current_usage_event.run_data = dynamic_form.extract(request)
    dynamic_form.charge_for_consumables(
        current_usage_event.user,
        current_usage_event.operator,
        current_usage_event.project,
        current_usage_event.run_data,
    )
    dynamic_form.update_counters(current_usage_event.run_data)

    current_usage_event.save()
    user: User = request.user
    if user.charging_staff_time():
        existing_staff_charge = user.get_staff_charge()
        if (existing_staff_charge.customer == current_usage_event.user and
                existing_staff_charge.project == current_usage_event.project):
            response = render(request, "staff_charges/reminder.html",
                              {"tool": tool})

    return response
Exemple #8
0
def disable_tool(request):
    tool = Tool.objects.get(id=request.POST['tool_id'])
    customer = User.objects.get(id=request.POST['customer_id'])
    downtime = timedelta(minutes=quiet_int(request.POST.get('downtime')))
    response = check_policy_to_disable_tool(tool, customer, downtime)
    if response.status_code != HTTPStatus.OK:
        dictionary = {
            'message': response.content,
            'delay': 10,
        }
        return render(request, 'kiosk/acknowledgement.html', dictionary)

    # Shorten the user's tool reservation since we are now done using the tool
    shorten_reservation(user=customer,
                        item=tool,
                        new_end=timezone.now() + downtime)

    # All policy checks passed so disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        raise Exception(
            "The interlock command for this tool failed. The error message returned: "
            + str(tool.interlock.most_recent_reply))
    # End the current usage event for the tool and save it.
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime

    # Collect post-usage questions
    dynamic_form = DynamicForm(tool.post_usage_questions)
    current_usage_event.run_data = dynamic_form.extract(request)
    dynamic_form.charge_for_consumables(current_usage_event.user,
                                        current_usage_event.operator,
                                        current_usage_event.project,
                                        current_usage_event.run_data)

    current_usage_event.save()
    dictionary = {
        'message': 'You are no longer using the {}'.format(tool),
        'badge_number': customer.badge_number,
    }
    return render(request, 'kiosk/acknowledgement.html', dictionary)
Exemple #9
0
def self_log_in(request, load_areas=True):
    user: User = request.user
    if not able_to_self_log_in_to_area(user):
        return redirect(reverse('landing'))

    dictionary = {
        'projects': user.active_projects(),
    }
    if request.GET.get('area_id'):
        dictionary['area_id'] = quiet_int(request.GET['area_id'])

    facility_name = get_customization('facility_name')
    try:
        check_policy_to_enter_any_area(user)
    except InactiveUserError:
        dictionary[
            'error_message'] = f'Your account has been deactivated. Please visit the {facility_name} staff to resolve the problem.'
        return render(request, 'area_access/self_login.html', dictionary)
    except NoActiveProjectsForUserError:
        dictionary[
            'error_message'] = f"You are not a member of any active projects. You won't be able to use any interlocked {facility_name} tools. Please visit the {facility_name} user office for more information."
        return render(request, 'area_access/self_login.html', dictionary)
    except PhysicalAccessExpiredUserError:
        dictionary[
            'error_message'] = f"Your physical access to the {facility_name} has expired. Have you completed your safety training within the last year? Please visit the User Office to renew your access."
        return render(request, 'area_access/self_login.html', dictionary)
    except NoPhysicalAccessUserError:
        dictionary[
            'error_message'] = f"You have not been granted physical access to any {facility_name} area. Please visit the User Office if you believe this is an error."
        return render(request, 'area_access/self_login.html', dictionary)

    if load_areas:
        dictionary['user_accessible_areas'], dictionary[
            'areas'] = load_areas_for_use_in_template(user)
    else:
        dictionary['user_accessible_areas'] = []
        dictionary['areas'] = []

    if request.method == 'GET':
        return render(request, 'area_access/self_login.html', dictionary)
    if request.method == 'POST':
        try:
            a = Area.objects.get(id=request.POST['area'])
            p = Project.objects.get(id=request.POST['project'])
            check_policy_to_enter_this_area(a, request.user)
            if p in dictionary['projects']:
                AreaAccessRecord.objects.create(area=a,
                                                customer=request.user,
                                                project=p)
        except NoAccessiblePhysicalAccessUserError as error:
            dictionary[
                'area_error_message'] = f"You do not have access to the {error.area.name} at this time. Please visit the User Office if you believe this is an error."
            return render(request, 'area_access/self_login.html', dictionary)
        except UnavailableResourcesUserError as error:
            dictionary[
                'area_error_message'] = f'The {error.area.name} is inaccessible because a required resource is unavailable ({error.resources[0]}).'
            return render(request, 'area_access/self_login.html', dictionary)
        except ScheduledOutageInProgressError as error:
            dictionary[
                'area_error_message'] = f'The {error.area.name} is inaccessible because a scheduled outage is in progress.'
            return render(request, 'area_access/self_login.html', dictionary)
        except MaximumCapacityReachedError as error:
            dictionary[
                'area_error_message'] = f'The {error.area.name} is inaccessible because it has reached its maximum capacity. Wait for somebody to exit and try again.'
            return render(request, 'area_access/self_login.html', dictionary)
        except ReservationRequiredUserError as error:
            dictionary[
                'area_error_message'] = f'You do not have a current reservation for the {error.area.name}. Please make a reservation before trying to access this area.'
            return render(request, 'area_access/self_login.html', dictionary)
        except Exception as error:
            area_access_logger.exception(error)
            dictionary['area_error_message'] = "unexpected error"
            return render(request, 'area_access/self_login.html', dictionary)
        return redirect(reverse('landing'))
Exemple #10
0
def disable_tool(request, tool_id):

    if not settings.ALLOW_CONDITIONAL_URLS:
        return HttpResponseBadRequest(
            'Tool control is only available on campus. We\'re working to change that! Thanks for your patience.'
        )

    tool = get_object_or_404(Tool, id=tool_id)
    if tool.get_current_usage_event() is None:
        return HttpResponse()
    downtime = timedelta(minutes=quiet_int(request.POST.get('downtime')))
    response = check_policy_to_disable_tool(tool, request.user, downtime)
    if response.status_code != HTTPStatus.OK:
        return response
    confirm = request.POST.get('confirm') == 'true'
    try:
        current_reservation = Reservation.objects.get(start__lt=timezone.now(),
                                                      end__gt=timezone.now(),
                                                      cancelled=False,
                                                      missed=False,
                                                      shortened=False,
                                                      user=request.user,
                                                      tool=tool)
        # Staff are exempt from mandatory reservation shortening when tool usage is complete.
        if request.user.is_staff is False:
            if confirm:
                # Shorten the user's reservation to the current time because they're done using the tool.
                new_reservation = deepcopy(current_reservation)
                new_reservation.id = None
                new_reservation.pk = None
                new_reservation.end = timezone.now() + downtime
                new_reservation.save()
                current_reservation.shortened = True
                current_reservation.descendant = new_reservation
                current_reservation.save()
            else:
                return render(
                    request, 'tool_control/confirm_tool_disable.html', {
                        'reservation': current_reservation,
                        'tool': tool,
                        'downtime': downtime.total_seconds() / 60
                    })
    except Reservation.DoesNotExist:
        pass

    # All policy checks passed so disable the tool for the user.
    if tool.interlock and not tool.interlock.lock():
        raise Exception(
            "The interlock command for this tool failed. The error message returned: "
            + str(tool.interlock.most_recent_reply))
    # End the current usage event for the tool and save it.
    current_usage_event = tool.get_current_usage_event()
    current_usage_event.end = timezone.now() + downtime
    current_usage_event.save()
    if request.user.charging_staff_time():
        existing_staff_charge = request.user.get_staff_charge()
        if existing_staff_charge.customer == current_usage_event.user and existing_staff_charge.project == current_usage_event.project:
            response = render(request, 'staff_charges/reminder.html',
                              {'tool': tool})

    return response