diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..129a20e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,111 @@
+application.properties
+
+
+# Created by https://www.gitignore.io/api/java,intellij
+# Edit at https://www.gitignore.io/?templates=java,intellij
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+git
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# End of https://www.gitignore.io/api/java,intellij
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index bb087f3..09f7e11 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -9,7 +9,7 @@
-
+
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..e05b8fd
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ postgresql
+ true
+ org.postgresql.Driver
+ jdbc:postgresql://ec2-54-75-230-41.eu-west-1.compute.amazonaws.com:5432/d3e1jrm08qe91q?ssl=true&sslmode=require&=org.postgresql.ssl.NonValidatingFactory
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index dc3894e..94a25f7 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,6 +2,5 @@
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index e7c6a5b..fb65724 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -3,6 +3,9 @@
+
+
+
@@ -22,16 +25,66 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
@@ -40,10 +93,10 @@
-
+
-
-
+
+
@@ -51,36 +104,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -91,8 +116,8 @@
-
-
+
+
@@ -100,23 +125,26 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
@@ -126,11 +154,16 @@
+
+
+ asc
+
+
@@ -144,17 +177,23 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -165,7 +204,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -179,6 +234,7 @@
+
@@ -237,26 +293,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -269,17 +306,17 @@
-
-
+
+
@@ -353,44 +390,120 @@
1547322958782
-
+
+
+
+ 1548121370553
+
+
+
+ 1548121370553
+
+
+ 1548123400861
+
+
+
+ 1548123400861
+
+
+ 1548125729921
+
+
+
+ 1548125729921
+
+
+ 1548126421537
+
+
+
+ 1548126421537
+
+
+ 1548127778120
+
+
+
+ 1548127778120
+
+
+ 1548128278948
+
+
+
+ 1548128278948
+
+
+ 1548128323215
+
+
+
+ 1548128323215
+
+
+ 1548176403757
+
+
+
+ 1548176403757
+
+
+ 1548177602799
+
+
+
+ 1548177602799
+
+
-
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
+
-
+
-
+
@@ -440,9 +553,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -452,78 +577,24 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -537,10 +608,148 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2f79a0b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,247 @@
+# DINO\_SCRUM
+
+## MODEL
+
+###Product
+```json5
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+``id`` - id of product,
+
+``name`` - name of product with minimal length 2;
+
+``price`` price of product, cannot be under 0.00;
+
+``quantity``: quantity of product in database, cannot be under 0;
+
+``quantityMax``: maximum quantity of product in database, cannot be under 0;
+
+``imageLink``: link to image of product
+
+Any of these couldn't be ``null``
+
+## API
+
+###Edit quantity of the product.
+
+The service will handle `POST` requests for `/api/product/change-quantity`, by changing quantity of product in database.
+
+``id`` - product's to change `id`
+
+``change`` - value of change (positive value for increase quantity, negative valude for decrease).
+
+
+```json
+POST /api/product/change-quantity
+Content-Type: application/json
+
+{
+ "id": Int,
+ "change": Int
+}
+```
+
+Response `HttpStatus.OK` with ``JSON``:
+
+```json
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+
+
+* * *
+
+###Retrieve a paginated list of products
+
+The service will handle `GET` requests for `/api/get-all`, by retreving a paginated list of products. Optionally with a `page`, `size` **or** `page`, `size` and`sort` parameters in the query string.
+Page start numbering on `page=0`. Default list is sorted by `id`.
+
+
+```json
+GET /api/get-all?page=0&size=1&sort=id
+Content-Type: application/json
+```
+Response with ``HttpStatus.OK`` with ``JSON`` :
+
+```json
+{
+ "content": [
+ {
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": string
+ },
+ {
+ (...)
+ }
+ ],
+ "pageable": {
+ "sort": {
+ "sorted": Boolean,
+ "unsorted": Boolean,
+ "empty": Boolean
+ },
+ "offset": Int,
+ "pageSize": Int,
+ "pageNumber": Int,
+ "unpaged": Boolean,
+ "paged": Boolean
+ },
+ "totalPages": Int,
+ "totalElements": Int,
+ "last": Boolean,
+ "size": Int,
+ "number": Int,
+ "numberOfElements": Int,
+ "first": Boolean,
+ "sort": {
+ "sorted": Boolean,
+ "unsorted": Boolean,
+ "empty": Boolean
+ },
+ "empty": Boolean
+}
+```
+
+* * *
+###Get price of all products.
+The service will handle `GET` request on `/api/get-price-of-all` returing `Float` price of all products in the database.
+
+```json
+GET /api/get-price-of-all
+Content-Type: application/json
+```
+Response ``Http.Status.OK`` with ``JSON``:
+
+```json
+{
+ "price-of-all": Float
+}
+```
+
+
+* * *
+###Create a new product.
+The service will handle `POST` request `/api/product/add`, by adding `Product` to database.
+
+```json
+POST /api/product/add
+Content-Type: application/json
+
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+Response `HttpStatus.CREATED` with `JSON`
+
+```json
+
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+
+* * *
+###Delete product with `id`.
+The service will handle `DELETE` request `/api/delete-product`, by
+
+```json
+DELETE /api/delete-product
+Content-Type: application/json
+
+{
+ "id": Int
+}
+
+```
+```json
+
+Response: HttpStatus.OK
+
+```
+* * *
+
+###Get product with `id`
+The service wil handle `GET` request `/api/product/get-by-id`, by returning product with `id`.
+
+```json
+GET /api/product/get-by-id
+Content-Type: application/json
+
+{
+ "id": Int
+}
+```
+
+Response ``Http.Status.OK`` with `JSON`:
+
+```json
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+
+* * *
+
+###Update product
+The service will handle ``POST`` request `/api/product/update/{id}` with path variable `id`, by updating existing product. In request
+`id` is required, fields which won't be modified should be `null`.
+
+
+```json
+POST /api/product/update/{id}
+Content-Type: application/json
+
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
+
+Response ``Http.Status.OK`` with `JSON`:
+
+```json
+{
+ "id": Int,
+ "name": String,
+ "price": Float,
+ "quantity": Int,
+ "quantityMax": Int,
+ "imageLink": String
+}
+```
\ No newline at end of file
diff --git a/src/main/java/com/dino/scrum/sysmag/SysmagApplication.java b/src/main/java/com/dino/scrum/sysmag/SysmagApplication.java
index 7a7666a..20ce59f 100644
--- a/src/main/java/com/dino/scrum/sysmag/SysmagApplication.java
+++ b/src/main/java/com/dino/scrum/sysmag/SysmagApplication.java
@@ -6,9 +6,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SysmagApplication {
- public static void main(String[] args) {
- SpringApplication.run(SysmagApplication.class, args);
- }
+ public static void main(String[] args) {
+ SpringApplication.run(SysmagApplication.class, args);
+ }
}
diff --git a/src/main/java/com/dino/scrum/sysmag/controller/HomeController.java b/src/main/java/com/dino/scrum/sysmag/controller/HomeController.java
index 353c1c4..2f5244b 100644
--- a/src/main/java/com/dino/scrum/sysmag/controller/HomeController.java
+++ b/src/main/java/com/dino/scrum/sysmag/controller/HomeController.java
@@ -1,7 +1,6 @@
package com.dino.scrum.sysmag.controller;
import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -12,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
public class HomeController {
@GetMapping("/")
- public String home(){
+ public String home() {
return "System magazynowy";
}
}
diff --git a/src/main/java/com/dino/scrum/sysmag/controller/ProductController.java b/src/main/java/com/dino/scrum/sysmag/controller/ProductController.java
index 3f0ce5e..87572f2 100644
--- a/src/main/java/com/dino/scrum/sysmag/controller/ProductController.java
+++ b/src/main/java/com/dino/scrum/sysmag/controller/ProductController.java
@@ -3,12 +3,19 @@ package com.dino.scrum.sysmag.controller;
import com.dino.scrum.sysmag.model.Product;
import com.dino.scrum.sysmag.model.dto.IdDto;
import com.dino.scrum.sysmag.model.dto.QuantityChange;
-import com.dino.scrum.sysmag.service.ProductService;
import com.dino.scrum.sysmag.service.ProductServiceImpl;
+import com.dino.scrum.sysmag.validationGroup.UpdateGroup;
+import com.dino.scrum.sysmag.validator.QuantityChangeValidator;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+import javax.validation.Valid;
import java.util.Collections;
import java.util.Map;
@@ -16,53 +23,82 @@ import java.util.Map;
* Created by prgres on 2019-01-12.
*/
-@Controller
+@RestController
@RequestMapping(value = "/api")
public class ProductController {
- private final ProductServiceImpl productService;
+ private final
+ ProductServiceImpl productService;
+ private final
+ QuantityChangeValidator quantityChangeValidator;
@Autowired
- public ProductController(ProductServiceImpl productService) {
+ public ProductController(ProductServiceImpl productService, QuantityChangeValidator quantityChangeValidator) {
this.productService = productService;
+ this.quantityChangeValidator = quantityChangeValidator;
}
@GetMapping(value = "/get-all")
- public @ResponseBody
- Iterable getAll(){
- return productService.getAllProducts();
+ public Iterable getAll(@PageableDefault(size = Integer.MAX_VALUE) Pageable pageable) {
+ System.out.println(pageable.getPageSize());
+
+ try {
+ return productService.getAll(pageable);
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
}
-
@GetMapping(value = "/get-price-of-all")
- public @ResponseBody
- Map getPriceOfAllProducts(){
- return Collections.singletonMap("price-of-all", productService.getPriceOfAllProducts());
+ public Map getPriceOfAllProducts() {
+ return Collections.singletonMap("price-of-all", productService.getPriceOfAll());
}
@PostMapping(value = "/product/add")
- public @ResponseBody
- Product addProduct(@RequestBody Product product){
- return productService.addProduct(product);
+ public ResponseEntity addProduct(@Valid @RequestBody Product product) {
+ try {
+ productService.add(product);
+ return new ResponseEntity(product, HttpStatus.CREATED);
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
}
@DeleteMapping(value = "/product/delete")
- public @ResponseBody
- String deleteProduct(@RequestBody IdDto id){
- productService.deleteProduct(id.getId());
- return "Deleted" + id;
+ public ResponseEntity deleteProduct(@RequestBody IdDto id) {
+ try {
+ productService.delete(id.getId());
+ return new ResponseEntity("Deleted" + id, HttpStatus.OK);
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
}
@GetMapping(value = "/product/get-by-id")
- public @ResponseBody
- Product getById(@RequestBody IdDto id){
- return productService.getById(id.getId());
+ public Product getById(@RequestBody IdDto id) {
+ try {
+ return productService.getById(id.getId());
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
+ }
+
+ @PostMapping(value = "/product/update/{id}")
+ public Product update(@Validated(UpdateGroup.class) @RequestBody Product product, @PathVariable("id") long id) {
+ try {
+ return productService.update(product, id);
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
}
@PostMapping(value = "/product/change-quantity")
- public @ResponseBody
- Product changeQuantity(@RequestBody QuantityChange quantityChange){
- return productService.changeQuantity(quantityChange);
+ public Product changeQuantity(@RequestBody QuantityChange quantityChange) {
+ try {
+ quantityChangeValidator.validate(quantityChange);
+ return productService.changeQuantity(quantityChange);
+ } catch (Exception e) {
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.toString());
+ }
}
-
}
\ No newline at end of file
diff --git a/src/main/java/com/dino/scrum/sysmag/exception/ProductNotFoundException.java b/src/main/java/com/dino/scrum/sysmag/exception/ProductNotFoundException.java
new file mode 100644
index 0000000..bf339b6
--- /dev/null
+++ b/src/main/java/com/dino/scrum/sysmag/exception/ProductNotFoundException.java
@@ -0,0 +1,8 @@
+package com.dino.scrum.sysmag.exception;
+
+/**
+ * Created by prgres on 2019-01-21.
+ */
+
+public class ProductNotFoundException extends ClassNotFoundException {
+}
diff --git a/src/main/java/com/dino/scrum/sysmag/model/Product.java b/src/main/java/com/dino/scrum/sysmag/model/Product.java
index bc2d178..ba9b301 100644
--- a/src/main/java/com/dino/scrum/sysmag/model/Product.java
+++ b/src/main/java/com/dino/scrum/sysmag/model/Product.java
@@ -5,6 +5,10 @@ import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
import java.math.BigDecimal;
/**
@@ -23,16 +27,35 @@ public class Product {
@Column(name = "id")
private Long id;
+ @NotNull(message = "name cannot be null")
+ @Size(min = 2, message = "name cannot be shorter that 2")
@Column(name = "name")
private String name;
+ @NotNull(message = "price cannot be null")
+ @DecimalMin(value = "0.00", message = "price cannot be under 0.00")
@Column(name = "price")
private BigDecimal price;
+ @NotNull(message = "quantity cannot be null")
+ @Min(value = 0, message = "quantity cannot be under 0")
@Column(name = "quantity")
private long quantity;
+ @NotNull(message = "quantityMax cannot be null")
+ @Min(value = 1, message = "quantityMax cannot be under 1")
+ @Column(name = "quantityMax")
+ private long quantityMax;
+
+ @NotNull(message = "image_link cannot be null")
@Column(name = "image_link")
private String imageLink;
+ public Product setChangeQuantity(long change) {
+ System.out.println("IN MODEL quantity: " + this.getQuantity() + " change" + change);
+ this.quantity += change;
+ System.out.println("IN MODEL after change quantity: " + this.getQuantity());
+ return this;
+ }
+
}
diff --git a/src/main/java/com/dino/scrum/sysmag/model/dto/IdDto.java b/src/main/java/com/dino/scrum/sysmag/model/dto/IdDto.java
index 0b5e89c..f8e2f26 100644
--- a/src/main/java/com/dino/scrum/sysmag/model/dto/IdDto.java
+++ b/src/main/java/com/dino/scrum/sysmag/model/dto/IdDto.java
@@ -8,5 +8,6 @@ import lombok.Getter;
@Getter
public class IdDto {
+
long id;
}
diff --git a/src/main/java/com/dino/scrum/sysmag/model/dto/QuantityChange.java b/src/main/java/com/dino/scrum/sysmag/model/dto/QuantityChange.java
index 62718fc..81d2881 100644
--- a/src/main/java/com/dino/scrum/sysmag/model/dto/QuantityChange.java
+++ b/src/main/java/com/dino/scrum/sysmag/model/dto/QuantityChange.java
@@ -1,5 +1,6 @@
package com.dino.scrum.sysmag.model.dto;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
/**
@@ -7,6 +8,7 @@ import lombok.Getter;
*/
@Getter
+@EqualsAndHashCode
public class QuantityChange {
long id;
long change;
diff --git a/src/main/java/com/dino/scrum/sysmag/repository/ProductRepository.java b/src/main/java/com/dino/scrum/sysmag/repository/ProductRepository.java
index f1b5f0f..f9aebcb 100644
--- a/src/main/java/com/dino/scrum/sysmag/repository/ProductRepository.java
+++ b/src/main/java/com/dino/scrum/sysmag/repository/ProductRepository.java
@@ -1,16 +1,19 @@
package com.dino.scrum.sysmag.repository;
import com.dino.scrum.sysmag.model.Product;
-import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
-import java.math.BigDecimal;
-import java.util.List;
import java.util.Optional;
/**
* Created by prgres on 2019-01-12.
*/
+@Repository
+public interface ProductRepository extends PagingAndSortingRepository {
+ boolean existsByName(String name);
-public interface ProductRepository extends CrudRepository {
- List findAll();
+ Optional findByName(String name);
+
+ Product findById(long id);
}
diff --git a/src/main/java/com/dino/scrum/sysmag/service/ProductService.java b/src/main/java/com/dino/scrum/sysmag/service/ProductService.java
index 869e29e..2ffd3c5 100644
--- a/src/main/java/com/dino/scrum/sysmag/service/ProductService.java
+++ b/src/main/java/com/dino/scrum/sysmag/service/ProductService.java
@@ -2,19 +2,28 @@ package com.dino.scrum.sysmag.service;
import com.dino.scrum.sysmag.model.Product;
import com.dino.scrum.sysmag.model.dto.QuantityChange;
-
-import java.util.List;
-import java.util.Optional;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
/**
* Created by prgres on 2019-01-12.
*/
public interface ProductService {
- List getAllProducts();
- Product changeQuantity(QuantityChange quantityChange);
- Product getById(Long id);
- float getPriceOfAllProducts();
- Product addProduct(Product product);
- void deleteProduct(long id);
+ Page getAll(Pageable pageable) throws Exception;
+
+ Product changeQuantity(QuantityChange quantityChange) throws Exception;
+
+ Product getById(Long id) throws Exception;
+
+ Product add(Product product) throws Exception;
+
+ Product update(Product product, long id) throws Exception;
+
+ long count();
+
+ float getPriceOfAll();
+
+ void delete(long id) throws Exception;
}
+
diff --git a/src/main/java/com/dino/scrum/sysmag/service/ProductServiceImpl.java b/src/main/java/com/dino/scrum/sysmag/service/ProductServiceImpl.java
index 1c77e15..37fa85f 100644
--- a/src/main/java/com/dino/scrum/sysmag/service/ProductServiceImpl.java
+++ b/src/main/java/com/dino/scrum/sysmag/service/ProductServiceImpl.java
@@ -3,14 +3,15 @@ package com.dino.scrum.sysmag.service;
import com.dino.scrum.sysmag.model.Product;
import com.dino.scrum.sysmag.model.dto.QuantityChange;
import com.dino.scrum.sysmag.repository.ProductRepository;
+import com.dino.scrum.sysmag.validator.ProductValidator;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
-import javax.persistence.EntityNotFoundException;
import java.math.BigDecimal;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
/**
* Created by prgres on 2019-01-12.
@@ -19,57 +20,104 @@ import java.util.stream.Collectors;
@Service
public class ProductServiceImpl implements ProductService {
- private final ProductRepository productRepository;
+ private final
+ ProductRepository productRepository;
+
+ private final
+ ProductValidator productValidator;
@Autowired
- public ProductServiceImpl(ProductRepository productRepository) {
+ public ProductServiceImpl(ProductRepository productRepository, ProductValidator productValidator) {
this.productRepository = productRepository;
+ this.productValidator = productValidator;
}
@Override
- public List getAllProducts() {
- return productRepository.findAll();
+ public Page getAll(Pageable pageable) throws Exception {
+ System.out.println("pagenumber: " + pageable.getPageNumber() + " pageSize: " + pageable.getPageSize() + " sort: " + pageable.getSort());
+
+ if (pageable.getSort().isUnsorted()) {
+ pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), new Sort(Sort.Direction.ASC, "id"));
+ }
+
+ Page productSlice = productRepository.findAll(pageable);
+
+ productValidator.checkIfPageIsOutOfBound(productSlice.getTotalPages(), pageable.getPageNumber());
+
+ return productSlice;
}
@Override
- public Product changeQuantity(QuantityChange quantityChange) {
- return productRepository.findById(quantityChange.getId())
- .map(product -> {
- product.setQuantity(
- product.getQuantity() + quantityChange.getChange()
- );
- return productRepository.save(product);
- }).orElse(null);
+ public Product changeQuantity(QuantityChange quantityChange) throws Exception {
+ productValidator.checkIfNotExists(quantityChange.getId());
+
+ productRepository.save(
+ productRepository.findById(quantityChange.getId())
+ .setChangeQuantity(quantityChange.getChange())
+ );
+
+ return productRepository.findById(quantityChange.getId());
}
@Override
- public Product getById(Long id) {
- return productRepository.findById(id).orElse(null);
+ public Product getById(Long id) throws Exception {
+ productValidator.checkIfNotExists(id);
+ return productRepository.findById(id.longValue());
}
@Override
- public float getPriceOfAllProducts() {
- BigDecimal result = new BigDecimal(0);
- List tempProductList = productRepository.findAll();
+ public float getPriceOfAll() {
+ BigDecimal result = new BigDecimal(0);
+ Iterable tempProductList = productRepository.findAll();
- for (Product product : tempProductList) {
+ for (Product product : tempProductList) {
result = result.add(
product.getPrice()
- .multiply( new BigDecimal(product.getQuantity())));
- }
-
- return result.floatValue();
-
+ .multiply(new BigDecimal(product.getQuantity())));
+ }
+ return result.floatValue();
}
@Override
- public Product addProduct(Product product) {
+ public Product add(Product product) throws Exception {
+ productValidator.checkIfNotExists(product.getName());
return productRepository.save(product);
}
@Override
- public void deleteProduct(long id) {
- productRepository.deleteById(id);
+ public Product update(Product productReceived, long id) throws Exception {
+ productValidator.checkIfNotExists(productReceived.getId());
+
+ Product productToChange = productRepository.findById(id);
+
+ if (productReceived.getName() != null)
+ productToChange.setName(productReceived.getName());
+
+ if (productReceived.getName() != null)
+ productToChange.setPrice(productReceived.getPrice());
+
+ if (productReceived.getName() != null)
+ productToChange.setQuantity(productReceived.getQuantity());
+
+ if (productReceived.getName() != null)
+ productToChange.setQuantityMax(productReceived.getQuantityMax());
+
+ if (productReceived.getName() != null)
+ productToChange.setImageLink(productReceived.getImageLink());
+
+ productRepository.save(productToChange);
+
+ return productRepository.findById(productToChange.getId().longValue());
}
+ @Override
+ public long count() {
+ return productRepository.count();
+ }
+
+ @Override
+ public void delete(long id) throws Exception {
+ productValidator.checkIfNotExists(id);
+ productRepository.deleteById(id);
+ }
}
diff --git a/src/main/java/com/dino/scrum/sysmag/validationGroup/UpdateGroup.java b/src/main/java/com/dino/scrum/sysmag/validationGroup/UpdateGroup.java
new file mode 100644
index 0000000..5f8f3a5
--- /dev/null
+++ b/src/main/java/com/dino/scrum/sysmag/validationGroup/UpdateGroup.java
@@ -0,0 +1,8 @@
+package com.dino.scrum.sysmag.validationGroup;
+
+/**
+ * Created by prgres on 2019-01-22.
+ */
+
+public interface UpdateGroup {
+}
diff --git a/src/main/java/com/dino/scrum/sysmag/validator/ProductValidator.java b/src/main/java/com/dino/scrum/sysmag/validator/ProductValidator.java
new file mode 100644
index 0000000..d3c7654
--- /dev/null
+++ b/src/main/java/com/dino/scrum/sysmag/validator/ProductValidator.java
@@ -0,0 +1,48 @@
+package com.dino.scrum.sysmag.validator;
+
+import com.dino.scrum.sysmag.repository.ProductRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by prgres on 2019-01-22.
+ */
+
+@Component
+public class ProductValidator {
+
+ private final ProductRepository productRepository;
+
+ @Autowired
+ public ProductValidator(ProductRepository productRepository) {
+ this.productRepository = productRepository;
+ }
+
+ private boolean existsById(long id) {
+ return productRepository.existsById(id);
+ }
+
+ private boolean existsByName(String name) {
+ return productRepository.existsByName(name);
+ }
+
+ private boolean ifRequestPageInLimit(int limit, int requestPage) {
+ return requestPage < limit;
+ }
+
+ public void checkIfNotExists(long id) throws Exception {
+ if (!existsById(id))
+ throw new Exception("Product with id: " + id + " not found");
+ System.out.println(id + " exists");
+ }
+
+ public void checkIfNotExists(String name) throws Exception {
+ if (existsByName(name))
+ throw new Exception("Product " + name + " already exists");
+ }
+
+ public void checkIfPageIsOutOfBound(int totalPages, int requestPage) throws Exception {
+ if (ifRequestPageInLimit(requestPage, totalPages))
+ throw new Exception("Page " + requestPage + " is out of the total pages number.");
+ }
+}
diff --git a/src/main/java/com/dino/scrum/sysmag/validator/QuantityChangeValidator.java b/src/main/java/com/dino/scrum/sysmag/validator/QuantityChangeValidator.java
new file mode 100644
index 0000000..915a051
--- /dev/null
+++ b/src/main/java/com/dino/scrum/sysmag/validator/QuantityChangeValidator.java
@@ -0,0 +1,44 @@
+package com.dino.scrum.sysmag.validator;
+
+import com.dino.scrum.sysmag.model.Product;
+import com.dino.scrum.sysmag.model.dto.QuantityChange;
+import com.dino.scrum.sysmag.service.ProductServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by prgres on 2019-01-20.
+ */
+
+@Component
+public class QuantityChangeValidator {
+
+ private final
+ ProductServiceImpl productService;
+
+ @Autowired
+ public QuantityChangeValidator(ProductServiceImpl productService) {
+ this.productService = productService;
+ }
+
+ public void validate(QuantityChange quantityChange) throws Exception {
+
+ Product product = productService.getById(quantityChange.getId());
+
+ if (ifUnderStock(product.getQuantity(), quantityChange.getChange())) {
+ throw new RuntimeException("Too low product with id: " + quantityChange.getId() + " on stock");
+ }
+
+ if (ifAboveMaxLimitStock(product.getQuantity(), product.getQuantityMax(), quantityChange.getChange())) {
+ throw new RuntimeException("Over max quantity limit of product with id: " + quantityChange.getId());
+ }
+ }
+
+ private boolean ifUnderStock(long quantityOfProduct, long quantityChange) {
+ return ((quantityOfProduct + quantityChange) < 0);
+ }
+
+ private boolean ifAboveMaxLimitStock(long quantityOfProduct, long maxQuantityOfProduct, long quantityChange) {
+ return ((quantityOfProduct + quantityChange) > maxQuantityOfProduct);
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644
index 008d38f..0000000
--- a/src/main/resources/application.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# Details for our datasource heroku
-spring.datasource.url=jdbc:postgresql://ec2-54-75-230-41.eu-west-1.compute.amazonaws.com/d3e1jrm08qe91q?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.NonValidatingFactory
-spring.datasource.username=eecsegponwphcn
-spring.datasource.password=4045a1e5a2de22362149709c3a2a1d5eb6e243cd553fd1a15f76fc54923638ce
-spring.datasource.driverClassName=org.postgresql.Driver
-# Hibernate properties
-spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
-spring.jpa.generate-ddl=true
-spring.jpa.show-sql=false
-spring.jpa.hibernate.ddl-auto=validate
-spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
-spring.jpa.properties.hibernate.format_sql=true
-spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
-spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
-#spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
-
diff --git a/src/test/java/com/dino/scrum/sysmag/SysmagApplicationTests.java b/src/test/java/com/dino/scrum/sysmag/SysmagApplicationTests.java
index ecaf828..a646b1d 100644
--- a/src/test/java/com/dino/scrum/sysmag/SysmagApplicationTests.java
+++ b/src/test/java/com/dino/scrum/sysmag/SysmagApplicationTests.java
@@ -9,9 +9,9 @@ import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
public class SysmagApplicationTests {
- @Test
- public void contextLoads() {
- }
+ @Test
+ public void contextLoads() {
+ }
}
diff --git a/target/classes/META-INF/sysmag.kotlin_module b/target/classes/META-INF/sysmag.kotlin_module
new file mode 100644
index 0000000..8fb6019
Binary files /dev/null and b/target/classes/META-INF/sysmag.kotlin_module differ
diff --git a/target/classes/application.properties b/target/classes/application.properties
index 5da0c2b..ea762f5 100644
--- a/target/classes/application.properties
+++ b/target/classes/application.properties
@@ -1,10 +1,16 @@
-# H2
-spring.h2.console.enabled=true
-spring.h2.console.path=/h2
-spring.jpa.hibernate.ddl-auto=create
+# Details for our datasource heroku
+spring.datasource.url=jdbc:postgresql://ec2-54-75-230-41.eu-west-1.compute.amazonaws.com/d3e1jrm08qe91q?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.NonValidatingFactory
+spring.datasource.username=eecsegponwphcn
+spring.datasource.password=4045a1e5a2de22362149709c3a2a1d5eb6e243cd553fd1a15f76fc54923638ce
+spring.datasource.driverClassName=org.postgresql.Driver
+# Hibernate properties
+spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.generate-ddl=true
-# Datasource
-spring.datasource.url=jdbc:h2:file:~/sysmag
-spring.datasource.username=sa
-spring.datasource.password=
-spring.datasource.driver-class-name=org.h2.Driver
\ No newline at end of file
+spring.jpa.show-sql=false
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
+spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
+#spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
+