Skip to content

Commit a2f6561

Browse files
Merge pull request #11 from companieshouse/pci-609-create-order-following-payment
PCI-609: Create order following payment
2 parents 04c1972 + abe11d0 commit a2f6561

File tree

18 files changed

+774
-130
lines changed

18 files changed

+774
-130
lines changed

src/main/java/uk/gov/companieshouse/orders/api/controller/BasketController.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package uk.gov.companieshouse.orders.api.controller;
22

3+
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
34
import org.springframework.http.HttpStatus;
45
import org.springframework.http.ResponseEntity;
56
import org.springframework.web.bind.annotation.PatchMapping;
@@ -17,15 +18,11 @@
1718
import uk.gov.companieshouse.orders.api.exception.ConflictException;
1819
import uk.gov.companieshouse.orders.api.mapper.BasketMapper;
1920
import uk.gov.companieshouse.orders.api.mapper.DeliveryDetailsMapper;
20-
import uk.gov.companieshouse.orders.api.model.ApiError;
21-
import uk.gov.companieshouse.orders.api.model.Basket;
22-
import uk.gov.companieshouse.orders.api.model.Checkout;
23-
import uk.gov.companieshouse.orders.api.model.DeliveryDetails;
24-
import uk.gov.companieshouse.orders.api.model.Item;
25-
import uk.gov.companieshouse.orders.api.model.PaymentStatus;
21+
import uk.gov.companieshouse.orders.api.model.*;
2622
import uk.gov.companieshouse.orders.api.service.ApiClientService;
2723
import uk.gov.companieshouse.orders.api.service.BasketService;
2824
import uk.gov.companieshouse.orders.api.service.CheckoutService;
25+
import uk.gov.companieshouse.orders.api.service.OrderService;
2926
import uk.gov.companieshouse.orders.api.util.EricHeaderHelper;
3027
import uk.gov.companieshouse.orders.api.validator.CheckoutBasketValidator;
3128
import uk.gov.companieshouse.orders.api.validator.DeliveryDetailsValidator;
@@ -55,21 +52,24 @@ public class BasketController {
5552
private final CheckoutBasketValidator checkoutBasketValidator;
5653
private final DeliveryDetailsValidator deliveryDetailsValidator;
5754
private final ApiClientService apiClientService;
55+
private final OrderService orderService;
5856

5957
public BasketController(final BasketMapper mapper,
6058
final DeliveryDetailsMapper deliveryDetailsMapper,
6159
final BasketService basketService,
6260
final CheckoutService checkoutService,
6361
final CheckoutBasketValidator checkoutBasketValidator,
62+
final ApiClientService apiClientService,
6463
final DeliveryDetailsValidator deliveryDetailsValidator,
65-
final ApiClientService apiClientService){
64+
final OrderService orderService){
6665
this.mapper = mapper;
6766
this.deliveryDetailsMapper = deliveryDetailsMapper;
6867
this.basketService = basketService;
6968
this.checkoutService = checkoutService;
7069
this.checkoutBasketValidator = checkoutBasketValidator;
7170
this.deliveryDetailsValidator = deliveryDetailsValidator;
7271
this.apiClientService = apiClientService;
72+
this.orderService = orderService;
7373
}
7474

7575
@PostMapping("${uk.gov.companieshouse.orders.api.basket.items}")
@@ -166,12 +166,28 @@ public ResponseEntity<String> patchBasketPaymentDetails(final @RequestBody Baske
166166
final @RequestHeader(REQUEST_ID_HEADER_NAME) String requestId) {
167167
trace("ENTERING patchBasketPaymentDetails(" + basketPaymentRequestDTO + ", " + id + ", " + requestId + ")", requestId);
168168
if(basketPaymentRequestDTO.getStatus().equals(PaymentStatus.PAID)) {
169-
Basket basket = basketService.clearBasket(EricHeaderHelper.getIdentity(request));
170-
trace("Cleared basket: " + basket, requestId);
169+
processSuccessfulPayment(request, requestId, id);
171170
}
172171
return ResponseEntity.ok("");
173172
}
174173

174+
/**
175+
* Performs the actions required to process a successful payment.
176+
* @param request the request
177+
* @param requestId the request ID
178+
* @param checkoutId the checkout ID
179+
*/
180+
private void processSuccessfulPayment(final HttpServletRequest request,
181+
final String requestId,
182+
final String checkoutId) {
183+
final Checkout checkout = checkoutService.getCheckoutById(checkoutId)
184+
.orElseThrow(ResourceNotFoundException::new);
185+
final Order order = orderService.createOrder(checkout);
186+
trace("Created order: " + order, requestId);
187+
final Basket basket = basketService.clearBasket(EricHeaderHelper.getIdentity(request));
188+
trace("Cleared basket: " + basket, requestId);
189+
}
190+
175191
/**
176192
* Utility method that logs each message with the request ID for log tracing/analysis.
177193
* @param message the message to log

src/main/java/uk/gov/companieshouse/orders/api/converter/StringToEnumConverterFactory.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import org.springframework.core.convert.converter.ConverterFactory;
55
import org.springframework.data.convert.ReadingConverter;
66

7+
import static uk.gov.companieshouse.orders.api.converter.EnumValueNameConverter.convertEnumValueJsonToName;
8+
79
@ReadingConverter
810
public final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
911

@@ -19,8 +21,9 @@ public StringToEnumConverter(Class<T> enumType) {
1921
this.enumType = enumType;
2022
}
2123

24+
@SuppressWarnings("squid:S1905") // SonarQube false positive - cast is necessary.
2225
public T convert(String source) {
23-
return (T) Enum.valueOf(this.enumType, source.trim());
26+
return (T) Enum.valueOf(this.enumType, convertEnumValueJsonToName(source));
2427
}
2528
}
2629
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package uk.gov.companieshouse.orders.api.exception;
2+
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.web.bind.annotation.ResponseStatus;
5+
6+
@ResponseStatus(HttpStatus.FORBIDDEN)
7+
public class ForbiddenException extends RuntimeException {
8+
9+
public ForbiddenException(String message) {
10+
this(message, null);
11+
}
12+
13+
public ForbiddenException(String message, Throwable cause) {
14+
super(message, cause);
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package uk.gov.companieshouse.orders.api.mapper;
2+
3+
import org.mapstruct.Mapper;
4+
import org.mapstruct.Mapping;
5+
import uk.gov.companieshouse.orders.api.model.Checkout;
6+
import uk.gov.companieshouse.orders.api.model.Order;
7+
8+
@Mapper(componentModel = "spring")
9+
public interface CheckoutToOrderMapper {
10+
11+
@Mapping(source = "data.paidAt", target = "data.orderedAt")
12+
@Mapping(source = "data.checkedOutBy", target = "data.orderedBy")
13+
Order checkoutToOrder(Checkout checkout);
14+
15+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import com.google.gson.Gson;
4+
import org.springframework.data.annotation.Id;
5+
6+
import java.time.LocalDateTime;
7+
8+
/**
9+
* Factors out those data fields common to both {@link Checkout} and {@link Order}.
10+
*/
11+
public abstract class AbstractOrder {
12+
@Id
13+
private String id;
14+
15+
private LocalDateTime createdAt;
16+
17+
private LocalDateTime updatedAt;
18+
19+
private String userId;
20+
21+
public String getId() {
22+
return id;
23+
}
24+
25+
public void setId(String id) {
26+
this.id = id;
27+
}
28+
29+
public LocalDateTime getCreatedAt() {
30+
return createdAt;
31+
}
32+
33+
public void setCreatedAt(LocalDateTime createdAt) {
34+
this.createdAt = createdAt;
35+
}
36+
37+
public LocalDateTime getUpdatedAt() {
38+
return updatedAt;
39+
}
40+
41+
public void setUpdatedAt(LocalDateTime updatedAt) {
42+
this.updatedAt = updatedAt;
43+
}
44+
45+
public String getUserId() {
46+
return userId;
47+
}
48+
49+
public void setUserId(String userId) {
50+
this.userId = userId;
51+
}
52+
53+
@Override
54+
public String toString() { return new Gson().toJson(this); }
55+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import com.google.gson.Gson;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
/**
9+
* Factors out those data fields common to both {@link CheckoutData} and {@link OrderData}.
10+
*/
11+
public abstract class AbstractOrderData {
12+
private String paymentReference;
13+
14+
private String etag;
15+
16+
private DeliveryDetails deliveryDetails = new DeliveryDetails();
17+
18+
private List<Item> items = new ArrayList<>();
19+
20+
private String kind;
21+
22+
private Links links;
23+
24+
private String totalBasketCost;
25+
26+
private String reference;
27+
28+
29+
public String getPaymentReference() {
30+
return paymentReference;
31+
}
32+
33+
public void setPaymentReference(String paymentReference) {
34+
this.paymentReference = paymentReference;
35+
}
36+
37+
public String getEtag() {
38+
return etag;
39+
}
40+
41+
public void setEtag(String etag) {
42+
this.etag = etag;
43+
}
44+
45+
public DeliveryDetails getDeliveryDetails() {
46+
return deliveryDetails;
47+
}
48+
49+
public void setDeliveryDetails(DeliveryDetails deliveryDetails) {
50+
this.deliveryDetails = deliveryDetails;
51+
}
52+
53+
public List<Item> getItems() {
54+
return items;
55+
}
56+
57+
public void setItems(List<Item> items) {
58+
this.items = items;
59+
}
60+
61+
public String getKind() {
62+
return kind;
63+
}
64+
65+
public void setKind(String kind) {
66+
this.kind = kind;
67+
}
68+
69+
public Links getLinks() {
70+
return links;
71+
}
72+
73+
public void setLinks(Links links) {
74+
this.links = links;
75+
}
76+
77+
public String getTotalBasketCost() {
78+
return totalBasketCost;
79+
}
80+
81+
public void setTotalBasketCost(String totalBasketCost) {
82+
this.totalBasketCost = totalBasketCost;
83+
}
84+
85+
public String getReference() {
86+
return reference;
87+
}
88+
89+
public void setReference(String reference) {
90+
this.reference = reference;
91+
}
92+
93+
@Override
94+
public String toString() { return new Gson().toJson(this); }
95+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
public class ActionedBy {
4+
private String email;
5+
private String id;
6+
7+
public String getEmail() {
8+
return email;
9+
}
10+
11+
public void setEmail(String email) {
12+
this.email = email;
13+
}
14+
15+
public String getId() {
16+
return id;
17+
}
18+
19+
public void setId(String id) {
20+
this.id = id;
21+
}
22+
}
Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,12 @@
11
package uk.gov.companieshouse.orders.api.model;
22

3-
import org.springframework.data.annotation.Id;
43
import org.springframework.data.mongodb.core.mapping.Document;
54

6-
import java.time.LocalDateTime;
7-
85
@Document(collection = "checkout")
9-
public class Checkout {
10-
@Id
11-
private String id;
12-
13-
private LocalDateTime createdAt;
14-
15-
private LocalDateTime updatedAt;
6+
public class Checkout extends AbstractOrder {
167

178
private CheckoutData data = new CheckoutData();
189

19-
private String userId;
20-
21-
public String getId() {
22-
return id;
23-
}
24-
25-
public void setId(String id) {
26-
this.id = id;
27-
}
28-
29-
public LocalDateTime getCreatedAt() {
30-
return createdAt;
31-
}
32-
33-
public void setCreatedAt(LocalDateTime createdAt) {
34-
this.createdAt = createdAt;
35-
}
36-
37-
public LocalDateTime getUpdatedAt() {
38-
return updatedAt;
39-
}
40-
41-
public void setUpdatedAt(LocalDateTime updatedAt) {
42-
this.updatedAt = updatedAt;
43-
}
44-
4510
public CheckoutData getData() {
4611
return data;
4712
}
@@ -50,11 +15,4 @@ public void setData(CheckoutData data) {
5015
this.data = data;
5116
}
5217

53-
public String getUserId() {
54-
return userId;
55-
}
56-
57-
public void setUserId(String userId) {
58-
this.userId = userId;
59-
}
6018
}

0 commit comments

Comments
 (0)