def badge_list(request):
    if request.method == 'GET':
        if request.GET.get("type") == "recent":
            # from_date = datetime_to_utc(datetime.today()) - timedelta(days=1)
            # to_date = datetime_to_utc(datetime.today())
            from_date = datetime.today() - timedelta(days=1)
            to_date = datetime.today()

            response = requests.get("{}/badge/temp_badge/status/time?from={}&to={}&badge_status={}".format
                                    (settings.TBADGE_WS_URL, from_date.strftime("%Y-%m-%d %H:%M:%S"),
                                     to_date.strftime("%Y-%m-%d %H:%M:%S"), "not_returned"))
            validate_api_call(response, [404])
            if response.status_code == 404:
                response_data = {"data": []}
            else:
                response_data = json.loads(response.text)
                data = sorted(response_data["data"], key=lambda k: datetime.strptime(k["issued_on"],
                                                                                     '%m/%d/%Y %I:%M %p'), reverse=True)
                response_data["data"] = data
            if request.GET.get("f") == "json":
                return JsonResponse(response_data, safe=False)
            return render(request, "tbadge_portal/badge/badge_list.html", {"type": "recent",
                                                                           "issued_data": json.dumps(response_data)})
        if request.GET.get("type") == "overdue":
            response = requests.get("{}/badge/temp_badge/status/time?badge_status={}".format
                                    (settings.TBADGE_WS_URL, "overdue"))
            validate_api_call(response, [404])
            if response.status_code == 404:
                response_data = {"data": []}
            else:
                response_data = json.loads(response.text)
            return render(request, "tbadge_portal/badge/badge_list.html", {"type": "overdue",
                                                                           "overdue": json.dumps(response_data)})
    raise Http404
def badge_return(request):
    if request.method == 'GET':
        return render(request, "tbadge_portal/badge/badge_return.html")
    else:
        form = forms.BadgeQueryForm(request.POST)
        if form.is_valid:
            response = requests.get("{}/badge/temp_badge/{}".format(settings.TBADGE_WS_URL,
                                                                    request.POST.get("badge_query")))
            # Badge Not Found #
            validate_api_call(response, [404])
            if response.status_code == 404:
                messages.error(request, "The badge could not be found. Please try again.", extra_tags="danger")
                logger.error("status_code={} message=User '{}' attempted to access badge '{}' that does not exist."
                             .format(404, request.session["username"], request.POST.get("badge_query")))
                if request.GET.get("next"):
                    return redirect(request.GET.get("next"))
                return render(request, "tbadge_portal/badge/badge_return.html")

            if request.POST.get("type") == "readonly":
                return redirect(reverse("badge_view_only", kwargs={"badge_id": request.POST.get("badge_query")}))

            return redirect(reverse("badge_view", kwargs={"badge_id": request.POST.get("badge_query")}))
        else:
            messages.warning(request, "The badge could not be validated. Please try again.", extra_tags="danger")
            logger.warning("status_code={} message=User '{}' attempted to submit invalid badge '{}'."
                           .format(400, request.session["username"], request.POST.get("badge_query")))
            return render(request, "tbadge_portal/badge/badge_return.html", "")
def badge_history(request, badge_id):
    if request.method == 'GET':
        response = requests.get("{}/badge/temp_badge/{}".format(settings.TBADGE_WS_URL, badge_id))
        validate_api_call(response, [404])
        if response.status_code == 404:
            messages.error(request, "The badge could not be found. Please try again.", extra_tags="danger")
            logger.error("status_code={} message=User '{}' attempted to access badge '{}' that does not exist."
                         .format(404, request.session["username"], badge_id))
            return redirect(reverse('login'))
        response_data = json.loads(response.text)
        return render(request, "tbadge_portal/badge/badge_history.html",
                      {"badge_data": json.dumps(response_data), "badge_id": badge_id})
    raise Http404
def badge_csn_escort_view(request, escort_csn):
    if request.method == 'GET':
        response = requests.get("{}/badge/escort_badge/csn/{}?issued_badges=true".format(settings.TBADGE_WS_URL,
                                                                                         escort_csn))
        validate_api_call(response, [404])
        if response.status_code == 404:
            messages.error(request, "The escort could not be found. Please make sure you have the right ID, "
                                    "and try again.", extra_tags="danger")
            return redirect(reverse('badge_lookup') + "?type=id")
        response_data = json.loads(response.text)
        issued_badges = sorted(response_data["data"]["issuedBadges"],
                               key=lambda k: datetime.strptime(k["issued_on"], '%m/%d/%Y %I:%M %p'), reverse=True)
        response_data["data"]["issuedBadges"] = issued_badges
        return render(request, "tbadge_portal/badge/badge_escort_view.html", {"escort_data": json.dumps(response_data),
                                                                              "csn_view": True})
    raise Http404
