FinancialDocumentRepository.java

package com.tdmconsult.ete.documents;

import com.tdmconsult.ete.configuration.CustomJwtAuthenticationToken;
import com.tdmconsult.ete.exceptions.DocumentNotFound;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface FinancialDocumentRepository extends JpaRepository<FinancialDocument, Long> {

    @Data
    @AllArgsConstructor
    public static class UploadSummaryDto {

        private String publicId;
        private LocalDateTime createdAt;
        private FinancialDocument.TypeOfDocument typeOfDocument;
        private LocalDate dateReceived;
        private String uploadBy;
        private FinancialDocument.State state;
        private long numberOfAttachments;
    }

    @Query("""
        SELECT new com.tdmconsult.ete.documents.FinancialDocumentRepository$UploadSummaryDto(
            fd.publicId,
            fd.createdAt,
            fd.typeOfDocument,
            fd.dateReceived,
            fd.uploadBy,
            fd.state,
            COUNT(a)
        )
        FROM FinancialDocument fd
        LEFT JOIN fd.attachments a
        GROUP BY fd.publicId, fd.createdAt, fd.typeOfDocument, fd.dateReceived, fd.uploadBy, fd.state
        """)
    List<UploadSummaryDto> findAllUploadSummaries();

    Optional<FinancialDocument> findByPublicId(String publicId);

    @Query("select fd.uploadBy from FinancialDocument fd where fd.publicId=:publicId")
    String getUploadByUsername(String publicId);

    default boolean isUploadBy(
            final String publicId,
            final CustomJwtAuthenticationToken.CustomUserPrincipal userDetails) {
        return StringUtils.equals(getUploadByUsername(publicId), userDetails.username());
    }

    default FinancialDocument findByPublicIdOrThrow(final String publicId) {
        return findByPublicId(publicId).orElseThrow(() -> DocumentNotFound.byId(publicId));
    }
}