From bee6fef5e24b100faf7c4162c4363711676c70b8 Mon Sep 17 00:00:00 2001 From: luxic Date: Thu, 23 Oct 2025 13:45:51 +0700 Subject: [PATCH] super basic queue system --- .../mai_queue/config/ExceptionHandling.java | 5 +++ .../controller/LocationController.java | 7 ++++ .../mai_queue/controller/QueueController.java | 16 ++++++++ .../java/id/luxic/mai_queue/model/Queue.java | 1 - .../repository/LocationRepository.java | 1 + .../mai_queue/repository/QueueRepository.java | 14 +++++-- .../request/queue/ReorderQueueRequest.java | 14 +++++++ .../mai_queue/service/LocationService.java | 37 ++++++++++++++++++- .../luxic/mai_queue/service/QueueService.java | 34 +++++++++++++++-- 9 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 src/main/java/id/luxic/mai_queue/request/queue/ReorderQueueRequest.java diff --git a/src/main/java/id/luxic/mai_queue/config/ExceptionHandling.java b/src/main/java/id/luxic/mai_queue/config/ExceptionHandling.java index d27fe16..221e99b 100644 --- a/src/main/java/id/luxic/mai_queue/config/ExceptionHandling.java +++ b/src/main/java/id/luxic/mai_queue/config/ExceptionHandling.java @@ -25,4 +25,9 @@ public class ExceptionHandling { return ResponseMessage.of(HttpStatus.BAD_REQUEST, errors); } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity handleIllegalArgumentException(IllegalArgumentException ex) { + return ResponseMessage.of(HttpStatus.BAD_REQUEST, ex.getCause(), ex.getMessage()); + } } diff --git a/src/main/java/id/luxic/mai_queue/controller/LocationController.java b/src/main/java/id/luxic/mai_queue/controller/LocationController.java index 83c870e..be9d7a2 100644 --- a/src/main/java/id/luxic/mai_queue/controller/LocationController.java +++ b/src/main/java/id/luxic/mai_queue/controller/LocationController.java @@ -52,4 +52,11 @@ public class LocationController { return ResponseEntity.ok().build(); } + @GetMapping("/nextQueue/{locationId}") + public ResponseEntity nextQueue(@PathVariable String locationId) { + + locationService.nextQueue(locationId); + return ResponseMessage.of(HttpStatus.OK, null, "Next Queue"); + } + } diff --git a/src/main/java/id/luxic/mai_queue/controller/QueueController.java b/src/main/java/id/luxic/mai_queue/controller/QueueController.java index 18eabae..e9a7a5d 100644 --- a/src/main/java/id/luxic/mai_queue/controller/QueueController.java +++ b/src/main/java/id/luxic/mai_queue/controller/QueueController.java @@ -1,6 +1,7 @@ package id.luxic.mai_queue.controller; import id.luxic.mai_queue.request.queue.QueueInsertSoloRequest; +import id.luxic.mai_queue.request.queue.ReorderQueueRequest; import id.luxic.mai_queue.response.ResponseMessage; import id.luxic.mai_queue.service.QueueService; import org.springframework.http.HttpStatus; @@ -33,4 +34,19 @@ public class QueueController { return ResponseMessage.of(HttpStatus.OK, queueService.getQueueByLocation(id), "Find by location id"); } + @PostMapping("/reorder") + public ResponseEntity reorderQueue(@RequestBody ReorderQueueRequest request) { + + queueService.reorderQueue(request.getLocationId(), request.getFrom(), request.getTo()); + + return ResponseMessage.of(HttpStatus.OK, null, "Success Reorder"); + } + + @DeleteMapping("/delete/{id}") + public ResponseEntity deleteQueue(@PathVariable Integer id) { + queueService.deleteQueue(id); + + return ResponseMessage.of(HttpStatus.OK, null, "Success Delete"); + } + } diff --git a/src/main/java/id/luxic/mai_queue/model/Queue.java b/src/main/java/id/luxic/mai_queue/model/Queue.java index ee8d665..fd98866 100644 --- a/src/main/java/id/luxic/mai_queue/model/Queue.java +++ b/src/main/java/id/luxic/mai_queue/model/Queue.java @@ -1,7 +1,6 @@ package id.luxic.mai_queue.model; import com.fasterxml.jackson.annotation.JsonBackReference; -import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/id/luxic/mai_queue/repository/LocationRepository.java b/src/main/java/id/luxic/mai_queue/repository/LocationRepository.java index 297e032..4d6147a 100644 --- a/src/main/java/id/luxic/mai_queue/repository/LocationRepository.java +++ b/src/main/java/id/luxic/mai_queue/repository/LocationRepository.java @@ -4,4 +4,5 @@ import id.luxic.mai_queue.model.Location; import org.springframework.data.jpa.repository.JpaRepository; public interface LocationRepository extends JpaRepository { + } diff --git a/src/main/java/id/luxic/mai_queue/repository/QueueRepository.java b/src/main/java/id/luxic/mai_queue/repository/QueueRepository.java index ff44db3..2d241a8 100644 --- a/src/main/java/id/luxic/mai_queue/repository/QueueRepository.java +++ b/src/main/java/id/luxic/mai_queue/repository/QueueRepository.java @@ -13,15 +13,23 @@ public interface QueueRepository extends JpaRepository { @Query("SELECT MAX(q.order) FROM Queue q WHERE q.location.id = :locationId") Integer findLastOrderByLocationId(@Param("locationId") String locationId); - @Query("SELECT q FROM Queue q WHERE q.location.id = :locationId ORDER BY order ASC") + @Query("SELECT q FROM Queue q WHERE q.location.id = :locationId AND q.order >= q.location.currentQueue ORDER BY order ASC") List findByLocationId(@Param("locationId") String locationId); @Modifying @Query(""" UPDATE Queue q - set q.order = q.order + 1 - where q.location.id = :locationId and q.order > :targetOrder + SET q.order = q.order + 1 + WHERE q.location.id = :locationId AND q.order > :targetOrder """) void reorderQueue(@Param("locationId") String locationId, Integer targetOrder); + @Query (value = """ + SELECT q."order" FROM queue q JOIN location l ON q.location_id = l.id WHERE q.location_id = :locationId AND q."order" >= l.current ORDER BY q."order" ASC OFFSET :offset LIMIT 1 + """, nativeQuery = true) + Integer nextQueueByLocation(@Param("locationId") String locationId, @Param("offset") Integer offset); + + @Query("SELECT q FROM Queue q WHERE q.location.id = :locationId AND order = :order") + Queue findByLocationIdAndOrder(@Param("locationId") String locationId, @Param("order") Integer order); + } diff --git a/src/main/java/id/luxic/mai_queue/request/queue/ReorderQueueRequest.java b/src/main/java/id/luxic/mai_queue/request/queue/ReorderQueueRequest.java new file mode 100644 index 0000000..34a819a --- /dev/null +++ b/src/main/java/id/luxic/mai_queue/request/queue/ReorderQueueRequest.java @@ -0,0 +1,14 @@ +package id.luxic.mai_queue.request.queue; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ReorderQueueRequest { + + private String locationId; + private Integer from; + private Integer to; + +} diff --git a/src/main/java/id/luxic/mai_queue/service/LocationService.java b/src/main/java/id/luxic/mai_queue/service/LocationService.java index acadb52..8c77ec8 100644 --- a/src/main/java/id/luxic/mai_queue/service/LocationService.java +++ b/src/main/java/id/luxic/mai_queue/service/LocationService.java @@ -1,22 +1,25 @@ package id.luxic.mai_queue.service; import id.luxic.mai_queue.model.Location; +import id.luxic.mai_queue.model.Queue; import id.luxic.mai_queue.repository.LocationRepository; +import id.luxic.mai_queue.repository.QueueRepository; import id.luxic.mai_queue.request.location.NewLocationRequest; import id.luxic.mai_queue.tools.IdGenerator; import org.springframework.stereotype.Service; import java.sql.Timestamp; -import java.time.Instant; import java.util.List; @Service public class LocationService { private final LocationRepository locationRepository; + private final QueueRepository queueRepository; - public LocationService(LocationRepository locationRepository) { + public LocationService(LocationRepository locationRepository, QueueRepository queueRepository) { this.locationRepository = locationRepository; + this.queueRepository = queueRepository; } public List getAllLocation() { @@ -43,4 +46,34 @@ public class LocationService { locationRepository.deleteById(id); } + public void nextQueue(String locationId) { + + Location location = locationRepository.findById(locationId).orElse(null); + + if (location == null) { + throw new IllegalArgumentException("Location not found"); + } + + Queue queue = queueRepository.findByLocationIdAndOrder(location.getId(), location.getCurrentQueue()); + + if (queue == null) { + throw new IllegalArgumentException("There's no one here"); + } + + Integer offset = 2; + if (queue.isSolo()) offset = 1; + + Integer nextOrder = queueRepository.nextQueueByLocation(locationId, offset); + Integer lastOrder = queueRepository.findLastOrderByLocationId(locationId); + + if (nextOrder == null || nextOrder.equals(lastOrder)) nextOrder = lastOrder + 1; + + location.setCurrentQueue(nextOrder); + + // TODO: Use FCM to push notification + + locationRepository.save(location); + + } + } diff --git a/src/main/java/id/luxic/mai_queue/service/QueueService.java b/src/main/java/id/luxic/mai_queue/service/QueueService.java index 5065e93..24075d5 100644 --- a/src/main/java/id/luxic/mai_queue/service/QueueService.java +++ b/src/main/java/id/luxic/mai_queue/service/QueueService.java @@ -56,11 +56,37 @@ public class QueueService { return queueRepository.findByLocationId(locationId); } - public void reorderQueue(String locationId, Queue source, Integer targetOrder) { - // Source must be higher order than target - queueRepository.reorderQueue(locationId, targetOrder); + @Transactional + public void reorderQueue(String locationId, Integer from, Integer to) { + // From must be higher order than target + Location location = locationRepository.findById(locationId).orElse(null); - source.setOrder(targetOrder+1); + // Make sure from is higher order than target + if (to > from) { + int temp = to; + to = from; + from = temp; + } + + System.out.println("to: " + to + ", from: " + from); + + if (to < location.getCurrentQueue()) { + throw new IllegalArgumentException("Target queue is lower than current queue"); + } + + Queue source = queueRepository.findById(from).orElse(null); + + if (source == null) { + throw new IllegalArgumentException("Queue not found"); + } + + queueRepository.reorderQueue(locationId, to); + + source.setOrder(to+1); queueRepository.save(source); } + + public void deleteQueue(Integer id) { + queueRepository.deleteById(id); + } }