예제 #5
0
def applicant_results(request):
    if request.method == 'GET':
        return redirect(reverse('applicant_lookup'))
    else:
        form = PersonSearchForm(request.POST)
        if form.is_valid():
            response = requests.get(
                "{}/applicant/search?first_name={}&last_name={}&middle_name={}"
                .format(settings.TBADGE_WS_URL, request.POST.get("first_name"),
                        request.POST.get("last_name"),
                        request.POST.get("middle_name")))
            validate_api_call(response, [404])
            if response.status_code == 404:
                messages.error(
                    request,
                    "Your query produced no results. Please make sure the name is spelled correctly, "
                    "and try again.",
                    extra_tags="danger")
                return render(request,
                              "tbadge_portal/applicant/applicant_lookup.html",
                              "")
            response_data = json.loads(response.text)
            if len(response_data["data"]) == 1:
                encoded_id = hashid(response_data["data"][0]["applicant_id"],
                                    "encode")
                return redirect(
                    reverse('applicant_view',
                            kwargs={"applicant_id": encoded_id}))
            else:
                return render(request,
                              "tbadge_portal/applicant/applicant_list.html",
                              {"applicants": response.text})
        else:
            messages.warning(
                request,
                "Your query could not be validated. Please try again.",
                extra_tags="danger")
            logger.warning(
                "status_code={} message=User '{}' attempted to submit invalid applicant name '{} {} {}'."
                .format(400, request.session["username"],
                        request.POST.get("first_name"),
                        request.POST.get("middle_name"),
                        request.POST.get("last_name")))
            return redirect(reverse("applicant_lookup"))
def badge_view_only(request, badge_id):

    if request.method == 'GET':
        response = requests.get("{}/badge/temp_badge/{}/latest".format(settings.TBADGE_WS_URL, badge_id))
        validate_api_call(response, [404])
        if response.status_code == 404:
            messages.error(request, "The badge could not be found. Please try again.", extra_tags="danger")
            logger.error("status_code={} message=User '{}' attempted to access badge '{}' that does not exist."
                         .format(404, request.session["username"], badge_id))
            return redirect(reverse('login'))
        response_data = json.loads(response.text)

        # IF RETURNED, SHOW HISTORY INSTEAD #
        if response_data["data"]["badge_status"]["status_id"] == 2:
            return redirect(reverse('badge_history', kwargs={"badge_id": badge_id}))

        return render(request, "tbadge_portal/badge/badge_view.html",
                      {"badge_data": json.dumps(response_data["data"]), "badge_id": badge_id, "readonly": True})
    raise Http404
def badge_escort_csn_to_upid(request):
    if request.method == 'GET':
        if request.GET.get("csn"):
            response = requests.get("{}/badge/escort_badge/csn/{}".format(settings.TBADGE_WS_URL,
                                                                          request.GET.get("csn")))
            validate_api_call(response, [404])
            if response.status_code == 404:
                messages.error(request, "The escort could not be found. Please make sure you have the right ID, "
                                        "and try again.", extra_tags="danger")
                return redirect(reverse('badge_lookup') + "?type=id")

            response_data = json.loads(response.text)["data"]
            if "upid" not in response_data:
                messages.error(request, "The escort could not be found. Please make sure you have the right ID, "
                                        "and try again.", extra_tags="danger")
                return redirect(reverse('badge_lookup') + "?type=id")

            return redirect(reverse('badge_escort_view',
                                    kwargs={"escort_upid": hashid(response_data["upid"], "encode")}))
        raise Http404
    raise Http404
def badge_view(request, badge_id):

    if request.method == 'GET':
        # RETURN A BADGE #
        if request.GET.get("action") == "return":
            response = requests.put("{}/badge/temp_badge/{}/status/{}".format(settings.TBADGE_WS_URL, badge_id, "1"),
                                    data={"operator_fullname": "{} {}".format(request.session["first_name"].title(),
                                                                              request.session["last_name"].title())})
            validate_api_call(response, [304])
            if request.GET.get("type") == "inline":
                j = {'status': response.status_code}
                return JsonResponse(j, safe=False)
            elif response.status_code == 304:
                messages.error(request, "The badge could not be found or has already been returned. Please try again.",
                               extra_tags="danger")
                logger.error("status_code={} message=User '{}' attempted to return badge '{}' that either does not "
                             "exist or has already been returned.".format(304, request.session["username"], badge_id))
                return redirect(reverse('login'))
            messages.success(request, "Successfully returned badge.")
            return redirect(reverse('login'))
        else:
            response = requests.get("{}/badge/temp_badge/{}/latest".format(settings.TBADGE_WS_URL, badge_id))
            validate_api_call(response, [404])
            if response.status_code == 404:
                messages.error(request, "The badge could not be found. Please try again.", extra_tags="danger")
                logger.error("status_code={} message=User '{}' attempted to access badge '{}' that does not exist."
                             .format(404, request.session["username"], badge_id))
                return redirect(reverse('login'))
            response_data = json.loads(response.text)

            # IF RETURNED, SHOW HISTORY INSTEAD #
            if response_data["data"]["badge_status"]["status_id"] == 2:
                return redirect(reverse('badge_history', kwargs={"badge_id": badge_id}))

            return render(request, "tbadge_portal/badge/badge_view.html",
                          {"badge_data": json.dumps(response_data["data"]), "badge_id": badge_id})
    raise Http404
