mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 10:09:35 +01:00
feat(production): articleId für Rezepte, TUI-Verbesserungen mit UoM-Carousel, ArticlePicker und Zutaten-Reorder
Backend: - articleId als Pflichtfeld im Recipe-Aggregate (Domain, Application, Infrastructure) - Liquibase-Migration 015 mit defaultValue für bestehende Daten - Alle Tests angepasst (Unit, Integration) Frontend: - UoM-Carousel-Selektor in RecipeCreateScreen, AddBatchScreen, AddIngredientScreen - ArticlePicker-Komponente mit Typeahead-Suche für Artikelauswahl - Auto-Position bei Zutatenzugabe (kein manuelles Feld mehr) - Automatische subRecipeId-Erkennung bei Artikelauswahl - Zutaten-Reorder per Drag im RecipeDetailScreen (Remove + Re-Add) - Artikelnamen statt UUIDs in der Rezept-Detailansicht - Navigation-Context: replace()-Methode ergänzt
This commit is contained in:
parent
b46495e1aa
commit
6c1e6c24bc
48 changed files with 999 additions and 237 deletions
|
|
@ -26,7 +26,7 @@ public class CreateRecipe {
|
|||
var draft = new RecipeDraft(
|
||||
cmd.name(), cmd.version(), cmd.type(), cmd.description(),
|
||||
cmd.yieldPercentage(), cmd.shelfLifeDays(),
|
||||
cmd.outputQuantity(), cmd.outputUom()
|
||||
cmd.outputQuantity(), cmd.outputUom(), cmd.articleId()
|
||||
);
|
||||
|
||||
Recipe recipe;
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@ public record CreateRecipeCommand(
|
|||
int yieldPercentage,
|
||||
Integer shelfLifeDays,
|
||||
String outputQuantity,
|
||||
String outputUom
|
||||
String outputUom,
|
||||
String articleId
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import static de.effigenix.shared.common.Result.*;
|
|||
* 11. Recipe can only be activated when it has at least one ingredient
|
||||
* 12. Recipe can only be activated from DRAFT status
|
||||
* 13. Recipe can only be archived from ACTIVE status
|
||||
* 14. ArticleId must not be blank (references the output article in Master Data)
|
||||
*/
|
||||
public class Recipe {
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ public class Recipe {
|
|||
private YieldPercentage yieldPercentage;
|
||||
private Integer shelfLifeDays;
|
||||
private Quantity outputQuantity;
|
||||
private String articleId;
|
||||
private RecipeStatus status;
|
||||
private final List<Ingredient> ingredients;
|
||||
private final List<ProductionStep> productionSteps;
|
||||
|
|
@ -57,6 +59,7 @@ public class Recipe {
|
|||
YieldPercentage yieldPercentage,
|
||||
Integer shelfLifeDays,
|
||||
Quantity outputQuantity,
|
||||
String articleId,
|
||||
RecipeStatus status,
|
||||
List<Ingredient> ingredients,
|
||||
List<ProductionStep> productionSteps,
|
||||
|
|
@ -71,6 +74,7 @@ public class Recipe {
|
|||
this.yieldPercentage = yieldPercentage;
|
||||
this.shelfLifeDays = shelfLifeDays;
|
||||
this.outputQuantity = outputQuantity;
|
||||
this.articleId = articleId;
|
||||
this.status = status;
|
||||
this.ingredients = new ArrayList<>(ingredients);
|
||||
this.productionSteps = new ArrayList<>(productionSteps);
|
||||
|
|
@ -111,7 +115,12 @@ public class Recipe {
|
|||
}
|
||||
}
|
||||
|
||||
// 5. Output Quantity (required, positive)
|
||||
// 5. ArticleId (required)
|
||||
if (draft.articleId() == null || draft.articleId().isBlank()) {
|
||||
return Result.failure(new RecipeError.ValidationFailure("ArticleId must not be blank"));
|
||||
}
|
||||
|
||||
// 6. Output Quantity (required, positive)
|
||||
Quantity outputQuantity;
|
||||
try {
|
||||
BigDecimal amount = new BigDecimal(draft.outputQuantity());
|
||||
|
|
@ -128,7 +137,7 @@ public class Recipe {
|
|||
return Result.success(new Recipe(
|
||||
RecipeId.generate(), name, draft.version(), draft.type(),
|
||||
draft.description(), yieldPercentage, shelfLifeDays, outputQuantity,
|
||||
RecipeStatus.DRAFT, List.of(), List.of(), now, now
|
||||
draft.articleId(), RecipeStatus.DRAFT, List.of(), List.of(), now, now
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -144,6 +153,7 @@ public class Recipe {
|
|||
YieldPercentage yieldPercentage,
|
||||
Integer shelfLifeDays,
|
||||
Quantity outputQuantity,
|
||||
String articleId,
|
||||
RecipeStatus status,
|
||||
List<Ingredient> ingredients,
|
||||
List<ProductionStep> productionSteps,
|
||||
|
|
@ -151,7 +161,7 @@ public class Recipe {
|
|||
OffsetDateTime updatedAt
|
||||
) {
|
||||
return new Recipe(id, name, version, type, description,
|
||||
yieldPercentage, shelfLifeDays, outputQuantity, status, ingredients, productionSteps, createdAt, updatedAt);
|
||||
yieldPercentage, shelfLifeDays, outputQuantity, articleId, status, ingredients, productionSteps, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
// ==================== Ingredient Management ====================
|
||||
|
|
@ -253,6 +263,7 @@ public class Recipe {
|
|||
public YieldPercentage yieldPercentage() { return yieldPercentage; }
|
||||
public Integer shelfLifeDays() { return shelfLifeDays; }
|
||||
public Quantity outputQuantity() { return outputQuantity; }
|
||||
public String articleId() { return articleId; }
|
||||
public RecipeStatus status() { return status; }
|
||||
public List<Ingredient> ingredients() { return Collections.unmodifiableList(ingredients); }
|
||||
public List<ProductionStep> productionSteps() { return Collections.unmodifiableList(productionSteps); }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ package de.effigenix.domain.production;
|
|||
* @param shelfLifeDays Shelf life in days (nullable; required for FINISHED_PRODUCT and INTERMEDIATE)
|
||||
* @param outputQuantity Expected output quantity amount (required)
|
||||
* @param outputUom Expected output unit of measure (required)
|
||||
* @param articleId Article ID of the output product (optional; null if not linked)
|
||||
*/
|
||||
public record RecipeDraft(
|
||||
String name,
|
||||
|
|
@ -21,5 +22,6 @@ public record RecipeDraft(
|
|||
int yieldPercentage,
|
||||
Integer shelfLifeDays,
|
||||
String outputQuantity,
|
||||
String outputUom
|
||||
String outputUom,
|
||||
String articleId
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ public class RecipeEntity {
|
|||
@Column(name = "output_uom", nullable = false, length = 20)
|
||||
private String outputUom;
|
||||
|
||||
@Column(name = "article_id", nullable = false, length = 36)
|
||||
private String articleId;
|
||||
|
||||
@Column(name = "status", nullable = false, length = 20)
|
||||
private String status;
|
||||
|
||||
|
|
@ -61,7 +64,7 @@ public class RecipeEntity {
|
|||
|
||||
public RecipeEntity(String id, String name, int version, String type, String description,
|
||||
int yieldPercentage, Integer shelfLifeDays, BigDecimal outputQuantity,
|
||||
String outputUom, String status, OffsetDateTime createdAt, OffsetDateTime updatedAt) {
|
||||
String outputUom, String articleId, String status, OffsetDateTime createdAt, OffsetDateTime updatedAt) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
|
|
@ -71,6 +74,7 @@ public class RecipeEntity {
|
|||
this.shelfLifeDays = shelfLifeDays;
|
||||
this.outputQuantity = outputQuantity;
|
||||
this.outputUom = outputUom;
|
||||
this.articleId = articleId;
|
||||
this.status = status;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
|
|
@ -85,6 +89,7 @@ public class RecipeEntity {
|
|||
public Integer getShelfLifeDays() { return shelfLifeDays; }
|
||||
public BigDecimal getOutputQuantity() { return outputQuantity; }
|
||||
public String getOutputUom() { return outputUom; }
|
||||
public String getArticleId() { return articleId; }
|
||||
public String getStatus() { return status; }
|
||||
public OffsetDateTime getCreatedAt() { return createdAt; }
|
||||
public OffsetDateTime getUpdatedAt() { return updatedAt; }
|
||||
|
|
@ -100,6 +105,7 @@ public class RecipeEntity {
|
|||
public void setShelfLifeDays(Integer shelfLifeDays) { this.shelfLifeDays = shelfLifeDays; }
|
||||
public void setOutputQuantity(BigDecimal outputQuantity) { this.outputQuantity = outputQuantity; }
|
||||
public void setOutputUom(String outputUom) { this.outputUom = outputUom; }
|
||||
public void setArticleId(String articleId) { this.articleId = articleId; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
public void setCreatedAt(OffsetDateTime createdAt) { this.createdAt = createdAt; }
|
||||
public void setUpdatedAt(OffsetDateTime updatedAt) { this.updatedAt = updatedAt; }
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public class RecipeMapper {
|
|||
recipe.shelfLifeDays(),
|
||||
recipe.outputQuantity().amount(),
|
||||
recipe.outputQuantity().uom().name(),
|
||||
recipe.articleId(),
|
||||
recipe.status().name(),
|
||||
recipe.createdAt(),
|
||||
recipe.updatedAt()
|
||||
|
|
@ -64,6 +65,7 @@ public class RecipeMapper {
|
|||
entity.getOutputQuantity(),
|
||||
UnitOfMeasure.valueOf(entity.getOutputUom())
|
||||
),
|
||||
entity.getArticleId(),
|
||||
RecipeStatus.valueOf(entity.getStatus()),
|
||||
ingredients,
|
||||
productionSteps,
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ public class RecipeController {
|
|||
var cmd = new CreateRecipeCommand(
|
||||
request.name(), request.version(), request.type(), request.description(),
|
||||
request.yieldPercentage(), request.shelfLifeDays(),
|
||||
request.outputQuantity(), request.outputUom()
|
||||
request.outputQuantity(), request.outputUom(), request.articleId()
|
||||
);
|
||||
var result = createRecipe.execute(cmd, actorId);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@ public record CreateRecipeRequest(
|
|||
int yieldPercentage,
|
||||
Integer shelfLifeDays,
|
||||
@NotBlank String outputQuantity,
|
||||
@NotBlank String outputUom
|
||||
@NotBlank String outputUom,
|
||||
@NotBlank String articleId
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(requiredProperties = {"id", "name", "version", "type", "description", "yieldPercentage", "outputQuantity", "outputUom", "status", "ingredients", "productionSteps", "createdAt", "updatedAt"})
|
||||
@Schema(requiredProperties = {"id", "name", "version", "type", "description", "yieldPercentage", "outputQuantity", "outputUom", "articleId", "status", "ingredients", "productionSteps", "createdAt", "updatedAt"})
|
||||
public record RecipeResponse(
|
||||
String id,
|
||||
String name,
|
||||
|
|
@ -17,6 +17,7 @@ public record RecipeResponse(
|
|||
@Schema(nullable = true) Integer shelfLifeDays,
|
||||
String outputQuantity,
|
||||
String outputUom,
|
||||
String articleId,
|
||||
String status,
|
||||
List<IngredientResponse> ingredients,
|
||||
List<ProductionStepResponse> productionSteps,
|
||||
|
|
@ -34,6 +35,7 @@ public record RecipeResponse(
|
|||
recipe.shelfLifeDays(),
|
||||
recipe.outputQuantity().amount().toPlainString(),
|
||||
recipe.outputQuantity().uom().name(),
|
||||
recipe.articleId(),
|
||||
recipe.status().name(),
|
||||
recipe.ingredients().stream().map(IngredientResponse::from).toList(),
|
||||
recipe.productionSteps().stream().map(ProductionStepResponse::from).toList(),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
@Schema(requiredProperties = {"id", "name", "version", "type", "description", "yieldPercentage", "outputQuantity", "outputUom", "status", "ingredientCount", "stepCount", "createdAt", "updatedAt"})
|
||||
@Schema(requiredProperties = {"id", "name", "version", "type", "description", "yieldPercentage", "outputQuantity", "outputUom", "articleId", "status", "ingredientCount", "stepCount", "createdAt", "updatedAt"})
|
||||
public record RecipeSummaryResponse(
|
||||
String id,
|
||||
String name,
|
||||
|
|
@ -16,6 +16,7 @@ public record RecipeSummaryResponse(
|
|||
@Schema(nullable = true) Integer shelfLifeDays,
|
||||
String outputQuantity,
|
||||
String outputUom,
|
||||
String articleId,
|
||||
String status,
|
||||
int ingredientCount,
|
||||
int stepCount,
|
||||
|
|
@ -33,6 +34,7 @@ public record RecipeSummaryResponse(
|
|||
recipe.shelfLifeDays(),
|
||||
recipe.outputQuantity().amount().toPlainString(),
|
||||
recipe.outputQuantity().uom().name(),
|
||||
recipe.articleId(),
|
||||
recipe.status().name(),
|
||||
recipe.ingredients().size(),
|
||||
recipe.productionSteps().size(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<changeSet id="018-add-article-id-to-recipes" author="effigenix">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="recipes" columnName="article_id"/>
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="recipes">
|
||||
<column name="article_id" type="VARCHAR(36)" defaultValue="UNKNOWN">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
@ -22,5 +22,6 @@
|
|||
<include file="db/changelog/changes/015-create-batches-table.xml"/>
|
||||
<include file="db/changelog/changes/016-create-batch-number-sequences-table.xml"/>
|
||||
<include file="db/changelog/changes/017-timestamps-to-timestamptz.xml"/>
|
||||
<include file="db/changelog/changes/018-add-article-id-to-recipes.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class ActivateRecipeTest {
|
|||
private Recipe draftRecipeWithIngredient() {
|
||||
var recipe = Recipe.create(new RecipeDraft(
|
||||
"Bratwurst", 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, 85, 14, "100", "KILOGRAM"
|
||||
null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
)).unsafeGetValue();
|
||||
recipe.addIngredient(new IngredientDraft(1, "article-123", "5.5", "KILOGRAM", null, false));
|
||||
return recipe;
|
||||
|
|
@ -52,7 +52,7 @@ class ActivateRecipeTest {
|
|||
private Recipe draftRecipeWithoutIngredient() {
|
||||
return Recipe.create(new RecipeDraft(
|
||||
"Bratwurst", 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, 85, 14, "100", "KILOGRAM"
|
||||
null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
)).unsafeGetValue();
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ class ActivateRecipeTest {
|
|||
RecipeId.of("recipe-1"), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class AddRecipeIngredientTest {
|
|||
private Recipe draftRecipe() {
|
||||
return Recipe.create(new RecipeDraft(
|
||||
"Bratwurst", 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, 85, 14, "100", "KILOGRAM"
|
||||
null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
)).unsafeGetValue();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class ArchiveRecipeTest {
|
|||
RecipeId.of("recipe-1"), new RecipeName("Bratwurst"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class ArchiveRecipeTest {
|
|||
private Recipe draftRecipe() {
|
||||
return Recipe.create(new RecipeDraft(
|
||||
"Bratwurst", 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, 85, 14, "100", "KILOGRAM"
|
||||
null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
)).unsafeGetValue();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ class ArchiveRecipeTest {
|
|||
RecipeId.of("recipe-2"), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
when(authPort.can(performedBy, ProductionAction.RECIPE_WRITE)).thenReturn(true);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class GetRecipeTest {
|
|||
RecipeId.of(id), new RecipeName("Bratwurst"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
"Beschreibung", new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class ListRecipesTest {
|
|||
RecipeId.of(id), new RecipeName("Rezept-" + id), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
status, List.of(), List.of(),
|
||||
"article-123", status, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class PlanBatchTest {
|
|||
RecipeId.of("recipe-1"), new RecipeName("Bratwurst"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ class PlanBatchTest {
|
|||
RecipeId.of("recipe-1"), new RecipeName("Bratwurst"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.DRAFT, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.DRAFT, List.of(), List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class RecipeCycleCheckerTest {
|
|||
RecipeId.of(id), new RecipeName("Recipe-" + id), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(100), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.DRAFT, ingredients, List.of(),
|
||||
"article-123", RecipeStatus.DRAFT, ingredients, List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC));
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ class RecipeCycleCheckerTest {
|
|||
RecipeId.of("B"), new RecipeName("Recipe-B"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(100), 14,
|
||||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.DRAFT, ingredients, List.of(),
|
||||
"article-123", RecipeStatus.DRAFT, ingredients, List.of(),
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC));
|
||||
|
||||
when(recipeRepository.findById(RecipeId.of("B"))).thenReturn(Result.success(Optional.of(recipeB)));
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class RecipeTest {
|
|||
return new RecipeDraft(
|
||||
"Bratwurst Grob", 1, RecipeType.FINISHED_PRODUCT,
|
||||
"Grobe Bratwurst nach Hausrezept", 85,
|
||||
14, "100", "KILOGRAM"
|
||||
14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when name is blank")
|
||||
void should_Fail_When_NameIsBlank() {
|
||||
var draft = new RecipeDraft(
|
||||
"", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM"
|
||||
"", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -69,7 +69,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when name is null")
|
||||
void should_Fail_When_NameIsNull() {
|
||||
var draft = new RecipeDraft(
|
||||
null, 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM"
|
||||
null, 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -82,7 +82,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when version is less than 1")
|
||||
void should_Fail_When_VersionLessThanOne() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 0, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM"
|
||||
"Test", 0, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -95,7 +95,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when yield percentage is 0")
|
||||
void should_Fail_When_YieldPercentageIsZero() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 0, 14, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 0, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -108,7 +108,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when yield percentage is 201")
|
||||
void should_Fail_When_YieldPercentageIs201() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 201, 14, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 201, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -121,7 +121,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when shelf life is 0 for FINISHED_PRODUCT")
|
||||
void should_Fail_When_ShelfLifeZeroForFinishedProduct() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 0, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 0, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -134,7 +134,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when shelf life is null for FINISHED_PRODUCT")
|
||||
void should_Fail_When_ShelfLifeNullForFinishedProduct() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, null, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, null, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -147,7 +147,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when shelf life is 0 for INTERMEDIATE")
|
||||
void should_Fail_When_ShelfLifeZeroForIntermediate() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.INTERMEDIATE, null, 85, 0, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.INTERMEDIATE, null, 85, 0, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -160,7 +160,7 @@ class RecipeTest {
|
|||
@DisplayName("should allow null shelf life for RAW_MATERIAL")
|
||||
void should_AllowNullShelfLife_When_RawMaterial() {
|
||||
var draft = new RecipeDraft(
|
||||
"Schweinefleisch", 1, RecipeType.RAW_MATERIAL, null, 100, null, "50", "KILOGRAM"
|
||||
"Schweinefleisch", 1, RecipeType.RAW_MATERIAL, null, 100, null, "50", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -173,7 +173,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when output quantity is zero")
|
||||
void should_Fail_When_OutputQuantityZero() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "0", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "0", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -186,7 +186,7 @@ class RecipeTest {
|
|||
@DisplayName("should fail when output UoM is invalid")
|
||||
void should_Fail_When_OutputUomInvalid() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "INVALID"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "INVALID", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -199,7 +199,7 @@ class RecipeTest {
|
|||
@DisplayName("should allow description to be null")
|
||||
void should_AllowNullDescription() {
|
||||
var draft = new RecipeDraft(
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM"
|
||||
"Test", 1, RecipeType.FINISHED_PRODUCT, null, 85, 14, "100", "KILOGRAM", "article-123"
|
||||
);
|
||||
|
||||
var result = Recipe.create(draft);
|
||||
|
|
@ -238,7 +238,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -444,7 +444,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -506,7 +506,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -527,7 +527,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -553,7 +553,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
var updatedBefore = recipe.updatedAt();
|
||||
|
|
@ -587,7 +587,7 @@ class RecipeTest {
|
|||
RecipeId.generate(), new RecipeName("Test"), 1, RecipeType.FINISHED_PRODUCT,
|
||||
null, new YieldPercentage(85), 14,
|
||||
Quantity.of(new java.math.BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
"article-123", RecipeStatus.ARCHIVED, List.of(), List.of(),
|
||||
java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC), java.time.OffsetDateTime.now(java.time.ZoneOffset.UTC)
|
||||
);
|
||||
|
||||
|
|
@ -614,7 +614,7 @@ class RecipeTest {
|
|||
recipe1.id(), new RecipeName("Other"), 2, RecipeType.RAW_MATERIAL,
|
||||
null, new YieldPercentage(100), null,
|
||||
Quantity.of(new java.math.BigDecimal("50"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
RecipeStatus.ACTIVE, List.of(), List.of(), recipe1.createdAt(), recipe1.updatedAt()
|
||||
"article-123", RecipeStatus.ACTIVE, List.of(), List.of(), recipe1.createdAt(), recipe1.updatedAt()
|
||||
);
|
||||
|
||||
assertThat(recipe1).isEqualTo(recipe2);
|
||||
|
|
|
|||
|
|
@ -312,7 +312,8 @@ class BatchControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
"yieldPercentage": 85,
|
||||
"shelfLifeDays": 14,
|
||||
"outputQuantity": "100",
|
||||
"outputUom": "KILOGRAM"
|
||||
"outputUom": "KILOGRAM",
|
||||
"articleId": "article-123"
|
||||
}
|
||||
""".formatted(UUID.randomUUID().toString().substring(0, 8));
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ class GetRecipeIntegrationTest extends AbstractIntegrationTest {
|
|||
"yieldPercentage": 85,
|
||||
"shelfLifeDays": 14,
|
||||
"outputQuantity": "100",
|
||||
"outputUom": "KILOGRAM"
|
||||
"outputUom": "KILOGRAM",
|
||||
"articleId": "article-123"
|
||||
}
|
||||
""";
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ class ListRecipesIntegrationTest extends AbstractIntegrationTest {
|
|||
"yieldPercentage": 85,
|
||||
"shelfLifeDays": 14,
|
||||
"outputQuantity": "100",
|
||||
"outputUom": "KILOGRAM"
|
||||
"outputUom": "KILOGRAM",
|
||||
"articleId": "article-123"
|
||||
}
|
||||
""".formatted(name, version);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue