From 386fedc835f6fd9f5459c9d292c890fdbd876909 Mon Sep 17 00:00:00 2001 From: Leonhard Brunner Date: Tue, 24 Aug 2021 17:04:50 +0200 Subject: [PATCH] ATLDEV-330 Show violations by user --- .../timesheet/activeobjects/Timesheet.java | 5 + .../activeobjects/impl/TimesheetImpl.java | 52 +++++++++ .../jira/timesheet/rest/UserRest.java | 2 + .../rest/json/JsonUserInformation.java | 10 ++ src/main/resources/js/user_information.js | 1 + src/main/resources/user_information.vm | 6 + .../impl/TimesheetEntryServiceImplTest.java | 110 ++++++++++++++++++ 7 files changed, 186 insertions(+) diff --git a/src/main/java/org/catrobat/jira/timesheet/activeobjects/Timesheet.java b/src/main/java/org/catrobat/jira/timesheet/activeobjects/Timesheet.java index 6d3a10a..52cc127 100644 --- a/src/main/java/org/catrobat/jira/timesheet/activeobjects/Timesheet.java +++ b/src/main/java/org/catrobat/jira/timesheet/activeobjects/Timesheet.java @@ -73,4 +73,9 @@ enum State { @Ignore TimesheetEntry[] getEntriesDesc(); + @Ignore + TimesheetEntry[] getEntriesAsc(); + + @Ignore + int calculateViolations(int monitoring_period, int required_hours); } diff --git a/src/main/java/org/catrobat/jira/timesheet/activeobjects/impl/TimesheetImpl.java b/src/main/java/org/catrobat/jira/timesheet/activeobjects/impl/TimesheetImpl.java index 682fd38..3ace7b7 100644 --- a/src/main/java/org/catrobat/jira/timesheet/activeobjects/impl/TimesheetImpl.java +++ b/src/main/java/org/catrobat/jira/timesheet/activeobjects/impl/TimesheetImpl.java @@ -18,7 +18,9 @@ import org.catrobat.jira.timesheet.activeobjects.Timesheet; import org.catrobat.jira.timesheet.activeobjects.TimesheetEntry; +import org.joda.time.DateTime; +import java.time.LocalDateTime; import java.util.*; public class TimesheetImpl { @@ -63,4 +65,54 @@ public final TimesheetEntry[] getEntriesDesc() { Arrays.sort(entries, Comparator.comparing(TimesheetEntry::getBeginDate).reversed()); return entries; } + + public final TimesheetEntry[] getEntriesAsc() { + TimesheetEntry[] entries = timesheet.getEntries(); + Arrays.sort(entries, Comparator.comparing(TimesheetEntry::getBeginDate)); + return entries; + } + + + public final int calculateViolations(int monitoring_period, int required_hours) { + TimesheetEntry[] entries = getEntriesAsc(); + //TODO: add some checks here + if(entries.length == 0 || monitoring_period == 0) { + return 0; + } + DateTime first_entry_date = new DateTime(entries[0].getBeginDate()); + DateTime last_entry_date = new DateTime(entries[entries.length - 1].getBeginDate()); + + DateTime start = first_entry_date.withDayOfMonth(1).plusMonths(1).withTimeAtStartOfDay(); + DateTime end = last_entry_date.withDayOfMonth(1).withTimeAtStartOfDay(); + + DateTime start_t = start.minusMillis(1); + DateTime end_t = start.plusMonths(monitoring_period); + + int required_minutes = required_hours * 60; + int violations = 0; + int i = 0; + DateTime date; + + while(end_t.isBefore(end) || end_t.isEqual(end)) { + int minutes = 0; + + do { + date = new DateTime(entries[i].getBeginDate()); + if(date.isAfter(start_t) && date.isBefore(end_t)) { + minutes += entries[i].getDurationMinutes(); + } + i++; + } + while(date.isBefore(end_t)); + i--; + + if(minutes < required_minutes) { + violations++; + } + + start_t = end_t.minusMillis(1); + end_t = end_t.plusMonths(monitoring_period); + } + return violations; + } } diff --git a/src/main/java/org/catrobat/jira/timesheet/rest/UserRest.java b/src/main/java/org/catrobat/jira/timesheet/rest/UserRest.java index d745c5a..612b83a 100644 --- a/src/main/java/org/catrobat/jira/timesheet/rest/UserRest.java +++ b/src/main/java/org/catrobat/jira/timesheet/rest/UserRest.java @@ -154,6 +154,8 @@ private List timesheetsToJson(List timesheetList jsonUserInformation.setHoursPerMonitoringPeriod(timesheetEntryService.getHours(timesheet, cur_interval.getKey(), cur_interval.getValue())); jsonUserInformation.setHoursPerLastMonitoringPeriod(timesheetEntryService.getHours(timesheet, last_interval.getKey(), last_interval.getValue())); + jsonUserInformation.setViolations(timesheet.calculateViolations(monitoringService.getMonitoring().getPeriod(),monitoringService.getMonitoring().getRequiredHours())); + TimesheetEntry latestInactiveEntry = timesheetEntryService.getLatestInactiveEntry(timesheet); if (latestInactiveEntry != null && (timesheet.getState() == Timesheet.State.INACTIVE || timesheet.getState() == Timesheet.State.INACTIVE_OFFLINE)) { diff --git a/src/main/java/org/catrobat/jira/timesheet/rest/json/JsonUserInformation.java b/src/main/java/org/catrobat/jira/timesheet/rest/json/JsonUserInformation.java index 95581a4..805ac2a 100644 --- a/src/main/java/org/catrobat/jira/timesheet/rest/json/JsonUserInformation.java +++ b/src/main/java/org/catrobat/jira/timesheet/rest/json/JsonUserInformation.java @@ -50,6 +50,8 @@ public class JsonUserInformation { private int timesheetID; @XmlElement private boolean isEnabled; + @XmlElement + private int violations; public JsonUserInformation (Timesheet timesheet) { @@ -205,4 +207,12 @@ public boolean isEnabled() { public void setEnabled(boolean enabled) { isEnabled = enabled; } + + public int getViolations() { + return violations; + } + + public void setViolations(int violations) { + this.violations = violations; + } } diff --git a/src/main/resources/js/user_information.js b/src/main/resources/js/user_information.js index 5952829..e491eb4 100644 --- a/src/main/resources/js/user_information.js +++ b/src/main/resources/js/user_information.js @@ -128,6 +128,7 @@ AJS.toInit(function () { "" + userInformation[i].hoursPerHalfYear + "" + userInformation[i].hoursPerMonitoringPeriod + "" + userInformation[i].hoursPerLastMonitoringPeriod + + "" + userInformation[i].violations + "" + firstEntryDate + "" + latestEntryDate + "" + userInformation[i].latestEntryDescription + diff --git a/src/main/resources/user_information.vm b/src/main/resources/user_information.vm index 3b9fb14..3714fd0 100644 --- a/src/main/resources/user_information.vm +++ b/src/main/resources/user_information.vm @@ -121,6 +121,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry @@ -151,6 +152,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry @@ -181,6 +183,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry @@ -211,6 +214,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry @@ -241,6 +245,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry @@ -271,6 +276,7 @@ Hours last Half Year Hours ($monitoringPeriod) Hours ($lastMonitoringPeriod) + Violations Date of the First Entry Date of the Latest Entry Description of the Latest Entry diff --git a/src/test/java/ut/org/catrobat/jira/timesheet/services/impl/TimesheetEntryServiceImplTest.java b/src/test/java/ut/org/catrobat/jira/timesheet/services/impl/TimesheetEntryServiceImplTest.java index 4881ef2..5bdc62a 100644 --- a/src/test/java/ut/org/catrobat/jira/timesheet/services/impl/TimesheetEntryServiceImplTest.java +++ b/src/test/java/ut/org/catrobat/jira/timesheet/services/impl/TimesheetEntryServiceImplTest.java @@ -557,6 +557,116 @@ public void testCheckParamsPause() throws Exception { pairProgrammingUserName, teamroom); } + @Test + public void TestCalculateViolations() throws ServiceException { + + Timesheet sheet = createTestTimesheet(); + Category category = createTestCategory(); + Team team = createTestTeam(); + + Date inactiveEnd = Date.from(ZonedDateTime.now().minusMonths(6).toInstant()); + + Date begin = Date.from(ZonedDateTime.now().toInstant()); + Date end = Date.from(ZonedDateTime.now().plusHours(1).toInstant()); + String desc = "Debugged this thingy..."; + int pause = 0; + boolean isGoogleDocImport = false; + String jiraTicketID = "ATLDEV-287"; + String pairProgrammingUserName = "TestUser"; + boolean teamroom = false; + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + begin = Date.from(ZonedDateTime.now().minusMonths(1).toInstant()); + end = Date.from(ZonedDateTime.now().minusMonths(1).plusHours(1).toInstant()); + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + begin = Date.from(ZonedDateTime.now().minusMonths(2).toInstant()); + end = Date.from(ZonedDateTime.now().minusMonths(2).plusHours(1).toInstant()); + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + begin = Date.from(ZonedDateTime.now().minusMonths(3).toInstant()); + end = Date.from(ZonedDateTime.now().minusMonths(3).plusHours(1).toInstant()); + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + int monitoring_period = 1; + int required_hours = 25; + int result = sheet.calculateViolations(monitoring_period, required_hours); + Assert.assertEquals(2, result); + } + + @Test + public void TestCalculateViolationsOneEntry() throws ServiceException { + + Timesheet sheet = createTestTimesheet(); + Category category = createTestCategory(); + Team team = createTestTeam(); + + Date inactiveEnd = Date.from(ZonedDateTime.now().minusMonths(6).toInstant()); + + Date begin = Date.from(ZonedDateTime.now().toInstant()); + Date end = Date.from(ZonedDateTime.now().plusHours(1).toInstant()); + String desc = "Debugged this thingy..."; + int pause = 0; + boolean isGoogleDocImport = false; + String jiraTicketID = "ATLDEV-287"; + String pairProgrammingUserName = "TestUser"; + boolean teamroom = false; + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + int monitoring_period = 1; + int required_hours = 25; + int result = sheet.calculateViolations(monitoring_period, required_hours); + Assert.assertEquals(0, result); + } + + @Test + public void TestCalculateViolationsNoTimeBetween() throws ServiceException { + + Timesheet sheet = createTestTimesheet(); + Category category = createTestCategory(); + Team team = createTestTeam(); + + Date inactiveEnd = Date.from(ZonedDateTime.now().minusMonths(6).toInstant()); + + Date begin = Date.from(ZonedDateTime.now().toInstant()); + Date end = Date.from(ZonedDateTime.now().plusHours(1).toInstant()); + String desc = "Debugged this thingy..."; + int pause = 0; + boolean isGoogleDocImport = false; + String jiraTicketID = "ATLDEV-287"; + String pairProgrammingUserName = "TestUser"; + boolean teamroom = false; + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + end = begin; + begin = Date.from(ZonedDateTime.now().minusHours(1).toInstant()); + + service.add(sheet, begin, end, category, desc, pause, team, isGoogleDocImport, inactiveEnd, jiraTicketID, pairProgrammingUserName, teamroom); + + int monitoring_period = 1; + int required_hours = 25; + int result = sheet.calculateViolations(monitoring_period, required_hours); + Assert.assertEquals(0, result); + } + + @Test + public void TestCalculateViolationsNoMonitoring() { + + Timesheet sheet = createTestTimesheet(); + + int monitoring_period = 0; + int required_hours = 25; + int result = sheet.calculateViolations(monitoring_period, required_hours); + Assert.assertEquals(0, result); + } + + public static class MyDatabaseUpdater implements DatabaseUpdater {