def badge_escort_view(request, escort_upid):
    if request.method == 'GET':
        decoded_id = hashid(escort_upid, "decode")
        if decoded_id is None:
            messages.error(request,
                           "The escort could not be found. Please make sure you have the right ID, and try again.",
                           extra_tags="danger")
            logger.warning("status_code={} message=User '{}' attempted to retrieve escort with invalid hashid '{}'."
                           .format(400, request.session["username"], escort_upid))
            return redirect(reverse('badge_lookup') + "?type=id")
        response = requests.get(
            "{}/badge/escort_badge/upid/{}".format(settings.TBADGE_WS_URL, decoded_id))
        validate_api_call(response, [404])
        if response.status_code == 404:
            messages.error(request,
                           "The escort could not be found. Please make sure you have the right ID, and try again.",
                           extra_tags="danger")
            return redirect(reverse('badge_lookup') + "?type=id")
        response_data = json.loads(response.text)
        issued_badges = sorted(response_data["data"]["issuedBadges"],
                               key=lambda k: datetime.strptime(k["issued_on"], '%m/%d/%Y %I:%M %p'), reverse=True)
        response_data["data"]["issuedBadges"] = issued_badges
        return render(request, "tbadge_portal/badge/badge_escort_view.html", {"escort_data": json.dumps(response_data)})
    raise Http404
def badge_results(request):
    if request.method == 'POST':
        if request.GET.get("type") == "id":
            return redirect(reverse("badge_view", kwargs={"badge_id": request.POST.get("badge_id")}))
        if request.GET.get("type") == "date":
            form = forms.DateSearchForm(request.POST)
            if form.is_valid():
                from_date = request.POST.get("from_date")
                to_date = request.POST.get("to_date")
                not_returned_response = requests.get("{}/badge/temp_badge/status/time?from={}&to={}&badge_status={}".
                                                     format(settings.TBADGE_WS_URL, from_date, to_date, "not_returned"))
                validate_api_call(not_returned_response, [404])
                not_returned_data = {"data": []}

                overdue_response = requests.get("{}/badge/temp_badge/status/time?from={}&to={}&badge_status={}".
                                                format(settings.TBADGE_WS_URL, from_date, to_date, "overdue"))
                validate_api_call(overdue_response, [404])
                overdue_data = {"data": []}

                if not_returned_response.status_code != 404:
                    not_returned_data = json.loads(not_returned_response.text)

                if overdue_response.status_code != 404:
                    overdue_data = json.loads(overdue_response.text)

                returned_response = requests.get("{}/badge/temp_badge/status/time?to={}&from={}&badge_status={}".
                                                 format(settings.TBADGE_WS_URL, request.POST.get("to_date"),
                                                        request.POST.get("from_date"), "returned"))
                validate_api_call(returned_response, [404])
                returned_data = {"data": []}
                if returned_response.status_code != 404:
                    returned_data = json.loads(returned_response.text)
                    sorted_returned_data = sorted(
                        returned_data["data"], key=lambda k: datetime.strptime(k["issued_on"], '%m/%d/%Y %I:%M %p'),
                        reverse=True)
                    returned_data["data"] = sorted_returned_data

                return render(request, "tbadge_portal/badge/badge_results.html",
                              {
                                  "type": "all",
                                  "from": request.POST.get("from_date"),
                                  "to": request.POST.get("to_date"),
                                  "not_returned": json.dumps(not_returned_data),
                                  "returned": json.dumps(returned_data),
                                  "overdue": json.dumps(overdue_data)
                              })
            else:
                messages.warning(request, "The date data provided in the form could not be validated. "
                                          "Please try again.", extra_tags="danger")
                logger.warning("status_code={} message=User '{}' attempted to submit invalid date range for search."
                               .format(400, request.session["username"]))
                return render(request, "tbadge_portal/badge/badge_date_lookup.html")
    else:
        if request.GET.get("type") == "id":
            return redirect(reverse('badge_lookup') + "?type=id")
        return redirect(reverse('badge_lookup') + "?type=date")
