Files
qavion-time-tracker-assessment/backend/src/main/java/com/example/app/project/ProjectService.java
T

84 lines
2.9 KiB
Java

package com.example.app.project;
import com.example.app.project.ProjectDtos.CreateProjectRequest;
import com.example.app.project.ProjectDtos.ProjectResponse;
import com.example.app.project.ProjectDtos.UpdateProjectRequest;
import com.example.app.time.TimeEntryRepository;
import jakarta.persistence.EntityNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ProjectService {
private final ProjectRepository projectRepository;
private final TimeEntryRepository timeEntryRepository;
public ProjectService(
ProjectRepository projectRepository, TimeEntryRepository timeEntryRepository) {
this.projectRepository = projectRepository;
this.timeEntryRepository = timeEntryRepository;
}
@Transactional(readOnly = true)
public List<ProjectResponse> findAll() {
List<Project> projects = projectRepository.findAll();
// one aggregate query for totals across all entries
Map<Long, long[]> totals = new HashMap<>();
for (Object[] row : timeEntryRepository.aggregateAllByProject()) {
long projectId = ((Number) row[0]).longValue();
long minutes = ((Number) row[1]).longValue();
long cost = ((Number) row[2]).longValue();
totals.put(projectId, new long[] {minutes, cost});
}
return projects.stream()
.map(
p -> {
long[] t = totals.getOrDefault(p.getId(), new long[] {0, 0});
return ProjectResponse.from(p, t[0], t[1]);
})
.toList();
}
@Transactional
public ProjectResponse create(CreateProjectRequest req) {
Project p = new Project();
p.setName(req.name());
p.setTimeBudgetMinutes(req.timeBudgetMinutes());
p.setCostBudgetCents(req.costBudgetCents());
p.setHourlyRateCents(req.hourlyRateCents());
Project saved = projectRepository.save(p);
return ProjectResponse.from(saved, 0, 0);
}
@Transactional
public ProjectResponse update(Long id, UpdateProjectRequest req) {
Project project =
projectRepository
.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Project not found: " + id));
project.setName(req.name());
project.setTimeBudgetMinutes(req.timeBudgetMinutes());
project.setCostBudgetCents(req.costBudgetCents());
project.setHourlyRateCents(req.hourlyRateCents());
Project saved = projectRepository.save(project);
long[] totals = new long[] {0, 0};
for (Object[] row : timeEntryRepository.aggregateAllByProject()) {
long projectId = ((Number) row[0]).longValue();
if (projectId == saved.getId()) {
totals[0] = ((Number) row[1]).longValue();
totals[1] = ((Number) row[2]).longValue();
break;
}
}
return ProjectResponse.from(saved, totals[0], totals[1]);
}
}