backend updated for counter login
This commit is contained in:
@@ -19,6 +19,9 @@ public class ProductController {
|
||||
@Autowired
|
||||
private com.rit.canteen.sales.repository.StallRepository stallRepository;
|
||||
|
||||
@Autowired
|
||||
private StockUpdateController stockUpdateController;
|
||||
|
||||
@GetMapping
|
||||
public org.springframework.data.domain.Page<Product> getAllProducts(
|
||||
@RequestParam(required = false) String search,
|
||||
@@ -32,9 +35,12 @@ public class ProductController {
|
||||
|
||||
@GetMapping("/category/{categoryName}")
|
||||
public List<Product> getProductsByCategory(@PathVariable String categoryName) {
|
||||
return productRepository.findAll().stream()
|
||||
.filter(p -> categoryName.equals(p.getCategory()))
|
||||
.toList();
|
||||
return productRepository.findByCategory(categoryName);
|
||||
}
|
||||
|
||||
@GetMapping("/categories")
|
||||
public List<String> getAllCategories() {
|
||||
return productRepository.findDistinctCategories();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@@ -81,6 +87,9 @@ public class ProductController {
|
||||
Product updated = productRepository.save(product);
|
||||
updateStallAssociations(updated, productDetails.getStalls());
|
||||
|
||||
// Broadcast update
|
||||
stockUpdateController.broadcastStockUpdate(updated.getId(), updated.getStock());
|
||||
|
||||
return ResponseEntity.ok(productRepository.findById(updated.getId()).orElse(updated));
|
||||
})
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
@@ -127,8 +136,40 @@ public class ProductController {
|
||||
.map(product -> {
|
||||
Integer currentStock = product.getStock() != null ? product.getStock() : 0;
|
||||
product.setStock(currentStock > 0 ? 0 : 99); // Toggle between Out of Stock and In Stock
|
||||
return ResponseEntity.ok(productRepository.save(product));
|
||||
Product saved = productRepository.save(product);
|
||||
stockUpdateController.broadcastStockUpdate(saved.getId(), saved.getStock());
|
||||
return ResponseEntity.ok(saved);
|
||||
})
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
@PatchMapping("/{id}/stock-adjust")
|
||||
public ResponseEntity<Product> adjustStock(@PathVariable Long id, @RequestParam int delta) {
|
||||
return productRepository.findById(id)
|
||||
.map(product -> {
|
||||
int currentStock = product.getStock() != null ? product.getStock() : 0;
|
||||
product.setStock(Math.max(0, currentStock + delta));
|
||||
Product saved = productRepository.save(product);
|
||||
stockUpdateController.broadcastStockUpdate(saved.getId(), saved.getStock());
|
||||
return ResponseEntity.ok(saved);
|
||||
})
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
@PatchMapping("/batch-assign-category")
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public ResponseEntity<Void> batchAssignCategory(@RequestBody java.util.Map<String, Object> payload) {
|
||||
String categoryName = (String) payload.get("categoryName");
|
||||
List<Integer> productIds = (List<Integer>) payload.get("productIds");
|
||||
|
||||
if (categoryName == null || productIds == null) return ResponseEntity.badRequest().build();
|
||||
|
||||
for (Integer id : productIds) {
|
||||
productRepository.findById(id.longValue()).ifPresent(p -> {
|
||||
p.setCategory(categoryName);
|
||||
productRepository.save(p);
|
||||
});
|
||||
}
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.rit.canteen.sales.controller;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/stock")
|
||||
public class StockUpdateController {
|
||||
|
||||
private final List<SseEmitter> emitters = new CopyOnWriteArrayList<>();
|
||||
|
||||
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public SseEmitter streamStockUpdates() {
|
||||
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
|
||||
this.emitters.add(emitter);
|
||||
|
||||
emitter.onCompletion(() -> this.emitters.remove(emitter));
|
||||
emitter.onTimeout(() -> this.emitters.remove(emitter));
|
||||
emitter.onError((e) -> this.emitters.remove(emitter));
|
||||
|
||||
// Send initial heartbeat to keep connection alive
|
||||
try {
|
||||
emitter.send(SseEmitter.event()
|
||||
.name("init")
|
||||
.data("Connection Established"));
|
||||
} catch (IOException e) {
|
||||
this.emitters.remove(emitter);
|
||||
}
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
public void broadcastStockUpdate(Long productId, Integer stock) {
|
||||
List<SseEmitter> deadEmitters = new CopyOnWriteArrayList<>();
|
||||
Map<String, Object> payload = Map.of(
|
||||
"productId", productId,
|
||||
"stock", stock
|
||||
);
|
||||
|
||||
this.emitters.forEach(emitter -> {
|
||||
try {
|
||||
emitter.send(SseEmitter.event()
|
||||
.name("stockUpdate")
|
||||
.data(payload));
|
||||
} catch (Exception e) {
|
||||
deadEmitters.add(emitter);
|
||||
}
|
||||
});
|
||||
|
||||
this.emitters.removeAll(deadEmitters);
|
||||
}
|
||||
}
|
||||
@@ -20,5 +20,8 @@ public interface ProductRepository extends JpaRepository<Product, Long> {
|
||||
|
||||
List<Product> findByCategory(String category);
|
||||
|
||||
@Query("SELECT DISTINCT p.category FROM Product p WHERE p.category IS NOT NULL")
|
||||
List<String> findDistinctCategories();
|
||||
|
||||
boolean existsByNameAndCategory(String name, String category);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user