def test_lease_search_form_tenantcontact_type_choices(tenantcontact_type, expected): form = LeaseSearchForm({ 'tenantcontact_type': tenantcontact_type, }) assert expected == form.is_valid()
def test_lease_search_form_lease_type_choices(lease_type, expected): form = LeaseSearchForm({"lease_type": lease_type}) assert expected == form.is_valid()
def test_lease_search_form_no_fields_required(): form = LeaseSearchForm({}) assert form.is_valid()
def test_lease_search_form_business_id(business_id, expected): form = LeaseSearchForm({"business_id": business_id}) assert expected == form.is_valid()
def get_queryset(self): # noqa: C901 """Allow filtering leases by various query parameters `identifier` query parameter can be used to find the Lease with the provided identifier. example: .../lease/?identifier=S0120-219 `search` query parameter can be used to find leases by identifier and multiple other fields """ succinct = self.request.query_params.get("succinct") if succinct: queryset = Lease.objects.succinct_select_related_and_prefetch_related() else: queryset = Lease.objects.full_select_related_and_prefetch_related() if self.action != "list": return queryset # Simple search identifier = self.request.query_params.get("identifier") search = self.request.query_params.get("search") if identifier is not None or search is not None: if search is None: search_string = identifier search_by_other = False else: search_string = search search_by_other = True looks_like_identifier = bool( re.match(r"[A-Z]\d{4}-\d+$", search_string.strip(), re.IGNORECASE) ) # Search by identifier or parts of it if len(search_string) < 3: identifier_q = Q( identifier__type__identifier__istartswith=search_string ) elif len(search_string) == 3: identifier_q = Q( identifier__type__identifier__iexact=search_string[:2], identifier__municipality__identifier=search_string[2:3], ) elif len(search_string) < 7: district_identifier = search_string[3:5] if district_identifier == "0": identifier_q = Q( identifier__type__identifier__iexact=search_string[:2], identifier__municipality__identifier=search_string[2:3], identifier__district__identifier__in=range(0, 10), ) else: if district_identifier == "00": district_identifier = "0" else: district_identifier = district_identifier.lstrip("0") identifier_q = Q( identifier__type__identifier__iexact=search_string[:2], identifier__municipality__identifier=search_string[2:3], identifier__district__identifier__startswith=district_identifier, ) elif looks_like_identifier: district_identifier = search_string[3:5] if district_identifier == "00": district_identifier = "0" else: district_identifier = district_identifier.lstrip("0") identifier_q = Q( identifier__type__identifier__iexact=search_string[:2], identifier__municipality__identifier=search_string[2:3], identifier__district__identifier=district_identifier, identifier__sequence__startswith=search_string[6:], ) else: identifier_q = Q() other_q = Q() # Search also by other fields if the search string is clearly not a lease identifier if search_by_other and not looks_like_identifier: # Address other_q |= Q(lease_areas__addresses__address__icontains=search_string) # Property identifier other_q |= Q(lease_areas__identifier__icontains=search_string) normalized_identifier = normalize_property_identifier(search_string) if search_string != normalized_identifier: other_q |= Q( lease_areas__identifier__icontains=normalized_identifier ) # Tenantcontact name other_q |= Q( tenants__tenantcontact__contact__name__icontains=search_string ) if " " in search_string: tenant_name_parts = search_string.split(" ", 2) other_q |= Q( tenants__tenantcontact__contact__first_name__icontains=tenant_name_parts[ 0 ] ) & Q( tenants__tenantcontact__contact__last_name__icontains=tenant_name_parts[ 1 ] ) other_q |= Q( tenants__tenantcontact__contact__first_name__icontains=tenant_name_parts[ 1 ] ) & Q( tenants__tenantcontact__contact__last_name__icontains=tenant_name_parts[ 0 ] ) else: other_q |= Q( tenants__tenantcontact__contact__first_name__icontains=search_string ) other_q |= Q( tenants__tenantcontact__contact__last_name__icontains=search_string ) # Lessor other_q |= Q(lessor__name__icontains=search_string) other_q |= Q(lessor__first_name__icontains=search_string) other_q |= Q(lessor__last_name__icontains=search_string) # Date try: search_date = parse( search_string, parserinfo=parserinfo(dayfirst=True) ) if search_date: other_q |= Q(start_date=search_date.date()) other_q |= Q(end_date=search_date.date()) except ValueError: pass queryset = queryset.filter(identifier_q | other_q) # Advanced search search_form = LeaseSearchForm(self.request.query_params) if search_form.is_valid(): if search_form.cleaned_data.get("tenant_name"): tenant_name = search_form.cleaned_data.get("tenant_name") # Tenantcontact name q = Q(tenants__tenantcontact__contact__name__icontains=tenant_name) if " " in tenant_name: tenant_name_parts = tenant_name.split(" ", 2) q |= Q( tenants__tenantcontact__contact__first_name__icontains=tenant_name_parts[ 0 ] ) & Q( tenants__tenantcontact__contact__last_name__icontains=tenant_name_parts[ 1 ] ) q |= Q( tenants__tenantcontact__contact__first_name__icontains=tenant_name_parts[ 1 ] ) & Q( tenants__tenantcontact__contact__last_name__icontains=tenant_name_parts[ 0 ] ) else: q |= Q( tenants__tenantcontact__contact__first_name__icontains=tenant_name ) q |= Q( tenants__tenantcontact__contact__last_name__icontains=tenant_name ) if search_form.cleaned_data.get("tenantcontact_type"): q &= Q( tenants__tenantcontact__type__in=search_form.cleaned_data.get( "tenantcontact_type" ) ) if search_form.cleaned_data.get("only_past_tenants"): q &= Q(tenants__tenantcontact__end_date__lte=datetime.date.today()) if search_form.cleaned_data.get("tenant_activity"): if search_form.cleaned_data.get("tenant_activity") == "past": q &= Q( tenants__tenantcontact__end_date__lte=datetime.date.today() ) if search_form.cleaned_data.get("tenant_activity") == "active": # No need to filter by start date because future start dates are also considered active q &= Q(tenants__tenantcontact__end_date=None) | Q( tenants__tenantcontact__end_date__gte=datetime.date.today() ) queryset = queryset.filter(q) if search_form.cleaned_data.get("sequence"): queryset = queryset.filter( identifier__sequence=search_form.cleaned_data.get("sequence") ) if search_form.cleaned_data.get("lease_start_date_start"): queryset = queryset.filter( start_date__gte=search_form.cleaned_data.get( "lease_start_date_start" ) ) if search_form.cleaned_data.get("lease_start_date_end"): queryset = queryset.filter( start_date__lte=search_form.cleaned_data.get("lease_start_date_end") ) if search_form.cleaned_data.get("lease_end_date_start"): queryset = queryset.filter( end_date__gte=search_form.cleaned_data.get("lease_end_date_start") ) if search_form.cleaned_data.get("lease_end_date_end"): queryset = queryset.filter( end_date__lte=search_form.cleaned_data.get("lease_end_date_end") ) # Filter by active / expired only when only one of the options is set if bool(search_form.cleaned_data.get("only_active_leases")) ^ bool( search_form.cleaned_data.get("only_expired_leases") ): if search_form.cleaned_data.get("only_active_leases"): # No need to filter by start date because future start dates are also considered active queryset = queryset.filter( Q(end_date__isnull=True) | Q(end_date__gte=datetime.date.today()) ) if search_form.cleaned_data.get("only_expired_leases"): queryset = queryset.filter(end_date__lte=datetime.date.today()) if "has_geometry" in search_form.cleaned_data: if search_form.cleaned_data.get("has_geometry") is True: queryset = queryset.filter(lease_areas__geometry__isnull=False) if search_form.cleaned_data.get("has_geometry") is False: queryset = queryset.filter(lease_areas__geometry__isnull=True) if search_form.cleaned_data.get("property_identifier"): property_identifier = search_form.cleaned_data.get( "property_identifier" ) normalized_identifier = normalize_property_identifier( property_identifier ) queryset = queryset.filter( Q(lease_areas__identifier__icontains=property_identifier) | Q(lease_areas__identifier__icontains=normalized_identifier) ) if search_form.cleaned_data.get("address"): queryset = queryset.filter( lease_areas__addresses__address__icontains=search_form.cleaned_data.get( "address" ) ) if search_form.cleaned_data.get("lease_state"): queryset = queryset.filter( state__in=search_form.cleaned_data.get("lease_state") ) if search_form.cleaned_data.get("business_id"): queryset = queryset.filter( tenants__tenantcontact__contact__business_id__icontains=search_form.cleaned_data.get( "business_id" ) ) if search_form.cleaned_data.get("national_identification_number"): nat_id = search_form.cleaned_data.get("national_identification_number") queryset = queryset.filter( tenants__tenantcontact__contact__national_identification_number__icontains=nat_id ) if search_form.cleaned_data.get("lessor"): queryset = queryset.filter( lessor=search_form.cleaned_data.get("lessor") ) if search_form.cleaned_data.get("contract_number"): queryset = queryset.filter( contracts__contract_number__icontains=search_form.cleaned_data.get( "contract_number" ) ) if search_form.cleaned_data.get("decision_maker"): queryset = queryset.filter( decisions__decision_maker=search_form.cleaned_data.get( "decision_maker" ) ) if search_form.cleaned_data.get("decision_date"): queryset = queryset.filter( decisions__decision_date=search_form.cleaned_data.get( "decision_date" ) ) if search_form.cleaned_data.get("decision_section"): queryset = queryset.filter( decisions__section=search_form.cleaned_data.get("decision_section") ) if search_form.cleaned_data.get("reference_number"): reference_number = search_form.cleaned_data.get("reference_number") queryset = queryset.filter( Q(reference_number__icontains=reference_number) | Q(decisions__reference_number__icontains=reference_number) ) if search_form.cleaned_data.get("invoice_number"): queryset = queryset.filter( invoices__number__icontains=search_form.cleaned_data.get( "invoice_number" ) ) return queryset.distinct()
def get_queryset(self): # noqa: C901 """Allow filtering leases by various query parameters `identifier` query parameter can be used to find the Lease with the provided identifier. example: .../lease/?identifier=S0120-219 """ identifier = self.request.query_params.get('identifier') succinct = self.request.query_params.get('succinct') if succinct: queryset = Lease.objects.succinct_select_related_and_prefetch_related( ) else: queryset = Lease.objects.full_select_related_and_prefetch_related() if self.action != 'list': return queryset if identifier is not None: if len(identifier) < 3: queryset = queryset.filter( identifier__type__identifier__istartswith=identifier) elif len(identifier) == 3: queryset = queryset.filter( identifier__type__identifier__iexact=identifier[:2], identifier__municipality__identifier=identifier[2:3]) elif len(identifier) < 7: district_identifier = identifier[3:5] if district_identifier == '0': queryset = queryset.filter( identifier__type__identifier__iexact=identifier[:2], identifier__municipality__identifier=identifier[2:3], identifier__district__identifier__in=range(0, 10)) else: if district_identifier != '00': district_identifier = district_identifier.lstrip('0') queryset = queryset.filter( identifier__type__identifier__iexact=identifier[:2], identifier__municipality__identifier=identifier[2:3], identifier__district__identifier__startswith= district_identifier) else: queryset = queryset.filter( identifier__type__identifier__iexact=identifier[:2], identifier__municipality__identifier=identifier[2:3], identifier__district__identifier=identifier[3:5], identifier__sequence__startswith=identifier[6:]) search_form = LeaseSearchForm(self.request.query_params) if search_form.is_valid(): if search_form.cleaned_data.get('tenant_name'): tenant_name = search_form.cleaned_data.get('tenant_name') queryset = queryset.filter( Q(tenants__tenantcontact__contact__name__icontains= tenant_name) | Q(tenants__tenantcontact__contact__first_name__icontains= tenant_name) | Q(tenants__tenantcontact__contact__last_name__icontains= tenant_name)) # Limit further only if searching by tenants if search_form.cleaned_data.get('tenantcontact_type'): queryset = queryset.filter( tenants__tenantcontact__type__in=search_form. cleaned_data.get('tenantcontact_type')) if search_form.cleaned_data.get('only_past_tenants'): queryset = queryset.filter( tenants__tenantcontact__end_date__lte=datetime.date. today()) if search_form.cleaned_data.get('sequence'): queryset = queryset.filter(identifier__sequence=search_form. cleaned_data.get('sequence')) if search_form.cleaned_data.get('lease_start_date_start'): queryset = queryset.filter( start_date__gte=search_form.cleaned_data.get( 'lease_start_date_start')) if search_form.cleaned_data.get('lease_start_date_end'): queryset = queryset.filter( start_date__lte=search_form.cleaned_data.get( 'lease_start_date_end')) if search_form.cleaned_data.get('lease_end_date_start'): queryset = queryset.filter( end_date__gte=search_form.cleaned_data.get( 'lease_end_date_start')) if search_form.cleaned_data.get('lease_end_date_end'): queryset = queryset.filter( end_date__lte=search_form.cleaned_data.get( 'lease_end_date_end')) if search_form.cleaned_data.get('only_active_leases'): queryset = queryset.filter( (Q(start_date__isnull=True) | Q(start_date__lte=datetime.date.today())) & (Q(end_date__isnull=True) | Q(end_date__gte=datetime.date.today()))) if search_form.cleaned_data.get('only_expired_leases'): queryset = queryset.filter(end_date__lte=datetime.date.today()) if search_form.cleaned_data.get('property_identifier'): queryset = queryset.filter( lease_areas__identifier__icontains=search_form. cleaned_data.get('property_identifier')) if search_form.cleaned_data.get('address'): queryset = queryset.filter( lease_areas__addresses__address__icontains=search_form. cleaned_data.get('address')) if search_form.cleaned_data.get('lease_state'): queryset = queryset.filter( state__in=search_form.cleaned_data.get('lease_state')) return queryset.distinct()
def test_lease_search_form_lease_state_choices(lease_state, expected): form = LeaseSearchForm({ 'lease_state': lease_state, }) assert expected == form.is_valid()