diff --git a/backend/hitas/services/owner.py b/backend/hitas/services/owner.py index 29286494b..3439e2f4e 100644 --- a/backend/hitas/services/owner.py +++ b/backend/hitas/services/owner.py @@ -101,6 +101,7 @@ def find_owners_with_multiple_ownerships() -> list[OwnershipWithApartmentCount]: Ownership.objects.select_related( "owner", "sale__apartment__building__real_estate__housing_company__postal_code", + "sale__apartment__building__real_estate__housing_company", ) .annotate( apartment_count=subquery_count(Ownership, "owner"), diff --git a/backend/hitas/services/reports.py b/backend/hitas/services/reports.py index dafa52d6f..464c89fb9 100644 --- a/backend/hitas/services/reports.py +++ b/backend/hitas/services/reports.py @@ -95,6 +95,10 @@ class MultipleOwnershipReportColumns(NamedTuple): apartment_address: str postal_code: str apartment_count: int | str + owner_identifier: str + housing_company_name: str + housing_company_completion_date: datetime.date | str + cost_area: int | str class OwnersByHousingCompanyReportColumns(NamedTuple): @@ -718,6 +722,10 @@ def build_multiple_ownerships_report_excel(ownerships: list[OwnershipWithApartme apartment_address="Asunnon osoite", postal_code="Postinumero", apartment_count="Omistajan asuntojen lukumäärä", + owner_identifier="Omistajan henkilö- tai Y-tunnus", + housing_company_name="Yhtiön nimi", + housing_company_completion_date="Yhtiön valmistumispäivä", + cost_area="Kalleusalue", ) worksheet.append(column_headers) @@ -728,6 +736,10 @@ def build_multiple_ownerships_report_excel(ownerships: list[OwnershipWithApartme apartment_address=ownership.apartment.address, postal_code=ownership.apartment.postal_code.value, apartment_count=ownership.apartment_count, + owner_identifier="" if ownership.owner.non_disclosure else ownership.owner.identifier, + housing_company_name=ownership.apartment.building.real_estate.housing_company.display_name, + housing_company_completion_date=ownership.apartment.building.real_estate.housing_company.completion_date, + cost_area=ownership.apartment.postal_code.cost_area, ) ) diff --git a/backend/hitas/tests/apis/test_api_reports.py b/backend/hitas/tests/apis/test_api_reports.py index b46be09d4..7b687ef1a 100644 --- a/backend/hitas/tests/apis/test_api_reports.py +++ b/backend/hitas/tests/apis/test_api_reports.py @@ -1427,7 +1427,16 @@ def test__api__multiple_ownerships_report__no_owners(api_client: HitasAPIClient) worksheet: Worksheet = workbook.worksheets[0] assert list(worksheet.values) == [ - ("Omistajan nimi", "Asunnon osoite", "Postinumero", "Omistajan asuntojen lukumäärä"), + ( + "Omistajan nimi", + "Asunnon osoite", + "Postinumero", + "Omistajan asuntojen lukumäärä", + "Omistajan henkilö- tai Y-tunnus", + "Yhtiön nimi", + "Yhtiön valmistumispäivä", + "Kalleusalue", + ), ] @@ -1438,10 +1447,12 @@ def test__api__multiple_ownerships_report__single_owner(api_client: HitasAPIClie ownership_1: Ownership = OwnershipFactory.create( owner=owner, sale__apartment__building__real_estate__housing_company__postal_code__value="00001", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) ownership_2: Ownership = OwnershipFactory.create( owner=owner, sale__apartment__building__real_estate__housing_company__postal_code__value="00002", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_II, ) url = reverse("hitas:multiple-ownerships-report-list") @@ -1451,18 +1462,39 @@ def test__api__multiple_ownerships_report__single_owner(api_client: HitasAPIClie worksheet: Worksheet = workbook.worksheets[0] assert list(worksheet.values) == [ - ("Omistajan nimi", "Asunnon osoite", "Postinumero", "Omistajan asuntojen lukumäärä"), + ( + "Omistajan nimi", + "Asunnon osoite", + "Postinumero", + "Omistajan asuntojen lukumäärä", + "Omistajan henkilö- tai Y-tunnus", + "Yhtiön nimi", + "Yhtiön valmistumispäivä", + "Kalleusalue", + ), ( Owner.OBFUSCATED_OWNER_NAME if non_disclosure else ownership_1.owner.name, ownership_1.apartment.address, ownership_1.apartment.postal_code.value, 2, + None if non_disclosure else ownership_1.owner.identifier, + ownership_1.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_1.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_1.apartment.postal_code.cost_area, ), ( Owner.OBFUSCATED_OWNER_NAME if non_disclosure else ownership_2.owner.name, ownership_2.apartment.address, ownership_2.apartment.postal_code.value, 2, + None if non_disclosure else ownership_2.owner.identifier, + ownership_2.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_2.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_2.apartment.postal_code.cost_area, ), ] @@ -1473,24 +1505,29 @@ def test__api__multiple_ownerships_report__multiple_owners(api_client: HitasAPIC ownership_1: Ownership = OwnershipFactory.create( owner=owner_1, sale__apartment__building__real_estate__housing_company__postal_code__value="00001", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) ownership_2: Ownership = OwnershipFactory.create( owner=owner_1, sale__apartment__building__real_estate__housing_company__postal_code__value="00002", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) owner_2: Owner = OwnerFactory.create(name="Owner 2", non_disclosure=True) ownership_3: Ownership = OwnershipFactory.create( owner=owner_2, sale__apartment__building__real_estate__housing_company__postal_code__value="00001", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) ownership_4: Ownership = OwnershipFactory.create( owner=owner_2, sale__apartment__building__real_estate__housing_company__postal_code__value="00002", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) ownership_5: Ownership = OwnershipFactory.create( owner=owner_2, sale__apartment__building__real_estate__housing_company__postal_code__value="00003", + sale__apartment__building__real_estate__housing_company__hitas_type=HitasType.NEW_HITAS_I, ) url = reverse("hitas:multiple-ownerships-report-list") @@ -1500,12 +1537,76 @@ def test__api__multiple_ownerships_report__multiple_owners(api_client: HitasAPIC worksheet: Worksheet = workbook.worksheets[0] assert list(worksheet.values) == [ - ("Omistajan nimi", "Asunnon osoite", "Postinumero", "Omistajan asuntojen lukumäärä"), - (ownership_1.owner.name, ownership_1.apartment.address, ownership_1.apartment.postal_code.value, 2), - (ownership_2.owner.name, ownership_2.apartment.address, ownership_2.apartment.postal_code.value, 2), - (Owner.OBFUSCATED_OWNER_NAME, ownership_3.apartment.address, ownership_3.apartment.postal_code.value, 3), - (Owner.OBFUSCATED_OWNER_NAME, ownership_4.apartment.address, ownership_4.apartment.postal_code.value, 3), - (Owner.OBFUSCATED_OWNER_NAME, ownership_5.apartment.address, ownership_5.apartment.postal_code.value, 3), + ( + "Omistajan nimi", + "Asunnon osoite", + "Postinumero", + "Omistajan asuntojen lukumäärä", + "Omistajan henkilö- tai Y-tunnus", + "Yhtiön nimi", + "Yhtiön valmistumispäivä", + "Kalleusalue", + ), + ( + ownership_1.owner.name, + ownership_1.apartment.address, + ownership_1.apartment.postal_code.value, + 2, + None if ownership_1.owner.non_disclosure else ownership_1.owner.identifier, + ownership_1.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_1.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_1.apartment.postal_code.cost_area, + ), + ( + ownership_2.owner.name, + ownership_2.apartment.address, + ownership_2.apartment.postal_code.value, + 2, + None if ownership_2.owner.non_disclosure else ownership_2.owner.identifier, + ownership_2.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_2.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_2.apartment.postal_code.cost_area, + ), + ( + Owner.OBFUSCATED_OWNER_NAME, + ownership_3.apartment.address, + ownership_3.apartment.postal_code.value, + 3, + None if ownership_3.owner.non_disclosure else ownership_3.owner.identifier, + ownership_3.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_3.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_3.apartment.postal_code.cost_area, + ), + ( + Owner.OBFUSCATED_OWNER_NAME, + ownership_4.apartment.address, + ownership_4.apartment.postal_code.value, + 3, + None if ownership_4.owner.non_disclosure else ownership_4.owner.identifier, + ownership_4.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_4.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_4.apartment.postal_code.cost_area, + ), + ( + Owner.OBFUSCATED_OWNER_NAME, + ownership_5.apartment.address, + ownership_5.apartment.postal_code.value, + 3, + None if ownership_5.owner.non_disclosure else ownership_5.owner.identifier, + ownership_5.apartment.building.real_estate.housing_company.display_name, + datetime.datetime.combine( + ownership_5.apartment.building.real_estate.housing_company.completion_date, datetime.datetime.min.time() + ), + ownership_5.apartment.postal_code.cost_area, + ), ]