예제 #11
0
def login(request):
    try:
        # Redirect to Home if session is already valid
        if request.session.session_key and 'role' in request.session and not settings.UNDER_CONSTRUCTION:
            if request.GET.get('next'):
                return redirect(request.GET.get('next'))
            return render(request, "tbadge_portal/main/home.html", "")

        # Login POST
        elif request.method == 'POST' and not settings.UNDER_CONSTRUCTION:
            form = LoginForm(request.POST)

            # Ensure login form parameters are valid
            if form.is_valid():
                username = request.POST.get('username')
                password = request.POST.get('password')

                # First attempt to log in using SFO AD
                response = requests.post("{}/ad/auth".format(settings.AD_WS_URL),
                                         data={"username": username, "password": password, "attributes": True})
                validate_api_call(response, [])
                response_data = json.loads(response.text)["response"]

                # If SFO AD returns a valid set of credentials
                if response_data["validPassword"] is True:

                    # Assign role corresponding to database role
                    if '#REDACTED' in response_data["role"]:
                        request.session["role"] = 'Admin'
                    elif '#REDACTED' in response_data["role"]:
                        request.session["role"] = 'Admin'
                    elif '#REDACTED' in response_data["role"]:
                        request.session["role"] = 'Admin'
                    elif '#REDACTED' in response_data["role"]:
                        request.session["role"] = 'User'
                    elif '#REDACTED' in response_data["role"]:
                        request.session["role"] = 'User'
                    elif '#REDACTED' in response_data["role"] and settings.ALLOW_TEST_USER:
                        request.session["role"] = 'User'

                    # No role or incorrect role implies unauthorized access
                    else:
                        logger.warning("status_code={} message=Unauthorized user {} attempted to login."
                                       .format(403, username))
                        messages.error(request, "You do not have authorization to access this system.",
                                       extra_tags="danger")
                        return redirect(reverse('login'))

                    # Fill session metadata
                    request.session["logged_in"] = True
                    request.session["first_name"] = response_data["firstName"].title()
                    request.session["last_name"] = response_data["lastName"].title()
                    request.session["username"] = username
                    request.session["id"] = response_data["id"]

                    # Redirect to next page/home page
                    logger.info("Redirection to page '{}'.".format(request.GET.get('next')))
                    if request.GET.get('next'):
                        return redirect(request.GET.get('next'))
                    return render(request, "tbadge_portal/main/home.html", "")

                # Otherwise try SFPD AD
                else:
                    response = requests.post("{}/ad-sfpd/auth".format(settings.AD_WS_URL),
                                             data={"username": username, "password": password,
                                                   "attributes": True})
                    validate_api_call(response, [])
                    response_data = json.loads(response.text)["response"]

                    # If they have a valid SFPD AD, grant them 'User Access'
                    if response_data["validPassword"] is True:

                        # Check for specific role?

                        request.session["role"] = 'User'
                        request.session["logged_in"] = True
                        request.session["first_name"] = response_data["firstName"].title()
                        request.session["last_name"] = response_data["lastName"].title()
                        request.session["username"] = username
                        request.session["id"] = response_data["id"]

                        # Redirect to next page/home page
                        logger.info("Redirection to page '{}'.".format(request.GET.get('next')))
                        if request.GET.get('next'):
                            return redirect(request.GET.get('next'))
                        return render(request, "tbadge_portal/main/home.html", "")

                    # Otherwise user failed both AD checks - alert them of incorrect username/password.
                    else:
                        messages.error(request, 'Wrong username or password.', extra_tags="danger")
                    logger.warning("status_code={} message=Invalid credentials for user '{}' after trying sfo and "
                                   "sfpd ad".format(401, username))
                    return render(request, "tbadge_portal/account/login.html", "")

        # Default - Redirect to Login
        else:
            request.session.clear()
            return render(request, "tbadge_portal/account/login.html", "")
    except KeyError:
        request.session.clear()
        django_logout(request)
        messages.error(request, "Unable to validate credentials. Please contact an administrator.", extra_tags="danger")
        return redirect(reverse('login'))
