Skip to content

Commit ccf1951

Browse files
authored
Merge pull request #115 from AnswerConsulting/BENCH-182-TEST
Bench 182
2 parents cd442d8 + 9d32b91 commit ccf1951

24 files changed

+625
-481
lines changed

init_scripts/V1__init.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ CREATE TABLE IF NOT EXISTS product_category (
3434

3535
CREATE TABLE IF NOT EXISTS `order` (
3636
id BIGINT NOT NULL AUTO_INCREMENT,
37-
address VARCHAR(255) NOT NULL,
37+
created_on TIMESTAMP NOT NULL,
38+
last_updated TIMESTAMP NOT NULL,
3839
order_status VARCHAR(255) NOT NULL,
3940

4041
PRIMARY KEY (id)

init_scripts/schema.sql

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
CREATE TABLE IF NOT EXISTS product (
2+
id BIGINT NOT NULL AUTO_INCREMENT,
3+
name VARCHAR(255) NOT NULL,
4+
description VARCHAR(255) NOT NULL,
5+
retired BIT(1) NOT NULL,
6+
price DECIMAL(12,2) NOT NULL,
7+
8+
PRIMARY KEY (id)
9+
);
10+
11+
CREATE TABLE IF NOT EXISTS category (
12+
id BIGINT NOT NULL AUTO_INCREMENT,
13+
name VARCHAR(255),
14+
description VARCHAR(255) NOT NULL,
15+
retired BIT(1) NOT NULL,
16+
17+
PRIMARY KEY (id)
18+
);
19+
20+
CREATE TABLE IF NOT EXISTS product_category (
21+
id BIGINT NOT NULL AUTO_INCREMENT,
22+
product_id BIGINT NOT NULL,
23+
category_id BIGINT NOT NULL,
24+
25+
PRIMARY KEY (id),
26+
FOREIGN KEY (product_id) REFERENCES product(id),
27+
FOREIGN KEY (category_id) REFERENCES category(id)
28+
);
29+
30+
CREATE TABLE IF NOT EXISTS `order` (
31+
id BIGINT NOT NULL AUTO_INCREMENT,
32+
created_on TIMESTAMP NOT NULL,
33+
last_updated TIMESTAMP NOT NULL,
34+
order_status VARCHAR(255) NOT NULL,
35+
36+
PRIMARY KEY (id)
37+
);
38+
39+
CREATE TABLE IF NOT EXISTS order_product (
40+
id BIGINT NOT NULL AUTO_INCREMENT,
41+
order_id BIGINT NOT NULL,
42+
product_id BIGINT NOT NULL,
43+
quantity INT NOT NULL,
44+
45+
PRIMARY KEY (id),
46+
FOREIGN KEY (order_id) REFERENCES `order`(id),
47+
FOREIGN KEY (product_id) REFERENCES product(id)
48+
);
Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,106 @@
11
package com.answerdigital.answerking.controller;
22

3-
import com.answerdigital.answerking.model.Order;
3+
import com.answerdigital.answerking.exception.util.ErrorResponse;
44
import com.answerdigital.answerking.request.OrderRequest;
5+
import com.answerdigital.answerking.response.OrderResponse;
56
import com.answerdigital.answerking.service.OrderService;
7+
import io.swagger.v3.oas.annotations.Operation;
8+
import io.swagger.v3.oas.annotations.media.ArraySchema;
9+
import io.swagger.v3.oas.annotations.media.Content;
10+
import io.swagger.v3.oas.annotations.media.Schema;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
12+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
613
import io.swagger.v3.oas.annotations.tags.Tag;
714
import org.springframework.beans.factory.annotation.Autowired;
815
import org.springframework.http.HttpStatus;
916
import org.springframework.http.ResponseEntity;
10-
import org.springframework.validation.annotation.Validated;
17+
import org.springframework.web.bind.annotation.DeleteMapping;
1118
import org.springframework.web.bind.annotation.GetMapping;
19+
import org.springframework.web.bind.annotation.PathVariable;
1220
import org.springframework.web.bind.annotation.PostMapping;
1321
import org.springframework.web.bind.annotation.PutMapping;
14-
import org.springframework.web.bind.annotation.DeleteMapping;
1522
import org.springframework.web.bind.annotation.RequestBody;
1623
import org.springframework.web.bind.annotation.RequestMapping;
1724
import org.springframework.web.bind.annotation.RestController;
18-
import org.springframework.web.bind.annotation.PathVariable;
1925

2026
import javax.validation.Valid;
2127
import javax.validation.constraints.NotNull;
2228
import java.util.List;
2329

24-
@Validated
25-
@Tag(name = "Orders", description = "Create and manage customer orders.")
2630
@RestController
2731
@RequestMapping(path = "/orders")
32+
@Tag(name = "Orders", description = "Create and manage customer orders.")
2833
public class OrderController {
29-
3034
private final OrderService orderService;
3135

3236
@Autowired
3337
public OrderController(final OrderService orderService) {
3438
this.orderService = orderService;
3539
}
3640

41+
@GetMapping
42+
@Operation(summary = "Get all orders.")
43+
@ApiResponses(value = {
44+
@ApiResponse(responseCode = "200", description = "When all the orders have been returned.",
45+
content = {
46+
@Content(mediaType = "application/json",
47+
array = @ArraySchema(schema = @Schema(implementation = OrderResponse.class)))}
48+
)
49+
})
50+
public ResponseEntity<List<OrderResponse>> getAllOrders() {
51+
return new ResponseEntity<>(orderService.findAll(), HttpStatus.OK);
52+
}
53+
3754
@PostMapping
38-
public ResponseEntity<Order> addOrder(@Valid @RequestBody final OrderRequest orderRequest) {
55+
@Operation(summary = "Create a new order.")
56+
@ApiResponses(value = {
57+
@ApiResponse(responseCode = "201", description = "When the order has been created.",
58+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = OrderResponse.class))}),
59+
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
60+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))})
61+
})
62+
public ResponseEntity<OrderResponse> createOrder(@Valid @RequestBody final OrderRequest orderRequest) {
3963
return new ResponseEntity<>(orderService.addOrder(orderRequest), HttpStatus.CREATED);
4064
}
4165

