def aaq()

in kitsune/questions/views.py [0:0]


def aaq(request, product_slug=None, step=1, is_loginless=False):
    """Ask a new question."""
    # After the migration to a DB based AAQ, we need to account for
    # product slugs that were not present in the questions config.
    should_redirect = True
    match product_slug:
        case "desktop":
            product_slug = "firefox"
        case "focus":
            product_slug = "focus-firefox"
        case _:
            should_redirect = False

    if should_redirect:
        return HttpResponsePermanentRedirect(reverse("questions.aaq_step2", args=[product_slug]))

    template = "questions/new_question.html"

    # Check if the user is using a mobile device,
    # render step 2 if they are
    product_slug = product_slug or request.GET.get("product")
    if product_slug is None:
        change_product = False
        if request.GET.get("q") == "change_product":
            change_product = True

        is_mobile_device = get_user_agent(request).is_mobile

        if is_mobile_device and not change_product:
            user_agent = request.META.get("HTTP_USER_AGENT", "")
            if product_slug := get_mobile_product_from_ua(user_agent):
                # redirect needed for InAAQMiddleware
                step_2 = reverse("questions.aaq_step2", args=[product_slug])
                return HttpResponseRedirect(step_2)

    # Return 404 if the products does not have an AAQ form or if it is archived
    product = None
    products_with_aaqs = Product.active.filter(aaq_configs__is_active=True).distinct()
    if product_slug:
        try:
            product = Product.active.get(slug=product_slug)
        except Product.DoesNotExist:
            raise Http404
        else:
            if product not in products_with_aaqs:
                raise Http404

    context = {
        "products": products_with_aaqs,
        "current_product": product,
        "current_step": step,
        "host": Site.objects.get_current().domain,
        "is_loginless": is_loginless,
        "ga_content_group": f"aaq-step-{step}",
    }
    # If the selected product doesn't exist in DB, render a 404
    if step > 1:
        set_aaq_context(request, product)
        has_public_forum = product.questions_enabled(locale=request.LANGUAGE_CODE)
        context["has_ticketing_support"] = product.has_ticketing_support
        context["ga_products"] = f"/{product_slug}/"

    if step == 2:
        topics = topics_for(request.user, product, parent=None)

        context["featured"] = get_featured_articles(product, locale=request.LANGUAGE_CODE)
        context["topics"] = build_topics_data(request, product, topics)

    elif step == 3:
        context["cancel_url"] = get_next_url(request) or (
            reverse("products.product", args=[product.slug])
            if is_loginless
            else reverse("questions.aaq_step2", args=[product_slug])
        )

        # Check if the selected product has a forum in the user's locale
        if not has_public_forum:
            locale, path = split_into_language_and_path(request.path_info)
            path = f"/{settings.WIKI_DEFAULT_LANGUAGE}{path}"

            old_lang = settings.LANGUAGES_DICT[request.LANGUAGE_CODE.lower()]
            new_lang = settings.LANGUAGES_DICT[settings.WIKI_DEFAULT_LANGUAGE.lower()]
            msg = _(
                "The questions forum isn't available for {product} in {old_lang}, we "
                "have redirected you to the {new_lang} questions forum."
            ).format(product=product.title, old_lang=old_lang, new_lang=new_lang)
            messages.add_message(request, messages.WARNING, msg)

            return HttpResponseRedirect(path)

        if product.has_ticketing_support:
            zendesk_form = ZendeskForm(
                data=request.POST or None,
                product=product,
                user=request.user,
            )
            context["form"] = zendesk_form
            context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json(
                request.session, product
            )

            if zendesk_form.is_valid() and not is_ratelimited(request, "loginless", "3/d"):
                try:
                    zendesk_form.send(request.user, product)
                    email = zendesk_form.cleaned_data["email"]
                    messages.add_message(
                        request,
                        messages.SUCCESS,
                        _(
                            "Done! Thank you for reaching out Mozilla Support."
                            " We've sent a confirmation email to {email}"
                        ).format(email=email),
                    )

                    url = reverse("products.product", args=[product.slug])
                    return HttpResponseRedirect(url)

                except APIException as err:
                    messages.add_message(
                        request, messages.ERROR, _("That didn't work. Please try again.")
                    )
                    capture_exception(err)

            if getattr(request, "limited", False):
                messages.add_message(
                    request,
                    messages.ERROR,
                    _("You've exceeded the number of submissions for today."),
                )

            return render(request, template, context)

        form = NewQuestionForm(
            product=product,
            data=request.POST or None,
        )
        context["form"] = form

        if form.is_valid() and not is_ratelimited(request, "aaq-day", "5/d"):
            question = form.save(
                user=request.user,
                locale=request.LANGUAGE_CODE,
                product=product,
            )

            if visits := get_kb_visited(request.session, product, question.topic):
                question.add_metadata(kb_visits_prior=json.dumps(visits))

            if form.cleaned_data.get("is_spam"):
                _add_to_moderation_queue(request, question)

            # Submitting the question counts as a vote
            question_vote(request, question.id)

            my_questions_url = reverse("users.questions", args=[request.user.username])
            messages.add_message(
                request,
                messages.SUCCESS,
                _(
                    "Done! Your question is now posted on the Mozilla community support forum. "
                    + "You can see your post anytime by visiting the {a_open}My Questions"
                    + "{a_close} page in your profile."
                ).format(a_open="<a href='" + my_questions_url + "'>", a_close="</a>"),
                extra_tags="safe",
            )

            request.session["aaq-final-step"] = True

            url = reverse("questions.details", kwargs={"question_id": question.id})
            return HttpResponseRedirect(url)

        if getattr(request, "limited", False):
            raise PermissionDenied

        user_ct = ContentType.objects.get_for_model(request.user)
        context["images"] = ImageAttachment.objects.filter(
            creator=request.user,
            content_type=user_ct,
        ).order_by("-id")[:IMG_LIMIT]

        if form.is_bound and (topic := form.cleaned_data.get("category")):
            # We've got invalid POST data, but the topic has been provided.
            # Let's set the proper GA4 event parameters on the submit button.
            context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json(
                request.session, product, topic=topic
            )
        else:
            # We don't know the topic yet, since that's set via the form, so let's
            # start by providing default GA4 event parameters for the submit button.
            context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json()

    return render(request, template, context)