예제 #12
0
def applicant_view(request, applicant_id):
    decoded_id = hashid(applicant_id, "decode")
    if decoded_id is None:
        logger.warning(
            "status_code={} message=User '{}' attempted to retrieve applicant with invalid hashid '{}'."
            .format(400, request.session["username"], applicant_id))
        messages.error(
            request,
            "The applicant you're looking for does not exist. Please try again.",
            extra_tags="danger")
        return redirect(reverse('login'))
    if request.method == 'GET':
        applicant_response = requests.get("{}/applicant/{}".format(
            settings.TBADGE_WS_URL, decoded_id))
        validate_api_call(applicant_response, [404])
        if applicant_response.status_code == 404 or len(
                json.loads(applicant_response.text)["data"]) == 0:
            messages.error(
                request,
                "The applicant you're looking for does not exist. Please try again.",
                extra_tags="danger")
            return redirect(reverse('login'))
        applicant_data = json.loads(applicant_response.text)["data"][0]
        if "middle_name" in applicant_data:
            applicant_name = "{} {} {}".format(applicant_data["first_name"],
                                               applicant_data["middle_name"],
                                               applicant_data["last_name"])
        else:
            applicant_name = "{} {}".format(applicant_data["first_name"],
                                            applicant_data["last_name"])

        # ISSUANCE HISTORY #
        if request.GET.get("history") == "issuance":
            response = requests.get("{}/applicant/{}/badge".format(
                settings.TBADGE_WS_URL, decoded_id))
            validate_api_call(response, [404])
            response_data = {"data": []}
            if response.status_code != 404:
                response_data = json.loads(response.text)
                data = sorted(response_data["data"],
                              key=lambda k: datetime.strptime(
                                  k["issued_on"], '%m/%d/%Y %I:%M %p'),
                              reverse=True)
                response_data["data"] = data
            return render(
                request, "tbadge_portal/applicant/applicant_issuances.html", {
                    "issuance": json.dumps(response_data),
                    "applicant": applicant_name,
                    "applicant_id": applicant_id
                })

        # REQUEST HISTORY #
        elif request.GET.get("history") == "requests":
            response = requests.get("{}/applicant/{}/badge/request".format(
                settings.TBADGE_WS_URL, decoded_id))
            validate_api_call(response, [404])
            if response.status_code == 404:
                messages.error(
                    request,
                    "The applicant you're looking for does not exist. Please try again.",
                    extra_tags="danger")
                return redirect(reverse('login'))
            response_data = json.loads(response.text)
            data = sorted(response_data["data"],
                          key=lambda k: datetime.strptime(
                              k["timestamp"], '%m/%d/%Y %I:%M %p'),
                          reverse=True)
            response_data["data"] = data
            return render(
                request, "tbadge_portal/applicant/applicant_requests.html", {
                    "requests": json.dumps(response_data),
                    "applicant": applicant_name,
                    "applicant_id": applicant_id
                })

        else:
            # APPLICANT PROFILE #
            return render(request,
                          "tbadge_portal/applicant/applicant_view.html",
                          {"applicant": applicant_response.text})
    else:
        # Post Notes
        form = NotesForm(request.POST)
        if form.is_valid():
            response = requests.put(
                "{}/applicant/{}".format(settings.TBADGE_WS_URL, decoded_id),
                data={
                    "notes":
                    request.POST.get("notes"),
                    "operator_username":
                    "******".format(request.session["first_name"],
                                   request.session["last_name"])
                })
            validate_api_call(response, [])
            messages.success(request, "Applicant notes successfully updated!")
            return redirect(
                reverse('applicant_view',
                        kwargs={"applicant_id": applicant_id}))
        else:
            logger.warning(
                "status_code={} message=Notes post failed django form validation"
                .format(400))
            messages.error(request,
                           "Your notes submission could not be validated.",
                           extra_tags="danger")
            return redirect(
                reverse('applicant_view',
                        kwargs={"applicant_id": applicant_id}))
