Midway ingkey/shopcat
This commit is contained in:
parent
a86f45e4c4
commit
9a88b81b7a
|
@ -3,6 +3,10 @@ package com.mousetech.gourmetj;
|
||||||
import com.mousetech.gourmetj.persistence.model.Ingredient;
|
import com.mousetech.gourmetj.persistence.model.Ingredient;
|
||||||
import com.mousetech.gourmetj.persistence.model.IngredientIF;
|
import com.mousetech.gourmetj.persistence.model.IngredientIF;
|
||||||
import com.mousetech.gourmetj.persistence.model.Recipe;
|
import com.mousetech.gourmetj.persistence.model.Recipe;
|
||||||
|
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||||
|
|
||||||
|
import net.bytebuddy.asm.Advice.This;
|
||||||
|
|
||||||
import com.mousetech.gourmetj.IngredientDigester;
|
import com.mousetech.gourmetj.IngredientDigester;
|
||||||
import com.mousetech.gourmetj.IngredientDigester.IngredientAmountFormat;
|
import com.mousetech.gourmetj.IngredientDigester.IngredientAmountFormat;
|
||||||
|
|
||||||
|
@ -355,22 +359,22 @@ public class IngredientUI implements IngredientIF {
|
||||||
ingredient.setUnit(unit);
|
ingredient.setUnit(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This goes to the shopCats table via ManyToOne at save
|
|
||||||
// time.
|
|
||||||
private String shopCat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the shopCat
|
* @return the shopCat
|
||||||
*/
|
*/
|
||||||
public String getShopCat() {
|
public String getShopCat() {
|
||||||
return shopCat;
|
Shopcat scat = this.ingredient.getShopCat();
|
||||||
|
if ( scat == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return scat.getShopcategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param shopCat the shopCat to set
|
* @param shopCat the shopCat to set
|
||||||
*/
|
*/
|
||||||
public void setShopCat(String shopCat) {
|
public void setShopCat(Shopcat shopCat) {
|
||||||
this.shopCat = shopCat;
|
this.ingredient.setShopCat(shopCat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class RecipeDetailBean implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistency service for Recipes
|
* Persistency service for Recipes, Shopcats and Categories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -257,7 +257,7 @@ public class RecipeDetailBean implements Serializable {
|
||||||
if (recipe == null) {
|
if (recipe == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Category> cList = recipe.getCategories();
|
Set<Category> cList = recipe.getCategories();
|
||||||
StringBuffer sb = new StringBuffer(35);
|
StringBuffer sb = new StringBuffer(35);
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
@ -308,7 +308,7 @@ public class RecipeDetailBean implements Serializable {
|
||||||
// Shopcat is an eager fetch on Ingredient
|
// Shopcat is an eager fetch on Ingredient
|
||||||
Shopcat shopCat = ing.getShopCat();
|
Shopcat shopCat = ing.getShopCat();
|
||||||
if (shopCat != null) {
|
if (shopCat != null) {
|
||||||
ingUi.setShopCat(shopCat.getShopcategory());
|
ingUi.setShopCat(shopCat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -510,11 +510,13 @@ public class RecipeDetailBean implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMoveUpAble() {
|
public boolean isMoveUpAble() {
|
||||||
if (isSelectionActive()) {
|
return true;
|
||||||
List<IngredientUI> rows = getWrappedIngredients();
|
// TODO:
|
||||||
return !rows.get(0).isSelected();
|
// if (isSelectionActive()) {
|
||||||
}
|
// List<IngredientUI> rows = getWrappedIngredients();
|
||||||
return false;
|
// return !rows.get(0).isSelected();
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMoveDownAble() {
|
public boolean isMoveDownAble() {
|
||||||
|
@ -572,24 +574,6 @@ public class RecipeDetailBean implements Serializable {
|
||||||
return "main";
|
return "main";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply ingredient group IDs (optional) to individual
|
|
||||||
* ingredients.
|
|
||||||
*
|
|
||||||
* @param wrappedIngredients The wrapped ingredient facade.
|
|
||||||
*/
|
|
||||||
private void updateRecipeGroups(
|
|
||||||
List<IngredientUI> wrappedIngredients) {
|
|
||||||
String ingGroup = null;
|
|
||||||
for (IngredientUI ingUI : wrappedIngredients) {
|
|
||||||
if (ingUI.isIngGroup()) {
|
|
||||||
ingGroup = ingUI.getItem();
|
|
||||||
} else {
|
|
||||||
ingUI.getIngredient().setInggroup(ingGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update ingredients and shopcat from UI model
|
* Update ingredients and shopcat from UI model
|
||||||
*
|
*
|
||||||
|
@ -612,34 +596,58 @@ public class RecipeDetailBean implements Serializable {
|
||||||
iList.clear();
|
iList.clear();
|
||||||
for (IngredientUI iui : saveIng) {
|
for (IngredientUI iui : saveIng) {
|
||||||
Ingredient ing = iui.getIngredient();
|
Ingredient ing = iui.getIngredient();
|
||||||
ing.setRecipe(recipe);
|
ing.setRecipe(recipe);
|
||||||
String ingKey = iui.getIngkey();
|
if ( ! updateShopcat(ing) ) {
|
||||||
String shopCatName = iui.getShopCat();
|
return false;
|
||||||
Shopcat scat = ing.getShopCat();
|
|
||||||
if (scat == null) {
|
|
||||||
if ((ingKey != null) && !ingKey.isBlank()) {
|
|
||||||
scat = new Shopcat();
|
|
||||||
// scat.setIngkey(ingKey);
|
|
||||||
scat.setShopcategory(shopCatName);
|
|
||||||
ing.setShopCat(scat);
|
|
||||||
} else {
|
|
||||||
JSFUtils.addErrorMessage(
|
|
||||||
"Shopping Category requires an Ingredient Key");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((ingKey == null) || ingKey.isBlank()) {
|
|
||||||
ing.setShopCat(null);
|
|
||||||
} else {
|
|
||||||
ing.getShopCat()
|
|
||||||
.setShopcategory(shopCatName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
iList.add(ing);
|
iList.add(ing);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply ingredient group IDs (optional) to individual
|
||||||
|
* ingredients.
|
||||||
|
*
|
||||||
|
* @param wrappedIngredients The wrapped ingredient facade.
|
||||||
|
*/
|
||||||
|
private void updateRecipeGroups(
|
||||||
|
List<IngredientUI> wrappedIngredients) {
|
||||||
|
String ingGroup = null;
|
||||||
|
for (IngredientUI ingUI : wrappedIngredients) {
|
||||||
|
if (ingUI.isIngGroup()) {
|
||||||
|
ingGroup = ingUI.getItem();
|
||||||
|
} else {
|
||||||
|
ingUI.getIngredient().setInggroup(ingGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update shopcat for Ingredient.
|
||||||
|
*
|
||||||
|
* @param ing Ingredient to update
|
||||||
|
* @return true if update succeeded.
|
||||||
|
*/
|
||||||
|
private boolean updateShopcat(Ingredient ing) {
|
||||||
|
final String ingKey = ing.getIngkey();
|
||||||
|
if ( (ingKey == null) || (ingKey.isBlank())) {
|
||||||
|
ing.setIngkey(null);
|
||||||
|
ing.setShopCat(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Shopcat scat = recipeService.findShopcatForIngredientKey(ingKey);
|
||||||
|
if ( scat == null ) {
|
||||||
|
JSFUtils.addErrorMessage(
|
||||||
|
"No Shopping Category is defined for Ingredient Key "+ ingKey);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
ing.setShopCat(scat);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse out the comma-separated category text control and
|
* Parse out the comma-separated category text control and
|
||||||
* post the results as children of the recipe
|
* post the results as children of the recipe
|
||||||
|
@ -797,8 +805,10 @@ public class RecipeDetailBean implements Serializable {
|
||||||
return shopcatList;
|
return shopcatList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ajaxShopcat(AjaxBehaviorEvent event) {
|
public void ajaxUpdateShopcat(AjaxBehaviorEvent event) {
|
||||||
log.warn("SHOPCAT ");
|
log.warn("SHOPCAT ");
|
||||||
|
// Shopcat scat = recipeService.findShopcatForIngredientKey(ssss);
|
||||||
|
// ing.setShopcat(scat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***
|
// ***
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository;
|
||||||
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JpaRepository for Shoppind Categories, which relate ManyToOne to Ingredient.
|
* JpaRepository for Shopping Categories, which relate ManyToOne to Ingredient.
|
||||||
* Service method is @see RecipeService
|
* Service method is @see RecipeService
|
||||||
*
|
*
|
||||||
* @author timh
|
* @author timh
|
||||||
|
@ -27,4 +27,6 @@ public interface ShopcatRepository
|
||||||
|
|
||||||
@Query(value = SQL_FIND_CATEGORIES, nativeQuery = true)
|
@Query(value = SQL_FIND_CATEGORIES, nativeQuery = true)
|
||||||
public List<String> findDistinctCategoryNative();
|
public List<String> findDistinctCategoryNative();
|
||||||
|
|
||||||
|
public Shopcat findShopcatByIngkey(String ingkey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,7 @@ public class Ingredient implements Serializable, IngredientIF {
|
||||||
@ManyToOne(fetch = FetchType.EAGER, cascade = {
|
@ManyToOne(fetch = FetchType.EAGER, cascade = {
|
||||||
CascadeType.PERSIST, CascadeType.MERGE,
|
CascadeType.PERSIST, CascadeType.MERGE,
|
||||||
CascadeType.REFRESH }, optional = true)
|
CascadeType.REFRESH }, optional = true)
|
||||||
@JoinColumn(name = "ingkey", insertable = false,
|
@JoinColumn(name = "ingkey", referencedColumnName = "ingkey")
|
||||||
updatable = false, nullable = true,
|
|
||||||
foreignKey = @ForeignKey(name = "ingkey"))
|
|
||||||
Shopcat shopCat;
|
Shopcat shopCat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +51,7 @@ public class Ingredient implements Serializable, IngredientIF {
|
||||||
@Column(name = "inggroup")
|
@Column(name = "inggroup")
|
||||||
private String inggroup;
|
private String inggroup;
|
||||||
|
|
||||||
@Column(name = "ingkey")
|
@Column(name = "ingkey",insertable = false, updatable = false)
|
||||||
private String ingkey;
|
private String ingkey;
|
||||||
|
|
||||||
@Column(name = "item")
|
@Column(name = "item")
|
||||||
|
|
|
@ -39,7 +39,10 @@ public class Shopcat implements Serializable {
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
//@Column(name = "ingkey", unique = true, nullable = false )
|
@Column(name = "ingkey", unique = true, nullable = false )
|
||||||
|
private String ingkey;
|
||||||
|
|
||||||
|
|
||||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "ingkey" )
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "ingkey" )
|
||||||
private List<Ingredient> ingredients;
|
private List<Ingredient> ingredients;
|
||||||
|
|
||||||
|
@ -73,7 +76,21 @@ public class Shopcat implements Serializable {
|
||||||
public void setId(Long id) {
|
public void setId(Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ingkey
|
||||||
|
*/
|
||||||
|
public String getIngkey() {
|
||||||
|
return ingkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ingkey the ingkey to set
|
||||||
|
*/
|
||||||
|
public void setIngkey(String ingkey) {
|
||||||
|
this.ingkey = ingkey;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getPosition() {
|
public Integer getPosition() {
|
||||||
return this.position;
|
return this.position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,15 @@ import java.util.Optional;
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.persistence.NamedEntityGraph;
|
|
||||||
import javax.persistence.NamedNativeQuery;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.jpa.repository.EntityGraph;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.mousetech.gourmetj.RecipeDetailBean;
|
|
||||||
import com.mousetech.gourmetj.persistence.dao.CategoryRepository;
|
import com.mousetech.gourmetj.persistence.dao.CategoryRepository;
|
||||||
|
import com.mousetech.gourmetj.persistence.dao.IngredientRepository;
|
||||||
import com.mousetech.gourmetj.persistence.dao.RecipeRepository;
|
import com.mousetech.gourmetj.persistence.dao.RecipeRepository;
|
||||||
import com.mousetech.gourmetj.persistence.dao.ShopcatRepository;
|
import com.mousetech.gourmetj.persistence.dao.ShopcatRepository;
|
||||||
import com.mousetech.gourmetj.persistence.model.Category;
|
|
||||||
import com.mousetech.gourmetj.persistence.model.Ingredient;
|
import com.mousetech.gourmetj.persistence.model.Ingredient;
|
||||||
import com.mousetech.gourmetj.persistence.model.Recipe;
|
import com.mousetech.gourmetj.persistence.model.Recipe;
|
||||||
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||||
|
@ -27,6 +23,17 @@ import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||||
@Named
|
@Named
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@Transactional
|
@Transactional
|
||||||
|
/**
|
||||||
|
* Persistence service class for Recipes.
|
||||||
|
*
|
||||||
|
* While normally, I would have separate service classes for
|
||||||
|
* different Entity Working Sets, Recipes are so central to this
|
||||||
|
* application, this class contains additional functions that
|
||||||
|
* would ordinarily have their own Service classes.
|
||||||
|
*
|
||||||
|
* @author timh
|
||||||
|
* @since Jan 4, 2022
|
||||||
|
*/
|
||||||
public class RecipeService implements Serializable {
|
public class RecipeService implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -54,14 +61,6 @@ public class RecipeService implements Serializable {
|
||||||
return recipeRepository.findDetailsById(recipeId);
|
return recipeRepository.findDetailsById(recipeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* final String sql = "SELECT DISTINCT cuisine from recipe" +
|
|
||||||
* " where cuisine is not null and cuisine <> ''" + " ORDER
|
|
||||||
* BY cuisine ASC";
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
public List<String> findCuisines() {
|
public List<String> findCuisines() {
|
||||||
return recipeRepository.FindCuisinesNative();
|
return recipeRepository.FindCuisinesNative();
|
||||||
}
|
}
|
||||||
|
@ -72,10 +71,13 @@ public class RecipeService implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(Recipe recipe) {
|
public void delete(Recipe recipe) {
|
||||||
// TODO Auto-generated method stub
|
recipeRepository.delete(recipe);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShopcatService as a sub-function of RecipeService
|
||||||
|
*/
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ShopcatRepository shopcatRepository;
|
ShopcatRepository shopcatRepository;
|
||||||
|
|
||||||
|
@ -83,6 +85,14 @@ public class RecipeService implements Serializable {
|
||||||
return shopcatRepository.findDistinctCategoryNative();
|
return shopcatRepository.findDistinctCategoryNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Shopcat findShopcatForIngredientKey(String ingkey) {
|
||||||
|
return shopcatRepository.findShopcatByIngkey(ingkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryService as a sub-function of RecipeService
|
||||||
|
*/
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CategoryRepository categoryRepository;
|
CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@
|
||||||
<f:facet name="header">Ingredients</f:facet>
|
<f:facet name="header">Ingredients</f:facet>
|
||||||
<h:panelGroup id="ingButtons">
|
<h:panelGroup id="ingButtons">
|
||||||
<p:commandButton value="Up"
|
<p:commandButton value="Up"
|
||||||
|
disabled="#{not recipeDetailBean.moveUpAble}"
|
||||||
id="ctlUp"
|
id="ctlUp"
|
||||||
>
|
>
|
||||||
<f:ajax
|
<f:ajax
|
||||||
|
@ -144,6 +145,7 @@
|
||||||
/>
|
/>
|
||||||
</p:commandButton>
|
</p:commandButton>
|
||||||
<p:commandButton value="Down"
|
<p:commandButton value="Down"
|
||||||
|
disabled="#{not recipeDetailBean.moveDownAble}"
|
||||||
id="ctlDown"
|
id="ctlDown"
|
||||||
>
|
>
|
||||||
<f:ajax
|
<f:ajax
|
||||||
|
@ -193,9 +195,10 @@
|
||||||
id="selected"
|
id="selected"
|
||||||
value="#{item.selected}"
|
value="#{item.selected}"
|
||||||
>
|
>
|
||||||
<!-- <f:ajax immediate="true"
|
<f:ajax
|
||||||
render="ingredientTable"
|
immediate="true"
|
||||||
/> -->
|
render="pnlIngredients"
|
||||||
|
/>
|
||||||
</p:selectBooleanCheckbox>
|
</p:selectBooleanCheckbox>
|
||||||
</p:column>
|
</p:column>
|
||||||
<p:column
|
<p:column
|
||||||
|
@ -260,22 +263,11 @@
|
||||||
<f:facet name="header">
|
<f:facet name="header">
|
||||||
Shop. Cat.
|
Shop. Cat.
|
||||||
</f:facet>
|
</f:facet>
|
||||||
<p:autoComplete
|
<h:outputText
|
||||||
id="shopCat"
|
id="shopCat"
|
||||||
value="#{item.shopCat}"
|
value="#{item.shopCat}"
|
||||||
rendered="#{not item.ingGroup}"
|
rendered="#{not item.ingGroup}"
|
||||||
editable="true"
|
/>
|
||||||
forceSelection="false"
|
|
||||||
autoSelection="false"
|
|
||||||
dropdown="true"
|
|
||||||
cache="true"
|
|
||||||
title="Note that changing Shopping category for an ingredient key changes it for all users of that key."
|
|
||||||
completeMethod="#{recipeDetailBean.shopcatList}"
|
|
||||||
>
|
|
||||||
<p:ajax event="blur"
|
|
||||||
listener="#{recipeDetailBean.ajaxShopcat}"
|
|
||||||
/>
|
|
||||||
</p:autoComplete>
|
|
||||||
</p:column>
|
</p:column>
|
||||||
</p:dataTable>
|
</p:dataTable>
|
||||||
</h:panelGrid>
|
</h:panelGrid>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user