diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountModel.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountModel.kt index 7c2a7d0..00a23cc 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountModel.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/AccountModel.kt @@ -23,33 +23,42 @@ private const val EMPLOYEE_PASSWORD_EMPTY_MESSAGE = "Un mot de passe est requis" private const val EMPLOYEE_PASSWORD_TOO_SHORT_MESSAGE = "Le mot de passe doit contenir au moins 8 caractères" @Entity +@Table(name = "employee") data class Employee( @Id override val id: Long, + @Column(name = "first_name") val firstName: String = "", + @Column(name = "last_name") val lastName: String = "", @JsonIgnore val password: String = "", @JsonIgnore + @Column(name = "default_group_user") val isDefaultGroupUser: Boolean = false, @JsonIgnore + @Column(name = "system_user") val isSystemUser: Boolean = false, - @field:ManyToOne + @ManyToOne + @JoinColumn(name = "group_id") @Fetch(FetchMode.SELECT) var group: EmployeeGroup? = null, @Enumerated(EnumType.STRING) @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "employee_permission", joinColumns = [JoinColumn(name = "employee_id")]) + @Column(name = "permission") @Fetch(FetchMode.SUBSELECT) @get:JsonIgnore val permissions: MutableSet = mutableSetOf(), + @Column(name = "last_login_time") var lastLoginTime: LocalDateTime? = null ) : Model { @JsonProperty("permissions") @@ -119,6 +128,7 @@ private const val GROUP_NAME_NULL_MESSAGE = "Un nom est requis" private const val GROUP_PERMISSIONS_EMPTY_MESSAGE = "Au moins une permission est requise" @Entity +@Table(name = "employee_group") data class EmployeeGroup( @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -129,9 +139,12 @@ data class EmployeeGroup( @Enumerated(EnumType.STRING) @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "group_permission", joinColumns = [JoinColumn(name = "group_id")]) + @Column(name = "permission") + @Fetch(FetchMode.SUBSELECT) val permissions: MutableSet = mutableSetOf(), - @OneToMany + @OneToMany(mappedBy = "group") @JsonIgnore val employees: MutableSet = mutableSetOf() ) : NamedModel { diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Company.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Company.kt index b971530..fb45019 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Company.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Company.kt @@ -10,6 +10,7 @@ private const val COMPANY_ID_NULL_MESSAGE = "Un identifiant est requis" private const val COMPANY_NAME_NULL_MESSAGE = "Un nom est requis" @Entity +@Table(name = "company") data class Company( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt index a37379c..c97b836 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Material.kt @@ -18,22 +18,33 @@ private const val MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE = "La quantité d private const val MATERIAL_TYPE_NULL_MESSAGE = "Un type de produit est requis" @Entity +@Table(name = "material") data class Material( - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - override val id: Long?, + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + override val id: Long?, - @Column(unique = true) - override var name: String, + @Column(unique = true) + override var name: String, - var inventoryQuantity: Float, + @Column(name = "inventory_quantity") + var inventoryQuantity: Float, - val isMixType: Boolean, + @Column(name = "mix_type") + val isMixType: Boolean, - @ManyToOne - var materialType: MaterialType? + @ManyToOne + @JoinColumn(name = "material_type_id") + var materialType: MaterialType? ) : NamedModel { - constructor(name: String, inventoryQuantity: Float, isMixType: Boolean, materialType: MaterialType) : this(null, name, inventoryQuantity, isMixType, materialType) + constructor(name: String, inventoryQuantity: Float, isMixType: Boolean, materialType: MaterialType) : this( + null, + name, + inventoryQuantity, + isMixType, + materialType + ) + constructor() : this(null, "", 0f, false, null) override fun equals(other: Any?): Boolean = other is Material && name == other.name @@ -41,48 +52,50 @@ data class Material( } open class MaterialSaveDto( - @field:NotBlank(message = MATERIAL_NAME_NULL_MESSAGE) - val name: String, + @field:NotBlank(message = MATERIAL_NAME_NULL_MESSAGE) + val name: String, - @field:NotNull(message = MATERIAL_INVENTORY_QUANTITY_NULL_MESSAGE) - @field:Min(value = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) - val inventoryQuantity: Float, + @field:NotNull(message = MATERIAL_INVENTORY_QUANTITY_NULL_MESSAGE) + @field:Min(value = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) + val inventoryQuantity: Float, - @field:NotNull(message = MATERIAL_TYPE_NULL_MESSAGE) - val materialType: MaterialType, + @field:NotNull(message = MATERIAL_TYPE_NULL_MESSAGE) + val materialType: MaterialType, - val simdutFile: MultipartFile? = null + val simdutFile: MultipartFile? = null ) : EntityDto { override fun toEntity(): Material = Material(null, name, inventoryQuantity, false, materialType) fun toMaterial() = toEntity() } open class MaterialUpdateDto( - @field:NotNull(message = MATERIAL_ID_NULL_MESSAGE) - val id: Long, + @field:NotNull(message = MATERIAL_ID_NULL_MESSAGE) + val id: Long, - @field:NullOrNotBlank(message = MATERIAL_NAME_NULL_MESSAGE) - val name: String?, + @field:NullOrNotBlank(message = MATERIAL_NAME_NULL_MESSAGE) + val name: String?, - @field:NullOrSize(min = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) - val inventoryQuantity: Float?, + @field:NullOrSize(min = 0, message = MATERIAL_INVENTORY_QUANTITY_NEGATIVE_MESSAGE) + val inventoryQuantity: Float?, - val materialType: MaterialType?, + val materialType: MaterialType?, - val simdutFile: MultipartFile? = null + val simdutFile: MultipartFile? = null ) : EntityDto { - override fun toEntity(): Material = Material(id, name ?: "", inventoryQuantity - ?: Float.MIN_VALUE, false, materialType) + override fun toEntity(): Material = Material( + id, name ?: "", inventoryQuantity + ?: Float.MIN_VALUE, false, materialType + ) fun toMaterial() = toEntity() } data class InventoryMaterial( - @NotNull val id: Long, - @NotNull val name: String, - @NotNull val inventoryQuantity: Float, - @NotNull val materialTypeName: String, - @NotNull val lowQuantity: Boolean = false + @NotNull val id: Long, + @NotNull val name: String, + @NotNull val inventoryQuantity: Float, + @NotNull val materialTypeName: String, + @NotNull val lowQuantity: Boolean = false ) fun Material.toInventoryMaterial(minimumQuantity: Float): InventoryMaterial { @@ -94,34 +107,36 @@ fun Material.toInventoryMaterial(minimumQuantity: Float): InventoryMaterial { // ==== DSL ==== fun material( - id: Long? = null, - name: String = "name", - inventoryQuantity: Float = 0f, - isMixType: Boolean = false, - materialType: MaterialType? = materialType(), - op: Material.() -> Unit = {} + id: Long? = null, + name: String = "name", + inventoryQuantity: Float = 0f, + isMixType: Boolean = false, + materialType: MaterialType? = materialType(), + op: Material.() -> Unit = {} ) = Material(id, name, inventoryQuantity, isMixType, materialType).apply(op) fun material( - material: Material, - id: Long? = null, - name: String? = null, -) = Material(id ?: material.id, name - ?: material.name, material.inventoryQuantity, material.isMixType, material.materialType) + material: Material, + id: Long? = null, + name: String? = null, +) = Material( + id ?: material.id, name + ?: material.name, material.inventoryQuantity, material.isMixType, material.materialType +) fun materialSaveDto( - name: String = "name", - inventoryQuantity: Float = 0f, - materialType: MaterialType = materialType(), - simdutFile: MultipartFile? = null, - op: MaterialSaveDto.() -> Unit = {} + name: String = "name", + inventoryQuantity: Float = 0f, + materialType: MaterialType = materialType(), + simdutFile: MultipartFile? = null, + op: MaterialSaveDto.() -> Unit = {} ) = MaterialSaveDto(name, inventoryQuantity, materialType, simdutFile).apply(op) fun materialUpdateDto( - id: Long = 0L, - name: String? = "name", - inventoryQuantity: Float? = 0f, - materialType: MaterialType? = materialType(), - simdutFile: MultipartFile? = null, - op: MaterialUpdateDto.() -> Unit = {} + id: Long = 0L, + name: String? = "name", + inventoryQuantity: Float? = 0f, + materialType: MaterialType? = materialType(), + simdutFile: MultipartFile? = null, + op: MaterialUpdateDto.() -> Unit = {} ) = MaterialUpdateDto(id, name, inventoryQuantity, materialType, simdutFile).apply(op) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MaterialType.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MaterialType.kt index 2487102..3d5d281 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MaterialType.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MaterialType.kt @@ -17,82 +17,93 @@ private const val MATERIAL_TYPE_PREFIX_SIZE_MESSAGE = "Le préfixe doit faire ex const val IDENTIFIER_PREFIX_NAME = "prefix" @Entity +@Table(name = "material_type") data class MaterialType( - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - override val id: Long? = null, + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + override val id: Long? = null, - @Column(unique = true) - override val name: String = "", + @Column(unique = true) + override val name: String = "", - @Column(unique = true) - val prefix: String = "", + @Column(unique = true) + val prefix: String = "", - @ColumnDefault("false") - val usePercentages: Boolean = false, + @Column(name = "use_percentages") + @ColumnDefault("false") + val usePercentages: Boolean = false, - @ColumnDefault("false") - val systemType: Boolean = false + @Column(name = "system_type") + @ColumnDefault("false") + val systemType: Boolean = false ) : NamedModel { override fun equals(other: Any?): Boolean = other is MaterialType && name == other.name && prefix == other.prefix override fun hashCode(): Int = Objects.hash(name, prefix) } open class MaterialTypeSaveDto( - @field:NotBlank(message = MATERIAL_TYPE_NAME_NULL_MESSAGE) - val name: String, + @field:NotBlank(message = MATERIAL_TYPE_NAME_NULL_MESSAGE) + val name: String, - @field:NotBlank(message = MATERIAL_TYPE_PREFIX_NULL_MESSAGE) - @field:Size(min = 3, max = 3, message = MATERIAL_TYPE_PREFIX_SIZE_MESSAGE) - val prefix: String, + @field:NotBlank(message = MATERIAL_TYPE_PREFIX_NULL_MESSAGE) + @field:Size(min = 3, max = 3, message = MATERIAL_TYPE_PREFIX_SIZE_MESSAGE) + val prefix: String, - val usePercentages: Boolean = false + val usePercentages: Boolean = false ) : EntityDto { override fun toEntity(): MaterialType = - MaterialType(null, name, prefix, usePercentages) + MaterialType(null, name, prefix, usePercentages) } open class MaterialTypeUpdateDto( - @field:NotNull(message = MATERIAL_TYPE_ID_NULL_MESSAGE) - val id: Long, + @field:NotNull(message = MATERIAL_TYPE_ID_NULL_MESSAGE) + val id: Long, - @field:NullOrNotBlank(message = MATERIAL_TYPE_NAME_NULL_MESSAGE) - val name: String?, + @field:NullOrNotBlank(message = MATERIAL_TYPE_NAME_NULL_MESSAGE) + val name: String?, - @field:NullOrSize(min = 3, max = 3, message = MATERIAL_TYPE_PREFIX_NULL_MESSAGE) - val prefix: String? + @field:NullOrSize(min = 3, max = 3, message = MATERIAL_TYPE_PREFIX_NULL_MESSAGE) + val prefix: String? ) : EntityDto { override fun toEntity(): MaterialType = - MaterialType(id, name ?: "", prefix ?: "") + MaterialType(id, name ?: "", prefix ?: "") } // ==== DSL ==== fun materialType( - id: Long? = null, - name: String = "name", - prefix: String = "PRE", - usePercentages: Boolean = false, - systemType: Boolean = false, - op: MaterialType.() -> Unit = {} + id: Long? = null, + name: String = "name", + prefix: String = "PRE", + usePercentages: Boolean = false, + systemType: Boolean = false, + op: MaterialType.() -> Unit = {} ) = MaterialType(id, name, prefix, usePercentages, systemType).apply(op) fun materialType( - materialType: MaterialType, - newId: Long? = null, - newName: String? = null, - newSystemType: Boolean? = null -) = with(materialType) { MaterialType(newId ?: id, newName ?: name, prefix, usePercentages, newSystemType ?: systemType) } + materialType: MaterialType, + newId: Long? = null, + newName: String? = null, + newSystemType: Boolean? = null +) = with(materialType) { + MaterialType( + newId ?: id, + newName ?: name, + prefix, + usePercentages, + newSystemType ?: systemType + ) +} fun materialTypeSaveDto( - name: String = "name", - prefix: String = "PRE", - usePercentages: Boolean = false, - op: MaterialTypeSaveDto.() -> Unit = {} + name: String = "name", + prefix: String = "PRE", + usePercentages: Boolean = false, + op: MaterialTypeSaveDto.() -> Unit = {} ) = MaterialTypeSaveDto(name, prefix, usePercentages).apply(op) fun materialTypeUpdateDto( - id: Long = 0L, - name: String? = null, - prefix: String? = null, - op: MaterialTypeUpdateDto.() -> Unit = {} + id: Long = 0L, + name: String? = null, + prefix: String? = null, + op: MaterialTypeUpdateDto.() -> Unit = {} ) = MaterialTypeUpdateDto(id, name, prefix).apply(op) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Mix.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Mix.kt index 0b9f74a..fff6cfe 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Mix.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Mix.kt @@ -15,6 +15,7 @@ private const val MIX_RECIPE_NULL_MESSAGE = "Un recette est requise" private const val MIX_MATERIAL_TYPE_NULL_MESSAGE = "Un type de prodsuit est requis" @Entity +@Table(name = "mix") data class Mix( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @@ -24,12 +25,14 @@ data class Mix( @JsonIgnore @ManyToOne + @JoinColumn(name = "recipe_id") val recipe: Recipe, @ManyToOne + @JoinColumn(name = "mix_type_id") var mixType: MixType, - @OneToMany(cascade = [CascadeType.ALL]) + @OneToMany(cascade = [CascadeType.ALL], mappedBy = "mix") var mixMaterials: MutableCollection, ) : Model { constructor(recipe: Recipe, mixType: MixType) : this(null, null, recipe, mixType, mutableListOf()) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixMaterial.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixMaterial.kt index b73cadf..af91cac 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixMaterial.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixMaterial.kt @@ -5,6 +5,7 @@ import java.util.* import javax.persistence.* @Entity +@Table(name = "mix_material") data class MixMaterial( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @@ -12,9 +13,11 @@ data class MixMaterial( @JsonIgnore @ManyToOne + @JoinColumn(name = "mix_id") val mix: Mix, @ManyToOne + @JoinColumn(name = "material_id") val material: Material, val quantity: Float diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixType.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixType.kt index 92d8cb9..5c23056 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixType.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/MixType.kt @@ -6,6 +6,7 @@ import javax.persistence.* const val IDENTIFIER_MATERIAL_NAME = "material" @Entity +@Table(name = "mix_type") data class MixType( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @@ -15,6 +16,7 @@ data class MixType( override var name: String, @OneToOne(cascade = [CascadeType.ALL]) + @JoinColumn(name = "material_id") var material: Material ) : NamedModel { constructor(name: String, material: Material) : this(null, name, material) diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt index 17f894f..a8a6763 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/Recipe.kt @@ -18,6 +18,7 @@ private const val RECIPE_SAMPLE_TOO_SMALL_MESSAGE = "Le numéro d'échantillon d private const val RECIPE_COMPANY_NULL_MESSAGE = "Une bannière est requise" @Entity +@Table(name = "recipe") data class Recipe( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @@ -30,6 +31,7 @@ data class Recipe( val sample: Int, + @Column(name = "approbation_date") val approbationDate: LocalDate?, /** A remark given by the creator of the recipe. */ @@ -39,12 +41,13 @@ data class Recipe( var note: String, @ManyToOne + @JoinColumn(name = "company_id") val company: Company, - @OneToMany(cascade = [CascadeType.ALL]) + @OneToMany(cascade = [CascadeType.ALL], mappedBy = "recipe") val mixes: MutableCollection, - @OneToMany(cascade = [CascadeType.ALL]) + @OneToMany(cascade = [CascadeType.ALL], mappedBy = "recipe") var steps: MutableCollection ) : Model { constructor( diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.kt index 40cd5cf..15f356c 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/model/RecipeStep.kt @@ -7,6 +7,7 @@ import javax.persistence.* import javax.validation.constraints.NotNull @Entity +@Table(name = "recipe_step") data class RecipeStep( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @@ -14,6 +15,7 @@ data class RecipeStep( @JsonIgnore @ManyToOne + @JoinColumn(name = "recipe_id") val recipe: Recipe?, val message: String diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt index 62e8cbc..27ce618 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/service/RecipeService.kt @@ -69,7 +69,7 @@ class RecipeServiceImpl( note = persistedRecipe.note, company = persistedRecipe.company, mixes = persistedRecipe.mixes, - steps = steps?.toMutableList() ?: persistedRecipe.steps + steps = steps?.map { recipeStep(recipe = persistedRecipe, message = it.message) }?.toMutableList() ?: persistedRecipe.steps ) }) }