예제 #13
0
def admin_statistics(request):
    if request.method == 'GET':
        stat_history = {"data": []}
        today = datetime.today().replace(hour=0,
                                         minute=0,
                                         second=0,
                                         microsecond=0)
        if request.GET.get("type") is not None and request.GET.get(
                "value") is not None:
            stats_type = int(request.GET.get("type"))
            value = int(request.GET.get("value"))
            # By MONTH: VALUE/YEAR #
            if stats_type == 1:
                year = int(request.GET.get("year"))
                # CURRENT MONTH: PARTIAL DAYS #
                if value == today.month and year == today.year:
                    for i in range(today.day - 1, -1, -1):
                        cur_day = datetime(today.year, today.month,
                                           today.day - i)
                        cur_day_start = cur_day
                        cur_day_end = cur_day.replace(hour=23,
                                                      minute=59,
                                                      second=59)
                        cur_day_start = cur_day_start.strftime(
                            "%Y-%m-%d %H:%M:%S")
                        cur_day_end = cur_day_end.strftime("%Y-%m-%d %H:%M:%S")
                        cur_day = cur_day.strftime("%m/%d")

                        response = requests.get(
                            "{}/badge/temp_badge/status/summary?from={}&to={}".
                            format(settings.TBADGE_WS_URL, cur_day_start,
                                   cur_day_end))
                        validate_api_call(response, [404])
                        if response.status_code == 404:
                            data = {"data": []}
                        else:
                            data = json.loads(response.text)
                        stat_history["data"].append({cur_day:
                                                     data["data"]}.copy())
                    return JsonResponse(stat_history, safe=False)

                # OTHER MONTH: ALL DAYS #
                else:
                    for i in range(1, calendar.monthrange(year, value)[1] + 1):
                        cur_day = datetime(year, value, i)
                        cur_day_start = cur_day
                        cur_day_end = cur_day.replace(hour=23,
                                                      minute=59,
                                                      second=59)
                        cur_day_start = cur_day_start.strftime(
                            "%Y-%m-%d %H:%M:%S")
                        cur_day_end = cur_day_end.strftime("%Y-%m-%d %H:%M:%S")
                        cur_day = cur_day.strftime("%m/%d")

                        response = requests.get(
                            "{}/badge/temp_badge/status/summary?from={}&to={}".
                            format(settings.TBADGE_WS_URL, cur_day_start,
                                   cur_day_end))
                        validate_api_call(response, [404])
                        if response.status_code == 404:
                            data = {"data": []}
                        else:
                            data = json.loads(response.text)
                        stat_history["data"].append({cur_day:
                                                     data["data"]}.copy())
                    return JsonResponse(stat_history, safe=False)

            # BY YEAR: VALUE #
            elif stats_type == 2:
                # $CURRENT_YEAR: PARTIAL YEAR #
                if value == today.year:
                    for i in range(1, today.month + 1):
                        cur_day = datetime(today.year, i, 1)
                        cur_day_start = cur_day
                        cur_day_end = cur_day.replace(day=calendar.monthrange(
                            today.year, i)[1],
                                                      hour=23,
                                                      minute=59,
                                                      second=59)
                        cur_day_start = cur_day_start.strftime(
                            "%Y-%m-%d %H:%M:%S")
                        cur_day_end = cur_day_end.strftime("%Y-%m-%d %H:%M:%S")
                        cur_day = cur_day.strftime("%m/%Y")

                        response = requests.get(
                            "{}/badge/temp_badge/status/summary?from={}&to={}".
                            format(settings.TBADGE_WS_URL, cur_day_start,
                                   cur_day_end))
                        validate_api_call(response, [404])
                        if response.status_code == 404:
                            data = {"data": []}
                        else:
                            data = json.loads(response.text)
                        stat_history["data"].append({cur_day:
                                                     data["data"]}.copy())
                    return JsonResponse(stat_history, safe=False)
                # OTHER YEAR: FULL YEAR #
                else:
                    for i in range(1, 13):
                        cur_day = datetime(value, i, 1)
                        cur_day_start = cur_day
                        cur_day_end = cur_day.replace(day=calendar.monthrange(
                            value, i)[1],
                                                      hour=23,
                                                      minute=59,
                                                      second=59)
                        cur_day_start = cur_day_start.strftime(
                            "%Y-%m-%d %H:%M:%S")
                        cur_day_end = cur_day_end.strftime("%Y-%m-%d %H:%M:%S")
                        cur_day = cur_day.strftime("%m/%Y")
                        response = requests.get(
                            "{}/badge/temp_badge/status/summary?from={}&to={}".
                            format(settings.TBADGE_WS_URL, cur_day_start,
                                   cur_day_end))
                        validate_api_call(response, [404])
                        if response.status_code == 404:
                            data = {"data": []}
                        else:
                            data = json.loads(response.text)
                        stat_history["data"].append({cur_day:
                                                     data["data"]}.copy())
                    return JsonResponse(stat_history, safe=False)

        # DEFAULT: CURRENT MONTH #
        for i in range(today.day - 1, -1, -1):
            cur_day = datetime(today.year, today.month, today.day - i)
            cur_day_start = cur_day
            cur_day_end = cur_day.replace(hour=23, minute=59, second=59)
            cur_day_start = cur_day_start.strftime("%Y-%m-%d %H:%M:%S")
            cur_day_end = cur_day_end.strftime("%Y-%m-%d %H:%M:%S")
            cur_day = cur_day.strftime("%m/%d")

            response = requests.get(
                "{}/badge/temp_badge/status/summary?from={}&to={}".format(
                    settings.TBADGE_WS_URL, cur_day_start, cur_day_end))
            validate_api_call(response, [404])
            if response.status_code == 404:
                data = {"data": []}
            else:
                data = json.loads(response.text)
            stat_history["data"].append({cur_day: data["data"]}.copy())
        return render(request, "tbadge_portal/admin/statistics.html",
                      {"stats": json.dumps(stat_history)})
    else:
        raise Http404
