diff --git a/bc_obps/registration/api/v1/transfer_events.py b/bc_obps/registration/api/v1/transfer_events.py index 97c2dfc1a3..970084118e 100644 --- a/bc_obps/registration/api/v1/transfer_events.py +++ b/bc_obps/registration/api/v1/transfer_events.py @@ -1,5 +1,4 @@ -from typing import List, Literal, Optional -from registration.models.event.transfer_event import TransferEvent +from typing import List, Literal, Optional, Dict, Any from registration.schema.v1.transfer_event import TransferEventFilterSchema, TransferEventListOut from service.transfer_event_service import TransferEventService from common.permissions import authorize @@ -11,7 +10,6 @@ from ..router import router from service.error_service.custom_codes_4xx import custom_codes_4xx from ninja import Query -from django.db.models import QuerySet from registration.schema.generic import Message @@ -31,6 +29,6 @@ def list_transfer_events( sort_field: Optional[str] = "status", sort_order: Optional[Literal["desc", "asc"]] = "desc", paginate_result: bool = Query(True, description="Whether to paginate the results"), -) -> QuerySet[TransferEvent]: +) -> List[Dict[str, Any]]: # NOTE: PageNumberPagination raises an error if we pass the response as a tuple (like 200, ...) return TransferEventService.list_transfer_events(sort_field, sort_order, filters) diff --git a/bc_obps/registration/models/event/transfer_event.py b/bc_obps/registration/models/event/transfer_event.py index 23a679f6ad..ffd6a7bef1 100644 --- a/bc_obps/registration/models/event/transfer_event.py +++ b/bc_obps/registration/models/event/transfer_event.py @@ -10,6 +10,7 @@ class Statuses(models.TextChoices): COMPLETE = "Complete" TO_BE_TRANSFERRED = "To be transferred" TRANSFERRED = "Transferred" + description = models.TextField(db_comment="Description of the transfer or change in designated operator.") other_operator = models.ForeignKey( Operator, diff --git a/bc_obps/registration/schema/v1/transfer_event.py b/bc_obps/registration/schema/v1/transfer_event.py index c38ef8684f..a3fb870364 100644 --- a/bc_obps/registration/schema/v1/transfer_event.py +++ b/bc_obps/registration/schema/v1/transfer_event.py @@ -1,5 +1,5 @@ -from typing import List, Optional -from uuid import UUID, uuid4 +from typing import Optional +from uuid import UUID from registration.models.facility import Facility from registration.models.event.transfer_event import TransferEvent @@ -19,14 +19,19 @@ class TransferEventListOut(ModelSchema): facility__id: Optional[UUID] = Field(None, alias="facilities__id") id: UUID - class Meta: - model = TransferEvent - fields = ['effective_date', 'status','created_at'] - @staticmethod - def resolve_id(obj): - return obj['operation__id'] if obj['operation__id'] else obj['facilities__id'] + def resolve_id(obj: TransferEvent) -> UUID: + operation_id = getattr(obj, 'operation__id', None) + facility_id = getattr(obj, 'facilities__id', None) + record_id = operation_id if operation_id else facility_id + if not isinstance(record_id, UUID): + raise Exception('Missing valid UUID') + return record_id + + class Meta: + model = TransferEvent + fields = ['effective_date', 'status', 'created_at'] class TransferEventFilterSchema(FilterSchema): diff --git a/bc_obps/registration/tests/endpoints/v1/test_transfer_events.py b/bc_obps/registration/tests/endpoints/v1/test_transfer_events.py index d6a76616ba..c598ccd5ad 100644 --- a/bc_obps/registration/tests/endpoints/v1/test_transfer_events.py +++ b/bc_obps/registration/tests/endpoints/v1/test_transfer_events.py @@ -1,19 +1,9 @@ from datetime import datetime, timedelta from django.utils import timezone -from registration.models.event.transfer_event import TransferEvent from bc_obps.settings import NINJA_PAGINATION_PER_PAGE from model_bakery import baker -from localflavor.ca.models import CAPostalCodeField -from registration.models import ( - BcObpsRegulatedOperation, - NaicsCode, - Operation, - UserOperator, -) from registration.tests.utils.helpers import CommonTestSetup, TestUtils -from registration.tests.utils.bakers import operation_baker, operator_baker, user_operator_baker -from registration.constants import PAGE_SIZE from registration.utils import custom_reverse_lazy @@ -24,26 +14,31 @@ def test_list_transfer_events_unpaginated(self): # transfer of an operation baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation')) # transfer of 50 facilities - baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility',_quantity=50)) + baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility', _quantity=50)) for role in ['cas_admin', 'cas_analyst']: - response = TestUtils.mock_get_with_auth_role( - self, role, self.url+ "?paginate_result=False" - ) + response = TestUtils.mock_get_with_auth_role(self, role, self.url + "?paginate_result=False") assert response.status_code == 200 assert response.json().keys() == {'count', 'items'} assert response.json()['count'] == 51 - + items = response.json().get('items', []) for item in items: - assert set(item.keys()) == {'operation__name','operation__id','effective_date','status','id','facilities__name','facility__id','created_at'} - - + assert set(item.keys()) == { + 'operation__name', + 'operation__id', + 'effective_date', + 'status', + 'id', + 'facilities__name', + 'facility__id', + 'created_at', + } def test_list_transfer_events_paginated(self): # transfer of an operation baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation')) # transfer of 50 facilities - baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility',_quantity=50)) + baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility', _quantity=50)) # Get the default page 1 response response = TestUtils.mock_get_with_auth_role(self, "cas_admin", custom_reverse_lazy("list_transfer_events")) assert response.status_code == 200 @@ -87,27 +82,32 @@ def test_transfer_events_endpoint_list_transfer_events_with_sorting(self): today = timezone.make_aware(datetime.now()) yesterday = today - timedelta(days=1) # transfer of an operation - baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation'),effective_date=today) + baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation'), effective_date=today) # transfer of 50 facilities - baker.make_recipe('utils.transfer_event', effective_date=yesterday, facilities=baker.make_recipe('utils.facility',_quantity=50)) + baker.make_recipe( + 'utils.transfer_event', + effective_date=yesterday, + facilities=baker.make_recipe('utils.facility', _quantity=50), + ) - response_ascending = TestUtils.mock_get_with_auth_role(self, "cas_admin", self.url+ "?page=1&sort_field=effective_date&sort_order=asc") + response_ascending = TestUtils.mock_get_with_auth_role( + self, "cas_admin", self.url + "?page=1&sort_field=effective_date&sort_order=asc" + ) # save the id of the first paginated response item first_item_ascending = response_ascending.json()['items'][0] - + # # Sort created at descending - response_descending = TestUtils.mock_get_with_auth_role(self, "cas_admin", self.url+ "?page=1&sort_field=effective_date&sort_order=desc") + response_descending = TestUtils.mock_get_with_auth_role( + self, "cas_admin", self.url + "?page=1&sort_field=effective_date&sort_order=desc" + ) first_item_descending = response_descending.json()['items'][0] assert first_item_descending['effective_date'] > first_item_ascending['effective_date'] - - - def test_transfer_events_endpoint_list_transfer_events_with_filter(self): # transfer of an operation baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation', name='Test Operation')) # transfer of 50 facilities - baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility',_quantity=50)) + baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility', _quantity=50)) # Get the default page 1 response response = TestUtils.mock_get_with_auth_role( @@ -119,16 +119,14 @@ def test_transfer_events_endpoint_list_transfer_events_with_filter(self): assert item.get('facilities__name') == "Facility 010" # Test with a status filter that doesn't exist - response = TestUtils.mock_get_with_auth_role( - self, "cas_admin", self.url + "?status=unreal" - ) + response = TestUtils.mock_get_with_auth_role(self, "cas_admin", self.url + "?status=unreal") assert response.status_code == 200 assert response.json().get('count') == 0 # Test with two filters - facilities__name_to_filter, status_to_filter = response_items_1[0].get('facilities__name'), response_items_1[0].get( - 'status' - ) + facilities__name_to_filter, status_to_filter = response_items_1[0].get('facilities__name'), response_items_1[ + 0 + ].get('status') response = TestUtils.mock_get_with_auth_role( self, "cas_admin", self.url + f"?facilities__name={facilities__name_to_filter}&status={status_to_filter}" ) @@ -137,4 +135,4 @@ def test_transfer_events_endpoint_list_transfer_events_with_filter(self): assert len(response_items_2) == 1 assert response.json().get('count') == 1 assert response_items_2[0].get('facilities__name') == facilities__name_to_filter - assert response_items_2[0].get('status') == status_to_filter \ No newline at end of file + assert response_items_2[0].get('status') == status_to_filter diff --git a/bc_obps/service/tests/test_transfer_event_service.py b/bc_obps/service/tests/test_transfer_event_service.py index 59a08e80a7..607456f5c6 100644 --- a/bc_obps/service/tests/test_transfer_event_service.py +++ b/bc_obps/service/tests/test_transfer_event_service.py @@ -1,9 +1,6 @@ from registration.schema.v1.transfer_event import TransferEventFilterSchema -from registration.models.event.transfer_event import TransferEvent from service.transfer_event_service import TransferEventService import pytest -from registration.models import Activity -from service.activity_service import ActivityService from model_bakery import baker pytestmark = pytest.mark.django_db @@ -13,11 +10,13 @@ class TestTransferEventService: @staticmethod def test_list_transfer_events(): # transfer of 3 operations - baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation'),_quantity=3) + baker.make_recipe('utils.transfer_event', operation=baker.make_recipe('utils.operation'), _quantity=3) # transfer of 4 facilities - baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility',_quantity=4)) + baker.make_recipe('utils.transfer_event', facilities=baker.make_recipe('utils.facility', _quantity=4)) # sorting and filtering are tested in the endpoint test in conjunction with pagination - result = TransferEventService.list_transfer_events("status","desc",TransferEventFilterSchema(effective_date=None, operation__name=None, facilities__name=None, status=None)) + result = TransferEventService.list_transfer_events( + "status", + "desc", + TransferEventFilterSchema(effective_date=None, operation__name=None, facilities__name=None, status=None), + ) assert result.count() == 7 - - diff --git a/bc_obps/service/transfer_event_service.py b/bc_obps/service/transfer_event_service.py index 29665cc585..7b5530a5cc 100644 --- a/bc_obps/service/transfer_event_service.py +++ b/bc_obps/service/transfer_event_service.py @@ -1,6 +1,5 @@ from registration.models.event.transfer_event import TransferEvent -from typing import Optional -from django.db.models import QuerySet +from typing import Optional, Dict, Any, List from registration.schema.v1.transfer_event import TransferEventFilterSchema @@ -14,7 +13,20 @@ def list_transfer_events( sort_field: Optional[str], sort_order: Optional[str], filters: TransferEventFilterSchema = Query(...), - ) -> QuerySet[TransferEvent]: + ) -> List[Dict[str, Any]]: sort_direction = "-" if sort_order == "desc" else "" sort_by = f"{sort_direction}{sort_field}" - return filters.filter(TransferEvent.objects.order_by(sort_by)).values('effective_date', 'status','created_at', 'operation__name', 'operation__id','facilities__name', 'facilities__id').distinct() + queryset = ( + filters.filter(TransferEvent.objects.order_by(sort_by)) + .values( + 'effective_date', + 'status', + 'created_at', + 'operation__name', + 'operation__id', + 'facilities__name', + 'facilities__id', + ) + .distinct() + ) + return list(queryset) diff --git a/bciers/apps/registration/app/components/transfers/TransfersDataGridPage.tsx b/bciers/apps/registration/app/components/transfers/TransfersDataGridPage.tsx index dd9b913327..ecc4431fc3 100644 --- a/bciers/apps/registration/app/components/transfers/TransfersDataGridPage.tsx +++ b/bciers/apps/registration/app/components/transfers/TransfersDataGridPage.tsx @@ -15,7 +15,6 @@ export default async function TransfersDataGridPage({ rows: TransferRow[]; row_count: number; } = await fetchTransferEventsPageData(searchParams); - console.log("transfers", transfers); if (!transfers) { return
No transfers data in database.
; } diff --git a/bciers/apps/registration/app/components/transfers/fetchTransferEventsPageData.tsx b/bciers/apps/registration/app/components/transfers/fetchTransferEventsPageData.tsx index 739a2f4aff..ce469e0929 100644 --- a/bciers/apps/registration/app/components/transfers/fetchTransferEventsPageData.tsx +++ b/bciers/apps/registration/app/components/transfers/fetchTransferEventsPageData.tsx @@ -5,7 +5,6 @@ import { GridRowsProp } from "@mui/x-data-grid"; import formatTimestamp from "@bciers/utils/src/formatTimestamp"; export const formatTransferRows = (rows: GridRowsProp) => { - console.log("rows", rows); return rows.map( ({ id, diff --git a/bciers/apps/registration/app/components/transfers/types.ts b/bciers/apps/registration/app/components/transfers/types.ts index 235633bc52..4f91c7784e 100644 --- a/bciers/apps/registration/app/components/transfers/types.ts +++ b/bciers/apps/registration/app/components/transfers/types.ts @@ -1,10 +1,10 @@ export interface TransferRow { id: string; - operation__name: string; - facilities__name: string; + operation__name?: string; + facilities__name?: string; status: string; - created_at: string; - effective_date: string; + created_at: string | undefined; + effective_date?: string | undefined; } export interface TransfersSearchParams { diff --git a/erd_diagrams/erd_registration.md b/erd_diagrams/erd_registration.md index 0e49abefd9..68950cf68a 100644 --- a/erd_diagrams/erd_registration.md +++ b/erd_diagrams/erd_registration.md @@ -847,7 +847,6 @@ HistoricalTransferEvent { UUIDField id DateTimeField effective_date TextField description - CharField future_designated_operator CharField status UUIDField history_user_id ForeignKey created_by @@ -872,7 +871,6 @@ TransferEvent { DateTimeField effective_date ForeignKey operation TextField description - CharField future_designated_operator ForeignKey other_operator ForeignKey other_operator_contact CharField status