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 @@ -20,76 +20,58 @@
package org.greenbuttonalliance.espi.common.dto.usage;

import jakarta.xml.bind.annotation.*;
import java.time.OffsetDateTime;
import java.util.List;

/**
* IntervalBlock DTO record for JAXB XML marshalling/unmarshalling.
*
*
* Represents a time sequence of readings of the same ReadingType.
* Contains a date/time interval and a collection of interval readings.
* Supports Atom protocol XML wrapping.
*
* Field order strictly matches espi.xsd IntervalBlock element sequence.
*
* @see <a href="https://www.naesb.org/ESPI_Standards.asp">NAESB ESPI 4.0</a>
*/
@XmlRootElement(name = "IntervalBlock", namespace = "http://naesb.org/espi")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IntervalBlock", namespace = "http://naesb.org/espi", propOrder = {
"published", "updated", "relatedLinks", "selfLink", "upLink", "description", "interval", "intervalReadings"
"interval", "intervalReadings"
})
public record IntervalBlockDto(

@XmlTransient
Long id,

@XmlTransient
//@XmlAttribute(name = "mRID")
String uuid,

@XmlElement(name = "published")
OffsetDateTime published,

@XmlElement(name = "updated")
OffsetDateTime updated,

@XmlElement(name = "link")
@XmlElementWrapper(name = "relatedLinks")
List<String> relatedLinks,

@XmlElement(name = "selfLink")
String selfLink,

@XmlElement(name = "upLink")
String upLink,

@XmlElement(name = "description")
String description,


@XmlElement(name = "interval")
DateTimeIntervalDto interval,

@XmlElement(name = "IntervalReading")
// @XmlElementWrapper(name = "IntervalReadings")
List<IntervalReadingDto> intervalReadings
) {

/**
* Default constructor for JAXB.
*/
public IntervalBlockDto() {
this(null, null, null, null, null, null, null, null, null, null);
this(null, null, null, null);
}

/**
* Minimal constructor for basic interval block data.
*/
public IntervalBlockDto(String uuid, DateTimeIntervalDto interval) {
this(null, uuid, null, null, null, null, null, null, interval, null);
this(null, uuid, interval, null);
}

/**
* Constructor with interval and readings.
*/
public IntervalBlockDto(String uuid, DateTimeIntervalDto interval, List<IntervalReadingDto> intervalReadings) {
this(null, uuid, null, null, null, null, null, null, interval, intervalReadings);
this(null, uuid, interval, intervalReadings);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.greenbuttonalliance.espi.common.mapper.DateTimeMapper;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;

/**
* MapStruct mapper for converting between IntervalBlockEntity and IntervalBlockDto.
Expand All @@ -45,56 +44,33 @@ public interface IntervalBlockMapper {
/**
* Converts an IntervalBlockEntity to an IntervalBlockDto.
* Maps all related entities to their corresponding DTOs.
*
*
* @param entity the interval block entity
* @return the interval block DTO
*/
@Mapping(target = "id", ignore = true) // DTO id field not used
@Mapping(target = "id", ignore = true) // DTO id field not used (legacy field)
@Mapping(target = "uuid", source = "id", qualifiedByName = "uuidToString")
@Mapping(target = "published", source = "published", qualifiedByName = "localToOffset")
@Mapping(target = "updated", source = "updated", qualifiedByName = "localToOffset")
@Mapping(target = "relatedLinks", ignore = true) // Links handled separately
@Mapping(target = "selfLink", ignore = true)
@Mapping(target = "upLink", ignore = true)
@Mapping(target = "description", source = "description")
@Mapping(target = "interval", source = "interval")
@Mapping(target = "intervalReadings", source = "intervalReadings")
IntervalBlockDto toDto(IntervalBlockEntity entity);

/**
* Converts an IntervalBlockDto to an IntervalBlockEntity.
* Maps all related DTOs to their corresponding entities.
*
*
* @param dto the interval block DTO
* @return the interval block entity
*/
@Mapping(target = "id", source = "uuid", qualifiedByName = "stringToUuid")
@Mapping(target = "created", ignore = true)
@Mapping(target = "updated", ignore = true)
@Mapping(target = "published", source = "published", qualifiedByName = "offsetToLocal")
@Mapping(target = "published", ignore = true)
@Mapping(target = "upLink", ignore = true)
@Mapping(target = "selfLink", ignore = true)
@Mapping(target = "relatedLinks", ignore = true)
@Mapping(target = "description", source = "description")
@Mapping(target = "description", ignore = true)
@Mapping(target = "interval", source = "interval")
@Mapping(target = "intervalReadings", source = "intervalReadings")
@Mapping(target = "meterReading", ignore = true) // Relationships handled separately
IntervalBlockEntity toEntity(IntervalBlockDto dto);

/**
* Updates an existing IntervalBlockEntity with data from an IntervalBlockDto.
* Useful for merge operations where the entity ID should be preserved.
*
* @param dto the source DTO
* @param entity the target entity to update
*/
@Mapping(target = "id", ignore = true)
@Mapping(target = "created", ignore = true)
@Mapping(target = "updated", ignore = true)
@Mapping(target = "published", source = "published", qualifiedByName = "offsetToLocal")
@Mapping(target = "upLink", ignore = true)
@Mapping(target = "selfLink", ignore = true)
@Mapping(target = "relatedLinks", ignore = true)
@Mapping(target = "meterReading", ignore = true) // Relationships handled separately
void updateEntity(IntervalBlockDto dto, @MappingTarget IntervalBlockEntity entity);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,23 @@

import org.greenbuttonalliance.espi.common.domain.usage.IntervalBlockEntity;
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;
import java.util.Optional;
import java.util.UUID;

@Repository
public interface IntervalBlockRepository extends JpaRepository<IntervalBlockEntity, UUID> {

// JpaRepository provides: save(), findById(), findAll(), deleteById(), etc.

// findById is already provided by JpaRepository<IntervalBlockEntity, UUID>
// Optional<IntervalBlockEntity> findById(UUID id) is inherited

@Query("SELECT i.id FROM IntervalBlockEntity i")
List<UUID> findAllIds();

@Modifying
@Transactional
@Query("DELETE FROM IntervalBlockEntity i WHERE i.id = :id")
void deleteById(@Param("id") UUID id);

@Modifying
@Transactional
@Query("DELETE FROM IntervalBlockEntity i WHERE i.id = :uuid")
void deleteByUuid(@Param("uuid") UUID uuid);

// Custom method for createOrReplaceByUUID - should be implemented in service layer

@Query("SELECT i FROM IntervalBlockEntity i WHERE i.meterReading.id = :meterReadingId")
List<IntervalBlockEntity> findAllByMeterReadingId(@Param("meterReadingId") UUID meterReadingId);

@Query("SELECT i.id FROM IntervalBlockEntity i WHERE i.meterReading.usagePoint.id = :usagePointId")
List<UUID> findAllIdsByUsagePointId(@Param("usagePointId") UUID usagePointId);

@Query("SELECT DISTINCT i.id FROM UsagePointEntity u, MeterReadingEntity m, IntervalBlockEntity i WHERE u.retailCustomer.id = :o1Id AND m.usagePoint.id = :o2Id AND i.meterReading.id = :o3Id")
List<UUID> findAllIdsByXpath3(@Param("o1Id") UUID o1Id, @Param("o2Id") UUID o2Id, @Param("o3Id") UUID o3Id);

@Query("SELECT DISTINCT i.id FROM UsagePointEntity u, MeterReadingEntity m, IntervalBlockEntity i WHERE u.retailCustomer.id = :o1Id AND m.usagePoint.id = :o2Id AND i.meterReading.id = :o3Id AND i.id = :o4Id")
Optional<UUID> findIdByXpath(@Param("o1Id") UUID o1Id, @Param("o2Id") UUID o2Id, @Param("o3Id") UUID o3Id, @Param("o4Id") UUID o4Id);

@Query("SELECT i FROM IntervalBlockEntity i WHERE i.meterReading = :meterReading")
List<IntervalBlockEntity> findByMeterReadingEntity(@Param("meterReading") org.greenbuttonalliance.espi.common.domain.usage.MeterReadingEntity meterReading);

@Query("SELECT i FROM IntervalBlockEntity i WHERE i.selfLink.href = :uri")
Optional<IntervalBlockEntity> findByUri(@Param("uri") String uri);
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,15 @@ public void delete(IntervalBlockEntity intervalBlock) {

@Override
public List<IntervalBlockEntity> findAllByMeterReading(MeterReadingEntity meterReading) {
// TODO: Implement findAllByMeterReading query in repository
return intervalBlockRepository.findByMeterReadingEntity(meterReading);
return intervalBlockRepository.findAllByMeterReadingId(meterReading.getId());
}

@Override
public IntervalBlockEntity findByURI(String uri) {
// TODO: Implement findByURI query in repository
return intervalBlockRepository.findByUri(uri).orElse(null);
// Note: findByURI removed from repository (non-indexed query on self_link_href)
// URI-based lookup should use ID-based queries instead
log.warn("findByURI is deprecated - use findById with extracted UUID instead");
return null;
}

@Override
Expand Down
Loading
Loading