Commit: 188fc92

Commit Details

SHA188fc92ac938e5ecdaaba64fb6d1dbffeba30181
Tree2cc04755c4f7f8be29aafd7e581f1f25e14edd58
Author<f69e50@finnacloud.com> 1766442998 +0300
Committer<f69e50@finnacloud.com> 1766442998 +0300
Message
increment
GPG Signature
-----BEGIN PGP SIGNATURE-----

iQJSBAABCAA8FiEEWJb139mJI+vZ81KkoAIVSUsXI0oFAmlJx/YeHHNvcGhpYS5l
cmFzbGFuQGZpbm5hY2xvdWQuY29tAAoJEKACFUlLFyNKyF8P/j6F8McjkGTBhDFX
frSY0CqkszvNegnZnDj4AkVjoJl7AK0RY0KLLQxrRUJq/MIA/FPj9G7df9jUJcae
TS+tvTZzWOXZ3EXomyNPangFgm5yAgmelwJYgeQdTmzIY3miM8/BdQg10GNC6Fjq
iEn6PKkpkItfiy+vftAABqe73SI9Vn6nwkUn2zVEsXBX1Kmv/ya9auodjFegvcbz
pRx5BL3xNYaA57c8WG9Fx+XaQPdaeLMcu/kM8diY0XTWqtdR+OfrPlU2JOApB0yO
G4P6zG6h5w2XWCqtbqfszDt94drbArJ9cQbWLlgbiNjpK+qJVvG+HGXxPGgvzLA3
9HhZxzUJobkt0MycngmZryj25b6kdO6OA5BCBCjdMkHjIvmBpLXYD5y5uYnerR0n
YEDyB5noRAiYbb2Skg1dp9dpNxq5LF1WkJpWM+nCXlOU6jKj3ucOJ7JP2+gVWA7N
jFdEUIfX65Q9CcBQqQX1vWyGJCc/Z0sNGE0Dc06PrpPk/U10oFNZOdCbUNEWU4Pk
yqATdaAI1BdvZjAip6QQ/jtIuHkwigAk9uUp21VlZ1NnXXLixmA53y12fi8f3DnB
yl55qYeoTOyEg5N7k1ukOt5rgoJ28szscEwvYmwL56uDtlrXly/vrSNrMi322aJK
IJeozLKMpf6Q9A3vN000vGTA6VjP
=Whh7
-----END PGP SIGNATURE-----

✓ Verified

File: src/main/java/com/paymentlink/service/OrderService.java

