From 1b5480e8009fedaafa6bdd1b2222871a9e490f7c Mon Sep 17 00:00:00 2001 From: FyloZ Date: Wed, 19 Feb 2020 15:01:10 -0500 Subject: [PATCH] Finalisation transition vers exceptions + DTO --- .../ColorRecipesExplorerApplication.java | 17 +- .../core/configuration/InitialDataLoader.java | 14 +- .../model/EntityNotFoundException.java | 20 ++- .../core/model/Material.java | 4 +- .../core/model/MixType.java | 2 + .../core/model/Recipe.java | 12 +- .../core/services/GenericService.java | 3 +- .../core/services/InventoryService.java | 8 +- .../core/services/files/FilesService.java | 32 +++- .../core/services/files/ImagesService.java | 24 +++ .../core/services/files/SimdutService.java | 77 +++++++++ .../core/services/files/XlsService.java | 68 ++++++++ .../core/services/model/MaterialService.java | 38 ++--- .../services/model/MixQuantityService.java | 2 +- .../core/services/model/MixService.java | 160 +++++++++--------- .../core/services/model/MixTypeService.java | 42 +++-- .../core/services/model/RecipeService.java | 71 +++----- .../web/controller/InventoryController.java | 136 +++++++-------- .../web/controller/OthersController.java | 7 +- .../files/ImageFilesController.java | 117 +++---------- .../files/SIMDUTFilesController.java | 44 +++-- .../files/XlsExporterController.java | 62 ++----- .../removers/CompanyRemoverController.java | 4 +- .../removers/MaterialRemoverController.java | 51 ++---- .../MaterialTypeRemoverController.java | 23 ++- .../removers/RecipeRemoverController.java | 52 ++---- 26 files changed, 548 insertions(+), 542 deletions(-) create mode 100644 src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java create mode 100644 src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.java index 3139f68..77728d4 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/ColorRecipesExplorerApplication.java @@ -2,6 +2,7 @@ package dev.fyloz.trial.colorrecipesexplorer; import dev.fyloz.trial.colorrecipesexplorer.core.io.file.FileHandler; import dev.fyloz.trial.colorrecipesexplorer.core.services.PasswordService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.files.FilesService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -25,6 +26,7 @@ public class ColorRecipesExplorerApplication { public static ColorRecipesExplorerApplication CREApp; private MessageSource messageSource; + private FilesService filesService; public static void main(String[] args) { UPLOAD_LOCATION = args[0] != null ? args[0] : "./"; @@ -33,8 +35,9 @@ public class ColorRecipesExplorerApplication { } @Autowired - public ColorRecipesExplorerApplication(MessageSource messageSource) { + public ColorRecipesExplorerApplication(MessageSource messageSource, FilesService filesService) { this.messageSource = messageSource; + this.filesService = filesService; CREApp = this; LOGGER.info("Le fichier des utilisateurs se situe à: " + new File(UPLOAD_LOCATION + "/" + USERS_FILE_NAME).getAbsolutePath()); @@ -48,16 +51,14 @@ public class ColorRecipesExplorerApplication { * Un mot de passe correspond à une ligne dans le fichier passwords.txt. */ private void loadPasswords() { - FileHandler fileHandler = new FileHandler(USERS_FILE_NAME, FileHandler.FileContext.OTHERS, FileHandler.FileExtension.TEXT); - if (!fileHandler.isValid()) { - fileHandler.createFile(); - } + String filePath = String.format("%s/%s.txt", UPLOAD_LOCATION, USERS_FILE_NAME); try { - List fileContent = Files.readAllLines(fileHandler.getPath()); + if(filesService.fileExists(filePath)) filesService.createFile(filePath); + List fileContent = filesService.readFileAsStrings(filePath); if (fileContent.size() < 1) { - LOGGER.warn("Aucun mot de passe trouvé. Il sera impossible d'utiliser certaines fonctionnalitées de l'application."); + LOGGER.warn("Aucun mot de passe trouvé. Il sera impossible d'utiliser certaines fonctionnalités de l'application."); } for (String line : fileContent) { @@ -65,7 +66,7 @@ public class ColorRecipesExplorerApplication { } } catch (IOException e) { LOGGER.error("Une erreur est survenue lors du chargement du fichier des utilisateurs", e); - LOGGER.warn("Il sera impossible d'utiliser certaines fonctionnalitées de l'application."); + LOGGER.warn("Il sera impossible d'utiliser certaines fonctionnalités de l'application."); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java index 327eb83..b64b288 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java @@ -1,6 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.core.configuration; import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; import org.springframework.beans.factory.annotation.Autowired; @@ -10,8 +11,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import java.util.Optional; - @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class InitialDataLoader implements ApplicationListener { @@ -25,16 +24,17 @@ public class InitialDataLoader implements ApplicationListener optionalSavedMaterialType = materialTypeService.save(materialType); - if (optionalSavedMaterialType.isEmpty()) { - ColorRecipesExplorerApplication.LOGGER.warn(String.format("Échec de la création du type de produit par défaut '%s'.", materialType.getName())); + try { + materialTypeService.save(materialType); + } catch (ModelException ex) { + ColorRecipesExplorerApplication.LOGGER.warn(String.format("Échec de la création du type de produit par défaut '%s': %s", materialType.getName(), ex.getMessage())); } } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java index 301de4b..0a83d13 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/exception/model/EntityNotFoundException.java @@ -1,11 +1,12 @@ package dev.fyloz.trial.colorrecipesexplorer.core.exception.model; import dev.fyloz.trial.colorrecipesexplorer.core.model.IModel; -import org.hibernate.type.IdentifierType; +import lombok.Getter; /** * Représente une exception qui sera lancée lorsqu'un objet du modèle n'est pas trouvé. */ +@Getter public class EntityNotFoundException extends ModelException { /** @@ -13,6 +14,11 @@ public class EntityNotFoundException extends ModelException { */ private IdentifierType identifierType; + /** + * Le nom de l'identifiant utilisé (optionnel) + */ + private String identifierName; + /** * La valeur de l'identifiant */ @@ -24,12 +30,10 @@ public class EntityNotFoundException extends ModelException { this.requestedId = requestedId; } - public IdentifierType getIdentifierType() { - return identifierType; + public EntityNotFoundException(Class type, IdentifierType identifierType, String identifierName, Object requestedId) { + super(type); + this.identifierType = identifierType; + this.identifierName = identifierName != null ? identifierName : identifierType.getName(); + this.requestedId = requestedId; } - - public Object getRequestedId() { - return requestedId; - } - } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java index f55a994..9f4eab6 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java @@ -27,12 +27,12 @@ public class Material implements IModel { @NonNull @NotNull @ColumnDefault("0") - private float inventoryQuantity; + private Float inventoryQuantity; @NonNull @NotNull @ColumnDefault("false") - private boolean isMixType; + private Boolean isMixType; @NonNull @NotNull diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java index a3f5e4e..50910e0 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MixType.java @@ -12,6 +12,8 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor public class MixType implements IModel { + public static final String IDENTIFIER_MATERIAL_NAME = "material"; + @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java index e5c9106..63b9e6e 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java @@ -6,7 +6,9 @@ import org.hibernate.validator.constraints.Length; import javax.persistence.*; import javax.validation.constraints.NotNull; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; @Entity @Data @@ -35,7 +37,7 @@ public class Recipe implements IModel { @NonNull @NotNull - private int sample; + private Integer sample; private String approbationDate; @@ -49,4 +51,12 @@ public class Recipe implements IModel { @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List recipeSteps; + + public Collection getMixTypes() { + return mixes + .stream() + .map(Mix::getMixType) + .collect(Collectors.toList()); + } + } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/GenericService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/GenericService.java index 8370ba6..72c41b7 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/GenericService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/GenericService.java @@ -116,13 +116,12 @@ public class GenericService> } @Override - @Deprecated(since = "v.1.3.0", forRemoval = true) public boolean exists(T entity) { return entity != null && entity.getId() != null && existsById(entity.getId()); } @Override - public final boolean existsById(Long id) { + public boolean existsById(Long id) { return dao.existsById(id); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java index c8e0d60..b8d4575 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java @@ -1,5 +1,6 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; import dev.fyloz.trial.colorrecipesexplorer.core.model.MixQuantity; @@ -38,7 +39,12 @@ public class InventoryService { if (!material.isMixType()) { material.setInventoryQuantity(material.getInventoryQuantity() - entry.getValue()); - if (materialService.update(material).isEmpty()) return false; + + try { + materialService.update(material); + } catch (EntityNotFoundException ex) { + return false; + } } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java index b22f630..64fff49 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java @@ -14,6 +14,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.List; @Service public class FilesService { @@ -65,6 +66,17 @@ public class FilesService { return Files.readAllBytes(Paths.get(path)); } + /** + * Récupère le contenu d'un fichier dans une liste de String. + * + * @param path Le chemin vers le fichier + * @return Le contenu du fichier dans une liste de String + * @throws IOException La lecture du fichier a échoué + */ + public List readFileAsStrings(String path) throws IOException { + return Files.readAllLines(Paths.get(path)); + } + /** * Écrit un fichier Multipart sur le disque. * @@ -93,7 +105,7 @@ public class FilesService { * @throws IOException La création du fichier échoue */ public File createFile(String path) throws IOException { - File file = new File(path); + File file = getFile(path); if (!file.exists() || file.isDirectory()) { Files.createDirectories(file.getParentFile().toPath()); @@ -110,7 +122,7 @@ public class FilesService { * @throws IOException La suppression du fichier échoue */ public void deleteFile(String path) { - File file = new File(path); + File file = getFile(path); try { if (file.exists() && !file.isDirectory()) Files.delete(file.toPath()); @@ -119,4 +131,20 @@ public class FilesService { } } + /** + * Vérifie si un fichier existe sur le disque. + * + * @param path Le chemin vers le fichier + * @return Si le fichier existe + */ + public boolean fileExists(String path) { + File file = getFile(path); + + return file.exists() && !file.isDirectory(); + } + + private File getFile(String path) { + return new File(path); + } + } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java index d2db0d7..5da78b2 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java @@ -3,8 +3,12 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services.files; import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import javax.imageio.ImageIO; +import java.io.File; import java.io.IOException; +import java.io.InputStream; @Service public class ImagesService { @@ -26,6 +30,26 @@ public class ImagesService { } } + public boolean writeMultipartImage(MultipartFile image, String name) { + return filesService.writeMultiPartFile(image, getPath(name)); + } + + public void deleteImage(String name) { + filesService.deleteFile(getPath(name)); + } + + public boolean isImage(InputStream input) { + try { + return !(ImageIO.read(input) == null); + } catch (IOException ex) { + throw new RuntimeException("Erreur lors de la vérification d'une image: " + ex.getMessage()); + } + } + + public File getDirectoryFile() { + return new File(getPath("")); + } + private String getPath(String name) { return String.format("%s/%s/%s", ColorRecipesExplorerApplication.UPLOAD_LOCATION, IMAGES_DIRECTORY, name); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java new file mode 100644 index 0000000..8d3f0dc --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/SimdutService.java @@ -0,0 +1,77 @@ +package dev.fyloz.trial.colorrecipesexplorer.core.services.files; + +import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; +import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +@Service +public class SimdutService { + + private static final String SIMDUT_DIRECTORY = "simdut"; + + private FilesService filesService; + private MaterialService materialService; + + @Autowired + public SimdutService(FilesService filesService, MaterialService materialService) { + this.filesService = filesService; + this.materialService = materialService; + } + + /** + * Lit le fichier SIMDUT d'un produit et retourne son contenu. + * + * @param material Le produit + * @return Le contenu du fichier SIMDUT du produit + */ + public byte[] readSimdutForMaterial(Material material) { + String path = getPath(material); + + if (filesService.fileExists(path)) return new byte[0]; + + try { + return filesService.readFileAsBytes(path); + } catch (IOException ex) { + throw new RuntimeException("Impossible de lire un fichier SIMDUT: " + ex.getMessage()); + } + } + + /** + * Lit le fichier SIMDUT du produit correspondant à un identifiant et retourne son contenu. + * + * @param id L'identifiant du produit + * @return Le contenu du fichier SIMDUT du produit correspondant à l'identifiant + */ + public byte[] readSimdutForMaterialId(Long id) { + return readSimdutForMaterial(materialService.getById(id)); + } + + /** + * Vérifie si un produit a un fichier SIMDUT. + * + * @param material Le produit + * @return Si le produit a un fichier SIMDUT + */ + public boolean simdutExistsForMaterial(Material material) { + return filesService.fileExists(getPath(material)); + } + + /** + * Vérifie si le produit correspondant à un identifiant a un fichier SIMDUT. + * + * @param id L'identifiant du produit + * @return si le produit correspondant à l'identifiant a un fichier SIMDUT + */ + public boolean simdutExistsForMaterialId(Long id) { + return simdutExistsForMaterial(materialService.getById(id)); + } + + private String getPath(Material material) { + return String.format("%s/%s/%s", ColorRecipesExplorerApplication.UPLOAD_LOCATION, SIMDUT_DIRECTORY, materialService.getSimdutFileName(material)); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java new file mode 100644 index 0000000..94051c9 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/XlsService.java @@ -0,0 +1,68 @@ +package dev.fyloz.trial.colorrecipesexplorer.core.services.files; + +import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; +import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +@Service +public class XlsService { + + private RecipeService recipeService; + + @Autowired + public XlsService(RecipeService recipeService) { + this.recipeService = recipeService; + } + + /** + * Génère le fichier XLS d'une recette. + * + * @param recipe La recette + * @return Le fichier XLS de la recette + */ + public byte[] generateXlsForRecipe(Recipe recipe) { + return new XlsxExporter().generate(recipe); + } + + /** + * Génère le fichier XLS de la recette correspondant à l'identifiant. + * + * @param id L'identifiant de la recette + * @return Le fichier XLS de la recette + */ + public byte[] generateXlsForRecipeId(Long id) { + return generateXlsForRecipe(recipeService.getById(id)); + } + + /** + * Génère les fichiers XLS de toutes les recettes et les écrit dans un fichier ZIP. + * + * @return Le fichier ZIP contenant tous les fichiers XLS + */ + public byte[] generateXlsForAllRecipes() { + ColorRecipesExplorerApplication.LOGGER.info("Exportation de toutes les couleurs en XLS"); + + Collection recipes = recipeService.getAll(); + try (ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); ZipOutputStream zipOutput = new ZipOutputStream(byteOutput)) { + for (Recipe recipe : recipes) { + byte[] recipeXLS = generateXlsForRecipe(recipe); + zipOutput.putNextEntry(new ZipEntry(String.format("%s_%s.xlsx", recipe.getCompany().getName(), recipe.getName()))); + zipOutput.write(recipeXLS, 0, recipeXLS.length); + zipOutput.closeEntry(); + } + + return byteOutput.toByteArray(); + } catch (IOException ex) { + throw new RuntimeException("Impossible d'exporter toutes les recettes vers le format XLS: " + ex.getMessage()); + } + } +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java index 1221801..0c4b8c7 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java @@ -34,10 +34,6 @@ public class MaterialService extends GenericService { this.filesService = filesService; } - public Optional getByName(String name) { - return dao.findByName(name); - } - public List getAllByMaterialType(MaterialType materialType) { if (materialType == null) return new ArrayList<>(); @@ -77,6 +73,12 @@ public class MaterialService extends GenericService { return super.update(material); } + @Override + public void delete(Material material) { + removeSimdut(material); + super.delete(material); + } + /** * Vérifie si un produit est lié à un ou plusieurs mélanges. * @@ -94,30 +96,6 @@ public class MaterialService extends GenericService { } } - @Override - public boolean exists(Material material) { - return material != null && (super.exists(material) || dao.existsByName(material.getName())); - } - - @Override - public boolean isValidForUpdate(Material material) { - if (material == null) return false; - - Optional materialByCode = dao.findByName(material.getName()); - return super.isValidForUpdate(material) && (materialByCode.isEmpty() || material.getId().equals(materialByCode.get().getId())); - } - - /** - * Crée un FileHandler pour le produit passé en paramètre. - * - * @param material Le produit dont on veut créer un FileHandler - * @return Le FileHandler correspondant au produit. - */ - private FileHandler getFileHandlerForMaterial(Material material) { - String filename = String.format("%s_%s", material.getId(), material.getName()); - return new FileHandler(filename, FileHandler.FileContext.SIMDUT, FileHandler.FileExtension.PDF); - } - /** * Récupère le chemin vers le fichier SIMDUT d'un produit. * @@ -165,4 +143,8 @@ public class MaterialService extends GenericService { public void removeSimdut(Material material) { filesService.deleteFile(getSimdutPath(material)); } + + public String getSimdutFileName(Material material) { + return String.format("%s_%s", material.getId(), material.getName()); + } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixQuantityService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixQuantityService.java index 7774f78..86c3707 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixQuantityService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixQuantityService.java @@ -12,7 +12,7 @@ public class MixQuantityService extends GenericService { private MaterialService materialService; private MixQuantityService mixQuantityService; private MixTypeService mixTypeService; - private RecipeService recipeService; @Autowired - public MixService(MixDao mixDao, MaterialService materialService, MixQuantityService mixQuantityService, MixTypeService mixTypeService, RecipeService recipeService) { + public MixService(MixDao mixDao, MaterialService materialService, MixQuantityService mixQuantityService, MixTypeService mixTypeService) { super(mixDao, Mix.class); this.materialService = materialService; this.mixQuantityService = mixQuantityService; this.mixTypeService = mixTypeService; - this.recipeService = recipeService; } /** * Récupère les produits disponibles pour un mélange. * Le mélange peut ne pas exister. * - * @param recipeId L'identifiant de la recette dans laquelle se trouve le mélange - * @param mixId L'identifiant du mélange (-1 si le mélange n'existe pas) + * @param recipe La recette dans laquelle se trouve le mélange + * @param mixId L'identifiant du mélange (-1 si le mélange n'existe pas) * @return Les produits disponibles pour ce mélange */ - public Collection getAvailableMaterialsForMixId(Long recipeId, Long mixId) { - return existsById(mixId) ? getAvailableMaterialsForMix(getById(mixId)) : getAvailableMaterialsForNewMix(recipeService.getById(recipeId)); + public Collection getAvailableMaterialsForMixId(Recipe recipe, Long mixId) { + return existsById(mixId) ? getAvailableMaterialsForMix(getById(mixId)) : getAvailableMaterialsForNewMix(recipe); } /** @@ -65,12 +63,12 @@ public class MixService extends GenericService { * @return Les produits disponibles pour le nouveau mélange */ public Collection getAvailableMaterialsForNewMix(Recipe recipe) { - Collection recipeMixTypes = recipeService.getAssociatedMixesTypes(recipe); + Collection recipeMixTypes = recipe.getMixTypes(); return materialService .getAll() .stream() - .filter(m -> !m.isMixType() || recipeMixTypes.contains(mixTypeService.getByMaterial(m).get())) + .filter(m -> !m.isMixType() || recipeMixTypes.contains(mixTypeService.getByMaterial(m))) .sorted(Comparator.comparing(Material::getName)) .sorted(Comparator.comparing(m -> m.getMaterialType().getName())) .collect(Collectors.toList()); @@ -78,77 +76,81 @@ public class MixService extends GenericService { @Transactional public ModelResponseBuilder create(MixCreationFormDto formDto, @NotNull Recipe recipe) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); + throw new UnsupportedOperationException("TODO"); - List materials = new ArrayList<>(); - for (String materialCode : formDto.getMaterials()) { - Optional found = materialService.getByName(materialCode); - if (found.isEmpty()) { - return modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND_BY_NAME, materialCode); - } - - materials.add(found.get()); - } - - Optional optionalMixType = mixTypeService.createByName(formDto.getMixTypeName(), formDto.getMaterialType()); - if (optionalMixType.isEmpty()) return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); - - MixType mixType = optionalMixType.get(); - if (recipeService.hasMixType(recipe, mixType)) - return modelResponseBuilder.addResponseCode(ResponseCode.MIX_TYPE_ALREADY_USED, mixType.getName()); - - // Crée le mélange en premier pour avoir accès à son ID pour les autres éléments - Mix mix = new Mix(recipe, mixType); - - Optional savedMix = save(mix); - if (savedMix.isPresent()) { - mix = savedMix.get(); - - List mixQuantities = createMixQuantities(savedMix.get(), materials, formDto.getQuantities()); - mix.setMixQuantities(mixQuantities); - - // Retourne aucune erreur s'il la mise à jour à lieu - if (update(mix).isPresent()) return null; - - deleteMix(mix); - } - - return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); +// ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); +// +// List materials = new ArrayList<>(); +// for (String materialCode : formDto.getMaterials()) { +// Optional found = materialService.getByName(materialCode); +// if (found.isEmpty()) { +// return modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND_BY_NAME, materialCode); +// } +// +// materials.add(found.get()); +// } +// +// Optional optionalMixType = mixTypeService.createByName(formDto.getMixTypeName(), formDto.getMaterialType()); +// if (optionalMixType.isEmpty()) return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); +// +// MixType mixType = optionalMixType.get(); +// if (recipeService.hasMixType(recipe, mixType)) +// return modelResponseBuilder.addResponseCode(ResponseCode.MIX_TYPE_ALREADY_USED, mixType.getName()); +// +// // Crée le mélange en premier pour avoir accès à son ID pour les autres éléments +// Mix mix = new Mix(recipe, mixType); +// +// Optional savedMix = save(mix); +// if (savedMix.isPresent()) { +// mix = savedMix.get(); +// +// List mixQuantities = createMixQuantities(savedMix.get(), materials, formDto.getQuantities()); +// mix.setMixQuantities(mixQuantities); +// +// // Retourne aucune erreur s'il la mise à jour à lieu +// if (update(mix).isPresent()) return null; +// +// deleteMix(mix); +// } +// +// return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); } @Transactional public ModelResponseBuilder edit(Mix mix, MixCreationFormDto formDto) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Material material = mix.getMixType().getMaterial(); + throw new UnsupportedOperationException("TODO"); - List materials = new ArrayList<>(); - for (String materialCode : formDto.getMaterials()) { - Optional 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 oldQuantities = mix.getMixQuantities(); - List 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); - } +// ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); +// Material material = mix.getMixType().getMaterial(); +// +// List materials = new ArrayList<>(); +// for (String materialCode : formDto.getMaterials()) { +// Optional 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 oldQuantities = mix.getMixQuantities(); +// List 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) @@ -160,7 +162,7 @@ public class MixService extends GenericService { @Override public void delete(Mix mix) { mixQuantityService.deleteAll(mix.getMixQuantities()); -/ + super.delete(mix); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java index 2b42ba9..8cafbc6 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixTypeService.java @@ -1,7 +1,8 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.ModelException; import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MaterialType; import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; import dev.fyloz.trial.colorrecipesexplorer.core.services.GenericService; import dev.fyloz.trial.colorrecipesexplorer.dao.MixTypeDao; @@ -13,26 +14,35 @@ import java.util.Optional; @Service public class MixTypeService extends GenericService { - private MaterialTypeService materialTypeService; - @Autowired - public MixTypeService(MixTypeDao mixTypeDao, MaterialTypeService materialTypeService) { - super(mixTypeDao); - this.materialTypeService = materialTypeService; + public MixTypeService(MixTypeDao mixTypeDao) { + super(mixTypeDao, MixType.class); } - public Optional getByName(String name) { - return dao.findByName(name); + /** + * Récupère le type de mélange correspondant à un nom. + * + * @param name Le nom du type de mélange + * @return Le type de mélange correspondant au nom + */ + public MixType getByName(String name) { + Optional found = dao.findByName(name); + if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name); + + return found.get(); } - public Optional getByMaterial(Material material) { - return dao.findByMaterial(material); - } + /** + * Récupère le type de mélange correspondant à un produit. + * + * @param material Le produit du type de mélange + * @return Le type de mélange correspondant au produit + */ + public MixType getByMaterial(Material material) { + Optional found = dao.findByMaterial(material); + if (found.isEmpty()) + throw new EntityNotFoundException(type, ModelException.IdentifierType.OTHER, MixType.IDENTIFIER_MATERIAL_NAME, material); - public Optional createByName(String name, MaterialType type) { - Material mixTypeMaterial = new Material(name, 0f, true, type); - MixType mixType = new MixType(name, mixTypeMaterial); - - return save(mixType); + return found.get(); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java index 8918d71..5aa5240 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java @@ -1,11 +1,10 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services.model; -import dev.fyloz.trial.colorrecipesexplorer.core.io.file.FileHandler; -import dev.fyloz.trial.colorrecipesexplorer.core.io.file.ImageHandler; import dev.fyloz.trial.colorrecipesexplorer.core.model.*; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeEditorFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeExplorerFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.services.GenericService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.files.ImagesService; import dev.fyloz.trial.colorrecipesexplorer.dao.RecipeDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,13 +21,15 @@ public class RecipeService extends GenericService { private CompanyService companyService; private MixService mixService; private StepService stepService; + private ImagesService imagesService; @Autowired - public RecipeService(RecipeDao recipeDao, CompanyService companyService, MixService mixService, StepService stepService) { + public RecipeService(RecipeDao recipeDao, CompanyService companyService, MixService mixService, StepService stepService, ImagesService imagesService) { super(recipeDao, Recipe.class); this.companyService = companyService; this.mixService = mixService; this.stepService = stepService; + this.imagesService = imagesService; } /** @@ -127,16 +128,21 @@ public class RecipeService extends GenericService { * @return Une liste contenant le nom des images liées à la recette. */ public List getImageFiles(Recipe recipe) { - Long recipeId = recipe.getId(); - String name = recipe.getName(); - String fileName = String.format("%s_%s", recipeId, name); + String imageName = getImageFileName(recipe); + File[] allImages = imagesService.getDirectoryFile().listFiles((d, n) -> n.startsWith(imageName)); - File imageLocation = new File(ImageHandler.IMAGES_LOCATION); - File[] result = imageLocation.listFiles((d, n) -> n.startsWith(fileName) && n.endsWith("jpeg")); + if (allImages == null) return new ArrayList<>(); + return Arrays.stream(allImages).map(File::getName).collect(Collectors.toList()); + } - if (result == null) return new ArrayList<>(); + // TODO test + public int getNextImageIndex(Recipe recipe) { + String imageName = getImageFileName(recipe); + List allImages = getImageFiles(recipe); + List indexes = allImages.stream().map(i -> Integer.parseInt(i.replace(imageName + "-", ""))).collect(Collectors.toList()); + int maxIndex = Collections.max(indexes); - return Arrays.stream(result).map(File::getName).collect(Collectors.toList()); + return maxIndex + 1; } /** @@ -164,32 +170,6 @@ public class RecipeService extends GenericService { .collect(Collectors.toList()); } - /** - * Récupère les types de mélanges associés à la recette. - * - * @param recipe La recette dont on veut récupérer les types de mélange - * @return Une liste contenant les types de mélanges. - */ - public List getAssociatedMixesTypes(Recipe recipe) { - return recipe - .getMixes() - .stream() - .map(Mix::getMixType) - .collect(Collectors.toList()); - } - - /** - * Vérifie si une recette contient un mélange ayant le type de mélange spécifié. - * - * @param recipe La recette - * @param mixType Le type de mélange - * @return Si la recette contient le type de mélange - */ - public boolean hasMixType(Recipe recipe, MixType mixType) { - return getAssociatedMixesTypes(recipe) - .contains(mixType); - } - private Map> mappedByCompany(List recipes) { List companies = companyService.getAll(); Map> mappedRecipes = new HashMap<>(); @@ -236,18 +216,19 @@ public class RecipeService extends GenericService { return update(recipe); } - private boolean removeAllFiles(Recipe recipe) { - FileHandler fileHandler; - for (String image : getImageFiles(recipe)) { - fileHandler = new FileHandler(image.replace(".jpeg", ""), FileHandler.FileContext.IMAGE, FileHandler.FileExtension.JPEG); - - if (!fileHandler.deleteFile()) return false; - } - - return true; + private void removeAllFiles(Recipe recipe) { + getImageFiles(recipe).forEach(f -> imagesService.deleteImage(f)); } public String getImageFileName(Recipe recipe) { return String.format("%s_%s", recipe.getId(), recipe.getName()); } + + public String getImageFileNameWithIndex(Recipe recipe) { + return getImageFileNameWithIndex(recipe, getNextImageIndex(recipe)); + } + + public String getImageFileNameWithIndex(Recipe recipe, int index) { + return String.format("%s-%s", getImageFileName(recipe), index); + } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java index 115ec9c..baf93f9 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java @@ -50,91 +50,69 @@ public class InventoryController { .build(); } - /** - * Déduit les quantités utilisées de chaque matériaux présents dans le corps de la requête (JSON) de l'inventaire. - * Le JSON dans le corps de la requête doit prendre cette forme: - * { - * "mixID 1": { - * "materialID 1": "quantité 1", - * "materialID 2": "quantité 2", - * "materialID 3": "quantité 3" - * }, - * "mixID 2": { - * "materialID 1": "quantité 1" - * }, - * .. - * } - * S'il y a une erreur, l'opération est annulée et aucun changement n'est fait dans l'inventaire. - *

- * Réponse de la méthode: - * - error: Contient le message d'erreur, s'il y a lieu - * - reason: Contient la raison de l'erreur (le champ fautif) - * - success: Contient le message à affiche lors du succès de la méthode - * - * @param form Le JSON contenant les quantités à utiliser. - * @return Une réponse sous forme de Map (vers Json). - */ @PostMapping(value = USE_INVENTORY, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @Transactional // TODO vers DTO // TODO + vers service public Map consumeMaterials(@RequestBody Map> form) { - JSONResponseBuilder responseBuilder = new JSONResponseBuilder(); + throw new UnsupportedOperationException("TODO"); - List mixes = new ArrayList<>(); - Map> quantities = new HashMap<>(); - - for (String mixIDStr : form.keySet()) { - Long mixID = Long.parseLong(mixIDStr); - - Optional optionalMix = mixService.getById(mixID); - if (optionalMix.isEmpty()) { - return responseBuilder - .addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID) - .build(); - } - - Mix mix = optionalMix.get(); - mixes.add(mix); - - Map formMaterials = form.get(mixIDStr); - Map mixQuantities = new HashMap<>(); - - for (Material material : mix.getMixQuantities().stream().map(MixQuantity::getMaterial).collect(Collectors.toList())) { - String materialIDAsString = String.valueOf(material.getId()); - - if (formMaterials.containsKey(materialIDAsString)) { - Float quantityAsString = formMaterials.get(materialIDAsString); - mixQuantities.put(material, quantityAsString); - } - } - - quantities.put(mix, mixQuantities); - } - - for (Mix mix : mixes) { - String errorCode = inventoryService.checkQuantities(mix, quantities.get(mix)); - if (errorCode != null) { - String materialCode = materialService.getById(Long.parseLong(errorCode.split("-")[1])).orElse(new Material()).getName(); - - return responseBuilder - .addResponseCode(ResponseCode.NOT_ENOUGH_MATERIAL, materialCode) - .addAttribute(RESPONSE_REASON, errorCode) - .build(); - } - } - - for (Mix mix : mixes) { - if (!inventoryService.useMix(quantities.get(mix))) { - return responseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING) - .build(); - } - } - - return responseBuilder - .addResponseCode(ResponseCode.SUCCESS_USING_MATERIALS) - .build(); +// JSONResponseBuilder responseBuilder = new JSONResponseBuilder(); +// +// List mixes = new ArrayList<>(); +// Map> quantities = new HashMap<>(); +// +// for (String mixIDStr : form.keySet()) { +// Long mixID = Long.parseLong(mixIDStr); +// +// Optional optionalMix = mixService.getById(mixID); +// if (optionalMix.isEmpty()) { +// return responseBuilder +// .addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID) +// .build(); +// } +// +// Mix mix = optionalMix.get(); +// mixes.add(mix); +// +// Map formMaterials = form.get(mixIDStr); +// Map mixQuantities = new HashMap<>(); +// +// for (Material material : mix.getMixQuantities().stream().map(MixQuantity::getMaterial).collect(Collectors.toList())) { +// String materialIDAsString = String.valueOf(material.getId()); +// +// if (formMaterials.containsKey(materialIDAsString)) { +// Float quantityAsString = formMaterials.get(materialIDAsString); +// mixQuantities.put(material, quantityAsString); +// } +// } +// +// quantities.put(mix, mixQuantities); +// } +// +// for (Mix mix : mixes) { +// String errorCode = inventoryService.checkQuantities(mix, quantities.get(mix)); +// if (errorCode != null) { +// String materialCode = materialService.getById(Long.parseLong(errorCode.split("-")[1])).orElse(new Material()).getName(); +// +// return responseBuilder +// .addResponseCode(ResponseCode.NOT_ENOUGH_MATERIAL, materialCode) +// .addAttribute(RESPONSE_REASON, errorCode) +// .build(); +// } +// } +// +// for (Mix mix : mixes) { +// if (!inventoryService.useMix(quantities.get(mix))) { +// return responseBuilder +// .addResponseCode(ResponseCode.ERROR_SAVING) +// .build(); +// } +// } +// +// return responseBuilder +// .addResponseCode(ResponseCode.SUCCESS_USING_MATERIALS) +// .build(); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java index 7cc0d99..0994de8 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java @@ -5,6 +5,7 @@ import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilde import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.services.files.MarkdownFilesService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -22,11 +23,13 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; public class OthersController { private MixService mixService; + private RecipeService recipeService; private MarkdownFilesService markdownService; @Autowired - public OthersController(MixService mixService, MarkdownFilesService markdownService) { + public OthersController(MixService mixService, RecipeService recipeService, MarkdownFilesService markdownService) { this.mixService = mixService; + this.recipeService = recipeService; this.markdownService = markdownService; } @@ -40,7 +43,7 @@ public class OthersController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(MATERIAL_SELECTOR_FRAGMENT); try { - modelResponseBuilder.addAttribute(MATERIALS, mixService.getAvailableMaterialsForMixId(recipeId, mixId)); + modelResponseBuilder.addAttribute(MATERIALS, mixService.getAvailableMaterialsForMixId(recipeService.getById(recipeId), mixId)); } catch (EntityNotFoundException ex) { modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeId); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java index eb2b376..ad999ad 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java @@ -1,7 +1,6 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; -import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; -import dev.fyloz.trial.colorrecipesexplorer.core.io.file.ImageHandler; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.JSONResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; @@ -9,22 +8,21 @@ import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; import dev.fyloz.trial.colorrecipesexplorer.core.services.files.ImagesService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; -import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; 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.*; +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.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import javax.imageio.ImageIO; -import java.io.File; import java.io.IOException; import java.util.Map; -import java.util.Optional; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @@ -47,17 +45,6 @@ public class ImageFilesController { return new ResponseEntity<>(imagesService.readImage(image), headers, HttpStatus.OK); } - /** - * Affiche la page pour ajouter une image pour une recette. - * Cette méthode requiert l'identifiant de la recette dans l'URL. - *

- * Modèle de la page: - * - id: Contient l'identifiant de la recette - * - * @param model Le Model injecté par Thymeleaf - * @param id L'identifiant de la recette - * @return La page à afficher. - */ @GetMapping(ADD_IMAGE_SPECIFIC) public ModelAndView getPage(ModelAndView model, @PathVariable Long id) { return new ModelResponseBuilder(model) @@ -66,94 +53,32 @@ public class ImageFilesController { .build(); } - /** - * Permet à l'utilisateur d'uploader une image. - *

- * L'upload échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action. - * - La recette n'existe pas - * - Une erreur est survenue lors de la création du fichier de l'image - * - Une erreur est survenue lors du transfert de l'image vers le fichier - *

- * Modèle de la page: - * - error: Contient le message d'erreur, s'il y a lieu - * - recipeCode: Contient la couleur de la recette - * - id: Contient l'identifiant de la recette - *

- * REQUIERT UNE AUTORISATION - * - * @param id L'identifiant de la recette - * @param image L'image uploadée - * @return La page à afficher. - */ @PostMapping(ADD_IMAGE) public ModelAndView addImage(Long id, MultipartFile image) throws IOException { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(ControllerUtils.redirect(EDITOR_RECIPE_SPECIFIC.replace("{id}", String.valueOf(id)))); - - // Vérifie que le fichier est bien une image - if (ImageIO.read(image.getInputStream()) == null) { - return getPage(modelResponseBuilder - .addResponseCode(ResponseCode.FILE_NOT_IMAGE) - .build(), id); - } - - Optional optionalRecipe = recipeService.getById(id); - if (optionalRecipe.isEmpty()) { - return getPage(modelResponseBuilder - .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id) - .build(), id); - } - - Recipe recipe = optionalRecipe.get(); - ImageHandler imageHandler = new ImageHandler(recipe, recipeService); - if (!imageHandler.createFile()) { - return getPage(modelResponseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING_IMAGE) - .build(), id); - } - - modelResponseBuilder - .addResponseData(ResponseDataType.RECIPE_CODE, recipe.getName()) - .addResponseData(ResponseDataType.RECIPE_ID, recipe.getId()); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_RECIPE_SPECIFIC, id); try { - // Si je n'utilise pas le path, il cherche un fichier dans les tmp ? - image.transferTo(new File(imageHandler.getFile().getAbsolutePath())); + if (imagesService.isImage(image.getInputStream())) { + modelResponseBuilder.addResponseCode(ResponseCode.FILE_NOT_IMAGE); + } else { + Recipe recipe = recipeService.getById(id); - return modelResponseBuilder.build(); - } catch (IOException e) { - ColorRecipesExplorerApplication.LOGGER.error("Erreur inconnue lors de la création d'une image", e); - modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_IMAGE); - - return getPage(modelResponseBuilder.build(), id); + if (imagesService.writeMultipartImage(image, recipeService.getImageFileNameWithIndex(recipe))) + return modelResponseBuilder.build(); + else modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_IMAGE); + } + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id); } + + return getPage(modelResponseBuilder.build(), id); } - /** - * Permet à l'utilisateur de supprimer une image. - *

- * La suppression échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action - * - Une erreur est survenue lors de la suppression du fichier - *

- * Réponse de la méthode: - * - error: Contient le message d'erreur, s'il y a lieu - *

- * REQUIERT UNE AUTORISATION - * - * @param form Le formulaire contenant les informations sur l'opération - * @return La réponse sous forme de Map (pour y accéder en Json) - */ @PostMapping(value = DELETE_IMAGE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public Map deleteImage(@RequestBody Map form) { - JSONResponseBuilder responseBuilder = new JSONResponseBuilder(); + public Map deleteImage(String image) { + imagesService.deleteImage(image); - ImageHandler imageHandler = new ImageHandler(form.get("image"), recipeService); - if (!imageHandler.deleteFile()) { - responseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_IMAGE); - } - - return responseBuilder.build(); + return new JSONResponseBuilder().build(); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java index d616d3f..0a71e14 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java @@ -1,7 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; -import dev.fyloz.trial.colorrecipesexplorer.core.io.file.FileHandler; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; +import dev.fyloz.trial.colorrecipesexplorer.core.services.files.SimdutService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest; -import java.util.Optional; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CLOSE_TAB; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.SIMDUT_FILES; @@ -22,41 +21,38 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.SIMDUT_FILES @Controller public class SIMDUTFilesController { - private MaterialService materialService; + private SimdutService simdutService; @Autowired - public SIMDUTFilesController(MaterialService materialService) { - this.materialService = materialService; + public SIMDUTFilesController(SimdutService simdutService) { + this.simdutService = simdutService; } @GetMapping(SIMDUT_FILES) public ResponseEntity getFile(HttpServletRequest request, @PathVariable Long id) { - Optional optionalMaterial = materialService.getById(id); HttpHeaders headers = new HttpHeaders(); - if (optionalMaterial.isEmpty()) { - headers.add("Location", request.getHeader("referer")); - return new ResponseEntity<>(headers, HttpStatus.FOUND); - } - - FileHandler fileHandler = new FileHandler(String.format("%s_%s", id, optionalMaterial.get().getName()), FileHandler.FileContext.SIMDUT, FileHandler.FileExtension.PDF); - if (!fileHandler.isValid()) { + try { + if (simdutService.simdutExistsForMaterialId(id)) { + byte[] simdutContent = simdutService.readSimdutForMaterialId(id); + headers.setContentType(MediaType.APPLICATION_PDF); + return new ResponseEntity<>(simdutContent, headers, HttpStatus.OK); + } else { + headers.add("Location", request.getHeader("referer")); + } + } catch (EntityNotFoundException ex) { headers.add("Location", "/" + CLOSE_TAB); - return new ResponseEntity<>(headers, HttpStatus.FOUND); } - byte[] fileContent = fileHandler.readFile(); - headers.setContentType(MediaType.APPLICATION_PDF); - return new ResponseEntity<>(fileContent, headers, HttpStatus.OK); + return new ResponseEntity<>(headers, HttpStatus.FOUND); } @PostMapping(SIMDUT_FILES) public ResponseEntity getFile(@PathVariable Long id) { - Optional optionalMaterial = materialService.getById(id); - if (optionalMaterial.isEmpty()) return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); - - FileHandler fileHandler = new FileHandler(String.format("%s_%s", id, optionalMaterial.get().getName()), FileHandler.FileContext.SIMDUT, FileHandler.FileExtension.PDF); - if (!fileHandler.isValid()) return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); - return ResponseEntity.status(HttpStatus.FOUND).build(); + try { + return ResponseEntity.status(simdutService.simdutExistsForMaterialId(id) ? HttpStatus.FOUND : HttpStatus.NOT_FOUND).build(); + } catch (EntityNotFoundException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java index eb7feb0..84dd5ed 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java @@ -1,9 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; -import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; -import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; +import dev.fyloz.trial.colorrecipesexplorer.core.services.files.XlsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -14,76 +12,50 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import javax.servlet.http.HttpServletRequest; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.Collection; -import java.util.Optional; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.ALL_RECIPES_XLS; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.RECIPE_XLS; -// TODO Une grande partie du code de ce controlleur devrait se trouver dans un service @Controller public class XlsExporterController { - private RecipeService recipeService; + private XlsService xlsService; @Autowired - public XlsExporterController(RecipeService recipeService) { - this.recipeService = recipeService; + public XlsExporterController(XlsService xlsService) { + this.xlsService = xlsService; } @GetMapping(RECIPE_XLS) public ResponseEntity getXlsForRecipe(HttpServletRequest request, @PathVariable Long id) { HttpHeaders headers = new HttpHeaders(); - Optional optionalRecipe = recipeService.getById(id); - if (optionalRecipe.isEmpty()) { + try { + byte[] xlsContent = xlsService.generateXlsForRecipeId(id); + + return ResponseEntity.ok() + .headers(headers) + .contentLength(xlsContent.length) + .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) + .body(xlsContent); + } catch (EntityNotFoundException ex) { headers.add(HttpHeaders.LOCATION, request.getHeader("referer")); return new ResponseEntity<>(headers, HttpStatus.FOUND); } - - byte[] recipeXLS = new XlsxExporter().generate(optionalRecipe.get()); - if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - - return ResponseEntity.ok() - .headers(headers) - .contentLength(recipeXLS.length) - .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) - .body(recipeXLS); } @GetMapping(value = ALL_RECIPES_XLS, produces = "application/zip") public ResponseEntity getAllXls() throws IOException { HttpHeaders headers = new HttpHeaders(); - ColorRecipesExplorerApplication.LOGGER.info("Exportation de toutes les couleurs en XLS"); - - ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); - ZipOutputStream out = new ZipOutputStream(byteOS); - - Collection recipes = recipeService.getAll(); - for (Recipe recipe : recipes) { - 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().getName(), recipe.getName()))); - out.write(recipeXLS, 0, recipeXLS.length); - out.closeEntry(); - } - - out.close(); - - byte[] zipContent = byteOS.toByteArray(); - byteOS.close(); + byte[] allXlsContent = xlsService.generateXlsForAllRecipes(); return ResponseEntity.ok() .headers(headers) - .contentLength(zipContent.length) + .contentLength(allXlsContent.length) .contentType(MediaType.parseMediaType("application/zip")) - .body(zipContent); + .body(allXlsContent); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java index ac2a8c5..92c4afb 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java @@ -41,9 +41,9 @@ public class CompanyRemoverController { try { companyService.deleteById(id); - modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_COMPANY, companyService.getById(id)); + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_COMPANY, companyService.getById(id).getName()); } catch (EntityLinkedException ex) { - modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_LINKED, companyService.getById(id)); + modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_LINKED, companyService.getById(id).getName()); } catch (EntityNotFoundException ex) { modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_NOT_FOUND, id); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java index 0a5f455..df2273f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java @@ -1,5 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.removers; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; @@ -28,12 +30,6 @@ public class MaterialRemoverController { this.materialService = materialService; } - /** - * Affiche la page de suppression des produits - * - * @param model Le Model injecté par Thymeleaf - * @return La page à afficher. - */ @GetMapping(REMOVER_MATERIAL) public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) @@ -42,45 +38,20 @@ public class MaterialRemoverController { .build(); } - /** - * Permet à l'utilisateur de supprimer un produit. - * Cette méthode requiert l'identifiant du produit dans l'URL. - *

- * La suppression échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action - * - Le produit n'existe pas - * - Le produit est lié à d'autres mélanges - *

- * Modèle de la page: - * - error: Contient le message d'erreur, s'il y a lieu - * - materialCode: Contient le code de produit du produit supprimé - *

- * REQUIERT UNE AUTORISATION - * - * @param id L'identifiant du produit à supprimer - * @return La page à afficher. - */ @PostMapping(REMOVER_MATERIAL_SPECIFIC) public ModelAndView removeMaterial(@PathVariable Long id) { - ModelResponseBuilder responseBuilder = new ModelResponseBuilder(""); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Optional optionalMaterial = materialService.getById(id); - if (optionalMaterial.isEmpty()) { - responseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, id); - } else { - Material material = optionalMaterial.get(); + try { + materialService.deleteById(id); - if (materialService.deleteIfNotLinked(material)) { - responseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL, material.getName()); - - if (!materialService.removeSimdut(material)) { - responseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_SIMDUT); - } - } else { - responseBuilder.addResponseCode(ResponseCode.MATERIAL_LINKED, material.getName()); - } + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL, materialService.getById(id).getName()); + } catch (EntityLinkedException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_LINKED, materialService.getById(id).getName()); + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, id); } - return getPage(responseBuilder.build()); + return getPage(modelResponseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java index ee4ca2c..1daa79c 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java @@ -1,5 +1,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.removers; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityLinkedException; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; @@ -38,21 +40,18 @@ public class MaterialTypeRemoverController { @PostMapping(REMOVER_MATERIAL_TYPE_SPECIFIC) public ModelAndView removeMaterialType(@PathVariable Long id) { - ModelResponseBuilder responseBuilder = new ModelResponseBuilder(""); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Optional optionalMaterialType = materialTypeService.getById(id); - if (optionalMaterialType.isEmpty()) { - responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, id); - } else { - MaterialType materialType = optionalMaterialType.get(); + try { + materialTypeService.deleteById(id); - if (materialTypeService.deleteIfNotLinked(materialType)) { - responseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL_TYPE, materialType.getName()); - } else { - responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_LINKED, materialType.getName()); - } + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL_TYPE, materialTypeService.getById(id).getName()); + } catch (EntityLinkedException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_LINKED, materialTypeService.getById(id).getName()); + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, id); } - return getPage(responseBuilder.build()); + return getPage(modelResponseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java index 34d151f..ff4ee7b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java @@ -1,5 +1,6 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.removers; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; @@ -25,59 +26,26 @@ public class RecipeRemoverController { this.recipeService = recipeService; } - /** - * Affiche la liste de toutes les recettes. - * - * @param model Le Model injecté par Thymeleaf - * @return La page à afficher. - */ @GetMapping(REMOVER_RECIPE) - public ModelAndView listRecipes(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(REMOVER_RECIPE) .addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getRecipesByCompany()) .build(); } - /** - * Permet à l'utilisateur de supprimer une recette. - * Cette méthode requiert l'identifiant de la recette dans l'URL. - *

- * La suppression échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action - * - La recette n'existe pas - * - Une erreur est survenue lors de la suppression dans la base de données - *

- * Modèle de la page: - * - error: Contient le message d'erreur, s'il y a lieu - * - recipeCode: Contient la couleur de la recette - *

- * REQUIERT UNE AUTORISATION - * - * @param id L'identifiant de la recette - * @return La page à afficher. - */ @PostMapping(REMOVER_RECIPE_SPECIFIC) public ModelAndView removeRecipe(@PathVariable Long id) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(""); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Optional optionalRecipe = recipeService.getById(id); - if (optionalRecipe.isEmpty()) { - return listRecipes( - modelResponseBuilder - .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id) - .build()); + try { + recipeService.deleteById(id); + + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_RECIPE, recipeService.getById(id).getName()); + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id); } - Recipe recipe = optionalRecipe.get(); - if (!recipeService.deleteRecipe(recipe)) { - return listRecipes( - modelResponseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING) - .build()); - } - - modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_RECIPE, recipe.getName()); - return listRecipes(modelResponseBuilder.build()); + return getPage(modelResponseBuilder.build()); } }