Implement custom record searches
Create record overview projection Add today search with scoped principal Add sample data for records
This commit is contained in:
parent
3310062138
commit
9f8fd0af1e
@ -0,0 +1,26 @@
|
|||||||
|
package de.hft.geotime.controllers;
|
||||||
|
|
||||||
|
import de.hft.geotime.repositories.RecordRepository;
|
||||||
|
import de.hft.geotime.repositories.TimetrackUserRepository;
|
||||||
|
import org.springframework.data.projection.ProjectionFactory;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class RecordController {
|
||||||
|
|
||||||
|
private final RecordRepository recordRepository;
|
||||||
|
private final TimetrackUserRepository userRepository;
|
||||||
|
private final ProjectionFactory projectionFactory;
|
||||||
|
|
||||||
|
public RecordController(RecordRepository recordRepository, TimetrackUserRepository userRepository, ProjectionFactory projectionFactory) {
|
||||||
|
this.recordRepository = recordRepository;
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.projectionFactory = projectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/track")
|
||||||
|
public void track() {
|
||||||
|
//"/track?accountid=bla" → start/stop recording for that account
|
||||||
|
}
|
||||||
|
}
|
@ -5,8 +5,8 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.time.Duration;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -17,11 +17,20 @@ public class TimeRecord {
|
|||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private long id;
|
private long id;
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
|
||||||
|
@ManyToOne
|
||||||
private TimetrackAccount account;
|
private TimetrackAccount account;
|
||||||
private Date startdate;
|
|
||||||
private Date enddate;
|
@Column(columnDefinition = "TIMESTAMP")
|
||||||
private Duration time;
|
private LocalDateTime startdate;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "TIMESTAMP")
|
||||||
|
private LocalDateTime enddate;
|
||||||
|
|
||||||
private RecordType type;
|
private RecordType type;
|
||||||
|
|
||||||
|
public long getDuration() {
|
||||||
|
return startdate.until(enddate, ChronoUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package de.hft.geotime.entities;
|
package de.hft.geotime.entities;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -18,7 +20,12 @@ public class TimetrackAccount {
|
|||||||
private double revenue;
|
private double revenue;
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@JsonBackReference
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private TimetrackUser user;
|
private TimetrackUser user;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "account")
|
||||||
|
private List<TimeRecord> records;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.hft.geotime.entities;
|
package de.hft.geotime.entities;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -28,10 +29,11 @@ public class TimetrackUser {
|
|||||||
|
|
||||||
private String lastname;
|
private String lastname;
|
||||||
|
|
||||||
@OneToOne(fetch = FetchType.EAGER)
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
private Role role;
|
private Role role;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
@JsonManagedReference
|
||||||
|
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
|
||||||
private List<TimetrackAccount> accounts;
|
private List<TimetrackAccount> accounts;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package de.hft.geotime.entities.projections;
|
||||||
|
|
||||||
|
import de.hft.geotime.entities.TimeRecord;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.data.rest.core.config.Projection;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Projection(name = "overview", types = TimeRecord.class)
|
||||||
|
public interface RecordOverviewProjection {
|
||||||
|
|
||||||
|
LocalDateTime getStartdate();
|
||||||
|
|
||||||
|
LocalDateTime getEnddate();
|
||||||
|
|
||||||
|
long getDuration();
|
||||||
|
|
||||||
|
@Value("#{target.type.name()}")
|
||||||
|
String getType();
|
||||||
|
|
||||||
|
@Value("#{target.account.name}")
|
||||||
|
String getAccount();
|
||||||
|
|
||||||
|
@Value("#{target.account.user.username}")
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package de.hft.geotime.repositories;
|
package de.hft.geotime.repositories;
|
||||||
|
|
||||||
import de.hft.geotime.entities.TimeRecord;
|
import de.hft.geotime.entities.TimeRecord;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||||
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.util.List;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@RepositoryRestResource(
|
@RepositoryRestResource(
|
||||||
path = "records",
|
path = "records",
|
||||||
@ -14,4 +18,34 @@ import java.util.List;
|
|||||||
)
|
)
|
||||||
public interface RecordRepository extends PagingAndSortingRepository<TimeRecord, Long> {
|
public interface RecordRepository extends PagingAndSortingRepository<TimeRecord, Long> {
|
||||||
|
|
||||||
|
@RestResource(rel = "allBetween", path = "allBetween")
|
||||||
|
Page<TimeRecord> findAllByStartdateBetween(
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime start,
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime end,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@RestResource(rel = "allBetweenAndUser", path = "allBetweenAndUser")
|
||||||
|
Page<TimeRecord> findAllByStartdateBetweenAndAccount_User_Username(
|
||||||
|
LocalDateTime start,
|
||||||
|
LocalDateTime end,
|
||||||
|
String username,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@RestResource(rel = "allForUser", path = "allForUser")
|
||||||
|
Page<TimeRecord> findAllByAccount_User_Username(String username, Pageable pageable);
|
||||||
|
|
||||||
|
@RestResource(rel = "allForUserAndAccount", path = "allForUserAndAccount")
|
||||||
|
Page<TimeRecord> findAllByAccount_User_UsernameAndAccount_Name(String username, String account, Pageable pageable);
|
||||||
|
|
||||||
|
@RestResource(rel = "allFrom", path = "allFrom")
|
||||||
|
Page<TimeRecord> findAllByStartdateGreaterThanEqual(
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime date,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@Query("SELECT record from TimeRecord record where record.account.user.username = :#{principal} AND record.startdate > (current_date-1)")
|
||||||
|
Page<TimeRecord> today(Pageable pageable);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package de.hft.geotime.security;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class SecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
EvaluationContextExtension securityExtension() {
|
||||||
|
return new SecurityEvaluationContextExtension();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package de.hft.geotime.security;
|
||||||
|
|
||||||
|
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||||
|
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
public class SecurityEvaluationContextExtension implements EvaluationContextExtension {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExtensionId() {
|
||||||
|
return "security";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SecurityExpressionRoot getRootObject() {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
return new SecurityExpressionRoot(authentication) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -20,8 +20,15 @@ INSERT INTO timetrack_user (id, firstname, lastname, password, username, role_id
|
|||||||
(3, 'Tim', 'Zieger' ,'$2y$10$pYGHZhoaelceImO7aIN4nOkWJBp.oqNGFYaRAonHkYF4u9ljqPelC', 'ziti', 1, 1),
|
(3, 'Tim', 'Zieger' ,'$2y$10$pYGHZhoaelceImO7aIN4nOkWJBp.oqNGFYaRAonHkYF4u9ljqPelC', 'ziti', 1, 1),
|
||||||
(4, 'Simon', 'Kellner' ,'$2y$10$Puzm/Nr/Dyq3nQxlkXGIfubS5JPtXJSOf2e6mrQ6HhVYQN9YiQQsC', 'kesi', 1, 1);
|
(4, 'Simon', 'Kellner' ,'$2y$10$Puzm/Nr/Dyq3nQxlkXGIfubS5JPtXJSOf2e6mrQ6HhVYQN9YiQQsC', 'kesi', 1, 1);
|
||||||
|
|
||||||
INSERT INTO timetrack_account (description, `name`, revenue, user_id) VALUES
|
INSERT INTO timetrack_account (id, description, `name`, revenue, user_id) VALUES
|
||||||
('Gleitzeit Marcel', 'Primary Marcel', 16.0, 1),
|
(1, 'Gleitzeit Marcel', 'Primary', 16.0, 1),
|
||||||
('Festgeld Marcel', 'Secondary Marcel', 25.0, 1);
|
(2, 'Festgeld Marcel', 'Secondary', 25.0, 1),
|
||||||
|
(3, 'Festgeld Tim', 'Primary', 25.0, 3);
|
||||||
|
|
||||||
|
INSERT INTO time_record (id, enddate, startdate, `type`, account_id) VALUES
|
||||||
|
(1, '2020-05-10 16:00:00', '2020-05-10 12:00:00', 0, 1),
|
||||||
|
(2, '2020-05-09 16:00:00', '2020-05-09 12:00:00', 1, 1),
|
||||||
|
(3, '2020-05-20 16:00:00', '2020-05-20 00:00:00', 1, 2),
|
||||||
|
(4, '2020-05-11 16:00:00', '2020-05-11 12:00:00', 1, 3);
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
Loading…
Reference in New Issue
Block a user