Erweiterungen
This commit is contained in:
@@ -2,11 +2,16 @@ package de.assecutor.votianlt.controller;
|
|||||||
|
|
||||||
import de.assecutor.votianlt.dto.AppLoginRequest;
|
import de.assecutor.votianlt.dto.AppLoginRequest;
|
||||||
import de.assecutor.votianlt.dto.AppLoginResponse;
|
import de.assecutor.votianlt.dto.AppLoginResponse;
|
||||||
|
import de.assecutor.votianlt.dto.JobWithRelatedDataDTO;
|
||||||
import de.assecutor.votianlt.model.AppUser;
|
import de.assecutor.votianlt.model.AppUser;
|
||||||
|
import de.assecutor.votianlt.model.CargoItem;
|
||||||
import de.assecutor.votianlt.model.Job;
|
import de.assecutor.votianlt.model.Job;
|
||||||
|
import de.assecutor.votianlt.model.TaskEntry;
|
||||||
import de.assecutor.votianlt.pages.service.AppUserService;
|
import de.assecutor.votianlt.pages.service.AppUserService;
|
||||||
import de.assecutor.votianlt.repository.AppUserRepository;
|
import de.assecutor.votianlt.repository.AppUserRepository;
|
||||||
|
import de.assecutor.votianlt.repository.CargoItemRepository;
|
||||||
import de.assecutor.votianlt.repository.JobRepository;
|
import de.assecutor.votianlt.repository.JobRepository;
|
||||||
|
import de.assecutor.votianlt.repository.TaskRepository;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||||
import org.springframework.messaging.handler.annotation.SendTo;
|
import org.springframework.messaging.handler.annotation.SendTo;
|
||||||
@@ -40,6 +45,12 @@ public class MessageController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private JobRepository jobRepository;
|
private JobRepository jobRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CargoItemRepository cargoItemRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TaskRepository taskRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles messages sent to /app/message and broadcasts them to all subscribers of /topic/messages
|
* Handles messages sent to /app/message and broadcasts them to all subscribers of /topic/messages
|
||||||
*/
|
*/
|
||||||
@@ -151,20 +162,20 @@ public class MessageController {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLoginResponse response = new AppLoginResponse(true, "Anmeldung erfolgreich", user.getId() != null ? user.getId().toHexString() : null);
|
AppLoginResponse response = new AppLoginResponse(true, "Anmeldung erfolgreich", user.getIdAsString());
|
||||||
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}', appUserId='{}'",
|
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}', appUserId='{}'",
|
||||||
true, "Anmeldung erfolgreich", response.getAppUserId());
|
true, "Anmeldung erfolgreich", response.getAppUserId());
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint to retrieve jobs assigned to a specific app user.
|
* Endpoint to retrieve jobs assigned to a specific app user with related cargo items and tasks.
|
||||||
* Client sends to /app/jobs/assigned with payload { appUserId }.
|
* Client sends to /app/jobs/assigned with payload { appUserId }.
|
||||||
* The response is sent back to the requesting user on /user/queue/jobs
|
* The response is sent back to the requesting user on /user/queue/jobs
|
||||||
*/
|
*/
|
||||||
@MessageMapping("/jobs/assigned")
|
@MessageMapping("/jobs/assigned")
|
||||||
@SendToUser("/queue/jobs")
|
@SendToUser("/queue/jobs")
|
||||||
public List<Job> handleGetAssignedJobs(Map<String, Object> request) {
|
public List<JobWithRelatedDataDTO> handleGetAssignedJobs(Map<String, Object> request) {
|
||||||
log.info("STOMP Endpoint '/app/jobs/assigned' called with data: {}", request);
|
log.info("STOMP Endpoint '/app/jobs/assigned' called with data: {}", request);
|
||||||
|
|
||||||
if (request == null || !request.containsKey("appUserId")) {
|
if (request == null || !request.containsKey("appUserId")) {
|
||||||
@@ -180,9 +191,19 @@ public class MessageController {
|
|||||||
|
|
||||||
// Find jobs assigned to this app user
|
// Find jobs assigned to this app user
|
||||||
List<Job> assignedJobs = jobRepository.findByAppUser(appUserId);
|
List<Job> assignedJobs = jobRepository.findByAppUser(appUserId);
|
||||||
log.info("STOMP Response for '/app/jobs/assigned' sent to '/user/queue/jobs': {} jobs found for appUserId='{}'",
|
|
||||||
assignedJobs.size(), appUserId);
|
|
||||||
|
|
||||||
return assignedJobs;
|
// For each job, fetch related cargo items and tasks
|
||||||
|
List<JobWithRelatedDataDTO> jobsWithRelatedData = assignedJobs.stream()
|
||||||
|
.map(job -> {
|
||||||
|
List<CargoItem> cargoItems = cargoItemRepository.findByJobId(job.getId());
|
||||||
|
List<TaskEntry> tasks = taskRepository.findByJobId(job.getId());
|
||||||
|
return new JobWithRelatedDataDTO(job, cargoItems, tasks);
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
log.info("STOMP Response for '/app/jobs/assigned' sent to '/user/queue/jobs': {} jobs with related data found for appUserId='{}'",
|
||||||
|
jobsWithRelatedData.size(), appUserId);
|
||||||
|
|
||||||
|
return jobsWithRelatedData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package de.assecutor.votianlt.dto;
|
||||||
|
|
||||||
|
import de.assecutor.votianlt.model.CargoItem;
|
||||||
|
import de.assecutor.votianlt.model.Job;
|
||||||
|
import de.assecutor.votianlt.model.TaskEntry;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for returning job data with related cargo items and tasks.
|
||||||
|
* This combines Job entity with its associated CargoItems and TaskEntries.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class JobWithRelatedDataDTO {
|
||||||
|
private Job job;
|
||||||
|
private List<CargoItem> cargoItems;
|
||||||
|
private List<TaskEntry> tasks;
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.assecutor.votianlt.model;
|
package de.assecutor.votianlt.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
@@ -13,6 +15,7 @@ import java.time.LocalDateTime;
|
|||||||
public class AppUser {
|
public class AppUser {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@JsonIgnore
|
||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
@Field("bezeichnung")
|
@Field("bezeichnung")
|
||||||
@@ -62,4 +65,13 @@ public class AppUser {
|
|||||||
this.erstelltAm = LocalDateTime.now();
|
this.erstelltAm = LocalDateTime.now();
|
||||||
this.aktualisiertAm = LocalDateTime.now();
|
this.aktualisiertAm = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ObjectId as string for JSON serialization.
|
||||||
|
* This ensures that the app user id is returned as a string when users are retrieved via API.
|
||||||
|
*/
|
||||||
|
@JsonGetter("id")
|
||||||
|
public String getIdAsString() {
|
||||||
|
return id != null ? id.toString() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.assecutor.votianlt.model;
|
package de.assecutor.votianlt.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -14,6 +16,7 @@ import org.springframework.data.mongodb.core.mapping.Field;
|
|||||||
@Document(collection = "cargo_items")
|
@Document(collection = "cargo_items")
|
||||||
public class CargoItem {
|
public class CargoItem {
|
||||||
@Id
|
@Id
|
||||||
|
@JsonIgnore
|
||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
@Field("job_id")
|
@Field("job_id")
|
||||||
@@ -36,5 +39,14 @@ public class CargoItem {
|
|||||||
|
|
||||||
@Field("height_mm")
|
@Field("height_mm")
|
||||||
private Double heightMm;
|
private Double heightMm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ObjectId as string for JSON serialization.
|
||||||
|
* This ensures that the cargo item id is returned as a string when items are retrieved via API.
|
||||||
|
*/
|
||||||
|
@JsonGetter("id")
|
||||||
|
public String getIdAsString() {
|
||||||
|
return id != null ? id.toString() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.assecutor.votianlt.model;
|
package de.assecutor.votianlt.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
@@ -14,6 +16,7 @@ import java.math.BigDecimal;
|
|||||||
@Document(collection = "jobs")
|
@Document(collection = "jobs")
|
||||||
public class Job {
|
public class Job {
|
||||||
@Id
|
@Id
|
||||||
|
@JsonIgnore
|
||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
// Metadaten
|
// Metadaten
|
||||||
@@ -122,4 +125,13 @@ public class Job {
|
|||||||
// Preis (netto)
|
// Preis (netto)
|
||||||
@Field("price")
|
@Field("price")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ObjectId as string for JSON serialization.
|
||||||
|
* This ensures that the job id is returned as a string when jobs are retrieved via API.
|
||||||
|
*/
|
||||||
|
@JsonGetter("id")
|
||||||
|
public String getIdAsString() {
|
||||||
|
return id != null ? id.toString() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.assecutor.votianlt.model;
|
package de.assecutor.votianlt.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -14,12 +16,32 @@ import org.springframework.data.mongodb.core.mapping.Field;
|
|||||||
@Document(collection = "tasks")
|
@Document(collection = "tasks")
|
||||||
public class TaskEntry {
|
public class TaskEntry {
|
||||||
@Id
|
@Id
|
||||||
|
@JsonIgnore
|
||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
@Field("job_id")
|
@Field("job_id")
|
||||||
|
@JsonIgnore
|
||||||
private ObjectId jobId;
|
private ObjectId jobId;
|
||||||
|
|
||||||
@Field("text")
|
@Field("text")
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ObjectId as string for JSON serialization.
|
||||||
|
* This ensures that the task id is returned as a string when jobs are retrieved via API.
|
||||||
|
*/
|
||||||
|
@JsonGetter("id")
|
||||||
|
public String getIdAsString() {
|
||||||
|
return id != null ? id.toString() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the job ObjectId as string for JSON serialization.
|
||||||
|
* This ensures that the job id is returned as a string instead of ObjectId object.
|
||||||
|
*/
|
||||||
|
@JsonGetter("jobId")
|
||||||
|
public String getJobIdAsString() {
|
||||||
|
return jobId != null ? jobId.toString() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
60
src/test/java/JsonSerializationTest.java
Normal file
60
src/test/java/JsonSerializationTest.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import de.assecutor.votianlt.dto.JobWithRelatedDataDTO;
|
||||||
|
import de.assecutor.votianlt.model.CargoItem;
|
||||||
|
import de.assecutor.votianlt.model.Job;
|
||||||
|
import de.assecutor.votianlt.model.TaskEntry;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple test to verify JSON serialization of ObjectIds as strings
|
||||||
|
*/
|
||||||
|
public class JsonSerializationTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("[DEBUG_LOG] Testing Job ID serialization...");
|
||||||
|
|
||||||
|
// Create test data
|
||||||
|
Job job = new Job();
|
||||||
|
job.setId(new ObjectId());
|
||||||
|
job.setJobNumber("TEST-001");
|
||||||
|
|
||||||
|
CargoItem cargo = new CargoItem();
|
||||||
|
cargo.setId(new ObjectId());
|
||||||
|
cargo.setJobId(job.getId());
|
||||||
|
cargo.setDescription("Test cargo");
|
||||||
|
|
||||||
|
TaskEntry task = new TaskEntry();
|
||||||
|
task.setId(new ObjectId());
|
||||||
|
task.setJobId(job.getId());
|
||||||
|
task.setText("Test task");
|
||||||
|
|
||||||
|
JobWithRelatedDataDTO dto = new JobWithRelatedDataDTO(job, List.of(cargo), List.of(task));
|
||||||
|
|
||||||
|
// Serialize to JSON
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String json = mapper.writeValueAsString(dto);
|
||||||
|
|
||||||
|
System.out.println("[DEBUG_LOG] Serialized JSON: " + json);
|
||||||
|
|
||||||
|
// Check if job ID is serialized as string
|
||||||
|
if (json.contains("\"id\":\"" + job.getId().toString() + "\"")) {
|
||||||
|
System.out.println("[DEBUG_LOG] ✓ Job ID correctly serialized as string");
|
||||||
|
} else if (json.contains("\"id\":{")) {
|
||||||
|
System.out.println("[DEBUG_LOG] ✗ Job ID serialized as ObjectId object");
|
||||||
|
} else {
|
||||||
|
System.out.println("[DEBUG_LOG] ? Job ID serialization format unclear");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test individual Job serialization
|
||||||
|
String jobJson = mapper.writeValueAsString(job);
|
||||||
|
System.out.println("[DEBUG_LOG] Individual Job JSON: " + jobJson);
|
||||||
|
|
||||||
|
if (jobJson.contains("\"id\":\"" + job.getId().toString() + "\"")) {
|
||||||
|
System.out.println("[DEBUG_LOG] ✓ Individual Job ID correctly serialized as string");
|
||||||
|
} else {
|
||||||
|
System.out.println("[DEBUG_LOG] ✗ Individual Job ID not serialized as string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user