Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.applicationform.domain.ApplicationFormStatus;
import com.jobnote.domain.applicationformdocument.dto.ApplicationFormDocumentRequest;
import com.jobnote.domain.schedule.dto.ScheduleRequest;
import com.jobnote.domain.user.domain.User;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.util.Collections;
import java.util.List;

public record ApplicationFormRequest(
Expand All @@ -35,7 +35,10 @@ public record ApplicationFormRequest(
ApplicationFormStatus status,

@Valid
List<ScheduleRequest> schedules
List<ScheduleRequest> schedules,

@Valid
List<ApplicationFormDocumentRequest> documents
) {
public ApplicationForm toEntity(final User user) {
return ApplicationForm.builder()
Expand All @@ -52,8 +55,14 @@ public ApplicationForm toEntity(final User user) {
.build();
}

/* null-safe */
@Override
public List<ScheduleRequest> schedules() {
return schedules != null ? schedules : Collections.emptyList();
return schedules != null ? schedules : List.of();
}

@Override
public List<ApplicationFormDocumentRequest> documents() {
return documents != null ? documents : List.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.applicationform.domain.ApplicationFormStatus;
import com.jobnote.domain.document.dto.DocumentSimpleResponse;
import com.jobnote.domain.schedule.dto.ScheduleResponse;
import lombok.AccessLevel;
import lombok.Builder;

import java.util.Collections;
import java.util.List;

@Builder(access = AccessLevel.PRIVATE)
Expand All @@ -21,9 +21,10 @@ public record ApplicationFormResponse(
String position,
String memo,
ApplicationFormStatus status,
List<ScheduleResponse> schedules
List<ScheduleResponse> schedules,
List<DocumentSimpleResponse> documents
) {
public static ApplicationFormResponse from(final ApplicationForm form, final List<ScheduleResponse> schedules) {
public static ApplicationFormResponse from(final ApplicationForm form, final List<ScheduleResponse> schedules, final List<DocumentSimpleResponse> documents) {
return ApplicationFormResponse.builder()
.id(form.getId())
.companyName(form.getCompanyName())
Expand All @@ -36,11 +37,18 @@ public static ApplicationFormResponse from(final ApplicationForm form, final Lis
.memo(form.getMemo())
.status(form.getStatus())
.schedules(schedules)
.documents(documents)
.build();
}

/* null-safe */
@Override
public List<ScheduleResponse> schedules() {
return schedules != null ? schedules : Collections.emptyList();
return schedules != null ? schedules : List.of();
}

@Override
public List<DocumentSimpleResponse> documents() {
return documents != null ? documents : List.of();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.jobnote.domain.applicationform.dto;

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.applicationform.domain.ApplicationFormStatus;
import lombok.AccessLevel;
import lombok.Builder;

@Builder(access = AccessLevel.PRIVATE)
public record ApplicationFormSimpleResponse(
Long id,
String companyName,
String companyAddress,
ApplicationFormStatus status
) {
public static ApplicationFormSimpleResponse from(final ApplicationForm applicationForm) {
return ApplicationFormSimpleResponse.builder()
.id(applicationForm.getId())
.companyName(applicationForm.getCompanyName())
.companyAddress(applicationForm.getCompanyAddress())
.status(applicationForm.getStatus())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.jobnote.domain.applicationform.service;

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.applicationform.dto.ApplicationFormSimpleResponse;
import com.jobnote.domain.applicationformdocument.domain.ApplicationFormDocument;
import com.jobnote.domain.applicationformdocument.dto.ApplicationFormDocumentRequest;
import com.jobnote.domain.applicationform.repository.ApplicationFormRepository;
import com.jobnote.domain.applicationform.dto.ApplicationFormRequest;
import com.jobnote.domain.applicationform.dto.ApplicationFormResponse;
import com.jobnote.domain.applicationformdocument.service.ApplicationFormDocumentService;
import com.jobnote.domain.document.dto.DocumentSimpleResponse;
import com.jobnote.domain.schedule.dto.ScheduleResponse;
import com.jobnote.domain.schedule.service.ScheduleService;
import com.jobnote.global.exception.JobNoteException;
Expand All @@ -15,6 +20,9 @@

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.jobnote.global.common.ResponseCode.NOT_FOUND_APPLICATION_FORM;

Expand All @@ -26,25 +34,40 @@ public class ApplicationFormService {
private final ApplicationFormRepository applicationFormRepository;
private final UserService userService;
private final ScheduleService scheduleService;
private final ApplicationFormDocumentService applicationFormDocumentService;

/* READ */
public ApplicationFormResponse getById(final Long userId, final Long formId) {
ApplicationForm form = getByIdOrThrow(formId);
form.validateOwner(userId);

List<ScheduleResponse> schedules = scheduleService.getAllByApplicationFormId(userId, formId);
List<DocumentSimpleResponse> documents = applicationFormDocumentService.getSimpleResponsesByApplicationFormId(userId, formId);

return ApplicationFormResponse.from(form, schedules);
return ApplicationFormResponse.from(form, schedules, documents);
}

public List<ApplicationFormResponse> getAll(final Long userId) {
List<ApplicationForm> forms = applicationFormRepository.findAllByUserId(userId);
List<Long> formIds = forms.stream().map(ApplicationForm::getId).toList();

Map<Long, List<ScheduleResponse>> schedulesByFormId = scheduleService.getAllGroupedByApplicationFormIds(userId, formIds);
Map<Long, List<DocumentSimpleResponse>> documentsByFormId = applicationFormDocumentService.getSimpleResponsesGroupedByApplicationFormIds(userId, formIds);

return forms.stream()
.map(form -> ApplicationFormResponse.from(form, schedulesByFormId.getOrDefault(form.getId(), List.of())))
.map(form -> ApplicationFormResponse.from(
form,
schedulesByFormId.getOrDefault(form.getId(), List.of()),
documentsByFormId.getOrDefault(form.getId(), List.of()))
)
.toList();
}

public List<ApplicationFormSimpleResponse> getAllSimple(final Long userId) {
List<ApplicationForm> forms = applicationFormRepository.findAllByUserId(userId);

return forms.stream()
.map(ApplicationFormSimpleResponse::from)
.toList();
}

Expand All @@ -53,9 +76,15 @@ public List<ApplicationFormResponse> getAll(final Long userId) {
public Long save(final Long userId, final ApplicationFormRequest request) {
User user = userService.getUserById(userId);

// 지원서 생성
ApplicationForm form = applicationFormRepository.save(request.toEntity(user));

// 일정 등록
scheduleService.saveAll(userId, form, request.schedules());

// 연결된 문서 등록
applicationFormDocumentService.saveAll(form, request.documents());

return form.getId();
}

Expand All @@ -65,8 +94,14 @@ public void update(final Long userId, final Long formId, final ApplicationFormRe
ApplicationForm form = getByIdOrThrow(formId);
form.validateOwner(userId);

// 지원서 업데이트
form.update(request);

// 일정 업데이트
scheduleService.updateAll(userId, form, request.schedules());

// 연결된 문서 업데이트
updateApplicationFormDocuments(userId, form, request.documents());
}

/* DELETE */
Expand All @@ -76,6 +111,7 @@ public void delete(final Long userId, final Long formId) {
form.validateOwner(userId);

scheduleService.deleteAllByApplicationFormId(form.getId());
applicationFormDocumentService.deleteAllByApplicationFormId(form.getId());
applicationFormRepository.delete(form);
}

Expand All @@ -84,4 +120,29 @@ public ApplicationForm getByIdOrThrow(final Long formId) {
return applicationFormRepository.findById(formId)
.orElseThrow(() -> new JobNoteException(NOT_FOUND_APPLICATION_FORM));
}

private void updateApplicationFormDocuments(final Long userId, final ApplicationForm form, final List<ApplicationFormDocumentRequest> requests) {
// 기존 연결된 문서 조회
List<ApplicationFormDocument> existsDocuments = applicationFormDocumentService.getAllByApplicationFormId(userId, form.getId());

// 요청 문서 ID 목록
Set<Long> requestsIds = requests.stream()
.map(ApplicationFormDocumentRequest::id)
.filter(Objects::nonNull)
.collect(Collectors.toSet());

// 삭제 : 기존 문서 중 요청에 없는 문서 삭제
for (ApplicationFormDocument document : existsDocuments) {
if (!requestsIds.contains(document.getId())) {
applicationFormDocumentService.delete(document);
}
}

// 신규 생성 (
for (ApplicationFormDocumentRequest req : requests) {
if (req.id() == null) {
applicationFormDocumentService.saveAll(form, List.of(req));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.jobnote.domain.applicationformdocument.domain;

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.common.BaseTimeEntity;
import com.jobnote.domain.document.domain.Document;
import com.jobnote.global.exception.JobNoteException;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static com.jobnote.global.common.ResponseCode.FORBIDDEN;

@Entity
@Getter
@Table(name = "application_form_document")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ApplicationFormDocument extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "application_form_document_id")
private Long id;

@ManyToOne
@JoinColumn(name = "application_form_id")
private ApplicationForm applicationForm;

@ManyToOne
@JoinColumn(name = "document_id")
private Document document;

@Builder
public ApplicationFormDocument(
final ApplicationForm applicationForm,
final Document document
) {
this.applicationForm = applicationForm;
this.document = document;
}

public void validateOwner(final Long userId) {
if (!this.applicationForm.getUser().getId().equals(userId) &&
!this.document.getUser().getId().equals(userId)) {
throw new JobNoteException(FORBIDDEN);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.jobnote.domain.applicationformdocument.dto;

import com.jobnote.domain.applicationform.domain.ApplicationForm;
import com.jobnote.domain.applicationformdocument.domain.ApplicationFormDocument;
import com.jobnote.domain.document.domain.Document;
import jakarta.validation.constraints.NotNull;

public record ApplicationFormDocumentRequest(
Long id,

@NotNull(message = "문서 ID는 null일 수 없습니다.")
Long documentId
) {
public ApplicationFormDocument toEntity(final ApplicationForm form, final Document document) {
return ApplicationFormDocument.builder()
.applicationForm(form)
.document(document)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.jobnote.domain.applicationformdocument.repository;

import com.jobnote.domain.applicationformdocument.domain.ApplicationFormDocument;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface ApplicationFormDocumentRepository extends JpaRepository<ApplicationFormDocument, Long> {
// 해당 지원서에 속한 문서(지원서-문서 맵핑 엔티티) 목록 반환
@Query("select afd from ApplicationFormDocument afd join fetch afd.applicationForm af join fetch af.user where af.user.id = :userId and af.id in :formId")
List<ApplicationFormDocument> findAllByUserIdAndApplicationFormIdIn(final Long userId, final List<Long> formId);

// 해당 지원서에 속한 문서 연결 해제
void deleteAllByApplicationFormId(final Long formId);

// 해당 문서에 속한 지원서 연결 해제
void deleteAllByDocumentId(final Long documentId);
}
Loading
Loading