Erweiterungen
This commit is contained in:
@@ -20,6 +20,7 @@ import de.assecutor.votianlt.model.Barcode;
|
||||
import de.assecutor.votianlt.model.Signature;
|
||||
import de.assecutor.votianlt.service.JobHistoryService;
|
||||
import de.assecutor.votianlt.service.EmailService;
|
||||
import de.assecutor.votianlt.model.JobStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
@@ -29,6 +30,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
@@ -450,8 +452,8 @@ public class MessageController {
|
||||
|
||||
emailService.sendTaskCompletionNotification(jobId, taskType, taskIdStr, completedBy);
|
||||
|
||||
// Check if this was the last task and send job completion notification
|
||||
emailService.checkAndSendJobCompletionNotification(jobId, completedBy);
|
||||
// Check if all tasks are completed and handle job completion
|
||||
checkAndHandleJobCompletion(jobId, completedBy);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to send task completion email notification for task {}: {}", taskIdStr,
|
||||
e.getMessage());
|
||||
@@ -467,6 +469,66 @@ public class MessageController {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndHandleJobCompletion(ObjectId jobId, String completedBy) {
|
||||
try {
|
||||
// Check if all tasks for this job are completed
|
||||
var allTasks = taskRepository.findByJobIdOrderByTaskOrderAsc(jobId);
|
||||
if (allTasks.isEmpty()) {
|
||||
log.debug("No tasks found for job {}", jobId);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean allCompleted = allTasks.stream().allMatch(task -> task.isCompleted());
|
||||
|
||||
if (allCompleted) {
|
||||
log.info("All tasks completed for job {}, updating job status and sending completion notification",
|
||||
jobId);
|
||||
|
||||
// Update job status to COMPLETED
|
||||
updateJobStatusToCompleted(jobId);
|
||||
|
||||
// Send completion notification
|
||||
try {
|
||||
emailService.sendJobCompletionNotification(jobId, completedBy);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to send job completion notification for job {}: {}", jobId, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
long completedCount = allTasks.stream().mapToLong(task -> task.isCompleted() ? 1L : 0L).sum();
|
||||
log.debug("Job {} not yet complete: {}/{} tasks completed", jobId, completedCount, allTasks.size());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to check job completion for job {}: {}", jobId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateJobStatusToCompleted(ObjectId jobId) {
|
||||
try {
|
||||
Optional<Job> jobOpt = jobRepository.findById(jobId);
|
||||
if (jobOpt.isEmpty()) {
|
||||
log.warn("Job not found for status update: {}", jobId);
|
||||
return;
|
||||
}
|
||||
|
||||
Job job = jobOpt.get();
|
||||
JobStatus oldStatus = job.getStatus();
|
||||
|
||||
// Only update if not already completed
|
||||
if (job.getStatus() != JobStatus.COMPLETED) {
|
||||
job.setStatus(JobStatus.COMPLETED);
|
||||
job.setUpdatedAt(LocalDateTime.now());
|
||||
jobRepository.save(job);
|
||||
|
||||
log.info("Job status updated from {} to COMPLETED for job {}", oldStatus != null ? oldStatus : "null",
|
||||
job.getJobNumber());
|
||||
} else {
|
||||
log.debug("Job {} already has COMPLETED status", job.getJobNumber());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to update job status to COMPLETED for job {}: {}", jobId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the mapping between userId and clientId for active session
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.assecutor.votianlt.service;
|
||||
|
||||
import de.assecutor.votianlt.model.AppUser;
|
||||
import de.assecutor.votianlt.model.Job;
|
||||
import de.assecutor.votianlt.model.JobStatus;
|
||||
import de.assecutor.votianlt.model.User;
|
||||
import de.assecutor.votianlt.repository.AppUserRepository;
|
||||
import de.assecutor.votianlt.repository.JobRepository;
|
||||
@@ -43,22 +42,9 @@ public class EmailService {
|
||||
Job job = jobOpt.get();
|
||||
|
||||
// Find the app user who completed the task
|
||||
Optional<AppUser> appUserOpt = appUserRepository.findByAppCode(completedBy);
|
||||
if (appUserOpt.isEmpty()) {
|
||||
log.warn("AppUser not found for task completion notification: {}", completedBy);
|
||||
return;
|
||||
}
|
||||
AppUser appUser = appUserOpt.get();
|
||||
|
||||
// Find the owner (User) of the AppUser
|
||||
if (appUser.getOwner() == null) {
|
||||
log.warn("AppUser has no owner for task completion notification: {}", completedBy);
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<User> userOpt = userRepository.findById(appUser.getOwner());
|
||||
Optional<User> userOpt = userRepository.findById(new ObjectId(job.getCreatedBy()));
|
||||
if (userOpt.isEmpty()) {
|
||||
log.warn("Owner user not found for task completion notification: {}", appUser.getOwner());
|
||||
log.warn("User not found for task completion notification: {}", job.getId());
|
||||
return;
|
||||
}
|
||||
User user = userOpt.get();
|
||||
@@ -70,7 +56,7 @@ public class EmailService {
|
||||
}
|
||||
|
||||
// Send email
|
||||
sendEmail(user, job, taskType, taskId, appUser);
|
||||
sendEmail(user, job, taskType);
|
||||
log.info("Task completion notification sent to {} for job {} task {}", user.getEmail(), job.getJobNumber(),
|
||||
taskId);
|
||||
|
||||
@@ -80,7 +66,7 @@ public class EmailService {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendEmail(User user, Job job, String taskType, String taskId, AppUser appUser) {
|
||||
private void sendEmail(User user, Job job, String taskType) {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(smtpUsername);
|
||||
message.setTo(user.getEmail());
|
||||
@@ -88,7 +74,7 @@ public class EmailService {
|
||||
"Aufgabe abgeschlossen - " + (job.getJobNumber() != null ? job.getJobNumber() : "Job " + job.getId()));
|
||||
|
||||
String fullName = buildFullName(user);
|
||||
String appUserName = buildAppUserName(appUser);
|
||||
String appUserName = buildAppUserName(user);
|
||||
String taskTypeName = getTaskTypeDisplayName(taskType);
|
||||
|
||||
StringBuilder body = new StringBuilder();
|
||||
@@ -137,18 +123,15 @@ public class EmailService {
|
||||
return fullName.isEmpty() ? "Benutzer" : fullName;
|
||||
}
|
||||
|
||||
private String buildAppUserName(AppUser appUser) {
|
||||
private String buildAppUserName(User user) {
|
||||
StringBuilder name = new StringBuilder();
|
||||
if (appUser.getVorname() != null && !appUser.getVorname().isBlank()) {
|
||||
name.append(appUser.getVorname()).append(" ");
|
||||
if (user.getFirstname() != null && !user.getFirstname().isBlank()) {
|
||||
name.append(user.getFirstname()).append(" ");
|
||||
}
|
||||
if (appUser.getNachname() != null && !appUser.getNachname().isBlank()) {
|
||||
name.append(appUser.getNachname());
|
||||
if (user.getName() != null && !user.getName().isBlank()) {
|
||||
name.append(user.getName());
|
||||
}
|
||||
String fullName = name.toString().trim();
|
||||
if (fullName.isEmpty() && appUser.getBezeichnung() != null && !appUser.getBezeichnung().isBlank()) {
|
||||
return appUser.getBezeichnung();
|
||||
}
|
||||
return fullName.isEmpty() ? "App-Benutzer" : fullName;
|
||||
}
|
||||
|
||||
@@ -166,54 +149,7 @@ public class EmailService {
|
||||
};
|
||||
}
|
||||
|
||||
private String buildRouteString(Job job) {
|
||||
if (job.getPickupCity() == null && job.getDeliveryCity() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder route = new StringBuilder();
|
||||
if (job.getPickupCity() != null) {
|
||||
route.append(job.getPickupCity());
|
||||
}
|
||||
if (job.getPickupCity() != null && job.getDeliveryCity() != null) {
|
||||
route.append(" → ");
|
||||
}
|
||||
if (job.getDeliveryCity() != null) {
|
||||
route.append(job.getDeliveryCity());
|
||||
}
|
||||
return route.toString();
|
||||
}
|
||||
|
||||
public void checkAndSendJobCompletionNotification(ObjectId jobId, String completedBy) {
|
||||
try {
|
||||
// Check if all tasks for this job are completed
|
||||
var allTasks = taskRepository.findByJobIdOrderByTaskOrderAsc(jobId);
|
||||
if (allTasks.isEmpty()) {
|
||||
log.debug("No tasks found for job {}", jobId);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean allCompleted = allTasks.stream().allMatch(task -> task.isCompleted());
|
||||
|
||||
if (allCompleted) {
|
||||
log.info("All tasks completed for job {}, updating job status and sending completion notification",
|
||||
jobId);
|
||||
|
||||
// Update job status to COMPLETED
|
||||
updateJobStatusToCompleted(jobId);
|
||||
|
||||
// Send completion notification
|
||||
sendJobCompletionNotification(jobId, completedBy);
|
||||
} else {
|
||||
long completedCount = allTasks.stream().mapToLong(task -> task.isCompleted() ? 1L : 0L).sum();
|
||||
log.debug("Job {} not yet complete: {}/{} tasks completed", jobId, completedCount, allTasks.size());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to check job completion for job {}: {}", jobId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendJobCompletionNotification(ObjectId jobId, String completedBy) {
|
||||
public void sendJobCompletionNotification(ObjectId jobId, String completedBy) {
|
||||
try {
|
||||
// Load job
|
||||
Optional<Job> jobOpt = jobRepository.findById(jobId);
|
||||
@@ -224,22 +160,9 @@ public class EmailService {
|
||||
Job job = jobOpt.get();
|
||||
|
||||
// Find the app user who completed the last task
|
||||
Optional<AppUser> appUserOpt = appUserRepository.findByAppCode(completedBy);
|
||||
if (appUserOpt.isEmpty()) {
|
||||
log.warn("AppUser not found for job completion notification: {}", completedBy);
|
||||
return;
|
||||
}
|
||||
AppUser appUser = appUserOpt.get();
|
||||
|
||||
// Find the owner (User) of the AppUser
|
||||
if (appUser.getOwner() == null) {
|
||||
log.warn("AppUser has no owner for job completion notification: {}", completedBy);
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<User> userOpt = userRepository.findById(appUser.getOwner());
|
||||
Optional<User> userOpt = userRepository.findById(new ObjectId(job.getCreatedBy()));
|
||||
if (userOpt.isEmpty()) {
|
||||
log.warn("Owner user not found for job completion notification: {}", appUser.getOwner());
|
||||
log.warn("User not found for job completion notification: {}", completedBy);
|
||||
return;
|
||||
}
|
||||
User user = userOpt.get();
|
||||
@@ -251,7 +174,7 @@ public class EmailService {
|
||||
}
|
||||
|
||||
// Send job completion email
|
||||
sendJobCompletionEmail(user, job, appUser);
|
||||
sendJobCompletionEmail(user, job);
|
||||
log.info("Job completion notification sent to {} for job {}", user.getEmail(), job.getJobNumber());
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -259,7 +182,7 @@ public class EmailService {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendJobCompletionEmail(User user, Job job, AppUser appUser) {
|
||||
private void sendJobCompletionEmail(User user, Job job) {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(smtpUsername);
|
||||
message.setTo(user.getEmail());
|
||||
@@ -267,7 +190,7 @@ public class EmailService {
|
||||
"Job abgeschlossen - " + (job.getJobNumber() != null ? job.getJobNumber() : "Job " + job.getId()));
|
||||
|
||||
String fullName = buildFullName(user);
|
||||
String appUserName = buildAppUserName(appUser);
|
||||
String appUserName = buildAppUserName(user);
|
||||
|
||||
// Count completed tasks
|
||||
var allTasks = taskRepository.findByJobIdOrderByTaskOrderAsc(job.getId());
|
||||
@@ -306,33 +229,6 @@ public class EmailService {
|
||||
mailSender.send(message);
|
||||
}
|
||||
|
||||
private void updateJobStatusToCompleted(ObjectId jobId) {
|
||||
try {
|
||||
Optional<Job> jobOpt = jobRepository.findById(jobId);
|
||||
if (jobOpt.isEmpty()) {
|
||||
log.warn("Job not found for status update: {}", jobId);
|
||||
return;
|
||||
}
|
||||
|
||||
Job job = jobOpt.get();
|
||||
JobStatus oldStatus = job.getStatus();
|
||||
|
||||
// Only update if not already completed
|
||||
if (job.getStatus() != JobStatus.COMPLETED) {
|
||||
job.setStatus(JobStatus.COMPLETED);
|
||||
job.setUpdatedAt(java.time.LocalDateTime.now());
|
||||
jobRepository.save(job);
|
||||
|
||||
log.info("Job status updated from {} to COMPLETED for job {}", oldStatus != null ? oldStatus : "null",
|
||||
job.getJobNumber());
|
||||
} else {
|
||||
log.debug("Job {} already has COMPLETED status", job.getJobNumber());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to update job status to COMPLETED for job {}: {}", jobId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendJobCreationNotification(ObjectId jobId, String createdBy) {
|
||||
try {
|
||||
// Load job
|
||||
|
||||
Reference in New Issue
Block a user