File History: src/main/java/com/paymentlink/controller/api/CartApiController.java

← View file content

File Content at Commit 690c1f6

1 package com.paymentlink.controller.api;
2
3 import com.paymentlink.model.entity.Product;
4 import com.paymentlink.reservation.ReservationService;
5 import com.paymentlink.service.ProductService;
6 import org.springframework.http.HttpStatus;
7 import org.springframework.http.ResponseEntity;
8 import org.springframework.web.bind.annotation.*;
9
10 import java.util.HashMap;
11 import java.util.Map;
12
13 @RestController
14 @RequestMapping("/api/cart")
15 public class CartApiController {
16
17 private final ReservationService reservationService;
18 private final ProductService productService;
19
20 public CartApiController(ReservationService reservationService, ProductService productService) {
21 this.reservationService = reservationService;
22 this.productService = productService;
23 }
24
25 /**
26 * POST /api/cart/reserve - Reserve stock for cart item
27 */
28 @PostMapping("/reserve")
29 public ResponseEntity<Map<String, Object>> reserveStock(
30 @RequestHeader(value = "x-session-id", required = false) String sessionId,
31 @RequestBody Map<String, Object> request) {
32
33 try {
34 if (sessionId == null || sessionId.isEmpty()) {
35 Map<String, Object> error = new HashMap<>();
36 error.put("success", false);
37 error.put("error", "Session ID is required");
38 return ResponseEntity.badRequest().body(error);
39 }
40
41 Long productId = toLong(request.get("productId"));
42 Integer quantity = toInteger(request.get("quantity"));
43
44 // Get product
45 Product product = productService.getProductByIdRaw(productId)
46 .orElseThrow(() -> new IllegalArgumentException("Product not found"));
47
48 // Check if product has stock tracking
49 if (product.getStock() == null) {
50 // Unlimited stock, no reservation needed
51 Map<String, Object> response = new HashMap<>();
52 response.put("success", true);
53 response.put("message", "No reservation needed (unlimited stock)");
54 return ResponseEntity.ok(response);
55 }
56
57 // Reserve stock
58 reservationService.reserve(sessionId, productId, quantity, product.getStock());
59
60 Map<String, Object> response = new HashMap<>();
61 response.put("success", true);
62 response.put("message", "Stock reserved successfully");
63 return ResponseEntity.ok(response);
64
65 } catch (IllegalStateException e) {
66 // Insufficient stock
67 Map<String, Object> error = new HashMap<>();
68 error.put("success", false);
69 error.put("error", e.getMessage());
70 return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
71
72 } catch (Exception e) {
73 Map<String, Object> error = new HashMap<>();
74 error.put("success", false);
75 error.put("error", e.getMessage());
76 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
77 }
78 }
79
80 /**
81 * POST /api/cart/release - Release reservation
82 */
83 @PostMapping("/release")
84 public ResponseEntity<Map<String, Object>> releaseStock(
85 @RequestHeader(value = "x-session-id", required = false) String sessionId,
86 @RequestBody Map<String, Object> request) {
87
88 try {
89 if (sessionId == null || sessionId.isEmpty()) {
90 Map<String, Object> error = new HashMap<>();
91 error.put("success", false);
92 error.put("error", "Session ID is required");
93 return ResponseEntity.badRequest().body(error);
94 }
95
96 Long productId = toLong(request.get("productId"));
97
98 // Release reservation
99 reservationService.release(sessionId, productId);
100
101 Map<String, Object> response = new HashMap<>();
102 response.put("success", true);
103 response.put("message", "Reservation released successfully");
104 return ResponseEntity.ok(response);
105
106 } catch (Exception e) {
107 Map<String, Object> error = new HashMap<>();
108 error.put("success", false);
109 error.put("error", e.getMessage());
110 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
111 }
112 }
113
114 // Helper methods to safely convert Object to Long/Integer
115 private Long toLong(Object value) {
116 if (value == null) return null;
117 if (value instanceof Number) {
118 return ((Number) value).longValue();
119 }
120 if (value instanceof String) {
121 return Long.parseLong((String) value);
122 }
123 throw new IllegalArgumentException("Cannot convert " + value.getClass() + " to Long");
124 }
125
126 private Integer toInteger(Object value) {
127 if (value == null) return null;
128 if (value instanceof Number) {
129 return ((Number) value).intValue();
130 }
131 if (value instanceof String) {
132 return Integer.parseInt((String) value);
133 }
134 throw new IllegalArgumentException("Cannot convert " + value.getClass() + " to Integer");
135 }
136 }
137
138

Commits

Commit Author Date Message File SHA Actions
f0438c2 <f69e50@finnacloud.com> 1766443042 +0300 12/22/2025, 10:37:22 PM increment once more 99540be View
188fc92 <f69e50@finnacloud.com> 1766442998 +0300 12/22/2025, 10:36:38 PM increment 99540be View
4617f76 <f69e50@finnacloud.com> 1766442953 +0300 12/22/2025, 10:35:53 PM rename branch from main to master oops 99540be View
e6d1548 <f69e50@finnacloud.com> 1766442769 +0300 12/22/2025, 10:32:49 PM add initial test workflow file 99540be View
9c24ca4 <f69e50@finnacloud.com> 1766442705 +0300 12/22/2025, 10:31:45 PM add CI configuration and test script for Jenkins build 99540be View
690c1f6 <f69e50@finnacloud.com> 1766368110 +0300 12/22/2025, 1:48:30 AM initialize backend structure with controllers, DTOs, and configuration files 99540be Hide