From fe2f9ac1c3a3785f65f90b56b4c8a17630036cf4 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 21 Jan 2026 13:38:02 +0100 Subject: [PATCH 1/3] feat(client/nutrition-model): init modules for shopping list; missing impl but it has interface :) --- client/src/main/java/client/MyModule.java | 5 ++ .../NonFunctionalShoppingListService.java | 63 +++++++++++++++++++ .../client/service/ShoppingListService.java | 30 +++++++++ .../client/service/ShoppingListViewModel.java | 22 +++++++ 4 files changed, 120 insertions(+) create mode 100644 client/src/main/java/client/service/NonFunctionalShoppingListService.java create mode 100644 client/src/main/java/client/service/ShoppingListService.java create mode 100644 client/src/main/java/client/service/ShoppingListViewModel.java diff --git a/client/src/main/java/client/MyModule.java b/client/src/main/java/client/MyModule.java index 4d027ca..e40e613 100644 --- a/client/src/main/java/client/MyModule.java +++ b/client/src/main/java/client/MyModule.java @@ -21,6 +21,9 @@ import client.scenes.nutrition.NutritionDetailsCtrl; import client.scenes.nutrition.NutritionViewCtrl; import client.scenes.recipe.IngredientListCtrl; import client.scenes.recipe.RecipeStepListCtrl; +import client.service.NonFunctionalShoppingListService; +import client.service.ShoppingListService; +import client.service.ShoppingListViewModel; import client.utils.ConfigService; import client.utils.LocaleManager; import client.utils.server.ServerUtils; @@ -57,6 +60,8 @@ public class MyModule implements Module { binder.bind(new TypeLiteral>() {}).toInstance( new WebSocketDataService<>() ); + binder.bind(ShoppingListViewModel.class).toInstance(new ShoppingListViewModel()); + binder.bind(ShoppingListService.class).to(NonFunctionalShoppingListService.class); binder.bind(new TypeLiteral>() {}).toInstance( new WebSocketDataService<>() ); diff --git a/client/src/main/java/client/service/NonFunctionalShoppingListService.java b/client/src/main/java/client/service/NonFunctionalShoppingListService.java new file mode 100644 index 0000000..f5638ed --- /dev/null +++ b/client/src/main/java/client/service/NonFunctionalShoppingListService.java @@ -0,0 +1,63 @@ +package client.service; + +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Recipe; +import commons.RecipeIngredient; +import javafx.util.Pair; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.List; +import java.util.Optional; + +public class NonFunctionalShoppingListService extends ShoppingListService { + @Inject + public NonFunctionalShoppingListService(ShoppingListViewModel viewModel) { + super(viewModel); + } + + @Override + public void putIngredient(RecipeIngredient ingredient) { + throw new NotImplementedException(); + } + + @Override + public void putIngredient(RecipeIngredient ingredient, Recipe recipe) { + throw new NotImplementedException(); + } + + @Override + public void putIngredient(RecipeIngredient ingredient, String recipeName) { + throw new NotImplementedException(); + } + + @Override + public void putArbitraryItem(String name) { + throw new NotImplementedException(); + } + + @Override + public FormalIngredient purgeIngredient(Long id) { + throw new NotImplementedException(); + } + + @Override + public FormalIngredient purgeIngredient(String ingredientName) { + throw new NotImplementedException(); + } + + @Override + public void reset() { + throw new NotImplementedException(); + } + + @Override + public List>> getItems() { + throw new NotImplementedException(); + } + + @Override + public String makePrintable() { + throw new NotImplementedException(); + } +} diff --git a/client/src/main/java/client/service/ShoppingListService.java b/client/src/main/java/client/service/ShoppingListService.java new file mode 100644 index 0000000..c212750 --- /dev/null +++ b/client/src/main/java/client/service/ShoppingListService.java @@ -0,0 +1,30 @@ +package client.service; + +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Recipe; +import commons.RecipeIngredient; +import javafx.util.Pair; + +import java.util.List; +import java.util.Optional; + +public abstract class ShoppingListService { + private ShoppingListViewModel viewModel; + @Inject + public ShoppingListService(ShoppingListViewModel viewModel) { + this.viewModel = viewModel; + } + public abstract void putIngredient(FormalIngredient ingredient); + public abstract void putIngredient(FormalIngredient ingredient, Recipe recipe); + public abstract void putIngredient(FormalIngredient ingredient, String recipeName); + public abstract void putArbitraryItem(String name); + + public abstract FormalIngredient purgeIngredient(Long id); + public abstract FormalIngredient purgeIngredient(String ingredientName); + + public abstract void reset(); + + public abstract List>> getItems(); + public abstract String makePrintable(); +} diff --git a/client/src/main/java/client/service/ShoppingListViewModel.java b/client/src/main/java/client/service/ShoppingListViewModel.java new file mode 100644 index 0000000..30e03df --- /dev/null +++ b/client/src/main/java/client/service/ShoppingListViewModel.java @@ -0,0 +1,22 @@ +package client.service; + +import commons.FormalIngredient; +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.util.Pair; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.Optional; + +public class ShoppingListViewModel { + /** + * The formal ingredient provides the ingredient and its amount, + * and the string (optional) describes the recipe where it came from. + */ + private final ListProperty>> listItems = new SimpleListProperty<>(FXCollections.observableArrayList()); + public void addArbitrary() { + throw new NotImplementedException(); + } + +} From 11b038de1dd2724efbb2200ec34a0d53ecbb4981 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 21 Jan 2026 13:47:54 +0100 Subject: [PATCH 2/3] fix: non-functional API --- .../client/service/NonFunctionalShoppingListService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/client/service/NonFunctionalShoppingListService.java b/client/src/main/java/client/service/NonFunctionalShoppingListService.java index f5638ed..82dad5c 100644 --- a/client/src/main/java/client/service/NonFunctionalShoppingListService.java +++ b/client/src/main/java/client/service/NonFunctionalShoppingListService.java @@ -17,17 +17,17 @@ public class NonFunctionalShoppingListService extends ShoppingListService { } @Override - public void putIngredient(RecipeIngredient ingredient) { + public void putIngredient(FormalIngredient ingredient) { throw new NotImplementedException(); } @Override - public void putIngredient(RecipeIngredient ingredient, Recipe recipe) { + public void putIngredient(FormalIngredient ingredient, Recipe recipe) { throw new NotImplementedException(); } @Override - public void putIngredient(RecipeIngredient ingredient, String recipeName) { + public void putIngredient(FormalIngredient ingredient, String recipeName) { throw new NotImplementedException(); } From 79b46541a8104fa9794dd96c8817b36e3dcfa8a7 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 21 Jan 2026 14:37:40 +0100 Subject: [PATCH 3/3] feat: revised shop list item api --- client/src/main/java/client/MyModule.java | 4 +- .../NonFunctionalShoppingListService.java | 8 +-- .../java/client/service/ShopListItem.java | 32 +++++++++ .../client/service/ShoppingListService.java | 15 +++-- .../service/ShoppingListServiceImpl.java | 65 +++++++++++++++++++ .../client/service/ShoppingListViewModel.java | 38 +++++++++-- 6 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 client/src/main/java/client/service/ShopListItem.java create mode 100644 client/src/main/java/client/service/ShoppingListServiceImpl.java diff --git a/client/src/main/java/client/MyModule.java b/client/src/main/java/client/MyModule.java index e40e613..3ebcfe0 100644 --- a/client/src/main/java/client/MyModule.java +++ b/client/src/main/java/client/MyModule.java @@ -21,8 +21,8 @@ import client.scenes.nutrition.NutritionDetailsCtrl; import client.scenes.nutrition.NutritionViewCtrl; import client.scenes.recipe.IngredientListCtrl; import client.scenes.recipe.RecipeStepListCtrl; -import client.service.NonFunctionalShoppingListService; import client.service.ShoppingListService; +import client.service.ShoppingListServiceImpl; import client.service.ShoppingListViewModel; import client.utils.ConfigService; import client.utils.LocaleManager; @@ -61,7 +61,7 @@ public class MyModule implements Module { new WebSocketDataService<>() ); binder.bind(ShoppingListViewModel.class).toInstance(new ShoppingListViewModel()); - binder.bind(ShoppingListService.class).to(NonFunctionalShoppingListService.class); + binder.bind(ShoppingListService.class).to(ShoppingListServiceImpl.class); binder.bind(new TypeLiteral>() {}).toInstance( new WebSocketDataService<>() ); diff --git a/client/src/main/java/client/service/NonFunctionalShoppingListService.java b/client/src/main/java/client/service/NonFunctionalShoppingListService.java index 82dad5c..595f6a3 100644 --- a/client/src/main/java/client/service/NonFunctionalShoppingListService.java +++ b/client/src/main/java/client/service/NonFunctionalShoppingListService.java @@ -3,12 +3,10 @@ package client.service; import com.google.inject.Inject; import commons.FormalIngredient; import commons.Recipe; -import commons.RecipeIngredient; -import javafx.util.Pair; +import commons.Unit; import org.apache.commons.lang3.NotImplementedException; import java.util.List; -import java.util.Optional; public class NonFunctionalShoppingListService extends ShoppingListService { @Inject @@ -32,7 +30,7 @@ public class NonFunctionalShoppingListService extends ShoppingListService { } @Override - public void putArbitraryItem(String name) { + public void putArbitraryItem(Double amount, String name, Unit unit) { throw new NotImplementedException(); } @@ -52,7 +50,7 @@ public class NonFunctionalShoppingListService extends ShoppingListService { } @Override - public List>> getItems() { + public List getItems() { throw new NotImplementedException(); } diff --git a/client/src/main/java/client/service/ShopListItem.java b/client/src/main/java/client/service/ShopListItem.java new file mode 100644 index 0000000..f35b8d0 --- /dev/null +++ b/client/src/main/java/client/service/ShopListItem.java @@ -0,0 +1,32 @@ +package client.service; + +import commons.FormalIngredient; + +public class ShopListItem { + private FormalIngredient ingredient; + private String refRecipeName; + public ShopListItem(FormalIngredient ingredient, String refRecipeName) { + this.ingredient = ingredient; + this.refRecipeName = refRecipeName; + } + public ShopListItem(FormalIngredient ingredient) { + this.ingredient = ingredient; + this.refRecipeName = null; + } + + public FormalIngredient getIngredient() { + return ingredient; + } + + public String getRefRecipeName() { + return refRecipeName; + } + + public void setRefRecipeName(String refRecipeName) { + this.refRecipeName = refRecipeName; + } + + public void setIngredient(FormalIngredient ingredient) { + this.ingredient = ingredient; + } +} diff --git a/client/src/main/java/client/service/ShoppingListService.java b/client/src/main/java/client/service/ShoppingListService.java index c212750..8f32152 100644 --- a/client/src/main/java/client/service/ShoppingListService.java +++ b/client/src/main/java/client/service/ShoppingListService.java @@ -3,28 +3,31 @@ package client.service; import com.google.inject.Inject; import commons.FormalIngredient; import commons.Recipe; -import commons.RecipeIngredient; -import javafx.util.Pair; +import commons.Unit; import java.util.List; -import java.util.Optional; public abstract class ShoppingListService { - private ShoppingListViewModel viewModel; + private final ShoppingListViewModel viewModel; @Inject public ShoppingListService(ShoppingListViewModel viewModel) { this.viewModel = viewModel; } + + public ShoppingListViewModel getViewModel() { + return viewModel; + } + public abstract void putIngredient(FormalIngredient ingredient); public abstract void putIngredient(FormalIngredient ingredient, Recipe recipe); public abstract void putIngredient(FormalIngredient ingredient, String recipeName); - public abstract void putArbitraryItem(String name); + public abstract void putArbitraryItem(Double amount, String name, Unit unit); public abstract FormalIngredient purgeIngredient(Long id); public abstract FormalIngredient purgeIngredient(String ingredientName); public abstract void reset(); - public abstract List>> getItems(); + public abstract List getItems(); public abstract String makePrintable(); } diff --git a/client/src/main/java/client/service/ShoppingListServiceImpl.java b/client/src/main/java/client/service/ShoppingListServiceImpl.java new file mode 100644 index 0000000..03a23f6 --- /dev/null +++ b/client/src/main/java/client/service/ShoppingListServiceImpl.java @@ -0,0 +1,65 @@ +package client.service; + +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Recipe; +import commons.Unit; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.List; + +public class ShoppingListServiceImpl extends ShoppingListService { + @Inject + public ShoppingListServiceImpl(ShoppingListViewModel viewModel) { + super(viewModel); + } + + @Override + public void putIngredient(FormalIngredient ingredient) { + getViewModel().add(ingredient); + } + + @Override + public void putIngredient(FormalIngredient ingredient, Recipe recipe) { + putIngredient(ingredient, recipe.getName()); + } + + @Override + public void putIngredient(FormalIngredient ingredient, String recipeName) { + getViewModel().add(ingredient, recipeName); + } + + @Override + public void putArbitraryItem(Double amount, String name, Unit unit) { + throw new NotImplementedException(); + } + + @Override + public FormalIngredient purgeIngredient(Long id) { + FormalIngredient i = getViewModel().get(id).getIngredient(); + getViewModel().delete(id); + return i; + } + + @Override + public FormalIngredient purgeIngredient(String ingredientName) { + FormalIngredient i = getViewModel().get(ingredientName).getIngredient(); + getViewModel().delete(ingredientName); + return i; + } + + @Override + public void reset() { + throw new NotImplementedException(); + } + + @Override + public List getItems() { + return getViewModel().getListItems(); + } + + @Override + public String makePrintable() { + return ""; + } +} diff --git a/client/src/main/java/client/service/ShoppingListViewModel.java b/client/src/main/java/client/service/ShoppingListViewModel.java index 30e03df..7bce792 100644 --- a/client/src/main/java/client/service/ShoppingListViewModel.java +++ b/client/src/main/java/client/service/ShoppingListViewModel.java @@ -4,19 +4,49 @@ import commons.FormalIngredient; import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; import javafx.collections.FXCollections; -import javafx.util.Pair; +import javafx.collections.ObservableList; import org.apache.commons.lang3.NotImplementedException; - -import java.util.Optional; +import java.util.function.Predicate; public class ShoppingListViewModel { /** * The formal ingredient provides the ingredient and its amount, * and the string (optional) describes the recipe where it came from. */ - private final ListProperty>> listItems = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty listItems = new SimpleListProperty<>(FXCollections.observableArrayList()); public void addArbitrary() { throw new NotImplementedException(); } + public void add(FormalIngredient formalIngredient) { + listItems.get().add(new ShopListItem(formalIngredient)); + } + public void add(FormalIngredient formalIngredient, String recipeName) { + listItems.get().add(new ShopListItem(formalIngredient, recipeName)); + } + public ShopListItem get(Long id) { + return get(item -> item.getIngredient().getId().equals(id)); + } + private ShopListItem get(Predicate matcher) { + return listItems.get().stream() + .filter(matcher) + .findFirst() + .orElseThrow(NullPointerException::new); + } + public ShopListItem get(String recipeName) { + return get(i -> i.getRefRecipeName().equals(recipeName)); + } + public void delete(Long id) { + throw new NotImplementedException(); + } + public ObservableList getListItems() { + return listItems.get(); + } + + /** + * Deleting an item of name which is not associated to any recipe. + * @param name the name of the ingredient + */ + public void delete(String name) { + } }