Commit: 4617f76

Commit Details

SHA4617f76246bf039920879ae5497436d31494ed7c
Treee78bcb155880b8c167af124554a6db724c41264e
Author<f69e50@finnacloud.com> 1766442953 +0300
Committer<f69e50@finnacloud.com> 1766442953 +0300
Message
rename branch from main to master oops
GPG Signature
-----BEGIN PGP SIGNATURE-----

iQJSBAABCAA8FiEEWJb139mJI+vZ81KkoAIVSUsXI0oFAmlJx8keHHNvcGhpYS5l
cmFzbGFuQGZpbm5hY2xvdWQuY29tAAoJEKACFUlLFyNK2BQP/3EfkXtKsmQoqa4E
e9jdO5BKWUnHwF31PdpxExXwoogkZg2hSjSc0jB9htAKSbQspx+Pst7f9yj2Gf2u
ENGTEQHqqVeLEve2IPc1YJ+F+yedI3NE2PCZJ0+rh1/S14vQTT0kWMSqs6d8Te4K
x4hiTNNjfWidOXQ1vHMXl9iUnevmnko8XqNe3aBZ3JUSRLhhCvehsiPwSjfKGqB8
Sm9i1Y/HaTizFfl4WG5f6MppDgzV2I7Bm/c6K1oDIviO/Wken5vk4TXgLUWDfHJ5
d9m9gh4N9unX4Ivf5G22JVRzxPgox0Y0yFQwpj4IqQ9LzjT2Vz2s+hXoV6HZkfUW
BCLc/6oRmImcSflxOgV/TGaZrvysQ0pz32H8lyLoOI1QAS3o4u1icPFjfHlc5298
zpjGAqPjlVEx4Sjghrow4pb7sb/OyFihTwfjxlLgVfR4tXfb/l5rRt2f9vsm1HJB
qc9F/Qqc6xpb9ECyYZtuuCMToS0MRNkqy2KifrvOaKi2EznhcJu2VcLmjQJookFY
meevIkRenUvjwbs+aoDOa76HmycWkw1NtTtE9M+NSZ9SCBOD+Gp1rqO66z758bUQ
NmISh50GPDiZw5AKDrtsygWRZumLbrWHBleHm935V5O3gYkEKo9kb40Zf2sDsvlS
/wXQCTVz3XuSby3pyaMGgd3ol6gk
=YOD1
-----END PGP SIGNATURE-----

✓ Verified

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