def badge_escort_results(request):
    if request.method == 'POST':
        if request.GET.get("type") == "name":
            form = forms.PersonSearchForm(request.POST)
            if form.is_valid():
                response = requests.get("{}/applicant/escort/search?first_name={}&last_name={}&middle_name={}".format(
                    settings.TBADGE_WS_URL, request.POST.get("first_name"), request.POST.get("last_name"),
                    request.POST.get("middle_name")))
                validate_api_call(response, [404])
                if response.status_code == 404:
                    messages.error(request,
                                   "Your query produced no results. Please make sure the name is spelled correctly, "
                                   "and try again.", extra_tags="danger")
                    return render(request, "tbadge_portal/applicant/applicant_lookup.html", "")
                response_data = json.loads(response.text)
                if len(response_data["data"]) == 1:
                    return redirect(reverse('badge_escort_view',
                                            kwargs={"escort_upid": hashid(json.loads(response.text)["data"][0]["upid"],
                                                                          "encode")}))
                else:
                    return render(request, "tbadge_portal/badge/badge_escort_list.html", {"escorts": response.text})
            else:
                messages.warning(request, "Your query could not be validated. Please try again.", extra_tags="danger")
                logger.warning("status_code={} message=User '{}' attempted to submit invalid escort name '{} {} {}'."
                               .format(400, request.session["username"], request.POST.get("first_name"),
                                       request.POST.get("middle_name"), request.POST.get("last_name")))
                return redirect(reverse("applicant_lookup"))

        if request.GET.get("type") == "csn":
            form = forms.BadgeQueryForm(request.POST)
            if form.is_valid():
                response = requests.get("{}/badge/escort_badge/csn/{}?issued_badges=true"
                                        .format(settings.TBADGE_WS_URL, request.POST.get("badge_query")))
                validate_api_call(response, [404])
                if response.status_code == 404:
                    messages.error(request, "The escort could not be found. Please make sure you have the right ID, "
                                            "and try again.", extra_tags="danger")
                    return redirect(reverse('badge_lookup') + "?type=id")

                response_data = json.loads(response.text)
                issued_badges = sorted(response_data["data"]["issuedBadges"],
                                       key=lambda k: datetime.strptime(k["issued_on"], '%m/%d/%Y %I:%M %p'),
                                       reverse=True)
                response_data["data"]["issuedBadges"] = issued_badges
                return render(request, "tbadge_portal/badge/badge_escort_view.html",
                              {"escort_data": json.dumps(response_data), "csn_view": True})

            else:
                messages.warning(request, "The escort csn could not be validated. Please try again.",
                                 extra_tags="danger")
                logger.warning("status_code={} message=User '{}' attempted to submit invalid escort csn '{}'."
                               .format(400, request.session["username"], request.POST.get("badge_query")))
                return redirect(reverse('badge_lookup') + "?type=id")

        if request.GET.get("type") == "upid":
            form = forms.BadgeQueryForm(request.POST)
            if form.is_valid():
                response = requests.get(
                    "{}/badge/escort_badge/upid/{}".format(settings.TBADGE_WS_URL, request.POST.get("badge_query")))
                validate_api_call(response, [404])
                if response.status_code == 404:
                    messages.error(request,
                                   "The escort could not be found. Please make sure you have the right ID, "
                                   "and try again.", extra_tags="danger")
                    return redirect(reverse('badge_lookup') + "?type=id")
                return redirect(reverse('badge_escort_view',
                                        kwargs={"escort_upid": hashid(json.loads(response.text)["data"]["upid"],
                                                                      "encode")}))
            else:
                messages.warning(request, "The escort upid could not be validated. "
                                          "Please try again.", extra_tags="danger")
                logger.warning("status_code={} message=User '{}' attempted to submit invalid escort upid '{}'."
                               .format(400, request.session["username"], request.POST.get("badge_query")))
                return redirect(reverse('badge_lookup') + "?type=id")
    else:
        return redirect(reverse('applicant_lookup'))
