From 33fd3e75c788e2504a9831b56f9532ffbed5256d Mon Sep 17 00:00:00 2001 From: "Donald F. Coffin" Date: Fri, 9 Jan 2026 15:09:41 -0500 Subject: [PATCH] refactor: Phase 7 - ServiceDeliveryPoint ESPI 4.0 schema compliance Per ESPI 4.0 specification, ServiceDeliveryPoint extends Object (not IdentifiedObject), so it has NO Atom metadata fields. This phase aligns the DTO, mapper, and repository with the XSD definition. Changes: - ServiceDeliveryPointDto: Remove id/uuid fields (Object type has no mRID) - ServiceDeliveryPointDto: Update propOrder to match XSD sequence (name, tariffProfile, customerAgreement, tariffRiderRefs) - ServiceDeliveryPointMapper: Remove id/uuid mappings, add explicit XSD element mappings - ServiceDeliveryPointMapper: Remove updateEntity method (read-only operations) - ServiceDeliveryPointRepository: Keep only indexed query (findAllIds) - ServiceDeliveryPointRepositoryTest: Remove tests for deleted custom queries All 536 tests pass. Entity already matches XSD structure correctly. Co-Authored-By: Claude Sonnet 4.5 --- .../dto/usage/ServiceDeliveryPointDto.java | 60 ++------- .../usage/ServiceDeliveryPointMapper.java | 26 ++-- .../usage/ServiceDeliveryPointRepository.java | 26 ---- .../ServiceDeliveryPointRepositoryTest.java | 121 ------------------ 4 files changed, 22 insertions(+), 211 deletions(-) diff --git a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/ServiceDeliveryPointDto.java b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/ServiceDeliveryPointDto.java index b4a98cc7..0fb10976 100644 --- a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/ServiceDeliveryPointDto.java +++ b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/ServiceDeliveryPointDto.java @@ -34,40 +34,18 @@ @XmlRootElement(name = "ServiceDeliveryPoint", namespace = "http://naesb.org/espi") @XmlAccessorType(XmlAccessType.PROPERTY) @XmlType(name = "ServiceDeliveryPoint", namespace = "http://naesb.org/espi", propOrder = { - "description", "name", "tariffProfile", "customerAgreement", "tariffRiderRefs" + "name", "tariffProfile", "customerAgreement", "tariffRiderRefs" }) public record ServiceDeliveryPointDto( - - Long id, - String uuid, - String description, + String name, String tariffProfile, String customerAgreement, TariffRiderRefsDto tariffRiderRefs ) { - - @XmlTransient - public Long getId() { - return id; - } - - @XmlAttribute(name = "mRID") - public String getUuid() { - return uuid; - } - - /** - * Human-readable description of the service delivery point. - * Typically describes the location or purpose of the delivery point. - */ - @XmlElement(name = "description") - public String getDescription() { - return description; - } - + /** - * The name is any free human readable and possibly non unique text + * The name is any free human readable and possibly non unique text * naming the service delivery point object. */ @XmlElement(name = "name") @@ -106,35 +84,27 @@ public TariffRiderRefsDto getTariffRiderRefs() { * Default constructor for JAXB. */ public ServiceDeliveryPointDto() { - this(null, null, null, null, null, null, null); + this(null, null, null, null); } - + /** * Minimal constructor for basic service delivery point data. */ - public ServiceDeliveryPointDto(String uuid, String name) { - this(null, uuid, null, name, null, null, null); + public ServiceDeliveryPointDto(String name) { + this(name, null, null, null); } - - /** - * Constructor with full service delivery point information. - */ - public ServiceDeliveryPointDto(String uuid, String name, String tariffProfile, - String customerAgreement, TariffRiderRefsDto tariffRiderRefs) { - this(null, uuid, null, name, tariffProfile, customerAgreement, tariffRiderRefs); - } - + /** * Gets a display name for this service delivery point. * Uses the name if available, otherwise creates a default display name. - * + * * @return display name string */ public String getDisplayName() { if (name != null && !name.trim().isEmpty()) { return name.trim(); } - return "Service Delivery Point " + (uuid != null ? uuid : "Unknown"); + return "Service Delivery Point (Unknown)"; } /** @@ -196,17 +166,13 @@ public boolean isValid() { /** * Creates a residential service delivery point with common settings. - * - * @param uuid unique identifier + * * @param name display name * @param customerAgreement customer agreement reference * @return ServiceDeliveryPoint with residential configuration */ - public static ServiceDeliveryPointDto createResidential(String uuid, String name, String customerAgreement) { + public static ServiceDeliveryPointDto createResidential(String name, String customerAgreement) { return new ServiceDeliveryPointDto( - null, - uuid, - "Residential electric service delivery point", name, "RESIDENTIAL_TOU", customerAgreement, diff --git a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/ServiceDeliveryPointMapper.java b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/ServiceDeliveryPointMapper.java index 9d2e8e3b..da613400 100644 --- a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/ServiceDeliveryPointMapper.java +++ b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/ServiceDeliveryPointMapper.java @@ -23,7 +23,6 @@ import org.greenbuttonalliance.espi.common.dto.usage.ServiceDeliveryPointDto; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.MappingTarget; /** * MapStruct mapper for converting between ServiceDeliveryPointEntity and ServiceDeliveryPointDto. @@ -39,15 +38,15 @@ public interface ServiceDeliveryPointMapper { /** * Converts a ServiceDeliveryPointEntity to a ServiceDeliveryPointDto. - * Maps service delivery point attributes per ESPI 4.0 XSD. + * Maps service delivery point attributes per ESPI 4.0 XSD element sequence. * * @param entity the service delivery point entity * @return the service delivery point DTO */ - @Mapping(target = "id", ignore = true) - @Mapping(target = "uuid", ignore = true) // No mRID in entity or XSD - @Mapping(target = "description", ignore = true) // Not in XSD for ServiceDeliveryPoint - @Mapping(target = "tariffRiderRefs", ignore = true) // Relationship handled separately + @Mapping(target = "name", source = "name") + @Mapping(target = "tariffProfile", source = "tariffProfile") + @Mapping(target = "customerAgreement", source = "customerAgreement") + @Mapping(target = "tariffRiderRefs", ignore = true) // XML-only field, not persisted in entity ServiceDeliveryPointDto toDto(ServiceDeliveryPointEntity entity); /** @@ -57,16 +56,9 @@ public interface ServiceDeliveryPointMapper { * @param dto the service delivery point DTO * @return the service delivery point entity */ - @Mapping(target = "id", ignore = true) + @Mapping(target = "id", ignore = true) // Auto-generated primary key + @Mapping(target = "name", source = "name") + @Mapping(target = "tariffProfile", source = "tariffProfile") + @Mapping(target = "customerAgreement", source = "customerAgreement") ServiceDeliveryPointEntity toEntity(ServiceDeliveryPointDto dto); - - /** - * Updates an existing ServiceDeliveryPointEntity with data from a ServiceDeliveryPointDto. - * Useful for merge operations where entity values need to be updated. - * - * @param dto the source DTO - * @param entity the target entity to update - */ - @Mapping(target = "id", ignore = true) - void updateEntity(ServiceDeliveryPointDto dto, @MappingTarget ServiceDeliveryPointEntity entity); } \ No newline at end of file diff --git a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepository.java b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepository.java index 65c66091..83e41a2d 100644 --- a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepository.java +++ b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepository.java @@ -21,41 +21,15 @@ import org.greenbuttonalliance.espi.common.domain.usage.ServiceDeliveryPointEntity; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; import java.util.List; @Repository public interface ServiceDeliveryPointRepository extends JpaRepository { - // JpaRepository provides: save(), findById(), findAll(), deleteById(), etc. - - @Modifying - @Transactional - @Query("DELETE FROM ServiceDeliveryPointEntity s WHERE s.id = :id") - void deleteById(@Param("id") Long id); - @Query("SELECT s.id FROM ServiceDeliveryPointEntity s") List findAllIds(); - @Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.name = :name") - List findByName(@Param("name") String name); - - @Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.tariffProfile = :tariffProfile") - List findByTariffProfile(@Param("tariffProfile") String tariffProfile); - - @Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.customerAgreement = :customerAgreement") - List findByCustomerAgreement(@Param("customerAgreement") String customerAgreement); - - @Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE LOWER(s.name) LIKE LOWER(CONCAT('%', :searchText, '%'))") - List findByNameContaining(@Param("searchText") String searchText); - - // Additional utility methods - @Query("SELECT COUNT(s) FROM ServiceDeliveryPointEntity s WHERE s.tariffProfile = :tariffProfile") - Long countByTariffProfile(@Param("tariffProfile") String tariffProfile); - } \ No newline at end of file diff --git a/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepositoryTest.java b/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepositoryTest.java index a9ae5af2..b17e813a 100644 --- a/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepositoryTest.java +++ b/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/ServiceDeliveryPointRepositoryTest.java @@ -172,127 +172,6 @@ void shouldCountServiceDeliveryPointsCorrectly() { @DisplayName("Custom Query Methods") class CustomQueryMethodsTest { - @Test - @DisplayName("Should find service delivery points by name") - void shouldFindServiceDeliveryPointsByName() { - // Arrange - ServiceDeliveryPointEntity sdp1 = createValidServiceDeliveryPoint(); - sdp1.setName("Unique Location Name"); - ServiceDeliveryPointEntity sdp2 = createValidServiceDeliveryPoint(); - sdp2.setName("Unique Location Name"); // Same name - ServiceDeliveryPointEntity sdp3 = createValidServiceDeliveryPoint(); - sdp3.setName("Different Location Name"); - - persistAndFlush(sdp1); - persistAndFlush(sdp2); - persistAndFlush(sdp3); - - // Act - List sdps = serviceDeliveryPointRepository.findByName("Unique Location Name"); - - // Assert - assertThat(sdps).hasSize(2); - assertThat(sdps).extracting(ServiceDeliveryPointEntity::getName) - .allMatch(name -> name.equals("Unique Location Name")); - } - - @Test - @DisplayName("Should find service delivery points by tariff profile") - void shouldFindServiceDeliveryPointsByTariffProfile() { - // Arrange - ServiceDeliveryPointEntity sdp1 = createValidServiceDeliveryPoint(); - sdp1.setTariffProfile("RESIDENTIAL-STANDARD"); - ServiceDeliveryPointEntity sdp2 = createValidServiceDeliveryPoint(); - sdp2.setTariffProfile("RESIDENTIAL-STANDARD"); // Same tariff - ServiceDeliveryPointEntity sdp3 = createValidServiceDeliveryPoint(); - sdp3.setTariffProfile("COMMERCIAL-BASIC"); - - persistAndFlush(sdp1); - persistAndFlush(sdp2); - persistAndFlush(sdp3); - - // Act - List sdps = serviceDeliveryPointRepository.findByTariffProfile("RESIDENTIAL-STANDARD"); - - // Assert - assertThat(sdps).hasSize(2); - assertThat(sdps).extracting(ServiceDeliveryPointEntity::getTariffProfile) - .allMatch(tariff -> tariff.equals("RESIDENTIAL-STANDARD")); - } - - @Test - @DisplayName("Should find service delivery points by customer agreement") - void shouldFindServiceDeliveryPointsByCustomerAgreement() { - // Arrange - ServiceDeliveryPointEntity sdp1 = createValidServiceDeliveryPoint(); - sdp1.setCustomerAgreement("AGREEMENT-12345"); - ServiceDeliveryPointEntity sdp2 = createValidServiceDeliveryPoint(); - sdp2.setCustomerAgreement("AGREEMENT-12345"); // Same agreement - ServiceDeliveryPointEntity sdp3 = createValidServiceDeliveryPoint(); - sdp3.setCustomerAgreement("AGREEMENT-67890"); - - persistAndFlush(sdp1); - persistAndFlush(sdp2); - persistAndFlush(sdp3); - - // Act - List sdps = serviceDeliveryPointRepository.findByCustomerAgreement("AGREEMENT-12345"); - - // Assert - assertThat(sdps).hasSize(2); - assertThat(sdps).extracting(ServiceDeliveryPointEntity::getCustomerAgreement) - .allMatch(agreement -> agreement.equals("AGREEMENT-12345")); - } - - @Test - @DisplayName("Should find service delivery points by name containing text") - void shouldFindServiceDeliveryPointsByNameContaining() { - // Arrange - ServiceDeliveryPointEntity sdp1 = createValidServiceDeliveryPoint(); - sdp1.setName("Main Street Office Building"); - ServiceDeliveryPointEntity sdp2 = createValidServiceDeliveryPoint(); - sdp2.setName("Oak Street Residential"); - ServiceDeliveryPointEntity sdp3 = createValidServiceDeliveryPoint(); - sdp3.setName("Pine Avenue Commercial"); - - persistAndFlush(sdp1); - persistAndFlush(sdp2); - persistAndFlush(sdp3); - - // Act - List sdps = serviceDeliveryPointRepository.findByNameContaining("Street"); - - // Assert - assertThat(sdps).hasSize(2); - assertThat(sdps).extracting(ServiceDeliveryPointEntity::getName) - .allMatch(name -> name.toLowerCase().contains("street")); - } - - @Test - @DisplayName("Should count service delivery points by tariff profile") - void shouldCountServiceDeliveryPointsByTariffProfile() { - // Arrange - ServiceDeliveryPointEntity sdp1 = createValidServiceDeliveryPoint(); - sdp1.setTariffProfile("COMMERCIAL-PREMIUM"); - ServiceDeliveryPointEntity sdp2 = createValidServiceDeliveryPoint(); - sdp2.setTariffProfile("COMMERCIAL-PREMIUM"); - ServiceDeliveryPointEntity sdp3 = createValidServiceDeliveryPoint(); - sdp3.setTariffProfile("COMMERCIAL-PREMIUM"); - ServiceDeliveryPointEntity sdp4 = createValidServiceDeliveryPoint(); - sdp4.setTariffProfile("RESIDENTIAL-BASIC"); - - persistAndFlush(sdp1); - persistAndFlush(sdp2); - persistAndFlush(sdp3); - persistAndFlush(sdp4); - - // Act - Long count = serviceDeliveryPointRepository.countByTariffProfile("COMMERCIAL-PREMIUM"); - - // Assert - assertThat(count).isEqualTo(3L); - } - @Test @DisplayName("Should find all IDs") void shouldFindAllIds() {