Skip to content

Commit

Permalink
feat #45 : milestone API
Browse files Browse the repository at this point in the history
  • Loading branch information
JJONSOO committed Aug 7, 2023
1 parent efc9d66 commit 74de407
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.issuetrackermax.controller.milestone.dto.request;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class MilestoneModifyRequest {
private String name;
private String description;
private LocalDateTime dueDate;

@Builder
public MilestoneModifyRequest(String name, String description, LocalDateTime dueDate) {
this.name = name;
this.description = description;
this.dueDate = dueDate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.issuetrackermax.controller.milestone.dto.request;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class MilestonePostRequest {
private String name;
private LocalDateTime dueDate;
private String description;

@Builder
public MilestonePostRequest(String name, LocalDateTime dueDate, String description) {
this.name = name;
this.dueDate = dueDate;
this.description = description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.issuetrackermax.controller.milestone.dto.response;

import java.util.List;

import lombok.Builder;
import lombok.Getter;

@Getter
public class MilestoneCloseResponse {
private Long labelCount;
private Long openMilestoneCount;
private List<MilestoneDetailResponse> milestones;

@Builder
public MilestoneCloseResponse(Long labelCount, Long openMilestoneCount,
List<MilestoneDetailResponse> milestones) {
this.labelCount = labelCount;
this.openMilestoneCount = openMilestoneCount;
this.milestones = milestones;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.issuetrackermax.controller.milestone.dto.response;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;

@Getter
public class MilestoneDetailResponse {
private Long id;
private String name;
private String description;
private LocalDateTime dueDate;
private Long openIssueCount;
private Long closedIssueCount;

@Builder
public MilestoneDetailResponse(Long id, String name, String description, LocalDateTime dueDate,
Long openIssueCount, Long closedIssueCount) {
this.id = id;
this.name = name;
this.description = description;
this.dueDate = dueDate;
this.openIssueCount = openIssueCount;
this.closedIssueCount = closedIssueCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.issuetrackermax.controller.milestone.dto.response;

import java.util.List;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class MilestoneOpenResponse {
private Long labelCount;
private Long closedMilestoneCount;
private List<MilestoneDetailResponse> milestones;

@Builder
public MilestoneOpenResponse(Long labelCount, Long closedMilestoneCount,
List<MilestoneDetailResponse> milestones) {
this.labelCount = labelCount;
this.closedMilestoneCount = closedMilestoneCount;
this.milestones = milestones;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.issuetrackermax.controller.milestone.dto.response;

import lombok.Builder;
import lombok.Getter;

@Getter
public class MilestonePostResponse {
private Long id;

@Builder
public MilestonePostResponse(Long id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public IssueResultVO findIssueDetailsById(Long id) {
.orElseThrow(() -> new ApiException(IssueException.NOT_FOUND_ISSUE));
}

public List<Issue> findByMilestoneId(Long milestoneId) {
String sql = "SELECT id, title, is_open, writer_id, milestone_id,created_at FROM issue WHERE milestone_id = :milestoneId";
return jdbcTemplate.query(sql, Map.of("milestoneId", milestoneId), ISSUE_ROW_MAPPER);
}

public Long save(Issue issue) {
String sql = "INSERT INTO issue(title, is_open, writer_id, milestone_id) "
+ "VALUES (:title, :isOpen, :writerId, :milestoneId)";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.issuetrackermax.domain.milestone;

import java.sql.Types;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
Expand All @@ -22,28 +26,76 @@ public MilestoneRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
}

public Milestone findbyId(Long id) {
String sql = "SELECT id, title, is_open, duedate, description FROM milestone WHERE id = :id ";
return Optional.ofNullable(
DataAccessUtils.singleResult(jdbcTemplate.query(sql, Map.of("id", id), MILESTONE_ROW_MAPPER))).get();
}

public Long save(Milestone milestone) {
String sql = "INSERT INTO milestone(title, description,is_open) VALUES (:title,:description,:isOpen)";
String sql = "INSERT INTO milestone(title, description,is_open, duedate) VALUES (:title,:description,:isOpen, :dueDate)";
KeyHolder keyHolder = new GeneratedKeyHolder();
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("title", milestone.getTitle(), Types.VARCHAR)
.addValue("description", milestone.getDescription(), Types.VARCHAR)
.addValue("isOpen", milestone.getIsOpen(), Types.TINYINT);
.addValue("isOpen", milestone.getIsOpen(), Types.TINYINT)
.addValue("dueDate", milestone.getDuedate(), Types.DATE);

jdbcTemplate.update(sql, parameters, keyHolder);
Map<String, Object> keys = keyHolder.getKeys();
return (Long)Objects.requireNonNull(keys).get("ID");
}

public Long update(Long id, Milestone milestone) {
String sql = "UPDATE milestone SET title = :title, description = :description, duedate = :dueDate WHERE id = :milestoneId";
KeyHolder keyHolder = new GeneratedKeyHolder();
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("milestoneId", id)
.addValue("title", milestone.getTitle(), Types.VARCHAR)
.addValue("description", milestone.getDescription(), Types.VARCHAR)
.addValue("dueDate", milestone.getDuedate(), Types.DATE);
jdbcTemplate.update(sql, parameters, keyHolder);
Map<String, Object> keys = keyHolder.getKeys();
return (Long)Objects.requireNonNull(keys).get("ID");
}

public Long getMilestoneCount() {
String sql = "SELECT COUNT(*) FROM milestone";
return jdbcTemplate.queryForObject(sql, new MapSqlParameterSource(), Long.class);
}

public List<Milestone> getOpenMilestone() {
String sql = "SELECT id, title, is_open, description,duedate FROM milestone WHERE is_open = :isOpen";
return jdbcTemplate.query(sql, Map.of("isOpen", 1), MILESTONE_ROW_MAPPER);
}

public List<Milestone> getClosedMilestone() {
String sql = "SELECT id, title, is_open, description,duedate FROM milestone WHERE is_open = :isOpen";
return jdbcTemplate.query(sql, Map.of("isOpen", 0), MILESTONE_ROW_MAPPER);
}

public Boolean existById(Long id) {
String sql = "SELECT EXISTS (SELECT 1 FROM milestone WHERE id = :id)";
return jdbcTemplate.queryForObject(sql, new MapSqlParameterSource()
.addValue("id", id), Boolean.class);
}

public int deleteById(Long id) {
String sql = "DELETE FROM milestone WHERE id = :id";
return jdbcTemplate.update(sql, new MapSqlParameterSource("id", id));
}

private static final RowMapper<Milestone> MILESTONE_ROW_MAPPER = (rs, rowNum) ->
Milestone.builder()
.id(rs.getLong("id"))
.title(rs.getString("title"))
.isOpen(rs.getBoolean("is_open"))
.description(rs.getString("description"))
.duedate(rs.getTimestamp("duedate").toLocalDateTime())
.build();

public int updateStatus(Long id) {
String sql = "UPDATE milestone SET is_open = NOT is_open WHERE id = :id";
return jdbcTemplate.update(sql, new MapSqlParameterSource("id", id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.time.LocalDateTime;

import com.issuetrackermax.controller.milestone.dto.request.MilestoneModifyRequest;
import com.issuetrackermax.controller.milestone.dto.request.MilestonePostRequest;

import lombok.Builder;
import lombok.Getter;

Expand All @@ -21,4 +24,24 @@ public Milestone(Long id, String title, String description, LocalDateTime duedat
this.duedate = duedate;
this.isOpen = isOpen;
}

public static Milestone from(MilestonePostRequest milestonePostRequest) {
return Milestone
.builder()
.title(milestonePostRequest.getName())
.description(milestonePostRequest.getDescription())
.duedate(milestonePostRequest.getDueDate())
.isOpen(true)
.build();
}

public static Milestone from(MilestoneModifyRequest milestoneModifyRequest) {
return Milestone
.builder()
.title(milestoneModifyRequest.getName())
.description(milestoneModifyRequest.getDescription())
.duedate(milestoneModifyRequest.getDueDate())
.build();

}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,86 @@
package com.issuetrackermax.service.milestone;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.issuetrackermax.controller.milestone.dto.request.MilestoneModifyRequest;
import com.issuetrackermax.controller.milestone.dto.request.MilestonePostRequest;
import com.issuetrackermax.controller.milestone.dto.response.MilestoneDetailResponse;
import com.issuetrackermax.domain.issue.IssueRepository;
import com.issuetrackermax.domain.issue.entity.Issue;
import com.issuetrackermax.domain.milestone.MilestoneRepository;
import com.issuetrackermax.domain.milestone.entity.Milestone;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class MilestoneService {
private final MilestoneRepository milestoneRepository;
private final IssueRepository issueRepository;

public Long getMilstoneCount() {
public Long getMilestoneCount() {
return milestoneRepository.getMilestoneCount();
}

public List<MilestoneDetailResponse> getOpenMilestone() {
List<Milestone> openMilestone = milestoneRepository.getOpenMilestone();
return getMilestoneDetailResponses(openMilestone);
}

public List<MilestoneDetailResponse> getClosedMilestone() {
List<Milestone> closedMilestone = milestoneRepository.getClosedMilestone();
return getMilestoneDetailResponses(closedMilestone);

}

private List<MilestoneDetailResponse> getMilestoneDetailResponses(List<Milestone> openMilestone) {
List<MilestoneDetailResponse> response =
openMilestone.stream()
.map(milestone -> {
long openIssueCount = issueRepository.findByMilestoneId(milestone.getId())
.stream()
.filter(Issue::getIsOpen)
.count();

long closedIssueCount = issueRepository.findByMilestoneId(milestone.getId())
.stream()
.filter(issue -> !issue.getIsOpen())
.count();

return MilestoneDetailResponse.builder()
.id(milestone.getId())
.description(milestone.getDescription())
.name(milestone.getTitle())
.dueDate(milestone.getDuedate())
.openIssueCount(openIssueCount)
.closedIssueCount(closedIssueCount)
.build();
})
.collect(Collectors.toList());

return response;
}

public Long save(MilestonePostRequest milestonePostRequest) {
Milestone milestone = Milestone.from(milestonePostRequest);
return milestoneRepository.save(milestone);
}

public void update(Long id, MilestoneModifyRequest milestoneModifyRequest) {
milestoneRepository.update(id, Milestone.from(milestoneModifyRequest));
return;
}

public void delete(Long id) {
int count = milestoneRepository.deleteById(id);
return;
}

public void updateStatus(Long id) {
milestoneRepository.updateStatus(id);
return;
}
}

0 comments on commit 74de407

Please sign in to comment.