diff --git a/plugins/polio/api/vaccines/repository.py b/plugins/polio/api/vaccines/repository.py index 266538666c..acbaad4940 100644 --- a/plugins/polio/api/vaccines/repository.py +++ b/plugins/polio/api/vaccines/repository.py @@ -27,17 +27,10 @@ class VaccineReportingFilterBackend(filters.BaseFilterBackend): """Filter backend for vaccine reporting that handles campaign status, country, and file type filtering.""" def filter_queryset(self, request, queryset, view): - # Filter by campaign status - campaign_status = request.query_params.get("campaign_status", None) - - if campaign_status: - today = datetime.now().date() - if campaign_status.upper() == "ONGOING": - queryset = queryset.filter(campaign_started_at__lte=today, campaign_ended_at__gte=today) - elif campaign_status.upper() == "PAST": - queryset = queryset.filter(campaign_started_at__lt=today, campaign_ended_at__lt=today) - elif campaign_status.upper() == "PREPARING": - queryset = queryset.filter(campaign_started_at__gte=today) + # Filter by vaccine name (single) + vaccine_name = request.query_params.get("vaccine_name", None) + if vaccine_name: + queryset = queryset.filter(vaccine_name=vaccine_name) # Filter by country block country_block = request.query_params.get("country_block", None) @@ -57,15 +50,6 @@ def filter_queryset(self, request, queryset, view): except ValueError: raise ValidationError("countries must be a comma-separated list of integers") - # Filter by campaign category - campaign_category = request.query_params.get("campaignCategory", None) - if campaign_category == "test": - queryset = queryset.filter(campaign__is_test=True) - if campaign_category == "preventive": - queryset = queryset.filter(campaign__is_preventive=True) - if campaign_category == "regular": - queryset = queryset.filter(campaign__is_preventive=False).filter(campaign__is_test=False) - # Filter by campaign campaign = request.query_params.get("campaign", None) if campaign: @@ -76,14 +60,18 @@ def filter_queryset(self, request, queryset, view): if file_type: file_type = file_type.upper() if file_type == "VRF": - queryset = queryset.filter(campaign__vaccinerequestform__isnull=False) + queryset = queryset.filter( + campaign__vaccinerequestform__isnull=False, + ) elif file_type == "PRE_ALERT": queryset = queryset.filter( campaign__vaccinerequestform__isnull=False, campaign__vaccinerequestform__vaccineprealert__isnull=False, ).distinct("id") elif file_type == "FORM_A": - queryset = queryset.filter(outgoingstockmovement__isnull=False) + queryset = queryset.filter( + outgoingstockmovement__isnull=False, + ) # Filter by VRF type vrf_type = request.query_params.get("vrf_type", None) @@ -303,7 +291,6 @@ def get_queryset(self): "campaign_ended_at", ) - # 393 results without filter rounds_queryset = rounds_queryset.annotate( vaccine_name=Case( When(campaign__separate_scopes_per_round=False, then="campaign__scopes__vaccine"), diff --git a/plugins/polio/js/src/constants/urls.ts b/plugins/polio/js/src/constants/urls.ts index c292816167..0ba38aecc3 100644 --- a/plugins/polio/js/src/constants/urls.ts +++ b/plugins/polio/js/src/constants/urls.ts @@ -93,10 +93,9 @@ export const polioRouteConfigs: Record = { ...paginationPathParams, 'countries', 'campaignType', - 'campaignCategory', 'file_type', 'country_block', - 'campaignStatus', + 'vaccine_name', ], }, embeddedCalendar: { @@ -115,10 +114,9 @@ export const polioRouteConfigs: Record = { ...paginationPathParams, 'countries', 'campaignType', - 'campaignCategory', 'file_type', 'country_block', - 'campaignStatus', + 'vaccine_name', ], }, lqasCountry: { diff --git a/plugins/polio/js/src/domains/VaccineModule/Repository/VaccineRepository.tsx b/plugins/polio/js/src/domains/VaccineModule/Repository/VaccineRepository.tsx index 6e5abff72f..58d0536570 100644 --- a/plugins/polio/js/src/domains/VaccineModule/Repository/VaccineRepository.tsx +++ b/plugins/polio/js/src/domains/VaccineModule/Repository/VaccineRepository.tsx @@ -99,7 +99,6 @@ export const VaccineRepository: FunctionComponent = () => { )} = ({ params, - isEmbedded = false, redirectUrl, }) => { const redirectToReplace = useRedirectToReplace(); @@ -38,13 +35,9 @@ export const VaccineRepositoryFilters: FunctionComponent = ({ const [fileType, setFileType] = useState( params.file_type || 'VRF,PRE_ALERT,FORM_A', ); - const [campaignStatus, setCampaignStatus] = useState(params.campaignStatus); + const [vaccineName, setVaccineName] = useState(params.vaccine_name); const [countryBlocks, setCountryBlocks] = useState(params.country_block); - const [campaignCategory, setCampaignCategory] = useState( - isEmbedded - ? (params.campaignCategory ?? 'all') - : params.campaignCategory, - ); + const handleSearch = useCallback(() => { if (filtersUpdated) { setFiltersUpdated(false); @@ -52,10 +45,9 @@ export const VaccineRepositoryFilters: FunctionComponent = ({ ...params, countries, page: undefined, - campaignCategory, country_block: countryBlocks, file_type: fileType, - campaignStatus, + vaccine_name: vaccineName, }; redirectToReplace(redirectUrl, urlParams); } @@ -63,10 +55,9 @@ export const VaccineRepositoryFilters: FunctionComponent = ({ filtersUpdated, params, countries, - campaignCategory, countryBlocks, + vaccineName, fileType, - campaignStatus, redirectToReplace, redirectUrl, ]); @@ -77,94 +68,74 @@ export const VaccineRepositoryFilters: FunctionComponent = ({ const countriesList = (data && data.orgUnits) || []; - const campaignCategoryOptions = useCampaignCategoryOptions(); - const fileTypes = useGetFileTypes(); - const campaignStatusOptions = useGetCampaignStatus(); useEffect(() => { setFiltersUpdated(true); - }, [countries, campaignCategory, countryBlocks, fileType, campaignStatus]); + }, [countries, countryBlocks, fileType, vaccineName]); useEffect(() => { setFiltersUpdated(false); }, []); return ( - <> - - - { - setCampaignStatus(value); - }} - value={campaignStatus} - type="select" - options={campaignStatusOptions} - label={MESSAGES.campaignStatus} - /> - { - setCountryBlocks(value); - }} - value={countryBlocks} - type="select" - options={groupedOrgUnits} - label={MESSAGES.countryBlock} - /> - - - { - setCountries(value); - }} - value={countries} - type="select" - options={countriesList.map(c => ({ - label: c.name, - value: c.id, - }))} - label={MESSAGES.country} - /> - - - { - setCampaignCategory(value); - }} - value={campaignCategory} - type="select" - options={campaignCategoryOptions} - label={MESSAGES.campaignCategory} - /> - - - { - setFileType(value); - }} - value={fileType} - type="select" - options={fileTypes} - label={MESSAGES.fileType} - /> - + + + { + setCountries(value); + }} + value={countries} + type="select" + options={countriesList.map(c => ({ + label: c.name, + value: c.id, + }))} + label={MESSAGES.country} + /> + { + setVaccineName(value); + }} + value={vaccineName} + type="select" + options={defaultVaccineOptions} + label={MESSAGES.vaccine} + /> - + + { + setCountryBlocks(value); + }} + value={countryBlocks} + type="select" + options={groupedOrgUnits} + label={MESSAGES.countryBlock} + /> + { + setFileType(value); + }} + value={fileType} + type="select" + options={fileTypes} + label={MESSAGES.fileType} + /> + + - + ); }; diff --git a/plugins/polio/js/src/domains/VaccineModule/Repository/hooks/useGetCampaignStatus.ts b/plugins/polio/js/src/domains/VaccineModule/Repository/hooks/useGetCampaignStatus.ts deleted file mode 100644 index 9e64a597d0..0000000000 --- a/plugins/polio/js/src/domains/VaccineModule/Repository/hooks/useGetCampaignStatus.ts +++ /dev/null @@ -1,26 +0,0 @@ -// import { useSafeIntl } from 'bluesquare-components'; -import { useMemo } from 'react'; -import { useSafeIntl } from 'bluesquare-components'; -import MESSAGES from '../messages'; -import { DropdownOptions } from '../../../../../../../../hat/assets/js/apps/Iaso/types/utils'; - -export const useGetCampaignStatus = (): DropdownOptions[] => { - const { formatMessage } = useSafeIntl(); - return useMemo( - () => [ - { - value: 'PREPARING', - label: formatMessage(MESSAGES.preparing), - }, - { - value: 'PAST', - label: formatMessage(MESSAGES.pastCampaigns), - }, - { - value: 'ONGOING', - label: formatMessage(MESSAGES.ongoingCampaigns), - }, - ], - [formatMessage], - ); -}; diff --git a/plugins/polio/js/src/domains/VaccineModule/Repository/types.ts b/plugins/polio/js/src/domains/VaccineModule/Repository/types.ts index bbd2cfe694..75b53b10ef 100644 --- a/plugins/polio/js/src/domains/VaccineModule/Repository/types.ts +++ b/plugins/polio/js/src/domains/VaccineModule/Repository/types.ts @@ -1,14 +1,13 @@ import { PaginationParams } from '../../../../../../../hat/assets/js/apps/Iaso/types/general'; -import { CampaignCategory } from '../../Campaigns/hooks/api/useGetCampaigns'; +import { Vaccine } from '../../../constants/types'; export type VaccineRepositoryParams = PaginationParams & { countries?: string; campaignType?: string; - campaignCategory?: CampaignCategory; country_block?: string; campaignGroups?: string; file_type?: string; - campaignStatus?: string; + vaccine_name?: Vaccine; }; export type DocumentData = { diff --git a/plugins/polio/tests/api/test.py b/plugins/polio/tests/api/test.py index 477ab675c0..1e02e6fe78 100644 --- a/plugins/polio/tests/api/test.py +++ b/plugins/polio/tests/api/test.py @@ -13,6 +13,7 @@ def create_campaign( district_ou_type, country_name="Groland", district_name="Groville", + vaccine=pm.VACCINES[0][0], ): country = m.OrgUnit.objects.create( org_unit_type=country_ou_type, @@ -36,7 +37,7 @@ def create_campaign( ) scope_group = m.Group.objects.create(name="campaign_scope", source_version=source_version) scope_group.org_units.set([district]) # FIXME: we should actually have children org units - scope = pm.CampaignScope.objects.create(campaign=campaign, vaccine=pm.VACCINES[0][0], group=scope_group) + scope = pm.CampaignScope.objects.create(campaign=campaign, vaccine=vaccine, group=scope_group) round_1 = pm.Round.objects.create( campaign=campaign, diff --git a/plugins/polio/tests/test_vaccine_repository.py b/plugins/polio/tests/test_vaccine_repository.py index 66fc364464..735aa79188 100644 --- a/plugins/polio/tests/test_vaccine_repository.py +++ b/plugins/polio/tests/test_vaccine_repository.py @@ -210,7 +210,7 @@ def test_ordering(self): def test_filtering(self): """Test filtering functionality of VaccineReportingViewSet""" # Create test data - campaign2, campaign2_round, campaign2_rnd2, campaign2_rnd3, zambia, _district = self.create_campaign( + campaign2, campaign2_round, campaign2_rnd2, campaign2_rnd3, _, _ = self.create_campaign( obr_name="Another Campaign", account=self.account, source_version=self.source_version_1, @@ -218,6 +218,7 @@ def test_filtering(self): country_name="WillBeIgnored", district_ou_type=self.org_unit_type_district, district_name="ZDistrict", + vaccine=pm.VACCINES[1][0], ) campaign2_round.delete() campaign2_rnd2.delete() @@ -234,13 +235,15 @@ def test_filtering(self): number=1, ) + campaign2.save + ( preparing_campaign, preparing_campaign_round, preparing_campaign2_rnd2, preparing_campaign_rnd3, - zambia_bis, - _district, + _, + _, ) = self.create_campaign( obr_name="Preparing Campaign", account=self.account, @@ -272,27 +275,10 @@ def test_filtering(self): date_dg_approval=self.now, quantities_ordered_in_doses=500, ) + vrf2.rounds.set([campaign2_round]) self.client.force_authenticate(user=self.user) - # Test filtering by campaign status - ONGOING - response = self.client.get(f"{BASE_URL}?campaign_status=ONGOING") - data = response.json() - self.assertEqual(len(data["results"]), 1) - self.assertEqual(data["results"][0]["campaign_obr_name"], "Another Campaign") - - # # Test filtering by campaign status - PAST - response = self.client.get(f"{BASE_URL}?campaign_status=PAST") - data = response.json() - self.assertEqual(len(data["results"]), 3) - self.assertEqual(data["results"][0]["campaign_obr_name"], "Test Campaign") - - # Test filtering by campaign status - PREPARING - response = self.client.get(f"{BASE_URL}?campaign_status=PREPARING") - data = response.json() - self.assertEqual(len(data["results"]), 1) - self.assertEqual(data["results"][0]["campaign_obr_name"], "Preparing Campaign") - # Test filtering by country response = self.client.get(f"{BASE_URL}?countries={self.zambia.id}") data = response.json() @@ -319,3 +305,13 @@ def test_filtering(self): data = response.json() self.assertEqual(len(data["results"]), 2) self.assertTrue(all(result["country_name"] == "Zambia" for result in data["results"])) + + # Test filtering by vaccine name + response = self.client.get(f"{BASE_URL}?vaccine_name={pm.VACCINES[1][0]}") + response = self.assertJSONResponse(response, 200) + data = response["results"] + self.assertEqual(len(data), 1) + response = self.client.get(f"{BASE_URL}?vaccine_name={pm.VACCINES[0][0]}") + response = self.assertJSONResponse(response, 200) + data = response["results"] + self.assertEqual(len(data), 4)