def badge_issue(request):

    # GET #
    if request.method == 'GET':

        # Validate Temporary Badge Status #
        if request.GET.get("action") == "validate_temporary":
            csn = request.GET['csn']

            # First, check if the badge tapped is actually an escort badge via escort badge status
            response = requests.get("{}/badge/escort_badge/csn/{}".format(settings.TBADGE_WS_URL, csn))
            validate_api_call(response, [404])

            # 200 implies the badge tapped was found in the table
            if response.status_code == 200:
                j = json.loads(response.text)

                # If it has a non-zero UPID, it is NOT a temporary badge so return error code 5
                if 'upid' in j['data']:
                    temp_upid = j['data']['upid']
                    unicodedata.normalize('NFKD', temp_upid).encode('ascii', 'ignore')
                    if temp_upid != '0':
                        j = {'status': response.status_code, 'status_id': 5}
                        return JsonResponse(j, safe=False)

            # Otherwise no UPID or a 404 (badge not found) means it's a valid temp badge
            # So continue to check whether the badge can be issued by TABS
            response = requests.get("{}/badge/temp_badge/{}/current_status".format(settings.TBADGE_WS_URL, csn))
            validate_api_call(response, [404])
            # 404 implies badge has never been issued - so it is valid
            if response.status_code == 200:
                j = json.loads(response.text)
                j['status'] = 200
                j['status_id'] = j['data']['status_id']
                return JsonResponse(j, safe=False)
            else:
                j = {'status': response.status_code, 'status_id': 4}
                return JsonResponse(j, safe=False)

        # Validate Escort Badge Status #
        elif request.GET.get("action") == "validate_escort":
            csn = request.GET['csn']
            response = requests.get("{}/badge/escort_badge/csn/{}".format(settings.TBADGE_WS_URL, csn))
            validate_api_call(response, [404])
            # 404 implies escort badge not found - valid call but invalid status
            if response.status_code == 200:
                j = json.loads(response.text)
                j['status'] = 200
                return JsonResponse(j, safe=False)
            else:
                j = {'status': response.status_code}
                return JsonResponse(j, safe=False)

        # Start Issue Badge with type 'Limited' #
        elif request.GET.get("type") == "ld":
            return render(request, "tbadge_portal/badge/badge_issue.html", {"type": 'ld'})

        # Start Issue Badge with type 'Standard' #
        elif request.GET.get("type") == "standard":
            return render(request, "tbadge_portal/badge/badge_issue.html", {"type:": 'std'})

    # POST #
    elif request.method == 'POST':

        # Create a request (step 1 to step 2) #
        if request.POST.get("action") == "create_request":

            # Create a validation form for the request to ensure formatting
            form = forms.CreateRequestForm(request.POST)
            if form.is_valid():

                # First make the request/create applicant and store it's return body #
                data = json.loads(json.dumps(request.POST))
                response = requests.post("{}/applicant/badge/request".format(settings.TBADGE_WS_URL), data=data)
                validate_api_call(response, [])
                j = json.loads(response.text)
                j['status'] = response.status_code

                # Then check if the applicant already has a badge issued and store the result
                # 404 implies applicant has no issuances and therefore is cleared
                app_id = j['data']['applicant_id']
                response = requests.get("{}/applicant/{}/badge/current_status".format(settings.TBADGE_WS_URL, app_id))
                validate_api_call(response, [404])
                if response.status_code == 200:
                    k = json.loads(response.text)
                    j['status_id'] = k['data']['status_id']
                else:
                    j['status_id'] = 4
                return JsonResponse(j, safe=False)
            else:
                logger.warning("status_code={} message=User '{}' Form data for CREATE REQUEST could not be validated."
                               .format(400, request.session["username"]))
                j = {'status': 400}
                return JsonResponse(j, safe=False)

        # Complete an issuance (step 3 to step 4) #
        elif request.POST.get("action") == "complete_issue":

            # Create the corresponding validation form to ensure correct formatting
            if request.POST.get("badge_type") == "Limited":
                form = forms.CreateLimitedIssuanceForm(request.POST)
            elif request.POST.get("badge_type") == "Standard":
                form = forms.CreateStandardIssuanceForm(request.POST)
            else:
                logger.warning("status_code={} message=User '{}' Tried to issue badge without a badge type."
                               .format(400, request.session["username"]))
                j = {'status': 400}
                return JsonResponse(j, safe=False)

            # Make the API call only if the form is in the correct format
            if form.is_valid():
                data = json.loads(json.dumps(request.POST))
                temp_csn = request.POST['csn']
                app_id = request.POST['applicant_id']
                req_id = request.POST['request_id']
                response = requests.post("{}/badge/temp_badge/{}/applicant/{}/request/{}"
                                         .format(settings.TBADGE_WS_URL, temp_csn, app_id, req_id), data=data)
                validate_api_call(response, [])
                j = {'status': response.status_code}
                return JsonResponse(j, safe=False)

            # Otherwise force a 400 error on the client side
            else:
                logger.warning("status_code={} message=User '{}' Form data for CREATE ISSUANCE could not be validated."
                               .format(400, request.session["username"]))
                j = {'status': 400}
                return JsonResponse(j, safe=False)

    # Default: Return Issue page with no type specified - Defaults to Standard Badge #
    return render(request, "tbadge_portal/badge/badge_issue.html")