4266
@GetMapping(path = "/{orderId}")
43-
public ResponseEntity<Order> getOrder(@PathVariable @NotNull final Long orderId) {
44-
return new ResponseEntity<>(orderService.findById(orderId), HttpStatus.CREATED);
67+
@Operation(summary = "Get a single order.")
68+
@ApiResponses(value = {
69+
@ApiResponse(responseCode = "200", description = "When the order with the provided id has been found.",
70+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = OrderResponse.class))}),
71+
@ApiResponse(responseCode = "404", description = "When the order with the given id does not exist.",
72+
content = {@Content(mediaType = "application/problem+json", schema = @Schema(implementation = ErrorResponse.class))})
73+
})
74+
public ResponseEntity<OrderResponse> getOrderById(@PathVariable @NotNull final Long orderId) {
75+
return new ResponseEntity<>(orderService.getOrderResponseById(orderId), HttpStatus.CREATED);
4576
}
4677

4778
@PutMapping("/{orderId}")
48-
public ResponseEntity<Order> updateOrder(@PathVariable @NotNull final Long orderId,
79+
@Operation(summary = "Update an existing order.")
80+
@ApiResponses(value = {
81+
@ApiResponse(responseCode = "200", description = "When the order has been updated.",
82+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = OrderResponse.class))}),
83+
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
84+
content = {@Content(mediaType = "application/problem+json", schema = @Schema(implementation = ErrorResponse.class))}),
85+
@ApiResponse(responseCode = "404", description = "When the order with the given id does not exist.",
86+
content = {@Content(mediaType = "application/problem+json", schema = @Schema(implementation = ErrorResponse.class))})
87+
})
88+
public ResponseEntity<OrderResponse> updateOrder(@PathVariable @NotNull final Long orderId,
4989
@Valid @RequestBody final OrderRequest orderRequest) {
5090
return new ResponseEntity<>(orderService.updateOrder(orderId, orderRequest), HttpStatus.OK);
5191
}
5292

53-
@GetMapping
54-
public ResponseEntity<List<Order>> getAllOrders() {
55-
final List<Order> foundOrders = orderService.findAll();
56-
return new ResponseEntity<>(foundOrders, foundOrders.isEmpty() ? HttpStatus.NO_CONTENT : HttpStatus.OK);
57-
}
58-
59-
@PostMapping(path = "/{orderId}/product/{productId}/quantity/{quantity}")
60-
public ResponseEntity<Order> addProductToBasket(@PathVariable @NotNull final Long orderId,
61-
@PathVariable @NotNull final Long productId,
62-
@PathVariable @NotNull final Integer quantity) {
63-
return new ResponseEntity<>(orderService.addProductToBasket(orderId, productId, quantity), HttpStatus.OK);
64-
}
65-
66-
@DeleteMapping(path = "/{orderId}/product/{productId}")
67-
public ResponseEntity<Void> deleteProductInBasket(@PathVariable @NotNull final Long orderId,
68-
@PathVariable @NotNull final Long productId) {
69-
orderService.deleteProductInBasket(orderId, productId);
70-
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
71-
}
72-
73-
@PutMapping(path = "/{orderId}/product/{productId}/quantity/{quantity}")
74-
public ResponseEntity<Order> updateProductQuantity(@PathVariable @NotNull final Long orderId,
75-
@PathVariable @NotNull final Long productId,
76-
@PathVariable @NotNull final Integer quantity) {
77-
return new ResponseEntity<>(orderService.updateProductQuantity(orderId, productId, quantity), HttpStatus.OK);
93+
@DeleteMapping(path = "/{orderId}")
94+
@Operation(summary = "Cancel an existing order.")
95+
@ApiResponses(value = {
96+
@ApiResponse(responseCode = "200", description = "When the order has been cancelled.",
97+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = OrderResponse.class))}),
98+
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
99+
content = {@Content(mediaType = "application/problem+json", schema = @Schema(implementation = ErrorResponse.class))}),
100+
@ApiResponse(responseCode = "404", description = "When the order with the given id does not exist.",
101+
content = {@Content(mediaType = "application/problem+json", schema = @Schema(implementation = ErrorResponse.class))})
102+
})
103+
public ResponseEntity<OrderResponse> cancelOrder(@PathVariable @NotNull final Long orderId) {
104+
return new ResponseEntity<>(orderService.cancelOrder(orderId), HttpStatus.OK);
78105
}
79106
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.answerdigital.answerking.exception.custom;
2+
3+
import com.answerdigital.answerking.exception.AnswerKingException;
4+
import org.springframework.http.HttpStatus;
5+
6+
public class OrderCancelledException extends AnswerKingException {
7+
private static final String TYPE = "https://www.rfc-editor.org/rfc/rfc7231";
8+
9+
private static final String TITLE = "Order Cancelled Exception";
10+
11+
private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST;
12+
13+
public OrderCancelledException(final String error) {
14+
super(TYPE, TITLE, STATUS, error);
15+
}
16+
}
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
package com.answerdigital.answerking.mapper;
22

