Skip to content

Commit

Permalink
ADM-806:[backend]feat: export top 50 when none done cards grater than…
Browse files Browse the repository at this point in the history
… 50 in board (#1076)

* ADM-806:[backend]feat: export top 50 when none done cards grater than 50 in board

* ADM-806:[backend]fix: fix name

* ADM-829:[backend]fix: delete bad checkSite api (#1077)

* ADM-806:[backend]fix: update logic to get lasted none done card when fetch jira api

* ADM-806:[backend]fix: add content to README.md

* ADM-806:[backend]fix: update content in README.md

* ADM-806:[backend]fix: not to page get all nonDone card when get nonDone card

---------

Co-authored-by: junbo dai <junbo.dai@thoughtworks.com>
  • Loading branch information
yulongcai and BoBoDai authored Feb 27, 2024
1 parent 414e833 commit 2522b97
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 36 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,13 @@ After generating the report, you can export the original data for your board and

### 3.5.1 Export board data

It will export a csv file for board data. It contains two parts:
**Part 1:** Export the all done tickets during the time period
**Part 2:** Export the all non-done tickets in your current active board. And it will order by ticket status (Image 3-16)
It will export a csv file for board data

#### 3.5.1.1 Done card exporting
Export the all done tickets during the time period(Image 1)

#### 3.5.1.1 Undone card exporting
Export the latest updated 50 non-done tickets in your current active board. And it will order by heartbeat state and then last status change date(Image 3-16)

![Image 3-16](https://user-images.githubusercontent.com/995849/89784291-01f3b380-db4b-11ea-8f5a-d475e80014fb.png)\
_Image 3-16,Exported Board Data_
Expand Down
8 changes: 5 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,13 @@ _Image 3-15,Change Failure Rate Report_

### 3.4.1 导出看板数据 / Export board data

本功能会导出看板数据到 csv 文件,该文件包含两个部分:
本功能会导出看板数据到 csv 文件

**Part 1:** 在所选择时间段内所有的 Jira Ticket
#### 3.4.1.1 导出已完成card
在所选择时间段内导出所有已完成的card

**Part 2:** 在所选时间段内所有未完成的 Jira Ticket,并且会根据状态进行排序。(Image 3-16)
#### 3.4.1.2 导出未完成card
在所选时间段内拉取最新修改的50张cards,导出时先根据heartBeat的状态排序,然后再根据最近状态改变时间排序。(Image 3-16)

![Image 3-16](https://user-images.githubusercontent.com/995849/89784291-01f3b380-db4b-11ea-8f5a-d475e80014fb.png)\
_Image 3-16,Exported Board Data_
Expand Down
41 changes: 22 additions & 19 deletions backend/src/main/java/heartbeat/service/board/jira/JiraService.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -88,11 +88,15 @@ public class JiraService {

public static final int QUERY_COUNT = 100;

public static final int NONE_DONE_MAX_QUERY_COUNT = 50;

public static final List<String> FIELDS_IGNORE = List.of("summary", "description", "attachment", "duedate",
"issuelinks", "Development", "Start date", "Rank", "Issue color");

private static final String DONE_CARD_TAG = "done";

private static final String NONE_DONE_CARD_TAG = "nonDone";

private final ThreadPoolTaskExecutor customTaskExecutor;

private final JiraFeignClient jiraFeignClient;
Expand Down Expand Up @@ -358,7 +362,7 @@ private JiraCardWithFields getAllDoneCards(BoardType boardType, URI baseUrl, Lis
BoardRequestParam boardRequestParam) {
String jql = parseJiraJql(boardType, doneColumns, boardRequestParam);

return getCardList(baseUrl, boardRequestParam, jql, "done");
return getCardList(baseUrl, boardRequestParam, jql, "done", QUERY_COUNT);
}

private JiraCardWithFields getAllCards(BoardType boardType, URI baseUrl, BoardRequestParam boardRequestParam) {
Expand All @@ -370,7 +374,7 @@ private JiraCardWithFields getAllCards(BoardType boardType, URI baseUrl, BoardRe
else {
throw new BadRequestException("boardType param is not correct");
}
return getCardList(baseUrl, boardRequestParam, jql, "all");
return getCardList(baseUrl, boardRequestParam, jql, "all", QUERY_COUNT);
}

private AllCardsResponseDTO formatAllCards(String allCardResponse, List<TargetField> targetFields) {
Expand Down Expand Up @@ -446,9 +450,9 @@ else if (customFieldValue.equals("Flagged") && !fieldValue.isJsonNull()
jiraCards.get(index).getFields().setCustomFields(customFieldMapList.get(index));
}

for (int index = 0; index < jiraCards.size(); index++) {
String key = jiraCards.get(index).getKey();
jiraCards.get(index).getFields().setSprint(sprintMap.get(key));
for (JiraCard jiraCard : jiraCards) {
String key = jiraCard.getKey();
jiraCard.getFields().setSprint(sprintMap.get(key));
}
return allCardsResponseDTO;
}
Expand Down Expand Up @@ -745,9 +749,7 @@ private CardCycleTime calculateCardCycleTime(String cardId, List<CycleTimeInfo>
stepsDay.setReview(stepsDay.getReview() + cycleTimeInfo.getDay());
total += cycleTimeInfo.getDay();
}
case ANALYSE -> {
stepsDay.setAnalyse(stepsDay.getAnalyse() + cycleTimeInfo.getDay());
}
case ANALYSE -> stepsDay.setAnalyse(stepsDay.getAnalyse() + cycleTimeInfo.getDay());
default -> {
}
}
Expand Down Expand Up @@ -870,31 +872,32 @@ private JiraCardWithFields getAllNonDoneCardsForActiveSprint(URI baseUrl, List<S
BoardRequestParam boardRequestParam) {
String jql;
if (status.isEmpty()) {
jql = "sprint in openSprints() ";
jql = "sprint in openSprints() ORDER BY updated DESC";
}
else {
jql = "sprint in openSprints() AND status not in ('" + String.join("','", status) + "')";
jql = "sprint in openSprints() AND status not in ('" + String.join("','", status)
+ "') ORDER BY updated DESC";
}

return getCardList(baseUrl, boardRequestParam, jql, "nonDone");
return getCardList(baseUrl, boardRequestParam, jql, NONE_DONE_CARD_TAG, NONE_DONE_MAX_QUERY_COUNT);
}

private JiraCardWithFields getAllNonDoneCardsForKanBan(URI baseUrl, List<String> status,
BoardRequestParam boardRequestParam) {
String jql;
if (status.isEmpty()) {
jql = "";
jql = "ORDER BY updated DESC";
}
else {
jql = "status not in ('" + String.join("','", status) + "')";
jql = "status not in ('" + String.join("','", status) + "') ORDER BY updated DESC";
}
return getCardList(baseUrl, boardRequestParam, jql, "nonDone");
return getCardList(baseUrl, boardRequestParam, jql, NONE_DONE_CARD_TAG, NONE_DONE_MAX_QUERY_COUNT);
}

private JiraCardWithFields getCardList(URI baseUrl, BoardRequestParam boardRequestParam, String jql,
String cardType) {
String cardType, int queryCount) {
log.info("Start to get first-page xxx card information form kanban, _param {}", cardType);
String allCardResponse = jiraFeignClient.getJiraCards(baseUrl, boardRequestParam.getBoardId(), QUERY_COUNT, 0,
String allCardResponse = jiraFeignClient.getJiraCards(baseUrl, boardRequestParam.getBoardId(), queryCount, 0,
jql, boardRequestParam.getToken());
if (allCardResponse.isEmpty()) {
return JiraCardWithFields.builder().jiraCards(Collections.emptyList()).build();
Expand All @@ -904,9 +907,9 @@ private JiraCardWithFields getCardList(URI baseUrl, BoardRequestParam boardReque
List<TargetField> targetField = getTargetField(baseUrl, boardRequestParam);
AllCardsResponseDTO allCardsResponseDTO = formatAllCards(allCardResponse, targetField);

List<JiraCard> cards = new ArrayList<>(new HashSet<>(allCardsResponseDTO.getIssues()));
List<JiraCard> cards = new ArrayList<>(new LinkedHashSet<>(allCardsResponseDTO.getIssues()));
int pages = (int) Math.ceil(Double.parseDouble(allCardsResponseDTO.getTotal()) / QUERY_COUNT);
if (pages <= 1) {
if (cardType.equals(NONE_DONE_CARD_TAG) || pages <= 1) {
return JiraCardWithFields.builder().jiraCards(cards).targetFields(targetField).build();
}

Expand Down
22 changes: 11 additions & 11 deletions backend/src/test/java/heartbeat/service/jira/JiraServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

import static heartbeat.controller.board.BoardRequestFixture.BOARD_REQUEST_BUILDER;
import static heartbeat.controller.board.dto.request.BoardVerifyRequestFixture.BOARD_VERIFY_REQUEST_BUILDER;
import static heartbeat.service.board.jira.JiraService.NONE_DONE_MAX_QUERY_COUNT;
import static heartbeat.service.board.jira.JiraService.QUERY_COUNT;
import static heartbeat.service.jira.JiraBoardConfigDTOFixture.ALL_DONE_CARDS_RESPONSE_FOR_ASSIGNEE_FILTER_TEST;
import static heartbeat.service.jira.JiraBoardConfigDTOFixture.ALL_DONE_CARDS_RESPONSE_FOR_MULTIPLE_STATUS;
Expand Down Expand Up @@ -512,7 +513,6 @@ void shouldCallJiraFeignClientBoardAndThrowNotFoundWhenVerifyJiraBoard() {
void shouldCallJiraFeignClientAndThrowNotFoundExceptionWhenGetJiraBoardConfig() throws JsonProcessingException {
JiraBoardConfigDTO jiraBoardConfigDTO = JIRA_BOARD_CONFIG_RESPONSE_BUILDER().build();
StatusSelfDTO doneStatusSelf = DONE_STATUS_SELF_RESPONSE_BUILDER().build();
StatusSelfDTO doingStatusSelf = DOING_STATUS_SELF_RESPONSE_BUILDER().build();
URI baseUrl = URI.create(SITE_ATLASSIAN_NET);
String token = "token";
BoardRequestParam boardRequestParam = BOARD_REQUEST_BUILDER().build();
Expand Down Expand Up @@ -1202,14 +1202,14 @@ public void shouldReturnCardsWhenCallGetStoryPointsAndCycleTimeForNonDoneCardsFo
StoryPointsAndCycleTimeRequest storyPointsAndCycleTimeRequest = STORY_POINTS_FORM_ALL_DONE_CARD().build();
BoardRequestParam boardRequestParam = BOARD_REQUEST_BUILDER().build();
String jqlForKanban = "status not in ('" + String.join("','", storyPointsAndCycleTimeRequest.getStatus())
+ "')";
+ "') ORDER BY updated DESC";
String jqlForActiveSprint = "sprint in openSprints() AND status not in ('"
+ String.join("','", storyPointsAndCycleTimeRequest.getStatus()) + "')";
+ String.join("','", storyPointsAndCycleTimeRequest.getStatus()) + "') ORDER BY updated DESC";
when(urlGenerator.getUri(any())).thenReturn(baseUrl);
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, QUERY_COUNT, 0, jqlForActiveSprint,
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, NONE_DONE_MAX_QUERY_COUNT, 0, jqlForActiveSprint,
boardRequestParam.getToken()))
.thenReturn("");
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, QUERY_COUNT, 0, jqlForKanban,
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, NONE_DONE_MAX_QUERY_COUNT, 0, jqlForKanban,
boardRequestParam.getToken()))
.thenReturn(objectMapper.writeValueAsString(ALL_NON_DONE_CARDS_RESPONSE_FOR_STORY_POINT_BUILDER().build()));

Expand All @@ -1232,13 +1232,13 @@ public void shouldReturnCardsWhenCallGetStoryPointsAndCycleTimeForNonDoneCardsFo
StoryPointsAndCycleTimeRequest storyPointsAndCycleTimeRequest = STORY_POINTS_FORM_ALL_DONE_CARD_WITH_EMPTY_STATUS()
.build();
BoardRequestParam boardRequestParam = BOARD_REQUEST_BUILDER().build();
String jqlForKanban = "";
String jqlForActiveSprint = "sprint in openSprints() ";
String jqlForKanban = "ORDER BY updated DESC";
String jqlForActiveSprint = "sprint in openSprints() ORDER BY updated DESC";
when(urlGenerator.getUri(any())).thenReturn(baseUrl);
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, QUERY_COUNT, 0, jqlForActiveSprint,
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, NONE_DONE_MAX_QUERY_COUNT, 0, jqlForActiveSprint,
boardRequestParam.getToken()))
.thenReturn("");
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, QUERY_COUNT, 0, jqlForKanban,
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, NONE_DONE_MAX_QUERY_COUNT, 0, jqlForKanban,
boardRequestParam.getToken()))
.thenReturn(objectMapper.writeValueAsString(ALL_NON_DONE_CARDS_RESPONSE_FOR_STORY_POINT_BUILDER().build()));

Expand All @@ -1260,10 +1260,10 @@ void shouldReturnCardsWithSprintWhenCallGetStoryPointsAndCycleTimeForNonDoneCard
StoryPointsAndCycleTimeRequest storyPointsAndCycleTimeRequest = STORY_POINTS_FORM_ALL_DONE_CARD_WITH_EMPTY_STATUS()
.build();
BoardRequestParam boardRequestParam = BOARD_REQUEST_BUILDER().build();
String jqlForActiveSprint = "sprint in openSprints() ";
String jqlForActiveSprint = "sprint in openSprints() ORDER BY updated DESC";
String allDoneCards = JiraBoardConfigDTOFixture.JIRA_CARD_WITH_TWO_SPRINT;
when(urlGenerator.getUri(any())).thenReturn(baseUrl);
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, QUERY_COUNT, 0, jqlForActiveSprint,
when(jiraFeignClient.getJiraCards(baseUrl, BOARD_ID, NONE_DONE_MAX_QUERY_COUNT, 0, jqlForActiveSprint,
boardRequestParam.getToken()))
.thenReturn(allDoneCards);
when(jiraFeignClient.getTargetField(any(), any(), any())).thenReturn(ALL_FIELD_RESPONSE_BUILDER().build());
Expand Down

0 comments on commit 2522b97

Please sign in to comment.