Début du refactoring

This commit is contained in:
FyloZ 2020-02-17 06:54:28 -05:00
parent 9fa96adda8
commit 43b06d30f4
36 changed files with 54 additions and 75 deletions

View File

@ -40,7 +40,4 @@ public class MaterialType implements IModel {
@NotNull
@ColumnDefault("false")
private Boolean usePercentages;
@OneToMany
private List<Material> materials;
}

View File

@ -30,6 +30,7 @@ public class Mix implements IModel {
private MixType mixType;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "mix")
private List<MixQuantity> mixQuantities;
// Casier

View File

@ -44,9 +44,9 @@ public class Recipe implements IModel {
private String note;
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL)
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
private List<Mix> mixes;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<RecipeStep> recipeSteps;
}

View File

@ -105,7 +105,7 @@ public abstract class GenericService<T extends IModel, R extends JpaRepository<T
* @return Si l'entité est valide pour l'édition.
*/
public boolean isValidForUpdate(@NonNull T entity) {
return exists(entity);
return entity.getId() != null && exists(entity);
}
/**
@ -116,7 +116,7 @@ public abstract class GenericService<T extends IModel, R extends JpaRepository<T
*/
@Override
public boolean exists(T entity) {
return entity != null && existsById(entity.getId());
return entity != null && entity.getId() != null && existsById(entity.getId());
}
@Override

View File

@ -71,8 +71,8 @@ public class MaterialService extends GenericService<Material, MaterialDao> {
public boolean isValidForUpdate(Material material) {
if (material == null) return false;
Optional<Material> materialByCode = dao.findByMaterialCode(material.getMaterialCode());
return super.isValidForUpdate(material) && (materialByCode.isEmpty() || material.getMaterialID().equals(materialByCode.get().getMaterialID()));
Optional<Material> materialByCode = dao.findByName(material.getName());
return super.isValidForUpdate(material) && (materialByCode.isEmpty() || material.getId().equals(materialByCode.get().getId()));
}
@Deprecated(since = "1.2.0")

View File

@ -38,8 +38,8 @@ public class MixService extends GenericService<Mix, MixDao> {
.getAll()
.stream()
.filter(m -> !m.isMixType() || recipeMixTypes.contains(mixTypeService.getByMaterial(m).get()))
.sorted(Comparator.comparing(Material::getMaterialCode))
.sorted(Comparator.comparing(m -> m.getMaterialType().getMaterialTypeName()))
.sorted(Comparator.comparing(Material::getName))
.sorted(Comparator.comparing(m -> m.getMaterialType().getName()))
.collect(Collectors.toList());
}
@ -109,16 +109,20 @@ public class MixService extends GenericService<Mix, MixDao> {
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(mix.getMixQuantities())) {
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);
if (materialService.update(material).isPresent() && update(mix).isPresent()) {
return null;
} else {
return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);
}
}
public boolean deleteMix(Mix mix) {

View File

@ -46,7 +46,7 @@ public class RecipeService extends GenericService<Recipe, RecipeDao> {
public List<Mix> getSortedMixes(Recipe recipe) {
List<Mix> mixes = recipe.getMixes();
mixes.sort(Comparator.comparing(Mix::getId));
return mixes;
return new ArrayList<>(mixes); // Convertit le PersistentBag en ArrayList
}
/**

View File

@ -67,7 +67,7 @@ public class WebsitePaths {
public static final String EDITOR_MATERIAL_TYPE_SPECIFIC = "materialType/editor/{id}";
public static final String EDITOR_MATERIAL_TYPE_EDITOR = "materialType/edit";
// Mélanges(
// Mélanges
public static final String CREATOR_MIX = "mix/creator";
public static final String CREATOR_MIX_SPECIFIC = "mix/creator/{id}";
public static final String EDITOR_MIX = "mix/editor";

View File

@ -43,21 +43,6 @@ public class IndexController {
.build();
}
// @GetMapping(value = SEARCH, produces = MediaType.APPLICATION_JSON_VALUE)
// @ResponseBody
public Map<String, Object> searchWord(@RequestParam String searchString) {
Map<Company, List<Recipe>> searchResult = recipeService.getRecipesForSearchString(searchString);
Map<Long, List<Long>> outputResult = new HashMap<>();
for (Company c : searchResult.keySet()) {
outputResult.put(c.getId(), searchResult.get(c).stream().map(Recipe::getId).collect(Collectors.toList()));
}
return new JSONResponseBuilder()
.addAttribute("result", outputResult)
.build();
}
/**
* Valide un mot de passe reçu dans une requête HTTP POST, dans le champ "password".
*

View File

@ -16,8 +16,8 @@ import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
import java.util.Optional;
import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_COMPANY;
import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.INDEX;
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_COMPANY;
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX;
@Controller
public class CompanyCreatorController {
@ -63,13 +63,13 @@ public class CompanyCreatorController {
if (savedCompany.isPresent()) {
return modelResponseBuilder
.addResponseData(ResponseDataType.COMPANY_NAME, savedCompany.get().getCompanyName())
.addResponseData(ResponseDataType.COMPANY_NAME, savedCompany.get().getName())
.build();
} else {
modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);
}
} else {
modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_ALREADY_EXIST, company.getCompanyName());
modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_ALREADY_EXIST, company.getName());
}
return showCreationPage(modelResponseBuilder.build(), company);

View File

@ -44,7 +44,7 @@ public class MaterialTypeCreatorController {
Optional<MaterialType> optionalMaterialType = materialTypeService.save(materialType);
if (optionalMaterialType.isPresent()) {
return getPage(modelResponseBuilder
.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, optionalMaterialType.get().getMaterialTypeName())
.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, optionalMaterialType.get().getName())
.build(), null);
} else {
modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);

View File

@ -67,7 +67,7 @@ public class RecipeCreatorController {
Optional<Recipe> savedRecipe = recipeService.save(recipe);
if (savedRecipe.isPresent()) {
return modelResponseBuilder
.withRedirect(EDITOR_RECIPE_SPECIFIC, savedRecipe.get().getRecipeID())
.withRedirect(EDITOR_RECIPE_SPECIFIC, savedRecipe.get().getId())
.build();
}
modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING);

View File

@ -76,7 +76,7 @@ public class MaterialTypeEditorController {
responseBuilder
.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialType.getName())
.build(),
materialType.getMaterialTypeID(), materialType);
materialType.getId(), materialType);
} else if (!materialTypeService.isValidForUpdatePrefix(materialType)) {
return showEditPage(
responseBuilder

View File

@ -10,10 +10,7 @@ import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
@ -51,7 +48,7 @@ public class MixEditorController {
@GetMapping(EDITOR_MIX_SPECIFIC)
public ModelAndView getPage(ModelAndView model, @PathVariable Long id) {
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model)
.withView(EDITOR_MIX_SPECIFIC.replaceAll("/\\{" + MIX_ID + "}", ""));
.withView(EDITOR_MIX_SPECIFIC.replaceAll("/\\{id}", ""));
Optional<Mix> optionalMix = mixService.getById(id);
if (optionalMix.isEmpty()) {
@ -90,7 +87,7 @@ public class MixEditorController {
* @return La page à afficher.
*/
@PostMapping(value = EDITOR_MIX, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ModelAndView saveMix(@ModelAttribute @Valid MixCreationFormDto formDto, Long id) {
public ModelAndView saveMix(@ModelAttribute @Valid MixCreationFormDto formDto, @RequestParam("mixId") Long id) {
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
Optional<Mix> optionalMix = mixService.getById(id);

View File

@ -73,7 +73,7 @@ public class RecipeEditorController {
return modelResponseBuilder
.addResponseData(ResponseDataType.RECIPE, recipe)
.addResponseData(ResponseDataType.COMPANIES, companyService.getAll())
.addResponseData(ResponseDataType.MIXES, new ArrayList<>(recipeService.getSortedMixes(recipe))) // Convertit le PersistentBag en ArrayList
.addResponseData(ResponseDataType.MIXES, recipeService.getSortedMixes(recipe))
.addResponseData(ResponseDataType.IMAGES, recipeService.getImageFiles(recipe))
.addAttribute("recipeJSON", recipeService.asJson(recipe))
.build();

View File

@ -105,7 +105,7 @@ public class ImageFilesController {
.build(), id);
}
Optional<Recipe> optionalRecipe = recipeService.getByID(id);
Optional<Recipe> optionalRecipe = recipeService.getById(id);
if (optionalRecipe.isEmpty()) {
return getPage(modelResponseBuilder
.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id)

View File

@ -36,10 +36,10 @@ public class XlsExporterController {
}
@GetMapping(RECIPE_XLS)
public ResponseEntity<byte[]> getXlsForRecipe(HttpServletRequest request, @PathVariable int recipeID) {
public ResponseEntity<byte[]> getXlsForRecipe(HttpServletRequest request, @PathVariable Long id) {
HttpHeaders headers = new HttpHeaders();
Optional<Recipe> optionalRecipe = recipeService.getByID(recipeID);
Optional<Recipe> optionalRecipe = recipeService.getById(id);
if (optionalRecipe.isEmpty()) {
headers.add(HttpHeaders.LOCATION, request.getHeader("referer"));
return new ResponseEntity<>(headers, HttpStatus.FOUND);
@ -69,7 +69,7 @@ public class XlsExporterController {
byte[] recipeXLS = new XlsxExporter().generate(recipe);
if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
out.putNextEntry(new ZipEntry(String.format("%s_%s.xlsx", recipe.getCompany().getCompanyName(), recipe.getRecipeCode())));
out.putNextEntry(new ZipEntry(String.format("%s_%s.xlsx", recipe.getCompany().getName(), recipe.getName())));
out.write(recipeXLS, 0, recipeXLS.length);
out.closeEntry();
}

View File

@ -75,9 +75,10 @@ nav a {
.dropdown-content {
display: none;
position: absolute;
top: 70px;
background-color: #0d0d0d;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
z-index: 1;
}

View File

@ -73,10 +73,14 @@
background-color: #fafafa;
}
.material, .material *, .quantity, .quantity * {
.material, .quantity {
width: 200px;
}
.material *, .quantity * {
width: 180px;
}
.material input {
text-align: left;
padding: 0 10px;

View File

@ -58,7 +58,6 @@ $(() => {
const removerForm = $(".requireAuth-remover");
removerForm.find(".remover").on({
click: function () {
console.log($(this));
removerForm.attr({
action: removerForm.attr("action") + $(this).data("entityid")
});
@ -234,7 +233,6 @@ function changeUnits(unitSelect, quantitiesSelector, unitsDisplay) {
$(this).text(currentUnit);
const quantityElem = $(this).parents(".materialRow").find(quantitiesSelector);
console.log(quantityElem);
if (quantityElem) {
const originalQuantity = parseInt(quantityElem.data("quantityml"));
quantityElem.text(convertMlToUnit(originalQuantity));

View File

@ -8,10 +8,10 @@ let materialSelectorHtml;
let recipeID;
$(() => {
recipeID = $("#recipeID").val();
recipeID = $("#recipeId").val();
const mixIDInput = $("#mixID");
const mixID = mixIDInput ? mixIDInput.val() : -1;
const mixID = mixIDInput.val() ? mixIDInput.val() : -1;
axios.get(`/mix/selector/${recipeID}/${mixID}`)
.then(r => {
@ -35,10 +35,6 @@ $(document).on("click", ".materialSelector", function (event) {
showMaterialList($(this)[0]);
});
// $(document).on("click", ".materialList p", function () {
// $(this).parents(".materialSelector").find("input").val($(this).data("materialcode"));
// });
$(document).on("click", ".removeMaterial", function () {
const id = $(this).data("removerow");
if ($(".materialListRow").length > 1) $(`#${id}`).remove();
@ -232,7 +228,6 @@ function searchMaterial(input) {
function checkUnits(materialSelector) {
const quantityUnits = $(materialSelector).parents(".materialListRow").find(".quantityUnits");
console.log($(quantityUnits));
if ($(materialSelector).data("usepercentages")) quantityUnits.text("%");
else quantityUnits.text("mL");
}

View File

@ -93,7 +93,7 @@
<!--Produits-->
<tr class="materialRow" th:each="material : ${materials}"
th:data-materialType="${material.materialType.id}"
th:data-materialId="${material.materialId}">
th:data-materialId="${material.id}">
<td class="materialCode" th:data-materialId="${material.id}"
th:text="${material.name}"></td>
<td class="inventoryQuantity" th:data-quantityML="${material.inventoryQuantity}"

View File

@ -6,10 +6,10 @@
<body>
<!-- Fragment de l'entête -->
<header th:include="fragments.html :: header"></header>
<header th:include="fragments.html :: header(false)"></header>
<!-- Corps de la page -->
<section>
<p th:if="${materialCode != null}" th:text="#{material.success.created(${materialCode})}" class="success"></p>
<p th:if="${name != null}" th:text="#{material.success.created(${name})}" class="success"></p>
<div th:include="fragments.html :: messages"></div>
<h1 th:text="#{material.add.title}"></h1>
@ -20,7 +20,7 @@
<div class="formWrap">
<div class="formColumn">
<div>
<label th:for="${#ids.next('materialCode')}" th:text="#{material.code} + ':'"></label>
<label th:for="${#ids.next('name')}" th:text="#{material.code} + ':'"></label>
</div>
<div>
<label for="quantity" th:text="#{material.inventoryQuantity} + ':'"></label>
@ -29,14 +29,14 @@
<label th:for="${#ids.next('materialType')}" th:text="#{material.type} + ':'"></label>
</div>
<div>
<label for="simdut" th:text="#{material.simdutFile} + ':'"></label>
<label for="simdut" th:text="#{material.simdut} + ':'"></label>
</div>
</div>
<div class="formColumn">
<div>
<input type="text"
class="rawInput"
th:field="*{materialCode}"
th:field="*{name}"
style="width: 145px"
required/>
</div>
@ -66,8 +66,8 @@
</div>
<div>
<select th:field="*{materialType}" required>
<option th:each="materialType : ${materialTypes}" th:value="${materialType.materialTypeID}"
th:text="${materialType.materialTypeName}"></option>
<option th:each="materialType : ${materialTypes}" th:value="${materialType.id}"
th:text="${materialType.name}"></option>
</select>
</div>
<div>

View File

@ -97,7 +97,7 @@
// Ajoute les produits déjà présents dans la recette
mix.mixQuantities.forEach(q => {
addMaterial(q.material.materialCode, q.quantity);
addMaterial(q.material.name, q.quantity);
});
}

View File

@ -55,11 +55,11 @@
<div class="content">
<!-- Informations -->
<div class="flexContent" style="padding-top: 40px">
<input type="hidden" th:field="*{recipeId}"/>
<input type="hidden" th:field="*{id}"/>
<div class="formWrap">
<div class="formColumn">
<div>
<label th:for="${#ids.next('recipeId')}" th:text="#{keyword.id}"></label>
<label th:for="${#ids.next('id')}" th:text="#{keyword.id}"></label>
</div>
<div>
<label th:for="${#ids.next('name')}" th:text="#{recipe.color}"></label>
@ -82,7 +82,7 @@
</div>
<div class="formColumn">
<div>
<input type="number" th:field="*{recipeId}" required disabled/>
<input type="number" th:field="*{id}" required disabled/>
</div>
<div>
<input type="text" th:field="*{name}" required/>

View File

@ -1,3 +0,0 @@
[Dolphin]
Timestamp=2019,5,9,10,28,30
Version=4

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.