diff --git a/dodam-api/src/main/java/b1nd/dodamapi/bus/BusController.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/BusController.java deleted file mode 100644 index 586cf9b4..00000000 --- a/dodam-api/src/main/java/b1nd/dodamapi/bus/BusController.java +++ /dev/null @@ -1,91 +0,0 @@ -package b1nd.dodamapi.bus; - -import b1nd.dodamapi.common.response.Response; -import b1nd.dodamapi.common.response.ResponseData; -import b1nd.dodamcore.bus.application.BusService; -import b1nd.dodamcore.bus.application.dto.req.BusReq; -import b1nd.dodamcore.bus.application.dto.res.BusRes; -import b1nd.dodamcore.bus.domain.entity.Bus; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping("/bus") -@RequiredArgsConstructor -public class BusController { - - private final BusService busService; - - @GetMapping - public ResponseData> getValidBuses() { - List buses = busService.getValidBuses(); - return ResponseData.ok("유효 버스 조회 성공", buses); - } - - @GetMapping("/list") - public ResponseData> getBuses( - @RequestParam int page, - @RequestParam int limit - ) { - List buses = busService.getBuses(page, limit); - return ResponseData.ok("버스 조회 성공", buses); - } - - @GetMapping("/date") - public ResponseData> getBusesByDate( - @RequestParam int year, - @RequestParam int month, - @RequestParam int day - ) { - List buses = busService.getBusesByDate(year, month, day); - return ResponseData.ok("해당 날짜의 버스 조회 성공", buses); - } - - @GetMapping("/apply") - public ResponseData getAppliedBus() { - Bus bus = busService.getAppliedBus(); - return ResponseData.ok("신청한 버스 조회 성공", bus); - } - - @PostMapping - public Response createBus(@RequestBody @Valid BusReq createBusReq) { - busService.createBus(createBusReq); - return Response.created("버스 생성 성공"); - } - - @PatchMapping("/{id}") - public Response modifyBus( - @PathVariable int id, - @RequestBody BusReq modifyBusReq - ) { - busService.modifyBus(id, modifyBusReq); - return Response.ok("버스 수정 성공"); - } - - @DeleteMapping("/{id}") - public Response deleteBus(@PathVariable int id) { - busService.deleteBus(id); - return Response.ok("버스 삭제 성공"); - } - - @PostMapping("/apply/{id}") - public Response applyBus(@PathVariable int id) { - busService.applyBus(id); - return Response.created("버스 신청 성공"); - } - - @PatchMapping("/apply/{id}") - public Response modifyAppliedBus(@PathVariable int id) { - busService.modifyAppliedBus(id); - return Response.ok("버스 신청 수정 성공"); - } - - @DeleteMapping("/apply/{id}") - public Response cancelAppliedBus(@PathVariable int id) { - busService.cancelAppliedBus(id); - return Response.ok("버스 탑승 취소 성공"); - } -} diff --git a/dodam-api/src/main/java/b1nd/dodamapi/bus/handler/BusController.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/handler/BusController.java new file mode 100644 index 00000000..56056948 --- /dev/null +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/handler/BusController.java @@ -0,0 +1,77 @@ +package b1nd.dodamapi.bus.handler; + +import b1nd.dodamapi.bus.usecase.BusApplicationUseCase; +import b1nd.dodamapi.common.response.Response; +import b1nd.dodamapi.common.response.ResponseData; +import b1nd.dodamapi.bus.usecase.BusUseCase; +import b1nd.dodamapi.bus.usecase.dto.req.BusReq; +import b1nd.dodamapi.bus.usecase.dto.res.BusRes; +import b1nd.dodamcore.bus.domain.entity.Bus; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/bus") +@RequiredArgsConstructor +public class BusController { + + private final BusUseCase busUseCase; + private final BusApplicationUseCase busApplicationUseCase; + + @PostMapping + public Response registerBus(@RequestBody @Valid BusReq req) { + return busUseCase.register(req); + } + + @PatchMapping("/{id}") + public Response modifyBus(@PathVariable int id, @RequestBody BusReq req) { + return busUseCase.modify(id, req); + } + + @DeleteMapping("/{id}") + public Response deleteBus(@PathVariable int id) { + return busUseCase.delete(id); + } + + @GetMapping + public ResponseData> getValidBuses() { + return busUseCase.getValid(); + } + + @GetMapping("/list") + public ResponseData> getBuses(@RequestParam int page, @RequestParam int limit) { + return busUseCase.getBuses(page, limit); + } + + @GetMapping("/date") + public ResponseData> getBusesByDate( + @RequestParam int year, + @RequestParam int month, + @RequestParam int day + ) { + return busUseCase.getBusesByDate(year, month, day); + } + + @GetMapping("/apply") + public ResponseData getMy() { + return busUseCase.getMy(); + } + + @PostMapping("/apply/{id}") + public Response applyBus(@PathVariable int id) { + return busApplicationUseCase.apply(id); + } + + @PatchMapping("/apply/{id}") + public Response modifyApplication(@PathVariable int id) { + return busApplicationUseCase.modify(id); + } + + @DeleteMapping("/apply/{id}") + public Response cancelApplication(@PathVariable int id) { + return busApplicationUseCase.cancel(id); + } +} diff --git a/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusApplicationUseCase.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusApplicationUseCase.java new file mode 100644 index 00000000..a204cb82 --- /dev/null +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusApplicationUseCase.java @@ -0,0 +1,85 @@ +package b1nd.dodamapi.bus.usecase; + +import b1nd.dodamapi.common.response.Response; +import b1nd.dodamcore.bus.application.BusApplicationService; +import b1nd.dodamcore.bus.application.BusService; +import b1nd.dodamcore.bus.domain.entity.Bus; +import b1nd.dodamcore.bus.domain.entity.BusMember; +import b1nd.dodamcore.bus.domain.exception.BusAlreadyApplyException; +import b1nd.dodamcore.bus.domain.exception.BusMemberNotFoundException; +import b1nd.dodamcore.common.util.ZonedDateTimeUtil; +import b1nd.dodamcore.member.application.MemberService; +import b1nd.dodamcore.member.domain.entity.Student; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.function.Consumer; + + +@Component +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class BusApplicationUseCase { + + private final BusService busService; + private final BusApplicationService busApplicationService; + private final MemberService memberService; + + public Response apply(int busId) { + Bus bus = busService.getByIdForUpdate(busId); + Student student = memberService.getStudentFromSession(); + if(busApplicationService.hasValidApplication(student, ZonedDateTimeUtil.nowToLocalDateTime())) { + throw new BusAlreadyApplyException(); + } + busApplicationService.save( + BusMember.builder() + .bus(bus) + .student(student) + .build() + ); + return Response.created("버스 신청 성공"); + } + + public Response modify(int busId) { + Bus newBus = busService.getByIdForUpdate(busId); + Student student = memberService.getStudentFromSession(); + findValidApplication( + student, + ZonedDateTimeUtil.nowToLocalDateTime(), + (busMember) -> { + Bus oldBus = busService.getByIdForUpdate(busMember.getBus().getId()); + oldBus.decreaseApplyCount(); + busMember.modifyBus(newBus); + newBus.increaseApplyCount(); + } + ); + return Response.noContent("버스 신청 수정 성공"); + } + + public Response cancel(int busId) { + Student student = memberService.getStudentFromSession(); + findValidApplication( + student, + ZonedDateTimeUtil.nowToLocalDateTime(), + (busMember) -> { + Bus bus = busService.getByIdForUpdate(busId); + bus.decreaseApplyCount(); + busApplicationService.delete(busMember); + } + ); + return Response.noContent("버스 신청 취소 성공"); + } + + private void findValidApplication(Student student, LocalDateTime now, Consumer action) { + busApplicationService.findValidApplication(student, now) + .ifPresentOrElse( + action, + () -> { + throw new BusMemberNotFoundException(); + } + ); + } + +} diff --git a/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusUseCase.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusUseCase.java new file mode 100644 index 00000000..031072ec --- /dev/null +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/BusUseCase.java @@ -0,0 +1,91 @@ +package b1nd.dodamapi.bus.usecase; + +import b1nd.dodamapi.bus.usecase.dto.req.BusReq; +import b1nd.dodamapi.bus.usecase.dto.res.BusMemberRes; +import b1nd.dodamapi.bus.usecase.dto.res.BusRes; +import b1nd.dodamapi.common.response.Response; +import b1nd.dodamapi.common.response.ResponseData; +import b1nd.dodamcore.bus.application.BusApplicationService; +import b1nd.dodamcore.bus.application.BusService; +import b1nd.dodamcore.bus.domain.entity.Bus; +import b1nd.dodamcore.bus.domain.entity.BusMember; +import b1nd.dodamcore.common.util.ModifyUtil; +import b1nd.dodamcore.common.util.ZonedDateTimeUtil; +import b1nd.dodamcore.member.application.MemberService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BusUseCase { + + private final BusService busService; + private final BusApplicationService busApplicationService; + private final MemberService memberService; + + @Transactional(rollbackFor = Exception.class) + public Response register(BusReq req) { + busService.save(req.mapToBus()); + return Response.created("버스 등록 성공"); + } + + @Transactional(rollbackFor = Exception.class) + public Response modify(int id, BusReq modifyBusReq) { + Bus bus = busService.getByIdForUpdate(id); + bus.updateBus( + ModifyUtil.modifyIfNotNull(modifyBusReq.busName(), bus.getBusName()), + ModifyUtil.modifyIfNotNull(modifyBusReq.description(), bus.getDescription()), + ModifyUtil.modifyIfNotNull(modifyBusReq.leaveTime(), bus.getLeaveTime()), + ModifyUtil.modifyIfNotNull(modifyBusReq.timeRequired(), bus.getTimeRequired()), + ModifyUtil.modifyIfNotZero(modifyBusReq.peopleLimit(), bus.getPeopleLimit()) + ); + return Response.noContent("버스 수정 성공"); + } + + @Transactional(rollbackFor = Exception.class) + public Response delete(int id) { + Bus bus = busService.getById(id); + busService.delete(bus); + return Response.noContent("버스 삭제 성공"); + } + + public ResponseData> getValid() { + LocalDateTime now = ZonedDateTimeUtil.nowToLocalDateTime(); + return ResponseData.ok("유효 버스 조회 성공", busService.getValid(now, now.plusDays(7))); + } + + public ResponseData> getBuses(int page, int limit) { + return ResponseData.ok("버스 조회 성공", parseToBusList(busService.getAll(page, limit))); + } + + public ResponseData> getBusesByDate(int year, int month, int day) { + return ResponseData.ok("해당 날짜의 버스 조회 성공", parseToBusList(busService.getAllByDate(LocalDate.of(year, month, day)))); + } + + private List parseToBusList(List buses) { + return buses.stream() + .map(bus -> BusRes.createFromBus( + bus, + getBusApplications(bus).stream() + .map(BusMemberRes::createFromBusMember) + .toList() + ) + ).toList(); + } + + private List getBusApplications(Bus bus) { + return busApplicationService.getByBus(bus); + } + + public ResponseData getMy() { + int studentId = memberService.getStudentFromSession().getId(); + return ResponseData.ok("신청한 버스 조회 성공", busService.getByStudent(ZonedDateTimeUtil.nowToLocalDateTime(), studentId)); + } + +} diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/req/BusReq.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/req/BusReq.java similarity index 93% rename from dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/req/BusReq.java rename to dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/req/BusReq.java index 691e702d..eca9f7ed 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/req/BusReq.java +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/req/BusReq.java @@ -1,4 +1,4 @@ -package b1nd.dodamcore.bus.application.dto.req; +package b1nd.dodamapi.bus.usecase.dto.req; import b1nd.dodamcore.bus.domain.entity.Bus; import jakarta.validation.constraints.NotEmpty; diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusMemberRes.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusMemberRes.java similarity index 91% rename from dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusMemberRes.java rename to dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusMemberRes.java index 1890845a..8f40347a 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusMemberRes.java +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusMemberRes.java @@ -1,4 +1,4 @@ -package b1nd.dodamcore.bus.application.dto.res; +package b1nd.dodamapi.bus.usecase.dto.res; import b1nd.dodamcore.bus.domain.entity.BusMember; diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusRes.java b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusRes.java similarity index 84% rename from dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusRes.java rename to dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusRes.java index cd7a9e50..dfe87cf1 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/dto/res/BusRes.java +++ b/dodam-api/src/main/java/b1nd/dodamapi/bus/usecase/dto/res/BusRes.java @@ -1,4 +1,4 @@ -package b1nd.dodamcore.bus.application.dto.res; +package b1nd.dodamapi.bus.usecase.dto.res; import b1nd.dodamcore.bus.domain.entity.Bus; diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusApplicationService.java b/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusApplicationService.java new file mode 100644 index 00000000..c146ad60 --- /dev/null +++ b/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusApplicationService.java @@ -0,0 +1,40 @@ +package b1nd.dodamcore.bus.application; + +import b1nd.dodamcore.bus.domain.entity.Bus; +import b1nd.dodamcore.bus.domain.entity.BusMember; +import b1nd.dodamcore.bus.repository.BusMemberRepository; +import b1nd.dodamcore.member.domain.entity.Student; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class BusApplicationService { + + private final BusMemberRepository repository; + + public void save(BusMember busMember) { + repository.save(busMember); + } + + public void delete(BusMember busMember) { + repository.delete(busMember); + } + + public Optional findValidApplication(Student student, LocalDateTime now) { + return repository.findByStudentAndBus_LeaveTimeAfter(student, now); + } + + public boolean hasValidApplication(Student student, LocalDateTime now) { + return repository.existsByStudentAndBus_LeaveTimeAfter(student, now); + } + + public List getByBus(Bus bus) { + return repository.findByBusOrderByStudentAsc(bus); + } + +} diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusService.java b/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusService.java index 1d51dcd5..eda80ac4 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusService.java +++ b/dodam-core/src/main/java/b1nd/dodamcore/bus/application/BusService.java @@ -1,177 +1,64 @@ package b1nd.dodamcore.bus.application; -import b1nd.dodamcore.bus.application.dto.req.BusReq; -import b1nd.dodamcore.bus.application.dto.res.BusMemberRes; -import b1nd.dodamcore.bus.application.dto.res.BusRes; import b1nd.dodamcore.bus.domain.entity.Bus; -import b1nd.dodamcore.bus.domain.entity.BusMember; -import b1nd.dodamcore.bus.domain.exception.*; -import b1nd.dodamcore.bus.repository.BusMemberRepository; +import b1nd.dodamcore.bus.domain.exception.BusFullOfSeatException; +import b1nd.dodamcore.bus.domain.exception.BusNotFoundException; +import b1nd.dodamcore.bus.domain.exception.BusPeriodExpiredException; import b1nd.dodamcore.bus.repository.BusRepository; -import b1nd.dodamcore.common.util.ModifyUtil; import b1nd.dodamcore.common.util.ZonedDateTimeUtil; -import b1nd.dodamcore.member.application.MemberSessionHolder; -import b1nd.dodamcore.member.domain.entity.Student; -import b1nd.dodamcore.member.repository.StudentRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor -@Transactional(readOnly = true) public class BusService { - private final MemberSessionHolder memberSessionHolder; - private final BusRepository busRepository; - private final BusMemberRepository busMemberRepository; - private final StudentRepository studentRepository; + private final BusRepository repository; - public List getValidBuses() { - - LocalDateTime now = ZonedDateTimeUtil.nowToLocalDateTime(); - List buses = busRepository.findBusByLeaveTimeBetween(now, now.plusDays(7)); - - if(buses.size() == 0) return new ArrayList<>(); - else return buses; - } - - public List getBuses(int page, int limit) { - - PageRequest pageRequest = PageRequest.of(page - 1, limit); - List buses = busRepository.findAllByOrderByIdDesc(pageRequest); - - return parseToBusList(buses); - } - - public List getBusesByDate(int year, int month, int day) { - List buses = busRepository.findAllByLeaveTime(LocalDate.of(year, month, day)); - return parseToBusList(buses); - } - - private List parseToBusList(List buses) { - return buses.stream().map(bus -> - BusRes.createFromBus( - bus, - getBusMembers(bus).stream() - .map(BusMemberRes::createFromBusMember) - .collect(Collectors.toList()) - ) - ).collect(Collectors.toList()); + public void save(Bus bus) { + repository.save(bus); } - private List getBusMembers(Bus bus) { - return busMemberRepository.findByBusOrderByStudentAsc(bus); - } - - public Bus getAppliedBus() { - Student student = studentRepository.findByMember(memberSessionHolder.current()) - .orElseThrow(RuntimeException::new); - return busRepository.findBusByStudent(LocalDateTime.now(), student.getId()); - } - - @Transactional(rollbackFor = Exception.class) - public void createBus(BusReq createBusReq) { - busRepository.save(createBusReq.mapToBus()); - } - - @Transactional(rollbackFor = Exception.class) - public void modifyBus(int id, BusReq modifyBusReq) { - - Bus bus = busRepository.findById(id) - .orElseThrow(BusNotFoundException::new); - - if(bus.getLeaveTime().isBefore(ZonedDateTimeUtil.nowToLocalDateTime())) { - throw new BusPeriodExpiredException(); - } - - bus.updateBus( - ModifyUtil.modifyIfNotNull(modifyBusReq.busName(), bus.getBusName()), - ModifyUtil.modifyIfNotNull(modifyBusReq.description(), bus.getDescription()), - ModifyUtil.modifyIfNotNull(modifyBusReq.leaveTime(), bus.getLeaveTime()), - ModifyUtil.modifyIfNotNull(modifyBusReq.timeRequired(), bus.getTimeRequired()), - ModifyUtil.modifyIfNotZero(modifyBusReq.peopleLimit(), bus.getPeopleLimit()) - ); + public void delete(Bus bus) { + repository.delete(bus); } - @Transactional(rollbackFor = Exception.class) - public void deleteBus(int id) { - - Bus bus = busRepository.findById(id) + public Bus getById(int id) { + return repository.findById(id) .orElseThrow(BusNotFoundException::new); - - busRepository.delete(bus); } - @Transactional(rollbackFor = Exception.class) - public void applyBus(int id) { - - Bus bus = busRepository.findById(id) + public Bus getByIdForUpdate(int id) { + Bus bus = repository.findByIdWithPessimisticLock(id) .orElseThrow(BusNotFoundException::new); - //TODO: studentService Exception 처리 - 중복되는 로직 - Student student = studentRepository.findByMember(memberSessionHolder.current()) - .orElseThrow(RuntimeException::new); - - bus.increaseApplyCount(); - - if(bus.getPeopleLimit() <= bus.getApplyCount()) { + if(bus.isFullOfSeat()) { throw new BusFullOfSeatException(); } - if(bus.getLeaveTime().isBefore(ZonedDateTimeUtil.nowToLocalDateTime())) { + if(bus.isExpired(ZonedDateTimeUtil.nowToLocalDateTime())) { throw new BusPeriodExpiredException(); } - if(busMemberRepository.existsByStudentAndBus_LeaveTimeAfter(student, ZonedDateTimeUtil.nowToLocalDateTime())) { - throw new BusAlreadyApplyException(); - } - - BusMember busMember = BusMember.builder() - .student(student) - .bus(bus) - .build(); - busMemberRepository.save(busMember); + return bus; } - @Transactional(rollbackFor = Exception.class) - public void modifyAppliedBus(int id) { - - Bus changeBus = busRepository.findById(id) - .orElseThrow(BusNotFoundException::new); - Student student = studentRepository.findByMember(memberSessionHolder.current()) - .orElseThrow(RuntimeException::new); - - if(changeBus.getLeaveTime().isBefore(ZonedDateTimeUtil.nowToLocalDateTime())) { - throw new BusPeriodExpiredException(); - } - - busMemberRepository.findByStudentAndBus_LeaveTimeAfter(student, ZonedDateTimeUtil.nowToLocalDateTime()).ifPresentOrElse( - busMember -> { - busMember.getBus().decreaseApplyCount(); - busMember.modifyBus(changeBus); - changeBus.increaseApplyCount(); - }, - () -> {throw new BusMemberNotFoundException();} - ); + public Bus getByStudent(LocalDateTime now, int studentId) { + return repository.findBusByStudent(now, studentId); } - @Transactional(rollbackFor = Exception.class) - public void cancelAppliedBus(int id) { + public List getAll(int page, int limit) { + return repository.findAllByOrderByIdDesc(PageRequest.of(page - 1, limit)); + } - Student student = studentRepository.findByMember(memberSessionHolder.current()) - .orElseThrow(RuntimeException::new); + public List getAllByDate(LocalDate date) { + return repository.findAllByLeaveTime(date); + } - busMemberRepository.findByStudentAndBus_Id(student, id).ifPresentOrElse( - busMember -> { - busMember.getBus().decreaseApplyCount(); - busMemberRepository.delete(busMember); - }, - () -> {throw new BusMemberNotFoundException();} - ); + public List getValid(LocalDateTime startAt, LocalDateTime endAt) { + return repository.findBusByLeaveTimeBetween(startAt, endAt); } + } diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/domain/entity/Bus.java b/dodam-core/src/main/java/b1nd/dodamcore/bus/domain/entity/Bus.java index d4642b81..e401e870 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/domain/entity/Bus.java +++ b/dodam-core/src/main/java/b1nd/dodamcore/bus/domain/entity/Bus.java @@ -51,6 +51,14 @@ public void decreaseApplyCount() { this.applyCount -= 1; } + public boolean isFullOfSeat() { + return peopleLimit == applyCount; + } + + public boolean isExpired(LocalDateTime now) { + return leaveTime.isBefore(now); + } + public void updateBus(String busName, String description, LocalDateTime leaveTime, LocalTime timeRequired, int peopleLimit) { this.busName = busName; this.description = description; @@ -67,4 +75,5 @@ public Bus(String busName, String description, int peopleLimit, LocalDateTime le this.leaveTime = leaveTime; this.timeRequired = timeRequired; } + } diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusMemberRepository.java b/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusMemberRepository.java index 041940f5..ebbd24c8 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusMemberRepository.java +++ b/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusMemberRepository.java @@ -17,10 +17,9 @@ public interface BusMemberRepository extends JpaRepository { @EntityGraph(attributePaths = {"student", "student.member"}) List findByBusOrderByStudentAsc(Bus bus); - Optional findByStudentAndBus_Id(Student student, int busId); - @EntityGraph(attributePaths = {"bus"}) Optional findByStudentAndBus_LeaveTimeAfter(Student student, LocalDateTime now); boolean existsByStudentAndBus_LeaveTimeAfter(Student student, LocalDateTime now); + } diff --git a/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusRepository.java b/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusRepository.java index 97f77800..10412b92 100644 --- a/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusRepository.java +++ b/dodam-core/src/main/java/b1nd/dodamcore/bus/repository/BusRepository.java @@ -1,8 +1,10 @@ package b1nd.dodamcore.bus.repository; import b1nd.dodamcore.bus.domain.entity.Bus; +import jakarta.persistence.LockModeType; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -10,11 +12,17 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @Repository public interface BusRepository extends JpaRepository { - List findBusByLeaveTimeBetween(LocalDateTime leaveTime1, LocalDateTime localTime2); + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("select b from bus b where b.id = :id") + Optional findByIdWithPessimisticLock(@Param("id") int id); + + List findBusByLeaveTimeBetween(LocalDateTime startAt, LocalDateTime endAt); + List findAllByOrderByIdDesc(Pageable pageable); @Query(value = "select * from bus " + @@ -24,4 +32,5 @@ public interface BusRepository extends JpaRepository { @Query("select b from bus b where b.leaveTime LIKE concat(:localDate, '%')") List findAllByLeaveTime(LocalDate localDate); + }