diff --git a/README.md b/README.md index e701a6a..7d9e858 100644 --- a/README.md +++ b/README.md @@ -202,14 +202,31 @@ EnergyLabelCollection { addition: null, street: "Schiphol Boulevard", city: "Schiphol", + registrationDate: DateTime("2022-08-30"), inspectionDate: DateTime("2022-08-02"), validUntilDate: DateTime("2032-08-02"), constructionType: "utiliteitsbouw", buildingType: null, energyLabel: "A+++", - maxEnergyDemand: 98.4, - maxFossilEnergyDemand: 55.48, - minRenewableShare: 55.3 + calculationType: "NTA 8800:2022 (basisopname utiliteitsbouw)", + inspectionType: "basis", + status: "bestaand", + constructionYear: 2019, + usageAreaThermalZone: 5648.39, + compactness: 1.16, + energyDemand: 98.4, + energyDemandRequirement: null, + primaryFossilEnergy: 55.48, + primaryFossilEnergyRequirement: null, + primaryFossilEnergyEmg: null, + renewableShare: 55.3, + renewableShareRequirement: null, + renewableShareEmg: null, + calculatedEnergyConsumption: 55.48, + heatDemand: 55.02, + calculatedCo2Emission: 13.01, + temperatureExcess: 0, + temperatureExcessRequirement: null } ] } diff --git a/src/DTO/EnergyLabel.php b/src/DTO/EnergyLabel.php index 056d539..bdb3ed3 100644 --- a/src/DTO/EnergyLabel.php +++ b/src/DTO/EnergyLabel.php @@ -12,13 +12,30 @@ public function __construct( public readonly ?string $addition, public readonly string $street, public readonly string $city, + public readonly DateTime $registrationDate, public readonly DateTime $inspectionDate, public readonly DateTime $validUntilDate, public readonly string $constructionType, public readonly ?string $buildingType, - public readonly string $energyLabel, - public readonly ?float $maxEnergyDemand, - public readonly ?float $maxFossilEnergyDemand, - public readonly ?float $minRenewableShare, + public readonly ?string $energyLabel, + public readonly string $calculationType, + public readonly ?string $inspectionType, + public readonly ?string $status, + public readonly int $constructionYear, + public readonly ?float $usageAreaThermalZone, + public readonly ?float $compactness, + public readonly ?float $energyDemand, + public readonly ?float $energyDemandRequirement, + public readonly ?float $primaryFossilEnergy, + public readonly ?float $primaryFossilEnergyRequirement, + public readonly ?float $primaryFossilEnergyEmg, + public readonly ?float $renewableShare, + public readonly ?float $renewableShareRequirement, + public readonly ?float $renewableShareEmg, + public readonly ?float $calculatedEnergyConsumption, + public readonly ?float $heatDemand, + public readonly ?float $calculatedCo2Emission, + public readonly ?float $temperatureExcess, + public readonly ?float $temperatureExcessRequirement, ) {} } diff --git a/src/Factories/EnergyLabelCollectionFactory.php b/src/Factories/EnergyLabelCollectionFactory.php index 376479b..498f9a0 100644 --- a/src/Factories/EnergyLabelCollectionFactory.php +++ b/src/Factories/EnergyLabelCollectionFactory.php @@ -15,14 +15,31 @@ class EnergyLabelCollectionFactory * street: string, * city: string, * energy_labels: array * } * } $response diff --git a/src/Factories/EnergyLabelFactory.php b/src/Factories/EnergyLabelFactory.php index e8e612e..67f7758 100644 --- a/src/Factories/EnergyLabelFactory.php +++ b/src/Factories/EnergyLabelFactory.php @@ -14,14 +14,31 @@ class EnergyLabelFactory * addition?: string|null, * street: string, * city: string, + * registration_date: string, * inspection_date: string, * valid_until_date: string, + * status: string|null, * construction_type: string, * building_type: string|null, - * energy_label: string, - * max_energy_demand: float, - * max_fossil_energy_demand: float, - * min_renewable_share: float, + * energy_label: string|null, + * calculation_type: string, + * inspection_type: string|null, + * construction_year: int, + * thermal_zone_area?: float|null, + * compactness?: float|null, + * energy_demand?: float|null, + * energy_demand_requirement?: float|null, + * primary_fossil_energy?: float|null, + * primary_fossil_energy_requirement?: float|null, + * primary_fossil_energy_emg?: float|null, + * renewable_energy_share?: float|null, + * renewable_energy_share_requirement?: float|null, + * renewable_energy_share_emg?: float|null, + * calculated_energy_consumption?: float|null, + * heat_demand?: float|null, + * calculated_co2_emission?: float|null, + * temperature_excess?: float|null, + * temperature_excess_requirement?: float|null, * } $attributes */ public static function make(array $attributes): EnergyLabel @@ -32,14 +49,31 @@ public static function make(array $attributes): EnergyLabel addition: $attributes['addition'] ?? null, street: $attributes['street'], city: $attributes['city'], - inspectionDate: new DateTime($attributes['inspection_date']), - validUntilDate: new DateTime($attributes['valid_until_date']), + registrationDate: DateTime::createFromFormat('d-m-Y', $attributes['registration_date']), // @phpstan-ignore argument.type + inspectionDate: DateTime::createFromFormat('d-m-Y', $attributes['inspection_date']), // @phpstan-ignore argument.type + validUntilDate: DateTime::createFromFormat('d-m-Y', $attributes['valid_until_date']), // @phpstan-ignore argument.type constructionType: $attributes['construction_type'], - buildingType: $attributes['building_type'], - energyLabel: $attributes['energy_label'], - maxEnergyDemand: $attributes['max_energy_demand'], - maxFossilEnergyDemand: $attributes['max_fossil_energy_demand'], - minRenewableShare: $attributes['min_renewable_share'], + buildingType: $attributes['building_type'] ?? null, + energyLabel: $attributes['energy_label'] ?? null, + calculationType: $attributes['calculation_type'], + inspectionType: $attributes['inspection_type'] ?? null, + status: $attributes['status'] ?? null, + constructionYear: $attributes['construction_year'], + usageAreaThermalZone: $attributes['thermal_zone_area'] ?? null, + compactness: $attributes['compactness'] ?? null, + energyDemand: $attributes['energy_demand'] ?? null, + energyDemandRequirement: $attributes['energy_demand_requirement'] ?? null, + primaryFossilEnergy: $attributes['primary_fossil_energy'] ?? null, + primaryFossilEnergyRequirement: $attributes['primary_fossil_energy_requirement'] ?? null, + primaryFossilEnergyEmg: $attributes['primary_fossil_energy_emg'] ?? null, + renewableShare: $attributes['renewable_energy_share'] ?? null, + renewableShareRequirement: $attributes['renewable_energy_share_requirement'] ?? null, + renewableShareEmg: $attributes['renewable_energy_share_emg'] ?? null, + calculatedEnergyConsumption: $attributes['calculated_energy_consumption'] ?? null, + heatDemand: $attributes['heat_demand'] ?? null, + calculatedCo2Emission: $attributes['calculated_co2_emission'] ?? null, + temperatureExcess: $attributes['temperature_excess'] ?? null, + temperatureExcessRequirement: $attributes['temperature_excess_requirement'] ?? null, ); } } diff --git a/src/Resources/EnergyLabelResource.php b/src/Resources/EnergyLabelResource.php index 6e0a4df..61121fe 100644 --- a/src/Resources/EnergyLabelResource.php +++ b/src/Resources/EnergyLabelResource.php @@ -15,7 +15,7 @@ public function get( // @phpstan-ignore-next-line return EnergyLabelCollectionFactory::make($this->request( method: 'GET', - path: 'v1/energy-label', + path: 'v2/energy-label', query: [ 'postcode' => $postcode, 'number' => $number, diff --git a/tests/Resources/AddressResourceTest.php b/tests/Resources/AddressResourceTest.php index 138c413..4a116f8 100644 --- a/tests/Resources/AddressResourceTest.php +++ b/tests/Resources/AddressResourceTest.php @@ -19,6 +19,25 @@ public function test_get_single_result(): void $this->assertInstanceOf(AddressCollection::class, $result); $this->assertCount(1, $result); + + $address = $result->all()[0]; + $this->assertSame('1118BN', $address->postcode); + $this->assertSame(800, $address->number); + $this->assertSame('', $address->addition); + $this->assertSame('Schiphol Boulevard', $address->street); + $this->assertSame('Schiphol', $address->city); + $this->assertSame('Haarlemmermeer', $address->municipality); + $this->assertSame('Noord-Holland', $address->province); + $this->assertSame('Nederland', $address->country); + $this->assertSame(52.30528553688755, $address->coordinates->latitude); + $this->assertSame(4.750645160863609, $address->coordinates->longitude); + $this->assertNull($address->neighborhood); + $this->assertNull($address->district); + $this->assertNull($address->function); + $this->assertNull($address->location_status); + $this->assertNull($address->property_status); + $this->assertNull($address->surface_area); + $this->assertNull($address->construction_year); } public function test_get_multiple_results(): void @@ -33,5 +52,19 @@ public function test_get_multiple_results(): void $this->assertInstanceOf(AddressCollection::class, $result); $this->assertCount(4, $result); + + $additions = array_map(fn($address) => $address->addition, $result->all()); + $this->assertSame(['A', 'B', 'C', 'D'], $additions); + + $first = $result->all()[0]; + $this->assertSame('1015CN', $first->postcode); + $this->assertSame(10, $first->number); + $this->assertSame('Keizersgracht', $first->street); + $this->assertSame('Amsterdam', $first->city); + $this->assertSame('Amsterdam', $first->municipality); + $this->assertSame('Noord-Holland', $first->province); + $this->assertSame('Nederland', $first->country); + $this->assertSame(52.379401496779124, $first->coordinates->latitude); + $this->assertSame(4.889216673725493, $first->coordinates->longitude); } } diff --git a/tests/Resources/EnergyLabelResourceTest.php b/tests/Resources/EnergyLabelResourceTest.php index 380d347..1eb730f 100644 --- a/tests/Resources/EnergyLabelResourceTest.php +++ b/tests/Resources/EnergyLabelResourceTest.php @@ -12,13 +12,45 @@ public function test_get_single_result(): void $result = $this->client ->energyLabels() ->get( - postcode: '1118BN', - number: 800, + postcode: '5465SM', + number: 7, addition: null, ); $this->assertInstanceOf(EnergyLabelCollection::class, $result); $this->assertCount(1, $result); + + $label = $result->all()[0]; + $this->assertSame('5465SM', $label->postcode); + $this->assertSame(7, $label->number); + $this->assertNull($label->addition); + $this->assertSame('Klaverhoeve', $label->street); + $this->assertSame('Veghel', $label->city); + $this->assertSame('31-08-2026', $label->registrationDate->format('d-m-Y')); + $this->assertSame('31-08-2026', $label->inspectionDate->format('d-m-Y')); + $this->assertSame('31-08-2036', $label->validUntilDate->format('d-m-Y')); + $this->assertSame('woningbouw', $label->constructionType); + $this->assertSame('twee-onder-één-kap', $label->buildingType); + $this->assertSame('A++++', $label->energyLabel); + $this->assertSame('NTA 8800:2025 (detailopname woningbouw)', $label->calculationType); + $this->assertSame('detail', $label->inspectionType); + $this->assertSame('oplevering', $label->status); + $this->assertSame(2025, $label->constructionYear); + $this->assertSame(130.89, $label->usageAreaThermalZone); + $this->assertSame(2.31, $label->compactness); + $this->assertSame(76.54, $label->energyDemand); + $this->assertSame(79.38, $label->energyDemandRequirement); + $this->assertSame(-7.02, $label->primaryFossilEnergy); + $this->assertSame(30.0, $label->primaryFossilEnergyRequirement); + $this->assertNull($label->primaryFossilEnergyEmg); + $this->assertSame(107.7, $label->renewableShare); + $this->assertSame(50.0, $label->renewableShareRequirement); + $this->assertNull($label->renewableShareEmg); + $this->assertSame(-7.03, $label->calculatedEnergyConsumption); + $this->assertSame(47.59, $label->heatDemand); + $this->assertSame(-1.3, $label->calculatedCo2Emission); + $this->assertSame(0.0, $label->temperatureExcess); + $this->assertSame(1.2, $label->temperatureExcessRequirement); } public function test_get_multiple_results(): void @@ -26,12 +58,42 @@ public function test_get_multiple_results(): void $result = $this->client ->energyLabels() ->get( - postcode: '1015CN', - number: 10, - addition: 'A', + postcode: '7316ER', + number: 73, + addition: null, ); $this->assertInstanceOf(EnergyLabelCollection::class, $result); - $this->assertCount(2, $result); + $this->assertCount(3, $result); + + $energyLabels = array_map(fn($label) => $label->energyLabel, $result->all()); + $this->assertSame(['C', 'E', 'G'], $energyLabels); + + $first = $result->all()[0]; + $this->assertSame('7316ER', $first->postcode); + $this->assertSame(73, $first->number); + $this->assertNull($first->addition); + $this->assertSame('Laan van Kerschoten', $first->street); + $this->assertSame('Apeldoorn', $first->city); + $this->assertSame('09-10-2025', $first->registrationDate->format('d-m-Y')); + $this->assertSame('07-10-2025', $first->inspectionDate->format('d-m-Y')); + $this->assertSame('07-10-2035', $first->validUntilDate->format('d-m-Y')); + $this->assertSame('woningbouw', $first->constructionType); + $this->assertSame('twee-onder-één-kap', $first->buildingType); + $this->assertSame('basis', $first->inspectionType); + $this->assertSame('bestaand', $first->status); + $this->assertSame(1958, $first->constructionYear); + $this->assertSame(177.57, $first->energyDemand); + $this->assertSame(218.86, $first->primaryFossilEnergy); + $this->assertSame(1.24, $first->temperatureExcess); + $this->assertNull($first->temperatureExcessRequirement); + + $third = $result->all()[2]; + $this->assertSame('utiliteitsbouw', $third->constructionType); + $this->assertNull($third->buildingType); + $this->assertSame('G', $third->energyLabel); + $this->assertSame(580.39, $third->primaryFossilEnergyEmg); + $this->assertSame(3.2, $third->renewableShare); + $this->assertSame(3.2, $third->renewableShareEmg); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 54ba6c3..0d8fcd6 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -42,8 +42,8 @@ protected function mockNederlandPostcodeClient(): void $mockEnergyLabels->method('get') ->willReturnCallback(function (string $postcode, int $number, ?string $addition) { return match (true) { - $postcode === '1118BN' && $number === 800 => $this->singleEnergyLabelsResponse(), - $postcode === '1015CN' && $number === 10 => $this->multipleEnergyLabelsResponse(), + $postcode === '5465SM' && $number === 7 => $this->singleEnergyLabelsResponse(), + $postcode === '7316ER' && $number === 73 => $this->multipleEnergyLabelsResponse(), default => new EnergyLabelCollection([]), }; }); @@ -57,7 +57,7 @@ protected function mockNederlandPostcodeClient(): void public EnergyLabelResource $energyLabelsResource; public QuotaResource $quotaResource; - public function __construct($addresses, $energyLabels, $quota) + public function __construct(AddressesResource $addresses, EnergyLabelResource $energyLabels, QuotaResource $quota) { $this->addressesResource = $addresses; $this->energyLabelsResource = $energyLabels; @@ -202,19 +202,36 @@ private function singleEnergyLabelsResponse(): EnergyLabelCollection { return new EnergyLabelCollection([ new EnergyLabel( - postcode: '1118BN', - number: 800, - addition: '', - street: 'Schiphol Boulevard', - city: 'Schiphol', - inspectionDate: new DateTime('2026-01-15'), - validUntilDate: new DateTime('2036-01-15'), - constructionType: 'utiliteitsbouw', - buildingType: null, - energyLabel: 'A+++', - maxEnergyDemand: 98.4, - maxFossilEnergyDemand: 55.48, - minRenewableShare: 55.3, + postcode: '5465SM', + number: 7, + addition: null, + street: 'Klaverhoeve', + city: 'Veghel', + registrationDate: DateTime::createFromFormat('d-m-Y', '31-08-2026'), + inspectionDate: DateTime::createFromFormat('d-m-Y', '31-08-2026'), + validUntilDate: DateTime::createFromFormat('d-m-Y', '31-08-2036'), + constructionType: 'woningbouw', + buildingType: 'twee-onder-één-kap', + energyLabel: 'A++++', + calculationType: 'NTA 8800:2025 (detailopname woningbouw)', + inspectionType: 'detail', + status: 'oplevering', + constructionYear: 2025, + usageAreaThermalZone: 130.89, + compactness: 2.31, + energyDemand: 76.54, + energyDemandRequirement: 79.38, + primaryFossilEnergy: -7.02, + primaryFossilEnergyRequirement: 30, + primaryFossilEnergyEmg: null, + renewableShare: 107.7, + renewableShareRequirement: 50, + renewableShareEmg: null, + calculatedEnergyConsumption: -7.03, + heatDemand: 47.59, + calculatedCo2Emission: -1.3, + temperatureExcess: 0, + temperatureExcessRequirement: 1.2, ), ]); } @@ -223,34 +240,100 @@ private function multipleEnergyLabelsResponse(): EnergyLabelCollection { return new EnergyLabelCollection([ new EnergyLabel( - postcode: '1015CN', - number: 10, - addition: 'A', - street: 'Keizersgracht', - city: 'Amsterdam', - inspectionDate: new DateTime('2026-01-05'), - validUntilDate: new DateTime('2036-01-05'), + postcode: '7316ER', + number: 73, + addition: null, + street: 'Laan van Kerschoten', + city: 'Apeldoorn', + registrationDate: DateTime::createFromFormat('d-m-Y', '09-10-2025'), + inspectionDate: DateTime::createFromFormat('d-m-Y', '07-10-2025'), + validUntilDate: DateTime::createFromFormat('d-m-Y', '07-10-2035'), constructionType: 'woningbouw', - buildingType: 'vrijstaande woning', - energyLabel: 'B', - maxEnergyDemand: 99.57, - maxFossilEnergyDemand: 150, - minRenewableShare: 33.5, + buildingType: 'twee-onder-één-kap', + energyLabel: 'C', + calculationType: 'NTA 8800:2024 (basisopname woningbouw)', + inspectionType: 'basis', + status: 'bestaand', + constructionYear: 1958, + usageAreaThermalZone: 138.51, + compactness: 2.13, + energyDemand: 177.57, + energyDemandRequirement: null, + primaryFossilEnergy: 218.86, + primaryFossilEnergyRequirement: null, + primaryFossilEnergyEmg: null, + renewableShare: 11, + renewableShareRequirement: null, + renewableShareEmg: null, + calculatedEnergyConsumption: 218.86, + heatDemand: 177.83, + calculatedCo2Emission: 38.68, + temperatureExcess: 1.24, + temperatureExcessRequirement: null, ), new EnergyLabel( - postcode: '1015CN', - number: 10, - addition: 'A', - street: 'Keizersgracht', - city: 'Amsterdam', - inspectionDate: new DateTime('2015-06-01'), - validUntilDate: new DateTime('2025-06-01'), + postcode: '7316ER', + number: 73, + addition: null, + street: 'Laan van Kerschoten', + city: 'Apeldoorn', + registrationDate: DateTime::createFromFormat('d-m-Y', '19-10-2021'), + inspectionDate: DateTime::createFromFormat('d-m-Y', '19-08-2021'), + validUntilDate: DateTime::createFromFormat('d-m-Y', '19-08-2031'), constructionType: 'woningbouw', buildingType: 'vrijstaande woning', + energyLabel: 'E', + calculationType: 'NTA 8800:2020 (basisopname woningbouw)', + inspectionType: 'basis', + status: 'bestaand', + constructionYear: 1958, + usageAreaThermalZone: 139.42, + compactness: 2.03, + energyDemand: 238.61, + energyDemandRequirement: null, + primaryFossilEnergy: 334.74, + primaryFossilEnergyRequirement: null, + primaryFossilEnergyEmg: 334.74, + renewableShare: 0, + renewableShareRequirement: null, + renewableShareEmg: 0, + calculatedEnergyConsumption: 334.55, + heatDemand: 237.55, + calculatedCo2Emission: 61.29, + temperatureExcess: 2, + temperatureExcessRequirement: null, + ), + new EnergyLabel( + postcode: '7316ER', + number: 73, + addition: null, + street: 'Laan van Kerschoten', + city: 'Apeldoorn', + registrationDate: DateTime::createFromFormat('d-m-Y', '19-10-2021'), + inspectionDate: DateTime::createFromFormat('d-m-Y', '19-08-2021'), + validUntilDate: DateTime::createFromFormat('d-m-Y', '19-08-2031'), + constructionType: 'utiliteitsbouw', + buildingType: null, energyLabel: 'G', - maxEnergyDemand: 177.57, - maxFossilEnergyDemand: 218.86, - minRenewableShare: 11, + calculationType: 'NTA 8800:2020 (basisopname utiliteitsbouw)', + inspectionType: 'basis', + status: 'bestaand', + constructionYear: 1958, + usageAreaThermalZone: 79.79, + compactness: 3.51, + energyDemand: 472, + energyDemandRequirement: null, + primaryFossilEnergy: 580.39, + primaryFossilEnergyRequirement: null, + primaryFossilEnergyEmg: 580.39, + renewableShare: 3.2, + renewableShareRequirement: null, + renewableShareEmg: 3.2, + calculatedEnergyConsumption: 596.67, + heatDemand: 452.11, + calculatedCo2Emission: 105.77, + temperatureExcess: 1.46, + temperatureExcessRequirement: null, ), ]); }