mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 13:49:36 +01:00
refactor(inventory): InvalidFilterCombination Error und CreateStockResponse trennen
- StockError.InvalidFilterCombination statt InvalidArticleId für ungültige Filter-Kombination in ListStocks - CreateStockResponse als eigenständiges DTO für POST createStock (ohne batches/quantities), StockResponse bleibt für GET-Endpoints - MinimumLevelResponse als shared Top-Level-Record extrahiert
This commit is contained in:
parent
1ef37497c3
commit
fef3baa0ae
8 changed files with 55 additions and 7 deletions
|
|
@ -22,7 +22,7 @@ public class ListStocks {
|
|||
|
||||
public Result<StockError, List<Stock>> execute(String storageLocationId, String articleId) {
|
||||
if (storageLocationId != null && articleId != null) {
|
||||
return Result.failure(new StockError.InvalidArticleId(
|
||||
return Result.failure(new StockError.InvalidFilterCombination(
|
||||
"Only one filter parameter allowed: storageLocationId or articleId"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ public sealed interface StockError {
|
|||
@Override public String message() { return "Batch " + id + " is not blocked"; }
|
||||
}
|
||||
|
||||
record InvalidFilterCombination(String message) implements StockError {
|
||||
@Override public String code() { return "INVALID_FILTER_COMBINATION"; }
|
||||
}
|
||||
|
||||
record Unauthorized(String message) implements StockError {
|
||||
@Override public String code() { return "UNAUTHORIZED"; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import de.effigenix.shared.security.ActorId;
|
|||
import de.effigenix.infrastructure.inventory.web.dto.AddStockBatchRequest;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.BlockStockBatchRequest;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.CreateStockRequest;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.CreateStockResponse;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.RemoveStockBatchRequest;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.StockBatchResponse;
|
||||
import de.effigenix.infrastructure.inventory.web.dto.StockResponse;
|
||||
|
|
@ -93,7 +94,7 @@ public class StockController {
|
|||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('STOCK_WRITE')")
|
||||
public ResponseEntity<StockResponse> createStock(
|
||||
public ResponseEntity<CreateStockResponse> createStock(
|
||||
@Valid @RequestBody CreateStockRequest request,
|
||||
Authentication authentication
|
||||
) {
|
||||
|
|
@ -113,7 +114,7 @@ public class StockController {
|
|||
|
||||
logger.info("Stock created: {}", result.unsafeGetValue().id().value());
|
||||
return ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(StockResponse.from(result.unsafeGetValue()));
|
||||
.body(CreateStockResponse.from(result.unsafeGetValue()));
|
||||
}
|
||||
|
||||
@PostMapping("/{stockId}/batches")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package de.effigenix.infrastructure.inventory.web.dto;
|
||||
|
||||
import de.effigenix.domain.inventory.Stock;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(requiredProperties = {"id", "articleId", "storageLocationId"})
|
||||
public record CreateStockResponse(
|
||||
String id,
|
||||
String articleId,
|
||||
String storageLocationId,
|
||||
@Schema(nullable = true) MinimumLevelResponse minimumLevel,
|
||||
@Schema(nullable = true) Integer minimumShelfLifeDays
|
||||
) {
|
||||
|
||||
public static CreateStockResponse from(Stock stock) {
|
||||
MinimumLevelResponse minimumLevel = null;
|
||||
if (stock.minimumLevel() != null) {
|
||||
minimumLevel = new MinimumLevelResponse(
|
||||
stock.minimumLevel().quantity().amount(),
|
||||
stock.minimumLevel().quantity().uom().name()
|
||||
);
|
||||
}
|
||||
|
||||
Integer shelfLifeDays = null;
|
||||
if (stock.minimumShelfLife() != null) {
|
||||
shelfLifeDays = stock.minimumShelfLife().days();
|
||||
}
|
||||
|
||||
return new CreateStockResponse(
|
||||
stock.id().value(),
|
||||
stock.articleId().value(),
|
||||
stock.storageLocationId().value(),
|
||||
minimumLevel,
|
||||
shelfLifeDays
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package de.effigenix.infrastructure.inventory.web.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(requiredProperties = {"amount", "unit"})
|
||||
public record MinimumLevelResponse(BigDecimal amount, String unit) {}
|
||||
|
|
@ -63,7 +63,4 @@ public record StockResponse(
|
|||
availableQuantity
|
||||
);
|
||||
}
|
||||
|
||||
@Schema(requiredProperties = {"amount", "unit"})
|
||||
public record MinimumLevelResponse(BigDecimal amount, String unit) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public final class InventoryErrorHttpStatusMapper {
|
|||
case StockError.InvalidBatchReference e -> 400;
|
||||
case StockError.InvalidQuantity e -> 400;
|
||||
case StockError.InvalidExpiryDate e -> 400;
|
||||
case StockError.InvalidFilterCombination e -> 400;
|
||||
case StockError.Unauthorized e -> 403;
|
||||
case StockError.RepositoryFailure e -> 500;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class ListStocksTest {
|
|||
var result = listStocks.execute("location-1", "article-1");
|
||||
|
||||
assertThat(result.isFailure()).isTrue();
|
||||
assertThat(result.unsafeGetError()).isInstanceOf(StockError.InvalidArticleId.class);
|
||||
assertThat(result.unsafeGetError()).isInstanceOf(StockError.InvalidFilterCombination.class);
|
||||
verifyNoInteractions(stockRepository);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue