Corrections étapes de recette

Corrections images
This commit is contained in:
FyloZ 2020-02-20 12:23:27 -05:00
parent b13d8c8e63
commit 700f8eedfd
11 changed files with 41 additions and 151 deletions

View File

@ -49,7 +49,7 @@ public class Recipe implements IModel {
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
private List<Mix> mixes;
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
private List<RecipeStep> recipeSteps;
public Collection<MixType> getMixTypes() {

View File

@ -20,8 +20,8 @@ public class RecipeStep implements IModel {
@NonNull
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
@ManyToOne
private Recipe recipe;
@NonNull

View File

@ -71,26 +71,17 @@ public class GenericService<T extends IModel, R extends JpaRepository<T, Long>>
@Override
public void delete(@NonNull T entity) {
if (entity.getId() == null) throw new NullIdentifierException(type);
if (!existsById(entity.getId()))
throw new EntityNotFoundException(type, ModelException.IdentifierType.ID, entity.getId());
dao.delete(entity);
}
@Override
public void deleteById(Long id) {
if (!existsById(id))
throw new EntityNotFoundException(type, ModelException.IdentifierType.ID, id);
delete(getById(id));
}
@Override
@Transactional
public void deleteAll(@NonNull List<T> entities) {
entities
.forEach(this::delete);
public void deleteAll(List<T> entities) {
dao.deleteAll(entities);
}
/**

View File

@ -97,38 +97,6 @@ public class MixService extends GenericService<Mix, MixDao> {
.build();
update(mix);
// ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
// Material material = mix.getMixType().getMaterial();
//
// List<Material> materials = new ArrayList<>();
// for (String materialCode : formDto.getMaterials()) {
// Optional<Material> found = materialService.getByName(materialCode);
// if (found.isEmpty()) {
// return modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND_BY_NAME, materialCode);
// }
//
// materials.add(found.get());
// }
//
// mix.getMixType().getMaterial().setMaterialType(formDto.getMaterialType());
// mix.getMixType().setName(formDto.getMixTypeName());
// material.setName(formDto.getMixTypeName());
//
// List<MixQuantity> oldQuantities = mix.getMixQuantities();
// List<MixQuantity> mixQuantities = createMixQuantities(mix, materials, formDto.getQuantities());
//
// // Supprime les anciens MixQuantity pour éviter les doublons et les entrées inutiles dans la base de données
// if (!mixQuantityService.deleteAll(oldQuantities)) {
// return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);
// }
//
// mix.setMixQuantities(mixQuantities);
// if (materialService.update(material).isPresent() && update(mix).isPresent()) {
// return null;
// } else {
// return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);
// }
}
@Deprecated(since = "1.3.0", forRemoval = true)

View File

@ -63,31 +63,17 @@ public class RecipeService extends GenericService<Recipe, RecipeDao> {
return mappedByCompany(getAll());
}
@Deprecated(since = "1.3.0", forRemoval = true)
public Recipe updateRecipe(Recipe newRecipe, Recipe storedRecipe, MultiValueMap<String, Object> form) {
storedRecipe.setName(newRecipe.getName());
storedRecipe.setCompany(newRecipe.getCompany());
storedRecipe.setDescription(newRecipe.getDescription());
storedRecipe.setSample(newRecipe.getSample());
storedRecipe.setApprobationDate(newRecipe.getApprobationDate());
storedRecipe.setRemark(newRecipe.getRemark());
storedRecipe.setNote(newRecipe.getNote());
return convertAndCreateSteps(storedRecipe, form);
}
/**
* Met à jour une recette ainsi que ses étapes.
*
* @param recipeDto Les informations de la recette à mettre à jour
* @return La recette mise à jour
*/
@Transactional
public Recipe updateRecipeAndSteps(RecipeEditorFormDto recipeDto) {
Recipe recipe = recipeDto.getRecipe();
stepService.createAllForRecipe(recipe, recipeDto.getStep());
return update(recipeDto.getRecipe());
List<RecipeStep> steps = stepService.createAllForRecipe(recipe, recipeDto.getStep());
return setSteps(recipe, steps);
}
/**
@ -139,10 +125,8 @@ public class RecipeService extends GenericService<Recipe, RecipeDao> {
public int getNextImageIndex(Recipe recipe) {
String imageName = getImageFileName(recipe);
List<String> allImages = getImageFiles(recipe);
List<Integer> indexes = allImages.stream().map(i -> Integer.parseInt(i.replace(imageName + "-", ""))).collect(Collectors.toList());
int maxIndex = Collections.max(indexes);
return maxIndex + 1;
List<Integer> indexes = allImages.stream().map(i -> Integer.parseInt(i.replace(imageName + "-", "").replace(".jpeg", ""))).collect(Collectors.toList());
return indexes.size() > 0 ? Collections.max(indexes) + 1 : 0;
}
/**
@ -185,34 +169,11 @@ public class RecipeService extends GenericService<Recipe, RecipeDao> {
return mappedRecipes;
}
/**
* Crée et assigne des étapes à une recette, en se basant sur l'entrée de utilisateur.
*
* @param recipe La recette à assigner les étapes
* @param input L'entrée de l'utilisateur, contenant les étapes (key = "step_*")
* @return La recette avec les étapes.
*/
@Transactional
public Recipe convertAndCreateSteps(Recipe recipe, MultiValueMap<String, Object> input) {
// Convertit les étapes en RecipeSteps
List<RecipeStep> steps = new ArrayList<>();
if (input.containsKey("step")) {
Object field = input.get("step");
if (field instanceof LinkedList && ((LinkedList) field).getFirst() instanceof String) {
for (String step : (LinkedList<String>) field) {
steps.add(new RecipeStep(recipe, step));
}
}
}
return setSteps(recipe, steps);
}
private Recipe setSteps(Recipe recipe, List<RecipeStep> steps) {
protected Recipe setSteps(Recipe recipe, List<RecipeStep> steps) {
stepService.deleteAll(recipe.getRecipeSteps());
recipe.setRecipeSteps(steps);
return update(recipe);
}

View File

@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class StepService extends GenericService<RecipeStep, StepDao> {
@ -25,8 +26,8 @@ public class StepService extends GenericService<RecipeStep, StepDao> {
* @param recipe La recette
* @param message Le message de l'étape à créer
*/
public void createForRecipe(Recipe recipe, String message) {
save(new RecipeStep(recipe, message));
public RecipeStep createForRecipe(Recipe recipe, String message) {
return new RecipeStep(recipe, message);
}
/**
@ -36,8 +37,7 @@ public class StepService extends GenericService<RecipeStep, StepDao> {
* @param messages Tous les messages des étapes à créer
*/
@Transactional
public void createAllForRecipe(Recipe recipe, List<String> messages) {
messages.forEach(m -> createForRecipe(recipe, m));
public List<RecipeStep> createAllForRecipe(Recipe recipe, List<String> messages) {
return messages.stream().map(m -> createForRecipe(recipe, m)).collect(Collectors.toList());
}
}

View File

@ -5,10 +5,7 @@ import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixFormDto;
import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService;
import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixTypeService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class MixBuilder {
@ -21,7 +18,7 @@ public class MixBuilder {
private String location;
private List<MixQuantity> mixQuantities = new ArrayList<>();
private Map<String, Float> quantities = new HashMap<>();
private Map<String, Float> quantities = new LinkedHashMap<>();
public MixBuilder(MixTypeService mixTypeService, MaterialService materialService) {
this.mixTypeService = mixTypeService;
@ -40,7 +37,7 @@ public class MixBuilder {
public MixBuilder withDto(MixFormDto dto) {
if (this.mixType == null) {
mixTypeService.createByName(dto.getMixTypeName(), dto.getMaterialType());
this.mixType = mixTypeService.createByName(dto.getMixTypeName(), dto.getMaterialType());
} else {
this.mixType.setName(dto.getMixTypeName());
this.mixType.getMaterial().setMaterialType(dto.getMaterialType());

View File

@ -19,7 +19,7 @@ public class WebsitePaths {
public static final String IMAGES_FILES = "images/{image}";
public static final String ADD_IMAGE = "images/add";
public static final String ADD_IMAGE_SPECIFIC = "images/add/{id}";
public static final String DELETE_IMAGE = "images/delete";
public static final String DELETE_IMAGE = "images/delete/{image}";
// Touch up kits
public static final String TOUCHUP = "touchup";

View File

@ -44,7 +44,6 @@ public class RecipeEditorController {
public ModelAndView getEditPage(ModelAndView model, @PathVariable Long id, Recipe recipe) {
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_RECIPE_EDITOR);
// TODO les produits dans les mélanges ne sont pas dans l'ordre de création
try {
if (recipe.getName() == null) recipe = recipeService.getById(id);

View File

@ -14,10 +14,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
@ -58,7 +56,7 @@ public class ImageFilesController {
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_RECIPE_SPECIFIC, id);
try {
if (imagesService.isImage(image.getInputStream())) {
if (!imagesService.isImage(image.getInputStream())) {
modelResponseBuilder.addResponseCode(ResponseCode.FILE_NOT_IMAGE);
} else {
Recipe recipe = recipeService.getById(id);
@ -74,9 +72,9 @@ public class ImageFilesController {
return getPage(modelResponseBuilder.build(), id);
}
@PostMapping(value = DELETE_IMAGE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = DELETE_IMAGE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Map<String, Object> deleteImage(String image) {
public Map<String, Object> deleteImage(@PathVariable String image) {
imagesService.deleteImage(image);
return new JSONResponseBuilder().build();

View File

@ -55,7 +55,7 @@
<div class="content">
<!-- Informations -->
<div class="flexContent" style="padding-top: 40px">
<input type="hidden" th:field="*{id}"/>
<input type="hidden" name="recipe" id="recipeId" th:value="${recipe.id}"/>
<div class="formWrap">
<div class="formColumn">
<div>
@ -220,26 +220,26 @@
$(".deleteImg").on({
click: function () {
showConfirm(askChangePage, false, () => {
let data = {
image: $(this).data("image")
}
checkPassword(null, () => {
const image = $(this).data("image");
axios.post("/images/delete", data)
.then(r => {
const responseData = r.data;
axios.get("/images/delete/" + image)
.then(r => {
const responseData = r.data;
if (responseData.error) showMessage(errorMsg, responseData.error);
else window.location.reload();
})
.catch(e => {
console.log(e);
showMessage(errorMsg, generalErrorText);
});
if (responseData.error) showMessage(errorMsg, responseData.error);
else window.location.reload();
})
.catch(e => {
console.log(e);
showMessage(errorMsg, generalErrorText);
});
})
});
}
});
const recipeText = "[[${recipeJSON}]]";
const recipeText = "[[${recipeJson}]]";
const recipeJSON = JSON.parse(recipeText.replace(/&quot;/g, '"').replace(/&#39;/g, '\'').replace(/\r\n/g, ""));
// Ajoute les étapes déjà présentes dans la recette
@ -256,50 +256,27 @@
value: value
});
// let input = document.createElement("input");
// input.type = "text";
// input.id = `step_${stepNbr}`;
// input.classList.add("step", "rawInput", "toSave");
// input.name = "step";
// input.autocomplete = "off";
// if (value != null) input.value = value;
const number = $("<label></label>")
.attr({
for: input.id
for: input.attr("id")
})
.text(`${stepNbr + 1}`);
// let number = document.createElement("label");
// number.textContent = `${stepNbr + 1}. `;
// number.for = input.id;
const deleteButton = $("<button></button>")
.attr({
type: "button"
})
.text(removeText)
.on({
click: () => deleteStep(input.id)
click: () => deleteStep(input.attr("id"))
});
// let deleteButton = document.createElement("button");
// deleteButton.type = "button";
// deleteButton.innerText = "[[#{keyword.remove}]]";
// deleteButton.addEventListener("click", () => deleteStep(input.id));
const div = $("<div></div>")
.append(number)
.append(input)
.append(deleteButton);
// let div = document.createElement("div");
// div.appendChild(number);
// div.appendChild(input);
// div.appendChild(deleteButton);
$("#steps").append(div);
// document.querySelector("#steps").appendChild(div);
stepNbr++;
}
@ -307,7 +284,6 @@
function deleteStep(stepId) {
// Supprime la rangée de l'étape
$(`#${stepId}`).parent().remove();
// document.querySelector(`#${stepId}`).parentElement.remove();
}
/*]]*/