33
import com.answerdigital.answerking.model.Order;
4-
import com.answerdigital.answerking.request.OrderRequest;
4+
import com.answerdigital.answerking.response.OrderResponse;
55
import org.mapstruct.Mapper;
6-
import org.mapstruct.Mapping;
7-
import org.mapstruct.MappingTarget;
6+
87
import java.util.Collections;
98

109
@Mapper(componentModel = "spring", imports = Collections.class)
1110
public interface OrderMapper {
1211

13-
@Mapping(target = "orderStatus", constant = "IN_PROGRESS")
14-
@Mapping(target = "lineItems", expression = "java(Collections.EMPTY_SET)")
15-
Order addRequestToOrder(OrderRequest orderRequest);
16-
17-
Order updateOrderRequest(@MappingTarget Order order, OrderRequest orderRequest);
12+
OrderResponse orderToOrderResponse(Order order);
1813
}

src/main/java/com/answerdigital/answerking/mapper/ProductMapper.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,15 @@
66
import org.mapstruct.Mapper;
77
import org.mapstruct.Mapping;
88
import org.mapstruct.MappingTarget;
9-
109
import java.util.List;
11-
import java.util.stream.Collectors;
1210

13-
@Mapper(componentModel = "spring", imports = {List.class, Collectors.class})
11+
@Mapper(componentModel = "spring", imports = {List.class})
1412
public interface ProductMapper {
1513
@Mapping(target = "retired", constant = "false")
1614
Product addRequestToProduct(ProductRequest productRequest);
1715

1816
Product updateRequestToProduct(@MappingTarget Product product, ProductRequest productRequest);
1917

20-
@Mapping(target = "category.products",
21-
expression = "java(category.getProducts().stream().map(product -> product.getId()).collect(Collectors.toList()) )")
2218
ProductResponse convertProductEntityToProductResponse(Product product);
2319

2420
}

src/main/java/com/answerdigital/answerking/model/LineItem.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package com.answerdigital.answerking.model;
22

3-
import com.fasterxml.jackson.annotation.JsonIgnore;
4-
import com.fasterxml.jackson.annotation.JsonInclude;
53
import lombok.AccessLevel;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
66
import lombok.Getter;
77
import lombok.NoArgsConstructor;
88
import lombok.Setter;
9-
import lombok.Builder;
10-
import lombok.AllArgsConstructor;
119

1210
import javax.persistence.Column;
1311
import javax.persistence.Entity;
@@ -32,12 +30,10 @@
3230
public class LineItem {
3331
@Id
3432
@GeneratedValue(strategy = GenerationType.IDENTITY)
35-
@JsonIgnore
3633
private Long id;
3734

38-
@ManyToOne(fetch = FetchType.LAZY, optional = false)
35+
@ManyToOne(fetch = FetchType.EAGER, optional = false)
3936
@JoinColumn(name = "order_id")
40-
@JsonIgnore
4137
private Order order;
4238

4339
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@@ -53,8 +49,7 @@ public LineItem(final Order order, final Product product, final int quantity) {
5349
this.quantity = quantity;
5450
}
5551

56-
@JsonInclude
57-
public BigDecimal getProductTotalPrice() {
52+
public BigDecimal getSubTotal() {
5853
return new BigDecimal(quantity).multiply(product.getPrice()).setScale(2, RoundingMode.DOWN);
5954
}
6055

@@ -63,12 +58,15 @@ public boolean equals(final Object o) {
6358
if (this == o) return true;
6459
if (o == null || getClass() != o.getClass()) return false;
6560
final LineItem lineItem = (LineItem) o;
66-
return id.equals(lineItem.id);
61+
return (
62+
Objects.equals(order, lineItem.order)
63+
&& Objects.equals(product, lineItem.product)
64+
&& Objects.equals(quantity, lineItem.quantity));
6765
}
6866

6967
@Override
7068
public int hashCode() {
71-
return Objects.hash(id);
69+
return Objects.hash(order, product, quantity);
7270
}
7371

7472
@Override

0 commit comments

Comments
 (0)