Merge branch 'drop-thymeleaf' into 'master'
Drop thymeleaf See merge request color-recipes-explorer/backend!15
This commit is contained in:
commit
376d244f29
46
backup.ps1
46
backup.ps1
|
@ -1,46 +0,0 @@
|
|||
param (
|
||||
[string]$WorkDir = "./workdir",
|
||||
[string]$BackupPath = "./backup",
|
||||
[boolean]$OverWrite = $False
|
||||
)
|
||||
|
||||
Write-Host "Démarrage de la sauvegarde..."
|
||||
if (!(Test-Path -Path $WorkDir))
|
||||
{
|
||||
Write-Host "Le dossier de travail ($WorkDir) n'existe pas."
|
||||
exit
|
||||
}
|
||||
|
||||
if (!(Test-Path -Path $BackupPath))
|
||||
{
|
||||
Write-Host "Création du dossier des sauvegardes. ($BackupPath)"
|
||||
New-Item -ItemType directory -Path $BackupPath | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Début de la compression..."
|
||||
$BackupFile = "$BackupPath/backup_$( Get-Date -f yyyyMMdd-HHmm ).zip"
|
||||
$CompressArgs = @{
|
||||
'Path' = $WorkDir
|
||||
'DestinationPath' = $BackupFile
|
||||
'Update' = $OverWrite
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Compress-Archive @CompressArgs
|
||||
|
||||
Write-Host "Sauvegarde réussie! ($BackupFile)"
|
||||
}
|
||||
catch [System.IO.IOException]
|
||||
{
|
||||
Write-Output "Une erreur est survenue lors de la sauvegarde:"
|
||||
|
||||
if ($_.FullyQualifiedErrorId -like "ArchiveFileExists*")
|
||||
{
|
||||
Write-Host "L'archive de sauvegarde '$BackupFile' existe déjà. Ajoutez l'argument '-OverWrite `$true' pour écraser l'archive."
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host $_
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ plugins {
|
|||
id("org.jetbrains.kotlin.jvm") version "1.4.30"
|
||||
id("org.jetbrains.dokka") version "1.4.20"
|
||||
id("com.leobia.gradle.sassjavacompiler") version "0.2.1"
|
||||
id("io.freefair.lombok") version "5.2.1"
|
||||
id("org.springframework.boot") version "2.3.4.RELEASE"
|
||||
id("org.jetbrains.kotlin.plugin.spring") version "1.4.30"
|
||||
id("org.jetbrains.kotlin.plugin.jpa") version "1.4.30"
|
||||
|
@ -29,13 +28,10 @@ dependencies {
|
|||
implementation("io.jsonwebtoken:jjwt:0.9.1")
|
||||
implementation("org.apache.poi:poi-ooxml:4.1.0")
|
||||
implementation("org.apache.pdfbox:pdfbox:2.0.4")
|
||||
implementation("com.atlassian.commonmark:commonmark:0.13.1")
|
||||
implementation("commons-io:commons-io:2.6")
|
||||
implementation("dev.fyloz.colorrecipesexplorer:database-manager:1.1.0")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.3.4.RELEASE")
|
||||
implementation("org.springframework.boot:spring-boot-starter-jdbc:2.3.4.RELEASE")
|
||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:2.3.4.RELEASE")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web:2.3.4.RELEASE")
|
||||
implementation("org.springframework.boot:spring-boot-starter-validation:2.3.4.RELEASE")
|
||||
implementation("org.springframework.boot:spring-boot-starter-security:2.3.4.RELEASE")
|
||||
|
@ -55,8 +51,6 @@ dependencies {
|
|||
runtimeOnly("mysql:mysql-connector-java:8.0.22")
|
||||
runtimeOnly("org.postgresql:postgresql:42.2.16")
|
||||
runtimeOnly("com.microsoft.sqlserver:mssql-jdbc:9.2.1.jre11")
|
||||
|
||||
compileOnly("org.projectlombok:lombok:1.18.10")
|
||||
}
|
||||
|
||||
java {
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# This file is generated by the 'io.freefair.lombok' Gradle plugin
|
||||
config.stopBubbling = true
|
|
@ -1,32 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.MaterialService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.MaterialTypeService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class InitialDataLoader implements ApplicationListener<ApplicationReadyEvent> {
|
||||
private final MaterialTypeService materialTypeService;
|
||||
private final MaterialTypeProperties materialTypeProperties;
|
||||
|
||||
@Autowired
|
||||
public InitialDataLoader(MaterialTypeService materialTypeService, MaterialTypeProperties materialTypeProperties) {
|
||||
this.materialTypeService = materialTypeService;
|
||||
this.materialTypeProperties = materialTypeProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
|
||||
materialTypeService.saveSystemTypes(materialTypeProperties.getSystemTypes());
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Configuration
|
||||
public class LocaleConfiguration implements WebMvcConfigurer {
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
|
||||
messageSource.setBasenames("classpath:lang/messages", "classpath:lang/responses");
|
||||
messageSource.setDefaultEncoding("UTF-8");
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
|
||||
localeResolver.setDefaultLocale(Locale.FRENCH);
|
||||
return localeResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocaleChangeInterceptor localeChangeInterceptor() {
|
||||
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
|
||||
localeChangeInterceptor.setParamName("lang");
|
||||
return localeChangeInterceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalValidatorFactoryBean validator(MessageSource messageSource) {
|
||||
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
|
||||
bean.setValidationMessageSource(messageSource);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(localeChangeInterceptor());
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.context.MessageSource;
|
||||
|
||||
public class Preferences {
|
||||
|
||||
public static Logger logger;
|
||||
|
||||
public static MessageSource messageSource;
|
||||
|
||||
public static boolean urlUsePort;
|
||||
|
||||
public static boolean urlUseHttps;
|
||||
|
||||
public static String uploadDirectory;
|
||||
|
||||
public static String passwordsFileName;
|
||||
|
||||
public static String baseMaterialTypeName;
|
||||
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.CREProperties;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.PasswordService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.FilesService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class SpringConfiguration {
|
||||
|
||||
private FilesService filesService;
|
||||
private MessageSource messageSource;
|
||||
private CREProperties creProperties;
|
||||
private MaterialTypeProperties materialTypeProperties;
|
||||
|
||||
@Autowired
|
||||
public void setFilesService(FilesService filesService) {
|
||||
this.filesService = filesService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier("CREProperties")
|
||||
public void setCreProperties(CREProperties creProperties) {
|
||||
this.creProperties = creProperties;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialTypeProperties(MaterialTypeProperties materialTypeProperties) {
|
||||
this.materialTypeProperties = materialTypeProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Logger getLogger() {
|
||||
return LoggerFactory.getLogger(ColorRecipesExplorerApplication.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public void setPreferences() {
|
||||
Preferences.urlUsePort = creProperties.isUrlUsePort();
|
||||
Preferences.urlUseHttps = creProperties.isUrlUseHttps();
|
||||
Preferences.uploadDirectory = creProperties.getUploadDirectory();
|
||||
Preferences.passwordsFileName = creProperties.getPasswordFile();
|
||||
Preferences.logger = getLogger();
|
||||
Preferences.messageSource = messageSource;
|
||||
Preferences.baseMaterialTypeName = materialTypeProperties.getBaseName();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public void initializePasswords() {
|
||||
Logger logger = Preferences.logger;
|
||||
String filePath = filesService.getPath(Preferences.passwordsFileName);
|
||||
|
||||
logger.info("Le fichier des utilisateurs se situe à: " + filesService.getFile(filePath).getAbsolutePath());
|
||||
|
||||
try {
|
||||
if (!filesService.exists(filePath)) filesService.create(filePath);
|
||||
List<String> fileContent = filesService.readAsStrings(filePath);
|
||||
|
||||
if (fileContent.size() < 1) {
|
||||
logger.warn("Aucun mot de passe trouvé. Il sera impossible d'utiliser certaines fonctionnalités de l'application.");
|
||||
}
|
||||
|
||||
for (String line : fileContent) {
|
||||
PasswordService.addPassword(line);
|
||||
}
|
||||
} 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és de l'application.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "cre.server")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CREProperties {
|
||||
|
||||
private String passwordFile;
|
||||
private String uploadDirectory;
|
||||
private boolean urlUseHttps;
|
||||
private boolean urlUsePort;
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class CannotDeleteDefaultMaterialTypeException extends RuntimeException {
|
||||
|
||||
private MaterialType materialType;
|
||||
|
||||
public CannotDeleteDefaultMaterialTypeException(MaterialType materialType) {
|
||||
this.materialType = materialType;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MaterialTypeEditorDto;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class CannotEditDefaultMaterialTypeException extends RuntimeException {
|
||||
|
||||
private MaterialTypeEditorDto materialType;
|
||||
|
||||
public CannotEditDefaultMaterialTypeException(MaterialTypeEditorDto materialType) {
|
||||
this.materialType = materialType;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
|
||||
public class SimdutException extends RuntimeException {
|
||||
|
||||
private Material material;
|
||||
|
||||
public SimdutException(Material material) {
|
||||
this.material = material;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class TooLowQuantityException extends RuntimeException {
|
||||
|
||||
private Long mixId;
|
||||
private Material material;
|
||||
private Float storedQuantity;
|
||||
private Float requestQuantity;
|
||||
|
||||
private String response;
|
||||
|
||||
public TooLowQuantityException(Long mixId, Material material, Float storedQuantity, Float requestQuantity) {
|
||||
this.mixId = mixId;
|
||||
this.material = material;
|
||||
this.storedQuantity = storedQuantity;
|
||||
this.requestQuantity = requestQuantity;
|
||||
|
||||
response = String.format("%s_%s", mixId, material.getId());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
//package dev.fyloz.trial.colorrecipesexplorer.exception.model;
|
||||
//
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.model.IModel;
|
||||
//import lombok.Getter;
|
||||
//import lombok.NonNull;
|
||||
//import org.springframework.http.HttpStatus;
|
||||
//import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
//
|
||||
//@Getter
|
||||
//@ResponseStatus(HttpStatus.CONFLICT)
|
||||
//public class EntityAlreadyExistsException extends ModelException {
|
||||
//
|
||||
// @NonNull
|
||||
// private IdentifierType identifierType;
|
||||
//
|
||||
// private String identifierName;
|
||||
//
|
||||
// @NonNull
|
||||
// private Object requestedId;
|
||||
//
|
||||
// public EntityAlreadyExistsException(EntityAlreadyExistsException ex) {
|
||||
// this(ex.type, ex.identifierType, ex.identifierName, ex.requestedId);
|
||||
// }
|
||||
//
|
||||
// public EntityAlreadyExistsException(Class<? extends IModel> type, IdentifierType identifierType, Object requestedId) {
|
||||
// super(type);
|
||||
// this.identifierType = identifierType;
|
||||
// this.requestedId = requestedId;
|
||||
// }
|
||||
//
|
||||
// public EntityAlreadyExistsException(Class<? extends IModel> type, IdentifierType identifierType, String identifierName, Object requestedId) {
|
||||
// super(type);
|
||||
// this.identifierType = identifierType;
|
||||
// this.identifierName = identifierName != null ? identifierName : identifierType.getName();
|
||||
// this.requestedId = requestedId;
|
||||
// }
|
||||
//}
|
|
@ -1,13 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model;
|
||||
|
||||
/**
|
||||
* Représente une exception qui sera lancée lorsqu'un objet du modèle qui est lié à un autre entité doit être supprimé
|
||||
*/
|
||||
public class EntityLinkedException extends ModelException {
|
||||
|
||||
public EntityLinkedException(Class<? extends Model> type) {
|
||||
super(type);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//package dev.fyloz.trial.colorrecipesexplorer.exception.model;
|
||||
//
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.model.IModel;
|
||||
//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 {
|
||||
//
|
||||
// /**
|
||||
// * Le type d'identifiant utilisé
|
||||
// */
|
||||
// private IdentifierType identifierType;
|
||||
//
|
||||
// /**
|
||||
// * Le nom de l'identifiant utilisé (optionnel)
|
||||
// */
|
||||
// private String identifierName;
|
||||
//
|
||||
// /**
|
||||
// * La valeur de l'identifiant
|
||||
// */
|
||||
// private Object requestedId;
|
||||
//
|
||||
// public EntityNotFoundException(Class<? extends IModel> type, IdentifierType identifierType, Object requestedId) {
|
||||
// super(type);
|
||||
// this.identifierType = identifierType;
|
||||
// this.requestedId = requestedId;
|
||||
// }
|
||||
//
|
||||
// public EntityNotFoundException(Class<? extends IModel> type, IdentifierType identifierType, String identifierName, Object requestedId) {
|
||||
// super(type);
|
||||
// this.identifierType = identifierType;
|
||||
// this.identifierName = identifierName != null ? identifierName : identifierType.getName();
|
||||
// this.requestedId = requestedId;
|
||||
// }
|
||||
//}
|
|
@ -1,38 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model;
|
||||
|
||||
/**
|
||||
* Représente une exception qui sera déclenchée lors des opérations sur le modèle.
|
||||
*/
|
||||
public class ModelException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Le type de modèle qui est sujet à l'exception
|
||||
*/
|
||||
protected Class<? extends Model> type;
|
||||
|
||||
public ModelException(Class<? extends Model> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Class<? extends Model> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public enum IdentifierType {
|
||||
ID("id"),
|
||||
NAME("name"),
|
||||
OTHER("");
|
||||
|
||||
private String name;
|
||||
|
||||
IdentifierType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model;
|
||||
|
||||
public class NullIdentifierException extends ModelException {
|
||||
|
||||
public NullIdentifierException(Class<? extends Model> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("Un modèle de type '%s' avait un identifiant nécessaire null", type.getSimpleName());
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.model.dto;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MaterialTypeEditorDto {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String oldName;
|
||||
|
||||
private String name;
|
||||
|
||||
private String oldPrefix;
|
||||
|
||||
private String prefix;
|
||||
|
||||
private boolean usePercentages;
|
||||
|
||||
public MaterialTypeEditorDto(MaterialType materialType) {
|
||||
this.id = materialType.getId();
|
||||
this.oldName = materialType.getName();
|
||||
this.name = materialType.getName();
|
||||
this.oldPrefix = materialType.getPrefix();
|
||||
this.prefix = materialType.getPrefix();
|
||||
this.usePercentages = materialType.getUsePercentages();
|
||||
}
|
||||
|
||||
public MaterialType getMaterialType() {
|
||||
return new MaterialType(id, name, prefix, usePercentages, false);
|
||||
}
|
||||
|
||||
public MaterialType getOldMaterialType() {
|
||||
return new MaterialType(id, oldName, oldPrefix, usePercentages, false);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.model.dto;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class MixFormDto {
|
||||
|
||||
private Recipe recipe;
|
||||
|
||||
private String oldMixTypeName;
|
||||
|
||||
private String mixTypeName;
|
||||
|
||||
private MaterialType materialType;
|
||||
|
||||
private List<String> materials;
|
||||
|
||||
private List<Float> quantities;
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.model.dto;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RecipeEditorFormDto {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Company company;
|
||||
|
||||
private String description;
|
||||
|
||||
private Integer sample;
|
||||
|
||||
private LocalDate approbationDate;
|
||||
|
||||
private String remark;
|
||||
|
||||
private String note;
|
||||
|
||||
private List<String> step;
|
||||
|
||||
public Recipe getRecipe() {
|
||||
return new Recipe(id, name, company, description, "ffffff", (byte) 0, sample, approbationDate, remark, note);
|
||||
}
|
||||
|
||||
public Recipe update(Recipe original) {
|
||||
return new Recipe(original.getId(), name, company, description, "ffffff", (byte) 0, sample, approbationDate, remark, note);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class RecipeExplorerFormDto {
|
||||
|
||||
private Long recipeId;
|
||||
private Map<Long, String> locations;
|
||||
private String note;
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.NamedJpaRepository;
|
||||
|
||||
abstract public class AbstractJavaNamedService<E extends NamedModel, R extends NamedJpaRepository<E>> extends AbstractJavaService<E, R> {
|
||||
|
||||
public AbstractJavaNamedService(Class<E> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
public boolean existsByName(String name) {
|
||||
return repository.existsByName(name);
|
||||
}
|
||||
|
||||
public E getByName(String name) {
|
||||
E found = repository.findByName(name);
|
||||
if (found == null) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
public void deleteByName(String name) {
|
||||
repository.deleteByName(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.NullIdentifierException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class AbstractJavaService<E extends Model, R extends JpaRepository<E, Long>> implements IGenericJavaService<E> {
|
||||
|
||||
protected Logger logger = Preferences.logger;
|
||||
protected R repository;
|
||||
protected Class<E> type;
|
||||
|
||||
public AbstractJavaService(Class<E> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public R getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsById(Long id) {
|
||||
return repository.existsById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une entité correspondant à un identifiant existe.
|
||||
* <p>
|
||||
* Méthode pour la compatibilité avec les services Kotlin.
|
||||
*
|
||||
* @param id L'identifiant de l'entité
|
||||
* @return Si un entité correspondant à l'identifiant existe
|
||||
*/
|
||||
public boolean existsById(long id) {
|
||||
return existsById(Long.valueOf(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode utilitaire pour wrapper les entités nullables dans un Optional.
|
||||
* <p>
|
||||
* Méthode pour la compatibilité avec les repository Kotlin.
|
||||
*
|
||||
* @param entity L'entité nullable
|
||||
* @return Un optional wrapper l'entité donnée
|
||||
*/
|
||||
protected Optional<E> findOptional(@Nullable E entity) {
|
||||
return Optional.ofNullable(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getById(Long id) {
|
||||
Optional<E> found = repository.findById(id);
|
||||
if (found.isEmpty()) throw new EntityNotFoundException(type, EntityNotFoundException.IdentifierType.ID, id);
|
||||
|
||||
return found.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère l'entité de type T correspondant à un identifiant.
|
||||
* <p>
|
||||
* Méthode pour la compatibilité avec les services Kotlin.
|
||||
*
|
||||
* @param id L'identifiant de l'entité
|
||||
* @return L'entité correspondant à l'identifiant
|
||||
*/
|
||||
public E getById(long id) {
|
||||
return getById(Long.valueOf(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> getAll() {
|
||||
return repository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E save(@NotNull E entity) {
|
||||
if (entity.getId() != null && existsById(entity.getId()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.ID, entity.getId());
|
||||
|
||||
return repository.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<E> saveAll(@NotNull Collection<E> entities) {
|
||||
return entities
|
||||
.stream()
|
||||
.map(this::save)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public E update(@NotNull E entity) {
|
||||
if (entity.getId() == null) throw new NullIdentifierException(type);
|
||||
if (!existsById(entity.getId()))
|
||||
throw new EntityNotFoundException(type, ModelException.IdentifierType.ID, entity.getId());
|
||||
|
||||
return repository.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(@NotNull E entity) {
|
||||
repository.delete(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id) {
|
||||
delete(getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime une entité correspondant à l'identifiant.
|
||||
* <p>
|
||||
* Méthode pour la compatibilité avec les services Kotlin.
|
||||
*
|
||||
* @param id L'identifiant de l'entité à supprimer
|
||||
*/
|
||||
public void deleteById(long id) {
|
||||
deleteById(Long.valueOf(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(Collection<E> entities) {
|
||||
repository.deleteAll(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforme un objet en Json.
|
||||
*
|
||||
* @param obj L'objet à transformer
|
||||
* @return L'objet sous forme de Json.
|
||||
*/
|
||||
public String asJson(Object obj) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
Preferences.logger.error("Une erreur est survenue lors de la transformation d'un objet en Json", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface IGenericJavaService<T extends Model> {
|
||||
|
||||
/**
|
||||
* Vérifie si une entité correspondant à un identifiant existe.
|
||||
*
|
||||
* @param id L'identifiant de l'entité
|
||||
* @return Si un entité correspondant à l'identifiant existe
|
||||
*/
|
||||
boolean existsById(Long id);
|
||||
|
||||
/**
|
||||
* Récupère toutes les entités de type T.
|
||||
*
|
||||
* @return Toutes les entités de type T
|
||||
*/
|
||||
List<T> getAll();
|
||||
|
||||
/**
|
||||
* Récupère l'entité de type T correspondant à un identifiant.
|
||||
*
|
||||
* @param id L'identifiant de l'entité
|
||||
* @return L'entité correspondant à l'identifiant
|
||||
*/
|
||||
T getById(Long id);
|
||||
|
||||
/**
|
||||
* Crée une entité.
|
||||
*
|
||||
* @param entity L'entité à créer
|
||||
* @return L'entité créée
|
||||
*/
|
||||
T save(T entity);
|
||||
|
||||
/**
|
||||
* Crée plusieurs entités.
|
||||
*
|
||||
* @param entities Les entités à créer
|
||||
* @return Les entités créées
|
||||
*/
|
||||
Collection<T> saveAll(Collection<T> entities);
|
||||
|
||||
/**
|
||||
* Met à jour une entité dans le stockage.
|
||||
*
|
||||
* @param entity L'entité à mettre à jour
|
||||
* @return L'entité mise à jour
|
||||
*/
|
||||
T update(T entity);
|
||||
|
||||
/**
|
||||
* Supprime une entité.
|
||||
*
|
||||
* @param entity L'entité à supprimer
|
||||
*/
|
||||
void delete(T entity);
|
||||
|
||||
/**
|
||||
* Supprime une entité correspondant à l'identifiant.
|
||||
*
|
||||
* @param id L'identifiant de l'entité à supprimer
|
||||
*/
|
||||
void deleteById(Long id);
|
||||
|
||||
/**
|
||||
* Supprime plusieurs entités.
|
||||
*
|
||||
* @param entities Les entités à supprimer
|
||||
*/
|
||||
void deleteAll(Collection<T> entities);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PasswordService {
|
||||
|
||||
private static List<String> passwords = new ArrayList<>();
|
||||
|
||||
public static boolean isValid(String password) {
|
||||
return passwords.contains(password);
|
||||
}
|
||||
|
||||
public static void addPassword(String password) {
|
||||
passwords.add(password);
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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 {
|
||||
|
||||
private ResourceLoader resources;
|
||||
|
||||
@Autowired
|
||||
public FilesService(ResourceLoader resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit un fichier dans le dossier resources.
|
||||
*
|
||||
* @param path Le chemin vers la fichier (sans classpath:, depuis le dossier resources)
|
||||
* @return Le contenu du fichier
|
||||
*/
|
||||
public String readResource(String path) {
|
||||
String fullPath = String.format("classpath:%s", path);
|
||||
try (InputStream stream = resources.getResource(fullPath).getInputStream()) {
|
||||
return readInputStreamAsString(stream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit un InputStream et le transforme en String
|
||||
*
|
||||
* @param input L'InputStream
|
||||
* @return Le InputStream transformé en String
|
||||
* @throws IOException La transformation vers un String a échoué
|
||||
*/
|
||||
public String readInputStreamAsString(InputStream input) throws IOException {
|
||||
byte[] data = FileCopyUtils.copyToByteArray(input);
|
||||
return new String(data, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le contenu d'un fichier dans un tableau de Byte.
|
||||
*
|
||||
* @param path Le chemin vers le fichier
|
||||
* @return Le contenu du fichier dans un tableau de Byte
|
||||
* @throws IOException La lecture du fichier a échoué
|
||||
*/
|
||||
public byte[] readAsBytes(String path) throws IOException {
|
||||
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<String> readAsStrings(String path) throws IOException {
|
||||
return Files.readAllLines(Paths.get(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Écrit un fichier Multipart sur le disque.
|
||||
*
|
||||
* @param multipartFile Le fichier à écrire
|
||||
* @param path Le chemin vers le fichier
|
||||
* @return Si le fichier a bien été créé
|
||||
*/
|
||||
public boolean write(MultipartFile multipartFile, String path) {
|
||||
if (multipartFile.getSize() <= 0) return true;
|
||||
|
||||
try {
|
||||
File file = create(path);
|
||||
multipartFile.transferTo(file.toPath());
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
Preferences.logger.error("Impossible d'écrire un fichier Multipart: " + ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un fichier sur le disque.
|
||||
*
|
||||
* @param path Le chemin vers le fichier
|
||||
* @return Le fichier créé
|
||||
* @throws IOException La création du fichier échoue
|
||||
*/
|
||||
public File create(String path) throws IOException {
|
||||
File file = getFile(path);
|
||||
|
||||
try {
|
||||
if (!file.exists() || file.isDirectory()) {
|
||||
Files.createDirectories(file.getParentFile().toPath());
|
||||
Files.createFile(file.toPath());
|
||||
}
|
||||
|
||||
return file;
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Impossible de créer un fichier: ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un fichier sur le disque.
|
||||
*
|
||||
* @param path Le chemin vers le fichier
|
||||
*/
|
||||
public void delete(String path) {
|
||||
File file = getFile(path);
|
||||
|
||||
try {
|
||||
if (file.exists() && !file.isDirectory()) Files.delete(file.toPath());
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Impossible de supprimer un fichier: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un fichier existe sur le disque.
|
||||
*
|
||||
* @param path Le chemin vers le fichier
|
||||
* @return Si le fichier existe
|
||||
*/
|
||||
public boolean exists(String path) {
|
||||
File file = getFile(path);
|
||||
|
||||
return file.exists() && !file.isDirectory();
|
||||
}
|
||||
|
||||
public File getFile(String path) {
|
||||
return new File(path);
|
||||
}
|
||||
|
||||
public String getPath(String fileName) {
|
||||
return String.format("%s/%s", Preferences.uploadDirectory, fileName);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files;
|
||||
|
||||
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 {
|
||||
|
||||
private static final String IMAGES_DIRECTORY = "images";
|
||||
|
||||
private FilesService filesService;
|
||||
|
||||
@Autowired
|
||||
public ImagesService(FilesService filesService) {
|
||||
this.filesService = filesService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit une image.
|
||||
*
|
||||
* @param name Le nom de l'image
|
||||
* @return Le contenu de l'image
|
||||
*/
|
||||
public byte[] read(String name) {
|
||||
try {
|
||||
return filesService.readAsBytes(getPath(name));
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Erreur lors de la lecture d'une image: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Écrit des données image sur le disque.
|
||||
*
|
||||
* @param image Le contenu du fichier
|
||||
* @param name Le nom de l'image
|
||||
* @return Si l'écriture du fichier s'est achevée
|
||||
*/
|
||||
public boolean write(MultipartFile image, String name) {
|
||||
return filesService.write(image, getPath(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un fichier image.
|
||||
*
|
||||
* @param name Le nom de l'image
|
||||
*/
|
||||
public void delete(String name) {
|
||||
filesService.delete(getPath(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un InputStream contient une image.
|
||||
*
|
||||
* @param input L'InputStream
|
||||
* @return Si l'InputStream contient une image
|
||||
*/
|
||||
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 filesService.getPath(String.format("%s/%s", IMAGES_DIRECTORY, name));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files;
|
||||
|
||||
import org.commonmark.node.Node;
|
||||
import org.commonmark.parser.Parser;
|
||||
import org.commonmark.renderer.html.HtmlRenderer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MarkdownFilesService {
|
||||
|
||||
private FilesService filesService;
|
||||
|
||||
@Autowired
|
||||
public MarkdownFilesService(FilesService filesService) {
|
||||
this.filesService = filesService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit et fait le rendu en HTML d'un fichier MarkDown.
|
||||
*
|
||||
* @param path Le chemin vers la fichier (sans classpath:, depuis le dossier resources)
|
||||
* @return Le MarkDown rendu en HTML
|
||||
*/
|
||||
public String render(String path) {
|
||||
String fileContent = filesService.readResource(path);
|
||||
|
||||
Parser parser = Parser.builder().build();
|
||||
Node document = parser.parse(fileContent);
|
||||
HtmlRenderer renderer = HtmlRenderer.builder().build();
|
||||
|
||||
return renderer.render(document);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Service
|
||||
public class SimdutService {
|
||||
|
||||
private static final String SIMDUT_DIRECTORY = "simdut";
|
||||
|
||||
private FilesService filesService;
|
||||
private MaterialJavaService materialService;
|
||||
|
||||
@Autowired
|
||||
public SimdutService(FilesService filesService) {
|
||||
this.filesService = filesService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
public void setMaterialService(MaterialJavaService materialService) {
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un produit a un fichier SIMDUT.
|
||||
*
|
||||
* @param material Le produit
|
||||
* @return Si le produit a un fichier SIMDUT
|
||||
*/
|
||||
public boolean exists(Material material) {
|
||||
return filesService.exists(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 exists(Long id) {
|
||||
return exists(materialService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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[] read(Material material) {
|
||||
String path = getPath(material);
|
||||
|
||||
if (!filesService.exists(path)) return new byte[0];
|
||||
|
||||
try {
|
||||
return filesService.readAsBytes(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[] read(Long id) {
|
||||
return read(materialService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Écrit le fichier SIMDUT d'un produit.
|
||||
*
|
||||
* @param material Le produit
|
||||
* @param simdut Le contenu du fichier SIMDUT à écrire
|
||||
*/
|
||||
public void write(Material material, MultipartFile simdut) {
|
||||
if (!filesService.write(simdut, getPath(material))) throw new SimdutException(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour le fichier SIMDUT d'un produit
|
||||
*
|
||||
* @param simdut Le contenu du fichier SIMDUT mis à jour
|
||||
* @param material Le produit du SIMDUT
|
||||
*/
|
||||
public void update(MultipartFile simdut, Material material) {
|
||||
delete(material);
|
||||
write(material, simdut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime le fichier SIMDUT pour un produit.
|
||||
*
|
||||
* @param material Le produit
|
||||
*/
|
||||
public void delete(Material material) {
|
||||
filesService.delete(getPath(material));
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le chemin vers le fichier SIMDUT d'un produit.
|
||||
*
|
||||
* @param material Le produit
|
||||
* @return Le chemin vers le fichier SIMDUT du produit
|
||||
*/
|
||||
private String getPath(Material material) {
|
||||
return filesService.getPath(String.format("%s/%s", SIMDUT_DIRECTORY, getSimdutFileName(material)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nom du fichier SIMDUT d'un produit.
|
||||
*
|
||||
* @param material Le produit
|
||||
* @return Le nom du fichier SIMDUT du produit
|
||||
*/
|
||||
public String getSimdutFileName(Material material) {
|
||||
return String.valueOf(material.getId());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.RecipeService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -16,11 +16,13 @@ import java.util.zip.ZipOutputStream;
|
|||
@Service
|
||||
public class XlsService {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
private RecipeService recipeService;
|
||||
private Logger logger;
|
||||
|
||||
@Autowired
|
||||
public XlsService(RecipeJavaService recipeService) {
|
||||
public XlsService(RecipeService recipeService, Logger logger) {
|
||||
this.recipeService = recipeService;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +32,7 @@ public class XlsService {
|
|||
* @return Le fichier XLS de la recette
|
||||
*/
|
||||
public byte[] generate(Recipe recipe) {
|
||||
return new XlsxExporter().generate(recipe);
|
||||
return new XlsxExporter(logger).generate(recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +51,7 @@ public class XlsService {
|
|||
* @return Le fichier ZIP contenant tous les fichiers XLS
|
||||
*/
|
||||
public byte[] generateForAll() throws IOException {
|
||||
Preferences.logger.info("Exportation de toutes les couleurs en XLS");
|
||||
logger.info("Exportation de toutes les couleurs en XLS");
|
||||
|
||||
byte[] zipContent;
|
||||
Collection<Recipe> recipes = recipeService.getAll();
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.CompanyRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Service
|
||||
public class CompanyJavaService extends AbstractJavaService<Company, CompanyRepository> {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
|
||||
public CompanyJavaService() {
|
||||
super(Company.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setCompanyDao(CompanyRepository companyRepository) {
|
||||
this.repository = companyRepository;
|
||||
}
|
||||
|
||||
// Pour éviter les dépendances circulaires
|
||||
@Autowired
|
||||
@Lazy
|
||||
public void setRecipeService(RecipeJavaService recipeService) {
|
||||
this.recipeService = recipeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une bannière correspondant à un nom existe.
|
||||
*
|
||||
* @param name Le nom de la bannière
|
||||
* @return Si une bannière correspondant au nome existe
|
||||
*/
|
||||
public boolean existsByName(String name) {
|
||||
return repository.existsByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une bannière est liée à une recette.
|
||||
*
|
||||
* @param company La bannière
|
||||
* @return Si la bannière est liée à une recette
|
||||
*/
|
||||
public boolean isLinkedToRecipes(Company company) {
|
||||
return recipeService.existsByCompany(company);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Company save(@NotNull Company entity) {
|
||||
if (existsByName(entity.getName()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, entity.getName());
|
||||
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Company entity) {
|
||||
if (isLinkedToRecipes(entity)) throw new EntityLinkedException(type);
|
||||
|
||||
super.delete(entity);
|
||||
}
|
||||
|
||||
@Deprecated(since = "1.3.0", forRemoval = true)
|
||||
public void deleteIfNotLinked(Company company) {
|
||||
if (!isLinkedToRecipes(company)) delete(company);
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialSaveDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialUpdateDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaNamedService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.SimdutService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MaterialJavaService extends AbstractJavaNamedService<Material, MaterialRepository> {
|
||||
|
||||
private MixMaterialJavaService mixQuantityService;
|
||||
private SimdutService simdutService;
|
||||
|
||||
public MaterialJavaService() {
|
||||
super(Material.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialDao(MaterialRepository materialRepository) {
|
||||
this.repository = materialRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixQuantityService(MixMaterialJavaService mixQuantityService) {
|
||||
this.mixQuantityService = mixQuantityService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setSimdutService(SimdutService simdutService) {
|
||||
this.simdutService = simdutService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si des produits sont d'un type de produit
|
||||
*
|
||||
* @param materialType Le type de produit
|
||||
* @return Si des produits sont du type de produit
|
||||
*/
|
||||
public boolean existsByMaterialType(MaterialType materialType) {
|
||||
return repository.existsByMaterialType(materialType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un produit est lié à un ou plusieurs mélanges.
|
||||
*
|
||||
* @param material Le produit à vérifier.
|
||||
* @return Si le produit est lié à d'autres mélanges.
|
||||
*/
|
||||
public boolean isLinkedToMixes(Material material) {
|
||||
return mixQuantityService.existsByMaterial(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère tous les produits qui ne sont pas des types de mélange.
|
||||
*
|
||||
* @return Tous les produits qui ne sont pas des types de mélange
|
||||
*/
|
||||
@NotNull
|
||||
public List<Material> getAllNotMixType() {
|
||||
return getAll()
|
||||
.stream()
|
||||
.filter(m -> !m.isMixType())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Material save(MaterialSaveDto material) {
|
||||
if (existsByName(material.getName()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, material.getName());
|
||||
Material saved = save(material.toMaterial());
|
||||
if (material.getSimdutFile() != null && !material.getSimdutFile().isEmpty())
|
||||
simdutService.write(saved, material.getSimdutFile());
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material update(Material material) {
|
||||
Optional<Material> materialByName = findOptional(repository.findByName(material.getName()));
|
||||
if (materialByName.isPresent() && !Objects.equals(material.getId(), materialByName.get().getId()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, material.getName());
|
||||
|
||||
return super.update(material);
|
||||
}
|
||||
|
||||
public Material update(MaterialUpdateDto material) {
|
||||
simdutService.update(material.getSimdutFile(), material.toMaterial());
|
||||
return update(material.toMaterial());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Material material) {
|
||||
simdutService.delete(material);
|
||||
|
||||
super.delete(material);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteDefaultMaterialTypeException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotEditDefaultMaterialTypeException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MaterialTypeEditorDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialTypeRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeKt;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MaterialTypeJavaService extends AbstractJavaService<MaterialType, MaterialTypeRepository> {
|
||||
|
||||
private MaterialJavaService materialService;
|
||||
|
||||
private List<MaterialType> defaultMaterialTypes = new LinkedList<>();
|
||||
|
||||
public MaterialTypeJavaService() {
|
||||
super(MaterialType.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialTypeDao(MaterialTypeRepository materialTypeRepository) {
|
||||
this.repository = materialTypeRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialService(MaterialJavaService materialService) {
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
public void setDefaultMaterialTypes(List<MaterialType> defaultMaterialTypes) {
|
||||
this.defaultMaterialTypes = defaultMaterialTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute un type de produit dans les types de produit par défaut.
|
||||
*
|
||||
* @param materialType Le type de produit
|
||||
*/
|
||||
public void addDefault(MaterialType materialType) {
|
||||
defaultMaterialTypes.add(materialType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un type de produit est un type de produit par défaut.
|
||||
*
|
||||
* @param materialType Le type de produit
|
||||
* @return Si le type de produite est un type de produit par défaut
|
||||
*/
|
||||
public boolean isDefault(MaterialType materialType) {
|
||||
return defaultMaterialTypes.contains(materialType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un type de produit correspondant à un nom existe.
|
||||
*
|
||||
* @param name Le nom à vérifier
|
||||
* @return Si un type de produit ayant le nom existe
|
||||
*/
|
||||
public boolean existsByName(String name) {
|
||||
return repository.existsByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un type de produit correspondant à un préfixe existe.
|
||||
*
|
||||
* @param prefix Le préfixe à vérifier
|
||||
* @return Si un type de produit ayant le préfixe existe
|
||||
*/
|
||||
public boolean existsByPrefix(String prefix) {
|
||||
return repository.existsByPrefix(prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un type de produit est utilisé par des produits.
|
||||
*
|
||||
* @param materialType Le type de produit
|
||||
* @return si le type de produit est utilisé par des produits.
|
||||
*/
|
||||
public boolean isLinkedToMaterials(MaterialType materialType) {
|
||||
return materialService.existsByMaterialType(materialType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère tous les type de produits qui ne sont pas des types de produit.
|
||||
*
|
||||
* @return Tous les type de produits qui ne sont pas des types de produit
|
||||
*/
|
||||
public List<MaterialType> getAllNotDefault() {
|
||||
return getAll().stream()
|
||||
.filter(t -> !isDefault(t))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère un type de produit par son nom.
|
||||
*
|
||||
* @param name Le nom du type de produit à récupérer
|
||||
* @return Le type de produit correspondant au nom.
|
||||
*/
|
||||
public MaterialType getByName(String name) {
|
||||
Optional<MaterialType> found = findOptional(repository.findByName(name));
|
||||
if (found.isEmpty())
|
||||
throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name);
|
||||
|
||||
return found.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialType save(@NotNull MaterialType materialType) {
|
||||
if (existsByName(materialType.getName()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, materialType.getName());
|
||||
if (existsByPrefix(materialType.getPrefix()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MaterialTypeKt.IDENTIFIER_PREFIX_NAME, materialType.getPrefix());
|
||||
|
||||
return super.save(materialType);
|
||||
}
|
||||
|
||||
public MaterialType update(MaterialTypeEditorDto materialTypeDto) {
|
||||
MaterialType materialType = materialTypeDto.getMaterialType();
|
||||
|
||||
if (isDefault(materialTypeDto.getOldMaterialType()))
|
||||
throw new CannotEditDefaultMaterialTypeException(materialTypeDto);
|
||||
if (!existsByName(materialTypeDto.getOldName()))
|
||||
throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, materialTypeDto.getOldName());
|
||||
if (!materialTypeDto.getOldName().equals(materialType.getName()) && existsByName(materialType.getName()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.NAME, materialType.getName());
|
||||
if (!materialTypeDto.getOldPrefix().equals(materialType.getPrefix()) && existsByPrefix(materialType.getPrefix()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MaterialTypeKt.IDENTIFIER_PREFIX_NAME, materialType.getPrefix());
|
||||
|
||||
return super.update(materialType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(MaterialType materialType) {
|
||||
if (isDefault(materialType)) throw new CannotDeleteDefaultMaterialTypeException(materialType);
|
||||
|
||||
super.delete(materialType);
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MixFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MixRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.utils.MixBuilder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MixJavaService extends AbstractJavaService<Mix, MixRepository> {
|
||||
|
||||
private MaterialJavaService materialService;
|
||||
private MixMaterialJavaService mixQuantityService;
|
||||
private MixTypeJavaService mixTypeService;
|
||||
|
||||
public MixJavaService() {
|
||||
super(Mix.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixDao(MixRepository mixRepository) {
|
||||
this.repository = mixRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialService(MaterialJavaService materialService) {
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixQuantityService(MixMaterialJavaService mixQuantityService) {
|
||||
this.mixQuantityService = mixQuantityService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixTypeService(MixTypeJavaService mixTypeService) {
|
||||
this.mixTypeService = mixTypeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les produits disponibles pour un mélange.
|
||||
* Le mélange peut ne pas exister.
|
||||
*
|
||||
* @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<Material> getAvailableMaterialsForMixId(Recipe recipe, Long mixId) {
|
||||
return existsById(mixId) ? getAvailableMaterialsForMix(getById(mixId)) : getAvailableMaterialsForNewMix(recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les produits disponibles pour un mélange existant.
|
||||
* `
|
||||
*
|
||||
* @param mix Le mélange
|
||||
* @return Les produits disponibles pour ce mélange
|
||||
*/
|
||||
public Collection<Material> getAvailableMaterialsForMix(Mix mix) {
|
||||
return getAvailableMaterialsForNewMix(mix.getRecipe())
|
||||
.stream()
|
||||
.filter(m -> !m.equals(mix.getMixType().getMaterial()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les produits disponibles pour un mélange inexistant.
|
||||
*
|
||||
* @param recipe La recette dans laquelle se trouve le mélange
|
||||
* @return Les produits disponibles pour le nouveau mélange
|
||||
*/
|
||||
public Collection<Material> getAvailableMaterialsForNewMix(Recipe recipe) {
|
||||
Collection<MixType> recipeMixTypes = recipe.getMixTypes();
|
||||
|
||||
return materialService
|
||||
.getAll()
|
||||
.stream()
|
||||
.filter(m -> !m.isMixType() || recipeMixTypes.contains(mixTypeService.getByMaterial(m)))
|
||||
.sorted(Comparator.comparing(Material::getName))
|
||||
.sorted(Comparator.comparing(m -> m.getMaterialType().getName()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void save(MixFormDto formDto) {
|
||||
Mix mix = new MixBuilder(mixTypeService, materialService)
|
||||
.withDto(formDto)
|
||||
.build();
|
||||
|
||||
if (mix.getRecipe().containsMixType(mix.getMixType()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MixKt.IDENTIFIER_MIX_TYPE_NAME, mix.getMixType().getName());
|
||||
|
||||
mixTypeService.save(mix.getMixType());
|
||||
save(mix);
|
||||
}
|
||||
|
||||
public void update(Mix mix, MixFormDto formDto) {
|
||||
mix = new MixBuilder(mixTypeService, materialService)
|
||||
.withMix(mix)
|
||||
.withDto(formDto)
|
||||
.build();
|
||||
|
||||
MixType mixType = mix.getMixType();
|
||||
|
||||
if (!formDto.getOldMixTypeName().equals(mixType.getName()) && mixTypeService.existsByName(formDto.getMixTypeName()) && mix.getRecipe().containsMixType(mixType))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MixKt.IDENTIFIER_MIX_TYPE_NAME, mix.getMixType().getName());
|
||||
|
||||
if (materialService.existsByName(mixType.getName()) && !materialService.getByName(mixType.getName()).isMixType())
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MixTypeKt.IDENTIFIER_MATERIAL_NAME, mixType.getName());
|
||||
|
||||
mixTypeService.update(mixType);
|
||||
update(mix);
|
||||
}
|
||||
|
||||
@Deprecated(since = "1.3.0", forRemoval = true)
|
||||
public void deleteMix(Mix mix) {
|
||||
mixQuantityService.deleteAll(mix.getMixMaterials());
|
||||
delete(mix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Mix mix) {
|
||||
mixQuantityService.deleteAll(mix.getMixMaterials());
|
||||
|
||||
super.delete(mix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id) {
|
||||
delete(getById(id));
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixMaterial;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MixMaterialRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MixMaterialJavaService extends AbstractJavaService<MixMaterial, MixMaterialRepository> {
|
||||
|
||||
public MixMaterialJavaService() {
|
||||
super(MixMaterial.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixQuantityDao(MixMaterialRepository mixMaterialRepository) {
|
||||
this.repository = mixMaterialRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie s'il y a un mélange qui contient un produit.
|
||||
*
|
||||
* @param material Le produit
|
||||
* @return S'il y a un mélange qui contient le produit
|
||||
*/
|
||||
public boolean existsByMaterial(Material material) {
|
||||
return repository.existsByMaterial(material);
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixTypeKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MixTypeRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class MixTypeJavaService extends AbstractJavaService<MixType, MixTypeRepository> {
|
||||
|
||||
private MaterialJavaService materialService;
|
||||
|
||||
public MixTypeJavaService() {
|
||||
super(MixType.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixTypeDao(MixTypeRepository mixTypeRepository) {
|
||||
this.repository = mixTypeRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMaterialService(MaterialJavaService materialService) {
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si un type de mélange correspondant à un nom existe.
|
||||
*
|
||||
* @param name Le nom du type de mélange
|
||||
* @return Si un type de mélange correspondant au nom existe
|
||||
*/
|
||||
public boolean existsByName(String name) {
|
||||
return repository.existsByName(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<MixType> found = findOptional(repository.findByName(name));
|
||||
if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name);
|
||||
|
||||
return found.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<MixType> found = findOptional(repository.findByMaterial(material));
|
||||
if (found.isEmpty())
|
||||
throw new EntityNotFoundException(type, ModelException.IdentifierType.OTHER, material);
|
||||
|
||||
return found.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un type de mélange.
|
||||
*
|
||||
* @param name Le nom du type de mélange
|
||||
* @param materialType Le type de produit du type de mélange
|
||||
* @return Le type de mélange créé
|
||||
*/
|
||||
public MixType create(String name, MaterialType materialType) {
|
||||
Material mixTypeMaterial = new Material(name, 0f, true, materialType);
|
||||
return new MixType(name, mixTypeMaterial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MixType save(@NotNull MixType entity) {
|
||||
if (materialService.existsByName(entity.getName()))
|
||||
throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MixTypeKt.IDENTIFIER_MATERIAL_NAME, entity.getName());
|
||||
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MixType update(MixType mixType) {
|
||||
|
||||
return super.update(mixType);
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Mix;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeEditorFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeExplorerFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.RecipeRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.ImagesService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RecipeJavaService extends AbstractJavaService<Recipe, RecipeRepository> {
|
||||
|
||||
private CompanyJavaService companyService;
|
||||
private MixJavaService mixService;
|
||||
private RecipeStepJavaService stepService;
|
||||
private ImagesService imagesService;
|
||||
|
||||
public RecipeJavaService() {
|
||||
super(Recipe.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRecipeDao(RecipeRepository recipeRepository) {
|
||||
this.repository = recipeRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setCompanyService(CompanyJavaService companyService) {
|
||||
this.companyService = companyService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMixService(MixJavaService mixService) {
|
||||
this.mixService = mixService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setStepService(RecipeStepJavaService stepService) {
|
||||
this.stepService = stepService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setImagesService(ImagesService imagesService) {
|
||||
this.imagesService = imagesService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie s'il y a une recette liée à une compagnie.
|
||||
*
|
||||
* @param company La compagnie
|
||||
* @return S'il y a une recette liée à la compagnie
|
||||
*/
|
||||
public boolean existsByCompany(Company company) {
|
||||
return repository.existsByCompany(company);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère toutes les recettes pour une compagnie.
|
||||
*
|
||||
* @param company La compagnie
|
||||
* @return Toutes les recettes pour la compagnie
|
||||
*/
|
||||
public Collection<Recipe> getAllByCompany(Company company) {
|
||||
return repository.findAllByCompany(company);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère toutes les recettes dans la base de données et les classes par compagnie.
|
||||
*
|
||||
* @return Un Map contenant les recettes classées par compagnie.
|
||||
*/
|
||||
public Map<Company, Collection<Recipe>> getAllMappedByCompany() {
|
||||
return companyService.getAll().stream()
|
||||
.collect(Collectors.toMap(c -> c, this::getAllByCompany));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.update(getById(recipeDto.getId()));
|
||||
|
||||
stepService.deleteAll(recipe.getSteps());
|
||||
recipe.setSteps(stepService.createAllForRecipe(recipe, recipeDto.getStep()));
|
||||
|
||||
return update(recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour les informations d'une recette trouvées dans l'explorateur de recette.
|
||||
*
|
||||
* @param form Le formulaire contenant les données mises à jour
|
||||
*/
|
||||
@Transactional
|
||||
public void updateRecipeExplorerInfos(RecipeExplorerFormDto form) {
|
||||
long recipeId = form.getRecipeId();
|
||||
Map<Long, String> locations = form.getLocations();
|
||||
String note = form.getNote();
|
||||
|
||||
Recipe recipe = getById(recipeId);
|
||||
|
||||
// Note
|
||||
recipe.setNote(note);
|
||||
update(recipe);
|
||||
|
||||
// Casiers
|
||||
for (Map.Entry<Long, String> location : locations.entrySet()) {
|
||||
Mix mix = mixService.getById(location.getKey());
|
||||
mix.setLocation(location.getValue());
|
||||
mixService.update(mix);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Recipe recipe) {
|
||||
super.delete(recipe);
|
||||
removeAllFiles(recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nom des images liées à une recette.
|
||||
*
|
||||
* @param recipe La recette dont on veut récupérer les images
|
||||
* @return Une liste contenant le nom des images liées à la recette.
|
||||
*/
|
||||
public List<String> getImageFiles(Recipe recipe) {
|
||||
String imageName = getImageFileName(recipe);
|
||||
File[] allImages = imagesService.getDirectoryFile().listFiles((d, n) -> n.startsWith(imageName));
|
||||
|
||||
if (allImages == null) return new ArrayList<>();
|
||||
return Arrays.stream(allImages).map(File::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère l'index de la prochaine image pour une recette.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @return L'index de la prochaine image pour la recette
|
||||
*/
|
||||
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 + "-", "").replace(".jpeg", ""))).collect(Collectors.toList());
|
||||
return indexes.size() > 0 ? Collections.max(indexes) + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nom des fichiers image d'une recette.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @return Le nom des fichiers image de la recette
|
||||
*/
|
||||
public String getImageFileName(Recipe recipe) {
|
||||
return recipe.getId().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nom du fichier image d'une recette avec le prochain index disponible.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @return Le nom du fichier image de la recette avec le prochain index disponible
|
||||
*/
|
||||
public String getImageFileNameWithIndex(Recipe recipe) {
|
||||
return getImageFileNameWithIndex(recipe, getNextImageIndex(recipe));
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nom du fichier image d'une recette avec un index.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @param index L'index du fichier image
|
||||
* @return Le nom du fichier image de la recette avec l'index
|
||||
*/
|
||||
public String getImageFileNameWithIndex(Recipe recipe, int index) {
|
||||
return String.format("%s-%s", getImageFileName(recipe), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime tous les fichiers image d'une recette.
|
||||
*
|
||||
* @param recipe La recette
|
||||
*/
|
||||
private void removeAllFiles(Recipe recipe) {
|
||||
getImageFiles(recipe).forEach(f -> imagesService.delete(f));
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.model;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.RecipeStep;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.RecipeStepRepository;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RecipeStepJavaService extends AbstractJavaService<RecipeStep, RecipeStepRepository> {
|
||||
|
||||
public RecipeStepJavaService() {
|
||||
super(RecipeStep.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setStepDao(RecipeStepRepository recipeStepRepository) {
|
||||
this.repository = recipeStepRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une étape pour une recette.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @param message Le message de l'étape à créer
|
||||
*/
|
||||
public RecipeStep createForRecipe(Recipe recipe, String message) {
|
||||
return new RecipeStep(recipe, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée toutes les étapes pour une recette.
|
||||
*
|
||||
* @param recipe La recette
|
||||
* @param messages Tous les messages des étapes à créer
|
||||
*/
|
||||
@Transactional
|
||||
public List<RecipeStep> createAllForRecipe(Recipe recipe, List<String> messages) {
|
||||
return messages.stream().map(m -> createForRecipe(recipe, m)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.utils;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class ControllerUtils {
|
||||
|
||||
private static final String HTTP_SCHEME = "http";
|
||||
private static final String HTTPS_SCHEME = "https";
|
||||
|
||||
public static String redirect(String viewName) {
|
||||
return String.format("redirect:/%s", viewName);
|
||||
}
|
||||
|
||||
public static URI getUri(HttpServletRequest request) throws URISyntaxException {
|
||||
return new URI(request.getRequestURL().toString());
|
||||
}
|
||||
|
||||
public static String getUrlFromURI(URI uri) {
|
||||
String host = uri.getHost();
|
||||
int port = uri.getPort();
|
||||
String scheme = getScheme();
|
||||
|
||||
return String.format("%s://%s:%s", scheme, host, port);
|
||||
}
|
||||
|
||||
public static String getCurrentBaseUrl() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null) return "";
|
||||
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
String port = ":" + (Preferences.urlUsePort ? request.getServerPort() : "");
|
||||
return String.format("%s://%s%s%s", getScheme(), request.getServerName(), port, request.getContextPath());
|
||||
}
|
||||
|
||||
public static String getLatestUrl() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null) return "";
|
||||
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
try {
|
||||
String currentDomainName = getUrlFromURI(getUri(request));
|
||||
String referer = request.getHeader("referer");
|
||||
if (referer == null) return currentDomainName;
|
||||
|
||||
String refererURL = getUrlFromURI(new URI(referer));
|
||||
|
||||
return refererURL.equals(currentDomainName) ? referer : currentDomainName;
|
||||
} catch (URISyntaxException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String getScheme() {
|
||||
return Preferences.urlUseHttps ? HTTPS_SCHEME : HTTP_SCHEME;
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.utils;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MixFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MixTypeJavaService;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MixBuilder {
|
||||
|
||||
private MixTypeJavaService mixTypeService;
|
||||
private MaterialJavaService materialService;
|
||||
|
||||
private Long id;
|
||||
private Recipe recipe;
|
||||
private MixType mixType;
|
||||
private String location;
|
||||
private Collection<MixMaterial> mixMaterials = new ArrayList<>();
|
||||
|
||||
private Map<String, Float> quantities = new LinkedHashMap<>();
|
||||
|
||||
public MixBuilder(MixTypeJavaService mixTypeService, MaterialJavaService materialService) {
|
||||
this.mixTypeService = mixTypeService;
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
public MixBuilder withMix(Mix mix) {
|
||||
this.id = mix.getId();
|
||||
this.recipe = mix.getRecipe();
|
||||
this.mixType = mix.getMixType();
|
||||
this.location = mix.getLocation();
|
||||
this.mixMaterials = mix.getMixMaterials();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withDto(MixFormDto dto) {
|
||||
String mixTypeName = dto.getMixTypeName();
|
||||
|
||||
if (this.mixType == null) {
|
||||
this.mixType = mixTypeService.create(mixTypeName, dto.getMaterialType());
|
||||
} else {
|
||||
this.mixType = new MixType(this.mixType.getId(), this.mixType.getName(), this.mixType.getMaterial());
|
||||
|
||||
if (materialService.existsByName(mixTypeName)) {
|
||||
this.mixType.setName(mixTypeName);
|
||||
this.mixType.setMaterial(materialService.getByName(mixTypeName));
|
||||
} else {
|
||||
this.mixType.setName(mixTypeName);
|
||||
this.mixType.getMaterial().setName(mixTypeName);
|
||||
}
|
||||
|
||||
this.mixType.getMaterial().setMaterialType(dto.getMaterialType());
|
||||
}
|
||||
|
||||
this.recipe = dto.getRecipe();
|
||||
|
||||
for (int i = 0; i < dto.getMaterials().size(); i++)
|
||||
quantities.put(dto.getMaterials().get(i), dto.getQuantities().get(i));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withId(Long id) {
|
||||
this.id = id;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withRecipe(Recipe recipe) {
|
||||
this.recipe = recipe;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withMixType(MixType mixType) {
|
||||
this.mixType = mixType;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withMixQuantity(MixMaterial mixMaterial) {
|
||||
this.mixMaterials.add(mixMaterial);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MixBuilder withMixQuantities(List<MixMaterial> mixQuantities) {
|
||||
this.mixMaterials = mixQuantities;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Mix build() {
|
||||
Mix mix = new Mix(this.id, this.location, this.recipe, this.mixType, new ArrayList<>());
|
||||
|
||||
createMixQuantities(mix);
|
||||
mix.getMixMaterials().addAll(this.mixMaterials);
|
||||
|
||||
return mix;
|
||||
}
|
||||
|
||||
private void createMixQuantities(Mix mix) {
|
||||
List<MixMaterial> mixQuantities = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Float> quantityEntry : quantities.entrySet()) {
|
||||
Material material = materialService.getByName(quantityEntry.getKey());
|
||||
Float quantity = quantityEntry.getValue();
|
||||
|
||||
mixQuantities.add(new MixMaterial(mix, material, quantity));
|
||||
}
|
||||
|
||||
this.mixMaterials = mixQuantities;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.utils;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -17,6 +14,8 @@ import java.util.Collection;
|
|||
|
||||
public class PdfBuilder {
|
||||
|
||||
private static final String PATH_FONT_ARIAL_BOLD = "classpath:fonts/arialbd.ttf";
|
||||
|
||||
private PDFont font;
|
||||
private PDDocument document = new PDDocument();
|
||||
private PDPage page = new PDPage();
|
||||
|
@ -33,7 +32,7 @@ public class PdfBuilder {
|
|||
this.lineSpacing = (int) (this.fontSize * 1.5f);
|
||||
|
||||
document.addPage(page);
|
||||
font = PDType0Font.load(document, resourceLoader.getResource(WebsitePaths.FONT_ARIAL_BOLD).getInputStream());
|
||||
font = PDType0Font.load(document, resourceLoader.getResource(PATH_FONT_ARIAL_BOLD).getInputStream());
|
||||
}
|
||||
|
||||
public PdfBuilder addLine(String text, boolean bold, int marginTop) {
|
||||
|
@ -88,14 +87,44 @@ public class PdfBuilder {
|
|||
contentStream.newLineAtOffset(-textX, -textY); // Réinitialise la position pour la prochaine ligne
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class PdfLine {
|
||||
|
||||
private String text;
|
||||
private boolean bold;
|
||||
private int marginTop;
|
||||
|
||||
public PdfLine() {
|
||||
}
|
||||
|
||||
public PdfLine(String text, boolean bold, int marginTop) {
|
||||
this.text = text;
|
||||
this.bold = bold;
|
||||
this.marginTop = marginTop;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public boolean isBold() {
|
||||
return bold;
|
||||
}
|
||||
|
||||
public void setBold(boolean bold) {
|
||||
this.bold = bold;
|
||||
}
|
||||
|
||||
public int getMarginTop() {
|
||||
return marginTop;
|
||||
}
|
||||
|
||||
public void setMarginTop(int marginTop) {
|
||||
this.marginTop = marginTop;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web;
|
||||
|
||||
public class StringBank {
|
||||
|
||||
// Types de réponse
|
||||
public static final String RESPONSE_ERROR = "error";
|
||||
public static final String RESPONSE_SUCCESS = "success";
|
||||
public static final String RESPONSE_REASON = "reason";
|
||||
|
||||
// Types d'attributs communs
|
||||
public static final String MATERIALS = "materials";
|
||||
public static final String MATERIAL = "material";
|
||||
public static final String MATERIAL_ID = "materialID";
|
||||
public static final String MATERIAL_CODE = "materialCode";
|
||||
public static final String MATERIAL_TYPES = "materialTypes";
|
||||
public static final String MATERIAL_TYPE = "materialType";
|
||||
public static final String RECIPES = "recipes";
|
||||
public static final String RECIPE = "recipe";
|
||||
public static final String RECIPE_ID = "recipeId";
|
||||
public static final String RECIPE_CODE = "recipeCode";
|
||||
public static final String MIXES = "mixes";
|
||||
public static final String MIX = "mix";
|
||||
public static final String MIX_ID = "mixID";
|
||||
public static final String MIX_TYPE = "mixType";
|
||||
public static final String MIX_TYPES = "mixTypes";
|
||||
public static final String COMPANIES = "companies";
|
||||
public static final String COMPANY = "company";
|
||||
public static final String COMPANY_ID = "companyID";
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web;
|
||||
|
||||
public class WebsitePaths {
|
||||
// Autres
|
||||
public static final String INDEX = "index";
|
||||
public static final String SIMDUT_FILES = "simdut/{id}";
|
||||
public static final String PASSWORD_VALIDATION = "password/valid";
|
||||
public static final String RECIPE_XLS = "recipe/xls/{id}";
|
||||
public static final String ALL_RECIPES_XLS = "recipe/xls";
|
||||
public static final String ERROR = "error";
|
||||
public static final String CLOSE_TAB = "closeTab";
|
||||
public static final String UPDATES = "updates";
|
||||
public static final String UPDATES_GET = "updates/get";
|
||||
public static final String FONT_ARIAL_BOLD = "classpath:fonts/arialbd.ttf";
|
||||
|
||||
// Images
|
||||
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/{image}";
|
||||
|
||||
// Touch up kits
|
||||
public static final String TOUCHUP = "touchup";
|
||||
public static final String TOUCHUP_PDF = "touchup/pdf";
|
||||
public static final String TOUCHUP_PTOUCH = "touchup/ptouch";
|
||||
public static final String TOUCHUP_PTOUCH_PAGE = "touchupPtouch";
|
||||
|
||||
// Inventaire
|
||||
public static final String INVENTORY = "inventory";
|
||||
public static final String USE_INVENTORY = "inventory/use";
|
||||
|
||||
// Recettes
|
||||
public static final String EXPLORER_RECIPE = "recipe/explore";
|
||||
public static final String EXPLORER_RECIPE_SPECIFIC = "recipe/explore/{id}";
|
||||
public static final String CREATOR_RECIPE = "recipe/creator";
|
||||
public static final String EDITOR_RECIPE = "recipe/editor";
|
||||
public static final String EDITOR_RECIPE_SPECIFIC = "recipe/editor/{id}";
|
||||
public static final String EDITOR_RECIPE_EDITOR = "recipe/edit";
|
||||
public static final String REMOVER_RECIPE = "recipe/remover";
|
||||
public static final String REMOVER_RECIPE_SPECIFIC = "recipe/remover/{id}";
|
||||
|
||||
// Compagnies
|
||||
public static final String CREATOR_COMPANY = "company/creator";
|
||||
public static final String REMOVER_COMPANY = "company/remover";
|
||||
public static final String REMOVER_COMPANY_SPECIFIC = "company/remover/{id}";
|
||||
|
||||
// Matériaux
|
||||
public static final String CREATOR_MATERIAL = "material/creator";
|
||||
public static final String EDIT_MATERIAL_SIMDUT = "material/simdut";
|
||||
public static final String EDIT_MATERIAL_SIMDUT_SPECIFIC = "material/simdut/{id}";
|
||||
public static final String REMOVER_MATERIAL = "material/remover";
|
||||
public static final String REMOVER_MATERIAL_SPECIFIC = "material/remover/{id}";
|
||||
public static final String EDITOR_MATERIAL = "material/editor";
|
||||
public static final String EDITOR_MATERIAL_SPECIFIC = "material/editor/{id}";
|
||||
public static final String EDITOR_MATERIAL_EDITOR = "material/edit";
|
||||
|
||||
// Types de matériaux
|
||||
public static final String CREATOR_MATERIAL_TYPE = "materialType/creator";
|
||||
public static final String REMOVER_MATERIAL_TYPE = "materialType/remover";
|
||||
public static final String REMOVER_MATERIAL_TYPE_SPECIFIC = "materialType/remover/{id}";
|
||||
public static final String EDITOR_MATERIAL_TYPE = "materialType/editor";
|
||||
public static final String EDITOR_MATERIAL_TYPE_SPECIFIC = "materialType/editor/{id}";
|
||||
public static final String EDITOR_MATERIAL_TYPE_EDITOR = "materialType/edit";
|
||||
|
||||
// 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";
|
||||
public static final String EDITOR_MIX_SPECIFIC = "mix/editor/{id}";
|
||||
public static final String REMOVER_MIX_SPECIFIC = "mix/remover/{id}";
|
||||
public static final String MATERIAL_SELECTOR_MIX = "mix/selector/{recipeId}/{mixId}";
|
||||
public static final String MATERIAL_SELECTOR_FRAGMENT = "mix/selector.html :: materialSelector";
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.angular
|
||||
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
|
||||
@Controller
|
||||
@Profile("angular")
|
||||
class AngularController {
|
||||
@GetMapping("/explore")
|
||||
fun frontend(): String {
|
||||
return "forward:/"
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import org.springframework.boot.web.servlet.error.ErrorController;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.ERROR;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class CREErrorController implements ErrorController {
|
||||
|
||||
@RequestMapping("/error")
|
||||
public ModelAndView handleError(HttpServletRequest request) {
|
||||
ModelResponseBuilder responseBuilder = new ModelResponseBuilder("error");
|
||||
responseBuilder.addAttribute("referer", request.getHeader("referer"));
|
||||
|
||||
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
|
||||
|
||||
ResponseCode responseCode = ResponseCode._500;
|
||||
if (status != null) {
|
||||
int statusCode = Integer.parseInt(status.toString());
|
||||
|
||||
switch (statusCode) {
|
||||
case 401:
|
||||
responseCode = ResponseCode._401;
|
||||
break;
|
||||
case 404:
|
||||
responseCode = ResponseCode._404;
|
||||
break;
|
||||
default:
|
||||
responseCode = ResponseCode._500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
responseBuilder.addResponseCode(responseCode);
|
||||
return responseBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorPath() {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode
|
||||
import dev.fyloz.trial.colorrecipesexplorer.utils.ControllerUtils
|
||||
import org.springframework.web.servlet.ModelAndView
|
||||
|
||||
fun modelAndView(model: ModelAndView = ModelAndView(), op: ModelAndView.() -> Unit = {}) = model.apply {
|
||||
addObject("baseUrl", ControllerUtils.getCurrentBaseUrl())
|
||||
addObject("referer", ControllerUtils.getLatestUrl())
|
||||
apply(op)
|
||||
}
|
||||
|
||||
fun modelAndView(viewName: String, op: ModelAndView.() -> Unit = {}) = modelAndView(ModelAndView(viewName), op)
|
||||
|
||||
fun ModelAndView.message(responseCode: ResponseCode, vararg parameters: Any?) {
|
||||
addObject(if (responseCode.type == ResponseCode.ResponseCodeType.ERROR) "error" else "success", "response.${responseCode.code}")
|
||||
parameters.forEachIndexed { index, param ->
|
||||
addObject("responseArg${index + 1}", param)
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.PasswordService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.PASSWORD_VALIDATION;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class IndexController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
|
||||
@Autowired
|
||||
public IndexController(RecipeJavaService recipeService) {
|
||||
this.recipeService = recipeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche la page d'acceuil.
|
||||
*
|
||||
* @return La page à afficher.
|
||||
*/
|
||||
@GetMapping({INDEX, "/"})
|
||||
public ModelAndView getPage() {
|
||||
return new ModelResponseBuilder(INDEX)
|
||||
.addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getAllMappedByCompany())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Valide un mot de passe reçu dans une requête HTTP POST, dans le champ "password".
|
||||
*
|
||||
* @param data Corps de la requête HTTP
|
||||
* @return Si le mot de passe est valide.
|
||||
*/
|
||||
@PostMapping(value = PASSWORD_VALIDATION, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public boolean validatePassword(@RequestBody Map<String, Object> data) {
|
||||
return PasswordService.isValid((String) data.get("password"));
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.TooLowQuantityException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.JSONResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.InventoryDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.InventoryService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.RESPONSE_REASON;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INVENTORY;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.USE_INVENTORY;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class InventoryController {
|
||||
|
||||
private InventoryService inventoryService;
|
||||
private MaterialJavaService materialService;
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public InventoryController(InventoryService inventoryService, MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) {
|
||||
this.inventoryService = inventoryService;
|
||||
this.materialService = materialService;
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(INVENTORY)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(INVENTORY)
|
||||
.addResponseData(ResponseDataType.MATERIALS, materialService.getAllNotMixType())
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = USE_INVENTORY, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@Transactional
|
||||
public Map<String, Object> consumeMaterials(@RequestBody List<InventoryDto> mixes) {
|
||||
JSONResponseBuilder jsonResponseBuilder = new JSONResponseBuilder();
|
||||
|
||||
try {
|
||||
inventoryService.use(mixes);
|
||||
|
||||
jsonResponseBuilder.addResponseCode(ResponseCode.SUCCESS_USING_MATERIALS);
|
||||
} catch (TooLowQuantityException ex) {
|
||||
jsonResponseBuilder.addResponseCode(ResponseCode.NOT_ENOUGH_MATERIAL, ex.getMaterial().getName())
|
||||
.addAttribute(RESPONSE_REASON, ex.getResponse());
|
||||
}
|
||||
|
||||
return jsonResponseBuilder.build();
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.MarkdownFilesService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MixJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.ResponseBody;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.MATERIALS;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class OthersController {
|
||||
|
||||
private MixJavaService mixService;
|
||||
private RecipeJavaService recipeService;
|
||||
private MarkdownFilesService markdownService;
|
||||
|
||||
@Autowired
|
||||
public OthersController(MixJavaService mixService, RecipeJavaService recipeService, MarkdownFilesService markdownService) {
|
||||
this.mixService = mixService;
|
||||
this.recipeService = recipeService;
|
||||
this.markdownService = markdownService;
|
||||
}
|
||||
|
||||
@GetMapping(CLOSE_TAB)
|
||||
public ModelAndView getCloseTab() {
|
||||
return new ModelResponseBuilder(CLOSE_TAB).build();
|
||||
}
|
||||
|
||||
@GetMapping(MATERIAL_SELECTOR_MIX)
|
||||
public ModelAndView getMaterialSelectorFragment(@PathVariable Long recipeId, @PathVariable Long mixId) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(MATERIAL_SELECTOR_FRAGMENT);
|
||||
|
||||
try {
|
||||
modelResponseBuilder.addAttribute(MATERIALS, mixService.getAvailableMaterialsForMixId(recipeService.getById(recipeId), mixId));
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeId);
|
||||
}
|
||||
|
||||
return modelResponseBuilder.build();
|
||||
}
|
||||
|
||||
@GetMapping(value = UPDATES)
|
||||
public ModelAndView getUpdatesPage() {
|
||||
return new ModelResponseBuilder(UPDATES).build();
|
||||
}
|
||||
|
||||
@GetMapping(value = UPDATES_GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<String> getUpdates() {
|
||||
return new ResponseEntity<>(markdownService.render("updates.md"), HttpStatus.OK);
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.JSONResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeExplorerFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class RecipeExplorerController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
|
||||
@Autowired
|
||||
public RecipeExplorerController(RecipeJavaService recipeService) {
|
||||
this.recipeService = recipeService;
|
||||
}
|
||||
|
||||
@GetMapping(EXPLORER_RECIPE_SPECIFIC)
|
||||
public ModelAndView getPage(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(EXPLORER_RECIPE);
|
||||
|
||||
try {
|
||||
Recipe recipe = recipeService.getById(id);
|
||||
|
||||
return modelResponseBuilder
|
||||
.addResponseData(ResponseDataType.RECIPE, recipe)
|
||||
.addResponseData(ResponseDataType.MIXES, recipe.getMixesSortedById())
|
||||
.addResponseData(ResponseDataType.IMAGES, recipeService.getImageFiles(recipe))
|
||||
.build();
|
||||
} catch (EntityNotFoundException e) {
|
||||
return modelResponseBuilder
|
||||
.withView(INDEX)
|
||||
.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = EXPLORER_RECIPE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public Map<String, Object> saveRecipeInformations(@RequestBody RecipeExplorerFormDto form) {
|
||||
JSONResponseBuilder responseBuilder = new JSONResponseBuilder();
|
||||
|
||||
try {
|
||||
recipeService.updateRecipeExplorerInfos(form);
|
||||
|
||||
responseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_RECIPE_INFORMATIONS);
|
||||
} catch (EntityNotFoundException e) {
|
||||
responseBuilder.addResponseCode(
|
||||
e.getType().equals(Recipe.class) ?
|
||||
ResponseCode.RECIPE_NOT_FOUND :
|
||||
ResponseCode.MIX_NOT_FOUND,
|
||||
e.getRequestedId()
|
||||
);
|
||||
}
|
||||
|
||||
return responseBuilder.build();
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_COMPANY;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class CompanyCreatorController {
|
||||
|
||||
private CompanyJavaService companyService;
|
||||
|
||||
@Autowired
|
||||
public CompanyCreatorController(CompanyJavaService companyService) {
|
||||
this.companyService = companyService;
|
||||
}
|
||||
|
||||
@GetMapping(CREATOR_COMPANY)
|
||||
public ModelAndView getPage(ModelAndView model, Company company) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(CREATOR_COMPANY)
|
||||
.addResponseData(ResponseDataType.COMPANY, company)
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = CREATOR_COMPANY, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public ModelAndView createCompany(@ModelAttribute @Valid Company company) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
company = companyService.save(company);
|
||||
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_COMPANY, company.getName());
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_ALREADY_EXIST, company.getName());
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build(), company);
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
//package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators;
|
||||
//
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.services.model.MaterialService;
|
||||
//import dev.fyloz.trial.colorrecipesexplorer.services.model.MaterialTypeService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.http.MediaType;
|
||||
//import org.springframework.lang.Nullable;
|
||||
//import org.springframework.stereotype.Controller;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.PostMapping;
|
||||
//import org.springframework.web.multipart.MultipartFile;
|
||||
//import org.springframework.web.servlet.ModelAndView;
|
||||
//
|
||||
//import javax.validation.Valid;
|
||||
//
|
||||
//import java.util.Optional;
|
||||
//
|
||||
//import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_MATERIAL;
|
||||
//
|
||||
//@Controller
|
||||
//public class MaterialCreatorController {
|
||||
//
|
||||
// private MaterialService materialService;
|
||||
// private MaterialTypeService materialTypeService;
|
||||
//
|
||||
// @Autowired
|
||||
// public MaterialCreatorController(MaterialService materialService, MaterialTypeService materialTypeService) {
|
||||
// this.materialService = materialService;
|
||||
// this.materialTypeService = materialTypeService;
|
||||
// }
|
||||
//
|
||||
// @GetMapping(CREATOR_MATERIAL)
|
||||
// public ModelAndView getPage(ModelAndView model, Material material) {
|
||||
// return new ModelResponseBuilder(model)
|
||||
// .withView(CREATOR_MATERIAL)
|
||||
//// .addResponseData(ResponseDataType.MATERIAL, material)
|
||||
//// .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
|
||||
// .build();
|
||||
// }
|
||||
//
|
||||
// @PostMapping(value = CREATOR_MATERIAL, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
// public ModelAndView createMaterial(@Valid Material material, MultipartFile simdut) {
|
||||
// ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
//
|
||||
// try {
|
||||
// materialService.save(material, simdut);
|
||||
// return getPage(
|
||||
// modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL, material.getName()).build(),
|
||||
// new Material()
|
||||
// );
|
||||
// } catch (EntityAlreadyExistsException ex) {
|
||||
// modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_ALREADY_EXIST, material.getName());
|
||||
// } catch (SimdutException ex) {
|
||||
// modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL, material.getName());
|
||||
// modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_SIMDUT);
|
||||
// }
|
||||
//
|
||||
// return getPage(modelResponseBuilder.build(), material);
|
||||
// }
|
||||
//}
|
|
@ -1,49 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialSaveDto
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_MATERIAL
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.message
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.modelAndView
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import org.springframework.web.servlet.ModelAndView
|
||||
import javax.validation.Valid
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
class MaterialCreatorController(val materialService: MaterialJavaService, val materialTypeService: MaterialTypeJavaService) {
|
||||
@GetMapping(CREATOR_MATERIAL)
|
||||
fun getPage(model: ModelAndView, @RequestParam(required = false) material: Material? = null): ModelAndView {
|
||||
return modelAndView(model) {
|
||||
viewName = CREATOR_MATERIAL
|
||||
addObject("material", material ?: Material())
|
||||
addObject("materialTypes", materialTypeService.all)
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = [CREATOR_MATERIAL], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||
fun createMaterial(@Valid material: Material, simdut: MultipartFile): ModelAndView {
|
||||
return getPage(modelAndView {
|
||||
try {
|
||||
materialService.save(MaterialSaveDto(material.name, material.inventoryQuantity, material.materialType!!, simdut))
|
||||
message(ResponseCode.SUCCESS_SAVING_MATERIAL, material.name)
|
||||
} catch (ex: EntityAlreadyExistsException) {
|
||||
message(ResponseCode.MATERIAL_ALREADY_EXIST, material.name)
|
||||
} catch (ex: SimdutException) {
|
||||
message(ResponseCode.SUCCESS_SAVING_MATERIAL, material.name)
|
||||
message(ResponseCode.ERROR_SAVING_SIMDUT)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.utils.ControllerUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_MATERIAL_TYPE;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MaterialTypeCreatorController {
|
||||
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public MaterialTypeCreatorController(MaterialTypeJavaService materialTypeService) {
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(CREATOR_MATERIAL_TYPE)
|
||||
public ModelAndView getPage(ModelAndView model, MaterialType materialType) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(CREATOR_MATERIAL_TYPE)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPE, materialType == null ? new MaterialType() : materialType)
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(CREATOR_MATERIAL_TYPE)
|
||||
public ModelAndView createMaterialType(@Valid MaterialType materialType) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(ControllerUtils.redirect(INDEX));
|
||||
|
||||
try {
|
||||
materialTypeService.save(materialType);
|
||||
return getPage(
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, materialType.getName()).build(),
|
||||
null
|
||||
);
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
if (ex.getIdentifierType() == ModelException.IdentifierType.NAME) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialType.getName());
|
||||
} else {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST_PREFIX, materialType.getPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build(), materialType);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixTypeKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MixFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.ServiceKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MixCreatorController {
|
||||
|
||||
private MixJavaService mixService;
|
||||
private RecipeJavaService recipeService;
|
||||
private MaterialJavaService materialService;
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public MixCreatorController(MixJavaService mixService, RecipeJavaService recipeService, MaterialJavaService materialService, MixTypeJavaService mixTypeService, MaterialTypeJavaService materialTypeService) {
|
||||
this.mixService = mixService;
|
||||
this.recipeService = recipeService;
|
||||
this.materialService = materialService;
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(CREATOR_MIX_SPECIFIC)
|
||||
public ModelAndView getPage(ModelAndView model, @PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model)
|
||||
.withView(CREATOR_MIX);
|
||||
|
||||
try {
|
||||
Recipe recipe = recipeService.getById(id);
|
||||
|
||||
modelResponseBuilder
|
||||
.addResponseData(ResponseDataType.RECIPE, recipe)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
|
||||
.addResponseData(ResponseDataType.MATERIALS_JSON, ServiceKt.asJson(mixService.getAvailableMaterialsForNewMix(recipe)));
|
||||
|
||||
if (materialService.getAll().isEmpty())
|
||||
modelResponseBuilder.addResponseData(ResponseDataType.BLOCK_BUTTON, true);
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder
|
||||
.withRedirect(EDITOR_RECIPE);
|
||||
}
|
||||
|
||||
return modelResponseBuilder.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = CREATOR_MIX, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public ModelAndView createMix(@ModelAttribute @Valid MixFormDto formDto) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
mixService.save(formDto);
|
||||
|
||||
return modelResponseBuilder
|
||||
.withRedirect(EDITOR_RECIPE_SPECIFIC, formDto.getRecipe().getId())
|
||||
.build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, ex.getRequestedId());
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
if (ex.getIdentifierName().equals(MixKt.IDENTIFIER_MIX_TYPE_NAME))
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MIX_TYPE_ALREADY_USED, ex.getRequestedId());
|
||||
else if (ex.getIdentifierName().equals(MixTypeKt.IDENTIFIER_MATERIAL_NAME))
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_AND_MIX_TYPE_CANNOT_HAVE_SAME_NAME);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build(), formDto.getRecipe().getId());
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.creators;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_RECIPE;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.EDITOR_RECIPE_SPECIFIC;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class RecipeCreatorController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
private CompanyJavaService companyService;
|
||||
|
||||
@Autowired
|
||||
public RecipeCreatorController(RecipeJavaService recipeService, CompanyJavaService companyService) {
|
||||
this.recipeService = recipeService;
|
||||
this.companyService = companyService;
|
||||
}
|
||||
|
||||
@GetMapping(CREATOR_RECIPE)
|
||||
public ModelAndView getPage(ModelAndView model, Recipe recipe) {
|
||||
ModelResponseBuilder responseBuilder = new ModelResponseBuilder(model)
|
||||
.withView(CREATOR_RECIPE)
|
||||
.addResponseData(ResponseDataType.COMPANIES, companyService.getAll())
|
||||
.addResponseData(ResponseDataType.RECIPE, recipe == null ? new Recipe() : recipe);
|
||||
|
||||
if (companyService.getAll().isEmpty()) {
|
||||
responseBuilder.addResponseCode(ResponseCode.NO_COMPANY)
|
||||
.addResponseData(ResponseDataType.BLOCK_BUTTON, true);
|
||||
}
|
||||
|
||||
return responseBuilder.build();
|
||||
}
|
||||
|
||||
@PostMapping(CREATOR_RECIPE)
|
||||
public ModelAndView createRecipe(@Valid Recipe recipe) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
long id = recipeService.save(recipe).getId();
|
||||
|
||||
return modelResponseBuilder.withRedirect(EDITOR_RECIPE_SPECIFIC, id).build();
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialUpdateDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
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.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MaterialEditorController {
|
||||
|
||||
private MaterialJavaService materialService;
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public MaterialEditorController(MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) {
|
||||
this.materialService = materialService;
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_MATERIAL)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(EDITOR_MATERIAL)
|
||||
.addResponseData(ResponseDataType.MATERIALS, materialService.getAllNotMixType())
|
||||
.build();
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_MATERIAL_SPECIFIC)
|
||||
public ModelAndView getEditPage(ModelAndView model, @PathVariable Long id, Material material) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_MATERIAL_EDITOR);
|
||||
|
||||
try {
|
||||
if (material.getName() == null) material = materialService.getById(id);
|
||||
return modelResponseBuilder
|
||||
.addResponseData(ResponseDataType.MATERIAL, material)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
|
||||
.build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, id);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build());
|
||||
}
|
||||
|
||||
@PostMapping(value = EDITOR_MATERIAL, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public ModelAndView updateMaterial(Material material) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
material = materialService.update(material);
|
||||
|
||||
return getPage(modelResponseBuilder
|
||||
.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL, material.getName())
|
||||
.build());
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, material.getId());
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_ALREADY_EXIST, material.getName());
|
||||
}
|
||||
|
||||
return getEditPage(modelResponseBuilder.build(), material.getId(), material);
|
||||
}
|
||||
|
||||
@GetMapping(value = EDIT_MATERIAL_SIMDUT_SPECIFIC)
|
||||
public ModelAndView getSimdutPage(ModelAndView model, @PathVariable Long id) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(EDIT_MATERIAL_SIMDUT)
|
||||
.addResponseData(ResponseDataType.MATERIAL_ID, id)
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = EDIT_MATERIAL_SIMDUT, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public ModelAndView updateSimdut(Long id, MultipartFile simdut) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_MATERIAL_SPECIFIC, id);
|
||||
|
||||
try {
|
||||
Material material = materialService.getById(id);
|
||||
materialService.update(new MaterialUpdateDto(material.getId(), material.getName(), material.getInventoryQuantity(), material.getMaterialType(), simdut));
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return getSimdutPage(
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, id).build(),
|
||||
id
|
||||
);
|
||||
} catch (SimdutException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_SIMDUT);
|
||||
}
|
||||
|
||||
return modelResponseBuilder.build();
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotEditDefaultMaterialTypeException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MaterialTypeEditorDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeKt;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MaterialTypeEditorController {
|
||||
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public MaterialTypeEditorController(MaterialTypeJavaService materialTypeService) {
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_MATERIAL_TYPE)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(EDITOR_MATERIAL_TYPE)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAllNotDefault())
|
||||
.build();
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_MATERIAL_TYPE_SPECIFIC)
|
||||
public ModelAndView getEditPage(ModelAndView model, @PathVariable Long id, MaterialTypeEditorDto materialTypeDto) {
|
||||
ModelResponseBuilder responseBuilder = new ModelResponseBuilder(model).withView(EDITOR_MATERIAL_TYPE_EDITOR);
|
||||
|
||||
try {
|
||||
if (materialTypeDto.getName() == null) materialTypeDto = new MaterialTypeEditorDto(materialTypeService.getById(id));
|
||||
|
||||
return responseBuilder
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPE_DTO, materialTypeDto)
|
||||
.build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return getPage(responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, id).build());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = EDITOR_MATERIAL_TYPE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public ModelAndView updateMaterialType(MaterialTypeEditorDto materialTypeDto) {
|
||||
ModelResponseBuilder responseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
materialTypeService.update(materialTypeDto);
|
||||
|
||||
return getPage(responseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, materialTypeDto.getMaterialType().getName()).build());
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return getPage(responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, materialTypeDto.getOldName()).build());
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
if (ModelException.IdentifierType.NAME.equals(ex.getIdentifierType()))
|
||||
responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialTypeDto.getMaterialType().getName());
|
||||
else if (MaterialTypeKt.IDENTIFIER_PREFIX_NAME.equals(ex.getIdentifierName()))
|
||||
responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST_PREFIX, materialTypeDto.getMaterialType().getPrefix());
|
||||
} catch(CannotEditDefaultMaterialTypeException ex) {
|
||||
responseBuilder.addResponseCode(ResponseCode.CANNOT_EDIT_DEFAULT_MATERIAL_TYPE);
|
||||
}
|
||||
|
||||
return getEditPage(responseBuilder.build(), materialTypeDto.getMaterialType().getId(), materialTypeDto);
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Mix;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixTypeKt;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MixFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MixJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MixEditorController {
|
||||
|
||||
private MixJavaService mixService;
|
||||
private MaterialJavaService materialService;
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
public MixEditorController(MixJavaService mixService, MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) {
|
||||
this.mixService = mixService;
|
||||
this.materialService = materialService;
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_MIX_SPECIFIC)
|
||||
public ModelAndView getPage(ModelAndView model, @PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_MIX);
|
||||
|
||||
try {
|
||||
Mix mix = mixService.getById(id);
|
||||
|
||||
return modelResponseBuilder
|
||||
.addResponseData(ResponseDataType.MIX, mix)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPE, mix.getMixType().getMaterial().getMaterialType())
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
|
||||
.addResponseData(ResponseDataType.MIX_JSON, mixService.asJson(mix))
|
||||
.addResponseData(ResponseDataType.MATERIALS_JSON, materialService.asJson(mixService.getAvailableMaterialsForMix(mix)))
|
||||
.build();
|
||||
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return modelResponseBuilder
|
||||
.withRedirect(EDITOR_RECIPE)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = EDITOR_MIX, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public ModelAndView updateMix(@ModelAttribute @Valid MixFormDto formDto, @RequestParam("mixId") Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_RECIPE_SPECIFIC, formDto.getRecipe().getId());
|
||||
|
||||
try {
|
||||
Mix mix = mixService.getById(id);
|
||||
|
||||
mixService.update(mix, formDto);
|
||||
|
||||
return modelResponseBuilder.build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, id).build();
|
||||
} catch (EntityAlreadyExistsException ex) {
|
||||
if (ex.getIdentifierName().equals(MixTypeKt.IDENTIFIER_MATERIAL_NAME))
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_AND_MIX_TYPE_CANNOT_HAVE_SAME_NAME);
|
||||
else if (ex.getIdentifierName().equals(MixKt.IDENTIFIER_MIX_TYPE_NAME))
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MIX_TYPE_ALREADY_USED, ex.getRequestedId());
|
||||
else throw new EntityAlreadyExistsException(ex);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build(), id);
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.editors;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.RecipeEditorFormDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyJavaService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class RecipeEditorController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
private CompanyJavaService companyService;
|
||||
|
||||
@Autowired
|
||||
public RecipeEditorController(RecipeJavaService recipeService, CompanyJavaService companyService) {
|
||||
this.recipeService = recipeService;
|
||||
this.companyService = companyService;
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_RECIPE)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(EDITOR_RECIPE)
|
||||
.addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getAllMappedByCompany())
|
||||
.build();
|
||||
}
|
||||
|
||||
@GetMapping(EDITOR_RECIPE_SPECIFIC)
|
||||
public ModelAndView getEditPage(ModelAndView model, @PathVariable Long id, Recipe recipe) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_RECIPE_EDITOR);
|
||||
|
||||
try {
|
||||
if (recipe.getName() == null) recipe = recipeService.getById(id);
|
||||
|
||||
modelResponseBuilder
|
||||
.addResponseData(ResponseDataType.RECIPE, recipe)
|
||||
.addResponseData(ResponseDataType.COMPANIES, companyService.getAll())
|
||||
.addResponseData(ResponseDataType.MIXES, recipe.getMixesSortedById())
|
||||
.addResponseData(ResponseDataType.IMAGES, recipeService.getImageFiles(recipe))
|
||||
.addResponseData(ResponseDataType.RECIPE_JSON, recipeService.asJson(recipe));
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return getPage(modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id).build());
|
||||
}
|
||||
|
||||
return modelResponseBuilder.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = EDITOR_RECIPE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@Transactional
|
||||
public ModelAndView updateRecipe(RecipeEditorFormDto recipeDto) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
recipeService.updateRecipeAndSteps(recipeDto);
|
||||
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_RECIPE, recipeDto.getRecipe().getName());
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeDto.getRecipe().getId()).build();
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build());
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.JSONResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.ImagesService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class ImageFilesController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
private ImagesService imagesService;
|
||||
|
||||
@Autowired
|
||||
public ImageFilesController(RecipeJavaService recipeService, ImagesService imagesService) {
|
||||
this.recipeService = recipeService;
|
||||
this.imagesService = imagesService;
|
||||
}
|
||||
|
||||
@GetMapping(IMAGES_FILES)
|
||||
public ResponseEntity<byte[]> getImage(@PathVariable String image) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.IMAGE_JPEG);
|
||||
return new ResponseEntity<>(imagesService.read(image), headers, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping(ADD_IMAGE_SPECIFIC)
|
||||
public ModelAndView getPage(ModelAndView model, @PathVariable Long id) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(ADD_IMAGE)
|
||||
.addResponseData(ResponseDataType.RECIPE_ID, id)
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(ADD_IMAGE)
|
||||
public ModelAndView addImage(Long id, MultipartFile image) throws IOException {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_RECIPE_SPECIFIC, id);
|
||||
|
||||
try {
|
||||
if (!imagesService.isImage(image.getInputStream())) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.FILE_NOT_IMAGE);
|
||||
} else {
|
||||
Recipe recipe = recipeService.getById(id);
|
||||
|
||||
if (imagesService.write(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);
|
||||
}
|
||||
|
||||
@GetMapping(value = DELETE_IMAGE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public Map<String, Object> deleteImage(@PathVariable String image) {
|
||||
imagesService.delete(image);
|
||||
|
||||
return new JSONResponseBuilder().build();
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.SimdutService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CLOSE_TAB;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.SIMDUT_FILES;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class SimdutFilesController {
|
||||
|
||||
private SimdutService simdutService;
|
||||
|
||||
@Autowired
|
||||
public SimdutFilesController(SimdutService simdutService) {
|
||||
this.simdutService = simdutService;
|
||||
}
|
||||
|
||||
@GetMapping(SIMDUT_FILES)
|
||||
public ResponseEntity<byte[]> getFile(HttpServletRequest request, @PathVariable Long id) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
try {
|
||||
if (simdutService.exists(id)) {
|
||||
byte[] simdutContent = simdutService.read(id);
|
||||
headers.setContentType(MediaType.APPLICATION_PDF);
|
||||
return new ResponseEntity<>(simdutContent, headers, HttpStatus.OK);
|
||||
} else {
|
||||
headers.add("Location", "/" + CLOSE_TAB);
|
||||
}
|
||||
} catch (EntityNotFoundException ex) {
|
||||
headers.add("Location", request.getHeader("referer"));
|
||||
}
|
||||
|
||||
return new ResponseEntity<>(headers, HttpStatus.FOUND);
|
||||
}
|
||||
|
||||
@PostMapping(SIMDUT_FILES)
|
||||
public ResponseEntity<Void> getFile(@PathVariable Long id) {
|
||||
try {
|
||||
return ResponseEntity.status(simdutService.exists(id) ? HttpStatus.OK : HttpStatus.NOT_FOUND).build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.TouchUpKitService;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class TouchUpKitController {
|
||||
|
||||
private TouchUpKitService touchUpKitService;
|
||||
private RecipeJavaService recipeService;
|
||||
|
||||
@Autowired
|
||||
public TouchUpKitController(TouchUpKitService touchUpKitService, RecipeJavaService recipeService) {
|
||||
this.touchUpKitService = touchUpKitService;
|
||||
this.recipeService = recipeService;
|
||||
}
|
||||
|
||||
@GetMapping(TOUCHUP)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(TOUCHUP)
|
||||
.addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getAllMappedByCompany())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(value = TOUCHUP_PDF, produces = MediaType.APPLICATION_PDF_VALUE)
|
||||
public ResponseEntity<byte[]> getTouchUpKitPdf(String jobNumber) {
|
||||
return new ResponseEntity<>(touchUpKitService.generatePdfForJobNumber(jobNumber), HttpStatus.FOUND);
|
||||
}
|
||||
|
||||
@PostMapping(value = TOUCHUP_PTOUCH)
|
||||
public ModelAndView getTouchUpKitPtouch(String jobNumber) {
|
||||
return new ModelResponseBuilder(TOUCHUP_PTOUCH_PAGE)
|
||||
.addAttribute("jobNumber", jobNumber)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.files;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.XlsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.ALL_RECIPES_XLS;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.RECIPE_XLS;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class XlsExporterController {
|
||||
|
||||
private XlsService xlsService;
|
||||
|
||||
@Autowired
|
||||
public XlsExporterController(XlsService xlsService) {
|
||||
this.xlsService = xlsService;
|
||||
}
|
||||
|
||||
@GetMapping(RECIPE_XLS)
|
||||
public ResponseEntity<byte[]> getXlsForRecipe(HttpServletRequest request, @PathVariable Long id) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
try {
|
||||
byte[] xlsContent = xlsService.generate(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);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = ALL_RECIPES_XLS, produces = "application/zip")
|
||||
public ResponseEntity<byte[]> getAllXls() throws IOException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
byte[] allXlsContent = xlsService.generateForAll();
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentLength(allXlsContent.length)
|
||||
.contentType(MediaType.parseMediaType("application/zip"))
|
||||
.body(allXlsContent);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.CompanyJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_COMPANY;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_COMPANY_SPECIFIC;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class CompanyRemoverController {
|
||||
|
||||
private CompanyJavaService companyService;
|
||||
|
||||
@Autowired
|
||||
public CompanyRemoverController(CompanyJavaService companyService) {
|
||||
this.companyService = companyService;
|
||||
}
|
||||
|
||||
@GetMapping(REMOVER_COMPANY)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(REMOVER_COMPANY)
|
||||
.addResponseData(ResponseDataType.COMPANIES, companyService.getAll())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(REMOVER_COMPANY_SPECIFIC)
|
||||
public ModelAndView removeCompany(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder("");
|
||||
|
||||
try {
|
||||
Company company = companyService.getById(id);
|
||||
companyService.delete(company);
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_COMPANY, company.getName());
|
||||
} catch (EntityLinkedException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_LINKED, companyService.getById(id).getName());
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_NOT_FOUND, id);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build());
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_SPECIFIC;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MaterialRemoverController {
|
||||
|
||||
private MaterialJavaService materialService;
|
||||
|
||||
@Autowired
|
||||
public MaterialRemoverController(MaterialJavaService materialService) {
|
||||
this.materialService = materialService;
|
||||
}
|
||||
|
||||
@GetMapping(REMOVER_MATERIAL)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(REMOVER_MATERIAL)
|
||||
.addResponseData(ResponseDataType.MATERIALS, materialService.getAll().stream().filter(m -> !m.isMixType()).collect(Collectors.toList()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(REMOVER_MATERIAL_SPECIFIC)
|
||||
public ModelAndView removeMaterial(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
Material material = materialService.getById(id);
|
||||
materialService.delete(material);
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL, material.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(modelResponseBuilder.build());
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteDefaultMaterialTypeException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityLinkedException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_TYPE;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_TYPE_SPECIFIC;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MaterialTypeRemoverController {
|
||||
|
||||
private MaterialTypeJavaService materialTypeService;
|
||||
|
||||
@Autowired
|
||||
|
||||
public MaterialTypeRemoverController(MaterialTypeJavaService materialTypeService) {
|
||||
this.materialTypeService = materialTypeService;
|
||||
}
|
||||
|
||||
@GetMapping(REMOVER_MATERIAL_TYPE)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(REMOVER_MATERIAL_TYPE)
|
||||
.addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAllNotDefault())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(REMOVER_MATERIAL_TYPE_SPECIFIC)
|
||||
public ModelAndView removeMaterialType(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
MaterialType materialType = materialTypeService.getById(id);
|
||||
materialTypeService.delete(materialType);
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL_TYPE, materialType.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);
|
||||
} catch (CannotDeleteDefaultMaterialTypeException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.CANNOT_REMOVE_DEFAULT_MATERIAL_TYPE);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build());
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Mix;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.MixJavaService;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class MixRemoverController {
|
||||
|
||||
private MixJavaService mixService;
|
||||
|
||||
public MixRemoverController(MixJavaService mixService) {
|
||||
this.mixService = mixService;
|
||||
}
|
||||
|
||||
@GetMapping(REMOVER_MIX_SPECIFIC)
|
||||
public ModelAndView removeMix(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
Mix mix = mixService.getById(id);
|
||||
mixService.delete(mix);
|
||||
return modelResponseBuilder
|
||||
.withRedirect(EDITOR_RECIPE_SPECIFIC, mix.getRecipe().getId())
|
||||
.build();
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, id);
|
||||
}
|
||||
|
||||
return modelResponseBuilder
|
||||
.withRedirect(EDITOR_MIX_SPECIFIC, id)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf.removers;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
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.servlet.ModelAndView;
|
||||
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_RECIPE;
|
||||
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_RECIPE_SPECIFIC;
|
||||
|
||||
@Controller
|
||||
@Profile("thymeleaf")
|
||||
public class RecipeRemoverController {
|
||||
|
||||
private RecipeJavaService recipeService;
|
||||
|
||||
public RecipeRemoverController(RecipeJavaService recipeService) {
|
||||
this.recipeService = recipeService;
|
||||
}
|
||||
|
||||
@GetMapping(REMOVER_RECIPE)
|
||||
public ModelAndView getPage(ModelAndView model) {
|
||||
return new ModelResponseBuilder(model)
|
||||
.withView(REMOVER_RECIPE)
|
||||
.addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getAllMappedByCompany())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostMapping(REMOVER_RECIPE_SPECIFIC)
|
||||
public ModelAndView removeRecipe(@PathVariable Long id) {
|
||||
ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder();
|
||||
|
||||
try {
|
||||
Recipe recipe = recipeService.getById(id);
|
||||
recipeService.delete(recipe);
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_RECIPE, recipe.getName());
|
||||
} catch (EntityNotFoundException ex) {
|
||||
modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id);
|
||||
}
|
||||
|
||||
return getPage(modelResponseBuilder.build());
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.response;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class JSONResponseBuilder extends ResponseBuilder<JSONResponseBuilder, Map<String, Object>> {
|
||||
|
||||
@Override
|
||||
protected void addResponseCodeToAttribute(String responseCodeType, String responseMessagePath, String[] parameters) {
|
||||
Map<String, Object> attributeContent = new HashMap<>();
|
||||
|
||||
// Récupère le message depuis le fichier des messages de la bonne language et rajoute ces paramètres.
|
||||
String message = Preferences.messageSource.getMessage(responseMessagePath, parameters, LocaleContextHolder.getLocale());
|
||||
attributeContent.put("message", message);
|
||||
|
||||
addAttribute(responseCodeType, attributeContent);
|
||||
}
|
||||
|
||||
public Map<String, Object> build() {
|
||||
return attributes;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.response;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
public class ModelResponseBuilder extends ResponseBuilder<ModelResponseBuilder, ModelAndView> {
|
||||
|
||||
private static final String PATH_PARAMETER_PATTERN = "(\\{\\w+\\})";
|
||||
private static final String REDIRECT_PATH_PREFIX = "redirect:/";
|
||||
|
||||
private ModelAndView model;
|
||||
|
||||
public ModelResponseBuilder() {
|
||||
this.model = new ModelAndView();
|
||||
}
|
||||
|
||||
public ModelResponseBuilder(String view) {
|
||||
this(new ModelAndView(view));
|
||||
}
|
||||
|
||||
public ModelResponseBuilder(ModelAndView model) {
|
||||
this.model = model == null ? new ModelAndView() : model;
|
||||
}
|
||||
|
||||
public ModelResponseBuilder withView(String path) {
|
||||
model.setViewName(path);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelResponseBuilder withView(String path, Object... parameters) {
|
||||
path = replaceInPath(path, parameters);
|
||||
model.setViewName(path);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelResponseBuilder withRedirect(String path, Object... parameters) {
|
||||
return withView(REDIRECT_PATH_PREFIX + path, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addResponseCodeToAttribute(String responseCodeType, String responseMessagePath, String[] parameters) {
|
||||
addAttribute(responseCodeType, responseMessagePath);
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
addAttribute(String.format("responseArg%s", i + 1), parameters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelAndView build() {
|
||||
model.addAllObjects(attributes);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
private String replaceInPath(String path, Object... parameters) {
|
||||
for (Object parameter : parameters) {
|
||||
path = path.replaceFirst(PATH_PARAMETER_PATTERN, parameter.toString());
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.response;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.utils.ControllerUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ResponseBuilder<T extends ResponseBuilder, R> {
|
||||
|
||||
protected static final String RESPONSE_PREFIX = "response.";
|
||||
protected static final String ERROR_ATTRIBUTE_NAME = "error";
|
||||
protected static final String SUCCESS_ATTRIBUTE_NAME = "success";
|
||||
|
||||
protected Map<String, Object> attributes;
|
||||
|
||||
private boolean containsErrors = false;
|
||||
|
||||
public ResponseBuilder() {
|
||||
attributes = new HashMap<>();
|
||||
|
||||
// Ajoute l'URL de base à toutes les réponses
|
||||
attributes.put("baseUrl", ControllerUtils.getCurrentBaseUrl());
|
||||
attributes.put("referer", ControllerUtils.getLatestUrl());
|
||||
}
|
||||
|
||||
protected abstract void addResponseCodeToAttribute(String responseCodeType, String responseMessagePath, String[] parameters);
|
||||
|
||||
protected abstract R build();
|
||||
|
||||
public T addResponseCode(ResponseCode responseCode, Object... parameters) {
|
||||
String[] parametersAsStr = new String[parameters.length];
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parametersAsStr[i] = parameters[i].toString();
|
||||
}
|
||||
|
||||
return addResponseCode(responseCode, parametersAsStr);
|
||||
}
|
||||
|
||||
public T addResponseCode(ResponseCode responseCode, String... parameters) {
|
||||
int requiredParametersNumber = responseCode.getParametersNumber();
|
||||
int givenParametersNumber = parameters.length;
|
||||
|
||||
if (requiredParametersNumber != givenParametersNumber) {
|
||||
throw new IllegalArgumentException(String.format("Mauvais nombre de paramètre dans une réponse de modèle: %s requis, %s fournis", requiredParametersNumber, givenParametersNumber));
|
||||
}
|
||||
|
||||
// Ajoute les paramètres, si nécessaire
|
||||
if (requiredParametersNumber > 0) {
|
||||
// Avertit s'il y a plus de paramètres que le nombre de paramètres supporté par le template thymeleaf (aussi MAX_PARAMETERS_NUMBER)
|
||||
int maxParametersNumber = ResponseCode.MAX_PARAMETERS_NUMBER;
|
||||
if (givenParametersNumber > maxParametersNumber) {
|
||||
Preferences.logger.warn(String.format("Trop de paramètres fournis pour le code de réponse %s: %s maximum, %s fournis", responseCode.name(), maxParametersNumber, givenParametersNumber));
|
||||
}
|
||||
}
|
||||
|
||||
String responseCodeType;
|
||||
if (responseCode.getType() == ResponseCode.ResponseCodeType.ERROR) {
|
||||
containsErrors = true;
|
||||
responseCodeType = ERROR_ATTRIBUTE_NAME;
|
||||
} else {
|
||||
responseCodeType = SUCCESS_ATTRIBUTE_NAME;
|
||||
}
|
||||
|
||||
String responseMessagePath = RESPONSE_PREFIX + responseCode.getCode();
|
||||
addResponseCodeToAttribute(responseCodeType, responseMessagePath, parameters);
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T addResponseData(ResponseDataType responseDataType, Object data) {
|
||||
Class requiredDataTypeClass = responseDataType.getDataType();
|
||||
Class requiredListDataTypeClass = responseDataType.getListDataType();
|
||||
Class givenDataTypeClass = data.getClass();
|
||||
|
||||
// Vérifie le type de l'objet
|
||||
if (!requiredDataTypeClass.equals(givenDataTypeClass)) {
|
||||
throw new IllegalArgumentException(String.format("L'objet passé en paramètre n'est pas du bon type. Requis: %s, fournis: %s", requiredDataTypeClass.getName(), givenDataTypeClass.getName()));
|
||||
}
|
||||
|
||||
// Si l'objet est une liste, vérifie qu'elle n'est pas vide et qu'elle est du bon type
|
||||
if (requiredDataTypeClass.equals(List.class) && requiredListDataTypeClass != null) {
|
||||
List listData = (List) data;
|
||||
|
||||
if (listData.size() < 1) {
|
||||
throw new IllegalArgumentException("La liste passée en paramètre ne contient aucun élément");
|
||||
}
|
||||
|
||||
Class givenListDataTypeClass = listData.get(0).getClass();
|
||||
if (givenDataTypeClass.equals(requiredListDataTypeClass)) {
|
||||
throw new IllegalArgumentException(String.format("La liste passée en paramètre contient des éléments du mauvais type. Requis: %s, fournis: %s", requiredListDataTypeClass.getName(), givenListDataTypeClass.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
// Ajoute l'attribut dans le Map
|
||||
addAttribute(responseDataType.getDataTypeName(), data);
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T addAttribute(String attributeName, Object content) {
|
||||
attributes.put(attributeName, content);
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public boolean containsErrors() {
|
||||
return containsErrors;
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.response;
|
||||
|
||||
public enum ResponseCode {
|
||||
SUCCESS_USING_MATERIALS(1, ResponseCodeType.SUCCESS, 0),
|
||||
SUCCESS_SAVING_RECIPE_INFORMATIONS(2, ResponseCodeType.SUCCESS, 0),
|
||||
ERROR_SAVING(3, ResponseCodeType.ERROR, 0),
|
||||
ERROR_SAVING_IMAGE(4, ResponseCodeType.ERROR, 0),
|
||||
ERROR_SAVING_SIMDUT(5, ResponseCodeType.ERROR, 0),
|
||||
AUTH_ERROR(6, ResponseCodeType.ERROR, 0),
|
||||
RECIPE_NOT_FOUND(7, ResponseCodeType.ERROR, 1),
|
||||
MIX_NOT_FOUND(8, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_NOT_FOUND(9, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_ALREADY_EXIST(10, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_TYPE_ALREADY_EXIST(11, ResponseCodeType.ERROR, 1),
|
||||
COMPANY_NOT_FOUND(12, ResponseCodeType.ERROR, 1),
|
||||
COMPANY_ALREADY_EXIST(13, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_LINKED(14, ResponseCodeType.ERROR, 1),
|
||||
COMPANY_LINKED(15, ResponseCodeType.ERROR, 1),
|
||||
MIX_NOT_ASSOCIATED_WITH_RECIPE(16, ResponseCodeType.ERROR, 2),
|
||||
NOT_ENOUGH_MATERIAL(17, ResponseCodeType.ERROR, 1),
|
||||
MIX_TYPE_ALREADY_USED(18, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_TYPE_NOT_FOUND(19, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_TYPE_ALREADY_EXIST_PREFIX(20, ResponseCodeType.ERROR, 1),
|
||||
MATERIAL_TYPE_LINKED(21, ResponseCodeType.ERROR, 1),
|
||||
NO_COMPANY(22, ResponseCodeType.ERROR, 0),
|
||||
NO_MATERIAL(23, ResponseCodeType.ERROR, 0),
|
||||
FILE_NOT_IMAGE(24, ResponseCodeType.ERROR, 0),
|
||||
RECIPE_NOT_FOUND_NO_PARAMS(25, ResponseCodeType.ERROR, 0),
|
||||
MATERIAL_NOT_FOUND_BY_NAME(26, ResponseCodeType.ERROR, 1),
|
||||
SUCCESS_DELETING_COMPANY(27, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_SAVING_MATERIAL(28, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_SAVING_MATERIAL_TYPE(29, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_SAVING_RECIPE(30, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_DELETING_MATERIAL(31, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_SAVING_COMPANY(32, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_DELETING_RECIPE(33, ResponseCodeType.SUCCESS, 1),
|
||||
SUCCESS_DELETING_MATERIAL_TYPE(34, ResponseCodeType.SUCCESS, 1),
|
||||
RECIPE_ALREADY_EXIST(35, ResponseCodeType.ERROR, 1),
|
||||
CANNOT_REMOVE_DEFAULT_MATERIAL_TYPE(36, ResponseCodeType.ERROR, 0),
|
||||
CANNOT_EDIT_DEFAULT_MATERIAL_TYPE(37, ResponseCodeType.ERROR, 0),
|
||||
MATERIAL_AND_MIX_TYPE_CANNOT_HAVE_SAME_NAME(38, ResponseCodeType.ERROR, 0),
|
||||
|
||||
// HTTP Errors
|
||||
_500(100, ResponseCodeType.ERROR, 0),
|
||||
_404(101, ResponseCodeType.ERROR, 0),
|
||||
_401(102, ResponseCodeType.ERROR, 0),
|
||||
;
|
||||
|
||||
public static final int MAX_PARAMETERS_NUMBER = 2;
|
||||
|
||||
private int code;
|
||||
private ResponseCodeType type;
|
||||
private int parametersNumber;
|
||||
|
||||
ResponseCode(int code, ResponseCodeType type, int parametersNumber) {
|
||||
this.code = code;
|
||||
this.type = type;
|
||||
this.parametersNumber = parametersNumber;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public ResponseCodeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getParametersNumber() {
|
||||
return parametersNumber;
|
||||
}
|
||||
|
||||
public enum ResponseCodeType {
|
||||
ERROR,
|
||||
SUCCESS
|
||||
}
|
||||
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.web.response;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.MaterialTypeEditorDto;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum ResponseDataType {
|
||||
MATERIAL("material", Material.class),
|
||||
MATERIALS("materials", ArrayList.class, MATERIAL),
|
||||
MATERIAL_ID("materialId", Long.class),
|
||||
MATERIAL_CODE("materialCode", String.class),
|
||||
MATERIALS_JSON("materialsJson", String.class),
|
||||
|
||||
MATERIAL_TYPE("materialType", MaterialType.class),
|
||||
MATERIAL_TYPES("materialTypes", ArrayList.class, MATERIAL_TYPE),
|
||||
MATERIAL_TYPE_NAME("materialTypeName", String.class),
|
||||
MATERIAL_TYPE_DTO("materialTypeDto", MaterialTypeEditorDto.class),
|
||||
|
||||
RECIPE("recipe", Recipe.class),
|
||||
RECIPES("recipes", ArrayList.class, RECIPE),
|
||||
RECIPE_ID("recipeId", Long.class),
|
||||
RECIPE_CODE("recipeCode", String.class),
|
||||
RECIPE_MAP("recipeMap", HashMap.class),
|
||||
RECIPE_JSON("recipeJson", String.class),
|
||||
|
||||
RECIPE_STEP("recipeStep", RecipeStep.class),
|
||||
RECIPE_STEPS("recipeSteps", ArrayList.class, RECIPE_STEP),
|
||||
|
||||
MIX("mix", Mix.class),
|
||||
MIXES("mixes", ArrayList.class, MIX),
|
||||
MIX_ID("mixId", Long.class),
|
||||
MIX_JSON("mixJson", String.class),
|
||||
|
||||
MIX_TYPE("mixType", MixType.class),
|
||||
MIX_TYPES("mixTypes", ArrayList.class, MIX_TYPE),
|
||||
|
||||
MIX_QUANTITY("mixQuantity", MixMaterial.class),
|
||||
MIX_QUANTITIES("mixQuantities", ArrayList.class, MIX_QUANTITY),
|
||||
|
||||
COMPANY("company", Company.class),
|
||||
COMPANIES("companies", ArrayList.class, COMPANY),
|
||||
COMPANY_ID("companyId", Long.class),
|
||||
COMPANY_NAME("companyName", String.class),
|
||||
|
||||
IMAGE("image", String.class),
|
||||
IMAGES("images", ArrayList.class, IMAGE),
|
||||
|
||||
BLOCK_BUTTON("blockButton", boolean.class);
|
||||
|
||||
private String dataTypeName;
|
||||
private Class dataType;
|
||||
private Class listDataType;
|
||||
|
||||
ResponseDataType(String dataTypeName, Class dataType) {
|
||||
this(dataTypeName, dataType, null);
|
||||
}
|
||||
|
||||
ResponseDataType(String dataTypeName, Class dataType, ResponseDataType listDataType) {
|
||||
this.dataTypeName = dataTypeName;
|
||||
this.dataType = dataType;
|
||||
|
||||
if (listDataType != null) {
|
||||
this.listDataType = listDataType.getDataType();
|
||||
}
|
||||
}
|
||||
|
||||
public String getDataTypeName() {
|
||||
return dataTypeName;
|
||||
}
|
||||
|
||||
public Class getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public Class getListDataType() {
|
||||
return listDataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDataTypeName();
|
||||
}
|
||||
|
||||
public static ResponseDataType getModelDataTypeFromDataType(Class dataType) {
|
||||
return Stream.of(values()).filter(r -> r.getDataType().equals(dataType)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.xlsx;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Mix;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MixMaterial;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
|
||||
|
@ -14,17 +13,23 @@ import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.NoteCell;
|
|||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.SectionTitleCell;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.TitleCell;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.util.Position;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
public class XlsxExporter {
|
||||
private Logger logger;
|
||||
|
||||
public XlsxExporter(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public byte[] generate(Recipe recipe) {
|
||||
Preferences.logger.info(String.format("Génération du XLS de la couleur %s (%s)", recipe.getName(), recipe.getId()));
|
||||
logger.info(String.format("Génération du XLS de la couleur %s (%s)", recipe.getName(), recipe.getId()));
|
||||
|
||||
Document document = new Document(recipe.getName());
|
||||
Document document = new Document(recipe.getName(), logger);
|
||||
Sheet sheet = document.getSheet();
|
||||
registerCells(recipe, sheet);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.xlsx.component;
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.builder.SheetBuilder;
|
||||
import dev.fyloz.trial.colorrecipesexplorer.xlsx.exception.InvalidCellTypeException;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbookType;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Document extends XSSFWorkbook {
|
||||
|
||||
|
@ -12,9 +12,11 @@ public class Document extends XSSFWorkbook {
|
|||
private static final XSSFWorkbookType WORKBOOK_TYPE = XSSFWorkbookType.XLSX;
|
||||
|
||||
private Sheet sheet;
|
||||
private Logger logger;
|
||||
|
||||
public Document(String name) {
|
||||
public Document(String name, Logger logger) {
|
||||
super(WORKBOOK_TYPE);
|
||||
this.logger = logger;
|
||||
|
||||
sheet = new Sheet(this, createSheet(name));
|
||||
}
|
||||
|
@ -23,7 +25,7 @@ public class Document extends XSSFWorkbook {
|
|||
try {
|
||||
new SheetBuilder(sheet).build();
|
||||
} catch (InvalidCellTypeException e) {
|
||||
Preferences.logger.error("Une erreur est survenue lors de la génération du document: " + e.getLocalizedMessage());
|
||||
logger.error("Une erreur est survenue lors de la génération du document: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.CREProperties
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.CreProperties
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
|
||||
|
@ -8,7 +8,11 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication(exclude = [LiquibaseAutoConfiguration::class])
|
||||
@EnableConfigurationProperties(MaterialTypeProperties::class, CREProperties::class, DatabaseUpdaterProperties::class)
|
||||
@EnableConfigurationProperties(
|
||||
MaterialTypeProperties::class,
|
||||
CreProperties::class,
|
||||
DatabaseUpdaterProperties::class
|
||||
)
|
||||
class ColorRecipesExplorerApplication
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.MaterialTypeService
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent
|
||||
import org.springframework.context.ApplicationListener
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.core.Ordered
|
||||
import org.springframework.core.annotation.Order
|
||||
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
class InitialDataLoader(
|
||||
private val materialTypeService: MaterialTypeService,
|
||||
private val materialTypeProperties: MaterialTypeProperties
|
||||
) : ApplicationListener<ApplicationReadyEvent> {
|
||||
override fun onApplicationEvent(event: ApplicationReadyEvent) =
|
||||
materialTypeService.saveSystemTypes(materialTypeProperties.systemTypes)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
@Configuration
|
||||
class SpringConfiguration {
|
||||
@Bean
|
||||
fun logger(): Logger = LoggerFactory.getLogger(ColorRecipesExplorerApplication::class.java)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Employee
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.EmployeeLoginRequest
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.EmployeePermission
|
||||
|
@ -291,7 +291,7 @@ class JwtAuthorizationFilter(
|
|||
private fun getAuthenticationToken(employeeId: String): UsernamePasswordAuthenticationToken? = try {
|
||||
val employeeDetails = userDetailsService.loadUserByEmployeeId(employeeId.toLong(), false)
|
||||
UsernamePasswordAuthenticationToken(employeeDetails.username, null, employeeDetails.authorities)
|
||||
} catch (_: EntityNotFoundRestException) {
|
||||
} catch (_: EntityNotFoundException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.config.properties
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
|
||||
@ConfigurationProperties(prefix = "cre.server")
|
||||
class CreProperties {
|
||||
var workingDirectory: String = "data"
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model
|
||||
|
||||
class EntityAlreadyExistsException(
|
||||
modelType: Class<out Model>,
|
||||
val identifierType: IdentifierType,
|
||||
val identifierName: String?,
|
||||
val requestedId: Any
|
||||
) : ModelException(modelType) {
|
||||
constructor(modelType: Class<out Model>, identifierType: IdentifierType, requestedId: Any) : this(
|
||||
modelType,
|
||||
identifierType,
|
||||
identifierType.name,
|
||||
requestedId
|
||||
)
|
||||
|
||||
constructor(exception: EntityAlreadyExistsException) : this(
|
||||
exception.type,
|
||||
exception.identifierType,
|
||||
exception.identifierName,
|
||||
exception.requestedId
|
||||
)
|
||||
}
|
||||
|
||||
class EntityNotFoundException(
|
||||
modelType: Class<out Model>,
|
||||
val identifierType: IdentifierType,
|
||||
val requestedId: Any
|
||||
) : ModelException(modelType)
|
|
@ -1,8 +1,7 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.exception
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.HttpStatus
|
||||
|
@ -26,7 +25,7 @@ abstract class RestException(val exceptionMessage: String, val httpStatus: HttpS
|
|||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.CONFLICT)
|
||||
class EntityAlreadyExistsRestException(val value: Any) :
|
||||
class EntityAlreadyExistsException(val value: Any) :
|
||||
RestException("An entity with the given identifier already exists", HttpStatus.CONFLICT) {
|
||||
@Suppress("unused")
|
||||
override fun buildBody(): RestExceptionBody = object : RestExceptionBody() {
|
||||
|
@ -35,7 +34,7 @@ class EntityAlreadyExistsRestException(val value: Any) :
|
|||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
class EntityNotFoundRestException(val value: Any) :
|
||||
class EntityNotFoundException(val value: Any) :
|
||||
RestException("An entity could not be found with the given identifier", HttpStatus.NOT_FOUND) {
|
||||
@Suppress("unused")
|
||||
override fun buildBody(): RestExceptionBody = object : RestExceptionBody() {
|
||||
|
@ -44,7 +43,7 @@ class EntityNotFoundRestException(val value: Any) :
|
|||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.CONFLICT)
|
||||
class CannotDeleteEntityRestException(val value: Long) :
|
||||
class CannotDeleteEntityException(val value: Long) :
|
||||
RestException(
|
||||
"The entity with the given identifier could not be deleted because it is required by other entities",
|
||||
HttpStatus.CONFLICT
|
||||
|
@ -55,15 +54,22 @@ class CannotDeleteEntityRestException(val value: Long) :
|
|||
}
|
||||
}
|
||||
|
||||
@ResponseStatus
|
||||
class SimdutWriteException(val material: Material) :
|
||||
RestException(
|
||||
"Could not write the SIMDUT file to disk",
|
||||
HttpStatus.INTERNAL_SERVER_ERROR
|
||||
) {
|
||||
@Suppress("unused")
|
||||
override fun buildBody(): RestExceptionBody = object : RestExceptionBody() {
|
||||
val materialId = material.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ControllerAdvice
|
||||
@Profile("rest")
|
||||
class RestResponseEntityExceptionHandler : ResponseEntityExceptionHandler() {
|
||||
@ExceptionHandler(ModelException::class)
|
||||
fun handleModelExceptions(exception: ModelException, request: WebRequest): ResponseEntity<Any> {
|
||||
return handleRestExceptions(exception.toRestException(), request)
|
||||
}
|
||||
|
||||
@ExceptionHandler(RestException::class)
|
||||
fun handleRestExceptions(exception: RestException, request: WebRequest): ResponseEntity<Any> {
|
||||
return handleExceptionInternal(exception, exception.buildBody(), HttpHeaders(), exception.httpStatus, request)
|
||||
|
@ -84,11 +90,3 @@ class RestResponseEntityExceptionHandler : ResponseEntityExceptionHandler() {
|
|||
return ResponseEntity(errors, headers, status)
|
||||
}
|
||||
}
|
||||
|
||||
fun ModelException.toRestException(): RestException {
|
||||
return when (this) {
|
||||
is EntityAlreadyExistsException -> EntityAlreadyExistsRestException(requestedId)
|
||||
is EntityNotFoundException -> EntityNotFoundRestException(requestedId)
|
||||
else -> throw UnsupportedOperationException("Cannot convert ${this::class.simpleName} to REST exception")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@ package dev.fyloz.trial.colorrecipesexplorer.service
|
|||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.blacklistedJwtTokens
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.defaultGroupCookieName
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.validation.or
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.EmployeeGroupRepository
|
||||
|
@ -109,7 +108,7 @@ class EmployeeServiceImpl(employeeRepository: EmployeeRepository, val passwordEn
|
|||
|
||||
override fun getById(id: Long, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee =
|
||||
super.getById(id).apply {
|
||||
if (ignoreSystemUsers && isSystemUser || ignoreDefaultGroupUsers && isDefaultGroupUser) throw EntityNotFoundRestException(
|
||||
if (ignoreSystemUsers && isSystemUser || ignoreDefaultGroupUsers && isDefaultGroupUser) throw EntityNotFoundException(
|
||||
id
|
||||
)
|
||||
}
|
||||
|
@ -138,7 +137,7 @@ class EmployeeServiceImpl(employeeRepository: EmployeeRepository, val passwordEn
|
|||
|
||||
override fun save(entity: Employee): Employee {
|
||||
if (existsByFirstNameAndLastName(entity.firstName, entity.lastName))
|
||||
throw EntityAlreadyExistsRestException("${entity.firstName} ${entity.lastName}")
|
||||
throw EntityAlreadyExistsException("${entity.firstName} ${entity.lastName}")
|
||||
return super<AbstractExternalModelService>.save(entity)
|
||||
}
|
||||
|
||||
|
@ -188,7 +187,7 @@ class EmployeeServiceImpl(employeeRepository: EmployeeRepository, val passwordEn
|
|||
override fun update(entity: Employee, ignoreDefaultGroupUsers: Boolean, ignoreSystemUsers: Boolean): Employee {
|
||||
with(repository.findByFirstNameAndLastName(entity.firstName, entity.lastName)) {
|
||||
if (this != null && id != entity.id)
|
||||
throw EntityAlreadyExistsRestException("${entity.firstName} ${entity.lastName}")
|
||||
throw EntityAlreadyExistsException("${entity.firstName} ${entity.lastName}")
|
||||
}
|
||||
|
||||
return super<AbstractExternalModelService>.update(entity)
|
||||
|
@ -270,7 +269,7 @@ class EmployeeGroupServiceImpl(
|
|||
|
||||
override fun getRequestDefaultGroup(request: HttpServletRequest): EmployeeGroup {
|
||||
val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName)
|
||||
?: throw EntityNotFoundRestException("defaultGroup")
|
||||
?: throw EntityNotFoundException("defaultGroup")
|
||||
val defaultGroupUser = employeeService.getById(
|
||||
defaultGroupCookie.value.toLong(),
|
||||
ignoreDefaultGroupUsers = false,
|
||||
|
@ -327,7 +326,7 @@ class EmployeeUserDetailsServiceImpl(
|
|||
return loadUserByEmployeeId(username.toLong(), true)
|
||||
} catch (ex: EntityNotFoundException) {
|
||||
throw UsernameNotFoundException(username)
|
||||
} catch (ex: EntityNotFoundRestException) {
|
||||
} catch (ex: EntityNotFoundException) {
|
||||
throw UsernameNotFoundException(username)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Company
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.CompanySaveDto
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.CompanyUpdateDto
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.company
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.CompanyRepository
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.model.RecipeJavaService
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface CompanyService : ExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, CompanyRepository> {
|
||||
|
@ -15,7 +15,10 @@ interface CompanyService : ExternalNamedModelService<Company, CompanySaveDto, Co
|
|||
}
|
||||
|
||||
@Service
|
||||
class CompanyServiceImpl(companyRepository: CompanyRepository, val recipeService: RecipeJavaService) :
|
||||
class CompanyServiceImpl(
|
||||
companyRepository: CompanyRepository,
|
||||
@Lazy val recipeService: RecipeService
|
||||
) :
|
||||
AbstractExternalNamedModelService<Company, CompanySaveDto, CompanyUpdateDto, CompanyRepository>(companyRepository),
|
||||
CompanyService {
|
||||
override fun isLinkedToRecipes(company: Company): Boolean = recipeService.existsByCompany(company)
|
||||
|
@ -33,7 +36,7 @@ class CompanyServiceImpl(companyRepository: CompanyRepository, val recipeService
|
|||
}
|
||||
|
||||
override fun deleteById(id: Long) {
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityRestException(id)
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityException(id)
|
||||
super.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,6 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.TooLowQuantityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.dto.InventoryDto
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class InventoryService(val materialService: MaterialService) {
|
||||
/**
|
||||
* Use all materials in the given [mixes].
|
||||
* @throws TooLowQuantityException When there is not enough stock for a material
|
||||
*/
|
||||
fun use(mixes: List<InventoryDto>) {
|
||||
mixes.forEach { mix ->
|
||||
val materials = mix.materialIds.toMaterials()
|
||||
|
||||
materials.forEachIndexed { index, material ->
|
||||
val quantity = mix.quantities[index]
|
||||
|
||||
if (!material.hasEnoughStock(quantity))
|
||||
throw TooLowQuantityException(mix.mixId, material, material.inventoryQuantity, quantity)
|
||||
|
||||
material.use(quantity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert material ids to [Material]s. */
|
||||
private fun List<Long>.toMaterials(): List<Material> {
|
||||
return map { materialService.getById(it) }
|
||||
}
|
||||
|
||||
/** Check if there is at least the given [quantity] in stock for a [Material]. */
|
||||
private fun Material.hasEnoughStock(quantity: Float): Boolean {
|
||||
return inventoryQuantity >= quantity
|
||||
}
|
||||
|
||||
/** Use a given [Material], for the given [quantity]. */
|
||||
private fun Material.use(quantity: Float) {
|
||||
inventoryQuantity -= quantity
|
||||
materialService.update(this)
|
||||
}
|
||||
}
|
||||
//interface InventoryService {
|
||||
// fun deduct(quantities: InventoryDeductDto)
|
||||
// fun deduct(material: Material, quantity: Float)
|
||||
//}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MaterialRepository
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.SimdutService
|
||||
|
@ -93,7 +93,7 @@ class MaterialServiceImpl(
|
|||
}
|
||||
|
||||
override fun deleteById(id: Long) {
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityRestException(id)
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityException(id)
|
||||
super.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.RestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeSaveDto
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialTypeUpdateDto
|
||||
|
@ -47,7 +47,7 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma
|
|||
|
||||
override fun save(entity: MaterialType): MaterialType {
|
||||
if (existsByPrefix(entity.prefix))
|
||||
throw EntityAlreadyExistsRestException(entity.prefix)
|
||||
throw EntityAlreadyExistsException(entity.prefix)
|
||||
return super<AbstractExternalNamedModelService>.save(entity)
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,14 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma
|
|||
override fun update(entity: MaterialType): MaterialType {
|
||||
with(repository.findByPrefix(entity.prefix)) {
|
||||
if (this != null && id != entity.id)
|
||||
throw EntityAlreadyExistsRestException(entity.prefix)
|
||||
throw EntityAlreadyExistsException(entity.prefix)
|
||||
}
|
||||
|
||||
return super<AbstractExternalNamedModelService>.update(entity)
|
||||
}
|
||||
|
||||
override fun deleteById(id: Long) {
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityRestException(id)
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityException(id)
|
||||
super.deleteById(id)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MixRepository
|
||||
import org.springframework.context.annotation.Lazy
|
||||
|
@ -113,7 +113,7 @@ class MixServiceImpl(
|
|||
}
|
||||
|
||||
override fun deleteById(id: Long) {
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityRestException(id)
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityException(id)
|
||||
super.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.CannotDeleteEntityException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.MixTypeRepository
|
||||
import org.springframework.context.annotation.Lazy
|
||||
|
@ -39,11 +39,11 @@ class MixTypeServiceImpl(
|
|||
repository.existsByNameAndMaterialType(name, materialType)
|
||||
|
||||
override fun getByMaterial(material: Material): MixType =
|
||||
repository.findByMaterial(material) ?: throw EntityNotFoundRestException(material.name)
|
||||
repository.findByMaterial(material) ?: throw EntityNotFoundException(material.name)
|
||||
|
||||
override fun getByNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
repository.findByNameAndMaterialType(name, materialType)
|
||||
?: throw EntityNotFoundRestException("$name/${materialType.name}")
|
||||
?: throw EntityNotFoundException("$name/${materialType.name}")
|
||||
|
||||
override fun getOrCreateForNameAndMaterialType(name: String, materialType: MaterialType): MixType =
|
||||
if (existsByNameAndMaterialType(name, materialType))
|
||||
|
@ -53,7 +53,7 @@ class MixTypeServiceImpl(
|
|||
|
||||
override fun save(entity: MixType): MixType {
|
||||
if (materialService.existsByName(entity.name))
|
||||
throw EntityAlreadyExistsRestException(entity.name)
|
||||
throw EntityAlreadyExistsException(entity.name)
|
||||
return super.save(entity)
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ class MixTypeServiceImpl(
|
|||
})
|
||||
|
||||
override fun deleteById(id: Long) {
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityRestException(id)
|
||||
if (!repository.canBeDeleted(id)) throw CannotDeleteEntityException(id)
|
||||
super.deleteById(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.validation.isNotNullAndNotBlank
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.validation.or
|
||||
import dev.fyloz.trial.colorrecipesexplorer.repository.RecipeRepository
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.FilesService
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.files.FileService
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.io.File
|
||||
|
@ -134,12 +134,12 @@ interface RecipeImageService {
|
|||
}
|
||||
|
||||
@Service
|
||||
class RecipeImageServiceImpl(val recipeService: RecipeService, val filesService: FilesService) : RecipeImageService {
|
||||
class RecipeImageServiceImpl(val recipeService: RecipeService, val fileService: FileService) : RecipeImageService {
|
||||
override fun getByIdForRecipe(id: Long, recipeId: Long): ByteArray =
|
||||
try {
|
||||
filesService.readAsBytes(getPath(id, recipeId))
|
||||
fileService.readAsBytes(getPath(id, recipeId))
|
||||
} catch (ex: NoSuchFileException) {
|
||||
throw EntityNotFoundRestException("$recipeId/$id")
|
||||
throw EntityNotFoundException("$recipeId/$id")
|
||||
}
|
||||
|
||||
override fun getAllIdsForRecipe(recipeId: Long): Collection<Long> {
|
||||
|
@ -164,16 +164,16 @@ class RecipeImageServiceImpl(val recipeService: RecipeService, val filesService:
|
|||
}
|
||||
|
||||
val nextAvailableId = getNextAvailableId()
|
||||
filesService.write(image, getPath(nextAvailableId, recipeId))
|
||||
fileService.write(image, getPath(nextAvailableId, recipeId))
|
||||
return nextAvailableId
|
||||
}
|
||||
|
||||
override fun delete(id: Long, recipeId: Long) =
|
||||
filesService.delete(getPath(id, recipeId))
|
||||
fileService.delete(getPath(id, recipeId))
|
||||
|
||||
/** Gets the images directory of the recipe with the given [recipeId]. */
|
||||
fun getRecipeDirectory(recipeId: Long) = File(filesService.getPath("$RECIPE_IMAGES_DIRECTORY/$recipeId"))
|
||||
fun getRecipeDirectory(recipeId: Long) = File(fileService.getPath("$RECIPE_IMAGES_DIRECTORY/$recipeId"))
|
||||
|
||||
/** Gets the file of the image with the given [recipeId] and [id]. */
|
||||
fun getPath(id: Long, recipeId: Long): String = filesService.getPath("$RECIPE_IMAGES_DIRECTORY/$recipeId/$id")
|
||||
fun getPath(id: Long, recipeId: Long): String = fileService.getPath("$RECIPE_IMAGES_DIRECTORY/$recipeId/$id")
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundRestException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityAlreadyExistsException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.EntityNotFoundException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.EntityDto
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Model
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel
|
||||
|
@ -69,18 +69,18 @@ abstract class AbstractService<E, R : JpaRepository<E, *>>(override val reposito
|
|||
abstract class AbstractModelService<E : Model, R : JpaRepository<E, Long>>(repository: R) :
|
||||
AbstractService<E, R>(repository), ModelService<E, R> {
|
||||
override fun existsById(id: Long): Boolean = repository.existsById(id)
|
||||
override fun getById(id: Long): E = repository.findByIdOrNull(id) ?: throw EntityNotFoundRestException(id)
|
||||
override fun getById(id: Long): E = repository.findByIdOrNull(id) ?: throw EntityNotFoundException(id)
|
||||
|
||||
override fun save(entity: E): E {
|
||||
if (entity.id != null && existsById(entity.id!!))
|
||||
throw EntityAlreadyExistsRestException(entity.id!!)
|
||||
throw EntityAlreadyExistsException(entity.id!!)
|
||||
return super.save(entity)
|
||||
}
|
||||
|
||||
override fun update(entity: E): E {
|
||||
assertId(entity.id)
|
||||
if (!existsById(entity.id!!))
|
||||
throw EntityNotFoundRestException(entity.id!!)
|
||||
throw EntityNotFoundException(entity.id!!)
|
||||
return super.update(entity)
|
||||
}
|
||||
|
||||
|
@ -95,12 +95,12 @@ abstract class AbstractModelService<E : Model, R : JpaRepository<E, Long>>(repos
|
|||
abstract class AbstractNamedModelService<E : NamedModel, R : NamedJpaRepository<E>>(repository: R) :
|
||||
AbstractModelService<E, R>(repository), NamedModelService<E, R> {
|
||||
override fun existsByName(name: String): Boolean = repository.existsByName(name)
|
||||
override fun getByName(name: String): E = repository.findByName(name) ?: throw EntityNotFoundRestException(name)
|
||||
override fun getByName(name: String): E = repository.findByName(name) ?: throw EntityNotFoundException(name)
|
||||
override fun deleteByName(name: String) = repository.deleteByName(name)
|
||||
|
||||
override fun save(entity: E): E {
|
||||
if (existsByName(entity.name))
|
||||
throw EntityAlreadyExistsRestException(entity.name)
|
||||
throw EntityAlreadyExistsException(entity.name)
|
||||
return super.save(entity)
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ abstract class AbstractNamedModelService<E : NamedModel, R : NamedJpaRepository<
|
|||
assertName(entity.name)
|
||||
with(repository.findByName(entity.name)) {
|
||||
if (this != null && id != entity.id)
|
||||
throw EntityAlreadyExistsRestException(entity.name)
|
||||
throw EntityAlreadyExistsException(entity.name)
|
||||
}
|
||||
return super.update(entity)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.config.properties.CreProperties
|
||||
import org.slf4j.Logger
|
||||
import org.springframework.core.io.ResourceLoader
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.util.FileCopyUtils
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
|
||||
@Service
|
||||
class FileService(
|
||||
private val resourcesLoader: ResourceLoader,
|
||||
private val creProperties: CreProperties,
|
||||
private val logger: Logger
|
||||
) {
|
||||
/** Reads the resource at the given [path] as a [String]. */
|
||||
fun readResource(path: String): String = try {
|
||||
resourcesLoader.getResource("classpath:$path").inputStream.use {
|
||||
readInputStreamAsString(it)
|
||||
}
|
||||
} catch (ex: IOException) {
|
||||
logger.error("Could not read resource", ex)
|
||||
""
|
||||
}
|
||||
|
||||
/** Reads the given [stream] as a [String]. */
|
||||
fun readInputStreamAsString(stream: InputStream) = with(FileCopyUtils.copyToByteArray(stream)) {
|
||||
String(this, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
/** Reads the file at the given [path] as a [ByteArray]. */
|
||||
fun readAsBytes(path: String) =
|
||||
Files.readAllBytes(Paths.get(path))
|
||||
|
||||
/** Reads the file at the given [path] as a [List] of [String]. */
|
||||
fun readAsStrings(path: String) =
|
||||
Files.readAllLines(Paths.get(path))
|
||||
|
||||
/** Write the given [multipartFile] to the file at the given [path]. */
|
||||
fun write(multipartFile: MultipartFile, path: String): Boolean =
|
||||
if (multipartFile.size <= 0) true
|
||||
else try {
|
||||
multipartFile.transferTo(create(path).toPath())
|
||||
true
|
||||
} catch (ex: IOException) {
|
||||
logger.error("Unable to write multipart file", ex)
|
||||
false
|
||||
}
|
||||
|
||||
/** Creates a new file at the given [path]. If the file already exists, nothing will be done. */
|
||||
fun create(path: String) = withFileAt(path) {
|
||||
if (!exists(path)) {
|
||||
try {
|
||||
Files.createDirectories(this.parentFile.toPath())
|
||||
Files.createFile(this.toPath())
|
||||
} catch (ex: IOException) {
|
||||
logger.error("Unable to create file", ex)
|
||||
}
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
/** Deletes the file at the given [path]. */
|
||||
fun delete(path: String) = withFileAt(path) {
|
||||
try {
|
||||
if (exists(path)) Files.delete(this.toPath())
|
||||
} catch (ex: IOException) {
|
||||
logger.error("Unable to delete file", ex)
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if a file with the given [path] exists on the disk. */
|
||||
fun exists(path: String): Boolean = withFileAt(path) {
|
||||
this.exists() && this.isFile
|
||||
}
|
||||
|
||||
/** Runs the given [block] in the context of a file with the given [path]. */
|
||||
fun <T> withFileAt(path: String, block: File.() -> T) =
|
||||
with(File(path)) { block() }
|
||||
|
||||
fun getPath(fileName: String): String =
|
||||
"${creProperties.workingDirectory}/$fileName"
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package dev.fyloz.trial.colorrecipesexplorer.service.files
|
||||
|
||||
import dev.fyloz.trial.colorrecipesexplorer.exception.SimdutWriteException
|
||||
import dev.fyloz.trial.colorrecipesexplorer.model.Material
|
||||
import dev.fyloz.trial.colorrecipesexplorer.service.MaterialService
|
||||
import org.slf4j.Logger
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.io.IOException
|
||||
|
||||
private const val SIMDUT_DIRECTORY = "simdut"
|
||||
|
||||
@Service
|
||||
class SimdutService(
|
||||
private val fileService: FileService,
|
||||
@Lazy private val materialService: MaterialService,
|
||||
private val logger: Logger
|
||||
) {
|
||||
/** Checks if the given [material] has a SIMDUT file. */
|
||||
fun exists(material: Material) =
|
||||
fileService.exists(getPath(material))
|
||||
|
||||
/** Reads the SIMDUT file of the given [material]. */
|
||||
fun read(material: Material): ByteArray {
|
||||
val path = getPath(material)
|
||||
if (fileService.exists(path)) return ByteArray(0)
|
||||
|
||||
return try {
|
||||
fileService.readAsBytes(path)
|
||||
} catch (ex: IOException) {
|
||||
logger.error("Could not read SIMDUT file", ex)
|
||||
ByteArray(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads the SIMDUT file of the material with the given [id]. */
|
||||
fun read(id: Long) =
|
||||
read(materialService.getById(id))
|
||||
|
||||
/** Writes the given [simdut] file for the given [material] to the disk. */
|
||||
fun write(material: Material, simdut: MultipartFile) {
|
||||
if (!fileService.write(simdut, getPath(material)))
|
||||
throw SimdutWriteException(material)
|
||||
}
|
||||
|
||||
/** Updates the SIMDUT file of the given [material] with the given [simdut]. */
|
||||
fun update(simdut: MultipartFile, material: Material) {
|
||||
delete(material)
|
||||
write(material, simdut)
|
||||
}
|
||||
|
||||
/** Deletes the SIMDUT file of the given [material]. */
|
||||
fun delete(material: Material) =
|
||||
fileService.delete(getPath(material))
|
||||
|
||||
/** Gets the path of the SIMDUT file of the given [material]. */
|
||||
fun getPath(material: Material) =
|
||||
fileService.getPath("$SIMDUT_DIRECTORY/${getSimdutFileName(material)}")
|
||||
|
||||
/** Gets the name of the SIMDUT file of the given [material]. */
|
||||
fun getSimdutFileName(material: Material) =
|
||||
material.id.toString()
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"properties": [
|
||||
{
|
||||
"name": "http.port",
|
||||
"type": "java.lang.String",
|
||||
"description": "Port HTTP."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
|
|
@ -1,3 +0,0 @@
|
|||
spring.resources.static-locations=classpath:/thymeleaf/static/
|
||||
spring.thymeleaf.prefix=classpath:/thymeleaf/templates/
|
||||
spring.thymeleaf.suffix=.html
|
|
@ -1,10 +1,7 @@
|
|||
# PORT
|
||||
server.port=9090
|
||||
# CRE
|
||||
cre.server.upload-directory=data
|
||||
cre.server.password-file=passwords.txt
|
||||
cre.server.url-use-port=true
|
||||
cre.server.url-use-https=false
|
||||
cre.server.working-directory=data
|
||||
cre.security.jwt-secret=CtnvGQjgZ44A1fh295gE
|
||||
cre.security.jwt-duration=18000000
|
||||
# Root user
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
app.title=Color recipes explorer
|
||||
company.add.title=Add a banner
|
||||
company.delete.title=Delete banners
|
||||
company.error.anyFound=No banners were found.
|
||||
company.form.companyName=Banner name
|
||||
company.success.created=The banner {0} has been saved.
|
||||
company.success.deleted=The banner {0} has been deleted.
|
||||
error.serverError=An error occurred while sending data to the server.
|
||||
footer.lang=Voir en français
|
||||
image.add.title=Add an image
|
||||
inventory.askUseMix=Do you really want to deduct this mix from the inventory?
|
||||
inventory.askUseRecipe=Do you really want to deduct this recipe from the inventory?
|
||||
inventory.hideOthers=Hide other materials
|
||||
inventory.lowQuantity=Low quantity
|
||||
inventory.showOnly=Show only
|
||||
keyword.back=Back
|
||||
keyword.calculation=Calculation
|
||||
keyword.cancel=Cancel
|
||||
keyword.characters=characters
|
||||
keyword.company=Banner
|
||||
keyword.continue=Continue
|
||||
keyword.delete=Delete
|
||||
keyword.edit=Edit
|
||||
keyword.id=ID
|
||||
keyword.images=Images
|
||||
keyword.material=Material
|
||||
keyword.pdf=PDF
|
||||
keyword.print=Print
|
||||
keyword.ptouch=P-touch
|
||||
keyword.ptouchTemplate=P-touch templates
|
||||
keyword.quantity=Quantity
|
||||
keyword.recipe=Recipe
|
||||
keyword.remove=Remove
|
||||
keyword.save=Save
|
||||
keyword.search=Search
|
||||
keyword.see=See
|
||||
keyword.type=Type
|
||||
keyword.units=Units
|
||||
keyword.updates=Updates history
|
||||
keyword.use=Use
|
||||
material.add.title=Add a material
|
||||
material.code=Code
|
||||
material.delete.title=Delete materials
|
||||
material.edit.title=Edit materials
|
||||
material.editing.title=Editing {0}
|
||||
material.error.anyFound=No materials were found.
|
||||
material.inventoryQuantity=Inventory quantity
|
||||
material.simdut.choose=Choose material's SIMDUT file
|
||||
material.simdut.error.notFound=No SIMDUT file found
|
||||
material.simdut=SIMDUT File
|
||||
material.success.created=The material {0} has been saved.
|
||||
material.success.deleted=The material {0} has been deleted.
|
||||
material.success.saved=The material {0} has been saved.
|
||||
material.type=Material type
|
||||
materialType.add.title=Add a material type
|
||||
materialType.delete.title=Delete material types
|
||||
materialType.editing.title=Editing {0}
|
||||
materialType.editor.title=Edit material types
|
||||
materialType.error.anyFound=Any material type has been found.
|
||||
materialType.name=Name
|
||||
materialType.prefix=Prefix
|
||||
materialType.success.deleted=The material type {0} has been deleted.
|
||||
materialType.success.saved=The material type {0} has been saved.
|
||||
materialType.usePercents=Use percentages
|
||||
menu.add=Add
|
||||
menu.delete=Delete
|
||||
menu.edit=Edit
|
||||
menu.explore=Explore
|
||||
menu.inventory=Inventory
|
||||
menu.others=Others
|
||||
mix.add.subtitle=Add a mix for the recipe {0}
|
||||
mix.add.title=Add a banner
|
||||
mix.edit.subtitle=Editing a mix for the recipe {0} ({1})
|
||||
mix.edit.title=Editing a mix
|
||||
mix.location=Location
|
||||
mix.mixType=Mix type
|
||||
password.ask=What is your password?
|
||||
password.notValid=Your password is not valid
|
||||
recipe.add.title=Add a recipe
|
||||
recipe.approbationDate=Approbation date
|
||||
recipe.color=Color
|
||||
recipe.delete.title=Delete recipes
|
||||
recipe.description=Description
|
||||
recipe.edit.addImage=Add an image
|
||||
recipe.edit.addMix=Add a mix
|
||||
recipe.edit.title=Edit a recipe
|
||||
recipe.editing.title=Editing {0}
|
||||
recipe.error.anyFound=No recipes were found.
|
||||
recipe.explore.title={0} color
|
||||
recipe.exportAllXLS=Export all colors (XLSX)
|
||||
recipe.image.corrupted=Image deleted or corrupted
|
||||
recipe.notice=Notice
|
||||
recipe.print.confirm=Are you sure you want to print this mix?
|
||||
recipe.print.error.bpacNotInstalled=BPac is not installed
|
||||
recipe.print.error.noBase=There is no base in this mix
|
||||
recipe.print.error=An error occurred while printing
|
||||
recipe.print.printing=Printing in progress. This may take a few seconds.
|
||||
recipe.print.status.error=The b-Pac extension is not installed
|
||||
recipe.print.status.ok=The b-Pac extension is installed
|
||||
recipe.remark=Remark
|
||||
recipe.sample=Sample
|
||||
recipe.steps=Steps
|
||||
recipe.success.deleted=The recipe {0} has been deleted.
|
||||
recipe.success.edit=The recipe {0} has been saved.
|
||||
recipe.sucess.saved=The recipe {0} has been saved. You can now add ingredients.
|
||||
recipe.touchup.title=Touch-up kit labels
|
||||
recipe.touchup=Touch-up kit labels
|
||||
recipe.warning.changesNotSaved=Changes are not saved
|
||||
recipe.warning.exportAll=Do you really want to export all the colors? This can take some times and slow down the application.
|
||||
recipe.warning.notApproved.short=Not approved
|
||||
recipe.warning.notApproved=This recipe is not approved
|
||||
recipe.xlsVersion=XLSX version
|
||||
units.gallons=Gallons
|
||||
units.liters=Liters
|
||||
units.milliliters=Milliliters
|
||||
warning.askChangePage=Are you sure you want to continue? Unsaved changes will be lost.
|
||||
warning.noResult=Search returned no results
|
||||
keyword.jobNumber=Job number
|
|
@ -1,118 +0,0 @@
|
|||
app.title=Explorateur de recettes de couleur
|
||||
company.add.title=Ajout d'une bannière
|
||||
company.delete.title=Supprimer des bannières
|
||||
company.error.anyFound=Aucune bannière n'a été trouvée.
|
||||
company.form.companyName=Nom de la bannière
|
||||
company.success.created=La bannière {0} à été enregistrée.
|
||||
company.success.deleted=La bannière {0} a bien été supprimée.
|
||||
error.serverError=Une erreur est survenue lors de l'envoie des informations vers le serveur.
|
||||
footer.lang=See in english
|
||||
image.add.title=Ajout une image
|
||||
inventory.askUseMix=Êtes-vous certain de vouloir déduire ce mélange de l'inventaire?
|
||||
inventory.askUseRecipe=Êtes-vous certain de vouloir déduire cette recette de l'inventaire?
|
||||
inventory.hideOthers=Cacher les autres produits
|
||||
inventory.lowQuantity=Quantité faible
|
||||
inventory.showOnly=Voir seulement
|
||||
keyword.back=Retour
|
||||
keyword.calculation=Calcul
|
||||
keyword.cancel=Annuler
|
||||
keyword.characters=caractères
|
||||
keyword.company=Bannière
|
||||
keyword.continue=Continuer
|
||||
keyword.delete=Supprimer
|
||||
keyword.edit=Modifier
|
||||
keyword.id=Identifiant
|
||||
keyword.images=Images
|
||||
keyword.material=Produit
|
||||
keyword.pdf=PDF
|
||||
keyword.print=Imprimer
|
||||
keyword.ptouch=P-touch
|
||||
keyword.ptouchTemplate=Modèles P-touch
|
||||
keyword.quantity=Quantité
|
||||
keyword.recipe=Recette
|
||||
keyword.remove=Retirer
|
||||
keyword.save=Enregistrer
|
||||
keyword.search=Rechercher
|
||||
keyword.see=Voir
|
||||
keyword.type=Type
|
||||
keyword.units=Unités
|
||||
keyword.updates=Historique des mises à jour
|
||||
keyword.use=Utiliser
|
||||
material.add.title=Ajout d'un produit
|
||||
material.code=Code
|
||||
material.delete.title=Supprimer des produits
|
||||
material.edit.title=Modifer des produits
|
||||
material.editing.title=Modification de {0}
|
||||
material.error.anyFound=Aucun produit n'a été trouvé.
|
||||
material.inventoryQuantity=Quantité en inventaire
|
||||
material.simdut.choose=Choisissez le fichier SIMDUT du produit
|
||||
material.simdut.error.notFound=Aucun fichier SIMDUT trouvé
|
||||
material.simdut=Fichier SIMDUT
|
||||
material.success.created=Le produit {0} a été enregistré.
|
||||
material.success.deleted=Le produit {0} a bien été supprimée.
|
||||
material.success.saved=Le produit {0} a bien été sauvegardé.
|
||||
material.type=Type de produit
|
||||
materialType.add.title=Ajout d'un type de produit
|
||||
materialType.delete.title=Supprimer des types de produit
|
||||
materialType.editing.title=Modification de {0}
|
||||
materialType.editor.title=Modifier un type de produit
|
||||
materialType.error.anyFound=Aucun type de produit n'a été trouvé.
|
||||
materialType.name=Nom
|
||||
materialType.prefix=Préfix
|
||||
materialType.success.deleted=Le type de produit {0} a bien été supprimé.
|
||||
materialType.success.saved=Le type de produit {0} a bien été sauvegardé.
|
||||
materialType.usePercents=Utiliser les pourcentages
|
||||
menu.add=Ajouter
|
||||
menu.delete=Supprimer
|
||||
menu.edit=Modifier
|
||||
menu.explore=Explorer
|
||||
menu.inventory=Inventaire
|
||||
menu.others=Autres
|
||||
mix.add.subtitle=Ajout d''un mélange pour la recette {0}
|
||||
mix.add.title=Ajout d'un mélange
|
||||
mix.edit.subtitle=Modifier un mélange pour la recette {0} ({1})
|
||||
mix.edit.title=Modifier un mélange
|
||||
mix.location=Position
|
||||
mix.mixType=Type de mélange
|
||||
password.ask=Quel est votre mot de passe?
|
||||
password.notValid=Votre mot de passe n'est pas valide
|
||||
recipe.add.title=Ajout d'une recette
|
||||
recipe.approbationDate=Date d'approbation
|
||||
recipe.color=Couleur
|
||||
recipe.delete.title=Supprimer des recettes
|
||||
recipe.description=Description
|
||||
recipe.edit.addImage=Ajouter une image
|
||||
recipe.edit.addMix=Ajouter un mélange
|
||||
recipe.edit.title=Modifier une recette
|
||||
recipe.editing.title=Modification de {0}
|
||||
recipe.error.anyFound=Aucune recette n'a été trouvée.
|
||||
recipe.explore.title=Couleur {0}
|
||||
recipe.exportAllXLS=Exporter toutes les couleurs (XLSX)
|
||||
recipe.image.corrupted=Image supprimée ou corrompue
|
||||
recipe.notice=Note
|
||||
recipe.print.confirm=Voulez-vous vraiment imprimer ce mélange?
|
||||
recipe.print.error.bpacNotInstalled=BPac n'est pas installé
|
||||
recipe.print.error.noBase=Il n'y a pas de base dans ce mélange
|
||||
recipe.print.error=Une erreur est survenue pendant l'impression
|
||||
recipe.print.printing=Impression en cours. Cette opération peut prendre quelques secondes.
|
||||
recipe.print.status.error=L'extension b-Pac n'est pas installée
|
||||
recipe.print.status.ok=L'extension b-Pac est installée
|
||||
recipe.remark=Remarque
|
||||
recipe.sample=Échantillon
|
||||
recipe.steps=Étapes
|
||||
recipe.success.deleted=La recette {0} a bien été supprimée.
|
||||
recipe.success.edit=La recette {0} a bien été sauvegardée.
|
||||
recipe.sucess.saved=La recette {0} à été enregistrée. Vous pouvez maintenant ajouter les ingrédients.
|
||||
recipe.touchup.title=Étiquettes de kit de retouche
|
||||
recipe.touchup=Étiquettes de kit de retouche
|
||||
recipe.warning.changesNotSaved=Des modifications ne sont pas sauvegardées
|
||||
recipe.warning.exportAll=Voulez-vous vraiment exporter toutes les couleurs? Cela peut prendre un certain temps et ralentir l'application.
|
||||
recipe.warning.notApproved.short=Non approuvée
|
||||
recipe.warning.notApproved=Cette recette n'est pas approuvée
|
||||
recipe.xlsVersion=Version XLSX
|
||||
units.gallons=Gallons
|
||||
units.liters=Litres
|
||||
units.milliliters=Millilitres
|
||||
warning.askChangePage=Êtes-vous sûr de vouloir continuer? Les modifications non enregistrées seront perdues.
|
||||
warning.noResult=La recherche n'a donné aucun résultat
|
||||
keyword.jobNumber=Numéro de job
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue