Shopcat in progress (doSave)

This commit is contained in:
Tim Holloway 2022-01-03 16:48:15 -05:00
parent 735bf814cf
commit a86f45e4c4
10 changed files with 121 additions and 73 deletions

View File

@ -123,6 +123,7 @@ public class AdminMainBean implements Serializable {
*/
@PostConstruct
void init() {
log.info("Constructing AdminMainBean " + this);
this.setSearchText(userSession.getLastSearch());
// Clean up from any previous operations.
this.userSession.setRecipe(null);
@ -191,6 +192,7 @@ public class AdminMainBean implements Serializable {
/**
* Get printable preptime. Database version is in seconds.
* @deprecated User {@link UserSession#formatTime(Long)}
*
* @return Formatted time. Called from EL on main page.
*/
@ -210,17 +212,4 @@ public class AdminMainBean implements Serializable {
return sb.toString();
}
public String formatCategories(Recipe r) {
StringBuffer sb = new StringBuffer(30);
boolean first = true;
for (Category cat : r.getCategories()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(cat.getCategory());
}
return sb.toString();
}
}

View File

@ -218,6 +218,8 @@ public class RecipeDetailBean implements Serializable {
private void init() {
this.recipe = userSession.getRecipe();
log.info("Using recipe: " + this.recipe );
/**
* For "create new, this recipe is a blank constructed
* and passed from main page. For Detail display, it's
@ -241,6 +243,7 @@ public class RecipeDetailBean implements Serializable {
getIngredients().setWrappedData(
buildIngredientFacade(recipe.getIngredientHash()));
log.info("Set recipe: " + this.recipe );
}
/**
@ -367,8 +370,8 @@ public class RecipeDetailBean implements Serializable {
*
* Note: In the original Tobago port of this app, the input
* was an inputText. In PrimeFaces, this did not preserve
* line separation characters, so an inputTextArea was
* used instead.
* line separation characters, so an inputTextArea was used
* instead.
*
* @param event Unused
*/
@ -450,7 +453,8 @@ public class RecipeDetailBean implements Serializable {
}
// Otherwise, try for split.
String[] lineArray = ingredientTextLines.split(RE_INGSPLIT);
String[] lineArray =
ingredientTextLines.split(RE_INGSPLIT);
for (String line : lineArray) {
if (line.isBlank()) {
continue; // actually should discard any above
@ -538,16 +542,22 @@ public class RecipeDetailBean implements Serializable {
* save ingredients.
*/
public String doSave() {
// if ! isDirty()...
// Update recipe object based on UI:
if (!saveIngredients()) {
JSFUtils
.addErrorMessage("Could not save Ingredients");
return null;
}
updateRecipeCategories(recipe, category);
// Rebuild ingredients list with groups applied
updateRecipeGroups(getWrappedIngredients());
recipeService.save(recipe);
if (recipeService.save(this.getRecipe())) {
userSession.setRecipe(null);
setDirty(false);
return "main";
} else {
JSFUtils.addErrorMessage("Save recipe failed");
return null;
}
}
/**
@ -587,6 +597,16 @@ public class RecipeDetailBean implements Serializable {
* it.
*/
private boolean saveIngredients() {
if ( ! updateIngredientList()) {
return false;
}
updateRecipeCategories(recipe, category);
// Rebuild ingredients list with groups applied
updateRecipeGroups(getWrappedIngredients());
return true;
}
private boolean updateIngredientList() {
List<IngredientUI> saveIng = getWrappedIngredients();
List<Ingredient> iList = recipe.getIngredientHash();
iList.clear();
@ -599,7 +619,7 @@ public class RecipeDetailBean implements Serializable {
if (scat == null) {
if ((ingKey != null) && !ingKey.isBlank()) {
scat = new Shopcat();
scat.setIngkey(ingKey);
// scat.setIngkey(ingKey);
scat.setShopcategory(shopCatName);
ing.setShopCat(scat);
} else {
@ -766,7 +786,7 @@ public class RecipeDetailBean implements Serializable {
this.cuisineList = cuisineList;
}
//***
// ***
// Shopcat for IngredientUI
private List<String> shopcatList;
@ -894,6 +914,7 @@ public class RecipeDetailBean implements Serializable {
PictureController.importImage(recipe, foo.getContents());
}
/**
* Remove images from recipe
*

View File

@ -5,6 +5,7 @@ import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import com.mousetech.gourmetj.persistence.model.Category;
import com.mousetech.gourmetj.persistence.model.Recipe;
@Named
@ -97,6 +98,21 @@ public class UserSession implements Serializable {
}
// ====
public String formatCategories(Recipe r) {
StringBuffer sb = new StringBuffer(30);
boolean first = true;
for (Category cat : r.getCategories()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(cat.getCategory());
}
return sb.toString();
}
public String formatTime(Long ltime) {
if (ltime == null) {
return "";

View File

@ -5,9 +5,10 @@ import javax.persistence.*;
import javax.validation.constraints.NotNull;
/**
* The persistent class for the "ingredients" database table.
* The display model is @see IngredientUI. Persistence
* is usually done along with the containing recipe via
* The persistent class for the "ingredients" database table. The
* display model is @see IngredientUI. Persistence is usually
* done along with the containing recipe via
*
* @see RecipeService.
*/
@Entity
@ -16,9 +17,12 @@ import javax.validation.constraints.NotNull;
public class Ingredient implements Serializable, IngredientIF {
private static final long serialVersionUID = 1L;
@ManyToOne(fetch = FetchType.LAZY, cascade = {
CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, optional = true)
@JoinColumn(name = "ingkey",insertable = false, updatable = false, nullable = true)
@ManyToOne(fetch = FetchType.EAGER, cascade = {
CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.REFRESH }, optional = true)
@JoinColumn(name = "ingkey", insertable = false,
updatable = false, nullable = true,
foreignKey = @ForeignKey(name = "ingkey"))
Shopcat shopCat;
/**

View File

@ -1,8 +1,20 @@
package com.mousetech.gourmetj.persistence.model;
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the "shopcats" database table.
@ -19,9 +31,6 @@ import javax.validation.constraints.NotNull;
*/
@Entity
@Table(name = "shopcats")
@NamedQueries({
@NamedQuery(name = "Shopcat.findAll", query = "SELECT s FROM Shopcat s"),
@NamedQuery(name = "Shopcat.findIngkey", query = "SELECT s FROM Shopcat s where s.ingkey = :ingkey") })
public class Shopcat implements Serializable {
private static final long serialVersionUID = 1L;
@ -30,11 +39,23 @@ public class Shopcat implements Serializable {
@Column(name = "id")
private Long id;
@Column(name = "ingkey")
@NotNull
// @UniqueConstraint(name="ingkey")
private String ingkey;
// @OneToMany ingredients
//@Column(name = "ingkey", unique = true, nullable = false )
@OneToMany(fetch = FetchType.LAZY, mappedBy = "ingkey" )
private List<Ingredient> ingredients;
/**
* @return the ingredients
*/
public List<Ingredient> getIngredients() {
return ingredients;
}
/**
* @param ingredients the ingredients to set
*/
public void setIngredients(List<Ingredient> ingredient) {
this.ingredients = ingredient;
}
@Column(name = "position")
private Integer position;
@ -53,14 +74,6 @@ public class Shopcat implements Serializable {
this.id = id;
}
public String getIngkey() {
return this.ingkey;
}
public void setIngkey(String ingkey) {
this.ingkey = ingkey;
}
public Integer getPosition() {
return this.position;
}
@ -79,7 +92,7 @@ public class Shopcat implements Serializable {
@Override
public String toString() {
return "Shopcat for " + ingkey + "(" + shopcategory
return "Shopcat for " + "(" + shopcategory
+ ")";
}
}

View File

@ -66,9 +66,9 @@ public class RecipeService implements Serializable {
return recipeRepository.FindCuisinesNative();
}
public void save(Recipe recipe) {
// TODO Auto-generated method stub
public boolean save(Recipe recipe) {
recipeRepository.save(recipe);
return true;
}
public void delete(Recipe recipe) {

View File

@ -143,7 +143,12 @@ public class PictureController {
httpHeaders.set(HttpHeaders.CONTENT_TYPE,
MediaType.IMAGE_PNG_VALUE);
httpHeaders.set(HttpHeaders.CACHE_CONTROL, "no-cache");
byte[] image = editRecipe.getImage();
byte[] image = null;
if ( editRecipe != null ) {
// Otherwise we are creating new recipe, pre-display
image = editRecipe.getImage();
}
if (image == null) {
image = BLANK_IMAGE;
}

View File

@ -133,7 +133,6 @@
>
<p:panel id="pnlIngredients">
<f:facet name="header">Ingredients</f:facet>
<!-- NOTE: disabled doesn't work from AJAX render. Swap images -->
<h:panelGroup id="ingButtons">
<p:commandButton value="Up"
id="ctlUp"
@ -289,7 +288,8 @@
<p:outputLabel for="@next"
value="Add Ingredient: "
/>
<p:inputTextarea id="ctlAddIngTxt"
<p:inputTextarea
id="ctlAddIngTxt"
focus="true" rows="1"
cols="65"
value="#{recipeDetailBean.ingredientText}"
@ -326,8 +326,8 @@
</p:panel>
</p:tab>
</p:tabView>
<p:button id="doSave" value="Save"
disabled="{recipeDetailBean.dirty}"
<p:commandButton id="doSave" value="Save"
disabled="{not recipeDetailBean.dirty}"
action="#{recipeDetailBean.doSave}"
/>
<p:commandButton id="doCancel" value="Cancel"

View File

@ -57,7 +57,7 @@
</p:column>
<p:column headerText="Category">
<h:outputText
value="#{adminMainBean.formatCategories(row)}"
value="#{userSession.formatCategories(row)}"
/>
</p:column>
<p:column headerText="Cuisine">
@ -73,7 +73,7 @@
</p:column>
<p:column headerText="Prep Time">
<h:outputText
value="#{adminMainBean.formatPreptime(row.preptime)}"
value="#{userSession.formatTime(row.preptime)}"
/>
</p:column>
</p:dataTable>

View File

@ -61,7 +61,7 @@
/>
<h:outputText
label="Category: "
value="#{adminMainBean.formatCategories(recipeDetailBean.recipe)}"
value="#{userSession.formatCategories(recipeDetailBean.recipe)}"
/>
<p:outputLabel for="@next"
value="Cuisine:"