1 package com.paymentlink.service;
2
3 import com.paymentlink.model.entity.Order;
4 import com.paymentlink.model.entity.OrderItem;
5 import com.paymentlink.model.entity.Product;
6 import com.paymentlink.repository.OrderRepository;
7 import com.paymentlink.reservation.ReservationService;
8 import com.paymentlink.util.IdGenerator;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.springframework.stereotype.Service;
12 import org.springframework.transaction.annotation.Transactional;
13
14 import java.util.List;
15 import java.util.Optional;
16
17 @Service
18 public class OrderService {
19
20 private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
21
22 private final OrderRepository orderRepository;
23 private final ProductService productService;
24 private final TaxService taxService;
25 private final ShippingService shippingService;
26 private final ReservationService reservationService;
27 private final NodeIdService nodeIdService;
28
29 public OrderService(OrderRepository orderRepository,
30 ProductService productService,
31 TaxService taxService,
32 ShippingService shippingService,
33 ReservationService reservationService,
34 NodeIdService nodeIdService) {
35 this.orderRepository = orderRepository;
36 this.productService = productService;
37 this.taxService = taxService;
38 this.shippingService = shippingService;
39 this.reservationService = reservationService;
40 this.nodeIdService = nodeIdService;
41 }
42
43 /**
44 * Create a new order
45 */
46 @Transactional
47 public Order createOrder(List<OrderItem> items, String customerEmail, String customerName,
48 String customerPhone, String customerContactPreference,
49 String shippingAddress, String shippingCity, String shippingState,
50 String shippingZip, String shippingCountry, String shippingMethod,
51 String sessionId) {
52
53 logger.info("Creating order for customer: {}", customerEmail);
54
55 // Validate stock and calculate totals
56 long subtotal = 0;
57 String currency = "USD";
58
59 for (OrderItem item : items) {
60 Optional<Product> productOpt = productService.getProductByIdRaw(item.getProductId());
61 if (productOpt.isEmpty()) {
62 throw new IllegalArgumentException("Product not found: " + item.getProductId());
63 }
64
65 Product product = productOpt.get();
66 currency = product.getCurrency();
67
68 // Check stock availability (considering reservations)
69 if (product.getStock() != null) {
70 int reservedByOthers = reservationService.getReservedCountExcludingSession(
71 product.getId(), sessionId
72 );
73 int effectiveStock = product.getStock() - reservedByOthers;
74
75 if (effectiveStock < item.getQuantity()) {
76 throw new IllegalStateException(
77 String.format("Insufficient stock for %s. Only %d available.",
78 product.getName(), effectiveStock)
79 );
80 }
81 }
82
83 // Set item details
84 item.setProductName(product.getName());
85 item.setPrice(product.getPrice());
86 subtotal += product.getPrice() * item.getQuantity();
87 }
88
89 // Calculate shipping
90 long shippingCost = shippingService.calculateShippingCost(shippingMethod, shippingCountry);
91
92 // Calculate tax
93 long taxAmount = taxService.calculateTax(subtotal, shippingCountry, shippingState);
94
95 // Calculate total
96 long total = subtotal + shippingCost + taxAmount;
97
98 // Create order
99 Order order = Order.builder()
100 .orderId(IdGenerator.generateOrderId())
101 .status("pending")
102 .subtotal(subtotal)
103 .total(total)
104 .currency(currency)
105 .customerEmail(customerEmail)
106 .customerName(customerName)
107 .customerPhone(customerPhone)
108 .customerContactPreference(customerContactPreference)
109 .shippingAddress(shippingAddress)
110 .shippingCity(shippingCity)
111 .shippingState(shippingState)
112 .shippingZip(shippingZip)
113 .shippingCountry(shippingCountry)
114 .shippingMethod(shippingMethod)
115 .shippingCost(shippingCost)
116 .taxAmount(taxAmount)
117 .nodeId(nodeIdService.getNodeId())
118 .build();
119
120 // Add items
121 for (OrderItem item : items) {
122 order.addItem(item);
123 }
124
125 // Save order
126 order = orderRepository.save(order);
127 logger.info("Created order: {}", order.getOrderId());
128
129 return order;
130 }
131
132 /**
133 * Complete an order (update stock, release reservations)
134 */
135 @Transactional
136 public void completeOrder(String orderId, String sessionId) {
137 Optional<Order> orderOpt = orderRepository.findByOrderId(orderId);
138 if (orderOpt.isEmpty()) {
139 throw new IllegalArgumentException("Order not found: " + orderId);
140 }
141
142 Order order = orderOpt.get();
143
144 // Update stock for each item
145 for (OrderItem item : order.getItems()) {
146 productService.decreaseStock(item.getProductId(), item.getQuantity());
147
148 // Release reservation
149 if (sessionId != null) {
150 reservationService.release(sessionId, item.getProductId());
151 }
152 }
153
154 // Update order status
155 order.setStatus("completed");
156 orderRepository.save(order);
157
158 logger.info("Completed order: {}", orderId);
159 }
160
161 /**
162 * Get order by ID
163 */
164 public Optional<Order> getOrderById(String orderId) {
165 return orderRepository.findByOrderIdWithItems(orderId);
166 }
167
168 /**
169 * Get orders by customer email
170 */
171 public List<Order> getOrdersByCustomerEmail(String email) {
172 return orderRepository.findByCustomerEmail(email);
173 }
174
175 /**
176 * Get all orders (admin)
177 */
178 public List<Order> getAllOrders() {
179 return orderRepository.findAllWithItems();
180 }
181
182 /**
183 * Update order tracking information
184 */
185 @Transactional
186 public Optional<Order> updateTracking(String orderId, String trackingId, String carrier) {
187 return orderRepository.findByOrderId(orderId).map(order -> {
188 order.setTrackingId(trackingId);
189 order.setCarrier(carrier);
190 return orderRepository.save(order);
191 });
192 }
193
194 /**
195 * Verify email matches order
196 */
197 public boolean verifyOrderEmail(String orderId, String email) {
198 Optional<Order> order = orderRepository.findByOrderId(orderId);
199 return order.isPresent() && order.get().getCustomerEmail().equalsIgnoreCase(email);
200 }
201 }
202
203