Repository: cisagov/manage.get.gov

Issue:
Domain request table: Capture the "CISA region" a `domain request` is in
### Issue description

_As an analyst
I want to know which [CISA region](https://www.cisa.gov/about/regions) a request is in 
so that if my research doesn't determine a request is authentic/eligible, I can know which region I need to reach out to_

Each US state/territory is in a "CISA region". When we need additional assistance in verification, we can reach out to regional contacts. Having regional designations in-registrar means we don't have to look it up, saving analyst time.

### Acceptance criteria

- [ ] For **non-federal requests**, the domain request detail page shows the CISA Region number based on the state abbreviation code of the organization address in the request. (See markup in "Additional Context")
- [ ] For **federal requests**, the domain request detail page shows "N/A" for the CISA region number, and no table lookup is necessary.
- [ ] The CISA region is not displayed on any user-facing views.

### Additional context
Please make this reusable by domain information as well. consider domain helper or other utility that can then take in the org address state/territory abbreviation and returns the number for the region. Regions and state abbreviations haven't changed in a long time and aren't expected to change in the future, they do not need to be in a table and a simple dictionary lookup (while ugly) is probably the simplest solution.

Based on the official two-letter state/territory abbreviation from the organization address, use the data in the following table to determine the region number:

| Region | Locales |
| ------- | ----- |
| 1 |Connecticut, Maine, Massachusetts, New Hampshire, Rhode Island, Vermont|
| 2 |New Jersey, New York, Puerto Rico, U.S. Virgin Islands|
|3| Delaware, District of Columbia, Maryland, Pennsylvania, Virginia, West Virginia|
|4| Alabama, Florida, Georgia, Kentucky, Mississippi, North Carolina, South Carolina, Tennessee|
|5| Illinois, Indiana, Michigan, Minnesota, Ohio, Wisconsin|
|6| Arkansas, Louisiana, New Mexico, Oklahoma, Texas|
|7|Iowa, Kansas, Missouri, Nebraska|
|8|Colorado, Montana, North Dakota, South Dakota, Utah, Wyoming|
|9|Arizona, California, Hawaii, Nevada, Guam, American Samoa, Commonwealth of the Northern Mariana Islands|
|10|Alaska, Idaho, Oregon, Washington|

Click Image to open Miro:
[![Image](https://github.com/cisagov/manage.get.gov/assets/62573986/bca81201-ce20-409b-bb31-10bca552ed23)](https://miro.com/app/board/uXjVKNvtde0=/?moveToWidget=3458764587423408611&cot=14)

### Links to other issues

Blocks #2095 


Discussion:
I added the second note to the A/C about federal requests.

Resolving patch:
diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py
--- a/src/registrar/templatetags/custom_filters.py
+++ b/src/registrar/templatetags/custom_filters.py
@@ -67,3 +67,69 @@ def get_organization_long_name(generic_org_type):
 @register.filter(name="has_permission")
 def has_permission(user, permission):
     return user.has_perm(permission)
+
+
+@register.filter
+def get_region(state):
+    if state and isinstance(state, str):
+        regions = {
+            "CT": 1,
+            "ME": 1,
+            "MA": 1,
+            "NH": 1,
+            "RI": 1,
+            "VT": 1,
+            "NJ": 2,
+            "NY": 2,
+            "PR": 2,
+            "VI": 2,
+            "DE": 3,
+            "DC": 3,
+            "MD": 3,
+            "PA": 3,
+            "VA": 3,
+            "WV": 3,
+            "AL": 4,
+            "FL": 4,
+            "GA": 4,
+            "KY": 4,
+            "MS": 4,
+            "NC": 4,
+            "SC": 4,
+            "TN": 4,
+            "IL": 5,
+            "IN": 5,
+            "MI": 5,
+            "MN": 5,
+            "OH": 5,
+            "WI": 5,
+            "AR": 6,
+            "LA": 6,
+            "NM": 6,
+            "OK": 6,
+            "TX": 6,
+            "IA": 7,
+            "KS": 7,
+            "MO": 7,
+            "NE": 7,
+            "CO": 8,
+            "MT": 8,
+            "ND": 8,
+            "SD": 8,
+            "UT": 8,
+            "WY": 8,
+            "AZ": 9,
+            "CA": 9,
+            "HI": 9,
+            "NV": 9,
+            "GU": 9,
+            "AS": 9,
+            "MP": 9,
+            "AK": 10,
+            "ID": 10,
+            "OR": 10,
+            "WA": 10,
+        }
+        return regions.get(state.upper(), "N/A")
+    else:
+        return None


Test patch:
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -2392,6 +2392,66 @@ def test_investigator_list_is_alphabetically_sorted(self):
 
             self.assertEqual(expected_list, actual_list)
 
+    @less_console_noise_decorator
+    def test_staff_can_see_cisa_region_federal(self):
+        """Tests if staff can see CISA Region: N/A"""
+
+        # Create a fake domain request
+        _domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+
+        p = "userpass"
+        self.client.login(username="staffuser", password=p)
+        response = self.client.get(
+            "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk),
+            follow=True,
+        )
+
+        # Make sure the page loaded, and that we're on the right page
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, _domain_request.requested_domain.name)
+
+        # Test if the page has the right CISA region
+        expected_html = '<div class="flex-container margin-top-2"><span>CISA region: N/A</span></div>'
+        # Remove whitespace from expected_html
+        expected_html = "".join(expected_html.split())
+
+        # Remove whitespace from response content
+        response_content = "".join(response.content.decode().split())
+
+        # Check if response contains expected_html
+        self.assertIn(expected_html, response_content)
+
+    @less_console_noise_decorator
+    def test_staff_can_see_cisa_region_non_federal(self):
+        """Tests if staff can see the correct CISA region"""
+
+        # Create a fake domain request. State will be NY (2).
+        _domain_request = completed_domain_request(
+            status=DomainRequest.DomainRequestStatus.IN_REVIEW, generic_org_type="interstate"
+        )
+
+        p = "userpass"
+        self.client.login(username="staffuser", password=p)
+        response = self.client.get(
+            "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk),
+            follow=True,
+        )
+
+        # Make sure the page loaded, and that we're on the right page
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, _domain_request.requested_domain.name)
+
+        # Test if the page has the right CISA region
+        expected_html = '<div class="flex-container margin-top-2"><span>CISA region: 2</span></div>'
+        # Remove whitespace from expected_html
+        expected_html = "".join(expected_html.split())
+
+        # Remove whitespace from response content
+        response_content = "".join(response.content.decode().split())
+
+        # Check if response contains expected_html
+        self.assertIn(expected_html, response_content)
+
     def tearDown(self):
         super().tearDown()
         Domain.objects.all().delete()