From 9d6d51e771cea68be8d00ac94faccfbdf2e23e06 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Tue, 27 May 2025 16:48:58 -0700 Subject: [PATCH] 3684: Organization overview page [ES] (#3788) * Add organization overview page * Add tests * Change margin between overview headings --- src/.pa11yci | 5 +- src/registrar/config/urls.py | 9 +- src/registrar/permissions.py | 3 +- src/registrar/templates/domain_base.html | 4 +- src/registrar/templates/domain_detail.html | 6 +- .../templates/domain_request_form.html | 5 +- src/registrar/templates/includes/contact.html | 2 +- .../includes/organization_address.html | 4 +- .../templates/includes/summary_item.html | 4 +- src/registrar/templates/portfolio_base.html | 4 +- .../templates/portfolio_organization.html | 81 ++------- .../portfolio_organization_info.html | 92 ++++++++++ .../portfolio_organization_sidebar.html | 11 +- .../templates/portfolio_senior_official.html | 20 +- src/registrar/templatetags/custom_filters.py | 3 +- src/registrar/tests/test_views_portfolio.py | 171 +++++++++++++++--- src/registrar/views/portfolios.py | 34 +++- 17 files changed, 342 insertions(+), 116 deletions(-) create mode 100644 src/registrar/templates/portfolio_organization_info.html diff --git a/src/.pa11yci b/src/.pa11yci index 21def88c5..925d6b80a 100644 --- a/src/.pa11yci +++ b/src/.pa11yci @@ -27,6 +27,9 @@ "http://localhost:8080/request/requesting_entity/", "http://localhost:8080/user-profile/", "http://localhost:8080/members/", - "http://localhost:8080/members/new-member" + "http://localhost:8080/members/new-member", + "http://localhost:8080/organization", + "http://localhost:8080/organization/organization-info", + "http://localhost:8080/organization/senior-official" ] } diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index c73b735f5..bd691cedb 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -164,9 +164,14 @@ urlpatterns = [ name="organization", ), path( - "senior-official/", + "organization/organization-info", + views.PortfolioOrganizationInfoView.as_view(), + name="organization-info", + ), + path( + "organization/senior-official", views.PortfolioSeniorOfficialView.as_view(), - name="senior-official", + name="organization-senior-official", ), path( "admin/analytics/export_data_type/", diff --git a/src/registrar/permissions.py b/src/registrar/permissions.py index 6847c16d5..892b201a2 100644 --- a/src/registrar/permissions.py +++ b/src/registrar/permissions.py @@ -63,7 +63,8 @@ URL_PERMISSIONS = { "domain-requests": [HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM], "no-portfolio-requests": [IS_PORTFOLIO_MEMBER], "organization": [IS_PORTFOLIO_MEMBER], - "senior-official": [IS_PORTFOLIO_MEMBER], + "organization-info": [IS_PORTFOLIO_MEMBER], + "organization-senior-official": [IS_PORTFOLIO_MEMBER], # Domain requests "domain-request-status": [HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT, IS_DOMAIN_REQUEST_CREATOR], "domain-request-status-viewonly": [HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL], diff --git a/src/registrar/templates/domain_base.html b/src/registrar/templates/domain_base.html index 5637fa52b..919178577 100644 --- a/src/registrar/templates/domain_base.html +++ b/src/registrar/templates/domain_base.html @@ -21,8 +21,7 @@ {% endif %} -
-
+
{% if not domain.domain_info %}
@@ -63,7 +62,6 @@ {% endblock %} {# domain_content #} {% endif %} -
diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index e4c3f703d..9a99440de 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -20,8 +20,8 @@ {% endblock breadcrumb %} {{ block.super }} -
-

{{ domain.name }}

+
+

{{ domain.name }}

{% include 'domain_request_sidebar.html' %}
-
-
+
{% if steps.current == steps.first %} {% if portfolio %} @@ -142,8 +141,6 @@ {% block after_form_content %}{% endblock %} - -
diff --git a/src/registrar/templates/includes/contact.html b/src/registrar/templates/includes/contact.html index 68c243558..91fff269a 100644 --- a/src/registrar/templates/includes/contact.html +++ b/src/registrar/templates/includes/contact.html @@ -2,5 +2,5 @@ {{ contact.get_formatted_name }}
{% if contact.title %}{{ contact.title }}
{% endif %} {% if contact.email %}{{ contact.email }}
{% endif %} - {% if contact.phone %}{{ contact.phone.as_national }}{% endif %} + {% if not portfolio and contact.phone %}{{ contact.phone.as_national }}{% endif %} diff --git a/src/registrar/templates/includes/organization_address.html b/src/registrar/templates/includes/organization_address.html index d6126d681..5b03620c0 100644 --- a/src/registrar/templates/includes/organization_address.html +++ b/src/registrar/templates/includes/organization_address.html @@ -1,6 +1,6 @@
- {% if organization.federal_agency %} - {{ organization.federal_agency }}
+ {% if not portfolio and organization.federal_agency %} + {{ organization.federal_agency }}
{% endif %} {% if organization.organization_name %} {{ organization.organization_name }} diff --git a/src/registrar/templates/includes/summary_item.html b/src/registrar/templates/includes/summary_item.html index 0ce7910bb..057423488 100644 --- a/src/registrar/templates/includes/summary_item.html +++ b/src/registrar/templates/includes/summary_item.html @@ -1,6 +1,8 @@ {% load static url_helpers %} -
+{% if portfolio_first_section %}
+{% else %}
+{% endif %}
diff --git a/src/registrar/templates/portfolio_base.html b/src/registrar/templates/portfolio_base.html index 28e8b60e0..e356e7a6e 100644 --- a/src/registrar/templates/portfolio_base.html +++ b/src/registrar/templates/portfolio_base.html @@ -7,10 +7,12 @@
{% if user.is_authenticated %} {# the entire logged in page goes here #} + + {# portfolio organization page layout #} + {% block portfolio_organization_content %}{% endblock %}
- {% block portfolio_content %}{% endblock %}
diff --git a/src/registrar/templates/portfolio_organization.html b/src/registrar/templates/portfolio_organization.html index 2cc7e3f0f..eaca5767e 100644 --- a/src/registrar/templates/portfolio_organization.html +++ b/src/registrar/templates/portfolio_organization.html @@ -1,13 +1,11 @@ {% extends 'portfolio_base.html' %} {% load static field_helpers%} -{% block title %}Organization name and mailing address | {{ portfolio.name }}{% endblock %} +{% block title %}Organization overview | {{ portfolio }}{% endblock %} -{% load static %} - -{% block portfolio_content %} -
-
+{% block portfolio_organization_content %} +
+

@@ -17,63 +15,18 @@ {% include 'portfolio_organization_sidebar.html' %}

-
- - {% include "includes/form_errors.html" with form=form %} - {% block messages %} - {% include "includes/form_messages.html" %} - {% endblock messages%} - -

Organization

- -

The name of your organization will be publicly listed as the domain registrant.

- - {% if has_edit_portfolio_permission %} -

- Your organization name can’t be updated here. - To suggest an update, email help@get.gov. -

- - {% include "includes/required_fields.html" %} -
- {% csrf_token %} -

Organization name

-

- {{ portfolio.federal_agency }} -

- {% input_with_errors form.address_line1 %} - {% input_with_errors form.address_line2 %} - {% input_with_errors form.city %} - {% input_with_errors form.state_territory %} - {% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %} - {% input_with_errors form.zipcode %} - {% endwith %} - -
- {% else %} -

Organization name

-

- {{ portfolio.federal_agency }} -

- {% if form.address_line1.value is not None %} - {% include "includes/input_read_only.html" with field=form.address_line1 %} - {% endif %} - {% if form.address_line2.value is not None %} - {% include "includes/input_read_only.html" with field=form.address_line2 %} - {% endif %} - {% if form.city.value is not None %} - {% include "includes/input_read_only.html" with field=form.city %} - {% endif %} - {% if form.state_territory.value is not None %} - {% include "includes/input_read_only.html" with field=form.state_territory %} - {% endif %} - {% if form.zipcode.value is not None %} - {% include "includes/input_read_only.html" with field=form.zipcode %} - {% endif %} - {% endif %} - -
+
+

Organization overview

+
+

{{ portfolio }}

+ {% url 'organization-info' as url %} + {% include "includes/summary_item.html" with title='Organization' value=portfolio address='true' edit_link=url editable=has_edit_portfolio_permission view_button='true' portfolio_first_section='true'%} + + {% url 'organization-senior-official' as url %} + {% include "includes/summary_item.html" with title='Senior official' value=portfolio.senior_official contact='true' edit_link=url view_button='true' %} +
+ + +
{% endblock %} diff --git a/src/registrar/templates/portfolio_organization_info.html b/src/registrar/templates/portfolio_organization_info.html new file mode 100644 index 000000000..546b06b83 --- /dev/null +++ b/src/registrar/templates/portfolio_organization_info.html @@ -0,0 +1,92 @@ +{% extends 'portfolio_base.html' %} +{% load static field_helpers%} + +{% block title %}Organization name and mailing address | {{ portfolio }}{% endblock %} + +{% load static %} + +{% block portfolio_organization_content %} +
+
+

+ Portfolio name: {{ portfolio }} +

+ + {% include 'portfolio_organization_sidebar.html' %} +
+ +
+ {% block breadcrumb %} + + + {% endblock breadcrumb %} + + {% include "includes/form_errors.html" with form=form %} + {% block messages %} + {% include "includes/form_messages.html" %} + {% endblock messages%} + +

Organization

+
+

The name of your organization will be publicly listed as the domain registrant.

+ + {% if has_edit_portfolio_permission %} +

+ Your organization name can’t be updated here. + To suggest an update, email help@get.gov. +

+ + {% include "includes/required_fields.html" %} +
+ {% csrf_token %} +

Organization name

+

+ {{ portfolio.federal_agency }} +

+ {% input_with_errors form.address_line1 %} + {% input_with_errors form.address_line2 %} + {% input_with_errors form.city %} + {% input_with_errors form.state_territory %} + {% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %} + {% input_with_errors form.zipcode %} + {% endwith %} + +
+ {% else %} +

Organization name

+

+ {{ portfolio.federal_agency }} +

+ {% if form.address_line1.value is not None %} + {% include "includes/input_read_only.html" with field=form.address_line1 %} + {% endif %} + {% if form.address_line2.value is not None %} + {% include "includes/input_read_only.html" with field=form.address_line2 %} + {% endif %} + {% if form.city.value is not None %} + {% include "includes/input_read_only.html" with field=form.city %} + {% endif %} + {% if form.state_territory.value is not None %} + {% include "includes/input_read_only.html" with field=form.state_territory %} + {% endif %} + {% if form.zipcode.value is not None %} + {% include "includes/input_read_only.html" with field=form.zipcode %} + {% endif %} + {% endif %} +
+
+
+{% endblock %} diff --git a/src/registrar/templates/portfolio_organization_sidebar.html b/src/registrar/templates/portfolio_organization_sidebar.html index cfbb30e91..89fcf773b 100644 --- a/src/registrar/templates/portfolio_organization_sidebar.html +++ b/src/registrar/templates/portfolio_organization_sidebar.html @@ -5,6 +5,15 @@
  • {% url 'organization' as url %} + + Organization overview + +
  • + +
  • + {% url 'organization-info' as url %} @@ -13,7 +22,7 @@
  • - {% url 'senior-official' as url %} + {% url 'organization-senior-official' as url %} diff --git a/src/registrar/templates/portfolio_senior_official.html b/src/registrar/templates/portfolio_senior_official.html index d521c015b..0b48befe2 100644 --- a/src/registrar/templates/portfolio_senior_official.html +++ b/src/registrar/templates/portfolio_senior_official.html @@ -5,10 +5,10 @@ {% load static %} -{% block portfolio_content %} +{% block portfolio_organization_content %} -
    -
    +
    +

    @@ -19,6 +19,20 @@

    + {% block breadcrumb %} + + + {% endblock breadcrumb %} + {% include "includes/senior_official.html" with can_edit=False %}
    diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py index e02a29e73..a2e727557 100644 --- a/src/registrar/templatetags/custom_filters.py +++ b/src/registrar/templatetags/custom_filters.py @@ -241,7 +241,8 @@ def is_portfolio_subpage(path): # Since our pages aren't unified under a common path, we need this approach for now. url_names = [ "organization", - "senior-official", + "organization-info", + "organization-senior-official", ] return get_url_name(path) in url_names diff --git a/src/registrar/tests/test_views_portfolio.py b/src/registrar/tests/test_views_portfolio.py index 81be0d3ad..40a9482f1 100644 --- a/src/registrar/tests/test_views_portfolio.py +++ b/src/registrar/tests/test_views_portfolio.py @@ -74,7 +74,7 @@ class TestPortfolio(WebTest): additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO], ) - so_portfolio_page = self.app.get(reverse("senior-official")) + so_portfolio_page = self.app.get(reverse("organization-senior-official")) # Assert that we're on the right page self.assertContains(so_portfolio_page, "Senior official") self.assertContains(so_portfolio_page, "Saturn Enceladus") @@ -196,29 +196,119 @@ class TestPortfolio(WebTest): self.assertEqual(response.status_code, 403) @less_console_noise_decorator - def test_portfolio_organization_page_read_only(self): - """Test that user with a portfolio can access the portfolio organization page, read only""" + def test_portfolio_organization_page_includes_org_info_and_senior_official(self): + """Test that portfolio user on the organization overview page includes sections on the organization's + info and senior official""" + self.app.set_user(self.user.username) + portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( + user=self.user, + portfolio=self.portfolio, + additional_permissions=[ + UserPortfolioPermissionChoices.VIEW_PORTFOLIO, + UserPortfolioPermissionChoices.EDIT_PORTFOLIO, + ], + ) + so = SeniorOfficial.objects.create( + first_name="Saturn", last_name="Enceladus", title="Planet/Moon", email="spacedivision@igorville.com" + ) + + self.portfolio.senior_official = so + self.portfolio.organization_name = "Hotel California" + self.portfolio.city = "Los Angeles" + self.portfolio.save() + + with override_flag("organization_feature", active=True): + # User can access organization info form via organization overview page + response = self.app.get(reverse("organization")) + self.assertEqual(response.status_code, 200) + # Organization overview page includes organization name + self.assertContains(response, "

    Organization overview

    ") + self.assertContains(response, "Hotel California") + # Organization overview page includes organization info and senior official details + self.assertContains(response, "Los Angeles") + self.assertContains(response, "spacedivision@igorville.com") + + @less_console_noise_decorator + def test_portfolio_organization_page_directs_to_org_detail_forms(self): + """Test that portfolio user on the organization overview page can click on the overview + sections to their respective forms""" + self.app.set_user(self.user.username) + portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( + user=self.user, + portfolio=self.portfolio, + additional_permissions=[ + UserPortfolioPermissionChoices.VIEW_PORTFOLIO, + UserPortfolioPermissionChoices.EDIT_PORTFOLIO, + ], + ) + self.portfolio.save() + + with override_flag("organization_feature", active=True): + # User can access organization info form via organization overview page + response = self.app.get(reverse("organization")) + # The overview page includes button to edit organization + org_info_url = reverse("organization-info") + org_senior_official_url = reverse("organization-senior-official") + self.assertContains(response, f'href="{org_info_url}"') + self.assertContains(response, f'href="{org_senior_official_url}"') + + @less_console_noise_decorator + def test_portfolio_organization_page_section_viewonly_icon(self): + """Test organization page setion displays viewonly icon for portfolio nonadmin member""" self.app.set_user(self.user.username) portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( user=self.user, portfolio=self.portfolio, additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO], ) - self.portfolio.city = "Los Angeles" self.portfolio.save() + with override_flag("organization_feature", active=True): - response = self.app.get(reverse("organization")) - # Assert the response is a 200 - self.assertEqual(response.status_code, 200) - # The label for Federal agency will always be a h4 - self.assertContains(response, '

    Organization name

    ') - # The read only label for city will be a h4 - self.assertContains(response, '

    City

    ') - self.assertNotContains(response, 'for="id_city"') - self.assertContains(response, '

    Los Angeles

    ') + # User can access view-only form via organization overview page + org_overview_response = self.app.get(reverse("organization")) + # Viewonly icons for org info and senior official (which is always viewonly) + # visibility is html id of view only icon + self.assertContains(org_overview_response, "visibility", count=2) @less_console_noise_decorator - def test_portfolio_organization_page_edit_access(self): + def test_portfolio_organization_page_section_edit_icon(self): + """Test organization page setion displays viewonly icon for portfolio nonadmin member""" + self.app.set_user(self.user.username) + portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( + user=self.user, + portfolio=self.portfolio, + additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO], + ) + self.portfolio.save() + + with override_flag("organization_feature", active=True): + # User can access view-only form via organization overview page + org_overview_response = self.app.get(reverse("organization")) + # Viewonly icons for org info and senior official (which is always viewonly) + # visibility is html id of view only icon + self.assertContains(org_overview_response, "visibility", count=2) + + @less_console_noise_decorator + def test_portfolio_organization_info_page_read_only(self): + """Test that user with a portfolio can access the portfolio organization page, read only""" + self.app.set_user(self.user.username) + portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( + user=self.user, + portfolio=self.portfolio, + additional_permissions=[ + UserPortfolioPermissionChoices.VIEW_PORTFOLIO, + UserPortfolioPermissionChoices.EDIT_PORTFOLIO, + ], + ) + self.portfolio.save() + with override_flag("organization_feature", active=True): + # User can access view-only form via organization overview page + org_overview_response = self.app.get(reverse("organization")) + # Edit icons for org info (senior official is always viewonly) + self.assertContains(org_overview_response, "Edit") + + @less_console_noise_decorator + def test_portfolio_organization_info_page_edit_access(self): """Test that user with a portfolio can access the portfolio organization page, read only""" self.app.set_user(self.user.username) portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( @@ -231,8 +321,10 @@ class TestPortfolio(WebTest): ) self.portfolio.city = "Los Angeles" self.portfolio.save() + with override_flag("organization_feature", active=True): - response = self.app.get(reverse("organization")) + # User can access editable form via organization info page + response = self.app.get(reverse("organization-info")) # Assert the response is a 200 self.assertEqual(response.status_code, 200) # The label for Federal agency will always be a h4 @@ -242,6 +334,33 @@ class TestPortfolio(WebTest): self.assertNotContains(response, '

    Los Angeles

    ') self.assertContains(response, 'for="id_city"') + @less_console_noise_decorator + def test_portfolio_organization_detail_pages_include_breadcrumb(self): + """Test that breadcrumb menus display on portfolio detail pages""" + self.app.set_user(self.user.username) + portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( + user=self.user, + portfolio=self.portfolio, + additional_permissions=[ + UserPortfolioPermissionChoices.VIEW_PORTFOLIO, + UserPortfolioPermissionChoices.EDIT_PORTFOLIO, + ], + ) + self.portfolio.organization_name = "Hotel California" + self.portfolio.save() + + with override_flag("organization_feature", active=True): + # Breadcrumb appears on organization info page + org_info_response = self.app.get(reverse("organization-info")) + self._assert_has_organization_breadcrumb(org_info_response) + so_response = self.app.get(reverse("organization-senior-official")) + self._assert_has_organization_breadcrumb(so_response) + + def _assert_has_organization_breadcrumb(self, response): + self.assertContains(response, '
      ') + self.assertContains(response, "Hotel California") + self.assertContains(response, 'href="/organization/"') + @less_console_noise_decorator @override_flag("organization_requests", active=True) def test_accessible_pages_when_user_does_not_have_permission(self): @@ -285,7 +404,7 @@ class TestPortfolio(WebTest): # The organization page should still be accessible org_page = self.app.get(reverse("organization")) self.assertContains(org_page, self.portfolio.organization_name) - self.assertContains(org_page, "

      Organization

      ") + self.assertContains(org_page, "

      Organization overview

      ") # Both domain pages should not be accessible domain_page = self.app.get(reverse("domains"), expect_errors=True) @@ -332,7 +451,7 @@ class TestPortfolio(WebTest): # The organization page should still be accessible org_page = self.app.get(reverse("organization")) self.assertContains(org_page, self.portfolio.organization_name) - self.assertContains(org_page, "

      Organization

      ") + self.assertContains(org_page, "

      Organization overview

      ") # Both domain pages should not be accessible domain_page = self.app.get(reverse("domains"), expect_errors=True) @@ -352,12 +471,12 @@ class TestPortfolio(WebTest): portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( user=self.user, portfolio=self.portfolio, additional_permissions=portfolio_additional_permissions ) - page = self.app.get(reverse("organization")) + page = self.app.get(reverse("organization-info")) self.assertContains(page, "The name of your organization will be publicly listed as the domain registrant.") @less_console_noise_decorator - def test_domain_org_name_address_content(self): - """Org name and address information appears on the page.""" + def test_portfolio_org_info_includes_name_and_address(self): + """Org name and address appears on the org info page.""" with override_flag("organization_feature", active=True): self.app.set_user(self.user.username) portfolio_additional_permissions = [ @@ -370,9 +489,9 @@ class TestPortfolio(WebTest): self.portfolio.organization_name = "Hotel California" self.portfolio.save() - page = self.app.get(reverse("organization")) - # Once in the sidenav, once in the main nav - self.assertContains(page, "Hotel California", count=2) + page = self.app.get(reverse("organization-info")) + # Org name in Sidenav, main nav, webpage title, and breadcrumb + self.assertContains(page, "Hotel California", count=4) self.assertContains(page, "Non-Federal Agency") @less_console_noise_decorator @@ -390,7 +509,7 @@ class TestPortfolio(WebTest): self.portfolio.address_line1 = "1600 Penn Ave" self.portfolio.save() - portfolio_org_name_page = self.app.get(reverse("organization")) + portfolio_org_name_page = self.app.get(reverse("organization-info")) session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] portfolio_org_name_page.form["address_line1"] = "6 Downing st" @@ -419,7 +538,7 @@ class TestPortfolio(WebTest): self.portfolio.address_line1 = "1600 Penn Ave" self.portfolio.save() - portfolio_org_name_page = self.app.get(reverse("organization")) + portfolio_org_name_page = self.app.get(reverse("organization-info")) session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] # Form validates and redirects with all required fields @@ -458,7 +577,7 @@ class TestPortfolio(WebTest): self.portfolio.address_line1 = "1600 Penn Ave" self.portfolio.save() - portfolio_org_name_page = self.app.get(reverse("organization")) + portfolio_org_name_page = self.app.get(reverse("organization-info")) session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] portfolio_org_name_page.form["address_line1"] = "6 Downing st" portfolio_org_name_page.form["city"] = "London" diff --git a/src/registrar/views/portfolios.py b/src/registrar/views/portfolios.py index fe8095335..008f60e51 100644 --- a/src/registrar/views/portfolios.py +++ b/src/registrar/views/portfolios.py @@ -890,13 +890,43 @@ class PortfolioNoDomainRequestsView(View): @grant_access(IS_PORTFOLIO_MEMBER) -class PortfolioOrganizationView(DetailView, FormMixin): +class PortfolioOrganizationView(DetailView): + """ + View to handle displaying and updating overview of portfolio's information. + """ + + model = Portfolio + template_name = "portfolio_organization.html" + context_object_name = "portfolio" + + def get_context_data(self, **kwargs): + """Add additional context data to the template.""" + context = super().get_context_data(**kwargs) + portfolio = self.request.session.get("portfolio") + context["has_edit_portfolio_permission"] = self.request.user.has_edit_portfolio_permission(portfolio) + return context + + def get_object(self, queryset=None): + """Get the portfolio object based on the session.""" + portfolio = self.request.session.get("portfolio") + if portfolio is None: + raise Http404("No organization found for this user") + return portfolio + + def get(self, request, *args, **kwargs): + self.object = self.get_object() + context = self.get_context_data(object=self.object) + return self.render_to_response(context) + + +@grant_access(IS_PORTFOLIO_MEMBER) +class PortfolioOrganizationInfoView(DetailView, FormMixin): """ View to handle displaying and updating the portfolio's organization details. """ model = Portfolio - template_name = "portfolio_organization.html" + template_name = "portfolio_organization_info.html" form_class = portfolioForms.PortfolioOrgAddressForm context_object_name = "portfolio"