diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java index a0036667..e7fba545 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java @@ -9,7 +9,6 @@ import ddingdong.ddingdongBE.domain.club.entity.Club; import ddingdong.ddingdongBE.domain.club.service.ClubService; import ddingdong.ddingdongBE.domain.clubmember.entity.ClubMember; -import ddingdong.ddingdongBE.domain.filemetadata.entity.DomainType; import ddingdong.ddingdongBE.domain.filemetadata.service.FileMetaDataService; import ddingdong.ddingdongBE.domain.form.entity.Form; import ddingdong.ddingdongBE.domain.form.entity.FormField; @@ -26,13 +25,13 @@ import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.ApplicantStatisticQuery; import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.DepartmentStatisticQuery; import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.FieldStatisticsQuery; -import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; -import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplicationStatus; -import ddingdong.ddingdongBE.domain.formapplication.service.FormApplicationService; import ddingdong.ddingdongBE.domain.form.service.dto.query.MultipleFieldStatisticsQuery; import ddingdong.ddingdongBE.domain.form.service.dto.query.MultipleFieldStatisticsQuery.OptionStatisticQuery; import ddingdong.ddingdongBE.domain.form.service.dto.query.SingleFieldStatisticsQuery; import ddingdong.ddingdongBE.domain.form.service.dto.query.SingleFieldStatisticsQuery.SingleStatisticsQuery; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplicationStatus; +import ddingdong.ddingdongBE.domain.formapplication.service.FormApplicationService; import ddingdong.ddingdongBE.domain.user.entity.User; import ddingdong.ddingdongBE.email.SesEmailService; import ddingdong.ddingdongBE.email.dto.EmailContent; @@ -98,7 +97,7 @@ public void deleteForm(Long formId, User user) { Club club = clubService.getByUserId(user.getId()); Form form = formService.getById(formId); validateEqualsClub(club, form); - fileMetaDataService.updateStatusToDelete(DomainType.FORM_FILE, formId); + // TODO : fileMetaData의 formFile formAnswer 지우기 formService.delete(form); //테이블 생성 시 외래 키에 cascade 설정하여 formField 삭제도 자동으로 됨. } @@ -252,13 +251,13 @@ private void validateEndDate(LocalDate startDate, LocalDate endDate) { } private List toUpdateFormFields(Form originform, - List updateFormFieldCommands) { + List updateFormFieldCommands) { return updateFormFieldCommands.stream() .map(formFieldCommand -> formFieldCommand.toEntity(originform)).toList(); } private List toCreateFormFields(Form savedForm, - List createFormFieldCommands) { + List createFormFieldCommands) { return createFormFieldCommands.stream() .map(formFieldCommand -> formFieldCommand.toEntity(savedForm)).toList(); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormStatisticServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormStatisticServiceImpl.java index 9d21583a..b420e754 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormStatisticServiceImpl.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormStatisticServiceImpl.java @@ -4,7 +4,6 @@ import ddingdong.ddingdongBE.common.utils.CalculationUtils; import ddingdong.ddingdongBE.common.utils.TimeUtils; import ddingdong.ddingdongBE.domain.club.entity.Club; -import ddingdong.ddingdongBE.domain.filemetadata.service.FileMetaDataService; import ddingdong.ddingdongBE.domain.form.entity.Form; import ddingdong.ddingdongBE.domain.form.entity.FormField; import ddingdong.ddingdongBE.domain.form.repository.FormFieldRepository; @@ -18,11 +17,11 @@ import ddingdong.ddingdongBE.domain.formapplication.repository.FormAnswerRepository; import ddingdong.ddingdongBE.domain.formapplication.repository.FormApplicationRepository; import ddingdong.ddingdongBE.domain.formapplication.repository.dto.DepartmentInfo; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.FileAnswerInfo; import ddingdong.ddingdongBE.domain.formapplication.repository.dto.RecentFormInfo; import ddingdong.ddingdongBE.domain.formapplication.repository.dto.TextAnswerInfo; -import ddingdong.ddingdongBE.file.service.S3FileService; +import ddingdong.ddingdongBE.domain.formapplication.service.FileFormAnswerService; import java.time.LocalDate; -import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; @@ -41,8 +40,7 @@ public class FormStatisticServiceImpl implements FormStatisticService { private final FormFieldRepository formFieldRepository; private final FormAnswerRepository formAnswerRepository; private final StringListConverter stringListConverter; - private final S3FileService s3FileService; - private final FileMetaDataService fileMetaDataService; + private final FileFormAnswerService fileFormAnswerService; @Override public int getTotalApplicationCountByForm(Form form) { @@ -123,33 +121,25 @@ public List createOptionStatistics(FormField formField) { public List createTextStatistics(FormField formField) { List textAnswerInfos = formAnswerRepository.getTextAnswerInfosByFormFieldId(formField.getId()); return textAnswerInfos.stream() - .map(textAnswerInfo -> { - Long id = textAnswerInfo.getId(); - String name = textAnswerInfo.getName(); - String answer = getAnswer(textAnswerInfo.getValue()); - return new SingleStatisticsQuery(id, name, answer); - }) + .map(textAnswerInfo -> + SingleStatisticsQuery.fromTextInfo(textAnswerInfo, getAnswer(textAnswerInfo.getValue())) + ) .toList(); } @Override public List createFileStatistics(FormField formField) { - List textAnswerInfos = formAnswerRepository.getTextAnswerInfosByFormFieldId(formField.getId()); - List textStatisticsQueries = new ArrayList<>(); - for(TextAnswerInfo textAnswerInfo : textAnswerInfos) { - Long id = textAnswerInfo.getId(); - String name = textAnswerInfo.getName(); - List answers = stringListConverter.convertToEntityAttribute(textAnswerInfo.getValue()); - for (String answer : answers) { - textStatisticsQueries.add(new SingleStatisticsQuery(id, name, answer)); - } - } - return textStatisticsQueries; + List answerIds = formAnswerRepository.findAllAnswerByFormFieldId(formField.getId()); + List fileAnswerInfos = fileFormAnswerService.getAllFileApplicationInfo( + answerIds); + return fileAnswerInfos.stream() + .map(SingleStatisticsQuery::fromFileInfo) + .toList(); } private String getAnswer(String value) { List answer = stringListConverter.convertToEntityAttribute(value); - if(answer.isEmpty()) { + if (answer.isEmpty()) { return null; } return answer.get(0); diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/SingleFieldStatisticsQuery.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/SingleFieldStatisticsQuery.java index ab91ded0..0be0e2b0 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/SingleFieldStatisticsQuery.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/SingleFieldStatisticsQuery.java @@ -1,5 +1,7 @@ package ddingdong.ddingdongBE.domain.form.service.dto.query; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.FileAnswerInfo; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.TextAnswerInfo; import java.util.List; public record SingleFieldStatisticsQuery( @@ -12,5 +14,13 @@ public record SingleStatisticsQuery( String name, String answer ) { + + public static SingleStatisticsQuery fromFileInfo(FileAnswerInfo info) { + return new SingleStatisticsQuery(info.getId(), info.getName(), info.getFileName()); + } + + public static SingleStatisticsQuery fromTextInfo(TextAnswerInfo info, String answer) { + return new SingleStatisticsQuery(info.getId(), info.getName(), answer); + } } } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormAnswerRepository.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormAnswerRepository.java index 68316ecb..9abf8500 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormAnswerRepository.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormAnswerRepository.java @@ -3,10 +3,10 @@ import ddingdong.ddingdongBE.domain.form.entity.FormField; import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer; import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.FileAnswerInfo; import ddingdong.ddingdongBE.domain.formapplication.repository.dto.TextAnswerInfo; -import org.springframework.data.jpa.repository.JpaRepository; - import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -35,4 +35,28 @@ public interface FormAnswerRepository extends JpaRepository { ORDER BY fap.id """, nativeQuery = true) List getTextAnswerInfosByFormFieldId(Long fieldId); + + @Query(value = """ + SELECT DISTINCT fa.id + FROM form_answer fa + WHERE fa.field_id = :fieldId + """, nativeQuery = true) + List findAllAnswerByFormFieldId(@Param("fieldId") Long fieldId); + + @Query(value = """ + SELECT fa.id as id, fap.name as name, fmd.file_name as fileName + FROM form_answer fa + JOIN file_meta_data fmd + ON fmd.entity_id = fa.id + JOIN form_application fap + ON fa.application_id = fap.id + WHERE fmd.domain_type = :domainType + AND fmd.entity_id IN (:answerIds) + AND fmd.file_status = :fileStatus + ORDER BY fmd.file_name + """, nativeQuery = true) + List findAllFileAnswerInfo( + @Param("domainType") String domainType, + @Param("answerIds") List answerIds, + @Param("fileStatus") String fileStatus ); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepository.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepository.java index 1b4ae3b6..e76cf22e 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepository.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepository.java @@ -60,5 +60,4 @@ List findRecentFormByDateWithApplicationCount( List findAllByForm(Form form); List getAllByFormIdAndStatus(Long formId, FormApplicationStatus status); - } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/dto/FileAnswerInfo.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/dto/FileAnswerInfo.java new file mode 100644 index 00000000..8a9d7069 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/repository/dto/FileAnswerInfo.java @@ -0,0 +1,11 @@ +package ddingdong.ddingdongBE.domain.formapplication.repository.dto; + +public interface FileAnswerInfo { + + Long getId(); + + String getName(); + + String getFileName(); + +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java index b2a59ab5..2d1bc1c9 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java @@ -39,7 +39,7 @@ public void createFormApplication(CreateFormApplicationCommand createFormApplica List formAnswers = toFormAnswers(savedFormApplication, createFormApplicationCommand.formAnswerCommands()); - updateFileMetaDataStatusToCoupled(formAnswers, form); + updateFileMetaDataStatusToCoupled(formAnswers); formAnswerService.createAll(formAnswers); } @@ -50,16 +50,14 @@ private void validateFormPeriod(LocalDate startDate, } } - private void updateFileMetaDataStatusToCoupled(List formAnswers, Form form) { - formAnswers.forEach(formAnswer -> { - if (formAnswer.isFile()) { - fileMetaDataService.updateStatusToCoupled( + private void updateFileMetaDataStatusToCoupled(List formAnswers) { + formAnswers.stream() + .filter(FormAnswer::isFile) + .forEach(formAnswer -> fileMetaDataService.updateStatusToCoupled( formAnswer.getValue(), FORM_FILE, - form.getId() - ); - } - }); + formAnswer.getId() + )); } private List toFormAnswers( diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FileFormAnswerService.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FileFormAnswerService.java new file mode 100644 index 00000000..a8dbfa16 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FileFormAnswerService.java @@ -0,0 +1,21 @@ +package ddingdong.ddingdongBE.domain.formapplication.service; + +import static ddingdong.ddingdongBE.domain.filemetadata.entity.DomainType.FORM_FILE; +import static ddingdong.ddingdongBE.domain.filemetadata.entity.FileStatus.COUPLED; + +import ddingdong.ddingdongBE.domain.formapplication.repository.FormAnswerRepository; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.FileAnswerInfo; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class FileFormAnswerService { + + private final FormAnswerRepository formAnswerRepository; + + public List getAllFileApplicationInfo(List answerIds) { + return formAnswerRepository.findAllFileAnswerInfo(FORM_FILE.name(), answerIds, COUPLED.name()); + } +} diff --git a/src/test/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepositoryTest.java b/src/test/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepositoryTest.java new file mode 100644 index 00000000..9ef6f1bb --- /dev/null +++ b/src/test/java/ddingdong/ddingdongBE/domain/formapplication/repository/FormApplicationRepositoryTest.java @@ -0,0 +1,90 @@ +package ddingdong.ddingdongBE.domain.formapplication.repository; + +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +import com.navercorp.fixturemonkey.FixtureMonkey; +import ddingdong.ddingdongBE.common.support.DataJpaTestSupport; +import ddingdong.ddingdongBE.common.support.FixtureMonkeyFactory; +import ddingdong.ddingdongBE.domain.filemetadata.entity.DomainType; +import ddingdong.ddingdongBE.domain.filemetadata.entity.FileMetaData; +import ddingdong.ddingdongBE.domain.filemetadata.entity.FileStatus; +import ddingdong.ddingdongBE.domain.filemetadata.repository.FileMetaDataRepository; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; +import ddingdong.ddingdongBE.domain.formapplication.repository.dto.FileAnswerInfo; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class FormApplicationRepositoryTest extends DataJpaTestSupport { + + @Autowired + private FormApplicationRepository formApplicationRepository; + + @Autowired + private FileMetaDataRepository fileMetaDataRepository; + + @Autowired + private FormAnswerRepository formAnswerRepository; + + private FixtureMonkey fixtureMonkey = FixtureMonkeyFactory.getNotNullBuilderIntrospectorMonkey(); + + @DisplayName("폼 지원서id와 FileMetaData의 entityId와 조인하여 정보를 조회한다") + @Test + void findAllFileApplicationInfo() { + // given + FormApplication formApplication = fixtureMonkey.giveMeBuilder(FormApplication.class) + .set("name", "이름1") + .set("form", null) + .sample(); + FormApplication savedFormApplication = formApplicationRepository.save(formApplication); + FormAnswer formAnswer = FormAnswer.builder() + .formApplication(savedFormApplication) + .value(List.of()) + .build(); + FormAnswer savedFormAnswer = formAnswerRepository.save(formAnswer); + FormApplication formApplication2 = fixtureMonkey.giveMeBuilder(FormApplication.class) + .set("name", "이름2") + .set("form", null) + .sample(); + FormApplication savedFormApplication2 = formApplicationRepository.save(formApplication2); + FormAnswer formAnswer2 = FormAnswer.builder() + .formApplication(savedFormApplication2) + .value(List.of()) + .build(); + FormAnswer savedFormAnswer2 = formAnswerRepository.save(formAnswer2); + FileMetaData fileMetaData = FileMetaData.builder() + .id(UUID.randomUUID()) + .entityId(savedFormAnswer.getId()) + .fileName("파일 이름1") + .domainType(DomainType.FORM_FILE) + .fileStatus(FileStatus.COUPLED) + .fileKey("1") + .build(); + FileMetaData fileMetaData2 = FileMetaData.builder() + .id(UUID.randomUUID()) + .entityId(savedFormAnswer2.getId()) + .fileName("파일 이름2") + .domainType(DomainType.FORM_FILE) + .fileStatus(FileStatus.COUPLED) + .fileKey("1") + .build(); + fileMetaDataRepository.saveAll(List.of(fileMetaData, fileMetaData2)); + List ids = List.of(savedFormAnswer.getId(), savedFormAnswer2.getId()); + + // when + List fileAnswerInfos = formAnswerRepository.findAllFileAnswerInfo( + DomainType.FORM_FILE.name(), ids, FileStatus.COUPLED.name()); + + // then + assertSoftly(softly -> { + softly.assertThat(fileAnswerInfos).hasSize(2); + softly.assertThat(fileAnswerInfos.get(0).getFileName()).isEqualTo(fileMetaData.getFileName()); + softly.assertThat(fileAnswerInfos.get(0).getName()).isEqualTo(savedFormApplication.getName()); + softly.assertThat(fileAnswerInfos.get(0).getId()).isEqualTo(savedFormAnswer.getId()); + softly.assertThat(fileAnswerInfos.get(1).getFileName()).isEqualTo(fileMetaData2.getFileName()); + }); + } +}