diff --git a/pom.xml b/pom.xml
index b9ce463c2..e3b302d74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,8 @@
${maven.build.timestamp}
dd.MM.yyyy HH:mm
17
+ 1.5.5.Final
+ 5.6.14.Final
@@ -225,7 +227,11 @@
bootstrap-icons
1.11.3
-
+
+ org.mapstruct
+ mapstruct
+ ${org.mapstruct.version}
+
@@ -273,6 +279,43 @@
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ 17
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${org.mapstruct.version}
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+
+
+ org.hibernate
+ hibernate-jpamodelgen
+ ${org.hibernate.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+
+
+
+
+
+ maven-surefire-plugin
+
+ -Dspring.profiles.active=test
+
diff --git a/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java b/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java
index 0c12a8905..243086ba3 100644
--- a/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java
+++ b/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java
@@ -35,7 +35,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager
@Bean
public WebSecurityCustomizer ignoringCustomizer() {
- return (web) -> web.ignoring().antMatchers("*.png", "/images/**", "/style/**", "/scripts/**", "/webjars/**", "/favicon.ico");
+ return (web) -> web.ignoring().antMatchers("*.png", "/images/**", "/style/**", "/scripts/**", "/webjars/**", "/favicon.ico","/rest/doc/**");
}
@Bean
diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java
new file mode 100644
index 000000000..86f8ee705
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java
@@ -0,0 +1,23 @@
+package org.tb.rest.favorites.adapter_rest;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.FieldDefaults;
+
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@FieldDefaults(level = AccessLevel.PRIVATE)
+@Schema(description = "to save your favorite reports", name = "Favorite")
+public class FavoriteDto {
+ Long id;
+ Long employeeorderId;
+ int hours;
+ int minutes;
+ String comment;
+}
diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java
new file mode 100644
index 000000000..3ae2f74b6
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java
@@ -0,0 +1,21 @@
+package org.tb.rest.favorites.adapter_rest;
+
+import java.util.Collection;
+import org.mapstruct.CollectionMappingStrategy;
+import org.mapstruct.Mapper;
+import org.mapstruct.NullValueCheckStrategy;
+import org.mapstruct.ReportingPolicy;
+import org.tb.rest.favorites.core.Favorite;
+
+@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
+ nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+ unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface FavoriteDtoMapper {
+
+ FavoriteDto map(Favorite favorite);
+ Favorite map(FavoriteDto favorite);
+
+ Collection map(Collection favorites);
+
+
+}
diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java
new file mode 100644
index 000000000..b294ec455
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java
@@ -0,0 +1,63 @@
+package org.tb.rest.favorites.adapter_rest;
+
+import static org.springframework.http.HttpStatus.UNAUTHORIZED;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.Collection;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.mapstruct.factory.Mappers;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ResponseStatusException;
+import org.tb.auth.AuthorizedUser;
+import org.tb.rest.favorites.core.FavoriteService;
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping(path = "/rest/favorite")
+@SecurityRequirement(name = "bearerAuth")
+@Tag(name = "favorite")
+public class FavoriteRestEndpoint {
+
+ private final FavoriteService favoriteService;
+ private final FavoriteDtoMapper favoriteDtoMapper = Mappers.getMapper(FavoriteDtoMapper.class);
+ private final AuthorizedUser authorizedUser;
+
+ @GetMapping(path = "", produces = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseStatus(HttpStatus.OK)
+ @Operation(security = {@SecurityRequirement(name = "bearerAuth")})
+ public Collection getFavorites() {
+ if(!authorizedUser.isAuthenticated()) {
+ throw new ResponseStatusException(UNAUTHORIZED);
+ }
+ return favoriteDtoMapper.map(favoriteService.getFavorites(authorizedUser.getEmployeeId()));
+ }
+
+ @PutMapping(path = "", consumes = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseStatus(HttpStatus.CREATED)
+ @Operation(security = {@SecurityRequirement(name = "bearerAuth")})
+ public FavoriteDto addFavorite(@RequestBody FavoriteDto favorite) {
+ return favoriteDtoMapper.map(favoriteService.addFavorite(favoriteDtoMapper.map(favorite)));
+ }
+
+ @DeleteMapping(path = "/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ @Operation(security = {@SecurityRequirement(name = "bearerAuth")})
+ public void deleteFavorite(@PathVariable long id) {
+ favoriteService.deleteFavorite(id);
+ }
+}
+
+
diff --git a/src/main/java/org/tb/rest/favorites/core/Favorite.java b/src/main/java/org/tb/rest/favorites/core/Favorite.java
new file mode 100644
index 000000000..95f66861e
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/core/Favorite.java
@@ -0,0 +1,34 @@
+package org.tb.rest.favorites.core;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.FieldDefaults;
+
+@Builder
+@Data
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldDefaults(level = AccessLevel.PRIVATE)
+public class Favorite {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ Long id;
+ Long employeeId;
+ Long employeeorderId;
+ Integer hours;
+ Integer minutes;
+ @Lob
+ @Column(columnDefinition = "text")
+ String comment;
+}
diff --git a/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java b/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java
new file mode 100644
index 000000000..04528ac2c
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java
@@ -0,0 +1,13 @@
+package org.tb.rest.favorites.core;
+
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface FavoriteRepository extends CrudRepository,
+ JpaSpecificationExecutor {
+
+ List findAllByEmployeeId(long employeeId);
+}
diff --git a/src/main/java/org/tb/rest/favorites/core/FavoriteService.java b/src/main/java/org/tb/rest/favorites/core/FavoriteService.java
new file mode 100644
index 000000000..2729f21b5
--- /dev/null
+++ b/src/main/java/org/tb/rest/favorites/core/FavoriteService.java
@@ -0,0 +1,45 @@
+package org.tb.rest.favorites.core;
+
+import java.util.Collection;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import org.springframework.web.server.ResponseStatusException;
+import org.tb.auth.AuthorizedUser;
+import org.webjars.NotFoundException;
+
+@Service
+@RequiredArgsConstructor
+public class FavoriteService {
+
+ private final FavoriteRepository favoriteRepository;
+ private final AuthorizedUser authorizedUser;
+
+ public Collection getFavorites(Long employeeId) {
+ return favoriteRepository.findAllByEmployeeId(employeeId);
+ }
+
+ public Favorite addFavorite(Favorite favorite) {
+ favorite.setEmployeeId(authorizedUser.getEmployeeId());
+ try {
+ return favoriteRepository.save(favorite);
+ } catch (DataIntegrityViolationException e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
+ }
+ }
+
+ public void deleteFavorite(long id) {
+ Optional favorite = favoriteRepository.findById(id);
+ if (favorite.isEmpty()) {
+ throw new NotFoundException("Favorite not found");
+ }
+ if (authorizedUser.getEmployeeId().equals(favorite.get().getEmployeeId())) {
+
+ favoriteRepository.deleteById(id);
+ } else {
+ throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not your Favorite");
+ }
+ }
+}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 8deff9366..94e4b6fb9 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -42,3 +42,14 @@ salat:
mail-host: localhost
auth-service:
cache-expiry: 5m
+springdoc:
+ swagger-ui:
+ path: '/rest/doc/'
+ try-it-out-enabled: true
+ api-docs:
+ path: '/rest/doc/api-docs'
+ default-produces-media-type: 'application/json'
+openapi:
+ description: 'Open API Documentation for the Salat Endpoints'
+ version: 0.1
+ title: 'Salat API'
\ No newline at end of file
diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt
new file mode 100644
index 000000000..fc0f742a8
--- /dev/null
+++ b/src/main/resources/banner.txt
@@ -0,0 +1,3 @@
+┏┓ ┓
+┗┓┏┓┃┏┓╋
+┗┛┗┻┗┗┻┗
\ No newline at end of file
diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml
index 9102a9ea0..25ba61449 100644
--- a/src/main/resources/db/changelog/db.changelog-master.yaml
+++ b/src/main/resources/db/changelog/db.changelog-master.yaml
@@ -746,3 +746,43 @@ databaseChangeLog:
referencedTableName: customerorder
referencedColumnNames:
- id
+ - changeSet:
+ id: 21
+ author: jp
+ changes:
+ - createTable:
+ tableName: favorite
+ columns:
+ - column:
+ name: id
+ type: bigint(20)
+ autoIncrement: true
+ constraints:
+ primaryKey: true
+ nullable: false
+ - column:
+ name: employeeId
+ type: bigint(20)
+ constraints:
+ nullable: false
+ - column:
+ name: employeeorderId
+ type: bigint(20)
+ constraints:
+ nullable: false
+ - column:
+ name: hours
+ type: int(11)
+ constraints:
+ nullable: false
+ - column:
+ name: minutes
+ type: int(11)
+ constraints:
+ nullable: false
+ - column:
+ name: comment
+ type: text
+ defaultOnNull: true
+# - include:
+# file: db/changelog/includes/addAllEmployees.sql
\ No newline at end of file
diff --git a/src/main/webapp/welcome/showWelcome.jsp b/src/main/webapp/welcome/showWelcome.jsp
index a71ea10b6..6db5030d2 100644
--- a/src/main/webapp/welcome/showWelcome.jsp
+++ b/src/main/webapp/welcome/showWelcome.jsp
@@ -33,7 +33,7 @@
diff --git a/startDB.bat b/startDB.bat
new file mode 100644
index 000000000..a018d25ac
--- /dev/null
+++ b/startDB.bat
@@ -0,0 +1 @@
+docker-compose -f .\docker-compose-infra.yml up
\ No newline at end of file
diff --git a/testdb/testdb.sql b/testdb/testdb.sql
index 75f677135..569b51024 100644
--- a/testdb/testdb.sql
+++ b/testdb/testdb.sql
@@ -99,7 +99,11 @@ CREATE TABLE `customerorder` (
LOCK TABLES `customerorder` WRITE;
/*!40000 ALTER TABLE `customerorder` DISABLE KEYS */;
-INSERT INTO `customerorder` VALUES (5190,'2006-12-05 13:35:24','mm','EUR',NULL,NULL,'Urlaub','2007-01-01','\0',0,'2007-07-16 12:44:37','adm','Urlaub','---','---','Urlaub','URLAUB',0,NULL,7,3201,1680,1680),(5191,'2006-12-05 13:36:31','mm','EUR',NULL,NULL,'Krankheit','2007-01-01','\0',0,'2007-07-16 12:44:09','adm','Krankheit','---','---','Krankheit','KRANK',0,NULL,7,3201,1680,1680),(180969,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Rumsitzen','2019-09-11','\0',100,NULL,NULL,'Ergonomische Studie','Dörte Dörtersen','Hans Hansmann','Rumsitzen','111',0,'2023-10-21',NULL,181388,178367,178367);
+INSERT INTO `customerorder` VALUES
+ (5190,'2006-12-05 13:35:24','mm','EUR',NULL,NULL,'Urlaub','2007-01-01','\0',0,'2007-07-16 12:44:37','adm','Urlaub','---','---','Urlaub','URLAUB',0,NULL,7,3201,1680,1680),
+ (5191,'2006-12-05 13:36:31','mm','EUR',NULL,NULL,'Krankheit','2007-01-01','\0',0,'2007-07-16 12:44:09','adm','Krankheit','---','---','Krankheit','KRANK',0,NULL,7,3201,1680,1680),
+ (180969,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Rumsitzen','2019-09-11','\0',100,NULL,NULL,'Ergonomische Studie','Dörte Dörtersen','Hans Hansmann','Rumsitzen','111',0,NULL,NULL,181388,178367,178367),
+ (180970,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Fortbildung','2019-09-11','\0',100,NULL,NULL,'Fortbildung','Dörte Dörtersen','Hans Hansmann','Fortbildung','i976',0,NULL,NULL,3201,1680,1680);
/*!40000 ALTER TABLE `customerorder` ENABLE KEYS */;
UNLOCK TABLES;
@@ -222,7 +226,9 @@ CREATE TABLE `employeeorder` (
LOCK TABLES `employeeorder` WRITE;
/*!40000 ALTER TABLE `employeeorder` DISABLE KEYS */;
-INSERT INTO `employeeorder` VALUES (183209,'2019-09-11 04:54:51','bm',NULL,NULL,'2019-09-11',NULL,NULL,'','2022-10-21',NULL,NULL,180662,180692),(183210,'2019-09-11 04:55:00','system',240,0,'2019-09-11',NULL,NULL,' ','2019-12-31',NULL,NULL,180662,60208),(183211,'2019-09-11 04:55:00','system',NULL,NULL,'2019-09-11',NULL,NULL,' ','2019-12-31',NULL,NULL,180662,5861);
+INSERT INTO `employeeorder` VALUES (183209,'2019-09-11 04:54:51','bm',NULL,NULL,'2019-09-11',NULL,NULL,'',NULL,NULL,NULL,180662,180692),
+ (183210,'2019-09-11 04:55:00','system',240,0,'2019-09-11',NULL,NULL,' ',NULL,NULL,NULL,180662,60208),
+ (183211,'2019-09-11 04:55:00','system',NULL,NULL,'2019-09-11',NULL,NULL,' ',NULL,NULL,NULL,180662,5861);
/*!40000 ALTER TABLE `employeeorder` ENABLE KEYS */;
UNLOCK TABLES;
@@ -523,7 +529,9 @@ CREATE TABLE `suborder` (
LOCK TABLES `suborder` WRITE;
/*!40000 ALTER TABLE `suborder` DISABLE KEYS */;
-INSERT INTO `suborder` VALUES (5861,'\0','2006-12-22 14:14:18','adm','EUR',NULL,NULL,'Krankheit 2019','\0','2019-01-01','\0',0,'N','2009-02-02 10:42:35','adm','\0','Krankheit 2019','2019','','','\0','2019-12-31',3,5191,NULL),(60208,'\0','2010-01-04 13:27:24','adm','EUR',NULL,NULL,'Urlaub 2019','\0','2019-01-01','\0',0,'N','2011-05-17 14:23:53','adm','\0','Urlaub 2019','2019','','','\0','2019-12-31',3,5190,NULL),(180692,'','2019-09-11 04:53:23','bm','EUR',NULL,NULL,'Testen der Stuhlpolsterung','\0','2019-09-11','\0',100,'Y',NULL,NULL,'\0','Stuhlpolsterung','111.01','\0','SP1','\0','2023-10-21',NULL,180969,NULL);
+INSERT INTO `suborder` VALUES (5861,'\0','2006-12-22 14:14:18','adm','EUR',NULL,NULL,'Krankheit 2019','\0','2019-01-01','\0',0,'N','2009-02-02 10:42:35','adm','\0','Krankheit 2019','2019','','','\0',NULL,3,5191,NULL),
+ (60208,'\0','2010-01-04 13:27:24','adm','EUR',NULL,NULL,'Urlaub 2019','\0','2019-01-01','\0',0,'N','2011-05-17 14:23:53','adm','\0','Urlaub 2019','2019','','','\0',NULL,3,5190,NULL),
+ (180692,'\0','2019-09-11 04:53:23','bm','EUR',NULL,NULL,'Testen der Stuhlpolsterung','\0','2019-09-11','\0',100,'Y',NULL,NULL,'\0','Stuhlpolsterung','111.01','\0','SP1','\0',NULL,NULL,180969,NULL);
/*!40000 ALTER TABLE `suborder` ENABLE KEYS */;
UNLOCK TABLES;
@@ -649,3 +657,17 @@ UNLOCK TABLES;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-09-11 7:07:08
+
+DROP TABLE IF EXISTS `favorite`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `favorite` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `employeeId`bigint(20) NOT NULL,
+ `employeeorderId` bigint(20) NOT NULL,
+ `hours` int(11) NOT NULL,
+ `minutes` int(11) NOT NULL,
+ `comment` text COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`id`),
+) ENGINE=InnoDB AUTO_INCREMENT=183915 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;