1 package com.paymentlink.service;
2
3 import com.paymentlink.model.entity.Product;
4 import com.paymentlink.repository.ProductRepository;
5 import com.paymentlink.reservation.ReservationService;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.stereotype.Service;
9 import org.springframework.transaction.annotation.Transactional;
10
11 import java.util.List;
12 import java.util.Optional;
13
14 @Service
15 public class ProductService {
16
17 private static final Logger logger = LoggerFactory.getLogger(ProductService.class);
18
19 private final ProductRepository productRepository;
20 private final ReservationService reservationService;
21 private final NodeIdService nodeIdService;
22
23 public ProductService(ProductRepository productRepository,
24 ReservationService reservationService,
25 NodeIdService nodeIdService) {
26 this.productRepository = productRepository;
27 this.reservationService = reservationService;
28 this.nodeIdService = nodeIdService;
29 }
30
31 /**
32 * Get all products with adjusted stock (minus reservations)
33 */
34 public List<Product> getAllProducts() {
35 List<Product> products = productRepository.findAll();
36 return adjustStockForReservations(products);
37 }
38
39 /**
40 * Get products by category with adjusted stock
41 */
42 public List<Product> getProductsByCategory(String category) {
43 List<Product> products = productRepository.findByCategory(category);
44 return adjustStockForReservations(products);
45 }
46
47 /**
48 * Search products with adjusted stock
49 */
50 public List<Product> searchProducts(String query, String category) {
51 List<Product> products;
52 if (category != null && !category.isEmpty()) {
53 products = productRepository.searchProductsByCategory(query, category);
54 } else {
55 products = productRepository.searchProducts(query);
56 }
57 return adjustStockForReservations(products);
58 }
59
60 /**
61 * Get products in stock (after reservations)
62 */
63 public List<Product> getProductsInStock() {
64 List<Product> products = productRepository.findAll();
65 products = adjustStockForReservations(products);
66 return products.stream()
67 .filter(p -> p.getStock() == null || p.getStock() > 0)
68 .toList();
69 }
70
71 /**
72 * Get product by ID with adjusted stock
73 */
74 public Optional<Product> getProductById(Long id) {
75 Optional<Product> product = productRepository.findById(id);
76 if (product.isPresent()) {
77 Product p = product.get();
78 if (p.getStock() != null) {
79 int reserved = reservationService.getReservedCount(p.getId());
80 p.setStock(Math.max(0, p.getStock() - reserved));
81 }
82 }
83 return product;
84 }
85
86 /**
87 * Get product by ID without adjustment (for internal use)
88 */
89 public Optional<Product> getProductByIdRaw(Long id) {
90 return productRepository.findById(id);
91 }
92
93 /**
94 * Get all categories
95 */
96 public List<String> getAllCategories() {
97 return productRepository.findDistinctCategories();
98 }
99
100 /**
101 * Create a new product
102 */
103 @Transactional
104 public Product createProduct(Product product) {
105 product.setNodeId(nodeIdService.getNodeId());
106 logger.info("Creating product: {}", product.getName());
107 return productRepository.save(product);
108 }
109
110 /**
111 * Update a product
112 */
113 @Transactional
114 public Optional<Product> updateProduct(Long id, Product updates) {
115 return productRepository.findById(id).map(existing -> {
116 if (updates.getName() != null) existing.setName(updates.getName());
117 if (updates.getDescription() != null) existing.setDescription(updates.getDescription());
118 if (updates.getPrice() != null) existing.setPrice(updates.getPrice());
119 if (updates.getCurrency() != null) existing.setCurrency(updates.getCurrency());
120 if (updates.getImage() != null) existing.setImage(updates.getImage());
121 if (updates.getStock() != null) existing.setStock(updates.getStock());
122 if (updates.getCategory() != null) existing.setCategory(updates.getCategory());
123 if (updates.getTaxIncluded() != null) existing.setTaxIncluded(updates.getTaxIncluded());
124
125 logger.info("Updating product: {}", id);
126 return productRepository.save(existing);
127 });
128 }
129
130 /**
131 * Delete a product
132 */
133 @Transactional
134 public boolean deleteProduct(Long id) {
135 if (productRepository.existsById(id)) {
136 productRepository.deleteById(id);
137 logger.info("Deleted product: {}", id);
138 return true;
139 }
140 return false;
141 }
142
143 /**
144 * Update stock for a product
145 */
146 @Transactional
147 public void updateStock(Long productId, int newStock) {
148 productRepository.findById(productId).ifPresent(product -> {
149 product.setStock(newStock);
150 productRepository.save(product);
151 logger.info("Updated stock for product {}: {}", productId, newStock);
152 });
153 }
154
155 /**
156 * Decrease stock (for order completion)
157 */
158 @Transactional
159 public void decreaseStock(Long productId, int quantity) {
160 productRepository.findById(productId).ifPresent(product -> {
161 if (product.getStock() != null) {
162 int newStock = product.getStock() - quantity;
163 product.setStock(Math.max(0, newStock));
164 productRepository.save(product);
165 logger.info("Decreased stock for product {}: {} -> {}",
166 productId, product.getStock() + quantity, newStock);
167 }
168 });
169 }
170
171 /**
172 * Adjust stock counts for reservations
173 */
174 private List<Product> adjustStockForReservations(List<Product> products) {
175 return products.stream().map(p -> {
176 if (p.getStock() != null) {
177 int reserved = reservationService.getReservedCount(p.getId());
178 p.setStock(Math.max(0, p.getStock() - reserved));
179 }
180 return p;
181 }).toList();
182 }
183 }
184
185