Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,41 @@ public void execute(Map<String, Object> map) {

List<Timesheet> timesheetList = sheetService.all();
Config config = configService.getConfiguration();

int inactiveNotified = 0;
int offlineNotified = 0;

for (Timesheet timesheet : timesheetList) {
String userKey = timesheet.getUserKey();
ApplicationUser user = ComponentAccessor.getUserManager().getUserByKey(userKey);


if (user == null) {
logger.warn("User with key {} not found, skipping timesheet {}", userKey, timesheet.getID());
continue;
}

if (timesheet.getEntries().length == 0) { // nothing to do
continue;
}

if (timesheet.getState() == Timesheet.State.INACTIVE_OFFLINE) { // user is offline
informCoordinatorsOffline(user, config);
informTimesheetAdminsOffline(config);
offlineNotified++;
} else if (timesheet.getState() == Timesheet.State.INACTIVE) { // user is inactive
// FIXME: check is not needed if state is correct
TimesheetEntry latestInactiveEntry = entryService.getLatestInactiveEntry(timesheet);
if (latestInactiveEntry != null) {
if (schedulingService.isOlderThanInactiveTime(latestInactiveEntry.getInactiveEndDate())) {
informCoordinatorsInactive(user, config);
inactiveNotified++;
}
}
}
}

// ✅ Algorithm improvement: Summary logging for visibility
logger.info("ActivityNotificationJob finished: {} inactive users notified, {} offline users notified",
inactiveNotified, offlineNotified);
}

private void informCoordinatorsInactive(ApplicationUser user, Config config) {
Expand All @@ -76,18 +91,28 @@ private void informCoordinatorsOffline(ApplicationUser user, Config config) {
private void informTimesheetAdminsOffline(Config config) {
TimesheetAdmin[] timesheetAdmins = config.getTimesheetAdminUsers();
for (TimesheetAdmin timesheetAdmin : timesheetAdmins) {
emailUtil.sendEmail(timesheetAdmin.getEmailAddress(), config.getMailSubjectOfflineState(),
config.getMailBodyOfflineState());
String adminEmail = timesheetAdmin.getEmailAddress();
if (adminEmail != null) {
emailUtil.sendEmail(adminEmail, config.getMailSubjectOfflineState(),
config.getMailBodyOfflineState());
} else {
logger.warn("TimesheetAdmin {} has no email address", timesheetAdmin.getUserKey());
}
}
}

private List<String> getCoordinatorsMailAddress(ApplicationUser user) {
List<String> coordinatorMailAddressList = new LinkedList<>();
for (Team team : teamService.getTeamsOfUser(user.getName())) {
for (String coordinator : teamService.getGroupsForRole(team.getTeamName(), TeamToGroup.Role.COORDINATOR))
coordinatorMailAddressList.add(ComponentAccessor.getUserManager().getUserByName(coordinator).getEmailAddress());
for (Team team : teamService.getTeamsOfUser(user.getUsername())) { // ✅ getUsername instead of deprecated getName()
for (String coordinator : teamService.getGroupsForRole(team.getTeamName(), TeamToGroup.Role.COORDINATOR)) {
ApplicationUser coordinatorUser = ComponentAccessor.getUserManager().getUserByName(coordinator);
if (coordinatorUser != null && coordinatorUser.getEmailAddress() != null) {
coordinatorMailAddressList.add(coordinatorUser.getEmailAddress());
} else {
logger.warn("Coordinator {} not found or has no email address", coordinator);
}
}
}

return coordinatorMailAddressList;
}
}