MovementController.java
/*
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openwms.wms.movements;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.ameba.http.MeasuredRestController;
import org.openwms.core.http.AbstractWebController;
import org.openwms.core.http.Index;
import org.openwms.wms.movements.api.MovementType;
import org.openwms.wms.movements.api.MovementVO;
import org.openwms.wms.movements.api.ValidationGroups;
import org.openwms.wms.movements.spi.DefaultMovementState;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import static java.util.Arrays.asList;
import static org.openwms.wms.movements.api.MovementApi.API_MOVEMENTS;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
/**
* A MovementController.
*
* @author Heiko Scherrer
*/
@Validated
@MeasuredRestController
@RefreshScope
public class MovementController extends AbstractWebController {
private final MovementService service;
public MovementController(MovementService service) {
this.service = service;
}
@GetMapping(API_MOVEMENTS + "/index")
public ResponseEntity<Index> index() {
return ResponseEntity.ok(
new Index(
linkTo(methodOn(MovementController.class).create("transportUnitBK", new MovementVO(), null)).withRel("movement-create"),
linkTo(methodOn(MovementController.class).findAll()).withRel("movement-findAll"),
linkTo(methodOn(MovementController.class).findForTuAndTypesAndStates("transportUnitBK", asList(MovementType.INBOUND), asList("state"))).withRel("movement-findForTuAndTypesAndStates"),
linkTo(methodOn(MovementController.class).findForStateAndTypesAndSource("state", "source", MovementType.INBOUND)).withRel("movement-findForStateAndTypesAndSource"),
linkTo(methodOn(MovementController.class).move("pKey", new MovementVO())).withRel("movement-move"),
linkTo(methodOn(MovementController.class).cancel("pKey")).withRel("movement-cancel"),
linkTo(methodOn(MovementController.class).complete("pKey", new MovementVO())).withRel("movement-complete")
)
);
}
@PostMapping("/v1/transport-units/{bk}/movements")
@Validated(ValidationGroups.Movement.Create.class)
public ResponseEntity<MovementVO> create(@PathVariable("bk") String bk,
@Valid @RequestBody MovementVO movement,
HttpServletRequest req) {
movement.setTransportUnitBk(bk);
var created = service.create(bk, movement);
return ResponseEntity
.created(getLocationURIForCreatedResource(req, created.getPersistentKey()))
.body(created);
}
@PatchMapping(API_MOVEMENTS + "/{pKey}")
@Validated(ValidationGroups.Movement.Move.class)
public ResponseEntity<MovementVO> move(@PathVariable("pKey") String pKey,
@Valid @RequestBody MovementVO movement) {
return ResponseEntity.ok(service.move(pKey, movement));
}
@PatchMapping(API_MOVEMENTS + "/{pKey}/complete")
@Validated(ValidationGroups.Movement.Complete.class)
public ResponseEntity<MovementVO> complete(@PathVariable("pKey") String pKey,
@Valid @RequestBody MovementVO movement) {
return ResponseEntity.ok(service.complete(pKey, movement));
}
@DeleteMapping(API_MOVEMENTS + "/{pKey}")
public ResponseEntity<MovementVO> cancel(@PathVariable("pKey") String pKey) {
return ResponseEntity.ok(service.cancel(pKey));
}
@GetMapping(value = API_MOVEMENTS)
public ResponseEntity<List<MovementVO>> findAll(){
return ResponseEntity.ok(service.findAll());
}
@GetMapping(value = API_MOVEMENTS, params = {"barcode", "types", "states"})
public ResponseEntity<List<MovementVO>> findForTuAndTypesAndStates(
@RequestParam("barcode") String barcode,
@RequestParam("types") List<MovementType> types,
@RequestParam("states") List<String> states) {
return ResponseEntity.ok(service.findForTuAndTypesAndStates(barcode, types, states));
}
@GetMapping(value = API_MOVEMENTS, params = {"state", "types"})
public ResponseEntity<List<MovementVO>> findForStateAndTypesAndSource(@RequestParam("state") String state,
@RequestParam(value = "source", required = false) String source,
@RequestParam("types") MovementType... types) {
return ResponseEntity.ok(service.findFor(DefaultMovementState.valueOf(state), source, types));
}
}