Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)";
}

/**
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);

/**
Expand All @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<ServiceDeliveryPointEntity, Long> {

// 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<Long> findAllIds();

@Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.name = :name")
List<ServiceDeliveryPointEntity> findByName(@Param("name") String name);

@Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.tariffProfile = :tariffProfile")
List<ServiceDeliveryPointEntity> findByTariffProfile(@Param("tariffProfile") String tariffProfile);

@Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE s.customerAgreement = :customerAgreement")
List<ServiceDeliveryPointEntity> findByCustomerAgreement(@Param("customerAgreement") String customerAgreement);

@Query("SELECT s FROM ServiceDeliveryPointEntity s WHERE LOWER(s.name) LIKE LOWER(CONCAT('%', :searchText, '%'))")
List<ServiceDeliveryPointEntity> 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);

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<ServiceDeliveryPointEntity> 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<ServiceDeliveryPointEntity> 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<ServiceDeliveryPointEntity> 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<ServiceDeliveryPointEntity> 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() {
Expand Down
Loading