LoadUnitController.java
package com.v1rex.liftnexus.loadunit.controller;
import com.v1rex.liftnexus.loadunit.domain.LoadUnitStatus;
import com.v1rex.liftnexus.loadunit.dto.LoadUnitRequest;
import com.v1rex.liftnexus.loadunit.dto.LoadUnitResponse;
import com.v1rex.liftnexus.loadunit.service.LoadUnitService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
@RestController
@RequestMapping("/api/v1/load-units")
@Validated
@Slf4j
@RequiredArgsConstructor
@Tag(
name = "Load Units",
description = "Manage load units (pallets, containers) and their tracking")
public class LoadUnitController {
private final LoadUnitService loadUnitService;
@Operation(
summary = "Register a new load unit",
description =
"Creates a new load unit with a unique tracking code, weight, initial status, and optional storage bin assignment.")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Load unit created"),
@ApiResponse(
responseCode = "400",
description = "Invalid input",
content = @io.swagger.v3.oas.annotations.media.Content),
@ApiResponse(
responseCode = "409",
description = "Tracking code already exists",
content = @io.swagger.v3.oas.annotations.media.Content)
})
@PostMapping
public ResponseEntity<LoadUnitResponse> createLoadUnit(
@RequestBody @Valid LoadUnitRequest request) {
log.info("REST request to create Load Unit with tracking code: {}", request.trackingCode());
LoadUnitResponse savedUnit = loadUnitService.createLoadUnit(request);
URI location =
ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(savedUnit.id())
.toUri();
return ResponseEntity.created(location).body(savedUnit);
}
@Operation(
summary = "Get a load unit by ID",
description = "Retrieves details of a specific load unit.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Load unit found"),
@ApiResponse(
responseCode = "404",
description = "Load unit not found",
content = @io.swagger.v3.oas.annotations.media.Content)
})
@GetMapping("/{id}")
public ResponseEntity<LoadUnitResponse> findById(@PathVariable Long id) {
log.info("REST request to get Load Unit by ID: {}", id);
return ResponseEntity.ok(loadUnitService.findById(id));
}
@Operation(
summary = "Find a load unit by tracking code",
description = "Retrieves a load unit using its unique tracking code.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Load unit found"),
@ApiResponse(
responseCode = "404",
description = "Load unit not found",
content = @io.swagger.v3.oas.annotations.media.Content)
})
@GetMapping("/tracking/{trackingCode}")
public ResponseEntity<LoadUnitResponse> findByTrackingCode(@PathVariable String trackingCode) {
log.info("REST request to get Load Unit by tracking code: {}", trackingCode);
return ResponseEntity.ok(loadUnitService.findByTrackingCode(trackingCode));
}
@Operation(
summary = "List all load units",
description = "Returns a paginated list of all load units in the system.")
@ApiResponse(responseCode = "200", description = "Paginated list of load units")
@GetMapping
public ResponseEntity<Page<LoadUnitResponse>> findAll(
@PageableDefault(size = 20, sort = "id", direction = Sort.Direction.ASC) Pageable pageable) {
log.info(
"REST request to get all Load Units (Page size: {}, Page number: {})",
pageable.getPageSize(),
pageable.getPageNumber());
return ResponseEntity.ok(loadUnitService.findAll(pageable));
}
@Operation(
summary = "Filter load units by status",
description =
"Returns a paginated list of load units filtered by their current status (e.g., STORED, IN_TRANSIT).")
@ApiResponse(responseCode = "200", description = "Matching load units")
@GetMapping("/status/{status}")
public ResponseEntity<Page<LoadUnitResponse>> findByStatus(
@Parameter(description = "Load unit status to filter by") @PathVariable LoadUnitStatus status,
@PageableDefault(size = 20, sort = "id", direction = Sort.Direction.ASC) Pageable pageable) {
log.info("REST request to get Load Units by status: {}", status);
return ResponseEntity.ok(loadUnitService.findByStatus(status, pageable));
}
}