-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
ShoppingCartsController.java
156 lines (137 loc) · 4.93 KB
/
ShoppingCartsController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package io.eventdriven.ecommerce.api.controller;
import io.eventdriven.ecommerce.api.requests.ShoppingCartsRequests;
import io.eventdriven.ecommerce.core.http.ETag;
import io.eventdriven.ecommerce.shoppingcarts.ShoppingCartService;
import io.eventdriven.ecommerce.shoppingcarts.gettingbyid.GetShoppingCartById;
import io.eventdriven.ecommerce.shoppingcarts.gettingbyid.ShoppingCartDetails;
import io.eventdriven.ecommerce.shoppingcarts.gettingcarts.GetShoppingCarts;
import io.eventdriven.ecommerce.shoppingcarts.gettingcarts.ShoppingCartShortInfo;
import io.eventdriven.ecommerce.shoppingcarts.productitems.PricedProductItem;
import io.eventdriven.ecommerce.shoppingcarts.productitems.ProductItem;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.UUID;
@Validated
@RestController
@RequestMapping("api/shopping-carts")
class ShoppingCartsController {
private final ShoppingCartService shoppingCartsService;
ShoppingCartsController(
ShoppingCartService shoppingCartsService
) {
this.shoppingCartsService = shoppingCartsService;
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
ResponseEntity<Void> open(
@Valid @RequestBody ShoppingCartsRequests.Open request
) throws URISyntaxException {
var cartId = UUID.randomUUID();
var result = shoppingCartsService.open(cartId,request.clientId());
return ResponseEntity
.created(new URI("api/shopping-carts/%s".formatted(cartId)))
.eTag(result.value())
.build();
}
@PostMapping("{id}/products")
ResponseEntity<Void> addProduct(
@PathVariable UUID id,
@RequestBody ShoppingCartsRequests.AddProduct request,
@RequestHeader(name = HttpHeaders.IF_MATCH) @Parameter(in = ParameterIn.HEADER, required = true, schema = @Schema(type = "string")) @NotNull ETag ifMatch
) {
if (request.productItem() == null)
throw new IllegalArgumentException("Product Item has to be defined");
var result = shoppingCartsService.addProductItem(
id,
new ProductItem(
request.productItem().productId(),
request.productItem().quantity()
),
ifMatch.toLong()
);
return ResponseEntity
.ok()
.eTag(result.value())
.build();
}
@DeleteMapping("{id}/products/{productId}")
ResponseEntity<Void> removeProduct(
@PathVariable UUID id,
@PathVariable UUID productId,
@RequestParam @NotNull Integer quantity,
@RequestParam @NotNull Double price,
@RequestHeader(name = HttpHeaders.IF_MATCH) @Parameter(in = ParameterIn.HEADER, required = true, schema = @Schema(type = "string")) @NotNull ETag ifMatch
) {
var result = shoppingCartsService.removeProductItem(
id,
new PricedProductItem(
new ProductItem(
productId,
quantity
),
price
),
ifMatch.toLong()
);
return ResponseEntity
.ok()
.eTag(result.value())
.build();
}
@PutMapping("{id}")
ResponseEntity<Void> confirmCart(
@PathVariable UUID id,
@RequestHeader(name = HttpHeaders.IF_MATCH) @Parameter(in = ParameterIn.HEADER, required = true, schema = @Schema(type = "string")) @NotNull ETag ifMatch
) {
var result = shoppingCartsService.confirm(id, ifMatch.toLong());
return ResponseEntity
.ok()
.eTag(result.value())
.build();
}
@DeleteMapping("{id}")
ResponseEntity<Void> cancelCart(
@PathVariable UUID id,
@RequestHeader(name = HttpHeaders.IF_MATCH) @Parameter(in = ParameterIn.HEADER, required = true, schema = @Schema(type = "string")) @NotNull ETag ifMatch
) {
var result = shoppingCartsService.cancel(id, ifMatch.toLong());
return ResponseEntity
.ok()
.eTag(result.value())
.build();
}
@GetMapping("{id}")
ResponseEntity<ShoppingCartDetails> getById(
@PathVariable UUID id,
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH) @Parameter(in = ParameterIn.HEADER, schema = @Schema(type = "string")) @Nullable ETag ifNoneMatch
) {
var result = shoppingCartsService
.getById(new GetShoppingCartById(id, ifNoneMatch));
return ResponseEntity
.ok()
.eTag(ETag.weak(result.getVersion()).value())
.body(result);
}
@GetMapping
List<ShoppingCartShortInfo> get(
@RequestParam @Nullable Integer pageNumber,
@RequestParam @Nullable Integer pageSize
) {
return shoppingCartsService
.getShoppingCarts(GetShoppingCarts.of(pageNumber, pageSize))
.stream()
.toList();
}
}