opr-rest-api/src/main/java/com/goi/erp/controller/VehicleDispatchController.java

261 lines
10 KiB
Java

package com.goi.erp.controller;
import com.goi.erp.common.permission.PermissionSet;
import com.goi.erp.dto.VehicleDispatchRequestDto;
import com.goi.erp.entity.VehicleDispatch;
import com.goi.erp.repository.VehicleDispatchRepository;
import com.goi.erp.common.permission.PermissionChecker;
import com.goi.erp.token.PermissionAuthenticationToken;
import com.goi.erp.service.VehicleDispatchService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/api/vehicle-dispatch")
@RequiredArgsConstructor
public class VehicleDispatchController {
private final VehicleDispatchService dispatchService;
private final VehicleDispatchRepository dispatchRepository;
// 기본값
private final int defaultPage = 0;
private final int defaultSize = 50;
private final int maxSize = 500;
/* ============================================================
CREATE (MANUAL)
============================================================ */
@PostMapping("/manual")
public ResponseEntity<VehicleDispatch> createManualDispatch(
@RequestBody VehicleDispatchRequestDto requestDto
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canCreateOPR(permissionSet)) {
throw new AccessDeniedException("You do not have permission to create dispatch");
}
VehicleDispatch created =
dispatchService.createManualDispatch(requestDto, auth.getName());
return new ResponseEntity<>(created, HttpStatus.CREATED);
}
/* ============================================================
PATCH (MANUAL)
============================================================ */
@PatchMapping("/manual/{uuid}")
public ResponseEntity<VehicleDispatch> patchManualDispatch(
@PathVariable UUID uuid,
@RequestBody VehicleDispatchRequestDto requestDto
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canUpdateOPR(permissionSet)) {
throw new AccessDeniedException("You do not have permission to update dispatch");
}
VehicleDispatch updated =
dispatchService.patchManualDispatch(uuid, requestDto, auth.getName());
return ResponseEntity.ok(updated);
}
/* ============================================================
STATE CHANGE (MANUAL)
============================================================ */
@PostMapping("/{uuid}/pause")
public ResponseEntity<Void> pauseDispatch(
@PathVariable UUID uuid,
@RequestParam(required = false) LocalDateTime pausedAt
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canUpdateOPR(permissionSet)) {
throw new AccessDeniedException("You do not have permission to update dispatch");
}
dispatchService.pauseDispatch(uuid, pausedAt);
return ResponseEntity.ok().build();
}
@PostMapping("/{uuid}/close")
public ResponseEntity<Void> closeDispatch(
@PathVariable UUID uuid,
@RequestParam(required = false) LocalDateTime endAt,
@RequestParam(required = false) BigDecimal endOdometerEnd, // DB: ved_odometer_end 로 저장
@RequestParam(required = false) String reason
) {
PermissionAuthenticationToken auth =
(PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canUpdateOPR(permissionSet)) {
throw new AccessDeniedException("You do not have permission to update dispatch");
}
dispatchService.closeDispatch(
uuid,
endAt,
endOdometerEnd,
(reason == null || reason.isBlank()) ? "MANUAL_CLOSE" : reason
);
return ResponseEntity.ok().build();
}
/* ============================================================
READ ONE
============================================================ */
@GetMapping("/{uuid}")
public ResponseEntity<VehicleDispatch> getOne(
@PathVariable UUID uuid
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canReadOPRAll(permissionSet)) {
throw new AccessDeniedException("You do not have permission to read dispatch data");
}
return dispatchRepository.findByVedUuid(uuid)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
/* ============================================================
READ ALL (Paged)
============================================================ */
@GetMapping
public ResponseEntity<Page<VehicleDispatch>> getAll(
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canReadOPRAll(permissionSet)) {
throw new AccessDeniedException("You do not have permission to read dispatch data");
}
int p = (page == null) ? defaultPage : page;
int s = (size == null) ? defaultSize : size;
if (s > maxSize) s = maxSize;
Pageable pageable = PageRequest.of(p, s);
return ResponseEntity.ok(dispatchRepository.findAll(pageable));
}
/* ============================================================
READ BY DATE (가장 자주 쓰는 API)
- date만: 그날 전체
- date + vehId: 그 차량의 그날
- date + driverId: 그 기사 그날
============================================================ */
@GetMapping("/by-date")
public ResponseEntity<List<VehicleDispatch>> getByDate(
@RequestParam LocalDate date,
@RequestParam(required = false) Long vehId,
@RequestParam(required = false) Long driverId
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canReadOPRAll(permissionSet)) {
throw new AccessDeniedException("You do not have permission to read dispatch data");
}
if (vehId != null && driverId != null) {
// 둘 다 넣는 케이스가 있을까
throw new IllegalArgumentException("Use either vehId or driverId, not both");
}
if (vehId != null) {
return ResponseEntity.ok(
dispatchRepository.findByVedVehIdAndVedDispatchDate(vehId, date)
);
}
if (driverId != null) {
return ResponseEntity.ok(
dispatchRepository.findByVedDriverIdAndVedDispatchDate(driverId, date)
);
}
return ResponseEntity.ok(
dispatchRepository.findByVedDispatchDate(date)
);
}
/* ============================================================
JOB TRIGGER
- paused to closed
============================================================ */
@PostMapping("/jobs/close-paused")
public ResponseEntity<Void> closePaused(
@RequestParam(defaultValue = "60") long minutes
) {
PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getPermissionSet() == null) {
throw new AccessDeniedException("Permission information is missing");
}
PermissionSet permissionSet = auth.getPermissionSet();
if (!PermissionChecker.canUpdateOPR(permissionSet)) {
throw new AccessDeniedException("You do not have permission to update dispatch");
}
dispatchService.closePausedDispatches(Duration.ofMinutes(minutes));
return ResponseEntity.ok().build();
}
}