Skip to content

Commit 99251c8

Browse files
authored
Merge pull request #206 from PublicisSapient/bug/DTS-51847-num-of-check-in-err-valanil
Number of Check-ins - Kanban - Dev dashboard --> Dont Merge
2 parents 596bfda + 7005818 commit 99251c8

File tree

2 files changed

+332
-1
lines changed

2 files changed

+332
-1
lines changed
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
/*
2+
* Copyright 2014 CapitalOne, LLC.
3+
* Further development Copyright 2022 Sapient Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.publicissapient.kpidashboard.apis.bitbucket.service.scm.impl;
19+
20+
import java.time.LocalDateTime;
21+
import java.util.*;
22+
23+
import org.apache.commons.collections4.CollectionUtils;
24+
import org.apache.commons.lang3.tuple.Pair;
25+
import org.bson.types.ObjectId;
26+
import org.springframework.stereotype.Service;
27+
28+
import com.publicissapient.kpidashboard.apis.appsetting.service.ConfigHelperService;
29+
import com.publicissapient.kpidashboard.apis.bitbucket.service.BitBucketKPIService;
30+
import com.publicissapient.kpidashboard.apis.bitbucket.service.scm.ScmKpiHelperService;
31+
import com.publicissapient.kpidashboard.apis.common.service.impl.KpiHelperService;
32+
import com.publicissapient.kpidashboard.apis.constant.Constant;
33+
import com.publicissapient.kpidashboard.apis.enums.KPICode;
34+
import com.publicissapient.kpidashboard.apis.enums.KPIExcelColumn;
35+
import com.publicissapient.kpidashboard.apis.enums.KPISource;
36+
import com.publicissapient.kpidashboard.apis.errors.ApplicationException;
37+
import com.publicissapient.kpidashboard.apis.model.CustomDateRange;
38+
import com.publicissapient.kpidashboard.apis.model.KPIExcelData;
39+
import com.publicissapient.kpidashboard.apis.model.KpiElement;
40+
import com.publicissapient.kpidashboard.apis.model.KpiRequest;
41+
import com.publicissapient.kpidashboard.apis.model.Node;
42+
import com.publicissapient.kpidashboard.apis.repotools.model.RepoToolValidationData;
43+
import com.publicissapient.kpidashboard.apis.util.DeveloperKpiHelper;
44+
import com.publicissapient.kpidashboard.apis.util.KPIExcelUtility;
45+
import com.publicissapient.kpidashboard.apis.util.KpiDataHelper;
46+
import com.publicissapient.kpidashboard.common.model.application.DataCount;
47+
import com.publicissapient.kpidashboard.common.model.application.FieldMapping;
48+
import com.publicissapient.kpidashboard.common.model.application.Tool;
49+
import com.publicissapient.kpidashboard.common.model.application.ValidationData;
50+
import com.publicissapient.kpidashboard.common.model.jira.Assignee;
51+
import com.publicissapient.kpidashboard.common.model.scm.ScmCommits;
52+
import com.publicissapient.kpidashboard.common.util.DateUtil;
53+
54+
import lombok.AllArgsConstructor;
55+
import lombok.extern.slf4j.Slf4j;
56+
57+
/**
58+
* This service is used to calculate the Kanban no of Check-in Request KPI.
59+
*
60+
* @author valanil
61+
*/
62+
@Slf4j
63+
@Service
64+
@AllArgsConstructor
65+
public class ScmKanbanNumberOfChekIns
66+
extends BitBucketKPIService<Long, List<Object>, Map<String, Object>> {
67+
68+
private static final String NO_CHECKIN = "No. of Checkins";
69+
private static final String ASSIGNEE_SET = "assigneeSet";
70+
private static final String COMMIT_LIST = "commitList";
71+
private static final int DAYS_AGO = 21;
72+
73+
private final ConfigHelperService configHelperService;
74+
private final KpiHelperService kpiHelperService;
75+
private final ScmKpiHelperService scmKpiHelperService;
76+
77+
/** {@inheritDoc} */
78+
@Override
79+
public String getQualifierType() {
80+
return KPICode.REPO_TOOL_NUMBER_OF_CHECK_INS.name();
81+
}
82+
83+
@Override
84+
public KpiElement getKpiData(KpiRequest kpiRequest, KpiElement kpiElement, Node projectNode)
85+
throws ApplicationException {
86+
Map<String, Node> nodeMap = Map.of(projectNode.getId(), projectNode);
87+
calculateProjectKpiTrendData(kpiElement, nodeMap, projectNode, kpiRequest);
88+
89+
log.debug(
90+
"[PROJECT-WISE][{}]. Values of leaf node after KPI calculation {}",
91+
kpiRequest.getRequestTrackerId(),
92+
projectNode);
93+
94+
Map<Pair<String, String>, Node> nodeWiseKPIValue = new HashMap<>();
95+
calculateAggregatedValueMap(
96+
projectNode, nodeWiseKPIValue, KPICode.REPO_TOOL_NUMBER_OF_CHECK_INS);
97+
Map<String, List<DataCount>> trendValuesMap =
98+
getTrendValuesMap(
99+
kpiRequest, kpiElement, nodeWiseKPIValue, KPICode.REPO_TOOL_NUMBER_OF_CHECK_INS);
100+
101+
kpiElement.setTrendValueList(
102+
DeveloperKpiHelper.prepareDataCountGroups(
103+
trendValuesMap, KPICode.REPO_TOOL_NUMBER_OF_CHECK_INS.getKpiId()));
104+
kpiElement.setNodeWiseKPIValue(nodeWiseKPIValue);
105+
log.debug(
106+
"[KANBAN-CODE-COMMIT-AGGREGATED-VALUE][{}]. Aggregated Value at each level in the tree {}",
107+
kpiRequest.getRequestTrackerId(),
108+
projectNode);
109+
return kpiElement;
110+
}
111+
112+
/** {@inheritDoc} */
113+
@Override
114+
public Long calculateKPIMetrics(Map<String, Object> t) {
115+
return null;
116+
}
117+
118+
/** {@inheritDoc} */
119+
@Override
120+
public Map<String, Object> fetchKPIDataFromDb(
121+
List<Node> leafNodeList, String startDate, String endDate, KpiRequest kpiRequest) {
122+
Map<String, Object> resultMap = new HashMap<>();
123+
CustomDateRange dateRange = KpiDataHelper.getStartAndEndDate(kpiRequest);
124+
LocalDateTime extendedStartDate = dateRange.getStartDate().atStartOfDay().minusDays(DAYS_AGO);
125+
LocalDateTime endDateTime = dateRange.getEndDate().atTime(23, 59, 59);
126+
127+
CustomDateRange extendedDateRange = new CustomDateRange();
128+
extendedDateRange.setStartDate(extendedStartDate.toLocalDate());
129+
extendedDateRange.setEndDate(endDateTime.toLocalDate());
130+
131+
ObjectId projectBasicConfigId =
132+
leafNodeList.get(0).getProjectFilter().getBasicProjectConfigId();
133+
134+
List<ScmCommits> commits =
135+
scmKpiHelperService.getCommitDetails(projectBasicConfigId, extendedDateRange);
136+
137+
resultMap.put(COMMIT_LIST, commits);
138+
resultMap.put(ASSIGNEE_SET, getScmUsersFromBaseClass());
139+
return resultMap;
140+
}
141+
142+
/** {@inheritDoc} */
143+
@Override
144+
public Long calculateKpiValue(List<Long> valueList, String kpiId) {
145+
return calculateKpiValueForLong(valueList, kpiId);
146+
}
147+
148+
/** {@inheritDoc} */
149+
@Override
150+
public Double calculateThresholdValue(FieldMapping fieldMapping) {
151+
return calculateThresholdValue(
152+
fieldMapping.getThresholdValueKPI159(), KPICode.REPO_TOOL_NUMBER_OF_CHECK_INS.getKpiId());
153+
}
154+
155+
/**
156+
* Populates KPI value to project leaf nodes. It also gives the trend analysis project wise.
157+
*
158+
* @param kpiElement kpi element
159+
* @param mapTmp node map
160+
* @param projectLeafNode leaf node of project
161+
* @param kpiRequest kpi request
162+
*/
163+
@SuppressWarnings("unchecked")
164+
private void calculateProjectKpiTrendData(
165+
KpiElement kpiElement,
166+
Map<String, Node> mapTmp,
167+
Node projectLeafNode,
168+
KpiRequest kpiRequest) {
169+
Map<String, ValidationData> validationMap = new HashMap<>();
170+
List<KPIExcelData> excelData = new ArrayList<>();
171+
LocalDateTime currentDate = DateUtil.getTodayTime();
172+
int dataPoints = kpiRequest.getXAxisDataPoints();
173+
String duration = kpiRequest.getDuration();
174+
175+
List<Tool> scmTools =
176+
DeveloperKpiHelper.getScmToolsForProject(
177+
projectLeafNode, configHelperService, kpiHelperService);
178+
if (CollectionUtils.isEmpty(scmTools)) {
179+
log.error(
180+
"[BITBUCKET-AGGREGATED-VALUE]. No SCM tools found for project {}",
181+
projectLeafNode.getProjectFilter());
182+
return;
183+
}
184+
185+
Map<String, Object> scmDataMap =
186+
fetchKPIDataFromDb(List.of(projectLeafNode), null, null, kpiRequest);
187+
List<ScmCommits> allCommits = (List<ScmCommits>) scmDataMap.get(COMMIT_LIST);
188+
Set<Assignee> assignees = new HashSet<>((Collection<Assignee>) scmDataMap.get(ASSIGNEE_SET));
189+
190+
if (CollectionUtils.isEmpty(allCommits)) {
191+
log.error("[BITBUCKET-AGGREGATED-VALUE]. No commits found for project {}", projectLeafNode);
192+
return;
193+
}
194+
195+
Map<String, List<DataCount>> kpiTrendDataByGroup = new LinkedHashMap<>();
196+
List<RepoToolValidationData> validationDataList = new ArrayList<>();
197+
198+
for (int i = 0; i < dataPoints; i++) {
199+
CustomDateRange periodRange =
200+
KpiDataHelper.getStartAndEndDateTimeForDataFiltering(currentDate, duration);
201+
String dateLabel = KpiHelperService.getDateRange(periodRange, duration);
202+
203+
List<ScmCommits> commitsInRange =
204+
DeveloperKpiHelper.filterCommitsByCommitTimeStamp(allCommits, periodRange);
205+
206+
scmTools.forEach(
207+
tool ->
208+
processToolData(
209+
tool,
210+
commitsInRange,
211+
assignees,
212+
dateLabel,
213+
projectLeafNode.getProjectFilter().getName(),
214+
kpiTrendDataByGroup,
215+
validationDataList));
216+
217+
currentDate = DeveloperKpiHelper.getNextRangeDate(duration, currentDate);
218+
}
219+
220+
mapTmp.get(projectLeafNode.getId()).setValue(kpiTrendDataByGroup);
221+
if (getRequestTrackerIdKanban().toLowerCase().contains(KPISource.EXCEL.name().toLowerCase())) {
222+
KPIExcelUtility.populateCodeCommitKanbanExcelData(validationDataList, excelData);
223+
}
224+
kpiElement.setExcelData(excelData);
225+
kpiElement.setExcelColumns(KPIExcelColumn.REPO_TOOL_CODE_COMMIT_MERGE_KANBAN.getColumns());
226+
kpiElement.setMapOfSprintAndData(validationMap);
227+
}
228+
229+
private void processToolData(
230+
Tool tool,
231+
List<ScmCommits> commits,
232+
Set<Assignee> assignees,
233+
String dateLabel,
234+
String projectName,
235+
Map<String, List<DataCount>> kpiTrendDataByGroup,
236+
List<RepoToolValidationData> validationDataList) {
237+
238+
if (!DeveloperKpiHelper.isValidTool(tool)) {
239+
return;
240+
}
241+
242+
String branchName = getBranchSubFilter(tool, projectName);
243+
String overallKpiGroup = branchName + "#" + Constant.AGGREGATED_VALUE;
244+
245+
List<ScmCommits> commitsForBranch = DeveloperKpiHelper.filterCommitsForBranch(commits, tool);
246+
247+
long totalCommits = commitsForBranch.size();
248+
249+
setDataCount(projectName, dateLabel, overallKpiGroup, totalCommits, kpiTrendDataByGroup);
250+
251+
Map<String, List<ScmCommits>> userWiseAllCommits =
252+
DeveloperKpiHelper.groupCommitsByUser(commitsForBranch);
253+
254+
Set<String> allUsers = userWiseAllCommits.keySet();
255+
256+
allUsers.forEach(
257+
userEmail -> {
258+
String developerName = DeveloperKpiHelper.getDeveloperName(userEmail, assignees);
259+
List<ScmCommits> userCommits =
260+
userWiseAllCommits.getOrDefault(userEmail, Collections.emptyList());
261+
long commitCount = userCommits.size();
262+
String userKpiGroup = branchName + "#" + developerName;
263+
setDataCount(projectName, dateLabel, userKpiGroup, commitCount, kpiTrendDataByGroup);
264+
validationDataList.add(
265+
createValidationData(projectName, tool, developerName, dateLabel, commitCount));
266+
});
267+
}
268+
269+
/**
270+
* set individual data count
271+
*
272+
* @param projectName project name
273+
* @param week date
274+
* @param kpiGroup combined filter
275+
* @param commitValue value
276+
* @param dataCountMap data count map by filter
277+
*/
278+
private void setDataCount(
279+
String projectName,
280+
String week,
281+
String kpiGroup,
282+
Long commitValue,
283+
Map<String, List<DataCount>> dataCountMap) {
284+
List<DataCount> dataCounts = dataCountMap.get(kpiGroup);
285+
Optional<DataCount> optionalDataCount =
286+
dataCounts != null
287+
? dataCounts.stream()
288+
.filter(dataCount1 -> dataCount1.getDate().equals(week))
289+
.findFirst()
290+
: Optional.empty();
291+
if (optionalDataCount.isPresent()) {
292+
DataCount updatedDataCount = optionalDataCount.get();
293+
updatedDataCount.setValue(((Number) updatedDataCount.getValue()).longValue() + commitValue);
294+
dataCounts.set(dataCounts.indexOf(optionalDataCount.get()), updatedDataCount);
295+
} else {
296+
DataCount dataCount = new DataCount();
297+
dataCount.setData(String.valueOf(commitValue));
298+
dataCount.setSProjectName(projectName);
299+
dataCount.setDate(week);
300+
dataCount.setValue(commitValue);
301+
dataCount.setKpiGroup(kpiGroup);
302+
Map<String, Object> hoverValues = new HashMap<>();
303+
hoverValues.put(NO_CHECKIN, commitValue);
304+
dataCount.setHoverValue(hoverValues);
305+
dataCountMap.computeIfAbsent(kpiGroup, k -> new ArrayList<>()).add(dataCount);
306+
}
307+
}
308+
309+
private RepoToolValidationData createValidationData(
310+
String projectName, Tool tool, String developerName, String dateLabel, long commitCount) {
311+
RepoToolValidationData validationData = new RepoToolValidationData();
312+
validationData.setProjectName(projectName);
313+
validationData.setDeveloperName(developerName);
314+
validationData.setBranchName(tool.getBranch());
315+
validationData.setRepoUrl(
316+
tool.getRepositoryName() != null ? tool.getRepositoryName() : tool.getRepoSlug());
317+
validationData.setDate(dateLabel);
318+
validationData.setCommitCount(commitCount);
319+
return validationData;
320+
}
321+
}

src/main/java/com/publicissapient/kpidashboard/apis/userboardconfig/service/UserBoardConfigServiceImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,17 @@ private void setFiltersInfoInBoard(
379379

380380
// Set filters for each type of board
381381
setFiltersForBoards.accept(scrumBoards, 0);
382-
kanbanBoards.forEach(boardDTO -> boardDTO.setFilters(copyFiltersWithoutId(filtersMap.get(1))));
382+
kanbanBoards.forEach(
383+
boardDTO -> {
384+
boolean hasKpi159 =
385+
boardDTO.getKpis() != null
386+
&& boardDTO.getKpis().stream().anyMatch(kpi -> "kpi159".equals(kpi.getKpiId()));
387+
if (hasKpi159) {
388+
boardDTO.setFilters(copyFiltersWithoutId(filtersMap.get(6)));
389+
} else {
390+
boardDTO.setFilters(copyFiltersWithoutId(filtersMap.get(1)));
391+
}
392+
});
383393
setFiltersForBoards.accept(otherBoards, 0);
384394
}
385395

0 commit comments

Comments
 (0)