This commit is contained in:
parent
0e97fef70e
commit
d785cfdbe7
|
@ -2,13 +2,14 @@ package dev.fyloz.colorrecipesexplorer
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
object ControllerPaths {
|
object ControllerPaths {
|
||||||
const val file = "/api/file"
|
const val FILE = "/api/file"
|
||||||
const val material = "/api/material"
|
const val MATERIAL = "/api/material"
|
||||||
|
const val MATERIAL_TYPE = "/api/materialtype"
|
||||||
}
|
}
|
||||||
|
|
||||||
object FilePaths {
|
object FilePaths {
|
||||||
const val pdfs = "pdf"
|
const val PDF = "pdf"
|
||||||
|
|
||||||
const val simdut = "$pdfs/simdut"
|
const val SIMDUT = "$PDF/simdut"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,8 +2,8 @@ package dev.fyloz.colorrecipesexplorer.config.initializers
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
||||||
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
import dev.fyloz.colorrecipesexplorer.config.properties.MaterialTypeProperties
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
@ -23,17 +23,16 @@ class MaterialTypeInitializer(
|
||||||
|
|
||||||
private fun ensureSystemMaterialTypesExists() {
|
private fun ensureSystemMaterialTypesExists() {
|
||||||
val systemTypes = materialTypeProperties.systemTypes.map { it.toMaterialType() }
|
val systemTypes = materialTypeProperties.systemTypes.map { it.toMaterialType() }
|
||||||
val oldSystemTypes = materialTypeLogic.getAllSystemTypes().toMutableSet()
|
val oldSystemTypes = materialTypeLogic.getAll(true).toMutableSet()
|
||||||
|
|
||||||
fun saveOrUpdateSystemType(type: MaterialType) {
|
fun saveOrUpdateSystemType(type: MaterialTypeDto) {
|
||||||
if (materialTypeLogic.existsByName(type.name)) {
|
val storedMaterialType = materialTypeLogic.getByName(type.name)
|
||||||
with(materialTypeLogic.getByName(type.name)) {
|
if (storedMaterialType != null) {
|
||||||
if (!this.systemType) {
|
if (!storedMaterialType.systemType) {
|
||||||
logger.info("Material type '${type.name}' already exists and will be flagged as a system type")
|
logger.info("Material type '${type.name}' already exists and will be flagged as a system type")
|
||||||
materialTypeLogic.update(this.copy(systemType = true))
|
materialTypeLogic.update(storedMaterialType.copy(systemType = true))
|
||||||
} else {
|
} else {
|
||||||
logger.debug("System material type '${type.name}' already exists")
|
logger.debug("System material type '${type.name}' already exists")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.info("System material type '${type.name}' will be created")
|
logger.info("System material type '${type.name}' will be created")
|
||||||
|
@ -50,7 +49,7 @@ class MaterialTypeInitializer(
|
||||||
// Remove old system types
|
// Remove old system types
|
||||||
oldSystemTypes.forEach {
|
oldSystemTypes.forEach {
|
||||||
logger.info("Material type '${it.name}' is not a system type anymore")
|
logger.info("Material type '${it.name}' is not a system type anymore")
|
||||||
materialTypeLogic.updateSystemType(it.copy(systemType = false))
|
materialTypeLogic.updateNonSystemType(it.copy(systemType = false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.config.properties
|
package dev.fyloz.colorrecipesexplorer.config.properties
|
||||||
|
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||||
import dev.fyloz.colorrecipesexplorer.model.materialType
|
import dev.fyloz.colorrecipesexplorer.model.materialType
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
|
@ -16,9 +17,9 @@ class MaterialTypeProperties {
|
||||||
var prefix: String = "",
|
var prefix: String = "",
|
||||||
var usePercentages: Boolean = false
|
var usePercentages: Boolean = false
|
||||||
) {
|
) {
|
||||||
fun toMaterialType(): MaterialType {
|
fun toMaterialType(): MaterialTypeDto {
|
||||||
Assert.hasText(name, "A system material type has an empty name")
|
Assert.hasText(name, "A system material type has an empty name")
|
||||||
return materialType(name = name, prefix = prefix, usePercentages = usePercentages, systemType = true)
|
return MaterialTypeDto(name = name, prefix = prefix, usePercentages = usePercentages, systemType = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.dtos
|
package dev.fyloz.colorrecipesexplorer.dtos
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
|
||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import javax.validation.constraints.Min
|
import javax.validation.constraints.Min
|
||||||
import javax.validation.constraints.NotBlank
|
import javax.validation.constraints.NotBlank
|
||||||
|
@ -14,7 +13,7 @@ data class MaterialDto(
|
||||||
|
|
||||||
val isMixType: Boolean,
|
val isMixType: Boolean,
|
||||||
|
|
||||||
val materialType: MaterialType,
|
val materialType: MaterialTypeDto,
|
||||||
|
|
||||||
val simdutUrl: String? = null
|
val simdutUrl: String? = null
|
||||||
) : EntityDto
|
) : EntityDto
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package dev.fyloz.colorrecipesexplorer.dtos
|
||||||
|
|
||||||
|
data class MaterialTypeDto(
|
||||||
|
override val id: Long = 0L,
|
||||||
|
|
||||||
|
val name: String,
|
||||||
|
|
||||||
|
val prefix: String,
|
||||||
|
|
||||||
|
val usePercentages: Boolean,
|
||||||
|
|
||||||
|
val systemType: Boolean = false
|
||||||
|
) : EntityDto
|
|
@ -19,13 +19,13 @@ interface Logic<D : EntityDto, S : Service<D, *, *>> {
|
||||||
/** Get all DTOs. */
|
/** Get all DTOs. */
|
||||||
fun getAll(): Collection<D>
|
fun getAll(): Collection<D>
|
||||||
|
|
||||||
/** Get the DTO for the given [id]. */
|
/** Get the DTO for the given [id]. Throws if no DTO were found. */
|
||||||
fun getById(id: Long): D
|
fun getById(id: Long): D
|
||||||
|
|
||||||
/** Saves the given [dto]. */
|
/** Saves the given [dto]. */
|
||||||
fun save(dto: D): D
|
fun save(dto: D): D
|
||||||
|
|
||||||
/** Updates the given [dto]. */
|
/** Updates the given [dto]. Throws if no DTO with the same id exists. */
|
||||||
fun update(dto: D): D
|
fun update(dto: D): D
|
||||||
|
|
||||||
/** Deletes the dto with the given [id]. */
|
/** Deletes the dto with the given [id]. */
|
||||||
|
|
|
@ -1,88 +1,75 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.logic
|
package dev.fyloz.colorrecipesexplorer.logic
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.config.annotations.RequireDatabase
|
import dev.fyloz.colorrecipesexplorer.config.annotations.LogicComponent
|
||||||
import dev.fyloz.colorrecipesexplorer.model.*
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.model.validation.isNotNullAndNotBlank
|
import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException
|
||||||
import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
|
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||||
import org.springframework.stereotype.Service
|
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
|
||||||
|
|
||||||
interface MaterialTypeLogic :
|
interface MaterialTypeLogic : Logic<MaterialTypeDto, MaterialTypeService> {
|
||||||
ExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository> {
|
/** Gets all material types which are or not [systemType]s. */
|
||||||
/** Checks if a material type with the given [prefix] exists. */
|
fun getAll(systemType: Boolean): Collection<MaterialTypeDto>
|
||||||
fun existsByPrefix(prefix: String): Boolean
|
|
||||||
|
|
||||||
/** Gets all system material types. */
|
/** Gets the material type with the given [name]. */
|
||||||
fun getAllSystemTypes(): Collection<MaterialType>
|
fun getByName(name: String): MaterialTypeDto?
|
||||||
|
|
||||||
/** Gets all material types who are not a system type. */
|
/** Updates the given [dto], and throws if it is a system types. */
|
||||||
fun getAllNonSystemType(): Collection<MaterialType>
|
fun updateNonSystemType(dto: MaterialTypeDto)
|
||||||
|
|
||||||
/** Allows to update the given system [materialType], should not be exposed to users. */
|
|
||||||
fun updateSystemType(materialType: MaterialType): MaterialType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@LogicComponent
|
||||||
@RequireDatabase
|
class DefaultMaterialTypeLogic(service: MaterialTypeService) :
|
||||||
class DefaultMaterialTypeLogic(repository: MaterialTypeRepository) :
|
BaseLogic<MaterialTypeDto, MaterialTypeService>(service, MaterialType::class.simpleName!!), MaterialTypeLogic {
|
||||||
AbstractExternalNamedModelService<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialType, MaterialTypeRepository>(
|
override fun getAll(systemType: Boolean) = service.getAll(systemType)
|
||||||
repository
|
override fun getByName(name: String) = service.getByName(name)
|
||||||
), MaterialTypeLogic {
|
|
||||||
override fun idNotFoundException(id: Long) = materialTypeIdNotFoundException(id)
|
|
||||||
override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id)
|
|
||||||
override fun nameNotFoundException(name: String) = materialTypeNameNotFoundException(name)
|
|
||||||
override fun nameAlreadyExistsException(name: String) = materialTypeNameAlreadyExistsException(name)
|
|
||||||
|
|
||||||
override fun MaterialType.toOutput() = this
|
override fun updateNonSystemType(dto: MaterialTypeDto) {
|
||||||
|
if (service.existsById(dto.id, true)) {
|
||||||
override fun existsByPrefix(prefix: String): Boolean = repository.existsByPrefix(prefix)
|
throw CannotUpdateException(
|
||||||
|
typeNameLowerCase,
|
||||||
override fun getAllSystemTypes(): Collection<MaterialType> = repository.findAllBySystemTypeIs(true)
|
"Cannot update $typeNameLowerCase",
|
||||||
override fun getAllNonSystemType(): Collection<MaterialType> = repository.findAllBySystemTypeIs(false)
|
"Cannot update material type '${dto.name}' because it is a system material type"
|
||||||
|
|
||||||
override fun save(entity: MaterialType): MaterialType {
|
|
||||||
if (existsByPrefix(entity.prefix))
|
|
||||||
throw materialTypePrefixAlreadyExistsException(entity.prefix)
|
|
||||||
return super<AbstractExternalNamedModelService>.save(entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun update(entity: MaterialTypeUpdateDto): MaterialType {
|
|
||||||
val persistedMaterialType by lazy { getById(entity.id) }
|
|
||||||
|
|
||||||
return update(with(entity) {
|
|
||||||
MaterialType(
|
|
||||||
id = id,
|
|
||||||
name = if (isNotNullAndNotBlank(name)) name else persistedMaterialType.name,
|
|
||||||
prefix = if (isNotNullAndNotBlank(prefix)) prefix else persistedMaterialType.prefix,
|
|
||||||
systemType = false
|
|
||||||
)
|
)
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updateSystemType(materialType: MaterialType) =
|
|
||||||
update(materialType, true)
|
|
||||||
|
|
||||||
override fun update(entity: MaterialType) =
|
|
||||||
update(entity, false)
|
|
||||||
|
|
||||||
private fun update(entity: MaterialType, allowSystemTypes: Boolean): MaterialType {
|
|
||||||
if (!allowSystemTypes && repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) {
|
|
||||||
throw cannotUpdateSystemMaterialTypeException(entity)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
with(repository.findByPrefix(entity.prefix)) {
|
update(dto)
|
||||||
if (this != null && id != entity.id)
|
|
||||||
throw materialTypePrefixAlreadyExistsException(entity.prefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.update(entity)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(entity: MaterialType) {
|
override fun save(dto: MaterialTypeDto): MaterialTypeDto {
|
||||||
if (repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) {
|
throwIfNameAlreadyExists(dto.name)
|
||||||
throw cannotDeleteSystemMaterialTypeException(entity)
|
throwIfPrefixAlreadyExists(dto.prefix)
|
||||||
|
|
||||||
|
return super.save(dto)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(dto: MaterialTypeDto): MaterialTypeDto {
|
||||||
|
throwIfNameAlreadyExists(dto.name, dto.id)
|
||||||
|
throwIfPrefixAlreadyExists(dto.prefix, dto.id)
|
||||||
|
|
||||||
|
return super.update(dto)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteById(id: Long) {
|
||||||
|
if (service.isUsedByMaterial(id)) {
|
||||||
|
throw cannotDeleteException("Cannot delete material type with the id '$id' because one or more materials depends on it")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!repository.canBeDeleted(entity.id)) throw cannotDeleteMaterialTypeException(entity)
|
super.deleteById(id)
|
||||||
super.delete(entity)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun throwIfNameAlreadyExists(name: String, id: Long? = null) {
|
||||||
|
if (service.existsByName(name, id)) {
|
||||||
|
throw alreadyExistsException(value = name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun throwIfPrefixAlreadyExists(prefix: String, id: Long? = null) {
|
||||||
|
if (service.existsByPrefix(prefix, id)) {
|
||||||
|
throw alreadyExistsException(PREFIX_IDENTIFIER_NAME, prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val PREFIX_IDENTIFIER_NAME = "prefix"
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,7 +53,7 @@ class DefaultMixLogic(
|
||||||
override fun save(entity: MixSaveDto): Mix {
|
override fun save(entity: MixSaveDto): Mix {
|
||||||
val recipe = recipeLogic.getById(entity.recipeId)
|
val recipe = recipeLogic.getById(entity.recipeId)
|
||||||
val materialType = materialTypeLogic.getById(entity.materialTypeId)
|
val materialType = materialTypeLogic.getById(entity.materialTypeId)
|
||||||
val mixType = mixTypeLogic.getOrCreateForNameAndMaterialType(entity.name, materialType)
|
val mixType = mixTypeLogic.getOrCreateForNameAndMaterialType(entity.name, materialType(materialType))
|
||||||
|
|
||||||
val mixMaterials = if (entity.mixMaterials != null) mixMaterialLogic.create(entity.mixMaterials) else setOf()
|
val mixMaterials = if (entity.mixMaterials != null) mixMaterialLogic.create(entity.mixMaterials) else setOf()
|
||||||
mixMaterialLogic.validateMixMaterials(mixMaterials)
|
mixMaterialLogic.validateMixMaterials(mixMaterials)
|
||||||
|
@ -72,7 +72,7 @@ class DefaultMixLogic(
|
||||||
if (entity.name != null || entity.materialTypeId != null) {
|
if (entity.name != null || entity.materialTypeId != null) {
|
||||||
val name = entity.name ?: mix.mixType.name
|
val name = entity.name ?: mix.mixType.name
|
||||||
val materialType = if (entity.materialTypeId != null)
|
val materialType = if (entity.materialTypeId != null)
|
||||||
materialTypeLogic.getById(entity.materialTypeId)
|
materialType(materialTypeLogic.getById(entity.materialTypeId))
|
||||||
else
|
else
|
||||||
mix.mixType.material.materialType!!
|
mix.mixType.material.materialType!!
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ data class Material(
|
||||||
) : ModelEntity {
|
) : ModelEntity {
|
||||||
companion object {
|
companion object {
|
||||||
fun getSimdutFilePath(name: String) =
|
fun getSimdutFilePath(name: String) =
|
||||||
"${Constants.FilePaths.simdut}/$name.pdf"
|
"${Constants.FilePaths.SIMDUT}/$name.pdf"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +66,12 @@ fun material(
|
||||||
@Deprecated("Temporary DSL for transition")
|
@Deprecated("Temporary DSL for transition")
|
||||||
fun material(
|
fun material(
|
||||||
dto: MaterialDto
|
dto: MaterialDto
|
||||||
) = Material(dto.id, dto.name, dto.inventoryQuantity, dto.isMixType, dto.materialType)
|
) = Material(dto.id, dto.name, dto.inventoryQuantity, dto.isMixType, materialType(dto.materialType))
|
||||||
|
|
||||||
@Deprecated("Temporary DSL for transition")
|
@Deprecated("Temporary DSL for transition")
|
||||||
fun materialDto(
|
fun materialDto(
|
||||||
entity: Material
|
entity: Material
|
||||||
) = MaterialDto(entity.id!!, entity.name, entity.inventoryQuantity, entity.isMixType, entity.materialType!!)
|
) = MaterialDto(entity.id!!, entity.name, entity.inventoryQuantity, entity.isMixType, materialTypeDto(entity.materialType!!))
|
||||||
|
|
||||||
fun materialQuantityDto(
|
fun materialQuantityDto(
|
||||||
materialId: Long,
|
materialId: Long,
|
||||||
|
|
|
@ -1,171 +1,62 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.model
|
package dev.fyloz.colorrecipesexplorer.model
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException
|
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
|
||||||
import org.hibernate.annotations.ColumnDefault
|
import org.hibernate.annotations.ColumnDefault
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
import javax.validation.constraints.NotBlank
|
|
||||||
import javax.validation.constraints.Size
|
|
||||||
|
|
||||||
private const val VALIDATION_PREFIX_SIZE = "Must contains exactly 3 characters"
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "material_type")
|
@Table(name = "material_type")
|
||||||
data class MaterialType(
|
data class MaterialType(
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
override val id: Long? = null,
|
override val id: Long? = null,
|
||||||
|
|
||||||
@Column(unique = true)
|
@Column(unique = true)
|
||||||
override val name: String = "",
|
val name: String = "",
|
||||||
|
|
||||||
@Column(unique = true)
|
@Column(unique = true)
|
||||||
val prefix: String = "",
|
val prefix: String = "",
|
||||||
|
|
||||||
@Column(name = "use_percentages")
|
@Column(name = "use_percentages")
|
||||||
@ColumnDefault("false")
|
@ColumnDefault("false")
|
||||||
val usePercentages: Boolean = false,
|
val usePercentages: Boolean = false,
|
||||||
|
|
||||||
@Column(name = "system_type")
|
@Column(name = "system_type")
|
||||||
@ColumnDefault("false")
|
@ColumnDefault("false")
|
||||||
val systemType: Boolean = false
|
val systemType: Boolean = false
|
||||||
) : NamedModelEntity
|
) : ModelEntity
|
||||||
|
|
||||||
open class MaterialTypeSaveDto(
|
|
||||||
@field:NotBlank
|
|
||||||
val name: String,
|
|
||||||
|
|
||||||
@field:NotBlank
|
|
||||||
@field:Size(min = 3, max = 3, message = VALIDATION_PREFIX_SIZE)
|
|
||||||
val prefix: String,
|
|
||||||
|
|
||||||
val usePercentages: Boolean = false
|
|
||||||
) : EntityDto<MaterialType> {
|
|
||||||
override fun toEntity(): MaterialType =
|
|
||||||
MaterialType(null, name, prefix, usePercentages)
|
|
||||||
}
|
|
||||||
|
|
||||||
open class MaterialTypeUpdateDto(
|
|
||||||
val id: Long,
|
|
||||||
|
|
||||||
@field:NotBlank
|
|
||||||
val name: String?,
|
|
||||||
|
|
||||||
@field:Size(min = 3, max = 3, message = VALIDATION_PREFIX_SIZE)
|
|
||||||
val prefix: String?
|
|
||||||
) : EntityDto<MaterialType> {
|
|
||||||
override fun toEntity(): MaterialType =
|
|
||||||
MaterialType(id, name ?: "", prefix ?: "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== DSL ====
|
// ==== DSL ====
|
||||||
fun materialType(
|
fun materialType(
|
||||||
id: Long? = null,
|
id: Long? = null,
|
||||||
name: String = "name",
|
name: String = "name",
|
||||||
prefix: String = "PRE",
|
prefix: String = "PRE",
|
||||||
usePercentages: Boolean = false,
|
usePercentages: Boolean = false,
|
||||||
systemType: Boolean = false,
|
systemType: Boolean = false,
|
||||||
op: MaterialType.() -> Unit = {}
|
op: MaterialType.() -> Unit = {}
|
||||||
) = MaterialType(id, name, prefix, usePercentages, systemType).apply(op)
|
) = MaterialType(id, name, prefix, usePercentages, systemType).apply(op)
|
||||||
|
|
||||||
fun materialType(
|
fun materialType(
|
||||||
materialType: MaterialType,
|
materialType: MaterialType,
|
||||||
newId: Long? = null,
|
newId: Long? = null,
|
||||||
newName: String? = null,
|
newName: String? = null,
|
||||||
newSystemType: Boolean? = null
|
newSystemType: Boolean? = null
|
||||||
) = with(materialType) {
|
) = with(materialType) {
|
||||||
MaterialType(
|
MaterialType(
|
||||||
newId ?: id,
|
newId ?: id,
|
||||||
newName ?: name,
|
newName ?: name,
|
||||||
prefix,
|
prefix,
|
||||||
usePercentages,
|
usePercentages,
|
||||||
newSystemType ?: systemType
|
newSystemType ?: systemType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun materialTypeSaveDto(
|
@Deprecated("Temporary DSL for transition")
|
||||||
name: String = "name",
|
fun materialType(
|
||||||
prefix: String = "PRE",
|
dto: MaterialTypeDto
|
||||||
usePercentages: Boolean = false,
|
) = MaterialType(dto.id, dto.name, dto.prefix, dto.usePercentages, dto.systemType)
|
||||||
op: MaterialTypeSaveDto.() -> Unit = {}
|
|
||||||
) = MaterialTypeSaveDto(name, prefix, usePercentages).apply(op)
|
|
||||||
|
|
||||||
fun materialTypeUpdateDto(
|
@Deprecated("Temporary DSL for transition")
|
||||||
id: Long = 0L,
|
fun materialTypeDto(
|
||||||
name: String? = null,
|
entity: MaterialType
|
||||||
prefix: String? = null,
|
) = MaterialTypeDto(entity.id!!, entity.name, entity.prefix, entity.usePercentages, entity.systemType)
|
||||||
op: MaterialTypeUpdateDto.() -> Unit = {}
|
|
||||||
) = MaterialTypeUpdateDto(id, name, prefix).apply(op)
|
|
||||||
|
|
||||||
// ==== Exceptions ====
|
|
||||||
private const val MATERIAL_TYPE_NOT_FOUND_EXCEPTION_TITLE = "Material type not found"
|
|
||||||
private const val MATERIAL_TYPE_ALREADY_EXISTS_EXCEPTION_TITLE = "Material type already exists"
|
|
||||||
private const val MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE = "Cannot delete material type"
|
|
||||||
private const val MATERIAL_TYPE_CANNOT_UPDATE_EXCEPTION_TITLE = "Cannot update material type"
|
|
||||||
private const val MATERIAL_TYPE_EXCEPTION_ERROR_CODE = "materialtype"
|
|
||||||
|
|
||||||
fun materialTypeIdNotFoundException(id: Long) =
|
|
||||||
NotFoundException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_NOT_FOUND_EXCEPTION_TITLE,
|
|
||||||
"A material type with the id $id could not be found",
|
|
||||||
id
|
|
||||||
)
|
|
||||||
|
|
||||||
fun materialTypeNameNotFoundException(name: String) =
|
|
||||||
NotFoundException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_NOT_FOUND_EXCEPTION_TITLE,
|
|
||||||
"A material type with the name $name could not be found",
|
|
||||||
name,
|
|
||||||
"name"
|
|
||||||
)
|
|
||||||
|
|
||||||
fun materialTypeIdAlreadyExistsException(id: Long) =
|
|
||||||
AlreadyExistsException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_ALREADY_EXISTS_EXCEPTION_TITLE,
|
|
||||||
"A material type with the id $id already exists",
|
|
||||||
id
|
|
||||||
)
|
|
||||||
|
|
||||||
fun materialTypeNameAlreadyExistsException(name: String) =
|
|
||||||
AlreadyExistsException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_ALREADY_EXISTS_EXCEPTION_TITLE,
|
|
||||||
"A material type with the name $name already exists",
|
|
||||||
name,
|
|
||||||
"name"
|
|
||||||
)
|
|
||||||
|
|
||||||
fun materialTypePrefixAlreadyExistsException(prefix: String) =
|
|
||||||
AlreadyExistsException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_ALREADY_EXISTS_EXCEPTION_TITLE,
|
|
||||||
"A material type with the prefix $prefix already exists",
|
|
||||||
prefix,
|
|
||||||
"prefix"
|
|
||||||
)
|
|
||||||
|
|
||||||
fun cannotUpdateSystemMaterialTypeException(materialType: MaterialType) =
|
|
||||||
CannotUpdateException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_CANNOT_UPDATE_EXCEPTION_TITLE,
|
|
||||||
"Cannot update material type ${materialType.name} because it is a system material type"
|
|
||||||
)
|
|
||||||
|
|
||||||
fun cannotDeleteMaterialTypeException(materialType: MaterialType) =
|
|
||||||
CannotDeleteException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE,
|
|
||||||
"Cannot delete material type ${materialType.name} because one or more materials depends on it"
|
|
||||||
)
|
|
||||||
|
|
||||||
fun cannotDeleteSystemMaterialTypeException(materialType: MaterialType) =
|
|
||||||
CannotDeleteException(
|
|
||||||
MATERIAL_TYPE_EXCEPTION_ERROR_CODE,
|
|
||||||
MATERIAL_TYPE_CANNOT_DELETE_EXCEPTION_TITLE,
|
|
||||||
"Cannot delete material type ${materialType.name} because it is a system material type"
|
|
||||||
)
|
|
|
@ -70,7 +70,7 @@ data class Recipe(
|
||||||
groupsInformation.firstOrNull { it.group.id == groupId }
|
groupsInformation.firstOrNull { it.group.id == groupId }
|
||||||
|
|
||||||
fun imageUrl(deploymentUrl: String, name: String) =
|
fun imageUrl(deploymentUrl: String, name: String) =
|
||||||
"$deploymentUrl${Constants.ControllerPaths.file}?path=${
|
"$deploymentUrl${Constants.ControllerPaths.FILE}?path=${
|
||||||
URLEncoder.encode(
|
URLEncoder.encode(
|
||||||
"${this.imagesDirectoryPath}/$name",
|
"${this.imagesDirectoryPath}/$name",
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface MaterialRepository : JpaRepository<Material, Long> {
|
||||||
fun existsByNameAndIdNot(name: String, id: Long): Boolean
|
fun existsByNameAndIdNot(name: String, id: Long): Boolean
|
||||||
|
|
||||||
/** Gets all non mix type materials. */
|
/** Gets all non mix type materials. */
|
||||||
fun getAllByIsMixTypeIsFalse(): Collection<Material>
|
fun findAllByIsMixTypeIsFalse(): Collection<Material>
|
||||||
|
|
||||||
/** Updates the [inventoryQuantity] of the [Material] with the given [id]. */
|
/** Updates the [inventoryQuantity] of the [Material] with the given [id]. */
|
||||||
@Modifying
|
@Modifying
|
||||||
|
|
|
@ -1,30 +1,33 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.repository
|
package dev.fyloz.colorrecipesexplorer.repository
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import org.springframework.data.jpa.repository.Query
|
import org.springframework.data.jpa.repository.Query
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
interface MaterialTypeRepository : NamedJpaRepository<MaterialType> {
|
interface MaterialTypeRepository : JpaRepository<MaterialType, Long> {
|
||||||
/** Checks if a material type exists with the given [prefix]. */
|
|
||||||
fun existsByPrefix(prefix: String): Boolean
|
|
||||||
|
|
||||||
/** Checks if a system material type with the given [id] exists. */
|
/** Checks if a system material type with the given [id] exists. */
|
||||||
fun existsByIdAndSystemTypeIsTrue(id: Long): Boolean
|
fun existsByIdAndSystemTypeIs(id: Long, systemType: Boolean): Boolean
|
||||||
|
|
||||||
/** Gets all material types which are not system types. */
|
/** Checks if a material type with the given [name] and a different [id] exists. */
|
||||||
fun findAllBySystemTypeIs(value: Boolean): Collection<MaterialType>
|
fun existsByNameAndIdNot(name: String, id: Long): Boolean
|
||||||
|
|
||||||
/** Gets the material type with the given [prefix]. */
|
/** Checks if a material type with the given [prefix] and a different [id] exists. */
|
||||||
fun findByPrefix(prefix: String): MaterialType?
|
fun existsByPrefixAndIdNot(prefix: String, id: Long): Boolean
|
||||||
|
|
||||||
|
/** Find all material types which are or not [systemType]s. */
|
||||||
|
fun findAllBySystemTypeIs(systemType: Boolean): Collection<MaterialType>
|
||||||
|
|
||||||
|
/** Find the material type with the given [name]. */
|
||||||
|
fun findByName(name: String): MaterialType?
|
||||||
|
|
||||||
|
/** Checks if a material depends on the material type with the given [id]. */
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
select case when(count(m.id) > 0) then false else true end
|
select case when(count(m) > 0) then true else false end
|
||||||
from MaterialType t
|
from Material m where m.materialType.id = :id
|
||||||
left join Material m on t.id = m.materialType.id
|
"""
|
||||||
where t.id = :id
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
fun canBeDeleted(id: Long): Boolean
|
fun isUsedByMaterial(id: Long): Boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import org.springframework.web.multipart.MultipartFile
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(Constants.ControllerPaths.file)
|
@RequestMapping(Constants.ControllerPaths.FILE)
|
||||||
class FileController(
|
class FileController(
|
||||||
private val fileLogic: WriteableFileLogic,
|
private val fileLogic: WriteableFileLogic,
|
||||||
private val configurationLogic: ConfigurationLogic
|
private val configurationLogic: ConfigurationLogic
|
||||||
|
@ -43,6 +43,6 @@ class FileController(
|
||||||
|
|
||||||
private fun created(path: String): ResponseEntity<Void> =
|
private fun created(path: String): ResponseEntity<Void> =
|
||||||
ResponseEntity
|
ResponseEntity
|
||||||
.created(URI.create("${configurationLogic.get(ConfigurationType.INSTANCE_URL)}${Constants.ControllerPaths.file}?path=$path"))
|
.created(URI.create("${configurationLogic.get(ConfigurationType.INSTANCE_URL)}${Constants.ControllerPaths.FILE}?path=$path"))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.springframework.web.multipart.MultipartFile
|
||||||
import javax.validation.Valid
|
import javax.validation.Valid
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(Constants.ControllerPaths.material)
|
@RequestMapping(Constants.ControllerPaths.MATERIAL)
|
||||||
@Profile("!emergency")
|
@Profile("!emergency")
|
||||||
@PreAuthorizeViewCatalog
|
@PreAuthorizeViewCatalog
|
||||||
class MaterialController(
|
class MaterialController(
|
||||||
|
@ -34,7 +34,7 @@ class MaterialController(
|
||||||
@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||||
@PreAuthorize("hasAuthority('EDIT_MATERIALS')")
|
@PreAuthorize("hasAuthority('EDIT_MATERIALS')")
|
||||||
fun save(@Valid material: MaterialSaveDto, simdutFile: MultipartFile?) =
|
fun save(@Valid material: MaterialSaveDto, simdutFile: MultipartFile?) =
|
||||||
created<MaterialDto>(Constants.ControllerPaths.material) {
|
created<MaterialDto>(Constants.ControllerPaths.MATERIAL) {
|
||||||
materialLogic.save(material.copy(simdutFile = simdutFile))
|
materialLogic.save(material.copy(simdutFile = simdutFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +1,46 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.rest
|
package dev.fyloz.colorrecipesexplorer.rest
|
||||||
|
|
||||||
|
import dev.fyloz.colorrecipesexplorer.Constants
|
||||||
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
|
import dev.fyloz.colorrecipesexplorer.config.annotations.PreAuthorizeViewCatalog
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
import dev.fyloz.colorrecipesexplorer.logic.MaterialTypeLogic
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeSaveDto
|
|
||||||
import dev.fyloz.colorrecipesexplorer.model.MaterialTypeUpdateDto
|
|
||||||
import org.springframework.context.annotation.Profile
|
import org.springframework.context.annotation.Profile
|
||||||
import org.springframework.security.access.prepost.PreAuthorize
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import javax.validation.Valid
|
import javax.validation.Valid
|
||||||
|
|
||||||
private const val MATERIAL_TYPE_CONTROLLER_PATH = "api/materialtype"
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(MATERIAL_TYPE_CONTROLLER_PATH)
|
@RequestMapping(Constants.ControllerPaths.MATERIAL_TYPE)
|
||||||
@Profile("!emergency")
|
@Profile("!emergency")
|
||||||
@PreAuthorizeViewCatalog
|
@PreAuthorizeViewCatalog
|
||||||
class MaterialTypeController(private val materialTypeLogic: MaterialTypeLogic) {
|
class MaterialTypeController(private val materialTypeLogic: MaterialTypeLogic) {
|
||||||
@GetMapping
|
@GetMapping
|
||||||
fun getAll() =
|
fun getAll() =
|
||||||
ok(materialTypeLogic.getAllForOutput())
|
ok(materialTypeLogic.getAll())
|
||||||
|
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
fun getById(@PathVariable id: Long) =
|
fun getById(@PathVariable id: Long) =
|
||||||
ok(materialTypeLogic.getByIdForOutput(id))
|
ok(materialTypeLogic.getById(id))
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||||
fun save(@Valid @RequestBody materialType: MaterialTypeSaveDto) =
|
fun save(@Valid @RequestBody materialType: MaterialTypeDto) =
|
||||||
created<MaterialType>(MATERIAL_TYPE_CONTROLLER_PATH) {
|
created<MaterialTypeDto>(Constants.ControllerPaths.MATERIAL_TYPE) {
|
||||||
materialTypeLogic.save(materialType)
|
materialTypeLogic.save(materialType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping
|
@PutMapping
|
||||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||||
fun update(@Valid @RequestBody materialType: MaterialTypeUpdateDto) =
|
fun update(@Valid @RequestBody materialType: MaterialTypeDto) =
|
||||||
noContent {
|
noContent {
|
||||||
materialTypeLogic.update(materialType)
|
materialTypeLogic.updateNonSystemType(materialType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("{id}")
|
@DeleteMapping("{id}")
|
||||||
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
@PreAuthorize("hasAuthority('EDIT_MATERIAL_TYPES')")
|
||||||
fun deleteById(@PathVariable id: Long) =
|
fun deleteById(@PathVariable id: Long) =
|
||||||
noContent {
|
noContent {
|
||||||
materialTypeLogic.deleteById(id)
|
materialTypeLogic.deleteById(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,17 @@ interface MaterialService : Service<MaterialDto, Material, MaterialRepository> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ServiceComponent
|
@ServiceComponent
|
||||||
class DefaultMaterialService(repository: MaterialRepository, @Qualifier("defaultFileLogic") val fileLogic: FileLogic) :
|
class DefaultMaterialService(
|
||||||
|
repository: MaterialRepository,
|
||||||
|
private val materialTypeService: MaterialTypeService,
|
||||||
|
@Qualifier("defaultFileLogic") val fileLogic: FileLogic
|
||||||
|
) :
|
||||||
BaseService<MaterialDto, Material, MaterialRepository>(repository), MaterialService {
|
BaseService<MaterialDto, Material, MaterialRepository>(repository), MaterialService {
|
||||||
override fun existsByName(name: String, id: Long?) = repository.existsByNameAndIdNot(name, id ?: 0)
|
override fun existsByName(name: String, id: Long?) = repository.existsByNameAndIdNot(name, id ?: 0)
|
||||||
override fun getAllNotMixType() = repository.getAllByIsMixTypeIsFalse().map(this::toDto)
|
override fun getAllNotMixType() = repository.findAllByIsMixTypeIsFalse().map(::toDto)
|
||||||
override fun updateInventoryQuantityById(id: Long, inventoryQuantity: Float) = repository.updateInventoryQuantityById(id, inventoryQuantity)
|
override fun updateInventoryQuantityById(id: Long, inventoryQuantity: Float) =
|
||||||
|
repository.updateInventoryQuantityById(id, inventoryQuantity)
|
||||||
|
|
||||||
override fun isUsedByMixMaterialOrMixType(id: Long) = repository.isUsedByMixMaterialOrMixType(id)
|
override fun isUsedByMixMaterialOrMixType(id: Long) = repository.isUsedByMixMaterialOrMixType(id)
|
||||||
|
|
||||||
override fun toDto(entity: Material) =
|
override fun toDto(entity: Material) =
|
||||||
|
@ -38,21 +44,21 @@ class DefaultMaterialService(repository: MaterialRepository, @Qualifier("default
|
||||||
entity.name,
|
entity.name,
|
||||||
entity.inventoryQuantity,
|
entity.inventoryQuantity,
|
||||||
entity.isMixType,
|
entity.isMixType,
|
||||||
entity.materialType!!,
|
materialTypeService.toDto(entity.materialType!!),
|
||||||
getSimdutUrl(entity)
|
getSimdutUrl(entity)
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun toEntity(dto: MaterialDto) =
|
override fun toEntity(dto: MaterialDto) =
|
||||||
Material(dto.id, dto.name, dto.inventoryQuantity, dto.isMixType, dto.materialType)
|
Material(dto.id, dto.name, dto.inventoryQuantity, dto.isMixType, materialTypeService.toEntity(dto.materialType))
|
||||||
|
|
||||||
private fun getSimdutUrl(material: Material): String? {
|
private fun getSimdutUrl(material: Material): String? {
|
||||||
val filePath = "${Constants.FilePaths.simdut}/${material.name}.pdf"
|
val filePath = "${Constants.FilePaths.SIMDUT}/${material.name}.pdf"
|
||||||
|
|
||||||
if (!fileLogic.exists(filePath)) {
|
if (!fileLogic.exists(filePath)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val encodedPath = URLEncoder.encode(filePath, StandardCharsets.UTF_8)
|
val encodedPath = URLEncoder.encode(filePath, StandardCharsets.UTF_8)
|
||||||
return "${Constants.ControllerPaths.file}?path=$encodedPath"
|
return "${Constants.ControllerPaths.FILE}?path=$encodedPath"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package dev.fyloz.colorrecipesexplorer.service
|
||||||
|
|
||||||
|
import dev.fyloz.colorrecipesexplorer.config.annotations.ServiceComponent
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
|
import dev.fyloz.colorrecipesexplorer.model.MaterialType
|
||||||
|
import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
|
||||||
|
|
||||||
|
interface MaterialTypeService : Service<MaterialTypeDto, MaterialType, MaterialTypeRepository> {
|
||||||
|
/** Checks if a system material type with the given [id] exists. */
|
||||||
|
fun existsById(id: Long, systemType: Boolean): Boolean
|
||||||
|
|
||||||
|
/** Checks if a material type with the given [name] and a different [id] exists. */
|
||||||
|
fun existsByName(name: String, id: Long?): Boolean
|
||||||
|
|
||||||
|
/** Checks if a material type with the given [prefix] and a different [id] exists. */
|
||||||
|
fun existsByPrefix(prefix: String, id: Long?): Boolean
|
||||||
|
|
||||||
|
/** Gets all material types which are or not a [systemType]. */
|
||||||
|
fun getAll(systemType: Boolean): Collection<MaterialTypeDto>
|
||||||
|
|
||||||
|
/** Gets the material type with the given [name]. */
|
||||||
|
fun getByName(name: String): MaterialTypeDto?
|
||||||
|
|
||||||
|
/** Checks if a material depends on the material type with the given [id]. */
|
||||||
|
fun isUsedByMaterial(id: Long): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
@ServiceComponent
|
||||||
|
class DefaultMaterialTypeService(repository: MaterialTypeRepository) :
|
||||||
|
BaseService<MaterialTypeDto, MaterialType, MaterialTypeRepository>(repository), MaterialTypeService {
|
||||||
|
override fun existsById(id: Long, systemType: Boolean) = repository.existsByIdAndSystemTypeIs(id, systemType)
|
||||||
|
override fun existsByName(name: String, id: Long?) = repository.existsByNameAndIdNot(name, id ?: 0)
|
||||||
|
override fun existsByPrefix(prefix: String, id: Long?) = repository.existsByPrefixAndIdNot(prefix, id ?: 0)
|
||||||
|
override fun getAll(systemType: Boolean) = repository.findAllBySystemTypeIs(systemType).map(::toDto)
|
||||||
|
override fun getByName(name: String) = repository.findByName(name)?.let(::toDto)
|
||||||
|
|
||||||
|
override fun isUsedByMaterial(id: Long) = repository.isUsedByMaterial(id)
|
||||||
|
|
||||||
|
override fun toDto(entity: MaterialType) =
|
||||||
|
MaterialTypeDto(entity.id!!, entity.name, entity.prefix, entity.usePercentages, entity.systemType)
|
||||||
|
|
||||||
|
override fun toEntity(dto: MaterialTypeDto) =
|
||||||
|
MaterialType(dto.id, dto.name, dto.prefix, dto.usePercentages, dto.systemType)
|
||||||
|
}
|
|
@ -31,6 +31,12 @@ interface Service<D : EntityDto, E : ModelEntity, R : JpaRepository<E, Long>> {
|
||||||
|
|
||||||
/** Deletes the entity with the given [id]. */
|
/** Deletes the entity with the given [id]. */
|
||||||
fun deleteById(id: Long)
|
fun deleteById(id: Long)
|
||||||
|
|
||||||
|
/** Converts the given [entity] to a DTO. */
|
||||||
|
fun toDto(entity: E): D
|
||||||
|
|
||||||
|
/** Converts the given [dto] to an entity. */
|
||||||
|
fun toEntity(dto: D): E
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BaseService<D : EntityDto, E : ModelEntity, R : JpaRepository<E, Long>>(protected val repository: R) :
|
abstract class BaseService<D : EntityDto, E : ModelEntity, R : JpaRepository<E, Long>>(protected val repository: R) :
|
||||||
|
@ -58,7 +64,4 @@ abstract class BaseService<D : EntityDto, E : ModelEntity, R : JpaRepository<E,
|
||||||
override fun deleteById(id: Long) {
|
override fun deleteById(id: Long) {
|
||||||
repository.deleteById(id)
|
repository.deleteById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun toDto(entity: E): D
|
|
||||||
abstract fun toEntity(dto: D): E
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ package dev.fyloz.colorrecipesexplorer.logic
|
||||||
|
|
||||||
import dev.fyloz.colorrecipesexplorer.dtos.MaterialDto
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialDto
|
||||||
import dev.fyloz.colorrecipesexplorer.dtos.MaterialSaveDto
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialSaveDto
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
||||||
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
import dev.fyloz.colorrecipesexplorer.logic.files.WriteableFileLogic
|
||||||
|
@ -31,9 +32,7 @@ class DefaultMaterialLogicTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val materialType = MaterialType(
|
private val materialType = MaterialTypeDto(1L, "Unit test material type", "UNT", usePercentages = false)
|
||||||
1L, "Unit test material type", "UNT", usePercentages = false, systemType = false
|
|
||||||
) // TODO move to DTO
|
|
||||||
private val material = MaterialDto(1L, "Unit test material", 1000f, false, materialType)
|
private val material = MaterialDto(1L, "Unit test material", 1000f, false, materialType)
|
||||||
private val materialMixType = material.copy(id = 2L, isMixType = true)
|
private val materialMixType = material.copy(id = 2L, isMixType = true)
|
||||||
private val materialMixType2 = material.copy(id = 3L, isMixType = true)
|
private val materialMixType2 = material.copy(id = 3L, isMixType = true)
|
||||||
|
@ -59,8 +58,8 @@ class DefaultMaterialLogicTest {
|
||||||
private val simdutFileMock = MockMultipartFile(
|
private val simdutFileMock = MockMultipartFile(
|
||||||
"Unit test SIMDUT",
|
"Unit test SIMDUT",
|
||||||
byteArrayOf(1, 2, 3, 4)
|
byteArrayOf(1, 2, 3, 4)
|
||||||
) // Put some content in the mock file so it is not ignored
|
) // Put some content in the mock file, so it is not ignored
|
||||||
private val materialSaveDto = MaterialSaveDto(1L, "Unit test material", 1000f, materialType.id!!, simdutFileMock)
|
private val materialSaveDto = MaterialSaveDto(1L, "Unit test material", 1000f, materialType.id, simdutFileMock)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
recipe.mixes.addAll(listOf(mix, mix2))
|
recipe.mixes.addAll(listOf(mix, mix2))
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
package dev.fyloz.colorrecipesexplorer.logic
|
||||||
|
|
||||||
|
import dev.fyloz.colorrecipesexplorer.dtos.MaterialTypeDto
|
||||||
|
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||||
|
import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
||||||
|
import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException
|
||||||
|
import dev.fyloz.colorrecipesexplorer.service.MaterialTypeService
|
||||||
|
import io.mockk.*
|
||||||
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
|
class DefaultMaterialTypeLogicTest {
|
||||||
|
private val materialTypeServiceMock = mockk<MaterialTypeService>()
|
||||||
|
|
||||||
|
private val materialTypeLogic = spyk(DefaultMaterialTypeLogic(materialTypeServiceMock))
|
||||||
|
|
||||||
|
private val materialType = MaterialTypeDto(1L, "Unit test material type", "UTMT", false)
|
||||||
|
private val systemMaterialType =
|
||||||
|
MaterialTypeDto(2L, "Unit test system material type", "UTSMT", false, systemType = true)
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
internal fun afterEach() {
|
||||||
|
clearAllMocks()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAll_normalBehavior_returnsFromService() {
|
||||||
|
// Arrange
|
||||||
|
val expectedMaterialTypes = listOf(materialType, systemMaterialType)
|
||||||
|
|
||||||
|
every { materialTypeServiceMock.getAll(any()) } returns expectedMaterialTypes
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actualMaterialTypes = materialTypeLogic.getAll(true)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(expectedMaterialTypes, actualMaterialTypes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getByName_normalBehavior_returnsMaterialType() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.getByName(any()) } returns materialType
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actualMaterialType = materialTypeLogic.getByName(materialType.name)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(materialType, actualMaterialType)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getByName_nameNotFound_returnsNull() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.getByName(any()) } returns null
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actualMaterialType = materialTypeLogic.getByName(materialType.name)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNull(actualMaterialType)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateNonSystemType_normalBehavior_callsUpdate() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsById(any(), any()) } returns false
|
||||||
|
every { materialTypeLogic.update(any()) } returnsArgument 0
|
||||||
|
|
||||||
|
// Act
|
||||||
|
materialTypeLogic.updateNonSystemType(materialType)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify {
|
||||||
|
materialTypeLogic.update(materialType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateNonSystemType_isSystemType_throwsCannotUpdateException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsById(any(), any()) } returns true
|
||||||
|
every { materialTypeLogic.update(any()) } returnsArgument 0
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<CannotUpdateException> { materialTypeLogic.updateNonSystemType(materialType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun save_nameExists_throwsAlreadyExistsException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsByName(any(), any()) } returns true
|
||||||
|
every { materialTypeServiceMock.existsByPrefix(any(), any()) } returns false
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<AlreadyExistsException> { materialTypeLogic.save(materialType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun save_prefixExists_throwsAlreadyExistsException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsByName(any(), any()) } returns false
|
||||||
|
every { materialTypeServiceMock.existsByPrefix(any(), any()) } returns true
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<AlreadyExistsException> { materialTypeLogic.save(materialType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun update_nameExists_throwsAlreadyExistsException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsByName(any(), any()) } returns true
|
||||||
|
every { materialTypeServiceMock.existsByPrefix(any(), any()) } returns false
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<AlreadyExistsException> { materialTypeLogic.update(materialType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun update_prefixExists_throwsAlreadyExistsException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.existsByName(any(), any()) } returns false
|
||||||
|
every { materialTypeServiceMock.existsByPrefix(any(), any()) } returns true
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<AlreadyExistsException> { materialTypeLogic.update(materialType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun deleteById_usedByMaterial_throwsCannotDeleteException() {
|
||||||
|
// Arrange
|
||||||
|
every { materialTypeServiceMock.isUsedByMaterial(any()) } returns true
|
||||||
|
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
assertThrows<CannotDeleteException> { materialTypeLogic.deleteById(materialType.id) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,182 +1,182 @@
|
||||||
package dev.fyloz.colorrecipesexplorer.logic
|
//package dev.fyloz.colorrecipesexplorer.logic
|
||||||
|
//
|
||||||
import com.nhaarman.mockitokotlin2.*
|
//import com.nhaarman.mockitokotlin2.*
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
//import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
//import dev.fyloz.colorrecipesexplorer.exception.CannotDeleteException
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException
|
//import dev.fyloz.colorrecipesexplorer.exception.CannotUpdateException
|
||||||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
//import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
||||||
import dev.fyloz.colorrecipesexplorer.model.*
|
//import dev.fyloz.colorrecipesexplorer.model.*
|
||||||
import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
|
//import dev.fyloz.colorrecipesexplorer.repository.MaterialTypeRepository
|
||||||
import org.junit.jupiter.api.AfterEach
|
//import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.Test
|
//import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
//import org.junit.jupiter.api.TestInstance
|
||||||
import org.junit.jupiter.api.assertThrows
|
//import org.junit.jupiter.api.assertThrows
|
||||||
import kotlin.test.assertEquals
|
//import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
//import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
//import kotlin.test.assertTrue
|
||||||
|
//
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
//@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class MaterialTypeLogicTest :
|
//class MaterialTypeLogicTest :
|
||||||
AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeLogic, MaterialTypeRepository>() {
|
// AbstractExternalNamedModelServiceTest<MaterialType, MaterialTypeSaveDto, MaterialTypeUpdateDto, MaterialTypeLogic, MaterialTypeRepository>() {
|
||||||
override val repository: MaterialTypeRepository = mock()
|
// override val repository: MaterialTypeRepository = mock()
|
||||||
private val materialService: MaterialLogic = mock()
|
// private val materialService: MaterialLogic = mock()
|
||||||
override val logic: MaterialTypeLogic = spy(DefaultMaterialTypeLogic(repository))
|
// override val logic: MaterialTypeLogic = spy(DefaultMaterialTypeLogic(repository))
|
||||||
override val entity: MaterialType = materialType(id = 0L, name = "material type", prefix = "MAT")
|
// override val entity: MaterialType = materialType(id = 0L, name = "material type", prefix = "MAT")
|
||||||
override val anotherEntity: MaterialType = materialType(id = 1L, name = "another material type", prefix = "AMT")
|
// override val anotherEntity: MaterialType = materialType(id = 1L, name = "another material type", prefix = "AMT")
|
||||||
override val entityWithEntityName: MaterialType = materialType(2L, name = entity.name, prefix = "EEN")
|
// override val entityWithEntityName: MaterialType = materialType(2L, name = entity.name, prefix = "EEN")
|
||||||
private val systemType = materialType(id = 3L, name = "systype", prefix = "SYS", systemType = true)
|
// private val systemType = materialType(id = 3L, name = "systype", prefix = "SYS", systemType = true)
|
||||||
private val anotherSystemType = materialType(id = 4L, name = "another systype", prefix = "ASY", systemType = true)
|
// private val anotherSystemType = materialType(id = 4L, name = "another systype", prefix = "ASY", systemType = true)
|
||||||
override val entitySaveDto: MaterialTypeSaveDto = spy(materialTypeSaveDto(name = "material type", prefix = "MAT"))
|
// override val entitySaveDto: MaterialTypeSaveDto = spy(materialTypeSaveDto(name = "material type", prefix = "MAT"))
|
||||||
override val entityUpdateDto: MaterialTypeUpdateDto =
|
// override val entityUpdateDto: MaterialTypeUpdateDto =
|
||||||
spy(materialTypeUpdateDto(id = 0L, name = "material type", prefix = "MAT"))
|
// spy(materialTypeUpdateDto(id = 0L, name = "material type", prefix = "MAT"))
|
||||||
|
//
|
||||||
@AfterEach
|
// @AfterEach
|
||||||
override fun afterEach() {
|
// override fun afterEach() {
|
||||||
reset(materialService)
|
// reset(materialService)
|
||||||
super.afterEach()
|
// super.afterEach()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// existsByPrefix()
|
// // existsByPrefix()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `existsByPrefix() returns true when a material type with the given prefix exists`() {
|
// fun `existsByPrefix() returns true when a material type with the given prefix exists`() {
|
||||||
whenever(repository.existsByPrefix(entity.prefix)).doReturn(true)
|
// whenever(repository.existsByPrefix(entity.prefix)).doReturn(true)
|
||||||
|
//
|
||||||
val found = logic.existsByPrefix(entity.prefix)
|
// val found = logic.existsByPrefix(entity.prefix)
|
||||||
|
//
|
||||||
assertTrue(found)
|
// assertTrue(found)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `existsByPrefix() returns false when no material type with the given prefix exists`() {
|
// fun `existsByPrefix() returns false when no material type with the given prefix exists`() {
|
||||||
whenever(repository.existsByPrefix(entity.prefix)).doReturn(false)
|
// whenever(repository.existsByPrefix(entity.prefix)).doReturn(false)
|
||||||
|
//
|
||||||
val found = logic.existsByPrefix(entity.prefix)
|
// val found = logic.existsByPrefix(entity.prefix)
|
||||||
|
//
|
||||||
assertFalse(found)
|
// assertFalse(found)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// getAllSystemTypes()
|
// // getAllSystemTypes()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `getAllSystemTypes() returns all system types`() {
|
// fun `getAllSystemTypes() returns all system types`() {
|
||||||
whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType))
|
// whenever(repository.findAllBySystemTypeIs(true)).doReturn(listOf(systemType, anotherSystemType))
|
||||||
|
//
|
||||||
val found = logic.getAllSystemTypes()
|
// val found = logic.getAllSystemTypes()
|
||||||
|
//
|
||||||
assertTrue(found.contains(systemType))
|
// assertTrue(found.contains(systemType))
|
||||||
assertTrue(found.contains(anotherSystemType))
|
// assertTrue(found.contains(anotherSystemType))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// getAllNonSystemTypes()
|
// // getAllNonSystemTypes()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `getAllNonSystemTypes() returns all non system types`() {
|
// fun `getAllNonSystemTypes() returns all non system types`() {
|
||||||
whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity))
|
// whenever(repository.findAllBySystemTypeIs(false)).doReturn(listOf(entity, anotherEntity))
|
||||||
|
//
|
||||||
val found = logic.getAllNonSystemType()
|
// val found = logic.getAllNonSystemType()
|
||||||
|
//
|
||||||
assertTrue(found.contains(entity))
|
// assertTrue(found.contains(entity))
|
||||||
assertTrue(found.contains(anotherEntity))
|
// assertTrue(found.contains(anotherEntity))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// save()
|
// // save()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
override fun `save(dto) calls and returns save() with the created entity`() {
|
// override fun `save(dto) calls and returns save() with the created entity`() {
|
||||||
withBaseSaveDtoTest(entity, entitySaveDto, logic)
|
// withBaseSaveDtoTest(entity, entitySaveDto, logic)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// saveMaterialType()
|
// // saveMaterialType()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `saveMaterialType() throws AlreadyExistsException when a material type with the given prefix already exists`() {
|
// fun `saveMaterialType() throws AlreadyExistsException when a material type with the given prefix already exists`() {
|
||||||
doReturn(true).whenever(logic).existsByPrefix(entity.prefix)
|
// doReturn(true).whenever(logic).existsByPrefix(entity.prefix)
|
||||||
|
//
|
||||||
assertThrows<AlreadyExistsException> { logic.save(entity) }
|
// assertThrows<AlreadyExistsException> { logic.save(entity) }
|
||||||
.assertErrorCode("prefix")
|
// .assertErrorCode("prefix")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// update()
|
// // update()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
override fun `update(dto) calls and returns update() with the created entity`() =
|
// override fun `update(dto) calls and returns update() with the created entity`() =
|
||||||
withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
// withBaseUpdateDtoTest(entity, entityUpdateDto, logic, { any() })
|
||||||
|
//
|
||||||
override fun `update() saves in the repository and returns the updated value`() {
|
// override fun `update() saves in the repository and returns the updated value`() {
|
||||||
whenever(repository.save(entity)).doReturn(entity)
|
// whenever(repository.save(entity)).doReturn(entity)
|
||||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
// whenever(repository.findByName(entity.name)).doReturn(null)
|
||||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
// whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
// doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
// doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||||
|
//
|
||||||
val found = logic.update(entity)
|
// val found = logic.update(entity)
|
||||||
|
//
|
||||||
verify(repository).save(entity)
|
// verify(repository).save(entity)
|
||||||
assertEquals(entity, found)
|
// assertEquals(entity, found)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun `update() throws NotFoundException when no entity with the given id exists in the repository`() {
|
// override fun `update() throws NotFoundException when no entity with the given id exists in the repository`() {
|
||||||
whenever(repository.findByName(entity.name)).doReturn(null)
|
// whenever(repository.findByName(entity.name)).doReturn(null)
|
||||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
// whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||||
doReturn(false).whenever(logic).existsById(entity.id!!)
|
// doReturn(false).whenever(logic).existsById(entity.id!!)
|
||||||
doReturn(null).whenever(logic).getById(entity.id!!)
|
// doReturn(null).whenever(logic).getById(entity.id!!)
|
||||||
|
//
|
||||||
assertThrows<NotFoundException> { logic.update(entity) }
|
// assertThrows<NotFoundException> { logic.update(entity) }
|
||||||
.assertErrorCode()
|
// .assertErrorCode()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
|
// override fun `update() throws AlreadyExistsException when an entity with the updated name exists`() {
|
||||||
whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName)
|
// whenever(repository.findByName(entity.name)).doReturn(entityWithEntityName)
|
||||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
// whenever(repository.findByPrefix(entity.prefix)).doReturn(null)
|
||||||
doReturn(true).whenever(logic).existsById(entity.id!!)
|
// doReturn(true).whenever(logic).existsById(entity.id!!)
|
||||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
// doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||||
|
//
|
||||||
assertThrows<AlreadyExistsException> { logic.update(entity) }
|
// assertThrows<AlreadyExistsException> { logic.update(entity) }
|
||||||
.assertErrorCode("name")
|
// .assertErrorCode("name")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `update() throws AlreadyExistsException when an entity with the updated prefix exists`() {
|
// fun `update() throws AlreadyExistsException when an entity with the updated prefix exists`() {
|
||||||
val anotherMaterialType = materialType(prefix = entity.prefix)
|
// val anotherMaterialType = materialType(prefix = entity.prefix)
|
||||||
whenever(repository.findByPrefix(entity.prefix)).doReturn(anotherMaterialType)
|
// whenever(repository.findByPrefix(entity.prefix)).doReturn(anotherMaterialType)
|
||||||
doReturn(entity).whenever(logic).getById(entity.id!!)
|
// doReturn(entity).whenever(logic).getById(entity.id!!)
|
||||||
|
//
|
||||||
assertThrows<AlreadyExistsException> { logic.update(entity) }
|
// assertThrows<AlreadyExistsException> { logic.update(entity) }
|
||||||
.assertErrorCode("prefix")
|
// .assertErrorCode("prefix")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `update() throws CannotUpdateException when updating a system material type`() {
|
// fun `update() throws CannotUpdateException when updating a system material type`() {
|
||||||
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
// whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
||||||
|
//
|
||||||
assertThrows<CannotUpdateException> { logic.update(systemType) }
|
// assertThrows<CannotUpdateException> { logic.update(systemType) }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// delete()
|
// // delete()
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
fun `delete() throws CannotDeleteException when deleting a system material type`() {
|
// fun `delete() throws CannotDeleteException when deleting a system material type`() {
|
||||||
whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
// whenever(repository.existsByIdAndSystemTypeIsTrue(systemType.id!!)).doReturn(true)
|
||||||
|
//
|
||||||
assertThrows<CannotDeleteException> { logic.delete(systemType) }
|
// assertThrows<CannotDeleteException> { logic.delete(systemType) }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun `delete() deletes in the repository`() {
|
// override fun `delete() deletes in the repository`() {
|
||||||
whenCanBeDeleted {
|
// whenCanBeDeleted {
|
||||||
super.`delete() deletes in the repository`()
|
// super.`delete() deletes in the repository`()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun `deleteById() deletes the entity with the given id in the repository`() {
|
// override fun `deleteById() deletes the entity with the given id in the repository`() {
|
||||||
whenCanBeDeleted {
|
// whenCanBeDeleted {
|
||||||
super.`deleteById() deletes the entity with the given id in the repository`()
|
// super.`deleteById() deletes the entity with the given id in the repository`()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun whenCanBeDeleted(id: Long = any(), test: () -> Unit) {
|
// private fun whenCanBeDeleted(id: Long = any(), test: () -> Unit) {
|
||||||
whenever(repository.canBeDeleted(id)).doReturn(true)
|
// whenever(repository.canBeDeleted(id)).doReturn(true)
|
||||||
|
//
|
||||||
test()
|
// test()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
|
@ -62,7 +62,7 @@ class MixLogicTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpdate
|
||||||
val mixMaterials = setOf(mixMaterial(material = material(id = 1L), quantity = 1000f))
|
val mixMaterials = setOf(mixMaterial(material = material(id = 1L), quantity = 1000f))
|
||||||
|
|
||||||
whenever(recipeService.getById(recipe.id!!)).doReturn(recipe)
|
whenever(recipeService.getById(recipe.id!!)).doReturn(recipe)
|
||||||
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialType)
|
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialTypeDto(materialType))
|
||||||
whenever(mixMaterialService.create(entitySaveDto.mixMaterials!!)).doReturn(mixMaterials)
|
whenever(mixMaterialService.create(entitySaveDto.mixMaterials!!)).doReturn(mixMaterials)
|
||||||
whenever(
|
whenever(
|
||||||
mixTypeService.getOrCreateForNameAndMaterialType(
|
mixTypeService.getOrCreateForNameAndMaterialType(
|
||||||
|
@ -98,7 +98,7 @@ class MixLogicTest : AbstractExternalModelServiceTest<Mix, MixSaveDto, MixUpdate
|
||||||
doAnswer { it.arguments[0] }.whenever(logic).update(any<Mix>())
|
doAnswer { it.arguments[0] }.whenever(logic).update(any<Mix>())
|
||||||
|
|
||||||
if (mixUpdateDto.materialTypeId != null) {
|
if (mixUpdateDto.materialTypeId != null) {
|
||||||
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialType)
|
whenever(materialTypeService.getById(materialType.id!!)).doReturn(materialTypeDto(materialType))
|
||||||
}
|
}
|
||||||
|
|
||||||
op()
|
op()
|
||||||
|
|
Loading…
Reference in New Issue